Robert Lupton, I think I've accomplished the spirit of this issue, but not the letter: a Camera and all of its Detectors now share the same TransformMap, making it possible to do any coordinate transform with just a Detector object. Detector does not have a getCamera, however - my original plan to do that fizzled when I realized that it's actually quite hard to do without cycles:
- if Detector only has a weak_ptr to its Camera, there's nothing to keep the Camera from being destroyed in the common case where you have an Exposure with just a Detector attached;
- if Camera only has weak_ptrs to its Detectors, then there's nothing to keep the Detectors alive in the also-common case where you're getting a Camera from a Butler;
- any scheme involving attaching Cameras separately to Exposures runs into messy questions of how to guarantee that that Camera instance is the same as the instance the Exposure Detector has a pointer to;
- I'd really rather not try to do custom allocation and garbage collection here.
Those problems are neatly solved by having Camera and Detector each have a shared_ptr to a TransformMap that does not have any shared_ptrs back to the Camera or Detector. In fact, this solution doesn't even require moving Camera back to C++ (though I think we'll still need that for DM-15918).
I should also add that this new functionality is only enabled if the Camera is built via the makeCameraFromCatalogs or makeCameraFromPath functions in cameraFactory.py, and I'm not sure if that's the case for the YAML cameras. It is isn't, the changes I've made to makeCameraFromCatalogs should demonstrate how to fix it. In particular, you can no longer call makeDetector directly, because we need to aggregate the transforms from all of them before actually constructing any of them. I've kept that API around for backwards compatibility (I really don't have time to deal with random obs_ package breakage right now), but I hope we'll be able to remove it in the future. It'd actually be ideal to ultimately replace all of cameraFactory.py and cameraConfig.py with native support for building cameras from YAML in afw, but that's definitely a problem for the future.
Anyhow, if all of that sounds reasonable to you, I also wanted to see if you might have time to review this ticket. If not, please let me know and I'll find someone else.
afw PR (the only one) is here: https://github.com/lsst/afw/pull/399
Calling this gen3-middleware because we're going to want this Camera refactor to happen before (at least some of) overhauling its persistence.