Coverage for python/lsst/faro/measurement/TractMeasurementTasks.py : 44%

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
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
12__all__ = ("WPerpConfig", "WPerpTask", "TExConfig", "TExTask")
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 )
25class WPerpTask(Task):
26 ConfigClass = WPerpConfig
27 _DefaultName = "WPerpTask"
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])
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)
43 wPerp = self.calcWPerp(rgicat, extVals, metricName)
44 return wPerp
45 else:
46 return Struct(measurement=Measurement(metricName, np.nan * u.mmag))
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 )
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 }
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))
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
102class TExTask(Task):
103 ConfigClass = TExConfig
104 _DefaultName = "TExTask"
106 def run(
107 self, metricName, catalogs, photoCalibs=None, astromCalibs=None, dataIds=None
108 ):
109 self.log.info("Measuring %s", metricName)
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("")))
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 )