I enjoyed reading this code & found the exercise quite informative. I have added a number of comments to the pull request, but these are in general quite minor: most of them are just suggestions for where the documentation could be made a little more helpful to the reader. I've not bothered commenting on the whitespace issue that Tim brought up, but I do think splitting that into a separate commit would be helpful.
The only more substantive concern I have here is regarding testing, or, rather, lack thereof. The high level functionality is already covered by the existing tests, so that's fine. However, those tests do cover a lot of ground at once, and I can't help but wonder if lower level tests, directed at simpler units of code (like FitsSchemaInputMapper) wouldn't be helpful to provide some more fine-grained information when things break. That said, I realise that much of this functionality isn't exposed to Python, and that we prefer to do all our testing in Python code as far as is possible – it may be that testing at this level is impractical or not worth the effort, but I think it's worth considering.
One area where I'm concerned that the high-level test coverage may not be adequate is in the backwards-compatibility code. For example, SourceFitsReader switches between OldSourceFootprintReader and SourceFootprintReader depending on the input file. I think the test cases rely on creating some data, persisting it, and then demonstrating that it can be read correctly: presumably that will only ever test one of the possible code paths here.
John Swinbank, if you're got a bit of time for reviewing while enjoying Aspen (if not, let me know, and I'll reassign), here's some afw::table refactoring for you to enjoy. More info is available on the GitHub PR:
https://github.com/lsst/afw/pull/26
Note that it's a diff relative to tickets/
DM-2533, not master, because I'm trying to split up the reviews of all theDM-1766subtasks to make them more digestible.