#include <imageanalysis/ImageAnalysis/ImageHanningSmoother.h> namespace casa { template<class T> ImageHanningSmoother<T>::ImageHanningSmoother( const SPCIIT image, const casacore::Record *const region, const casacore::String& mask, const casacore::String& outname, casacore::Bool overwrite ) : Image1DSmoother<T>( image, region, mask, outname, overwrite ) { this->_construct(); this->_setNMinPixels(3); } template<class T> SPIIT ImageHanningSmoother<T>::_smooth( const casacore::ImageInterface<T>& image ) const { casacore::IPosition inTileShape = image.niceCursorShape(); casacore::uInt axis = this->_getAxis(); casacore::TiledLineStepper inNav(image.shape(), inTileShape, axis); casacore::RO_MaskedLatticeIterator<T> inIter(image, inNav); casacore::IPosition sliceShape(image.ndim(), 1); sliceShape[axis] = image.shape()[axis]; casacore::Array<T> slice(sliceShape); casacore::String empty; casacore::Record emptyRecord; SPIIT out( SubImageFactory<T>::createImage( image, empty, emptyRecord, empty, false, false, false, false ) ); while (!inIter.atEnd()) { slice = _hanningSmooth(inIter.cursor()); out->putSlice(slice, inIter.position()); inIter++; } if (this->_getDecimate()) { // remove the first plane from _axis casacore::IPosition shape = out->shape(); casacore::IPosition blc(shape.size(), 0); blc[axis] = 1; ImageDecimatorData::Function f = this->_getDecimationFunction(); casacore::IPosition trc = shape - 1; if (shape[axis] % 2 == 0) { trc[axis]--; } casacore::LCBox lcbox(blc, trc, shape); casacore::Record x = lcbox.toRecord(""); ImageDecimator<T> decimator( SPIIT(out->cloneII()), &x, casacore::String(""), casacore::String(""), false ); decimator.setFunction(f); decimator.setAxis(axis); decimator.setFactor(2); decimator.suppressHistoryWriting(true); out = decimator.decimate(); this->addHistory(decimator.getHistory()); } return out; } template<class T> casacore::Array<T> ImageHanningSmoother<T>::_hanningSmooth( const casacore::Array<T>& in ) const { // although the passed in array may have more than one // dimensions, only one of those will have length > 1 casacore::uInt size = in.size(); casacore::Array<T> out(in.shape(), T(0.0)); casacore::uInt count = 1; casacore::uInt end = size - 1; typename casacore::Array<T>::const_iterator prev = in.begin(); typename casacore::Array<T>::const_iterator cur = in.begin(); cur++; typename casacore::Array<T>::const_iterator next = in.begin(); next++; next++; casacore::Bool skip = this->_getDecimate() && this->_getDecimationFunction() == ImageDecimatorData::COPY; casacore::uInt inc = skip ? 2 : 1; if (skip && size % 2 == 0) { end--; } typename casacore::Array<T>::iterator outIter = out.begin(); if (! skip) { *outIter = 0.5*(*cur + *prev); } outIter++; while (count < end) { *outIter = 0.25*(*prev + *next) + 0.5 * (*cur); for (casacore::uInt i=0; i<inc; i++) { outIter++; prev++; cur++; next++; } count += inc; } if (! skip) { *outIter = 0.5 * (*cur + *prev); } return out; } }