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",
192 allowed={
"simple":
"One constant zeropoint per ccd and visit",
193 "constrained":
"Constrained zeropoint per ccd, and one polynomial per visit"}
195 photometryVisitOrder = pexConfig.Field(
196 doc=
"Order of the per-visit polynomial transform for the constrained photometry model.",
200 photometryDoRankUpdate = pexConfig.Field(
201 doc=
"Do the rank update step during minimization. " 202 "Skipping this can help deal with models that are too non-linear.",
206 astrometryDoRankUpdate = pexConfig.Field(
207 doc=
"Do the rank update step during minimization (should not change the astrometry fit). " 208 "Skipping this can help deal with models that are too non-linear.",
212 outlierRejectSigma = pexConfig.Field(
213 doc=
"How many sigma to reject outliers at during minimization.",
217 maxPhotometrySteps = pexConfig.Field(
218 doc=
"Maximum number of minimize iterations to take when fitting photometry.",
222 maxAstrometrySteps = pexConfig.Field(
223 doc=
"Maximum number of minimize iterations to take when fitting photometry.",
227 astrometryRefObjLoader = pexConfig.ConfigurableField(
228 target=LoadIndexedReferenceObjectsTask,
229 doc=
"Reference object loader for astrometric fit",
231 photometryRefObjLoader = pexConfig.ConfigurableField(
232 target=LoadIndexedReferenceObjectsTask,
233 doc=
"Reference object loader for photometric fit",
235 sourceSelector = sourceSelectorRegistry.makeField(
236 doc=
"How to select sources for cross-matching",
239 writeInitMatrix = pexConfig.Field(
241 doc=
"Write the pre/post-initialization Hessian and gradient to text files, for debugging." 242 "The output files will be of the form 'astrometry_preinit-mat.txt', in the current directory." 243 "Note that these files are the dense versions of the matrix, and so may be very large.",
246 writeChi2ContributionFiles = pexConfig.Field(
248 doc=
"Write initial/final fit files containing the contributions to chi2.",
251 sourceFluxType = pexConfig.Field(
253 doc=
"Source flux field to use in source selection and to get fluxes from the catalog.",
259 sourceSelector.setDefaults()
261 sourceSelector.badFlags.extend([
"slot_Shape_flag"])
267 """Jointly astrometrically and photometrically calibrate a group of images.""" 269 ConfigClass = JointcalConfig
270 RunnerClass = JointcalRunner
271 _DefaultName =
"jointcal" 273 def __init__(self, butler=None, profile_jointcal=False, **kwargs):
275 Instantiate a JointcalTask. 279 butler : lsst.daf.persistence.Butler 280 The butler is passed to the refObjLoader constructor in case it is 281 needed. Ignored if the refObjLoader argument provides a loader directly. 282 Used to initialize the astrometry and photometry refObjLoaders. 283 profile_jointcal : bool 284 set to True to profile different stages of this jointcal run. 286 pipeBase.CmdLineTask.__init__(self, **kwargs)
288 self.makeSubtask(
"sourceSelector")
289 if self.config.doAstrometry:
290 self.makeSubtask(
'astrometryRefObjLoader', butler=butler)
291 if self.config.doPhotometry:
292 self.makeSubtask(
'photometryRefObjLoader', butler=butler)
295 self.
job = Job.load_metrics_package(subset=
'jointcal')
299 def _getConfigName(self):
302 def _getMetadataName(self):
306 def _makeArgumentParser(cls):
307 """Create an argument parser""" 309 parser.add_argument(
"--profile_jointcal", default=
False, action=
"store_true",
310 help=
"Profile steps of jointcal separately.")
311 parser.add_id_argument(
"--id",
"calexp", help=
"data ID, e.g. --id visit=6789 ccd=0..9",
312 ContainerClass=PerTractCcdDataIdContainer)
315 def _build_ccdImage(self, dataRef, associations, jointcalControl):
317 Extract the necessary things from this dataRef to add a new ccdImage. 321 dataRef : lsst.daf.persistence.ButlerDataRef 322 dataRef to extract info from. 323 associations : lsst.jointcal.Associations 324 object to add the info to, to construct a new CcdImage 325 jointcalControl : jointcal.JointcalControl 326 control object for associations management 331 wcs : lsst.afw.geom.SkyWcs 332 the TAN WCS of this image, read from the calexp 334 a key to identify this dataRef by its visit and ccd ids 338 if "visit" in dataRef.dataId.keys():
339 visit = dataRef.dataId[
"visit"]
341 visit = dataRef.getButler().queryMetadata(
"calexp", (
"visit"), dataRef.dataId)[0]
343 src = dataRef.get(
"src", flags=lsst.afw.table.SOURCE_IO_NO_FOOTPRINTS, immediate=
True)
345 visitInfo = dataRef.get(
'calexp_visitInfo')
346 detector = dataRef.get(
'calexp_detector')
347 ccdId = detector.getId()
348 calib = dataRef.get(
'calexp_calib')
349 tanWcs = dataRef.get(
'calexp_wcs')
350 bbox = dataRef.get(
'calexp_bbox')
351 filt = dataRef.get(
'calexp_filter')
352 filterName = filt.getName()
353 fluxMag0 = calib.getFluxMag0()
354 photoCalib = afwImage.PhotoCalib(1.0/fluxMag0[0], fluxMag0[1]/fluxMag0[0]**2, bbox)
356 goodSrc = self.sourceSelector.
run(src)
358 if len(goodSrc.sourceCat) == 0:
359 self.log.warn(
"No sources selected in visit %s ccd %s", visit, ccdId)
361 self.log.info(
"%d sources selected in visit %d ccd %d", len(goodSrc.sourceCat), visit, ccdId)
362 associations.createCcdImage(goodSrc.sourceCat,
373 Result = collections.namedtuple(
'Result_from_build_CcdImage', (
'wcs',
'key',
'filter'))
374 Key = collections.namedtuple(
'Key', (
'visit',
'ccd'))
375 return Result(tanWcs, Key(visit, ccdId), filterName)
378 def run(self, dataRefs, profile_jointcal=False):
380 Jointly calibrate the astrometry and photometry across a set of images. 384 dataRefs : list of lsst.daf.persistence.ButlerDataRef 385 List of data references to the exposures to be fit. 386 profile_jointcal : bool 387 Profile the individual steps of jointcal. 393 * dataRefs: the provided data references that were fit (with updated WCSs) 394 * oldWcsList: the original WCS from each dataRef 395 * metrics: dictionary of internally-computed metrics for testing/validation. 397 if len(dataRefs) == 0:
398 raise ValueError(
'Need a non-empty list of data references!')
402 sourceFluxField =
"slot_%sFlux" % (self.config.sourceFluxType,)
406 visit_ccd_to_dataRef = {}
409 load_cat_prof_file =
'jointcal_build_ccdImage.prof' if profile_jointcal
else '' 410 with pipeBase.cmdLineTask.profile(load_cat_prof_file):
413 camera = dataRefs[0].get(
'camera', immediate=
True)
417 oldWcsList.append(result.wcs)
418 visit_ccd_to_dataRef[result.key] = ref
419 filters.append(result.filter)
420 filters = collections.Counter(filters)
422 associations.computeCommonTangentPoint()
427 bbox = associations.getRaDecBBox()
429 bboxCenter = bbox.getCenter()
430 center = afwGeom.SpherePoint(bboxCenter[0], bboxCenter[1], afwGeom.degrees)
431 bboxMax = bbox.getMax()
432 corner = afwGeom.SpherePoint(bboxMax[0], bboxMax[1], afwGeom.degrees)
433 radius = center.separation(corner).asRadians()
438 raise RuntimeError(
"astrometry_net_data is not setup")
441 defaultFilter = filters.most_common(1)[0][0]
442 self.log.debug(
"Using %s band for reference flux", defaultFilter)
445 tract = dataRefs[0].dataId[
'tract']
447 if self.config.doAstrometry:
450 refObjLoader=self.astrometryRefObjLoader,
452 profile_jointcal=profile_jointcal,
458 if self.config.doPhotometry:
461 refObjLoader=self.photometryRefObjLoader,
463 profile_jointcal=profile_jointcal,
466 reject_bad_fluxes=
True)
471 return pipeBase.Struct(dataRefs=dataRefs,
472 oldWcsList=oldWcsList,
474 exitStatus=exitStatus)
476 def _do_load_refcat_and_fit(self, associations, defaultFilter, center, radius,
477 name="", refObjLoader=None, filters=[], fit_function=None,
478 tract=None, profile_jointcal=False, match_cut=3.0,
479 reject_bad_fluxes=False):
480 """Load reference catalog, perform the fit, and return the result. 484 associations : lsst.jointcal.Associations 485 The star/reference star associations to fit. 487 filter to load from reference catalog. 488 center : lsst.afw.geom.SpherePoint 489 ICRS center of field to load from reference catalog. 490 radius : lsst.afw.geom.Angle 491 On-sky radius to load from reference catalog. 493 Name of thing being fit: "Astrometry" or "Photometry". 494 refObjLoader : lsst.meas.algorithms.LoadReferenceObjectsTask 495 Reference object loader to load from for fit. 496 filters : list of str, optional 497 List of filters to load from the reference catalog. 498 fit_function : function 499 function to call to perform fit (takes associations object). 501 Name of tract currently being fit. 502 profile_jointcal : bool, optional 503 Separately profile the fitting step. 504 match_cut : float, optional 505 Radius in arcseconds to find cross-catalog matches to during 506 associations.associateCatalogs. 507 reject_bad_fluxes : bool, optional 508 Reject refCat sources with NaN/inf flux or NaN/0 fluxErr. 512 Result of `fit_function()` 514 self.log.info(
"====== Now processing %s...", name)
517 associations.associateCatalogs(match_cut)
519 associations.fittedStarListSize())
521 skyCircle = refObjLoader.loadSkyCircle(center,
522 afwGeom.Angle(radius, afwGeom.radians),
526 if not skyCircle.refCat.isContiguous():
527 refCat = skyCircle.refCat.copy(deep=
True)
529 refCat = skyCircle.refCat
536 filtKeys = lsst.meas.algorithms.getRefFluxKeys(refCat.schema, filt)
537 refFluxes[filt] = refCat.get(filtKeys[0])
538 refFluxErrs[filt] = refCat.get(filtKeys[1])
540 associations.collectRefStars(refCat, self.config.matchCut*afwGeom.arcseconds,
541 skyCircle.fluxField, refFluxes, refFluxErrs, reject_bad_fluxes)
543 associations.refStarListSize())
545 associations.prepareFittedStars(self.config.minMeasurements)
549 associations.nFittedStarsWithAssociatedRefStar())
551 associations.fittedStarListSize())
553 associations.nCcdImagesValidForFit())
555 load_cat_prof_file =
'jointcal_fit_%s.prof'%name
if profile_jointcal
else '' 556 dataName =
"{}_{}".format(tract, defaultFilter)
557 with pipeBase.cmdLineTask.profile(load_cat_prof_file):
558 result = fit_function(associations, dataName)
561 if self.config.writeChi2ContributionFiles:
562 baseName =
"{}_final_chi2-{}.csv".format(name, dataName)
563 result.fit.saveChi2Contributions(baseName)
567 def _check_star_lists(self, associations, name):
569 if associations.nCcdImagesValidForFit() == 0:
570 raise RuntimeError(
'No images in the ccdImageList!')
571 if associations.fittedStarListSize() == 0:
572 raise RuntimeError(
'No stars in the {} fittedStarList!'.format(name))
573 if associations.refStarListSize() == 0:
574 raise RuntimeError(
'No stars in the {} reference star list!'.format(name))
576 def _fit_photometry(self, associations, dataName=None):
578 Fit the photometric data. 582 associations : lsst.jointcal.Associations 583 The star/reference star associations to fit. 585 Name of the data being processed (e.g. "1234_HSC-Y"), for 586 identifying debugging files. 591 fit : lsst.jointcal.PhotometryFit 592 The photometric fitter used to perform the fit. 593 model : lsst.jointcal.PhotometryModel 594 The photometric model that was fit. 596 self.log.info(
"=== Starting photometric fitting...")
599 if self.config.photometryModel ==
"constrained":
602 visitOrder=self.config.photometryVisitOrder)
604 doLineSearch = self.config.allowLineSearch
605 elif self.config.photometryModel ==
"simple":
610 chi2 = fit.computeChi2()
613 if self.config.writeChi2ContributionFiles:
614 baseName =
"photometry_initial_chi2-{}.csv".format(dataName)
615 fit.saveChi2Contributions(baseName)
617 if not np.isfinite(chi2.chi2):
618 raise FloatingPointError(
'Initial chi2 is invalid: %s'%chi2)
619 self.log.info(
"Initialized: %s", str(chi2))
622 dumpMatrixFile =
"photometry_preinit" if self.config.writeInitMatrix
else "" 623 if self.config.photometryModel ==
"constrained":
626 fit.minimize(
"ModelVisit", dumpMatrixFile=dumpMatrixFile)
627 chi2 = fit.computeChi2()
628 self.log.info(str(chi2))
630 fit.minimize(
"Model", doLineSearch=doLineSearch, dumpMatrixFile=dumpMatrixFile)
631 chi2 = fit.computeChi2()
632 self.log.info(str(chi2))
633 fit.minimize(
"Fluxes")
634 chi2 = fit.computeChi2()
635 self.log.info(str(chi2))
636 fit.minimize(
"Model Fluxes", doLineSearch=doLineSearch)
637 chi2 = fit.computeChi2()
638 if not np.isfinite(chi2.chi2):
639 raise FloatingPointError(
'Pre-iteration chi2 is invalid: %s'%chi2)
640 self.log.info(
"Fit prepared with %s", str(chi2))
642 model.freezeErrorTransform()
643 self.log.debug(
"Photometry error scales are frozen.")
648 self.config.maxPhotometrySteps,
651 doRankUpdate=self.config.photometryDoRankUpdate,
652 doLineSearch=doLineSearch)
658 def _fit_astrometry(self, associations, dataName=None):
660 Fit the astrometric data. 664 associations : lsst.jointcal.Associations 665 The star/reference star associations to fit. 667 Name of the data being processed (e.g. "1234_HSC-Y"), for 668 identifying debugging files. 673 fit : lsst.jointcal.AstrometryFit 674 The astrometric fitter used to perform the fit. 675 model : lsst.jointcal.AstrometryModel 676 The astrometric model that was fit. 677 sky_to_tan_projection : lsst.jointcal.ProjectionHandler 678 The model for the sky to tangent plane projection that was used in the fit. 681 self.log.info(
"=== Starting astrometric fitting...")
683 associations.deprojectFittedStars()
690 if self.config.astrometryModel ==
"constrained":
692 sky_to_tan_projection,
693 chipOrder=self.config.astrometryChipOrder,
694 visitOrder=self.config.astrometryVisitOrder)
695 elif self.config.astrometryModel ==
"simple":
697 sky_to_tan_projection,
698 self.config.useInputWcs,
700 order=self.config.astrometrySimpleOrder)
703 chi2 = fit.computeChi2()
706 if self.config.writeChi2ContributionFiles:
707 baseName =
"astrometry_initial_chi2-{}.csv".format(dataName)
708 fit.saveChi2Contributions(baseName)
710 if not np.isfinite(chi2.chi2):
711 raise FloatingPointError(
'Initial chi2 is invalid: %s'%chi2)
712 self.log.info(
"Initialized: %s", str(chi2))
713 dumpMatrixFile =
"astrometry_preinit" if self.config.writeInitMatrix
else "" 716 if self.config.astrometryModel ==
"constrained":
717 fit.minimize(
"DistortionsVisit", dumpMatrixFile=dumpMatrixFile)
718 chi2 = fit.computeChi2()
719 self.log.info(str(chi2))
721 fit.minimize(
"Distortions", dumpMatrixFile=dumpMatrixFile)
722 chi2 = fit.computeChi2()
723 self.log.info(str(chi2))
724 fit.minimize(
"Positions")
725 chi2 = fit.computeChi2()
726 self.log.info(str(chi2))
727 fit.minimize(
"Distortions Positions")
728 chi2 = fit.computeChi2()
729 self.log.info(str(chi2))
730 if not np.isfinite(chi2.chi2):
731 raise FloatingPointError(
'Pre-iteration chi2 is invalid: %s'%chi2)
732 self.log.info(
"Fit prepared with %s", str(chi2))
737 self.config.maxAstrometrySteps,
739 "Distortions Positions",
740 doRankUpdate=self.config.astrometryDoRankUpdate)
745 return Astrometry(fit, model, sky_to_tan_projection)
747 def _check_stars(self, associations):
748 """Count measured and reference stars per ccd and warn/log them.""" 749 for ccdImage
in associations.getCcdImageList():
750 nMeasuredStars, nRefStars = ccdImage.countStars()
751 self.log.debug(
"ccdImage %s has %s measured and %s reference stars",
752 ccdImage.getName(), nMeasuredStars, nRefStars)
753 if nMeasuredStars < self.config.minMeasuredStarsPerCcd:
754 self.log.warn(
"ccdImage %s has only %s measuredStars (desired %s)",
755 ccdImage.getName(), nMeasuredStars, self.config.minMeasuredStarsPerCcd)
756 if nRefStars < self.config.minRefStarsPerCcd:
757 self.log.warn(
"ccdImage %s has only %s RefStars (desired %s)",
758 ccdImage.getName(), nRefStars, self.config.minRefStarsPerCcd)
760 def _iterate_fit(self, associations, fit, model, max_steps, name, whatToFit, doRankUpdate=True,
762 """Run fit.minimize up to max_steps times, returning the final chi2.""" 764 dumpMatrixFile =
"%s_postinit" % name
if self.config.writeInitMatrix
else "" 765 for i
in range(max_steps):
767 r = fit.minimize(whatToFit,
768 self.config.outlierRejectSigma,
769 doRankUpdate=doRankUpdate,
770 doLineSearch=doLineSearch,
771 dumpMatrixFile=dumpMatrixFile)
773 chi2 = fit.computeChi2()
775 if not np.isfinite(chi2.chi2):
776 raise FloatingPointError(
'Fit iteration chi2 is invalid: %s'%chi2)
777 self.log.info(str(chi2))
778 if r == MinimizeResult.Converged:
780 self.log.debug(
"fit has converged - no more outliers - redo minimization " 781 "one more time in case we have lost accuracy in rank update.")
783 r = fit.minimize(whatToFit, 5)
784 chi2 = fit.computeChi2()
785 self.log.info(
"Fit completed with: %s", str(chi2))
787 elif r == MinimizeResult.Chi2Increased:
788 self.log.warn(
"still some ouliers but chi2 increases - retry")
789 elif r == MinimizeResult.Failed:
790 raise RuntimeError(
"Chi2 minimization failure, cannot complete fit.")
792 raise RuntimeError(
"Unxepected return code from minimize().")
794 self.log.error(
"%s failed to converge after %d steps"%(name, max_steps))
798 def _write_astrometry_results(self, associations, model, visit_ccd_to_dataRef):
800 Write the fitted astrometric results to a new 'jointcal_wcs' dataRef. 804 associations : lsst.jointcal.Associations 805 The star/reference star associations to fit. 806 model : lsst.jointcal.AstrometryModel 807 The astrometric model that was fit. 808 visit_ccd_to_dataRef : dict of Key: lsst.daf.persistence.ButlerDataRef 809 dict of ccdImage identifiers to dataRefs that were fit 812 ccdImageList = associations.getCcdImageList()
813 for ccdImage
in ccdImageList:
816 visit = ccdImage.visit
817 dataRef = visit_ccd_to_dataRef[(visit, ccd)]
818 self.log.info(
"Updating WCS for visit: %d, ccd: %d", visit, ccd)
819 skyWcs = model.makeSkyWcs(ccdImage)
821 dataRef.put(skyWcs,
'jointcal_wcs')
822 except pexExceptions.Exception
as e:
823 self.log.fatal(
'Failed to write updated Wcs: %s', str(e))
826 def _write_photometry_results(self, associations, model, visit_ccd_to_dataRef):
828 Write the fitted photometric results to a new 'jointcal_photoCalib' dataRef. 832 associations : lsst.jointcal.Associations 833 The star/reference star associations to fit. 834 model : lsst.jointcal.PhotometryModel 835 The photoometric model that was fit. 836 visit_ccd_to_dataRef : dict of Key: lsst.daf.persistence.ButlerDataRef 837 dict of ccdImage identifiers to dataRefs that were fit 840 ccdImageList = associations.getCcdImageList()
841 for ccdImage
in ccdImageList:
844 visit = ccdImage.visit
845 dataRef = visit_ccd_to_dataRef[(visit, ccd)]
846 self.log.info(
"Updating PhotoCalib for visit: %d, ccd: %d", visit, ccd)
847 photoCalib = model.toPhotoCalib(ccdImage)
849 dataRef.put(photoCalib,
'jointcal_photoCalib')
850 except pexExceptions.Exception
as e:
851 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)
Photometric response model which has a single photometric factor per CcdImage.
def __init__(self, butler=None, profile_jointcal=False, kwargs)