Xmipp  v3.23.11-Nereus
metadata_split_3D.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar Sanchez Sorzano coss@cnb.csic.es (2014)
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 <algorithm>
27 #include "metadata_split_3D.h"
28 #include "core/geometry.h"
29 #include "core/metadata_vec.h"
30 #include "data/filters.h"
31 #include "data/basic_pca.h"
32 
33 // Read arguments ==========================================================
35 {
36  fn_in = getParam("-i");
37  fn_vol = getParam("--vol");
38  fn_sym = getParam("--sym");
39  fn_oroot = getParam("--oroot");
40  angularSampling = getDoubleParam("--angSampling");
41  maxDist = getDoubleParam("--maxDist");
42 }
43 
44 // Show ====================================================================
46 {
47  if (!verbose)
48  return;
49  std::cout
50  << "Input images: " << fn_in << std::endl
51  << "Reference volume: " << fn_vol << std::endl
52  << "Output rootname: " << fn_oroot << std::endl
53  << "Symmetry: " << fn_sym << std::endl
54  << "Angular sampling: " << angularSampling << std::endl
55  << "Maximum distance: " << maxDist << std::endl
56  ;
57 }
58 
59 // usage ===================================================================
61 {
62  addUsageLine("Separate projections according to a volume");
63  addParamsLine(" -i <metadata> : Metadata with the images to separate. Make sure they have an angular assignment");
64  addParamsLine(" --vol <volume> : Reference volume");
65  addParamsLine(" [--oroot <rootname=split>] : Rootname for the output files");
66  addParamsLine(" [--sym <symmetry_file=c1>] : Symmetry file if any");
67  addParamsLine(" :+The definition of the symmetry is described at [[transform_symmetrize_v3][transform_symmetrize]]");
68  addParamsLine(" [--angSampling <a=5>] : Angular sampling in degrees");
69  addParamsLine(" [--maxDist <a=10>] : Maximum angular distance in degrees");
70  addExampleLine("xmipp_metadata_split_3D -i projections.sel --vol volume.vol --oroot split");
71 }
72 
73 void getNeighbours(MetaDataDb &mdIn, const Matrix1D<double> &projectionDir, MetaDataDb &mdNeighbours, double maxDist)
74 {
75  Matrix1D<double> projectionDir2;
76  FileName fnImg;
77  mdNeighbours.clear();
78  MetaDataDb mdAux;
79  size_t refno;
80  double cc;
81  for (size_t objId : mdIn.ids())
82  {
83  double rot, tilt;
84  mdIn.getValue(MDL_ANGLE_ROT,rot, objId);
85  mdIn.getValue(MDL_ANGLE_TILT,tilt, objId);
86  mdIn.getValue(MDL_IMAGE_IDX,refno, objId);
87  mdIn.getValue(MDL_MAXCC,cc, objId);
88  Euler_direction(rot,tilt,0,projectionDir2);
89 
90  double angle=acos(dotProduct(projectionDir,projectionDir2));
91  if (angle<maxDist)
92  {
93  mdIn.getValue(MDL_IMAGE,fnImg, objId);
94  size_t id=mdAux.addObject();
95  mdAux.setValue(MDL_IMAGE,fnImg,id);
96  mdAux.setValue(MDL_IMAGE_IDX,refno,id);
97  mdAux.setValue(MDL_MAXCC,cc,id);
98  }
99  }
100  mdNeighbours.removeDuplicates(mdAux,MDL_IMAGE_IDX);
101  std::vector<MDLabel> groupBy;
102  groupBy.push_back(MDL_IMAGE_IDX);
103  groupBy.push_back(MDL_IMAGE);
104  if (mdAux.size()>0)
105  mdNeighbours.aggregateGroupBy(mdAux,AGGR_MAX,groupBy,MDL_MAXCC,MDL_MAXCC);
106 }
107 
108 void analyzeNeighbours(MetaData &mdNeighbours, const FileName &fnRef)
109 {
110  std::vector<double> cc;
111  mdNeighbours.getColumnValues(MDL_MAXCC,cc);
112  std::sort(cc.begin(),cc.end());
113 
114  double ccMedian=cc[cc.size()/2];
115  for (size_t objId : mdNeighbours.ids())
116  {
117  double cci;
118  mdNeighbours.getValue(MDL_MAXCC, cci, objId);
119  if (cci>ccMedian)
120  mdNeighbours.setValue(MDL_COST, 1.0, objId);
121  else
122  mdNeighbours.setValue(MDL_COST, -1.0, objId);
123  }
124 }
125 
126 // usage ===================================================================
128 {
129  // Generate projections
130  std::cerr << "Generating projections ..." << std::endl;
131  String cmd=formatString("xmipp_angular_project_library -i %s -o %s_gallery.stk --sampling_rate %f --sym %s --method fourier 1 0.25 bspline --compute_neighbors --angular_distance -1 --experimental_images %s -v 0",
132  fn_vol.c_str(),fn_oroot.c_str(),angularSampling,fn_sym.c_str(),fn_in.c_str());
133  if (system(cmd.c_str())!=0)
134  REPORT_ERROR(ERR_UNCLASSIFIED,"Error when generating projections");
135 
136  // Read reference and input metadatas
137  mdIn.read(fn_in);
139  REPORT_ERROR(ERR_MD_MISSINGLABEL,"Input metadata with images does not contain an imageIndex column");
141  mdRef.read(fn_oroot+"_gallery.doc");
142  deleteFile(fn_oroot+"_gallery.doc");
143  deleteFile(fn_oroot+"_gallery.stk");
144  deleteFile(fn_oroot+"_gallery_sampling.xmd");
145 
146  // Get the maximum reference number
147  size_t maxRef=0, refno;
148  for (size_t objId : mdIn.ids())
149  {
150  mdIn.getValue(MDL_IMAGE_IDX, refno, objId);
151  if (refno>maxRef)
152  maxRef=refno;
153  }
154 
155  // Calculate coocurrence matrix
156  correlatesWell.initZeros(maxRef+1);
157  Matrix1D<double> projectionDir;
158  std::vector<FileName> fnNeighbours;
159  FileName fnImg;
161  MetaDataDb mdNeighbours;
162  std::vector<size_t> refs;
163  std::vector<double> upperHalf;
164  int i=0;
165  std::cerr << "Classifying projections ...\n";
167 
168  for (size_t objId : mdRef.ids())
169  {
170  // Get the projection direction of this image
171  double rot, tilt;
172  mdRef.getValue(MDL_ANGLE_ROT,rot, objId);
173  mdRef.getValue(MDL_ANGLE_TILT,tilt, objId);
174  Euler_direction(rot,tilt,0,projectionDir);
175 
176  // Get all images in the input metadata that are close to this one
177  getNeighbours(mdIn,projectionDir,mdNeighbours,maxDist);
178 
179  // Check if it is upper or lower half
180  if (mdNeighbours.size()>0)
181  {
182  mdRef.getValue(MDL_IMAGE,fnImg, objId);
183  analyzeNeighbours(mdNeighbours,fnImg);
184  mdNeighbours.getColumnValues(MDL_IMAGE_IDX,refs);
185  mdNeighbours.getColumnValues(MDL_COST,upperHalf);
186 
187  size_t imax=refs.size();
188  for (size_t i=0; i<imax; ++i)
189  VEC_ELEM(correlatesWell,refs[i])+=upperHalf[i];
190  }
191  ++i;
192  progress_bar(i);
193  }
195 
196  // Split in two metadatas
197  MetaDataVec mdUpper, mdLower;
198  for (auto& row : mdIn)
199  {
200  mdIn.getValue(MDL_IMAGE_IDX, refno, row.id());
201  row.setValue(MDL_COST,(double)VEC_ELEM(correlatesWell,refno));
202 
203  if (VEC_ELEM(correlatesWell,refno)>0)
204  mdUpper.addRow(row);
205  else if (VEC_ELEM(correlatesWell,refno)<0)
206  mdLower.addRow(row);
207  }
208  mdUpper.write(fn_oroot+"_upper.xmd");
209  mdLower.write(fn_oroot+"_lower.xmd");
210 }
Just to locate unclassified errors.
Definition: xmipp_error.h:192
void init_progress_bar(long total)
Rotation angle of an image (double,degrees)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
double getDoubleParam(const char *param, int arg=0)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Index of an image within a list (size_t)
void Euler_direction(double alpha, double beta, double gamma, Matrix1D< double > &v)
Definition: geometry.cpp:721
#define DEG2RAD(d)
Definition: xmipp_macros.h:312
bool getValue(MDObject &mdValueOut, size_t id) const override
Tilting angle of an image (double,degrees)
void getNeighbours(MetaDataDb &mdIn, const Matrix1D< double > &projectionDir, MetaDataDb &mdNeighbours, double maxDist)
virtual IdIteratorProxy< false > ids()
void aggregateGroupBy(const MetaDataDb &mdIn, AggregateOperation op, const std::vector< MDLabel > &groupByLabels, MDLabel operateLabel, MDLabel resultLabel)
virtual bool getValue(MDObject &mdValueOut, size_t id) const =0
#define i
void deleteFile(const char *line)
Definition: tools.cpp:280
void analyzeNeighbours(MetaData &mdNeighbours, const FileName &fnRef)
const char * getParam(const char *param, int arg=0)
void getColumnValues(const MDLabel label, std::vector< MDObject > &valuesOut) const override
size_t addObject() override
Cost for the image (double)
void progress_bar(long rlen)
void clear() override
Definition: metadata_db.cpp:54
Missing expected label.
Definition: xmipp_error.h:158
void addExampleLine(const char *example, bool verbatim=true)
Maximum cross-correlation for the image (double)
void removeDuplicates(MetaDataDb &MDin, MDLabel label=MDL_UNDEFINED)
int verbose
Verbosity level.
void initZeros()
Definition: matrix1d.h:592
void sort(struct DCEL_T *dcel)
Definition: sorting.cpp:18
size_t size() const override
std::vector< T > getColumnValues(const MDLabel label) const
bool getValue(MDObject &mdValueOut, size_t id) const override
bool setValue(const MDLabel label, const T &valueIn, size_t id)
bool setValue(const MDObject &mdValueIn, size_t id) override
Definition: metadata_db.cpp:90
T dotProduct(const Matrix1D< T > &v1, const Matrix1D< T > &v2)
Definition: matrix1d.h:1140
virtual void removeDisabled()
Matrix1D< int > correlatesWell
std::string String
Definition: xmipp_strings.h:34
void readParams()
Read argument from command line.
void defineParams()
Usage.
String formatString(const char *format,...)
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=NULL, bool decomposeStack=true) override
void addUsageLine(const char *line, bool verbatim=false)
Name of an image (std::string)
void addParamsLine(const String &line)
bool containsLabel(const MDLabel label) const override
Definition: metadata_db.h:305