Skip to content

Commit

Permalink
Add Ex metric for TEx computation in visit and ccd table.
Browse files Browse the repository at this point in the history
  • Loading branch information
PFLeget committed Nov 6, 2024
1 parent 1c8e634 commit e28e3cc
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 5 deletions.
98 changes: 94 additions & 4 deletions python/lsst/pipe/tasks/computeExposureSummaryStats.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import lsst.afw.image as afwImage
import lsst.geom as geom
from lsst.meas.algorithms import ScienceSourceSelectorTask
from lsst.meas.algorithms.computeExPsf import ComputeExPsfTask, ComputeExPsfConfig
from lsst.utils.timer import timeMethod
import lsst.ip.isr as ipIsr

Expand Down Expand Up @@ -137,6 +138,22 @@ class ComputeExposureSummaryStatsConfig(pexConfig.Config):
doc="Signal-to-noise ratio for computing the magnitude limit depth.",
default=5.0
)
psfTE1TreecorrConfig = pexConfig.ConfigField(
dtype=ComputeExPsfConfig,
doc="Treecorr config for computing scalar value of TE1.",
)
psfTE2TreecorrConfig = pexConfig.ConfigField(
dtype=ComputeExPsfConfig,
doc="Treecorr config for computing scalar value of TE1.",
)
psfTE3TreecorrConfig = pexConfig.ConfigField(
dtype=ComputeExPsfConfig,
doc="Treecorr config for computing scalar value of TE1.",
)
psfTE4TreecorrConfig = pexConfig.ConfigField(
dtype=ComputeExPsfConfig,
doc="Treecorr config for computing scalar value of TE1.",
)

def setDefaults(self):
super().setDefaults()
Expand All @@ -159,6 +176,22 @@ def setDefaults(self):
self.starSelector.signalToNoise.fluxField = "slot_PsfFlux_instFlux"
self.starSelector.signalToNoise.errField = "slot_PsfFlux_instFluxErr"

min_theta = [1e-6, 5.0, 1e-6, 5.0]
max_theta = [1.0, 100.0, 5.0, 20.0]
TExTreecorrConfig = [
self.psfTE1TreecorrConfig,
self.psfTE2TreecorrConfig,
self.psfTE3TreecorrConfig,
self.psfTE4TreecorrConfig,
]

for texc, mint, maxt in zip(TExTreecorrConfig, min_theta, max_theta):
texc.treecorr.min_sep = mint / 60.0
texc.treecorr.max_sep = maxt / 60.0
texc.treecorr.nbins = 1
texc.treecorr.bin_type = "Linear"
texc.treecorr.sep_units = "degree"


class ComputeExposureSummaryStatsTask(pipeBase.Task):
"""Task to compute exposure summary statistics.
Expand Down Expand Up @@ -199,6 +232,18 @@ class ComputeExposureSummaryStatsTask(pipeBase.Task):
- maxDistToNearestPsf
- psfTraceRadiusDelta
- psfApFluxDelta
- psfTE1E1
- psfTE1E2
- psfTE1Ex
- psfTE2E1
- psfTE2E2
- psfTE2Ex
- psfTE3E1
- psfTE3E2
- psfTE3Ex
- psfTE4E1
- psfTE4E2
- psfTE4Ex
This quantity is computed based on the aperture correction map, the
psfSigma, and the image mask to assess the robustness of the aperture
Expand Down Expand Up @@ -325,6 +370,18 @@ def update_psf_stats(
summary.psfTraceRadiusDelta = nan
summary.psfApFluxDelta = nan
summary.psfApCorrSigmaScaledDelta = nan
summary.psfTE1E1 = nan
summary.psfTE1E2 = nan
summary.psfTE1Ex = nan
summary.psfTE2E1 = nan
summary.psfTE2E2 = nan
summary.psfTE2Ex = nan
summary.psfTE3E1 = nan
summary.psfTE3E2 = nan
summary.psfTE3Ex = nan
summary.psfTE4E1 = nan
summary.psfTE4E2 = nan
summary.psfTE4Ex = nan

if psf is None:
return
Expand Down Expand Up @@ -410,10 +467,13 @@ def update_psf_stats(
psfE1 = (psfXX - psfYY)/(psfXX + psfYY)
psfE2 = 2*psfXY/(psfXX + psfYY)

psfStarDeltaE1Median = np.median(starE1 - psfE1)
psfStarDeltaE1Scatter = sigmaMad(starE1 - psfE1, scale='normal')
psfStarDeltaE2Median = np.median(starE2 - psfE2)
psfStarDeltaE2Scatter = sigmaMad(starE2 - psfE2, scale='normal')
e1Residuals = starE1 - psfE1
e2Residuals = starE2 - psfE2

psfStarDeltaE1Median = np.median(e1Residuals)
psfStarDeltaE1Scatter = sigmaMad(e1Residuals, scale='normal')
psfStarDeltaE2Median = np.median(e2Residuals)
psfStarDeltaE2Scatter = sigmaMad(e2Residuals, scale='normal')

psfStarDeltaSizeMedian = np.median(starSize - psfSize)
psfStarDeltaSizeScatter = sigmaMad(starSize - psfSize, scale='normal')
Expand All @@ -427,6 +487,36 @@ def update_psf_stats(
summary.psfStarDeltaSizeScatter = float(psfStarDeltaSizeScatter)
summary.psfStarScaledDeltaSizeScatter = float(psfStarScaledDeltaSizeScatter)

ra = psf_cat["coord_ra"]
dec = psf_cat["coord_dec"]

# Comp TEx

TExTreecorrConfig = [
self.config.psfTE1TreecorrConfig,
self.config.psfTE2TreecorrConfig,
self.config.psfTE3TreecorrConfig,
self.config.psfTE4TreecorrConfig,
]

TExOutput = [
[summary.psfTE1E1, summary.psfTE1E2, summary.psfTE1Ex],
[summary.psfTE2E1, summary.psfTE2E2, summary.psfTE2Ex],
[summary.psfTE3E1, summary.psfTE3E2, summary.psfTE3Ex],
[summary.psfTE4E1, summary.psfTE4E2, summary.psfTE4Ex],
]

for config, texoutput in zip(TExTreecorrConfig, TExOutput):

task = ComputeExPsfTask(config)
output = task.run(
e1Residuals, e2Residuals, ra, dec, units="degree"
)

texoutput[0] = output.metric_E1
texoutput[1] = output.metric_E2
texoutput[2] = output.metric_Ex

if image_mask is not None:
maxDistToNearestPsf = maximum_nearest_psf_distance(
image_mask,
Expand Down
12 changes: 11 additions & 1 deletion python/lsst/pipe/tasks/postprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,10 @@ def run(self, visitSummaryRefs):
"maxDistToNearestPsf",
"effTime", "effTimePsfSigmaScale",
"effTimeSkyBgScale", "effTimeZeroPointScale",
"magLim"]
"magLim", "psfTE1E1", "psfTE1E2", "psfTE1Ex",
"psfTE2E1", "psfTE2E2", "psfTE2Ex",
"psfTE3E1", "psfTE3E2", "psfTE3Ex",
"psfTE4E1", "psfTE4E2", "psfTE4Ex"]
ccdEntry = summaryTable[selectColumns].to_pandas().set_index("id")
# 'visit' is the human readable visit number.
# 'visitId' is the key to the visitId table. They are the same.
Expand Down Expand Up @@ -1364,6 +1367,13 @@ def run(self, visitSummaries):
visitEntry["obsStart"] = visitEntry["expMidpt"] - 0.5 * pd.Timedelta(seconds=expTime)
expTime_days = expTime / (60*60*24)
visitEntry["obsStartMJD"] = visitEntry["expMidptMJD"] - 0.5 * expTime_days
TEx = [
"psfTE1E1", "psfTE1E2", "psfTE1Ex",
"psfTE2E1", "psfTE2E2", "psfTE2Ex",
"psfTE3E1", "psfTE3E2", "psfTE3Ex",
]
for tex in TEx:
visitEntry[tex] = visitRow[tex]
visitEntries.append(visitEntry)

# TODO: DM-30623, Add programId, exposureType, cameraTemp,
Expand Down
16 changes: 16 additions & 0 deletions tests/test_computeExposureSummaryStats.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,22 @@ def testComputeExposureSummary(self):
self.assertFloatsAlmostEqual(summary.effTime, expTime, rtol=1e-3)
self.assertFloatsAlmostEqual(summary.magLim, 26.584, rtol=1e-3)

# Check TExEx does exist, would need a more complex unit
# test with ~O(100) stars to check.
nan = float('nan')
self.assertFloatsAlmostEqual(summary.psfTE1E1, nan, ignoreNaNs=True)
self.assertFloatsAlmostEqual(summary.psfTE1E2, nan, ignoreNaNs=True)
self.assertFloatsAlmostEqual(summary.psfTE1Ex, nan, ignoreNaNs=True)
self.assertFloatsAlmostEqual(summary.psfTE2E1, nan, ignoreNaNs=True)
self.assertFloatsAlmostEqual(summary.psfTE2E2, nan, ignoreNaNs=True)
self.assertFloatsAlmostEqual(summary.psfTE2Ex, nan, ignoreNaNs=True)
self.assertFloatsAlmostEqual(summary.psfTE3E1, nan, ignoreNaNs=True)
self.assertFloatsAlmostEqual(summary.psfTE3E2, nan, ignoreNaNs=True)
self.assertFloatsAlmostEqual(summary.psfTE3Ex, nan, ignoreNaNs=True)
self.assertFloatsAlmostEqual(summary.psfTE4E1, nan, ignoreNaNs=True)
self.assertFloatsAlmostEqual(summary.psfTE4E2, nan, ignoreNaNs=True)
self.assertFloatsAlmostEqual(summary.psfTE4Ex, nan, ignoreNaNs=True)

def testComputeMagnitudeLimit(self):
"""Test the magnitude limit calculation using fiducials from SMTN-002
and syseng_throughputs."""
Expand Down

0 comments on commit e28e3cc

Please sign in to comment.