40 if (!
node->isMaster())
67 <<
"Input file: " <<
fnIn << std::endl
68 <<
"Output root: " <<
fnRoot << std::endl
69 <<
"Padding: " <<
pad << std::endl
70 <<
"MaxFreq: " <<
fmax << std::endl
71 <<
"Zoom: " <<
zoom << std::endl
72 <<
"Sigma1: " <<
sigma1 << std::endl
73 <<
"Sigma2: " <<
sigma2 << std::endl
74 <<
"N.Classes: " <<
nref << std::endl
76 <<
"Iterations: " <<
Niter << std::endl
77 <<
"Do phase: " <<
doPhase << std::endl
84 addUsageLine(
"Classify in 2D using Fourier Transform based Translational and Rotational Invariants");
85 addParamsLine(
" -i <infile> : Metadata or stack with input images");
86 addParamsLine(
" --oroot <rootname> : Rootname for output files");
88 addParamsLine(
" [--padding <p=4>] : Padding factor (it can be a non-integer factor");
89 addParamsLine(
" [--maxfreq <f=0.25>] : Maximum frequency for the spectrum classification");
91 addParamsLine(
" [--zoom <f=1>] : Perform polar transformation with this zoom factor (>=1) at low frequencies");
92 addParamsLine(
" : Log-polar corresponds to an approximate factor of 2.8");
93 addParamsLine(
" [--nmin <n=5>] : Minimum number of images in a class to be considered as such");
94 addParamsLine(
" [--iter <n=10>] : Number of iterations for FRTTI classfication.");
95 addParamsLine(
" : At each iteration, those classes whose size");
96 addParamsLine(
" : is smaller than nmin are removed from the classification");
97 addParamsLine(
" [--sigma1+ <s=0.707>] : First weight in the FTTRI, see paper for documentation");
98 addParamsLine(
" [--sigma2+ <s=1.5>] : Second weight in the FTTRI, see paper for documentation");
99 addParamsLine(
" [--doPhase] : Do also an amplitude and phase classification");
100 addExampleLine(
"mpirun -np 4 `which xmipp_mpi_classify_FTTRI` -i images.xmd --oroot class --nref 64");
109 size_t zdim, ydim, xdim, ndim;
111 if (
node->isMaster())
129 if (
node->isMaster())
133 mask().initZeros(xdim,xdim);
134 mask().setXmippOrigin();
135 double R2=0.25*xdim*xdim;
143 #ifndef FTTRI_ALREADY_COMPUTED 146 fnFTTRI.deleteFile();
157 std::cerr <<
"Computing FTTRI ...\n";
177 avgMagFTI().initZeros(padI);
181 for (
size_t idx=first; idx<=last; ++idx)
187 I().setXmippOrigin();
203 magFTI.
window(filteredMagFTI,
226 FFT_magnitude(FTpolarFilteredMagFTI,magFTpolarFilteredMagFTI);
227 CenterFFT(magFTpolarFilteredMagFTI,
true);
231 magFTpolarFilteredMagFTI.
window(centralMagFTpolarFilteredMagFTI(),
234 centralMagFTpolarFilteredMagFTI().rangeAdjust(1,255);
235 centralMagFTpolarFilteredMagFTI().selfLog10();
245 if (
node->isMaster())
253 std::vector< MultidimArray<double> > fttri;
256 for(
int i=0;
i<N;
i++)
260 fttri.push_back(aux());
264 for(
int i=0;
i<N-1;
i++)
267 for(
int j=
i+1;
j<N;
j++, idx++)
276 std::cout <<
"Initial epsilon range: [" <<
dMin <<
"," <<
dMax <<
"]\n";
284 const size_t unroll=4;
286 double* ptrI=
nullptr;
287 double* ptrJ=
nullptr;
290 n<
nmax; n+=unroll, ptrI+=unroll, ptrJ+=unroll)
292 double diff0=*ptrI-*ptrJ;
294 double diff1=*(ptrI+1)-*(ptrJ+1);
296 double diff2=*(ptrI+1)-*(ptrJ+1);
298 double diff3=*(ptrI+1)-*(ptrJ+1);
304 double diff0=*ptrI-*ptrJ;
312 size_t ¤tPointer,
size_t remaining)
315 if (
node->isMaster())
322 auto skip=(size_t) (remaining*
rnd_unif());
332 MPI_Bcast(¤tPointer, 1, MPI_LONG, 0, MPI_COMM_WORLD);
340 MPI_Recv(&length, 1, MPI_LONG, rank, 0, MPI_COMM_WORLD, &status);
342 MPI_Recv(&(
VEC_ELEM(aux,0)), length, MPI_LONG, rank, 0, MPI_COMM_WORLD, &status);
353 MPI_Send(&(
VEC_XSIZE(aux)), 1, MPI_LONG, rank, 0, MPI_COMM_WORLD);
362 size_t currentPointer=0;
366 std::vector<size_t> inNewClass;
373 fttriSeed.
read(fnSeed);
375 if (
node->isMaster())
376 inNewClass.push_back(currentPointer);
384 fftriCandidate.
read(fnCandidate);
386 if (distance<=epsilon)
387 inNewClass.push_back(
i);
391 if (
node->isMaster())
394 for (
size_t rank=1; rank<
node->size; rank++)
397 for (
size_t rank=1; rank<
node->size; rank++)
409 size_t imax=inNewClass.size();
410 for (
size_t i=0;
i<imax; ++
i)
413 if (
node->isMaster())
424 MPI_Bcast(&epsilon, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
427 double objective=fabs(retval-
nref);
434 std::cout <<
"Trying " << epsilon <<
" -> " << retval << std::endl;
440 if (
node->isMaster())
442 std::cerr <<
"Computing epsilon classification ..." << std::endl;
445 double epsilonLeft=
dMin;
446 double epsilonRight=
dMax;
457 epsilonRight=epsilonLeft;
464 else if (
nref<Nright)
466 epsilonLeft=epsilonRight;
476 double epsilonCentral=0.5*(epsilonLeft+epsilonRight);
479 if (Ncentral==
nref || Ndivisions==10)
484 epsilonLeft=epsilonCentral;
489 epsilonRight=epsilonCentral;
495 double finalize=-1e6;
496 MPI_Bcast(&finalize, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
504 MPI_Bcast(&epsilon, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
524 if (
node->isMaster())
528 std::vector< EpsilonClass > goodEpsilonClasses;
530 size_t imagesRemoved=0;
531 size_t classesRemoved=0;
533 for (
size_t i=0;
i<imax;
i++)
536 size_t nmax=class_i.size();
548 std::cout <<
"Removal of " << imagesRemoved <<
" images from " 549 << classesRemoved <<
" classes for being in too small classes\n";
568 const std::vector<size_t> &class_i_members=class_i.
memberIdx;
580 candidate.
read(fnCandidate);
581 candidate().setXmippOrigin();
585 d=
alignImages(seed,candidate(),M,xmipp_transformation::WRAP,aux,aux2,aux3);
586 if ((d>maxDistance && FTTRI) || (d<maxDistance && !FTTRI))
597 if (
node->isMaster())
599 std::cerr <<
"Splitting large classes ..." << std::endl;
612 std::vector<size_t> &class_0_members=class_0.
memberIdx;
622 seed1().setXmippOrigin();
629 seed1().setXmippOrigin();
638 seed2().setXmippOrigin();
643 c1.
memberIdx.push_back(class_0_members[n1]);
644 c2.
memberIdx.push_back(class_0_members[n2]);
645 int nmax=class_0_members.size();
652 size_t trueIdx=class_0_members[
n];
657 candidate.
read(fnCandidate);
670 candidate().setXmippOrigin();
671 candidateCopy=candidate();
672 double d1=
alignImages(mSeed1,candidate(),M,xmipp_transformation::WRAP,aux,aux2,aux3);
673 double d2=
alignImages(mSeed2,candidateCopy,M,xmipp_transformation::WRAP,aux,aux2,aux3);
691 MPI_Bcast(&classSize, 1, MPI_INT, 0, MPI_COMM_WORLD);
704 MPI_Bcast(&classSize, 1, MPI_INT, 0, MPI_COMM_WORLD);
705 MPI_Bcast(buffer, classSize, MPI_LONG, 0, MPI_COMM_WORLD);
707 for (
size_t n=0;
n<classSize; ++
n)
719 fnCentroids=
fnRoot+
"_FTTRI_centroids.mrcs";
721 fnCentroids=
fnRoot+
"_image_centroids.mrcs";
722 if (
node->isMaster())
724 std::cerr <<
"Computing class centroids ..." << std::endl;
729 size_t Xdim, Ydim, Zdim, Ndim;
737 if (
node->isMaster())
759 size_t nmax=class_i.size();
768 size_t trueIdx=class_i[
n];
772 candidate.
read(fnCandidate);
773 mCentroid+=candidate();
783 mCentroid/=(double)nmax;
789 size_t trueIdx=class_i[
n];
791 candidate.
read(fnCandidate);
794 intraclassDistance.
sort(sortedDistance);
796 double limit=
A1D_ELEM(sortedDistance,idxLimit);
804 if (
A1D_ELEM(intraclassDistance,
n)>limit)
806 size_t trueIdx=class_i[
n];
808 candidate.
read(fnCandidate);
809 mCentroid+=candidate();
825 if (
node->isMaster())
828 if (
node->isMaster())
833 MPI_MAX, MPI_COMM_WORLD);
835 if (
node->isMaster())
836 std::cerr <<
"Maximum epsilon: " <<
epsilonMax << std::endl;
843 if (
node->isMaster())
844 std::cerr <<
"Computing class neighbours ..." << std::endl;
857 for (
size_t i1=0; i1<
nref; ++i1)
864 for (
size_t i1=0; i1<nref-1; ++i1)
867 for (
size_t i2=i1+1; i2<
nref; ++i2)
888 if (
node->isMaster())
890 for (
size_t i1=0; i1<nref-1; ++i1)
894 for (
size_t i2=i1+1; i2<
nref; ++i2, ++count)
896 if (((count+1)%
node->size)==
node->rank)
900 centroid_i2=centroid_i2p;
901 A2D_ELEM(corr,i2,i1)=
A2D_ELEM(corr,i1,i2)=
alignImages(centroid_i1,centroid_i2,M,xmipp_transformation::WRAP,aux,aux2,aux3);
904 if (
node->isMaster())
907 MPI_Allreduce(MPI_IN_PLACE,
MULTIDIM_ARRAY(corr), nref*nref, MPI_DOUBLE,
908 MPI_MAX, MPI_COMM_WORLD);
909 if (
node->isMaster())
915 const int Kneighbours=2;
916 for (
size_t i1=0; i1<
nref; ++i1)
921 for (
int k = 0;
k < Kneighbours;
k++)
922 neighbours_i.push_back(idx(nref -
k - 1) - 1);
933 if (
node->isMaster())
935 std::cerr <<
"Reassigning images to classes ..." << std::endl;
959 int nmax=class_i.size();
960 int neighMax=neighbours_i.size();
966 int trueIdx=class_i[
n];
971 candidate.
read(fnCandidate);
972 candidate().setXmippOrigin();
981 candidateCopy=candidate();
982 bestD=
alignImages(own_class,candidateCopy,M,xmipp_transformation::WRAP,aux,aux2,aux3);
987 bool alreadyChanged=
false;
988 for (
int neigh=0; neigh<neighMax; neigh++)
990 int neighbourIdx=neighbours_i[neigh];
998 candidateCopy=candidate();
999 d=
alignImages(neighbour,candidateCopy,M,xmipp_transformation::WRAP,aux,aux2,aux3);
1001 if ((d<bestD && FTTRI) || (d>bestD && !FTTRI))
1004 VEC_ELEM(newAssignment,trueIdx)=neighbourIdx;
1005 if (!alreadyChanged)
1008 alreadyChanged=
true;
1013 if (
node->isMaster())
1018 MPI_Allreduce(MPI_IN_PLACE, &(
VEC_ELEM(newAssignment,0)),
VEC_XSIZE(newAssignment), MPI_SHORT,
1019 MPI_MAX, MPI_COMM_WORLD);
1020 MPI_Allreduce(MPI_IN_PLACE, &changes, 1, MPI_LONG, MPI_SUM, MPI_COMM_WORLD);
1021 if (
node->isMaster())
1024 std::cerr <<
"Number of images changed: " << changes << std::endl;
1028 std::vector<EpsilonClass> newBestEpsilonClasses;
1029 newBestEpsilonClasses.resize(nref);
1032 newBestEpsilonClasses[
VEC_ELEM(newAssignment,
i)].memberIdx.push_back(
i);
1056 for (
int i=0;
i<imax;
i++)
1060 size_t nmax=class_i.size();
1076 candidate.
read(fnCandidate);
1087 int trueIdx=class_i[
n];
1089 candidate.
read(fnCandidate);
1090 candidate().setXmippOrigin();
1091 A1D_ELEM(distance,
n)=1-
alignImages(centroid,candidate(),M,xmipp_transformation::WRAP,aux,aux2,aux3);
1101 size_t trueId=
imgsId[class_i[trueIdx]];
1103 size_t idClass=MDclass.
addRow(row);
1118 fnCentroids=
fnRoot+
"_image_centroids.mrcs";
1119 if (
node->isMaster())
1121 std::cerr <<
"Aligning images within class ..." << std::endl;
1122 size_t Xdim, Ydim, Zdim, Ndim;
1126 node->barrierWait();
1129 if (
node->isMaster())
1144 size_t nmax=class_i.size();
1152 size_t trueIdx=class_i[
n];
1153 size_t trueId=
imgsId[trueIdx];
1165 for (
size_t objId : MDclass.
ids())
1168 candidate.
read(fnCandidate);
1169 candidate().setXmippOrigin();
1172 double scale, shiftx, shifty,
psi;
1185 if (
node->isMaster())
1188 node->barrierWait();
1189 if (
node->isMaster())
1196 MDclass.
read(fnClass);
1198 fnClass.deleteFile();
1203 MDsummary.
read(classesBlock);
1206 for (
size_t objId : MDsummary.
ids())
1208 fnRef.
compose(nref++,fnCentroids);
1220 #ifndef FTTRI_ALREADY_COMPUTED 1230 if (
node->isMaster())
1231 std::cout <<
"Final epsilon: " <<
bestEpsilon <<
"\n";
1235 if (
node->isMaster())
1236 std::cout << std::endl <<
"Amplitude classification ..." << std::endl;
1239 if (
node->isMaster())
1240 std::cout << std::endl <<
"Iteration " <<
n << std::endl;
1249 if (
node->isMaster())
1255 if (
node->isMaster())
1256 std::cout << std::endl <<
"Amplitude and phase classification ..." << std::endl;
1259 if (
node->isMaster())
1260 std::cout << std::endl <<
"Iteration " <<
n << std::endl;
1267 if (
node->isMaster())
1272 node->barrierWait();
double sigma1
First weight.
double zoom
Zoom factor for polar conversion.
void init_progress_bar(long total)
void removeSmallClasses()
Remove small classes.
void skipRandomNumberOfUnassignedClasses(size_t ¤tPointer, size_t remaining)
Skip random number of unassigned classes.
void min(Image< double > &op1, const Image< double > &op2)
void searchOptimalEpsilon()
Search for optimal epsilon.
#define A2D_ELEM(v, i, j)
double pad
Padding factor.
double getDoubleParam(const char *param, int arg=0)
void sendListToRank(std::vector< size_t > &listToSend, int rank)
__host__ __device__ float2 floor(const float2 v)
int Niter
Number of iterations.
void image_convertCartesianToPolar_ZoomAtCenter(const MultidimArray< double > &in, MultidimArray< double > &out, Matrix1D< double > &R, double zoomFactor, double Rmin, double Rmax, int NRSteps, float angMin, double angMax, int NAngSteps)
double alignImages(const MultidimArray< double > &Iref, const AlignmentTransforms &IrefTransforms, MultidimArray< double > &I, Matrix2D< double > &M, bool wrap, AlignmentAux &aux, CorrelationAux &aux2, RotationalCorrelationAux &aux3)
#define REPORT_ERROR(nerr, ErrormMsg)
point centroid(const std::vector< point > &pts)
void sort(MultidimArray< T > &result) const
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(m)
void produceFTTRI()
Produce invariants.
void resizeNoCopy(const MultidimArray< T1 > &v)
void computeClassNeighbours(bool FTTRI)
Compute centroid neighbours.
double fmax
Maximum frequency (normalized to 0.5)
void aliasImageInStack(const MultidimArray< T > &m, size_t select_image)
std::shared_ptr< MpiNode > node
bool getTasks(size_t &first, size_t &last)
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)
void estimateEpsilonInitialRange()
Estimate first epsilon range.
std::vector< size_t > memberIdx
#define MULTIDIM_ARRAY(v)
void compose(const String &str, const size_t no, const String &ext="")
size_t Rmax
Maximum frequency in pixels.
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)
size_t nMinImages
Minimum number of images in a class.
std::vector< size_t > imgsId
void CenterFFT(MultidimArray< T > &v, bool forward)
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
int argc
Original command line arguments.
Image< double > fttriCentroids
Matrix1D< unsigned char > notAssigned
void writeResults(bool FTTRI)
void window(MultidimArray< T1 > &result, int n0, int z0, int y0, int x0, int nF, int zF, int yF, int xF, T1 init_value=0) const
Matrix1D< double > classEpsilon
const char * getParam(const char *param, int arg=0)
size_t wrapperFitness(double epsilon)
Function to optimize.
MpiTaskDistributor * taskDistributor
double fttri_distance(const MultidimArray< double > &fttri_i, const MultidimArray< double > &fttri_j)
Distance between two invariants.
void readParams()
Read argument from command line.
void receiveListFromRank(std::vector< size_t > &listToKeepIt, int rank)
void resize(size_t Xdim, bool copy=true)
void alignSetOfImages(MetaData &MD, MultidimArray< double > &Iavg, int Niter, bool considerMirror)
void progress_bar(long rlen)
void max(Image< double > &op1, const Image< double > &op2)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
size_t nref
Desired number of classes.
#define DIRECT_MULTIDIM_ELEM(v, n)
void addExampleLine(const char *example, bool verbatim=true)
FileName fnRoot
Output rootname.
__host__ __device__ float length(float2 v)
double sum(bool average=false) const
void createEmptyFile(const FileName &filename, int xdim, int ydim, int Zdim, size_t select_img, bool isStack, int mode, int _swapWrite, const MDRowVec *md)
int verbose
Verbosity level.
void alignImagesWithinClasses()
bool operator()(EpsilonClass const &rpStart, EpsilonClass const &rpEnd)
void sort(struct DCEL_T *dcel)
std::vector< EpsilonClass > bestEpsilonClasses
FileName fnIn
Input selfile.
void getRow(size_t i, MultidimArray< T > &v) const
TYPE distance(struct Point_T *p, struct Point_T *q)
bool doPhase
Do phase optimization.
#define MATRIX1D_ARRAY(v)
size_t reassignImagesToClasses(bool FTTRI)
Reassign images to image classes.
#define FIRST_XMIPP_INDEX(size)
Matrix1D< unsigned char > notAssigned0
void defineParams()
Usage.
double psi(const double x)
void produceSideInfo()
Produce side info.
bool fileExists(const char *filename)
String formatString(const char *format,...)
void splitLargeClasses(bool FTTRI)
Split large classes.
void resizeNoCopy(int Xdim)
bool checkParam(const char *param)
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
Incorrect MultidimArray dimensions.
Image< double > imageCentroids
void epsilonClassification(double epsilon)
Epsilon classification.
void addUsageLine(const char *line, bool verbatim=false)
void initZeros(const MultidimArray< T1 > &op)
void computeClassCentroids(bool FTTRI)
#define LAST_XMIPP_INDEX(size)
int getIntParam(const char *param, int arg=0)
int findFarthest(const MultidimArray< double > &seed, const EpsilonClass &class_i, bool FTTRI)
void FFT_magnitude(const MultidimArray< std::complex< double > > &v, MultidimArray< double > &mag)
ProgClassifyFTTRI(int argc, char **argv)
Empty constructor.
void indexSort(MultidimArray< int > &indx) const
std::vector< EpsilonClass > epsilonClasses
void addParamsLine(const String &line)
double sigma2
Second weight.