Xmipp  v3.23.11-Nereus
volume_apply_deform_sph.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: David Herreros Calero dherreros@cnb.csic.es
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18  * 02111-1307 USA
19  *
20  * All comments concerning this program package may be sent to the
21  * e-mail address 'xmipp@cnb.uam.es'
22  ***************************************************************************/
23 
24 #include <data/numerical_tools.h>
25 #include <data/basis.h>
27 #include <data/numerical_tools.h>
28 #include <fstream>
29 
30 // TODO: Refactor this file so it is not so similar to angular_sph_alignment
31 
33 {
34  addUsageLine("Deform a PDB according to a list of SPH deformation coefficients");
35  addParamsLine("-i <volume> : Volume to deform");
36  addParamsLine("--clnm <metadata_file> : List of deformation coefficients");
37  addParamsLine("-o <volume> : Deformed volume");
38  addExampleLine("xmipp_apply_deform_sph -i input.vol -o volume_deformed.vol --clnm coefficients.txt");
39 }
40 
42 {
43  fn_vol=getParam("-i");
44  fn_sph=getParam("--clnm");
45  fn_out=getParam("-o");
46 }
47 
49 {
50  if (verbose==0)
51  return;
52  std::cout
53  << "Volume: " << fn_vol << std::endl
54  << "Coefficient list: " << fn_sph << std::endl
55  << "Output: " << fn_out << std::endl
56  ;
57 }
58 
60 {
61  Image<double> VI;
62  Image<double> VO;
63  VI.read(fn_vol);
64  VI().setXmippOrigin();
65  VO().initZeros(VI());
66  VO().setXmippOrigin();
67  std::string line;
68  line = readNthLine(0);
69  basisParams = string2vector(line);
70  line = readNthLine(1);
71  clnm = string2vector(line);
73  size_t idxY0=(clnm.size())/3;
74  size_t idxZ0=2*idxY0;
75  const MultidimArray<double> &mVI=VI();
76  double voxelI=0.0;
77  double Rmax=basisParams[2];
78  double Rmax2=Rmax*Rmax;
79  double iRmax=1.0/Rmax;
80  double zsph=0.0;
81  for (int k=STARTINGZ(mVI); k<=FINISHINGZ(mVI); k++)
82  {
83  for (int i=STARTINGY(mVI); i<=FINISHINGY(mVI); i++)
84  {
85  for (int j=STARTINGX(mVI); j<=FINISHINGX(mVI); j++)
86  {
87  double gx=0.0;
88  double gy=0.0;
89  double gz=0.0;
90  double k2=k*k;
91  double kr=k*iRmax;
92  double k2i2=k2+i*i;
93  double ir=i*iRmax;
94  double r2=k2i2+j*j;
95  double jr=j*iRmax;
96  double rr=std::sqrt(r2)*iRmax;
97  if (r2<Rmax2)
98  {
99  for (size_t idx=0; idx<idxY0; idx++)
100  {
101  int l1 = VEC_ELEM(vL1,idx);
102  int n = VEC_ELEM(vN,idx);
103  int l2 = VEC_ELEM(vL2,idx);
104  int m = VEC_ELEM(vM,idx);
105  zsph=ZernikeSphericalHarmonics(l1,n,l2,m,jr,ir,kr,rr);
106  if (rr>0 && l2!=0)
107  {
108  gx += clnm[idx] *zsph;
109  gy += clnm[idx+idxY0] *zsph;
110  gz += clnm[idx+idxZ0] *zsph;
111  }
112  }
113  }
114  voxelI=mVI.interpolatedElement3D(j+gx,i+gy,k+gz);
115  A3D_ELEM(VO(), k, i, j)=voxelI;
116  }
117  }
118  }
119  VO.write(fn_out);
120 }
121 
122 std::string ProgApplyVolDeformSph::readNthLine(int N) const
123 {
124  std::ifstream in(fn_sph.getString());
125  std::string s;
126 
127  //skip N lines
128  for(int i = 0; i < N; ++i)
129  std::getline(in, s);
130 
131  std::getline(in,s);
132  return s;
133 }
134 
135 std::vector<double> ProgApplyVolDeformSph::string2vector(std::string const &s) const
136 {
137  std::stringstream iss(s);
138  double number;
139  std::vector<double> v;
140  while (iss >> number)
141  v.push_back(number);
142  return v;
143 }
144 
146 {
147  int idx = 0;
148  auto vecSize = (int)((clnm.size())/3);
149  vL1.initZeros(vecSize);
150  vN.initZeros(vecSize);
151  vL2.initZeros(vecSize);
152  vM.initZeros(vecSize);
153  for (int h=0; h<=basisParams[1]; h++)
154  {
155  int totalSPH = 2*h+1;
156  auto aux = (int)(std::floor(totalSPH/2));
157  for (int l=h; l<=basisParams[0]; l+=2)
158  {
159  for (int m=0; m<totalSPH; m++)
160  {
161  VEC_ELEM(vL1,idx) = l;
162  VEC_ELEM(vN,idx) = h;
163  VEC_ELEM(vL2,idx) = h;
164  VEC_ELEM(vM,idx) = m-aux;
165  idx++;
166  }
167  }
168  }
169 }
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
__host__ __device__ float2 floor(const float2 v)
#define FINISHINGX(v)
void sqrt(Image< double > &op)
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)
#define FINISHINGZ(v)
#define STARTINGX(v)
#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
#define STARTINGY(v)
#define A3D_ELEM(V, k, i, j)
std::string readNthLine(int N) const
const char * getParam(const char *param, int arg=0)
int in
void addExampleLine(const char *example, bool verbatim=true)
T interpolatedElement3D(double x, double y, double z, T outside_value=(T) 0) const
int verbose
Verbosity level.
void show() const override
void initZeros()
Definition: matrix1d.h:592
#define j
int m
#define FINISHINGY(v)
double ZernikeSphericalHarmonics(int n, int m, double xr, double yr, double zr, double r)
String getString() const
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
float r2
void addUsageLine(const char *line, bool verbatim=false)
std::vector< double > string2vector(std::string const &s) const
#define STARTINGZ(v)
int * n
void addParamsLine(const String &line)
int ir