LSST Applications g04e9c324dd+8c5ae1fdc5,g134cb467dc+1b3060144d,g18429d2f64+f642bf4753,g199a45376c+0ba108daf9,g1fd858c14a+2dcf163641,g262e1987ae+7b8c96d2ca,g29ae962dfc+3bd6ecb08a,g2cef7863aa+aef1011c0b,g35bb328faa+8c5ae1fdc5,g3fd5ace14f+53e1a9e7c5,g4595892280+fef73a337f,g47891489e3+2efcf17695,g4d44eb3520+642b70b07e,g53246c7159+8c5ae1fdc5,g67b6fd64d1+2efcf17695,g67fd3c3899+b70e05ef52,g74acd417e5+317eb4c7d4,g786e29fd12+668abc6043,g87389fa792+8856018cbb,g89139ef638+2efcf17695,g8d7436a09f+3be3c13596,g8ea07a8fe4+9f5ccc88ac,g90f42f885a+a4e7b16d9b,g97be763408+ad77d7208f,g9dd6db0277+b70e05ef52,ga681d05dcb+a3f46e7fff,gabf8522325+735880ea63,gac2eed3f23+2efcf17695,gb89ab40317+2efcf17695,gbf99507273+8c5ae1fdc5,gd8ff7fe66e+b70e05ef52,gdab6d2f7ff+317eb4c7d4,gdc713202bf+b70e05ef52,gdfd2d52018+b10e285e0f,ge365c994fd+310e8507c4,ge410e46f29+2efcf17695,geaed405ab2+562b3308c0,gffca2db377+8c5ae1fdc5,w.2025.35
LSST Data Management Base Package
Loading...
Searching...
No Matches
TransformMap.cc
Go to the documentation of this file.
1// -*- lsst-c++ -*-
2/*
3 * Developed for the LSST Data Management System.
4 * This product includes software developed by the LSST Project
5 * (https://www.lsst.org).
6 * See the COPYRIGHT file at the top-level directory of this distribution
7 * for details of code ownership.
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22#include <sstream>
23#include <unordered_set>
24
25#include "lsst/geom/Point.h"
28#include "lsst/log/Log.h"
29#include "lsst/pex/exceptions.h"
35
36namespace lsst {
37namespace afw {
38namespace cameraGeom {
39
40namespace {
41
42// Allows conversions between LSST and AST data formats
43static lsst::afw::geom::Point2Endpoint const POINT2_ENDPOINT;
44
45static auto LOGGER = LOG_GET("lsst.afw.cameraGeom.TransformMap");
46
47// Make an AST Frame name for a CameraSys.
48std::string makeFrameName(CameraSys const &sys) {
49 std::string r = "Ident=" + sys.getSysName();
50 if (sys.hasDetectorName()) {
51 r += "_";
52 r += sys.getDetectorName();
53 }
54 return r;
55}
56
57/*
58 * Make a vector of `Connection` instances that can be safely passed to
59 * TransformMap's private constructor.
60 *
61 * This guarantees that:
62 * - Connections are sorted according to their distance (in number of
63 * intermediate connections) from the given reference `CameraSys`;
64 * - The `fromSys` of each `Connection` is closer to the reference than the
65 * `toSys`.
66 *
67 * @param[in] reference Reference coordinate system. All systems must be
68 * (indirectly) connected to this system, and will be
69 * sorted according to the number of connections to it.
70 * @param[in] connections Vector of `Connection` instances. Passed by value so
71 * we can either move into it (avoiding a copy) or copy
72 * into it (when we have a const reference and a copy is
73 * unavoidable), depending on the context.
74 *
75 * @returns connections An updated version of the connections vector.
76 *
77 * @throws pex::exceptions::InvalidParameterError Thrown if the vector of
78 * connections graph is empty, contains cycles, is not fully connected, or
79 * includes any connections in which `fromSys == toSys`.
80 */
81std::vector<TransformMap::Connection> standardizeConnections(
82 CameraSys const &reference, std::vector<TransformMap::Connection> connections) {
83 if (connections.empty()) {
84 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
85 "Cannot create a TransformMap with no connections.");
86 }
87 // Iterator to the first unprocessed connection in result; will be
88 // incremented as we proceed.
89 auto firstUnprocessed = connections.begin();
90 // All CameraSys whose associated Connections are already in the processed
91 // part of `connections`.
92 std::unordered_set<CameraSys> knownSystems = {reference};
93 // The set of CameraSys whose associated Connections are being processed
94 // in this iteration of the outer (while) loop. These are all some common
95 // distance N from the reference system (in number of connections), where
96 // N increases for each iteration (but is not tracked).
97 std::unordered_set<CameraSys> currentSystems = {reference};
98 // The set of CameraSys that will become currentSys at the next
99 // iteration.
100 std::unordered_set<CameraSys> nextSystems;
101 LOGLS_DEBUG(LOGGER, "Standardizing: starting with reference " << reference);
102 while (!currentSystems.empty()) {
103 LOGLS_DEBUG(LOGGER, "Standardizing: beginning iteration with currentSystems={ ");
104 for (auto const &sys : currentSystems) {
105 LOGLS_DEBUG(LOGGER, "Standardizing: " << sys << ", ");
106 }
107 LOGLS_DEBUG(LOGGER, "Standardizing: }");
108 // Iterate over all unsorted connections, looking for those associated
109 // with a CameraSys in currentSystems.
110 for (auto connection = firstUnprocessed; connection != connections.end(); ++connection) {
111 bool related = currentSystems.count(connection->fromSys) > 0;
112 if (!related && currentSystems.count(connection->toSys)) {
113 LOGLS_DEBUG(LOGGER, "Standardizing: reversing " << (*connection));
114 // Safe because `connections` is passed by value.
115 connection->reverse();
116 related = true;
117 }
118 if (related) {
119 if (connection->toSys == connection->fromSys) {
120 std::ostringstream ss;
121 ss << "Identity connection found: " << (*connection) << ".";
122 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, ss.str());
123 }
124 if (knownSystems.count(connection->toSys)) {
125 std::ostringstream ss;
126 ss << "Multiple paths between reference " << reference << " and " << connection->toSys
127 << ".";
128 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, ss.str());
129 }
130 LOGLS_DEBUG(LOGGER, "Standardizing: adding " << (*connection));
131 nextSystems.insert(connection->toSys);
132 knownSystems.insert(connection->toSys);
133 std::swap(*firstUnprocessed, *connection);
134 ++firstUnprocessed;
135 }
136 }
137 currentSystems.swap(nextSystems);
138 nextSystems.clear();
139 }
140 // Any connections we haven't processed yet must include only CameraSys
141 // we've never seen before.
142 if (firstUnprocessed != connections.end()) {
143 std::ostringstream ss;
144 ss << "Disconnected connection(s) found: " << (*firstUnprocessed);
145 ++firstUnprocessed;
146 for (auto connection = firstUnprocessed; connection != connections.end(); ++connection) {
147 ss << ", " << (*connection);
148 }
149 ss << ".";
150 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, ss.str());
151 }
152 // No RVO, because this is a function argument, but it's still a move so we
153 // don't care.
154 return connections;
155}
156
157// Return the reference coordinate system from an already-standardized vector of connections.
158CameraSys getReferenceSys(std::vector<TransformMap::Connection> const &connections) {
159 return connections.front().fromSys;
160}
161
162} // namespace
163
165 transform = transform->inverted();
166 toSys.swap(fromSys);
167}
168
170 return os << connection.fromSys << "->" << connection.toSys;
171}
172
174 Transforms const &transforms) {
175 std::vector<Connection> connections;
176 connections.reserve(transforms.size());
177 for (auto const &pair : transforms) {
178 connections.push_back(Connection{pair.second, reference, pair.first});
179 }
180 // We can't use make_shared because TransformMap ctor is private.
182 new TransformMap(standardizeConnections(reference, std::move(connections))));
183}
184
186 std::vector<Connection> const &connections) {
187 // We can't use make_shared because TransformMap ctor is private.
189 new TransformMap(standardizeConnections(reference, connections)));
190}
191
192// All resources owned by value or by smart pointer
193TransformMap::~TransformMap() noexcept = default;
194
195lsst::geom::Point2D TransformMap::transform(lsst::geom::Point2D const &point, CameraSys const &fromSys,
196 CameraSys const &toSys) const {
197 auto mapping = _getMapping(fromSys, toSys);
198 return POINT2_ENDPOINT.pointFromData(mapping->applyForward(POINT2_ENDPOINT.dataFromPoint(point)));
199}
200
202 CameraSys const &fromSys,
203 CameraSys const &toSys) const {
204 auto mapping = _getMapping(fromSys, toSys);
205 return POINT2_ENDPOINT.arrayFromData(mapping->applyForward(POINT2_ENDPOINT.dataFromArray(pointList)));
206}
207
208bool TransformMap::contains(CameraSys const &system) const noexcept { return _frameIds.count(system) > 0; }
209
211 CameraSys const &toSys) const {
212 return std::make_shared<geom::TransformPoint2ToPoint2>(*_getMapping(fromSys, toSys));
213}
214
215bool TransformMap::getFocalPlaneParity() const noexcept { return _focalPlaneParity; }
216
217int TransformMap::_getFrame(CameraSys const &system) const {
218 try {
219 return _frameIds.at(system);
220 } catch (std::out_of_range const &e) {
221 std::ostringstream buffer;
222 buffer << "Unsupported coordinate system: " << system;
224 }
225}
226
227std::shared_ptr<ast::Mapping const> TransformMap::_getMapping(CameraSys const &fromSys,
228 CameraSys const &toSys) const {
229 return _frameSet->getMapping(_getFrame(fromSys), _getFrame(toSys));
230}
231
232size_t TransformMap::size() const noexcept { return _frameIds.size(); }
233
235 : _connections(std::move(connections)), _focalPlaneParity(false) {
236 // standardizeConnections must be run by anything that calls the
237 // constructor, and that should throw on all of the conditions we assert
238 // on below (which is why those are asserts).
239 assert(!_connections.empty());
240
241 int nFrames = 0; // tracks frameSet->getNFrame() to avoid those (expensive) calls
242
243 // Local helper function that creates a Frame, updates the nFrames counter,
244 // and adds an entry to the frameIds map. Returns the new Frame.
245 // Should always be called in concert with an update to frameSet.
246 auto addFrameForSys = [this, &nFrames](CameraSys const &sys) mutable -> ast::Frame {
247#ifndef NDEBUG
248 auto r = // We only care about this return value for the assert below;
249#endif
250 _frameIds.emplace(sys, ++nFrames);
251 assert(r.second); // this must actually insert something, not find an already-inserted CameraSys.
252 return ast::Frame(2, makeFrameName(sys));
253 };
254
255 // FrameSet that manages all transforms; should always be updated in
256 // concert with a call to addFrameForSys.
257 _frameSet = std::make_unique<ast::FrameSet>(addFrameForSys(getReferenceSys(_connections)));
258
259 for (auto const &connection : _connections) {
260 auto fromSysIdIter = _frameIds.find(connection.fromSys);
261 assert(fromSysIdIter != _frameIds.end());
262 _frameSet->addFrame(fromSysIdIter->second, *connection.transform->getMapping(),
263 addFrameForSys(connection.toSys));
264 }
265
266 // We've maintained our own counter for frame IDs for performance and
267 // convenience reasons, but it had better match AST's internal counter.
268 assert(_frameSet->getNFrame() == nFrames);
269
270 // If the caller didn't provide the focal plane parity, get it from the
271 // determinant of the Jacobian of the FOCAL_PLANE -> FIELD_ANGLE transform.
272 try {
274 auto jacobian = transform->getJacobian(lsst::geom::Point2D(0.0, 0.0));
275 _focalPlaneParity = (jacobian.determinant() < 0);
276 } catch (pex::exceptions::InvalidParameterError &) {
277 }
278}
279
281
282namespace {
283
284struct PersistenceHelper {
285 static PersistenceHelper const &get() {
286 static PersistenceHelper const instance;
287 return instance;
288 }
289
290 // Schema and keys for the catalog that stores Connection objects.
291 // Considered as a graph, 'from' and 'to' identify vertices, and
292 // 'transform' identifies an edge.
293 table::Schema schema;
294 table::Key<std::string> fromSysName;
295 table::Key<std::string> fromSysDetectorName;
296 table::Key<std::string> toSysName;
297 table::Key<std::string> toSysDetectorName;
299
300private:
301 PersistenceHelper()
302 : schema(),
303 fromSysName(
304 schema.addField<std::string>("fromSysName", "Camera coordinate system name.", "", 0)),
305 fromSysDetectorName(schema.addField<std::string>(
306 "fromSysDetectorName", "Camera coordinate system detector name.", "", 0)),
307 toSysName(schema.addField<std::string>("toSysName", "Camera coordinate system name.", "", 0)),
308 toSysDetectorName(schema.addField<std::string>(
309 "toSysDetectorName", "Camera coordinate system detector name.", "", 0)),
310 transform(schema.addField<int>("transform", "Archive ID of the transform.", "")) {}
311
312 PersistenceHelper(PersistenceHelper const &) = delete;
313 PersistenceHelper(PersistenceHelper &&) = delete;
314
315 PersistenceHelper &operator=(PersistenceHelper const &) = delete;
316 PersistenceHelper &operator=(PersistenceHelper &&) = delete;
317};
318
319// PersistenceHelper for a previous format version; now only supported in
320// reading.
321struct OldPersistenceHelper {
322 static OldPersistenceHelper const &get() {
323 static OldPersistenceHelper const instance;
324 return instance;
325 }
326
327 // Schema and keys for the catalog that stores TransformMap._frameIds.
328 // Considered as a graph, this is a list of all of the vertices with the
329 // integers that identify them in the list of edges below.
330 table::Schema sysSchema;
331 table::Key<std::string> sysName;
332 table::Key<std::string> detectorName;
333 table::Key<int> id;
334
335 // Schema and keys for the catalog that stores
336 // TransformMap._canonicalConnections entries and the associated Transform
337 // extracted from TransformMap._transforms.
338 // Considered as a graph, 'from' and 'to' identify vertices, and
339 // 'transform' identifies an edge.
340 table::Schema connectionSchema;
341 table::Key<int> from;
342 table::Key<int> to;
343 table::Key<int> transform;
344
345 CameraSys makeCameraSys(table::BaseRecord const &record) const {
346 return CameraSys(record.get(sysName), record.get(detectorName));
347 }
348
349private:
350 OldPersistenceHelper()
351 : sysSchema(),
352 sysName(sysSchema.addField<std::string>("sysName", "Camera coordinate system name", "", 0)),
353 detectorName(sysSchema.addField<std::string>("detectorName",
354 "Camera coordinate system detector name", "", 0)),
355 id(sysSchema.addField<int>("id", "AST ID of the Frame for the CameraSys", "")),
356 connectionSchema(),
357 from(connectionSchema.addField<int>("from", "AST ID of the Frame this transform maps from.",
358 "")),
359 to(connectionSchema.addField<int>("to", "AST ID of the Frame this transform maps to.", "")),
360 transform(connectionSchema.addField<int>("transform", "Archive ID of the transform.", "")) {}
361
362 OldPersistenceHelper(OldPersistenceHelper const &) = delete;
363 OldPersistenceHelper(OldPersistenceHelper &&) = delete;
364
365 OldPersistenceHelper &operator=(OldPersistenceHelper const &) = delete;
366 OldPersistenceHelper &operator=(OldPersistenceHelper &&) = delete;
367};
368
369} // namespace
370
371std::string TransformMap::getPersistenceName() const { return "TransformMap"; }
372
373std::string TransformMap::getPythonModule() const { return "lsst.afw.cameraGeom"; }
374
376 auto const &keys = PersistenceHelper::get();
377
378 auto cat = handle.makeCatalog(keys.schema);
379 for (auto const &connection : _connections) {
380 auto record = cat.addNew();
381 record->set(keys.fromSysName, connection.fromSys.getSysName());
382 record->set(keys.fromSysDetectorName, connection.fromSys.getDetectorName());
383 record->set(keys.toSysName, connection.toSys.getSysName());
384 record->set(keys.toSysDetectorName, connection.toSys.getDetectorName());
385 record->set(keys.transform, handle.put(connection.transform));
386 }
387 handle.saveCatalog(cat);
388}
389
391public:
392 Factory() : PersistableFactory("TransformMap") {}
393
394 std::shared_ptr<Persistable> readOld(InputArchive const &archive, CatalogVector const &catalogs) const {
395 auto const &keys = OldPersistenceHelper::get();
396
397 LSST_ARCHIVE_ASSERT(catalogs.size() == 2u);
398 auto const &sysCat = catalogs[0];
399 auto const &connectionCat = catalogs[1];
400 LSST_ARCHIVE_ASSERT(sysCat.getSchema() == keys.sysSchema);
401 LSST_ARCHIVE_ASSERT(connectionCat.getSchema() == keys.connectionSchema);
402 LSST_ARCHIVE_ASSERT(sysCat.size() == connectionCat.size() + 1);
403 LSST_ARCHIVE_ASSERT(sysCat.isSorted(keys.id));
404
406 for (auto const &sysRecord : sysCat) {
407 auto sys = keys.makeCameraSys(sysRecord);
408 sysById.emplace(sysRecord.get(keys.id), sys);
409 }
410
411 auto const referenceSysIter = sysById.find(1);
412 LSST_ARCHIVE_ASSERT(referenceSysIter != sysById.end());
413 std::vector<Connection> connections;
414 for (auto const &connectionRecord : connectionCat) {
415 auto const fromSysIter = sysById.find(connectionRecord.get(keys.from));
416 LSST_ARCHIVE_ASSERT(fromSysIter != sysById.end());
417 auto const toSysIter = sysById.find(connectionRecord.get(keys.to));
418 LSST_ARCHIVE_ASSERT(toSysIter != sysById.end());
419 auto const transform =
420 archive.get<geom::TransformPoint2ToPoint2>(connectionRecord.get(keys.transform));
421
422 connections.push_back(Connection{transform, fromSysIter->second, toSysIter->second});
423 }
424
425 connections = standardizeConnections(referenceSysIter->second, std::move(connections));
426 return std::shared_ptr<TransformMap>(new TransformMap(std::move(connections)));
427 }
428
430 CatalogVector const &catalogs) const override {
431 if (catalogs.size() == 2u) {
432 return readOld(archive, catalogs);
433 }
434
435 auto const &keys = PersistenceHelper::get();
436
437 LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
438 auto const &cat = catalogs[0];
439 LSST_ARCHIVE_ASSERT(cat.getSchema() == keys.schema);
440
441 std::vector<Connection> connections;
442 for (auto const &record : cat) {
443 CameraSys const fromSys(record.get(keys.fromSysName), record.get(keys.fromSysDetectorName));
444 CameraSys const toSys(record.get(keys.toSysName), record.get(keys.toSysDetectorName));
445 auto const transform = archive.get<geom::TransformPoint2ToPoint2>(record.get(keys.transform));
446 connections.push_back(Connection{transform, fromSys, toSys});
447 }
448
449 // Deserialized connections should already be standardized, but be
450 // defensive anyway.
451 auto const referenceSys = getReferenceSys(connections);
452 connections = standardizeConnections(referenceSys, std::move(connections));
453 return std::shared_ptr<TransformMap>(new TransformMap(std::move(connections)));
454 }
455
456 static Factory const registration;
457};
458
460
461} // namespace cameraGeom
462
463namespace table {
464namespace io {
465
466template class PersistableFacade<cameraGeom::TransformMap>;
467
468} // namespace io
469} // namespace table
470
471} // namespace afw
472} // namespace lsst
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition Exception.h:48
LSST DM logging module built on log4cxx.
#define LOG_GET(logger)
Returns a Log object associated with logger.
Definition Log.h:75
#define LOGLS_DEBUG(logger, message)
Log a debug-level message using an iostream-based interface.
Definition Log.h:619
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
Definition Persistable.h:48
T at(T... args)
T begin(T... args)
Frame is used to represent a coordinate system.
Definition Frame.h:157
virtual void addFrame(int iframe, Mapping const &map, Frame const &frame)
Add a new Frame and an associated Mapping to this FrameSet so as to define a new coordinate system,...
Definition FrameSet.h:210
std::shared_ptr< Mapping > getMapping(int from=BASE, int to=CURRENT) const
Obtain a Mapping that converts between two Frames in a FrameSet.
Definition FrameSet.h:304
int getNFrame() const
Get FrameSet_NFrame "NFrame": number of Frames in the FrameSet, starting from 1.
Definition FrameSet.h:316
Camera coordinate system; used as a key in in TransformMap.
Definition CameraSys.h:83
std::shared_ptr< Persistable > readOld(InputArchive const &archive, CatalogVector const &catalogs) const
std::shared_ptr< Persistable > read(InputArchive const &archive, CatalogVector const &catalogs) const override
Construct a new object from the given InputArchive and vector of catalogs.
static std::shared_ptr< TransformMap const > make(CameraSys const &reference, Transforms const &transforms)
Construct a TransformMap with all transforms relative to a single reference CameraSys.
bool getFocalPlaneParity() const noexcept
Return True if there is an x-axis flip from FOCAL_PLANE to FIELD_ANGLE, false otherwise.
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
TransformMap(TransformMap const &other)=delete
std::unordered_map< CameraSys, std::shared_ptr< geom::TransformPoint2ToPoint2 > > Transforms
std::string getPythonModule() const override
Return the fully-qualified Python module that should be imported to guarantee that its factory is reg...
size_t size() const noexcept
Get the number of supported coordinate systems.
bool contains(CameraSys const &system) const noexcept
Can this transform to and from the specified coordinate system?
std::vector< Connection > getConnections() const
Return the sequence of connections used to construct this Transform.
std::shared_ptr< geom::TransformPoint2ToPoint2 > getTransform(CameraSys const &fromSys, CameraSys const &toSys) const
Get a Transform from one camera coordinate system to another.
lsst::geom::Point2D transform(lsst::geom::Point2D const &point, CameraSys const &fromSys, CameraSys const &toSys) const
Convert a point from one camera coordinate system to another.
ndarray::Array< double, 2, 2 > dataFromArray(Array const &arr) const override
Definition Endpoint.cc:123
std::vector< double > dataFromPoint(Point const &point) const override
Definition Endpoint.cc:114
Point pointFromData(std::vector< double > const &data) const override
Get a single point from raw data.
Definition Endpoint.cc:137
Array arrayFromData(ndarray::Array< double, 2, 2 > const &data) const override
Get an array of points from raw data.
Definition Endpoint.cc:147
A class used as a handle to a particular field in a table.
Definition Key.h:53
Defines the fields and offsets for a table.
Definition Schema.h:51
std::shared_ptr< Persistable > get(int id) const
Load the Persistable with the given ID and return it.
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
int put(Persistable const *obj, bool permissive=false)
Save an object to the archive and return a unique ID that can be used to retrieve it from an InputArc...
A base class for factory classes used to reconstruct objects from records.
PersistableFactory(std::string const &name)
Constructor for the factory.
io::OutputArchiveHandle OutputArchiveHandle
Reports invalid arguments.
Definition Runtime.h:66
T clear(T... args)
T count(T... args)
T emplace(T... args)
T empty(T... args)
T end(T... args)
T find(T... args)
T front(T... args)
T insert(T... args)
T make_shared(T... args)
T move(T... args)
transform(self, *, outOffset=None, outFlipX=False, outFlipY=False)
CameraSys const FIELD_ANGLE
Field angle coordinates: Angle of a principal ray relative to the optical axis (x,...
Definition CameraSys.cc:32
CameraSys const FOCAL_PLANE
Focal plane coordinates: Position on a 2-d planar approximation to the focal plane (x,...
Definition CameraSys.cc:30
std::ostream & operator<<(std::ostream &os, CameraSysPrefix const &detSysPrefix)
Definition CameraSys.cc:47
Point< double, 2 > Point2D
Definition Point.h:324
STL namespace.
T push_back(T... args)
T reserve(T... args)
T size(T... args)
T str(T... args)
Representation of a single edge in the graph defined by a TransformMap.
void reverse()
Reverse the connection, by swapping fromSys and toSys and inverting the transform.
std::shared_ptr< geom::TransformPoint2ToPoint2 const > transform
T swap(T... args)
T throw_with_nested(T... args)