Xmipp  v3.23.11-Nereus
steerable.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Manuel Sanchez Pau
4  * Carlos Oscar Sanchez Sorzano
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 "steerable.h"
28 #include <core/xmipp_fftw.h>
29 #include <core/histogram.h>
30 #include <data/filters.h>
31 #include <data/morphology.h>
32 #include "core/geometry.h"
33 
34 // Remove wedge ------------------------------------------------------------
36 {
37  Matrix2D<double> Epos, Eneg;
40 
41  Matrix1D<double> freq(3), freqPos, freqNeg;
42  Matrix1D<int> idx(3);
43 
44  FourierTransformer transformer;
46  transformer.FourierTransform(V,Vfft,false);
47 
49  {
50  // Frequency in the coordinate system of the volume
51  VECTOR_R3(idx,j,i,k);
52  FFT_idx2digfreq(V,idx,freq);
53 
54  // Frequency in the coordinate system of the plane
55  freqPos=Epos*freq;
56  freqNeg=Eneg*freq;
57  if (ZZ(freqPos)<0 || ZZ(freqNeg)>0)
58  Vfft(k,i,j)=0;
59  }
60  transformer.inverseFourierTransform();
61 }
62 
63 // Constructor -------------------------------------------------------------
64 Steerable::Steerable(double sigma, MultidimArray<double> &Vtomograph,
65  double deltaAng, const std::string &filterType, const MissingWedge *_MW)
66 {
67  MW=_MW;
68  buildBasis(Vtomograph,sigma);
69 
70  // Choose a,b,c parameters as a function of the filterType
71  double a;
72  double b;
73  double c;
74  if (filterType == "wall") {
75  // for wall structures
76  a = -(1.0/4.0);
77  b = 5.0/4.0;
78  c = 5.0/2.0;
79  }
80  else{
81  // for filament structures
82  a = 1.0;
83  b = -(5.0/3.0);
84  c = 10.0/3.0;
85  }
86 
87  // Filter along tilt=0 and 180 => u=(1,0,0)
88  double u0=1;
89  double u1=0;
90  double u2=0;
91  FOR_ALL_ELEMENTS_IN_ARRAY3D(Vtomograph){
92  Vtomograph(k,i,j) = basis[0](k,i,j) * (a+b*u0*u0) +
93  basis[1](k,i,j) * (a+b*u1*u1) +
94  basis[2](k,i,j) * (a+b*u2*u2) +
95  c*(basis[3](k,i,j) * u0*u1 +
96  basis[4](k,i,j) * u0*u2 +
97  basis[5](k,i,j) * u1*u2);
98  }
99 
100  // Filter the rest of directions and keep the maximum
101  double Ntilt = round(180.0/deltaAng);
102  for (int i=1;i<Ntilt;i++){
103  double tilt = deltaAng*i;
104  double deltaRoti = deltaAng/SIND(tilt);
105  double NrotP = round(360.0/deltaRoti);
106  for (int j=0;j<NrotP;j++){
107  double rot = j*deltaRoti;
108  double u0 = SIND(rot)*COSD(tilt);
109  double u1 = SIND(rot)*SIND(tilt);
110  double u2 = COSD(rot);
111  FOR_ALL_ELEMENTS_IN_ARRAY3D(Vtomograph)
112  {
113  double filterval =
114  basis[0](k,i,j) * (a+b*u0*u0) +
115  basis[1](k,i,j) * (a+b*u1*u1) +
116  basis[2](k,i,j) * (a+b*u2*u2) +
117  c*(basis[3](k,i,j) * u0*u1 +
118  basis[4](k,i,j) * u0*u2 +
119  basis[5](k,i,j) * u1*u2);
120 
121  if(filterval>Vtomograph(k,i,j))
122  Vtomograph(k,i,j) = filterval;
123  }
124  }
125  }
126 }
127 
128 /* Build basis ------------------------------------------------------------- */
129 void Steerable::buildBasis(const MultidimArray<double> &Vtomograph, double sigma)
130 {
131  std::vector< MultidimArray<double> > hx1, hy1, hz1;
132  generate1DFilters(sigma, Vtomograph, hx1, hy1, hz1);
133  for (int n=0; n<6; n++)
134  {
136  singleFilter(Vtomograph,hx1[n],hy1[n],hz1[n],aux);
137  basis.push_back(aux);
138  }
139 }
140 
143  MultidimArray<double> &Vout){
144 
146  Vout.initZeros(Vin);
147 
148  // Filter in X
149  #define MINUS_ONE_POWER(n) (((n)%2==0)? 1:-1)
150  FourierTransformer transformer;
151  transformer.FourierTransform(hx1,H);
152 
154  H(i)*= MINUS_ONE_POWER(i);
155 
156  FourierTransformer transformer2;
157 
158  MultidimArray<double> aux(XSIZE(Vin));
159 
160  transformer2.setReal(aux);
161 
162  for (size_t k=0; k<ZSIZE(Vin); k++)
163  for (size_t i=0; i<YSIZE(Vin); i++)
164  {
165  for (size_t j=0; j<XSIZE(Vin); j++)
166  DIRECT_A1D_ELEM(aux,j)=DIRECT_A3D_ELEM(Vin,k,i,j);
167 
168  transformer2.FourierTransform( );
169  transformer2.getFourierAlias( Aux );
170  Aux*=H;
171  transformer2.inverseFourierTransform( );
172 
173  for (size_t j=0; j<XSIZE(Vin); j++)
174  DIRECT_A3D_ELEM(Vout,k,i,j)=XSIZE(aux)*DIRECT_A1D_ELEM(aux,j);
175  }
176 
177  // Filter in Y
178  transformer.FourierTransform(hy1,H);
179 
181  H(i)*= MINUS_ONE_POWER(i);
182 
183  aux.initZeros(YSIZE(Vin));
184  transformer2.setReal(aux);
185 
186  for (size_t k=0; k<ZSIZE(Vin); k++)
187  for (size_t j=0; j<XSIZE(Vin); j++)
188  {
189  for (size_t i=0; i<YSIZE(Vin); i++)
190  DIRECT_A1D_ELEM(aux,i)=DIRECT_A3D_ELEM(Vout,k,i,j);
191 
192  transformer2.FourierTransform( );
193  transformer2.getFourierAlias( Aux );
194  Aux*=H;
195  transformer2.inverseFourierTransform( );
196 
197  for (size_t i=0; i<YSIZE(Vin); i++)
198  DIRECT_A3D_ELEM(Vout,k,i,j)=XSIZE(aux)*DIRECT_A1D_ELEM(aux,i);
199  }
200 
201  // Filter in Z
202 
203  transformer.FourierTransform(hz1,H);
204 
206  H(i)*= MINUS_ONE_POWER(i);
207 
208  aux.initZeros(ZSIZE(Vin));
209  transformer2.setReal(aux);
210 
211  for (size_t i=0; i<YSIZE(Vin); i++)
212  for (size_t j=0; j<XSIZE(Vin); j++)
213  {
214  for (size_t k=0; k<ZSIZE(Vin); k++)
215  DIRECT_A1D_ELEM(aux,k)=DIRECT_A3D_ELEM(Vout,k,i,j);
216 
217  transformer2.FourierTransform( );
218  transformer2.getFourierAlias( Aux );
219  Aux*=H;
220  transformer2.inverseFourierTransform( );
221 
222  for (size_t k=0; k<ZSIZE(Vin); k++)
223  DIRECT_A3D_ELEM(Vout,k,i,j)=XSIZE(aux)*DIRECT_A1D_ELEM(aux,k);
224  }
225 
226  // If Missing wedge
227  if (MW!=nullptr)
228  MW->removeWedge(Vout);
229 }
230 
231 /* Filter generation ------------------------------------------------------- */
233  const MultidimArray<double> &Vtomograph,
234  std::vector< MultidimArray<double> > &hx1,
235  std::vector< MultidimArray<double> > &hy1,
236  std::vector< MultidimArray<double> > &hz1){
237 
238  // Initialization
240  aux.initZeros(XSIZE(Vtomograph));
241  aux.setXmippOrigin();
242  for (int i=0; i<6; i++) hx1.push_back(aux);
243 
244  aux.initZeros(YSIZE(Vtomograph));
245  aux.setXmippOrigin();
246  for (int i=0; i<6; i++) hy1.push_back(aux);
247 
248  aux.initZeros(ZSIZE(Vtomograph));
249  aux.setXmippOrigin();
250  for (int i=0; i<6; i++) hz1.push_back(aux);
251 
252  double sigma2=sigma*sigma;
253  double k1 = 1.0/pow((2.0*PI*sigma),(3.0/2.0));
254  double k2 = -1.0/sigma2;
255 
257  {
258  double i2=i*i;
259  double g = -exp(-i2/(2.0*sigma2));
260  hx1[0](i) = k1*k2*g*(1.0-(i2/sigma2));
261  hx1[1](i) = k1*k2*g;
262  hx1[2](i) = k1*k2*g;
263  hx1[3](i) = k1*k2*k2*g*i;
264  hx1[4](i) = k1*k2*k2*g*i;
265  hx1[5](i) = k1*k2*k2*g;
266  }
268  {
269  double i2=i*i;
270  double g = -exp(-i2/(2.0*sigma2));
271  hy1[0](i) = g;
272  hy1[1](i) = g*(1.0-(i2/sigma2));
273  hy1[2](i) = g;
274  hy1[3](i) = g*i;
275  hy1[4](i) = g;
276  hy1[5](i) = g*i;
277  }
279  {
280  double i2=i*i;
281  double g = -exp(-i2/(2.0*sigma2));
282  hz1[0](i) = g;
283  hz1[1](i) = g;
284  hz1[2](i) = g*(1.0-(i2/sigma2));
285  hz1[3](i) = g;
286  hz1[4](i) = g*i;
287  hz1[5](i) = g*i;
288  }
289 }
290 
292  std::vector< MultidimArray<double> > &hx1,
293  std::vector< MultidimArray<double> > &hy1,
294  std::vector< MultidimArray<double> > &hz1)
295 {
296  h3D.initZeros(XSIZE(hz1[0]),XSIZE(hy1[0]),XSIZE(hx1[0]));
297  h3D.setXmippOrigin();
299  for (int n=0; n<6; n++)
300  h3D(k,i,j)+=(hz1[n](k)*hy1[n](i)*hx1[n](j));
301 }
302 
#define YSIZE(v)
void inverseFourierTransform()
Definition: xmipp_fftw.cpp:329
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
doublereal * c
doublereal * g
void removeWedge(MultidimArray< double > &V) const
Remove wedge.
Definition: steerable.cpp:35
void generate3DFilter(MultidimArray< double > &h3D, std::vector< MultidimArray< double > > &hx1, std::vector< MultidimArray< double > > &hy1, std::vector< MultidimArray< double > > &hz1)
Definition: steerable.cpp:291
#define SIND(x)
Definition: xmipp_macros.h:347
void FFT_idx2digfreq(T &v, const Matrix1D< int > &idx, Matrix1D< double > &freq)
Definition: xmipp_fft.h:80
double tiltPos
Tilt of the positive plane.
Definition: steerable.h:43
#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 DIRECT_A1D_ELEM(v, i)
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
doublereal * b
double rotNeg
Rot of the negative plane.
Definition: steerable.h:45
void buildBasis(const MultidimArray< double > &Vtomograph, double sigma)
Definition: steerable.cpp:129
void setReal(MultidimArray< double > &img)
Definition: xmipp_fftw.cpp:129
double tiltNeg
Tilt of the negative plane.
Definition: steerable.h:47
#define XSIZE(v)
void generate1DFilters(double sigma, const MultidimArray< double > &Vtomograph, std::vector< MultidimArray< double > > &hx1, std::vector< MultidimArray< double > > &hy1, std::vector< MultidimArray< double > > &hz1)
Definition: steerable.cpp:232
#define ZSIZE(v)
#define Ntilt
Definition: project.cpp:557
#define DIRECT_A3D_ELEM(v, k, i, j)
void FourierTransform(T &v, T1 &V, bool getCopy=true)
Definition: xmipp_fftw.h:166
#define j
double rotPos
Rot of the positive plane.
Definition: steerable.h:41
#define FOR_ALL_ELEMENTS_IN_ARRAY1D(v)
int round(double x)
Definition: ap.cpp:7245
Steerable(double sigma, MultidimArray< double > &Vtomograph, double deltaAng, const std::string &filterType, const MissingWedge *_MW)
Definition: steerable.cpp:64
void getFourierAlias(T &V)
Definition: xmipp_fftw.h:207
#define VECTOR_R3(v, x, y, z)
Definition: matrix1d.h:124
void initZeros(const MultidimArray< T1 > &op)
void singleFilter(const MultidimArray< double > &Vin, MultidimArray< double > &hx1, MultidimArray< double > &hy1, MultidimArray< double > &hz1, MultidimArray< double > &Vout)
Definition: steerable.cpp:141
#define COSD(x)
Definition: xmipp_macros.h:329
#define PI
Definition: tools.h:43
#define MINUS_ONE_POWER(n)
int * n
#define ZZ(v)
Definition: matrix1d.h:101
doublereal * a