13 from lsst.verify
import Job, Measurement
18 from .dataIds
import PerTractCcdDataIdContainer
23 __all__ = [
"JointcalConfig",
"JointcalRunner",
"JointcalTask"]
25 Photometry = collections.namedtuple(
'Photometry', (
'fit',
'model'))
26 Astrometry = collections.namedtuple(
'Astrometry', (
'fit',
'model',
'sky_to_tan_projection'))
31 meas = Measurement(job.metrics[name], value)
32 job.measurements.insert(meas)
36 """Subclass of TaskRunner for jointcalTask 38 jointcalTask.run() takes a number of arguments, one of which is a list of dataRefs 39 extracted from the command line (whereas most CmdLineTasks' run methods take 40 single dataRef, are are called repeatedly). This class transforms the processed 41 arguments generated by the ArgumentParser into the arguments expected by 44 See pipeBase.TaskRunner for more information. 50 Return a list of tuples per tract, each containing (dataRefs, kwargs). 52 Jointcal operates on lists of dataRefs simultaneously. 54 kwargs[
'profile_jointcal'] = parsedCmd.profile_jointcal
55 kwargs[
'butler'] = parsedCmd.butler
59 for ref
in parsedCmd.id.refList:
60 refListDict.setdefault(ref.dataId[
"tract"], []).append(ref)
62 result = [(refListDict[tract], kwargs)
for tract
in sorted(refListDict.keys())]
70 Arguments for Task.run() 75 if self.doReturnResults is False: 77 - ``exitStatus``: 0 if the task completed successfully, 1 otherwise. 79 if self.doReturnResults is True: 81 - ``result``: the result of calling jointcal.run() 82 - ``exitStatus``: 0 if the task completed successfully, 1 otherwise. 87 dataRefList, kwargs = args
88 butler = kwargs.pop(
'butler')
89 task = self.TaskClass(config=self.config, log=self.log, butler=butler)
92 result = task.run(dataRefList, **kwargs)
93 exitStatus = result.exitStatus
94 job_path = butler.get(
'verify_job_filename')
95 result.job.write(job_path[0])
96 except Exception
as e:
101 eName = type(e).__name__
102 tract = dataRefList[0].dataId[
'tract']
103 task.log.fatal(
"Failed processing tract %s, %s: %s", tract, eName, e)
105 if self.doReturnResults:
106 return pipeBase.Struct(result=result, exitStatus=exitStatus)
108 return pipeBase.Struct(exitStatus=exitStatus)
112 """Config for JointcalTask""" 114 doAstrometry = pexConfig.Field(
115 doc=
"Fit astrometry and write the fitted result.",
119 doPhotometry = pexConfig.Field(
120 doc=
"Fit photometry and write the fitted result.",
124 coaddName = pexConfig.Field(
125 doc=
"Type of coadd, typically deep or goodSeeing",
129 posError = pexConfig.Field(
130 doc=
"Constant term for error on position (in pixel unit)",
135 matchCut = pexConfig.Field(
136 doc=
"Matching radius between fitted and reference stars (arcseconds)",
140 minMeasurements = pexConfig.Field(
141 doc=
"Minimum number of associated measured stars for a fitted star to be included in the fit",
145 minMeasuredStarsPerCcd = pexConfig.Field(
146 doc=
"Minimum number of measuredStars per ccdImage before printing warnings",
150 minRefStarsPerCcd = pexConfig.Field(
151 doc=
"Minimum number of measuredStars per ccdImage before printing warnings",
155 allowLineSearch = pexConfig.Field(
156 doc=
"Allow a line search during minimization, if it is reasonable for the model" 157 " (models with a significant non-linear component, e.g. constrainedPhotometry).",
161 astrometrySimpleOrder = pexConfig.Field(
162 doc=
"Polynomial order for fitting the simple astrometry model.",
166 astrometryChipOrder = pexConfig.Field(
167 doc=
"Order of the per-chip transform for the constrained astrometry model.",
171 astrometryVisitOrder = pexConfig.Field(
172 doc=
"Order of the per-visit transform for the constrained astrometry model.",
176 useInputWcs = pexConfig.Field(
177 doc=
"Use the input calexp WCSs to initialize a SimpleAstrometryModel.",
181 astrometryModel = pexConfig.ChoiceField(
182 doc=
"Type of model to fit to astrometry",
185 allowed={
"simple":
"One polynomial per ccd",
186 "constrained":
"One polynomial per ccd, and one polynomial per visit"}
188 photometryModel = pexConfig.ChoiceField(
189 doc=
"Type of model to fit to photometry",
191 default=
"simpleFlux",
192 allowed={
"simpleFlux":
"One constant zeropoint per ccd and visit",
193 "constrainedFlux":
"Constrained zeropoint per ccd, and one polynomial per visit",
194 "simpleMagnitude":
"One constant zeropoint per ccd and visit"}
196 photometryVisitOrder = pexConfig.Field(
197 doc=
"Order of the per-visit polynomial transform for the constrained photometry model.",
201 photometryDoRankUpdate = pexConfig.Field(
202 doc=
"Do the rank update step during minimization. " 203 "Skipping this can help deal with models that are too non-linear.",
207 astrometryDoRankUpdate = pexConfig.Field(
208 doc=
"Do the rank update step during minimization (should not change the astrometry fit). " 209 "Skipping this can help deal with models that are too non-linear.",
213 outlierRejectSigma = pexConfig.Field(
214 doc=
"How many sigma to reject outliers at during minimization.",
218 maxPhotometrySteps = pexConfig.Field(
219 doc=
"Maximum number of minimize iterations to take when fitting photometry.",
223 maxAstrometrySteps = pexConfig.Field(
224 doc=
"Maximum number of minimize iterations to take when fitting photometry.",
228 astrometryRefObjLoader = pexConfig.ConfigurableField(
229 target=LoadIndexedReferenceObjectsTask,
230 doc=
"Reference object loader for astrometric fit",
232 photometryRefObjLoader = pexConfig.ConfigurableField(
233 target=LoadIndexedReferenceObjectsTask,
234 doc=
"Reference object loader for photometric fit",
236 sourceSelector = sourceSelectorRegistry.makeField(
237 doc=
"How to select sources for cross-matching",
240 writeInitMatrix = pexConfig.Field(
242 doc=
"Write the pre/post-initialization Hessian and gradient to text files, for debugging." 243 "The output files will be of the form 'astrometry_preinit-mat.txt', in the current directory." 244 "Note that these files are the dense versions of the matrix, and so may be very large.",
247 writeChi2ContributionFiles = pexConfig.Field(
249 doc=
"Write initial/final fit files containing the contributions to chi2.",
252 sourceFluxType = pexConfig.Field(
254 doc=
"Source flux field to use in source selection and to get fluxes from the catalog.",
260 sourceSelector.setDefaults()
262 sourceSelector.badFlags.extend([
"slot_Shape_flag"])
268 """Jointly astrometrically and photometrically calibrate a group of images.""" 270 ConfigClass = JointcalConfig
271 RunnerClass = JointcalRunner
272 _DefaultName =
"jointcal" 274 def __init__(self, butler=None, profile_jointcal=False, **kwargs):
276 Instantiate a JointcalTask. 280 butler : lsst.daf.persistence.Butler 281 The butler is passed to the refObjLoader constructor in case it is 282 needed. Ignored if the refObjLoader argument provides a loader directly. 283 Used to initialize the astrometry and photometry refObjLoaders. 284 profile_jointcal : bool 285 set to True to profile different stages of this jointcal run. 287 pipeBase.CmdLineTask.__init__(self, **kwargs)
289 self.makeSubtask(
"sourceSelector")
290 if self.config.doAstrometry:
291 self.makeSubtask(
'astrometryRefObjLoader', butler=butler)
292 if self.config.doPhotometry:
293 self.makeSubtask(
'photometryRefObjLoader', butler=butler)
296 self.
job = Job.load_metrics_package(subset=
'jointcal')
300 def _getConfigName(self):
303 def _getMetadataName(self):
307 def _makeArgumentParser(cls):
308 """Create an argument parser""" 310 parser.add_argument(
"--profile_jointcal", default=
False, action=
"store_true",
311 help=
"Profile steps of jointcal separately.")
312 parser.add_id_argument(
"--id",
"calexp", help=
"data ID, e.g. --id visit=6789 ccd=0..9",
313 ContainerClass=PerTractCcdDataIdContainer)
316 def _build_ccdImage(self, dataRef, associations, jointcalControl):
318 Extract the necessary things from this dataRef to add a new ccdImage. 322 dataRef : lsst.daf.persistence.ButlerDataRef 323 dataRef to extract info from. 324 associations : lsst.jointcal.Associations 325 object to add the info to, to construct a new CcdImage 326 jointcalControl : jointcal.JointcalControl 327 control object for associations management 332 wcs : lsst.afw.geom.SkyWcs 333 the TAN WCS of this image, read from the calexp 335 a key to identify this dataRef by its visit and ccd ids 339 if "visit" in dataRef.dataId.keys():
340 visit = dataRef.dataId[
"visit"]
342 visit = dataRef.getButler().queryMetadata(
"calexp", (
"visit"), dataRef.dataId)[0]
344 src = dataRef.get(
"src", flags=lsst.afw.table.SOURCE_IO_NO_FOOTPRINTS, immediate=
True)
346 visitInfo = dataRef.get(
'calexp_visitInfo')
347 detector = dataRef.get(
'calexp_detector')
348 ccdId = detector.getId()
349 calib = dataRef.get(
'calexp_calib')
350 tanWcs = dataRef.get(
'calexp_wcs')
351 bbox = dataRef.get(
'calexp_bbox')
352 filt = dataRef.get(
'calexp_filter')
353 filterName = filt.getName()
354 fluxMag0 = calib.getFluxMag0()
355 photoCalib = afwImage.PhotoCalib(1.0/fluxMag0[0], fluxMag0[1]/fluxMag0[0]**2, bbox)
357 goodSrc = self.sourceSelector.
run(src)
359 if len(goodSrc.sourceCat) == 0:
360 self.log.warn(
"No sources selected in visit %s ccd %s", visit, ccdId)
362 self.log.info(
"%d sources selected in visit %d ccd %d", len(goodSrc.sourceCat), visit, ccdId)
363 associations.createCcdImage(goodSrc.sourceCat,
374 Result = collections.namedtuple(
'Result_from_build_CcdImage', (
'wcs',
'key',
'filter'))
375 Key = collections.namedtuple(
'Key', (
'visit',
'ccd'))
376 return Result(tanWcs, Key(visit, ccdId), filterName)
379 def run(self, dataRefs, profile_jointcal=False):
381 Jointly calibrate the astrometry and photometry across a set of images. 385 dataRefs : list of lsst.daf.persistence.ButlerDataRef 386 List of data references to the exposures to be fit. 387 profile_jointcal : bool 388 Profile the individual steps of jointcal. 394 * dataRefs: the provided data references that were fit (with updated WCSs) 395 * oldWcsList: the original WCS from each dataRef 396 * metrics: dictionary of internally-computed metrics for testing/validation. 398 if len(dataRefs) == 0:
399 raise ValueError(
'Need a non-empty list of data references!')
403 sourceFluxField =
"slot_%sFlux" % (self.config.sourceFluxType,)
407 visit_ccd_to_dataRef = {}
410 load_cat_prof_file =
'jointcal_build_ccdImage.prof' if profile_jointcal
else '' 411 with pipeBase.cmdLineTask.profile(load_cat_prof_file):
414 camera = dataRefs[0].get(
'camera', immediate=
True)
418 oldWcsList.append(result.wcs)
419 visit_ccd_to_dataRef[result.key] = ref
420 filters.append(result.filter)
421 filters = collections.Counter(filters)
423 associations.computeCommonTangentPoint()
428 bbox = associations.getRaDecBBox()
430 bboxCenter = bbox.getCenter()
431 center = afwGeom.SpherePoint(bboxCenter[0], bboxCenter[1], afwGeom.degrees)
432 bboxMax = bbox.getMax()
433 corner = afwGeom.SpherePoint(bboxMax[0], bboxMax[1], afwGeom.degrees)
434 radius = center.separation(corner).asRadians()
439 raise RuntimeError(
"astrometry_net_data is not setup")
442 defaultFilter = filters.most_common(1)[0][0]
443 self.log.debug(
"Using %s band for reference flux", defaultFilter)
446 tract = dataRefs[0].dataId[
'tract']
448 if self.config.doAstrometry:
451 refObjLoader=self.astrometryRefObjLoader,
453 profile_jointcal=profile_jointcal,
459 if self.config.doPhotometry:
462 refObjLoader=self.photometryRefObjLoader,
464 profile_jointcal=profile_jointcal,
467 reject_bad_fluxes=
True)
472 return pipeBase.Struct(dataRefs=dataRefs,
473 oldWcsList=oldWcsList,
475 exitStatus=exitStatus)
477 def _do_load_refcat_and_fit(self, associations, defaultFilter, center, radius,
478 name="", refObjLoader=None, filters=[], fit_function=None,
479 tract=None, profile_jointcal=False, match_cut=3.0,
480 reject_bad_fluxes=False):
481 """Load reference catalog, perform the fit, and return the result. 485 associations : lsst.jointcal.Associations 486 The star/reference star associations to fit. 488 filter to load from reference catalog. 489 center : lsst.afw.geom.SpherePoint 490 ICRS center of field to load from reference catalog. 491 radius : lsst.afw.geom.Angle 492 On-sky radius to load from reference catalog. 494 Name of thing being fit: "Astrometry" or "Photometry". 495 refObjLoader : lsst.meas.algorithms.LoadReferenceObjectsTask 496 Reference object loader to load from for fit. 497 filters : list of str, optional 498 List of filters to load from the reference catalog. 499 fit_function : function 500 function to call to perform fit (takes associations object). 502 Name of tract currently being fit. 503 profile_jointcal : bool, optional 504 Separately profile the fitting step. 505 match_cut : float, optional 506 Radius in arcseconds to find cross-catalog matches to during 507 associations.associateCatalogs. 508 reject_bad_fluxes : bool, optional 509 Reject refCat sources with NaN/inf flux or NaN/0 fluxErr. 513 Result of `fit_function()` 515 self.log.info(
"====== Now processing %s...", name)
518 associations.associateCatalogs(match_cut)
520 associations.fittedStarListSize())
522 skyCircle = refObjLoader.loadSkyCircle(center,
523 afwGeom.Angle(radius, afwGeom.radians),
527 if not skyCircle.refCat.isContiguous():
528 refCat = skyCircle.refCat.copy(deep=
True)
530 refCat = skyCircle.refCat
537 filtKeys = lsst.meas.algorithms.getRefFluxKeys(refCat.schema, filt)
538 refFluxes[filt] = refCat.get(filtKeys[0])
539 refFluxErrs[filt] = refCat.get(filtKeys[1])
541 associations.collectRefStars(refCat, self.config.matchCut*afwGeom.arcseconds,
542 skyCircle.fluxField, refFluxes, refFluxErrs, reject_bad_fluxes)
544 associations.refStarListSize())
546 associations.prepareFittedStars(self.config.minMeasurements)
550 associations.nFittedStarsWithAssociatedRefStar())
552 associations.fittedStarListSize())
554 associations.nCcdImagesValidForFit())
556 load_cat_prof_file =
'jointcal_fit_%s.prof'%name
if profile_jointcal
else '' 557 dataName =
"{}_{}".format(tract, defaultFilter)
558 with pipeBase.cmdLineTask.profile(load_cat_prof_file):
559 result = fit_function(associations, dataName)
562 if self.config.writeChi2ContributionFiles:
563 baseName =
"{}_final_chi2-{}.csv".format(name, dataName)
564 result.fit.saveChi2Contributions(baseName)
568 def _check_star_lists(self, associations, name):
570 if associations.nCcdImagesValidForFit() == 0:
571 raise RuntimeError(
'No images in the ccdImageList!')
572 if associations.fittedStarListSize() == 0:
573 raise RuntimeError(
'No stars in the {} fittedStarList!'.format(name))
574 if associations.refStarListSize() == 0:
575 raise RuntimeError(
'No stars in the {} reference star list!'.format(name))
577 def _fit_photometry(self, associations, dataName=None):
579 Fit the photometric data. 583 associations : lsst.jointcal.Associations 584 The star/reference star associations to fit. 586 Name of the data being processed (e.g. "1234_HSC-Y"), for 587 identifying debugging files. 592 fit : lsst.jointcal.PhotometryFit 593 The photometric fitter used to perform the fit. 594 model : lsst.jointcal.PhotometryModel 595 The photometric model that was fit. 597 self.log.info(
"=== Starting photometric fitting...")
600 if self.config.photometryModel ==
"constrainedFlux":
603 visitOrder=self.config.photometryVisitOrder)
605 doLineSearch = self.config.allowLineSearch
606 elif self.config.photometryModel ==
"simpleFlux":
609 elif self.config.photometryModel ==
"simpleMagnitude":
614 chi2 = fit.computeChi2()
617 if self.config.writeChi2ContributionFiles:
618 baseName =
"photometry_initial_chi2-{}.csv".format(dataName)
619 fit.saveChi2Contributions(baseName)
621 if not np.isfinite(chi2.chi2):
622 raise FloatingPointError(
'Initial chi2 is invalid: %s'%chi2)
623 self.log.info(
"Initialized: %s", str(chi2))
626 dumpMatrixFile =
"photometry_preinit" if self.config.writeInitMatrix
else "" 627 if self.config.photometryModel ==
"constrained":
630 fit.minimize(
"ModelVisit", dumpMatrixFile=dumpMatrixFile)
631 chi2 = fit.computeChi2()
632 self.log.info(str(chi2))
634 fit.minimize(
"Model", doLineSearch=doLineSearch, dumpMatrixFile=dumpMatrixFile)
635 chi2 = fit.computeChi2()
636 self.log.info(str(chi2))
637 fit.minimize(
"Fluxes")
638 chi2 = fit.computeChi2()
639 self.log.info(str(chi2))
640 fit.minimize(
"Model Fluxes", doLineSearch=doLineSearch)
641 chi2 = fit.computeChi2()
642 if not np.isfinite(chi2.chi2):
643 raise FloatingPointError(
'Pre-iteration chi2 is invalid: %s'%chi2)
644 self.log.info(
"Fit prepared with %s", str(chi2))
646 model.freezeErrorTransform()
647 self.log.debug(
"Photometry error scales are frozen.")
652 self.config.maxPhotometrySteps,
655 doRankUpdate=self.config.photometryDoRankUpdate,
656 doLineSearch=doLineSearch)
662 def _fit_astrometry(self, associations, dataName=None):
664 Fit the astrometric data. 668 associations : lsst.jointcal.Associations 669 The star/reference star associations to fit. 671 Name of the data being processed (e.g. "1234_HSC-Y"), for 672 identifying debugging files. 677 fit : lsst.jointcal.AstrometryFit 678 The astrometric fitter used to perform the fit. 679 model : lsst.jointcal.AstrometryModel 680 The astrometric model that was fit. 681 sky_to_tan_projection : lsst.jointcal.ProjectionHandler 682 The model for the sky to tangent plane projection that was used in the fit. 685 self.log.info(
"=== Starting astrometric fitting...")
687 associations.deprojectFittedStars()
694 if self.config.astrometryModel ==
"constrained":
696 sky_to_tan_projection,
697 chipOrder=self.config.astrometryChipOrder,
698 visitOrder=self.config.astrometryVisitOrder)
699 elif self.config.astrometryModel ==
"simple":
701 sky_to_tan_projection,
702 self.config.useInputWcs,
704 order=self.config.astrometrySimpleOrder)
707 chi2 = fit.computeChi2()
710 if self.config.writeChi2ContributionFiles:
711 baseName =
"astrometry_initial_chi2-{}.csv".format(dataName)
712 fit.saveChi2Contributions(baseName)
714 if not np.isfinite(chi2.chi2):
715 raise FloatingPointError(
'Initial chi2 is invalid: %s'%chi2)
716 self.log.info(
"Initialized: %s", str(chi2))
717 dumpMatrixFile =
"astrometry_preinit" if self.config.writeInitMatrix
else "" 720 if self.config.astrometryModel ==
"constrained":
721 fit.minimize(
"DistortionsVisit", dumpMatrixFile=dumpMatrixFile)
722 chi2 = fit.computeChi2()
723 self.log.info(str(chi2))
725 fit.minimize(
"Distortions", dumpMatrixFile=dumpMatrixFile)
726 chi2 = fit.computeChi2()
727 self.log.info(str(chi2))
728 fit.minimize(
"Positions")
729 chi2 = fit.computeChi2()
730 self.log.info(str(chi2))
731 fit.minimize(
"Distortions Positions")
732 chi2 = fit.computeChi2()
733 self.log.info(str(chi2))
734 if not np.isfinite(chi2.chi2):
735 raise FloatingPointError(
'Pre-iteration chi2 is invalid: %s'%chi2)
736 self.log.info(
"Fit prepared with %s", str(chi2))
741 self.config.maxAstrometrySteps,
743 "Distortions Positions",
744 doRankUpdate=self.config.astrometryDoRankUpdate)
749 return Astrometry(fit, model, sky_to_tan_projection)
751 def _check_stars(self, associations):
752 """Count measured and reference stars per ccd and warn/log them.""" 753 for ccdImage
in associations.getCcdImageList():
754 nMeasuredStars, nRefStars = ccdImage.countStars()
755 self.log.debug(
"ccdImage %s has %s measured and %s reference stars",
756 ccdImage.getName(), nMeasuredStars, nRefStars)
757 if nMeasuredStars < self.config.minMeasuredStarsPerCcd:
758 self.log.warn(
"ccdImage %s has only %s measuredStars (desired %s)",
759 ccdImage.getName(), nMeasuredStars, self.config.minMeasuredStarsPerCcd)
760 if nRefStars < self.config.minRefStarsPerCcd:
761 self.log.warn(
"ccdImage %s has only %s RefStars (desired %s)",
762 ccdImage.getName(), nRefStars, self.config.minRefStarsPerCcd)
764 def _iterate_fit(self, associations, fit, model, max_steps, name, whatToFit, doRankUpdate=True,
766 """Run fit.minimize up to max_steps times, returning the final chi2.""" 768 dumpMatrixFile =
"%s_postinit" % name
if self.config.writeInitMatrix
else "" 769 for i
in range(max_steps):
771 r = fit.minimize(whatToFit,
772 self.config.outlierRejectSigma,
773 doRankUpdate=doRankUpdate,
774 doLineSearch=doLineSearch,
775 dumpMatrixFile=dumpMatrixFile)
777 chi2 = fit.computeChi2()
779 if not np.isfinite(chi2.chi2):
780 raise FloatingPointError(
'Fit iteration chi2 is invalid: %s'%chi2)
781 self.log.info(str(chi2))
782 if r == MinimizeResult.Converged:
784 self.log.debug(
"fit has converged - no more outliers - redo minimization " 785 "one more time in case we have lost accuracy in rank update.")
787 r = fit.minimize(whatToFit, 5)
788 chi2 = fit.computeChi2()
789 self.log.info(
"Fit completed with: %s", str(chi2))
791 elif r == MinimizeResult.Chi2Increased:
792 self.log.warn(
"still some ouliers but chi2 increases - retry")
793 elif r == MinimizeResult.Failed:
794 raise RuntimeError(
"Chi2 minimization failure, cannot complete fit.")
796 raise RuntimeError(
"Unxepected return code from minimize().")
798 self.log.error(
"%s failed to converge after %d steps"%(name, max_steps))
802 def _write_astrometry_results(self, associations, model, visit_ccd_to_dataRef):
804 Write the fitted astrometric results to a new 'jointcal_wcs' dataRef. 808 associations : lsst.jointcal.Associations 809 The star/reference star associations to fit. 810 model : lsst.jointcal.AstrometryModel 811 The astrometric model that was fit. 812 visit_ccd_to_dataRef : dict of Key: lsst.daf.persistence.ButlerDataRef 813 dict of ccdImage identifiers to dataRefs that were fit 816 ccdImageList = associations.getCcdImageList()
817 for ccdImage
in ccdImageList:
820 visit = ccdImage.visit
821 dataRef = visit_ccd_to_dataRef[(visit, ccd)]
822 self.log.info(
"Updating WCS for visit: %d, ccd: %d", visit, ccd)
823 skyWcs = model.makeSkyWcs(ccdImage)
825 dataRef.put(skyWcs,
'jointcal_wcs')
826 except pexExceptions.Exception
as e:
827 self.log.fatal(
'Failed to write updated Wcs: %s', str(e))
830 def _write_photometry_results(self, associations, model, visit_ccd_to_dataRef):
832 Write the fitted photometric results to a new 'jointcal_photoCalib' dataRef. 836 associations : lsst.jointcal.Associations 837 The star/reference star associations to fit. 838 model : lsst.jointcal.PhotometryModel 839 The photoometric model that was fit. 840 visit_ccd_to_dataRef : dict of Key: lsst.daf.persistence.ButlerDataRef 841 dict of ccdImage identifiers to dataRefs that were fit 844 ccdImageList = associations.getCcdImageList()
845 for ccdImage
in ccdImageList:
848 visit = ccdImage.visit
849 dataRef = visit_ccd_to_dataRef[(visit, ccd)]
850 self.log.info(
"Updating PhotoCalib for visit: %d, ccd: %d", visit, ccd)
851 photoCalib = model.toPhotoCalib(ccdImage)
853 dataRef.put(photoCalib,
'jointcal_photoCalib')
854 except pexExceptions.Exception
as e:
855 self.log.fatal(
'Failed to write updated PhotoCalib: %s', str(e))
def _build_ccdImage(self, dataRef, associations, jointcalControl)
def _fit_photometry(self, associations, dataName=None)
def getTargetList(parsedCmd, kwargs)
def _fit_astrometry(self, associations, dataName=None)
def _check_star_lists(self, associations, name)
def _iterate_fit(self, associations, fit, model, max_steps, name, whatToFit, doRankUpdate=True, doLineSearch=False)
The class that implements the relations between MeasuredStar and FittedStar.
A projection handler in which all CCDs from the same visit have the same tangent point.
std::string getPackageDir(std::string const &packageName)
this is the model used to fit independent CCDs, meaning that there is no instrument model...
def _write_photometry_results(self, associations, model, visit_ccd_to_dataRef)
def _check_stars(self, associations)
Class that handles the photometric least squares problem.
Class that handles the astrometric least squares problem.
Photometry model with constraints, .
def add_measurement(job, name, value)
def _do_load_refcat_and_fit(self, associations, defaultFilter, center, radius, name="", refObjLoader=None, filters=[], fit_function=None, tract=None, profile_jointcal=False, match_cut=3.0, reject_bad_fluxes=False)
This is the model used to fit mappings as the combination of a transformation depending on the chip n...
def _write_astrometry_results(self, associations, model, visit_ccd_to_dataRef)
def run(self, dataRefs, profile_jointcal=False)
def __init__(self, butler=None, profile_jointcal=False, kwargs)