24 #include <unordered_set> 35 namespace cameraGeom {
44 template <
typename Iter>
49 pex::exceptions::InvalidParameterError,
50 (
boost::format(
"Amplifier with name %s not found.") % name).str()
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) {
117 (
boost::format(
"Multiple amplifiers with name %s") %
ptr->getName()).str());
124 auto shape = crosstalk.getShape();
125 assert(shape.size() == 2);
126 if (shape[0] != shape[1]) {
128 os <<
"Non-square crosstalk matrix: " << crosstalk <<
" for detector \"" << detectorName <<
"\"";
131 if (shape[0] != nAmps) {
133 os <<
"Wrong size crosstalk matrix: " << crosstalk <<
" for detector \"" << detectorName <<
"\"";
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) :
178 name(schema[
"name"]),
180 type(schema[
"type"]),
181 serial(schema[
"serial"]),
182 bbox(schema[
"bbox"]),
183 pixelSize(schema[
"pixelSize"]),
184 fpPosition(schema[
"fpPosition"]),
185 refPoint(schema[
"refPoint"]),
187 pitch(schema[
"pitch"]),
188 roll(schema[
"roll"]),
189 transformMap(schema[
"transformMap"]),
190 crosstalk(schema[
"crosstalk"])
195 }
catch (pex::exceptions::NotFoundError &) {}
199 setKeyIfPresent(physicalType,
"physicalType");
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")),
218 roll(schema.addField<
lsst::geom::Angle>(
"roll",
"Rotation about X'' (Y''=Y' to Z''), 3rd rotation")),
219 transformMap(schema.addField<
int>(
"transformMap",
"Archive ID of TransformMap",
"")),
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";
306 auto const &
keys = PersistenceHelper::get();
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);
340 auto record = ampCat.addNew();
341 amp->toRecord(*record);
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());
384 Builder(detector._fields, rebuildAmplifiers(detector)),
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) :
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>;
PartialRebuilder(Detector const &detector)
Construct a PartialRebuilder initialized to the state of the given Detector.
DetectorBase & operator=(DetectorBase const &)=default
DetectorBase has no state, and is hence default-constructable, copyable, and movable.
Orientation getOrientation() const
Get detector's orientation in the focal plane.
lsst::geom::Box2I getBBox() const
Get the bounding box.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
table::Key< std::string > name
Camera coordinate system; used as a key in in TransformMap.
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...
An object passed to Persistable::write to allow it to persist itself.
lsst::geom::Extent2D getPixelSize() const
Get size of pixel along (mm)
BoxKey< lsst::geom::Box2I > Box2IKey
void append(std::shared_ptr< Amplifier::Builder > builder)
Append a new amplifier.
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
std::shared_ptr< Amplifier::Builder > operator[](size_t i) const
Get the amplifier builder specified by index.
Fields const & getFields() const override
An iterator range over amplifers.
CameraSysPrefix const PIXELS
Pixel coordinates: Nominal position on the entry surface of a given detector (x, y unbinned pixels)...
A base class for factory classes used to reconstruct objects from records.
Fields const & getFields() const override
Return a reference to a Fields struct.
table::Point2DKey refPoint
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.
DetectorType getType() const
Return the purpose of this detector.
CameraSys makeCameraSys(CameraSys const &cameraSys) const
Get a coordinate system from a coordinate system (return input unchanged and untested) ...
PointKey< double > Point2DKey
int getId() const
Get the detector ID.
bool discardTransformFromPixelsTo(CameraSysPrefix const &toSys)
Remove any transformation from PIXELS to the given coordinate system.
std::string getPhysicalType() const
Get the detector's physical type.
A class representing an angle.
Describe a detector's orientation in the focal plane.
std::string getSerial() const
Get the detector serial "number".
table::Key< lsst::geom::Angle > pitch
Builder(Builder const &)=delete
A helper class for Detector that allows amplifiers and most fields to be modified.
std::shared_ptr< PartialRebuilder > rebuild() const
Return a Builder object initialized with the state of this Detector.
std::string getName() const
Get the detector name.
A base class for image defects.
std::string getDetectorName() const
Get detector name, or "" if not a detector-specific coordinate system.
CrosstalkMatrix getCrosstalk() const
Get the crosstalk coefficients.
table::Key< lsst::geom::Angle > roll
std::shared_ptr< TransformMap const > getTransformMap() const
Get the transform registry.
bool hasTransform(CameraSys const &cameraSys) const
Can this object convert between PIXELS and the specified camera coordinate system?
std::vector< lsst::geom::Point2D > getCorners(CameraSys const &cameraSys) const
Get the corners of the detector in the specified camera coordinate system.
table::Key< int > detector
table::Point2DKey pixelSize
lsst::geom::Point2D getCenter(CameraSys const &cameraSys) const
Get the center of the detector in the specified camera coordinate system.
static Factory const registration
static Builder fromRecord(table::BaseRecord const &record)
Construct a new Builder object from the fields in the given record.
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
Camera coordinate system prefix.
table::Point2DKey fpPosition
void reserve(size_type n)
Increase the capacity of the catalog to the given size.
~Builder() noexcept override=0
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
A vector of catalogs used by Persistable.
table::Key< std::string > physicalType
A representation of a detector in a mosaic camera.
std::shared_ptr< Detector const > finish() const
Construct a new Detector from the current state of the Builder.
table::Key< lsst::geom::Angle > yaw
std::size_t size() const
Get the number of amplifiers.
bool hasCrosstalk() const
Have we got crosstalk coefficients?
CameraSys getNativeCoordSys() const
The "native" coordinate system of this detector.
Reports invalid arguments.
std::shared_ptr< Amplifier const > operator[](size_t i) const
Get the amplifier specified by index.
std::vector< std::shared_ptr< Amplifier const > > finishAmplifiers() const
Create a vector of Amplifiers from the Amplifier::Builder sequence.
static std::vector< std::shared_ptr< Amplifier::Builder > > rebuildAmplifiers(Detector const &detector)
Create a vector of Amplifier::Builders from the Amplifiers in a Detector.
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
table::Key< int > transformMap
table::Key< std::string > serial
std::vector< std::shared_ptr< Amplifier const > > const & getAmplifiers() const
Return the sequence of Amplifiers directly.
table::Key< table::Array< float > > crosstalk
DetectorType
Type of imaging detector.
ndarray::Array< float const, 2 > CrosstalkMatrix
void setTransformFromPixelsTo(CameraSysPrefix const &toSys, std::shared_ptr< afw::geom::TransformPoint2ToPoint2 const > transform)
Set the transformation from PIXELS to the given coordinate system.
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...
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< table::io::Persistable > read(InputArchive const &archive, CatalogVector const &catalogs) const override
Construct a new object from the given InputArchive and vector of catalogs.
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.
std::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
static table::Schema getRecordSchema()
Return the schema used in the afw.table representation of amplifiers.