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 if "visit" in ref.dataId.keys():
79 visit = ref.dataId[
"visit"]
82 visit = namespace.butler.queryMetadata(
"calexp", (
"visit"), ref.dataId)[0]
83 if visit
not in visitRefs:
84 visitRefs[visit] = list()
85 visitRefs[visit].append(ref)
87 md = ref.get(
"calexp_md", immediate=
True)
88 wcs = lsst.afw.image.makeWcs(md)
89 box = lsst.afw.geom.Box2D(lsst.afw.image.bboxFromMetadata(md))
92 tract = skymap.findTract(wcs.pixelToSky(box.getCenter()))
94 if visit
not in visitTract:
95 visitTract[visit] = set()
96 visitTract[visit].add(tract.getId())
98 tract = dataId.pop(
"tract")
100 for ref
in namespace.butler.subset(
"src", dataId=dataId):
106 for visit, tractSet
in sorted(visitTract.items()):
107 for ref
in visitRefs[visit]:
108 for tract
in sorted(tractSet):
111 tractCounter = collections.Counter()
112 for tractSet
in visitTract.values():
113 tractCounter.update(tractSet)
114 log.infof(
"Number of visits per tract: {}", dict(tractCounter))
118 """Return whether the image (specified by Wcs and bounding box) overlaps the tract 119 @param tract: TractInfo specifying a tract 120 @param imageWcs: Wcs for image 121 @param imageBox: Bounding box for image 124 tractWcs = tract.getWcs()
125 tractCorners = [tractWcs.pixelToSky(lsst.afw.geom.Point2D(coord)).getVector()
for 126 coord
in tract.getBBox().getCorners()]
127 tractPoly = convexHull(tractCorners)
130 imageCorners = [imageWcs.pixelToSky(lsst.afw.geom.Point2D(pix))
for pix
in imageBox.getCorners()]
131 except lsst.pex.exceptions.LsstCppException
as e:
133 if (
not isinstance(e.message, lsst.pex.exceptions.DomainErrorException)
and 134 not isinstance(e.message, lsst.pex.exceptions.RuntimeErrorException)):
138 imagePoly = convexHull([coord.getVector()
for coord
in imageCorners])
139 if imagePoly
is None:
141 return tractPoly.intersects(imagePoly)
def _addDataRef(self, namespace, dataId, tract)
def castDataIds(self, butler)
def makeDataRefList(self, namespace)
def overlapsTract(tract, imageWcs, imageBox)