49 resetFitParameters, outputZeropoints,
50 lutFilterNames, tract=None, nCore=1, doPlots=False):
52 Make the FGCM fit cycle configuration dict
56 config : `lsst.fgcmcal.FgcmFitCycleConfig`
58 log : `logging.Logger`
60 camera : `lsst.afw.cameraGeom.Camera`
61 Camera from the butler
63 Maximum number of iterations
64 resetFitParameters: `bool`
65 Reset fit parameters before fitting?
66 outputZeropoints : `bool`
67 Compute zeropoints for output?
68 lutFilterNames : array-like, `str`
69 Array of physical filter names in the LUT.
70 tract : `int`, optional
71 Tract number for extending the output file name for debugging.
73 nCore : `int`, optional
74 Number of cores to use.
75 doPlots : `bool`, optional
81 Configuration dictionary for fgcm
84 notFitBands = [b
for b
in config.bands
if b
not in config.fitBands]
88 for ccut
in config.starColorCuts:
92 parts = ccut.split(
',')
93 starColorCutList.append([parts[0], parts[1], float(parts[2]), float(parts[3])])
96 refStarColorCutList = []
97 for ccut
in config.refStarColorCuts:
101 parts = ccut.split(
',')
102 refStarColorCutList.append([parts[0], parts[1], float(parts[2]), float(parts[3])])
107 if config.mirrorArea
is None:
108 mirrorArea = np.pi*(camera.telescopeDiameter*100./2.)**2.
111 mirrorArea = config.mirrorArea * 100.**2.
113 if config.cameraGain
is None:
115 gains = [amp.getGain()
for detector
in camera
for amp
in detector.getAmplifiers()]
116 cameraGain = float(np.median(gains))
118 cameraGain = config.cameraGain
121 filterToBand = {filterName: config.physicalFilterMap[filterName]
for
122 filterName
in lutFilterNames}
125 outfileBase = config.outfileBase
127 outfileBase =
'%s-%06d' % (config.outfileBase, tract)
129 if config.aperCorrPerCcd:
130 if config.aperCorrUsePsfFwhm:
131 seeingField =
'PSFFWHM_DETECTOR'
133 seeingField =
'DELTA_APER_DETECTOR'
134 seeingSubExposure =
True
136 if config.aperCorrUsePsfFwhm:
137 seeingField =
'PSFFWHM'
139 seeingField =
'DELTA_APER'
140 seeingSubExposure =
False
143 configDict = {
'outfileBase': outfileBase,
145 'exposureFile':
None,
149 'mirrorArea': mirrorArea,
150 'cameraGain': cameraGain,
151 'ccdStartIndex': camera[0].getId(),
152 'expField': FGCM_EXP_FIELD,
153 'ccdField': FGCM_CCD_FIELD,
154 'seeingField': seeingField,
155 'fwhmField':
'PSFFWHM',
156 'skyBrightnessField':
'SKYBACKGROUND',
157 'deepFlag':
'DEEPFLAG',
158 'bands': list(config.bands),
159 'fitBands': list(config.fitBands),
160 'notFitBands': notFitBands,
161 'requiredBands': list(config.requiredBands),
162 'filterToBand': filterToBand,
165 'nStarPerRun': config.nStarPerRun,
166 'nStarPerGrayRun': config.nStarPerGrayRun,
167 'nObsPerRun': config.nObsPerRun,
168 'nObsPerGrayRun': config.nObsPerGrayRun,
169 'nExpPerRun': config.nExpPerRun,
170 'reserveFraction': config.reserveFraction,
171 'freezeStdAtmosphere': config.freezeStdAtmosphere,
172 'precomputeSuperStarInitialCycle': config.precomputeSuperStarInitialCycle,
173 'superStarSubCCDDict': dict(config.superStarSubCcdDict),
174 'superStarSubCCDChebyshevOrder': config.superStarSubCcdChebyshevOrder,
175 'superStarSubCCDTriangular': config.superStarSubCcdTriangular,
176 'superStarSigmaClip': config.superStarSigmaClip,
177 'superStarPlotCCDResiduals': config.superStarPlotCcdResiduals,
178 'superStarForceZeroMean': config.superStarForceZeroMean,
179 'focalPlaneSigmaClip': config.focalPlaneSigmaClip,
180 'ccdGraySubCCDDict': dict(config.ccdGraySubCcdDict),
181 'ccdGraySubCCDChebyshevOrder': config.ccdGraySubCcdChebyshevOrder,
182 'ccdGraySubCCDTriangular': config.ccdGraySubCcdTriangular,
183 'ccdGrayFocalPlaneDict': dict(config.ccdGrayFocalPlaneDict),
184 'ccdGrayFocalPlaneChebyshevOrder': config.ccdGrayFocalPlaneChebyshevOrder,
185 'ccdGrayFocalPlaneFitMinCcd': config.ccdGrayFocalPlaneFitMinCcd,
186 'ccdGrayFocalPlaneMaxStars': config.ccdGrayFocalPlaneMaxStars,
187 'cycleNumber': config.cycleNumber,
189 'deltaMagBkgOffsetPercentile': config.deltaMagBkgOffsetPercentile,
190 'deltaMagBkgPerCcd': config.deltaMagBkgPerCcd,
191 'UTBoundary': config.utBoundary,
192 'washMJDs': config.washMjds,
193 'epochMJDs': config.epochMjds,
194 'coatingMJDs': config.coatingMjds,
195 'minObsPerBand': config.minObsPerBand,
196 'latitude': config.latitude,
197 'defaultCameraOrientation': config.defaultCameraOrientation,
198 'brightObsGrayMax': config.brightObsGrayMax,
199 'minStarPerCCD': config.minStarPerCcd,
200 'minCCDPerExp': config.minCcdPerExp,
201 'maxCCDGrayErr': config.maxCcdGrayErr,
202 'minStarPerExp': config.minStarPerExp,
203 'minExpPerNight': config.minExpPerNight,
204 'expGrayInitialCut': config.expGrayInitialCut,
205 'expFwhmCutDict': dict(config.expFwhmCutDict),
206 'expGrayPhotometricCutDict': dict(config.expGrayPhotometricCutDict),
207 'expGrayHighCutDict': dict(config.expGrayHighCutDict),
208 'expGrayRecoverCut': config.expGrayRecoverCut,
209 'expVarGrayPhotometricCutDict': dict(config.expVarGrayPhotometricCutDict),
210 'expGrayErrRecoverCut': config.expGrayErrRecoverCut,
211 'refStarSnMin': config.refStarSnMin,
212 'refStarOutlierNSig': config.refStarOutlierNSig,
213 'applyRefStarColorCuts': config.applyRefStarColorCuts,
214 'refStarMaxFracUse': config.refStarMaxFracUse,
215 'useExposureReferenceOffset': config.useExposureReferenceOffset,
216 'illegalValue': FGCM_ILLEGAL_VALUE,
217 'starColorCuts': starColorCutList,
218 'refStarColorCuts': refStarColorCutList,
219 'aperCorrFitNBins': config.aperCorrFitNBins,
220 'aperCorrInputSlopeDict': dict(config.aperCorrInputSlopeDict),
221 'seeingSubExposure': seeingSubExposure,
222 'sedBoundaryTermDict': config.sedboundaryterms.toDict()[
'data'],
223 'sedTermDict': config.sedterms.toDict()[
'data'],
224 'colorSplitBands': list(config.colorSplitBands),
225 'sigFgcmMaxErr': config.sigFgcmMaxErr,
226 'sigFgcmMaxEGrayDict': dict(config.sigFgcmMaxEGrayDict),
227 'ccdGrayMaxStarErr': config.ccdGrayMaxStarErr,
228 'approxThroughputDict': dict(config.approxThroughputDict),
229 'sigmaCalRange': list(config.sigmaCalRange),
230 'sigmaCalFitPercentile': list(config.sigmaCalFitPercentile),
231 'sigmaCalPlotPercentile': list(config.sigmaCalPlotPercentile),
232 'sigma0Phot': config.sigma0Phot,
233 'mapLongitudeRef': config.mapLongitudeRef,
234 'mapNSide': config.mapNSide,
237 'useNightlyRetrievedPwv':
False,
238 'useQuadraticPwv': config.useQuadraticPwv,
239 'useRetrievedPwv': config.useRetrievedPwv,
240 'pwvRetrievalSmoothBlock': config.retrievedPwvSmoothingBlock,
241 'retrievedPwvBands': list(config.retrievedPwvBands),
242 'useRetrievedTauInit':
False,
243 'tauRetrievalMinCCDPerNight': 500,
244 'modelMagErrors': config.modelMagErrors,
245 'instrumentParsPerBand': config.instrumentParsPerBand,
246 'instrumentSlopeMinDeltaT': config.instrumentSlopeMinDeltaT,
247 'fitMirrorChromaticity': config.fitMirrorChromaticity,
248 'fitCCDChromaticityDict': dict(config.fitCcdChromaticityDict),
249 'useRepeatabilityForExpGrayCutsDict': dict(config.useRepeatabilityForExpGrayCutsDict),
250 'autoPhotometricCutNSig': config.autoPhotometricCutNSig,
251 'autoHighCutNSig': config.autoHighCutNSig,
252 'deltaAperInnerRadiusArcsec': config.deltaAperInnerRadiusArcsec,
253 'deltaAperOuterRadiusArcsec': config.deltaAperOuterRadiusArcsec,
254 'deltaAperFitMinNgoodObs': config.deltaAperFitMinNgoodObs,
255 'deltaAperFitPerCcdNx': config.deltaAperFitPerCcdNx,
256 'deltaAperFitPerCcdNy': config.deltaAperFitPerCcdNy,
257 'deltaAperFitSpatialNside': config.deltaAperFitSpatialNside,
258 'doComputeDeltaAperExposures': config.doComputeDeltaAperPerVisit,
259 'doComputeDeltaAperStars': config.doComputeDeltaAperPerStar,
260 'doComputeDeltaAperMap': config.doComputeDeltaAperMap,
261 'doComputeDeltaAperPerCcd': config.doComputeDeltaAperPerCcd,
263 'quietMode': config.quietMode,
264 'randomSeed': config.randomSeed,
265 'outputStars':
False,
266 'outputPath': os.path.abspath(
'.'),
269 'resetParameters': resetFitParameters,
271 'outputFgcmcalZpts':
True,
272 'outputZeropoints': outputZeropoints}
279 Translate the FGCM look-up-table into an fgcm-compatible object
283 lutCat: `lsst.afw.table.BaseCatalog`
284 Catalog describing the FGCM look-up table
285 physicalFilterMap: `dict`
286 Physical filter to band mapping
290 fgcmLut: `lsst.fgcm.FgcmLut`
291 Lookup table for FGCM
292 lutIndexVals: `numpy.ndarray`
293 Numpy array with LUT index information for FGCM
294 lutStd: `numpy.ndarray`
295 Numpy array with LUT standard throughput values for FGCM
299 After running this code, it is wise to `del lutCat` to clear the memory.
303 lutFilterNames = np.array(lutCat[0][
'physicalFilters'].split(
','), dtype=
'U')
304 lutStdFilterNames = np.array(lutCat[0][
'stdPhysicalFilters'].split(
','), dtype=
'U')
309 lutIndexVals = np.zeros(1, dtype=[(
'FILTERNAMES', lutFilterNames.dtype.str,
310 lutFilterNames.size),
311 (
'STDFILTERNAMES', lutStdFilterNames.dtype.str,
312 lutStdFilterNames.size),
313 (
'PMB',
'f8', lutCat[0][
'pmb'].size),
314 (
'PMBFACTOR',
'f8', lutCat[0][
'pmbFactor'].size),
315 (
'PMBELEVATION',
'f8'),
316 (
'LAMBDANORM',
'f8'),
317 (
'PWV',
'f8', lutCat[0][
'pwv'].size),
318 (
'O3',
'f8', lutCat[0][
'o3'].size),
319 (
'TAU',
'f8', lutCat[0][
'tau'].size),
320 (
'ALPHA',
'f8', lutCat[0][
'alpha'].size),
321 (
'ZENITH',
'f8', lutCat[0][
'zenith'].size),
324 lutIndexVals[
'FILTERNAMES'][:] = lutFilterNames
325 lutIndexVals[
'STDFILTERNAMES'][:] = lutStdFilterNames
326 lutIndexVals[
'PMB'][:] = lutCat[0][
'pmb']
327 lutIndexVals[
'PMBFACTOR'][:] = lutCat[0][
'pmbFactor']
328 lutIndexVals[
'PMBELEVATION'] = lutCat[0][
'pmbElevation']
329 lutIndexVals[
'LAMBDANORM'] = lutCat[0][
'lambdaNorm']
330 lutIndexVals[
'PWV'][:] = lutCat[0][
'pwv']
331 lutIndexVals[
'O3'][:] = lutCat[0][
'o3']
332 lutIndexVals[
'TAU'][:] = lutCat[0][
'tau']
333 lutIndexVals[
'ALPHA'][:] = lutCat[0][
'alpha']
334 lutIndexVals[
'ZENITH'][:] = lutCat[0][
'zenith']
335 lutIndexVals[
'NCCD'] = lutCat[0][
'nCcd']
338 lutStd = np.zeros(1, dtype=[(
'PMBSTD',
'f8'),
344 (
'LAMBDARANGE',
'f8', 2),
345 (
'LAMBDASTEP',
'f8'),
346 (
'LAMBDASTD',
'f8', lutFilterNames.size),
347 (
'LAMBDASTDFILTER',
'f8', lutStdFilterNames.size),
348 (
'I0STD',
'f8', lutFilterNames.size),
349 (
'I1STD',
'f8', lutFilterNames.size),
350 (
'I10STD',
'f8', lutFilterNames.size),
351 (
'I2STD',
'f8', lutFilterNames.size),
352 (
'LAMBDAB',
'f8', lutFilterNames.size),
353 (
'ATMLAMBDA',
'f8', lutCat[0][
'atmLambda'].size),
354 (
'ATMSTDTRANS',
'f8', lutCat[0][
'atmStdTrans'].size)])
355 lutStd[
'PMBSTD'] = lutCat[0][
'pmbStd']
356 lutStd[
'PWVSTD'] = lutCat[0][
'pwvStd']
357 lutStd[
'O3STD'] = lutCat[0][
'o3Std']
358 lutStd[
'TAUSTD'] = lutCat[0][
'tauStd']
359 lutStd[
'ALPHASTD'] = lutCat[0][
'alphaStd']
360 lutStd[
'ZENITHSTD'] = lutCat[0][
'zenithStd']
361 lutStd[
'LAMBDARANGE'][:] = lutCat[0][
'lambdaRange'][:]
362 lutStd[
'LAMBDASTEP'] = lutCat[0][
'lambdaStep']
363 lutStd[
'LAMBDASTD'][:] = lutCat[0][
'lambdaStd']
364 lutStd[
'LAMBDASTDFILTER'][:] = lutCat[0][
'lambdaStdFilter']
365 lutStd[
'I0STD'][:] = lutCat[0][
'i0Std']
366 lutStd[
'I1STD'][:] = lutCat[0][
'i1Std']
367 lutStd[
'I10STD'][:] = lutCat[0][
'i10Std']
368 lutStd[
'I2STD'][:] = lutCat[0][
'i2Std']
369 lutStd[
'LAMBDAB'][:] = lutCat[0][
'lambdaB']
370 lutStd[
'ATMLAMBDA'][:] = lutCat[0][
'atmLambda'][:]
371 lutStd[
'ATMSTDTRANS'][:] = lutCat[0][
'atmStdTrans'][:]
373 lutTypes = [row[
'luttype']
for row
in lutCat]
376 lutFlat = np.zeros(lutCat[0][
'lut'].size, dtype=[(
'I0',
'f4'),
379 lutFlat[
'I0'][:] = lutCat[lutTypes.index(
'I0')][
'lut'][:]
380 lutFlat[
'I1'][:] = lutCat[lutTypes.index(
'I1')][
'lut'][:]
382 lutDerivFlat = np.zeros(lutCat[0][
'lut'].size, dtype=[(
'D_LNPWV',
'f4'),
386 (
'D_SECZENITH',
'f4'),
387 (
'D_LNPWV_I1',
'f4'),
389 (
'D_LNTAU_I1',
'f4'),
390 (
'D_ALPHA_I1',
'f4'),
391 (
'D_SECZENITH_I1',
'f4')])
393 for name
in lutDerivFlat.dtype.names:
394 lutDerivFlat[name][:] = lutCat[lutTypes.index(name)][
'lut'][:]
401 fgcmLut = fgcm.FgcmLUT(lutIndexVals, lutFlat, lutDerivFlat, lutStd,
402 filterToBand=physicalFilterMap)
404 return fgcmLut, lutIndexVals, lutStd