43struct FlattenWithSetter {
44 FlattenWithSetter(T
val) : _val(
val) {}
58 FlattenWithSetter(T
val) : _mask(~
val) {}
70template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
77 _variance(
ndarray::allocate(
ndarray::makeVector(foot.getArea()))) {
106template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
112 _variance(
ndarray::allocate(
ndarray::makeVector(foot.getArea()))) {}
114template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
118 getSpans()->unflatten(mimage.
getMask()->getArray(), _mask, mimage.
getXY0());
119 getSpans()->unflatten(mimage.
getVariance()->getArray(), _variance, mimage.
getXY0());
122template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
124 getSpans()->unflatten(
image.getArray(), _image,
image.getXY0());
127template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
147 return std::make_shared<HeavyFootprint<ImagePixelT, MaskPixelT, VariancePixelT>>(*foot, im1);
150template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
154 using ArrayIter =
typename ndarray::Array<const ImagePixelT, 1, 1>::Iterator;
155 ArrayIter lhsArray = getImageArray().begin(), rhsArray = rhs.
getImageArray().begin();
156 auto lhsIter = getSpans()->begin(), rhsIter = rhs.
getSpans()->begin();
157 auto const lhsEnd = getSpans()->end(), rhsEnd = rhs.
getSpans()->end();
159 while (lhsIter != lhsEnd && rhsIter != rhsEnd) {
160 geom::Span
const &lhsSpan = *lhsIter, rhsSpan = *rhsIter;
161 int const yLhs = lhsSpan.getY(), yRhs = rhsSpan.getY();
163 int const x0Lhs = lhsSpan.getX0(), x1Lhs = lhsSpan.getX1();
164 int const x0Rhs = rhsSpan.getX0(), x1Rhs = rhsSpan.getX1();
167 lhsArray += xMin - x0Lhs;
168 rhsArray += xMin - x0Rhs;
169 for (
int x = xMin;
x <= xMax; ++
x, ++lhsArray, ++rhsArray) {
170 sum += (*lhsArray) * (*rhsArray);
173 lhsArray -= xMax + 1 - x0Lhs;
174 rhsArray -= xMax + 1 - x0Rhs;
176 if (x1Lhs <= x1Rhs) {
177 lhsArray += lhsSpan.getWidth();
180 rhsArray += rhsSpan.getWidth();
184 }
else if (yLhs < yRhs) {
185 while (lhsIter != lhsEnd && lhsIter->getY() < yRhs) {
186 lhsArray += lhsIter->getWidth();
191 while (rhsIter != rhsEnd && rhsIter->getY() < yLhs) {
192 rhsArray += rhsIter->getWidth();
210struct HeavyFootprintPersistenceHelper {
212 afw::table::Key<afw::table::Array<ImagePixelT>>
image;
213 afw::table::Key<afw::table::Array<MaskPixelT>>
mask;
214 afw::table::Key<afw::table::Array<VariancePixelT>>
variance;
216 static HeavyFootprintPersistenceHelper
const& get() {
217 static HeavyFootprintPersistenceHelper
const instance;
222 HeavyFootprintPersistenceHelper()
225 "image",
"image pixels for HeavyFootprint",
"count")),
226 mask(
schema.addField<
afw::table::Array<MaskPixelT>>(
"mask",
"mask pixels for HeavyFootprint")),
228 "variance",
"variance pixels for HeavyFootprint",
"count^2")) {}
240struct ComputeSuffix<
std::uint16_t> {
244struct ComputeSuffix<float> {
248struct ComputeSuffix<double> {
252struct ComputeSuffix<int> {
258template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
260 return "HeavyFootprint" + ComputeSuffix<ImagePixelT, MaskPixelT, VariancePixelT>::apply();
263template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
265 HeavyFootprintPersistenceHelper<ImagePixelT, MaskPixelT, VariancePixelT>
const& keys =
266 HeavyFootprintPersistenceHelper<ImagePixelT, MaskPixelT, VariancePixelT>::get();
275 record->set(keys.image, ndarray::const_array_cast<ImagePixelT>(getImageArray()));
276 record->set(keys.mask, ndarray::const_array_cast<MaskPixelT>(getMaskArray()));
277 record->set(keys.variance, ndarray::const_array_cast<VariancePixelT>(getVarianceArray()));
281template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
289 HeavyFootprintPersistenceHelper<ImagePixelT, MaskPixelT, VariancePixelT>
const& keys =
290 HeavyFootprintPersistenceHelper<ImagePixelT, MaskPixelT, VariancePixelT>::get();
291 HeavyFootprintPersistenceHelper<ImagePixelT, std::uint16_t, VariancePixelT>
const& legacyKeys =
292 HeavyFootprintPersistenceHelper<ImagePixelT, std::uint16_t, VariancePixelT>::get();
298 readPeaks(catalogs[1], *loadedFootprint);
303 std::make_shared<HeavyFootprint<ImagePixelT, MaskPixelT, VariancePixelT>>(*loadedFootprint);
304 result->_image = ndarray::const_array_cast<ImagePixelT>(record.
get(keys.image));
307 if (catalogs[2].getSchema() == legacyKeys.schema) {
308 auto legacyMask = ndarray::const_array_cast<std::uint16_t>(record.
get(legacyKeys.mask));
309 result->_mask.deep() = legacyMask;
311 result->_mask = ndarray::const_array_cast<MaskPixelT>(record.
get(keys.mask));
313 result->_variance = ndarray::const_array_cast<VariancePixelT>(record.
get(keys.variance));
321template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
324 "HeavyFootprint" + ComputeSuffix<ImagePixelT, MaskPixelT, VariancePixelT>::apply());
331#define INSTANTIATE(TYPE) \
332 template std::shared_ptr<detection::HeavyFootprint<TYPE>> \
333 table::io::PersistableFacade<detection::HeavyFootprint<TYPE>>::dynamicCast( \
334 std::shared_ptr<table::io::Persistable> const&); \
335 template class detection::HeavyFootprint<TYPE>; \
336 template std::shared_ptr<detection::HeavyFootprint<TYPE>> detection::mergeHeavyFootprints<TYPE>( \
337 detection::HeavyFootprint<TYPE> const&, detection::HeavyFootprint<TYPE> const&);
table::Key< std::string > name
#define INSTANTIATE(FROMSYS, TOSYS)
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
A class to represent a 2-dimensional array of pixels.
A class to manipulate images, masks, and variance as a single object.
lsst::geom::Point2I getXY0() const
Return the image's origin.
VariancePtr getVariance() const
Return a (shared_ptr to) the MaskedImage's variance.
MaskPtr getMask() const
Return a (shared_ptr to) the MaskedImage's mask.
ImagePtr getImage() const
Return a (shared_ptr to) the MaskedImage's image.
Base class for all records.
Field< T >::Value get(Key< T > const &key) const
Return the value of a field for the given key.
std::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
A vector of catalogs used by Persistable.
An object passed to Persistable::write to allow it to persist itself.
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
A base class for factory classes used to reconstruct objects from records.
An integer coordinate rectangle.
std::shared_ptr< HeavyFootprint< ImagePixelT, MaskPixelT, VariancePixelT > > mergeHeavyFootprints(HeavyFootprint< ImagePixelT, MaskPixelT, VariancePixelT > const &h1, HeavyFootprint< ImagePixelT, MaskPixelT, VariancePixelT > const &h2)
Sum the two given HeavyFootprints h1 and h2, returning a HeavyFootprint with the union footprint,...
std::shared_ptr< Footprint > mergeFootprints(Footprint const &footprint1, Footprint const &footprint2)
Merges two Footprints – appends their peaks, and unions their spans, returning a new Footprint.
float VariancePixel
default type for MaskedImage variance images
std::int32_t MaskPixel
default type for Masks and MaskedImage Masks
details::ImageNdGetter< T, inA, inB > ndImage(ndarray::Array< T, inA, inB > const &array, lsst::geom::Point2I xy0=lsst::geom::Point2I())
Marks a ndarray to be interpreted as an image when applying a functor from a SpanSet.
details::FlatNdGetter< T, inA, inB > ndFlat(ndarray::Array< T, inA, inB > const &array)
Marks a ndarray to be interpreted as a 1D vector when applying a functor from a SpanSet.