Xmipp  v3.23.11-Nereus
Functions
image_rotational_pca.cpp File Reference
#include "image_rotational_pca.h"
#include "core/metadata_extension.h"
#include "core/transformations.h"
#include "core/xmipp_funcs.h"
Include dependency graph for image_rotational_pca.cpp:

Go to the source code of this file.

Functions

void threadApplyT (ThreadArgument &thArg)
 
void threadApplyTt (ThreadArgument &thArg)
 

Function Documentation

◆ threadApplyT()

void threadApplyT ( ThreadArgument thArg)

Definition at line 227 of file image_rotational_pca.cpp.

228 {
229  auto *self=(ProgImageRotationalPCA *) thArg.workClass;
230  //MpiNode *node=self->node;
231  int rank = self->rank;
232  std::vector<size_t> &objId=self->objId;
233  MetaDataVec &MD=self->MD[thArg.thread_id];
234 
235  Image<double> &I=self->I[thArg.thread_id];
236  MultidimArray<double> &Iaux=self->Iaux[thArg.thread_id];
237  Matrix2D<double> &Wnode=self->Wnode[thArg.thread_id];
238  Matrix2D<double> &Hblock=self->Hblock[thArg.thread_id];
239  Matrix2D<double> &A=self->A[thArg.thread_id];
240  Matrix2D<double> &H=self->H;
241  MultidimArray< unsigned char > &mask=self->mask;
242  Wnode.initZeros(self->Npixels,MAT_XSIZE(H));
243 
244  const int unroll=8;
245  const int jmax=(MAT_XSIZE(Wnode)/unroll)*unroll;
246 
247  size_t first, last;
248  if (IS_MASTER && thArg.thread_id==0)
249  {
250  std::cout << "Applying T ...\n";
251  init_progress_bar(objId.size());
252  }
253  while (self->taskDistributor->getTasks(first, last))
254  {
255  for (size_t idx=first; idx<=last; ++idx)
256  {
257  // Read image
258  I.readApplyGeo(MD,objId[idx]);
259  MultidimArray<double> &mI=I();
260 
261  // Locate the corresponding index in Matrix H
262  // and copy a block in memory to speed up calculations
263  size_t Hidx=idx*2*self->Nangles*self->Nshifts;
264  memcpy(&MAT_ELEM(Hblock,0,0),&MAT_ELEM(H,Hidx,0),MAT_XSIZE(Hblock)*MAT_YSIZE(Hblock)*sizeof(double));
265 
266  // For each rotation, shift and mirror
267  int block_idx=0;
268  for (int mirror=0; mirror<2; ++mirror)
269  {
270  if (mirror)
271  {
272  mI.selfReverseX();
273  mI.setXmippOrigin();
274  }
275  for (double psi=0; psi<360; psi+=self->psi_step)
276  {
277  rotation2DMatrix(psi,A,true);
278  for (double y=-self->max_shift_change; y<=self->max_shift_change; y+=self->shift_step)
279  {
280  MAT_ELEM(A,1,2)=y;
281  for (double x=-self->max_shift_change; x<=self->max_shift_change; x+=self->shift_step, ++block_idx)
282  {
283  MAT_ELEM(A,0,2)=x;
284 
285  // Rotate and shift image
286  applyGeometry(xmipp_transformation::LINEAR,Iaux,mI,A,xmipp_transformation::IS_INV,true);
287 
288  // Update Wnode
289  int i=0;
291  {
292  if (DIRECT_MULTIDIM_ELEM(mask,n)==0)
293  continue;
294  double pixval=DIRECT_MULTIDIM_ELEM(Iaux,n);
295  double *ptrWnode=&MAT_ELEM(Wnode,i,0);
296  double *ptrHblock=&MAT_ELEM(Hblock,block_idx,0);
297  for (int j=0; j<jmax; j+=unroll, ptrHblock+=unroll, ptrWnode+=unroll)
298  {
299  (*ptrWnode) +=pixval*(*ptrHblock);
300  (*(ptrWnode+1)) +=pixval*(*(ptrHblock+1));
301  (*(ptrWnode+2)) +=pixval*(*(ptrHblock+2));
302  (*(ptrWnode+3)) +=pixval*(*(ptrHblock+3));
303  (*(ptrWnode+4)) +=pixval*(*(ptrHblock+4));
304  (*(ptrWnode+5)) +=pixval*(*(ptrHblock+5));
305  (*(ptrWnode+6)) +=pixval*(*(ptrHblock+6));
306  (*(ptrWnode+7)) +=pixval*(*(ptrHblock+7));
307  }
308  for (size_t j=jmax; j<MAT_XSIZE(Wnode); ++j, ptrHblock+=1, ptrWnode+=1)
309  (*ptrWnode) +=pixval*(*ptrHblock );
310  ++i;
311  }
312  }
313  }
314  }
315  }
316  }
317  if (IS_MASTER && thArg.thread_id==0)
318  progress_bar(last);
319  }
320 }
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
void init_progress_bar(long total)
static double * y
void applyGeometry(int SplineDegree, MultidimArray< std::complex< double > > &V2, const MultidimArray< std::complex< double > > &V1, const Matrix2D< double > &A, bool inv, bool wrap, std::complex< double > outside, MultidimArray< double > *BcoeffsPtr)
doublereal * x
#define i
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
glob_log first
#define IS_MASTER
void progress_bar(long rlen)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
void * workClass
The class in which threads will be working.
void rotation2DMatrix(T ang, Matrix2D< T > &result, bool homogeneous)
#define j
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
double psi(const double x)
int thread_id
The thread id.
void initZeros(const MultidimArray< T1 > &op)
int * n

◆ threadApplyTt()

void threadApplyTt ( ThreadArgument thArg)

Definition at line 342 of file image_rotational_pca.cpp.

343 {
344  auto *self=(ProgImageRotationalPCA *) thArg.workClass;
345  //MpiNode *node=self->node;
346  int rank = self->rank;
347  std::vector<size_t> &objId=self->objId;
348  MetaDataVec &MD=self->MD[thArg.thread_id];
349 
350  Image<double> &I=self->I[thArg.thread_id];
351  MultidimArray<double> &Iaux=self->Iaux[thArg.thread_id];
352  Matrix2D<double> &A=self->A[thArg.thread_id];
353  Matrix2D<double> &Hblock=self->Hblock[thArg.thread_id];
354  Matrix2D<double> &H=self->H;
355  Matrix2D<double> &Wtranspose=self->Wtranspose;
356  MultidimArray< unsigned char > &mask=self->mask;
357 
358  const size_t unroll=8;
359  const size_t nmax=(MAT_XSIZE(Wtranspose)/unroll)*unroll;
360 
361  size_t first, last;
362  if (IS_MASTER && thArg.thread_id==0)
363  {
364  std::cout << "Applying Tt ...\n";
365  init_progress_bar(objId.size());
366  }
367  while (self->taskDistributor->getTasks(first, last))
368  {
369  for (size_t idx=first; idx<=last; ++idx)
370  {
371  // Read image
372  I.readApplyGeo(MD,objId[idx]);
373  MultidimArray<double> &mI=I();
374 
375  // For each rotation and shift
376  int block_idx=0;
377  for (int mirror=0; mirror<2; ++mirror)
378  {
379  if (mirror)
380  {
381  mI.selfReverseX();
382  mI.setXmippOrigin();
383  }
384  for (double psi=0; psi<360; psi+=self->psi_step)
385  {
386  rotation2DMatrix(psi,A,true);
387  for (double y=-self->max_shift_change; y<=self->max_shift_change; y+=self->shift_step)
388  {
389  MAT_ELEM(A,1,2)=y;
390  for (double x=-self->max_shift_change; x<=self->max_shift_change; x+=self->shift_step, ++block_idx)
391  {
392  MAT_ELEM(A,0,2)=x;
393 
394  // Rotate and shift image
395  applyGeometry(xmipp_transformation::LINEAR,Iaux,mI,A,xmipp_transformation::IS_INV,true);
396 
397  // Update Hblock
398  for (size_t j=0; j<MAT_XSIZE(Hblock); j++)
399  {
400  double dotproduct=0;
401  const double *ptrIaux=MULTIDIM_ARRAY(Iaux);
402  unsigned char *ptrMask=&DIRECT_MULTIDIM_ELEM(mask,0);
403  const double *ptrWtranspose=&MAT_ELEM(Wtranspose,j,0);
404  for (size_t n=0; n<nmax; n+=unroll, ptrIaux+=unroll, ptrMask+=unroll)
405  {
406  if (*ptrMask)
407  dotproduct+=(*ptrIaux)*(*ptrWtranspose++);
408  if (*(ptrMask+1))
409  dotproduct+=(*(ptrIaux+1))*(*ptrWtranspose++);
410  if (*(ptrMask+2))
411  dotproduct+=(*(ptrIaux+2))*(*ptrWtranspose++);
412  if (*(ptrMask+3))
413  dotproduct+=(*(ptrIaux+3))*(*ptrWtranspose++);
414  if (*(ptrMask+4))
415  dotproduct+=(*(ptrIaux+4))*(*ptrWtranspose++);
416  if (*(ptrMask+5))
417  dotproduct+=(*(ptrIaux+5))*(*ptrWtranspose++);
418  if (*(ptrMask+6))
419  dotproduct+=(*(ptrIaux+6))*(*ptrWtranspose++);
420  if (*(ptrMask+7))
421  dotproduct+=(*(ptrIaux+7))*(*ptrWtranspose++);
422  }
423  for (size_t n=nmax; n<MAT_XSIZE(Wtranspose); ++n, ++ptrMask, ++ptrIaux)
424  if (*ptrMask)
425  dotproduct+=(*ptrIaux)*(*ptrWtranspose++);
426  MAT_ELEM(Hblock,block_idx,j)=dotproduct;
427  }
428  }
429  }
430  }
431  }
432 
433  // Locate the corresponding index in Matrix H
434  // and copy block to disk
435  size_t Hidx=idx*2*self->Nangles*self->Nshifts;
436  // COSS std::cout << "idx=" << idx << " Hidx=" << Hidx << std::endl;
437  // COSS std::cout << "H shape " << MAT_YSIZE(H) << " x " << MAT_XSIZE(H) << std::endl;
438  self->writeToHBuffer(thArg.thread_id,&MAT_ELEM(H,Hidx,0));
439  }
440  if (IS_MASTER && thArg.thread_id==0)
441  progress_bar(last);
442  }
443 }
void init_progress_bar(long total)
int * nmax
static double * y
void applyGeometry(int SplineDegree, MultidimArray< std::complex< double > > &V2, const MultidimArray< std::complex< double > > &V1, const Matrix2D< double > &A, bool inv, bool wrap, std::complex< double > outside, MultidimArray< double > *BcoeffsPtr)
#define MULTIDIM_ARRAY(v)
doublereal * x
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
glob_log first
#define IS_MASTER
void progress_bar(long rlen)
#define DIRECT_MULTIDIM_ELEM(v, n)
void * workClass
The class in which threads will be working.
void rotation2DMatrix(T ang, Matrix2D< T > &result, bool homogeneous)
#define j
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
double psi(const double x)
int thread_id
The thread id.
int * n