28 #include "boost/format.hpp"
47 struct FlattenWithSetter {
48 FlattenWithSetter(T
val) : _val(
val) {}
62 FlattenWithSetter(T
val) : _mask(~
val) {}
74 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
81 _variance(
ndarray::allocate(
ndarray::makeVector(foot.getArea()))) {
110 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
116 _variance(
ndarray::allocate(
ndarray::makeVector(foot.getArea()))) {}
118 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
122 getSpans()->unflatten(mimage.
getMask()->getArray(), _mask, mimage.
getXY0());
123 getSpans()->unflatten(mimage.
getVariance()->getArray(), _variance, mimage.
getXY0());
126 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
128 getSpans()->unflatten(
image.getArray(), _image,
image.getXY0());
131 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
151 return std::make_shared<HeavyFootprint<ImagePixelT, MaskPixelT, VariancePixelT>>(*foot, im1);
154 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
159 ArrayIter lhsArray = getImageArray().begin(), rhsArray = rhs.
getImageArray().begin();
160 auto lhsIter = getSpans()->begin(), rhsIter = rhs.
getSpans()->begin();
161 auto const lhsEnd = getSpans()->end(), rhsEnd = rhs.
getSpans()->end();
163 while (lhsIter != lhsEnd && rhsIter != rhsEnd) {
164 geom::Span
const &lhsSpan = *lhsIter, rhsSpan = *rhsIter;
165 int const yLhs = lhsSpan.getY(), yRhs = rhsSpan.getY();
167 int const x0Lhs = lhsSpan.getX0(), x1Lhs = lhsSpan.getX1();
168 int const x0Rhs = rhsSpan.getX0(), x1Rhs = rhsSpan.getX1();
171 lhsArray += xMin - x0Lhs;
172 rhsArray += xMin - x0Rhs;
173 for (
int x = xMin;
x <= xMax; ++
x, ++lhsArray, ++rhsArray) {
174 sum += (*lhsArray) * (*rhsArray);
177 lhsArray -= xMax + 1 - x0Lhs;
178 rhsArray -= xMax + 1 - x0Rhs;
180 if (x1Lhs <= x1Rhs) {
181 lhsArray += lhsSpan.getWidth();
184 rhsArray += rhsSpan.getWidth();
188 }
else if (yLhs < yRhs) {
189 while (lhsIter != lhsEnd && lhsIter->getY() < yRhs) {
190 lhsArray += lhsIter->getWidth();
195 while (rhsIter != rhsEnd && rhsIter->getY() < yLhs) {
196 rhsArray += rhsIter->getWidth();
214 struct HeavyFootprintPersistenceHelper {
216 afw::table::Key<afw::table::Array<ImagePixelT>>
image;
217 afw::table::Key<afw::table::Array<MaskPixelT>>
mask;
218 afw::table::Key<afw::table::Array<VariancePixelT>>
variance;
220 static HeavyFootprintPersistenceHelper
const& get() {
221 static HeavyFootprintPersistenceHelper
const instance;
226 HeavyFootprintPersistenceHelper()
229 "image",
"image pixels for HeavyFootprint",
"count")),
230 mask(
schema.addField<
afw::table::Array<MaskPixelT>>(
"mask",
"mask pixels for HeavyFootprint")),
232 "variance",
"variance pixels for HeavyFootprint",
"count^2")) {}
242 struct ComputeSuffix;
244 struct ComputeSuffix<
std::uint16_t> {
248 struct ComputeSuffix<float> {
252 struct ComputeSuffix<double> {
256 struct ComputeSuffix<int> {
262 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
264 return "HeavyFootprint" + ComputeSuffix<ImagePixelT, MaskPixelT, VariancePixelT>::apply();
267 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
269 HeavyFootprintPersistenceHelper<ImagePixelT, MaskPixelT, VariancePixelT>
const&
keys =
270 HeavyFootprintPersistenceHelper<ImagePixelT, MaskPixelT, VariancePixelT>::get();
279 record->set(
keys.image, ndarray::const_array_cast<ImagePixelT>(getImageArray()));
280 record->set(
keys.mask, ndarray::const_array_cast<MaskPixelT>(getMaskArray()));
281 record->set(
keys.variance, ndarray::const_array_cast<VariancePixelT>(getVarianceArray()));
285 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
293 HeavyFootprintPersistenceHelper<ImagePixelT, MaskPixelT, VariancePixelT>
const&
keys =
294 HeavyFootprintPersistenceHelper<ImagePixelT, MaskPixelT, VariancePixelT>::get();
295 HeavyFootprintPersistenceHelper<ImagePixelT, std::uint16_t, VariancePixelT>
const& legacyKeys =
296 HeavyFootprintPersistenceHelper<ImagePixelT, std::uint16_t, VariancePixelT>::get();
302 readPeaks(catalogs[1], *loadedFootprint);
307 std::make_shared<HeavyFootprint<ImagePixelT, MaskPixelT, VariancePixelT>>(*loadedFootprint);
308 result->_image = ndarray::const_array_cast<ImagePixelT>(record.
get(
keys.image));
311 if (catalogs[2].getSchema() == legacyKeys.schema) {
312 auto legacyMask = ndarray::const_array_cast<std::uint16_t>(record.
get(legacyKeys.mask));
313 result->_mask.deep() = legacyMask;
315 result->_mask = ndarray::const_array_cast<MaskPixelT>(record.
get(
keys.mask));
317 result->_variance = ndarray::const_array_cast<VariancePixelT>(record.
get(
keys.variance));
325 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
328 "HeavyFootprint" + ComputeSuffix<ImagePixelT, MaskPixelT, VariancePixelT>::apply());
335 #define INSTANTIATE(TYPE) \
336 template std::shared_ptr<detection::HeavyFootprint<TYPE>> \
337 table::io::PersistableFacade<detection::HeavyFootprint<TYPE>>::dynamicCast( \
338 std::shared_ptr<table::io::Persistable> const&); \
339 template class detection::HeavyFootprint<TYPE>; \
340 template std::shared_ptr<detection::HeavyFootprint<TYPE>> detection::mergeHeavyFootprints<TYPE>( \
341 detection::HeavyFootprint<TYPE> const&, detection::HeavyFootprint<TYPE> const&);