Xmipp  v3.23.11-Nereus
local_volume_adjust.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Estrella Fernandez Gimenez (me.fernandez@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 "local_volume_adjust.h"
27 #include "core/transformations.h"
28 #include <core/histogram.h>
29 #include <core/xmipp_fftw.h>
30 #include <core/xmipp_program.h>
31 #include <data/fourier_filter.h>
32 
33 
34 // Usage ===================================================================
35 void ProgLocalVolumeAdjust::defineParams() {
36  // Usage
37  addUsageLine("This program modifies a volume in order to adjust its intensity locally to a reference volume");
38  // Parameters
39  addParamsLine("--i1 <volume> : Reference volume");
40  addParamsLine("--i2 <volume> : Volume to modify");
41  addParamsLine("[-o <structure=\"\">]\t: Volume 2 modified or volume difference");
42  addParamsLine("\t: If no name is given, then output_volume.mrc");
43  addParamsLine("--mask <mask=\"\"> : Mask for volume 1");
44  addParamsLine("[--sampling <sampling=1>]\t: Sampling rate (A/pixel)");
45  addParamsLine("[--neighborhood <n=5>]\t: side length (in Angstroms) of a square which will define the region of adjustment");
46  addParamsLine("[--sub]\t: Perform the subtraction of the volumes. Output will be the difference");
47  addParamsLine("--save <structure=\"\">\t: Path for saving occupancy volume");
48 }
49 
50 // Read arguments ==========================================================
51 void ProgLocalVolumeAdjust::readParams() {
52  fnVol1 = getParam("--i1");
53  fnVol2 = getParam("--i2");
54  fnOutVol = getParam("-o");
55  if (fnOutVol.isEmpty())
56  fnOutVol = "output_volume.mrc";
57  performSubtraction = checkParam("--sub");
58  fnMask = getParam("--mask");
59  sampling = getDoubleParam("--sampling");
60  neighborhood = getIntParam("--neighborhood");
61  fnOccup = getParam("--save");
62 }
63 
64 // Show ====================================================================
65 void ProgLocalVolumeAdjust::show() const {
66  std::cout << "Input volume 1 (reference):\t" << fnVol1 << std::endl
67  << "Input volume 2:\t" << fnVol2 << std::endl
68  << "Input mask:\t" << fnMask << std::endl
69  << "Output:\t" << fnOutVol << std::endl;
70 }
71 
72 void ProgLocalVolumeAdjust::run() {
73  show();
74  // Read inputs
75  Image<double> Vref;
76  Vref.read(fnVol1);
77  MultidimArray<double> &mVref=Vref();
78  mVref.setXmippOrigin();
79  Image<double> V;
80  V.read(fnVol2);
81  MultidimArray<double> &mV=V();
82  mV.setXmippOrigin();
83  Image<double> M;
84  M.read(fnMask);
85  MultidimArray<double> &mM=M();
86  mM.setXmippOrigin();
87  int iters;
88  int neighborhood_px;
89  neighborhood_px = round(neighborhood/sampling);
90  int cubic_neighborhood;
91  cubic_neighborhood = neighborhood_px*neighborhood_px*neighborhood_px;
92  iters = floor(ZYXSIZE(mV)/cubic_neighborhood);
93  int xsize = XSIZE(mV);
94  int ysize = YSIZE(mV);
95  int zsize = ZSIZE(mV);
96  int ki = 0;
97  int ii = 0;
98  int ji = 0;
99  // Initialize occupancy volume
100  Image<double> Voccupancy;
101  Voccupancy = Vref;
102  MultidimArray<double> &mVoc=Voccupancy();
103  mVoc.initZeros();
104 
105  for (size_t s=0; s < iters; s++)
106  {
107  sumV_Vref = 0;
108  sumVref2 = 0;
109  // Go over each subvolume
110  for (k=0; k < neighborhood_px; ++k)
111  {
112  for (i=0; i < neighborhood_px; ++i)
113  {
114  for (j=0; j < neighborhood_px; ++j)
115  {
116  if (DIRECT_A3D_ELEM(mM,ki+k,ii+i,ji+j) == 1) // Condition to check if we are inside mask
117  {
118  sumV_Vref += DIRECT_A3D_ELEM(mV,ki+k,ii+i,ji+j)*DIRECT_A3D_ELEM(mVref,ki+k,ii+i,ji+j);
119  sumVref2 += DIRECT_A3D_ELEM(mVref,ki+k,ii+i,ji+j)*DIRECT_A3D_ELEM(mVref,ki+k,ii+i,ji+j);
120  }
121  else
122  {
123  sumV_Vref += 0;
124  sumVref2 += 0;
125  }
126  }
127  }
128  }
129  // Compute constant (c)
130  if (sumVref2 == 0)
131  c = 0;
132  else
133  c = sumV_Vref/sumVref2;
134 
135  // Apply adjustment per regions
136  for (k=0; k < neighborhood_px; ++k)
137  {
138  for (i=0; i < neighborhood_px; ++i)
139  {
140  for (j=0; j < neighborhood_px; ++j)
141  {
142  if (DIRECT_A3D_ELEM(mM,ki+k,ii+i,ji+j) == 1) // Condition to check if we are inside mask
143  {
144  DIRECT_A3D_ELEM(mV,ki+k,ii+i,ji+j) /= c;
145  // construct occupancy volume
146  DIRECT_A3D_ELEM(mVoc,ki+k,ii+i,ji+j) = c;
147  }
148  }
149  }
150  }
151  // Take the index to start in next subvolume
152  if (ji < (xsize-neighborhood_px))
153  ji += neighborhood_px;
154  else
155  ji = 0;
156  if (ji == 0)
157  {
158  if (ii < (ysize-neighborhood_px))
159  ii += neighborhood_px;
160  else
161  ii = 0;
162  }
163  if (ii == 0 && ji == 0)
164  {
165  if (ki < (zsize-neighborhood_px))
166  ki += neighborhood_px;
167  else
168  ki = 0;
169  }
170  }
171  // Save occupancy volume
172  Voccupancy.write(formatString("%s/Occupancy.mrc", fnOccup.c_str()));
173 
174  // The output of this program is a modified version of V (V')
175  if (performSubtraction) // Or the output is the subtraction V = Vref - V
176  {
180  * DIRECT_MULTIDIM_ELEM(mM, n);
181  }
182  V.write(fnOutVol);
183 }
#define YSIZE(v)
void min(Image< double > &op1, const Image< double > &op2)
double getDoubleParam(const char *param, int arg=0)
__host__ __device__ float2 floor(const float2 v)
#define ZYXSIZE(v)
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)
const char * getParam(const char *param, int arg=0)
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define ZSIZE(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
#define DIRECT_A3D_ELEM(v, k, i, j)
int round(double x)
Definition: ap.cpp:7245
bool isEmpty() const
String formatString(const char *format,...)
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)
int getIntParam(const char *param, int arg=0)
int * n
void addParamsLine(const String &line)