Coverage for python/lsst/obs/lsst/imsim.py: 26%
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This file is part of obs_lsst.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the LSST License Statement and
20# the GNU General Public License along with this program. If not,
21# see <http://www.lsstcorp.org/LegalNotices/>.
22#
23import os
25import lsst.log
26import lsst.daf.persistence as dafPersist
27from lsst.obs.base import CameraMapper
29from . import LsstCamMapper, LsstCamMakeRawVisitInfo
30from .ingest import LsstCamParseTask
31from .translators import LsstCamImSimTranslator
32from ._instrument import LsstCamImSim
33from .filters import LSSTCAM_IMSIM_FILTER_DEFINITIONS
35__all__ = ["ImsimMapper", "ImsimParseTask"]
38class ImsimMakeRawVisitInfo(LsstCamMakeRawVisitInfo):
39 """Make a VisitInfo from the FITS header of a raw image."""
40 metadataTranslator = LsstCamImSimTranslator
43class ImsimMapper(LsstCamMapper):
44 """The Mapper for the imsim simulations of the LsstCam."""
45 translatorClass = LsstCamImSimTranslator
46 MakeRawVisitInfoClass = ImsimMakeRawVisitInfo
47 _gen3instrument = LsstCamImSim
49 _cameraName = "imsim"
50 yamlFileList = ["imsim/imsimMapper.yaml"] + list(LsstCamMapper.yamlFileList)
51 filterDefinitions = LSSTCAM_IMSIM_FILTER_DEFINITIONS
53 def __init__(self, inputPolicy=None, **kwargs):
54 #
55 # Merge the list of .yaml files
56 #
57 policy = None
58 for yamlFile in self.yamlFileList:
59 policyFile = dafPersist.Policy.defaultPolicyFile(self.packageName, yamlFile, "policy")
60 npolicy = dafPersist.Policy(policyFile)
62 if policy is None:
63 policy = npolicy
64 else:
65 policy.merge(npolicy)
66 #
67 # Look for the calibrations root "root/CALIB" if not supplied
68 #
69 if kwargs.get("root", None) and not kwargs.get("calibRoot", None):
70 calibSearch = [os.path.join(kwargs["root"], "CALIB")]
71 if "repositoryCfg" in kwargs:
72 calibSearch += [os.path.join(cfg.root, "CALIB") for cfg in kwargs["repositoryCfg"].parents if
73 hasattr(cfg, "root")]
74 calibSearch += [cfg.root for cfg in kwargs["repositoryCfg"].parents if hasattr(cfg, "root")]
75 for calibRoot in calibSearch:
76 if os.path.exists(os.path.join(calibRoot, "calibRegistry.sqlite3")):
77 kwargs["calibRoot"] = calibRoot
78 break
79 if not kwargs.get("calibRoot", None):
80 lsst.log.Log.getLogger("LsstCamMapper").warning("Unable to find valid calib root directory")
82 CameraMapper.__init__(self, policy, os.path.dirname(policyFile), **kwargs)
83 #
84 # The composite objects don't seem to set these
85 #
86 for d in (self.mappings, self.exposures):
87 d["raw"] = d["_raw"]
89 LsstCamMapper._nbit_tract = 16 # These have been set to mimic the Gen3 version
90 LsstCamMapper._nbit_patch = 9
91 LsstCamMapper._nbit_filter = 5
93 LsstCamMapper._nbit_id = 64 - (LsstCamMapper._nbit_tract + 2*LsstCamMapper._nbit_patch
94 + LsstCamMapper._nbit_filter)
96 baseFilters = set()
97 baseBands = set()
98 self.bandToIdNumDict = {} # this is to get rid of afwFilter.getId calls
99 filterNum = -1
100 for filterDef in self.filterDefinitions:
101 band = filterDef.band
102 physical_filter = filterDef.physical_filter
103 baseFilters.add(physical_filter)
104 baseBands.add(band)
105 if physical_filter not in self.bandToIdNumDict:
106 filterNum += 1
107 self.bandToIdNumDict[physical_filter] = filterNum
108 if band not in self.bandToIdNumDict:
109 self.bandToIdNumDict[band] = filterNum
111 nFilter = len(baseBands)
112 if nFilter >= 2**LsstCamMapper._nbit_filter:
113 raise RuntimeError("You have more filters (%d) defined than fit into the %d bits allocated" %
114 (nFilter, LsstCamMapper._nbit_filter))
116 def _computeCoaddExposureId(self, dataId, singleFilter):
117 """Compute the 64-bit (long) identifier for a coadd.
119 Parameters
120 ----------
121 dataId : `dict`
122 Data identifier with tract and patch.
123 singleFilter : `bool`
124 True means the desired ID is for a single-filter coadd, in which
125 case ``dataId`` must contain filter.
126 """
127 tract = int(dataId["tract"])
128 if tract < 0 or tract >= 2**LsstCamMapper._nbit_tract:
129 raise RuntimeError("tract not in range [0, %d)" % (2**LsstCamMapper._nbit_tract))
130 patchX, patchY = [int(patch) for patch in dataId["patch"].split(",")]
131 for p in (patchX, patchY):
132 if p < 0 or p >= 2**LsstCamMapper._nbit_patch:
133 raise RuntimeError("patch component not in range [0, %d)" % 2**LsstCamMapper._nbit_patch)
134 oid = (((tract << LsstCamMapper._nbit_patch) + patchX) << LsstCamMapper._nbit_patch) + patchY
135 if singleFilter:
136 if self.bandToIdNumDict[dataId["filter"]] >= 2**LsstCamMapper._nbit_filter:
137 raise RuntimeError("Filter %s has too high an ID (%d) to fit in %d bits",
138 dataId["filter"], self.bandToIdNumDict[dataId["filter"]],
139 LsstCamMapper._nbit_filter)
140 return (oid << LsstCamMapper._nbit_filter) + self.bandToIdNumDict[dataId["filter"]]
141 return oid
143 def bypass_ccdExposureId_bits(self, datasetType, pythonType, location, dataId):
144 """How many bits are required for the maximum exposure ID"""
145 return 34 # To match the value computed in gen3
147 def bypass_deepCoaddId_bits(self, *args, **kwargs):
148 """The number of bits used up for patch ID bits."""
149 return LsstCamMapper._nbit_id
151 def bypass_deepMergedCoaddId_bits(self, *args, **kwargs):
152 """The number of bits used up for patch ID bits."""
153 return LsstCamMapper._nbit_id - LsstCamMapper._nbit_filter
156class ImsimParseTask(LsstCamParseTask):
157 """Parser suitable for imsim data.
158 """
160 _mapperClass = ImsimMapper
161 _translatorClass = LsstCamImSimTranslator
163 def translate_controller(self, md):
164 """Always return Simulation as controller for imsim data."""
165 return "S"