Coverage for python/lsst/fgcmcal/photoCalibConsolidateGen2Gen3.py: 39%

71 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2024-02-08 07:46 +0000

1# See COPYRIGHT file at the top of the source tree. 

2# 

3# This file is part of fgcmcal. 

4# 

5# Developed for the LSST Data Management System. 

6# This product includes software developed by the LSST Project 

7# (https://www.lsst.org). 

8# See the COPYRIGHT file at the top-level directory of this distribution 

9# for details of code ownership. 

10# 

11# This program is free software: you can redistribute it and/or modify 

12# it under the terms of the GNU General Public License as published by 

13# the Free Software Foundation, either version 3 of the License, or 

14# (at your option) any later version. 

15# 

16# This program is distributed in the hope that it will be useful, 

17# but WITHOUT ANY WARRANTY; without even the implied warranty of 

18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

19# GNU General Public License for more details. 

20# 

21# You should have received a copy of the GNU General Public License 

22# along with this program. If not, see <https://www.gnu.org/licenses/>. 

23"""Convert gen2 to gen3 photocalib files. 

24""" 

25# import lsst.pex.config as pexConfig 

26import lsst.pipe.base as pipeBase 

27from lsst.pipe.base import connectionTypes 

28import lsst.afw.table as afwTable 

29import lsst.daf.base as dafBase 

30import lsst.utils as utils 

31 

32 

33__all__ = ['PhotoCalibConsolidateGen2Gen3Config', 

34 'PhotoCalibConsolidateGen2Gen3Connections', 

35 'PhotoCalibConsolidateGen2Gen3Task', 

36 'SkyWcsConsolidateGen2Gen3Config', 

37 'SkyWcsConsolidateGen2Gen3Connections', 

38 'SkyWcsConsolidateGen2Gen3Task'] 

39 

40 

41class PhotoCalibConsolidateGen2Gen3Connections(pipeBase.PipelineTaskConnections, 

42 dimensions=("instrument", "visit")): 

43 photoCalibList = connectionTypes.Input( 

44 doc="Per-detector photocalibs from fgcm", 

45 name="fgcm_photoCalib", 

46 storageClass="PhotoCalib", 

47 dimensions=("instrument", "visit", "detector"), 

48 deferLoad=True, 

49 multiple=True, 

50 ) 

51 photoCalibGlobalCatalog = connectionTypes.Output( 

52 doc="Global per-visit photocalibs.", 

53 name="fgcmPhotoCalibCatalog", 

54 storageClass="ExposureCatalog", 

55 dimensions=("instrument", "visit"), 

56 ) 

57 

58 

59class PhotoCalibConsolidateGen2Gen3Config(pipeBase.PipelineTaskConfig, 

60 pipelineConnections=PhotoCalibConsolidateGen2Gen3Connections): 

61 def validate(self): 

62 super().validate() 

63 

64 

65class PhotoCalibConsolidateGen2Gen3Task(pipeBase.PipelineTask): 

66 """Consolidate gen2 photocalibs into gen3 photocalibs.""" 

67 ConfigClass = PhotoCalibConsolidateGen2Gen3Config 

68 _DefaultName = "photoCalibConsolidateGen2Gen3" 

69 

70 def __init__(self, butler=None, **kwargs): 

71 super().__init__(**kwargs) 

72 

73 @utils.inheritDoc(pipeBase.PipelineTask) 

74 def runQuantum(self, butlerQC, inputRefs, outputRefs): 

75 visit = butlerQC.quantum.dataId['visit'] 

76 

77 schema = afwTable.ExposureTable.makeMinimalSchema() 

78 schema.addField('visit', type='L', doc='visit number') 

79 

80 metadata = dafBase.PropertyList() 

81 metadata.add("COMMENT", "Catalog id is detector id, sorted") 

82 metadata.add("COMMENT", "Only detectors with data have entries") 

83 

84 photoCalibCat = afwTable.ExposureCatalog(schema) 

85 photoCalibCat.setMetadata(metadata) 

86 photoCalibCat.reserve(len(inputRefs.photoCalibList)) 

87 

88 photoCalibList = butlerQC.get(inputRefs.photoCalibList) 

89 for dataRef in photoCalibList: 

90 detector = dataRef.dataId['detector'] 

91 photoCalib = dataRef.get() 

92 rec = photoCalibCat.addNew() 

93 rec['id'] = detector 

94 rec['visit'] = visit 

95 rec.setPhotoCalib(photoCalib) 

96 

97 photoCalibCat.sort() 

98 

99 butlerQC.put(photoCalibCat, outputRefs.photoCalibGlobalCatalog) 

100 

101 

102class SkyWcsConsolidateGen2Gen3Connections(pipeBase.PipelineTaskConnections, 

103 dimensions=("instrument", "visit", 

104 "skymap", "tract")): 

105 skyWcsList = connectionTypes.Input( 

106 doc="Per-tract, per-detector wcs calibrations.", 

107 name="jointcal_wcs", 

108 storageClass="Wcs", 

109 dimensions=("instrument", "visit", "detector", "tract", "skymap"), 

110 deferLoad=True, 

111 multiple=True, 

112 ) 

113 skyWcsTractCatalog = connectionTypes.Output( 

114 doc="Per-tract, per-visit wcs calibrations.", 

115 name="jointcalSkyWcsCatalog", 

116 storageClass="ExposureCatalog", 

117 dimensions=("instrument", "visit", "tract"), 

118 ) 

119 

120 

121class SkyWcsConsolidateGen2Gen3Config(pipeBase.PipelineTaskConfig, 

122 pipelineConnections=SkyWcsConsolidateGen2Gen3Connections): 

123 def validate(self): 

124 super().validate() 

125 

126 

127class SkyWcsConsolidateGen2Gen3Task(pipeBase.PipelineTask): 

128 """Consolidate gen2 skywcss into gen3 skywcss.""" 

129 ConfigClass = SkyWcsConsolidateGen2Gen3Config 

130 _DefaultName = "skyWcsConsolidateGen2Gen3" 

131 

132 def __init__(self, butler=None, **kwargs): 

133 super().__init__(**kwargs) 

134 

135 @utils.inheritDoc(pipeBase.PipelineTask) 

136 def runQuantum(self, butlerQC, inputRefs, outputRefs): 

137 visit = butlerQC.quantum.dataId['visit'] 

138 

139 schema = afwTable.ExposureTable.makeMinimalSchema() 

140 schema.addField('visit', type='L', doc='visit number') 

141 

142 metadata = dafBase.PropertyList() 

143 metadata.add("COMMENT", "Catalog id is detector id, sorted") 

144 metadata.add("COMMENT", "Only detectors with data have entries") 

145 

146 skyWcsCat = afwTable.ExposureCatalog(schema) 

147 skyWcsCat.setMetadata(metadata) 

148 skyWcsCat.reserve(len(inputRefs.skyWcsList)) 

149 

150 skyWcsList = butlerQC.get(inputRefs.skyWcsList) 

151 for dataRef in skyWcsList: 

152 detector = dataRef.dataId['detector'] 

153 skyWcs = dataRef.get() 

154 rec = skyWcsCat.addNew() 

155 rec['id'] = detector 

156 rec['visit'] = visit 

157 rec.setWcs(skyWcs) 

158 

159 skyWcsCat.sort() 

160 

161 butlerQC.put(skyWcsCat, outputRefs.skyWcsTractCatalog)