Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1import astropy.units as u 

2import numpy as np 

3from lsst.pipe.base import Struct, Task 

4from lsst.pex.config import Config, Field 

5from lsst.verify import Measurement 

6 

7from lsst.faro.utils.matcher import mergeCatalogs 

8 

9__all__ = ( 

10 "NumSourcesTask", 

11 "NumSourcesMergeTask", 

12 "NumpySummaryConfig", 

13 "NumpySummaryTask", 

14) 

15 

16 

17class NumSourcesConfig(Config): 

18 doPrimary = Field( 

19 doc="Only count sources where detect_isPrimary is True.", 

20 dtype=bool, 

21 default=False, 

22 ) 

23 

24 

25class NumSourcesTask(Task): 

26 r"""Simple default task count the number of sources/objects in catalog.""" 

27 

28 ConfigClass = NumSourcesConfig 

29 _DefaultName = "numSourcesTask" 

30 

31 def run(self, metricName, catalog, **kwargs): 

32 """Run NumSourcesTask 

33 

34 Parameters 

35 ---------- 

36 metricName : `str` 

37 The name of the metric to measure. 

38 catalog : `dict` 

39 `lsst.afw.table` Catalog type 

40 kwargs 

41 Extra keyword arguments used to construct the task. 

42 

43 Returns 

44 ------- 

45 measurement : `Struct` 

46 The measured value of the metric. 

47 """ 

48 self.log.info("Measuring %s", metricName) 

49 if self.config.doPrimary: 

50 nSources = np.sum(catalog["detect_isPrimary"] is True) 

51 else: 

52 nSources = len(catalog) 

53 self.log.info("Number of sources (nSources) = %i" % nSources) 

54 meas = Measurement("nsrcMeas", nSources * u.count) 

55 return Struct(measurement=meas) 

56 

57 

58class NumSourcesMergeTask(Task): 

59 

60 ConfigClass = Config 

61 _DefaultName = "numSourcesMergeTask" 

62 

63 def run(self, metricName, catalogs, photoCalibs, astromCalibs, **kwargs): 

64 self.log.info("Measuring %s", metricName) 

65 catalog = mergeCatalogs(catalogs, photoCalibs, astromCalibs) 

66 nSources = len(catalog) 

67 meas = Measurement("nsrcMeas", nSources * u.count) 

68 return Struct(measurement=meas) 

69 

70 

71class NumpySummaryConfig(Config): 

72 summary = Field( 

73 dtype=str, default="median", doc="Aggregation to use for summary metrics" 

74 ) 

75 

76 

77class NumpySummaryTask(Task): 

78 

79 ConfigClass = NumpySummaryConfig 

80 _DefaultName = "numpySummaryTask" 

81 

82 def run(self, measurements, agg_name, package, metric): 

83 agg = agg_name.lower() 

84 if agg == "summary": 

85 agg = self.config.summary 

86 self.log.info("Computing the %s of %s_%s values", agg, package, metric) 

87 

88 if len(measurements) == 0: 

89 self.log.info("Received zero length measurements list. Returning NaN.") 

90 # In the case of an empty list, there is nothing we can do other than 

91 # to return a NaN 

92 value = u.Quantity(np.nan) 

93 else: 

94 unit = measurements[0].quantity.unit 

95 value = getattr(np, agg)( 

96 u.Quantity( 

97 [x.quantity for x in measurements if np.isfinite(x.quantity)] 

98 ) 

99 ) 

100 # Make sure return has same unit as inputs 

101 # In some cases numpy can return a NaN and the unit gets dropped 

102 value = value.value * unit 

103 return Struct( 

104 measurement=Measurement( 

105 f"metricvalue_{agg_name.lower()}_{package}_{metric}", value 

106 ) 

107 )