Skip to content

Commit

Permalink
Change doc of used field to calib_photometryUsed. Add reserved and ca…
Browse files Browse the repository at this point in the history
…ndidate flags.

Flag marks sources used in final calibration, name changed from photometryStandard.

Added the ability to reserve a fraction of candidates selected from the initial match.
Mark those calib_photometryReserved.

Mark the remainder of the candidates calib_photometryCandidate.
  • Loading branch information
Perry Gee committed Apr 19, 2017
1 parent 7ffa3b3 commit 10e8f58
Showing 1 changed file with 52 additions and 9 deletions.
61 changes: 52 additions & 9 deletions python/lsst/pipe/tasks/photoCal.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from builtins import range

import math
import random
import sys

import numpy as np
Expand Down Expand Up @@ -70,7 +71,18 @@ class PhotoCalConfig(RefMatchConfig):
doWriteOutput = pexConf.Field(
dtype=bool,
default=True,
doc="Write a field name astrom_usedByPhotoCal to the schema",
doc="Write a field named calib_photometryUsed to the schema",
)
reserveFraction = pexConf.Field(
dtype=float,
doc="Fraction of candidates to reserve from fitting; none if <= 0",
default=-1.0,
)
reserveSeed = pexConf.Field(
dtype = int,
doc = "This number will be multiplied by the exposure ID "
"to set the random seed for reserving candidates",
default = 1,
)
fluxField = pexConf.Field(
dtype=str,
Expand Down Expand Up @@ -294,10 +306,16 @@ def __init__(self, refObjLoader, schema=None, **kwds):
self.scatterPlot = None
self.fig = None
if self.config.doWriteOutput:
self.outputField = schema.addField("photocal_photometricStandard", type="Flag",
self.usedKey = schema.addField("calib_photometryUsed", type="Flag",
doc="set if source was used in photometric calibration")
self.candidateKey = schema.addField("calib_photometryCandidate", type="Flag",
doc="set if source was used in photometric calibration")
self.reservedKey = schema.addField("calib_photometryReserved", type="Flag",
doc="set if source was reserved in photometric calibration")
else:
self.outputField = None
self.usedKey = None
self.candidateKey = None
self.reservedKey = None

def getSourceKeys(self, schema):
"""!Return a struct containing the source catalog keys for fields used by PhotoCalTask.
Expand Down Expand Up @@ -365,6 +383,10 @@ def selectMatches(self, matches, sourceKeys, filterName, frame=None):
if len(matches) == 0:
raise ValueError("No input matches")

for m in matches:
if self.candidateKey is not None:
m.second.set(self.candidateKey, True)

# Only use stars for which the flags indicate the photometry is good.
afterFlagCutInd = [i for i, m in enumerate(matches) if checkSourceFlags(m.second, sourceKeys)]
afterFlagCut = [matches[i] for i in afterFlagCutInd]
Expand Down Expand Up @@ -456,8 +478,8 @@ def selectMatches(self, matches, sourceKeys, filterName, frame=None):

result = []
for m in matches:
if self.outputField is not None:
m.second.set(self.outputField, True)
if self.usedKey is not None:
m.second.set(self.usedKey, True)
result.append(m)
return result

Expand Down Expand Up @@ -577,7 +599,7 @@ def extractMagArrays(self, matches, filterName, sourceKeys):
)

@pipeBase.timeMethod
def run(self, exposure, sourceCat):
def run(self, exposure, sourceCat, expId=0):
"""!Do photometric calibration - select matches to use and (possibly iteratively) compute
the zero point.
Expand Down Expand Up @@ -648,21 +670,42 @@ def run(self, exposure, sourceCat):
frame = None

res = self.loadAndMatch(exposure, sourceCat)

#from res.matches, reserve a fraction of the population and mark the sources as reserved
reserveList = []

if self.config.reserveFraction > 0:
random.seed(self.config.reserveSeed*expId)
reserveList = random.sample(res.matches,
int((self.config.reserveFraction)*len(res.matches)))

for cand in reserveList:
res.matches.remove(cand)

if reserveList and self.reservedKey is not None:
for cand in reserveList:
cand.second.set(self.reservedKey, True)

matches = res.matches
for m in matches:
if self.candidateKey is not None:
m.second.set(self.candidateKey, True)

filterName = exposure.getFilter().getName()
sourceKeys = self.getSourceKeys(matches[0].second.schema)

matches = self.selectMatches(matches=matches, sourceKeys=sourceKeys, filterName=filterName,
frame=frame)
arrays = self.extractMagArrays(matches=matches, filterName=filterName, sourceKeys=sourceKeys)

if matches and self.outputField:
if matches and self.usedKey:
try:
# matches[].second is a measured source, wherein we wish to set outputField.
# Check that the field is present in the Sources schema.
matches[0].second.getSchema().find(self.outputField)
matches[0].second.getSchema().find(self.usedKey)
except:
raise RuntimeError("sources' schema does not contain the used-in-calibration flag \"%s\"" %
self.outputField)
self.usedKey)

# Fit for zeropoint. We can run the code more than once, so as to
# give good stars that got clipped by a bad first guess a second
Expand Down

0 comments on commit 10e8f58

Please sign in to comment.