LSST Applications g0f08755f38+82efc23009,g12f32b3c4e+e7bdf1200e,g1653933729+a8ce1bb630,g1a0ca8cf93+50eff2b06f,g28da252d5a+52db39f6a5,g2bbee38e9b+37c5a29d61,g2bc492864f+37c5a29d61,g2cdde0e794+c05ff076ad,g3156d2b45e+41e33cbcdc,g347aa1857d+37c5a29d61,g35bb328faa+a8ce1bb630,g3a166c0a6a+37c5a29d61,g3e281a1b8c+fb992f5633,g414038480c+7f03dfc1b0,g41af890bb2+11b950c980,g5fbc88fb19+17cd334064,g6b1c1869cb+12dd639c9a,g781aacb6e4+a8ce1bb630,g80478fca09+72e9651da0,g82479be7b0+04c31367b4,g858d7b2824+82efc23009,g9125e01d80+a8ce1bb630,g9726552aa6+8047e3811d,ga5288a1d22+e532dc0a0b,gae0086650b+a8ce1bb630,gb58c049af0+d64f4d3760,gc28159a63d+37c5a29d61,gcf0d15dbbd+2acd6d4d48,gd7358e8bfb+778a810b6e,gda3e153d99+82efc23009,gda6a2b7d83+2acd6d4d48,gdaeeff99f8+1711a396fd,ge2409df99d+6b12de1076,ge79ae78c31+37c5a29d61,gf0baf85859+d0a5978c5a,gf3967379c6+4954f8c433,gfb92a5be7c+82efc23009,gfec2e1e490+2aaed99252,w.2024.46
LSST Data Management Base Package
Loading...
Searching...
No Matches
Camera.cc
Go to the documentation of this file.
1/*
2 * Developed for the LSST Data Management System.
3 * This product includes software developed by the LSST Project
4 * (https://www.lsst.org).
5 * See the COPYRIGHT file at the top-level directory of this distribution
6 * for details of code ownership.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
27
28namespace lsst {
29namespace afw {
30namespace cameraGeom {
31
32namespace {
33
34// Set this as a function to ensure FOCAL_PLANE is defined before use.
35CameraSys const getNativeCameraSys() { return FOCAL_PLANE; }
36
37} // anonymoous
38
39Camera::~Camera() noexcept = default;
40
41Camera::Builder Camera::rebuild() const {
42 return Camera::Builder(*this);
43}
44
46 CameraSys const &cameraSys) const {
47 auto nativePoint = transform(point, cameraSys, getNativeCameraSys());
48
49 DetectorList detectorList;
50 for (auto const &item : getIdMap()) {
51 auto detector = item.second;
52 auto pointPixels = detector->transform(nativePoint, getNativeCameraSys(), PIXELS);
53 if (lsst::geom::Box2D(detector->getBBox()).contains(pointPixels)) {
54 detectorList.push_back(std::move(detector));
55 }
56 }
57 return detectorList;
58}
59
61 CameraSys const &cameraSys) const {
62 std::vector<DetectorList> detectorListList(pointList.size());
63 auto nativePointList = transform(pointList, cameraSys, getNativeCameraSys());
64
65 for (auto const &item: getIdMap()) {
66 auto const &detector = item.second;
67 auto pointPixelsList = detector->transform(nativePointList, getNativeCameraSys(), PIXELS);
68 for (std::size_t i = 0; i < pointPixelsList.size(); ++i) {
69 auto const &pointPixels = pointPixelsList[i];
70 if (lsst::geom::Box2D(detector->getBBox()).contains(pointPixels)) {
71 detectorListList[i].push_back(detector);
72 }
73 }
74 }
75 return detectorListList;
76}
77
79 CameraSys const &toSys) const {
80 return getTransformMap()->getTransform(fromSys, toSys);
81}
82
84 CameraSys const &toSys) const {
85 auto transform = getTransform(fromSys, toSys);
86 return transform->applyForward(point);
87}
88
90 CameraSys const &fromSys,
91 CameraSys const &toSys) const {
92 auto transform = getTransform(fromSys, toSys);
93 return transform->applyForward(points);
94}
95
96std::shared_ptr<Detector::InCameraBuilder> Camera::makeDetectorBuilder(std::string const & name, int id) {
98}
99
100std::shared_ptr<Detector::InCameraBuilder> Camera::makeDetectorBuilder(Detector const & detector) {
101 return std::shared_ptr<Detector::InCameraBuilder>(new Detector::InCameraBuilder(detector));
102}
103
104
105std::vector<TransformMap::Connection> const & Camera::getDetectorBuilderConnections(
106 Detector::InCameraBuilder const & detector
107) {
108 return detector._connections;
109}
110
111
112namespace {
113
114class PersistenceHelper {
115public:
116
117 static PersistenceHelper const & get() {
118 static PersistenceHelper const instance;
119 return instance;
120 }
121
122 table::Schema schema;
123 table::Key<std::string> name;
124 table::Key<std::string> pupilFactoryName;
125 table::Key<int> transformMap;
126
127private:
128
129 PersistenceHelper() :
130 schema(),
131 name(schema.addField<std::string>("name", "Camera name", "", 0)),
132 pupilFactoryName(schema.addField<std::string>("pupilFactoryName",
133 "Fully-qualified name of a Python PupilFactory class",
134 "", 0)),
135 transformMap(schema.addField<int>("transformMap", "archive ID for Camera's TransformMap"))
136 {
137 }
138
139 PersistenceHelper(PersistenceHelper const &) = delete;
140 PersistenceHelper(PersistenceHelper &&) = delete;
141
142 PersistenceHelper & operator=(PersistenceHelper const &) = delete;
143 PersistenceHelper & operator=(PersistenceHelper &&) = delete;
144
145};
146
147} // anonymous
148
151 auto const & keys = PersistenceHelper::get();
152 auto cat = handle.makeCatalog(keys.schema);
153 auto record = cat.addNew();
154 record->set(keys.name, getName());
155 record->set(keys.pupilFactoryName, getPupilFactoryName());
156 record->set(keys.transformMap, handle.put(getTransformMap()));
157 handle.saveCatalog(cat);
158}
159
161public:
162
163 Factory() : table::io::PersistableFactory("Camera") {}
164
166 CatalogVector const& catalogs) const override {
167 // can't use make_shared because ctor is protected
168 return std::shared_ptr<Camera>(new Camera(archive, catalogs));
169 }
170
171 static Factory const registration;
172
173};
174
176
177Camera::Camera(std::string const & name, DetectorList detectors,
179 DetectorCollection(std::move(detectors)),
180 _name(name),
181 _pupilFactoryName(pupilFactoryName),
182 _transformMap(std::move(transformMap))
183{}
184
185Camera::Camera(table::io::InputArchive const & archive, table::io::CatalogVector const & catalogs) :
186 DetectorCollection(archive, catalogs)
187 // deferred initalization for data members is not ideal, but better than
188 // trying to initialize them before validating the archive
189{
190 auto const & keys = PersistenceHelper::get();
191 LSST_ARCHIVE_ASSERT(catalogs.size() >= 2u);
192 auto const & cat = catalogs[1];
193 LSST_ARCHIVE_ASSERT(cat.getSchema() == keys.schema);
194 LSST_ARCHIVE_ASSERT(cat.size() == 1u);
195 auto const & record = cat.front();
196 _name = record.get(keys.name);
197 _pupilFactoryName = record.get(keys.pupilFactoryName);
198 _transformMap = archive.get<TransformMap>(record.get(keys.transformMap));
199}
200
201std::string Camera::getPersistenceName() const { return "Camera"; }
202
203
204Camera::Builder::Builder(std::string const & name) : _name(name) {}
205
207 _name(camera.getName()),
208 _pupilFactoryName(camera.getPupilFactoryName())
209{
210 // Add Detector Builders for all Detectors; does not (yet) include
211 // coordinate transform information.
212 for (auto const & pair : camera.getIdMap()) {
213 BaseCollection::add(Camera::makeDetectorBuilder(*pair.second));
214 }
215 // Iterate over connections in TransformMap, distributing them between the
216 // Camera Builder and the Detector Builders.
217 for (auto const & connection : camera.getTransformMap()->getConnections()) {
218 // asserts below are on Detector, Camera, and TransformMap invariants:
219 // - Connections should always be from native sys to something else.
220 // - The only connections between full-camera and per-detector sys
221 // should be from the camera native sys (FOCAL_PLANE) to the
222 // detector native sys (PIXELS).
223 // - When TransformMap standardizes connections, it should maintain
224 // these directions, as that's consistent with "pointing away" from
225 // the overall reference sys (the camera native sys).
226 if (connection.fromSys.hasDetectorName()) {
227 assert(connection.toSys.getDetectorName() == connection.fromSys.getDetectorName());
228 auto detector = (*this)[connection.fromSys.getDetectorName()];
229 assert(connection.fromSys == detector->getNativeCoordSys());
230 detector->setTransformFromPixelsTo(CameraSysPrefix(connection.toSys.getSysName()),
231 connection.transform);
232 } else {
233 assert(connection.fromSys == getNativeCameraSys());
234 if (!connection.toSys.hasDetectorName()) {
235 _connections.push_back(connection);
236 }
237 // We ignore the FOCAL_PLANE to PIXELS transforms transforms, as
238 // those are always regenerated from the Orientation when we
239 // rebuild the Camera.
240 }
241 }
242}
243
244Camera::Builder::~Builder() noexcept = default;
245
246std::shared_ptr<Camera const> Camera::Builder::finish() const {
247 // Make a big vector of all coordinate transform connections;
248 // start with general transforms for the camera as a whole:
249 std::vector<TransformMap::Connection> connections(_connections);
250 // Loop over detectors and add the transforms from FOCAL_PLANE
251 // to PIXELS (via the Orientation), and then any extra transforms
252 // from PIXELS to other things.
253 for (auto const & pair : getIdMap()) {
254 auto const & detectorBuilder = *pair.second;
255 std::vector<TransformMap::Connection> detectorConnections = getDetectorBuilderConnections(detectorBuilder);
256 std::vector<std::vector<CameraSys>> allDetConnections;
257 for (auto const &connection : detectorConnections) {
258 std::vector<CameraSys> tmpConnection = {connection.fromSys, connection.toSys};
259 allDetConnections.push_back(tmpConnection);
260 }
261 std::vector<CameraSys> connection = {detectorBuilder.getNativeCoordSys(), getNativeCameraSys()};
262 std::vector<CameraSys> invConnection = {getNativeCameraSys(), detectorBuilder.getNativeCoordSys()};
263 if ((std::find(allDetConnections.begin(), allDetConnections.end(), connection) == allDetConnections.end())
264 && (std::find(allDetConnections.begin(), allDetConnections.end(), invConnection) == allDetConnections.end()) ) {
265
266 connections.push_back(
268 detectorBuilder.getOrientation().makeFpPixelTransform(detectorBuilder.getPixelSize()),
269 getNativeCameraSys(),
270 detectorBuilder.getNativeCoordSys()
271 }
272 );
273 }
274 connections.insert(connections.end(),
275 getDetectorBuilderConnections(detectorBuilder).begin(),
276 getDetectorBuilderConnections(detectorBuilder).end());
277 }
278 // Make a single big TransformMap.
279 auto transformMap = TransformMap::make(getNativeCameraSys(), connections);
280 // Make actual Detector objects, giving each the full TransformMap.
281 DetectorList detectors;
282 detectors.reserve(size());
283 for (auto const & pair : getIdMap()) {
284 auto const & detectorBuilder = *pair.second;
285 detectors.push_back(detectorBuilder.finish(transformMap));
286 }
287 return std::shared_ptr<Camera>(new Camera(_name, std::move(detectors), std::move(transformMap),
288 _pupilFactoryName));
289}
290
291
292namespace {
293
294// Return the first connection in the given range that has toSys as its "to"
295// endpoint.
296//
297// @tparam Iter Iterator that dereferences to `Connection const &`.
298//
299template <typename Iter>
300Iter findConnection(Iter first, Iter last, CameraSys const & toSys) {
301 return std::find_if(
302 first, last,
303 [&toSys](auto const & connection) {
304 return connection.toSys == toSys;
305 }
306 );
307}
308
309} // anonymous
310
312 CameraSys const & toSys,
314) {
315 if (toSys.hasDetectorName()) {
316 throw LSST_EXCEPT(
318 (boost::format("%s should be added to Detector %s, not Camera") %
319 toSys.getSysName() % toSys.getDetectorName()).str()
320 );
321 }
322 auto iter = findConnection(_connections.begin(), _connections.end(), toSys);
323 if (iter == _connections.end()) {
324 _connections.push_back(
325 TransformMap::Connection{transform, getNativeCameraSys(), toSys}
326 );
327 } else {
328 iter->transform = transform;
329 }
330}
331
333 auto iter = findConnection(_connections.begin(), _connections.end(), toSys);
334 if (iter != _connections.end()) {
335 _connections.erase(iter);
336 return true;
337 }
338 return false;
339}
340
342 auto detector = makeDetectorBuilder(name, id);
343 BaseCollection::add(detector);
344 return detector;
345}
346
347} // namespace cameraGeom
348
349namespace table {
350namespace io {
351
352template class PersistableFacade<cameraGeom::Camera>;
353
354} // namespace io
355} // namespace table
356
357} // namespace afw
358} // namespace lsst
int end
table::Key< std::string > pupilFactoryName
Definition Camera.cc:124
table::Key< int > transformMap
Definition Camera.cc:125
table::Key< int > detector
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition Exception.h:48
table::Key< int > transform
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
Definition Persistable.h:48
table::Schema schema
Definition python.h:134
T begin(T... args)
A helper class for creating and modifying cameras.
Definition Camera.h:208
void setTransformFromFocalPlaneTo(CameraSys const &toSys, std::shared_ptr< afw::geom::TransformPoint2ToPoint2 const > transform)
Set the transformation from FOCAL_PLANE to the given coordinate system.
Definition Camera.cc:311
Builder(std::string const &name)
Construct a Builder for a completely new Camera with the given name.
Definition Camera.cc:204
std::shared_ptr< Detector::InCameraBuilder > add(std::string const &name, int id)
Add a new Detector with the given name and ID.
Definition Camera.cc:341
bool discardTransformFromFocalPlaneTo(CameraSys const &toSys)
Remove any transformation from FOCAL_PLANE to the given coordinate system.
Definition Camera.cc:332
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.
Definition Camera.cc:165
static Factory const registration
Definition Camera.cc:171
An immutable representation of a camera.
Definition Camera.h:43
Camera(Camera const &)=delete
std::shared_ptr< TransformMap const > getTransformMap() const noexcept
Obtain the transform registry.
Definition Camera.h:120
std::string getPupilFactoryName() const
Return the fully-qualified name of the Python class that provides this Camera's PupilFactory.
Definition Camera.h:76
std::string getName() const
Return the name of the camera.
Definition Camera.h:71
DetectorList findDetectors(lsst::geom::Point2D const &point, CameraSys const &cameraSys) const
Find the detectors that cover a point in any camera system.
Definition Camera.cc:45
virtual ~Camera() noexcept
std::vector< DetectorList > findDetectorsList(std::vector< lsst::geom::Point2D > const &pointList, CameraSys const &cameraSys) const
Find the detectors that cover a list of points in any camera system.
Definition Camera.cc:60
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
Definition Camera.cc:201
lsst::geom::Point2D transform(lsst::geom::Point2D const &point, CameraSys const &fromSys, CameraSys const &toSys) const
Transform a point from one camera coordinate system to another.
Definition Camera.cc:83
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
Definition Camera.cc:149
std::shared_ptr< afw::geom::TransformPoint2ToPoint2 > getTransform(CameraSys const &fromSys, CameraSys const &toSys) const
Get a transform from one CameraSys to another.
Definition Camera.cc:78
Camera coordinate system; used as a key in in TransformMap.
Definition CameraSys.h:83
bool hasDetectorName() const noexcept
Does this have a non-blank detector name?
Definition CameraSys.h:125
std::string getSysName() const
Get coordinate system name.
Definition CameraSys.h:115
std::string getDetectorName() const
Get detector name, or "" if not a detector-specific coordinate system.
Definition CameraSys.h:120
Camera coordinate system prefix.
Definition CameraSys.h:44
A helper class that allows the properties of a detector to be modified in the course of modifying a f...
Definition Detector.h:555
std::size_t size() const noexcept
Get the number of detectors.
IdMap const & getIdMap() const noexcept
Get a map keyed and ordered by ID.
void add(std::shared_ptr< Detector::InCameraBuilder > detector)
Add a detector to the collection.
An immutable collection of Detectors that can be accessed by name or ID.
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
A registry of 2-dimensional coordinate transforms for a specific camera.
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.
std::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
Definition Catalog.h:489
A vector of catalogs used by Persistable.
A multi-catalog archive object used to load table::io::Persistable objects.
std::shared_ptr< Persistable > get(int id) const
Load the Persistable with the given ID and return it.
An object passed to Persistable::write to allow it to persist itself.
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.
A floating-point coordinate rectangle geometry.
Definition Box.h:413
bool contains(Point2D const &point) const noexcept
Return true if the box contains the point.
Definition Box.cc:322
Reports errors in the logical structure of the program.
Definition Runtime.h:46
T end(T... args)
T find(T... args)
T insert(T... args)
T move(T... args)
CameraSys const FOCAL_PLANE
Focal plane coordinates: Position on a 2-d planar approximation to the focal plane (x,...
Definition CameraSys.cc:30
CameraSysPrefix const PIXELS
Pixel coordinates: Nominal position on the entry surface of a given detector (x, y unbinned pixels).
Definition CameraSys.cc:34
STL namespace.
T push_back(T... args)
T reserve(T... args)
T size(T... args)
Representation of a single edge in the graph defined by a TransformMap.