LSSTApplications  18.1.0
LSSTDataManagementBasePackage
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 
22 #include "lsst/afw/table/io/Persistable.cc"
27 
28 namespace lsst {
29 namespace afw {
30 namespace cameraGeom {
31 
32 namespace {
33 
34 // Set this as a function to ensure FOCAL_PLANE is defined before use.
35 CameraSys const getNativeCameraSys() { return FOCAL_PLANE; }
36 
52 std::shared_ptr<afw::geom::TransformPoint2ToPoint2> getTransformFromOneTransformMap(
53  Camera const &camera, CameraSys const &fromSys, CameraSys const &toSys) {
54 
55  if (fromSys.hasDetectorName()) {
56  auto det = camera[fromSys.getDetectorName()];
57  return det->getTransformMap()->getTransform(fromSys, toSys);
58  } else if (toSys.hasDetectorName()) {
59  auto det = camera[toSys.getDetectorName()];
60  return det->getTransformMap()->getTransform(fromSys, toSys);
61  } else {
62  return camera.getTransformMap()->getTransform(fromSys, toSys);
63  }
64 }
65 
66 } // anonymous
67 
68 Camera::Camera(std::string const &name, DetectorList const &detectorList,
70  DetectorCollection(detectorList),
71  _name(name), _transformMap(std::move(transformMap)), _pupilFactoryName(pupilFactoryName)
72  {}
73 
74 Camera::~Camera() noexcept = default;
75 
77  CameraSys const &cameraSys) const {
78  auto transform = getTransformFromOneTransformMap(*this, cameraSys, getNativeCameraSys());
79  auto nativePoint = transform->applyForward(point);
80 
81  DetectorList detectorList;
82  for (auto const &item : getIdMap()) {
83  auto detector = item.second;
84  auto nativeToPixels = detector->getTransform(getNativeCameraSys(), PIXELS);
85  auto pointPixels = nativeToPixels->applyForward(nativePoint);
86  if (lsst::geom::Box2D(detector->getBBox()).contains(pointPixels)) {
87  detectorList.push_back(std::move(detector));
88  }
89  }
90  return detectorList;
91 }
92 
94  CameraSys const &cameraSys) const {
95  auto transform = getTransformFromOneTransformMap(*this, cameraSys, getNativeCameraSys());
96  std::vector<DetectorList> detectorListList(pointList.size());
97 
98  auto nativePointList = transform->applyForward(pointList);
99 
100  for (auto const &item: getIdMap()) {
101  auto const &detector = item.second;
102  auto nativeToPixels = detector->getTransform(getNativeCameraSys(), PIXELS);
103  auto pointPixelsList = nativeToPixels->applyForward(nativePointList);
104  for (std::size_t i = 0; i < pointPixelsList.size(); ++i) {
105  auto const &pointPixels = pointPixelsList[i];
106  if (lsst::geom::Box2D(detector->getBBox()).contains(pointPixels)) {
107  detectorListList[i].push_back(detector);
108  }
109  }
110  }
111  return detectorListList;
112 }
113 
115  CameraSys const &toSys) const {
116  try {
117  return getTransformMap()->getTransform(fromSys, toSys);
119 
120  // If the Camera was constructed after DM-14980 using the makeCamera*
121  // methods in cameraFactory.py, the Camera and all Detectors share a
122  // single TransformMap that knows about all of the coordinate systems. In
123  // that case the above call should succeed (unless the requested
124  // coordinate systems are totally bogus).
125  //
126  // But if someone built this Camera by hand, the Detectors will know about
127  // only the coordinate systems associated with them, while the Camera
128  // itself only knows about coordinate systems that aren't associated with
129  // any particular Detector. In that case we need to (in general) look up
130  // transforms in multiple places and connect them using the "native camera
131  // sys" that's known to everything (at least usually FOCAL_PLANE).
132  auto fromSysToNative = getTransformFromOneTransformMap(*this, fromSys, getNativeCameraSys());
133  auto nativeToToSys = getTransformFromOneTransformMap(*this, getNativeCameraSys(), toSys);
134  return fromSysToNative->then(*nativeToToSys);
135 }
136 
138  CameraSys const &toSys) const {
139  auto transform = getTransform(fromSys, toSys);
140  return transform->applyForward(point);
141 }
142 
144  CameraSys const &fromSys,
145  CameraSys const &toSys) const {
146  auto transform = getTransform(fromSys, toSys);
147  return transform->applyForward(points);
148 }
149 
150 
151 namespace {
152 
153 class PersistenceHelper {
154 public:
155 
156  static PersistenceHelper const & get() {
157  static PersistenceHelper const instance;
158  return instance;
159  }
160 
161  table::Schema schema;
162  table::Key<std::string> name;
163  table::Key<std::string> pupilFactoryName;
164  table::Key<int> transformMap;
165 
166 private:
167 
168  PersistenceHelper() :
169  schema(),
170  name(schema.addField<std::string>("name", "Camera name", "", 0)),
171  pupilFactoryName(schema.addField<std::string>("pupilFactoryName",
172  "Fully-qualified name of a Python PupilFactory class",
173  "", 0)),
174  transformMap(schema.addField<int>("transformMap", "archive ID for Camera's TransformMap"))
175  {
176  schema.getCitizen().markPersistent();
177  }
178 
179  PersistenceHelper(PersistenceHelper const &) = delete;
180  PersistenceHelper(PersistenceHelper &&) = delete;
181 
182  PersistenceHelper & operator=(PersistenceHelper const &) = delete;
183  PersistenceHelper & operator=(PersistenceHelper &&) = delete;
184 
185 };
186 
187 } // anonymous
188 
189 
191 public:
192 
193  Factory() : table::io::PersistableFactory("Camera") {}
194 
196  CatalogVector const& catalogs) const override {
197  // can't use make_shared because ctor is protected
198  return std::shared_ptr<Camera>(new Camera(archive, catalogs));
199  }
200 
201  static Factory const registration;
202 
203 };
204 
206 
207 
209  DetectorCollection(archive, catalogs)
210  // deferred initalization for data members is not ideal, but better than
211  // trying to initialize them before validating the archive
212 {
213  auto const & keys = PersistenceHelper::get();
214  LSST_ARCHIVE_ASSERT(catalogs.size() >= 2u);
215  auto const & cat = catalogs[1];
216  LSST_ARCHIVE_ASSERT(cat.getSchema() == keys.schema);
217  LSST_ARCHIVE_ASSERT(cat.size() == 1u);
218  auto const & record = cat.front();
219  _name = record.get(keys.name);
220  _pupilFactoryName = record.get(keys.pupilFactoryName);
221  _transformMap = archive.get<TransformMap>(record.get(keys.transformMap));
222 }
223 
224 
225 std::string Camera::getPersistenceName() const { return "Camera"; }
226 
227 void Camera::write(OutputArchiveHandle& handle) const {
229  auto const & keys = PersistenceHelper::get();
230  auto cat = handle.makeCatalog(keys.schema);
231  auto record = cat.addNew();
232  record->set(keys.name, getName());
233  record->set(keys.pupilFactoryName, getPupilFactoryName());
234  record->set(keys.transformMap, handle.put(getTransformMap()));
235  handle.saveCatalog(cat);
236 }
237 
238 } // namespace cameraGeom
239 
240 namespace table {
241 namespace io {
242 
243 template class PersistableFacade<cameraGeom::Camera>;
244 
245 } // namespace io
246 } // namespace table
247 
248 } // namespace afw
249 } // namespace lsst
250 
A registry of 2-dimensional coordinate transforms for a specific camera.
Definition: TransformMap.h:64
Camera coordinate system; used as a key in in TransformMap.
Definition: CameraSys.h:83
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...
bool contains(VertexIterator const begin, VertexIterator const end, UnitVector3d const &v)
std::shared_ptr< TransformMap const > getTransformMap() const noexcept
Obtain the transform registry.
Definition: Camera.h:122
A floating-point coordinate rectangle geometry.
Definition: Box.h:305
An object passed to Persistable::write to allow it to persist itself.
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:76
virtual ~Camera() noexcept
CameraSysPrefix const PIXELS
Pixel coordinates: Nominal position on the entry surface of a given detector (x, y unbinned pixels)...
Definition: CameraSys.cc:34
A base class for factory classes used to reconstruct objects from records.
Definition: Persistable.h:228
STL namespace.
std::string getName() const
Return the name of the camera.
Definition: Camera.h:72
STL class.
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:93
T push_back(T... args)
A base class for image defects.
Camera(std::string const &name, DetectorList const &detectorList, std::shared_ptr< TransformMap > transformMap, std::string const &pupilFactoryName)
Construct a camera.
Definition: Camera.cc:68
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:195
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
Definition: Persistable.h:48
static Factory const registration
Definition: Camera.cc:201
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:114
table::Schema schema
Definition: Camera.cc:161
table::Key< std::string > name
Definition: Camera.cc:162
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:137
table::Key< int > detector
T move(T... args)
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
An immutable collection of Detectors that can be accessed by name or ID.
table::Key< int > transformMap
Definition: Camera.cc:164
T size(T... args)
A vector of catalogs used by Persistable.
Definition: CatalogVector.h:29
STL class.
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
IdMap const & getIdMap() const noexcept
Get an unordered map over detector IDs.
table::Key< std::string > pupilFactoryName
Definition: Camera.cc:163
Reports invalid arguments.
Definition: Runtime.h:66
Camera & operator=(Camera const &)=delete
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
Definition: Camera.cc:227
A multi-catalog archive object used to load table::io::Persistable objects.
Definition: InputArchive.h:31
CameraSys const FOCAL_PLANE
Focal plane coordinates: Position on a 2-d planar approximation to the focal plane (x...
Definition: CameraSys.cc:30
std::shared_ptr< Persistable > get(int id) const
Load the Persistable with the given ID and return it.
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:485
std::string getPupilFactoryName() const
Return the fully-qualified name of the Python class that provides this Camera&#39;s PupilFactory.
Definition: Camera.h:77