35 bool includingBatchFT,
bool includingSingleFT,
36 bool allowDataOverwrite) {
42 m_cpu =
dynamic_cast<CPU*
>(hw.at(0));
43 }
catch (std::bad_cast&) {
48 includingBatchFT, includingSingleFT, allowDataOverwrite);
50 this->m_isInit =
true;
55 auto isReady = (this->m_isInit && (
AlignType::OneToN == this->m_type) && this->m_includingSingleFT);
64 this->m_is_ref_FD_loaded =
true;
73 auto settingsForw = this->m_settingsInv->createInverse();
74 if (this->m_includingBatchFT) {
75 m_batch_FD =
new std::complex<T>[this->m_settingsInv->fElemsBatch()];
76 m_batch_SD =
new T[this->m_settingsInv->sElemsBatch()];
79 if (this->m_includingSingleFT) {
80 m_single_FD =
new std::complex<T>[this->m_settingsInv->fDim().xyzPadded()];
88 if (this->m_includingSingleFT) {
91 if (this->m_includingBatchFT) {
113 m_single_FD =
nullptr;
114 m_batch_FD =
nullptr;
115 m_batch_SD =
nullptr;
118 m_singleToFD =
nullptr;
119 m_batchToFD =
nullptr;
120 m_batchToSD =
nullptr;
134 m_single_FD =
const_cast<std::complex<T>*
>(ref);
137 this->m_is_ref_FD_loaded =
true;
142 std::complex<T> *inOut,
bool center) {
143 bool isReady = (this->m_isInit && (
AlignType::OneToN == this->m_type) && this->m_is_ref_FD_loaded);
149 sComputeCorrelations2DOneToN(
152 this->m_settingsInv->fDim(),
159 std::complex<T> *inOut,
160 const std::complex<T> *ref,
165 cpu = &
dynamic_cast<const CPU&
>(hw);
166 }
catch (std::bad_cast&) {
169 return sComputeCorrelations2DOneToN(*cpu, inOut, ref, dims, center);
173 template<
bool CENTER>
176 std::complex<T> *__restrict inOut,
177 const std::complex<T> *__restrict ref,
181 assert(0 == (dims.y() % 2));
183 assert(0 < dims.x());
184 assert(0 < dims.y());
185 assert(1 == dims.z());
186 assert(0 < dims.n());
188 const size_t maxN = dims.n();
189 const size_t maxY = dims.y();
190 const size_t maxX = dims.x();
192 for (
size_t n = 0;
n < maxN; ++
n) {
193 size_t offsetN =
n * dims.xyzPadded();
194 for (
size_t y = 0;
y < maxY; ++
y) {
195 int centerCoeff = (0 ==
y % 2) ? 1 : -1;
196 size_t offsetY =
y * dims.xPadded();
197 for (
size_t x = 0;
x < maxX; ++
x) {
198 size_t destIndex = offsetN + offsetY +
x;
199 auto r = ref[offsetY +
x];
200 auto o = r *
std::conj(inOut[destIndex]);
201 inOut[destIndex] = o;
203 inOut[destIndex] *= centerCoeff;
215 && this->m_is_ref_FD_loaded && this->m_includingBatchFT);
222 this->m_shifts2D.reserve(this->m_settingsInv->fDim().n());
224 for (
size_t offset = 0; offset < this->m_settingsInv->fDim().n(); offset += this->m_settingsInv->batch()) {
226 size_t toProcess =
std::min(this->m_settingsInv->batch(), this->m_settingsInv->fDim().n() - offset);
229 if (toProcess == this->m_settingsInv->batch()) {
231 batchStart = others + offset * this->m_settingsInv->sDim().xyPadded();
233 assert(this->m_settingsInv->batch() <= this->m_settingsInv->sDim().n());
237 + (this->m_settingsInv->sDim().n() - this->m_settingsInv->batch())
238 * this->m_settingsInv->sDim().xy();
245 auto shifts = computeShifts2DOneToN(
250 this->m_settingsInv->createBatch(),
255 this->m_shifts2D.insert(this->m_shifts2D.end(),
257 shifts.begin() + this->m_settingsInv->batch() - toProcess,
262 this->m_is_shift_computed =
true;
268 std::complex<T> *othersF,
270 std::complex<T> *ref,
275 assert(0 == (settings.
sDim().
x() % 2));
276 assert(0 == (settings.
sDim().
y() % 2));
280 sComputeCorrelations2DOneToN(cpu,
282 settings.
fDim(),
true);
288 auto maxIndices = std::vector<float>(settings.
sDim().
n(), -1.f);
290 othersS, maxIndices.data(),
nullptr, maxShift);
293 int cX = settings.
sDim().
x() / 2;
294 int cY = settings.
sDim().
y() / 2;
295 auto result = std::vector<Point2D<float>>();
296 const int x = settings.
sDim().
x();
297 for (
auto i : maxIndices) {
298 result.emplace_back(((
int)
i % x) - cX, ((
int)
i / x) - cY);
306 if (this->m_settingsInv->isInPlace()) {
309 if (this->m_allowDataOverwrite) {
310 std::cerr <<
"'AllowDataOverwrite' flat ignored. This is not supported yet\n";
void min(Image< double > &op1, const Image< double > &op2)
alglib::complex conj(const alglib::complex &z)
virtual void init2DOneToN()
#define REPORT_ERROR(nerr, ErrormMsg)
virtual void init2D(const std::vector< HW *> &hw, AlignType type, const FFTSettings< T > &dims, size_t maxShift, bool includingBatchFT, bool includingSingleFT, bool allowDataOverwrite)=0
void load2DReferenceOneToN(const std::complex< T > *ref) override
static const fftw_plan createPlan(const CPU &cpu, const FFTSettings< double > &settings, bool isDataAligned=false)
constexpr Dimensions fDim() const
void setDefault() override
std::complex< T > * fft(T *inOut)
CUDA_HD constexpr size_t x() const
void init2D(const std::vector< HW *> &hw, AlignType type, const FFTSettings< T > &dims, size_t maxShift, bool includingBatchFT, bool includingSingleFT, bool allowDataOverwrite) override
constexpr size_t zPadded() const
void computeCorrelations2DOneToN(std::complex< T > *inOut, bool center) override
Incorrect argument received.
CUDA_HD constexpr size_t y() const
CUDA_HD constexpr size_t n() const
constexpr Dimensions sDim() const
T * ifft(std::complex< T > *inOut)
static std::vector< Point2D< float > > computeShifts2DOneToN(const CPU &cpu, std::complex< T > *othersF, T *othersS, std::complex< T > *ref, const FFTSettings< T > &settings, void *plan, size_t maxShift)
Incorrect value received.
void computeShift2DOneToN(T *others) override
static void sFindMax2DAroundCenter(const CPU &cpu, const Dimensions &dims, const T *data, float *positions, T *values, size_t maxDist)
static void sComputeCorrelations2DOneToN(const HW &hw, std::complex< T > *inOut, const std::complex< T > *ref, const Dimensions &dims, bool center)
Some logical error in the pipeline.