29 #include "lsst/afw/table/io/Persistable.cc" 34 namespace cameraGeom {
40 Detector(name, id, type, serial, bbox, ampInfoCatalog, orientation, pixelSize,
54 _ampInfoCatalog(ampInfoCatalog),
56 _orientation(orientation),
57 _pixelSize(pixelSize),
59 _transformMap(
std::move(transformMap)),
63 for (
auto ampIter = _ampInfoCatalog.
begin(); ampIter != _ampInfoCatalog.
end(); ++ampIter) {
66 if (_ampNameIterMap.
size() != _ampInfoCatalog.
size()) {
68 "Invalid ampInfoCatalog: not all amplifier names are unique");
73 auto shape = _crosstalk.getShape();
74 assert(shape.size() == 2);
75 if (shape[0] != shape[1]) {
77 os <<
"Non-square crosstalk matrix: " << _crosstalk <<
" for detector \"" << _name <<
"\"";
80 if (shape[0] != _ampInfoCatalog.
size()) {
82 os <<
"Wrong size crosstalk matrix: " << _crosstalk <<
" for detector \"" << _name <<
"\"";
90 auto nativeToCameraSys = _transformMap->getTransform(_nativeSys, cameraSys);
91 return nativeToCameraSys->applyForward(nativeCorners);
112 i = _ampInfoCatalog.
size() + i;
114 return _ampInfoCatalog.
get(i);
118 _AmpInfoMap::const_iterator ampIter = _ampNameIterMap.
find(name);
119 if (ampIter == _ampNameIterMap.
end()) {
121 os <<
"Unknown amplifier \"" << name <<
"\"";
124 return ampIter->second;
133 template <
typename FromSysT,
typename ToSysT>
135 ToSysT
const &toSys)
const {
139 template <
typename FromSysT,
typename ToSysT>
141 ToSysT
const &toSys)
const {
145 template <
typename FromSysT,
typename ToSysT>
147 FromSysT
const &fromSys, ToSysT
const &toSys)
const {
153 class PersistenceHelper {
156 static PersistenceHelper
const &
get() {
157 static PersistenceHelper
const instance;
170 table::Key<lsst::geom::Angle>
yaw;
171 table::Key<lsst::geom::Angle>
pitch;
172 table::Key<lsst::geom::Angle>
roll;
178 PersistenceHelper() :
180 name(schema.addField<
std::string>(
"name",
"Name of the detector",
"", 0)),
181 id(schema.addField<
int>(
"id",
"Integer ID for the detector",
"")),
182 type(schema.addField<
int>(
"type",
"Raw DetectorType enum value",
"")),
183 serial(schema.addField<
std::string>(
"serial",
"Serial name of the detector",
"", 0)),
184 bbox(table::
Box2IKey::addFields(schema,
"bbox",
"Detector bounding box",
"pixel")),
185 pixelSize(table::
Point2DKey::addFields(schema,
"pixelSize",
"Physical pixel size",
"mm")),
186 fpPosition(table::
Point2DKey::addFields(schema,
"fpPosition",
187 "Focal plane position of reference point",
"mm")),
188 refPoint(table::
Point2DKey::addFields(schema,
"refPoint",
189 "Pixel position of reference point",
"pixel")),
190 yaw(schema.addField<
lsst::geom::
Angle>(
"yaw",
"Rotation about Z (X to Y), 1st rotation")),
191 pitch(schema.addField<
lsst::geom::
Angle>(
"pitch",
"Rotation about Y' (Z'=Z to X'), 2nd rotation")),
192 roll(schema.addField<
lsst::geom::
Angle>(
"roll",
"Rotation about X'' (Y''=Y' to Z''), 3rd rotation")),
193 transformMap(schema.addField<
int>(
"transformMap",
"Archive ID of TransformMap",
"")),
194 crosstalk(schema.addField<table::Array<
float>>(
"crosstalk",
"Crosstalk matrix, flattened",
"", 0))
196 schema.getCitizen().markPersistent();
199 PersistenceHelper(PersistenceHelper
const &) =
delete;
200 PersistenceHelper(PersistenceHelper &&) =
delete;
202 PersistenceHelper &
operator=(PersistenceHelper
const &) =
delete;
203 PersistenceHelper &
operator=(PersistenceHelper &&) =
delete;
208 class DetectorFactory :
public table::io::PersistableFactory {
211 DetectorFactory() : PersistableFactory(
"Detector") {}
214 CatalogVector
const& catalogs)
const override {
215 auto const &
keys = PersistenceHelper::get();
220 auto const & record = catalogs.front().front();
223 amps.
reserve(catalogs.back().size());
227 for (
auto const & amp : catalogs.back()) {
228 amps.addNew()->assign(amp);
231 auto flattenedMatrix = record.get(
keys.crosstalk);
233 if (!flattenedMatrix.isEmpty()) {
234 crosstalk = ndarray::allocate(amps.size(), amps.size());
235 ndarray::flatten<1>(
crosstalk) = flattenedMatrix;
238 return std::make_shared<Detector>(
239 record.get(
keys.name),
242 record.get(
keys.serial),
243 record.get(
keys.bbox),
246 record.get(
keys.fpPosition),
247 record.get(
keys.refPoint),
248 record.get(
keys.yaw),
249 record.get(
keys.pitch),
250 record.get(
keys.roll)
253 archive.get<TransformMap>(record.get(
keys.transformMap)),
260 DetectorFactory
const registration;
269 return "lsst.afw.cameraGeom";
273 auto const &
keys = PersistenceHelper::get();
275 auto cat = handle.makeCatalog(
keys.schema);
276 auto record = cat.addNew();
279 record->set(
keys.type, static_cast<int>(
getType()));
291 auto flattenMatrix = [](ndarray::Array<float const, 2>
const & matrix) {
294 ndarray::Array<float, 2, 2> copied = ndarray::copy(matrix);
296 ndarray::Array<float, 1, 1> flattened = ndarray::flatten<1>(copied);
301 handle.saveCatalog(cat);
303 auto amps = handle.makeCatalog(_ampInfoCatalog.getSchema());
304 amps.assign(_ampInfoCatalog.begin(), _ampInfoCatalog.end(),
true);
305 handle.saveCatalog(amps);
312 #define INSTANTIATE(FROMSYS, TOSYS) \ 313 template std::shared_ptr<geom::TransformPoint2ToPoint2> Detector::getTransform(FROMSYS const &, \ 314 TOSYS const &) const; \ 315 template lsst::geom::Point2D Detector::transform(lsst::geom::Point2D const &, FROMSYS const &, \ 316 TOSYS const &) const; \ 317 template std::vector<lsst::geom::Point2D> Detector::transform(std::vector<lsst::geom::Point2D> const &, \ 318 FROMSYS const &, TOSYS const &) const; 330 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.
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
Nominal pixels on the detector (unbinned) This ignores manufacturing imperfections, "tree ring" distortions and all other such effects.
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.
PointKey< double > Point2DKey
DetectorType getType() const
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.
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.
std::string getName() const
Get the detector name.
Information about a CCD or other imaging detector.
table::Key< lsst::geom::Angle > yaw
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
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
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())
Make a Detector.
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.
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.