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.
41 __all__ = (
"SimpleMapper",
"makeSimpleCamera",
"makeDataRepo")
44 """Base class of a hierarchy used by SimpleMapper to defined different kinds of types of objects
47 PersistenceType objects are never instantiated; only the type objects are used (we needed a
48 simple singleton struct that could be inherited, which is exactly what a Python type is).
58 """Method called by SimpleMapping to implement a map_ method."""
62 """Persistence type for things that don't actually use daf_persistence.
65 python =
"lsst.daf.base.PropertySet"
69 """Method called by SimpleMapping to implement a map_ method; overridden to not use the path."""
73 """Persistence type of Exposure images.
76 python =
"lsst.afw.image.ExposureF"
78 storage =
"FitsStorage"
84 """Method called by SimpleMapping to implement a map_ method; overridden to support subimages."""
86 loc = super(ExposurePersistenceType, cls).
makeButlerLocation(path, dataId, suffix=
None)
87 elif suffix ==
"_sub":
89 bbox = subId.pop(
'bbox')
91 loc.additionalData.set(
'llcX', bbox.getMinX())
92 loc.additionalData.set(
'llcY', bbox.getMinY())
93 loc.additionalData.set(
'width', bbox.getWidth())
94 loc.additionalData.set(
'height', bbox.getHeight())
95 if 'imageOrigin' in dataId:
96 loc.additionalData.set(
'imageOrigin',
97 dataId[
'imageOrigin'])
101 python =
"lsst.skymap.BaseSkyMap"
102 storage =
"PickleStorage"
106 python =
"lsst.afw.table.BaseCatalog"
108 storage =
"FitsCatalogStorage"
112 python =
"lsst.afw.table.SimpleCatalog"
113 cpp =
"SimpleCatalog"
116 python =
"lsst.afw.table.SourceCatalog"
117 cpp =
"SourceCatalog"
120 python =
"lsst.afw.table.ExposureCatalog"
121 cpp =
"ExposureCatalog"
124 """Mapping object used to implement SimpleMapper, similar in intent to lsst.daf.peristence.Mapping.
130 def __init__(self, persistence, template=None, keys=None):
132 if template
is not None:
137 def map(self, dataset, root, dataId, suffix=None):
139 path = os.path.join(root, self.template.format(dataset=dataset, ext=self.persistence.ext,
143 return self.persistence.makeButlerLocation(path, dataId, suffix=suffix)
146 """Mapping for dataset types that are organized the same way as raw data (i.e. by CCD)."""
148 template =
"{dataset}-{visit:04d}-{ccd:01d}{ext}"
149 keys = dict(visit=int, ccd=int)
151 def query(self, index, level, format, dataId):
153 visit = dataId.get(
'visit',
None)
154 dictList = index[level][visit]
155 ccd = dataId.get(
'ccd',
None)
156 for d
in dictList.values():
157 if ccd
is not None and d[
'ccd'] != ccd:
159 results.append(tuple(d[f]
for f
in format))
163 """Mapping for dataset types that are organized according to a SkyMap subdivision of the sky."""
165 template =
"{dataset}-{filter}-{tract:02d}-{patch}{ext}"
166 keys = dict(filter=str, tract=int, patch=str)
169 """Mapping for CoaddTempExp datasets."""
171 template =
"{dataset}-{tract:02d}-{patch}-{visit:04d}{ext}"
172 keys = dict(tract=int, patch=str, visit=int)
175 """Mapping for forced_src datasets."""
177 template =
"{dataset}-{tract:02d}-{visit:04d}-{ccd:01d}{ext}"
178 keys = dict(tract=int, ccd=int, visit=int)
181 """Metaclass for SimpleMapper that creates map_ and query_ methods for everything found in the
182 'mappings' class variable.
187 def mapClosure(self, dataId, write=False):
188 return mapping.map(dataset, self.root, dataId, suffix=suffix)
193 def queryClosure(self, level, format, dataId):
194 return mapping.query(self.index, level, format, dataId)
198 type.__init__(cls, name, bases, dict_)
200 for dataset, mapping
in cls.mappings.iteritems():
201 setattr(cls,
"map_" + dataset, MapperMeta._makeMapClosure(dataset, mapping, suffix=
None))
202 for suffix
in mapping.persistence.suffixes:
203 setattr(cls,
"map_" + dataset + suffix,
204 MapperMeta._makeMapClosure(dataset, mapping, suffix=suffix))
205 if hasattr(mapping,
"query"):
206 setattr(cls,
"query_" + dataset, MapperMeta._makeQueryClosure(dataset, mapping))
207 cls.keyDict.update(mapping.keys)
211 An extremely simple mapper for an imaginary camera for use in integration tests.
213 As SimpleMapper does not inherit from daf.butlerUtils.CameraMapper, it does not
214 use a policy file to set mappings or a registry; all the information is here
215 (in the map_* and query_* methods).
217 The imaginary camera's raw data format has only 'visit' and 'ccd' keys, with
218 two CCDs per visit (by default).
221 __metaclass__ = MapperMeta
226 forced_src_schema =
SimpleMapping(SourceCatalogPersistenceType,
227 template=
"{dataset}{ext}", keys={}),
228 truth =
SimpleMapping(SimpleCatalogPersistenceType, template=
"{dataset}-{tract:02d}{ext}",
230 simsrc =
RawMapping(SimpleCatalogPersistenceType, template=
"{dataset}-{tract:02d}{ext}",
232 observations =
SimpleMapping(ExposureCatalogPersistenceType, template=
"{dataset}-{tract:02d}{ext}",
234 ccdExposureId =
RawMapping(BypassPersistenceType),
236 deepCoaddId =
SkyMapping(BypassPersistenceType),
238 deepCoadd_skyMap =
SimpleMapping(SkyMapPersistenceType, template=
"{dataset}{ext}", keys={}),
239 deepCoadd =
SkyMapping(ExposurePersistenceType),
240 deepCoadd_calexp =
SkyMapping(ExposurePersistenceType),
241 deepCoadd_calexpBackground =
SkyMapping(CatalogPersistenceType),
242 deepCoadd_icSrc =
SkyMapping(SourceCatalogPersistenceType),
243 deepCoadd_icSrc_schema =
SimpleMapping(SourceCatalogPersistenceType,
244 template=
"{dataset}{ext}", keys={}),
245 deepCoadd_src =
SkyMapping(SourceCatalogPersistenceType),
246 deepCoadd_src_schema =
SimpleMapping(SourceCatalogPersistenceType,
247 template=
"{dataset}{ext}", keys={}),
248 deepCoadd_forced_src =
SkyMapping(SourceCatalogPersistenceType),
249 deepCoadd_forced_src_schema =
SimpleMapping(SourceCatalogPersistenceType,
250 template=
"{dataset}{ext}", keys={}),
251 deepCoadd_mock =
SkyMapping(ExposurePersistenceType),
262 super(SimpleMapper, self).
__init__()
269 def getKeys(self, datasetType, level):
270 if datasetType
is None:
271 keyDict = self.keyDict
273 keyDict = self.
mappings[datasetType].keys
274 if level
is not None and level
in self.
levels:
275 keyDict = dict(keyDict)
276 for l
in self.
levels[level]:
282 filenames = os.listdir(self.
root)
283 rawRegex = re.compile(
r"(?P<dataset>\w+)-(?P<visit>\d+)-(?P<ccd>\d).*")
285 for filename
in filenames:
286 m = rawRegex.match(filename)
289 index = self.index.setdefault(m.group(
'dataset'), dict(ccd={
None:[]}, visit={
None:[]}))
290 visit = int(m.group(
'visit'))
291 ccd = int(m.group(
'ccd'))
292 d1 = dict(visit=visit, ccd=ccd)
293 d2 = dict(visit=visit)
294 index[
'ccd'].setdefault(visit, []).append(d1)
295 index[
'ccd'][
None].append(d1)
296 index[
'visit'][visit] = [d2]
297 index[
'visit'][
None].append(d1)
307 "lsst.afw.cameraGeom.Camera",
"Camera",
None, [], dataId
311 detectorId = dataId[
"ccd"]
312 detector = self.
camera[detectorId]
313 item.setDetector(detector)
317 return long(dataId[
"visit"]) * 10 + long(dataId[
"ccd"])
322 tract = long(dataId[
'tract'])
323 if tract < 0
or tract >= 128:
324 raise RuntimeError(
'tract not in range [0,128)')
325 patchX, patchY =
map(int, dataId[
'patch'].split(
','))
326 for p
in (patchX, patchY):
327 if p < 0
or p >= 2**13:
328 raise RuntimeError(
'patch component not in range [0, 8192)')
329 return (tract * 2**13 + patchX) * 2**13 + patchY
332 return dict(visit=(long(ccdExposureId) // 10), ccd=(long(ccdExposureId) % 10))
344 return 1 + 7 + 13*2 + 3
352 radialDistortion=0.925,
356 @param[in] nx: number of detectors in x
357 @param[in] ny: number of detectors in y
358 @param[in] sizeX: detector size in x (pixels)
359 @param[in] sizeY: detector size in y (pixels)
360 @param[in] gapX: gap between detectors in x (mm)
361 @param[in] gapY: gap between detectors in y (mm)
362 @param[in] pixelSize: pixel size (mm) (a float)
363 @param[in] plateScale: plate scale in arcsec/mm; 20.0 is for LSST
364 @param[in] radialDistortion: radial distortion, in mm/rad^2
365 (the r^3 coefficient of the radial distortion polynomial
366 that converts PUPIL in radians to FOCAL_PLANE in mm);
367 0.925 is the value Dave Monet measured for lsstSim data
369 Each detector will have one amplifier (with no raw information).
372 radialDistortCoeffs = [0.0, 1.0/pScaleRad, 0.0, radialDistortion/pScaleRad]
374 nativeSys = lsst.afw.cameraGeom.FOCAL_PLANE
376 lsst.afw.cameraGeom.PUPIL: focalPlaneToPupil,
383 cY = (iY - 0.5 * (nY - 1)) * (pixelSize * sizeY + gapY)
385 cX = (iX - 0.5 * (nX - 1)) * (pixelSize * sizeY + gapX)
387 detectorName =
"detector %d,%d" % (iX, iY)
388 detectorId = len(detectorList) + 1
392 serial = detectorName +
" serial",
394 ampExtent = ccdBBox.getDimensions(),
398 plateScale = plateScale,
399 radialDistortion = radialDistortion,
402 return lsst.afw.cameraGeom.Camera(
403 name =
"Simple Camera",
404 detectorList = detectorList,
405 transformMap = transformMap,
410 Create a data repository for SimpleMapper and return a butler for it.
412 Clobbers anything already in the given path.
414 if os.path.exists(root):
417 with open(os.path.join(root,
"_mapper"),
"w")
as f:
418 f.write(
"lsst.pipe.tasks.mocks.SimpleMapper\n")
A Detector and the data used to construct it.
def bypass_ccdExposureId_bits
An integer coordinate rectangle.
double arcsecToRad(double x)
def bypass_deepCoaddId_bits
def _computeCcdExposureId