34 fnMovie = getParam(
"-i");
35 fnOut = getParam(
"-o");
36 fnInitialAvg = getParam(
"--oavgInitial");
37 fnDark = getParam(
"--dark");
38 fnGain = getParam(
"--gain");
39 binning = getFloatParam(
"--bin");
42 Ts = getFloatParam(
"--sampling") * binning;
43 maxShift = getFloatParam(
"--maxShift") / Ts;
44 maxResForCorrelation = getFloatParam(
"--maxResForCorrelation");
45 fnAligned = getParam(
"--oaligned");
46 fnAvg = getParam(
"--oavg");
47 nfirst = getIntParam(
"--frameRange", 0);
48 nlast = getIntParam(
"--frameRange", 1);
49 nfirstSum = getIntParam(
"--frameRangeSum", 0);
50 nlastSum = getIntParam(
"--frameRangeSum", 1);
51 skipLocalAlignment = checkParam(
"--skipLocalAlignment");
52 minLocalRes = getIntParam(
"--minLocalRes");
56 this->getIntParam(
"--controlPoints", 0),
57 this->getIntParam(
"--controlPoints", 1),
59 this->getIntParam(
"--controlPoints", 2));
60 if ((cPoints.
x() < 3) || (cPoints.
y() < 3) || (cPoints.
n() < 3))
62 "All control points has to be bigger than 2");
63 localAlignmentControlPoints = cPoints;
69 if ((nfirstSum < nfirst) || (nlastSum > nlast)) {
71 "Check the intervals of the alignment and summation " 72 "(--frameRange and --frameRangeSum).");
74 if (getScaleFactor() >= 1) {
76 "Check that the sampling rate (--sampling) and maximal resolution to align " 77 "(--maxResForCorrelation) are correctly set. For current sampling, you can " 78 "use maximal resolution of " +
std::to_string(this->Ts * 8 * getC()) +
" or higher.");
80 if (!skipLocalAlignment) {
81 if (this->localAlignPatches.first <= this->localAlignmentControlPoints.x()
82 || this->localAlignPatches.second <= this->localAlignmentControlPoints.y()) {
93 <<
"Input movie: " << fnMovie << std::endl
94 <<
"Output metadata: " <<
fnOut << std::endl
95 <<
"Dark image: " << fnDark << std::endl
96 <<
"Gain image: " << fnGain << std::endl
97 <<
"Max. Shift (A / px): " << (maxShift * Ts) <<
" / " << maxShift << std::endl
98 <<
"Max resolution (A): " << maxResForCorrelation << std::endl
99 <<
"Sampling: " << Ts << std::endl
100 <<
"Aligned movie: " << fnAligned << std::endl
101 <<
"Aligned micrograph: " << fnAvg << std::endl
102 <<
"Unaligned micrograph: " << fnInitialAvg << std::endl
103 <<
"Frame range alignment: " << nfirst <<
" " << nlast << std::endl
104 <<
"Frame range sum: " << nfirstSum <<
" " << nlastSum << std::endl
105 <<
"Binning factor: " << binning << std::endl
106 <<
"Skip local alignment: " << (skipLocalAlignment ?
"yes" :
"no") << std::endl
107 <<
"Control points: " << this->localAlignmentControlPoints << std::endl
108 <<
"No of patches: " << this->localAlignPatches.first <<
" * " << localAlignPatches.second << std::endl;
113 addUsageLine(
"Align a set of frames by cross-correlation of the frames");
115 " -i <metadata> : Metadata with the list of frames to align");
117 " [-o <fn=\"out.xmd\">] : Metadata with the shifts of each frame.");
119 " : If no filename is given, the input is rewritten");
121 " [--bin <s=1>] : Binning factor, it may be any floating number > 1.");
123 " : Binning is applied during the data loading, i.e. the program will processed and store binned data.");
125 " [--maxShift <s=50>] : Maximum shift allowed in A");
127 " [--maxResForCorrelation <R=30>]: Maximum resolution to align (in Angstroms)");
129 " [--sampling <Ts=1>] : Sampling rate (A/pixel)");
131 " [--oaligned <fn=\"\">] : Aligned movie consists of aligned frames used for micrograph generation");
133 " [--oavgInitial <fn=\"\">] : Give the name of a micrograph to generate an unaligned (initial) micrograph");
135 " [--oavg <fn=\"\">] : Give the name of a micrograph to generate an aligned micrograph");
137 " [--frameRange <n0=-1> <nF=-1>] : First and last frame to align, frame numbers start at 0");
139 " [--frameRangeSum <n0=-1> <nF=-1>] : First and last frame to sum, frame numbers start at 0");
140 addParamsLine(
" [--dark <fn=\"\">] : Dark correction image");
141 addParamsLine(
" [--gain <fn=\"\">] : Gain correction image (we will multiply by it)");
143 " [--skipLocalAlignment] : If used, only global alignment will be performed. It's faster, but gives worse results.");
145 " [--controlPoints <x=6> <y=6> <t=5>]: Number of control points (including end points) used for defining the BSpline");
147 " [--patches <x=7> <y=7>]: Number of patches used for local alignment");
149 " [--minLocalRes <R=500>] : Minimal resolution (in A) of patches during local alignment");
150 addExampleLine(
"A typical example",
false);
151 addSeeAlsoLine(
"xmipp_movie_optical_alignment_cpu");
161 if (
XSIZE(dark()) > 0) {
165 "The dark image size does not match the movie frame size.");
169 if (
XSIZE(igain()) > 0) {
173 "The gain image size does not match the movie frame size.");
181 return this->Ts / scaleFactor;
186 assert(Ts >= this->Ts);
195 scaleLPF(lpf, dims, result);
207 T iX = 1 / (T)length;
208 T sigma = (Ts * getC()) / maxResForCorrelation;
211 filter.
data[
x] = (exp(-0.5*(w*w)/(sigma*sigma)));
232 totalShiftX = totalShiftY = 0;
234 for (
int jj = j - 1; jj >= iref; --jj) {
235 totalShiftX -= shiftX(jj);
236 totalShiftY -= shiftY(jj);
238 }
else if (iref > j) {
239 for (
int jj = j; jj <= iref - 1; ++jj) {
240 totalShiftX += shiftX(jj);
241 totalShiftY += shiftY(jj);
252 for (
int iref = 0; iref < N; ++iref) {
254 for (
int j = 0;
j < N; ++
j) {
255 T totalShiftX, totalShiftY;
256 computeTotalShift(iref,
j, shiftX, shiftY, totalShiftX,
258 if (fabs(totalShiftX) > worstShift)
259 worstShift = fabs(totalShiftX);
261 if (worstShift < worstShiftEver) {
262 worstShiftEver = worstShift;
271 if (fnDark.isEmpty())
278 if (fnGain.isEmpty())
281 T avg = igain().computeAvg();
282 if (std::isinf(avg) || std::isnan(avg))
284 "The input gain image is incorrect, it contains infinite or nan");
307 return maxResForCorrelation / (8.f * getC());
313 return Ts / getTsPrime();
319 if (fnMovie.isMetaData())
324 size_t Xdim, Ydim, Zdim, Ndim;
326 if (fnMovie.getExtension() ==
"mrc" and Ndim == 1)
330 for (
size_t i = 0;
i < Ndim;
i++) {
340 if (this->movieSizeRaw)
return movieSizeRaw.value();
341 int noOfImgs = this->nlast - this->nfirst + 1;
343 if (fnMovie.isMetaData()) {
350 size_t xdim, ydim, zdim, ndim;
352 this->movieSizeRaw =
Dimensions(xdim, ydim, 1, noOfImgs);
353 return movieSizeRaw.value();
358 if (movieSize)
return movieSize.value();
359 auto full = getMovieSizeRaw();
360 if (applyBinning()) {
362 auto x = ((
static_cast<float>(full.x()) / binning) / 2.f) * 2.
f;
363 auto y = ((
static_cast<float>(full.y()) / binning) / 2.f) * 2.
f;
364 movieSize =
Dimensions(static_cast<size_t>(
x), static_cast<size_t>(
y), 1L, full.n());
368 return movieSize.value();
376 auto negateToDouble = [binning=binning] (T v) {
return (
double) (v * -1) * binning;};
377 for (
size_t objId : movie.
ids())
379 if (n >= nfirst && n <= nlast) {
380 auto shift = alignment.
shifts.at(j);
410 this->findReferenceImage(N, shiftX, shiftY)};
411 result.shifts.reserve(N);
413 for (
size_t i = 0;
i < N; ++
i) {
415 this->computeTotalShift(result.refFrame,
i, shiftX, shiftY, x, y);
416 result.shifts.emplace_back(x, y);
423 size_t Ninitial,
Image<T>& averageMicrograph,
size_t N,
424 const MetaData& movie,
int bestIref) {
425 if (fnInitialAvg !=
"") {
426 initialMic() /= Ninitial;
427 initialMic.
write(fnInitialAvg);
430 averageMicrograph() /= N;
431 averageMicrograph.
write(fnAvg);
442 nlast = movie.
size() - 1;
445 nlastSum = movie.
size() - 1;
451 std::cout <<
"Reference frame: " << globAlignment.
refFrame <<
"\n";
452 std::cout <<
"Estimated global shifts (in px, from the reference frame";
453 std::cout << (applyBinning() ?
", ignoring binning" :
"");
455 for (
auto &s : globAlignment.
shifts) {
456 printf(
"X: %07.4f Y: %07.4f\n", s.x * binning, s.y * binning);
458 std::cout << std::endl;
469 "Missing BSpline representation. This should not happen. Please contact developers.");
472 std::vector<double> shifts;
473 for (
auto &&p : alignment.
shifts) {
474 int tileCenterX = p.first.rec.getCenter().x;
475 int tileCenterY = p.first.rec.getCenter().y;
476 int tileIdxT = p.first.id_t;
479 tileCenterX, tileCenterY, tileIdxT);
480 auto globalShift = alignment.
globalHint.shifts.at(tileIdxT);
481 shifts.emplace_back(hypot(shift.first - globalShift.x, shift.second - globalShift.y));
486 std::sort(shifts.begin(), shifts.end(), std::less<double>());
487 size_t indexL = shifts.size() * 0.025;
488 size_t indexU = shifts.size() * 0.975;
493 std::vector<size_t>{localAlignPatches.first, localAlignPatches.second}, id);
495 std::vector<double> tmpX;
496 std::vector<double> tmpY;
498 for (
int i = 0;
i < size; ++
i) {
507 localAlignmentControlPoints.x(),
508 localAlignmentControlPoints.y(),
509 localAlignmentControlPoints.n()},
518 if (checkParam(
"--patches")) {
519 localAlignPatches = {getIntParam(
"--patches", 0), getIntParam(
"--patches", 1)};
521 const auto &movieDim = getMovieSize();
522 auto patchDim = getRequestedPatchSize();
523 localAlignPatches = {
524 std::ceil(static_cast<float>(movieDim.x()) / static_cast<float>(patchDim.first)),
525 std::ceil(static_cast<float>(movieDim.y()) / static_cast<float>(patchDim.second))};
534 correctLoopIndices(movie);
541 loadDarkCorrection(dark);
542 loadGainCorrection(igain);
545 std::cout <<
"Computing global alignment ...\n";
546 globalAlignment = computeGlobalAlignment(movie, dark, igain);
549 storeGlobalShifts(globalAlignment, movie);
552 if (verbose) printGlobalShift(globalAlignment);
555 Image<T> initialMic, averageMicrograph;
557 if (skipLocalAlignment) {
558 applyShiftsComputeAverage(movie, dark, igain, initialMic, Ninitial,
559 averageMicrograph, N, globalAlignment);
561 std::cout <<
"Computing local alignment ...\n";
562 auto localAlignment = computeLocalAlignment(movie, dark, igain, globalAlignment);
563 applyShiftsComputeAverage(movie, dark, igain, initialMic, Ninitial,
564 averageMicrograph, N, localAlignment);
565 storeResults(localAlignment);
568 storeResults(initialMic, Ninitial, averageMicrograph, N, movie, globalAlignment.refFrame);
int findReferenceImage(size_t N, const Matrix1D< T > &shiftX, const Matrix1D< T > &shiftY)
#define A2D_ELEM(v, i, j)
static std::pair< T, T > getShift(const BSplineGrid< T > &grid, Dimensions dim, size_t x, size_t y, size_t n)
std::vector< Point2D< T > > shifts
AlignmentResult< T > computeAlignment(Matrix1D< T > &bX, Matrix1D< T > &bY, Matrix2D< T > &A, const core::optional< size_t > &refFrame, size_t N, int verbose)
#define REPORT_ERROR(nerr, ErrormMsg)
Dimensions getMovieSizeRaw()
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(m)
void sqrt(Image< double > &op)
std::vector< std::pair< FramePatchMeta< T >, Point2D< T > > > shifts
void computeTotalShift(int iref, int j, const Matrix1D< T > &shiftX, const Matrix1D< T > &shiftY, T &totalShiftX, T &totalShiftY)
const AlignmentResult< T > & globalHint
void write(const FileName &name="", size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE, CastWriteMode castMode=CW_CAST, int _swapWrite=0)
void loadFrame(const MetaData &movie, const Image< T > &dark, const Image< T > &igain, size_t objId, Image< T > &out) const
void compose(const String &str, const size_t no, const String &ext="")
void storeResults(const LocalAlignmentResult< T > &alignment)
CUDA_HD constexpr size_t x() const
void log(Image< double > &op)
void getDimensions(size_t &Xdim, size_t &Ydim, size_t &Zdim, size_t &Ndim) const
float getPixelResolution(float scaleFactor) const
MultidimArray< T > createLPF(T Ts, const Dimensions &dims)
Incorrect argument received.
static void solve(Matrix1D< T > &bXt, Matrix1D< T > &bYt, Matrix2D< T > &At, Matrix1D< T > &shiftXt, Matrix1D< T > &shiftYt, int verbosity, int iterations)
core::optional< BSplineGrid< T > > bsplineRep
void max(Image< double > &op1, const Image< double > &op2)
CUDA_HD constexpr size_t y() const
__host__ __device__ float length(float2 v)
void sort(struct DCEL_T *dcel)
__device__ float FFT_IDX2DIGFREQ(int idx, int size)
CUDA_HD constexpr size_t n() const
virtual void defineParams()
Define parameters.
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
std::string to_string(bond_type bondType)
float getScaleFactor() const
void initZeros(const MultidimArray< T1 > &op)
Dimensions getMovieSize()
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false)
T interpolatedElement1D(double x, T outside_value=(T) 0) const
Incorrect value received.
virtual void readParams()
Read argument from command line.
Some logical error in the pipeline.