23 """Mapper and cameraGeom definition for extremely simple mock data.
25 SimpleMapper inherits directly from Mapper, not CameraMapper. This means
26 we can avoid any problems with paf files at the expense of reimplementing
27 some parts of CameraMapper here. Jim is not sure this was the best
28 possible approach, but it gave him an opportunity to play around with
29 prototyping a future paf-free mapper class, and it does everything it
30 needs to do right now.
42 __all__ = (
"SimpleMapper",
"makeSimpleCamera",
"makeDataRepo")
45 """Base class of a hierarchy used by SimpleMapper to defined different kinds of types of objects
48 PersistenceType objects are never instantiated; only the type objects are used (we needed a
49 simple singleton struct that could be inherited, which is exactly what a Python type is).
59 """Method called by SimpleMapping to implement a map_ method."""
63 """Persistence type for things that don't actually use daf_persistence.
66 python =
"lsst.daf.base.PropertySet"
70 """Method called by SimpleMapping to implement a map_ method; overridden to not use the path."""
74 """Persistence type of Exposure images.
77 python =
"lsst.afw.image.ExposureF"
79 storage =
"FitsStorage"
85 """Method called by SimpleMapping to implement a map_ method; overridden to support subimages."""
87 loc = super(ExposurePersistenceType, cls).
makeButlerLocation(path, dataId, suffix=
None)
88 elif suffix ==
"_sub":
90 bbox = subId.pop(
'bbox')
92 loc.additionalData.set(
'llcX', bbox.getMinX())
93 loc.additionalData.set(
'llcY', bbox.getMinY())
94 loc.additionalData.set(
'width', bbox.getWidth())
95 loc.additionalData.set(
'height', bbox.getHeight())
96 if 'imageOrigin' in dataId:
97 loc.additionalData.set(
'imageOrigin',
98 dataId[
'imageOrigin'])
102 python =
"lsst.skymap.BaseSkyMap"
103 storage =
"PickleStorage"
107 python =
"lsst.afw.table.BaseCatalog"
109 storage =
"FitsCatalogStorage"
113 python =
"lsst.afw.table.SimpleCatalog"
114 cpp =
"SimpleCatalog"
117 python =
"lsst.afw.table.SourceCatalog"
118 cpp =
"SourceCatalog"
121 python =
"lsst.afw.table.ExposureCatalog"
122 cpp =
"ExposureCatalog"
125 python =
"lsst.afw.detection.PeakCatalog"
129 """Mapping object used to implement SimpleMapper, similar in intent to lsst.daf.peristence.Mapping.
135 def __init__(self, persistence, template=None, keys=None):
137 if template
is not None:
142 def map(self, dataset, root, dataId, suffix=None):
144 path = os.path.join(root, self.template.format(dataset=dataset, ext=self.persistence.ext,
148 return self.persistence.makeButlerLocation(path, dataId, suffix=suffix)
151 """Mapping for dataset types that are organized the same way as raw data (i.e. by CCD)."""
153 template =
"{dataset}-{visit:04d}-{ccd:01d}{ext}"
154 keys = dict(visit=int, ccd=int)
156 def query(self, index, level, format, dataId):
158 visit = dataId.get(
'visit',
None)
159 dictList = index[level][visit]
160 ccd = dataId.get(
'ccd',
None)
161 for d
in dictList.values():
162 if ccd
is not None and d[
'ccd'] != ccd:
164 results.append(tuple(d[f]
for f
in format))
168 """Mapping for dataset types that are organized according to a SkyMap subdivision of the sky."""
170 template =
"{dataset}-{filter}-{tract:02d}-{patch}{ext}"
171 keys = dict(filter=str, tract=int, patch=str)
174 """Mapping for CoaddTempExp datasets."""
176 template =
"{dataset}-{tract:02d}-{patch}-{visit:04d}{ext}"
177 keys = dict(tract=int, patch=str, visit=int)
180 """Mapping for forced_src datasets."""
182 template =
"{dataset}-{tract:02d}-{visit:04d}-{ccd:01d}{ext}"
183 keys = dict(tract=int, ccd=int, visit=int)
186 """Metaclass for SimpleMapper that creates map_ and query_ methods for everything found in the
187 'mappings' class variable.
192 def mapClosure(self, dataId, write=False):
193 return mapping.map(dataset, self.root, dataId, suffix=suffix)
198 def queryClosure(self, level, format, dataId):
199 return mapping.query(self.index, level, format, dataId)
203 type.__init__(cls, name, bases, dict_)
205 for dataset, mapping
in cls.mappings.iteritems():
206 setattr(cls,
"map_" + dataset, MapperMeta._makeMapClosure(dataset, mapping, suffix=
None))
207 for suffix
in mapping.persistence.suffixes:
208 setattr(cls,
"map_" + dataset + suffix,
209 MapperMeta._makeMapClosure(dataset, mapping, suffix=suffix))
210 if hasattr(mapping,
"query"):
211 setattr(cls,
"query_" + dataset, MapperMeta._makeQueryClosure(dataset, mapping))
212 cls.keyDict.update(mapping.keys)
216 An extremely simple mapper for an imaginary camera for use in integration tests.
218 As SimpleMapper does not inherit from daf.butlerUtils.CameraMapper, it does not
219 use a policy file to set mappings or a registry; all the information is here
220 (in the map_* and query_* methods).
222 The imaginary camera's raw data format has only 'visit' and 'ccd' keys, with
223 two CCDs per visit (by default).
226 __metaclass__ = MapperMeta
231 forced_src_schema =
SimpleMapping(SourceCatalogPersistenceType,
232 template=
"{dataset}{ext}", keys={}),
233 truth =
SimpleMapping(SimpleCatalogPersistenceType, template=
"{dataset}-{tract:02d}{ext}",
235 simsrc =
RawMapping(SimpleCatalogPersistenceType, template=
"{dataset}-{tract:02d}{ext}",
237 observations =
SimpleMapping(ExposureCatalogPersistenceType, template=
"{dataset}-{tract:02d}{ext}",
239 ccdExposureId =
RawMapping(BypassPersistenceType),
241 deepCoaddId =
SkyMapping(BypassPersistenceType),
243 deepMergedCoaddId =
SkyMapping(BypassPersistenceType),
244 deepMergedCoaddId_bits =
SimpleMapping(BypassPersistenceType),
245 deepCoadd_skyMap =
SimpleMapping(SkyMapPersistenceType, template=
"{dataset}{ext}", keys={}),
246 deepCoadd =
SkyMapping(ExposurePersistenceType),
247 deepCoadd_calexp_det =
SkyMapping(ExposurePersistenceType),
248 deepCoadd_calexp_detBackground =
SkyMapping(CatalogPersistenceType),
249 deepCoadd_icSrc =
SkyMapping(SourceCatalogPersistenceType),
250 deepCoadd_icSrc_schema =
SimpleMapping(SourceCatalogPersistenceType,
251 template=
"{dataset}{ext}", keys={}),
252 deepCoadd_src =
SkyMapping(SourceCatalogPersistenceType),
253 deepCoadd_src_schema =
SimpleMapping(SourceCatalogPersistenceType,
254 template=
"{dataset}{ext}", keys={}),
255 deepCoadd_peak_schema =
SimpleMapping(PeakCatalogPersistenceType,
256 template=
"{dataset}{ext}", keys={}),
257 deepCoadd_ref =
SkyMapping(SourceCatalogPersistenceType),
258 deepCoadd_ref_schema =
SimpleMapping(SourceCatalogPersistenceType,
259 template=
"{dataset}{ext}", keys={}),
260 deepCoadd_det =
SkyMapping(SourceCatalogPersistenceType),
261 deepCoadd_det_schema =
SimpleMapping(SourceCatalogPersistenceType,
262 template=
"{dataset}{ext}", keys={}),
263 deepCoadd_mergeDet =
SkyMapping(SourceCatalogPersistenceType),
264 deepCoadd_mergeDet_schema =
SimpleMapping(SourceCatalogPersistenceType,
265 template=
"{dataset}{ext}", keys={}),
266 deepCoadd_meas =
SkyMapping(SourceCatalogPersistenceType),
267 deepCoadd_meas_schema =
SimpleMapping(SourceCatalogPersistenceType,
268 template=
"{dataset}{ext}", keys={}),
269 deepCoadd_forced_src =
SkyMapping(SourceCatalogPersistenceType),
270 deepCoadd_forced_src_schema =
SimpleMapping(SourceCatalogPersistenceType,
271 template=
"{dataset}{ext}", keys={}),
272 deepCoadd_mock =
SkyMapping(ExposurePersistenceType),
283 super(SimpleMapper, self).
__init__()
286 afwImageUtils.defineFilter(
'r', 619.42)
291 def getKeys(self, datasetType, level):
292 if datasetType
is None:
293 keyDict = self.keyDict
295 keyDict = self.
mappings[datasetType].keys
296 if level
is not None and level
in self.
levels:
297 keyDict = dict(keyDict)
298 for l
in self.
levels[level]:
304 filenames = os.listdir(self.
root)
305 rawRegex = re.compile(
r"(?P<dataset>\w+)-(?P<visit>\d+)-(?P<ccd>\d).*")
307 for filename
in filenames:
308 m = rawRegex.match(filename)
311 index = self.index.setdefault(m.group(
'dataset'), dict(ccd={
None:[]}, visit={
None:[]}))
312 visit = int(m.group(
'visit'))
313 ccd = int(m.group(
'ccd'))
314 d1 = dict(visit=visit, ccd=ccd)
315 d2 = dict(visit=visit)
316 index[
'ccd'].setdefault(visit, []).append(d1)
317 index[
'ccd'][
None].append(d1)
318 index[
'visit'][visit] = [d2]
319 index[
'visit'][
None].append(d1)
329 "lsst.afw.cameraGeom.Camera",
"Camera",
None, [], dataId
333 detectorId = dataId[
"ccd"]
334 detector = self.
camera[detectorId]
335 item.setDetector(detector)
339 return long(dataId[
"visit"]) * 10 + long(dataId[
"ccd"])
344 tract = long(dataId[
'tract'])
345 if tract < 0
or tract >= 128:
346 raise RuntimeError(
'tract not in range [0,128)')
347 patchX, patchY =
map(int, dataId[
'patch'].split(
','))
348 for p
in (patchX, patchY):
349 if p < 0
or p >= 2**13:
350 raise RuntimeError(
'patch component not in range [0, 8192)')
351 return (tract * 2**13 + patchX) * 2**13 + patchY
354 return dict(visit=(long(ccdExposureId) // 10), ccd=(long(ccdExposureId) % 10))
366 return 1 + 7 + 13*2 + 3
372 return 1 + 7 + 13*2 + 3
380 radialDistortion=0.925,
384 @param[in] nx: number of detectors in x
385 @param[in] ny: number of detectors in y
386 @param[in] sizeX: detector size in x (pixels)
387 @param[in] sizeY: detector size in y (pixels)
388 @param[in] gapX: gap between detectors in x (mm)
389 @param[in] gapY: gap between detectors in y (mm)
390 @param[in] pixelSize: pixel size (mm) (a float)
391 @param[in] plateScale: plate scale in arcsec/mm; 20.0 is for LSST
392 @param[in] radialDistortion: radial distortion, in mm/rad^2
393 (the r^3 coefficient of the radial distortion polynomial
394 that converts PUPIL in radians to FOCAL_PLANE in mm);
395 0.925 is the value Dave Monet measured for lsstSim data
397 Each detector will have one amplifier (with no raw information).
400 radialDistortCoeffs = [0.0, 1.0/pScaleRad, 0.0, radialDistortion/pScaleRad]
402 nativeSys = lsst.afw.cameraGeom.FOCAL_PLANE
404 lsst.afw.cameraGeom.PUPIL: focalPlaneToPupil,
411 cY = (iY - 0.5 * (nY - 1)) * (pixelSize * sizeY + gapY)
413 cX = (iX - 0.5 * (nX - 1)) * (pixelSize * sizeY + gapX)
415 detectorName =
"detector %d,%d" % (iX, iY)
416 detectorId = len(detectorList) + 1
420 serial = detectorName +
" serial",
422 ampExtent = ccdBBox.getDimensions(),
426 plateScale = plateScale,
427 radialDistortion = radialDistortion,
430 return lsst.afw.cameraGeom.Camera(
431 name =
"Simple Camera",
432 detectorList = detectorList,
433 transformMap = transformMap,
438 Create a data repository for SimpleMapper and return a butler for it.
440 Clobbers anything already in the given path.
442 if os.path.exists(root):
445 with open(os.path.join(root,
"_mapper"),
"w")
as f:
446 f.write(
"lsst.pipe.tasks.mocks.SimpleMapper\n")
A Detector and the data used to construct it.
def bypass_ccdExposureId_bits
def bypass_deepMergedCoaddId
An integer coordinate rectangle.
double arcsecToRad(double x)
def bypass_deepMergedCoaddId_bits
def bypass_deepCoaddId_bits
def _computeCcdExposureId