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 

3 

4from lsst.pipe.base import Struct, Task 

5from lsst.verify import Measurement, Datum 

6from lsst.pex.config import Config, Field 

7from lsst.faro.utils.stellar_locus import stellarLocusResid, calcQuartileClippedStats 

8from lsst.faro.utils.matcher import makeMatchedPhotom 

9from lsst.faro.utils.extinction_corr import extinction_corr 

10from lsst.faro.utils.tex import calculateTEx 

11 

12__all__ = ("WPerpConfig", "WPerpTask", "TExConfig", "TExTask") 

13 

14 

15class WPerpConfig(Config): 

16 # These are cuts to apply to the r-band only: 

17 bright_rmag_cut = Field( 

18 doc="Bright limit of catalog entries to include", dtype=float, default=17.0 

19 ) 

20 faint_rmag_cut = Field( 

21 doc="Faint limit of catalog entries to include", dtype=float, default=23.0 

22 ) 

23 

24 

25class WPerpTask(Task): 

26 ConfigClass = WPerpConfig 

27 _DefaultName = "WPerpTask" 

28 

29 def run( 

30 self, metricName, catalogs, photoCalibs=None, astromCalibs=None, dataIds=None 

31 ): 

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

33 bands = set([f["band"] for f in dataIds]) 

34 

35 if ("g" in bands) & ("r" in bands) & ("i" in bands): 

36 rgicatAll = makeMatchedPhotom(dataIds, catalogs, photoCalibs) 

37 magcut = (rgicatAll["base_PsfFlux_mag_r"] < self.config.faint_rmag_cut) & ( 

38 rgicatAll["base_PsfFlux_mag_r"] > self.config.bright_rmag_cut 

39 ) 

40 rgicat = rgicatAll[magcut] 

41 extVals = extinction_corr(rgicat, bands) 

42 

43 wPerp = self.calcWPerp(rgicat, extVals, metricName) 

44 return wPerp 

45 else: 

46 return Struct(measurement=Measurement(metricName, np.nan * u.mmag)) 

47 

48 def calcWPerp(self, phot, extinctionVals, metricName): 

49 p1, p2, p1coeffs, p2coeffs = stellarLocusResid( 

50 phot["base_PsfFlux_mag_g"] - extinctionVals["A_g"], 

51 phot["base_PsfFlux_mag_r"] - extinctionVals["A_r"], 

52 phot["base_PsfFlux_mag_i"] - extinctionVals["A_i"], 

53 ) 

54 

55 if np.size(p2) > 2: 

56 p2_rms = calcQuartileClippedStats(p2).rms * u.mag 

57 extras = { 

58 "p1_coeffs": Datum( 

59 p1coeffs * u.Unit(""), 

60 label="p1_coefficients", 

61 description="p1 coeffs from wPerp fit", 

62 ), 

63 "p2_coeffs": Datum( 

64 p2coeffs * u.Unit(""), 

65 label="p2_coefficients", 

66 description="p2_coeffs from wPerp fit", 

67 ), 

68 } 

69 

70 return Struct( 

71 measurement=Measurement(metricName, p2_rms.to(u.mmag), extras=extras) 

72 ) 

73 else: 

74 return Struct(measurement=Measurement(metricName, np.nan * u.mmag)) 

75 

76 

77class TExConfig(Config): 

78 minSep = Field( 

79 doc="Inner radius of the annulus in arcmin", dtype=float, default=0.25 

80 ) 

81 maxSep = Field( 

82 doc="Outer radius of the annulus in arcmin", dtype=float, default=1.0 

83 ) 

84 nbins = Field(doc="Number of log-spaced angular bins", dtype=int, default=10) 

85 rhoStat = Field(doc="Rho statistic to be computed", dtype=int, default=1) 

86 shearConvention = Field( 

87 doc="Use shear ellipticity convention rather than distortion", 

88 dtype=bool, 

89 default=False, 

90 ) 

91 columnPsf = Field( 

92 doc="Column to use for PSF model shape moments", 

93 dtype=str, 

94 default="base_SdssShape_psf", 

95 ) 

96 column = Field( 

97 doc="Column to use for shape moments", dtype=str, default="base_SdssShape" 

98 ) 

99 # Eventually want to add option to use only PSF reserve stars 

100 

101 

102class TExTask(Task): 

103 ConfigClass = TExConfig 

104 _DefaultName = "TExTask" 

105 

106 def run( 

107 self, metricName, catalogs, photoCalibs=None, astromCalibs=None, dataIds=None 

108 ): 

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

110 

111 result = calculateTEx(catalogs, photoCalibs, astromCalibs, self.config) 

112 if "corr" not in result.keys(): 

113 return Struct(measurement=Measurement(metricName, np.nan * u.Unit(""))) 

114 

115 writeExtras = True 

116 if writeExtras: 

117 extras = {} 

118 extras["radius"] = Datum( 

119 result["radius"], label="radius", description="Separation (arcmin)." 

120 ) 

121 extras["corr"] = Datum( 

122 result["corr"], label="Correlation", description="Correlation." 

123 ) 

124 extras["corrErr"] = Datum( 

125 result["corrErr"], 

126 label="Correlation Uncertianty", 

127 description="Correlation Uncertainty.", 

128 ) 

129 else: 

130 extras = None 

131 return Struct( 

132 measurement=Measurement( 

133 metricName, np.mean(np.abs(result["corr"])), extras=extras 

134 ) 

135 )