Xmipp  v3.23.11-Nereus
compare_density.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar coss@cnb.csic.es
4  * David Herreros Calero dherreros@cnb.csic.es
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19  * 02111-1307 USA
20  *
21  * All comments concerning this program package may be sent to the
22  * e-mail address 'xmipp@cnb.uam.es'
23  ***************************************************************************/
24 
25 #include <fstream>
26 #include <iterator>
27 #include <numeric>
28 #include <algorithm>
29 #include "data/cpu.h"
30 #include "compare_density.h"
31 #include "data/projection.h"
33 #include "data/filters.h"
34 #include "data/fourier_filter.h"
35 
36 // Params definition =======================================================
37 // -i ---> V2 (paper) / -r --> V1 (paper)
39  addUsageLine("Compute the deformation that properly fits two volumes using spherical harmonics");
40  addParamsLine(" -v1 <volume> : First volume to compare");
41  addParamsLine(" -v2 <volume> : Second volume to compare");
42  addParamsLine(" [-o <image=\"\">] : Output correlation image");
43  addParamsLine(" [--degstep <d=5.0>] : Degrees step size for rot and tilt angles");
44  addParamsLine(" [--thr <N=-1>] : Maximal number of the processing CPU threads");
45  addExampleLine("xmipp_compare_density -v1 vol1.vol -v2 vol2.vol -o corr_img.xmp");
46 }
47 
48 // Read arguments ==========================================================
50  std::string aux;
51  fnVol1 = getParam("-v1");
52  fnVol2 = getParam("-v2");
53  fnImgOut = getParam("-o");
54  degstep = getDoubleParam("--degstep");
55 
56  if (fnImgOut=="")
57  fnImgOut="Rot_tilt_corr_map.xmp";
58 
59  V1.read(fnVol1);
60  V1().setXmippOrigin();
61  V2.read(fnVol2);
62  V2().setXmippOrigin();
63 
64  // Update degstep to have evenly spaced points in the interval [0,180]
65  degstep = 360. / ROUND(360./degstep);
66 
67  int size_rot = 360./degstep;
68  int size_tlt = 180./degstep;
69  tilt_v.resize(size_tlt + 1);
70  rot_v.resize(size_rot + 1);
71  CorrImg().initZeros(size_rot + 1, size_tlt + 1);
72  CorrImg().setXmippOrigin();
73 
74  std::generate(tilt_v.begin(), tilt_v.end(), [&, n = -degstep] () mutable { return n+=degstep; });
75  std::generate(rot_v.begin(), rot_v.end(), [&, n = -degstep] () mutable { return n+=degstep; });
76 
77  int threads = getIntParam("--thr");
78  if (0 >= threads) {
79  threads = CPU::findCores();
80  }
81  m_threadPool.resize(threads);
82 }
83 
84 // Show ====================================================================
86  if (verbose==0)
87  return;
88  std::cout
89  << "First volume: " << fnVol1 << std::endl
90  << "Second volume: " << fnVol2 << std::endl
91  << "Output image: " << fnImgOut << std::endl
92  << "Degree step: " << degstep << std::endl
93  ;
94 
95 }
96 
98 {
99  Projection P1, P2;
100  auto &mCorrImg = CorrImg();
101  auto &mV1 = V1();
102  auto &mV2 = V2();
103  auto &mP1 = P1();
104  auto &mP2 = P2();
105  int size_x = XSIZE(mV1);
106  int size_y = YSIZE(mV1);
107  auto rot = rot_v[i];
108 
109  // Filter
110  FourierFilter filter;
111  filter.FilterBand=LOWPASS;
112  filter.w1=1.0/12.0;
113  filter.raised_w=0.02;
114 
115  for (int j = 0; j < tilt_v.size(); j++)
116  {
117  projectVolume(mV1, P1, size_y, size_x, rot, tilt_v[j], 0.);
118  projectVolume(mV2, P2, size_y, size_x, rot, tilt_v[j], 0.);
119  auto &mP1 = P1();
120  auto &mP2 = P2();
121  filter.applyMaskSpace(mP1);
122  filter.applyMaskSpace(mP2);
123  OtsuSegmentation(mP1);
124  OtsuSegmentation(mP2);
125  MultidimArray<double> cmP1 = mP1;
126  MultidimArray<double> cmP2 = mP2;
127  keepBiggestComponent(cmP1);
128  keepBiggestComponent(cmP2);
129  mP1 = mP1 - cmP1;
130  mP2 = mP2 - cmP2;
131  compare(P1, P2);
132  double sum_cmp = mP1.sum();
133  if (sum_cmp > 0.0)
134  DIRECT_A2D_ELEM(mCorrImg, i, j) = 1.0;
135  else if (sum_cmp < 0.0)
136  DIRECT_A2D_ELEM(mCorrImg, i, j) = -1.0;
137  }
138 }
139 
141 {
142  MultidimArray<double> &mOp1 = op1();
143  const MultidimArray<double> &mOp2 = op2();
145  {
146  dAi(mOp1, n) = dAi(mOp1, n) == dAi(mOp2, n) ? 0 : (dAi(mOp1, n) < dAi(mOp2, n) ? -1 : 1 );
147  }
148 }
149 
150 // Run =====================================================================
152  auto futures = std::vector<std::future<void>>();
153  futures.reserve(V1().zdim);
154 
155  auto routine = [this](int thrId, int i) {
157  };
158 
159  for (int i=0; i<rot_v.size(); i++)
160  {
161  futures.emplace_back(m_threadPool.push(routine, i));
162  }
163 
164  for (auto &f : futures) {
165  f.get();
166  }
167 
169 }
#define dAi(v, i)
void defineParams()
Define params.
#define YSIZE(v)
double getDoubleParam(const char *param, int arg=0)
std::vector< double > tilt_v
Rot and tilt vectors.
double OtsuSegmentation(MultidimArray< double > &V)
Definition: filters.cpp:1028
auto push(F &&f, Rest &&... rest) -> std::future< decltype(f(0, rest...))>
Definition: ctpl.h:152
#define DIRECT_A2D_ELEM(v, i, j)
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)
static unsigned findCores()
Definition: cpu.h:41
void resize(int nThreads)
Definition: ctpl.h:70
#define i
FileName fnImgOut
Output corelation image.
void readParams()
Read arguments from command line.
Image< double > V2
double degstep
Degree step.
const char * getParam(const char *param, int arg=0)
void compare(Image< double > &op1, const Image< double > &op2)
Compare binary images.
double * f
Image< double > V1
Images.
Image< double > CorrImg
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
void addExampleLine(const char *example, bool verbatim=true)
#define ROUND(x)
Definition: xmipp_macros.h:210
void projectVolume(FourierProjector &projector, Projection &P, int Ydim, int Xdim, double rot, double tilt, double psi, const MultidimArray< double > *ctf)
int verbose
Verbosity level.
#define j
void keepBiggestComponent(MultidimArray< double > &I, double percentage, int neighbourhood)
Definition: filters.cpp:713
std::vector< double > rot_v
void computeCorrImage(int i)
Compute corr image.
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)
int getIntParam(const char *param, int arg=0)
int * n
FileName fnVol1
Volumes to compare.
#define LOWPASS
void addParamsLine(const String &line)
void applyMaskSpace(MultidimArray< double > &v)