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 seeingField =
'DELTA_APER_DETECTOR'
132 seeingField =
'DELTA_APER'
135 configDict = {
'outfileBase': outfileBase,
137 'exposureFile':
None,
141 'mirrorArea': mirrorArea,
142 'cameraGain': cameraGain,
143 'ccdStartIndex': camera[0].getId(),
144 'expField': FGCM_EXP_FIELD,
145 'ccdField': FGCM_CCD_FIELD,
146 'seeingField': seeingField,
147 'fwhmField':
'PSFFWHM',
148 'skyBrightnessField':
'SKYBACKGROUND',
149 'deepFlag':
'DEEPFLAG',
150 'bands': list(config.bands),
151 'fitBands': list(config.fitBands),
152 'notFitBands': notFitBands,
153 'requiredBands': list(config.requiredBands),
154 'filterToBand': filterToBand,
157 'nStarPerRun': config.nStarPerRun,
158 'nExpPerRun': config.nExpPerRun,
159 'reserveFraction': config.reserveFraction,
160 'freezeStdAtmosphere': config.freezeStdAtmosphere,
161 'precomputeSuperStarInitialCycle': config.precomputeSuperStarInitialCycle,
162 'superStarSubCCDDict': dict(config.superStarSubCcdDict),
163 'superStarSubCCDChebyshevOrder': config.superStarSubCcdChebyshevOrder,
164 'superStarSubCCDTriangular': config.superStarSubCcdTriangular,
165 'superStarSigmaClip': config.superStarSigmaClip,
166 'superStarPlotCCDResiduals': config.superStarPlotCcdResiduals,
167 'superStarForceZeroMean': config.superStarForceZeroMean,
168 'focalPlaneSigmaClip': config.focalPlaneSigmaClip,
169 'ccdGraySubCCDDict': dict(config.ccdGraySubCcdDict),
170 'ccdGraySubCCDChebyshevOrder': config.ccdGraySubCcdChebyshevOrder,
171 'ccdGraySubCCDTriangular': config.ccdGraySubCcdTriangular,
172 'ccdGrayFocalPlaneDict': dict(config.ccdGrayFocalPlaneDict),
173 'ccdGrayFocalPlaneChebyshevOrder': config.ccdGrayFocalPlaneChebyshevOrder,
174 'ccdGrayFocalPlaneFitMinCcd': config.ccdGrayFocalPlaneFitMinCcd,
175 'ccdGrayFocalPlaneMaxStars': config.ccdGrayFocalPlaneMaxStars,
176 'cycleNumber': config.cycleNumber,
178 'deltaMagBkgOffsetPercentile': config.deltaMagBkgOffsetPercentile,
179 'deltaMagBkgPerCcd': config.deltaMagBkgPerCcd,
180 'UTBoundary': config.utBoundary,
181 'washMJDs': config.washMjds,
182 'epochMJDs': config.epochMjds,
183 'coatingMJDs': config.coatingMjds,
184 'minObsPerBand': config.minObsPerBand,
185 'latitude': config.latitude,
186 'defaultCameraOrientation': config.defaultCameraOrientation,
187 'brightObsGrayMax': config.brightObsGrayMax,
188 'minStarPerCCD': config.minStarPerCcd,
189 'minCCDPerExp': config.minCcdPerExp,
190 'maxCCDGrayErr': config.maxCcdGrayErr,
191 'minStarPerExp': config.minStarPerExp,
192 'minExpPerNight': config.minExpPerNight,
193 'expGrayInitialCut': config.expGrayInitialCut,
194 'expFwhmCutDict': dict(config.expFwhmCutDict),
195 'expGrayPhotometricCutDict': dict(config.expGrayPhotometricCutDict),
196 'expGrayHighCutDict': dict(config.expGrayHighCutDict),
197 'expGrayRecoverCut': config.expGrayRecoverCut,
198 'expVarGrayPhotometricCutDict': dict(config.expVarGrayPhotometricCutDict),
199 'expGrayErrRecoverCut': config.expGrayErrRecoverCut,
200 'refStarSnMin': config.refStarSnMin,
201 'refStarOutlierNSig': config.refStarOutlierNSig,
202 'applyRefStarColorCuts': config.applyRefStarColorCuts,
203 'refStarMaxFracUse': config.refStarMaxFracUse,
204 'useExposureReferenceOffset': config.useExposureReferenceOffset,
205 'illegalValue': FGCM_ILLEGAL_VALUE,
206 'starColorCuts': starColorCutList,
207 'refStarColorCuts': refStarColorCutList,
208 'aperCorrFitNBins': config.aperCorrFitNBins,
209 'aperCorrInputSlopeDict': dict(config.aperCorrInputSlopeDict),
210 'sedBoundaryTermDict': config.sedboundaryterms.toDict()[
'data'],
211 'sedTermDict': config.sedterms.toDict()[
'data'],
212 'colorSplitBands': list(config.colorSplitBands),
213 'sigFgcmMaxErr': config.sigFgcmMaxErr,
214 'sigFgcmMaxEGrayDict': dict(config.sigFgcmMaxEGrayDict),
215 'ccdGrayMaxStarErr': config.ccdGrayMaxStarErr,
216 'approxThroughputDict': dict(config.approxThroughputDict),
217 'sigmaCalRange': list(config.sigmaCalRange),
218 'sigmaCalFitPercentile': list(config.sigmaCalFitPercentile),
219 'sigmaCalPlotPercentile': list(config.sigmaCalPlotPercentile),
220 'sigma0Phot': config.sigma0Phot,
221 'mapLongitudeRef': config.mapLongitudeRef,
222 'mapNSide': config.mapNSide,
225 'useRetrievedPwv':
False,
226 'useNightlyRetrievedPwv':
False,
227 'pwvRetrievalSmoothBlock': 25,
228 'useQuadraticPwv': config.useQuadraticPwv,
229 'useRetrievedTauInit':
False,
230 'tauRetrievalMinCCDPerNight': 500,
231 'modelMagErrors': config.modelMagErrors,
232 'instrumentParsPerBand': config.instrumentParsPerBand,
233 'instrumentSlopeMinDeltaT': config.instrumentSlopeMinDeltaT,
234 'fitMirrorChromaticity': config.fitMirrorChromaticity,
235 'fitCCDChromaticityDict': dict(config.fitCcdChromaticityDict),
236 'useRepeatabilityForExpGrayCutsDict': dict(config.useRepeatabilityForExpGrayCutsDict),
237 'autoPhotometricCutNSig': config.autoPhotometricCutNSig,
238 'autoHighCutNSig': config.autoHighCutNSig,
239 'deltaAperInnerRadiusArcsec': config.deltaAperInnerRadiusArcsec,
240 'deltaAperOuterRadiusArcsec': config.deltaAperOuterRadiusArcsec,
241 'deltaAperFitMinNgoodObs': config.deltaAperFitMinNgoodObs,
242 'deltaAperFitPerCcdNx': config.deltaAperFitPerCcdNx,
243 'deltaAperFitPerCcdNy': config.deltaAperFitPerCcdNy,
244 'deltaAperFitSpatialNside': config.deltaAperFitSpatialNside,
245 'doComputeDeltaAperExposures': config.doComputeDeltaAperPerVisit,
246 'doComputeDeltaAperStars': config.doComputeDeltaAperPerStar,
247 'doComputeDeltaAperMap': config.doComputeDeltaAperMap,
248 'doComputeDeltaAperPerCcd': config.doComputeDeltaAperPerCcd,
250 'quietMode': config.quietMode,
251 'randomSeed': config.randomSeed,
252 'outputStars':
False,
253 'outputPath': os.path.abspath(
'.'),
256 'resetParameters': resetFitParameters,
258 'outputFgcmcalZpts':
True,
259 'outputZeropoints': outputZeropoints}
266 Translate the FGCM look-up-table into an fgcm-compatible object
270 lutCat: `lsst.afw.table.BaseCatalog`
271 Catalog describing the FGCM look-up table
272 physicalFilterMap: `dict`
273 Physical filter to band mapping
277 fgcmLut: `lsst.fgcm.FgcmLut`
278 Lookup table for FGCM
279 lutIndexVals: `numpy.ndarray`
280 Numpy array with LUT index information for FGCM
281 lutStd: `numpy.ndarray`
282 Numpy array with LUT standard throughput values for FGCM
286 After running this code, it is wise to `del lutCat` to clear the memory.
290 lutFilterNames = np.array(lutCat[0][
'physicalFilters'].split(
','), dtype=
'U')
291 lutStdFilterNames = np.array(lutCat[0][
'stdPhysicalFilters'].split(
','), dtype=
'U')
296 lutIndexVals = np.zeros(1, dtype=[(
'FILTERNAMES', lutFilterNames.dtype.str,
297 lutFilterNames.size),
298 (
'STDFILTERNAMES', lutStdFilterNames.dtype.str,
299 lutStdFilterNames.size),
300 (
'PMB',
'f8', lutCat[0][
'pmb'].size),
301 (
'PMBFACTOR',
'f8', lutCat[0][
'pmbFactor'].size),
302 (
'PMBELEVATION',
'f8'),
303 (
'LAMBDANORM',
'f8'),
304 (
'PWV',
'f8', lutCat[0][
'pwv'].size),
305 (
'O3',
'f8', lutCat[0][
'o3'].size),
306 (
'TAU',
'f8', lutCat[0][
'tau'].size),
307 (
'ALPHA',
'f8', lutCat[0][
'alpha'].size),
308 (
'ZENITH',
'f8', lutCat[0][
'zenith'].size),
311 lutIndexVals[
'FILTERNAMES'][:] = lutFilterNames
312 lutIndexVals[
'STDFILTERNAMES'][:] = lutStdFilterNames
313 lutIndexVals[
'PMB'][:] = lutCat[0][
'pmb']
314 lutIndexVals[
'PMBFACTOR'][:] = lutCat[0][
'pmbFactor']
315 lutIndexVals[
'PMBELEVATION'] = lutCat[0][
'pmbElevation']
316 lutIndexVals[
'LAMBDANORM'] = lutCat[0][
'lambdaNorm']
317 lutIndexVals[
'PWV'][:] = lutCat[0][
'pwv']
318 lutIndexVals[
'O3'][:] = lutCat[0][
'o3']
319 lutIndexVals[
'TAU'][:] = lutCat[0][
'tau']
320 lutIndexVals[
'ALPHA'][:] = lutCat[0][
'alpha']
321 lutIndexVals[
'ZENITH'][:] = lutCat[0][
'zenith']
322 lutIndexVals[
'NCCD'] = lutCat[0][
'nCcd']
325 lutStd = np.zeros(1, dtype=[(
'PMBSTD',
'f8'),
331 (
'LAMBDARANGE',
'f8', 2),
332 (
'LAMBDASTEP',
'f8'),
333 (
'LAMBDASTD',
'f8', lutFilterNames.size),
334 (
'LAMBDASTDFILTER',
'f8', lutStdFilterNames.size),
335 (
'I0STD',
'f8', lutFilterNames.size),
336 (
'I1STD',
'f8', lutFilterNames.size),
337 (
'I10STD',
'f8', lutFilterNames.size),
338 (
'I2STD',
'f8', lutFilterNames.size),
339 (
'LAMBDAB',
'f8', lutFilterNames.size),
340 (
'ATMLAMBDA',
'f8', lutCat[0][
'atmLambda'].size),
341 (
'ATMSTDTRANS',
'f8', lutCat[0][
'atmStdTrans'].size)])
342 lutStd[
'PMBSTD'] = lutCat[0][
'pmbStd']
343 lutStd[
'PWVSTD'] = lutCat[0][
'pwvStd']
344 lutStd[
'O3STD'] = lutCat[0][
'o3Std']
345 lutStd[
'TAUSTD'] = lutCat[0][
'tauStd']
346 lutStd[
'ALPHASTD'] = lutCat[0][
'alphaStd']
347 lutStd[
'ZENITHSTD'] = lutCat[0][
'zenithStd']
348 lutStd[
'LAMBDARANGE'][:] = lutCat[0][
'lambdaRange'][:]
349 lutStd[
'LAMBDASTEP'] = lutCat[0][
'lambdaStep']
350 lutStd[
'LAMBDASTD'][:] = lutCat[0][
'lambdaStd']
351 lutStd[
'LAMBDASTDFILTER'][:] = lutCat[0][
'lambdaStdFilter']
352 lutStd[
'I0STD'][:] = lutCat[0][
'i0Std']
353 lutStd[
'I1STD'][:] = lutCat[0][
'i1Std']
354 lutStd[
'I10STD'][:] = lutCat[0][
'i10Std']
355 lutStd[
'I2STD'][:] = lutCat[0][
'i2Std']
356 lutStd[
'LAMBDAB'][:] = lutCat[0][
'lambdaB']
357 lutStd[
'ATMLAMBDA'][:] = lutCat[0][
'atmLambda'][:]
358 lutStd[
'ATMSTDTRANS'][:] = lutCat[0][
'atmStdTrans'][:]
360 lutTypes = [row[
'luttype']
for row
in lutCat]
363 lutFlat = np.zeros(lutCat[0][
'lut'].size, dtype=[(
'I0',
'f4'),
366 lutFlat[
'I0'][:] = lutCat[lutTypes.index(
'I0')][
'lut'][:]
367 lutFlat[
'I1'][:] = lutCat[lutTypes.index(
'I1')][
'lut'][:]
369 lutDerivFlat = np.zeros(lutCat[0][
'lut'].size, dtype=[(
'D_LNPWV',
'f4'),
373 (
'D_SECZENITH',
'f4'),
374 (
'D_LNPWV_I1',
'f4'),
376 (
'D_LNTAU_I1',
'f4'),
377 (
'D_ALPHA_I1',
'f4'),
378 (
'D_SECZENITH_I1',
'f4')])
380 for name
in lutDerivFlat.dtype.names:
381 lutDerivFlat[name][:] = lutCat[lutTypes.index(name)][
'lut'][:]
388 fgcmLut = fgcm.FgcmLUT(lutIndexVals, lutFlat, lutDerivFlat, lutStd,
389 filterToBand=physicalFilterMap)
391 return fgcmLut, lutIndexVals, lutStd