Xmipp  v3.23.11-Nereus
classify_first_split.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_split.h"
27 #include <core/symmetries.h>
28 #include <data/filters.h>
29 #include "core/metadata_db.h"
30 
31 // Read arguments ==========================================================
33 {
34  fnClasses = getParam("-i");
35  fnRoot = getParam("--oroot");
36  Nrec = getIntParam("--Nrec");
37  Nsamples = getIntParam("--Nsamples");
38  fnSym = getParam("--sym");
39  alpha = getDoubleParam("--alpha");
41  if ((externalMask=checkParam("--mask")))
42  mask.readParams(this);
43 }
44 
45 // Show ====================================================================
47 {
48  if (!verbose)
49  return;
50  std::cout
51  << "Input classes: " << fnClasses << std::endl
52  << "Output root: " << fnRoot << std::endl
53  << "N. reconstructions: " << Nrec << std::endl
54  << "N. samples: " << Nsamples << std::endl
55  << "Symmetry: " << fnSym << std::endl
56  << "Alpha: " << alpha << std::endl
57  ;
58 }
59 
60 // usage ===================================================================
62 {
63  addUsageLine("Produce a first volume split from a set of directional classes");
64  addParamsLine(" -i <metadata> : Metadata with the list of directional classes with angles");
65  addParamsLine(" [--oroot <fnroot=split>] : Rootname for the output");
66  addParamsLine(" [--Nrec <n=100>] : Number of reconstructions");
67  addParamsLine(" [--Nsamples <n=8>] : Number of images in each reconstruction");
68  addParamsLine(" [--sym <sym=c1>] : Symmetry");
69  addParamsLine(" [--alpha <a=0.05>] : Alpha for the generation of the two separated volumes");
71 }
72 
74 {
75  show();
76 
77  MetaDataDb md, mdRec;
78  md.read(fnClasses);
79 
80  // Generate the mean
81  std::cerr << "Reconstructing average" << std::endl;
82  String command=formatString("xmipp_reconstruct_fourier -i %s -o %s_avg.vol --max_resolution 0.25 --sym %s -v 0",fnClasses.c_str(),fnRoot.c_str(), fnSym.c_str());
83  int retval=system(command.c_str());
84  Image<double> Vavg;
85  Vavg.read(fnRoot+"_avg.vol");
86  Vavg().setXmippOrigin();
87 
88  SymList SL;
90  int Nsym=SL.symsNo()+1;
91  Matrix2D<double> E, L, R;
92 
93  FileName fnSubset=fnRoot+"_subset.xmd";
94  FileName fnSubsetVol=fnRoot+"_subset.vol";
95  command=formatString("xmipp_reconstruct_fourier -i %s -o %s --max_resolution 0.25 -v 0",fnSubset.c_str(),fnSubsetVol.c_str());
96 
97  Image<double> V;
98  Nvols = 0;
99  std::cerr << "Generating reconstructions from random subsets ...\n";
102  pca.maxzn=2; // Skip outliers
103  for (int n=0; n<Nrec; n++)
104  {
105  // Generate random subset and randomize angles according to symmetry
106  mdRec.selectRandomSubset(md,Nsamples);
107  if (Nsym>1)
108  {
109  double rot, tilt, psi, rotp, tiltp, psip;
110  for (size_t objId : mdRec.ids())
111  {
112  int idx=round(rnd_unif(0,Nsym));
113  if (idx>0)
114  {
115  mdRec.getValue(MDL_ANGLE_ROT, rot, objId);
116  mdRec.getValue(MDL_ANGLE_TILT, tilt, objId);
117  mdRec.getValue(MDL_ANGLE_PSI, psi, objId);
118 
119  SL.getMatrices(idx - 1, L, R, false);
120  Euler_apply_transf(L, R, rot, tilt, psi, rotp, tiltp, psip);
121 
122  mdRec.setValue(MDL_ANGLE_ROT, rotp, objId);
123  mdRec.setValue(MDL_ANGLE_TILT, tiltp, objId);
124  mdRec.setValue(MDL_ANGLE_PSI, psip, objId);
125  }
126  }
127  }
128  mdRec.write(fnSubset);
129 
130  // Perform reconstruction
131  retval=system(command.c_str());
132  V.read(fnSubsetVol);
133  V().setXmippOrigin();
134 // V.write(formatString("%s_%05d.vol",fnRoot.c_str(),n));
135  V()-=Vavg();
136 // V.write(formatString("%s_%05d_diff.vol",fnRoot.c_str(),n));
137  updateWithNewVolume(V());
138  zn(n)=pca.getCurrentProjection();
139 // std::cout << "zn=" << zn(n) << std::endl;
140 // char c; std::cin >> c;
141 
142  progress_bar(n);
143  }
144  progress_bar(Nrec);
145  deleteFile(fnSubset);
146  deleteFile(fnSubsetVol);
147 
148  // Save average and first principal component
149  Image<double> V1, V2, Vdiff;
150  vectorToVolume(pca.c1,V1());
151  V1.write(fnRoot+"_pc1.vol");
152  vectorToVolume(pca.ysum,V1());
153  V1()/=pca.N;
154  V1()+=Vavg();
155  V2()=V1();
156 
157  // Analyze now the projections
158  MultidimArray<double> znSorted;
159  zn.sort(znSorted);
160  double z1=znSorted(int(alpha/2*Nrec));
161  double z2=znSorted(int((1-alpha/2)*Nrec));
162  std::cout << "z1=" << z1 << " z2=" << z2 << std::endl;
163 
164  v=pca.c1;
165  v*=z1;
166  vectorToVolume(v,Vdiff());
167  V1()+=Vdiff();
168  V1.write(fnRoot+"_v1.vol");
169 
170  v=pca.c1;
171  v*=z2;
172  vectorToVolume(v,Vdiff());
173  V2()+=Vdiff();
174  V2.write(fnRoot+"_v2.vol");
175 
176  // Check if the mirrored volume is better
177  double corr=correlationIndex(V1(),V2());
178  V2().selfReverseX();
179  V2.write(fnRoot+"_v2mirrored.vol");
180  command="xmipp_volume_align --i1 "+fnRoot+"_v1.vol --i2 "+fnRoot+"_v2mirrored.vol --rot 0 360 15 --tilt 0 360 15 --psi 0 360 15 --apply";
181  std::cout << command << std::endl;
182  int ok=system(command.c_str());
183  command="xmipp_volume_align --i1 "+fnRoot+"_v1.vol --i2 "+fnRoot+"_v2mirrored.vol --local --apply";
184  std::cout << command << std::endl;
185  ok=system(command.c_str());
186  V2.read(fnRoot+"_v2mirrored.vol");
187  double corrM=correlationIndex(V1(),V2());
188  std::cout << "Correlation unmirrored: " << corr << std::endl;
189  std::cout << "Correlation mirrored: " << corrM << std::endl;
190  if (corrM>corr)
191  copyImage(fnRoot+"_v2mirrored.vol",fnRoot+"_v2.vol");
192  deleteFile(fnRoot+"_v2mirrored.vol");
193 
194  V2.read(fnRoot+"_v2.vol");
195  V1().setXmippOrigin();
196  V2().setXmippOrigin();
197  Vdiff()=V1();
198  Vdiff()-=V2();
199  Vdiff.write(fnRoot+"_pc1.vol");
200 }
201 
203 {
205  const MultidimArray<int> &mmask = mask.get_binary_mask();
206  size_t idx=0;
208  if (DIRECT_MULTIDIM_ELEM(mmask,n))
210 }
211 
213 {
214  const MultidimArray<int> &mmask = mask.get_binary_mask();
215  V.initZeros(mmask);
216  size_t idx=0;
218  if (DIRECT_MULTIDIM_ELEM(mmask,n))
220 }
221 
223 {
224  if (Nvols==0)
225  {
226  if (!externalMask)
227  {
229  mask.mode = INNER_MASK;
230  mask.R1 = XSIZE(V)/2;
231  }
232  mask.generate_mask(V);
233 
234  // Resize some internal variables
235  maskSize=(size_t) mask.get_binary_mask().sum();
236  }
237 
238  volumeToVector(V,v);
239  pca.addVector(v);
240  Nvols++;
241 }
242 
void selectRandomSubset(const MetaData &mdIn, size_t numberOfObjects, const MDLabel sortLabel=MDL_OBJID) override
void init_progress_bar(long total)
Rotation angle of an image (double,degrees)
void volumeToVector(const MultidimArray< double > &V, MultidimArray< double > &v)
void updateWithNewVolume(const MultidimArray< double > &V)
Update with new volume.
double getDoubleParam(const char *param, int arg=0)
void getMatrices(int i, Matrix2D< double > &L, Matrix2D< double > &R, bool homogeneous=true) const
Definition: symmetries.cpp:348
void sort(MultidimArray< T > &result) const
void copyImage(const FileName &source, const FileName &target)
void resizeNoCopy(const MultidimArray< T1 > &v)
void addVector(MultidimArray< double > &y)
Definition: basic_pca.cpp:525
bool getValue(MDObject &mdValueOut, size_t id) const override
Tilting angle of an image (double,degrees)
int readSymmetryFile(FileName fn_sym, double accuracy=SYM_ACCURACY)
Definition: symmetries.cpp:33
void write(const FileName &name="", size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE, CastWriteMode castMode=CW_CAST, int _swapWrite=0)
double correlationIndex(const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > *mask=NULL, MultidimArray< double > *Contributions=NULL)
int allowed_data_types
Definition: mask.h:495
Special label to be used when gathering MDs in MpiMetadataPrograms.
int symsNo() const
Definition: symmetries.h:268
virtual IdIteratorProxy< false > ids()
void Euler_apply_transf(const Matrix2D< double > &L, const Matrix2D< double > &R, double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
Definition: geometry.cpp:1038
MultidimArray< double > v
void deleteFile(const char *line)
Definition: tools.cpp:280
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
double rnd_unif()
void vectorToVolume(const MultidimArray< double > &v, MultidimArray< double > &V)
const char * getParam(const char *param, int arg=0)
double getCurrentProjection()
Get current projection.
Definition: basic_pca.h:184
double R1
Definition: mask.h:413
#define XSIZE(v)
void progress_bar(long rlen)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
int type
Definition: mask.h:402
double maxzn
Definition: basic_pca.h:168
#define DIRECT_MULTIDIM_ELEM(v, n)
void readParams(XmippProgram *program)
Definition: mask.cpp:1284
int verbose
Verbosity level.
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const override
void defineParams()
Define parameters.
MultidimArray< double > ysum
Definition: basic_pca.h:161
void generate_mask(bool apply_geo=false)
Definition: mask.cpp:1577
int round(double x)
Definition: ap.cpp:7245
bool setValue(const MDObject &mdValueIn, size_t id) override
Definition: metadata_db.cpp:90
#define BINARY_CIRCULAR_MASK
Definition: mask.h:365
std::string String
Definition: xmipp_strings.h:34
double psi(const double x)
#define INT_MASK
Definition: mask.h:385
String formatString(const char *format,...)
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=NULL, bool decomposeStack=true) override
void readParams()
Read argument from command line.
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)
void addUsageLine(const char *line, bool verbatim=false)
void initZeros(const MultidimArray< T1 > &op)
const MultidimArray< int > & get_binary_mask() const
Definition: mask.h:707
int getIntParam(const char *param, int arg=0)
int * n
double sum() const
void addParamsLine(const String &line)
MultidimArray< double > c1
Definition: basic_pca.h:163
int mode
Definition: mask.h:407
constexpr int INNER_MASK
Definition: mask.h:47