25 __all__ = [
"parseOptions",
"DiaSourceAnalystConfig",
"DiaSourceAnalyst"]
27 from optparse
import OptionParser
43 """Parse the command line options.""" 44 parser = OptionParser(
45 usage=
"""%prog cdDiffSources crDiffExposure 47 Read in sources and test for junk""")
48 options, args = parser.parse_args()
50 parser.error(
"incorrect number of arguments")
55 loc = dafPersist.LogicalLocation(boostFile)
56 storageList = dafPersist.StorageList()
57 additionalData = dafBase.PropertySet()
59 storageList.append(persistence.getRetrieveStorage(
"BoostStorage", loc))
60 psv = persistence.unsafeRetrieve(
"PersistableSourceVector", storageList, additionalData)
61 return psv.getSources()
65 srcBadMaskPlanes = pexConfig.ListField(
67 doc=
"""Mask planes that lead to an invalid detection. 68 Options: NO_DATA EDGE SAT BAD CR INTRP 69 E.g. : NO_DATA SAT BAD allows CR-masked and interpolated pixels""",
70 default=(
"NO_DATA",
"EDGE",
"SAT",
"BAD")
72 fBadPixels = pexConfig.Field(
74 doc=
"Fraction of bad pixels allowed in footprint",
77 fluxPolarityRatio = pexConfig.Field(
79 doc=
"Minimum fraction of flux in correct-polarity pixels",
82 nPolarityRatio = pexConfig.Field(
84 doc=
"Minimum fraction of correct-polarity pixels in unmasked subset",
87 nMaskedRatio = pexConfig.Field(
89 doc=
"Minimum fraction of correct-polarity unmasked to masked pixels",
92 nGoodRatio = pexConfig.Field(
94 doc=
"Minimum fraction of correct-polarity unmasked to all pixels",
103 self.
log = Log.getLogger(
"ip.diffim.DiaSourceAnalysis")
106 srcBadMaskPlanes = self.
config.srcBadMaskPlanes
107 for maskPlane
in srcBadMaskPlanes:
108 self.
bitMask |= afwImage.Mask.getPlaneBitMask(maskPlane)
111 idxP = num.where(mask & afwImage.Mask.getPlaneBitMask(
"DETECTED"))
112 idxN = num.where(mask & afwImage.Mask.getPlaneBitMask(
"DETECTED_NEGATIVE"))
113 return len(idxP[0]), len(idxN[0])
116 idxM = num.where(mask & self.
bitMask)
120 unmasked = ((mask & self.
bitMask) == 0)
121 idxP = num.where((pixels >= 0) & unmasked)
122 idxN = num.where((pixels < 0) & unmasked)
123 fluxP = num.sum(pixels[idxP])
124 fluxN = num.sum(pixels[idxN])
125 return len(idxP[0]), len(idxN[0]), fluxP, fluxN
128 imArr, maArr, varArr = subMi.getArrays()
129 flux = source.getApFlux()
131 nPixels = subMi.getWidth() * subMi.getHeight()
135 assert(nPixels == (nMasked + nPos + nNeg))
138 fMasked = (nMasked / nPixels)
139 fMaskedTol = self.
config.fBadPixels
140 if fMasked > fMaskedTol:
141 self.
log.debug(
"Candidate %d : BAD fBadPixels %.2f > %.2f", source.getId(), fMasked, fMaskedTol)
146 fluxRatio = fPos / (fPos + abs(fNeg))
147 ngoodRatio = nPos / nPixels
148 maskRatio = nPos / (nPos + nMasked)
149 npolRatio = nPos / (nPos + nNeg)
152 fluxRatio = abs(fNeg) / (fPos + abs(fNeg))
153 ngoodRatio = nNeg / nPixels
154 maskRatio = nNeg / (nNeg + nMasked)
155 npolRatio = nNeg / (nNeg + nPos)
158 fluxRatioTolerance = self.
config.fluxPolarityRatio
159 if fluxRatio < fluxRatioTolerance:
160 self.
log.debug(
"Candidate %d : BAD flux polarity %.2f < %.2f (pos=%.2f neg=%.2f)",
161 source.getId(), fluxRatio, fluxRatioTolerance, fPos, fNeg)
165 polarityTolerance = self.
config.nPolarityRatio
166 if npolRatio < polarityTolerance:
167 self.
log.debug(
"Candidate %d : BAD polarity count %.2f < %.2f (pos=%d neg=%d)",
168 source.getId(), npolRatio, polarityTolerance, nPos, nNeg)
172 maskedTolerance = self.
config.nMaskedRatio
173 if maskRatio < maskedTolerance:
174 self.
log.debug(
"Candidate %d : BAD unmasked count %.2f < %.2f (pos=%d neg=%d mask=%d)",
175 source.getId(), maskRatio, maskedTolerance, nPos, nNeg, nMasked)
179 ngoodTolerance = self.
config.nGoodRatio
180 if ngoodRatio < ngoodTolerance:
181 self.
log.debug(
"Candidate %d : BAD good pixel count %.2f < %.2f (pos=%d neg=%d tot=%d)",
182 source.getId(), ngoodRatio, ngoodTolerance, nPos, nNeg, nPixels)
185 self.
log.debug(
"Candidate %d : OK flux=%.2f nPos=%d nNeg=%d nTot=%d nDetPos=%d nDetNeg=%d " 186 "fPos=%.2f fNeg=%2f",
187 source.getId(), flux, nPos, nNeg, nPixels, nDetPos, nDetNeg, fPos, fNeg)
194 (crDiffSourceFile, crDiffExposureFile) = args
197 crDiffExposure = afwImage.ExposureF(crDiffExposureFile)
201 expX0 = crDiffExposure.getX0()
202 expY0 = crDiffExposure.getY0()
203 expX1 = expX0 + crDiffExposure.getWidth() - 1
204 expY1 = expY0 + crDiffExposure.getHeight() - 1
206 for i
in range(crDiffSources.size()):
207 crDiffSource = crDiffSources[i]
213 xAstrom = crDiffSource.getXAstrom()
214 yAstrom = crDiffSource.getYAstrom()
215 Ixx = max(1.0, crDiffSource.getIxx())
216 Iyy = max(1.0, crDiffSource.getIyy())
217 x0 = max(expX0, int(xAstrom - scaling * Ixx))
218 x1 = min(expX1, int(xAstrom + scaling * Ixx))
219 y0 = max(expY0, int(yAstrom - scaling * Iyy))
220 y1 = min(expY1, int(yAstrom + scaling * Iyy))
221 bbox = afwGeom.Box2I(afwGeom.Point2I(x0, y0),
222 afwGeom.Point2I(x1, y1))
223 subExp = afwImage.ExposureF(crDiffExposure, bbox)
224 subMi = subExp.getMaskedImage()
225 imArr, maArr, varArr = subMi.getArrays()
227 if analyst.testSource(crDiffSource, subMi):
228 ds9.mtv(subExp, frame=1)
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)