Xmipp  v3.23.11-Nereus
Namespaces | Functions
Geometrical transformations
Collaboration diagram for Geometrical transformations:

Namespaces

 applyGeometryImpl
 

Functions

void geo2TransformationMatrix (const MDRow &imageHeader, Matrix2D< double > &A, bool only_apply_shifts=false)
 
bool getLoopRange (double value, double min, double max, double delta, int loopLimit, int &minIter, int &maxIter)
 
void string2TransformationMatrix (const String &matrixStr, Matrix2D< double > &matrix, size_t dim=4)
 
template<typename T >
void transformationMatrix2Parameters2D (const Matrix2D< T > &A, bool &flip, T &scale, T &shiftX, T &shiftY, T &psi)
 
void transformationMatrix2Parameters3D (const Matrix2D< double > &A, bool &flip, double &scale, double &shiftX, double &shiftY, double &shiftZ, double &rot, double &tilt, double &psi)
 
void transformationMatrix2Geo (const Matrix2D< double > &A, MDRow &imageGeo)
 
template<typename T >
void rotation2DMatrix (T ang, Matrix2D< T > &m, bool homogeneous=true)
 
template<typename T >
void translation2DMatrix (const Matrix1D< T > &translation, Matrix2D< T > &resMatrix, bool inverse=false)
 
void rotation3DMatrix (double ang, char axis, Matrix2D< double > &m, bool homogeneous=true)
 
void rotation3DMatrix (double ang, const Matrix1D< double > &axis, Matrix2D< double > &m, bool homogeneous=true)
 
void alignWithZ (const Matrix1D< double > &axis, Matrix2D< double > &m, bool homogeneous=true)
 
template<typename T >
void translation3DMatrix (const Matrix1D< T > &translation, Matrix2D< T > &resMatrix, bool inverse=false)
 
void scale3DMatrix (const Matrix1D< double > &sc, Matrix2D< double > &m, bool homogeneous=true)
 
void rotation3DMatrixFromIcoOrientations (const char *icoFrom, const char *icoTo, Matrix2D< double > &R)
 
template<typename T1 , typename T , typename T2 >
void applyGeometry (int SplineDegree, MultidimArray< T > &__restrict__ V2, const MultidimArray< T1 > &__restrict__ V1, const Matrix2D< T2 > &At, bool inv, bool wrap, T outside=T(0), MultidimArray< double > *BcoeffsPtr=NULL)
 
template<typename T >
void applyGeometry (int SplineDegree, MultidimArray< T > &V2, const MultidimArrayGeneric &V1, const Matrix2D< double > &A, bool inv, bool wrap, T outside=0)
 
template<typename T >
void selfApplyGeometry (int SplineDegree, MultidimArray< T > &V1, const Matrix2D< double > &A, bool inv, bool wrap, T outside=0)
 
template<>
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)
 
template<>
void selfApplyGeometry (int SplineDegree, MultidimArray< std::complex< double > > &V1, const Matrix2D< double > &A, bool inv, bool wrap, std::complex< double > outside)
 
void applyGeometry (int SplineDegree, MultidimArrayGeneric &V2, const MultidimArrayGeneric &V1, const Matrix2D< double > &A, bool inv, bool wrap, double outside)
 
template<typename T >
void produceSplineCoefficients (int SplineDegree, MultidimArray< double > &coeffs, const MultidimArray< T > &V1)
 
void produceSplineCoefficients (int SplineDegree, MultidimArray< double > &coeffs, const MultidimArray< std::complex< double > > &V1)
 
template<typename T >
void produceImageFromSplineCoefficients (int SplineDegree, MultidimArray< T > &img, const MultidimArray< double > &coeffs)
 
template<typename T >
void rotate (int SplineDegree, MultidimArray< T > &V2, const MultidimArray< T > &V1, double ang, char axis='Z', bool wrap=xmipp_transformation::DONT_WRAP, T outside=0)
 
template<typename T >
void selfRotate (int SplineDegree, MultidimArray< T > &V1, double ang, char axis='Z', bool wrap=xmipp_transformation::DONT_WRAP, T outside=0)
 
template<typename T >
void translate (int SplineDegree, MultidimArray< T > &V2, const MultidimArray< T > &V1, const Matrix1D< double > &v, bool wrap=xmipp_transformation::WRAP, T outside=0)
 
template<typename T >
void selfTranslate (int SplineDegree, MultidimArray< T > &V1, const Matrix1D< double > &v, bool wrap=xmipp_transformation::WRAP, T outside=0)
 
template<typename T >
void translateCenterOfMassToCenter (int SplineDegree, MultidimArray< T > &V2, const MultidimArray< T > &V1, bool wrap=xmipp_transformation::WRAP)
 
template<typename T >
void selfTranslateCenterOfMassToCenter (int SplineDegree, MultidimArray< T > &V1, bool wrap=xmipp_transformation::WRAP)
 
template<typename T1 , typename T >
void scaleToSize (int SplineDegree, MultidimArray< T > &V2, const MultidimArray< T1 > &V1, size_t Xdim, size_t Ydim, size_t Zdim=1)
 
template<typename T >
void scaleToSize (int SplineDegree, MultidimArray< T > &V2, const MultidimArrayGeneric &V1, int Xdim, int Ydim, int Zdim=1)
 
template<typename T >
void scaleToSize (int SplineDegree, MultidimArrayGeneric &V2, const MultidimArray< T > &V1, int Xdim, int Ydim, int Zdim=1)
 
void scaleToSize (int SplineDegree, MultidimArrayGeneric &V2, const MultidimArrayGeneric &V1, int Xdim, int Ydim, int Zdim=1)
 
template<typename T >
void selfScaleToSize (int SplineDegree, MultidimArray< T > &V1, int Xdim, int Ydim, int Zdim=1)
 
void selfScaleToSize (int SplineDegree, MultidimArrayGeneric &V1, int Xdim, int Ydim, int Zdim=1)
 
void scaleToSize (int SplineDegree, MultidimArray< std::complex< double > > &V2, const MultidimArray< std::complex< double > > &V1, int Xdim, int Ydim, int Zdim=1)
 
void selfScaleToSize (int SplineDegree, MultidimArray< std::complex< double > > &V1, int Xdim, int Ydim, int Zdim=1)
 
template<typename T >
void reduceBSpline (int SplineDegree, MultidimArray< double > &V2, const MultidimArray< T > &V1)
 
template<typename T >
void expandBSpline (int SplineDegree, MultidimArray< double > &V2, const MultidimArray< T > &V1)
 
template<typename T >
void pyramidReduce (int SplineDegree, MultidimArray< T > &V2, const MultidimArray< T > &V1, int levels=1)
 
template<typename T >
void selfPyramidReduce (int SplineDegree, MultidimArray< T > &V1, int levels=1)
 
void selfPyramidReduce (int SplineDegree, MultidimArrayGeneric &V1, int levels=1)
 
template<typename T >
void pyramidExpand (int SplineDegree, MultidimArray< T > &V2, const MultidimArray< T > &V1, int levels=1)
 
void pyramidExpand (int SplineDegree, MultidimArrayGeneric &V2, const MultidimArrayGeneric &V1, int levels=1)
 
void pyramidReduce (int SplineDegree, MultidimArrayGeneric &V2, const MultidimArrayGeneric &V1, int levels=1)
 
template<typename T >
void selfPyramidExpand (int SplineDegree, MultidimArray< T > &V1, int levels=1)
 
void selfPyramidExpand (int SplineDegree, MultidimArrayGeneric &V1, int levels=1)
 
template<typename T >
void radialAverage (const MultidimArray< T > &m, Matrix1D< int > &center_of_rot, MultidimArray< T > &radial_mean, MultidimArray< int > &radial_count, const bool &rounding=false)
 
template<typename T >
void radialAveragePrecomputeDistance (const MultidimArray< T > &m, Matrix1D< int > &center_of_rot, MultidimArray< int > &distance, int &dim, const bool &rounding=false)
 
template<typename T >
void fastRadialAverage (const MultidimArray< T > &m, const MultidimArray< int > &distance, int dim, MultidimArray< T > &radial_mean, MultidimArray< int > &radial_count)
 
template<typename T >
void radialAverageAxis (const MultidimArray< T > &in, char axis, MultidimArray< double > &out)
 
template<typename T >
void radialAverageNonCubic (const MultidimArray< T > &m, Matrix1D< int > &center_of_rot, MultidimArray< T > &radial_mean, MultidimArray< int > &radial_count, bool rounding=false)
 
void radiallySymmetrize (const MultidimArray< double > &img, MultidimArray< double > &radialImg)
 
double interpolatedElementBSplineDiffX (MultidimArray< double > &vol, double x, double y, double z, int SplineDegree=3)
 
double interpolatedElementBSplineDiffY (MultidimArray< double > &vol, double x, double y, double z, int SplineDegree=3)
 
double interpolatedElementBSplineDiffZ (MultidimArray< double > &vol, double x, double y, double z, int SplineDegree=3)
 

Detailed Description

Function Documentation

◆ alignWithZ()

void alignWithZ ( const Matrix1D< double > &  axis,
Matrix2D< double > &  m,
bool  homogeneous = true 
)

Matrix which transforms the given axis into Z

A geometrical transformation matrix (4x4) is returned such that the given axis is rotated until it is aligned with the Z axis. This is very useful in order to produce rotational matrices, for instance, around any axis.

The returned matrix is such that A*axis=Z, where Z and axis are column vectors.

Definition at line 471 of file transformations.cpp.

473 {
474  if (axis.size() != 3)
475  REPORT_ERROR(ERR_MATRIX_SIZE, "alignWithZ: Axis is not in R3");
476  if (homogeneous)
477  {
478  result.initZeros(4,4);
479  dMij(result,3, 3) = 1;
480  }
481  else
482  result.initZeros(3,3);
483  Matrix1D<double> Axis(axis);
484  Axis.selfNormalize();
485 
486  // Compute length of the projection on YZ plane
487  double proj_mod = sqrt(YY(Axis) * YY(Axis) + ZZ(Axis) * ZZ(Axis));
488  if (proj_mod > XMIPP_EQUAL_ACCURACY)
489  { // proj_mod!=0
490  // Build Matrix result, which makes the turning axis coincident with Z
491  dMij(result,0, 0) = proj_mod;
492  dMij(result,0, 1) = -XX(Axis) * YY(Axis) / proj_mod;
493  dMij(result,0, 2) = -XX(Axis) * ZZ(Axis) / proj_mod;
494  dMij(result,1, 0) = 0;
495  dMij(result,1, 1) = ZZ(Axis) / proj_mod;
496  dMij(result,1, 2) = -YY(Axis) / proj_mod;
497  dMij(result,2, 0) = XX(Axis);
498  dMij(result,2, 1) = YY(Axis);
499  dMij(result,2, 2) = ZZ(Axis);
500  }
501  else
502  {
503  // I know that the Axis is the X axis, EITHER POSITIVE OR NEGATIVE!!
504  dMij(result,0, 0) = 0;
505  dMij(result,0, 1) = 0;
506  dMij(result,0, 2) = (XX(Axis) > 0)? -1 : 1;
507  dMij(result,1, 0) = 0;
508  dMij(result,1, 1) = 1;
509  dMij(result,1, 2) = 0;
510  dMij(result,2, 0) = (XX(Axis) > 0)? 1 : -1;
511  dMij(result,2, 1) = 0;
512  dMij(result,2, 2) = 0;
513  }
514 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
size_t size() const
Definition: matrix1d.h:508
Problem with matrix size.
Definition: xmipp_error.h:152
void sqrt(Image< double > &op)
#define XX(v)
Definition: matrix1d.h:85
#define dMij(m, i, j)
Definition: matrix2d.h:139
#define XMIPP_EQUAL_ACCURACY
Definition: xmipp_macros.h:119
#define YY(v)
Definition: matrix1d.h:93
#define ZZ(v)
Definition: matrix1d.h:101

◆ applyGeometry() [1/4]

template<typename T1 , typename T , typename T2 >
void applyGeometry ( int  SplineDegree,
MultidimArray< T > &__restrict__  V2,
const MultidimArray< T1 > &__restrict__  V1,
const Matrix2D< T2 > &  At,
bool  inv,
bool  wrap,
outside = T(0),
MultidimArray< double > *  BcoeffsPtr = NULL 
)

Applies a geometrical transformation.

Any geometrical transformation defined by the matrix A (double (4x4)!! ie, in homogeneous R3 coordinates) is applied to the volume V1. The result is stored in V2 (it cannot be the same as the input volume). An exception is thrown if the transformation matrix is not 4x4.

Structure of the transformation matrix: It should have the following components

r11 r12 r13 x r21 r22 r23 y r31 r32 r33 z 0 0 0 1

where (x,y,z) is the translation desired, and Rij are the components of the rotation matrix R. If you want to apply a scaling factor to the transformation, then multiply r11, r22 and r33 by it.

The result volume (with ndim=1) is resized to the same dimensions as V1 if V2 is empty (0x0) at the beginning, if it is not, ie, if V2 has got some size then only those values in the volume are filled, this is very useful for resizing the volume, then you manually resize the output volume to the desired size and then call this routine.

The relationship between the output coordinates and the input ones are

out = A * in
(x, y, z) = A * (x', y', z')

This function works independently from the logical indexing of each matrix, it sets the logical center and the physical center of the image and work with these 2 coordinate spaces. At the end the original logical indexing of each matrix is kept.

The procedure followed goes from coordinates in the output volume to the ones in the input one, so the inverse of the A matrix is needed. There is a flag telling if the given matrix is already the inverse one or the normal one. If it is the normal one internally the matrix is inversed. If you are to do many "rotations" then some time is spent in inverting the matrix. Normally the matrix is the normal one.

There is something else to tell about the geometrical tranformation. The value of the voxel in the output volume is computed via bilinear interpolation in the input volume. If any of the voxels participating in the interpolation falls outside the input volume, then automatically the corresponding output voxel is set to 0, unless that the wrap flag has been set to 1. In this case if the voxel falls out by the right hand then it is "wrapped" and the corresponding voxel in the left hand is used. The same is appliable to top-bottom. Usually wrap mode is off. Wrap mode is interesting for translations but not for rotations, for example.

The inverse mode and wrapping mode should be taken by default by the routine, g++ seems to have problems with template functions outside a class with default parameters. So, I'm sorry, you will have to put them always. The usual combination is

applyGeometry(..., IS_NOT_INV, DONT_WRAP).

Although you can also use the constants IS_INV, or WRAP.

A.initIdentity;
applyGeometry(V2, A, V1);

Definition at line 531 of file transformations.h.

536 {
537 #ifndef RELEASE_MODE
538  if (&V1 == (MultidimArray<T1>*)&V2)
539  REPORT_ERROR(ERR_VALUE_INCORRECT,"ApplyGeometry: Input array cannot be the same as output array");
540 
541  if ( V1.getDim()==2 && ((MAT_XSIZE(At) != 3) || (MAT_YSIZE(At) != 3)) )
542  REPORT_ERROR(ERR_MATRIX_SIZE,"ApplyGeometry: 2D transformation matrix is not 3x3");
543 
544  if ( V1.getDim()==3 && ((MAT_XSIZE(At) != 4) || (MAT_YSIZE(At) != 4)) )
545  REPORT_ERROR(ERR_MATRIX_SIZE,"ApplyGeometry: 3D transformation matrix is not 4x4");
546 #endif
547 
548  if (At.isIdentity() && ( XSIZE(V2) == 0 || SAME_SHAPE3D(V1,V2) ) )
549  {
550  typeCast(V1,V2);
551  return;
552  }
553 
554  if (XSIZE(V1) == 0)
555  {
556  V2.clear();
557  return;
558  }
559 
560  MultidimArray<double> Bcoeffs;
561  MultidimArray<double> *BcoeffsToUse=NULL;
562  Matrix2D<double> A, Ainv;
563  typeCast(At, A);
564  const Matrix2D<double> * Aptr=&A;
565  if (!inv)
566  {
567  Ainv = A.inv();
568  Aptr=&Ainv;
569  }
570  const Matrix2D<double> &Aref=*Aptr;
571 
572  // For scalings the output matrix is resized outside to the final
573  // size instead of being resized inside the routine with the
574  // same size as the input matrix
575  if (XSIZE(V2) == 0)
576  V2.resizeNoCopy(V1);
577 
578  if (outside != 0.)
579  {
580  // Initialize output matrix with value=outside
582  DIRECT_MULTIDIM_ELEM(V2, n) = outside;
583  }
584  else
585  V2.initZeros();
586 
587  if (V1.getDim() == 2)
588  {
589  // this version should be slightly more optimized than the general one bellow
590  if (1 == SplineDegree) {
591  if (wrap) {
592  applyGeometryImpl::applyGeometry2DDegree1<T1, T, true>(V2, V1, Aref);
593  } else {
594  applyGeometryImpl::applyGeometry2DDegree1<T1, T, false>(V2, V1, Aref);
595  }
596  return;
597  }
598 
599  // 2D transformation
600  double Aref00=MAT_ELEM(Aref,0,0);
601  double Aref10=MAT_ELEM(Aref,1,0);
602 
603  // Find center and limits of image
604  double cen_y = (int)(YSIZE(V2) / 2);
605  double cen_x = (int)(XSIZE(V2) / 2);
606  double cen_yp = (int)(YSIZE(V1) / 2);
607  double cen_xp = (int)(XSIZE(V1) / 2);
608  double minxp = -cen_xp;
609  double minyp = -cen_yp;
610  double minxpp = minxp-XMIPP_EQUAL_ACCURACY;
611  double minypp = minyp-XMIPP_EQUAL_ACCURACY;
612  double maxxp = XSIZE(V1) - cen_xp - 1;
613  double maxyp = YSIZE(V1) - cen_yp - 1;
614  double maxxpp = maxxp+XMIPP_EQUAL_ACCURACY;
615  double maxypp = maxyp+XMIPP_EQUAL_ACCURACY;
616  size_t Xdim = XSIZE(V1);
617  size_t Ydim = YSIZE(V1);
618 
619  if (SplineDegree > 1)
620  {
621  // Build the B-spline coefficients
622  if (BcoeffsPtr!=NULL)
623  BcoeffsToUse=BcoeffsPtr;
624  else
625  {
626  produceSplineCoefficients(SplineDegree, Bcoeffs, V1); //Bcoeffs is a single image
627  BcoeffsToUse = &Bcoeffs;
628  }
629  STARTINGX(*BcoeffsToUse) = (int) minxp;
630  STARTINGY(*BcoeffsToUse) = (int) minyp;
631  }
632 
633  // Now we go from the output image to the input image, ie, for any pixel
634  // in the output image we calculate which are the corresponding ones in
635  // the original image, make an interpolation with them and put this value
636  // at the output pixel
637 
638 #ifdef DEBUG_APPLYGEO
639  std::cout << "A\n" << Aref << std::endl
640  << "(cen_x ,cen_y )=(" << cen_x << "," << cen_y << ")\n"
641  << "(cen_xp,cen_yp)=(" << cen_xp << "," << cen_yp << ")\n"
642  << "(min_xp,min_yp)=(" << minxp << "," << minyp << ")\n"
643  << "(max_xp,max_yp)=(" << maxxp << "," << maxyp << ")\n";
644 #endif
645  // Calculate position of the beginning of the row in the output image
646  double x = -cen_x;
647  double y = -cen_y;
648  for (size_t i = 0; i < YSIZE(V2); i++)
649  {
650  // Calculate this position in the input image according to the
651  // geometrical transformation
652  // they are related by
653  // coords_output(=x,y) = A * coords_input (=xp,yp)
654  double xp = x * MAT_ELEM(Aref, 0, 0) + y * MAT_ELEM(Aref, 0, 1) + MAT_ELEM(Aref, 0, 2);
655  double yp = x * MAT_ELEM(Aref, 1, 0) + y * MAT_ELEM(Aref, 1, 1) + MAT_ELEM(Aref, 1, 2);
656 
657  // Inner loop boundaries.
658  int globalMin=0, globalMax=XSIZE(V2);
659 
660  if (!wrap)
661  {
662  // First and last iteration with valid values for x and y coordinates.
663  int minX, maxX, minY, maxY;
664 
665  // Compute valid iterations in x and y coordinates. If one of them is always out
666  // of boundaries then the inner loop is not executed this iteration.
667  if (!getLoopRange( xp, minxpp, maxxpp, Aref00, XSIZE(V2), minX, maxX) ||
668  !getLoopRange( yp, minypp, maxypp, Aref10, XSIZE(V2), minY, maxY))
669  {
670  y++;
671  continue;
672  }
673  else
674  {
675  // Compute initial iteration.
676  globalMin = minX;
677  if (minX < minY)
678  {
679  globalMin = minY;
680  }
681 
682  // Compute last iteration.
683  globalMax = maxX;
684  if (maxX > maxY)
685  {
686  globalMax = maxY;
687  }
688  globalMax++;
689 
690  // Check max iteration is not higher than image.
691  if ((globalMax >= 0) && ((size_t)globalMax > XSIZE(V2)))
692  {
693  globalMax = XSIZE(V2);
694  }
695 
696  xp += globalMin*Aref00;
697  yp += globalMin*Aref10;
698  }
699  }
700 
701  // Loop over j is splitted according to wrap (wrap==true is not
702  // vectorizable) and also according to SplineDegree value
703  // (I have not fully analyzed vector dependences for
704  // SplineDegree==3 and else branch)
705  if (wrap)
706  {
707  // This is original implementation
708  for (int j=globalMin; j<globalMax ;j++)
709  {
710 #ifdef DEBUG_APPLYGEO
711 
712  std::cout << "Computing (" << i << "," << j << ")\n";
713  std::cout << " (y, x) =(" << y << "," << x << ")\n"
714  << " before wrapping (y',x')=(" << yp << "," << xp << ") "
715  << std::endl;
716 #endif
717  bool x_isOut = XMIPP_RANGE_OUTSIDE_FAST(xp, minxpp, maxxpp);
718  bool y_isOut = XMIPP_RANGE_OUTSIDE_FAST(yp, minypp, maxypp);
719 
720  if (x_isOut)
721  {
722  xp = realWRAP(xp, minxp - 0.5, maxxp + 0.5);
723  }
724 
725  if (y_isOut)
726  {
727  yp = realWRAP(yp, minyp - 0.5, maxyp + 0.5);
728  }
729 
730 #ifdef DEBUG_APPLYGEO
731 
732  std::cout << " after wrapping (y',x')=(" << yp << "," << xp << ") "
733  << std::endl;
734  std::cout << " Interp = " << interp << std::endl;
735  // The following line sounds dangerous...
736  //x++;
737 #endif
738 
739  if (SplineDegree==1)
740  {
741  // Linear interpolation
742 
743  // Calculate the integer position in input image, be
744  // careful that it is not the nearest but the one
745  // at the top left corner of the interpolation square.
746  // Ie, (0.7,0.7) would give (0,0)
747  // Calculate also weights for point m1+1,n1+1
748  double wx = xp + cen_xp;
749  int m1 = (int) wx;
750  wx = wx - m1;
751  int m2 = m1 + 1;
752  double wy = yp + cen_yp;
753  int n1 = (int) wy;
754  wy = wy - n1;
755  int n2 = n1 + 1;
756 
757  // m2 and n2 can be out by 1 so wrap must be check here
758  if ((m2 >= 0) && ((size_t)m2 >= Xdim))
759  m2 = 0;
760  if ((n2 >=0) && ((size_t)n2 >= Ydim))
761  n2 = 0;
762 
763 #ifdef DEBUG_APPLYGEO
764  std::cout << " From (" << n1 << "," << m1 << ") and ("
765  << n2 << "," << m2 << ")\n";
766  std::cout << " wx= " << wx << " wy= " << wy
767  << std::endl;
768 #endif
769 
770  // Perform interpolation
771  // if wx == 0 means that the rightest point is useless
772  // for this interpolation, and even it might not be
773  // defined if m1=xdim-1
774  // The same can be said for wy.
775  double wx_1 = (1-wx);
776  double wy_1 = (1-wy);
777  double aux2=wy_1* wx_1 ;
778  double tmp = aux2 * DIRECT_A2D_ELEM(V1, n1, m1);
779 
780  if ((wx != 0) && ((m2 < 0) || ((size_t)m2 < V1.xdim)))
781  tmp += (wy_1-aux2) * DIRECT_A2D_ELEM(V1, n1, m2);
782 
783  if ((wy != 0) && ((n2 < 0) || ((size_t)n2 < V1.ydim)))
784  {
785  aux2=wy * wx_1;
786  tmp += aux2 * DIRECT_A2D_ELEM(V1, n2, m1);
787 
788  if ((wx != 0) && ((m2 < 0) || ((size_t)m2 < V1.xdim)))
789  tmp += (wy-aux2) * DIRECT_A2D_ELEM(V1, n2, m2);
790  }
791 
792  dAij(V2, i, j) = (T) tmp;
793  }
794  else if (SplineDegree==0)
795  {
796  dAij(V2, i, j) = (T) A2D_ELEM(V1,(int)trunc(yp),(int)trunc(xp));
797  }
798  else if (SplineDegree==3)
799  {
800  // B-spline interpolation
801  dAij(V2, i, j) = (T) BcoeffsToUse->interpolatedElementBSpline2D_Degree3(xp, yp);
802  }
803  else
804  {
805  // B-spline interpolation
806  dAij(V2, i, j) = (T) BcoeffsToUse->interpolatedElementBSpline2D(xp, yp, SplineDegree);
807  }
808 #ifdef DEBUG_APPYGEO
809  std::cout << " val= " << dAij(V2, i, j) << std::endl;
810 #endif
811 
812  // Compute new point inside input image
813  xp += Aref00;
814  yp += Aref10;
815  }
816  } /* wrap == true */
817  else
818  {
819  if (SplineDegree==1)
820  {
821  #pragma simd reduction (+:xp,yp)
822  for (int j=globalMin; j<globalMax ;j++)
823  {
824 #ifdef DEBUG_APPLYGEO
825 
826  std::cout << "Computing (" << i << "," << j << ")\n";
827  std::cout << " (y, x) =(" << y << "," << x << ")\n"
828  << " before wrapping (y',x')=(" << yp << "," << xp << ") "
829  << std::endl;
830 
831  std::cout << " after wrapping (y',x')=(" << yp << "," << xp << ") "
832  << std::endl;
833  std::cout << " Interp = " << interp << std::endl;
834  // The following line sounds dangerous...
835  //x++;
836 #endif
837 
838  // Linear interpolation
839 
840  // Calculate the integer position in input image, be careful
841  // that it is not the nearest but the one at the top left corner
842  // of the interpolation square. Ie, (0.7,0.7) would give (0,0)
843  // Calculate also weights for point m1+1,n1+1
844  double wx = xp + cen_xp;
845  int m1 = (int) wx;
846  wx = wx - m1;
847  int m2 = m1 + 1;
848  double wy = yp + cen_yp;
849  int n1 = (int) wy;
850  wy = wy - n1;
851  int n2 = n1 + 1;
852 
853 #ifdef DEBUG_APPLYGEO
854  std::cout << " From (" << n1 << "," << m1 << ") and ("
855  << n2 << "," << m2 << ")\n";
856  std::cout << " wx= " << wx << " wy= " << wy << std::endl;
857 #endif
858 
859  // Perform interpolation
860  // if wx == 0 means that the rightest point is useless for this
861  // interpolation, and even it might not be defined if m1=xdim-1
862  // The same can be said for wy.
863  double wx_1 = (1-wx);
864  double wy_1 = (1-wy);
865  double aux2=wy_1* wx_1 ;
866  double tmp = aux2 * DIRECT_A2D_ELEM(V1, n1, m1);
867 
868  if ((wx != 0) && ((m2 < 0) || ((size_t)m2 < V1.xdim)))
869  tmp += (wy_1-aux2) * DIRECT_A2D_ELEM(V1, n1, m2);
870 
871  if ((wy != 0) && ((n2 < 0) || ((size_t)n2 < V1.ydim)))
872  {
873  aux2=wy * wx_1;
874  tmp += aux2 * DIRECT_A2D_ELEM(V1, n2, m1);
875 
876  if ((wx != 0) && ((m2 < 0) || ((size_t)m2 < V1.xdim)))
877  tmp += (wy-aux2) * DIRECT_A2D_ELEM(V1, n2, m2);
878  }
879 
880  dAij(V2, i, j) = (T) tmp;
881 
882 #ifdef DEBUG_APPYGEO
883  std::cout << " val= " << dAij(V2, i, j) << std::endl;
884 #endif
885 
886  // Compute new point inside input image
887  xp += Aref00;
888  yp += Aref10;
889  }
890  }
891  else if (SplineDegree==0)
892  {
893  #pragma simd reduction (+:xp,yp)
894  for (int j=globalMin; j<globalMax ;j++)
895  {
896 #ifdef DEBUG_APPLYGEO
897 
898  std::cout << "Computing (" << i << "," << j << ")\n";
899  std::cout << " (y, x) =(" << y << "," << x << ")\n"
900  << " before wrapping (y',x')=(" << yp << "," << xp << ") "
901  << std::endl;
902 
903  std::cout << " after wrapping (y',x')=(" << yp << "," << xp << ") "
904  << std::endl;
905  std::cout << " Interp = " << interp << std::endl;
906  // The following line sounds dangerous...
907  //x++;
908 #endif
909  dAij(V2, i, j) = (T) A2D_ELEM(V1,(int)trunc(yp),(int)trunc(xp));
910 
911 #ifdef DEBUG_APPYGEO
912  std::cout << " val= " << dAij(V2, i, j) << std::endl;
913 #endif
914 
915  // Compute new point inside input image
916  xp += Aref00;
917  yp += Aref10;
918  }
919  }
920  else if (SplineDegree==3)
921  {
922  for (int j=globalMin; j<globalMax ;j++)
923  {
924 #ifdef DEBUG_APPLYGEO
925 
926  std::cout << "Computing (" << i << "," << j << ")\n";
927  std::cout << " (y, x) =(" << y << "," << x << ")\n"
928  << " before wrapping (y',x')=(" << yp << "," << xp << ") "
929  << std::endl;
930 
931  std::cout << " after wrapping (y',x')=(" << yp << "," << xp << ") "
932  << std::endl;
933  std::cout << " Interp = " << interp << std::endl;
934  // The following line sounds dangerous...
935  //x++;
936 #endif
937 
938  // B-spline interpolation
939  dAij(V2, i, j) = (T) BcoeffsToUse->interpolatedElementBSpline2D_Degree3(xp, yp);
940 
941 #ifdef DEBUG_APPYGEO
942  std::cout << " val= " << dAij(V2, i, j) << std::endl;
943 #endif
944 
945  // Compute new point inside input image
946  xp += Aref00;
947  yp += Aref10;
948  }
949  }
950  else
951  {
952  for (int j=globalMin; j<globalMax ;j++)
953  {
954 #ifdef DEBUG_APPLYGEO
955 
956  std::cout << "Computing (" << i << "," << j << ")\n";
957  std::cout << " (y, x) =(" << y << "," << x << ")\n"
958  << " before wrapping (y',x')=(" << yp << "," << xp << ") "
959  << std::endl;
960 
961  std::cout << " after wrapping (y',x')=(" << yp << "," << xp << ") "
962  << std::endl;
963  std::cout << " Interp = " << interp << std::endl;
964  // The following line sounds dangerous...
965  //x++;
966 #endif
967 
968  // B-spline interpolation
969  dAij(V2, i, j) = (T) BcoeffsToUse->interpolatedElementBSpline2D(xp, yp, SplineDegree);
970 #ifdef DEBUG_APPYGEO
971  std::cout << " val= " << dAij(V2, i, j) << std::endl;
972 #endif
973 
974  // Compute new point inside input image
975  xp += Aref00;
976  yp += Aref10;
977  }
978  }
979  } /* wrap == false */
980 
981  y++;
982  }
983  }
984  else
985  {
986  // 3D transformation
987  size_t m1, n1, o1, m2, n2, o2;
988  double x, y, z, xp, yp, zp;
989  double minxp, minyp, maxxp, maxyp, minzp, maxzp;
990  double cen_x, cen_y, cen_z, cen_xp, cen_yp, cen_zp;
991  double wx, wy, wz;
992  double Aref00=MAT_ELEM(Aref,0,0);
993  double Aref10=MAT_ELEM(Aref,1,0);
994  double Aref20=MAT_ELEM(Aref,2,0);
995 
996  // Find center of MultidimArray
997  cen_z = (int)(V2.zdim / 2);
998  cen_y = (int)(V2.ydim / 2);
999  cen_x = (int)(V2.xdim / 2);
1000  cen_zp = (int)(V1.zdim / 2);
1001  cen_yp = (int)(V1.ydim / 2);
1002  cen_xp = (int)(V1.xdim / 2);
1003  minxp = -cen_xp;
1004  minyp = -cen_yp;
1005  minzp = -cen_zp;
1006  maxxp = V1.xdim - cen_xp - 1;
1007  maxyp = V1.ydim - cen_yp - 1;
1008  maxzp = V1.zdim - cen_zp - 1;
1009 
1010 #ifdef DEBUG
1011 
1012  std::cout << "Geometry 2 center=("
1013  << cen_z << "," << cen_y << "," << cen_x << ")\n"
1014  << "Geometry 1 center=("
1015  << cen_zp << "," << cen_yp << "," << cen_xp << ")\n"
1016  << " min=("
1017  << minzp << "," << minyp << "," << minxp << ")\n"
1018  << " max=("
1019  << maxzp << "," << maxyp << "," << maxxp << ")\n"
1020  ;
1021 #endif
1022 
1023  if (SplineDegree > 1)
1024  {
1025  // Build the B-spline coefficients
1026  if (BcoeffsPtr!=NULL)
1027  BcoeffsToUse=BcoeffsPtr;
1028  else
1029  {
1030  produceSplineCoefficients(SplineDegree, Bcoeffs, V1); //Bcoeffs is a single image
1031  BcoeffsToUse = &Bcoeffs;
1032  }
1033  STARTINGX(*BcoeffsToUse) = (int) minxp;
1034  STARTINGY(*BcoeffsToUse) = (int) minyp;
1035  STARTINGZ(*BcoeffsToUse) = (int) minzp;
1036  }
1037 
1038  // Now we go from the output MultidimArray to the input MultidimArray, ie, for any
1039  // voxel in the output MultidimArray we calculate which are the corresponding
1040  // ones in the original MultidimArray, make an interpolation with them and put
1041  // this value at the output voxel
1042 
1043  // V2 is not initialised to 0 because all its pixels are rewritten
1044  for (size_t k = 0; k < V2.zdim; k++)
1045  for (size_t i = 0; i < V2.ydim; i++)
1046  {
1047  // Calculate position of the beginning of the row in the output
1048  // MultidimArray
1049  x = -cen_x;
1050  y = i - cen_y;
1051  z = k - cen_z;
1052 
1053  // Calculate this position in the input image according to the
1054  // geometrical transformation they are related by
1055  // coords_output(=x,y) = A * coords_input (=xp,yp)
1056  xp = x * MAT_ELEM(Aref, 0, 0) + y * MAT_ELEM(Aref, 0, 1) + z * MAT_ELEM(Aref, 0, 2) + MAT_ELEM(Aref, 0, 3);
1057  yp = x * MAT_ELEM(Aref, 1, 0) + y * MAT_ELEM(Aref, 1, 1) + z * MAT_ELEM(Aref, 1, 2) + MAT_ELEM(Aref, 1, 3);
1058  zp = x * MAT_ELEM(Aref, 2, 0) + y * MAT_ELEM(Aref, 2, 1) + z * MAT_ELEM(Aref, 2, 2) + MAT_ELEM(Aref, 2, 3);
1059 
1060  for (size_t j = 0; j < V2.xdim; j++)
1061  {
1062  bool interp;
1063  double tmp;
1064 
1065 #ifdef DEBUG
1066 
1067  bool show_debug = false;
1068  if ((i == 0 && j == 0 && k == 0) ||
1069  (i == V2.ydim - 1 && j == V2.xdim - 1 && k == V2.zdim - 1))
1070  show_debug = true;
1071 
1072  if (show_debug)
1073  std::cout << "(x,y,z)-->(xp,yp,zp)= "
1074  << "(" << x << "," << y << "," << z << ") "
1075  << "(" << xp << "," << yp << "," << zp << ")\n";
1076 #endif
1077 
1078  // If the point is outside the volume, apply a periodic
1079  // extension of the volume, what exits by one side enters by
1080  // the other
1081  interp = true;
1082  bool x_isOut = XMIPP_RANGE_OUTSIDE(xp, minxp, maxxp);
1083  bool y_isOut = XMIPP_RANGE_OUTSIDE(yp, minyp, maxyp);
1084  bool z_isOut = XMIPP_RANGE_OUTSIDE(zp, minzp, maxzp);
1085 
1086  if (wrap)
1087  {
1088  if (x_isOut)
1089  xp = realWRAP(xp, minxp - 0.5, maxxp + 0.5);
1090 
1091  if (y_isOut)
1092  yp = realWRAP(yp, minyp - 0.5, maxyp + 0.5);
1093 
1094  if (z_isOut)
1095  zp = realWRAP(zp, minzp - 0.5, maxzp + 0.5);
1096  }
1097  else if (x_isOut || y_isOut || z_isOut)
1098  interp = false;
1099 
1100  if (interp)
1101  {
1102  if (SplineDegree == 1)
1103  {
1104  // Linear interpolation
1105 
1106  // Calculate the integer position in input volume, be
1107  // careful that it is not the nearest but the one at the
1108  // top left corner of the interpolation square. Ie,
1109  // (0.7,0.7) would give (0,0)
1110  // Calculate also weights for point m1+1,n1+1
1111  wx = xp + cen_xp;
1112  m1 = (int) wx;
1113  wx = wx - m1;
1114  m2 = m1 + 1;
1115  wy = yp + cen_yp;
1116  n1 = (int) wy;
1117  wy = wy - n1;
1118  n2 = n1 + 1;
1119  wz = zp + cen_zp;
1120  o1 = (int) wz;
1121  wz = wz - o1;
1122  o2 = o1 + 1;
1123 
1124 #ifdef DEBUG
1125 
1126  if (show_debug)
1127  {
1128  std::cout << "After wrapping(xp,yp,zp)= "
1129  << "(" << xp << "," << yp << "," << zp << ")\n";
1130  std::cout << "(m1,n1,o1)-->(m2,n2,o2)="
1131  << "(" << m1 << "," << n1 << "," << o1 << ") "
1132  << "(" << m2 << "," << n2 << "," << o2 << ")\n";
1133  std::cout << "(wx,wy,wz)="
1134  << "(" << wx << "," << wy << "," << wz << ")\n";
1135  }
1136 #endif
1137 
1138  // Perform interpolation
1139  // if wx == 0 means that the rightest point is useless for
1140  // this interpolation, and even it might not be defined if
1141  // m1=xdim-1
1142  // The same can be said for wy.
1143  double wx_1=1-wx;
1144  double wy_1=1-wy;
1145  double wz_1=1-wz;
1146 
1147  double aux1=wz_1 * wy_1;
1148  double aux2=aux1*wx_1;
1149  tmp = aux2 * DIRECT_A3D_ELEM(V1, o1, n1, m1);
1150 
1151  if (wx != 0 && m2 < V1.xdim)
1152  tmp += (aux1-aux2)* DIRECT_A3D_ELEM(V1, o1, n1, m2);
1153 
1154  if (wy != 0 && n2 < V1.ydim)
1155  {
1156  aux1=wz_1 * wy;
1157  aux2=aux1*wx_1;
1158  tmp += aux2 * DIRECT_A3D_ELEM(V1, o1, n2, m1);
1159  if (wx != 0 && m2 < V1.xdim)
1160  tmp += (aux1-aux2) * DIRECT_A3D_ELEM(V1, o1, n2, m2);
1161  }
1162 
1163  if (wz != 0 && o2 < V1.zdim)
1164  {
1165  aux1=wz * wy_1;
1166  aux2=aux1*wx_1;
1167  tmp += aux2 * DIRECT_A3D_ELEM(V1, o2, n1, m1);
1168  if (wx != 0 && m2 < V1.xdim)
1169  tmp += (aux1-aux2) * DIRECT_A3D_ELEM(V1, o2, n1, m2);
1170  if (wy != 0 && n2 < V1.ydim)
1171  {
1172  aux1=wz * wy;
1173  aux2=aux1*wx_1;
1174  tmp += aux2 * DIRECT_A3D_ELEM(V1, o2, n2, m1);
1175  if (wx != 0 && m2 < V1.xdim)
1176  tmp += (aux1-aux2) * DIRECT_A3D_ELEM(V1, o2, n2, m2);
1177  }
1178  }
1179 
1180 #ifdef DEBUG
1181  if (show_debug)
1182  std::cout <<
1183  "tmp1=" << DIRECT_A3D_ELEM(V1, o1, n1, m1) << " "
1184  << (T)(wz_1 *wy_1 *wx_1 * DIRECT_A3D_ELEM(V1, o1, n1, m1))
1185  << std::endl <<
1186  "tmp2=" << DIRECT_A3D_ELEM(V1, o1, n1, m2) << " "
1187  << (T)(wz_1 *wy_1 * wx * DIRECT_A3D_ELEM(V1, o1, n1, m2))
1188  << std::endl <<
1189  "tmp3=" << DIRECT_A3D_ELEM(V1, o1, n2, m1) << " "
1190  << (T)(wz_1 * wy *wx_1 * DIRECT_A3D_ELEM(V1, o1, n2, m1))
1191  << std::endl <<
1192  "tmp4=" << DIRECT_A3D_ELEM(V1, o1, n2, m2) << " "
1193  << (T)(wz_1 * wy * wx * DIRECT_A3D_ELEM(V1, o2, n1, m1))
1194  << std::endl <<
1195  "tmp6=" << DIRECT_A3D_ELEM(V1, o2, n1, m2) << " "
1196  << (T)(wz * wy_1 * wx * DIRECT_A3D_ELEM(V1, o2, n1, m2))
1197  << std::endl <<
1198  "tmp7=" << DIRECT_A3D_ELEM(V1, o2, n2, m1) << " "
1199  << (T)(wz * wy *wx_1 * DIRECT_A3D_ELEM(V1, o2, n2, m1))
1200  << std::endl <<
1201  "tmp8=" << DIRECT_A3D_ELEM(V1, o2, n2, m2) << " "
1202  << (T)(wz * wy * wx * DIRECT_A3D_ELEM(V1, o2, n2, m2))
1203  << std::endl <<
1204  "tmp= " << tmp << std::endl;
1205 #endif
1206 
1207  dAkij(V2 , k, i, j) = (T)tmp;
1208  }
1209  else if (SplineDegree==0)
1210  {
1211  dAkij(V2, k, i, j)=(T)A3D_ELEM(V1,(int)trunc(zp),(int)trunc(yp),(int)trunc(xp));
1212  }
1213  else
1214  {
1215  // B-spline interpolation
1216  dAkij(V2, k, i, j) =
1217  (T) BcoeffsToUse->interpolatedElementBSpline3D(xp, yp, zp, SplineDegree);
1218  }
1219  }
1220  else
1221  dAkij(V2, k, i, j) = outside;
1222 
1223  // Compute new point inside input image
1224  xp += Aref00;
1225  yp += Aref10;
1226  zp += Aref20;
1227  }
1228  }
1229  }
1230 }
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
bool isIdentity() const
Definition: matrix2d.cpp:1323
#define YSIZE(v)
#define A2D_ELEM(v, i, j)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
T interpolatedElementBSpline2D_Degree3(double x, double y) const
Problem with matrix size.
Definition: xmipp_error.h:152
void resizeNoCopy(const MultidimArray< T1 > &v)
#define dAij(M, i, j)
static double * y
T interpolatedElementBSpline3D(double x, double y, double z, int SplineDegree=3) const
#define DIRECT_A2D_ELEM(v, i, j)
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
#define SAME_SHAPE3D(v1, v2)
#define STARTINGX(v)
doublereal * x
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define STARTINGY(v)
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
#define A3D_ELEM(V, k, i, j)
#define XMIPP_EQUAL_ACCURACY
Definition: xmipp_macros.h:119
void produceSplineCoefficients(int SplineDegree, MultidimArray< double > &coeffs, const MultidimArray< T > &V1)
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define dAkij(V, k, i, j)
double z
#define DIRECT_MULTIDIM_ELEM(v, n)
#define DIRECT_A3D_ELEM(v, k, i, j)
#define XMIPP_RANGE_OUTSIDE(x, min, max)
Definition: xmipp_macros.h:126
T interpolatedElementBSpline2D(double x, double y, int SplineDegree=3) const
#define j
int trunc(double x)
Definition: ap.cpp:7248
void typeCast(const Matrix1D< T1 > &v1, Matrix1D< T2 > &v2)
Definition: matrix1d.h:1227
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
bool getLoopRange(double value, double min, double max, double delta, int loopLimit, int &minIter, int &maxIter)
#define realWRAP(x, x0, xF)
Definition: xmipp_macros.h:304
#define XMIPP_RANGE_OUTSIDE_FAST(x, min, max)
Definition: xmipp_macros.h:128
void initZeros(const MultidimArray< T1 > &op)
Incorrect value received.
Definition: xmipp_error.h:195
#define STARTINGZ(v)
int * n

◆ applyGeometry() [2/4]

template<typename T >
void applyGeometry ( int  SplineDegree,
MultidimArray< T > &  V2,
const MultidimArrayGeneric V1,
const Matrix2D< double > &  A,
bool  inv,
bool  wrap,
outside = 0 
)

Definition at line 1234 of file transformations.h.

1239 {
1240 #define APPLYGEO(type) applyGeometry(SplineDegree,V2, (*(MultidimArray<type>*)(V1.im)), A, inv, wrap, outside);
1242 #undef APPLYGEO
1243 }
#define APPLYGEO(type)
#define SWITCHDATATYPE(datatype, OP)

◆ applyGeometry() [3/4]

template<>
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 
)

Definition at line 668 of file transformations.cpp.

674 {
675 
676  if (SplineDegree > 1)
677  {
678  MultidimArray<double> re, im, rotre, rotim;
680  double outre, outim;
681  re.resize(ZSIZE(V1), YSIZE(V1), XSIZE(V1));
682  im.resize(ZSIZE(V1), YSIZE(V1), XSIZE(V1));
683  outre = outside.real();
684  outim = outside.imag();
685  oneImg=V1;
688  MULTIDIM_SIZE(oneImg));
689  applyGeometry(SplineDegree, rotre, re, A, inv, wrap, outre);
690  applyGeometry(SplineDegree, rotim, im, A, inv, wrap, outim);
691  V2.resize(oneImg);
693  MULTIDIM_ARRAY(V2), MULTIDIM_SIZE(re));
694  }
695  else
696  { //FIXME I do not think you want to recall your self
697  REPORT_ERROR(ERR_NOT_IMPLEMENTED,"I do not think you want to recall your self");
698  // applyGeometry(SplineDegree, V2, V1, A, inv, wrap, outside); // this was causing crash of the sonarcloud analyzer
699  }
700 }
#define YSIZE(v)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
Case or algorithm not implemented yet.
Definition: xmipp_error.h:177
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
#define MULTIDIM_SIZE(v)
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)
void RealImag2Complex(const MultidimArray< double > &real, const MultidimArray< double > &imag, MultidimArray< std::complex< double > > &out)
Definition: xmipp_fft.cpp:114
#define XSIZE(v)
#define ZSIZE(v)
void Complex2RealImag(const MultidimArray< std::complex< double > > &in, MultidimArray< double > &real, MultidimArray< double > &imag)
Definition: xmipp_fft.cpp:103

◆ applyGeometry() [4/4]

void applyGeometry ( int  SplineDegree,
MultidimArrayGeneric V2,
const MultidimArrayGeneric V1,
const Matrix2D< double > &  A,
bool  inv,
bool  wrap,
double  outside 
)

Definition at line 713 of file transformations.cpp.

718 {
719 #define APPLYGEO(type) applyGeometry(SplineDegree,(*(MultidimArray<type>*)(V2.im)), \
720  (*(MultidimArray<type>*)(V1.im)), A, inv, wrap, (type) outside);
722 #undef APPLYGEO
723 
724 }
#define APPLYGEO(type)
#define SWITCHDATATYPE(datatype, OP)

◆ expandBSpline()

template<typename T >
void expandBSpline ( int  SplineDegree,
MultidimArray< double > &  V2,
const MultidimArray< T > &  V1 
)

Expand a set of B-spline coefficients.

Knowing that V1 is a (single image of) B-spline coefficients, produce the expanded set of B-spline coefficients using the two-scale relationship.

Definition at line 144 of file transformations.cpp.

147 {
148  double g[200]; // Coefficients of the reduce filter
149  long ng; // Number of coefficients of the reduce filter
150  double h[200]; // Coefficients of the expansion filter
151  long nh; // Number of coefficients of the expansion filter
152  short IsCentered; // Equal TRUE if the filter is a centered spline, FALSE otherwise */
153 
154  // Get the filter
155  if (GetPyramidFilter("Centered Spline", SplineDegree, g, &ng, h, &nh,
156  &IsCentered))
157  REPORT_ERROR(ERR_UNCLASSIFIED, "Unable to load the filter coefficients");
158 
160  typeCast(V1, aux);
161 
162  if (V1.getDim() == 2)
163  {
164  V2.initZeros(2 * YSIZE(aux), 2 * XSIZE(aux));
165  Expand_2D(MULTIDIM_ARRAY(aux), XSIZE(aux), YSIZE(aux),
166  MULTIDIM_ARRAY(V2), h, nh, IsCentered);
167  }
168  else if (V1.getDim() == 3)
169  {
170  V2.initZeros(2 * ZSIZE(aux), 2 * YSIZE(aux), 2 * XSIZE(aux));
171  Expand_3D(MULTIDIM_ARRAY(aux), XSIZE(aux), YSIZE(aux), ZSIZE(aux),
172  MULTIDIM_ARRAY(V2), h, nh, IsCentered);
173  }
174  else
175  REPORT_ERROR(ERR_MULTIDIM_DIM,"expandBSpline ERROR: only valid for 2D or 3D arrays");
176 }
Just to locate unclassified errors.
Definition: xmipp_error.h:192
#define YSIZE(v)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
int Expand_3D(double *In, long int NxIn, long int NyIn, long int NzIn, double *Out, double h[], long int nh, short FlagCentered)
doublereal * g
int Expand_2D(double *In, long int NxIn, long int NyIn, double *Out, double h[], long int nh, short FlagCentered)
#define MULTIDIM_ARRAY(v)
#define XSIZE(v)
#define ZSIZE(v)
void typeCast(const Matrix1D< T1 > &v1, Matrix1D< T2 > &v2)
Definition: matrix1d.h:1227
Incorrect MultidimArray dimensions.
Definition: xmipp_error.h:173
void initZeros(const MultidimArray< T1 > &op)
int GetPyramidFilter(const char *Filter, long int Order, double g[], long int *ng, double h[], long int *nh, short *FlagCentered)

◆ fastRadialAverage()

template<typename T >
void fastRadialAverage ( const MultidimArray< T > &  m,
const MultidimArray< int > &  distance,
int  dim,
MultidimArray< T > &  radial_mean,
MultidimArray< int > &  radial_count 
)

Definition at line 1854 of file transformations.h.

1859 {
1860  // Define the vectors
1861  radial_mean.initZeros(dim);
1862  radial_count.initZeros(dim);
1863 
1864  // Perform the radial sum and count pixels that contribute to every
1865  // distance
1867  {
1868  int d=DIRECT_MULTIDIM_ELEM(distance,n);
1869  A1D_ELEM(radial_mean,d) += DIRECT_MULTIDIM_ELEM(m,n);
1870  ++A1D_ELEM(radial_count,d);
1871  }
1872 
1873  // Perform the mean
1875  if (DIRECT_MULTIDIM_ELEM(radial_count,i) > 0)
1876  DIRECT_MULTIDIM_ELEM(radial_mean,i) /= DIRECT_MULTIDIM_ELEM(radial_count,i);
1877 }
#define A1D_ELEM(v, i)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY1D(v)
#define i
doublereal * d
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
void initZeros(const MultidimArray< T1 > &op)
int * n

◆ geo2TransformationMatrix()

void geo2TransformationMatrix ( const MDRow imageHeader,
Matrix2D< double > &  A,
bool  only_apply_shifts = false 
)

Get geometric transformation matrix from image geometry Now this info is stored in metadata The order is: first flip (if necessary), then rotate, then shift A=Translation*Rotation*(Mirror)

Definition at line 178 of file transformations.cpp.

180 {
181  // This has only been implemented for 2D images...
182  double psi = 0, shiftX = 0., shiftY = 0., scale = 1.;
183  bool flip = false;
184 
185  imageGeo.getValue(MDL_ANGLE_PSI, psi);
186  imageGeo.getValue(MDL_SHIFT_X, shiftX);
187  imageGeo.getValue(MDL_SHIFT_Y, shiftY);
188  imageGeo.getValue(MDL_SCALE, scale);
189  imageGeo.getValue(MDL_FLIP, flip);
190 
191  psi = realWRAP(psi, 0., 360.);
192 
193  int dim = A.Xdim() - 1;
194  //This check the case when matrix A is not initialized with correct size
195  if (dim < 2 || dim > 3)
196  {
197  dim = 3;
198  A.resizeNoCopy(dim + 1, dim + 1);
199  }
200 
201  if (only_apply_shifts)
202  A.initIdentity();
203  else if (dim == 2) //2D geometry
204  rotation2DMatrix(psi, A, true);
205  else if (dim == 3)//3D geometry
206  {
207  double rot = 0., tilt = 0., shiftZ = 0.;
208  imageGeo.getValue(MDL_ANGLE_ROT, rot);
209  imageGeo.getValue(MDL_ANGLE_TILT, tilt);
210  imageGeo.getValue(MDL_SHIFT_Z, shiftZ);
211  Euler_angles2matrix(rot, tilt, psi, A, true);
212  dMij(A, 2, dim) = shiftZ;
213  }
214  dMij(A, 0, dim) = shiftX;
215  dMij(A, 1, dim) = shiftY;
216 
217  if (scale != 1.)
218  {
219  if (scale==0.) // Protection against badly formed metadatas
220  scale=1.0;
221  if (dim == 2)
222  {
223  M3x3_BY_CT(A, A, scale);
224  }
225  else if (dim == 3)
226  {
227  M4x4_BY_CT(A, A, scale);
228  }
229  dMij(A, dim, dim) = 1.;
230  }
231 
232  if (flip)
233  {
234  dMij(A, 0, 0) *= -1.;
235  dMij(A, 0, 1) *= -1.;
236  if (dim == 3)
237  dMij(A, 0, 2) *= -1.;
238  }
239 }
size_t Xdim() const
Definition: matrix2d.h:575
Rotation angle of an image (double,degrees)
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
Tilting angle of an image (double,degrees)
Shift for the image in the X axis (double)
Special label to be used when gathering MDs in MpiMetadataPrograms.
void resizeNoCopy(int Ydim, int Xdim)
Definition: matrix2d.h:534
#define dMij(m, i, j)
Definition: matrix2d.h:139
Flip the image? (bool)
#define M3x3_BY_CT(M2, M1, k)
Definition: matrix2d.h:248
scaling factor for an image or volume (double)
void rotation2DMatrix(T ang, Matrix2D< T > &result, bool homogeneous)
double psi(const double x)
#define M4x4_BY_CT(M2, M1, k)
Definition: matrix2d.h:263
Shift for the image in the Z axis (double)
#define realWRAP(x, x0, xF)
Definition: xmipp_macros.h:304
Shift for the image in the Y axis (double)
void initIdentity()
Definition: matrix2d.h:673

◆ getLoopRange()

bool getLoopRange ( double  value,
double  min,
double  max,
double  delta,
int  loopLimit,
int &  minIter,
int &  maxIter 
)

Definition at line 603 of file transformations.cpp.

605 {
606  bool validRange=true;// Return value. TRUE if input value is into range boundaries.
607 
608  // Value is under lower boundary.
609  if (value < min)
610  {
611  // If delta is negative -> moving to lower values and never into valid range.
612  if (delta <= DELTA_THRESHOLD)
613  {
614  validRange = false;
615  }
616  // Compute first and last iterations into valid values.
617  else
618  {
619  minIter = (int) (fabs(min - value) / delta);
620  minIter++;
621  maxIter = (int) (fabs(max - value) / delta);
622  }
623  }
624  // Value is over upper boundary.
625  else if (value >= max)
626  {
627  // If delta is negative -> moving to lower values and never into valid range.
628  if (delta >= -DELTA_THRESHOLD)
629  {
630  validRange = false;
631  }
632  // Compute first and last iterations into valid values.
633  else
634  {
635  minIter = (int) (fabs(value - max) / -delta);
636  minIter++;
637  maxIter = (int) (fabs(value - min) / -delta);
638  }
639  }
640  // First value into valid range.
641  else
642  {
643  // Compute first and last iterations into valid values.
644  if (delta > DELTA_THRESHOLD)
645  {
646  minIter = 0;
647  maxIter = (int) (fabs(max - value) / delta);
648  }
649  // Compute first and last iterations into valid values.
650  else if (delta < -DELTA_THRESHOLD)
651  {
652  minIter = 0;
653  maxIter = (int) (fabs(value - min) / -delta);
654  }
655  // If delta is zero then always in valid range.
656  else
657  {
658  minIter = 0;
659  maxIter = loopLimit;
660  }
661  }
662 
663  return(validRange);
664 }
void min(Image< double > &op1, const Image< double > &op2)
void max(Image< double > &op1, const Image< double > &op2)
#define DELTA_THRESHOLD
double * delta

◆ interpolatedElementBSplineDiffX()

double interpolatedElementBSplineDiffX ( MultidimArray< double > &  vol,
double  x,
double  y,
double  z,
int  SplineDegree 
)

Interpolates the value of the 3D matrix M at the point (x,y,z) knowing that this image is a set of B-spline coefficients. And making the diff of x, such-> V=sum(Coef diff(Bx) By Bz) Only for BSplines of degree 3!!

(x,y,z) are in logical coordinates.

Definition at line 853 of file transformations.cpp.

856 {
857  int SplineDegree_1 = SplineDegree - 1;
858  double aux;
859 
860  // Logical to physical
861  z -= STARTINGZ(vol);
862  y -= STARTINGY(vol);
863  x -= STARTINGX(vol);
864 
865  int l1 = CEIL(x - SplineDegree_1);
866  int l2 = l1 + SplineDegree;
867 
868  int m1 = CEIL(y - SplineDegree_1);
869  int m2 = m1 + SplineDegree;
870 
871  int n1 = CEIL(z - SplineDegree_1);
872  int n2 = n1 + SplineDegree;
873 
874  double zyxsum = 0.0;
875  int Zdim=(int)ZSIZE(vol);
876  int Ydim=(int)YSIZE(vol);
877  int Xdim=(int)XSIZE(vol);
878  for (int n = n1; n <= n2; n++)
879  {
880  int equivalent_n=n;
881  if (n<0)
882  equivalent_n=-n-1;
883  else if (n>=Zdim)
884  equivalent_n=2*Zdim-n-1;
885  double yxsum = 0.0;
886  for (int m = m1; m <= m2; m++)
887  {
888  int equivalent_m=m;
889  if (m<0)
890  equivalent_m=-m-1;
891  else if (m>=Ydim)
892  equivalent_m=2*Ydim-m-1;
893  double xsum = 0.0;
894  for (int l = l1; l <= l2; l++)
895  {
896  double xminusl = x - (double) l;
897  int equivalent_l=l;
898  if (l<0)
899  equivalent_l=-l-1;
900  else if (l>=Xdim)
901  equivalent_l=2*Xdim-l-1;
902  double Coeff = (double) DIRECT_A3D_ELEM(vol, equivalent_n,
903  equivalent_m,
904  equivalent_l );
905  switch (SplineDegree)
906  {
907  case 2:
908  xsum += Coeff * Bspline02(xminusl);
909  break;
910  case 3:
911  BSPLINE03DIFF1(aux,xminusl);
912  xsum += Coeff * aux;
913  break;
914  case 4:
915  xsum += Coeff * Bspline04(xminusl);
916  break;
917  case 5:
918  xsum += Coeff * Bspline05(xminusl);
919  break;
920  case 6:
921  xsum += Coeff * Bspline06(xminusl);
922  break;
923  case 7:
924  xsum += Coeff * Bspline07(xminusl);
925  break;
926  case 8:
927  xsum += Coeff * Bspline08(xminusl);
928  break;
929  case 9:
930  xsum += Coeff * Bspline09(xminusl);
931  break;
932  }
933  }
934 
935  double yminusm = y - (double) m;
936  switch (SplineDegree)
937  {
938  case 2:
939  yxsum += xsum * Bspline02(yminusm);
940  break;
941  case 3:
942  BSPLINE03(aux,yminusm);
943  yxsum += xsum * aux;
944  break;
945  case 4:
946  yxsum += xsum * Bspline04(yminusm);
947  break;
948  case 5:
949  yxsum += xsum * Bspline05(yminusm);
950  break;
951  case 6:
952  yxsum += xsum * Bspline06(yminusm);
953  break;
954  case 7:
955  yxsum += xsum * Bspline07(yminusm);
956  break;
957  case 8:
958  yxsum += xsum * Bspline08(yminusm);
959  break;
960  case 9:
961  yxsum += xsum * Bspline09(yminusm);
962  break;
963  }
964  }
965 
966  double zminusn = z - (double) n;
967  switch (SplineDegree)
968  {
969  case 2:
970  zyxsum += yxsum * Bspline02(zminusn);
971  break;
972  case 3:
973  BSPLINE03(aux,zminusn);
974  zyxsum += yxsum * aux;
975  break;
976  case 4:
977  zyxsum += yxsum * Bspline04(zminusn);
978  break;
979  case 5:
980  zyxsum += yxsum * Bspline05(zminusn);
981  break;
982  case 6:
983  zyxsum += yxsum * Bspline06(zminusn);
984  break;
985  case 7:
986  zyxsum += yxsum * Bspline07(zminusn);
987  break;
988  case 8:
989  zyxsum += yxsum * Bspline08(zminusn);
990  break;
991  case 9:
992  zyxsum += yxsum * Bspline09(zminusn);
993  break;
994  }
995  }
996 
997  return zyxsum;
998 }
#define YSIZE(v)
double Bspline05(double Argument)
static double * y
#define BSPLINE03DIFF1(y, x)
Definition: kerneldiff1.h:60
#define STARTINGX(v)
doublereal * x
double Bspline04(double Argument)
#define STARTINGY(v)
#define CEIL(x)
Definition: xmipp_macros.h:225
#define XSIZE(v)
double Bspline07(double Argument)
#define ZSIZE(v)
double z
double Bspline08(double Argument)
#define DIRECT_A3D_ELEM(v, k, i, j)
int m
double Bspline02(double Argument)
double Bspline09(double Argument)
double Bspline06(double Argument)
#define STARTINGZ(v)
int * n
#define BSPLINE03(y, x)
Definition: kernel.h:83

◆ interpolatedElementBSplineDiffY()

double interpolatedElementBSplineDiffY ( MultidimArray< double > &  vol,
double  x,
double  y,
double  z,
int  SplineDegree 
)

Interpolates the value of the 3D matrix M at the point (x,y,z) knowing that this image is a set of B-spline coefficients. And making the diff of y, such-> V=sum(Coef Bx diff(By) Bz) Only for BSplines of degree 3!!

(x,y,z) are in logical coordinates.

Definition at line 1008 of file transformations.cpp.

1011 {
1012  int SplineDegree_1 = SplineDegree - 1;
1013  double aux;
1014 
1015  // Logical to physical
1016  z -= STARTINGZ(vol);
1017  y -= STARTINGY(vol);
1018  x -= STARTINGX(vol);
1019 
1020  int l1 = CEIL(x - SplineDegree_1);
1021  int l2 = l1 + SplineDegree;
1022 
1023  int m1 = CEIL(y - SplineDegree_1);
1024  int m2 = m1 + SplineDegree;
1025 
1026  int n1 = CEIL(z - SplineDegree_1);
1027  int n2 = n1 + SplineDegree;
1028 
1029  double zyxsum = 0.0;
1030  int Zdim=(int)ZSIZE(vol);
1031  int Ydim=(int)YSIZE(vol);
1032  int Xdim=(int)XSIZE(vol);
1033  for (int n = n1; n <= n2; n++)
1034  {
1035  int equivalent_n=n;
1036  if (n<0)
1037  equivalent_n=-n-1;
1038  else if (n>=Zdim)
1039  equivalent_n=2*Zdim-n-1;
1040  double yxsum = 0.0;
1041  for (int m = m1; m <= m2; m++)
1042  {
1043  int equivalent_m=m;
1044  if (m<0)
1045  equivalent_m=-m-1;
1046  else if (m>=Ydim)
1047  equivalent_m=2*Ydim-m-1;
1048  double xsum = 0.0;
1049  for (int l = l1; l <= l2; l++)
1050  {
1051  double xminusl = x - (double) l;
1052  int equivalent_l=l;
1053  if (l<0)
1054  equivalent_l=-l-1;
1055  else if (l>=Xdim)
1056  equivalent_l=2*Xdim-l-1;
1057  double Coeff = (double) DIRECT_A3D_ELEM(vol, equivalent_n,
1058  equivalent_m,
1059  equivalent_l );
1060  double aux;
1061  switch (SplineDegree)
1062  {
1063  case 2:
1064  xsum += Coeff * Bspline02(xminusl);
1065  break;
1066  case 3:
1067  BSPLINE03(aux,xminusl);
1068  xsum += Coeff * aux;
1069  break;
1070  case 4:
1071  xsum += Coeff * Bspline04(xminusl);
1072  break;
1073  case 5:
1074  xsum += Coeff * Bspline05(xminusl);
1075  break;
1076  case 6:
1077  xsum += Coeff * Bspline06(xminusl);
1078  break;
1079  case 7:
1080  xsum += Coeff * Bspline07(xminusl);
1081  break;
1082  case 8:
1083  xsum += Coeff * Bspline08(xminusl);
1084  break;
1085  case 9:
1086  xsum += Coeff * Bspline09(xminusl);
1087  break;
1088  }
1089  }
1090 
1091  double yminusm = y - (double) m;
1092  switch (SplineDegree)
1093  {
1094  case 2:
1095  yxsum += xsum * Bspline02(yminusm);
1096  break;
1097  case 3:
1098  BSPLINE03DIFF1(aux,yminusm);
1099  yxsum += xsum * aux;
1100  break;
1101  case 4:
1102  yxsum += xsum * Bspline04(yminusm);
1103  break;
1104  case 5:
1105  yxsum += xsum * Bspline05(yminusm);
1106  break;
1107  case 6:
1108  yxsum += xsum * Bspline06(yminusm);
1109  break;
1110  case 7:
1111  yxsum += xsum * Bspline07(yminusm);
1112  break;
1113  case 8:
1114  yxsum += xsum * Bspline08(yminusm);
1115  break;
1116  case 9:
1117  yxsum += xsum * Bspline09(yminusm);
1118  break;
1119  }
1120  }
1121 
1122  double zminusn = z - (double) n;
1123  switch (SplineDegree)
1124  {
1125  case 2:
1126  zyxsum += yxsum * Bspline02(zminusn);
1127  break;
1128  case 3:
1129  BSPLINE03(aux,zminusn);
1130  zyxsum += yxsum * aux;
1131  break;
1132  case 4:
1133  zyxsum += yxsum * Bspline04(zminusn);
1134  break;
1135  case 5:
1136  zyxsum += yxsum * Bspline05(zminusn);
1137  break;
1138  case 6:
1139  zyxsum += yxsum * Bspline06(zminusn);
1140  break;
1141  case 7:
1142  zyxsum += yxsum * Bspline07(zminusn);
1143  break;
1144  case 8:
1145  zyxsum += yxsum * Bspline08(zminusn);
1146  break;
1147  case 9:
1148  zyxsum += yxsum * Bspline09(zminusn);
1149  break;
1150  }
1151  }
1152 
1153  return zyxsum;
1154 }
#define YSIZE(v)
double Bspline05(double Argument)
static double * y
#define BSPLINE03DIFF1(y, x)
Definition: kerneldiff1.h:60
#define STARTINGX(v)
doublereal * x
double Bspline04(double Argument)
#define STARTINGY(v)
#define CEIL(x)
Definition: xmipp_macros.h:225
#define XSIZE(v)
double Bspline07(double Argument)
#define ZSIZE(v)
double z
double Bspline08(double Argument)
#define DIRECT_A3D_ELEM(v, k, i, j)
int m
double Bspline02(double Argument)
double Bspline09(double Argument)
double Bspline06(double Argument)
#define STARTINGZ(v)
int * n
#define BSPLINE03(y, x)
Definition: kernel.h:83

◆ interpolatedElementBSplineDiffZ()

double interpolatedElementBSplineDiffZ ( MultidimArray< double > &  vol,
double  x,
double  y,
double  z,
int  SplineDegree 
)

Interpolates the value of the 3D matrix M at the point (x,y,z) knowing that this image is a set of B-spline coefficients. And making the diff of z, such-> V=sum(Coef Bx By diff(Bz)) Only for BSplines of degree 3!!

(x,y,z) are in logical coordinates.

Definition at line 1164 of file transformations.cpp.

1167 {
1168  int SplineDegree_1 = SplineDegree - 1;
1169  double aux;
1170 
1171  // Logical to physical
1172  z -= STARTINGZ(vol);
1173  y -= STARTINGY(vol);
1174  x -= STARTINGX(vol);
1175 
1176  int l1 = CEIL(x - SplineDegree_1);
1177  int l2 = l1 + SplineDegree;
1178 
1179  int m1 = CEIL(y - SplineDegree_1);
1180  int m2 = m1 + SplineDegree;
1181 
1182  int n1 = CEIL(z - SplineDegree_1);
1183  int n2 = n1 + SplineDegree;
1184 
1185  double zyxsum = 0.0;
1186  int Zdim=(int)ZSIZE(vol);
1187  int Ydim=(int)YSIZE(vol);
1188  int Xdim=(int)XSIZE(vol);
1189  for (int n = n1; n <= n2; n++)
1190  {
1191  int equivalent_n=n;
1192  if (n<0)
1193  equivalent_n=-n-1;
1194  else if (n>=Zdim)
1195  equivalent_n=2*Zdim-n-1;
1196  double yxsum = 0.0;
1197  for (int m = m1; m <= m2; m++)
1198  {
1199  int equivalent_m=m;
1200  if (m<0)
1201  equivalent_m=-m-1;
1202  else if (m>=Ydim)
1203  equivalent_m=2*Ydim-m-1;
1204  double xsum = 0.0;
1205  for (int l = l1; l <= l2; l++)
1206  {
1207  double xminusl = x - (double) l;
1208  int equivalent_l=l;
1209  if (l<0)
1210  equivalent_l=-l-1;
1211  else if (l>=Xdim)
1212  equivalent_l=2*Xdim-l-1;
1213  double Coeff = (double) DIRECT_A3D_ELEM(vol, equivalent_n,
1214  equivalent_m,
1215  equivalent_l );
1216  double aux;
1217  switch (SplineDegree)
1218  {
1219  case 2:
1220  xsum += Coeff * Bspline02(xminusl);
1221  break;
1222  case 3:
1223  BSPLINE03(aux,xminusl);
1224  xsum += Coeff * aux;
1225  break;
1226  case 4:
1227  xsum += Coeff * Bspline04(xminusl);
1228  break;
1229  case 5:
1230  xsum += Coeff * Bspline05(xminusl);
1231  break;
1232  case 6:
1233  xsum += Coeff * Bspline06(xminusl);
1234  break;
1235  case 7:
1236  xsum += Coeff * Bspline07(xminusl);
1237  break;
1238  case 8:
1239  xsum += Coeff * Bspline08(xminusl);
1240  break;
1241  case 9:
1242  xsum += Coeff * Bspline09(xminusl);
1243  break;
1244  }
1245  }
1246 
1247  double yminusm = y - (double) m;
1248  switch (SplineDegree)
1249  {
1250  case 2:
1251  yxsum += xsum * Bspline02(yminusm);
1252  break;
1253  case 3:
1254  BSPLINE03(aux,yminusm);
1255  yxsum += xsum * aux;
1256  break;
1257  case 4:
1258  yxsum += xsum * Bspline04(yminusm);
1259  break;
1260  case 5:
1261  yxsum += xsum * Bspline05(yminusm);
1262  break;
1263  case 6:
1264  yxsum += xsum * Bspline06(yminusm);
1265  break;
1266  case 7:
1267  yxsum += xsum * Bspline07(yminusm);
1268  break;
1269  case 8:
1270  yxsum += xsum * Bspline08(yminusm);
1271  break;
1272  case 9:
1273  yxsum += xsum * Bspline09(yminusm);
1274  break;
1275  }
1276  }
1277 
1278  double zminusn = z - (double) n;
1279  switch (SplineDegree)
1280  {
1281  case 2:
1282  zyxsum += yxsum * Bspline02(zminusn);
1283  break;
1284  case 3:
1285  BSPLINE03DIFF1(aux,zminusn);
1286  zyxsum += yxsum * aux;
1287  break;
1288  case 4:
1289  zyxsum += yxsum * Bspline04(zminusn);
1290  break;
1291  case 5:
1292  zyxsum += yxsum * Bspline05(zminusn);
1293  break;
1294  case 6:
1295  zyxsum += yxsum * Bspline06(zminusn);
1296  break;
1297  case 7:
1298  zyxsum += yxsum * Bspline07(zminusn);
1299  break;
1300  case 8:
1301  zyxsum += yxsum * Bspline08(zminusn);
1302  break;
1303  case 9:
1304  zyxsum += yxsum * Bspline09(zminusn);
1305  break;
1306  }
1307  }
1308 
1309  return zyxsum;
1310 }
#define YSIZE(v)
double Bspline05(double Argument)
static double * y
#define BSPLINE03DIFF1(y, x)
Definition: kerneldiff1.h:60
#define STARTINGX(v)
doublereal * x
double Bspline04(double Argument)
#define STARTINGY(v)
#define CEIL(x)
Definition: xmipp_macros.h:225
#define XSIZE(v)
double Bspline07(double Argument)
#define ZSIZE(v)
double z
double Bspline08(double Argument)
#define DIRECT_A3D_ELEM(v, k, i, j)
int m
double Bspline02(double Argument)
double Bspline09(double Argument)
double Bspline06(double Argument)
#define STARTINGZ(v)
int * n
#define BSPLINE03(y, x)
Definition: kernel.h:83

◆ produceImageFromSplineCoefficients()

template<typename T >
void produceImageFromSplineCoefficients ( int  SplineDegree,
MultidimArray< T > &  img,
const MultidimArray< double > &  coeffs 
)

Produce image from B-spline coefficients.

Note that the coeffs and img are only single images!

Definition at line 64 of file transformations.cpp.

67 {
69  imgD.initZeros(ZSIZE(coeffs), YSIZE(coeffs), XSIZE(coeffs));
70  STARTINGX(img) = STARTINGX(coeffs);
71  STARTINGY(img) = STARTINGY(coeffs);
72  STARTINGZ(img) = STARTINGZ(coeffs);
73 
74  int Status;
75  MultidimArray< double > aux(coeffs);
76 
78  XSIZE(coeffs), YSIZE(coeffs), ZSIZE(coeffs),
79  BasicSpline, CardinalSpline, SplineDegree,
80  MirrorOnBounds, DBL_EPSILON, &Status);
81  if (Status)
82  REPORT_ERROR(ERR_UNCLASSIFIED, "Error in ImageFromSplineCoefficients...");
83  typeCast(imgD, img);
84 }
Just to locate unclassified errors.
Definition: xmipp_error.h:192
#define DBL_EPSILON
#define YSIZE(v)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
#define MULTIDIM_ARRAY(v)
#define STARTINGX(v)
#define STARTINGY(v)
#define XSIZE(v)
#define ZSIZE(v)
void typeCast(const Matrix1D< T1 > &v1, Matrix1D< T2 > &v2)
Definition: matrix1d.h:1227
int ChangeBasisVolume(double *VolumeSource, double *VolumeDestination, long Nx, long Ny, long Nz, enum TSplineBasis FromBasis, enum TSplineBasis ToBasis, long Degree, enum TBoundaryConvention Convention, double Tolerance, int *Status)
void initZeros(const MultidimArray< T1 > &op)
#define STARTINGZ(v)

◆ produceSplineCoefficients() [1/2]

template<typename T >
void produceSplineCoefficients ( int  SplineDegree,
MultidimArray< double > &  coeffs,
const MultidimArray< T > &  V1 
)

Produce spline coefficients.

Create a single image with spline coefficients for the nth image

Definition at line 41 of file transformations.cpp.

44 {
45 
46  coeffs.initZeros(ZSIZE(V1), YSIZE(V1), XSIZE(V1));
47  STARTINGX(coeffs) = STARTINGX(V1);
48  STARTINGY(coeffs) = STARTINGY(V1);
49  STARTINGZ(coeffs) = STARTINGZ(V1);
50 
51  int Status;
53  typeCast(V1, aux); // This will create a single volume!
54 
56  XSIZE(V1), YSIZE(V1), ZSIZE(V1),
57  CardinalSpline, BasicSpline, SplineDegree,
58  MirrorOffBounds, DBL_EPSILON, &Status);
59  if (Status)
60  REPORT_ERROR(ERR_UNCLASSIFIED, "Error in produceSplineCoefficients...");
61 }
Just to locate unclassified errors.
Definition: xmipp_error.h:192
#define DBL_EPSILON
#define YSIZE(v)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
#define MULTIDIM_ARRAY(v)
#define STARTINGX(v)
#define STARTINGY(v)
#define XSIZE(v)
#define ZSIZE(v)
void typeCast(const Matrix1D< T1 > &v1, Matrix1D< T2 > &v2)
Definition: matrix1d.h:1227
int ChangeBasisVolume(double *VolumeSource, double *VolumeDestination, long Nx, long Ny, long Nz, enum TSplineBasis FromBasis, enum TSplineBasis ToBasis, long Degree, enum TBoundaryConvention Convention, double Tolerance, int *Status)
void initZeros(const MultidimArray< T1 > &op)
#define STARTINGZ(v)

◆ produceSplineCoefficients() [2/2]

void produceSplineCoefficients ( int  SplineDegree,
MultidimArray< double > &  coeffs,
const MultidimArray< std::complex< double > > &  V1 
)

Definition at line 727 of file transformations.cpp.

730 {
731  // TODO Implement
732  REPORT_ERROR(ERR_NOT_IMPLEMENTED,"Spline coefficients of a complex matrix is not implemented.");
733 }
Case or algorithm not implemented yet.
Definition: xmipp_error.h:177
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211

◆ pyramidExpand() [1/2]

template<typename T >
void pyramidExpand ( int  SplineDegree,
MultidimArray< T > &  V2,
const MultidimArray< T > &  V1,
int  levels = 1 
)

Expand the nth volume by 2 using a BSpline pyramid.

Definition at line 1640 of file transformations.h.

1644 {
1645  MultidimArray< double > coeffs, coeffs2;
1646 
1647  produceSplineCoefficients(SplineDegree, coeffs, V1);
1648 
1649  for (int i = 0; i < levels; i++)
1650  {
1651  expandBSpline(SplineDegree, coeffs2, coeffs);
1652  coeffs = coeffs2;
1653  }
1654 
1655  produceImageFromSplineCoefficients(SplineDegree, V2, coeffs);
1656 
1657 }
#define i
void expandBSpline(int SplineDegree, MultidimArray< double > &V2, const MultidimArray< T > &V1)
void produceSplineCoefficients(int SplineDegree, MultidimArray< double > &coeffs, const MultidimArray< T > &V1)
void produceImageFromSplineCoefficients(int SplineDegree, MultidimArray< T > &img, const MultidimArray< double > &coeffs)

◆ pyramidExpand() [2/2]

void pyramidExpand ( int  SplineDegree,
MultidimArrayGeneric V2,
const MultidimArrayGeneric V1,
int  levels = 1 
)

Definition at line 819 of file transformations.cpp.

823 {
824  if (V1.datatype != V2.datatype)
825  REPORT_ERROR(ERR_PARAM_INCORRECT, "pyramidExpand: MultidimArrayGeneric requires same datatype");
826 #define PYRAMIDEXPAND(type) pyramidExpand(SplineDegree,MULTIDIM_ARRAY_TYPE(V2,type),\
827  MULTIDIM_ARRAY_TYPE(V1,type), levels);
829 #undef PYRAMIDEXPAND
830 }
Parameter incorrect.
Definition: xmipp_error.h:181
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
#define PYRAMIDEXPAND(type)
#define SWITCHDATATYPE(datatype, OP)

◆ pyramidReduce() [1/2]

template<typename T >
void pyramidReduce ( int  SplineDegree,
MultidimArray< T > &  V2,
const MultidimArray< T > &  V1,
int  levels = 1 
)

Reduce the nth volume by 2 using a BSpline pyramid.

Definition at line 1597 of file transformations.h.

1601 {
1602  MultidimArray< double > coeffs, coeffs2;
1603 
1604  produceSplineCoefficients(SplineDegree, coeffs, V1);
1605 
1606  for (int i = 0; i < levels; i++)
1607  {
1608  reduceBSpline(SplineDegree, coeffs2, coeffs);
1609  coeffs = coeffs2;
1610  }
1611 
1612  produceImageFromSplineCoefficients(SplineDegree, V2, coeffs);
1613 }
#define i
void produceSplineCoefficients(int SplineDegree, MultidimArray< double > &coeffs, const MultidimArray< T > &V1)
void reduceBSpline(int SplineDegree, MultidimArray< double > &V2, const MultidimArray< T > &V1)
void produceImageFromSplineCoefficients(int SplineDegree, MultidimArray< T > &img, const MultidimArray< double > &coeffs)

◆ pyramidReduce() [2/2]

void pyramidReduce ( int  SplineDegree,
MultidimArrayGeneric V2,
const MultidimArrayGeneric V1,
int  levels = 1 
)

Definition at line 832 of file transformations.cpp.

836 {
837  if (V1.datatype != V2.datatype)
838  REPORT_ERROR(ERR_PARAM_INCORRECT, "pyramidReduce: MultidimArrayGeneric requires same datatype");
839 #define PYRAMIDREDUCE(type) pyramidReduce(SplineDegree,MULTIDIM_ARRAY_TYPE(V2,type),\
840  MULTIDIM_ARRAY_TYPE(V1,type), levels);
842 #undef PYRAMIDREDUCE
843 }
Parameter incorrect.
Definition: xmipp_error.h:181
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
#define PYRAMIDREDUCE(type)
#define SWITCHDATATYPE(datatype, OP)

◆ radialAverage()

template<typename T >
void radialAverage ( const MultidimArray< T > &  m,
Matrix1D< int > &  center_of_rot,
MultidimArray< T > &  radial_mean,
MultidimArray< int > &  radial_count,
const bool &  rounding = false 
)

Does a radial average of a 2D/3D image, around the voxel where is the origin.

A vector radial_mean is returned where:

  • the first element is the mean of the voxels whose distance to the origin is (0-1),
  • the second element is the mean of the voxels whose distance to the origin is (1-2)
  • and so on.

A second vector radial_count is returned containing the number of voxels over which each radial average was calculated.

Sjors nov2003: if rounding=true, element=round(distance);

  • so the first element is the mean of the voxels whose distance to the origin is (0.5-1.5),
  • the second element is the mean of the voxels whose distance to the origin is (1.5-2.5)
  • and so on.

Definition at line 1711 of file transformations.h.

1716 {
1717  Matrix1D< double > idx(3);
1718 
1719  // If center_of_rot was written for 2D image
1720  if (center_of_rot.size() < 3)
1721  center_of_rot.resize(3);
1722 
1723  // First determine the maximum distance that one should expect, to set the
1724  // dimension of the radial average vector
1725  MultidimArray< int > distances(8);
1726 
1727  double z = STARTINGZ(m) - ZZ(center_of_rot);
1728  double y = STARTINGY(m) - YY(center_of_rot);
1729  double x = STARTINGX(m) - XX(center_of_rot);
1730 
1731  distances(0) = (int) floor(sqrt(x * x + y * y + z * z));
1732  x = FINISHINGX(m) - XX(center_of_rot);
1733 
1734  distances(1) = (int) floor(sqrt(x * x + y * y + z * z));
1735  y = FINISHINGY(m) - YY(center_of_rot);
1736 
1737  distances(2) = (int) floor(sqrt(x * x + y * y + z * z));
1738  x = STARTINGX(m) - XX(center_of_rot);
1739 
1740  distances(3) = (int) floor(sqrt(x * x + y * y + z * z));
1741  z = FINISHINGZ(m) - ZZ(center_of_rot);
1742 
1743  distances(4) = (int) floor(sqrt(x * x + y * y + z * z));
1744  x = FINISHINGX(m) - XX(center_of_rot);
1745 
1746  distances(5) = (int) floor(sqrt(x * x + y * y + z * z));
1747  y = STARTINGY(m) - YY(center_of_rot);
1748 
1749  distances(6) = (int) floor(sqrt(x * x + y * y + z * z));
1750  x = STARTINGX(m) - XX(center_of_rot);
1751 
1752  distances(7) = (int) floor(sqrt(x * x + y * y + z * z));
1753 
1754  int dim = (int) CEIL(distances.computeMax()) + 1;
1755  if (rounding)
1756  dim++;
1757 
1758  // Define the vectors
1759  radial_mean.initZeros(dim);
1760  radial_count.initZeros(dim);
1761 
1762  // Perform the radial sum and count pixels that contribute to every
1763  // distance
1765  {
1766  ZZ(idx) = k - ZZ(center_of_rot);
1767  YY(idx) = i - YY(center_of_rot);
1768  XX(idx) = j - XX(center_of_rot);
1769 
1770  // Determine distance to the center
1771  ;
1772  double module = sqrt(ZZ(idx)*ZZ(idx)+YY(idx)*YY(idx)+XX(idx)*XX(idx));
1773  int distance = (rounding) ? (int) round(module) : (int) floor(module);
1774 
1775  // Sum the value to the pixels with the same distance
1776  DIRECT_MULTIDIM_ELEM(radial_mean,distance) += A3D_ELEM(m, k, i, j);
1777 
1778  // Count the pixel
1779  DIRECT_MULTIDIM_ELEM(radial_count,distance)++;
1780  }
1781 
1782  // Perform the mean
1784  if (DIRECT_MULTIDIM_ELEM(radial_count,i) > 0)
1785  DIRECT_MULTIDIM_ELEM(radial_mean,i) /= DIRECT_MULTIDIM_ELEM(radial_count,i);
1786 }
__host__ __device__ float2 floor(const float2 v)
#define FINISHINGX(v)
size_t size() const
Definition: matrix1d.h:508
void sqrt(Image< double > &op)
static double * y
#define FINISHINGZ(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY1D(v)
#define STARTINGX(v)
doublereal * x
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define STARTINGY(v)
#define A3D_ELEM(V, k, i, j)
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
#define XX(v)
Definition: matrix1d.h:85
#define CEIL(x)
Definition: xmipp_macros.h:225
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
double z
#define DIRECT_MULTIDIM_ELEM(v, n)
#define j
#define YY(v)
Definition: matrix1d.h:93
TYPE distance(struct Point_T *p, struct Point_T *q)
Definition: point.cpp:28
#define FINISHINGY(v)
int round(double x)
Definition: ap.cpp:7245
void initZeros(const MultidimArray< T1 > &op)
#define STARTINGZ(v)
#define ZZ(v)
Definition: matrix1d.h:101

◆ radialAverageAxis()

template<typename T >
void radialAverageAxis ( const MultidimArray< T > &  in,
char  axis,
MultidimArray< double > &  out 
)

Definition at line 1880 of file transformations.h.

1881 {
1882  MultidimArray<double> inCentered;
1883  inCentered.alias(in);
1884  inCentered.setXmippOrigin();
1885  if (axis=='z')
1886  {
1887  out.initZeros(ZSIZE(in),XSIZE(in));
1888  out.setXmippOrigin();
1889  for (int i=STARTINGY(inCentered); i<=FINISHINGY(inCentered); ++i)
1890  {
1891  double z=i;
1892  for (int j=0; j<XSIZE(out)/2; ++j)
1893  {
1894  for (double ang=0; ang<TWOPI; ang+=TWOPI/72)
1895  {
1896  double x=j*cos(ang);
1897  double y=j*sin(ang);
1898  double val=inCentered.interpolatedElement3D(x,y,z);
1899  A2D_ELEM(out,i,j)+=val;
1900  }
1901  A2D_ELEM(out,i,j)/=73;
1902  A2D_ELEM(out,i,-j)=A2D_ELEM(out,i,j);
1903  }
1904  }
1905  }
1906 
1907  else
1908  REPORT_ERROR(ERR_ARG_INCORRECT,"Not implemented yet");
1909 }
#define A2D_ELEM(v, i, j)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
static double * y
#define TWOPI
Definition: xmipp_macros.h:111
doublereal * x
#define i
#define STARTINGY(v)
char axis
Incorrect argument received.
Definition: xmipp_error.h:113
#define XSIZE(v)
#define ZSIZE(v)
double z
T interpolatedElement3D(double x, double y, double z, T outside_value=(T) 0) const
void alias(const MultidimArray< T > &m)
#define j
#define FINISHINGY(v)
void initZeros(const MultidimArray< T1 > &op)

◆ radialAverageNonCubic()

template<typename T >
void radialAverageNonCubic ( const MultidimArray< T > &  m,
Matrix1D< int > &  center_of_rot,
MultidimArray< T > &  radial_mean,
MultidimArray< int > &  radial_count,
bool  rounding = false 
)

Definition at line 1375 of file transformations.cpp.

1380 {
1381  Matrix1D< double > idx(3);
1382 
1383  size_t sizemax = std::max({XSIZE(m), YSIZE(m), ZSIZE(m)});
1384  double scalex = double(XSIZE(m)/sizemax);
1385  double scaley = double(YSIZE(m)/sizemax);
1386  double scalez = double(ZSIZE(m)/sizemax);
1387 
1388  // If center_of_rot was written for 2D image
1389  if (center_of_rot.size() < 3)
1390  center_of_rot.resize(3);
1391 
1392  // First determine the maximum distance that one should expect, to set the
1393  // dimension of the radial average vector
1394  MultidimArray< int > distances(8);
1395 
1396  const double z0 = STARTINGZ(m) - ZZ(center_of_rot);
1397  const double y0 = STARTINGY(m) - YY(center_of_rot);
1398  const double x0 = STARTINGX(m) - XX(center_of_rot);
1399 
1400  const double xf = FINISHINGX(m) - XX(center_of_rot);
1401  const double yf = FINISHINGY(m) - YY(center_of_rot);
1402  const double zf = FINISHINGZ(m) - ZZ(center_of_rot);
1403 
1404  distances(0) = (int) floor(sqrt(x0 * x0 + y0 * y0 + z0 * z0));
1405  distances(1) = (int) floor(sqrt(xf * xf + y0 * y0 + z0 * z0));
1406  distances(2) = (int) floor(sqrt(xf * xf + yf * yf + z0 * z0));
1407  distances(3) = (int) floor(sqrt(x0 * x0 + yf * yf + z0 * z0));
1408  distances(4) = (int) floor(sqrt(x0 * x0 + yf * yf + zf * zf));
1409  distances(5) = (int) floor(sqrt(xf * xf + yf * yf + zf * zf));
1410  distances(6) = (int) floor(sqrt(xf * xf + y0 * y0 + zf * zf));
1411  distances(7) = (int) floor(sqrt(x0 * x0 + y0 * y0 + zf * zf));
1412 
1413  int dim = CEIL(distances.computeMax()) + 1;
1414  if (rounding)
1415  dim++;
1416 
1417  // Define the vectors
1418  radial_mean.initZeros(dim);
1419  radial_count.initZeros(dim);
1420 
1421  // Perform the radial sum and count pixels that contribute to every
1422  // distance
1424  {
1425  ZZ(idx) = scalez * (k - ZZ(center_of_rot));
1426  YY(idx) = scaley * (i - YY(center_of_rot));
1427  XX(idx) = scalex * (j - XX(center_of_rot));
1428 
1429  // Determine distance to the center
1430  double mod = sqrt(ZZ(idx)*ZZ(idx)+YY(idx)*YY(idx)+XX(idx)*XX(idx));
1431  int distance = rounding ? (int) round(mod) : (int) floor(mod);
1432 
1433  // Sum the value to the pixels with the same distance
1434  DIRECT_MULTIDIM_ELEM(radial_mean,distance) += A3D_ELEM(m, k, i, j);
1435 
1436  // Count the pixel
1437  DIRECT_MULTIDIM_ELEM(radial_count,distance)++;
1438  }
1439 
1440  // Perform the mean
1442  if (DIRECT_MULTIDIM_ELEM(radial_count,i) > 0)
1443  DIRECT_MULTIDIM_ELEM(radial_mean,i) /= DIRECT_MULTIDIM_ELEM(radial_count,i);
1444 }
#define YSIZE(v)
__host__ __device__ float2 floor(const float2 v)
#define FINISHINGX(v)
size_t size() const
Definition: matrix1d.h:508
void sqrt(Image< double > &op)
#define z0
#define FINISHINGZ(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY1D(v)
#define STARTINGX(v)
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define STARTINGY(v)
#define A3D_ELEM(V, k, i, j)
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
#define y0
#define x0
#define XX(v)
Definition: matrix1d.h:85
#define CEIL(x)
Definition: xmipp_macros.h:225
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
#define XSIZE(v)
void max(Image< double > &op1, const Image< double > &op2)
#define ZSIZE(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
void mod(const MultidimArray< T > &x, MultidimArray< T > &m, double y)
#define j
#define YY(v)
Definition: matrix1d.h:93
TYPE distance(struct Point_T *p, struct Point_T *q)
Definition: point.cpp:28
#define FINISHINGY(v)
int round(double x)
Definition: ap.cpp:7245
void initZeros(const MultidimArray< T1 > &op)
#define STARTINGZ(v)
#define ZZ(v)
Definition: matrix1d.h:101

◆ radialAveragePrecomputeDistance()

template<typename T >
void radialAveragePrecomputeDistance ( const MultidimArray< T > &  m,
Matrix1D< int > &  center_of_rot,
MultidimArray< int > &  distance,
int &  dim,
const bool &  rounding = false 
)

Definition at line 1789 of file transformations.h.

1794 {
1795  Matrix1D< double > idx(3);
1796 
1797  // If center_of_rot was written for 2D image
1798  if (center_of_rot.size() < 3)
1799  center_of_rot.resize(3);
1800 
1801  // First determine the maximum distance that one should expect, to set the
1802  // dimension of the radial average vector
1803  MultidimArray< int > distances(8);
1804 
1805  double z = STARTINGZ(m) - ZZ(center_of_rot);
1806  double y = STARTINGY(m) - YY(center_of_rot);
1807  double x = STARTINGX(m) - XX(center_of_rot);
1808 
1809  distances(0) = (int) floor(sqrt(x * x + y * y + z * z));
1810  x = FINISHINGX(m) - XX(center_of_rot);
1811 
1812  distances(1) = (int) floor(sqrt(x * x + y * y + z * z));
1813  y = FINISHINGY(m) - YY(center_of_rot);
1814 
1815  distances(2) = (int) floor(sqrt(x * x + y * y + z * z));
1816  x = STARTINGX(m) - XX(center_of_rot);
1817 
1818  distances(3) = (int) floor(sqrt(x * x + y * y + z * z));
1819  z = FINISHINGZ(m) - ZZ(center_of_rot);
1820 
1821  distances(4) = (int) floor(sqrt(x * x + y * y + z * z));
1822  x = FINISHINGX(m) - XX(center_of_rot);
1823 
1824  distances(5) = (int) floor(sqrt(x * x + y * y + z * z));
1825  y = STARTINGY(m) - YY(center_of_rot);
1826 
1827  distances(6) = (int) floor(sqrt(x * x + y * y + z * z));
1828  x = STARTINGX(m) - XX(center_of_rot);
1829 
1830  distances(7) = (int) floor(sqrt(x * x + y * y + z * z));
1831 
1832  dim = (int) CEIL(distances.computeMax()) + 1;
1833  if (rounding)
1834  dim++;
1835 
1836  // Perform the radial sum and count pixels that contribute to every
1837  // distance
1838  distance.initZeros(m);
1840  {
1841  ZZ(idx) = k - ZZ(center_of_rot);
1842  YY(idx) = i - YY(center_of_rot);
1843  XX(idx) = j - XX(center_of_rot);
1844 
1845  // Determine distance to the center
1846  if (rounding)
1847  A3D_ELEM(distance,k,i,j) = (int) round(idx.module());
1848  else
1849  A3D_ELEM(distance,k,i,j) = (int) floor(idx.module());
1850  }
1851 }
__host__ __device__ float2 floor(const float2 v)
#define FINISHINGX(v)
size_t size() const
Definition: matrix1d.h:508
void sqrt(Image< double > &op)
static double * y
#define FINISHINGZ(v)
#define STARTINGX(v)
doublereal * x
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define STARTINGY(v)
#define A3D_ELEM(V, k, i, j)
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
#define XX(v)
Definition: matrix1d.h:85
#define CEIL(x)
Definition: xmipp_macros.h:225
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
double z
#define j
#define YY(v)
Definition: matrix1d.h:93
#define FINISHINGY(v)
int round(double x)
Definition: ap.cpp:7245
void initZeros(const MultidimArray< T1 > &op)
#define STARTINGZ(v)
#define ZZ(v)
Definition: matrix1d.h:101

◆ radiallySymmetrize()

void radiallySymmetrize ( const MultidimArray< double > &  img,
MultidimArray< double > &  radialImg 
)

Definition at line 1312 of file transformations.cpp.

1314 {
1315  Matrix1D<int> center(2);
1316  center.initZeros();
1317  MultidimArray<int> distance, radial_count;
1318  MultidimArray<double> radial_mean;
1319  int dim;
1320  radialAveragePrecomputeDistance(img, center, distance, dim);
1321  fastRadialAverage(img, distance, dim, radial_mean, radial_count);
1322 
1323  radialImg.initZeros(img);
1325  {
1326  int d=DIRECT_MULTIDIM_ELEM(distance,n);
1327  DIRECT_MULTIDIM_ELEM(radialImg,n)=A1D_ELEM(radial_mean,d);
1328  }
1329 }
void fastRadialAverage(const MultidimArray< T > &m, const MultidimArray< int > &distance, int dim, MultidimArray< T > &radial_mean, MultidimArray< int > &radial_count)
#define A1D_ELEM(v, i)
doublereal * d
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
void radialAveragePrecomputeDistance(const MultidimArray< T > &m, Matrix1D< int > &center_of_rot, MultidimArray< int > &distance, int &dim, const bool &rounding=false)
TYPE distance(struct Point_T *p, struct Point_T *q)
Definition: point.cpp:28
void initZeros(const MultidimArray< T1 > &op)
int * n

◆ reduceBSpline()

template<typename T >
void reduceBSpline ( int  SplineDegree,
MultidimArray< double > &  V2,
const MultidimArray< T > &  V1 
)

Reduce a set of B-spline coefficients.

Knowing that V1 is a (single image of) B-spline coefficients, produce the reduced set of B-spline coefficients using the two-scale relationship.

Definition at line 87 of file transformations.cpp.

90 {
91  double g[200]; // Coefficients of the reduce filter
92  long ng; // Number of coefficients of the reduce filter
93  double h[200]; // Coefficients of the expansion filter
94  long nh; // Number of coefficients of the expansion filter
95  short IsCentered; // Equal TRUE if the filter is a centered spline
96 
97  // Get the filter
98  const char *splineType="Centered Spline";
99  if (GetPyramidFilter(splineType, SplineDegree,
100  g, &ng, h, &nh, &IsCentered))
101  REPORT_ERROR(ERR_UNCLASSIFIED, "Unable to load the filter coefficients");
102 
104  typeCast(V1, aux);
105  if (V1.getDim() == 2)
106  {
107  if (XSIZE(aux) % 2 != 0 && YSIZE(aux) % 2 != 0)
108  aux.resize(YSIZE(aux) - 1, XSIZE(aux) - 1);
109  else if (YSIZE(aux) % 2 != 0)
110  aux.resize(YSIZE(aux) - 1, XSIZE(aux));
111  else if (XSIZE(aux) % 2 != 0)
112  aux.resize(YSIZE(aux), XSIZE(aux) - 1);
113 
114  V2.initZeros(YSIZE(aux) / 2, XSIZE(aux) / 2);
115  Reduce_2D(MULTIDIM_ARRAY(aux), XSIZE(aux), YSIZE(aux),
116  MULTIDIM_ARRAY(V2), g, ng, IsCentered);
117  }
118  else if (V1.getDim() == 3)
119  {
120  if (XSIZE(aux) % 2 != 0 && YSIZE(aux) % 2 != 0 && ZSIZE(aux) % 2 != 0)
121  aux.resize(ZSIZE(aux - 1), YSIZE(aux) - 1, XSIZE(aux) - 1);
122  else if (XSIZE(aux) % 2 != 0 && YSIZE(aux) % 2 != 0 && ZSIZE(aux) % 2 == 0)
123  aux.resize(ZSIZE(aux), YSIZE(aux) - 1, XSIZE(aux) - 1);
124  else if (XSIZE(aux) % 2 != 0 && YSIZE(aux) % 2 == 0 && ZSIZE(aux) % 2 != 0)
125  aux.resize(ZSIZE(aux) - 1, YSIZE(aux), XSIZE(aux) - 1);
126  else if (XSIZE(aux) % 2 != 0 && YSIZE(aux) % 2 == 0 && ZSIZE(aux) % 2 == 0)
127  aux.resize(ZSIZE(aux), YSIZE(aux), XSIZE(aux) - 1);
128  else if (XSIZE(aux) % 2 == 0 && YSIZE(aux) % 2 != 0 && ZSIZE(aux) % 2 != 0)
129  aux.resize(ZSIZE(aux) - 1, YSIZE(aux) - 1, XSIZE(aux));
130  else if (XSIZE(aux) % 2 == 0 && YSIZE(aux) % 2 != 0 && ZSIZE(aux) % 2 == 0)
131  aux.resize(ZSIZE(aux), YSIZE(aux) - 1, XSIZE(aux));
132  else if (XSIZE(aux) % 2 == 0 && YSIZE(aux) % 2 == 0 && ZSIZE(aux) % 2 != 0)
133  aux.resize(ZSIZE(aux) - 1, YSIZE(aux), XSIZE(aux));
134 
135  V2.initZeros(ZSIZE(aux) / 2, YSIZE(aux) / 2, XSIZE(aux) / 2);
136  Reduce_3D(MULTIDIM_ARRAY(aux), XSIZE(aux), YSIZE(aux), ZSIZE(aux),
137  MULTIDIM_ARRAY(V2), g, ng, IsCentered);
138  }
139  else
140  REPORT_ERROR(ERR_MULTIDIM_DIM,"reduceBSpline ERROR: only valid for 2D or 3D arrays");
141 }
Just to locate unclassified errors.
Definition: xmipp_error.h:192
#define YSIZE(v)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
doublereal * g
#define MULTIDIM_ARRAY(v)
int Reduce_2D(double *In, long int NxIn, long int NyIn, double *Out, double w[], long int nw, short FlagCentered)
int Reduce_3D(double *In, long int NxIn, long int NyIn, long int NzIn, double *Out, double w[], long int nw, short FlagCentered)
#define XSIZE(v)
#define ZSIZE(v)
void typeCast(const Matrix1D< T1 > &v1, Matrix1D< T2 > &v2)
Definition: matrix1d.h:1227
Incorrect MultidimArray dimensions.
Definition: xmipp_error.h:173
void initZeros(const MultidimArray< T1 > &op)
int GetPyramidFilter(const char *Filter, long int Order, double g[], long int *ng, double h[], long int *nh, short *FlagCentered)

◆ rotate()

template<typename T >
void rotate ( int  SplineDegree,
MultidimArray< T > &  V2,
const MultidimArray< T > &  V1,
double  ang,
char  axis = 'Z',
bool  wrap = xmipp_transformation::DONT_WRAP,
outside = 0 
)

Rotate an array around a given system axis.

The rotation angle is in degrees, and the rotational axis is either 'X', 'Y' or 'Z' for 3D arrays and only 'Z' for 2D arrays. An exception is thrown if the axis given is not one of these.

V2 = V1.rotate(60);

Definition at line 1323 of file transformations.h.

1328 {
1329  Matrix2D< double > tmp;
1330  if (V1.getDim()==2)
1331  {
1332  rotation2DMatrix(ang,tmp);
1333  }
1334  else if (V1.getDim()==3)
1335  {
1336  rotation3DMatrix(ang, axis, tmp);
1337  }
1338  else
1339  REPORT_ERROR(ERR_MULTIDIM_DIM,"rotate ERROR: rotate only valid for 2D or 3D arrays");
1340 
1341  applyGeometry(SplineDegree, V2, V1, tmp, xmipp_transformation::IS_NOT_INV, wrap, outside);
1342 }
void applyGeometry(int SplineDegree, MultidimArray< T > &__restrict__ V2, const MultidimArray< T1 > &__restrict__ V1, const Matrix2D< T2 > &At, bool inv, bool wrap, T outside=T(0), MultidimArray< double > *BcoeffsPtr=NULL)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void rotation3DMatrix(double ang, char axis, Matrix2D< double > &m, bool homogeneous=true)
char axis
void rotation2DMatrix(T ang, Matrix2D< T > &m, bool homogeneous=true)
Incorrect MultidimArray dimensions.
Definition: xmipp_error.h:173

◆ rotation2DMatrix()

template<typename T >
void rotation2DMatrix ( ang,
Matrix2D< T > &  m,
bool  homogeneous = true 
)

Creates a rotational matrix (3x3) for images

The rotation angle is in degrees. m must have been already resized to 3x3

Definition at line 361 of file transformations.cpp.

362 {
363  // FIXME DS this might not be true, but just to make sure
364  static_assert(std::is_floating_point<T>::value,
365  "Only float and double are allowed as template parameters");
366 
367  T rad = DEG2RAD(ang);
368  T cosine = cos(rad);
369  T sine = sin(rad);
370 
371  if (homogeneous)
372  {
373  result.resizeNoCopy(3,3); // sizes will be tested inside
374  // now we have 3x3 matrix row wise matrix
375  result.mdata[0] = cosine;
376  result.mdata[1] = sine;
377  result.mdata[2] = 0;
378 
379  result.mdata[3] = -sine;
380  result.mdata[4] = cosine;
381  result.mdata[5] = 0;
382 
383  result.mdata[6] = 0;
384  result.mdata[7] = 0;
385  result.mdata[8] = 1;
386  } else {
387  result.resizeNoCopy(2,2); // sizes will be tested inside
388  // now we have 2x2 matrix row wise matrix
389  result.mdata[0] = cosine;
390  result.mdata[1] = sine;
391 
392  result.mdata[2] = -sine;
393  result.mdata[3] = cosine;
394  }
395 }
#define DEG2RAD(d)
Definition: xmipp_macros.h:312

◆ rotation3DMatrix() [1/2]

void rotation3DMatrix ( double  ang,
char  axis,
Matrix2D< double > &  m,
bool  homogeneous = true 
)

Creates a rotational matrix (4x4) for volumes around system axis

The rotation angle is in degrees, and the rotational axis is either 'X', 'Y' or 'Z'. An exception is thrown if the axis given is not one of these.

The returned matrices are respectively alpha degrees around Z

[ cos(A) -sin(A) 0 ]
[ sin(A) cos(A) 0 ]
[ 0 0 1 ]

alpha degrees around Y

[ cos(A) 0 -sin(A) ]
[ 0 1 0 ]
[ sin(A) 0 cos(A) ]

alpha degrees around X

[ 1 0 0 ]
[ 0 cos(A) -sin(A) ]
[ 0 sin(A) cos(A) ]
m = rotation3DMatrix(60, 'X');

Definition at line 426 of file transformations.cpp.

428 {
429  if (homogeneous)
430  {
431  result.initZeros(4,4);
432  dMij(result,3, 3) = 1;
433  }
434  else
435  result.initZeros(3,3);
436 
437  double cosine, sine;
438  ang = DEG2RAD(ang);
439  cosine = cos(ang);
440  sine = sin(ang);
441 
442  switch (axis)
443  {
444  case 'Z':
445  dMij(result,0, 0) = cosine;
446  dMij(result,0, 1) = sine;
447  dMij(result,1, 0) = -sine;
448  dMij(result,1, 1) = cosine;
449  dMij(result,2, 2) = 1;
450  break;
451  case 'Y':
452  dMij(result,0, 0) = cosine;
453  dMij(result,0, 2) = sine;
454  dMij(result,2, 0) = -sine;
455  dMij(result,2, 2) = cosine;
456  dMij(result,1, 1) = 1;
457  break;
458  case 'X':
459  dMij(result,1, 1) = cosine;
460  dMij(result,1, 2) = sine;
461  dMij(result,2, 1) = -sine;
462  dMij(result,2, 2) = cosine;
463  dMij(result,0, 0) = 1;
464  break;
465  default:
466  REPORT_ERROR(ERR_VALUE_INCORRECT, "rotation3DMatrix: Unknown axis");
467  }
468 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
#define DEG2RAD(d)
Definition: xmipp_macros.h:312
char axis
#define dMij(m, i, j)
Definition: matrix2d.h:139
Incorrect value received.
Definition: xmipp_error.h:195

◆ rotation3DMatrix() [2/2]

void rotation3DMatrix ( double  ang,
const Matrix1D< double > &  axis,
Matrix2D< double > &  m,
bool  homogeneous = true 
)

Creates a rotational matrix (4x4) for volumes around any axis

The rotation angle is in degrees, and the rotational axis is given as a R3 vector. An exception is thrown if the axis is not a R3 vector. The axis needs not to be unitary.

m = rotation3DMatrix(60, vectorR3(1, 1, 1));

Definition at line 517 of file transformations.cpp.

519 {
520 #ifdef NEVERDEFINED
521  // Compute a matrix which makes the turning axis coincident with Z
522  // And turn around this axis
523  Matrix2D<double> A, R;
524  alignWithZ(axis, A, homogeneous);
525  rotation3DMatrix(ang, 'Z', R, homogeneous);
526  result = A.transpose() * R * A;
527 #else
528  // http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle
529  if (homogeneous)
530  result.initIdentity(4);
531  else
532  result.initIdentity(3);
533  double s,c;
534  //sincos(-DEG2RAD(ang),&s,&c);
535  s = sin(-DEG2RAD(ang));
536  c = cos(-DEG2RAD(ang));
537  double c1=1-c;
538  double x=XX(axis);
539  double y=YY(axis);
540  double z=ZZ(axis);
541  double xy=x*y;
542  double xz=x*z;
543  double yz=y*z;
544  double x2=x*x;
545  double y2=y*y;
546  double z2=z*z;
547  dMij(result,0,0)=c+x2*c1;
548  dMij(result,0,1)=xy*c1-z*s;
549  dMij(result,0,2)=xz*c1+y*s;
550  dMij(result,1,0)=xy*c1+z*s;
551  dMij(result,1,1)=c+y2*c1;
552  dMij(result,1,2)=yz*c1-x*s;
553  dMij(result,2,0)=xz*c1-y*s;
554  dMij(result,2,1)=yz*c1+x*s;
555  dMij(result,2,2)=c+z2*c1;
556 #endif
557 }
doublereal * c
#define DEG2RAD(d)
Definition: xmipp_macros.h:312
static double * y
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
doublereal * x
void rotation3DMatrix(double ang, char axis, Matrix2D< double > &result, bool homogeneous)
#define XX(v)
Definition: matrix1d.h:85
#define dMij(m, i, j)
Definition: matrix2d.h:139
double z
#define YY(v)
Definition: matrix1d.h:93
void alignWithZ(const Matrix1D< double > &axis, Matrix2D< double > &result, bool homogeneous)
#define ZZ(v)
Definition: matrix1d.h:101
void initIdentity()
Definition: matrix2d.h:673

◆ rotation3DMatrixFromIcoOrientations()

void rotation3DMatrixFromIcoOrientations ( const char *  icoFrom,
const char *  icoTo,
Matrix2D< double > &  R 
)

Creates a rotation matrix (R) to change the orientation from one standard orientation (icoFrom) to another one (icoTo)

Definition at line 1332 of file transformations.cpp.

1334 {
1335  std::vector<char> symLabel;
1336  symLabel.push_back((int)icoFrom[1]);
1337  symLabel.push_back((int)icoTo[1]);
1338  Matrix1D<double> xyz(3);
1339  Matrix2D<double> Rfrom, Rto;
1340 
1341  for(int i=0; i<2; i++)
1342  {
1343  switch (symLabel[i])
1344  {
1345  case '1':
1346  xyz = vectorR3(0.0, 90.0, 0.0);
1347  break;
1348  case '2':
1349  xyz = vectorR3(0.0, 0.0, 0.0);
1350  break;
1351  case '3':
1352  xyz = vectorR3(0.0, 31.7175, 0.0);
1353  break;
1354  case '4':
1355  xyz = vectorR3(0.0, -31.7175, 0.0);
1356  break;
1357 /* case '5':
1358  xyz = vectorR3(31.7175, 90.0, 0.0); // not aviable yet
1359  break;
1360  case '6':
1361  xyz = vectorR3(-31.7175, 90.0, 0.0); // not aviable yet
1362  break;*/
1363  default:
1364  REPORT_ERROR(ERR_PARAM_INCORRECT, "Incorrect standard icosahedral orientation");
1365  }
1366  if (i==0)
1367  Euler_angles2matrix(XX(xyz), YY(xyz), ZZ(xyz), Rfrom, true);
1368  else
1369  Euler_angles2matrix(XX(xyz), YY(xyz), ZZ(xyz), Rto, true);
1370  }
1371  R = Rto * Rfrom.transpose();
1372 }
Parameter incorrect.
Definition: xmipp_error.h:181
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
Matrix1D< double > vectorR3(double x, double y, double z)
Definition: matrix1d.cpp:892
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
#define i
#define XX(v)
Definition: matrix1d.h:85
#define YY(v)
Definition: matrix1d.h:93
#define ZZ(v)
Definition: matrix1d.h:101

◆ scale3DMatrix()

void scale3DMatrix ( const Matrix1D< double > &  sc,
Matrix2D< double > &  m,
bool  homogeneous = true 
)

Creates a scaling matrix (4x4) for volumes

The scaling factors for the different axis must be given as a vector. So that, XX(sc)=scale for X axis, YY(sc)=...

Definition at line 584 of file transformations.cpp.

586 {
587  if (VEC_XSIZE(sc) != 3)
588  REPORT_ERROR(ERR_MATRIX_SIZE, "Scale3D_matrix: vector is not in R3");
589 
590  if (homogeneous)
591  {
592  result.initZeros(4,4);
593  dMij(result,3, 3) = 1;
594  }
595  else
596  result.initZeros(3,3);
597  dMij(result,0, 0) = XX(sc);
598  dMij(result,1, 1) = YY(sc);
599  dMij(result,2, 2) = ZZ(sc);
600 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Problem with matrix size.
Definition: xmipp_error.h:152
#define VEC_XSIZE(m)
Definition: matrix1d.h:77
#define XX(v)
Definition: matrix1d.h:85
#define dMij(m, i, j)
Definition: matrix2d.h:139
#define YY(v)
Definition: matrix1d.h:93
#define ZZ(v)
Definition: matrix1d.h:101

◆ scaleToSize() [1/5]

template<typename T1 , typename T >
void scaleToSize ( int  SplineDegree,
MultidimArray< T > &  V2,
const MultidimArray< T1 > &  V1,
size_t  Xdim,
size_t  Ydim,
size_t  Zdim = 1 
)

Scales to a new size.

The volume is scaled (resampled) to fill a new size. It is not the same as "selfWindow" in this same class. The size can be larger or smaller than the actual one.

V2 = V1.scaleToSize(128, 128, 128);

Definition at line 1451 of file transformations.h.

1455 {
1456  if (Xdim == XSIZE(V1) && Ydim == YSIZE(V1) && \
1457  (!(V1.getDim()==3) || (Zdim == ZSIZE(V1))) )
1458  {
1459  typeCast(V1,V2);
1460  return;
1461  }
1462 
1463  Matrix2D< double > tmp;
1464  if (V1.getDim()==2)
1465  {
1466  tmp.initIdentity(3);
1467  tmp(0, 0) = (double) Xdim / (double) XSIZE(V1);
1468  tmp(1, 1) = (double) Ydim / (double) YSIZE(V1);
1469  V2.initZeros(1, 1, Ydim, Xdim);
1470  }
1471  else if (V1.getDim()==3)
1472  {
1473  tmp.initIdentity(4);
1474  tmp(0, 0) = (double) Xdim / (double) XSIZE(V1);
1475  tmp(1, 1) = (double) Ydim / (double) YSIZE(V1);
1476  tmp(2, 2) = (double) Zdim / (double) ZSIZE(V1);
1477  V2.initZeros(1, Zdim, Ydim, Xdim);
1478  }
1479  else
1480  REPORT_ERROR(ERR_MULTIDIM_DIM,"scaleToSize ERROR: scaleToSize only valid for 2D or 3D arrays");
1481 
1482  V2.setXmippOrigin();
1483  applyGeometry(SplineDegree, V2, V1, tmp, xmipp_transformation::IS_NOT_INV, xmipp_transformation::WRAP, (T)0);
1484 }
#define YSIZE(v)
void applyGeometry(int SplineDegree, MultidimArray< T > &__restrict__ V2, const MultidimArray< T1 > &__restrict__ V1, const Matrix2D< T2 > &At, bool inv, bool wrap, T outside=T(0), MultidimArray< double > *BcoeffsPtr=NULL)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
#define XSIZE(v)
#define ZSIZE(v)
void typeCast(const Matrix1D< T1 > &v1, Matrix1D< T2 > &v2)
Definition: matrix1d.h:1227
Incorrect MultidimArray dimensions.
Definition: xmipp_error.h:173
void initZeros(const MultidimArray< T1 > &op)
void initIdentity()
Definition: matrix2d.h:673

◆ scaleToSize() [2/5]

template<typename T >
void scaleToSize ( int  SplineDegree,
MultidimArray< T > &  V2,
const MultidimArrayGeneric V1,
int  Xdim,
int  Ydim,
int  Zdim = 1 
)
inline

Scales to a new size.

The volume is scaled (resampled) to fill a new size. Same as previous, but in this case the input is a MultidimArrayGeneric.

scaleToSize(VolumeOut, VolumeGenericInput, 128, 128, 128);

Definition at line 1497 of file transformations.h.

1500 {
1501 #define SCALETOSIZE(type) scaleToSize(SplineDegree,V2,*((MultidimArray<type>*)(V1.im)),Xdim,Ydim,Zdim);
1503 #undef SCALETOSIZE
1504 }
#define SCALETOSIZE(type)
#define SWITCHDATATYPE(datatype, OP)

◆ scaleToSize() [3/5]

template<typename T >
void scaleToSize ( int  SplineDegree,
MultidimArrayGeneric V2,
const MultidimArray< T > &  V1,
int  Xdim,
int  Ydim,
int  Zdim = 1 
)
inline

Scales to a new size.

The volume is scaled (resampled) to fill a new size. Same as previous, but in this case the input is a MultidimArrayGeneric.

scaleToSize(VolumeOut, VolumeGenericInput, 128, 128, 128);

Definition at line 1517 of file transformations.h.

1520 {
1521 #define SCALETOSIZE(type) scaleToSize(SplineDegree,MULTIDIM_ARRAY_TYPE(V2,type),V1,Xdim,Ydim,Zdim);
1522  SWITCHDATATYPE(V1.datatype,SCALETOSIZE)
1523 #undef SCALETOSIZE
1524 }
#define SCALETOSIZE(type)
#define SWITCHDATATYPE(datatype, OP)

◆ scaleToSize() [4/5]

void scaleToSize ( int  SplineDegree,
MultidimArrayGeneric V2,
const MultidimArrayGeneric V1,
int  Xdim,
int  Ydim,
int  Zdim = 1 
)

Scales to a new size.

The volume is scaled (resampled) to fill a new size. Same as previous, but in this case the input is a MultidimArrayGeneric.

scaleToSize(VolumeOut, VolumeGenericInput, 128, 128, 128);

Definition at line 746 of file transformations.cpp.

749 {
750  if (V1.datatype != V2.datatype)
751  REPORT_ERROR(ERR_PARAM_INCORRECT, "scaleToSize: MultidimArrayGeneric requires same datatype");
752 #define SCALETOSIZE(type) scaleToSize(SplineDegree,MULTIDIM_ARRAY_TYPE(V2,type), \
753  MULTIDIM_ARRAY_TYPE(V1,type),Xdim,Ydim,Zdim);
755 #undef SCALETOSIZE
756 }
Parameter incorrect.
Definition: xmipp_error.h:181
#define SCALETOSIZE(type)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
#define SWITCHDATATYPE(datatype, OP)

◆ scaleToSize() [5/5]

void scaleToSize ( int  SplineDegree,
MultidimArray< std::complex< double > > &  V2,
const MultidimArray< std::complex< double > > &  V1,
int  Xdim,
int  Ydim,
int  Zdim = 1 
)

Definition at line 759 of file transformations.cpp.

763 {
764  if (SplineDegree > 1)
765  {
766  MultidimArray< double > re, im, aux;
768 
769  re.resize(ZSIZE(V1), YSIZE(V1), XSIZE(V1));
770  im.resize(ZSIZE(V1), YSIZE(V1), XSIZE(V1));
771 
772  oneImg=V1;
775  MULTIDIM_SIZE(oneImg));
776  aux = re;
777  scaleToSize(SplineDegree, re, aux, Ydim, Xdim, Zdim);
778  aux = im;
779  scaleToSize(SplineDegree, im, aux, Ydim, Xdim, Zdim);
781  MULTIDIM_ARRAY(V2), MULTIDIM_SIZE(re));
782  }
783  else
784  scaleToSize(SplineDegree, V2, V1, Xdim, Ydim, Zdim);
785 
786 }
#define YSIZE(v)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
#define MULTIDIM_SIZE(v)
#define MULTIDIM_ARRAY(v)
void RealImag2Complex(const MultidimArray< double > &real, const MultidimArray< double > &imag, MultidimArray< std::complex< double > > &out)
Definition: xmipp_fft.cpp:114
#define XSIZE(v)
#define ZSIZE(v)
void scaleToSize(int SplineDegree, MultidimArrayGeneric &V2, const MultidimArrayGeneric &V1, int Xdim, int Ydim, int Zdim)
void Complex2RealImag(const MultidimArray< std::complex< double > > &in, MultidimArray< double > &real, MultidimArray< double > &imag)
Definition: xmipp_fft.cpp:103

◆ selfApplyGeometry() [1/2]

template<typename T >
void selfApplyGeometry ( int  SplineDegree,
MultidimArray< T > &  V1,
const Matrix2D< double > &  A,
bool  inv,
bool  wrap,
outside = 0 
)

Applies a geometrical transformation and overwrites the input matrix.

The same as the previous function, but input array is overwritten

Definition at line 1253 of file transformations.h.

1257 {
1258  MultidimArray<T> aux = V1;
1259  V1.initZeros();
1260  applyGeometry(SplineDegree, V1, aux, A, inv, wrap, outside);
1261 }
void applyGeometry(int SplineDegree, MultidimArray< T > &__restrict__ V2, const MultidimArray< T1 > &__restrict__ V1, const Matrix2D< T2 > &At, bool inv, bool wrap, T outside=T(0), MultidimArray< double > *BcoeffsPtr=NULL)
void initZeros(const MultidimArray< T1 > &op)

◆ selfApplyGeometry() [2/2]

template<>
void selfApplyGeometry ( int  SplineDegree,
MultidimArray< std::complex< double > > &  V1,
const Matrix2D< double > &  A,
bool  inv,
bool  wrap,
std::complex< double >  outside 
)

Definition at line 704 of file transformations.cpp.

708 {
710  applyGeometry(Splinedegree, V1, aux, A, inv, wrap, outside);
711 }
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)

◆ selfPyramidExpand() [1/2]

template<typename T >
void selfPyramidExpand ( int  SplineDegree,
MultidimArray< T > &  V1,
int  levels = 1 
)

Expand the nth volume by 2 using a BSpline pyramid.

The same as the previous function, but input array is overwritten

Definition at line 1675 of file transformations.h.

1678 {
1679  MultidimArray<T> aux = V1;
1680  V1.initZeros();
1681  pyramidExpand(SplineDegree, V1, aux, levels);
1682 }
void pyramidExpand(int SplineDegree, MultidimArray< T > &V2, const MultidimArray< T > &V1, int levels=1)
void initZeros(const MultidimArray< T1 > &op)

◆ selfPyramidExpand() [2/2]

void selfPyramidExpand ( int  SplineDegree,
MultidimArrayGeneric V1,
int  levels 
)

Same as previous but for MultidimArrayGeneric

Definition at line 809 of file transformations.cpp.

812 {
813 #define SELFPYRAMIDEXPAND(type) selfPyramidExpand(SplineDegree, \
814  *((MultidimArray<type>*)(V1.im)), levels);
816 #undef SELFPYRAMIDEXPAND
817 }
#define SELFPYRAMIDEXPAND(type)
#define SWITCHDATATYPE(datatype, OP)

◆ selfPyramidReduce() [1/2]

template<typename T >
void selfPyramidReduce ( int  SplineDegree,
MultidimArray< T > &  V1,
int  levels = 1 
)

Reduce the nth volume by 2 using a BSpline pyramid.

The same as the previous function, but input array is overwritten

Definition at line 1621 of file transformations.h.

1624 {
1625  MultidimArray<T> aux = V1;
1626  V1.initZeros();
1627  pyramidReduce(SplineDegree, V1, aux, levels);
1628 }
void initZeros(const MultidimArray< T1 > &op)
void pyramidReduce(int SplineDegree, MultidimArray< T > &V2, const MultidimArray< T > &V1, int levels=1)

◆ selfPyramidReduce() [2/2]

void selfPyramidReduce ( int  SplineDegree,
MultidimArrayGeneric V1,
int  levels 
)

Same as previous but for MultidimArrayGeneric

Same as template version but for MultidimArrayGeneric

Definition at line 798 of file transformations.cpp.

801 {
802 #define SELFPYRAMIDREDUCE(type) selfPyramidReduce(SplineDegree, \
803  *((MultidimArray<type>*)(V1.im)), levels);
805 #undef SELFPYRAMIDREDUCE
806 }
#define SELFPYRAMIDREDUCE(type)
#define SWITCHDATATYPE(datatype, OP)

◆ selfRotate()

template<typename T >
void selfRotate ( int  SplineDegree,
MultidimArray< T > &  V1,
double  ang,
char  axis = 'Z',
bool  wrap = xmipp_transformation::DONT_WRAP,
outside = 0 
)

Rotate an array around a given system axis.

The same as the previous function, but input array is overwritten

Definition at line 1350 of file transformations.h.

1354 {
1355  MultidimArray<T> aux = V1;
1356  V1.initZeros();
1357  rotate(SplineDegree, V1, aux, ang, axis, wrap, outside);
1358 }
char axis
void rotate(int SplineDegree, MultidimArray< T > &V2, const MultidimArray< T > &V1, double ang, char axis='Z', bool wrap=xmipp_transformation::DONT_WRAP, T outside=0)
void initZeros(const MultidimArray< T1 > &op)

◆ selfScaleToSize() [1/3]

template<typename T >
void selfScaleToSize ( int  SplineDegree,
MultidimArray< T > &  V1,
int  Xdim,
int  Ydim,
int  Zdim = 1 
)

Scales to a new size.

The same as the previous function, but input array is overwritten

Definition at line 1546 of file transformations.h.

1549 {
1550  MultidimArray<T> aux = V1;
1551  scaleToSize(SplineDegree, V1, aux, Xdim, Ydim, Zdim);
1552 }
void scaleToSize(int SplineDegree, MultidimArray< T > &V2, const MultidimArray< T1 > &V1, size_t Xdim, size_t Ydim, size_t Zdim=1)

◆ selfScaleToSize() [2/3]

void selfScaleToSize ( int  SplineDegree,
MultidimArrayGeneric V1,
int  Xdim,
int  Ydim,
int  Zdim = 1 
)

Definition at line 736 of file transformations.cpp.

739 {
740 #define SELFSCALETOSIZE(type) selfScaleToSize(SplineDegree,MULTIDIM_ARRAY_TYPE(V1,type), \
741  Xdim,Ydim,Zdim);
743 #undef SELFSCALETOSIZE
744 }
#define SELFSCALETOSIZE(type)
#define SWITCHDATATYPE(datatype, OP)

◆ selfScaleToSize() [3/3]

void selfScaleToSize ( int  SplineDegree,
MultidimArray< std::complex< double > > &  V1,
int  Xdim,
int  Ydim,
int  Zdim = 1 
)

Definition at line 789 of file transformations.cpp.

792 {
794  scaleToSize(SplineDegree, V1, aux, Xdim, Ydim, Zdim);
795 }
void scaleToSize(int SplineDegree, MultidimArrayGeneric &V2, const MultidimArrayGeneric &V1, int Xdim, int Ydim, int Zdim)

◆ selfTranslate()

template<typename T >
void selfTranslate ( int  SplineDegree,
MultidimArray< T > &  V1,
const Matrix1D< double > &  v,
bool  wrap = xmipp_transformation::WRAP,
outside = 0 
)

Translate an array.

The same as the previous function, but input array is overwritten

Definition at line 1394 of file transformations.h.

1398 {
1399  MultidimArray<T> aux = V1;
1400  V1.initZeros();
1401  translate(SplineDegree, V1, aux, v, wrap, outside);
1402 }
void translate(int SplineDegree, MultidimArray< T > &V2, const MultidimArray< T > &V1, const Matrix1D< double > &v, bool wrap=xmipp_transformation::WRAP, T outside=0)
void initZeros(const MultidimArray< T1 > &op)

◆ selfTranslateCenterOfMassToCenter()

template<typename T >
void selfTranslateCenterOfMassToCenter ( int  SplineDegree,
MultidimArray< T > &  V1,
bool  wrap = xmipp_transformation::WRAP 
)

Translate center of mass to center

The same as the previous function, but input array is overwritten

Definition at line 1430 of file transformations.h.

1433 {
1434  MultidimArray<T> aux = V1;
1435  V1.initZeros();
1436  translateCenterOfMassToCenter(SplineDegree, V1, aux, wrap);
1437 }
void translateCenterOfMassToCenter(int SplineDegree, MultidimArray< T > &V2, const MultidimArray< T > &V1, bool wrap=xmipp_transformation::WRAP)
void initZeros(const MultidimArray< T1 > &op)

◆ string2TransformationMatrix()

void string2TransformationMatrix ( const String matrixStr,
Matrix2D< double > &  matrix,
size_t  dim = 4 
)

Retrieve the matrix from an string representation Valid formats are: [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] or 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 or 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1

Definition at line 241 of file transformations.cpp.

242 {
243  matrix.resizeNoCopy(dim, dim);
244 
245  String matrixStrCopy(matrixStr);
246  char c;
247 
248  for (size_t i = 0; i < matrixStr.size(); i++)
249  {
250  c = matrixStr[i];
251  if (c == '[' or c == ']' or c == ',')
252  matrixStrCopy[i] = ' ';
253  }
254 
255  size_t n = 4; // EMX matrix are always 4x4
256  std::stringstream ss(matrixStrCopy);
257  size_t d_1 = dim - 1;
258 
259  for (size_t i = 0; i < n; ++i)
260  for (size_t j = 0; j < n; ++j)
261  {
262  //TODO validate that M(dim, dim) is 1
263  //if (i == dim-1 && j == dim-1)
264 
265  ss >> dMij(matrix, i < dim ? i : i-1, j < dim ? j : j-1);
266  }
267  dMij(matrix, d_1, d_1) = 1.;
268 
269 }
doublereal * c
#define i
void resizeNoCopy(int Ydim, int Xdim)
Definition: matrix2d.h:534
#define dMij(m, i, j)
Definition: matrix2d.h:139
#define j
std::string String
Definition: xmipp_strings.h:34
int * n

◆ transformationMatrix2Geo()

void transformationMatrix2Geo ( const Matrix2D< double > &  A,
MDRow imageGeo 
)

Retrieve the geometry transfomations from matrix

Definition at line 330 of file transformations.cpp.

331 {
332  bool flip = false;
333  double scale = 1, shiftX = 0, shiftY = 0, psi = 0, shiftZ = 0, rot = 0, tilt = 0;
334 
335  int dim = A.Xdim() - 1;
336 
337  if (dim == 2)
338  transformationMatrix2Parameters2D(A, flip, scale, shiftX, shiftY, psi);
339  else if (dim == 3)
340  {
341  transformationMatrix2Parameters3D(A, flip, scale, shiftX, shiftY, shiftZ,
342  rot, tilt, psi);
346  }
347 
351 
352  if (imageGeo.containsLabel(MDL_SCALE) || !XMIPP_EQUAL_REAL(scale, 1.))
353  imageGeo.setValue(MDL_SCALE, scale);
354 
355  if (imageGeo.containsLabel(MDL_FLIP) || flip)
356  imageGeo.setValue(MDL_FLIP, flip);
357 }
size_t Xdim() const
Definition: matrix2d.h:575
Rotation angle of an image (double,degrees)
void transformationMatrix2Parameters2D(const Matrix2D< T > &A, bool &flip, T &scale, T &shiftX, T &shiftY, T &psi)
Tilting angle of an image (double,degrees)
Shift for the image in the X axis (double)
Special label to be used when gathering MDs in MpiMetadataPrograms.
#define XMIPP_EQUAL_REAL(x, y)
Definition: xmipp_macros.h:122
void transformationMatrix2Parameters3D(const Matrix2D< double > &A, bool &flip, double &scale, double &shiftX, double &shiftY, double &shiftZ, double &rot, double &tilt, double &psi)
Flip the image? (bool)
scaling factor for an image or volume (double)
void setValue(MDLabel label, const T &d, bool addLabel=true)
virtual bool containsLabel(MDLabel label) const =0
double psi(const double x)
Shift for the image in the Z axis (double)
#define ADD_IF_EXIST_NONZERO(label, value)
Shift for the image in the Y axis (double)

◆ transformationMatrix2Parameters2D()

template<typename T >
void transformationMatrix2Parameters2D ( const Matrix2D< T > &  A,
bool &  flip,
T &  scale,
T &  shiftX,
T &  shiftY,
T &  psi 
)

Retrieve the geometry transformations from matrix for 2D.

Definition at line 272 of file transformations.cpp.

275 {
276  // FIXME DS this might not be true, but just to make sure
277  static_assert(std::is_floating_point<T>::value,
278  "Only float and double are allowed as template parameters");
279  //Calculate determinant for getting flip
280  flip = ((dMij(A, 0, 0) * dMij(A, 1, 1) - dMij(A, 0, 1) * dMij(A, 1, 0) ) < 0);
281  int sgn = flip ? -1 : 1;
282  T cosine = sgn * dMij(A, 0, 0);
283  T sine = sgn * dMij(A, 0, 1);
284  T scale2 = cosine * cosine + sine * sine;
285  scale = sqrt(scale2);
286  T invScale = 1 / scale;
287  shiftX = dMij(A, 0, 2) * invScale;
288  shiftY = dMij(A, 1, 2) * invScale;
289  psi = RAD2DEG(atan2(sine, cosine));
290 }
void sqrt(Image< double > &op)
#define dMij(m, i, j)
Definition: matrix2d.h:139
#define RAD2DEG(r)
Definition: xmipp_macros.h:320
double psi(const double x)

◆ transformationMatrix2Parameters3D()

void transformationMatrix2Parameters3D ( const Matrix2D< double > &  A,
bool &  flip,
double &  scale,
double &  shiftX,
double &  shiftY,
double &  shiftZ,
double &  rot,
double &  tilt,
double &  psi 
)

Retrieve the geometry transformations from matrix for D.

Definition at line 295 of file transformations.cpp.

299 {
300  scale = sqrt(dMij(A,2,0)*dMij(A,2,0) \
301  + dMij(A,2,1)*dMij(A,2,1)\
302  + dMij(A,2,2)*dMij(A,2,2) );
303  double invScale = 1./ scale;
304 
305  Matrix2D<double> tmpMatrix(4,4);
306  M4x4_BY_CT(tmpMatrix, A, invScale);
307 
308  Matrix2D<double> eulerMatrix(3,3);
309 
310  FOR_ALL_ELEMENTS_IN_MATRIX2D(eulerMatrix)
311  dMij(eulerMatrix,i,j) = dMij(tmpMatrix, i, j);
312  //check determinant if -1 then flip = true
313  flip = tmpMatrix.det3x3() < 0;
314  if (flip)
315  {
316  dMij(eulerMatrix, 0, 0) *= -1.;
317  dMij(eulerMatrix, 0, 1) *= -1.;
318  dMij(eulerMatrix, 0, 2) *= -1.;
319  }
320  Euler_matrix2angles(eulerMatrix, rot, tilt, psi);
321 
322  shiftX = dMij(tmpMatrix,0,3);
323  shiftY = dMij(tmpMatrix,1,3);
324  shiftZ = dMij(tmpMatrix,2,3);
325 }
#define FOR_ALL_ELEMENTS_IN_MATRIX2D(m)
Definition: matrix2d.h:104
void sqrt(Image< double > &op)
#define i
#define dMij(m, i, j)
Definition: matrix2d.h:139
#define j
double psi(const double x)
void Euler_matrix2angles(const Matrix2D< double > &A, double &alpha, double &beta, double &gamma, bool homogeneous)
Definition: geometry.cpp:839
#define M4x4_BY_CT(M2, M1, k)
Definition: matrix2d.h:263

◆ translate()

template<typename T >
void translate ( int  SplineDegree,
MultidimArray< T > &  V2,
const MultidimArray< T > &  V1,
const Matrix1D< double > &  v,
bool  wrap = xmipp_transformation::WRAP,
outside = 0 
)

Translate a array.

The shift is given as a R2 or R3 vector (shift_X, shift_Y, shift_Z) for 2D and 3D arrays, respectively. An exception is thrown if the displacement is not a R3 vector.

// Displacement of 2 pixels down
V2 = V1.translate(vectorR3(0, 0, 2));

Definition at line 1372 of file transformations.h.

1377 {
1378  Matrix2D< double > tmp;
1379  if (V1.getDim()==2)
1380  translation2DMatrix(v, tmp,true);
1381  else if (V1.getDim()==3)
1382  translation3DMatrix(v, tmp,true);
1383  else
1384  REPORT_ERROR(ERR_MULTIDIM_DIM,"translate ERROR: translate only valid for 2D or 3D arrays");
1385  applyGeometry(SplineDegree, V2, V1, tmp, xmipp_transformation::IS_INV, wrap, outside);
1386 }
void applyGeometry(int SplineDegree, MultidimArray< T > &__restrict__ V2, const MultidimArray< T1 > &__restrict__ V1, const Matrix2D< T2 > &At, bool inv, bool wrap, T outside=T(0), MultidimArray< double > *BcoeffsPtr=NULL)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void translation2DMatrix(const Matrix1D< T > &translation, Matrix2D< T > &resMatrix, bool inverse=false)
void translation3DMatrix(const Matrix1D< T > &translation, Matrix2D< T > &resMatrix, bool inverse=false)
Incorrect MultidimArray dimensions.
Definition: xmipp_error.h:173

◆ translateCenterOfMassToCenter()

template<typename T >
void translateCenterOfMassToCenter ( int  SplineDegree,
MultidimArray< T > &  V2,
const MultidimArray< T > &  V1,
bool  wrap = xmipp_transformation::WRAP 
)

Translate center of mass to center

If the input has very high values, it is better to rescale it to be between 0 and 1.

Definition at line 1411 of file transformations.h.

1415 {
1416  V2 = V1;
1417  V2.setXmippOrigin();
1418  Matrix1D< double > center;
1419  V2.centerOfMass(center);
1420  center *= -1;
1421  translate(SplineDegree, V2, V1, center, wrap, 0);
1422 }
void translate(int SplineDegree, MultidimArray< T > &V2, const MultidimArray< T > &V1, const Matrix1D< double > &v, bool wrap=xmipp_transformation::WRAP, T outside=0)
void centerOfMass(Matrix1D< double > &center, void *mask=NULL, size_t n=0)

◆ translation2DMatrix()

template<typename T >
void translation2DMatrix ( const Matrix1D< T > &  translation,
Matrix2D< T > &  resMatrix,
bool  inverse = false 
)

Creates a translational matrix (3x3) for images

The shift is given as a R2 vector (shift_X, shift_Y). An exception is thrown if the displacement is not a R2 vector.

// Displacement of 1 pixel to the right
resMatrix = translation2DMatrix(vectorR2(1, 0));

Definition at line 405 of file transformations.cpp.

408 {
409  if (VEC_XSIZE(translation) != 2)
410  REPORT_ERROR(ERR_MATRIX_SIZE, "Translation2D_matrix: vector is not in R2");
411 
412  resMatrix.initIdentity(3);
413  if (inverse)
414  {
415  dMij(resMatrix,0, 2) = -XX(translation);
416  dMij(resMatrix,1, 2) = -YY(translation);
417  }
418  else
419  {
420  dMij(resMatrix,0, 2) = XX(translation);
421  dMij(resMatrix,1, 2) = YY(translation);
422  }
423 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Problem with matrix size.
Definition: xmipp_error.h:152
#define VEC_XSIZE(m)
Definition: matrix1d.h:77
#define XX(v)
Definition: matrix1d.h:85
#define dMij(m, i, j)
Definition: matrix2d.h:139
#define YY(v)
Definition: matrix1d.h:93
void initIdentity()
Definition: matrix2d.h:673

◆ translation3DMatrix()

template<typename T >
void translation3DMatrix ( const Matrix1D< T > &  translation,
Matrix2D< T > &  resMatrix,
bool  inverse = false 
)

Creates a translational matrix (4x4) for volumes

The shift is given as a R3 vector (shift_X, shift_Y, shift_Z). An exception is thrown if the displacement is not a R3 vector.

// Displacement of 2 pixels down
resMatrix = translation3DMatrix(vectorR3(0, 0, 2));

Definition at line 563 of file transformations.cpp.

564 {
565  if (VEC_XSIZE(translation) != 3)
566  REPORT_ERROR(ERR_MATRIX_SIZE, "Translation3D_matrix: vector is not in R3");
567 
568  resMatrix.initIdentity(4);
569  if (inverse)
570  {
571  dMij(resMatrix,0, 3) = -XX(translation);
572  dMij(resMatrix,1, 3) = -YY(translation);
573  dMij(resMatrix,2, 3) = -ZZ(translation);
574  }
575  else
576  {
577  dMij(resMatrix,0, 3) = XX(translation);
578  dMij(resMatrix,1, 3) = YY(translation);
579  dMij(resMatrix,2, 3) = ZZ(translation);
580  }
581 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Problem with matrix size.
Definition: xmipp_error.h:152
#define VEC_XSIZE(m)
Definition: matrix1d.h:77
#define XX(v)
Definition: matrix1d.h:85
#define dMij(m, i, j)
Definition: matrix2d.h:139
#define YY(v)
Definition: matrix1d.h:93
#define ZZ(v)
Definition: matrix1d.h:101
void initIdentity()
Definition: matrix2d.h:673