23 #include <unordered_set>
35 namespace cameraGeom {
42 static auto LOGGER =
LOG_GET(
"afw.cameraGeom.TransformMap");
47 if (sys.hasDetectorName()) {
49 r += sys.getDetectorName();
79 CameraSys
const & reference,
82 if (connections.
empty()) {
84 pex::exceptions::InvalidParameterError,
85 "Cannot create a TransformMap with no connections."
90 auto firstUnprocessed = connections.
begin();
102 LOGLS_DEBUG(LOGGER,
"Standardizing: starting with reference " << reference);
103 while (!currentSystems.
empty()) {
104 LOGLS_DEBUG(LOGGER,
"Standardizing: beginning iteration with currentSystems={ ");
105 for (
auto const & sys : currentSystems) {
106 LOGLS_DEBUG(LOGGER,
"Standardizing: " << sys <<
", ");
111 for (
auto connection = firstUnprocessed; connection != connections.
end(); ++connection) {
112 bool related = currentSystems.count(connection->fromSys) > 0;
113 if (!related && currentSystems.count(connection->toSys)) {
114 LOGLS_DEBUG(LOGGER,
"Standardizing: reversing " << (*connection));
116 connection->reverse();
120 if (connection->toSys == connection->fromSys) {
122 ss <<
"Identity connection found: " << (*connection) <<
".";
123 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, ss.
str());
125 if (knownSystems.
count(connection->toSys)) {
127 ss <<
"Multiple paths between reference " << reference
128 <<
" and " << connection->toSys <<
".";
129 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, ss.
str());
131 LOGLS_DEBUG(LOGGER,
"Standardizing: adding " << (*connection));
132 nextSystems.
insert(connection->toSys);
133 knownSystems.
insert(connection->toSys);
134 std::swap(*firstUnprocessed, *connection);
138 currentSystems.swap(nextSystems);
143 if (firstUnprocessed != connections.
end()) {
145 ss <<
"Disconnected connection(s) found: " << (*firstUnprocessed);
147 for (
auto connection = firstUnprocessed; connection != connections.
end(); ++connection) {
148 ss <<
", " << (*connection);
151 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, ss.
str());
180 for (
auto const & pair : transforms) {
195 new TransformMap(standardizeConnections(reference, connections))
205 auto mapping = _getMapping(fromSys, toSys);
212 auto mapping = _getMapping(fromSys, toSys);
220 return std::make_shared<geom::TransformPoint2ToPoint2>(*_getMapping(fromSys, toSys));
223 int TransformMap::_getFrame(
CameraSys const &system)
const {
225 return _frameIds.
at(system);
228 buffer <<
"Unsupported coordinate system: " << system;
234 CameraSys
const &toSys)
const {
235 return _frameSet->
getMapping(_getFrame(fromSys), _getFrame(toSys));
242 _connections(
std::move(connections))
247 assert(!_connections.empty());
258 _frameIds.
emplace(sys, ++nFrames);
265 _frameSet = std::make_unique<ast::FrameSet>(addFrameForSys(getReferenceSys(_connections)));
267 for (
auto const & connection : _connections) {
268 auto fromSysIdIter = _frameIds.
find(connection.fromSys);
269 assert(fromSysIdIter != _frameIds.
end());
270 _frameSet->
addFrame(fromSysIdIter->second, *connection.transform->getMapping(),
271 addFrameForSys(connection.toSys));
276 assert(_frameSet->
getNFrame() == nFrames);
284 struct PersistenceHelper {
286 static PersistenceHelper
const & get() {
287 static PersistenceHelper
const instance;
303 PersistenceHelper() :
306 "Camera coordinate system name.",
"", 0)),
308 "Camera coordinate system detector name.",
"", 0)),
310 "Camera coordinate system name.",
"", 0)),
312 "Camera coordinate system detector name.",
"", 0)),
313 transform(
schema.addField<int>(
"transform",
"Archive ID of the transform.",
""))
316 PersistenceHelper(PersistenceHelper
const &) =
delete;
317 PersistenceHelper(PersistenceHelper &&) =
delete;
319 PersistenceHelper & operator=(PersistenceHelper
const &) =
delete;
320 PersistenceHelper & operator=(PersistenceHelper &&) =
delete;
327 struct OldPersistenceHelper {
329 static OldPersistenceHelper
const & get() {
330 static OldPersistenceHelper
const instance;
352 CameraSys makeCameraSys(table::BaseRecord
const & record)
const {
358 OldPersistenceHelper() :
360 sysName(
sysSchema.addField<
std::string>(
"sysName",
"Camera coordinate system name",
"", 0)),
362 "Camera coordinate system detector name",
"", 0)),
363 id(
sysSchema.addField<int>(
"id",
"AST ID of the Frame for the CameraSys",
"")),
365 from(
connectionSchema.addField<int>(
"from",
"AST ID of the Frame this transform maps from.",
"")),
366 to(
connectionSchema.addField<int>(
"to",
"AST ID of the Frame this transform maps to.",
"")),
370 OldPersistenceHelper(OldPersistenceHelper
const &) =
delete;
371 OldPersistenceHelper(OldPersistenceHelper &&) =
delete;
373 OldPersistenceHelper & operator=(OldPersistenceHelper
const &) =
delete;
374 OldPersistenceHelper & operator=(OldPersistenceHelper &&) =
delete;
382 std::string TransformMap::getPersistenceName()
const {
383 return "TransformMap";
386 std::string TransformMap::getPythonModule()
const {
387 return "lsst.afw.cameraGeom";
390 void TransformMap::write(OutputArchiveHandle& handle)
const {
391 auto const &
keys = PersistenceHelper::get();
393 auto cat = handle.makeCatalog(
keys.schema);
394 for (
auto const & connection : _connections) {
395 auto record = cat.addNew();
396 record->set(
keys.fromSysName, connection.fromSys.getSysName());
397 record->set(
keys.fromSysDetectorName, connection.fromSys.getDetectorName());
398 record->set(
keys.toSysName, connection.toSys.getSysName());
399 record->set(
keys.toSysDetectorName, connection.toSys.getDetectorName());
400 record->set(
keys.transform, handle.put(connection.transform));
402 handle.saveCatalog(cat);
412 auto const &
keys = OldPersistenceHelper::get();
415 auto const & sysCat = catalogs[0];
416 auto const & connectionCat = catalogs[1];
423 for (
auto const & sysRecord : sysCat) {
424 auto sys =
keys.makeCameraSys(sysRecord);
428 auto const referenceSysIter = sysById.
find(1);
431 for (
auto const & connectionRecord : connectionCat) {
432 auto const fromSysIter = sysById.
find(connectionRecord.get(
keys.from));
434 auto const toSysIter = sysById.
find(connectionRecord.get(
keys.to));
437 connectionRecord.get(
keys.transform)
443 connections = standardizeConnections(referenceSysIter->second,
std::move(connections));
449 if (catalogs.
size() == 2u) {
450 return readOld(archive, catalogs);
453 auto const &
keys = PersistenceHelper::get();
456 auto const & cat = catalogs[0];
460 for (
auto const & record : cat) {
461 CameraSys const fromSys(record.get(
keys.fromSysName), record.get(
keys.fromSysDetectorName));
462 CameraSys const toSys(record.get(
keys.toSysName), record.get(
keys.toSysDetectorName));
469 auto const referenceSys = getReferenceSys(connections);
470 connections = standardizeConnections(referenceSys,
std::move(connections));
485 template class PersistableFacade<cameraGeom::TransformMap>;