24 from __future__
import absolute_import, division, print_function
26 __all__ = [
"parseOptions",
"DiaSourceAnalystConfig",
"DiaSourceAnalyst"]
28 from optparse
import OptionParser
30 from builtins
import input
31 from builtins
import range
32 from builtins
import object
49 """Parse the command line options.""" 50 parser = OptionParser(
51 usage=
"""%prog cdDiffSources crDiffExposure 53 Read in sources and test for junk""")
54 options, args = parser.parse_args()
56 parser.error(
"incorrect number of arguments")
61 loc = dafPersist.LogicalLocation(boostFile)
62 storageList = dafPersist.StorageList()
63 additionalData = dafBase.PropertySet()
65 storageList.append(persistence.getRetrieveStorage(
"BoostStorage", loc))
66 psv = persistence.unsafeRetrieve(
"PersistableSourceVector", storageList, additionalData)
67 return psv.getSources()
71 srcBadMaskPlanes = pexConfig.ListField(
73 doc=
"""Mask planes that lead to an invalid detection. 74 Options: NO_DATA EDGE SAT BAD CR INTRP 75 E.g. : NO_DATA SAT BAD allows CR-masked and interpolated pixels""",
76 default=(
"NO_DATA",
"EDGE",
"SAT",
"BAD")
78 fBadPixels = pexConfig.Field(
80 doc=
"Fraction of bad pixels allowed in footprint",
83 fluxPolarityRatio = pexConfig.Field(
85 doc=
"Minimum fraction of flux in correct-polarity pixels",
88 nPolarityRatio = pexConfig.Field(
90 doc=
"Minimum fraction of correct-polarity pixels in unmasked subset",
93 nMaskedRatio = pexConfig.Field(
95 doc=
"Minimum fraction of correct-polarity unmasked to masked pixels",
98 nGoodRatio = pexConfig.Field(
100 doc=
"Minimum fraction of correct-polarity unmasked to all pixels",
109 self.
log = Log.getLogger(
"ip.diffim.DiaSourceAnalysis")
112 srcBadMaskPlanes = self.
config.srcBadMaskPlanes
113 for maskPlane
in srcBadMaskPlanes:
114 self.
bitMask |= afwImage.Mask.getPlaneBitMask(maskPlane)
117 idxP = num.where(mask & afwImage.Mask.getPlaneBitMask(
"DETECTED"))
118 idxN = num.where(mask & afwImage.Mask.getPlaneBitMask(
"DETECTED_NEGATIVE"))
119 return len(idxP[0]), len(idxN[0])
122 idxM = num.where(mask & self.
bitMask)
126 unmasked = ((mask & self.
bitMask) == 0)
127 idxP = num.where((pixels >= 0) & unmasked)
128 idxN = num.where((pixels < 0) & unmasked)
129 fluxP = num.sum(pixels[idxP])
130 fluxN = num.sum(pixels[idxN])
131 return len(idxP[0]), len(idxN[0]), fluxP, fluxN
134 imArr, maArr, varArr = subMi.getArrays()
135 flux = source.getApFlux()
137 nPixels = subMi.getWidth() * subMi.getHeight()
141 assert(nPixels == (nMasked + nPos + nNeg))
144 fMasked = (nMasked / nPixels)
145 fMaskedTol = self.
config.fBadPixels
146 if fMasked > fMaskedTol:
147 self.
log.debug(
"Candidate %d : BAD fBadPixels %.2f > %.2f", source.getId(), fMasked, fMaskedTol)
152 fluxRatio = fPos / (fPos + abs(fNeg))
153 ngoodRatio = nPos / nPixels
154 maskRatio = nPos / (nPos + nMasked)
155 npolRatio = nPos / (nPos + nNeg)
158 fluxRatio = abs(fNeg) / (fPos + abs(fNeg))
159 ngoodRatio = nNeg / nPixels
160 maskRatio = nNeg / (nNeg + nMasked)
161 npolRatio = nNeg / (nNeg + nPos)
164 fluxRatioTolerance = self.
config.fluxPolarityRatio
165 if fluxRatio < fluxRatioTolerance:
166 self.
log.debug(
"Candidate %d : BAD flux polarity %.2f < %.2f (pos=%.2f neg=%.2f)",
167 source.getId(), fluxRatio, fluxRatioTolerance, fPos, fNeg)
171 polarityTolerance = self.
config.nPolarityRatio
172 if npolRatio < polarityTolerance:
173 self.
log.debug(
"Candidate %d : BAD polarity count %.2f < %.2f (pos=%d neg=%d)",
174 source.getId(), npolRatio, polarityTolerance, nPos, nNeg)
178 maskedTolerance = self.
config.nMaskedRatio
179 if maskRatio < maskedTolerance:
180 self.
log.debug(
"Candidate %d : BAD unmasked count %.2f < %.2f (pos=%d neg=%d mask=%d)",
181 source.getId(), maskRatio, maskedTolerance, nPos, nNeg, nMasked)
185 ngoodTolerance = self.
config.nGoodRatio
186 if ngoodRatio < ngoodTolerance:
187 self.
log.debug(
"Candidate %d : BAD good pixel count %.2f < %.2f (pos=%d neg=%d tot=%d)",
188 source.getId(), ngoodRatio, ngoodTolerance, nPos, nNeg, nPixels)
191 self.
log.debug(
"Candidate %d : OK flux=%.2f nPos=%d nNeg=%d nTot=%d nDetPos=%d nDetNeg=%d fPos=%.2f fNeg=%2f",
192 source.getId(), flux, nPos, nNeg, nPixels, nDetPos, nDetNeg, fPos, fNeg)
199 (crDiffSourceFile, crDiffExposureFile) = args
202 crDiffExposure = afwImage.ExposureF(crDiffExposureFile)
206 expX0 = crDiffExposure.getX0()
207 expY0 = crDiffExposure.getY0()
208 expX1 = expX0 + crDiffExposure.getWidth() - 1
209 expY1 = expY0 + crDiffExposure.getHeight() - 1
211 for i
in range(crDiffSources.size()):
212 crDiffSource = crDiffSources[i]
218 xAstrom = crDiffSource.getXAstrom()
219 yAstrom = crDiffSource.getYAstrom()
220 Ixx = max(1.0, crDiffSource.getIxx())
221 Iyy = max(1.0, crDiffSource.getIyy())
222 x0 = max(expX0, int(xAstrom - scaling * Ixx))
223 x1 = min(expX1, int(xAstrom + scaling * Ixx))
224 y0 = max(expY0, int(yAstrom - scaling * Iyy))
225 y1 = min(expY1, int(yAstrom + scaling * Iyy))
228 subExp = afwImage.ExposureF(crDiffExposure, bbox)
229 subMi = subExp.getMaskedImage()
230 imArr, maArr, varArr = subMi.getArrays()
232 if analyst.testSource(crDiffSource, subMi):
233 ds9.mtv(subExp, frame=1)
235 if __name__ ==
"__main__":
def countMasked(self, mask)
def testSource(self, source, subMi)
def __init__(self, config)
def countPolarity(self, mask, pixels)
def readSourceSet(boostFile)
def countDetected(self, mask)