5 from __future__
import division, absolute_import, print_function
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")
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)
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):
101 if ref.datasetExists():
107 for visit, tractSet
in sorted(visitTract.items()):
108 for ref
in visitRefs[visit]:
109 for tract
in sorted(tractSet):
112 tractCounter = collections.Counter()
113 for tractSet
in visitTract.values():
114 tractCounter.update(tractSet)
115 log.infof(
"Number of visits per tract: {}", dict(tractCounter))
119 """Return whether the image (specified by Wcs and bounding box) overlaps the tract 120 @param tract: TractInfo specifying a tract 121 @param imageWcs: Wcs for image 122 @param imageBox: Bounding box for image 125 tractWcs = tract.getWcs()
127 coord
in tract.getBBox().getCorners()]
128 tractPoly = convexHull(tractCorners)
132 except lsst.pex.exceptions.LsstCppException
as e:
134 if (
not isinstance(e.message, lsst.pex.exceptions.DomainErrorException)
and 135 not isinstance(e.message, lsst.pex.exceptions.RuntimeErrorException)):
139 imagePoly = convexHull([coord.getVector()
for coord
in imageCorners])
140 if imagePoly
is None:
142 return tractPoly.intersects(imagePoly)
def _addDataRef(self, namespace, dataId, tract)
std::shared_ptr< Wcs > makeWcs(coord::Coord const &crval, geom::Point2D const &crpix, double CD11, double CD12, double CD21, double CD22)
def castDataIds(self, butler)
def makeDataRefList(self, namespace)
def overlapsTract(tract, imageWcs, imageBox)
geom::Box2I bboxFromMetadata(daf::base::PropertySet &metadata)
static Log getLogger(std::string const &loggername)