Xmipp  v3.23.11-Nereus
Public Member Functions | Public Attributes | List of all members
ProgTomographAlignment Class Reference

#include <tomo_align_tilt_series.h>

Inheritance diagram for ProgTomographAlignment:
Inheritance graph
[legend]
Collaboration diagram for ProgTomographAlignment:
Collaboration graph
[legend]

Public Member Functions

 ~ProgTomographAlignment ()
 Destructor. More...
 
void defineParams ()
 Usage. More...
 
void readParams ()
 Read parameters from argument line. More...
 
void show ()
 Show parameters. More...
 
void produceSideInfo ()
 Produce side info. More...
 
void computeAffineTransformations (bool globalAffineToUse)
 Compute affine transformations. More...
 
void identifyOutliers (bool mark)
 Identify outliers. More...
 
void produceInformationFromLandmarks ()
 Produce information from landmarks. More...
 
bool refineLandmark (int ii, int jj, const Matrix1D< double > &rii, Matrix1D< double > &rjj, double &maxCorr, bool tryFourier) const
 
bool refineLandmark (const MultidimArray< double > &pieceii, int jj, Matrix1D< double > &rjj, double actualCorrThreshold, bool reversed, double &maxCorr) const
 
bool refineChain (LandmarkChain &chain, double &corrChain)
 
void generateLandmarkSet ()
 Generate landmark set using a grid. More...
 
void writeLandmarkSet (const FileName &fnLandmark) const
 Write landmark set. More...
 
void writeTransformations (const FileName &fnTransformations) const
 Write affine transformations. More...
 
void readLandmarkSet (const FileName &fnLandmark)
 Read landmark set. More...
 
void removeOutlierLandmarks (const Alignment &alignment)
 Remove Outliers. More...
 
void alignImages (const Alignment &alignment)
 Align images. More...
 
void run ()
 Run: do the real work. More...
 
- Public Member Functions inherited from XmippProgram
const char * getParam (const char *param, int arg=0)
 
const char * getParam (const char *param, const char *subparam, int arg=0)
 
int getIntParam (const char *param, int arg=0)
 
int getIntParam (const char *param, const char *subparam, int arg=0)
 
double getDoubleParam (const char *param, int arg=0)
 
double getDoubleParam (const char *param, const char *subparam, int arg=0)
 
float getFloatParam (const char *param, int arg=0)
 
float getFloatParam (const char *param, const char *subparam, int arg=0)
 
void getListParam (const char *param, StringVector &list)
 
int getCountParam (const char *param)
 
bool checkParam (const char *param)
 
bool existsParam (const char *param)
 
void addParamsLine (const String &line)
 
void addParamsLine (const char *line)
 
ParamDefgetParamDef (const char *param) const
 
virtual void quit (int exit_code=0) const
 
virtual int tryRun ()
 
void initProgress (size_t total, size_t stepBin=60)
 
void setProgress (size_t value=0)
 
void endProgress ()
 
void processDefaultComment (const char *param, const char *left)
 
void setDefaultComment (const char *param, const char *comment)
 
virtual void initComments ()
 
void setProgramName (const char *name)
 
void addUsageLine (const char *line, bool verbatim=false)
 
void clearUsage ()
 
void addExampleLine (const char *example, bool verbatim=true)
 
void addSeeAlsoLine (const char *seeAlso)
 
void addKeywords (const char *keywords)
 
const char * name () const
 
virtual void usage (int verb=0) const
 
virtual void usage (const String &param, int verb=2)
 
int version () const
 
virtual void show () const
 
virtual void read (int argc, const char **argv, bool reportErrors=true)
 
virtual void read (int argc, char **argv, bool reportErrors=true)
 
void read (const String &argumentsLine)
 
 XmippProgram ()
 
 XmippProgram (int argc, const char **argv)
 
virtual ~XmippProgram ()
 

Public Attributes

FileName fnSel
 MetaData File with all images. More...
 
FileName fnSelOrig
 MetaData File with all images at the original scale. More...
 
FileName fnRoot
 Output root. More...
 
int numThreads
 Number of threads to use for parallel computing. More...
 
bool globalAffine
 Look for local affine transformation. More...
 
bool useCriticalPoints
 Use critical points. More...
 
size_t Ncritical
 Number of critical points. More...
 
size_t seqLength
 Sequence Length. More...
 
size_t blindSeqLength
 
int gridSamples
 Grid samples. More...
 
double maxShiftPercentage
 Maxshift percentage. More...
 
int maxIterDE
 Maximum number of iterations in Differential Evolution. More...
 
double psiMax
 Maximum rotation. More...
 
int maxStep
 Maximum Step for chain refinement. More...
 
double deltaRot
 Delta rot. More...
 
double localSize
 Local refinement size. More...
 
bool optimizeTiltAngle
 Optimize tilt angle of tilt axis. More...
 
bool isCapillar
 This tilt series comes from a capillar. More...
 
bool dontNormalize
 Don't normalize the corrected images. More...
 
bool difficult
 Difficult. More...
 
double corrThreshold
 Correlation threshold for a good landmark. More...
 
bool showAffine
 Show affine transformations. More...
 
double thresholdAffine
 Threshold affine. More...
 
double identifyOutliersZ
 Identify outlier micrographs. More...
 
bool doNotIdentifyOutliers
 Do not identify outlier micrographs. More...
 
int pyramidLevel
 Pyramid. More...
 
int lastStep
 Last step to run (-1=run them all) More...
 
int iteration
 
MetaDataVec SF
 
MetaDataVec SForig
 
std::vector< MultidimArray< unsigned char > * > img
 
std::vector< MultidimArray< unsigned char > * > maskImg
 
int iMinTilt
 
std::vector< double > tiltList
 
std::vector< std::string > name_list
 
Matrix1D< double > avgForwardPatchCorr
 
Matrix1D< double > avgBackwardPatchCorr
 
Matrix1D< int > isOutlier
 
int Nimg
 
std::vector< std::vector< Matrix2D< double > > > affineTransformations
 
std::vector< double > correlationList
 
Matrix2D< double > allLandmarksX
 
Matrix2D< double > allLandmarksY
 
std::vector< std::vector< int > > Vseti
 
std::vector< std::vector< int > > Vsetj
 
std::vector< Matrix1D< double > > barpi
 
Matrix1D< int > ni
 
AlignmentbestPreviousAlignment
 
bool showRefinement
 
- Public Attributes inherited from XmippProgram
bool doRun
 
bool runWithoutArgs
 
int verbose
 Verbosity level. More...
 
int debug
 

Additional Inherited Members

- Protected Member Functions inherited from XmippProgram
void defineCommons ()
 
- Protected Attributes inherited from XmippProgram
int errorCode
 
ProgramDefprogDef
 Program definition and arguments parser. More...
 
std::map< String, CommentListdefaultComments
 
int argc
 Original command line arguments. More...
 
const char ** argv
 

Detailed Description

This is the main class

Definition at line 76 of file tomo_align_tilt_series.h.

Constructor & Destructor Documentation

◆ ~ProgTomographAlignment()

ProgTomographAlignment::~ProgTomographAlignment ( )

Destructor.

Definition at line 1621 of file tomo_align_tilt_series.cpp.

1622 {
1623  // Clear the list of images if not empty
1624  if (!img.empty())
1625  {
1626  for (size_t i=0; i<img.size(); i++)
1627  delete img[i];
1628  img.clear();
1629  }
1630 
1631  if (!maskImg.empty())
1632  {
1633  for (size_t i=0; i<maskImg.size(); i++)
1634  delete maskImg[i];
1635  maskImg.clear();
1636  }
1637 }
std::vector< MultidimArray< unsigned char > * > maskImg
#define i
std::vector< MultidimArray< unsigned char > * > img

Member Function Documentation

◆ alignImages()

void ProgTomographAlignment::alignImages ( const Alignment alignment)

Align images.

Definition at line 2245 of file tomo_align_tilt_series.cpp.

2246 {
2247  // Correct all landmarks
2248  Matrix1D<double> r(2);
2249  for (size_t i=0; i<MAT_XSIZE(allLandmarksX); i++)
2250  {
2251  Matrix2D<double> R;
2252  rotation2DMatrix(90-alignment.rot+alignment.psi(i),R,false);
2253  for (size_t j=0; j<MAT_YSIZE(allLandmarksX); j++)
2254  if (allLandmarksX(j,i)!=XSIZE(*img[0]))
2255  {
2257  r=R*(r-alignment.di[i]+alignment.diaxis[i]);
2258  allLandmarksX(j,i)=XX(r);
2259  allLandmarksY(j,i)=YY(r);
2260  }
2261  }
2262 
2263  // Compute the average height of the 3D landmarks seen at 0 degrees
2265  Euler_direction(alignment.rot, alignment.tilt, 0, axis);
2266  double z0=0, z0N=0;
2267  for (size_t j=0; j<MAT_YSIZE(allLandmarksX); j++)
2268  if (allLandmarksX(j,iMinTilt)!=XSIZE(*img[0]))
2269  {
2270  Matrix2D<double> Raxismin, Rmin, RtiltYmin;
2271  rotation3DMatrix(tiltList[iMinTilt],axis,Raxismin,false);
2272  rotation2DMatrix(90-alignment.rot+alignment.psi(iMinTilt),Rmin);
2273  rotation3DMatrix(-tiltList[iMinTilt],'Y',RtiltYmin,false);
2274  Matrix1D<double> rjp=RtiltYmin*Rmin*Raxismin*alignment.rj[j];
2275  z0+=ZZ(rjp);
2276  z0N++;
2277  }
2278  if (z0N==0)
2279  REPORT_ERROR(ERR_VALUE_INCORRECT,"There is no landmark at 0 degrees");
2280  z0/=z0N;
2281  std::cout << "Average height of the landmarks at 0 degrees=" << z0 << std::endl;
2282  MetaDataVec DF;
2283 
2284  std::unique_ptr<MetaDataVec::id_iterator> idIter;
2285 
2286  if (!fnSelOrig.empty())
2287  {
2288  idIter = memoryUtils::make_unique<MetaDataVec::id_iterator>(SForig.ids().begin());
2289  }
2290  DF.setComment("First shift by -(shiftX,shiftY), then rotate by psi");
2291 
2292  MultidimArray<double> mask;
2293  MultidimArray<int> iMask;
2294  Image<double> I;
2295  Matrix2D<double> M, M1, M2, M3;
2296  FileName fn_corrected;
2297 
2298  for (int n=0;n<Nimg; n++)
2299  {
2300  // Align the normal image
2301  I.read(name_list[n]);
2302  mask.initZeros(I());
2304  if (I(i,j)!=0)
2305  mask(i,j)=1;
2306  translation2DMatrix(vectorR2(-z0*sin(DEG2RAD(tiltList[n])),0),M1);
2307  rotation2DMatrix(90-alignment.rot+alignment.psi(n),M2);
2308  translation2DMatrix(-(alignment.di[n]+alignment.diaxis[n]),M3);
2309  M=M1*M2*M3;
2312  mask.binarize(0.5);
2313  typeCast(mask,iMask);
2314  double minval, maxval, avg, stddev;
2315  computeStats_within_binary_mask(iMask,I(),minval, maxval, avg, stddev);
2317  if (iMask(i,j)==0)
2318  I(i,j)=0;
2319  else if (!dontNormalize)
2320  I(i,j)-=avg;
2321  double rot=0;
2322  double tilt=tiltList[n];
2323  double psi=0;
2324  I.setEulerAngles(rot, tilt, psi);
2325  fn_corrected.compose(n+1, fnRoot+"_corrected_", "stk");
2326  I.write(fn_corrected);
2327 
2328  // Align the original image
2329  if (fnSelOrig!="")
2330  {
2331  FileName auxFn;
2332  SForig.getValue( MDL_IMAGE, auxFn, **idIter);
2333  Image<double> Iorig;
2334  Iorig.read( auxFn );
2335  //SForig.nextObject();
2336  ++(*idIter);
2337  mask.initZeros(Iorig());
2339  if (Iorig(i,j)!=0)
2340  mask(i,j)=1;
2342  (((double)XSIZE(Iorig()))/XSIZE(I())),0),M1);
2343  rotation2DMatrix(90-alignment.rot+alignment.psi(n),M2);
2344  translation2DMatrix(-(alignment.di[n]+alignment.diaxis[n])*
2345  (((double)XSIZE(Iorig()))/XSIZE(I())),M3);
2346  M=M1*M2*M3;
2347  selfApplyGeometry(xmipp_transformation::BSPLINE3,Iorig(),M,xmipp_transformation::IS_NOT_INV,xmipp_transformation::DONT_WRAP);
2349  mask.binarize(0.5);
2350  typeCast(mask,iMask);
2351  computeStats_within_binary_mask(iMask,Iorig(),minval, maxval,
2352  avg, stddev);
2354  if (iMask(i,j)==0)
2355  Iorig(i,j)=0;
2356  else if (!dontNormalize)
2357  Iorig(i,j)-=avg;
2358  Iorig.setEulerAngles(rot, tilt, psi);
2359  fn_corrected.compose(n+1, fnRoot+"_corrected_originalsize_", "stk");
2360  Iorig.write(fn_corrected);
2361  }
2362 
2363  // Prepare data for the docfile
2364  size_t id = DF.addObject();
2365  DF.setValue(MDL_IMAGE, fn_corrected, id);
2366  DF.setValue(MDL_ANGLE_PSI, 90.-alignment.rot+alignment.psi(n), id);
2367  DF.setValue(MDL_SHIFT_X, XX(alignment.di[n]+alignment.diaxis[n]), id);
2368  DF.setValue(MDL_SHIFT_Y, YY(alignment.di[n]+alignment.diaxis[n]), id);
2369  }
2370  DF.write(fnRoot+"_correction_parameters.txt");
2371 #ifdef DEBUG
2372 
2373  Image<double> save;
2374  save().initZeros(*img[0]);
2375  save().setXmippOrigin();
2376  for (int j=0; j<YSIZE(allLandmarksX); j++)
2377  if (allLandmarksX(j,iMinTilt)!=XSIZE(*img[0]))
2378  {
2380  Raxismin.resize(3,3);
2381  Matrix2D<double> Rmin=rotation2DMatrix(90-alignment.rot+alignment.psi(iMinTilt));
2383  RtiltYmin.resize(3,3);
2384  Matrix1D<double> rjp=RtiltYmin*Rmin*Raxismin*alignment.rj[j];
2385  std::cout << rjp.transpose() << std::endl;
2386  for (int i=0; i<XSIZE(allLandmarksX); i++)
2387  if (allLandmarksX(j,i)!=XSIZE(*img[0]))
2388  {
2389  save(allLandmarksY(j,i),allLandmarksX(j,i))=ABS(i-iMinTilt);
2390 
2391  /*
2392  Matrix2D<double> Raxis=rotation3DMatrix(tiltList[i],axis);
2393  Raxis.resize(3,3);
2394  Matrix2D<double> R=rotation2DMatrix(90-alignment.rot+alignment.psi(i));
2395  Matrix1D<double> p=R*Raxis*alignment.rj[j];
2396  if (YY(p)>=STARTINGY(save()) && YY(p)<=FINISHINGY(save()) &&
2397  XX(p)>=STARTINGX(save()) && XX(p)<=FINISHINGX(save()))
2398  save(YY(p),XX(p))=-ABS(i-iMinTilt);
2399  */
2400  Matrix2D<double> RtiltY=rotation3DMatrix(-tiltList[i],'Y');
2401  RtiltY.resize(3,3);
2402  Matrix1D<double> p=RtiltY*rjp;
2403  if (YY(p)>=STARTINGY(save()) && YY(p)<=FINISHINGY(save()) &&
2404  XX(p)>=STARTINGX(save()) && XX(p)<=FINISHINGX(save()))
2405  save(YY(p),XX(p))=-ABS(i-iMinTilt);
2406  }
2407  }
2408  save.write("PPPmovementsLandmarks0.xmp");
2409 #endif
2410 }
void selfApplyGeometry(int Splinedegree, MultidimArray< std::complex< double > > &V1, const Matrix2D< double > &A, bool inv, bool wrap, std::complex< double > outside)
#define VECTOR_R2(v, x, y)
Definition: matrix1d.h:112
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
std::vector< Matrix1D< double > > di
#define YSIZE(v)
template void translation2DMatrix(const Matrix1D< float > &, Matrix2D< float > &, bool inverse)
std::vector< Matrix1D< double > > rj
Matrix2D< double > allLandmarksY
std::vector< double > tiltList
#define FINISHINGX(v)
void write(std::ostream &os, const datablock &db)
Definition: cif2pdb.cpp:3747
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void Euler_direction(double alpha, double beta, double gamma, Matrix1D< double > &v)
Definition: geometry.cpp:721
#define DEG2RAD(d)
Definition: xmipp_macros.h:312
Shift for the image in the X axis (double)
Special label to be used when gathering MDs in MpiMetadataPrograms.
#define z0
#define M3
Matrix2D< double > allLandmarksX
virtual IdIteratorProxy< false > ids()
FileName fnRoot
Output root.
double * di
#define STARTINGX(v)
#define i
virtual void setComment(const String &newComment="No comment")
void computeStats_within_binary_mask(const MultidimArray< T1 > &mask, const MultidimArray< T > &m, double &min_val, double &max_val, double &avg, double &stddev)
Definition: mask.h:799
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
Matrix1D< T > transpose() const
Definition: matrix1d.cpp:644
std::vector< std::string > name_list
void rotation3DMatrix(double ang, char axis, Matrix2D< double > &result, bool homogeneous)
#define STARTINGY(v)
#define M2
#define M1
char axis
std::vector< Matrix1D< double > > diaxis
#define XX(v)
Definition: matrix1d.h:85
if(fabs(c[*nmax+ *nmax *c_dim1])==0.e0)
Matrix1D< double > psi
#define XSIZE(v)
#define ABS(x)
Definition: xmipp_macros.h:142
FileName fnSelOrig
MetaData File with all images at the original scale.
Matrix1D< double > vectorR2(double x, double y)
Definition: matrix1d.cpp:884
std::vector< MultidimArray< unsigned char > * > img
void rotation2DMatrix(T ang, Matrix2D< T > &result, bool homogeneous)
#define j
#define YY(v)
Definition: matrix1d.h:93
bool getValue(MDObject &mdValueOut, size_t id) const override
#define FINISHINGY(v)
void typeCast(const Matrix1D< T1 > &v1, Matrix1D< T2 > &v2)
Definition: matrix1d.h:1227
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
double psi(const double x)
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
Shift for the image in the Y axis (double)
void initZeros(const MultidimArray< T1 > &op)
bool dontNormalize
Don&#39;t normalize the corrected images.
Incorrect value received.
Definition: xmipp_error.h:195
int * n
Name of an image (std::string)
void resize(size_t Ydim, size_t Xdim, bool noCopy=false)
Definition: matrix2d.cpp:1022
#define ZZ(v)
Definition: matrix1d.h:101

◆ computeAffineTransformations()

void ProgTomographAlignment::computeAffineTransformations ( bool  globalAffineToUse)

Compute affine transformations.

Definition at line 674 of file tomo_align_tilt_series.cpp.

676 {
677  bool oldglobalAffine=globalAffine;
678  globalAffine=globalAffineToUse;
679 
680  auto * th_ids = new pthread_t[numThreads];
681  auto * th_args = new ThreadComputeTransformParams[numThreads];
682 
683  for( int nt = 0 ; nt < numThreads ; nt ++ )
684  {
685  // Passing parameters to each thread
686  th_args[nt].parent = this;
687  th_args[nt].myThreadID = nt;
688  pthread_create( (th_ids+nt) , nullptr, threadComputeTransform, (void *)(th_args+nt) );
689  }
690 
691  // Waiting for threads to finish
692  for( int nt = 0 ; nt < numThreads ; nt ++ )
693  pthread_join(*(th_ids+nt), nullptr);
694 
695  // Threads structures are not needed any more
696  delete[] th_ids;
697  delete[] th_args;
698  globalAffine=oldglobalAffine;
699 }
bool globalAffine
Look for local affine transformation.
int numThreads
Number of threads to use for parallel computing.
void * threadComputeTransform(void *args)

◆ defineParams()

void ProgTomographAlignment::defineParams ( )
virtual

Usage.

Reimplemented from XmippProgram.

Definition at line 522 of file tomo_align_tilt_series.cpp.

523 {
524  addUsageLine("Align a single-axis tilt series without any marker.");
525  addSeeAlsoLine("tomo_align_dual_tilt_series");
526  addParamsLine(" == General Options == ");
527  addParamsLine(" -i <metadatafile> : Input images");
528  addParamsLine(" : The selfile must contain the list of micrographs");
529  addParamsLine(" : and its tilt angles");
530  addParamsLine(" [--iorig <metadatafile=\"\">] : Metadata with images at original scale");
531  addParamsLine(" [--oroot <fn_out=\"\">] : Output alignment");
532  addParamsLine(" : If not given, the input selfile without extension");
533  addParamsLine(" [--thr <num=1>] : Parallel processing using \"num\" threads");
534  addParamsLine(" [--lastStep+ <step=-1>] : Last step to perform");
535  addParamsLine(" : Step -1 -> Perform all steps");
536  addParamsLine(" : Step 0 -> Determination of affine transformations");
537  addParamsLine(" : Step 1 -> Determination of landmark chains");
538  addParamsLine(" : Step 2 -> Determination of alignment parameters");
539  addParamsLine(" : Step 3 -> Writing aligned images");
540  addParamsLine(" == Step 0 (Affine alignment) Options == ");
541  addParamsLine(" [--maxShiftPercentage <p=0.2>] : Maximum shift as percentage of image size");
542  addParamsLine(" [--thresholdAffine <th=0.85>] : Threshold affine");
543  addParamsLine(" [--globalAffine] : Look globally for affine transformations");
544  addParamsLine(" [--difficult+] : Apply some filters before affine alignment");
545  addParamsLine(" [--maxIterDE+ <n=30>] : Maximum number of iteration in Differential Evolution");
546  addParamsLine(" [--showAffine+] : Show affine transformations as PPP*");
547  addParamsLine(" [--identifyOutliers+ <z=5>] : Z-score to be an outlier");
548  addParamsLine(" [--noOutliers+] : Do not identify outliers");
549  addParamsLine(" [--pyramid+ <level=1>] : Multiresolution for affine transformations");
550  addParamsLine(" == Step 1 (Landmark chain) Options == ");
551  addParamsLine(" [--seqLength <n=5>] : Sequence length");
552  addParamsLine(" [--localSize <size=0.04>] : In percentage");
553  addParamsLine(" [--useCriticalPoints <n=0>] : Use critical points instead of a grid");
554  addParamsLine(" : n is the number of critical points to choose");
555  addParamsLine(" : in each image");
556  addParamsLine(" [--threshold+ <th=-1>] : Correlation threshold");
557  addParamsLine(" [--blindSeqLength+ <n=-1>] : Blind sequence length, -1=No blind landmarks");
558  addParamsLine(" [--maxStep+ <step=4>] : Maximum step for chain refinement");
559  addParamsLine(" [--gridSamples+ <n=40>] : Total number of samples=n*n");
560  addParamsLine(" [--isCapillar+] : Set this flag if the tilt series is of a capillar");
561  addParamsLine(" == Step 2 (Determination of alignment parameters) Options == ");
562  addParamsLine(" [--psiMax+ <psi=-1>] : Maximum psi in absolute value (degrees)");
563  addParamsLine(" : -1 -> do not optimize for psi");
564  addParamsLine(" [--deltaRot+ <rot=5>] : In degrees. For the first optimization stage");
565  addParamsLine(" [--optimizeTiltAngle+] : Optimize tilt angle");
566  addParamsLine(" == Step 3 (Produce aligned images) Options == ");
567  addParamsLine(" [--dontNormalize+] : Don't normalize the output images");
568  addExampleLine("Typical run",false);
569  addExampleLine("xmipp_tomo_align_tilt_series -i tiltseries.sel --thr 8");
570  addExampleLine("If there are image with large shifts",false);
571  addExampleLine("xmipp_tomo_align_tilt_series -i tiltseries.sel --thr 8 --globalAffine");
572  addExampleLine("If there are clear landmarks that can be tracked",false);
573  addExampleLine("xmipp_tomo_align_tilt_series -i tiltseries.sel --thr 8 --criticalPoints");
574 }
void addSeeAlsoLine(const char *seeAlso)
void addExampleLine(const char *example, bool verbatim=true)
void addUsageLine(const char *line, bool verbatim=false)
void addParamsLine(const String &line)

◆ generateLandmarkSet()

void ProgTomographAlignment::generateLandmarkSet ( )

Generate landmark set using a grid.

Definition at line 1639 of file tomo_align_tilt_series.cpp.

1640 {
1641  FileName fn_tmp = fnRoot+"_landmarks.txt";
1642  if (!fn_tmp.exists())
1643  {
1644  auto * th_ids = new pthread_t[numThreads];
1645  auto * th_args=
1647  for( int nt = 0 ; nt < numThreads ; nt ++ )
1648  {
1649  th_args[nt].parent = this;
1650  th_args[nt].myThreadID = nt;
1651  if (useCriticalPoints)
1652  pthread_create( (th_ids+nt) , nullptr, threadgenerateLandmarkSetCriticalPoints, (void *)(th_args+nt) );
1653  else
1654  pthread_create( (th_ids+nt) , nullptr, threadgenerateLandmarkSetGrid, (void *)(th_args+nt) );
1655  }
1656 
1657  std::vector<LandmarkChain> chainList;
1658  int includedPoints=0;
1659  for( int nt = 0 ; nt < numThreads ; nt ++ )
1660  {
1661  pthread_join(*(th_ids+nt), nullptr);
1662  int imax=th_args[nt].chainList->size();
1663  for (int i=0; i<imax; i++)
1664  {
1665  chainList.push_back((*th_args[nt].chainList)[i]);
1666  includedPoints+=(*th_args[nt].chainList)[i].size();
1667  }
1668  delete th_args[nt].chainList;
1669  }
1670  delete[] th_ids;
1671  delete[] th_args;
1672 
1673  // Add blind landmarks
1674  if (blindSeqLength>0)
1675  {
1676  th_ids = new pthread_t[numThreads];
1678  for( int nt = 0 ; nt < numThreads ; nt ++ )
1679  {
1680  th_args[nt].parent = this;
1681  th_args[nt].myThreadID = nt;
1682  pthread_create( (th_ids+nt) , nullptr, threadgenerateLandmarkSetBlind, (void *)(th_args+nt) );
1683  }
1684 
1685  for( int nt = 0 ; nt < numThreads ; nt ++ )
1686  {
1687  pthread_join(*(th_ids+nt), nullptr);
1688  int imax=th_args[nt].chainList->size();
1689  for (int i=0; i<imax; i++)
1690  {
1691  chainList.push_back((*th_args[nt].chainList)[i]);
1692  includedPoints+=(*th_args[nt].chainList)[i].size();
1693  }
1694  delete th_args[nt].chainList;
1695  }
1696  delete[] th_ids;
1697  delete[] th_args;
1698  }
1699 
1700  // Generate the landmark "matrix"
1701  allLandmarksX.resize(chainList.size(),Nimg);
1702  allLandmarksY.resize(chainList.size(),Nimg);
1705  for (size_t i=0; i<chainList.size(); i++)
1706  {
1707  for (size_t j=0; j<chainList[i].size(); j++)
1708  {
1709  int idx=chainList[i][j].imgIdx;
1710  allLandmarksX(i,idx)=chainList[i][j].x;
1711  allLandmarksY(i,idx)=chainList[i][j].y;
1712  }
1713  }
1714 
1715  // Write landmarks
1716  if (includedPoints>0)
1717  {
1718  writeLandmarkSet(fnRoot+"_landmarks.txt");
1719  std::cout << " Number of points="
1720  << includedPoints
1721  << " Number of chains=" << chainList.size()
1722  << " ( " << ((double) includedPoints)/chainList.size() << " )\n";
1723  }
1724  else
1725  REPORT_ERROR(ERR_VALUE_INCORRECT,"There are no landmarks meeting this threshold. Try to lower it");
1726  }
1727  else
1728  {
1729  readLandmarkSet(fnRoot+"_landmarks.txt");
1730  }
1731 }
#define YSIZE(v)
void * threadgenerateLandmarkSetGrid(void *args)
Matrix2D< double > allLandmarksY
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void initConstant(T val)
Definition: matrix2d.h:602
Matrix2D< double > allLandmarksX
FileName fnRoot
Output root.
#define i
void * threadgenerateLandmarkSetCriticalPoints(void *args)
int numThreads
Number of threads to use for parallel computing.
#define XSIZE(v)
void readLandmarkSet(const FileName &fnLandmark)
Read landmark set.
bool exists() const
std::vector< MultidimArray< unsigned char > * > img
bool useCriticalPoints
Use critical points.
#define j
void writeLandmarkSet(const FileName &fnLandmark) const
Write landmark set.
void * threadgenerateLandmarkSetBlind(void *args)
Incorrect value received.
Definition: xmipp_error.h:195
void resize(size_t Ydim, size_t Xdim, bool noCopy=false)
Definition: matrix2d.cpp:1022

◆ identifyOutliers()

void ProgTomographAlignment::identifyOutliers ( bool  mark)

Identify outliers.

Definition at line 701 of file tomo_align_tilt_series.cpp.

702 {
704  MultidimArray<double> correlationListAux(Nimg);
705  for (int i=0; i<Nimg; i++)
706  correlationListAux(i)=correlationList[i];
707 
709  double medianCorr=correlationListAux.computeMedian();
710  diff=correlationListAux-medianCorr;
711  diff.selfABS();
712  double madCorr=diff.computeMedian();
713 
714  std::cout << "Cost distribution= " << 1-medianCorr << " +- "
715  << madCorr << std::endl;
716 
717  double thresholdCorr=medianCorr-identifyOutliersZ*madCorr;
718  for (size_t i=1; i<VEC_XSIZE(isOutlier); i++)
719  {
720  bool potentialOutlier=(correlationListAux(i)<thresholdCorr);
721  if (potentialOutlier)
722  {
723  affineTransformations[i-1][i].clear();
724  if (mark)
725  {
726  isOutlier(i)=true;
727  std::cout << name_list[i-1] << " [" << i
728  << "] is considered as an outlier. "
729  << "Its cost is " << 1-correlationListAux(i)
730  << std::endl;
731  }
732  else
733  std::cout << name_list[i-1] << " [" << i
734  << "] might be an outlier. "
735  << "Its cost is " << 1-correlationListAux(i)
736  << std::endl;
737  }
738  iteration++;
739  }
740 }
#define VEC_XSIZE(m)
Definition: matrix1d.h:77
#define i
std::vector< std::string > name_list
double identifyOutliersZ
Identify outlier micrographs.
double computeMedian() const
void initZeros()
Definition: matrix1d.h:592
std::vector< std::vector< Matrix2D< double > > > affineTransformations
std::vector< double > correlationList

◆ produceInformationFromLandmarks()

void ProgTomographAlignment::produceInformationFromLandmarks ( )

Produce information from landmarks.

Definition at line 2414 of file tomo_align_tilt_series.cpp.

2415 {
2416  // Produce V sets
2417  std::vector<int> emptyVector;
2418 
2419  Vseti.clear();
2420  for (size_t i=0; i<MAT_XSIZE(allLandmarksX); i++)
2421  Vseti.push_back(emptyVector);
2422 
2423  Vsetj.clear();
2424  for (size_t j=0; j<MAT_YSIZE(allLandmarksX); j++)
2425  Vsetj.push_back(emptyVector);
2426 
2427  for (size_t j=0; j<MAT_YSIZE(allLandmarksX); j++)
2428  for (size_t i=0; i<MAT_XSIZE(allLandmarksX); i++)
2429  if (allLandmarksX(j,i)!=XSIZE(*img[0]))
2430  {
2431  Vseti[i].push_back(j);
2432  Vsetj[j].push_back(i);
2433  }
2434 
2435  // Count the number of landmarks per image and average projection
2436  // of all landmarks in a given image
2437  ni.initZeros(Nimg);
2438  barpi.clear();
2439  for (int i=0; i<Nimg; i++)
2440  {
2441  ni(i)=static_cast<int>(Vseti[i].size());
2442  Matrix1D<double> pi(2);
2443  for (int jj=0; jj<ni(i); jj++)
2444  {
2445  int j=Vseti[i][jj];
2446  XX(pi)+=allLandmarksX(j,i);
2447  YY(pi)+=allLandmarksY(j,i);
2448  }
2449  pi/=ni(i);
2450  barpi.push_back(pi);
2451  }
2452 }
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
Matrix2D< double > allLandmarksY
std::vector< Matrix1D< double > > barpi
Matrix2D< double > allLandmarksX
#define i
#define XX(v)
Definition: matrix1d.h:85
std::vector< std::vector< int > > Vseti
#define XSIZE(v)
void initZeros()
Definition: matrix1d.h:592
std::vector< MultidimArray< unsigned char > * > img
#define j
#define YY(v)
Definition: matrix1d.h:93
std::vector< std::vector< int > > Vsetj
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
#define pi

◆ produceSideInfo()

void ProgTomographAlignment::produceSideInfo ( )

Produce side info.

Definition at line 742 of file tomo_align_tilt_series.cpp.

743 {
744  // Difficult images?
745  if (difficult)
746  {
747  if (pyramidLevel==0)
748  pyramidLevel=2;
749  if (localSize<0.05)
750  localSize=0.08;
751  if (seqLength==5)
752  seqLength=11;
753  }
754 
756  // Read input data
757  SF.read(fnSel,nullptr);
760  Nimg=SF.size();
761  if (Nimg!=0)
762  {
763  // Clear the list of images if not empty
764  if (!img.empty())
765  {
766  for (size_t i=0; i<img.size(); i++)
767  delete img[i];
768  img.clear();
769  }
770 
771  // Clear the list of masks if not empty
772  if (!maskImg.empty())
773  {
774  for (size_t i=0; i<maskImg.size(); i++)
775  delete maskImg[i];
776  maskImg.clear();
777  }
778 
779  std::cerr << "Reading input data\n";
781  iteration=0;
782  int n=0;
783 
784  iMinTilt=-1;
785  double minTilt=1000;
786  bool nonZeroTilt=false;
787  Image<double> imgaux;
788  FileName fn;
789  for (size_t objId : SF.ids())
790  {
791  SF.getValue( MDL_IMAGE, fn, objId);
792  imgaux.read(fn);
793  if (difficult)
794  {
795  //ImageXmipp save;
796  //save()=imgaux(); save.write("PPPoriginal.xmp");
797  MultidimArray<double> Ifiltered;
798  Ifiltered=imgaux();
799  Ifiltered.setXmippOrigin();
800 
801  // Reject outliers
802  reject_outliers(Ifiltered,0.5);
803 
804  // Subtract background plane
805  substractBackgroundPlane(Ifiltered);
806 
807  // Subtract the background (rolling ball)
809  XSIZE(Ifiltered)/10);
810 
811  // Bandpass the image
812  FourierFilter FilterBP;
813  FilterBP.FilterBand=BANDPASS;
814  FilterBP.w1=1.0/XSIZE(Ifiltered);
815  FilterBP.w2=100.0/XSIZE(Ifiltered);
816  FilterBP.raised_w=1.0/XSIZE(Ifiltered);
817  FilterBP.generateMask(Ifiltered);
818  FilterBP.applyMaskSpace(Ifiltered);
819 
820  // Equalize histogram
821  //histogram_equalization(Ifiltered,8);
822  imgaux()=Ifiltered;
823  //save()=Ifiltered; save.write("PPPpreprocessed.xmp");
824  //std::cout << "Press\n";
825  //char c; std::cin >> c;
826  }
827 
828  if (!useCriticalPoints)
829  {
830  auto* mask_i=new MultidimArray<unsigned char>;
831  generateMask(imgaux(),*mask_i,
832  XMIPP_MAX(ROUND(localSize*XSIZE(imgaux()))/2,5));
833  maskImg.push_back(mask_i);
834  }
835 
836  auto* img_i=new MultidimArray<unsigned char>;
837  imgaux().rangeAdjust(0,255);
838  typeCast(imgaux(),*img_i);
839  img_i->setXmippOrigin();
840  img.push_back(img_i);
841 
842  double tiltAngle;
844  SF.getValue(MDL_ANGLE_TILT,tiltAngle, objId);
845  else
846  tiltAngle=imgaux.tilt();
847  tiltList.push_back(tiltAngle);
848  if (tiltAngle!=0)
849  nonZeroTilt=true;
850  if (ABS(tiltAngle)<minTilt)
851  {
852  iMinTilt=n;
853  minTilt=ABS(tiltAngle);
854  }
855  name_list.push_back(imgaux.name());
856 
857  progress_bar(n++);
858  iteration++;
859  }
861  if (!nonZeroTilt)
862  REPORT_ERROR(ERR_VALUE_NOTSET,"Tilt angles have not been assigned to the input selfile");
863  }
864 
865  // Read images at original scale
866  if (!fnSelOrig.empty())
867  {
868  SForig.read(fnSelOrig,nullptr);
870 
871  if (SForig.size()!=SF.size())
872  REPORT_ERROR(ERR_MD_OBJECTNUMBER,"The number of images in both selfiles (-i and -iorig) is different");
873  }
874 
875  // Fill the affine transformations with empty matrices
876  std::vector< Matrix2D<double> > emptyRow;
877  for (int i=0; i<Nimg; i++)
878  {
880  emptyRow.push_back(A);
881  }
882  for (int i=0; i<Nimg; i++)
883  {
884  affineTransformations.push_back(emptyRow);
885  correlationList.push_back(-1);
886  }
887 
888  // Check if there are transformations already calculated
889  FileName fn_tmp = fnRoot+"_transformations.txt";
890  if (fn_tmp.exists())
891  {
892  std::ifstream fhIn;
893  fhIn.open(fn_tmp.c_str());
894  if (!fhIn)
895  REPORT_ERROR(ERR_IO_NOTEXIST,(String)"Cannot open "+ fn_tmp);
896  size_t linesRead=0;
897  while (!fhIn.eof())
898  {
899  std::string line;
900  getline(fhIn, line);
901  if (linesRead<affineTransformations.size()-1 && line!="")
902  {
903  std::vector< double > data;
904  readFloatList(line.c_str(), 8, data);
905  double tilt=data[0];
906  int i=0;
907  double bestDistance=ABS(tilt-tiltList[0]);
908  for (int j=0; j<Nimg; j++)
909  {
910  double distance=ABS(tilt-tiltList[j]);
911  if (bestDistance>distance)
912  {
913  bestDistance=distance;
914  i=j;
915  }
916  }
917  affineTransformations[i][i+1].resize(3,3);
918  affineTransformations[i][i+1].initIdentity(3);
919  affineTransformations[i][i+1](0,0)=data[2];
920  affineTransformations[i][i+1](1,0)=data[3];
921  affineTransformations[i][i+1](0,1)=data[4];
922  affineTransformations[i][i+1](1,1)=data[5];
923  affineTransformations[i][i+1](0,2)=data[6];
924  affineTransformations[i][i+1](1,2)=data[7];
925 
926  affineTransformations[i+1][i]=
927  affineTransformations[i][i+1].inv();
928 
929  if (showAffine)
930  {
932  MultidimArray<unsigned char>& img_j=*img[i+1];
933  int maxShift=FLOOR(XSIZE(*img[0])*maxShiftPercentage);
934  Matrix2D<double> Aij, Aji;
935  Aij=affineTransformations[i][i+1];
936  Aji=affineTransformations[i+1][i];
937  bool isMirror=false;
938  std::cout << "Transformation between " << i << " ("
939  << tiltList[i] << ") and " << i+1 << " ("
940  << tiltList[i+1] << std::endl;
941  double cost = computeAffineTransformation(img_i, img_j,
942  maxShift, maxIterDE, Aij, Aji,
944  isMirror,true, pyramidLevel);
945  if (cost<0)
946  {
947  affineTransformations[i][i+1].clear();
948  affineTransformations[i+1][i].clear();
949  writeTransformations(fn_tmp);
950  }
951  }
952  }
953  linesRead++;
954  }
955  fhIn.close();
956  }
957 
958  // Compute the rest of transformations
960 
961  // Do not show refinement
962  showRefinement = false;
963 
964  // Check which is the distribution of correlation
965  if (!useCriticalPoints)
966  {
967  auto X0=(int)(STARTINGX(*(img[0]))+2*localSize*XSIZE(*(img[0])));
968  auto XF=(int)(FINISHINGX(*(img[0]))-2*localSize*XSIZE(*(img[0])));
969  auto Y0=(int)(STARTINGY(*(img[0]))+2*localSize*YSIZE(*(img[0])));
970  auto YF=(int)(FINISHINGY(*(img[0]))-2*localSize*YSIZE(*(img[0])));
975 
976  for (int ii=0; ii<Nimg; ++ii)
977  {
978  // Compute average forward patch corr
979  MultidimArray<double> corrList;
980  if (ii<=Nimg-2)
981  {
982  corrList.initZeros(200);
984  {
985  Matrix1D<double> rii(3), rjj(3);
986  do
987  {
988  XX(rii)=rnd_unif(X0,XF);
989  YY(rii)=rnd_unif(Y0,YF);
990  rjj=affineTransformations[ii][ii+1]*rii;
991  refineLandmark(ii,ii+1,rii,rjj,corrList(i),false);
992  }
993  while (corrList(i)<-0.99);
994  }
995  avgForwardPatchCorr(ii)=corrList.computeAvg();
996  }
997 
998  // Compute average backward patch corr
999  if (ii>0)
1000  {
1001  corrList.initZeros(200);
1002  FOR_ALL_ELEMENTS_IN_ARRAY1D(corrList)
1003  {
1004  Matrix1D<double> rii(3), rjj(3);
1005  do
1006  {
1007  XX(rii)=rnd_unif(X0,XF);
1008  YY(rii)=rnd_unif(Y0,YF);
1009  rjj=affineTransformations[ii][ii-1]*rii;
1010  refineLandmark(ii,ii-1,rii,rjj,corrList(i),false);
1011  }
1012  while (corrList(i)<-0.99);
1013  }
1014  avgBackwardPatchCorr(ii)=corrList.computeAvg();
1015  }
1016 
1017  std::cout << "Image " << ii << " Average correlation forward="
1018  << avgForwardPatchCorr(ii)
1019  << " backward=" << avgBackwardPatchCorr(ii) << std::endl;
1020  iteration++;
1021  }
1022  }
1023 
1024  // Identify outliers
1025  if (!doNotIdentifyOutliers)
1026  {
1027  identifyOutliers(false);
1029  identifyOutliers(true);
1030  }
1031  else
1032  isOutlier.initZeros(Nimg);
1033  if (lastStep==0)
1034  exit(0);
1035 }
bool globalAffine
Look for local affine transformation.
void removeObjects(const std::vector< size_t > &toRemove) override
void init_progress_bar(long total)
bool refineLandmark(int ii, int jj, const Matrix1D< double > &rii, Matrix1D< double > &rjj, double &maxCorr, bool tryFourier) const
#define YSIZE(v)
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
double maxShiftPercentage
Maxshift percentage.
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
std::vector< double > tiltList
#define FINISHINGX(v)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
size_t seqLength
Sequence Length.
void generateMask(const MultidimArray< double > &I, MultidimArray< unsigned char > &mask, int patchSize)
std::vector< MultidimArray< unsigned char > * > maskImg
Tilting angle of an image (double,degrees)
#define BANDPASS
void readFloatList(const char *str, int N, std::vector< T > &v)
Definition: args.h:104
FileName fnSel
MetaData File with all images.
int maxIterDE
Maximum number of iterations in Differential Evolution.
const FileName & name() const
virtual IdIteratorProxy< false > ids()
FileName fnRoot
Output root.
#define STARTINGX(v)
size_t size() const override
#define i
Is this image enabled? (int [-1 or 1])
void computeAffineTransformations(bool globalAffineToUse)
Compute affine transformations.
Incorrect number of objects in Metadata.
Definition: xmipp_error.h:160
std::vector< std::string > name_list
double tilt(const size_t n=0) const
#define STARTINGY(v)
double rnd_unif()
Matrix1D< double > avgForwardPatchCorr
#define FLOOR(x)
Definition: xmipp_macros.h:240
#define XX(v)
Definition: matrix1d.h:85
int lastStep
Last step to run (-1=run them all)
void reject_outliers(T &v, double percentil_out=0.25)
Definition: histogram.h:605
Matrix1D< double > avgBackwardPatchCorr
#define XSIZE(v)
void progress_bar(long rlen)
double thresholdAffine
Threshold affine.
#define ABS(x)
Definition: xmipp_macros.h:142
File or directory does not exist.
Definition: xmipp_error.h:136
#define ROUND(x)
Definition: xmipp_macros.h:210
FileName fnSelOrig
MetaData File with all images at the original scale.
bool doNotIdentifyOutliers
Do not identify outlier micrographs.
double computeAffineTransformation(const MultidimArray< unsigned char > &I1, const MultidimArray< unsigned char > &I2, int maxShift, int maxIterDE, Matrix2D< double > &A12, Matrix2D< double > &A21, bool show, double thresholdAffine, bool globalAffine, bool isMirror, bool checkRotation, int pyramidLevel)
bool exists() const
void initZeros()
Definition: matrix1d.h:592
std::vector< MultidimArray< unsigned char > * > img
bool useCriticalPoints
Use critical points.
#define j
#define YY(v)
Definition: matrix1d.h:93
bool getValue(MDObject &mdValueOut, size_t id) const override
std::vector< std::vector< Matrix2D< double > > > affineTransformations
double localSize
Local refinement size.
TYPE distance(struct Point_T *p, struct Point_T *q)
Definition: point.cpp:28
#define FINISHINGY(v)
#define FOR_ALL_ELEMENTS_IN_ARRAY1D(v)
Value has not been set.
Definition: xmipp_error.h:196
virtual void removeDisabled()
void typeCast(const Matrix1D< T1 > &v1, Matrix1D< T2 > &v2)
Definition: matrix1d.h:1227
std::string String
Definition: xmipp_strings.h:34
void substractBackgroundRollingBall(MultidimArray< double > &I, int radius)
Definition: filters.cpp:75
void identifyOutliers(bool mark)
Identify outliers.
void writeTransformations(const FileName &fnTransformations) const
Write affine transformations.
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
void initZeros(const MultidimArray< T1 > &op)
double computeAvg() const
bool containsLabel(const MDLabel label) const override
bool showAffine
Show affine transformations.
void generateMask(MultidimArray< double > &v)
void initConstant(T val)
Definition: matrix1d.cpp:83
void substractBackgroundPlane(MultidimArray< double > &I)
Definition: filters.cpp:40
int * n
Name of an image (std::string)
std::vector< double > correlationList
void applyMaskSpace(MultidimArray< double > &v)

◆ readLandmarkSet()

void ProgTomographAlignment::readLandmarkSet ( const FileName fnLandmark)

Read landmark set.

Definition at line 2170 of file tomo_align_tilt_series.cpp.

2171 {
2172  std::ifstream fhIn;
2173  fhIn.open(fnLandmark.c_str());
2174  if (!fhIn)
2175  REPORT_ERROR(ERR_IO_NOTEXIST,(std::string)"Cannot open "+fnLandmark+" for input");
2176  std::string dummyStr;
2177  int Nlandmark;
2178  fhIn >> dummyStr >> dummyStr >> dummyStr >> dummyStr >> dummyStr
2179  >> Nlandmark >> Nimg;
2180  if (Nlandmark<=0)
2181  REPORT_ERROR(ERR_VALUE_INCORRECT,(std::string)"No landmarks are found in "+fnLandmark);
2182  allLandmarksX.resize(Nlandmark,Nimg);
2183  allLandmarksY.resize(Nlandmark,Nimg);
2186  fhIn.exceptions ( std::ifstream::eofbit |
2187  std::ifstream::failbit |
2188  std::ifstream::badbit );
2189  while (!fhIn.eof())
2190  {
2191  try
2192  {
2193  int dummyInt, x, y, i, j;
2194  fhIn >> dummyInt >> x >> y >> i >> j;
2195  i=i-1;
2196  allLandmarksX(j,i)=x+STARTINGX(*img[0]);
2197  allLandmarksY(j,i)=y+STARTINGY(*img[0]);
2198  }
2199  catch (std::ifstream::failure e)
2200  {
2201  // Do nothing with this line
2202  }
2203  }
2204  fhIn.close();
2205  std::cout << "The file " << fnLandmark << " has been read for the landmarks\n"
2206  << Nlandmark << " landmarks are read\n";
2207 }
Matrix2D< double > allLandmarksY
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void initConstant(T val)
Definition: matrix2d.h:602
static double * y
Matrix2D< double > allLandmarksX
#define STARTINGX(v)
doublereal * x
#define i
#define STARTINGY(v)
#define XSIZE(v)
File or directory does not exist.
Definition: xmipp_error.h:136
std::vector< MultidimArray< unsigned char > * > img
#define j
Incorrect value received.
Definition: xmipp_error.h:195
void resize(size_t Ydim, size_t Xdim, bool noCopy=false)
Definition: matrix2d.cpp:1022

◆ readParams()

void ProgTomographAlignment::readParams ( )
virtual

Read parameters from argument line.

Reimplemented from XmippProgram.

Definition at line 452 of file tomo_align_tilt_series.cpp.

453 {
454  fnSel=getParam("-i");
455  fnSelOrig=getParam("--iorig");
456  fnRoot=getParam("--oroot");
457  if (fnRoot=="")
459  globalAffine=checkParam("--globalAffine");
460  useCriticalPoints=checkParam("--useCriticalPoints");
461  if (useCriticalPoints)
462  Ncritical=getIntParam("--useCriticalPoints");
463  else
464  Ncritical=0;
465  seqLength=getIntParam("--seqLength");
466  blindSeqLength=getIntParam("--blindSeqLength");
467  maxStep=getIntParam("--maxStep");
468  gridSamples=getIntParam("--gridSamples");
469  psiMax=getDoubleParam("--psiMax");
470  deltaRot=getDoubleParam("--deltaRot");
471  localSize=getDoubleParam("--localSize");
472  optimizeTiltAngle=checkParam("--optimizeTiltAngle");
473  isCapillar=checkParam("--isCapillar");
474  dontNormalize=checkParam("--dontNormalize");
475  difficult=checkParam("--difficult");
476  corrThreshold=getDoubleParam("--threshold");
477  maxShiftPercentage=getDoubleParam("--maxShiftPercentage");
478  maxIterDE=getIntParam("--maxIterDE");
479  showAffine=checkParam("--showAffine");
480  thresholdAffine=getDoubleParam("--thresholdAffine");
481  identifyOutliersZ = getDoubleParam("--identifyOutliers");
482  doNotIdentifyOutliers = checkParam("--noOutliers");
483  pyramidLevel = getIntParam("--pyramid");
484  numThreads = getIntParam("--thr");
485  if (numThreads<1)
486  numThreads = 1;
487  lastStep=getIntParam("--lastStep");
488 }
bool globalAffine
Look for local affine transformation.
double maxShiftPercentage
Maxshift percentage.
double getDoubleParam(const char *param, int arg=0)
size_t seqLength
Sequence Length.
double corrThreshold
Correlation threshold for a good landmark.
FileName fnSel
MetaData File with all images.
int maxIterDE
Maximum number of iterations in Differential Evolution.
int maxStep
Maximum Step for chain refinement.
FileName fnRoot
Output root.
size_t Ncritical
Number of critical points.
const char * getParam(const char *param, int arg=0)
int lastStep
Last step to run (-1=run them all)
int numThreads
Number of threads to use for parallel computing.
double thresholdAffine
Threshold affine.
FileName fnSelOrig
MetaData File with all images at the original scale.
bool doNotIdentifyOutliers
Do not identify outlier micrographs.
double identifyOutliersZ
Identify outlier micrographs.
bool useCriticalPoints
Use critical points.
double localSize
Local refinement size.
FileName withoutExtension() const
bool isCapillar
This tilt series comes from a capillar.
bool checkParam(const char *param)
double psiMax
Maximum rotation.
bool optimizeTiltAngle
Optimize tilt angle of tilt axis.
bool showAffine
Show affine transformations.
int getIntParam(const char *param, int arg=0)
bool dontNormalize
Don&#39;t normalize the corrected images.

◆ refineChain()

bool ProgTomographAlignment::refineChain ( LandmarkChain chain,
double &  corrChain 
)

Refine chain.

Definition at line 1997 of file tomo_align_tilt_series.cpp.

1999 {
2000 #ifdef DEBUG
2001  std::cout << "Chain for refinement: ";
2002  for (int i=0; i<chain.size(); i++)
2003  std::cout << chain[i].imgIdx << " ";
2004  std::cout << std::endl;
2005 #endif
2006 
2007  for (int K=0; K<2 && (chain.size()>seqLength || useCriticalPoints); K++)
2008  {
2009  sort(chain.begin(), chain.end());
2010  Matrix1D<double> rii(2), rjj(2), newrjj(2);
2011 
2012  if (useCriticalPoints)
2013  {
2014  // compute average piece
2015  int halfSize=XMIPP_MAX(ROUND(localSize*XSIZE(*img[0]))/2,5);
2016  int chainLength=chain.size();
2017  MultidimArray<double> avgPiece(2*halfSize+1,2*halfSize+1), pieceAux;
2018  avgPiece.setXmippOrigin();
2019  pieceAux=avgPiece;
2020  for (int n=0; n<chainLength; n++)
2021  {
2022  int ii=chain[n].imgIdx;
2023  VECTOR_R2(rii,chain[n].x,chain[n].y);
2024  if (XX(rii)-halfSize<STARTINGX(*img[ii]) ||
2025  XX(rii)+halfSize>FINISHINGX(*img[ii]) ||
2026  YY(rii)-halfSize<STARTINGY(*img[ii]) ||
2027  YY(rii)+halfSize>FINISHINGY(*img[ii]))
2028  {
2029  corrChain=0;
2030  return false;
2031  }
2032  FOR_ALL_ELEMENTS_IN_ARRAY2D(avgPiece)
2033  pieceAux(i,j)=(*img[ii])((int)(YY(rii)+i),(int)(XX(rii)+j));
2034  if (isCapillar && ABS(chain[n].imgIdx-chain[0].imgIdx)>Nimg/2)
2035  pieceAux.selfReverseY();
2036  avgPiece+=pieceAux;
2037  }
2038  avgPiece/=chainLength;
2039 #ifdef DEBUG
2040 
2041  Image<double> save;
2042  save()=avgPiece;
2043  save.write("PPPavg.xmp");
2044  std::cout << "Average " << K << " ------------------- \n";
2045  showRefinement=true;
2046 #endif
2047 
2048  // Align all images with respect to this average
2049  corrChain=2;
2050  for (int j=0; j<chainLength; j++)
2051  {
2052  int jj=chain[j].imgIdx;
2053  VECTOR_R2(rjj,chain[j].x,chain[j].y);
2054  double corr;
2055  bool accepted=refineLandmark(avgPiece,jj,rjj,0,false,corr);
2056  if (accepted)
2057  {
2058  chain[j].x=XX(rjj);
2059  chain[j].y=YY(rjj);
2060  corrChain=XMIPP_MIN(corrChain,corr);
2061  }
2062  }
2063 
2064 #ifdef DEBUG
2065  showRefinement=false;
2066 #endif
2067 
2068  }
2069  else
2070  {
2071  // Refine every step
2072  for (int step=2; step<=maxStep; step++)
2073  {
2074  int chainLength=chain.size();
2075 
2076  // Refine forwards every step
2077  int ileft=-1;
2078  for (int i=0; i<chainLength-step; i++)
2079  {
2080  int ii=chain[i].imgIdx;
2081  VECTOR_R2(rii,chain[i].x,chain[i].y);
2082  int jj=chain[i+step].imgIdx;
2083  VECTOR_R2(rjj,chain[i+step].x,chain[i+step].y);
2084  newrjj=rjj;
2085  double corr;
2086  bool accepted=refineLandmark(ii,jj,rii,newrjj,corr,false);
2087  if (((newrjj-rjj).module()<4 && accepted) || useCriticalPoints)
2088  {
2089  chain[i+step].x=XX(newrjj);
2090  chain[i+step].y=YY(newrjj);
2091  }
2092  else
2093  ileft=i;
2094  }
2095 
2096 #ifdef DEBUG
2097  // COSS showRefinement=(step==maxStep);
2098 #endif
2099  // Refine backwards all images
2100  int iright=chainLength;
2101  corrChain=2;
2102  for (int i=chainLength-1; i>=1; i--)
2103  {
2104  int ii=chain[i].imgIdx;
2105  VECTOR_R2(rii,chain[i].x,chain[i].y);
2106  int jj=chain[i-1].imgIdx;
2107  VECTOR_R2(rjj,chain[i-1].x,chain[i-1].y);
2108  newrjj=rjj;
2109  double corr;
2110  bool accepted=refineLandmark(ii,jj,rii,newrjj,corr,false);
2111  corrChain=XMIPP_MIN(corrChain,corr);
2112  if (((newrjj-rjj).module()<4 && accepted) || useCriticalPoints)
2113  {
2114  chain[i-1].x=XX(newrjj);
2115  chain[i-1].y=YY(newrjj);
2116  }
2117  else
2118  iright=i;
2119  }
2120 #ifdef DEBUG
2121  // COSS: showRefinement=false;
2122 #endif
2123 
2124  LandmarkChain refinedChain;
2125  for (int ll=ileft+1; ll<=iright-1; ll++)
2126  refinedChain.push_back(chain[ll]);
2127  chain=refinedChain;
2128  double tilt0=tiltList[chain[0].imgIdx];
2129  double tiltF=tiltList[chain[chain.size()-1].imgIdx];
2130  double lengthThreshold=XMIPP_MAX(3.,FLOOR(seqLength*cos(DEG2RAD(0.5*(tilt0+tiltF)))));
2131  if (chain.size()<lengthThreshold && !useCriticalPoints)
2132  return false;
2133  }
2134  }
2135  }
2136 
2137  // Check that the chain is of the desired length
2138  double tilt0=tiltList[chain[0].imgIdx];
2139  double tiltF=tiltList[chain[chain.size()-1].imgIdx];
2140  double lengthThreshold=XMIPP_MAX(3,FLOOR(seqLength*cos(DEG2RAD(0.5*(tilt0+tiltF)))));
2141  return chain.size()>lengthThreshold;
2142 }
#define VECTOR_R2(v, x, y)
Definition: matrix1d.h:112
bool refineLandmark(int ii, int jj, const Matrix1D< double > &rii, Matrix1D< double > &rjj, double &maxCorr, bool tryFourier) const
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
std::vector< double > tiltList
#define FINISHINGX(v)
size_t seqLength
Sequence Length.
#define DEG2RAD(d)
Definition: xmipp_macros.h:312
static double * y
void write(const FileName &name="", size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE, CastWriteMode castMode=CW_CAST, int _swapWrite=0)
int maxStep
Maximum Step for chain refinement.
#define STARTINGX(v)
doublereal * x
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
#define STARTINGY(v)
#define FLOOR(x)
Definition: xmipp_macros.h:240
#define XX(v)
Definition: matrix1d.h:85
std::vector< Landmark > LandmarkChain
#define XSIZE(v)
#define ABS(x)
Definition: xmipp_macros.h:142
#define ROUND(x)
Definition: xmipp_macros.h:210
void sort(struct DCEL_T *dcel)
Definition: sorting.cpp:18
std::vector< MultidimArray< unsigned char > * > img
bool useCriticalPoints
Use critical points.
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
#define j
#define YY(v)
Definition: matrix1d.h:93
double localSize
Local refinement size.
#define FINISHINGY(v)
bool isCapillar
This tilt series comes from a capillar.
constexpr int K
int * n

◆ refineLandmark() [1/2]

bool ProgTomographAlignment::refineLandmark ( int  ii,
int  jj,
const Matrix1D< double > &  rii,
Matrix1D< double > &  rjj,
double &  maxCorr,
bool  tryFourier 
) const

Refine landmark. ii is the index of the original image, jj is the index in the image at which the landmark is being refined. rii and rjj are the corresponding landmark positions in both images.

The function returns whether the landmark is accepted or not.

Definition at line 1735 of file tomo_align_tilt_series.cpp.

1738 {
1739  maxCorr=-1;
1740  int halfSize=XMIPP_MAX(ROUND(localSize*XSIZE(*img[ii]))/2,5);
1741  if (XX(rii)-halfSize<STARTINGX(*img[ii]) ||
1742  XX(rii)+halfSize>FINISHINGX(*img[ii]) ||
1743  YY(rii)-halfSize<STARTINGY(*img[ii]) ||
1744  YY(rii)+halfSize>FINISHINGY(*img[ii]) ||
1745  XX(rjj)-halfSize<STARTINGX(*img[jj]) ||
1746  XX(rjj)+halfSize>FINISHINGX(*img[jj]) ||
1747  YY(rjj)-halfSize<STARTINGY(*img[jj]) ||
1748  YY(rjj)+halfSize>FINISHINGY(*img[jj]))
1749  return 0;
1750 
1751  // Check if the two pieces are reversed
1752  bool reversed=isCapillar && ABS(ii-jj)>Nimg/2;
1753 
1754  // Select piece in image ii, compute its statistics and normalize
1755  MultidimArray<double> pieceii(2*halfSize+1,2*halfSize+1);
1756  pieceii.setXmippOrigin();
1757  const MultidimArray<unsigned char> &Iii=(*img[ii]);
1759  A2D_ELEM(pieceii,i,j)=A2D_ELEM(Iii,
1760  (int)(YY(rii)+i),(int)(XX(rii)+j));
1761  if (showRefinement)
1762  {
1763  Image<double> save;
1764  save()=pieceii;
1765  save.write("PPPpieceii.xmp");
1766  std::cout << "ii=" << ii << " jj=" << jj << std::endl;
1767  std::cout << "rii=" << rii.transpose() << std::endl;
1768  }
1769 
1770  // Choose threshold
1771  double actualCorrThreshold=corrThreshold;
1772  if (actualCorrThreshold<0 && VEC_XSIZE(avgForwardPatchCorr)>0)
1773  {
1774  if (ii<jj)
1775  actualCorrThreshold=XMIPP_MIN(avgForwardPatchCorr(ii),
1776  avgBackwardPatchCorr(jj));
1777  else
1778  actualCorrThreshold=XMIPP_MIN(avgBackwardPatchCorr(ii),
1779  avgForwardPatchCorr(jj));
1780  }
1781  if (showRefinement)
1782  std::cout << "actualCorrThreshold=" << actualCorrThreshold << std::endl;
1783 
1784  // Try Fourier
1785  if (tryFourier)
1786  {
1787  const MultidimArray<unsigned char> &Ijj=(*img[jj]);
1788  if (XX(rjj)-halfSize>=STARTINGX(Ijj) &&
1789  XX(rjj)+halfSize<=FINISHINGX(Ijj) &&
1790  YY(rjj)-halfSize>=STARTINGY(Ijj) &&
1791  YY(rjj)+halfSize<=FINISHINGY(Ijj))
1792  {
1793  // Take the piece at jj
1794  MultidimArray<double> piecejj(2*halfSize+1,2*halfSize+1);
1795  piecejj.setXmippOrigin();
1797  A2D_ELEM(piecejj,i,j)=A2D_ELEM(Ijj,
1798  (int)(YY(rjj)+i),(int)(XX(rjj)+j));
1799 
1800  // Compute its correlation with pieceii
1801  double corrOriginal=correlationIndex(pieceii,piecejj);
1802  if (showRefinement)
1803  {
1804  Image<double> save;
1805  save()=piecejj;
1806  save.write("PPPpiecejjOriginal.xmp");
1807  std::cout << "Corr original=" << corrOriginal << std::endl;
1808  }
1809 
1810  // Now try with the best shift
1811  double shiftX,shiftY;
1812  CorrelationAux aux;
1813  bestNonwrappingShift(pieceii,piecejj,shiftX,shiftY,aux);
1814  Matrix1D<double> fftShift(2);
1815  VECTOR_R2(fftShift,shiftX,shiftY);
1816  selfTranslate(xmipp_transformation::LINEAR,piecejj,fftShift,xmipp_transformation::WRAP);
1817  double corrFFT=correlationIndex(pieceii,piecejj);
1818  if (corrFFT>corrOriginal)
1819  {
1820  XX(rjj)-=shiftX;
1821  YY(rjj)-=shiftY;
1822  }
1823 
1824  if (showRefinement)
1825  {
1826  Image<double> save;
1827  save()=piecejj;
1828  save.write("PPPpiecejjFFT.xmp");
1829  std::cout << "FFT shift=" << fftShift.transpose() << std::endl;
1830  std::cout << "Corr FFT=" << corrFFT << std::endl;
1831  if (corrFFT>corrOriginal)
1832  {
1833  if (XX(rjj)-halfSize>=STARTINGX(Ijj) &&
1834  XX(rjj)+halfSize<=FINISHINGX(Ijj) &&
1835  YY(rjj)-halfSize>=STARTINGY(Ijj) &&
1836  YY(rjj)+halfSize<=FINISHINGY(Ijj))
1837  {
1839  A2D_ELEM(piecejj,i,j)=A2D_ELEM(Ijj,
1840  (int)(YY(rjj)+i),(int)(XX(rjj)+j));
1841  save()=piecejj;
1842  save.write("PPPpiecejjNew.xmp");
1843  }
1844  }
1845  }
1846  }
1847  }
1848 
1849  bool retval=refineLandmark(pieceii,jj,rjj,actualCorrThreshold,
1850  reversed,maxCorr);
1851  return retval;
1852 }
#define VECTOR_R2(v, x, y)
Definition: matrix1d.h:112
bool refineLandmark(int ii, int jj, const Matrix1D< double > &rii, Matrix1D< double > &rjj, double &maxCorr, bool tryFourier) const
#define A2D_ELEM(v, i, j)
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
#define FINISHINGX(v)
#define VEC_XSIZE(m)
Definition: matrix1d.h:77
double corrThreshold
Correlation threshold for a good landmark.
void write(const FileName &name="", size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE, CastWriteMode castMode=CW_CAST, int _swapWrite=0)
double correlationIndex(const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > *mask=NULL, MultidimArray< double > *Contributions=NULL)
#define STARTINGX(v)
void bestNonwrappingShift(const MultidimArray< double > &I1, const MultidimArray< double > &I2, double &shiftX, double &shiftY, CorrelationAux &aux)
Definition: filters.cpp:1895
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
Matrix1D< T > transpose() const
Definition: matrix1d.cpp:644
#define STARTINGY(v)
Matrix1D< double > avgForwardPatchCorr
#define XX(v)
Definition: matrix1d.h:85
void selfTranslate(int SplineDegree, MultidimArray< T > &V1, const Matrix1D< double > &v, bool wrap=xmipp_transformation::WRAP, T outside=0)
Matrix1D< double > avgBackwardPatchCorr
#define XSIZE(v)
#define ABS(x)
Definition: xmipp_macros.h:142
#define ROUND(x)
Definition: xmipp_macros.h:210
std::vector< MultidimArray< unsigned char > * > img
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
#define j
#define YY(v)
Definition: matrix1d.h:93
double localSize
Local refinement size.
#define FINISHINGY(v)
bool isCapillar
This tilt series comes from a capillar.

◆ refineLandmark() [2/2]

bool ProgTomographAlignment::refineLandmark ( const MultidimArray< double > &  pieceii,
int  jj,
Matrix1D< double > &  rjj,
double  actualCorrThreshold,
bool  reversed,
double &  maxCorr 
) const

Refine landmark. The same as the previous function but an image is provided as pattern (ii) instead of an index and a position.

Definition at line 1854 of file tomo_align_tilt_series.cpp.

1857 {
1858  int halfSize=XSIZE(pieceii)/2;
1859 
1860  double mean_ii=0, stddev_ii=0;
1862  {
1863  mean_ii+=A2D_ELEM(pieceii,i,j);
1864  stddev_ii+=A2D_ELEM(pieceii,i,j)*A2D_ELEM(pieceii,i,j);
1865  }
1866  mean_ii/=MULTIDIM_SIZE(pieceii);
1867  stddev_ii = stddev_ii / MULTIDIM_SIZE(pieceii) - mean_ii * mean_ii;
1868  stddev_ii *= MULTIDIM_SIZE(pieceii) / (MULTIDIM_SIZE(pieceii) - 1);
1869  stddev_ii = sqrt(static_cast<double>((ABS(stddev_ii))));
1870  if (stddev_ii>XMIPP_EQUAL_ACCURACY)
1872  DIRECT_MULTIDIM_ELEM(pieceii,n)=
1873  (DIRECT_MULTIDIM_ELEM(pieceii,n)-mean_ii)/stddev_ii;
1874 
1875  // Try all possible shifts
1876  MultidimArray<double> corr((int)(1.5*(2*halfSize+1)),(int)(1.5*(2*halfSize+1)));
1877  corr.setXmippOrigin();
1878  corr.initConstant(-1.1);
1879  bool accept=false;
1880  double maxval=-1;
1881  MultidimArray<double> piecejj(2*halfSize+1,2*halfSize+1);
1882  piecejj.setXmippOrigin();
1883  if (stddev_ii>XMIPP_EQUAL_ACCURACY)
1884  {
1885  int imax=0, jmax=0;
1886  std::queue< Matrix1D<double> > Q;
1887  Q.push(vectorR2(0,0));
1888  while (!Q.empty())
1889  {
1890  // Get the first position to evaluate
1891  auto shifty=(int)YY(Q.front());
1892  auto shiftx=(int)XX(Q.front());
1893  Q.pop();
1894  if (!corr(shifty,shiftx)<-1)
1895  continue;
1896 
1897  // Select piece in image jj, compute its statistics and normalize
1898  double mean_jj=0, stddev_jj=0;
1899  const MultidimArray<unsigned char> &Ijj=(*img[jj]);
1900  if (XX(rjj)+shiftx+STARTINGX(piecejj)<STARTINGX(Ijj) ||
1901  YY(rjj)+shifty+STARTINGY(piecejj)<STARTINGY(Ijj) ||
1902  XX(rjj)+shiftx+FINISHINGX(piecejj)>FINISHINGX(Ijj) ||
1903  YY(rjj)+shifty+FINISHINGY(piecejj)>FINISHINGY(Ijj))
1904  continue;
1906  {
1907  double pixval=A2D_ELEM(Ijj,
1908  (int)(YY(rjj)+shifty+i),
1909  (int)(XX(rjj)+shiftx+j));
1910  A2D_ELEM(piecejj,i,j)=pixval;
1911  mean_jj+=pixval;
1912  stddev_jj+=pixval*pixval;
1913  }
1914  mean_jj/=MULTIDIM_SIZE(piecejj);
1915  stddev_jj = stddev_jj / MULTIDIM_SIZE(piecejj) - mean_jj * mean_jj;
1916  stddev_jj *= MULTIDIM_SIZE(piecejj) / (MULTIDIM_SIZE(piecejj) - 1);
1917  stddev_jj = sqrt(static_cast<double>((ABS(stddev_jj))));
1918  if (reversed)
1919  piecejj.selfReverseY();
1920 
1921  // Compute the correlation
1922  corr(shifty,shiftx)=0;
1923  double &corrRef=corr(shifty,shiftx);
1924  if (stddev_jj>XMIPP_EQUAL_ACCURACY)
1925  {
1926  double istddev_jj=1.0/stddev_jj;
1928  corrRef+=
1929  DIRECT_MULTIDIM_ELEM(pieceii,n)*
1930  (DIRECT_MULTIDIM_ELEM(piecejj,n)-mean_jj)*istddev_jj;
1931  corrRef/=MULTIDIM_SIZE(piecejj);
1932  }
1933 
1934  if (corrRef>maxval)
1935  {
1936  maxval=corrRef;
1937  imax=shifty;
1938  jmax=shiftx;
1939  for (int step=1; step<=5; step+=2)
1940  for (int stepy=-1; stepy<=1; stepy++)
1941  for (int stepx=-1; stepx<=1; stepx++)
1942  {
1943  int newshifty=shifty+stepy*step;
1944  int newshiftx=shiftx+stepx*step;
1945  if (newshifty>=STARTINGY(corr) &&
1946  newshifty<=FINISHINGY(corr) &&
1947  newshiftx>=STARTINGX(corr) &&
1948  newshiftx<=FINISHINGX(corr) &&
1949  (XX(rjj)+newshiftx-halfSize)>=STARTINGX(Ijj) &&
1950  (XX(rjj)+newshiftx+halfSize)<=FINISHINGX(Ijj) &&
1951  (YY(rjj)+newshifty-halfSize)>=STARTINGY(Ijj) &&
1952  (YY(rjj)+newshifty+halfSize)<=FINISHINGY(Ijj))
1953  if (corr(newshifty,newshiftx)<-1)
1954  Q.push(vectorR2(newshiftx,newshifty));
1955  }
1956  }
1957  }
1958 
1959  if (maxval>actualCorrThreshold)
1960  {
1961  XX(rjj)+=jmax;
1962  if (reversed)
1963  YY(rjj)-=imax;
1964  else
1965  YY(rjj)+=imax;
1966  accept=true;
1967  }
1968  if (showRefinement)
1969  {
1970  Image<double> save;
1972  piecejj(i,j)=(*img[jj])((int)(YY(rjj)+i),(int)(XX(rjj)+j));
1973  if (reversed)
1974  piecejj.selfReverseY();
1975  save()=piecejj;
1976  save.write("PPPpiecejj.xmp");
1977  save()=corr;
1978  save.write("PPPcorr.xmp");
1979  std::cout << "jj=" << jj << " rjj=" << rjj.transpose() << std::endl;
1980  std::cout << "imax=" << imax << " jmax=" << jmax << std::endl;
1981  std::cout << "maxval=" << maxval << std::endl;
1982  }
1983  }
1984  if (showRefinement)
1985  {
1986  std::cout << "Accepted=" << accept << std::endl;
1987  std::cout << "Press any key\n";
1988  char c;
1989  std::cin >> c;
1990  }
1991  maxCorr=maxval;
1992  return accept;
1993 }
#define A2D_ELEM(v, i, j)
#define FINISHINGX(v)
doublereal * c
#define MULTIDIM_SIZE(v)
void sqrt(Image< double > &op)
void write(const FileName &name="", size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE, CastWriteMode castMode=CW_CAST, int _swapWrite=0)
#define STARTINGX(v)
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
Matrix1D< T > transpose() const
Definition: matrix1d.cpp:644
#define STARTINGY(v)
#define XX(v)
Definition: matrix1d.h:85
#define XMIPP_EQUAL_ACCURACY
Definition: xmipp_macros.h:119
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define ABS(x)
Definition: xmipp_macros.h:142
#define DIRECT_MULTIDIM_ELEM(v, n)
Matrix1D< double > vectorR2(double x, double y)
Definition: matrix1d.cpp:884
std::vector< MultidimArray< unsigned char > * > img
#define j
#define YY(v)
Definition: matrix1d.h:93
#define FINISHINGY(v)
int * n

◆ removeOutlierLandmarks()

void ProgTomographAlignment::removeOutlierLandmarks ( const Alignment alignment)

Remove Outliers.

Definition at line 2455 of file tomo_align_tilt_series.cpp.

2457 {
2458  std::cout << "Removing outliers ...\n";
2459 
2460  // Compute threshold for outliers
2461  Histogram1D hist;
2462  compute_hist(alignment.errorLandmark, hist, 100);
2463  // double threshold0=hist.percentil(10);
2464  double thresholdF=hist.percentil(90);
2465 
2466  // Identify outliers
2467  std::vector<bool> validLandmark;
2468  int invalidCounter=0;
2469  int Nlandmark=MAT_YSIZE(allLandmarksX);
2470  for (int j=0; j<Nlandmark; j++)
2471  if (//COSS alignment.errorLandmark(j)<threshold0 ||
2472  alignment.errorLandmark(j)>thresholdF)
2473  {
2474  validLandmark.push_back(false);
2475  invalidCounter++;
2476  }
2477  else
2478  validLandmark.push_back(true);
2479 
2480  // Remove outliers
2481  Matrix2D<double> newAllLandmarksX(Nlandmark-invalidCounter,Nimg);
2482  Matrix2D<double> newAllLandmarksY(Nlandmark-invalidCounter,Nimg);
2483  int jj=0;
2484  for (int j=0; j<Nlandmark; j++)
2485  {
2486  if (!validLandmark[j])
2487  continue;
2488  for (int i=0; i<Nimg; i++)
2489  {
2490  newAllLandmarksX(jj,i)=allLandmarksX(j,i);
2491  newAllLandmarksY(jj,i)=allLandmarksY(j,i);
2492  }
2493  jj++;
2494  }
2495  allLandmarksX=newAllLandmarksX;
2496  allLandmarksY=newAllLandmarksY;
2497 
2498  std::cout << invalidCounter << " out of " << Nlandmark
2499  << " landmarks have been removed\n";
2500 }
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
Matrix2D< double > allLandmarksY
MultidimArray< double > errorLandmark
double percentil(double percent_mass)
Definition: histogram.cpp:160
Matrix2D< double > allLandmarksX
#define i
void compute_hist(const MultidimArrayGeneric &array, Histogram1D &hist, int no_steps)
Definition: histogram.cpp:572
#define j

◆ run()

void ProgTomographAlignment::run ( )
virtual

Run: do the real work.

Reimplemented from XmippProgram.

Definition at line 2518 of file tomo_align_tilt_series.cpp.

2519 {
2520  produceSideInfo();
2521  std::cerr << "generateLandmarkSet"<< std::endl;
2523  std::cerr << "produceInformationFromLandmarks" << std::endl;
2525  std::cerr << "alignment" << std::endl;
2526  auto *alignment=new Alignment(this);
2527 
2528  // Exhaustive search for rot
2529  double bestError=0, bestRot=-1;
2530  for (double rot=0; rot<=180-deltaRot; rot+=deltaRot)
2531  {
2532  alignment->clear();
2533  alignment->rot=rot;
2534  double error=alignment->optimizeGivenAxisDirection();
2535 #ifdef DEBUG
2536 
2537  std::cout << "rot= " << rot
2538  << " error= " << error << std::endl;
2539 #endif
2540 
2541  if (bestRot<0 || bestError>error)
2542  {
2543  bestRot=rot;
2544  bestError=error;
2545  *bestPreviousAlignment=*alignment;
2546  }
2547  }
2548  delete alignment;
2549  std::cout << "Best rot=" << bestRot
2550  << " Best error=" << bestError << std::endl;
2551 
2552  // Continuous optimization for the axis direction
2553  Matrix1D<double> axisAngles(2), steps(2);
2554  axisAngles(0)=bestRot;
2555  axisAngles(1)=90;
2556  steps.initConstant(1);
2557  if (!optimizeTiltAngle)
2558  steps(1)=0;
2559  double fitness;
2560  int iter;
2562  powellOptimizer(axisAngles,1,2,&wrapperError, nullptr,
2563  0.01,fitness,iter,steps,true);
2564 
2565  // Outlier removal
2566  for (int i=0; i<3; i++)
2567  {
2568  // Compute the best alignment
2569  bestPreviousAlignment->rot=axisAngles(0);
2570  bestPreviousAlignment->tilt=axisAngles(1);
2573 
2574  // Remove landmarks that are outliers in the current model
2577  delete bestPreviousAlignment;
2578  bestPreviousAlignment=new Alignment(this);
2579  bestPreviousAlignment->rot=axisAngles(0);
2580  bestPreviousAlignment->tilt=axisAngles(1);
2582 
2583  // Optimize again
2584  powellOptimizer(axisAngles,1,2,&wrapperError,nullptr,
2585  0.01,fitness,iter,steps,true);
2586  }
2587  bestPreviousAlignment->rot=axisAngles(0);
2588  bestPreviousAlignment->tilt=axisAngles(1);
2590 
2591  // Save the alignment
2592  writeLandmarkSet(fnRoot+"_good_landmarks.txt");
2593  std::ofstream fh_out;
2594  fh_out.open((fnRoot+"_alignment.txt").c_str());
2595  if (!fh_out)
2597  (std::string)"Cannot open "+fnRoot+"_alignment.txt for output");
2598  fh_out << *bestPreviousAlignment;
2599  fh_out.close();
2600 
2601  // Correct the input images
2602  alignImages(*bestPreviousAlignment);
2603  writeLandmarkSet(fnRoot+"_good_landmarks_corrected.txt");
2604  delete bestPreviousAlignment;
2605 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Couldn&#39;t write to file.
Definition: xmipp_error.h:140
void powellOptimizer(Matrix1D< double > &p, int i0, int n, double(*f)(double *x, void *), void *prm, double ftol, double &fret, int &iter, const Matrix1D< double > &steps, bool show)
glob_prnt iter
FileName fnRoot
Output root.
#define i
void removeOutlierLandmarks(const Alignment &alignment)
Remove Outliers.
void generateLandmarkSet()
Generate landmark set using a grid.
void alignImages(const Alignment &alignment)
Align images.
double wrapperError(double *p, void *prm)
void produceSideInfo()
Produce side info.
const ProgTomographAlignment * global_prm
double steps
double optimizeGivenAxisDirection()
void error(char *s)
Definition: tools.cpp:107
void produceInformationFromLandmarks()
Produce information from landmarks.
void writeLandmarkSet(const FileName &fnLandmark) const
Write landmark set.
bool optimizeTiltAngle
Optimize tilt angle of tilt axis.
double fitness(double *p)

◆ show()

void ProgTomographAlignment::show ( )

Show parameters.

Definition at line 490 of file tomo_align_tilt_series.cpp.

491 {
492  std::cout << "Input images: " << fnSel << std::endl
493  << "Original images: " << fnSelOrig << std::endl
494  << "Output rootname: " << fnRoot << std::endl
495  << "Global affine: " << globalAffine << std::endl
496  << "Use critical points:" << useCriticalPoints << std::endl
497  << "Num critical points:" << Ncritical << std::endl
498  << "SeqLength: " << seqLength << std::endl
499  << "BlindSeqLength: " << blindSeqLength << std::endl
500  << "MaxStep: " << maxStep << std::endl
501  << "Grid samples: " << gridSamples << std::endl
502  << "Maximum psi: " << psiMax << std::endl
503  << "Delta rot: " << deltaRot << std::endl
504  << "Local size: " << localSize << std::endl
505  << "Optimize tilt angle:" << optimizeTiltAngle << std::endl
506  << "isCapillar: " << isCapillar << std::endl
507  << "DontNormalize: " << dontNormalize << std::endl
508  << "Difficult: " << difficult << std::endl
509  << "Threshold: " << corrThreshold << std::endl
510  << "MaxShift Percentage:" << maxShiftPercentage << std::endl
511  << "MaxIterDE: " << maxIterDE << std::endl
512  << "Show Affine: " << showAffine << std::endl
513  << "Threshold Affine: " << thresholdAffine << std::endl
514  << "Identify outliers Z:" << identifyOutliersZ << std::endl
515  << "No outliers: " << doNotIdentifyOutliers << std::endl
516  << "Pyramid level: " << pyramidLevel << std::endl
517  << "Threads to use: " << numThreads << std::endl
518  << "Last step: " << lastStep << std::endl
519  ;
520 }
bool globalAffine
Look for local affine transformation.
double maxShiftPercentage
Maxshift percentage.
size_t seqLength
Sequence Length.
double corrThreshold
Correlation threshold for a good landmark.
FileName fnSel
MetaData File with all images.
int maxIterDE
Maximum number of iterations in Differential Evolution.
int maxStep
Maximum Step for chain refinement.
FileName fnRoot
Output root.
size_t Ncritical
Number of critical points.
int lastStep
Last step to run (-1=run them all)
int numThreads
Number of threads to use for parallel computing.
double thresholdAffine
Threshold affine.
FileName fnSelOrig
MetaData File with all images at the original scale.
bool doNotIdentifyOutliers
Do not identify outlier micrographs.
double identifyOutliersZ
Identify outlier micrographs.
bool useCriticalPoints
Use critical points.
double localSize
Local refinement size.
bool isCapillar
This tilt series comes from a capillar.
double psiMax
Maximum rotation.
bool optimizeTiltAngle
Optimize tilt angle of tilt axis.
bool showAffine
Show affine transformations.
bool dontNormalize
Don&#39;t normalize the corrected images.

◆ writeLandmarkSet()

void ProgTomographAlignment::writeLandmarkSet ( const FileName fnLandmark) const

Write landmark set.

Definition at line 2146 of file tomo_align_tilt_series.cpp.

2147 {
2148  std::ofstream fhOut;
2149  fhOut.open(fnLandmark.c_str());
2150  if (!fhOut)
2151  REPORT_ERROR(ERR_IO_NOWRITE,(std::string)"Cannot open "+fnLandmark+" for output");
2152  fhOut << "Point x y slice color "
2153  << MAT_YSIZE(allLandmarksX) << " " << MAT_XSIZE(allLandmarksX) << std::endl;
2154  for (size_t i=0; i<MAT_XSIZE(allLandmarksX); i++)
2155  {
2156  int counter=0;
2157  for (size_t j=0; j<MAT_YSIZE(allLandmarksX); j++)
2158  if (allLandmarksX(j,i)!=XSIZE(*img[0]))
2159  {
2160  fhOut << counter << " \t"
2161  << ROUND(allLandmarksX(j,i)-STARTINGX(*img[0])) << " \t"
2162  << ROUND(allLandmarksY(j,i)-STARTINGY(*img[0])) << " \t"
2163  << i+1 << " \t" << j << std::endl;
2164  counter++;
2165  }
2166  }
2167  fhOut.close();
2168 }
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
Matrix2D< double > allLandmarksY
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Couldn&#39;t write to file.
Definition: xmipp_error.h:140
Matrix2D< double > allLandmarksX
#define STARTINGX(v)
#define i
#define STARTINGY(v)
#define XSIZE(v)
#define ROUND(x)
Definition: xmipp_macros.h:210
std::vector< MultidimArray< unsigned char > * > img
#define j
#define MAT_XSIZE(m)
Definition: matrix2d.h:120

◆ writeTransformations()

void ProgTomographAlignment::writeTransformations ( const FileName fnTransformations) const

Write affine transformations.

Definition at line 2210 of file tomo_align_tilt_series.cpp.

2212 {
2213  std::ofstream fhOut;
2214  fhOut.open(fnTransformations.c_str());
2215  if (!fhOut)
2216  REPORT_ERROR(ERR_IO_NOWRITE,(std::string)"Cannot open "+fnTransformations+" for output");
2217  int imax=affineTransformations.size();
2218  int counter=0;
2219  for (int i=0; i<imax; i++)
2220  {
2221  int jmax=affineTransformations[i].size();
2222  for (int j=i+1; j<jmax; j++)
2223  if (MAT_XSIZE(affineTransformations[i][j])!=0)
2224  {
2225  fhOut << tiltList[i] << "\t0.0\t"
2226  << affineTransformations[i][j](0,0) << "\t"
2227  << affineTransformations[i][j](1,0) << "\t"
2228  << affineTransformations[i][j](0,1) << "\t"
2229  << affineTransformations[i][j](1,1) << "\t"
2230  << affineTransformations[i][j](0,2) << "\t"
2231  << affineTransformations[i][j](1,2) << std::endl;
2232  counter++;
2233  }
2234  }
2235  if (counter==imax-1)
2236  {
2237  fhOut << tiltList[tiltList.size()-1] << "\t0.0\t1.0\t0.0\t0.0\t1.0\t0.0\t0.0\n";
2238  fhOut << "1 0 0 1 0 0\n";
2239  }
2240  fhOut.close();
2241 }
std::vector< double > tiltList
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Couldn&#39;t write to file.
Definition: xmipp_error.h:140
#define i
#define j
std::vector< std::vector< Matrix2D< double > > > affineTransformations
#define MAT_XSIZE(m)
Definition: matrix2d.h:120

Member Data Documentation

◆ affineTransformations

std::vector< std::vector< Matrix2D<double> > > ProgTomographAlignment::affineTransformations

Definition at line 265 of file tomo_align_tilt_series.h.

◆ allLandmarksX

Matrix2D<double> ProgTomographAlignment::allLandmarksX

Definition at line 271 of file tomo_align_tilt_series.h.

◆ allLandmarksY

Matrix2D<double> ProgTomographAlignment::allLandmarksY

Definition at line 274 of file tomo_align_tilt_series.h.

◆ avgBackwardPatchCorr

Matrix1D<double> ProgTomographAlignment::avgBackwardPatchCorr

Definition at line 255 of file tomo_align_tilt_series.h.

◆ avgForwardPatchCorr

Matrix1D<double> ProgTomographAlignment::avgForwardPatchCorr

Definition at line 252 of file tomo_align_tilt_series.h.

◆ barpi

std::vector< Matrix1D<double> > ProgTomographAlignment::barpi

Definition at line 283 of file tomo_align_tilt_series.h.

◆ bestPreviousAlignment

Alignment* ProgTomographAlignment::bestPreviousAlignment

Definition at line 289 of file tomo_align_tilt_series.h.

◆ blindSeqLength

size_t ProgTomographAlignment::blindSeqLength

Add blind landmarks. Set to -1 for no blind landmarks

Definition at line 105 of file tomo_align_tilt_series.h.

◆ correlationList

std::vector< double > ProgTomographAlignment::correlationList

Definition at line 268 of file tomo_align_tilt_series.h.

◆ corrThreshold

double ProgTomographAlignment::corrThreshold

Correlation threshold for a good landmark.

Definition at line 141 of file tomo_align_tilt_series.h.

◆ deltaRot

double ProgTomographAlignment::deltaRot

Delta rot.

Definition at line 123 of file tomo_align_tilt_series.h.

◆ difficult

bool ProgTomographAlignment::difficult

Difficult.

Definition at line 138 of file tomo_align_tilt_series.h.

◆ doNotIdentifyOutliers

bool ProgTomographAlignment::doNotIdentifyOutliers

Do not identify outlier micrographs.

Definition at line 153 of file tomo_align_tilt_series.h.

◆ dontNormalize

bool ProgTomographAlignment::dontNormalize

Don't normalize the corrected images.

Definition at line 135 of file tomo_align_tilt_series.h.

◆ fnRoot

FileName ProgTomographAlignment::fnRoot

Output root.

Definition at line 86 of file tomo_align_tilt_series.h.

◆ fnSel

FileName ProgTomographAlignment::fnSel

MetaData File with all images.

Definition at line 80 of file tomo_align_tilt_series.h.

◆ fnSelOrig

FileName ProgTomographAlignment::fnSelOrig

MetaData File with all images at the original scale.

Definition at line 83 of file tomo_align_tilt_series.h.

◆ globalAffine

bool ProgTomographAlignment::globalAffine

Look for local affine transformation.

Definition at line 92 of file tomo_align_tilt_series.h.

◆ gridSamples

int ProgTomographAlignment::gridSamples

Grid samples.

Definition at line 108 of file tomo_align_tilt_series.h.

◆ identifyOutliersZ

double ProgTomographAlignment::identifyOutliersZ

Identify outlier micrographs.

Definition at line 150 of file tomo_align_tilt_series.h.

◆ img

std::vector< MultidimArray<unsigned char> *> ProgTomographAlignment::img

Definition at line 237 of file tomo_align_tilt_series.h.

◆ iMinTilt

int ProgTomographAlignment::iMinTilt

Definition at line 243 of file tomo_align_tilt_series.h.

◆ isCapillar

bool ProgTomographAlignment::isCapillar

This tilt series comes from a capillar.

Definition at line 132 of file tomo_align_tilt_series.h.

◆ isOutlier

Matrix1D<int> ProgTomographAlignment::isOutlier

Definition at line 258 of file tomo_align_tilt_series.h.

◆ iteration

int ProgTomographAlignment::iteration

Definition at line 162 of file tomo_align_tilt_series.h.

◆ lastStep

int ProgTomographAlignment::lastStep

Last step to run (-1=run them all)

Definition at line 159 of file tomo_align_tilt_series.h.

◆ localSize

double ProgTomographAlignment::localSize

Local refinement size.

Definition at line 126 of file tomo_align_tilt_series.h.

◆ maskImg

std::vector< MultidimArray<unsigned char> *> ProgTomographAlignment::maskImg

Definition at line 240 of file tomo_align_tilt_series.h.

◆ maxIterDE

int ProgTomographAlignment::maxIterDE

Maximum number of iterations in Differential Evolution.

Definition at line 114 of file tomo_align_tilt_series.h.

◆ maxShiftPercentage

double ProgTomographAlignment::maxShiftPercentage

Maxshift percentage.

Definition at line 111 of file tomo_align_tilt_series.h.

◆ maxStep

int ProgTomographAlignment::maxStep

Maximum Step for chain refinement.

Definition at line 120 of file tomo_align_tilt_series.h.

◆ name_list

std::vector< std::string > ProgTomographAlignment::name_list

Definition at line 249 of file tomo_align_tilt_series.h.

◆ Ncritical

size_t ProgTomographAlignment::Ncritical

Number of critical points.

Definition at line 98 of file tomo_align_tilt_series.h.

◆ ni

Matrix1D<int> ProgTomographAlignment::ni

Definition at line 286 of file tomo_align_tilt_series.h.

◆ Nimg

int ProgTomographAlignment::Nimg

Definition at line 261 of file tomo_align_tilt_series.h.

◆ numThreads

int ProgTomographAlignment::numThreads

Number of threads to use for parallel computing.

Definition at line 89 of file tomo_align_tilt_series.h.

◆ optimizeTiltAngle

bool ProgTomographAlignment::optimizeTiltAngle

Optimize tilt angle of tilt axis.

Definition at line 129 of file tomo_align_tilt_series.h.

◆ psiMax

double ProgTomographAlignment::psiMax

Maximum rotation.

Definition at line 117 of file tomo_align_tilt_series.h.

◆ pyramidLevel

int ProgTomographAlignment::pyramidLevel

Pyramid.

Definition at line 156 of file tomo_align_tilt_series.h.

◆ seqLength

size_t ProgTomographAlignment::seqLength

Sequence Length.

Definition at line 101 of file tomo_align_tilt_series.h.

◆ SF

MetaDataVec ProgTomographAlignment::SF

Definition at line 231 of file tomo_align_tilt_series.h.

◆ SForig

MetaDataVec ProgTomographAlignment::SForig

Definition at line 234 of file tomo_align_tilt_series.h.

◆ showAffine

bool ProgTomographAlignment::showAffine

Show affine transformations.

Definition at line 144 of file tomo_align_tilt_series.h.

◆ showRefinement

bool ProgTomographAlignment::showRefinement

Definition at line 292 of file tomo_align_tilt_series.h.

◆ thresholdAffine

double ProgTomographAlignment::thresholdAffine

Threshold affine.

Definition at line 147 of file tomo_align_tilt_series.h.

◆ tiltList

std::vector< double > ProgTomographAlignment::tiltList

Definition at line 246 of file tomo_align_tilt_series.h.

◆ useCriticalPoints

bool ProgTomographAlignment::useCriticalPoints

Use critical points.

Definition at line 95 of file tomo_align_tilt_series.h.

◆ Vseti

std::vector< std::vector<int> > ProgTomographAlignment::Vseti

Definition at line 277 of file tomo_align_tilt_series.h.

◆ Vsetj

std::vector< std::vector<int> > ProgTomographAlignment::Vsetj

Definition at line 280 of file tomo_align_tilt_series.h.


The documentation for this class was generated from the following files: