Xmipp  v3.23.11-Nereus
classify_first_split3.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar Sanchez Sorzano coss@cnb.csic.es
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #include "classify_first_split3.h"
27 #include "core/transformations.h"
28 #include "data/filters.h"
29 
30 // Read arguments ==========================================================
32 {
33  fnClasses = getParam("-i");
34  fnRoot = getParam("--oroot");
35  Niter = getIntParam("--Niter");
36  fnSym = getParam("--sym");
38  if ((externalMask=checkParam("--mask")))
39  mask.readParams(this);
40  if ((mpiUse=checkParam("--mpiCommand")))
41  mpiCommand = getParam("--mpiCommand");
42 }
43 
44 // Show ====================================================================
46 {
47  if (!verbose)
48  return;
49  std::cout
50  << "Input classes: " << fnClasses << std::endl
51  << "Output root: " << fnRoot << std::endl
52  << "N. iterations: " << Niter << std::endl
53  << "Symmetry: " << fnSym << std::endl
54  ;
55 }
56 
57 // usage ===================================================================
59 {
60  addUsageLine("Produce a first volume split from a set of directional classes using K-means");
61  addParamsLine(" -i <metadata> : Metadata with the list of directional classes with angles");
62  addParamsLine(" [--oroot <fnroot=split>] : Rootname for the output");
63  addParamsLine(" [--Niter <n=5000>] : Number of iterations");
64  addParamsLine(" [--sym <sym=c1>] : Symmetry");
65  addParamsLine(" [--mpiCommand <mystr>] : MPI command to parallelize the reconstruction process");
67 }
68 
69 
70 void ProgClassifyFirstSplit3::updateVolume(const std::vector<size_t> &objIds, const FileName &fnRoot, FourierProjector &projector)
71 {
72  MetaDataVec mdOut;
73  for(size_t i=0; i<objIds.size(); i++){
74  MDRowVec row;
75  md.getRow(row, objIds[i]);
76  mdOut.addRow(row);
77  }
78  mdOut.write(fnRoot+".xmd");
79 
80  String command;
81  if (!mpiUse){
82  command=formatString("xmipp_reconstruct_fourier -i %s.xmd -o %s.vol --max_resolution 0.25 --sym %s -v 0",
83  fnRoot.c_str(),fnRoot.c_str(), fnSym.c_str());
84  }else{
85  command=formatString(" `which xmipp_mpi_reconstruct_fourier` -i %s.xmd -o %s.vol --max_resolution 0.25 --sym %s -v 0",
86  fnRoot.c_str(),fnRoot.c_str(), fnSym.c_str());
87  command = mpiCommand + command;
88  }
89  //std::cout << command << std::endl;
90  int retval=system(command.c_str());
91  V.read(fnRoot+".vol");
92  V().setXmippOrigin();
93 
94  projector.updateVolume(V());
95 }
96 
97 
98 void ProgClassifyFirstSplit3::calculateProjectedIms (size_t id, double &corrI_P1, double &corrI_P2){
99 
100  //Project the first volume with the parameters in the randomly selected image
101  double rot, tilt, psi, x, y;
102  bool flip;
103  MDRowVec currentRow;
104  FileName fnImg;
106 
107  md.getRow(currentRow, id);
108  currentRow.getValue(MDL_IMAGE,fnImg);
109  imgV.read(fnImg);
110  currentRow.getValue(MDL_ANGLE_ROT,rot);
111  currentRow.getValue(MDL_ANGLE_TILT,tilt);
112  currentRow.getValue(MDL_ANGLE_PSI,psi);
113  currentRow.getValue(MDL_SHIFT_X,x);
114  currentRow.getValue(MDL_SHIFT_Y,y);
115  currentRow.getValue(MDL_FLIP,flip);
116  A.initIdentity(3);
117  MAT_ELEM(A,0,2)=x;
118  MAT_ELEM(A,1,2)=y;
119  if (flip)
120  {
121  MAT_ELEM(A,0,0)*=-1;
122  MAT_ELEM(A,0,1)*=-1;
123  MAT_ELEM(A,0,2)*=-1;
124  }
125  auto xdim = (int)XSIZE(V());
126  projectVolume(*projectorV1, PV, xdim, xdim, rot, tilt, psi);
127  applyGeometry(xmipp_transformation::LINEAR,projV,PV(),A,xmipp_transformation::IS_INV,xmipp_transformation::DONT_WRAP,0.);
128  corrI_P1 = correlation(imgV(), projV);
129 
130  projectVolume(*projectorV2, PV, xdim, xdim, rot, tilt, psi);
131  applyGeometry(xmipp_transformation::LINEAR,projV,PV(),A,xmipp_transformation::IS_INV,xmipp_transformation::DONT_WRAP,0.);
132  corrI_P2 = correlation(imgV(), projV);
133 }
134 
136 {
137  show();
138 
140 
141  countSwap=0;
142  countRandomSwap=0;
143  countNormalSwap=0;
144  double th=0.05;
145 
146  // Generate initial volumes
147  md.read(fnClasses);
148  std::vector<size_t> objIds1, objIds2;
149 
150  for (size_t objId : md.ids()) {
151  if(rnd_unif()<0.5)
152  objIds1.push_back(objId);
153  else
154  objIds2.push_back(objId);
155  }
156 
159 
160  updateVolume(objIds1, fnRoot+"_avg1", *projectorV1);
161  updateVolume(objIds2, fnRoot+"_avg2", *projectorV2);
162 
164  Image<double> img1, img2;
165  MultidimArray<double> imgProjectedV1, imgProjectedV2;
166 
167  for (int n=0; n<Niter; n++)
168  {
169  // Select a random image from the subset of every volume
170  size_t idx1 = floor(rnd_unif(0,objIds1.size()));
171  size_t idx2 = floor(rnd_unif(0,objIds2.size()));
172  size_t id1 = objIds1[idx1];
173  size_t id2 = objIds2[idx2];
174 
175  bool swap=false;
176  if(rnd_unif()<th){
177  swap = true;
178  countRandomSwap++;
179  //std::cout << "RANDOM" << std::endl;
180  }
181  else
182  {
183  //Calculating correlations
184  double corrI1_P1, corrI2_P1, corrI2_P2, corrI1_P2;
185  calculateProjectedIms(id1, corrI1_P1, corrI1_P2);
186  calculateProjectedIms(id2, corrI2_P1, corrI2_P2);
187 
188  //std::cout << " corrI1_P1 = " << corrI1_P1 << " corrI2_P1 = " << corrI2_P1
189  // << " corrI2_P2 = " << corrI2_P2 << " corrI1_P2 = " << corrI1_P2 << std::endl;
190  if (corrI1_P2>corrI1_P1 && corrI2_P1>corrI2_P2){
191  swap=true;
192  countNormalSwap++;
193  }
194 
195  }
196 
197  if(swap)
198  {
199  countSwap++;
200  //std::cout << "SWAPPING" << std::endl;
201  //Generate metadata with swapped images
202  objIds1.erase(objIds1.begin()+idx1);
203  objIds2.erase(objIds2.begin()+idx2);
204  objIds1.push_back(id2);
205  objIds2.push_back(id1);
206  updateVolume(objIds1, fnRoot+"_avg1", *projectorV1);
207  updateVolume(objIds2, fnRoot+"_avg2", *projectorV2);
208 
209  //char c;
210  //std::cout << "Press any key" << std::endl;
211  //std::cin >> c;
212  }
213 
214  if (countSwap>0){
215  th = (double)countSwap/(double)(n*10); //to make the th lower with time
216  //std::cout << " th = " << th << std::endl;
217  }
218 
219  progress_bar(n);
220 
221  }
222  progress_bar(Niter);
223  std::cout << " Niter = " << Niter << " Images in set1 = " << objIds1.size() << " Images in set2 = " << objIds2.size() << " countRandomSwap = " << countRandomSwap << " countNormalSwap = " << countNormalSwap << std::endl;
224  //deleteFile(fnSubset);
225  //deleteFile(fnSubsetVol);
226 
227  // Save volumes
228  //V1.write(fnRoot+"_v1.vol");
229  //V2.write(fnRoot+"_v2.vol");
230 }
void init_progress_bar(long total)
Rotation angle of an image (double,degrees)
__host__ __device__ float2 floor(const float2 v)
double correlation(const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > *mask=nullptr, int l=0, int m=0, int q=0)
Definition: filters.h:249
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
void readParams()
Read argument from command line.
Tilting angle of an image (double,degrees)
static double * y
Shift for the image in the X axis (double)
void applyGeometry(int SplineDegree, MultidimArray< std::complex< double > > &V2, const MultidimArray< std::complex< double > > &V1, const Matrix2D< double > &A, bool inv, bool wrap, std::complex< double > outside, MultidimArray< double > *BcoeffsPtr)
void updateVolume(MultidimArray< double > &V)
int allowed_data_types
Definition: mask.h:495
Special label to be used when gathering MDs in MpiMetadataPrograms.
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const
virtual IdIteratorProxy< false > ids()
std::unique_ptr< MDRow > getRow(size_t id) override
doublereal * x
#define i
size_t addRow(const MDRow &row) override
T & getValue(MDLabel label)
static void defineParams(XmippProgram *program, int allowed_data_types=ALL_KINDS, const char *prefix=nullptr, const char *comment=nullptr, bool moreOptions=false)
Definition: mask.cpp:1203
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
double rnd_unif()
const char * getParam(const char *param, int arg=0)
void defineParams()
Define parameters.
Flip the image? (bool)
#define XSIZE(v)
void progress_bar(long rlen)
void projectVolume(FourierProjector &projector, Projection &P, int Ydim, int Xdim, double rot, double tilt, double psi, const MultidimArray< double > *ctf)
void readParams(XmippProgram *program)
Definition: mask.cpp:1284
MultidimArray< double > projV
int verbose
Verbosity level.
void calculateProjectedIms(size_t id, double &corrI_P1, double &corrI_P2)
FourierProjector * projectorV2
std::string String
Definition: xmipp_strings.h:34
double psi(const double x)
#define INT_MASK
Definition: mask.h:385
void updateVolume(const std::vector< size_t > &objIds1, const FileName &fnOut, FourierProjector &projector)
String formatString(const char *format,...)
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)
Shift for the image in the Y axis (double)
void addUsageLine(const char *line, bool verbatim=false)
unsigned int randomize_random_generator()
int getIntParam(const char *param, int arg=0)
FourierProjector * projectorV1
int * n
Name of an image (std::string)
void addParamsLine(const String &line)
void initIdentity()
Definition: matrix2d.h:673