24 from __future__
import absolute_import, division, print_function
26 from optparse
import OptionParser
28 from builtins
import input
29 from builtins
import range
30 from builtins
import object
32 import lsst.afw.image
as afwImage
33 import lsst.afw.geom
as afwGeom
34 import lsst.afw.detection
as afwDet
35 from lsst.log
import Log
36 import lsst.pex.policy
as pexPolicy
37 import lsst.daf.persistence
as dafPersist
38 import lsst.daf.base
as dafBase
40 import lsst.afw.display.ds9
as ds9
41 import lsst.pex.config
as pexConfig
47 """Parse the command line options.""" 48 parser = OptionParser(
49 usage=
"""%prog cdDiffSources crDiffExposure 51 Read in sources and test for junk""")
52 options, args = parser.parse_args()
54 parser.error(
"incorrect number of arguments")
59 loc = dafPersist.LogicalLocation(boostFile)
60 storageList = dafPersist.StorageList()
61 additionalData = dafBase.PropertySet()
62 persistence = dafPersist.Persistence.getPersistence(pexPolicy.Policy())
63 storageList.append(persistence.getRetrieveStorage(
"BoostStorage", loc))
64 psv = persistence.unsafeRetrieve(
"PersistableSourceVector", storageList, additionalData)
65 return psv.getSources()
69 srcBadMaskPlanes = pexConfig.ListField(
71 doc=
"""Mask planes that lead to an invalid detection. 72 Options: NO_DATA EDGE SAT BAD CR INTRP 73 E.g. : NO_DATA SAT BAD allows CR-masked and interpolated pixels""",
74 default=(
"NO_DATA",
"EDGE",
"SAT",
"BAD")
76 fBadPixels = pexConfig.Field(
78 doc=
"Fraction of bad pixels allowed in footprint",
81 fluxPolarityRatio = pexConfig.Field(
83 doc=
"Minimum fraction of flux in correct-polarity pixels",
86 nPolarityRatio = pexConfig.Field(
88 doc=
"Minimum fraction of correct-polarity pixels in unmasked subset",
91 nMaskedRatio = pexConfig.Field(
93 doc=
"Minimum fraction of correct-polarity unmasked to masked pixels",
96 nGoodRatio = pexConfig.Field(
98 doc=
"Minimum fraction of correct-polarity unmasked to all pixels",
107 self.
log = Log.getLogger(
"ip.diffim.DiaSourceAnalysis")
110 srcBadMaskPlanes = self.
config.srcBadMaskPlanes
111 for maskPlane
in srcBadMaskPlanes:
112 self.
bitMask |= afwImage.Mask.getPlaneBitMask(maskPlane)
115 idxP = num.where(mask & afwImage.Mask.getPlaneBitMask(
"DETECTED"))
116 idxN = num.where(mask & afwImage.Mask.getPlaneBitMask(
"DETECTED_NEGATIVE"))
117 return len(idxP[0]), len(idxN[0])
120 idxM = num.where(mask & self.
bitMask)
124 unmasked = ((mask & self.
bitMask) == 0)
125 idxP = num.where((pixels >= 0) & unmasked)
126 idxN = num.where((pixels < 0) & unmasked)
127 fluxP = num.sum(pixels[idxP])
128 fluxN = num.sum(pixels[idxN])
129 return len(idxP[0]), len(idxN[0]), fluxP, fluxN
132 imArr, maArr, varArr = subMi.getArrays()
133 flux = source.getApFlux()
135 nPixels = subMi.getWidth() * subMi.getHeight()
139 assert(nPixels == (nMasked + nPos + nNeg))
142 fMasked = (nMasked / nPixels)
143 fMaskedTol = self.
config.fBadPixels
144 if fMasked > fMaskedTol:
145 self.
log.debug(
"Candidate %d : BAD fBadPixels %.2f > %.2f", source.getId(), fMasked, fMaskedTol)
150 fluxRatio = fPos / (fPos + abs(fNeg))
151 ngoodRatio = nPos / nPixels
152 maskRatio = nPos / (nPos + nMasked)
153 npolRatio = nPos / (nPos + nNeg)
156 fluxRatio = abs(fNeg) / (fPos + abs(fNeg))
157 ngoodRatio = nNeg / nPixels
158 maskRatio = nNeg / (nNeg + nMasked)
159 npolRatio = nNeg / (nNeg + nPos)
162 fluxRatioTolerance = self.
config.fluxPolarityRatio
163 if fluxRatio < fluxRatioTolerance:
164 self.
log.debug(
"Candidate %d : BAD flux polarity %.2f < %.2f (pos=%.2f neg=%.2f)",
165 source.getId(), fluxRatio, fluxRatioTolerance, fPos, fNeg)
169 polarityTolerance = self.
config.nPolarityRatio
170 if npolRatio < polarityTolerance:
171 self.
log.debug(
"Candidate %d : BAD polarity count %.2f < %.2f (pos=%d neg=%d)",
172 source.getId(), npolRatio, polarityTolerance, nPos, nNeg)
176 maskedTolerance = self.
config.nMaskedRatio
177 if maskRatio < maskedTolerance:
178 self.
log.debug(
"Candidate %d : BAD unmasked count %.2f < %.2f (pos=%d neg=%d mask=%d)",
179 source.getId(), maskRatio, maskedTolerance, nPos, nNeg, nMasked)
183 ngoodTolerance = self.
config.nGoodRatio
184 if ngoodRatio < ngoodTolerance:
185 self.
log.debug(
"Candidate %d : BAD good pixel count %.2f < %.2f (pos=%d neg=%d tot=%d)",
186 source.getId(), ngoodRatio, ngoodTolerance, nPos, nNeg, nPixels)
189 self.
log.debug(
"Candidate %d : OK flux=%.2f nPos=%d nNeg=%d nTot=%d nDetPos=%d nDetNeg=%d fPos=%.2f fNeg=%2f",
190 source.getId(), flux, nPos, nNeg, nPixels, nDetPos, nDetNeg, fPos, fNeg)
197 (crDiffSourceFile, crDiffExposureFile) = args
200 crDiffExposure = afwImage.ExposureF(crDiffExposureFile)
204 expX0 = crDiffExposure.getX0()
205 expY0 = crDiffExposure.getY0()
206 expX1 = expX0 + crDiffExposure.getWidth() - 1
207 expY1 = expY0 + crDiffExposure.getHeight() - 1
209 for i
in range(crDiffSources.size()):
210 crDiffSource = crDiffSources[i]
216 xAstrom = crDiffSource.getXAstrom()
217 yAstrom = crDiffSource.getYAstrom()
218 Ixx = max(1.0, crDiffSource.getIxx())
219 Iyy = max(1.0, crDiffSource.getIyy())
220 x0 = max(expX0, int(xAstrom - scaling * Ixx))
221 x1 = min(expX1, int(xAstrom + scaling * Ixx))
222 y0 = max(expY0, int(yAstrom - scaling * Iyy))
223 y1 = min(expY1, int(yAstrom + scaling * Iyy))
224 bbox = afwGeom.Box2I(afwGeom.Point2I(x0, y0),
225 afwGeom.Point2I(x1, y1))
226 subExp = afwImage.ExposureF(crDiffExposure, bbox)
227 subMi = subExp.getMaskedImage()
228 imArr, maArr, varArr = subMi.getArrays()
230 if analyst.testSource(crDiffSource, subMi):
231 ds9.mtv(subExp, frame=1)
233 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)