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")
46 """Base class of a hierarchy used by SimpleMapper to defined different kinds of types of objects 49 PersistenceType objects are never instantiated; only the type objects are used (we needed a 50 simple singleton struct that could be inherited, which is exactly what a Python type is). 60 """Method called by SimpleMapping to implement a map_ method.""" 70 """Persistence type for things that don't actually use daf_persistence. 73 python =
"lsst.daf.base.PropertySet" 77 """Method called by SimpleMapping to implement a map_ method; overridden to not use the path.""" 79 mapper=mapper, storage=storage)
83 """Persistence type of Exposure images. 86 python =
"lsst.afw.image.ExposureF" 88 storage =
"FitsStorage" 94 """Method called by SimpleMapping to implement a map_ method; overridden to support subimages.""" 96 loc = super(ExposurePersistenceType, cls).
makeButlerLocation(path, dataId, mapper, suffix=
None,
104 "compression.algorithm":
"NONE",
105 "compression.columns": 0,
106 "compression.rows": 0,
107 "compression.quantizeLevel": 0.0,
108 "scaling.algorithm":
"NONE",
109 "scaling.bzero": 0.0,
110 "scaling.bscale": 0.0,
112 "scaling.quantizeLevel": 0.0,
113 "scaling.quantizePad": 0.0,
114 "scaling.fuzz":
False,
117 for prefix
in (
"image",
"mask",
"variance"):
118 for k, v
in options.items():
119 loc.additionalData.set(
"{}.{}".
format(prefix, k), v)
120 elif suffix ==
"_sub":
121 subId = dataId.copy()
122 bbox = subId.pop(
'bbox')
123 loc = super(ExposurePersistenceType, cls).
makeButlerLocation(path, subId, mapper, suffix=
None,
125 loc.additionalData.set(
'llcX', bbox.getMinX())
126 loc.additionalData.set(
'llcY', bbox.getMinY())
127 loc.additionalData.set(
'width', bbox.getWidth())
128 loc.additionalData.set(
'height', bbox.getHeight())
129 if 'imageOrigin' in dataId:
130 loc.additionalData.set(
'imageOrigin',
131 dataId[
'imageOrigin'])
136 python =
"lsst.skymap.BaseSkyMap" 137 storage =
"PickleStorage" 142 python =
"lsst.afw.table.BaseCatalog" 144 storage =
"FitsCatalogStorage" 149 python =
"lsst.afw.table.SimpleCatalog" 150 cpp =
"SimpleCatalog" 154 python =
"lsst.afw.table.SourceCatalog" 155 cpp =
"SourceCatalog" 159 python =
"lsst.afw.table.ExposureCatalog" 160 cpp =
"ExposureCatalog" 164 python =
"lsst.afw.detection.PeakCatalog" 169 """Mapping object used to implement SimpleMapper, similar in intent to lsst.daf.peristence.Mapping. 175 def __init__(self, persistence, template=None, keys=None):
177 if template
is not None:
182 def map(self, dataset, root, dataId, mapper, suffix=None, storage=None):
187 return self.
persistence.makeButlerLocation(path, dataId, suffix=suffix, mapper=mapper,
192 """Mapping for dataset types that are organized the same way as raw data (i.e. by CCD).""" 194 template =
"{dataset}-{visit:04d}-{ccd:01d}{ext}" 195 keys = dict(visit=int, ccd=int)
197 def query(self, dataset, index, level, format, dataId):
198 dictList = index[dataset][level]
199 results = [
list(d.values())
for d
in dictList[dataId.get(level,
None)]]
204 """Mapping for dataset types that are organized according to a SkyMap subdivision of the sky.""" 206 template =
"{dataset}-{filter}-{tract:02d}-{patch}{ext}" 207 keys = dict(filter=str, tract=int, patch=str)
211 """Mapping for CoaddTempExp datasets.""" 213 template =
"{dataset}-{tract:02d}-{patch}-{visit:04d}{ext}" 214 keys = dict(tract=int, patch=str, visit=int)
218 """Mapping for forced_src datasets.""" 220 template =
"{dataset}-{tract:02d}-{visit:04d}-{ccd:01d}{ext}" 221 keys = dict(tract=int, ccd=int, visit=int)
225 """Metaclass for SimpleMapper that creates map_ and query_ methods for everything found in the 226 'mappings' class variable. 230 def _makeMapClosure(dataset, mapping, suffix=None):
231 def mapClosure(self, dataId, write=False):
232 return mapping.map(dataset, self.root, dataId, self, suffix=suffix, storage=self.storage)
236 def _makeQueryClosure(dataset, mapping):
237 def queryClosure(self, level, format, dataId):
238 return mapping.query(dataset, self.index, level, format, dataId)
242 type.__init__(cls, name, bases, dict_)
244 for dataset, mapping
in cls.mappings.
items():
245 setattr(cls,
"map_" + dataset, MapperMeta._makeMapClosure(dataset, mapping, suffix=
None))
246 for suffix
in mapping.persistence.suffixes:
247 setattr(cls,
"map_" + dataset + suffix,
248 MapperMeta._makeMapClosure(dataset, mapping, suffix=suffix))
249 if hasattr(mapping,
"query"):
250 setattr(cls,
"query_" + dataset, MapperMeta._makeQueryClosure(dataset, mapping))
251 cls.
keyDict.update(mapping.keys)
256 An extremely simple mapper for an imaginary camera for use in integration tests. 258 As SimpleMapper does not inherit from obs.base.CameraMapper, it does not 259 use a policy file to set mappings or a registry; all the information is here 260 (in the map_* and query_* methods). 262 The imaginary camera's raw data format has only 'visit' and 'ccd' keys, with 263 two CCDs per visit (by default). 269 forced_src_schema=
SimpleMapping(SourceCatalogPersistenceType,
270 template=
"{dataset}{ext}", keys={}),
271 truth=
SimpleMapping(SimpleCatalogPersistenceType, template=
"{dataset}-{tract:02d}{ext}",
272 keys={
"tract": int}),
273 simsrc=
RawMapping(SimpleCatalogPersistenceType, template=
"{dataset}-{tract:02d}{ext}",
274 keys={
"tract": int}),
275 observations=
SimpleMapping(ExposureCatalogPersistenceType, template=
"{dataset}-{tract:02d}{ext}",
276 keys={
"tract": int}),
277 ccdExposureId=
RawMapping(BypassPersistenceType),
279 deepCoaddId=
SkyMapping(BypassPersistenceType),
281 deepMergedCoaddId=
SkyMapping(BypassPersistenceType),
283 deepCoadd_skyMap=
SimpleMapping(SkyMapPersistenceType, template=
"{dataset}{ext}", keys={}),
284 deepCoadd=
SkyMapping(ExposurePersistenceType),
285 deepCoaddPsfMatched=
SkyMapping(ExposurePersistenceType),
286 deepCoadd_calexp=
SkyMapping(ExposurePersistenceType),
287 deepCoadd_calexp_background=
SkyMapping(CatalogPersistenceType),
288 deepCoadd_icSrc=
SkyMapping(SourceCatalogPersistenceType),
289 deepCoadd_icSrc_schema=
SimpleMapping(SourceCatalogPersistenceType,
290 template=
"{dataset}{ext}", keys={}),
291 deepCoadd_src=
SkyMapping(SourceCatalogPersistenceType),
292 deepCoadd_src_schema=
SimpleMapping(SourceCatalogPersistenceType,
293 template=
"{dataset}{ext}", keys={}),
294 deepCoadd_peak_schema=
SimpleMapping(PeakCatalogPersistenceType,
295 template=
"{dataset}{ext}", keys={}),
296 deepCoadd_ref=
SkyMapping(SourceCatalogPersistenceType),
297 deepCoadd_ref_schema=
SimpleMapping(SourceCatalogPersistenceType,
298 template=
"{dataset}{ext}", keys={}),
299 deepCoadd_det=
SkyMapping(SourceCatalogPersistenceType),
300 deepCoadd_det_schema=
SimpleMapping(SourceCatalogPersistenceType,
301 template=
"{dataset}{ext}", keys={}),
302 deepCoadd_mergeDet=
SkyMapping(SourceCatalogPersistenceType),
303 deepCoadd_mergeDet_schema=
SimpleMapping(SourceCatalogPersistenceType,
304 template=
"{dataset}{ext}", keys={}),
305 deepCoadd_deblendedFlux=
SkyMapping(SourceCatalogPersistenceType),
306 deepCoadd_deblendedFlux_schema=
SimpleMapping(SourceCatalogPersistenceType,
307 template=
"{dataset}{ext}", keys={}),
308 deepCoadd_deblendedModel=
SkyMapping(SourceCatalogPersistenceType),
309 deepCoadd_deblendedModel_schema=
SimpleMapping(SourceCatalogPersistenceType,
310 template=
"{dataset}{ext}", keys={}),
311 deepCoadd_meas=
SkyMapping(SourceCatalogPersistenceType),
312 deepCoadd_meas_schema=
SimpleMapping(SourceCatalogPersistenceType,
313 template=
"{dataset}{ext}", keys={}),
314 deepCoadd_forced_src=
SkyMapping(SourceCatalogPersistenceType),
315 deepCoadd_forced_src_schema=
SimpleMapping(SourceCatalogPersistenceType,
316 template=
"{dataset}{ext}", keys={}),
317 deepCoadd_mock=
SkyMapping(ExposurePersistenceType),
318 deepCoaddPsfMatched_mock=
SkyMapping(ExposurePersistenceType),
320 deepCoadd_directWarp_mock=
TempExpMapping(ExposurePersistenceType),
322 deepCoadd_psfMatchedWarp_mock=
TempExpMapping(ExposurePersistenceType),
331 self.
storage = lsst.daf.persistence.Storage.makeFromURI(root)
332 super(SimpleMapper, self).
__init__(**kwargs)
335 afwImageUtils.defineFilter(
'r', 619.42) 342 if datasetType
is None:
345 keyDict = self.
mappings[datasetType].keys
346 if level
is not None and level
in self.
levels:
347 keyDict = dict(keyDict)
348 for l
in self.
levels[level]:
354 filenames = os.listdir(self.
root)
355 rawRegex = re.compile(
r"(?P<dataset>\w+)-(?P<visit>\d+)-(?P<ccd>\d).*")
357 for filename
in filenames:
358 m = rawRegex.match(filename)
361 index = self.
index.setdefault(m.group(
'dataset'), dict(ccd={
None: []}, visit={
None: []}))
362 visit =
int(m.group(
'visit'))
363 ccd =
int(m.group(
'ccd'))
364 d1 = dict(visit=visit, ccd=ccd)
365 d2 = dict(visit=visit)
366 index[
'ccd'].setdefault(visit, []).
append(d1)
367 index[
'ccd'][
None].
append(d1)
368 index[
'visit'][visit] = [d2]
369 index[
'visit'][
None].
append(d1)
379 "lsst.afw.cameraGeom.Camera",
"Camera",
None, [], dataId, mapper=self, storage=self.
storage 383 detectorId = dataId[
"ccd"]
384 detector = self.
camera[detectorId]
385 item.setDetector(detector)
389 def _computeCcdExposureId(self, dataId):
390 return int(dataId[
"visit"]) * 10 +
int(dataId[
"ccd"])
392 def _computeCoaddId(self, dataId):
395 tract =
int(dataId[
'tract'])
396 if tract < 0
or tract >= 128:
397 raise RuntimeError(
'tract not in range [0,128)')
398 patchX, patchY = (
int(c)
for c
in dataId[
'patch'].split(
','))
399 for p
in (patchX, patchY):
400 if p < 0
or p >= 2**13:
401 raise RuntimeError(
'patch component not in range [0, 8192)')
402 return (tract * 2**13 + patchX) * 2**13 + patchY
406 return dict(visit=(
int(ccdExposureId) // 10), ccd=(
int(ccdExposureId) % 10))
418 return 1 + 7 + 13*2 + 3
424 return 1 + 7 + 13*2 + 3
433 radialDistortion=0.925,
437 @param[in] nx: number of detectors in x 438 @param[in] ny: number of detectors in y 439 @param[in] sizeX: detector size in x (pixels) 440 @param[in] sizeY: detector size in y (pixels) 441 @param[in] gapX: gap between detectors in x (mm) 442 @param[in] gapY: gap between detectors in y (mm) 443 @param[in] pixelSize: pixel size (mm) (a float) 444 @param[in] plateScale: plate scale in arcsec/mm; 20.0 is for LSST 445 @param[in] radialDistortion: radial distortion, in mm/rad^2 446 (the r^3 coefficient of the radial distortion polynomial 447 that converts FIELD_ANGLE in radians to FOCAL_PLANE in mm); 448 0.925 is the value Dave Monet measured for lsstSim data 450 Each detector will have one amplifier (with no raw information). 452 pScaleRad = lsst.afw.geom.arcsecToRad(plateScale)
453 radialDistortCoeffs = [0.0, 1.0/pScaleRad, 0.0, radialDistortion/pScaleRad]
455 nativeSys = lsst.afw.cameraGeom.FOCAL_PLANE
457 lsst.afw.cameraGeom.FIELD_ANGLE: focalPlaneToFieldAngle,
464 cY = (iY - 0.5 * (nY - 1)) * (pixelSize * sizeY + gapY)
466 cX = (iX - 0.5 * (nX - 1)) * (pixelSize * sizeY + gapX)
468 detectorName =
"detector %d,%d" % (iX, iY)
469 detectorId = len(detectorList) + 1
473 serial=detectorName +
" serial",
475 ampExtent=ccdBBox.getDimensions(),
479 plateScale=plateScale,
480 radialDistortion=radialDistortion,
484 name=
"Simple Camera",
485 detectorList=detectorList,
486 transformMap=transformMap,
492 Create a data repository for SimpleMapper and return a butler for it. 494 Clobbers anything already in the given path. 496 if os.path.exists(root):
499 with open(os.path.join(root,
"_mapper"),
"w")
as f:
500 f.write(
"lsst.pipe.tasks.mocks.SimpleMapper\n")
def canStandardize(self, datasetType)
def map_camera(self, dataId, write=False)
def splitCcdExposureId(ccdExposureId)
def bypass_camera(self, datasetType, pythonType, location, dataId)
A collection of Detectors plus additional coordinate system support.
def __init__(self, persistence, template=None, keys=None)
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series.
def _computeCcdExposureId(self, dataId)
def makeSimpleCamera(nX, nY, sizeX, sizeY, gapX, gapY, pixelSize=1.0, plateScale=20.0, radialDistortion=0.925)
def bypass_ccdExposureId_bits(self, datasetType, pythonType, location, dataId)
Describe a detector's orientation in the focal plane.
def map(self, dataset, root, dataId, mapper, suffix=None, storage=None)
def getDefaultLevel(self)
def _computeCoaddId(self, dataId)
def __init__(self, root, kwargs)
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
def bypass_deepMergedCoaddId(self, datasetType, pythonType, location, dataId)
std::shared_ptr< TransformPoint2ToPoint2 > makeRadialTransform(std::vector< double > const &forwardCoeffs, std::vector< double > const &inverseCoeffs)
A purely radial polynomial distortion.
Holds an integer identifier for an LSST filter.
def makeButlerLocation(cls, path, dataId, mapper, suffix=None, storage=None)
def bypass_deepCoaddId(self, datasetType, pythonType, location, dataId)
def getKeys(self, datasetType, level)
def std_calexp(self, item, dataId)
def bypass_ccdExposureId(self, datasetType, pythonType, location, dataId)
def bypass_deepMergedCoaddId_bits(self, datasetType, pythonType, location, dataId)
std::vector< SchemaItem< Flag > > * items
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects...
def query(self, dataset, index, level, format, dataId)
def bypass_deepCoaddId_bits(self, datasetType, pythonType, location, dataId)
def makeButlerLocation(cls, path, dataId, mapper, suffix=None, storage=None)
An integer coordinate rectangle.
daf::base::PropertyList * list
def makeButlerLocation(cls, path, dataId, mapper, suffix=None, storage=None)