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__ = ("WPerpTaskConfig", "WPerpTask", "TExTaskConfig", "TExTask") 

13 

14 

15class WPerpTaskConfig(Config): 

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

17 bright_rmag_cut = Field(doc="Bright limit of catalog entries to include", 

18 dtype=float, default=17.0) 

19 faint_rmag_cut = Field(doc="Faint limit of catalog entries to include", 

20 dtype=float, default=23.0) 

21 

22 

23class WPerpTask(Task): 

24 ConfigClass = WPerpTaskConfig 

25 _DefaultName = "WPerpTask" 

26 

27 def run(self, metricName, catalogs, photoCalibs=None, astromCalibs=None, dataIds=None): 

28 self.log.info(f"Measuring {metricName}") 

29 bands = set([f['band'] for f in dataIds]) 

30 

31 if ('g' in bands) & ('r' in bands) & ('i' in bands): 

32 rgicatAll = makeMatchedPhotom(dataIds, catalogs, photoCalibs) 

33 magcut = ((rgicatAll['base_PsfFlux_mag_r'] < self.config.faint_rmag_cut) 

34 & (rgicatAll['base_PsfFlux_mag_r'] > self.config.bright_rmag_cut)) 

35 rgicat = rgicatAll[magcut] 

36 extVals = extinction_corr(rgicat, bands) 

37 

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

39 return wPerp 

40 else: 

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

42 

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

44 p1, p2, p1coeffs, p2coeffs = stellarLocusResid(phot['base_PsfFlux_mag_g']-extinctionVals['A_g'], 

45 phot['base_PsfFlux_mag_r']-extinctionVals['A_r'], 

46 phot['base_PsfFlux_mag_i']-extinctionVals['A_i']) 

47 

48 if np.size(p2) > 2: 

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

50 extras = {'p1_coeffs': Datum(p1coeffs*u.Unit(''), label='p1_coefficients', 

51 description='p1 coeffs from wPerp fit'), 

52 'p2_coeffs': Datum(p2coeffs*u.Unit(''), label='p2_coefficients', 

53 description='p2_coeffs from wPerp fit')} 

54 

55 return Struct(measurement=Measurement(metricName, p2_rms.to(u.mmag), extras=extras)) 

56 else: 

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

58 

59 

60class TExTaskConfig(Config): 

61 minSep = Field(doc="Inner radius of the annulus in arcmin", 

62 dtype=float, default=0.25) 

63 maxSep = Field(doc="Outer radius of the annulus in arcmin", 

64 dtype=float, default=1.) 

65 nbins = Field(doc="Number of log-spaced angular bins", 

66 dtype=int, default=10) 

67 rhoStat = Field(doc="Rho statistic to be computed", 

68 dtype=int, default=1) 

69 shearConvention = Field(doc="Use shear ellipticity convention rather than distortion", 

70 dtype=bool, default=False) 

71 columnPsf = Field(doc="Column to use for PSF model shape moments", 

72 dtype=str, default='slot_PsfShape') 

73 column = Field(doc="Column to use for shape moments", 

74 dtype=str, default='slot_Shape') 

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

76 

77 

78class TExTask(Task): 

79 ConfigClass = TExTaskConfig 

80 _DefaultName = "TExTask" 

81 

82 def run(self, metricName, catalogs, photoCalibs=None, astromCalibs=None, dataIds=None): 

83 self.log.info(f"Measuring {metricName}") 

84 

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

86 if 'corr' not in result.keys(): 

87 return Struct(measurement=Measurement(metricName, np.nan*u.Unit(''))) 

88 

89 writeExtras = True 

90 if writeExtras: 

91 extras = {} 

92 extras['radius'] = Datum(result['radius'], label='radius', 

93 description='Separation (arcmin).') 

94 extras['corr'] = Datum(result['corr'], label='Correlation', 

95 description='Correlation.') 

96 extras['corrErr'] = Datum(result['corrErr'], label='Correlation Uncertianty', 

97 description='Correlation Uncertainty.') 

98 else: 

99 extras = None 

100 return Struct(measurement=Measurement(metricName, np.mean(np.abs(result['corr'])), extras=extras))