Xmipp  v3.23.11-Nereus
Classes | Macros | Functions | Variables
common_lines.cpp File Reference
#include <fstream>
#include "common_lines.h"
#include "data/mask.h"
#include "core/metadata_extension.h"
#include "data/fourier_filter.h"
#include "reconstruction/radon.h"
#include "core/linear_system_helper.h"
Include dependency graph for common_lines.cpp:

Go to the source code of this file.

Classes

struct  ThreadPrepareImages
 
struct  ThreadCompareImages
 

Macros

#define q0   dMi(q, 0)
 
#define q1   dMi(q, 1)
 
#define q2   dMi(q, 2)
 
#define q3   dMi(q, 3)
 
#define AXIS(var)   DVector var(3); var.initZeros()
 
#define cl(i, j)   dMij(clMatrix, k##i, k##j)
 
#define SET_POINT(x, y)   dMij(syncMatrix, x+2*k1, y+2*k2) = dMij(R, x, y)
 
#define SORTED_INDEX(i)   dMi(indexes, i)
 
#define SORTED_ELEM(M, i)   dMi(M, SORTED_INDEX(i))
 

Functions

void * threadPrepareImages (void *args)
 
void commonLineTwoImages (std::vector< MultidimArray< std::complex< double > > > &RTFsi, std::vector< MultidimArray< double > > &RTsi, int idxi, std::vector< MultidimArray< std::complex< double > > > &RTFsj, std::vector< MultidimArray< double > > &RTsj, int idxj, ProgCommonLine *parent, CommonLine &result, FourierTransformer &transformer)
 
void * threadCompareImages (void *args)
 
void randomQuaternions (int k, DMatrix &quaternions)
 
void saveMatrix (const char *fn, DMatrix &matrix)
 
void quaternionToMatrix (const DVector &q, DMatrix &rotMatrix)
 
void quaternionCommonLines (const DMatrix &quaternions, CommonLineInfo &clInfo)
 
void commonlineMatrixCheat (const DMatrix &quaternions, size_t nRays, DMatrix &clMatrix, DMatrix &clCorr)
 
void anglesRotationMatrix (size_t nRays, int clI, int clJ, const DVector &Q1, const DVector &Q2, DMatrix &R)
 
int tripletRotationMatrix (const DMatrix &clMatrix, size_t nRays, int k1, int k2, int k3, DMatrix &R)
 
void putRotationMatrix (const DMatrix &R, int k1, int k2, DMatrix &syncMatrix)
 
void computeSyncMatrix (const DMatrix &clMatrix, size_t nRays, DMatrix &sMatrix)
 
void rotationsFromSyncMatrix (const DMatrix &sMatrix)
 

Variables

constexpr long double EPS = 1.0e-13
 
constexpr int MAX_COND = 1000
 

Macro Definition Documentation

◆ AXIS

#define AXIS (   var)    DVector var(3); var.initZeros()

Definition at line 631 of file common_lines.cpp.

◆ cl

#define cl (   i,
  j 
)    dMij(clMatrix, k##i, k##j)

Definition at line 830 of file common_lines.cpp.

◆ q0

#define q0   dMi(q, 0)

◆ q1

#define q1   dMi(q, 1)

◆ q2

#define q2   dMi(q, 2)

◆ q3

#define q3   dMi(q, 3)

◆ SET_POINT

#define SET_POINT (   x,
  y 
)    dMij(syncMatrix, x+2*k1, y+2*k2) = dMij(R, x, y)

◆ SORTED_ELEM

#define SORTED_ELEM (   M,
  i 
)    dMi(M, SORTED_INDEX(i))

◆ SORTED_INDEX

#define SORTED_INDEX (   i)    dMi(indexes, i)

Function Documentation

◆ anglesRotationMatrix()

void anglesRotationMatrix ( size_t  nRays,
int  clI,
int  clJ,
const DVector Q1,
const DVector Q2,
DMatrix R 
)

Definition at line 793 of file common_lines.cpp.

796 {
797 
798  double alpha1 = TWOPI * clI / nRays;
799  double alpha2 = TWOPI * clJ / nRays;
800  DVector N1(3);
801  vectorProduct(Q1, Q2, N1);
802  N1.selfNormalize();
803 
804  DMatrix U(3, 3);
805 
806  //sincos(alpha1, &dMij(U, 1, 0), &dMij(U, 0, 0));
807  dMij(U, 1, 0) = sin(alpha1);
808  dMij(U, 0, 0) = cos(alpha1);
809  //sincos(alpha2, &dMij(U, 1, 1), &dMij(U, 0, 1));
810  dMij(U, 1, 1) = sin(alpha2);
811  dMij(U, 0, 1) = cos(alpha2);
812  dMij(U, 2, 2) = 1.;
813 
814  if (U.det3x3() < 0)
815  dMij(U, 2, 2) = -1.; //% Make sure we have a right-handed system)
816 
817  DMatrix Q(3, 3);
818  Q.setCol(0, Q1);
819  Q.setCol(1, Q2);
820  Q.setCol(2, N1);
821 
822  U.selfInverse();
823  DMatrix T = Q * U;
824  T.svd(U, N1, Q);
825  R = U * Q.transpose();
826 }//function
#define TWOPI
Definition: xmipp_macros.h:111
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
Matrix1D< T > vectorProduct(const Matrix1D< T > &v1, const Matrix1D< T > &v2)
Definition: matrix1d.h:1165
Definition: mask.h:36
#define dMij(m, i, j)
Definition: matrix2d.h:139
void svd(Matrix2D< double > &U, Matrix1D< double > &W, Matrix2D< double > &V) const
Definition: matrix2d.h:1124
Definition: ctf.h:38

◆ commonLineTwoImages()

void commonLineTwoImages ( std::vector< MultidimArray< std::complex< double > > > &  RTFsi,
std::vector< MultidimArray< double > > &  RTsi,
int  idxi,
std::vector< MultidimArray< std::complex< double > > > &  RTFsj,
std::vector< MultidimArray< double > > &  RTsj,
int  idxj,
ProgCommonLine parent,
CommonLine result,
FourierTransformer transformer 
)

Definition at line 247 of file common_lines.cpp.

254  {
255  MultidimArray<std::complex<double> > &RTFi = RTFsi[idxi];
256  MultidimArray<std::complex<double> > &RTFj = RTFsj[idxj];
257  MultidimArray<double> &RTi = RTsi[idxi];
258  MultidimArray<double> &RTj = RTsj[idxj];
259 
260  result.distanceij = 1e60;
261  result.angj = -1;
262  MultidimArray<std::complex<double> > lineFi, lineFj;
263  MultidimArray<double> linei, linej;
264  MultidimArray<double> correlationFunction;
265  int jmax;
266  for (size_t ii = 0; ii < YSIZE(RTFi) / 2 + 1; ii++) {
267  lineFi.aliasRow(RTFi,ii);
268  linei.aliasRow(RTi,ii);
269 
270  for (size_t jj=0; jj<YSIZE(RTFj); jj++)
271  {
272  lineFj.aliasRow(RTFj,jj);
273  linej.aliasRow(RTj,jj);
274 
275  // Compute distance between the two lines
276  fast_correlation_vector(lineFi, lineFj, correlationFunction, transformer);
277  correlationFunction.maxIndex(jmax);
278  double distance=1-A1D_ELEM(correlationFunction,jmax);
279 
280  // Check if this is the best match
281  if (distance<result.distanceij)
282  {
283  result.distanceij=distance;
284  result.angi=ii;
285  result.angj=jj;
286  result.jmax=jmax;
287  }
288  }
289  }
290  result.angi *= parent->stepAng;
291  result.angj *= parent->stepAng;
292 }
#define YSIZE(v)
#define A1D_ELEM(v, i)
void maxIndex(int &jmax) const
double angj
Angle of the best common line in image j.
Definition: common_lines.h:48
double angi
Angle of the best common line in image i.
Definition: common_lines.h:46
double stepAng
Angular sampling.
Definition: common_lines.h:78
void fast_correlation_vector(const MultidimArray< std::complex< double > > &FFT1, const MultidimArray< std::complex< double > > &FFT2, MultidimArray< double > &R, FourierTransformer &transformer)
Definition: xmipp_fftw.cpp:926
double distanceij
Distance between both common lines.
Definition: common_lines.h:50
TYPE distance(struct Point_T *p, struct Point_T *q)
Definition: point.cpp:28
void aliasRow(const MultidimArray< T > &m, size_t select_row)

◆ putRotationMatrix()

void putRotationMatrix ( const DMatrix R,
int  k1,
int  k2,
DMatrix syncMatrix 
)

Helper function to set the 2x2 upper left corner of a rotation matrix into a bigger matrix indexed by images

Definition at line 882 of file common_lines.cpp.

883 {
884 #define SET_POINT(x, y) dMij(syncMatrix, x+2*k1, y+2*k2) = dMij(R, x, y)
885  SET_POINT(0, 0);
886  SET_POINT(0, 1);
887  SET_POINT(1, 0);
888  SET_POINT(1, 1);
889 }
#define SET_POINT(x, y)

◆ threadCompareImages()

void* threadCompareImages ( void *  args)

Definition at line 306 of file common_lines.cpp.

307 {
308  auto * master = (ThreadCompareImages *) args;
309  ProgCommonLine * parent = master->parent;
310 
311  int blockIsize = master->RTFsi->size();
312  int blockJsize = master->RTFsj->size();
313  FourierTransformer transformer;
314  MultidimArray<double> linei;
315  linei.resize(parent->Xdim);
316  transformer.setReal(linei);
317  for (int i = 0; i < blockIsize; i++) {
318  long int ii = parent->Nblock * master->i + i;
319  for (int j = 0; j < blockJsize; j++) {
320  // Check if this two images have to be compared
321  long int jj = parent->Nblock * master->j + j;
322  if (ii >= jj)
323  continue;
324  if ((ii * blockJsize + jj + 1) % parent->Nthr != master->myThreadID)
325  continue;
326 
327  // Effectively compare the two images
328  long int idx_ij = ii * parent->Nimg + jj;
330  *(master->RTFsi), *(master->RTsi), i,
331  *(master->RTFsj), *(master->RTsj), j,
332  parent, parent->CLmatrix[idx_ij], transformer);
333 
334  // Compute the symmetric element
335  long int idx_ji = jj * parent->Nimg + ii;
336  parent->CLmatrix[idx_ji].distanceij = parent->CLmatrix[idx_ij].distanceij;
337  parent->CLmatrix[idx_ji].angi = parent->CLmatrix[idx_ij].angj;
338  parent->CLmatrix[idx_ji].angj = parent->CLmatrix[idx_ij].angi;
339  parent->CLmatrix[idx_ji].jmax = -parent->CLmatrix[idx_ij].jmax;
340  }
341  }
342  return nullptr;
343 }
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
CommonLine Parameters.
Definition: common_lines.h:60
#define i
std::vector< CommonLine > CLmatrix
Definition: common_lines.h:137
int Nthr
Number of threads.
Definition: common_lines.h:83
void setReal(MultidimArray< double > &img)
Definition: xmipp_fftw.cpp:129
void commonLineTwoImages(std::vector< MultidimArray< std::complex< double > > > &RTFsi, std::vector< MultidimArray< double > > &RTsi, int idxi, std::vector< MultidimArray< std::complex< double > > > &RTFsj, std::vector< MultidimArray< double > > &RTsj, int idxj, ProgCommonLine *parent, CommonLine &result, FourierTransformer &transformer)
#define j

◆ threadPrepareImages()

void* threadPrepareImages ( void *  args)

Definition at line 106 of file common_lines.cpp.

107 {
108  auto * master = (ThreadPrepareImages *) args;
109  ProgCommonLine * parent = master->parent;
110  MetaDataVec SFi = *(master->SFi);
111  size_t Ydim, Xdim, Zdim, Ndim;
112  getImageSize(SFi, Xdim, Ydim, Zdim, Ndim);
113 
114  MultidimArray<int> mask;
115  mask.resize(Ydim, Xdim);
116  mask.setXmippOrigin();
117  BinaryCircularMask(mask, Xdim / 2, OUTSIDE_MASK);
118  auto NInsideMask = (int)(XSIZE(mask) * YSIZE(mask) - mask.sum());
119 
120  FourierFilter Filter;
121  Filter.w1 = -1;
122  if (parent->lpf > 0 && parent->hpf > 0)
123  {
124  Filter.FilterBand = BANDPASS;
125  Filter.w1 = parent->lpf;
126  Filter.w2 = parent->hpf;
127  }
128  else if (parent->lpf > 0)
129  {
130  Filter.FilterBand = LOWPASS;
131  Filter.w1 = parent->lpf;
132  }
133  else if (parent->hpf > 0)
134  {
135  Filter.FilterBand = HIGHPASS;
136  Filter.w1 = parent->hpf;
137  }
138  Filter.raised_w = Filter.w1 / 3;
139 
140  int ii = 0;
141  bool first = true;
142  Image<double> I;
143  FileName fnImg;
144  MultidimArray<double> RT, linei(Xdim);
145  FourierTransformer transformer;
146  transformer.setReal(linei);
147  MultidimArray<std::complex<double> >&mlineiFourier=transformer.fFourier;
149  for (size_t objId : SFi.ids())
150  {
151  if ((ii + 1) % parent->Nthr == master->myThreadID) {
152  I.readApplyGeo(SFi, objId);
153  I().setXmippOrigin();
154  MultidimArray<double> &mI = I();
155 
156  // Bandpass filter images
157  if (Filter.w1 > 0)
158  {
159  if (first)
160  {
161  Filter.generateMask(mI);
162  first = false;
163  }
164  Filter.applyMaskSpace(mI);
165  }
166 
167  // Cut the image outside the largest circle
168  // And compute the DC value inside the mask
169  double meanInside = 0;
171  if (A2D_ELEM(mask,i,j))A2D_ELEM(mI,i,j)=0;
172  else
173  meanInside+=A2D_ELEM(mI,i,j);
174  meanInside /= NInsideMask;
175 
176  // Subtract the mean inside the circle
178  if (!A2D_ELEM(mask,i,j))
179  A2D_ELEM(mI,i,j)-=meanInside;
180 
181  // Compute the Radon transform
182  Radon_Transform(I(), parent->stepAng, RT);
183 
184  // Normalize each line in the Radon Transform so that the
185  // multiplication of any two lines is actually their correlation index
186  RTFourier.resize(YSIZE(RT), XSIZE(mlineiFourier));
187  for (size_t i = 0; i < YSIZE(RT); i++) {
188  memcpy(&(DIRECT_A1D_ELEM(linei,0)),&DIRECT_A2D_ELEM(RT,i,0),XSIZE(linei)*sizeof(double));
189  linei.statisticsAdjust(0.,1.);
190  transformer.FourierTransform();
191  transformer.fReal->initZeros();
192  transformer.inverseFourierTransform();
193  memcpy(&DIRECT_A2D_ELEM(RTFourier,i,0),&(DIRECT_A1D_ELEM(mlineiFourier,0)),XSIZE(mlineiFourier)*sizeof(std::complex<double>));
194 
195  memcpy(&DIRECT_A2D_ELEM(RT,i,0),&(DIRECT_A1D_ELEM(linei,0)),XSIZE(linei)*sizeof(double));
196  }
197 
198  (*(master->blockRTFs))[ii] = RTFourier;
199  (*(master->blockRTs))[ii] = RT;
200  }
201  ii++;
202  }
203  return nullptr;
204 }
double lpf
Low pass filter.
Definition: common_lines.h:74
#define YSIZE(v)
#define A2D_ELEM(v, i, j)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
void inverseFourierTransform()
Definition: xmipp_fftw.cpp:329
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
void BinaryCircularMask(MultidimArray< int > &mask, double radius, int mode, double x0, double y0, double z0)
Definition: mask.cpp:193
#define BANDPASS
CommonLine Parameters.
Definition: common_lines.h:60
#define DIRECT_A2D_ELEM(v, i, j)
void getImageSize(const MetaData &md, size_t &Xdim, size_t &Ydim, size_t &Zdim, size_t &Ndim, MDLabel image_label)
double hpf
High pass filter.
Definition: common_lines.h:76
virtual IdIteratorProxy< false > ids()
int readApplyGeo(const FileName &name, const MDRow &row, const ApplyGeoParams &params=DefaultApplyGeoParams)
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
MultidimArray< double > * fReal
Definition: xmipp_fftw.h:64
void Radon_Transform(const MultidimArray< double > &vol, double rot, double tilt, MultidimArray< double > &RT)
Definition: radon.cpp:30
glob_log first
#define DIRECT_A1D_ELEM(v, i)
int Nthr
Number of threads.
Definition: common_lines.h:83
void setReal(MultidimArray< double > &img)
Definition: xmipp_fftw.cpp:129
#define XSIZE(v)
#define HIGHPASS
double stepAng
Angular sampling.
Definition: common_lines.h:78
void FourierTransform(T &v, T1 &V, bool getCopy=true)
Definition: xmipp_fftw.h:166
#define j
constexpr int OUTSIDE_MASK
Definition: mask.h:48
void initZeros(const MultidimArray< T1 > &op)
void generateMask(MultidimArray< double > &v)
double sum() const
#define LOWPASS
void applyMaskSpace(MultidimArray< double > &v)

Variable Documentation

◆ EPS

constexpr long double EPS = 1.0e-13

Definition at line 828 of file common_lines.cpp.

◆ MAX_COND

constexpr int MAX_COND = 1000

Definition at line 829 of file common_lines.cpp.