24 #include <unordered_set>
35 namespace cameraGeom {
44 template <
typename Iter>
49 pex::exceptions::InvalidParameterError,
59 return std::make_shared<PartialRebuilder>(*
this);
64 auto nativeToCameraSys = _transformMap->getTransform(
getNativeCoordSys(), cameraSys);
65 return nativeToCameraSys->applyForward(nativeCorners);
88 template <
typename FromSysT,
typename ToSysT>
90 ToSysT
const &toSys)
const {
94 template <
typename FromSysT,
typename ToSysT>
96 ToSysT
const &toSys)
const {
100 template <
typename FromSysT,
typename ToSysT>
102 FromSysT
const &fromSys, ToSysT
const &toSys)
const {
107 return *findAmpIterByName(_amplifiers.begin(), _amplifiers.end(),
name);
112 void checkForDuplicateAmpNames(AmpVector
const & amplifiers) {
114 for (
auto const &
ptr : amplifiers) {
115 if (!amplifierNames.
insert(
ptr->getName()).second) {
117 (
boost::format(
"Multiple amplifiers with name %s") %
ptr->getName()).str());
125 assert(shape.size() == 2);
126 if (shape[0] != shape[1]) {
131 if (shape[0] != nAmps) {
141 AmpVector &&lifiers) :
144 checkForDuplicateAmpNames(_amplifiers);
152 class PersistenceHelper {
155 static PersistenceHelper
const & get() {
156 static PersistenceHelper
const instance;
169 table::Key<lsst::geom::Angle>
yaw;
170 table::Key<lsst::geom::Angle>
pitch;
171 table::Key<lsst::geom::Angle>
roll;
176 PersistenceHelper(table::Schema
const & existing) :
195 }
catch (pex::exceptions::NotFoundError &) {}
204 PersistenceHelper() :
206 name(
schema.addField<
std::string>(
"name",
"Name of the detector",
"", 0)),
207 id(
schema.addField<int>(
"id",
"Integer ID for the detector",
"")),
208 type(
schema.addField<int>(
"type",
"Raw DetectorType enum value",
"")),
209 serial(
schema.addField<
std::string>(
"serial",
"Serial name of the detector",
"", 0)),
213 "Focal plane position of reference point",
"mm")),
215 "Pixel position of reference point",
"pixel")),
220 crosstalk(
schema.addField<table::Array<float>>(
"crosstalk",
"Crosstalk matrix, flattened",
"", 0)),
224 PersistenceHelper(PersistenceHelper
const &) =
delete;
225 PersistenceHelper(PersistenceHelper &&) =
delete;
227 PersistenceHelper &
operator=(PersistenceHelper
const &) =
delete;
228 PersistenceHelper &
operator=(PersistenceHelper &&) =
delete;
242 auto const &
keys = PersistenceHelper(catalogs.
front().getSchema());
247 auto const & record = catalogs.
front().front();
250 amps.reserve(catalogs.
back().size());
251 for (
auto const & record : catalogs.
back()) {
255 auto flattenedMatrix = record.get(
keys.crosstalk);
257 if (!flattenedMatrix.isEmpty()) {
258 crosstalk = ndarray::allocate(amps.size(), amps.size());
259 ndarray::flatten<1>(
crosstalk) = flattenedMatrix;
265 record.get(
keys.name),
268 record.get(
keys.serial),
269 record.get(
keys.bbox),
271 record.get(
keys.fpPosition),
272 record.get(
keys.refPoint),
273 record.get(
keys.yaw),
274 record.get(
keys.pitch),
275 record.get(
keys.roll)
302 return "lsst.afw.cameraGeom";
305 void Detector::write(OutputArchiveHandle& handle)
const {
306 auto const &
keys = PersistenceHelper::get();
308 auto cat = handle.makeCatalog(
keys.schema);
309 auto record = cat.addNew();
312 record->set(
keys.type,
static_cast<int>(
getType()));
324 auto flattenMatrix = [](ndarray::Array<float const, 2>
const & matrix) {
327 ndarray::Array<float, 2, 2> copied = ndarray::copy(matrix);
329 ndarray::Array<float, 1, 1> flattened = ndarray::flatten<1>(copied);
335 handle.saveCatalog(cat);
340 auto record = ampCat.addNew();
341 amp->toRecord(*record);
343 handle.saveCatalog(ampCat);
348 return *findAmpIterByName(_amplifiers.begin(), _amplifiers.end(),
name);
352 _amplifiers.push_back(
std::move(builder));
360 for (
auto const & ampPtr :
detector) {
361 result.push_back(std::make_shared<Amplifier::Builder>(*ampPtr));
375 result.reserve(_amplifiers.size());
376 for (
auto const & ampBuilderPtr : _amplifiers) {
377 result.push_back(ampBuilderPtr->finish());
400 template <
typename Iter>
401 Iter findConnection(Iter
first, Iter last,
CameraSys const & toSys) {
404 [&toSys](
auto const & connection) {
405 return connection.toSys == toSys;
427 (
boost::format(
"Cannot add coordinate system for detector '%s' to detector '%s'.") %
431 auto iter = findConnection(_connections.begin(), _connections.end(), toSys);
432 if (
iter == _connections.end()) {
433 _connections.push_back(
449 (
boost::format(
"Cannot add coordinate system for detector '%s' to detector '%s'.") %
453 auto iter = findConnection(_connections.begin(), _connections.end(), toSys);
454 if (
iter != _connections.end()) {
455 _connections.erase(
iter);
466 Detector::InCameraBuilder::InCameraBuilder(
std::string const &
name,
int id) :
474 auto amplifiers = finishAmplifiers();
484 #define INSTANTIATE(FROMSYS, TOSYS) \
485 template std::shared_ptr<geom::TransformPoint2ToPoint2> Detector::getTransform(FROMSYS const &, \
486 TOSYS const &) const; \
487 template lsst::geom::Point2D Detector::transform(lsst::geom::Point2D const &, FROMSYS const &, \
488 TOSYS const &) const; \
489 template std::vector<lsst::geom::Point2D> Detector::transform(std::vector<lsst::geom::Point2D> const &, \
490 FROMSYS const &, TOSYS const &) const;
502 template class PersistableFacade<cameraGeom::Detector>;
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
static Builder fromRecord(table::BaseRecord const &record)
Construct a new Builder object from the fields in the given record.
static table::Schema getRecordSchema()
Return the schema used in the afw.table representation of amplifiers.
Camera coordinate system; used as a key in in TransformMap.
std::string getDetectorName() const
Get detector name, or "" if not a detector-specific coordinate system.
Camera coordinate system prefix.
A helper class for Detector that allows amplifiers and most fields to be modified.
~Builder() noexcept override=0
Builder(Builder const &)=delete
static std::vector< std::shared_ptr< Amplifier::Builder > > rebuildAmplifiers(Detector const &detector)
Create a vector of Amplifier::Builders from the Amplifiers in a Detector.
std::shared_ptr< Amplifier::Builder > operator[](size_t i) const
Get the amplifier builder specified by index.
void append(std::shared_ptr< Amplifier::Builder > builder)
Append a new amplifier.
std::shared_ptr< table::io::Persistable > read(InputArchive const &archive, CatalogVector const &catalogs) const override
Construct a new object from the given InputArchive and vector of catalogs.
static Factory const registration
void setTransformFromPixelsTo(CameraSysPrefix const &toSys, std::shared_ptr< afw::geom::TransformPoint2ToPoint2 const > transform)
Set the transformation from PIXELS to the given coordinate system.
bool discardTransformFromPixelsTo(CameraSysPrefix const &toSys)
Remove any transformation from PIXELS to the given coordinate system.
PartialRebuilder(Detector const &detector)
Construct a PartialRebuilder initialized to the state of the given Detector.
std::shared_ptr< Detector const > finish() const
Construct a new Detector from the current state of the Builder.
lsst::geom::Box2I getBBox() const
Get the bounding box.
lsst::geom::Extent2D getPixelSize() const
Get size of pixel along (mm)
std::string getName() const
Get the detector name.
CameraSys getNativeCoordSys() const
The "native" coordinate system of this detector.
bool hasCrosstalk() const
Have we got crosstalk coefficients?
int getId() const
Get the detector ID.
std::string getPhysicalType() const
Get the detector's physical type.
Orientation getOrientation() const
Get detector's orientation in the focal plane.
std::string getSerial() const
Get the detector serial "number".
CameraSys makeCameraSys(CameraSys const &cameraSys) const
Get a coordinate system from a coordinate system (return input unchanged and untested)
CrosstalkMatrix getCrosstalk() const
Get the crosstalk coefficients.
ndarray::Array< float const, 2 > CrosstalkMatrix
DetectorType getType() const
Return the purpose of this detector.
A representation of a detector in a mosaic camera.
Fields const & getFields() const override
Return a reference to a Fields struct.
bool hasTransform(CameraSys const &cameraSys) const
Can this object convert between PIXELS and the specified camera coordinate system?
std::size_t size() const
Get the number of amplifiers.
std::shared_ptr< TransformMap const > getTransformMap() const
Get the transform registry.
std::vector< std::shared_ptr< Amplifier const > > const & getAmplifiers() const
Return the sequence of Amplifiers directly.
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.
std::vector< lsst::geom::Point2D > getCorners(CameraSys const &cameraSys) const
Get the corners of the detector in the specified camera coordinate system.
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,...
lsst::geom::Point2D getCenter(CameraSys const &cameraSys) const
Get the center of the detector in the specified camera coordinate system.
std::shared_ptr< PartialRebuilder > rebuild() const
Return a Builder object initialized with the state of this Detector.
std::shared_ptr< Amplifier const > operator[](size_t i) const
Get the amplifier specified by index.
Describe a detector's orientation in the focal plane.
A vector of catalogs used by Persistable.
A base class for factory classes used to reconstruct objects from records.
PersistableFactory(std::string const &name)
Constructor for the factory.
A floating-point coordinate rectangle geometry.
Point2D const getCenter() const noexcept
Return true if the box contains no points.
std::vector< Point2D > getCorners() const
Get the corner points.
Reports invalid arguments.
CameraSysPrefix const PIXELS
Pixel coordinates: Nominal position on the entry surface of a given detector (x, y unbinned pixels).
DetectorType
Type of imaging detector.
FilterProperty & operator=(FilterProperty const &)=default
BoxKey< lsst::geom::Box2I > Box2IKey
PointKey< double > Point2DKey
Extent< double, 2 > Extent2D
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
int orientation(UnitVector3d const &a, UnitVector3d const &b, UnitVector3d const &c)
orientation computes and returns the orientations of 3 unit vectors a, b and c.
A base class for image defects.
table::Key< std::string > name
table::Point2DKey refPoint
table::Key< lsst::geom::Angle > yaw
table::Key< lsst::geom::Angle > roll
#define INSTANTIATE(FROMSYS, TOSYS)
table::Key< std::string > physicalType
table::Key< int > transformMap
table::Point2DKey fpPosition
table::Point2DKey pixelSize
table::Key< lsst::geom::Angle > pitch
table::Key< std::string > serial
table::Key< table::Array< float > > crosstalk
table::Key< int > detector