-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Working integration test for CFHT data. #14
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
94c04fd
Working integration test for CFHT data.
parejkoj f8994ec
Post review updates.
parejkoj 1238345
Better visit_list management.
parejkoj 0b478a6
Add profile_jointcal cmdline argument.
parejkoj bef3ff1
Default to not generate plots.
parejkoj be8c48a
Normalize histograms and pull common options into a kwarg
parejkoj 7cf737f
Updating based on comments from Ian S.
parejkoj File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,23 +40,45 @@ class JointcalRunner(pipeBase.TaskRunner): | |
|
||
@staticmethod | ||
def getTargetList(parsedCmd, **kwargs): | ||
""" | ||
Return a list tuples per tract: (dataRefs, kwargs). | ||
|
||
Jointcal operates on lists of dataRefs simultaneously. | ||
""" | ||
kwargs['profile_jointcal'] = parsedCmd.profile_jointcal | ||
|
||
# organize data IDs by tract | ||
refListDict = {} | ||
for ref in parsedCmd.id.refList: | ||
refListDict.setdefault(ref.dataId["tract"], []).append(ref) | ||
# we call run() once with each tract | ||
return [(refListDict[tract], | ||
tract | ||
) for tract in sorted(refListDict.keys())] | ||
result = [(refListDict[tract], kwargs) for tract in sorted(refListDict.keys())] | ||
return result | ||
|
||
def __call__(self, args): | ||
""" | ||
@param args Arguments for Task.run() | ||
|
||
@return | ||
- None if self.doReturnResults is False | ||
- A pipe.base.Struct containing these fields if self.doReturnResults is True: | ||
- dataRef: the provided data references, with update post-fit WCS's. | ||
""" | ||
task = self.TaskClass(config=self.config, log=self.log) | ||
task.run(*args) | ||
dataRefList, kwargs = args | ||
result = task.run(dataRefList, **kwargs) | ||
if self.doReturnResults: | ||
return pipeBase.Struct(result=result) | ||
|
||
|
||
class JointcalConfig(pexConfig.Config): | ||
"""Config for jointcalTask""" | ||
|
||
coaddName = pexConfig.Field( | ||
doc = "Type of coadd", | ||
dtype = str, | ||
default = "deep" | ||
) | ||
posError = pexConfig.Field( | ||
doc = "Constant term for error on position (in pixel unit)", | ||
dtype = float, | ||
|
@@ -77,11 +99,6 @@ class JointcalConfig(pexConfig.Config): | |
doc = "How to select sources for cross-matching", | ||
default = "astrometry" | ||
) | ||
profile = pexConfig.Field( | ||
doc = "Profile jointcal, including the catalog creation step.", | ||
dtype = bool, | ||
default = False | ||
) | ||
|
||
def setDefaults(self): | ||
sourceSelector = self.sourceSelector["astrometry"] | ||
|
@@ -98,11 +115,9 @@ class JointcalTask(pipeBase.CmdLineTask): | |
RunnerClass = JointcalRunner | ||
_DefaultName = "jointcal" | ||
|
||
def __init__(self, schema, *args, **kwargs): | ||
""" | ||
@param schema source catalog schema for all the catalogs we will work with. | ||
""" | ||
def __init__(self, profile_jointcal=False, *args, **kwargs): | ||
pipeBase.CmdLineTask.__init__(self, *args, **kwargs) | ||
self.profile_jointcal = profile_jointcal | ||
self.makeSubtask("sourceSelector") | ||
|
||
# We don't need to persist config and metadata at this stage. | ||
|
@@ -117,13 +132,24 @@ def _getMetadataName(self): | |
def _makeArgumentParser(cls): | ||
"""Create an argument parser""" | ||
parser = pipeBase.ArgumentParser(name=cls._DefaultName) | ||
|
||
parser.add_argument("--profile_jointcal", default=False, action="store_true", | ||
help="Profile steps of jointcal separately.") | ||
parser.add_id_argument("--id", "calexp", help="data ID, e.g. --selectId visit=6789 ccd=0..9", | ||
ContainerClass=PerTractCcdDataIdContainer) | ||
return parser | ||
|
||
def _build_ccdImage(self, dataRef, associations, jointcalControl): | ||
"""Extract the necessary things from this dataRef to add a new ccdImage.""" | ||
""" | ||
!Extract the necessary things from this dataRef to add a new ccdImage. | ||
|
||
@param dataRef (ButlerDataRef) dataRef to extract info from. | ||
@param associations (jointcal.Associations) object to add the info to, to | ||
construct a new CcdImage | ||
@param jointcalControl (jointcal.JointcalControl) control object for | ||
associations management | ||
|
||
@return (afw.image.TanWcs) the TAN WCS of this image | ||
""" | ||
src = dataRef.get("src", immediate=True) | ||
md = dataRef.get("calexp_md", immediate=True) | ||
tanwcs = afwImage.TanWcs.cast(afwImage.makeWcs(md)) | ||
|
@@ -135,39 +161,54 @@ def _build_ccdImage(self, dataRef, associations, jointcalControl): | |
|
||
goodSrc = self.sourceSelector.selectSources(src) | ||
|
||
# TODO: NOTE: Leaving the old catalog and comparison code in while we | ||
# TODO: Leaving the old catalog and comparison code in while we | ||
# sort out the old/new star selector differences. | ||
|
||
# configSel = StarSelectorConfig() | ||
# self.oldSS = StarSelector(configSel) | ||
# stars1 = goodSrc.sourceCat.copy(deep=True) | ||
# stars2 = self.oldSS.select(src, calib).copy(deep=True) | ||
# fluxField = jointcalControl.sourceFluxField | ||
# SN = stars1.get(fluxField+"_flux") / stars1.get(fluxField+"_fluxSigma") | ||
# aa = [x for x in stars1['id'] if x in stars2['id']] | ||
# print("new, old, shared:", len(stars1), len(stars2), len(aa)) | ||
# # import ipdb; ipdb.set_trace() | ||
|
||
# TODO: NOTE: End of old source selector debugging block. | ||
|
||
if len(goodSrc.sourceCat) == 0: | ||
print("no stars selected in ", dataRef.dataId["visit"], dataRef.dataId["ccd"]) | ||
return | ||
print("%d stars selected in visit %d - ccd %d"%(len(goodSrc.sourceCat), | ||
dataRef.dataId["visit"], | ||
dataRef.dataId["ccd"])) | ||
|
||
associations.AddImage(goodSrc.sourceCat, tanwcs, md, bbox, filt, calib, | ||
dataRef.dataId['visit'], dataRef.dataId['ccd'], | ||
dataRef.getButler().get("camera").getName(), | ||
jointcalControl) | ||
# This block, and the StarSelector at the bottom of this file, | ||
# will be removed when DM-6622 is completed (it's a useful check | ||
# on the old/new star selector differences until then). | ||
useOldStarSelector = False | ||
if useOldStarSelector: | ||
configSel = StarSelectorConfig() | ||
self.oldSS = StarSelector(configSel) | ||
stars1 = goodSrc.sourceCat.copy(deep=True) | ||
stars2 = self.oldSS.select(src, calib).copy(deep=True) | ||
# fluxField = jointcalControl.sourceFluxField | ||
# SN = stars1.get(fluxField+"_flux") / stars1.get(fluxField+"_fluxSigma") | ||
aa = [x for x in stars1['id'] if x in stars2['id']] | ||
print("new, old, shared:", len(stars1), len(stars2), len(aa)) | ||
# import ipdb; ipdb.set_trace() | ||
print("%d stars selected in visit %d - ccd %d"%(len(stars2), | ||
dataRef.dataId["visit"], | ||
dataRef.dataId["ccd"])) | ||
associations.AddImage(stars2, tanwcs, md, bbox, filt, calib, | ||
dataRef.dataId['visit'], dataRef.dataId['ccd'], | ||
dataRef.getButler().get("camera").getName(), | ||
jointcalControl) | ||
else: | ||
if len(goodSrc.sourceCat) == 0: | ||
print("no stars selected in ", dataRef.dataId["visit"], dataRef.dataId["ccd"]) | ||
return tanwcs | ||
print("%d stars selected in visit %d - ccd %d"%(len(goodSrc.sourceCat), | ||
dataRef.dataId["visit"], | ||
dataRef.dataId["ccd"])) | ||
|
||
associations.AddImage(goodSrc.sourceCat, tanwcs, md, bbox, filt, calib, | ||
dataRef.dataId['visit'], dataRef.dataId['ccd'], | ||
dataRef.getButler().get("camera").getName(), | ||
jointcalControl) | ||
return tanwcs | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a blank There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch! |
||
|
||
@pipeBase.timeMethod | ||
def run(self, dataRefs): | ||
def run(self, dataRefs, profile_jointcal=False): | ||
""" | ||
!Jointly calibrate the astrometry and photometry across a set of images. | ||
|
||
@param dataRefs list of data references. | ||
@param dataRefs list of data references. | ||
@param profile_jointcal (bool) profile the individual steps of jointcal. | ||
|
||
@return (pipe.base.Struct) struct containing: | ||
- dataRefs: the provided data references that were fit (with updated WCSs) | ||
- oldWcsList: the original WCS from each dataRef | ||
""" | ||
if len(dataRefs) == 0: | ||
raise ValueError('Need a list of data references!') | ||
|
@@ -177,20 +218,9 @@ def run(self, dataRefs): | |
|
||
associations = jointcalLib.Associations() | ||
|
||
if self.config.profile: | ||
import cProfile | ||
import pstats | ||
profile = cProfile.Profile() | ||
profile.enable() | ||
for dataRef in dataRefs: | ||
self._build_ccdImage(dataRef, associations, jointcalControl) | ||
profile.disable() | ||
profile.dump_stats('jointcal_load_catalog.prof') | ||
prof = pstats.Stats('jointcal_load_catalog.prof') | ||
prof.strip_dirs().sort_stats('cumtime').print_stats(20) | ||
else: | ||
for dataRef in dataRefs: | ||
self._build_ccdImage(dataRef, associations, jointcalControl) | ||
load_cat_prof_file = 'jointcal_load_catalog.prof' if profile_jointcal else '' | ||
with pipeBase.cmdLineTask.profile(load_cat_prof_file): | ||
oldWcsList = [self._build_ccdImage(ref, associations, jointcalControl) for ref in dataRefs] | ||
|
||
matchCut = 3.0 | ||
# TODO: this should not print "trying to invert a singular transformation:" | ||
|
@@ -275,7 +305,7 @@ def run(self, dataRefs): | |
print("unxepected return code from Minimize") | ||
|
||
# Fill reference and measurement n-tuples for each tract | ||
tupleName = "res_" + str(dataRef.dataId["tract"]) + ".list" | ||
tupleName = "res_" + str(dataRefs[0].dataId["tract"]) + ".list" | ||
fit.MakeResTuple(tupleName) | ||
|
||
# Build an updated wcs for each calexp | ||
|
@@ -299,9 +329,12 @@ def run(self, dataRefs): | |
self.log.warn('Failed to write updated Wcs: ' + str(e)) | ||
break | ||
|
||
return pipeBase.Struct(dataRefs=dataRefs, oldWcsList=oldWcsList) | ||
|
||
|
||
# TODO: Leaving StarSelector[Config] here for reference. | ||
# TODO: We can remove them once we're happy with astrometryStarSelector. | ||
# TODO: This will be removed once DM-6622 is completed. | ||
|
||
class StarSelectorConfig(pexConfig.Config): | ||
|
||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code should not be left commented out. I know you have philosophical disagreements, but I think you should submit to the way things are done until you have explicit approval to change them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just submitted an RFC. I'll note that I couldn't find any explicit statement about this in the python coding standards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did add a note about the conditions under which the code would be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've now wrapped this code in
if useOldStarSelector:
with the note above it describing when it will be removed.