I made some changes to astshim as part of this, to make it easier for Transform and Wcs:
- Add a copy argument to FrameSet.getFrame with a default value of true. Being able to access a shallow copy is necessary for some operations.
- Frame.findFrame and the similar FrameSet.convert now return std::shared_ptr<FrameSet> instead of FrameSet, and return an empty pointer instead of throwing an exception if the search is unsuccessful. This makes certain common operations easier and avoids throwing a C++ exception for a routine occurrence. However, it does require annoying boilerplate if you do want to throw an exception when the search fails, so it is worth considering a convenience function or overload of the method(s) to that throws with a specified error if the search fails.
- Add FitsChan.getCardNames to make it easy to purge PropertyList metadata that was used to create the frame set for a SkyWcs.
I also made some small changes to lsst::afw::geom::Transform, including:
- Making it usable as a base class, e.g. by making the destructor virtual.
- Adding a protected constructor that takes a std::shared_ptr<FrameSet> &&.
- Made a python function lsst.afw.geom.python.addTransformMethods that adds pure Python methods to Transform classes and subclasses. Note that the sub-namespace "python" was chosen to match the C++ namespace we use for pybind11 helpers. I also moved addTransformMapMethods into that namespace for consistency.
- Moved much of the unit test code into a base class, so subclasses of Transform can use it.
Finally I tweaked afw/formatters/Utils to add an ordered version of formatFitsProperties and changed a few functions to take a reference to a PropertySet instead of a shared pointer. Few, if any, of those functions should take a shared pointer, and more could easily be converted, but at some point it gets difficult due to needing to construct a LogicalLocation so I left the rest alone.