Xmipp  v3.23.11-Nereus
movie_alignment_correlation.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar Sanchez Sorzano coss@cnb.csic.es
4  * David Strelak (davidstrelak@gmail.com)
5  *
6  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21  * 02111-1307 USA
22  *
23  * All comments concerning this program package may be sent to the
24  * e-mail address 'xmipp@cnb.csic.es'
25  ***************************************************************************/
26 
28 #include "core/transformations.h"
29 
30 template<typename T>
33  this->addExampleLine(
34  "xmipp_movie_alignment_correlation -i movie.xmd --oaligned alignedMovie.stk --oavg alignedMicrograph.mrc");
35  this->addSeeAlsoLine("xmipp_cuda_movie_alignment_correlation");
36 }
37 
38 template<typename T>
41  if (this->getBinning() != 1.0)
42  REPORT_ERROR(ERR_ARG_INCORRECT, "Binning is not supported. Please contact developers if you really need it.");
43 }
44 
45 template<typename T>
47  const MetaData &movie, const Image<T> &dark, const Image<T> &igain) {
48  loadData(movie, dark, igain);
49  size_t N = this->nlast - this->nfirst + 1; // no of images to process
50  Matrix2D<T> A(N * (N - 1) / 2, N - 1);
51  Matrix1D<T> bX(N * (N - 1) / 2), bY(N * (N - 1) / 2);
52 
53  if (this->verbose)
54  std::cout << "Computing shifts between frames ..." << std::endl;
55  // Now compute all shifts
56  computeShifts(N, bX, bY, A);
57 
58  // Choose reference image as the minimax of shifts
59  auto ref = core::optional<size_t>();
60  return this->computeAlignment(bX, bY, A, ref, N, this->verbose);
61 }
62 
63 template<typename T>
65  const MetaData& movie, const Image<T>& dark, const Image<T>& igain,
66  Image<T>& initialMic, size_t& Ninitial, Image<T>& averageMicrograph,
67  size_t& N, const LocalAlignmentResult<T> &alignment) {
68  throw std::logic_error("Not implemented");
69 }
70 
71 template<typename T>
73  const MetaData &movie, const Image<T> &dark, const Image<T> &igain,
74  const AlignmentResult<T> &globAlignment) {
75  throw std::logic_error("Not implemented");
76 }
77 
78 template<typename T>
80  const Image<T>& dark, const Image<T>& igain) {
81  sizeFactor = this->getScaleFactor();
82  MultidimArray<T> filter;
83  FourierTransformer transformer;
84  bool firstImage = true;
85  int n = -1;
86  FileName fnFrame;
87  Image<T> croppedFrame, reducedFrame;
88 
89  if (this->verbose) {
90  std::cout << "Computing Fourier transform of frames ..." << std::endl;
91  init_progress_bar(movie.size());
92  }
93 
94  for (size_t objId : movie.ids())
95  {
96  ++n;
97  if (n >= this->nfirst && n <= this->nlast) {
98  this->loadFrame(movie, dark, igain, objId, croppedFrame);
99 
100  if (firstImage) {
101  firstImage = false;
102  newXdim = croppedFrame().xdim * sizeFactor;
103  newYdim = croppedFrame().ydim * sizeFactor;
104  filter = this->createLPF(this->getPixelResolution(sizeFactor), Dimensions(newXdim,
105  newYdim));
106  }
107 
108  // Reduce the size of the input frame
109  scaleToSizeFourier(1, newYdim, newXdim, croppedFrame(),
110  reducedFrame());
111 
112  // Now do the Fourier transform and filter
113  auto *reducedFrameFourier =
115  transformer.FourierTransform(reducedFrame(), *reducedFrameFourier,
116  true);
117  for (size_t nn = 0; nn < filter.nzyxdim; ++nn) {
118  T wlpf = DIRECT_MULTIDIM_ELEM(filter, nn);
119  DIRECT_MULTIDIM_ELEM(*reducedFrameFourier,nn) *= wlpf;
120  }
121  frameFourier.push_back(reducedFrameFourier);
122  }
123  if (this->verbose)
124  progress_bar(n);
125  }
126  if (this->verbose)
127  progress_bar(movie.size());
128 }
129 
130 template<typename T>
132  const Matrix1D<T>& bX, const Matrix1D<T>& bY, const Matrix2D<T>& A) {
133  int idx = 0;
134  assert(frameFourier.size() > 0);
135  MultidimArray<T> Mcorr;
136  Mcorr.resizeNoCopy(newYdim, newXdim);
137  Mcorr.setXmippOrigin();
138  CorrelationAux aux;
139  for (size_t i = 0; i < N - 1; ++i) {
140  for (size_t j = i + 1; j < N; ++j) {
141  bestShift(*frameFourier[i], *frameFourier[j], Mcorr, bX(idx),
142  bY(idx), aux, nullptr, this->maxShift * sizeFactor);
143  bX(idx) /= sizeFactor; // scale to expected size
144  bY(idx) /= sizeFactor;
145  if (this->verbose)
146  std::cerr << "Frame " << i + this->nfirst << " to Frame "
147  << j + this->nfirst << " -> ("
148  << bX(idx) << ","
149  << bY(idx) << ")\n";
150  for (int ij = i; ij < j; ij++)
151  A(idx, ij) = 1;
152 
153  idx++;
154  }
155  }
156 }
157 
158 template<typename T>
160  const MetaData& movie, const Image<T>& dark, const Image<T>& igain,
161  Image<T>& initialMic, size_t& Ninitial, Image<T>& averageMicrograph,
162  size_t& N, const AlignmentResult<T> &globAlignment) {
163  // Apply shifts and compute average
164  Image<T> frame, croppedFrame, reducedFrame, shiftedFrame;
165  Matrix1D<T> shift(2);
166  FileName fnFrame;
167  int frameIndex = -1;
168  Ninitial = N = 0;
169 
170  for (size_t objId : movie.ids())
171  {
172  frameIndex++;
173  if ((frameIndex >= this->nfirstSum) && (frameIndex <= this->nlastSum)) {
174  // user might want to align frames 3..10, but sum only 4..6
175  // by deducting the first frame that was aligned, we get proper offset to the stored memory
176  int frameOffset = frameIndex - this->nfirst;
177  // get shifts
178  XX(shift) = -globAlignment.shifts.at(frameOffset).x; // we want to compensate
179  YY(shift) = -globAlignment.shifts.at(frameOffset).y; // the shift
180  bool isZeroShift = (XX(shift) == YY(shift)) // if shift is the same in both dimensions
181  && (XX(shift) == (T)0); // and it's zero
182 
183  // load frame
184  this->loadFrame(movie, dark, igain, objId, croppedFrame);
185 
186  if ( ! this->fnInitialAvg.isEmpty()) {
187  if (frameIndex == this->nfirstSum)
188  initialMic() = croppedFrame();
189  else
190  initialMic() += croppedFrame();
191  Ninitial++;
192  }
193 
194  if (this->fnAligned != "" || this->fnAvg != "") {
195  // if there's no shift
196  if (isZeroShift) {
197  if (nullptr == shiftedFrame().data) {
198  shiftedFrame().resizeNoCopy(croppedFrame());
199  }
200  std::swap(shiftedFrame().data, croppedFrame().data);
201  } else {
202  translate(3, shiftedFrame(),
203  croppedFrame(), shift, xmipp_transformation::DONT_WRAP,
204  croppedFrame().computeAvg());
205  }
206  if (this->fnAligned != "")
207  shiftedFrame.write(this->fnAligned, frameOffset + 1, true,
208  WRITE_REPLACE);
209  if (this->fnAvg != "") {
210  if (frameIndex == this->nfirstSum)
211  averageMicrograph() = shiftedFrame();
212  else
213  averageMicrograph() += shiftedFrame();
214  N++;
215  }
216  if (isZeroShift) {
217  std::swap(shiftedFrame().data, croppedFrame().data);
218  }
219  }
220  if (this->verbose > 1) {
221  std::cout << "Frame " << std::to_string(frameIndex) << " processed." << std::endl;
222  }
223  }
224  }
225 }
226 
void init_progress_bar(long total)
std::vector< Point2D< T > > shifts
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void resizeNoCopy(const MultidimArray< T1 > &v)
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)
virtual IdIteratorProxy< false > ids()
#define i
void defineParams() override
Define parameters.
Definition: mask.h:36
void readParams() override
Read argument from command line.
#define XX(v)
Definition: matrix1d.h:85
Incorrect argument received.
Definition: xmipp_error.h:113
void progress_bar(long rlen)
#define DIRECT_MULTIDIM_ELEM(v, n)
void scaleToSizeFourier(int Zdim, int Ydim, int Xdim, MultidimArray< double > &mdaIn, MultidimArray< double > &mdaOut, int nThreads)
Definition: xmipp_fftw.cpp:658
virtual size_t size() const =0
void FourierTransform(T &v, T1 &V, bool getCopy=true)
Definition: xmipp_fftw.h:166
#define j
#define YY(v)
Definition: matrix1d.h:93
virtual void defineParams()
Define parameters.
void translate(PDB *pdb_original, PDB *pdb_move, unsigned num_atoms, double x0, double y0, double z0)
Definition: lib_pwk.cpp:125
Definition: ctf.h:38
template float bestShift(MultidimArray< float > &, float &, float &, const MultidimArray< int > *, int)
std::string to_string(bond_type bondType)
Definition: compound.cpp:43
int * n
virtual void readParams()
Read argument from command line.