29 #include "lsst/afw/table/io/Persistable.cc" 34 namespace cameraGeom {
41 Detector(name, id, type, serial, bbox, ampInfoCatalog, orientation, pixelSize,
43 crosstalk, physicalType)
56 _ampInfoCatalog(ampInfoCatalog),
58 _orientation(orientation),
59 _pixelSize(pixelSize),
61 _transformMap(
std::move(transformMap)),
62 _crosstalk(crosstalk),
63 _physicalType(physicalType)
66 for (
auto ampIter = _ampInfoCatalog.
begin(); ampIter != _ampInfoCatalog.
end(); ++ampIter) {
69 if (_ampNameIterMap.
size() != _ampInfoCatalog.
size()) {
71 "Invalid ampInfoCatalog: not all amplifier names are unique");
76 auto shape = _crosstalk.getShape();
77 assert(shape.size() == 2);
78 if (shape[0] != shape[1]) {
80 os <<
"Non-square crosstalk matrix: " << _crosstalk <<
" for detector \"" << _name <<
"\"";
83 if (shape[0] != _ampInfoCatalog.
size()) {
85 os <<
"Wrong size crosstalk matrix: " << _crosstalk <<
" for detector \"" << _name <<
"\"";
93 auto nativeToCameraSys = _transformMap->getTransform(_nativeSys, cameraSys);
94 return nativeToCameraSys->applyForward(nativeCorners);
115 i = _ampInfoCatalog.
size() + i;
117 return _ampInfoCatalog.
get(i);
121 _AmpInfoMap::const_iterator ampIter = _ampNameIterMap.
find(name);
122 if (ampIter == _ampNameIterMap.
end()) {
124 os <<
"Unknown amplifier \"" << name <<
"\"";
127 return ampIter->second;
136 template <
typename FromSysT,
typename ToSysT>
138 ToSysT
const &toSys)
const {
142 template <
typename FromSysT,
typename ToSysT>
144 ToSysT
const &toSys)
const {
148 template <
typename FromSysT,
typename ToSysT>
150 FromSysT
const &fromSys, ToSysT
const &toSys)
const {
156 class PersistenceHelper {
159 static PersistenceHelper
const &
get() {
160 static PersistenceHelper
const instance;
173 table::Key<lsst::geom::Angle>
yaw;
174 table::Key<lsst::geom::Angle>
pitch;
175 table::Key<lsst::geom::Angle>
roll;
180 PersistenceHelper(table::Schema
const & existing) :
182 name(schema[
"name"]),
184 type(schema[
"type"]),
185 serial(schema[
"serial"]),
186 bbox(schema[
"bbox"]),
187 pixelSize(schema[
"pixelSize"]),
188 fpPosition(schema[
"fpPosition"]),
189 refPoint(schema[
"refPoint"]),
191 pitch(schema[
"pitch"]),
192 roll(schema[
"roll"]),
193 transformMap(schema[
"transformMap"]),
194 crosstalk(schema[
"crosstalk"])
199 }
catch (pex::exceptions::NotFoundError &) {}
203 setKeyIfPresent(physicalType,
"physicalType");
208 PersistenceHelper() :
210 name(schema.addField<
std::string>(
"name",
"Name of the detector",
"", 0)),
211 id(schema.addField<
int>(
"id",
"Integer ID for the detector",
"")),
212 type(schema.addField<
int>(
"type",
"Raw DetectorType enum value",
"")),
213 serial(schema.addField<
std::string>(
"serial",
"Serial name of the detector",
"", 0)),
217 "Focal plane position of reference point",
"mm")),
219 "Pixel position of reference point",
"pixel")),
222 roll(schema.addField<
lsst::geom::Angle>(
"roll",
"Rotation about X'' (Y''=Y' to Z''), 3rd rotation")),
223 transformMap(schema.addField<
int>(
"transformMap",
"Archive ID of TransformMap",
"")),
224 crosstalk(schema.addField<table::Array<float>>(
"crosstalk",
"Crosstalk matrix, flattened",
"", 0)),
227 schema.getCitizen().markPersistent();
230 PersistenceHelper(PersistenceHelper
const &) =
delete;
231 PersistenceHelper(PersistenceHelper &&) =
delete;
233 PersistenceHelper &
operator=(PersistenceHelper
const &) =
delete;
234 PersistenceHelper &
operator=(PersistenceHelper &&) =
delete;
239 class DetectorFactory :
public table::io::PersistableFactory {
242 DetectorFactory() : PersistableFactory(
"Detector") {}
245 CatalogVector
const& catalogs)
const override {
247 auto const &
keys = PersistenceHelper(catalogs.front().getSchema());
252 auto const & record = catalogs.front().front();
255 amps.
reserve(catalogs.back().size());
259 for (
auto const & amp : catalogs.back()) {
260 amps.addNew()->assign(amp);
263 auto flattenedMatrix = record.get(
keys.crosstalk);
265 if (!flattenedMatrix.isEmpty()) {
266 crosstalk = ndarray::allocate(amps.size(), amps.size());
267 ndarray::flatten<1>(
crosstalk) = flattenedMatrix;
273 return std::make_shared<Detector>(
274 record.get(
keys.name),
277 record.get(
keys.serial),
278 record.get(
keys.bbox),
281 record.get(
keys.fpPosition),
282 record.get(
keys.refPoint),
283 record.get(
keys.yaw),
284 record.get(
keys.pitch),
285 record.get(
keys.roll)
288 archive.get<TransformMap>(record.get(
keys.transformMap)),
296 DetectorFactory
const registration;
305 return "lsst.afw.cameraGeom";
309 auto const &
keys = PersistenceHelper::get();
311 auto cat = handle.makeCatalog(
keys.schema);
312 auto record = cat.addNew();
315 record->set(
keys.type, static_cast<int>(
getType()));
327 auto flattenMatrix = [](ndarray::Array<float const, 2>
const & matrix) {
330 ndarray::Array<float, 2, 2> copied = ndarray::copy(matrix);
332 ndarray::Array<float, 1, 1> flattened = ndarray::flatten<1>(copied);
338 handle.saveCatalog(cat);
340 auto amps = handle.makeCatalog(_ampInfoCatalog.getSchema());
341 amps.assign(_ampInfoCatalog.begin(), _ampInfoCatalog.end(),
true);
342 handle.saveCatalog(amps);
349 #define INSTANTIATE(FROMSYS, TOSYS) \ 350 template std::shared_ptr<geom::TransformPoint2ToPoint2> Detector::getTransform(FROMSYS const &, \ 351 TOSYS const &) const; \ 352 template lsst::geom::Point2D Detector::transform(lsst::geom::Point2D const &, FROMSYS const &, \ 353 TOSYS const &) const; \ 354 template std::vector<lsst::geom::Point2D> Detector::transform(std::vector<lsst::geom::Point2D> const &, \ 355 FROMSYS const &, TOSYS const &) const; 367 template class PersistableFacade<cameraGeom::Detector>;
std::vector< Point2D > getCorners() const
Get the corner points.
table::Key< std::string > name
Camera coordinate system; used as a key in in TransformMap.
Detector(std::string const &name, int id, DetectorType type, std::string const &serial, lsst::geom::Box2I const &bbox, lsst::afw::table::AmpInfoCatalog const &InfoCatalog, Orientation const &orientation, lsst::geom::Extent2D const &pixelSize, TransformMap::Transforms const &transforms, CrosstalkMatrix const &crosstalk=CrosstalkMatrix(), std::string const &physicalType="")
Make a Detector.
Geometry and electronic information about raw amplifier images.
A floating-point coordinate rectangle geometry.
Point2D const getCenter() const noexcept
table::AmpInfoRecord const & operator[](size_t i) const
Get the amplifier specified by index.
BoxKey< lsst::geom::Box2I > Box2IKey
CameraSysPrefix const PIXELS
Pixel coordinates: Nominal position on the entry surface of a given detector (x, y unbinned pixels)...
table::Point2DKey refPoint
std::shared_ptr< table::AmpInfoRecord const > _get(int i) const
Get the amplifier specified by index, returning a shared pointer to an AmpInfo record.
static PointKey addFields(Schema &schema, std::string const &name, std::string const &doc, std::string const &unit)
Add a pair of _x, _y fields to a Schema, and return a PointKey that points to them.
std::string getPhysicalType() const
Get information about the physical type of the device (e.g.
PointKey< double > Point2DKey
DetectorType getType() const
Get the "type" (really purpose) of the Detector.
A class representing an angle.
Describe a detector's orientation in the focal plane.
table::Key< lsst::geom::Angle > pitch
CameraSys const makeCameraSys(CameraSys const &cameraSys) const
Get a coordinate system from a coordinate system (return input unchanged and untested) ...
Orientation const getOrientation() const
Get detector's orientation in the focal plane.
lsst::geom::Box2I getBBox() const
Get the bounding box.
A base class for image defects.
table::Key< lsst::geom::Angle > roll
std::shared_ptr< TransformMap const > getTransformMap() const
Get the transform registry.
iterator end()
Iterator access.
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
bool hasTransform(CameraSys const &cameraSys) const
Can this object convert between PIXELS and the specified camera coordinate system?
bool hasCrosstalk() const
Have we got crosstalk coefficients?
std::vector< lsst::geom::Point2D > getCorners(CameraSys const &cameraSys) const
Get the corners of the detector in the specified camera coordinate system.
CrosstalkMatrix const getCrosstalk() const
Get the crosstalk coefficients.
CatalogT< AmpInfoRecord > AmpInfoCatalog
table::Point2DKey pixelSize
lsst::geom::Point2D getCenter(CameraSys const &cameraSys) const
Get the center of the detector in the specified camera coordinate system.
Camera coordinate system prefix.
table::Point2DKey fpPosition
void reserve(size_type n)
Increase the capacity of the catalog to the given size.
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
table::Key< std::string > physicalType
std::string getName() const
Get the detector name.
Information about a CCD or other imaging detector.
table::Key< lsst::geom::Angle > yaw
Detector & operator=(Detector const &)=delete
std::shared_ptr< RecordT > const get(size_type i) const
Return a pointer to the record at index i.
int getId() const
Get the detector ID.
Reports invalid arguments.
io::OutputArchiveHandle OutputArchiveHandle
size_type size() const
Return the number of elements in the catalog.
table::Key< int > transformMap
table::Key< std::string > serial
iterator begin()
Iterator access.
table::Key< table::Array< float > > crosstalk
lsst::geom::Extent2D getPixelSize() const
Get size of pixel along (mm)
DetectorType
Type of imaging detector.
ndarray::Array< float const, 2 > CrosstalkMatrix
An integer coordinate rectangle.
static BoxKey addFields(Schema &schema, std::string const &name, std::string const &doc, std::string const &unit)
Add _min_x, _min_y, _max_x, _max_y fields to a Schema, and return a BoxKey that points to them...
std::string getSerial() const
Get the detector serial "number".
lsst::geom::Point2D transform(lsst::geom::Point2D const &point, FromSysT const &fromSys, ToSysT const &toSys) const
Transform a point from one camera system to another.
#define INSTANTIATE(FROMSYS, TOSYS)
std::shared_ptr< afw::geom::TransformPoint2ToPoint2 > getTransform(FromSysT const &fromSys, ToSysT const &toSys) const
Get a Transform from one camera coordinate system, or camera coordinate system prefix, to another.