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

#include <reconstruct_fourier.h>

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

Public Member Functions

void readParams ()
 Read arguments from command line. More...
 
void defineParams ()
 Read arguments from command line. More...
 
void show ()
 
void run ()
 
void produceSideinfo ()
 Produce side info: fill arrays with relevant transformation matrices. More...
 
void finishComputations (const FileName &out_name)
 
void processImages (int firstImageIndex, int lastImageIndex, bool saveFSC=false, bool reprocessFlag=false)
 Process one image. More...
 
void correctWeight ()
 Method for the correction of the fourier coefficients. More...
 
void forceWeightSymmetry (MultidimArray< double > &FourierWeights)
 Force the weights to be symmetrized. More...
 
virtual void setIO (const FileName &fn_in, const FileName &fn_out)
 Functions of common reconstruction interface. More...
 
- Public Member Functions inherited from ProgReconsBase
virtual ~ProgReconsBase ()
 
- 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 ()
 

Static Public Member Functions

static void * processImageThread (void *threadArgs)
 Defines what a thread should do. More...
 

Public Attributes

FileName fn_out
 
FileName fn_sym
 
FileName fn_sel
 
FileName fn_doc
 
FileName fn_fsc
 
MetaDataVec SF
 
bool do_weights
 
bool useCTF
 
bool phaseFlipped
 
double minCTF
 
double Ts
 
double padding_factor_proj
 
double padding_factor_vol
 
double sampling_rate
 
double maxResolution
 Max resolution in Angstroms. More...
 
int NiterWeight
 Number of iterations for the weight. More...
 
int numThreads
 Number of threads to use in parallel to process a single image. More...
 
pthread_t * th_ids
 IDs for the threads. More...
 
ImageThreadParamsth_args
 Contains parameters passed to each thread. More...
 
int threadOpCode
 Tells the threads what to do next. More...
 
size_t rowsProcessed
 Number of rows already processed on an image. More...
 
pthread_mutex_t workLoadMutex
 Controls mutual exclusion on critical zones of code. More...
 
barrier_t barrier
 To create a barrier synchronization for threads. More...
 
int * statusArray
 A status array for each row in an image (processing, processed,etc..) More...
 
int thrWidth
 How many image rows are processed at a time by a single thread. More...
 
int imgSize
 
int volPadSizeX
 
int volPadSizeY
 
int volPadSizeZ
 
Matrix1D< double > Fourier_blob_table
 
Matrix1D< double > blobTableSqrt
 
Matrix1D< double > fourierBlobTableSqrt
 
double iDeltaFourier
 
double iDeltaSqrt
 
double maxResolution2
 
struct blobtype blob
 
std::vector< Matrix2D< double > > R_repository
 
FourierTransformer transformerVol
 
FourierTransformer transformerImg
 
MultidimArray< std::complex< double > > VoutFourier
 
MultidimArray< std::complex< double > > VoutFourierTmp
 
MultidimArray< double > FourierWeights
 
MultidimArray< double > paddedImg
 
Image< double > Vout
 
- 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

Fourier reconstruction parameters.

Definition at line 76 of file reconstruct_fourier.h.

Member Function Documentation

◆ correctWeight()

void ProgRecFourier::correctWeight ( )

Method for the correction of the fourier coefficients.

Definition at line 1056 of file reconstruct_fourier.cpp.

1057 {
1058  // If NiterWeight=0 then set the weights to one
1060  if (NiterWeight==0)
1061  {
1064 
1065  }
1066  else
1067  {
1068  // Temporary save the Fourier of the volume
1070  VoutFourierTmp=VoutFourier;
1072  // Prepare the VoutFourier
1074  {
1075  auto *ptrOut=(double *)&(DIRECT_A3D_ELEM(VoutFourier, k,i,j));
1076  if (fabs(A3D_ELEM(FourierWeights,k,i,j))>1e-3)
1077  ptrOut[0] = 1.0/DIRECT_A3D_ELEM(FourierWeights, k,i,j);
1078  }
1079 
1080  for (int i=1;i<NiterWeight;i++)
1081  {
1084  processImages(0, SF.size() - 1, !fn_fsc.empty(), true);
1087  {
1088  auto *ptrOut=(double *)&(DIRECT_A3D_ELEM(VoutFourier, k,i,j));
1089  if (fabs(A3D_ELEM(FourierWeights,k,i,j))>1e-3)
1090  ptrOut[0] /= A3D_ELEM(FourierWeights,k,i,j);
1091  }
1092  }
1094  {
1095  // Put back the weights to FourierWeights from temporary variable VoutFourier
1096  auto *ptrOut=(double *)&(DIRECT_A3D_ELEM(VoutFourier, k,i,j));
1097  A3D_ELEM(FourierWeights,k,i,j) = ptrOut[0];
1098  }
1100  }
1101 }
int NiterWeight
Number of iterations for the weight.
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(V)
size_t size() const override
#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 A3D_ELEM(V, k, i, j)
MultidimArray< std::complex< double > > VoutFourier
void processImages(int firstImageIndex, int lastImageIndex, bool saveFSC=false, bool reprocessFlag=false)
Process one image.
#define DIRECT_A3D_ELEM(v, k, i, j)
#define j
MultidimArray< double > FourierWeights
MultidimArray< std::complex< double > > VoutFourierTmp
void forceWeightSymmetry(MultidimArray< double > &FourierWeights)
Force the weights to be symmetrized.

◆ defineParams()

void ProgRecFourier::defineParams ( )
virtual

Read arguments from command line.

Reimplemented from XmippProgram.

Definition at line 36 of file reconstruct_fourier.cpp.

37 {
38  //usage
39  addUsageLine("Generate 3D reconstructions from projections using direct Fourier interpolation with arbitrary geometry.");
40  addUsageLine("Kaisser-windows are used for interpolation in Fourier space.");
41  //params
42  addParamsLine(" -i <md_file> : Metadata file with input projections");
43  addParamsLine(" [-o <volume_file=\"rec_fourier.vol\">] : Filename for output volume");
44  addParamsLine(" [--iter <iterations=1>] : Number of iterations for weight correction");
45  addParamsLine(" [--sym <symfile=c1>] : Enforce symmetry in projections");
46  addParamsLine(" [--padding <proj=2.0> <vol=2.0>] : Padding used for projections and volume");
47  addParamsLine(" [--prepare_fsc <fscfile>] : Filename root for FSC files");
48  addParamsLine(" [--max_resolution <p=0.5>] : Max resolution (Nyquist=0.5)");
49  addParamsLine(" [--weight] : Use weights stored in the image metadata");
50  addParamsLine(" [--thr <threads=1> <rows=1>] : Number of concurrent threads and rows processed at time by a thread");
51  addParamsLine(" [--blob <radius=1.9> <order=0> <alpha=15>] : Blob parameters");
52  addParamsLine(" : radius in pixels, order of Bessel function in blob and parameter alpha");
53  addParamsLine(" [--useCTF] : Use CTF information if present");
54  addParamsLine(" [--sampling <Ts=1>] : sampling rate of the input images in Angstroms/pixel");
55  addParamsLine(" : It is only used when correcting for the CTF");
56  addParamsLine(" [--phaseFlipped] : Give this flag if images have been already phase flipped");
57  addParamsLine(" [--minCTF <ctf=0.01>] : Minimum value of the CTF that will be inverted");
58  addParamsLine(" : CTF values (in absolute value) below this one will not be corrected");
59  addExampleLine("For reconstruct enforcing i3 symmetry and using stored weights:", false);
60  addExampleLine(" xmipp_reconstruct_fourier -i reconstruction.sel --sym i3 --weight");
61 }
void addExampleLine(const char *example, bool verbatim=true)
void addUsageLine(const char *line, bool verbatim=false)
void addParamsLine(const String &line)

◆ finishComputations()

void ProgRecFourier::finishComputations ( const FileName out_name)

Definition at line 1103 of file reconstruct_fourier.cpp.

1104 {
1105  //#define DEBUG_VOL
1106 #ifdef DEBUG_VOL
1107  {
1108  VolumeXmipp save;
1109  save().alias( FourierWeights );
1110  save.write((std::string) fn_out + "Weights.vol");
1111 
1112  FourierVolume save2;
1113  save2().alias( VoutFourier );
1114  save2.write((std::string) fn_out + "FourierVol.vol");
1115  }
1116 #endif
1117 
1118  // Enforce symmetry in the Fourier values as well as the weights
1119  // Sjors 19aug10 enforceHermitianSymmetry first checks ndim...
1120  Vout().initZeros(volPadSizeZ,volPadSizeY,volPadSizeX);
1123  //forceWeightSymmetry(preFourierWeights);
1124 
1125  // Tell threads what to do
1126  //#define DEBUG_VOL1
1127 #ifdef DEBUG_VOL1
1128 
1129  {
1130  Image<double> save;
1131  save().alias( FourierWeights );
1132  save.write((std::string) fn_out + "hermiticWeights.vol");
1133 
1135  save2().alias( VoutFourier );
1136  save2.write((std::string) fn_out + "hermiticFourierVol.vol");
1137  }
1138 #endif
1140  // Awake threads
1141  barrier_wait( &barrier );
1142  // Threads are working now, wait for them to finish
1143  barrier_wait( &barrier );
1144 
1146  CenterFFT(Vout(),false);
1147 
1148  // Correct by the Fourier transform of the blob
1149  Vout().setXmippOrigin();
1153  double pad_relation= ((double)padding_factor_proj/padding_factor_vol);
1154  pad_relation = (pad_relation * pad_relation * pad_relation);
1155 
1156  MultidimArray<double> &mVout=Vout();
1157  double ipad_relation=1.0/pad_relation;
1158  double meanFactor2=0;
1160  {
1161  double radius=sqrt((double)(k*k+i*i+j*j));
1162  double aux=radius*iDeltaFourier;
1163  double factor = Fourier_blob_table(ROUND(aux));
1164  double factor2=(pow(Sinc(radius/(2*imgSize)),2));
1165  if (NiterWeight!=0)
1166  {
1167  A3D_ELEM(mVout,k,i,j) /= (ipad_relation*factor2*factor);
1168  meanFactor2+=factor2;
1169  }
1170  else
1171  A3D_ELEM(mVout,k,i,j) /= (ipad_relation*factor);
1172  }
1173  if (NiterWeight!=0)
1174  {
1175  meanFactor2/=MULTIDIM_SIZE(mVout);
1177  A3D_ELEM(mVout,k,i,j) *= meanFactor2;
1178  }
1179  Vout.write(out_name);
1180 }
int NiterWeight
Number of iterations for the weight.
void inverseFourierTransform()
Definition: xmipp_fftw.cpp:329
#define MULTIDIM_SIZE(v)
constexpr int PROCESS_WEIGHTS
void sqrt(Image< double > &op)
barrier_t barrier
To create a barrier synchronization for threads.
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 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
void CenterFFT(MultidimArray< T > &v, bool forward)
Definition: xmipp_fft.h:291
#define A3D_ELEM(V, k, i, j)
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
MultidimArray< std::complex< double > > VoutFourier
void setReal(MultidimArray< double > &img)
Definition: xmipp_fftw.cpp:129
#define ROUND(x)
Definition: xmipp_macros.h:210
Matrix1D< double > Fourier_blob_table
Image< double > Vout
#define j
double Sinc(double Argument)
MultidimArray< double > FourierWeights
#define FIRST_XMIPP_INDEX(size)
Definition: xmipp_macros.h:439
FourierTransformer transformerVol
int threadOpCode
Tells the threads what to do next.
#define LAST_XMIPP_INDEX(size)
Definition: xmipp_macros.h:448
int barrier_wait(barrier_t *barrier)
void enforceHermitianSymmetry()
Definition: xmipp_fftw.cpp:335

◆ forceWeightSymmetry()

void ProgRecFourier::forceWeightSymmetry ( MultidimArray< double > &  FourierWeights)

Force the weights to be symmetrized.

Definition at line 1188 of file reconstruct_fourier.cpp.

1189 {
1190  int yHalf=YSIZE(FourierWeights)/2;
1191  if (YSIZE(FourierWeights)%2==0)
1192  yHalf--;
1193  int zHalf=ZSIZE(FourierWeights)/2;
1194  if (ZSIZE(FourierWeights)%2==0)
1195  zHalf--;
1196  auto zsize=(int)ZSIZE(FourierWeights);
1197  int zsize_1=zsize-1;
1198  int ysize_1=(int)YSIZE(FourierWeights)-1;
1199  for (int k=0; k<zsize; k++)
1200  {
1201  int ksym=intWRAP(-k,0,zsize_1);
1202  for (int i=1; i<=yHalf; i++)
1203  {
1204  int isym=intWRAP(-i,0,ysize_1);
1205  double mean=0.5*(
1206  DIRECT_A3D_ELEM(FourierWeights,k,i,0)+
1207  DIRECT_A3D_ELEM(FourierWeights,ksym,isym,0));
1208  DIRECT_A3D_ELEM(FourierWeights,k,i,0)=
1209  DIRECT_A3D_ELEM(FourierWeights,ksym,isym,0)=mean;
1210  }
1211  }
1212  for (int k=1; k<=zHalf; k++)
1213  {
1214  int ksym=intWRAP(-k,0,zsize_1);
1215  double mean=0.5*(
1216  DIRECT_A3D_ELEM(FourierWeights,k,0,0)+
1217  DIRECT_A3D_ELEM(FourierWeights,ksym,0,0));
1218  DIRECT_A3D_ELEM(FourierWeights,k,0,0)=
1219  DIRECT_A3D_ELEM(FourierWeights,ksym,0,0)=mean;
1220  }
1221 }
#define YSIZE(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 ZSIZE(v)
#define DIRECT_A3D_ELEM(v, k, i, j)
#define intWRAP(x, x0, xF)
Definition: xmipp_macros.h:272

◆ processImages()

void ProgRecFourier::processImages ( int  firstImageIndex,
int  lastImageIndex,
bool  saveFSC = false,
bool  reprocessFlag = false 
)

Process one image.

Definition at line 835 of file reconstruct_fourier.cpp.

836 {
837  MultidimArray< std::complex<double> > *paddedFourier;
838 
839  auto repaint = (int)ceil((double)SF.size()/60);
840 
841  bool processed;
842  int imgno = 0;
843  int imgIndex = firstImageIndex;
844 
845  // This index tells when to save work for later FSC usage
846  int FSCIndex = (firstImageIndex + lastImageIndex)/2;
847 
848  // Index of the image that has just been processed. Used for
849  // FSC purposes
850  int current_index;
851 
852  do
853  {
855 
856  for ( int nt = 0 ; nt < numThreads ; nt ++ )
857  {
858  if ( imgIndex <= lastImageIndex )
859  {
860  th_args[nt].imageIndex = imgIndex;
861  th_args[nt].reprocessFlag = reprocessFlag;
862  imgIndex++;
863  }
864  else
865  {
866  th_args[nt].imageIndex = -1;
867  }
868  }
869 
870  // Awaking sleeping threads
871  barrier_wait( &barrier );
872  // here each thread is reading a different image and compute fft
873  // Threads are working now, wait for them to finish
874  // processing current projection
875  barrier_wait( &barrier );
876 
877  // each threads have read a different image and now
878  // all the thread will work in a different part of a single image.
880 
881  processed = false;
882 
883  for ( int nt = 0 ; nt < numThreads ; nt ++ )
884  {
885  if ( th_args[nt].read == 2 )
886  processed = true;
887  else if ( th_args[nt].read == 1 )
888  {
889  processed = true;
890  if (verbose) {
891  if (imgno % repaint == 0)
892  progress_bar(imgno);
893  imgno++;
894  }
895 
896  double weight = th_args[nt].localweight;
897  paddedFourier = th_args[nt].localPaddedFourier;
898  current_index = th_args[nt].imageIndex;
899  Matrix2D<double> *Ainv = th_args[nt].localAInv;
900 
901  //#define DEBUG22
902 #ifdef DEBUG22
903 
904  {
905  static int ii=0;
906  if(ii%1==0)
907  {
908  FourierImage save22;
909  //save22()=*paddedFourier;
910  save22().alias(*paddedFourier);
911  save22.write((std::string) integerToString(ii) + "_padded_fourier.spi");
912  }
913  ii++;
914  }
915 #endif
916  #undef DEBUG22
917 
918  // Initialized just once
919  if ( statusArray == nullptr )
920  {
921  statusArray = (int *) malloc ( sizeof(int) * paddedFourier->ydim );
922  }
923 
924  // Determine how many rows of the fourier
925  // transform are of interest for us. This is because
926  // the user can avoid to explore at certain resolutions
927  auto conserveRows=(size_t)ceil((double)paddedFourier->ydim * maxResolution * 2.0);
928  conserveRows=(size_t)ceil((double)conserveRows/2.0);
929 
930  // Loop over all symmetries
931  for (size_t isym = 0; isym < R_repository.size(); isym++)
932  {
933  rowsProcessed = 0;
934 
935  // Compute the coordinate axes of the symmetrized projection
936  Matrix2D<double> A_SL=R_repository[isym]*(*Ainv);
937 
938  // Fill the thread arguments for each thread
939  for ( int th = 0 ; th < numThreads ; th ++ )
940  {
941  // Passing parameters to each thread
942  th_args[th].symmetry = &A_SL;
943  th_args[th].paddedFourier = paddedFourier;
944  th_args[th].weight = weight;
945  th_args[th].reprocessFlag = reprocessFlag;
946  }
947 
948  // Init status array
949  for (size_t i = 0 ; i < paddedFourier->ydim ; i ++ )
950  {
951  if ( i >= conserveRows && i < (paddedFourier->ydim-conserveRows))
952  {
953  // -2 means "discarded"
954  statusArray[i] = -2;
955  rowsProcessed++;
956  }
957  else
958  {
959  statusArray[i] = 0;
960  }
961  }
962 
963  // Awaking sleeping threads
964  barrier_wait( &barrier );
965  // Threads are working now, wait for them to finish
966  // processing current projection
967  barrier_wait( &barrier );
968 
969  //#define DEBUG2
970 #ifdef DEBUG2
971 
972  {
973  static int ii=0;
974  if(ii%1==0)
975  {
976  Image<double> save;
977  save().alias( FourierWeights );
978  save.write((std::string) integerToString(ii) + "_1_Weights.vol");
979 
981  save2().alias( VoutFourier );
982  save2.write((std::string) integerToString(ii) + "_1_Fourier.vol");
983  }
984  ii++;
985  }
986 #endif
987  #undef DEBUG2
988 
989  }
990 
991  if ( current_index == FSCIndex && saveFSC )
992  {
993  // Save Current Fourier, Reconstruction and Weights
994  Image<double> save;
995  save().alias( FourierWeights );
996  save.write((std::string)fn_fsc + "_1_Weights.vol");
997 
999  save2().alias( VoutFourier );
1000  save2.write((std::string) fn_fsc + "_1_Fourier.vol");
1001 
1002  finishComputations(FileName((std::string) fn_fsc + "_1_recons.vol"));
1003  Vout().initZeros(volPadSizeZ, volPadSizeY, volPadSizeX);
1005  Vout().clear();
1009  }
1010  }
1011  }
1012  }
1013  while ( processed );
1014 
1015  if( saveFSC )
1016  {
1017  // Save Current Fourier, Reconstruction and Weights
1018  Image<double> auxVolume;
1019  auxVolume().alias( FourierWeights );
1020  auxVolume.write((std::string)fn_fsc + "_2_Weights.vol");
1021 
1022  Image< std::complex<double> > auxFourierVolume;
1023  auxFourierVolume().alias( VoutFourier );
1024  auxFourierVolume.write((std::string) fn_fsc + "_2_Fourier.vol");
1025 
1026  finishComputations(FileName((std::string) fn_fsc + "_2_recons.vol"));
1027 
1028  Vout().initZeros(volPadSizeZ, volPadSizeY, volPadSizeX);
1030  Vout().clear();
1034 
1035  auxVolume.sumWithFile(fn_fsc + "_1_Weights.vol");
1036  auxVolume.sumWithFile(fn_fsc + "_2_Weights.vol");
1037  auxFourierVolume.sumWithFile(fn_fsc + "_1_Fourier.vol");
1038  auxFourierVolume.sumWithFile(fn_fsc + "_2_Fourier.vol");
1039  remove((fn_fsc + "_1_Weights.vol").c_str());
1040  remove((fn_fsc + "_2_Weights.vol").c_str());
1041  remove((fn_fsc + "_1_Fourier.vol").c_str());
1042  remove((fn_fsc + "_2_Fourier.vol").c_str());
1043 
1044  /*
1045  //Save SUM
1046  //this is an image but not an xmipp image
1047  auxFourierVolume.write((std::string)fn_fsc + "_all_Fourier.vol",
1048  false,VDOUBLE);
1049  auxVolume.write((std::string)fn_fsc + "_all_Weight.vol",
1050  false,VDOUBLE);
1051  //
1052  */
1053  }
1054 }
double maxResolution
Max resolution in Angstroms.
virtual void read(int argc, const char **argv, bool reportErrors=true)
int numThreads
Number of threads to use in parallel to process a single image.
constexpr int PROCESS_IMAGE
barrier_t barrier
To create a barrier synchronization for threads.
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)
constexpr int PRELOAD_IMAGE
String integerToString(int I, int _width, char fill_with)
void finishComputations(const FileName &out_name)
int * statusArray
A status array for each row in an image (processing, processed,etc..)
size_t size() const override
#define i
ImageThreadParams * th_args
Contains parameters passed to each thread.
MultidimArray< std::complex< double > > VoutFourier
void setReal(MultidimArray< double > &img)
Definition: xmipp_fftw.cpp:129
void progress_bar(long rlen)
MultidimArray< std::complex< double > > * localPaddedFourier
int verbose
Verbosity level.
Image< double > Vout
MultidimArray< double > FourierWeights
MultidimArray< std::complex< double > > * paddedFourier
void getFourierAlias(T &V)
Definition: xmipp_fftw.h:207
void write(const FileName &fn) const
Definition: matrix2d.cpp:113
FourierTransformer transformerVol
Matrix2D< double > * localAInv
int threadOpCode
Tells the threads what to do next.
Matrix2D< double > * symmetry
std::vector< Matrix2D< double > > R_repository
void initZeros(const MultidimArray< T1 > &op)
void sumWithFile(const FileName &fn)
Definition: xmipp_image.h:1105
int barrier_wait(barrier_t *barrier)
void clear()
Definition: xmipp_image.h:144
size_t rowsProcessed
Number of rows already processed on an image.

◆ processImageThread()

void * ProgRecFourier::processImageThread ( void *  threadArgs)
static

Defines what a thread should do.

Definition at line 289 of file reconstruct_fourier.cpp.

290 {
291 
292  auto * threadParams = (ImageThreadParams *) threadArgs;
293  ProgRecFourier * parent = threadParams->parent;
294  barrier_t * barrier = &(parent->barrier);
295 
296  int minSeparation;
297 
298  if ( (int)ceil(parent->blob.radius) > parent->thrWidth )
299  minSeparation = (int)ceil(parent->blob.radius);
300  else
301  minSeparation = parent->thrWidth;
302 
303  minSeparation+=1;
304 
305  Matrix2D<double> localA(3, 3), localAinv(3, 3);
306  MultidimArray< std::complex<double> > localPaddedFourier;
307  MultidimArray<double> localPaddedImg;
308  FourierTransformer localTransformerImg;
309 
310  std::vector<size_t> objId;
311 
312  threadParams->selFile->findObjects(objId);
313  ApplyGeoParams params;
314  params.only_apply_shifts = true;
315  MultidimArray<int> zWrapped(3*parent->volPadSizeZ),yWrapped(3*parent->volPadSizeY),xWrapped(3*parent->volPadSizeX),
316  zNegWrapped, yNegWrapped, xNegWrapped;
317  zWrapped.initConstant(-1);
318  yWrapped.initConstant(-1);
319  xWrapped.initConstant(-1);
320  zWrapped.setXmippOrigin();
321  yWrapped.setXmippOrigin();
322  xWrapped.setXmippOrigin();
323  zNegWrapped=zWrapped;
324  yNegWrapped=yWrapped;
325  xNegWrapped=xWrapped;
326 
327  MultidimArray<double> x2precalculated(XSIZE(xWrapped)), y2precalculated(XSIZE(yWrapped)), z2precalculated(XSIZE(zWrapped));
328  x2precalculated.initConstant(-1);
329  y2precalculated.initConstant(-1);
330  z2precalculated.initConstant(-1);
331  x2precalculated.setXmippOrigin();
332  y2precalculated.setXmippOrigin();
333  z2precalculated.setXmippOrigin();
334 
335  bool hasCTF=(threadParams->selFile->containsLabel(MDL_CTF_MODEL) || threadParams->selFile->containsLabel(MDL_CTF_DEFOCUSU)) &&
336  parent->useCTF;
337  if (hasCTF)
338  {
339  threadParams->ctf.enable_CTF=true;
340  threadParams->ctf.enable_CTFnoise=false;
341  }
342  do
343  {
344  barrier_wait( barrier );
345 
346  switch ( parent->threadOpCode )
347  {
348  case PRELOAD_IMAGE:
349  {
350 
351  threadParams->read = 0;
352 
353  if ( threadParams->imageIndex >= 0 )
354  {
355  // Read input image
356  double rot, tilt, psi, weight;
357  Projection proj;
358 
359  //Read projection from selfile, read also angles and shifts if present
360  //but only apply shifts
361 
362  proj.readApplyGeo(*(threadParams->selFile), objId[threadParams->imageIndex], params);
363  rot = proj.rot();
364  tilt = proj.tilt();
365  psi = proj.psi();
366  weight = proj.weight();
367  if (hasCTF)
368  {
369  threadParams->ctf.readFromMetadataRow(*(threadParams->selFile),objId[threadParams->imageIndex]);
370  // threadParams->ctf.Tm=threadParams->parent->Ts;
371  threadParams->ctf.produceSideInfo();
372  }
373 
374  threadParams->weight = 1.;
375 
376  if(parent->do_weights)
377  threadParams->weight = weight;
378  else if (!parent->do_weights)
379  {
380  weight=1.0;
381  }
382  else if (weight==0.0)
383  {
384  threadParams->read = 2;
385  break;
386  }
387 
388  // Copy the projection to the center of the padded image
389  // and compute its Fourier transform
390  proj().setXmippOrigin();
391  auto localPaddedImgSize=(size_t)(parent->imgSize*parent->padding_factor_proj);
392  if (threadParams->reprocessFlag)
393  localPaddedFourier.initZeros(localPaddedImgSize,localPaddedImgSize/2+1);
394  else
395  {
396  localPaddedImg.initZeros(localPaddedImgSize,localPaddedImgSize);
397  localPaddedImg.setXmippOrigin();
398  const MultidimArray<double> &mProj=proj();
400  A2D_ELEM(localPaddedImg,i,j)=A2D_ELEM(mProj,i,j);
401  // COSS A2D_ELEM(localPaddedImg,i,j)=weight*A2D_ELEM(mProj,i,j);
402  CenterFFT(localPaddedImg,true);
403 
404  // Fourier transformer for the images
405  localTransformerImg.setReal(localPaddedImg);
406  localTransformerImg.FourierTransform();
407  localTransformerImg.getFourierAlias(localPaddedFourier);
408  }
409 
410  // Compute the coordinate axes associated to this image
411  Euler_angles2matrix(rot, tilt, psi, localA);
412  localAinv=localA.transpose();
413 
414  threadParams->localweight = weight;
415  threadParams->localAInv = &localAinv;
416  threadParams->localPaddedFourier = &localPaddedFourier;
417  //#define DEBUG22
418 #ifdef DEBUG22
419 
420  {//CORRECTO
421 
422  if(threadParams->myThreadID%1==0)
423  {
424  proj.write((std::string) integerToString(threadParams->myThreadID) + "_" +\
425  integerToString(threadParams->imageIndex) + "proj.spi");
426 
427  ImageXmipp save44;
428  save44()=localPaddedImg;
429  save44.write((std::string) integerToString(threadParams->myThreadID) + "_" +\
430  integerToString(threadParams->imageIndex) + "local_padded_img.spi");
431 
432  FourierImage save33;
433  save33()=localPaddedFourier;
434  save33.write((std::string) integerToString(threadParams->myThreadID) + "_" +\
435  integerToString(threadParams->imageIndex) + "local_padded_fourier.spi");
436  FourierImage save22;
437  //save22()=*paddedFourier;
438  save22().alias(*(threadParams->localPaddedFourier));
439  save22.write((std::string) integerToString(threadParams->myThreadID) + "_" +\
440  integerToString(threadParams->imageIndex) + "_padded_fourier.spi");
441  }
442 
443  }
444 #endif
445  #undef DEBUG22
446 
447  threadParams->read = 1;
448  }
449  break;
450  }
451  case EXIT_THREAD:
452  return nullptr;
453  case PROCESS_WEIGHTS:
454  {
455 
456  // Get a first approximation of the reconstruction
457  double corr2D_3D=pow(parent->padding_factor_proj,2.)/
458  (parent->imgSize* pow(parent->padding_factor_vol,3.));
459  // Divide by Zdim because of the
460  // the extra dimension added
461  // and padding differences
462  MultidimArray<double> &mFourierWeights=parent->FourierWeights;
463  for (int k=threadParams->myThreadID; k<=FINISHINGZ(mFourierWeights); k+=parent->numThreads)
464  for (int i=STARTINGY(mFourierWeights); i<=FINISHINGY(mFourierWeights); i++)
465  for (int j=STARTINGX(mFourierWeights); j<=FINISHINGX(mFourierWeights); j++)
466  {
467  if (parent->NiterWeight==0)
468  A3D_ELEM(parent->VoutFourier,k,i,j)*=corr2D_3D;
469  else
470  {
471  double weight_kij=A3D_ELEM(mFourierWeights,k,i,j);
472  if (1.0/weight_kij>ACCURACY)
473  A3D_ELEM(parent->VoutFourier,k,i,j)*=corr2D_3D*A3D_ELEM(mFourierWeights,k,i,j);
474  else
475  A3D_ELEM(parent->VoutFourier,k,i,j)=0;
476  }
477  }
478  break;
479  }
480  case PROCESS_IMAGE:
481  {
482  MultidimArray< std::complex<double> > *paddedFourier = threadParams->paddedFourier;
483  if (threadParams->weight==0.0)
484  break;
485  bool reprocessFlag = threadParams->reprocessFlag;
486  int * statusArray = parent->statusArray;
487 
488  int minAssignedRow;
489  int maxAssignedRow;
490  bool breakCase;
491  bool assigned;
492 
493  // Get the inverse of the sampling rate
494  // double iTs=parent->padding_factor_proj/parent->Ts;
495  double iTs=1.0/parent->Ts; // The padding factor is not considered here, but later when the indexes
496  // // are converted to digital frequencies
497  do
498  {
499  minAssignedRow = -1;
500  maxAssignedRow = -1;
501  breakCase = false;
502  assigned = false;
503 
504  do
505  {
506  pthread_mutex_lock( &(parent->workLoadMutex) );
507 
508  if ( parent->rowsProcessed == YSIZE(*paddedFourier) )
509  {
510  pthread_mutex_unlock( &(parent->workLoadMutex) );
511  breakCase = true;
512  break;
513  }
514 
515  for (size_t w = 0 ; w < YSIZE(*paddedFourier) ; w++ )
516  {
517  if ( statusArray[w]==0 )
518  {
519  assigned = true;
520  minAssignedRow = w;
521  maxAssignedRow = w+minSeparation-1;
522 
523  if ( maxAssignedRow > (int)(YSIZE(*paddedFourier)-1) )
524  maxAssignedRow = YSIZE(*paddedFourier)-1;
525 
526  for ( int in = (minAssignedRow - minSeparation) ; in < (int)minAssignedRow ; in ++ )
527  {
528  if ( ( in >= 0 ) && ( in < (int)YSIZE(*paddedFourier) ))
529  {
530  if ( statusArray[in] > -1 )
531  statusArray[in]++;
532  }
533  }
534 
535  for ( int in = minAssignedRow ; in <= (int)maxAssignedRow ; in ++ )
536  {
537  if ( ( in >= 0 ) && ( in < (int)YSIZE(*paddedFourier) ))
538  {
539  if ( statusArray[in] == 0 )
540  {
541  statusArray[in] = -1;
542  parent->rowsProcessed++;
543  }
544  }
545  }
546 
547  for ( int in = maxAssignedRow+1 ; in <= (maxAssignedRow+minSeparation) ; in ++ )
548  {
549  if ( ( in >= 0 ) && ( in < (int)YSIZE(*paddedFourier) ))
550  {
551  if ( statusArray[in] > -1 )
552  statusArray[in]++;
553  }
554  }
555 
556  break;
557  }
558  }
559 
560  pthread_mutex_unlock( &(parent->workLoadMutex) );
561  }
562  while ( !assigned );
563 
564  if ( breakCase == true )
565  {
566  break;
567  }
568 
569  Matrix2D<double> * A_SL = threadParams->symmetry;
570 
571  // Loop over all Fourier coefficients in the padded image
572  Matrix1D<double> freq(3), gcurrent(3), real_position(3), contFreq(3);
573  Matrix1D<int> corner1(3), corner2(3);
574 
575  // Some alias and calculations moved from heavy loops
576  double wCTF=1, wModulator=1.0;
577  double blobRadiusSquared = parent->blob.radius * parent->blob.radius;
578  double iDeltaSqrt = parent->iDeltaSqrt;
580  int xsize_1 = XSIZE(parent->VoutFourier) - 1;
581  int zsize_1 = ZSIZE(parent->VoutFourier) - 1;
583  MultidimArray<double> &fourierWeights = parent->FourierWeights;
584  // MultidimArray<double> &prefourierWeights = parent->preFourierWeights;
585  // Get i value for the thread
586  for (int i = minAssignedRow; i <= maxAssignedRow ; i ++ )
587  {
588  // Discarded rows can be between minAssignedRow and maxAssignedRow, check
589  if ( statusArray[i] == -1 )
590  for (int j=STARTINGX(*paddedFourier); j<=FINISHINGX(*paddedFourier); j++)
591  {
592  // Compute the frequency of this coefficient in the
593  // universal coordinate system
594  FFT_IDX2DIGFREQ(j,XSIZE(parent->paddedImg),XX(freq));
595  FFT_IDX2DIGFREQ(i,YSIZE(parent->paddedImg),YY(freq));
596  ZZ(freq)=0;
597  if (XX(freq)*XX(freq)+YY(freq)*YY(freq)>parent->maxResolution2)
598  continue;
599  wModulator=1.0;
600  if (hasCTF && !reprocessFlag)
601  {
602  XX(contFreq)=XX(freq)*iTs;
603  YY(contFreq)=YY(freq)*iTs;
604  threadParams->ctf.precomputeValues(XX(contFreq),YY(contFreq));
605  //wCTF=threadParams->ctf.getValueAt();
606  wCTF=threadParams->ctf.getValuePureNoKAt();
607  //wCTF=threadParams->ctf.getValuePureWithoutDampingAt();
608 
609  if (std::isnan(wCTF))
610  {
611  if (i==0 && j==0)
612  wModulator=wCTF=1.0;
613  else
614  wModulator=wCTF=0.0;
615  }
616  if (fabs(wCTF)<parent->minCTF)
617  {
618  wModulator=fabs(wCTF);
619  wCTF=SGN(wCTF);
620  }
621  else
622  wCTF=1.0/wCTF;
623  if (parent->phaseFlipped)
624  wCTF=fabs(wCTF);
625  }
626 
628  M3x3_BY_V3x1(freq,*A_SL,freq);
629 
630  // Look for the corresponding index in the volume Fourier transform
631  DIGFREQ2FFT_IDX_DOUBLE(XX(freq),parent->volPadSizeX,XX(real_position));
632  DIGFREQ2FFT_IDX_DOUBLE(YY(freq),parent->volPadSizeY,YY(real_position));
633  DIGFREQ2FFT_IDX_DOUBLE(ZZ(freq),parent->volPadSizeZ,ZZ(real_position));
634 
635  // Put a box around that coefficient
636  XX(corner1)=CEIL (XX(real_position)-parent->blob.radius);
637  YY(corner1)=CEIL (YY(real_position)-parent->blob.radius);
638  ZZ(corner1)=CEIL (ZZ(real_position)-parent->blob.radius);
639  XX(corner2)=FLOOR(XX(real_position)+parent->blob.radius);
640  YY(corner2)=FLOOR(YY(real_position)+parent->blob.radius);
641  ZZ(corner2)=FLOOR(ZZ(real_position)+parent->blob.radius);
642 
643 #ifdef DEBUG
644 
645  std::cout << "Idx Img=(0," << i << "," << j << ") -> Freq Img=("
646  << freq.transpose() << ") ->\n Idx Vol=("
647  << real_position.transpose() << ")\n"
648  << " Corner1=" << corner1.transpose() << std::endl
649  << " Corner2=" << corner2.transpose() << std::endl;
650 #endif
651  // Loop within the box
652  auto *ptrIn=(double *)&(A2D_ELEM(*paddedFourier, i,j));
653 
654  // Some precalculations
655  for (int intz = ZZ(corner1); intz <= ZZ(corner2); ++intz)
656  {
657  double z = intz - ZZ(real_position);
658  A1D_ELEM(z2precalculated,intz)=z*z;
659  if (A1D_ELEM(zWrapped,intz)<0)
660  {
661  int iz, izneg;
662  fastIntWRAP(iz, intz, 0, zsize_1);
663  A1D_ELEM(zWrapped,intz)=iz;
664  int miz=-iz;
665  fastIntWRAP(izneg, miz,0,zsize_1);
666  A1D_ELEM(zNegWrapped,intz)=izneg;
667  }
668  }
669  for (int inty = YY(corner1); inty <= YY(corner2); ++inty)
670  {
671  double y = inty - YY(real_position);
672  A1D_ELEM(y2precalculated,inty)=y*y;
673  if (A1D_ELEM(yWrapped,inty)<0)
674  {
675  int iy, iyneg;
676  fastIntWRAP(iy, inty, 0, zsize_1);
677  A1D_ELEM(yWrapped,inty)=iy;
678  int miy=-iy;
679  fastIntWRAP(iyneg, miy,0,zsize_1);
680  A1D_ELEM(yNegWrapped,inty)=iyneg;
681  }
682  }
683  for (int intx = XX(corner1); intx <= XX(corner2); ++intx)
684  {
685  double x = intx - XX(real_position);
686  A1D_ELEM(x2precalculated,intx)=x*x;
687  if (A1D_ELEM(xWrapped,intx)<0)
688  {
689  int ix, ixneg;
690  fastIntWRAP(ix, intx, 0, zsize_1);
691  A1D_ELEM(xWrapped,intx)=ix;
692  int mix=-ix;
693  fastIntWRAP(ixneg, mix,0,zsize_1);
694  A1D_ELEM(xNegWrapped,intx)=ixneg;
695  }
696  }
697 
698  // Actually compute
699  for (int intz = ZZ(corner1); intz <= ZZ(corner2); ++intz)
700  {
701  double z2 = A1D_ELEM(z2precalculated,intz);
702  int iz=A1D_ELEM(zWrapped,intz);
703  int izneg=A1D_ELEM(zNegWrapped,intz);
704 
705  for (int inty = YY(corner1); inty <= YY(corner2); ++inty)
706  {
707  double y2z2 = A1D_ELEM(y2precalculated,inty) + z2;
708  if (y2z2 > blobRadiusSquared)
709  continue;
710  int iy=A1D_ELEM(yWrapped,inty);
711  int iyneg=A1D_ELEM(yNegWrapped,inty);
712 
713  int size1=YXSIZE(VoutFourier)*izneg+(iyneg*XSIZE(VoutFourier));
714  int size2=YXSIZE(VoutFourier)*iz+(iy*XSIZE(VoutFourier));
715  int fixSize=0;
716 
717  for (int intx = XX(corner1); intx <= XX(corner2); ++intx)
718  {
719  // Compute distance to the center of the blob
720  // Compute blob value at that distance
721  double d2 = A1D_ELEM(x2precalculated,intx) + y2z2;
722 
723  if (d2 > blobRadiusSquared)
724  continue;
725  auto aux = (int)(d2 * iDeltaSqrt + 0.5);//Same as ROUND but avoid comparison
726  double w = VEC_ELEM(blobTableSqrt, aux)*threadParams->weight *wModulator;
727 
728  // Look for the location of this logical index
729  // in the physical layout
730 #ifdef DEBUG
731 
732  std::cout << " gcurrent=" << gcurrent.transpose()
733  << " d=" << d << std::endl;
734  std::cout << " 1: intx=" << intx
735  << " inty=" << inty
736  << " intz=" << intz << std::endl;
737 #endif
738 
739  int ix=A1D_ELEM(xWrapped,intx);
740 #ifdef DEBUG
741 
742  std::cout << " 2: ix=" << ix << " iy=" << iy
743  << " iz=" << iz << std::endl;
744 #endif
745 
746  bool conjugate=false;
747  int izp, iyp, ixp;
748  if (ix > xsize_1)
749  {
750  izp = izneg;
751  iyp = iyneg;
752  ixp = A1D_ELEM(xNegWrapped,intx);
753  conjugate=true;
754  fixSize = size1;
755  }
756  else
757  {
758  izp=iz;
759  iyp=iy;
760  ixp=ix;
761  fixSize = size2;
762  }
763 #ifdef DEBUG
764  std::cout << " 3: ix=" << ix << " iy=" << iy
765  << " iz=" << iz << " conj="
766  << conjugate << std::endl;
767 #endif
768 
769  // Add the weighted coefficient
770  if (reprocessFlag)
771  {
772  // Use VoutFourier as temporary to save the memory
773  auto *ptrOut=(double *)&(DIRECT_A3D_ELEM(VoutFourier, izp,iyp,ixp));
774  DIRECT_A3D_ELEM(fourierWeights, izp,iyp,ixp) += (w * ptrOut[0]);
775  }
776  else
777  {
778  double wEffective=w*wCTF;
779  size_t memIdx=fixSize + ixp;//YXSIZE(VoutFourier)*(izp)+((iyp)*XSIZE(VoutFourier))+(ixp);
780  auto *ptrOut=(double *)&(DIRECT_A1D_ELEM(VoutFourier, memIdx));
781  ptrOut[0] += wEffective * ptrIn[0];
782  DIRECT_A1D_ELEM(fourierWeights, memIdx) += w;
783 
784  if (conjugate)
785  ptrOut[1]-=wEffective*ptrIn[1];
786  else
787  ptrOut[1]+=wEffective*ptrIn[1];
788  }
789  }
790  }
791  }
792  }
793  }
794 
795  pthread_mutex_lock( &(parent->workLoadMutex) );
796 
797  for ( int w = (minAssignedRow - minSeparation) ; w < minAssignedRow ; w ++ )
798  {
799  if ( ( w >= 0 ) && ( w < (int)YSIZE(*paddedFourier) ))
800  {
801  if ( statusArray[w] > 0 )
802  {
803  statusArray[w]--;
804  }
805  }
806  }
807 
808  for ( int w = maxAssignedRow+1 ; w <= (maxAssignedRow+minSeparation) ; w ++ )
809  {
810  if ( ( w >= 0 ) && ( w < (int)YSIZE(*paddedFourier) ))
811  {
812  if ( statusArray[w] > 0 )
813  {
814  statusArray[w]--;
815  }
816  }
817  }
818 
819  pthread_mutex_unlock( &(parent->workLoadMutex) );
820 
821  }
822  while (!breakCase);
823  break;
824  }
825  default:
826  break;
827  }
828 
829  barrier_wait( barrier );
830  }
831  while ( 1 );
832 }
int thrWidth
How many image rows are processed at a time by a single thread.
struct blobtype blob
#define YSIZE(v)
#define A2D_ELEM(v, i, j)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
Defocus U (Angstroms)
MultidimArray< double > paddedImg
int NiterWeight
Number of iterations for the weight.
#define FINISHINGX(v)
double psi(const size_t n=0) const
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
constexpr int PROCESS_WEIGHTS
int numThreads
Number of threads to use in parallel to process a single image.
constexpr int PROCESS_IMAGE
static double * y
barrier_t barrier
To create a barrier synchronization for threads.
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 A1D_ELEM(v, i)
constexpr int PRELOAD_IMAGE
doublereal * w
void initConstant(T val)
Name for the CTF Model (std::string)
String integerToString(int I, int _width, char fill_with)
double rot(const size_t n=0) const
#define FINISHINGZ(v)
#define DIGFREQ2FFT_IDX_DOUBLE(freq, size, idx)
Definition: xmipp_fft.h:70
double weight(const size_t n=0) const
#define STARTINGX(v)
int * statusArray
A status array for each row in an image (processing, processed,etc..)
doublereal * x
int readApplyGeo(const FileName &name, const MDRow &row, const ApplyGeoParams &params=DefaultApplyGeoParams)
#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
doublereal * d
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
#define ACCURACY
double tilt(const size_t n=0) const
#define STARTINGY(v)
void CenterFFT(MultidimArray< T > &v, bool forward)
Definition: xmipp_fft.h:291
#define A3D_ELEM(V, k, i, j)
#define DIRECT_A1D_ELEM(v, i)
MultidimArray< std::complex< double > > VoutFourier
pthread_mutex_t workLoadMutex
Controls mutual exclusion on critical zones of code.
#define FLOOR(x)
Definition: xmipp_macros.h:240
#define XX(v)
Definition: matrix1d.h:85
void setReal(MultidimArray< double > &img)
Definition: xmipp_fftw.cpp:129
if(fabs(c[*nmax+ *nmax *c_dim1])==0.e0)
#define CEIL(x)
Definition: xmipp_macros.h:225
int in
#define XSIZE(v)
void write(const FileName &fn) const
#define ZSIZE(v)
double z
#define DIRECT_A3D_ELEM(v, k, i, j)
void FourierTransform(T &v, T1 &V, bool getCopy=true)
Definition: xmipp_fftw.h:166
__device__ float FFT_IDX2DIGFREQ(int idx, int size)
#define j
#define M3x3_BY_V3x1(a, M, b)
Definition: matrix2d.h:170
#define YY(v)
Definition: matrix1d.h:93
MultidimArray< double > FourierWeights
#define FINISHINGY(v)
void getFourierAlias(T &V)
Definition: xmipp_fftw.h:207
double psi(const double x)
int threadOpCode
Tells the threads what to do next.
constexpr int EXIT_THREAD
void initZeros(const MultidimArray< T1 > &op)
#define fastIntWRAP(y, x, x0, xF)
Definition: xmipp_macros.h:280
Matrix1D< double > blobTableSqrt
int barrier_wait(barrier_t *barrier)
#define YXSIZE(v)
#define SGN(x)
Definition: xmipp_macros.h:155
double radius
Spatial radius in Universal System units.
Definition: blobs.h:115
#define ZZ(v)
Definition: matrix1d.h:101
#define SPEED_UP_temps012
Definition: xmipp_macros.h:403
size_t rowsProcessed
Number of rows already processed on an image.

◆ produceSideinfo()

void ProgRecFourier::produceSideinfo ( )

Produce side info: fill arrays with relevant transformation matrices.

Definition at line 184 of file reconstruct_fourier.cpp.

185 {
186  // Translate the maximum resolution to digital frequency
187  // maxResolution=sampling_rate/maxResolution;
189 
190  // Read the input images
191  SF.read(fn_sel);
192  SF.removeDisabled();
193 
194  // Ask for memory for the output volume and its Fourier transform
195  size_t objId = SF.firstRowId();
196  FileName fnImg;
197  SF.getValue(MDL_IMAGE,fnImg,objId);
198  Image<double> I;
199  I.read(fnImg, HEADER);
200  int Ydim=YSIZE(I());
201  int Xdim=XSIZE(I());
202  if (Ydim!=Xdim)
203  REPORT_ERROR(ERR_MULTIDIM_SIZE,"This algorithm only works for squared images");
204  imgSize=Xdim;
207 
208  //use threads for volume inverse fourier transform, plan is created in setReal()
211 
212  Vout().clear(); // Free the memory so that it is available for FourierWeights
216 
217  // Ask for memory for the padded images
218  auto paddedImgSize=(size_t)(Xdim*padding_factor_proj);
219  paddedImg.resize(paddedImgSize,paddedImgSize);
222 
223  // Build a table of blob values
227 
228  struct blobtype blobFourier,blobnormalized;
229  blobFourier=blob;
230  //Sjors 18aug10 blobFourier.radius/=(padding_factor_proj*Xdim);
231  blobFourier.radius/=(padding_factor_vol*Xdim);
232  blobnormalized=blob;
233  blobnormalized.radius/=((double)padding_factor_proj/padding_factor_vol);
234  double deltaSqrt = (blob.radius*blob.radius) /(BLOB_TABLE_SIZE_SQRT-1);
235  double deltaFourier = (sqrt(3.)*Xdim/2.)/(BLOB_TABLE_SIZE_SQRT-1);
236 
237  // The interpolation kernel must integrate to 1
238  double iw0 = 1.0 / blob_Fourier_val(0.0, blobnormalized);
239  //Sjors 18aug10 double padXdim3 = padding_factor_proj * Xdim;
240  double padXdim3 = padding_factor_vol * Xdim;
241  padXdim3 = padXdim3 * padXdim3 * padXdim3;
242  double blobTableSize = blob.radius*sqrt(1./ (BLOB_TABLE_SIZE_SQRT-1));
243  //***
244  //Following commented line seems to be the right thing but I do not understand it
245  //double fourierBlobTableSize = (sqrt(3.)*Xdim*Xdim/2.)*blobFourier.radius *sqrt(1./ (BLOB_TABLE_SIZE_SQRT-1));
247 
248  {
249  //use a r*r sample instead of r
250  //DIRECT_VEC_ELEM(blob_table,i) = blob_val(delta*i, blob) *iw0;
251  VEC_ELEM(blobTableSqrt,i) = blob_val(blobTableSize*sqrt((double)i), blob) *iw0;
252  //***
253  //DIRECT_VEC_ELEM(fourierBlobTableSqrt,i) =
254  // blob_Fourier_val(fourierBlobTableSize*sqrt(i), blobFourier)*padXdim3 *iw0;
256  blob_Fourier_val(deltaFourier*i, blobFourier)*padXdim3 *iw0;
257  //#define DEBUG
258 #ifdef DEBUG
259 
260  std::cout << VEC_ELEM(Fourier_blob_table,i)
261  << " " << VEC_ELEM(fourierBlobTableSqrt,i)
262  << std::endl;
263 #endif
264  #undef DEBUG
265 
266  }
267  //iDelta = 1/delta;
268  iDeltaSqrt = 1/deltaSqrt;
269  iDeltaFourier = 1/deltaFourier;
270 
271  // Get symmetries
272  Matrix2D<double> Identity(3,3);
273  Identity.initIdentity();
274  R_repository.push_back(Identity);
275  if (fn_sym != "")
276  {
277  SymList SL;
279  for (int isym = 0; isym < SL.trueSymsNo(); isym++)
280  {
281  Matrix2D<double> L(4, 4), R(4, 4);
282  SL.getMatrices(isym, L, R);
283  R.resize(3, 3);
284  R_repository.push_back(R);
285  }
286  }
287 }
struct blobtype blob
#define YSIZE(v)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
MultidimArray< double > paddedImg
double maxResolution
Max resolution in Angstroms.
void getMatrices(int i, Matrix2D< double > &L, Matrix2D< double > &R, bool homogeneous=true) const
Definition: symmetries.cpp:348
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
void setThreadsNumber(int tNumber)
Definition: xmipp_fftw.h:119
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void sqrt(Image< double > &op)
int numThreads
Number of threads to use in parallel to process a single image.
int readSymmetryFile(FileName fn_sym, double accuracy=SYM_ACCURACY)
Definition: symmetries.cpp:33
FourierTransformer transformerImg
Incorrect MultidimArray size.
Definition: xmipp_error.h:174
#define i
#define BLOB_TABLE_SIZE_SQRT
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
Definition: matrix1d.h:72
MultidimArray< std::complex< double > > VoutFourier
void setReal(MultidimArray< double > &img)
Definition: xmipp_fftw.cpp:129
size_t firstRowId() const override
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
#define XSIZE(v)
#define blob_Fourier_val(w, blob)
Definition: blobs.h:174
Matrix1D< double > Fourier_blob_table
Image< double > Vout
Matrix1D< double > fourierBlobTableSqrt
bool getValue(MDObject &mdValueOut, size_t id) const override
MultidimArray< double > FourierWeights
virtual void removeDisabled()
void getFourierAlias(T &V)
Definition: xmipp_fftw.h:207
FourierTransformer transformerVol
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
std::vector< Matrix2D< double > > R_repository
void initZeros(const MultidimArray< T1 > &op)
#define blob_val(r, blob)
Definition: blobs.h:139
Matrix1D< double > blobTableSqrt
int trueSymsNo() const
Definition: symmetries.h:283
double radius
Spatial radius in Universal System units.
Definition: blobs.h:115
Name of an image (std::string)
void clear()
Definition: xmipp_image.h:144

◆ readParams()

void ProgRecFourier::readParams ( )
virtual

Read arguments from command line.

Reimplemented from XmippProgram.

Definition at line 64 of file reconstruct_fourier.cpp.

65 {
66  fn_sel = getParam("-i");
67  fn_out = getParam("-o");
68  fn_sym = getParam("--sym");
69  if(checkParam("--prepare_fsc"))
70  fn_fsc = getParam("--prepare_fsc");
71  do_weights = checkParam("--weight");
72  padding_factor_proj = getDoubleParam("--padding", 0);
73  padding_factor_vol = getDoubleParam("--padding", 1);
74  blob.radius = getDoubleParam("--blob", 0);
75  blob.order = getIntParam("--blob", 1);
76  blob.alpha = getDoubleParam("--blob", 2);
77  maxResolution = getDoubleParam("--max_resolution");
78  numThreads = getIntParam("--thr");
79  thrWidth = getIntParam("--thr", 1);
80  NiterWeight = getIntParam("--iter");
81  useCTF = checkParam("--useCTF");
82  phaseFlipped = checkParam("--phaseFlipped");
83  minCTF = getDoubleParam("--minCTF");
84  if (useCTF)
85  Ts=getDoubleParam("--sampling");
86 }
int thrWidth
How many image rows are processed at a time by a single thread.
struct blobtype blob
double alpha
Smoothness parameter.
Definition: blobs.h:121
double maxResolution
Max resolution in Angstroms.
double getDoubleParam(const char *param, int arg=0)
int NiterWeight
Number of iterations for the weight.
int numThreads
Number of threads to use in parallel to process a single image.
const char * getParam(const char *param, int arg=0)
int order
Derivation order and Bessel function order.
Definition: blobs.h:118
bool checkParam(const char *param)
int getIntParam(const char *param, int arg=0)
double radius
Spatial radius in Universal System units.
Definition: blobs.h:115

◆ run()

void ProgRecFourier::run ( )
virtual

Run.

Reimplemented from XmippProgram.

Definition at line 124 of file reconstruct_fourier.cpp.

125 {
126  show();
127  produceSideinfo();
128  // Process all images in the selfile
129  if (verbose)
130  {
131  if (NiterWeight!=0)
133  else
135  }
136  // Create threads stuff
138  pthread_mutex_init( &workLoadMutex, nullptr);
139  statusArray = nullptr;
140  th_ids = (pthread_t *)malloc( numThreads * sizeof( pthread_t));
141  th_args = (ImageThreadParams *) malloc ( numThreads * sizeof( ImageThreadParams ) );
142 
143  // Create threads
144  for ( int nt = 0 ; nt < numThreads ; nt ++ )
145  {
146  // Passing parameters to each thread
147  th_args[nt].parent = this;
148  th_args[nt].myThreadID = nt;
149  th_args[nt].selFile = new MetaDataVec(SF);
150  pthread_create( (th_ids+nt) , nullptr, processImageThread, (void *)(th_args+nt) );
151  }
152 
153  //Computing interpolated volume
154  processImages(0, SF.size() - 1, !fn_fsc.empty(), false);
155 
156  // Correcting the weights
157  correctWeight();
158 
159  //Saving the volume
161 
163 
164  // Waiting for threads to finish
165  barrier_wait( &barrier );
166  for ( int nt = 0 ; nt < numThreads ; nt ++ )
167  pthread_join(*(th_ids+nt), nullptr);
169 
170  // Deallocate resources.
171  if ( statusArray != nullptr)
172  {
173  free(statusArray);
174  }
175  for (int nt=0; nt<numThreads ;nt++)
176  {
177  delete(th_args[nt].selFile);
178  }
179  free(th_ids);
180  free(th_args);
181 }
int barrier_init(barrier_t *barrier, int needed)
void init_progress_bar(long total)
int NiterWeight
Number of iterations for the weight.
int numThreads
Number of threads to use in parallel to process a single image.
barrier_t barrier
To create a barrier synchronization for threads.
void finishComputations(const FileName &out_name)
int * statusArray
A status array for each row in an image (processing, processed,etc..)
int barrier_destroy(barrier_t *barrier)
size_t size() const override
ImageThreadParams * th_args
Contains parameters passed to each thread.
pthread_mutex_t workLoadMutex
Controls mutual exclusion on critical zones of code.
void processImages(int firstImageIndex, int lastImageIndex, bool saveFSC=false, bool reprocessFlag=false)
Process one image.
void correctWeight()
Method for the correction of the fourier coefficients.
free((char *) ob)
static void * processImageThread(void *threadArgs)
Defines what a thread should do.
void produceSideinfo()
Produce side info: fill arrays with relevant transformation matrices.
int verbose
Verbosity level.
pthread_t * th_ids
IDs for the threads.
ProgRecFourier * parent
int threadOpCode
Tells the threads what to do next.
constexpr int EXIT_THREAD
int barrier_wait(barrier_t *barrier)

◆ setIO()

void ProgRecFourier::setIO ( const FileName fn_in,
const FileName fn_out 
)
virtual

Functions of common reconstruction interface.

Implements ProgReconsBase.

Definition at line 1182 of file reconstruct_fourier.cpp.

1183 {
1184  this->fn_sel = fn_in;
1185  this->fn_out = fn_out;
1186 }

◆ show()

void ProgRecFourier::show ( )

Show.

Definition at line 89 of file reconstruct_fourier.cpp.

90 {
91  if (verbose > 0)
92  {
93  std::cout << " =====================================================================" << std::endl;
94  std::cout << " Direct 3D reconstruction method using Kaiser windows as interpolators" << std::endl;
95  std::cout << " =====================================================================" << std::endl;
96  std::cout << " Input selfile : " << fn_sel << std::endl;
97  std::cout << " padding_factor_proj : " << padding_factor_proj << std::endl;
98  std::cout << " padding_factor_vol : " << padding_factor_vol << std::endl;
99  std::cout << " Output volume : " << fn_out << std::endl;
100  if (fn_sym != "")
101  std::cout << " Symmetry file for projections : " << fn_sym << std::endl;
102  if (fn_fsc != "")
103  std::cout << " File root for FSC files: " << fn_fsc << std::endl;
104  if (do_weights)
105  std::cout << " Use weights stored in the image headers or doc file" << std::endl;
106  else
107  std::cout << " Do NOT use weights" << std::endl;
108  if (useCTF)
109  std::cout << "Using CTF information" << std::endl
110  << "Sampling rate: " << Ts << std::endl
111  << "Phase flipped: " << phaseFlipped << std::endl
112  << "Minimum CTF: " << minCTF << std::endl;
113  std::cout << "\n Interpolation Function"
114  << "\n blrad : " << blob.radius
115  << "\n blord : " << blob.order
116  << "\n blalpha : " << blob.alpha
117  //<< "\n sampling_rate : " << sampling_rate
118  << "\n max_resolution : " << maxResolution
119  << "\n -----------------------------------------------------------------" << std::endl;
120  }
121 }
struct blobtype blob
double alpha
Smoothness parameter.
Definition: blobs.h:121
double maxResolution
Max resolution in Angstroms.
int verbose
Verbosity level.
int order
Derivation order and Bessel function order.
Definition: blobs.h:118
double radius
Spatial radius in Universal System units.
Definition: blobs.h:115

Member Data Documentation

◆ barrier

barrier_t ProgRecFourier::barrier

To create a barrier synchronization for threads.

Definition at line 139 of file reconstruct_fourier.h.

◆ blob

struct blobtype ProgRecFourier::blob

Definition at line 170 of file reconstruct_fourier.h.

◆ blobTableSqrt

Matrix1D<double> ProgRecFourier::blobTableSqrt

Definition at line 160 of file reconstruct_fourier.h.

◆ do_weights

bool ProgRecFourier::do_weights

Flag whether to use the weights in the image metadata

Definition at line 86 of file reconstruct_fourier.h.

◆ fn_doc

FileName ProgRecFourier::fn_doc

Definition at line 80 of file reconstruct_fourier.h.

◆ fn_fsc

FileName ProgRecFourier::fn_fsc

Definition at line 80 of file reconstruct_fourier.h.

◆ fn_out

FileName ProgRecFourier::fn_out

Filenames

Definition at line 80 of file reconstruct_fourier.h.

◆ fn_sel

FileName ProgRecFourier::fn_sel

Definition at line 80 of file reconstruct_fourier.h.

◆ fn_sym

FileName ProgRecFourier::fn_sym

Definition at line 80 of file reconstruct_fourier.h.

◆ Fourier_blob_table

Matrix1D<double> ProgRecFourier::Fourier_blob_table

Definition at line 157 of file reconstruct_fourier.h.

◆ fourierBlobTableSqrt

Matrix1D<double> ProgRecFourier::fourierBlobTableSqrt

Definition at line 160 of file reconstruct_fourier.h.

◆ FourierWeights

MultidimArray<double> ProgRecFourier::FourierWeights

Definition at line 185 of file reconstruct_fourier.h.

◆ iDeltaFourier

double ProgRecFourier::iDeltaFourier

Definition at line 164 of file reconstruct_fourier.h.

◆ iDeltaSqrt

double ProgRecFourier::iDeltaSqrt

Definition at line 164 of file reconstruct_fourier.h.

◆ imgSize

int ProgRecFourier::imgSize

Definition at line 149 of file reconstruct_fourier.h.

◆ maxResolution

double ProgRecFourier::maxResolution

Max resolution in Angstroms.

Definition at line 112 of file reconstruct_fourier.h.

◆ maxResolution2

double ProgRecFourier::maxResolution2

Definition at line 167 of file reconstruct_fourier.h.

◆ minCTF

double ProgRecFourier::minCTF

Minimum CTF value to invert

Definition at line 97 of file reconstruct_fourier.h.

◆ NiterWeight

int ProgRecFourier::NiterWeight

Number of iterations for the weight.

Definition at line 115 of file reconstruct_fourier.h.

◆ numThreads

int ProgRecFourier::numThreads

Number of threads to use in parallel to process a single image.

Definition at line 118 of file reconstruct_fourier.h.

◆ paddedImg

MultidimArray<double> ProgRecFourier::paddedImg

Definition at line 188 of file reconstruct_fourier.h.

◆ padding_factor_proj

double ProgRecFourier::padding_factor_proj

Projection padding Factor

Definition at line 103 of file reconstruct_fourier.h.

◆ padding_factor_vol

double ProgRecFourier::padding_factor_vol

Volume padding Factor

Definition at line 106 of file reconstruct_fourier.h.

◆ phaseFlipped

bool ProgRecFourier::phaseFlipped

Phase flipped. True if the images have been phase flipped before entering.

Definition at line 94 of file reconstruct_fourier.h.

◆ R_repository

std::vector<Matrix2D<double> > ProgRecFourier::R_repository

Definition at line 173 of file reconstruct_fourier.h.

◆ rowsProcessed

size_t ProgRecFourier::rowsProcessed

Number of rows already processed on an image.

Definition at line 130 of file reconstruct_fourier.h.

◆ sampling_rate

double ProgRecFourier::sampling_rate

Sampling rate in Angstroms/pixel

Definition at line 109 of file reconstruct_fourier.h.

◆ SF

MetaDataVec ProgRecFourier::SF

SelFile containing all projections

Definition at line 83 of file reconstruct_fourier.h.

◆ statusArray

int* ProgRecFourier::statusArray

A status array for each row in an image (processing, processed,etc..)

Definition at line 142 of file reconstruct_fourier.h.

◆ th_args

ImageThreadParams* ProgRecFourier::th_args

Contains parameters passed to each thread.

Definition at line 124 of file reconstruct_fourier.h.

◆ th_ids

pthread_t* ProgRecFourier::th_ids

IDs for the threads.

Definition at line 121 of file reconstruct_fourier.h.

◆ threadOpCode

int ProgRecFourier::threadOpCode

Tells the threads what to do next.

Definition at line 127 of file reconstruct_fourier.h.

◆ thrWidth

int ProgRecFourier::thrWidth

How many image rows are processed at a time by a single thread.

Definition at line 145 of file reconstruct_fourier.h.

◆ transformerImg

FourierTransformer ProgRecFourier::transformerImg

Definition at line 179 of file reconstruct_fourier.h.

◆ transformerVol

FourierTransformer ProgRecFourier::transformerVol

Definition at line 176 of file reconstruct_fourier.h.

◆ Ts

double ProgRecFourier::Ts

Sampling rate

Definition at line 100 of file reconstruct_fourier.h.

◆ useCTF

bool ProgRecFourier::useCTF

Use CTF

Definition at line 89 of file reconstruct_fourier.h.

◆ volPadSizeX

int ProgRecFourier::volPadSizeX

Definition at line 152 of file reconstruct_fourier.h.

◆ volPadSizeY

int ProgRecFourier::volPadSizeY

Definition at line 153 of file reconstruct_fourier.h.

◆ volPadSizeZ

int ProgRecFourier::volPadSizeZ

Definition at line 154 of file reconstruct_fourier.h.

◆ Vout

Image<double> ProgRecFourier::Vout

Definition at line 191 of file reconstruct_fourier.h.

◆ VoutFourier

MultidimArray< std::complex<double> > ProgRecFourier::VoutFourier

Definition at line 182 of file reconstruct_fourier.h.

◆ VoutFourierTmp

MultidimArray< std::complex<double> > ProgRecFourier::VoutFourierTmp

Definition at line 182 of file reconstruct_fourier.h.

◆ workLoadMutex

pthread_mutex_t ProgRecFourier::workLoadMutex

Controls mutual exclusion on critical zones of code.

Definition at line 136 of file reconstruct_fourier.h.


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