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.");
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");
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;
99 std::cout <<
" Output volume : " <<
fn_out << std::endl;
101 std::cout <<
" Symmetry file for projections : " <<
fn_sym << std::endl;
103 std::cout <<
" File root for FSC files: " <<
fn_fsc << std::endl;
105 std::cout <<
" Use weights stored in the image headers or doc file" << std::endl;
107 std::cout <<
" Do NOT use weights" << std::endl;
109 std::cout <<
"Using CTF information" << std::endl
110 <<
"Sampling rate: " <<
Ts << std::endl
112 <<
"Minimum CTF: " <<
minCTF << std::endl;
113 std::cout <<
"\n Interpolation Function" 119 <<
"\n -----------------------------------------------------------------" << std::endl;
167 pthread_join(*(
th_ids+nt),
nullptr);
228 struct blobtype blobFourier,blobnormalized;
231 blobFourier.
radius/=(padding_factor_vol*Xdim);
233 blobnormalized.
radius/=((double)padding_factor_proj/padding_factor_vol);
240 double padXdim3 = padding_factor_vol * Xdim;
241 padXdim3 = padXdim3 * padXdim3 * padXdim3;
279 for (
int isym = 0; isym < SL.
trueSymsNo(); isym++)
299 minSeparation = (
int)ceil(parent->
blob.
radius);
310 std::vector<size_t> objId;
312 threadParams->selFile->findObjects(objId);
316 zNegWrapped, yNegWrapped, xNegWrapped;
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;
328 x2precalculated.initConstant(-1);
329 y2precalculated.initConstant(-1);
331 x2precalculated.setXmippOrigin();
332 y2precalculated.setXmippOrigin();
339 threadParams->ctf.enable_CTF=
true;
340 threadParams->ctf.enable_CTFnoise=
false;
351 threadParams->read = 0;
353 if ( threadParams->imageIndex >= 0 )
356 double rot, tilt,
psi, weight;
362 proj.
readApplyGeo(*(threadParams->selFile), objId[threadParams->imageIndex], params);
369 threadParams->ctf.readFromMetadataRow(*(threadParams->selFile),objId[threadParams->imageIndex]);
371 threadParams->ctf.produceSideInfo();
374 threadParams->weight = 1.;
377 threadParams->weight = weight;
382 else if (weight==0.0)
384 threadParams->read = 2;
390 proj().setXmippOrigin();
392 if (threadParams->reprocessFlag)
393 localPaddedFourier.
initZeros(localPaddedImgSize,localPaddedImgSize/2+1);
396 localPaddedImg.
initZeros(localPaddedImgSize,localPaddedImgSize);
405 localTransformerImg.
setReal(localPaddedImg);
414 threadParams->localweight = weight;
415 threadParams->localAInv = &localAinv;
416 threadParams->localPaddedFourier = &localPaddedFourier;
422 if(threadParams->myThreadID%1==0)
428 save44()=localPaddedImg;
433 save33()=localPaddedFourier;
435 integerToString(threadParams->imageIndex) +
"local_padded_fourier.spi");
438 save22().alias(*(threadParams->localPaddedFourier));
439 save22.write((std::string)
integerToString(threadParams->myThreadID) +
"_" +\
447 threadParams->read = 1;
483 if (threadParams->weight==0.0)
485 bool reprocessFlag = threadParams->reprocessFlag;
495 double iTs=1.0/parent->
Ts;
515 for (
size_t w = 0 ;
w <
YSIZE(*paddedFourier) ;
w++ )
517 if ( statusArray[
w]==0 )
521 maxAssignedRow =
w+minSeparation-1;
523 if ( maxAssignedRow > (
int)(
YSIZE(*paddedFourier)-1) )
524 maxAssignedRow =
YSIZE(*paddedFourier)-1;
526 for (
int in = (minAssignedRow - minSeparation) ;
in < (int)minAssignedRow ;
in ++ )
528 if ( (
in >= 0 ) && (
in < (int)
YSIZE(*paddedFourier) ))
530 if ( statusArray[
in] > -1 )
535 for (
int in = minAssignedRow ;
in <= (int)maxAssignedRow ;
in ++ )
537 if ( (
in >= 0 ) && (
in < (int)
YSIZE(*paddedFourier) ))
539 if ( statusArray[
in] == 0 )
541 statusArray[
in] = -1;
547 for (
int in = maxAssignedRow+1 ;
in <= (maxAssignedRow+minSeparation) ;
in ++ )
549 if ( (
in >= 0 ) && (
in < (int)
YSIZE(*paddedFourier) ))
551 if ( statusArray[
in] > -1 )
564 if ( breakCase ==
true )
576 double wCTF=1, wModulator=1.0;
586 for (
int i = minAssignedRow;
i <= maxAssignedRow ;
i ++ )
589 if ( statusArray[
i] == -1 )
600 if (hasCTF && !reprocessFlag)
602 XX(contFreq)=
XX(freq)*iTs;
603 YY(contFreq)=
YY(freq)*iTs;
604 threadParams->ctf.precomputeValues(
XX(contFreq),
YY(contFreq));
606 wCTF=threadParams->ctf.getValuePureNoKAt();
609 if (std::isnan(wCTF))
616 if (fabs(wCTF)<parent->
minCTF)
618 wModulator=fabs(wCTF);
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;
652 auto *ptrIn=(
double *)&(
A2D_ELEM(*paddedFourier,
i,
j));
655 for (
int intz =
ZZ(corner1); intz <=
ZZ(corner2); ++intz)
657 double z = intz -
ZZ(real_position);
669 for (
int inty =
YY(corner1); inty <=
YY(corner2); ++inty)
671 double y = inty -
YY(real_position);
683 for (
int intx =
XX(corner1); intx <=
XX(corner2); ++intx)
685 double x = intx -
XX(real_position);
699 for (
int intz =
ZZ(corner1); intz <=
ZZ(corner2); ++intz)
701 double z2 =
A1D_ELEM(z2precalculated,intz);
703 int izneg=
A1D_ELEM(zNegWrapped,intz);
705 for (
int inty =
YY(corner1); inty <=
YY(corner2); ++inty)
707 double y2z2 =
A1D_ELEM(y2precalculated,inty) + z2;
708 if (y2z2 > blobRadiusSquared)
711 int iyneg=
A1D_ELEM(yNegWrapped,inty);
713 int size1=
YXSIZE(VoutFourier)*izneg+(iyneg*
XSIZE(VoutFourier));
714 int size2=
YXSIZE(VoutFourier)*iz+(iy*
XSIZE(VoutFourier));
717 for (
int intx =
XX(corner1); intx <=
XX(corner2); ++intx)
721 double d2 =
A1D_ELEM(x2precalculated,intx) + y2z2;
723 if (d2 > blobRadiusSquared)
725 auto aux = (int)(d2 * iDeltaSqrt + 0.5);
726 double w =
VEC_ELEM(blobTableSqrt, aux)*threadParams->weight *wModulator;
732 std::cout <<
" gcurrent=" << gcurrent.transpose()
733 <<
" d=" <<
d << std::endl;
734 std::cout <<
" 1: intx=" << intx
736 <<
" intz=" << intz << std::endl;
742 std::cout <<
" 2: ix=" << ix <<
" iy=" << iy
743 <<
" iz=" << iz << std::endl;
746 bool conjugate=
false;
764 std::cout <<
" 3: ix=" << ix <<
" iy=" << iy
765 <<
" iz=" << iz <<
" conj=" 766 << conjugate << std::endl;
778 double wEffective=w*wCTF;
779 size_t memIdx=fixSize + ixp;
781 ptrOut[0] += wEffective * ptrIn[0];
785 ptrOut[1]-=wEffective*ptrIn[1];
787 ptrOut[1]+=wEffective*ptrIn[1];
797 for (
int w = (minAssignedRow - minSeparation) ;
w < minAssignedRow ;
w ++ )
799 if ( (
w >= 0 ) && (
w < (
int)
YSIZE(*paddedFourier) ))
801 if ( statusArray[
w] > 0 )
808 for (
int w = maxAssignedRow+1 ;
w <= (maxAssignedRow+minSeparation) ;
w ++ )
810 if ( (
w >= 0 ) && (
w < (int)
YSIZE(*paddedFourier) ))
812 if ( statusArray[
w] > 0 )
839 auto repaint = (int)ceil((
double)
SF.
size()/60);
843 int imgIndex = firstImageIndex;
846 int FSCIndex = (firstImageIndex + lastImageIndex)/2;
858 if ( imgIndex <= lastImageIndex )
891 if (imgno % repaint == 0)
910 save22().alias(*paddedFourier);
927 auto conserveRows=(size_t)ceil((
double)paddedFourier->
ydim *
maxResolution * 2.0);
928 conserveRows=(size_t)ceil((
double)conserveRows/2.0);
931 for (
size_t isym = 0; isym <
R_repository.size(); isym++)
949 for (
size_t i = 0 ;
i < paddedFourier->
ydim ;
i ++ )
951 if (
i >= conserveRows &&
i < (paddedFourier->
ydim-conserveRows))
991 if ( current_index == FSCIndex && saveFSC )
996 save.
write((std::string)
fn_fsc +
"_1_Weights.vol");
1000 save2.
write((std::string)
fn_fsc +
"_1_Fourier.vol");
1013 while ( processed );
1020 auxVolume.
write((std::string)
fn_fsc +
"_2_Weights.vol");
1024 auxFourierVolume.
write((std::string)
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());
1110 save.write((std::string)
fn_out +
"Weights.vol");
1112 FourierVolume save2;
1114 save2.write((std::string)
fn_out +
"FourierVol.vol");
1132 save.
write((std::string)
fn_out +
"hermiticWeights.vol");
1136 save2.
write((std::string)
fn_out +
"hermiticFourierVol.vol");
1149 Vout().setXmippOrigin();
1154 pad_relation = (pad_relation * pad_relation * pad_relation);
1157 double ipad_relation=1.0/pad_relation;
1158 double meanFactor2=0;
1167 A3D_ELEM(mVout,
k,
i,j) /= (ipad_relation*factor2*factor);
1168 meanFactor2+=factor2;
1171 A3D_ELEM(mVout,
k,
i,j) /= (ipad_relation*factor);
1190 int yHalf=
YSIZE(FourierWeights)/2;
1191 if (
YSIZE(FourierWeights)%2==0)
1193 int zHalf=
ZSIZE(FourierWeights)/2;
1194 if (
ZSIZE(FourierWeights)%2==0)
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++)
1202 for (
int i=1;
i<=yHalf;
i++)
1212 for (
int k=1;
k<=zHalf;
k++)
int thrWidth
How many image rows are processed at a time by a single thread.
int barrier_init(barrier_t *barrier, int needed)
void init_progress_bar(long total)
#define A2D_ELEM(v, i, j)
double alpha
Smoothness parameter.
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.
double getDoubleParam(const char *param, int arg=0)
virtual void read(int argc, const char **argv, bool reportErrors=true)
int NiterWeight
Number of iterations for the weight.
void getMatrices(int i, Matrix2D< double > &L, Matrix2D< double > &R, bool homogeneous=true) const
#define REPORT_ERROR(nerr, ErrormMsg)
double psi(const size_t n=0) const
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
constexpr int PROCESS_WEIGHTS
void sqrt(Image< double > &op)
int numThreads
Number of threads to use in parallel to process a single image.
constexpr int PROCESS_IMAGE
int readSymmetryFile(FileName fn_sym, double accuracy=SYM_ACCURACY)
barrier_t barrier
To create a barrier synchronization for threads.
FourierTransformer transformerImg
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)
Matrix2D< T > transpose() const
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(V)
double rot(const size_t n=0) const
Incorrect MultidimArray size.
#define DIGFREQ2FFT_IDX_DOUBLE(freq, size, idx)
void finishComputations(const FileName &out_name)
double weight(const size_t n=0) const
int * statusArray
A status array for each row in an image (processing, processed,etc..)
int barrier_destroy(barrier_t *barrier)
int readApplyGeo(const FileName &name, const MDRow &row, const ApplyGeoParams ¶ms=DefaultApplyGeoParams)
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 FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
Matrix1D< T > transpose() const
double tilt(const size_t n=0) const
void CenterFFT(MultidimArray< T > &v, bool forward)
#define A3D_ELEM(V, k, i, j)
ImageThreadParams * th_args
Contains parameters passed to each thread.
#define BLOB_TABLE_SIZE_SQRT
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
#define DIRECT_A1D_ELEM(v, i)
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
MultidimArray< std::complex< double > > VoutFourier
pthread_mutex_t workLoadMutex
Controls mutual exclusion on critical zones of code.
const char * getParam(const char *param, int arg=0)
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.
if(fabs(c[*nmax+ *nmax *c_dim1])==0.e0)
void readParams()
Read arguments from command line.
void resize(size_t Xdim, bool copy=true)
void progress_bar(long rlen)
void write(const FileName &fn) const
#define blob_Fourier_val(w, blob)
void addExampleLine(const char *example, bool verbatim=true)
MultidimArray< std::complex< double > > * localPaddedFourier
Matrix1D< double > Fourier_blob_table
double padding_factor_proj
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.
#define DIRECT_A3D_ELEM(v, k, i, j)
__device__ float FFT_IDX2DIGFREQ(int idx, int size)
pthread_t * th_ids
IDs for the threads.
#define M3x3_BY_V3x1(a, M, b)
Matrix1D< double > fourierBlobTableSqrt
double Sinc(double Argument)
MultidimArray< double > FourierWeights
virtual void setIO(const FileName &fn_in, const FileName &fn_out)
Functions of common reconstruction interface.
MultidimArray< std::complex< double > > VoutFourierTmp
MultidimArray< std::complex< double > > * paddedFourier
#define FIRST_XMIPP_INDEX(size)
double psi(const double x)
void write(const FileName &fn) const
FourierTransformer transformerVol
int order
Derivation order and Bessel function order.
Matrix2D< double > * localAInv
bool checkParam(const char *param)
int threadOpCode
Tells the threads what to do next.
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
Matrix2D< double > * symmetry
constexpr int EXIT_THREAD
std::vector< Matrix2D< double > > R_repository
void addUsageLine(const char *line, bool verbatim=false)
void initZeros(const MultidimArray< T1 > &op)
#define blob_val(r, blob)
#define fastIntWRAP(y, x, x0, xF)
Matrix1D< double > blobTableSqrt
#define LAST_XMIPP_INDEX(size)
double padding_factor_vol
void sumWithFile(const FileName &fn)
int barrier_wait(barrier_t *barrier)
void defineParams()
Read arguments from command line.
int getIntParam(const char *param, int arg=0)
double radius
Spatial radius in Universal System units.
void resize(size_t Ydim, size_t Xdim, bool noCopy=false)
#define intWRAP(x, x0, xF)
void addParamsLine(const String &line)
void forceWeightSymmetry(MultidimArray< double > &FourierWeights)
Force the weights to be symmetrized.
#define SPEED_UP_temps012
size_t rowsProcessed
Number of rows already processed on an image.