Xmipp  v3.23.11-Nereus
program_image_residuals.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Authors: Carlos Oscar S. Sorzano (coss@cnb.csic.es)
3  *
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 
28 #include "data/filters.h"
29 
31 {
33  produces_an_output = true;
34  addUsageLine("Analyze image residuals");
36  addParamsLine(" [--normalizeDivergence] : Normalize the divergence measure");
37  addExampleLine("xmipp_image_residuals -i residuals.stk -o autocorrelations.stk --save_metadata_stack autocorrelations.xmd");
38 }
39 
41 {
43  normalizeDivergence=checkParam("--normalizeDivergence");
44 }
45 
47 {
48  i=0;
51 }
52 
53 void ProgImageResiduals::processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
54 {
55  rowOut=rowIn;
56 
57  Image<double> img;
59  img.read(fnImg);
60  else
61  {
62  FileName fnResidual;
63  rowIn.getValue(MDL_IMAGE_RESIDUAL,fnResidual);
64  img.read(fnResidual);
65  }
66  covarianceMatrix(img(), R);
67  IR()=R;
68  IR.write(fnImgOut);
69  rowOut.setValue(MDL_IMAGE_COVARIANCE,fnImgOut);
70 
71  img().computeAvgStdev(A1D_ELEM(resmean,i),A1D_ELEM(resvar,i));
72  i++;
73 }
74 
75 // See formula (25) of
76 // Cherian, A.; Sra, S.; Banerjee, A. & Papanikolopoulos, N. Jensen-Bregman LogDet divergence with application to efficient
77 // similarity search for covariance matrices. IEEE Trans Pattern Anal Mach Intell, 2013, 35, 2161-2174
79 {
80  FileName fnR;
81  Matrix2D<double> R, Rinv, newRavg;
83  newRavg.initZeros(Ravg);
84  for (size_t objId : mdR.ids())
85  {
86  mdR.getValue(MDL_IMAGE_COVARIANCE,fnR,objId);
87  IR.read(fnR);
88  IR().copy(R);
89 
90  R+=Ravg;
91  R*=0.5;
92  R.inv(Rinv);
93  newRavg+=Rinv;
94  }
95  newRavg*=1.0/mdR.size();
96  newRavg.inv(Ravg);
97 }
98 
100 {
104  C=C1+C2;
105  C*=0.5;
106  firstEigs(C, MAT_XSIZE(C), D, P, false);
107  double retval=0;
108  for (size_t i=0; i<VEC_XSIZE(D)/2; ++i) // Only half of the eigenvalues are reliable
109  {
110  double l=fabs(VEC_ELEM(D,i));
111  if (l>1e-14)
112  retval+=log(l);
113  }
114 
115  C=C1*C2;
116  firstEigs(C, MAT_XSIZE(C), D, P, false);
117  for (size_t i=0; i<VEC_XSIZE(D)/2; ++i)
118  {
119  double l=fabs(VEC_ELEM(D,i));
120  if (l>1e-14)
121  retval-=0.5*log(l);
122  }
123  return retval;
124 }
125 
127 {
128  FileName fnMDout=fn_out.replaceExtension("xmd");
129  MetaDataVec mdR(fnMDout);
130 
131  // Ravg
132  Matrix2D<double> Ravg;
133  Ravg.initIdentity(MAT_XSIZE(R));
134  std::cerr << "Calculating covariance centroid ..." << std::endl;
135  init_progress_bar(10);
136  for (int i=0; i<10; i++)
137  {
138  progress_bar(i);
139  updateRavg(mdR,Ravg);
140  }
141  progress_bar(10);
142 
143  // Calculate the zscore of the mean and stddev
144  double mean, stddev;
145  resmean.computeAvgStdev(mean,stddev);
146  resmean-=mean;
147  resmean/=stddev;
148  resvar.computeAvgStdev(mean,stddev);
149  resvar-=mean;
150  resvar/=stddev;
151 
153  FileName fnR;
155  std::cerr << "Calculating covariance divergence ..." << std::endl;
156  init_progress_bar(mdR.size());
157  size_t n=0;
158  double minD=1e38;
159  for (size_t objId : mdR.ids())
160  {
161  mdR.getValue(MDL_IMAGE_COVARIANCE,fnR,objId);
162  IR.read(fnR);
163  IR().copy(R);
164 
165  double d=computeCovarianceMatrixDivergence(Ravg,R);
166  if (d<minD)
167  minD=d;
168  mdR.setValue(MDL_ZSCORE_RESMEAN,fabs(A1D_ELEM(resmean,n)),objId);
169  mdR.setValue(MDL_ZSCORE_RESVAR,fabs(A1D_ELEM(resvar,n)),objId);
170  mdR.setValue(MDL_ZSCORE_RESCOV,d,objId);
171  n++;
172  if (n%100==0)
173  progress_bar(n);
174  }
175  progress_bar(mdR.size());
176  if (normalizeDivergence) {
177  for (size_t objId : mdR.ids())
178  {
179  double d;
180  mdR.getValue(MDL_ZSCORE_RESCOV,d,objId);
181  mdR.setValue(MDL_ZSCORE_RESCOV,d/minD-1,objId);
182  }
183  }
184  mdR.write(fnMDout);
185 }
void init_progress_bar(long total)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
double computeCovarianceMatrixDivergence(const Matrix2D< double > &C1, const Matrix2D< double > &C2)
Compute the divergence between two covariance matrices.
MultidimArray< double > resmean
size_t mdInSize
Number of input elements.
FileName replaceExtension(const String &newExt) const
#define VEC_XSIZE(m)
Definition: matrix1d.h:77
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 processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
#define A1D_ELEM(v, i)
void computeAvgStdev(U &avg, U &stddev) const
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const
MultidimArray< double > resvar
virtual IdIteratorProxy< false > ids()
void updateRavg(MetaData &mdR, Matrix2D< double > &Ravg)
virtual bool getValue(MDObject &mdValueOut, size_t id) const =0
size_t size() const override
doublereal * d
T & getValue(MDLabel label)
void log(Image< double > &op)
bool setValue(const MDObject &mdValueIn, size_t id)
void progress_bar(long rlen)
void firstEigs(const Matrix2D< double > &A, size_t M, Matrix1D< double > &D, Matrix2D< double > &P, bool Pneeded)
Definition: matrix2d.cpp:284
bool produces_an_output
Indicate that a unique final output is produced.
void addExampleLine(const char *example, bool verbatim=true)
Name of a residual image associated to this image.
Z Score of the mean of the residuals (double)
virtual size_t size() const =0
Name of the covariance imagee associated to this image.
bool getValue(MDObject &mdValueOut, size_t id) const override
void setValue(MDLabel label, const T &d, bool addLabel=true)
virtual bool containsLabel(MDLabel label) const =0
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
void initZeros()
Definition: matrix2d.h:626
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)
bool each_image_produces_an_output
Indicate that an output is produced for each image in the input.
Z Score of the stddev of the residuals (double)
void addUsageLine(const char *line, bool verbatim=false)
void initZeros(const MultidimArray< T1 > &op)
Z Score of the covariance matrix of the residuals (double)
void copy(const ImageBase &other)
int * n
void addParamsLine(const String &line)
void initIdentity()
Definition: matrix2d.h:673
void covarianceMatrix(const MultidimArray< double > &I, Matrix2D< double > &C)
Definition: filters.cpp:1582