5 from __future__
import division, absolute_import, print_function
10 import lsst.pex.exceptions
13 from lsst.geom
import convexHull
15 from lsst.coadd.utils
import CoaddDataIdContainer
19 """A version of lsst.pipe.base.DataIdContainer that combines raw data IDs (defined as whatever we use
20 for 'src') with a tract.
24 """Validate data IDs and cast them to the correct type (modify idList in place).
25 @param butler: data butler
28 idKeyTypeDict = butler.getKeys(datasetType=
"src", level=self.level)
30 raise KeyError(
"Cannot get keys for datasetType %s at level %s: %s" % (
"src", self.level, e))
32 idKeyTypeDict = idKeyTypeDict.copy()
33 idKeyTypeDict[
"tract"] = int
35 for dataDict
in self.idList:
36 for key, strVal
in dataDict.items():
38 keyType = idKeyTypeDict[key]
40 validKeys = sorted(idKeyTypeDict.keys())
41 raise KeyError(
"Unrecognized ID key %r; valid keys are: %s" % (key, validKeys))
44 castVal = keyType(strVal)
46 raise TypeError(
"Cannot cast value %r to %s for ID key %r" % (strVal, keyType, key,))
47 dataDict[key] = castVal
49 def _addDataRef(self, namespace, dataId, tract):
50 """Construct a dataRef based on dataId, but with an added tract key"""
51 forcedDataId = dataId.copy()
52 forcedDataId[
'tract'] = tract
53 dataRef = namespace.butler.dataRef(datasetType=self.datasetType, dataId=forcedDataId)
54 self.refList.append(dataRef)
57 """Make self.refList from self.idList
59 if self.datasetType
is None:
60 raise RuntimeError(
"Must call setDatasetType first")
62 log = lsst.log.Log.getLogger(
"jointcal.dataIds")
65 for dataId
in self.idList:
66 if "tract" not in dataId:
68 log.infof(
"Reading WCS to determine tracts for components of dataId={}", dict(dataId))
70 skymap = self.getSkymap(namespace)
72 for ref
in namespace.butler.subset(
"calexp", dataId=dataId):
73 if not ref.datasetExists(
"calexp"):
74 log.warnf(
"calexp with dataId: {} not found.", dict(dataId))
78 visit = ref.dataId[
"visit"]
79 if visit
not in visitRefs:
80 visitRefs[visit] = list()
81 visitRefs[visit].append(ref)
83 md = ref.get(
"calexp_md", immediate=
True)
84 wcs = lsst.afw.image.makeWcs(md)
85 box = lsst.afw.geom.Box2D(lsst.afw.geom.Point2D(0, 0),
86 lsst.afw.geom.Point2D(md.get(
"NAXIS1"), md.get(
"NAXIS2")))
89 tract = skymap.findTract(wcs.pixelToSky(box.getCenter()))
91 if visit
not in visitTract:
92 visitTract[visit] = set()
93 visitTract[visit].add(tract.getId())
95 tract = dataId.pop(
"tract")
97 for ref
in namespace.butler.subset(
"src", dataId=dataId):
103 for visit, tractSet
in sorted(visitTract.items()):
104 for ref
in visitRefs[visit]:
105 for tract
in sorted(tractSet):
108 tractCounter = collections.Counter()
109 for tractSet
in visitTract.values():
110 tractCounter.update(tractSet)
111 log.infof(
"Number of visits per tract: {}", dict(tractCounter))
115 """Return whether the image (specified by Wcs and bounding box) overlaps the tract
116 @param tract: TractInfo specifying a tract
117 @param imageWcs: Wcs for image
118 @param imageBox: Bounding box for image
121 tractWcs = tract.getWcs()
122 tractCorners = [tractWcs.pixelToSky(lsst.afw.geom.Point2D(coord)).getVector()
for
123 coord
in tract.getBBox().getCorners()]
124 tractPoly = convexHull(tractCorners)
127 imageCorners = [imageWcs.pixelToSky(lsst.afw.geom.Point2D(pix))
for pix
in imageBox.getCorners()]
128 except lsst.pex.exceptions.LsstCppException
as e:
130 if (
not isinstance(e.message, lsst.pex.exceptions.DomainErrorException)
and
131 not isinstance(e.message, lsst.pex.exceptions.RuntimeErrorException)):
135 imagePoly = convexHull([coord.getVector()
for coord
in imageCorners])
136 if imagePoly
is None:
138 return tractPoly.intersects(imagePoly)