48 resetFitParameters, outputZeropoints,
49 lutFilterNames, tract=None):
51 Make the FGCM fit cycle configuration dict
55 config: `lsst.fgcmcal.FgcmFitCycleConfig`
59 camera: `lsst.afw.cameraGeom.Camera`
60 Camera from the butler
62 Maximum number of iterations
63 resetFitParameters: `bool`
64 Reset fit parameters before fitting?
65 outputZeropoints: `bool`
66 Compute zeropoints for output?
67 lutFilterNames : array-like, `str`
68 Array of physical filter names in the LUT.
69 tract: `int`, optional
70 Tract number for extending the output file name for debugging.
76 Configuration dictionary for fgcm
79 notFitBands = [b
for b
in config.bands
if b
not in config.fitBands]
83 for ccut
in config.starColorCuts:
87 parts = ccut.split(
',')
88 starColorCutList.append([parts[0], parts[1], float(parts[2]), float(parts[3])])
91 refStarColorCutList = []
92 for ccut
in config.refStarColorCuts:
96 parts = ccut.split(
',')
97 refStarColorCutList.append([parts[0], parts[1], float(parts[2]), float(parts[3])])
102 if config.mirrorArea
is None:
103 mirrorArea = np.pi*(camera.telescopeDiameter*100./2.)**2.
106 mirrorArea = config.mirrorArea * 100.**2.
109 gains = [amp.getGain()
for detector
in camera
for amp
in detector.getAmplifiers()]
110 cameraGain = float(np.median(gains))
113 filterToBand = {filterName: config.physicalFilterMap[filterName]
for
114 filterName
in lutFilterNames}
117 outfileBase = config.outfileBase
119 outfileBase =
'%s-%06d' % (config.outfileBase, tract)
122 configDict = {
'outfileBase': outfileBase,
124 'exposureFile':
None,
128 'mirrorArea': mirrorArea,
129 'cameraGain': cameraGain,
130 'ccdStartIndex': camera[0].getId(),
131 'expField': FGCM_EXP_FIELD,
132 'ccdField': FGCM_CCD_FIELD,
133 'seeingField':
'DELTA_APER',
134 'fwhmField':
'PSFSIGMA',
135 'skyBrightnessField':
'SKYBACKGROUND',
136 'deepFlag':
'DEEPFLAG',
137 'bands': list(config.bands),
138 'fitBands': list(config.fitBands),
139 'notFitBands': notFitBands,
140 'requiredBands': list(config.requiredBands),
141 'filterToBand': filterToBand,
143 'nCore': config.nCore,
144 'nStarPerRun': config.nStarPerRun,
145 'nExpPerRun': config.nExpPerRun,
146 'reserveFraction': config.reserveFraction,
147 'freezeStdAtmosphere': config.freezeStdAtmosphere,
148 'precomputeSuperStarInitialCycle': config.precomputeSuperStarInitialCycle,
149 'superStarSubCCDDict': dict(config.superStarSubCcdDict),
150 'superStarSubCCDChebyshevOrder': config.superStarSubCcdChebyshevOrder,
151 'superStarSubCCDTriangular': config.superStarSubCcdTriangular,
152 'superStarSigmaClip': config.superStarSigmaClip,
153 'superStarPlotCCDResiduals': config.superStarPlotCcdResiduals,
154 'focalPlaneSigmaClip': config.focalPlaneSigmaClip,
155 'ccdGraySubCCDDict': dict(config.ccdGraySubCcdDict),
156 'ccdGraySubCCDChebyshevOrder': config.ccdGraySubCcdChebyshevOrder,
157 'ccdGraySubCCDTriangular': config.ccdGraySubCcdTriangular,
158 'ccdGrayFocalPlaneDict': dict(config.ccdGrayFocalPlaneDict),
159 'ccdGrayFocalPlaneChebyshevOrder': config.ccdGrayFocalPlaneChebyshevOrder,
160 'ccdGrayFocalPlaneFitMinCcd': config.ccdGrayFocalPlaneFitMinCcd,
161 'cycleNumber': config.cycleNumber,
163 'deltaMagBkgOffsetPercentile': config.deltaMagBkgOffsetPercentile,
164 'deltaMagBkgPerCcd': config.deltaMagBkgPerCcd,
165 'UTBoundary': config.utBoundary,
166 'washMJDs': config.washMjds,
167 'epochMJDs': config.epochMjds,
168 'coatingMJDs': config.coatingMjds,
169 'minObsPerBand': config.minObsPerBand,
170 'latitude': config.latitude,
171 'defaultCameraOrientation': config.defaultCameraOrientation,
172 'brightObsGrayMax': config.brightObsGrayMax,
173 'minStarPerCCD': config.minStarPerCcd,
174 'minCCDPerExp': config.minCcdPerExp,
175 'maxCCDGrayErr': config.maxCcdGrayErr,
176 'minStarPerExp': config.minStarPerExp,
177 'minExpPerNight': config.minExpPerNight,
178 'expGrayInitialCut': config.expGrayInitialCut,
179 'expGrayPhotometricCutDict': dict(config.expGrayPhotometricCutDict),
180 'expGrayHighCutDict': dict(config.expGrayHighCutDict),
181 'expGrayRecoverCut': config.expGrayRecoverCut,
182 'expVarGrayPhotometricCutDict': dict(config.expVarGrayPhotometricCutDict),
183 'expGrayErrRecoverCut': config.expGrayErrRecoverCut,
184 'refStarSnMin': config.refStarSnMin,
185 'refStarOutlierNSig': config.refStarOutlierNSig,
186 'applyRefStarColorCuts': config.applyRefStarColorCuts,
187 'useExposureReferenceOffset': config.useExposureReferenceOffset,
188 'illegalValue': FGCM_ILLEGAL_VALUE,
189 'starColorCuts': starColorCutList,
190 'refStarColorCuts': refStarColorCutList,
191 'aperCorrFitNBins': config.aperCorrFitNBins,
192 'aperCorrInputSlopeDict': dict(config.aperCorrInputSlopeDict),
193 'sedBoundaryTermDict': config.sedboundaryterms.toDict()[
'data'],
194 'sedTermDict': config.sedterms.toDict()[
'data'],
195 'colorSplitBands': list(config.colorSplitBands),
196 'sigFgcmMaxErr': config.sigFgcmMaxErr,
197 'sigFgcmMaxEGrayDict': dict(config.sigFgcmMaxEGrayDict),
198 'ccdGrayMaxStarErr': config.ccdGrayMaxStarErr,
199 'approxThroughputDict': dict(config.approxThroughputDict),
200 'sigmaCalRange': list(config.sigmaCalRange),
201 'sigmaCalFitPercentile': list(config.sigmaCalFitPercentile),
202 'sigmaCalPlotPercentile': list(config.sigmaCalPlotPercentile),
203 'sigma0Phot': config.sigma0Phot,
204 'mapLongitudeRef': config.mapLongitudeRef,
205 'mapNSide': config.mapNSide,
208 'useRetrievedPwv':
False,
209 'useNightlyRetrievedPwv':
False,
210 'pwvRetrievalSmoothBlock': 25,
211 'useQuadraticPwv': config.useQuadraticPwv,
212 'useRetrievedTauInit':
False,
213 'tauRetrievalMinCCDPerNight': 500,
214 'modelMagErrors': config.modelMagErrors,
215 'instrumentParsPerBand': config.instrumentParsPerBand,
216 'instrumentSlopeMinDeltaT': config.instrumentSlopeMinDeltaT,
217 'fitMirrorChromaticity': config.fitMirrorChromaticity,
218 'fitCCDChromaticityDict': dict(config.fitCcdChromaticityDict),
219 'useRepeatabilityForExpGrayCutsDict': dict(config.useRepeatabilityForExpGrayCutsDict),
220 'autoPhotometricCutNSig': config.autoPhotometricCutNSig,
221 'autoHighCutNSig': config.autoHighCutNSig,
222 'deltaAperInnerRadiusArcsec': config.deltaAperInnerRadiusArcsec,
223 'deltaAperOuterRadiusArcsec': config.deltaAperOuterRadiusArcsec,
224 'deltaAperFitMinNgoodObs': config.deltaAperFitMinNgoodObs,
225 'deltaAperFitPerCcdNx': config.deltaAperFitPerCcdNx,
226 'deltaAperFitPerCcdNy': config.deltaAperFitPerCcdNy,
227 'deltaAperFitSpatialNside': config.deltaAperFitSpatialNside,
228 'doComputeDeltaAperExposures': config.doComputeDeltaAperPerVisit,
229 'doComputeDeltaAperStars': config.doComputeDeltaAperPerStar,
230 'doComputeDeltaAperMap': config.doComputeDeltaAperMap,
231 'doComputeDeltaAperPerCcd': config.doComputeDeltaAperPerCcd,
233 'quietMode': config.quietMode,
234 'randomSeed': config.randomSeed,
235 'outputStars':
False,
236 'outputPath': os.path.abspath(
'.'),
239 'resetParameters': resetFitParameters,
240 'doPlots': config.doPlots,
241 'outputFgcmcalZpts':
True,
242 'outputZeropoints': outputZeropoints}
249 Translate the FGCM look-up-table into an fgcm-compatible object
253 lutCat: `lsst.afw.table.BaseCatalog`
254 Catalog describing the FGCM look-up table
255 physicalFilterMap: `dict`
256 Physical filter to band mapping
260 fgcmLut: `lsst.fgcm.FgcmLut`
261 Lookup table for FGCM
262 lutIndexVals: `numpy.ndarray`
263 Numpy array with LUT index information for FGCM
264 lutStd: `numpy.ndarray`
265 Numpy array with LUT standard throughput values for FGCM
269 After running this code, it is wise to `del lutCat` to clear the memory.
273 lutFilterNames = np.array(lutCat[0][
'physicalFilters'].split(
','), dtype=
'U')
274 lutStdFilterNames = np.array(lutCat[0][
'stdPhysicalFilters'].split(
','), dtype=
'U')
279 lutIndexVals = np.zeros(1, dtype=[(
'FILTERNAMES', lutFilterNames.dtype.str,
280 lutFilterNames.size),
281 (
'STDFILTERNAMES', lutStdFilterNames.dtype.str,
282 lutStdFilterNames.size),
283 (
'PMB',
'f8', lutCat[0][
'pmb'].size),
284 (
'PMBFACTOR',
'f8', lutCat[0][
'pmbFactor'].size),
285 (
'PMBELEVATION',
'f8'),
286 (
'LAMBDANORM',
'f8'),
287 (
'PWV',
'f8', lutCat[0][
'pwv'].size),
288 (
'O3',
'f8', lutCat[0][
'o3'].size),
289 (
'TAU',
'f8', lutCat[0][
'tau'].size),
290 (
'ALPHA',
'f8', lutCat[0][
'alpha'].size),
291 (
'ZENITH',
'f8', lutCat[0][
'zenith'].size),
294 lutIndexVals[
'FILTERNAMES'][:] = lutFilterNames
295 lutIndexVals[
'STDFILTERNAMES'][:] = lutStdFilterNames
296 lutIndexVals[
'PMB'][:] = lutCat[0][
'pmb']
297 lutIndexVals[
'PMBFACTOR'][:] = lutCat[0][
'pmbFactor']
298 lutIndexVals[
'PMBELEVATION'] = lutCat[0][
'pmbElevation']
299 lutIndexVals[
'LAMBDANORM'] = lutCat[0][
'lambdaNorm']
300 lutIndexVals[
'PWV'][:] = lutCat[0][
'pwv']
301 lutIndexVals[
'O3'][:] = lutCat[0][
'o3']
302 lutIndexVals[
'TAU'][:] = lutCat[0][
'tau']
303 lutIndexVals[
'ALPHA'][:] = lutCat[0][
'alpha']
304 lutIndexVals[
'ZENITH'][:] = lutCat[0][
'zenith']
305 lutIndexVals[
'NCCD'] = lutCat[0][
'nCcd']
308 lutStd = np.zeros(1, dtype=[(
'PMBSTD',
'f8'),
314 (
'LAMBDARANGE',
'f8', 2),
315 (
'LAMBDASTEP',
'f8'),
316 (
'LAMBDASTD',
'f8', lutFilterNames.size),
317 (
'LAMBDASTDFILTER',
'f8', lutStdFilterNames.size),
318 (
'I0STD',
'f8', lutFilterNames.size),
319 (
'I1STD',
'f8', lutFilterNames.size),
320 (
'I10STD',
'f8', lutFilterNames.size),
321 (
'I2STD',
'f8', lutFilterNames.size),
322 (
'LAMBDAB',
'f8', lutFilterNames.size),
323 (
'ATMLAMBDA',
'f8', lutCat[0][
'atmLambda'].size),
324 (
'ATMSTDTRANS',
'f8', lutCat[0][
'atmStdTrans'].size)])
325 lutStd[
'PMBSTD'] = lutCat[0][
'pmbStd']
326 lutStd[
'PWVSTD'] = lutCat[0][
'pwvStd']
327 lutStd[
'O3STD'] = lutCat[0][
'o3Std']
328 lutStd[
'TAUSTD'] = lutCat[0][
'tauStd']
329 lutStd[
'ALPHASTD'] = lutCat[0][
'alphaStd']
330 lutStd[
'ZENITHSTD'] = lutCat[0][
'zenithStd']
331 lutStd[
'LAMBDARANGE'][:] = lutCat[0][
'lambdaRange'][:]
332 lutStd[
'LAMBDASTEP'] = lutCat[0][
'lambdaStep']
333 lutStd[
'LAMBDASTD'][:] = lutCat[0][
'lambdaStd']
334 lutStd[
'LAMBDASTDFILTER'][:] = lutCat[0][
'lambdaStdFilter']
335 lutStd[
'I0STD'][:] = lutCat[0][
'i0Std']
336 lutStd[
'I1STD'][:] = lutCat[0][
'i1Std']
337 lutStd[
'I10STD'][:] = lutCat[0][
'i10Std']
338 lutStd[
'I2STD'][:] = lutCat[0][
'i2Std']
339 lutStd[
'LAMBDAB'][:] = lutCat[0][
'lambdaB']
340 lutStd[
'ATMLAMBDA'][:] = lutCat[0][
'atmLambda'][:]
341 lutStd[
'ATMSTDTRANS'][:] = lutCat[0][
'atmStdTrans'][:]
343 lutTypes = [row[
'luttype']
for row
in lutCat]
346 lutFlat = np.zeros(lutCat[0][
'lut'].size, dtype=[(
'I0',
'f4'),
349 lutFlat[
'I0'][:] = lutCat[lutTypes.index(
'I0')][
'lut'][:]
350 lutFlat[
'I1'][:] = lutCat[lutTypes.index(
'I1')][
'lut'][:]
352 lutDerivFlat = np.zeros(lutCat[0][
'lut'].size, dtype=[(
'D_LNPWV',
'f4'),
356 (
'D_SECZENITH',
'f4'),
357 (
'D_LNPWV_I1',
'f4'),
359 (
'D_LNTAU_I1',
'f4'),
360 (
'D_ALPHA_I1',
'f4'),
361 (
'D_SECZENITH_I1',
'f4')])
363 for name
in lutDerivFlat.dtype.names:
364 lutDerivFlat[name][:] = lutCat[lutTypes.index(name)][
'lut'][:]
371 fgcmLut = fgcm.FgcmLUT(lutIndexVals, lutFlat, lutDerivFlat, lutStd,
372 filterToBand=physicalFilterMap)
374 return fgcmLut, lutIndexVals, lutStd