Skip to content

Commit

Permalink
Almost working, with original faro ADx/AFx method
Browse files Browse the repository at this point in the history
  • Loading branch information
cmsaunders committed May 11, 2023
1 parent fd9f876 commit c517813
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 60 deletions.
7 changes: 4 additions & 3 deletions pipelines/matchedVisitQualityCore.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@ tasks:
class: lsst.analysis.tools.tasks.AssociatedSourcesTractAnalysisTask
config:
connections.outputName: matchedVisitCore
# atools.stellarPhotometricRepeatability: StellarPhotometricRepeatability
#atools.stellarPhotometricRepeatability: StellarPhotometricRepeatability

Check warning on line 8 in pipelines/matchedVisitQualityCore.yaml

View workflow job for this annotation

GitHub Actions / call-workflow / yamllint

8:8 [comments] missing starting space in comment
# atools.stellarPhotometricResiduals: StellarPhotometricResidualsFocalPlane
# atools.stellarAstrometricResidualsRA: StellarAstrometricResidualsRAFocalPlanePlot
# atools.stellarAstrometricResidualsDec: StellarAstrometricResidualsDecFocalPlanePlot
# atools.stellarAstrometricResidualStdDevRA: StellarAstrometricResidualStdDevRAFocalPlanePlot
# atools.stellarAstrometricResidualStdDevDec: StellarAstrometricResidualStdDevDecFocalPlanePlot
atools.stellarAstrometricRepeatability1: AstrometricRelativeRepeatability
atools.stellarAstrometricRepeatability1.xValue: 1
atools.stellarAstrometricRepeatability1.fluxType: test
atools.stellarAstrometricRepeatability1.process.calculateActions.rms.annulus: 5
atools.stellarAstrometricRepeatability2: AstrometricRelativeRepeatability
atools.stellarAstrometricRepeatability2.xValue: 2
atools.stellarAstrometricRepeatability2.process.calculateActions.rms.annulus: 20
#atools.stellarAstrometricRepeatability2.xValue: 2

Check warning on line 19 in pipelines/matchedVisitQualityCore.yaml

View workflow job for this annotation

GitHub Actions / call-workflow / yamllint

19:8 [comments] missing starting space in comment
#atools.stellarAstrometricRepeatability2.process.calculateActions.rms.annulus: 20

Check warning on line 20 in pipelines/matchedVisitQualityCore.yaml

View workflow job for this annotation

GitHub Actions / call-workflow / yamllint

20:8 [comments] missing starting space in comment
atools.stellarAstrometricRepeatability3: AstrometricRelativeRepeatability
atools.stellarAstrometricRepeatability3.xValue: 3
atools.stellarAstrometricRepeatability3.process.calculateActions.rms.annulus: 200
Expand Down
30 changes: 13 additions & 17 deletions python/lsst/analysis/tools/actions/keyedData/calcDistances.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,26 @@
from astropy.coordinates import SkyCoord
from lsst.faro.utils.separations import matchVisitComputeDistance
from lsst.pex.config import Field
from lsst.pex.config.configurableActions import ConfigurableActionField

from ...interfaces import KeyedData, KeyedDataAction, KeyedDataSchema, Vector, VectorAction
from ...interfaces import KeyedData, KeyedDataAction, KeyedDataSchema, Vector


class CalcDistances(KeyedDataAction):
"""Calculate distances in a matched catalog"""

groupKey = Field[str](doc="Column key to use for forming groups", default="obj_index")
visitKey = Field[str](doc="Visit key", default="visit")
raKey = Field[str](doc="RA name", default="coord_ra")
decKey = Field[str](doc="RA name", default="coord_dec")
visitKey = Field[str](doc="Column key to use for matching visits", default="visit")
raKey = Field[str](doc="RA column key", default="coord_ra")
decKey = Field[str](doc="Dec column key", default="coord_dec")
annulus = Field[float](doc="Radial distance of the annulus in arcmin", default=5.0)
width = Field[float](doc="Width of annulus in arcmin", default=2.0)
mags = ConfigurableActionField[VectorAction](doc="Action which supplies magnitudes")
minMag = Field[float](doc="Minimum magnitude", default=17)
maxMag = Field[float](doc="Maximum magnitude", default=21.5)
threshAD = Field[float](doc="Threshold in mas for AFx calculation.", default=20.0)
threshAF = Field[float](
doc="Percentile of differences that can vary by more than threshAD.", default=10.0
)

def getInputSchema(self) -> KeyedDataSchema:
return tuple(self.mags.getInputSchema()) + (
return ( # tuple(self.mags.getInputSchema()) + (
(self.groupKey, Vector),
(self.raKey, Vector),
(self.decKey, Vector),
Expand All @@ -43,9 +39,6 @@ def __call__(self, data: KeyedData, **kwargs) -> KeyedData:
width = self.width * u.arcmin
annulus = (D + (width / 2) * np.array([-1, +1])).to(u.radian)

# This part copies calcRmsDistances/calcSepOutliers in Faro
inMagRange = (self.mags(data) > self.minMag) & (self.mags(data) < self.maxMag)

# TODO: this line needs to add ra, dec,
df = pd.DataFrame(
{
Expand All @@ -55,7 +48,7 @@ def __call__(self, data: KeyedData, **kwargs) -> KeyedData:
"visit": data[self.visitKey],
}
)
df = df[inMagRange]

meanRa = df.groupby("groupKey")["coord_ra"].aggregate("mean")
meanDec = df.groupby("groupKey")["coord_dec"].aggregate("mean")

Expand All @@ -74,7 +67,7 @@ def __call__(self, data: KeyedData, **kwargs) -> KeyedData:
tt4 = 0
import time

for id in range(len(meanRa)):
for id in range(len(meanRa[:100])):
match_inds = idx == id
match_ids = idxCatalog[match_inds & (idxCatalog != id)]
if match_ids.sum() == 0:
Expand Down Expand Up @@ -130,6 +123,8 @@ def __call__(self, data: KeyedData, **kwargs) -> KeyedData:
AFx = np.nan * u.percent
ADx = np.nan * u.marcsec
absDiffSeparations = np.array([]) * u.marcsec
absDiffSeparations2 = np.array([]) * u.marcsec

else:
sepResiduals = np.concatenate(sepResiduals)
sepResiduals2 = np.concatenate(sepResiduals2)
Expand All @@ -142,8 +137,9 @@ def __call__(self, data: KeyedData, **kwargs) -> KeyedData:
distanceParams = {
"rmsDistances": (np.array(rmsDistances) * u.radian).to(u.marcsec).value,
"separationResiduals": absDiffSeparations2.value,
"AMx": AMx,
"ADx": ADx,
"AFx": AFx,
"AMx": AMx.value,
"ADx": ADx.value,
"AFx": AFx.value,
}
print(distanceParams)
return distanceParams
75 changes: 35 additions & 40 deletions python/lsst/analysis/tools/atools/astrometricRepeatability.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
LoadVector,
MagColumnNanoJansky,
RAcosDec,
RangeSelector,
ResidualWithPerGroupStatistic,
SnSelector,
ThresholdSelector,
Expand Down Expand Up @@ -213,66 +214,60 @@ def setDefaults(self):


class AstrometricRelativeRepeatability(AnalysisTool):
"""This is going to make AMx, ADx, AFx"""
"""Calculate the AMx, ADx, AFx metrics and make histograms showing the data
used to compute the metrics.
"""

# TODO: add fluxTpye field
fluxType = Field[str](doc="Flux type to calculate repeatability with", default="psfFlux")
xValue = Field[int](doc="Metric suffix corresponding to annulus size (1, 2, or 3)", default=1)
AMThresh = Field[float](doc="AMx threshold", default=10.0)

def setDefaults(self):
super().setDefaults()
self.prep.selectors.bandSelector = BandSelector()
# Following what was done in faro, only sources with S/N between 50
# and 50000 are included. The other filtering that was done in faro
# is now covered by only including sources from isolated_star_sources.
self.prep.selectors.snSelector = SnSelector()
self.prep.selectors.snSelector.fluxType = "psfFlux"
self.prep.selectors.snSelector.threshold = 10
self.prep.selectors.snSelector.fluxType = self.fluxType
self.prep.selectors.snSelector.threshold = 50
self.prep.selectors.snSelector.maxSN = 50000
# TODO: fill in other filtering here, following filterMatches

# MOve mag calculation here, then do filter here, not in calcDistances
# Select only sources with magnitude between 17 and 21.5
self.process.buildActions.mags = MagColumnNanoJansky(vectorKey=self.fluxType)
self.process.filterActions.coord_ra = DownselectVector(vectorKey="coord_ra")
self.process.filterActions.coord_ra.selector = RangeSelector(key="mags", minimum=17, maximum=21.5)
self.process.filterActions.coord_dec = DownselectVector(
vectorKey="coord_dec", selector=self.process.filterActions.coord_ra.selector
)
self.process.filterActions.obj_index = DownselectVector(
vectorKey="obj_index", selector=self.process.filterActions.coord_ra.selector
)
self.process.filterActions.visit = DownselectVector(
vectorKey="visit", selector=self.process.filterActions.coord_ra.selector
)

# Maybe can make this a calculateAction?
self.process.calculateActions.rms = CalcDistances(mags=MagColumnNanoJansky(vectorKey="psfFlux"))
self.process.calculateActions.rms = CalcDistances()

self.produce.metric.units = {
"AMx": "mas",
"AFx": "mas",
"ADx": "percent",
"AFx": "percent",
"ADx": "mas",
}

self.produce.metric.newNames = {
"AMx": f"AM{self.xValue}",
"AFx": f"AF{self.xValue}",
"ADx": f"AD{self.xValue}",
"AMx": f"{{band}}_AM{self.xValue}", # f"AM{self.xValue}",
"AFx": f"{{band}}_AF{self.xValue}", # f"AF{self.xValue}",
"ADx": f"{{band}}_AD{self.xValue}", # f"AD{self.xValue}",
}

self.produce.plot = HistPlot()

self.produce.plot.panels["panel_rms"] = HistPanel()
self.produce.plot.panels["panel_rms"].hists = dict(rmsDistances="Object RMS")
self.produce.plot.panels["panel_rms"].label = "rms (marcsec)"
# self.produce.plot.panels["panel_rms"].statsPanel.stat1 = [
# f"AM{self.xValue}"]
# self.produce.plot.panels["panel_rms"].statsPanel.stat2 = [None]
# self.produce.plot.panels["panel_rms"].statsPanel.stat3 = [None]
# self.produce.plot.panels["panel_rms"].statsPanel.statsLabels = [
# f"AM{self.xValue}", "", ""]
self.produce.plot.panels["panel_rms"].statsPanel.statsLabels = [
"N$_{{data}}$",
f"AM{self.xValue}",
"${{\\sigma}}_{{MAD}}$",
]

self.produce.plot.panels["panel_sep"] = HistPanel()
self.produce.plot.panels["panel_sep"].hists = dict(separationResiduals="Source separations")
self.produce.plot.panels["panel_sep"].label = "Separations (marcsec)"
# self.produce.plot.panels["panel_sep"].statsPanel.stat1 = [
# f"AF{self.xValue}"]
self.produce.plot.panels["panel_sep"].statsPanel.stat3 = ["AMx"]
self.produce.plot.panels["panel_sep"].statsPanel.stat1 = ["ADx"]
self.produce.plot.panels["panel_sep"].statsPanel.stat2 = ["AFx"]
# self.produce.plot.panels["panel_rms"].statsPanel.stat3 = [None]
self.produce.plot.panels["panel_sep"].statsPanel.statsLabels = [
f"AD{self.xValue}",
f"AF{self.xValue}",
f"AM{self.xValue}",
]
self.produce.plot.panels["panel_sep"].label = "Separation Distances (marcsec)"

self.produce.plot.panels["panel_rms"] = HistPanel()
self.produce.plot.panels["panel_rms"].hists = dict(rmsDistances="Object RMS")
self.produce.plot.panels["panel_rms"].label = "Per-Object RMS (marcsec)"
# TODO: DM-39163 add reference lines for ADx, AMx, and AFx.

0 comments on commit c517813

Please sign in to comment.