Xmipp  v3.23.11-Nereus
transform_dimred.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Authors: Javier Vargas (jvargas@cnb.csic.es)
3  * Carlos Oscar Sorzano (coss@cnb.csic.es)
4  *
5  *
6  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21  * 02111-1307 USA
22  *
23  * All comments concerning this program package may be sent to the
24  * e-mail address 'xmipp@cnb.csic.es'
25  ***************************************************************************/
26 
27 #include "transform_dimred.h"
29 
31 {
33  if (checkParam("--randomSample"))
34  {
35  fnRandomSampling = getParam("--randomSample",0);
36  numGrids = getIntParam("--randomSample",1);
37  }
38  distance=getParam("--distance");
39 }
40 
41 // Show ====================================================================
43 {
44  if (verbose>0)
45  {
47  std::cout << "Distance: " << distance << std::endl;
48  if (fnRandomSampling!="")
49  std::cout << "Random sample output: " << fnRandomSampling << std::endl
50  << "Number of sampling grids: " << numGrids << std::endl;
51  }
52 }
53 
54 // usage ===================================================================
56 {
57  addUsageLine("This program takes an input metadata and projects each image onto a lower dimensional space using the selected method");
58  setDefaultComment("-i","Input metadata");
59  setDefaultComment("-o","Output metadata");
61  addParamsLine(" [--distance <d=Correlation>] : Distance between images");
62  addParamsLine(" where <d>");
63  addParamsLine(" Euclidean: Euclidean distance between images, no alignment");
64  addParamsLine(" Correlation: Correlation between images after alignment");
65  addParamsLine(" [--randomSample <file> <num=3>] : Generates a random sample of the reduced map with num grids in each direction");
66  addExampleLine("xmipp_transform_dimred -i images.xmd --randomSample randomSample.xmd");
67 }
68 
69 // Produce side info ======================================================
70 //#define DEBUG
72 {
75  double corr=alignImages(I1,I2,M,true,aux,aux2,aux3);
76  return 1.-corr;
77 }
78 
80 double correlationDistance(const Matrix2D<double> &X, size_t i1, size_t i2)
81 {
82  return prog->progCorrelationDistance(i1,i2);
83 }
84 
86 {
88 
89  // Read input selfile
90  SFin.read(fnIn);
91  if (SFin.size()==0)
92  return;
94 
95  // Adjust number of grid points
96  //JV I do not know why is this line below here and who has written!
97  //numGrids=floor(sqrt((double)(SFin.size())));
98 
99  MetaDataVec SFaux;
101  SFin=SFaux;
102 
103  // Design Mask
104  size_t Xdim, Ydim, Zdim, Ndim;
105  getImageSize(SFin,Xdim,Ydim,Zdim,Ndim);
106 
108  mask.mode = INNER_MASK;
109  mask.R1 = std::sqrt(0.25*Xdim*Xdim+0.25*Ydim*Ydim);
110  mask.resize(Ydim,Xdim);
112 
113  const MultidimArray<int> &mMask=mask.get_binary_mask();
114  X.resizeNoCopy(SFin.size(),mMask.sum());
115 
116  // Copy images
117  Image<double> img;
118  size_t index = 0;
119  for (size_t objId : SFin.ids())
120  {
121  img.readApplyGeo(SFin, objId);
122  insertImageInDataMatrix(index++, img());
123  }
125 
126  // Set distance
127  prog=this;
128  if (distance=="Correlation")
130  else
131  algorithm->distance=NULL;
132 }
133 
135 {
136  size_t index2 = 0;
137  const MultidimArray<int> &mMask=mask.get_binary_mask();
139  if (DIRECT_MULTIDIM_ELEM(mMask,n))
140  {
141  MAT_ELEM(X,index,index2)=DIRECT_MULTIDIM_ELEM(mImg,n);
142  index2++;
143  }
144 }
145 
147 {
148  size_t index2 = 0;
149  const MultidimArray<int> &mMask=mask.get_binary_mask();
150  mImg.initZeros(mMask);
152  if (DIRECT_MULTIDIM_ELEM(mMask,n))
153  {
154  DIRECT_MULTIDIM_ELEM(mImg,n)=MAT_ELEM(X,index,index2);
155  index2++;
156  }
157 }
158 
160 {
161  //number of grids in each axis
162  int num = numGrids;
163 
164  size_t numParticles = SFin.size();
165  std::vector<double> dimredProj;
166  std::vector< Matrix1D< double > > coor;
168  dummy.resizeNoCopy(numParticles);
169  for (int n = 0; n < outputDim; ++n)
170  coor.push_back(dummy);
171 
172  // Keep the reduced coefficients
173  size_t i = 0;
174  for (size_t objId : SFin.ids())
175  {
176  SFin.getValue(MDL_DIMRED, dimredProj, objId);
177  for (int n = 0; n < outputDim; ++n)
178  VEC_ELEM(coor[n],i) = dimredProj[n];
179  i++;
180  }
181 
182  // We obtain the max and min coordinate values
183  std::vector<double> minCoor, maxCoor;
184  for (int n=0; n<outputDim; ++n)
185  {
186  double minval, maxval;
187  coor[n].computeMinMax(minval, maxval);
188  minCoor.push_back(minval);
189  maxCoor.push_back(maxval);
190 
191  }
192 
193  Matrix2D <int> squares;
194  squares.resizeNoCopy(numParticles, (int)pow(num+1,outputDim));
195 
196  Matrix1D <int> numElems;
197  numElems.resizeNoCopy(MAT_XSIZE(squares));
198 
199  for (size_t i=0; i<numParticles; i++)
200  {
201  int index=0;
202  for (int n=(outputDim-1); n>=0; --n)
203  {
204  index*=num;
205  //std::cout << "minCoor : " << minCoor[n] << std::endl;
206  //std::cout << "maxCoor : " << maxCoor[n] << std::endl;
207  //std::cout << "VEC_ELEM(coor[n],i) : " << VEC_ELEM(coor[n],i) << std::endl;
208 
209  index+=(int)floor(( ( VEC_ELEM(coor[n],i) - minCoor[n]) / (maxCoor[n] - minCoor[n]))*num);
210  }
211 
212 
213  MAT_ELEM(squares,VEC_ELEM(numElems,index),index)=i;
214  VEC_ELEM(numElems,index)++;
215  }
216 
217  int numElemFirstRow = 0;
218  for (size_t k=0; k < MAT_XSIZE(squares); k++)
219  if (VEC_ELEM(numElems,k)!=0)
220  numElemFirstRow++;
221 
222  std::vector<Matrix1D<double> > selectedCoor;
223  dummy.resizeNoCopy(numElemFirstRow);
224  for (int n=0; n<outputDim; ++n)
225  selectedCoor.push_back(dummy);
226 
227  //Metadata with the well sampled projection and random projections assigned
228  MetaDataVec SFout;
229  int indx = 0;
231  std::vector<String> fnImg;
233  for (size_t k=0; k <MAT_XSIZE(squares); k++)
234  {
235  if (MAT_ELEM(squares,0,k)!=0)
236  {
237  int randomN = round((rnd_unif(0,1))*VEC_ELEM(numElems,k));
238  for (int n=0; n<outputDim; ++n)
239  VEC_ELEM(selectedCoor[n],indx)=VEC_ELEM(coor[n],MAT_ELEM(squares,randomN,k));
240  size_t id=SFout.addObject();
241  SFout.setValue(MDL_IMAGE,fnImg[MAT_ELEM(squares,randomN,k)],id);
242  SFout.setValue(MDL_ANGLE_ROT,(rnd_unif(0,360)-180),id);
243  SFout.setValue(MDL_ANGLE_TILT,(rnd_unif(0,180)),id);
244  SFout.setValue(MDL_ANGLE_TILT,(rnd_unif(0,180)),id);
245  SFout.setValue(MDL_ANGLE_PSI,(rnd_unif(0,360)),id);
246  indx++;
247  }
248  }
249 
250  SFout.write(fnRandomSampling);
251 }
252 
253 // Run ====================================================================
255 {
256  show();
257 
258  produceSideInfo();
259  if (outputDim<0)
261 
263  {
264 
266 
267  std::vector<double> dimredProj;
268  dimredProj.resize(outputDim);
269  int i=0;
271  for (size_t objId : SFin.ids())
272  {
273  memcpy(&dimredProj[0],&MAT_ELEM(Y,i,0),outputDim*sizeof(double));
274  SFin.setValue(MDL_DIMRED, dimredProj, objId);
275  i++;
276  }
277 
279  }
280 
281  if (fnRandomSampling!="")
283 }
virtual void produceSideInfo()
Produce side info.
Rotation angle of an image (double,degrees)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
void removeDuplicates(MetaData &MDin, MDLabel label=MDL_UNDEFINED)
__host__ __device__ float2 floor(const float2 v)
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
double alignImages(const MultidimArray< double > &Iref, const AlignmentTransforms &IrefTransforms, MultidimArray< double > &I, Matrix2D< double > &M, bool wrap, AlignmentAux &aux, CorrelationAux &aux2, RotationalCorrelationAux &aux3)
Definition: filters.cpp:2047
void setInputData(Matrix2D< double > &X)
Set input data.
void sqrt(Image< double > &op)
void setDefaultComment(const char *param, const char *comment)
Tilting angle of an image (double,degrees)
void getImageSize(const MetaData &md, size_t &Xdim, size_t &Ydim, size_t &Zdim, size_t &Ndim, MDLabel image_label)
void readParams()
Read argument from command line.
void insertImageInDataMatrix(size_t index, const MultidimArray< double > &mImg)
From image to data matrix.
void resize(size_t Xdim)
Definition: mask.cpp:654
Special label to be used when gathering MDs in MpiMetadataPrograms.
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const
const Matrix2D< double > & getReducedData()
Get reduced data.
DimRedAlgorithm * algorithm
Definition: matrix_dimred.h:68
FileName fnIn
Definition: matrix_dimred.h:51
virtual IdIteratorProxy< false > ids()
void produceSideInfo()
Produce side info.
int readApplyGeo(const FileName &name, const MDRow &row, const ApplyGeoParams &params=DefaultApplyGeoParams)
size_t size() const override
#define i
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
void resizeNoCopy(int Ydim, int Xdim)
Definition: matrix2d.h:534
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
double rnd_unif()
ProgTransformDimRed * prog
const char * getParam(const char *param, int arg=0)
double correlationDistance(const Matrix2D< double > &X, size_t i1, size_t i2)
viol index
Matrix2D< double > M
bool setValue(const MDObject &mdValueIn, size_t id)
size_t addObject() override
double R1
Definition: mask.h:413
virtual void reduceDimensionality()=0
Reduce dimensionality.
CorrelationAux aux2
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
void run()
Main routine.
int type
Definition: mask.h:402
Projection onto a reduced manifold (vector double)
#define DIRECT_MULTIDIM_ELEM(v, n)
void addExampleLine(const char *example, bool verbatim=true)
RotationalCorrelationAux aux3
virtual void readParams()
Read argument from command line.
int verbose
Verbosity level.
double dummy
void estimateDimension()
Estimate dimensionality.
bool getValue(MDObject &mdValueOut, size_t id) const override
void getColumnValues(const MDLabel label, std::vector< MDObject > &valuesOut) const override
virtual void defineParams()
Define parameters.
void generate_mask(bool apply_geo=false)
Definition: mask.cpp:1577
DimRedDistance2 distance
Distance function.
Definition: dimred_tools.h:150
int round(double x)
Definition: ap.cpp:7245
virtual void removeDisabled()
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
Matrix2D< double > X
Definition: matrix_dimred.h:67
#define BINARY_CIRCULAR_MASK
Definition: mask.h:365
virtual void show()
Show.
void defineParams()
Define parameters.
void resizeNoCopy(int Xdim)
Definition: matrix1d.h:458
bool checkParam(const char *param)
MultidimArray< double > I1
void addUsageLine(const char *line, bool verbatim=false)
void initZeros(const MultidimArray< T1 > &op)
unsigned int randomize_random_generator()
bool containsLabel(const MDLabel label) const override
const MultidimArray< int > & get_binary_mask() const
Definition: mask.h:707
int getIntParam(const char *param, int arg=0)
int * n
Name of an image (std::string)
double sum() const
MultidimArray< double > I2
void addParamsLine(const String &line)
void extractImageFromDataMatrix(size_t index, MultidimArray< double > &mImg)
From image to data matrix.
int mode
Definition: mask.h:407
double progCorrelationDistance(size_t i1, size_t i2)
Correlation distance between two images.
constexpr int INNER_MASK
Definition: mask.h:47