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

87 statements  

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 

24 

25import lsst.log 

26import lsst.daf.persistence as dafPersist 

27from lsst.obs.base import CameraMapper 

28 

29from . import LsstCamMapper, LsstCamMakeRawVisitInfo 

30from .ingest import LsstCamParseTask 

31from .translators import LsstCamImSimTranslator 

32from ._instrument import LsstCamImSim 

33from .filters import LSSTCAM_IMSIM_FILTER_DEFINITIONS 

34 

35__all__ = ["ImsimMapper", "ImsimParseTask"] 

36 

37 

38class ImsimMakeRawVisitInfo(LsstCamMakeRawVisitInfo): 

39 """Make a VisitInfo from the FITS header of a raw image.""" 

40 metadataTranslator = LsstCamImSimTranslator 

41 

42 

43class ImsimMapper(LsstCamMapper): 

44 """The Mapper for the imsim simulations of the LsstCam.""" 

45 translatorClass = LsstCamImSimTranslator 

46 MakeRawVisitInfoClass = ImsimMakeRawVisitInfo 

47 _gen3instrument = LsstCamImSim 

48 

49 _cameraName = "imsim" 

50 yamlFileList = ["imsim/imsimMapper.yaml"] + list(LsstCamMapper.yamlFileList) 

51 filterDefinitions = LSSTCAM_IMSIM_FILTER_DEFINITIONS 

52 

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) 

61 

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") 

81 

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"] 

88 

89 LsstCamMapper._nbit_tract = 16 # These have been set to mimic the Gen3 version 

90 LsstCamMapper._nbit_patch = 9 

91 LsstCamMapper._nbit_filter = 5 

92 

93 LsstCamMapper._nbit_id = 64 - (LsstCamMapper._nbit_tract + 2*LsstCamMapper._nbit_patch 

94 + LsstCamMapper._nbit_filter) 

95 

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 

110 

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)) 

115 

116 def _computeCoaddExposureId(self, dataId, singleFilter): 

117 """Compute the 64-bit (long) identifier for a coadd. 

118 

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 

142 

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 

146 

147 def bypass_deepCoaddId_bits(self, *args, **kwargs): 

148 """The number of bits used up for patch ID bits.""" 

149 return LsstCamMapper._nbit_id 

150 

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 

154 

155 

156class ImsimParseTask(LsstCamParseTask): 

157 """Parser suitable for imsim data. 

158 """ 

159 

160 _mapperClass = ImsimMapper 

161 _translatorClass = LsstCamImSimTranslator 

162 

163 def translate_controller(self, md): 

164 """Always return Simulation as controller for imsim data.""" 

165 return "S"