Xmipp  v3.23.11-Nereus
volume_deform_sph.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 "data/cpu.h"
29 #include "volume_deform_sph.h"
30 #include "data/fourier_filter.h"
31 #include "data/normalize.h"
32 
33 // Params definition =======================================================
34 // -i ---> V2 (paper) / -r --> V1 (paper)
36  addUsageLine("Compute the deformation that properly fits two volumes using spherical harmonics");
37  addParamsLine(" -i <volume> : Volume to deform");
38  addParamsLine(" -r <volume> : Reference volume");
39  addParamsLine(" [-o <volume=\"\">] : Output volume which is the deformed input volume");
40  addParamsLine(" [--oroot <rootname=\"Volumes\">] : Root name for output files");
41  addParamsLine(" : By default, the input file is rewritten");
42  addParamsLine(" [--sigma <Matrix1D=\"\">] : Sigma values to filter the volume to perform a multiresolution analysis");
43  addParamsLine(" [--analyzeStrain] : Save the deformation of each voxel for local strain and rotation analysis");
44  addParamsLine(" [--optimizeRadius] : Optimize the radius of each spherical harmonic");
45  addParamsLine(" [--l1 <l1=3>] : Degree Zernike Polynomials=1,2,3,...");
46  addParamsLine(" [--l2 <l2=2>] : Harmonical depth of the deformation=1,2,3,...");
47  addParamsLine(" [--regularization <l=0.00025>] : Regularization weight");
48  addParamsLine(" [--Rmax <r=-1>] : Maximum radius for the transformation");
49  addParamsLine(" [--thr <N=-1>] : Maximal number of the processing CPU threads");
50  addExampleLine("xmipp_volume_deform_sph -i vol1.vol -r vol2.vol -o vol1DeformedTo2.vol");
51 }
52 
53 // Read arguments ==========================================================
55  std::string aux;
56  fnVolI = getParam("-i");
57  fnVolR = getParam("-r");
58  L1 = getIntParam("--l1");
59  L2 = getIntParam("--l2");
60  fnRoot = getParam("--oroot");
61 
62  aux = getParam("--sigma");
63  // Transform string ov values separated by white spaces into substrings stored in a vector
64  std::stringstream ss(aux);
65  std::istream_iterator<std::string> begin(ss);
66  std::istream_iterator<std::string> end;
67  std::vector<std::string> vstrings(begin, end);
68  sigma.resize(vstrings.size());
69  std::transform(vstrings.begin(), vstrings.end(), sigma.begin(), [](const std::string& val)
70  {
71  return std::stod(val);
72  });
73 
74  fnVolOut = getParam("-o");
75  if (fnVolOut=="")
76  fnVolOut=fnVolI;
77  analyzeStrain=checkParam("--analyzeStrain");
78  optimizeRadius=checkParam("--optimizeRadius");
79  lambda = getDoubleParam("--regularization");
80  Rmax = getDoubleParam("--Rmax");
81  applyTransformation = false;
82  int threads = getIntParam("--thr");
83  if (0 >= threads) {
84  threads = CPU::findCores();
85  }
86  m_threadPool.resize(threads);
87 }
88 
89 // Show ====================================================================
91  if (verbose==0)
92  return;
93  std::cout
94  << "Volume to deform: " << fnVolI << std::endl
95  << "Reference volume: " << fnVolR << std::endl
96  << "Output volume: " << fnVolOut << std::endl
97  << "Zernike Degree: " << L1 << std::endl
98  << "SH Degree: " << L2 << std::endl
99  << "Save deformation: " << analyzeStrain << std::endl
100  << "Regularization: " << lambda << std::endl
101  ;
102 
103 }
104 
105 void ProgVolDeformSph::computeShift(int k) {
106  const auto &mVR = VR();
107  const double Rmax2=Rmax*Rmax;
108  const double iRmax = 1.0 / Rmax;
109  size_t vec_idx = mVR.yxdim * (k - STARTINGZ(mVR));
110  const auto &clnm_c = m_clnm;
111  const auto &zsh_vals_c = m_zshVals;
112  for (int i=STARTINGY(mVR); i<=FINISHINGY(mVR); i++) {
113  for (int j=STARTINGX(mVR); j<=FINISHINGX(mVR); j++, ++vec_idx) {
114  const auto r_vals = Radius_vals(i, j, k, iRmax);
115  if (r_vals.r2 < Rmax2) {
116  auto &g = m_shifts[vec_idx] = 0;
117  for (size_t idx=0; idx<clnm_c.size(); idx++) {
118  if (clnm_c[idx].x != 0) {
119  auto &tmp = zsh_vals_c[idx];
120  if (r_vals.rr>0 || tmp.l2==0) {
121  double zsph=ZernikeSphericalHarmonics(tmp.l1,tmp.n,tmp.l2,tmp.m,
122  r_vals.jr, r_vals.ir, r_vals.kr, r_vals.rr);
123  auto &c = clnm_c[idx];
124  g.x += c.x * zsph;
125  g.y += c.y * zsph;
126  g.z += c.z * zsph;
127  }
128  }
129  }
130  }
131  }
132  }
133 // }
134 }
135 
136 template<bool APPLY_TRANSFORM, bool SAVE_DEFORMATION>
137 void ProgVolDeformSph::computeDistance(Distance_vals &vals) {
138  const auto &mVR = VR();
139  const auto &VR_c = VR;
140  const auto &VI_c = VI;
141  const auto &VO_c = VO;
142  const auto &volumesR_c = volumesR;
143  const auto &volumesI_c = volumesI;
144  size_t vec_idx = 0;
145  for (int k=STARTINGZ(mVR); k<=FINISHINGZ(mVR); k++) {
146  for (int i=STARTINGY(mVR); i<=FINISHINGY(mVR); i++) {
147  for (int j=STARTINGX(mVR); j<=FINISHINGX(mVR); j++, ++vec_idx) {
148  const auto &g = m_shifts[vec_idx];
149  if (APPLY_TRANSFORM) {
150  double voxelR = A3D_ELEM(VR_c(),k,i,j);
151  double voxelI = VI_c().interpolatedElement3D(j+g.x,i+g.y,k+g.z);
152  if (voxelI >= 0.0)
153  vals.VD += voxelI;
154  VO_c(k,i,j) = voxelI;
155  double diff = voxelR-voxelI;
156  vals.diff += diff * diff;
157  vals.modg += (g.x * g.x) + (g.y * g.y) + (g.z * g.z);
158  vals.count++;
159  }
160  for (int idv=0; idv<volumesR_c.size(); idv++) {
161  double voxelR = A3D_ELEM(volumesR_c[idv](),k,i,j);
162  double voxelI = volumesI_c[idv]().interpolatedElement3D(j+g.x,i+g.y,k+g.z);
163  if (voxelI >= 0.0)
164  vals.VD += voxelI;
165  double diff = voxelR - voxelI;
166  vals.diff += diff * diff;
167  vals.modg += (g.x * g.x) + (g.y * g.y) + (g.z * g.z);
168  vals.count++;
169  }
170 
171  if (SAVE_DEFORMATION) {
172  Gx(k,i,j) = g.x;
173  Gy(k,i,j) = g.y;
174  Gz(k,i,j) = g.z;
175  }
176  }
177  }
178  }
179 }
180 
181 void ProgVolDeformSph::computeDistance(int k, Distance_vals &vals) {
182  const auto &mVR = VR();
183  for (int idv=0; idv<volumesR.size(); idv++) {
184  size_t voxel_idx = mVR.yxdim * (k - STARTINGZ(mVR));
185  const auto &volR = volumesR[idv]();
186  const auto &volI = volumesI[idv]();
187  for (int i=STARTINGY(mVR); i<=FINISHINGY(mVR); i++) {
188  for (int j=STARTINGX(mVR); j<=FINISHINGX(mVR); j++, ++voxel_idx) {
189  const auto &g = m_shifts[voxel_idx];
190  double voxelR = volR.data[voxel_idx];
191  double voxelI = volI.interpolatedElement3D(j+g.x,i+g.y,k+g.z);
192  if (voxelI >= 0.0) // background could be smaller than 0
193  vals.VD += voxelI;
194  double diff = voxelR - voxelI;
195  vals.diff += diff * diff;
196  vals.modg += (g.x * g.x) + (g.y * g.y) + (g.z * g.z);
197  vals.count++;
198  }
199  }
200  }
201 // }
202 }
203 
204 ProgVolDeformSph::Distance_vals ProgVolDeformSph::computeDistance() {
205  const bool usual_case = ( ! applyTransformation) && ( ! saveDeformation);
206  // parallelize at the level of Z slices
207  const auto &mVR = VR();
208  m_shifts.resize(mVR.zyxdim);
209  auto futures = std::vector<std::future<void>>();
210  futures.reserve(mVR.zdim);
211  auto vals = std::vector<Distance_vals>(m_threadPool.size());
212  // most common routine, run during the computation
213  // for each Z slice, compute shift and distance
214  auto usual_routine = [this, &vals](int thrId, int k) {
215  computeShift(k);
216  computeDistance(k, vals[thrId]);
217  };
218  // special routine, run at the end for the computation
219  // for each Z slice, compute shift. Distance will be computed later
220  auto special_routine = [this](int thrId, int k) {
221  computeShift(k);
222  };
223  for (int k=STARTINGZ(mVR); k<=FINISHINGZ(mVR); ++k) {
224  if (usual_case) {
225  futures.emplace_back(m_threadPool.push(usual_routine, k));
226  } else {
227  futures.emplace_back(m_threadPool.push(special_routine, k));
228  }
229  }
230  // wait till all slices are processed
231  for (auto &f : futures) {
232  f.get();
233  }
234  if ( ! usual_case) {
235  // shifts have been already computed, now compute the final distance
236  if (applyTransformation) {
237  if (saveDeformation) {
238  computeDistance<true, true>(vals[0]);
239  } else {
240  computeDistance<true, false>(vals[0]);
241  }
242  } else {
243  if (saveDeformation) {
244  computeDistance<false, true>(vals[0]);
245  } else {
246  computeDistance<false, false>(vals[0]);
247  }
248  }
249  }
250  // merge results
251  return std::accumulate(vals.begin(), vals.end(), Distance_vals());
252 }
253 
254 // Distance function =======================================================
255 // #define DEBUG
256 double ProgVolDeformSph::distance(double *pclnm)
257 {
259  {
260  VO().initZeros(VR());
261  VO().setXmippOrigin();
262  }
263  const MultidimArray<double> &mVR=VR();
264  const MultidimArray<double> &mVI=VI();
265  const size_t size = m_clnm.size();
266  for (size_t i = 0; i < size; ++i) {
267  auto &p = m_clnm[i];
268  p.x = pclnm[i + 1];
269  p.y = pclnm[i + size + 1];
270  p.z = pclnm[i + size + size + 1];
271  }
272 
273  const auto distance_vals = computeDistance();
274  deformation=std::sqrt(distance_vals.modg / (double)distance_vals.count);
275  sumVD = distance_vals.VD;
276 
278  VO.write(fnVolOut);
279 
280  double massDiff=std::abs(sumVI-sumVD)/sumVI;
281  return std::sqrt(distance_vals.diff / (double)distance_vals.count)+lambda*(deformation+massDiff);
282 }
283 #undef DEBUG
284 
285 double volDeformSphGoal(double *p, void *vprm)
286 {
287  auto *prm=(ProgVolDeformSph *) vprm;
288  return prm->distance(p);
289 }
290 
291 // Run =====================================================================
293  saveDeformation=false;
294 
295  VI.read(fnVolI);
296  VR.read(fnVolR);
297  sumVI = 0.0;
298  if (Rmax<0)
299  Rmax=XSIZE(VI())/2;
300 
301  VI().setXmippOrigin();
302  VR().setXmippOrigin();
303 
304  // Filter input and reference volumes according to the values of sigma
305  FourierFilter filter;
306  filter.FilterShape = REALGAUSSIAN;
307  filter.FilterBand = LOWPASS;
308  filter.generateMask(VI());
309 
310  // We need also to normalized the filtered volumes to compare them appropiately
311  Image<double> auxI = VI;
312  Image<double> auxR = VR;
313 
314  MultidimArray<int> bg_mask;
315  bg_mask.resizeNoCopy(VI().zdim, VI().ydim, VI().xdim);
316  bg_mask.setXmippOrigin();
317  normalize_Robust(auxI(), bg_mask, true);
318  bg_mask *= 0;
319  normalize_Robust(auxR(), bg_mask, true);
320 
322  {
323  if (DIRECT_A3D_ELEM(auxI(),k,i,j) >= 0.0)
324  sumVI += DIRECT_A3D_ELEM(auxI(),k,i,j);
325  }
326 
327  volumesI.push_back(auxI());
328  volumesR.push_back(auxR());
329  if (sigma.size() > 1 || sigma[0] != 0)
330  {
331  for (int ids=0; ids<sigma.size(); ids++)
332  {
333  Image<double> auxI = VI;
334  Image<double> auxR = VR;
335  filter.w1 = sigma[ids];
336 
337  // Filer input vol
338  filter.do_generate_3dmask = true;
339  filter.applyMaskSpace(auxI());
340  bg_mask *= 0;
341  normalize_Robust(auxI(), bg_mask, true);
342  volumesI.push_back(auxI);
344  {
345  if (DIRECT_A3D_ELEM(auxI(),k,i,j) >= 0.0)
346  sumVI += DIRECT_A3D_ELEM(auxI(),k,i,j);
347  }
348 
349  // Filter ref vol
350  filter.applyMaskSpace(auxR());
351  bg_mask *= 0;
352  normalize_Robust(auxR(), bg_mask, true);
353  volumesR.push_back(auxR);
354  }
355  }
356 
359  vecSize = 0;
361  size_t totalSize = 3*vecSize;
363  m_clnm.resize(vecSize);
364  x.initZeros(totalSize);
365  for (int h=0;h<=L2;h++)
366  {
367  steps.clear();
368  steps.initZeros(totalSize);
369  minimizepos(h,steps);
370 
371  std::cout<<std::endl;
372  std::cout<<"-------------------------- Basis Degrees: ("<<L1<<","<<h<<") --------------------------"<<std::endl;
373 #ifdef NEVERDEFINED
374  for (int d=0;d<VEC_XSIZE(x);d++)
375  {
376  if (x(d)==0)
377  {
378  steps(d) = 1;
379  }
380  else if (d>=VEC_XSIZE(steps)+nh(h)-nh(h+1)&d<VEC_XSIZE(steps)+nh(h+1))
381  {
382  steps(d) = 1;
383  }
384  else
385  {
386  steps(d) = 0;
387  }
388  //std::cout<<steps(d)<<" ";
389  }
390  //std::cout<<std::endl;
391 #endif
392  int iter;
393  double fitness;
394  powellOptimizer(x, 1, (int)(totalSize), &volDeformSphGoal, this,
395  0.01, fitness, iter, steps, true);
396 
397  std::cout<<std::endl;
398  std::cout << "Deformation " << deformation << std::endl;
399  std::ofstream deformFile;
400  deformFile.open (fnRoot+"_deformation.txt");
401  deformFile << deformation;
402  deformFile.close();
403 
404 // #define DEBUG
405 #ifdef DEBUG
406  Image<double> save;
407  save() = VI();
408  save.write(fnRoot+"_PPPIdeformed.vol");
409  save()-=VR();
410  save.write(fnRoot+"_PPPdiff.vol");
411  save()=VR();
412  save.write(fnRoot+"_PPPR.vol");
413  std::cout << "Error=" << deformation << std::endl;
414  std::cout << "Press any key\n";
415  char c; std::cin >> c;
416 #endif
417 
418  }
419  applyTransformation=true;
420  Matrix1D<double> degrees;
421  degrees.initZeros(3);
422  VEC_ELEM(degrees,0) = L1;
423  VEC_ELEM(degrees,1) = L2;
424  VEC_ELEM(degrees,2) = Rmax;
425  writeVector(fnRoot+"_clnm.txt", degrees, false);
426  writeVector(fnRoot+"_clnm.txt", x, true);
427  if (analyzeStrain)
428  {
429  saveDeformation=true;
430  Gx().initZeros(VR());
431  Gy().initZeros(VR());
432  Gz().initZeros(VR());
433  Gx().setXmippOrigin();
434  Gy().setXmippOrigin();
435  Gz().setXmippOrigin();
436  }
437 
438  distance(x.adaptForNumericalRecipes()); // To save the output volume
439 
440 #ifdef DEBUG
441  Image<double> save;
442  save() = Gx();
443  save.write(fnRoot+"_PPPGx.vol");
444  save() = Gy();
445  save.write(fnRoot+"_PPPGy.vol");
446  save() = Gz();
447  save.write(fnRoot+"_PPPGz.vol");
448 #endif
449 
450  if (analyzeStrain)
451  computeStrain();
452 }
453 
455 {
456  int size = 0;
457  numCoefficients(L1,l2,size);
458  auto totalSize = (int)(steps.size()/3);
459  for (int idx=0; idx<size; idx++)
460  {
461  VEC_ELEM(steps,idx) = 1;
462  VEC_ELEM(steps,idx+totalSize) = 1;
463  VEC_ELEM(steps,idx+2*totalSize) = 1;
464  }
465 }
466 
467 void ProgVolDeformSph::numCoefficients(int l1, int l2, int &nc) const
468 {
469  // l1 -> Degree Zernike
470  // l2 & h --> Degree SPH
471  for (int h=0; h<=l2; h++)
472  {
473  // For the current SPH degree (h), determine the number of SPH components/equations
474  int numSPH = 2*h+1;
475  // Finf the total number of radial components with even degree for a given l1 and h
476  int count=l1-h+1;
477  int numEven=(count>>1)+(count&1 && !(h&1));
478  // Total number of components is the number of SPH as many times as Zernike components
479  if (h%2 == 0)
480  nc += numSPH*numEven;
481  else
482  nc += numSPH*(l1-h+1-numEven);
483  }
484 }
485 
487 {
488  m_zshVals.resize(vecSize);
489  int idx = 0;
490  for (int h=0; h<=l2; h++)
491  {
492  int totalSPH = 2*h+1;
493  auto aux = (int)(std::floor(totalSPH/2));
494  for (int l=h; l<=l1; l+=2)
495  {
496  for (int m=0; m<totalSPH; m++)
497  {
498  auto &t = m_zshVals[idx];
499  t.l1 = l;
500  t.n = h;
501  t.l2 = h;
502  t.m = m - aux;
503  idx++;
504  }
505  }
506  }
507 }
508 
509 // Number Spherical Harmonics ==============================================
510 #define Dx(V) (A3D_ELEM(V,k,i,jm2)-8*A3D_ELEM(V,k,i,jm1)+8*A3D_ELEM(V,k,i,jp1)-A3D_ELEM(V,k,i,jp2))/12.0
511 #define Dy(V) (A3D_ELEM(V,k,im2,j)-8*A3D_ELEM(V,k,im1,j)+8*A3D_ELEM(V,k,ip1,j)-A3D_ELEM(V,k,ip2,j))/12.0
512 #define Dz(V) (A3D_ELEM(V,km2,i,j)-8*A3D_ELEM(V,km1,i,j)+8*A3D_ELEM(V,kp1,i,j)-A3D_ELEM(V,kp2,i,j))/12.0
513 
515 {
516  Image<double> LS, LR;
517  LS().initZeros(Gx());
518  LR().initZeros(Gx());
519 
520  // Gaussian filter of the derivatives
524  f.w1=2;
525  f.applyMaskSpace(Gx());
526  f.applyMaskSpace(Gy());
527  f.applyMaskSpace(Gz());
528 
529  Gx.write(fnRoot+"_PPPGx.vol");
530  Gy.write(fnRoot+"_PPPGy.vol");
531  Gz.write(fnRoot+"_PPPGz.vol");
532 
533  MultidimArray<double> &mLS=LS();
534  MultidimArray<double> &mLR=LR();
535  MultidimArray<double> &mGx=Gx();
536  MultidimArray<double> &mGy=Gy();
537  MultidimArray<double> &mGz=Gz();
538  Matrix2D<double> U(3,3), D(3,3), H(3,3);
539  std::vector< std::complex<double> > eigs;
540  H.initZeros();
541  for (int k=STARTINGZ(mLS)+2; k<=FINISHINGZ(mLS)-2; ++k)
542  {
543  int km1=k-1;
544  int kp1=k+1;
545  int km2=k-2;
546  int kp2=k+2;
547  for (int i=STARTINGY(mLS)+2; i<=FINISHINGY(mLS)-2; ++i)
548  {
549  int im1=i-1;
550  int ip1=i+1;
551  int im2=i-2;
552  int ip2=i+2;
553  for (int j=STARTINGX(mLS)+2; j<=FINISHINGX(mLS)-2; ++j)
554  {
555  int jm1=j-1;
556  int jp1=j+1;
557  int jm2=j-2;
558  int jp2=j+2;
559  MAT_ELEM(U,0,0)=Dx(mGx); MAT_ELEM(U,0,1)=Dy(mGx); MAT_ELEM(U,0,2)=Dz(mGx);
560  MAT_ELEM(U,1,0)=Dx(mGy); MAT_ELEM(U,1,1)=Dy(mGy); MAT_ELEM(U,1,2)=Dz(mGy);
561  MAT_ELEM(U,2,0)=Dx(mGz); MAT_ELEM(U,2,1)=Dy(mGz); MAT_ELEM(U,2,2)=Dz(mGz);
562 
563  MAT_ELEM(D,0,0) = MAT_ELEM(U,0,0);
564  MAT_ELEM(D,0,1) = MAT_ELEM(D,1,0) = 0.5*(MAT_ELEM(U,0,1)+MAT_ELEM(U,1,0));
565  MAT_ELEM(D,0,2) = MAT_ELEM(D,2,0) = 0.5*(MAT_ELEM(U,0,2)+MAT_ELEM(U,2,0));
566  MAT_ELEM(D,1,1) = MAT_ELEM(U,1,1);
567  MAT_ELEM(D,1,2) = MAT_ELEM(D,2,1) = 0.5*(MAT_ELEM(U,1,2)+MAT_ELEM(U,2,1));
568  MAT_ELEM(D,2,2) = MAT_ELEM(U,2,2);
569 
570  MAT_ELEM(H,0,1) = 0.5*(MAT_ELEM(U,0,1)-MAT_ELEM(U,1,0));
571  MAT_ELEM(H,0,2) = 0.5*(MAT_ELEM(U,0,2)-MAT_ELEM(U,2,0));
572  MAT_ELEM(H,1,2) = 0.5*(MAT_ELEM(U,1,2)-MAT_ELEM(U,2,1));
573  MAT_ELEM(H,1,0) = -MAT_ELEM(H,0,1);
574  MAT_ELEM(H,2,0) = -MAT_ELEM(H,0,2);
575  MAT_ELEM(H,2,1) = -MAT_ELEM(H,1,2);
576 
577  A3D_ELEM(mLS,k,i,j)=fabs(D.det());
578  allEigs(H,eigs);
579  for (size_t n=0; n < eigs.size(); n++)
580  {
581  double imagabs=fabs(eigs[n].imag());
582  if (imagabs>1e-6)
583  {
584  A3D_ELEM(mLR,k,i,j)=imagabs*180/PI;
585  break;
586  }
587  }
588  }
589  }
590  LS.write(fnVolOut.withoutExtension()+"_strain.mrc");
591  LR.write(fnVolOut.withoutExtension()+"_rotation.mrc");
592  }
593 }
594 
595 void ProgVolDeformSph::writeVector(std::string const &outPath, Matrix1D<double> const &v,
596  bool append) const
597 {
598  std::ofstream outFile;
599  if (append)
600  outFile.open(outPath, std::ios_base::app);
601  else
602  outFile.open(outPath);
604  outFile << VEC_ELEM(v,i) << " ";
605  outFile << std::endl;
606 }
607 
608 
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
#define Dx(V)
double getDoubleParam(const char *param, int arg=0)
__host__ __device__ float2 floor(const float2 v)
void clear()
Definition: matrix1d.cpp:67
#define FINISHINGX(v)
std::vector< Image< double > > volumesR
size_t size() const
Definition: matrix1d.h:508
std::vector< Image< double > > volumesI
Image Vector.
void computeStrain()
Compute strain.
#define VEC_XSIZE(m)
Definition: matrix1d.h:77
doublereal * c
doublereal * g
void resizeNoCopy(const MultidimArray< T1 > &v)
auto push(F &&f, Rest &&... rest) -> std::future< decltype(f(0, rest...))>
Definition: ctpl.h:152
void sqrt(Image< double > &op)
Image< double > VI
Images.
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)
FileName fnRoot
Root name for several output files.
#define Dy(V)
void abs(Image< double > &op)
void powellOptimizer(Matrix1D< double > &p, int i0, int n, double(*f)(double *x, void *), void *prm, double ftol, double &fret, int &iter, const Matrix1D< double > &steps, bool show)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(V)
Image< double > Gy
#define FINISHINGZ(v)
glob_prnt iter
static unsigned findCores()
Definition: cpu.h:41
void resize(int nThreads)
Definition: ctpl.h:70
#define STARTINGX(v)
void fillVectorTerms(int l1, int l2)
Zernike and SPH coefficients allocation.
doublereal * x
#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
void readParams()
Read arguments from command line.
doublereal * d
#define STARTINGY(v)
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
#define A3D_ELEM(V, k, i, j)
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
Definition: matrix1d.h:72
int L1
Degree of Zernike polynomials and spherical harmonics.
const char * getParam(const char *param, int arg=0)
void numCoefficients(int l1, int l2, int &nc) const
Length of coefficients vector.
double * f
#define XSIZE(v)
void normalize_Robust(MultidimArray< double > &I, const MultidimArray< int > &bg_mask, bool clip)
Definition: normalize.cpp:265
void addExampleLine(const char *example, bool verbatim=true)
Image< double > Gx
int verbose
Verbosity level.
void initZeros()
Definition: matrix1d.h:592
void writeVector(std::string const &outPath, Matrix1D< double > const &v, bool append) const
Save vector to file.
#define DIRECT_A3D_ELEM(v, k, i, j)
void allEigs(const Matrix2D< double > &A, std::vector< std::complex< double > > &eigs)
Definition: matrix2d.cpp:345
bool optimizeRadius
Radius optimization.
#define j
double steps
Image< double > Gz
int m
Image< double > VO
double distance(double *pclnm)
Distance.
double volDeformSphGoal(double *p, void *vprm)
#define FINISHINGY(v)
FileName withoutExtension() const
double ZernikeSphericalHarmonics(int n, int m, double xr, double yr, double zr, double r)
FileName fnVolI
Volume to deform.
int size()
Definition: ctpl.h:61
bool analyzeStrain
Save the deformation of each voxel for local strain and rotation analysis.
void initZeros()
Definition: matrix2d.h:626
bool checkParam(const char *param)
double Rmax
Maximum radius for the transformation.
int vecSize
Coefficient vector size.
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
Image< double > VR
ProgClassifyCL2D * prm
#define REALGAUSSIAN
void addUsageLine(const char *line, bool verbatim=false)
FileName fnVolR
Reference volume.
std::vector< double > sigma
Gaussian width to filter the volumes.
void minimizepos(int l2, Matrix1D< double > &steps) const
Determine the positions to be minimize of a vector containing spherical harmonic coefficients.
#define PI
Definition: tools.h:43
void defineParams()
Define params.
T * adaptForNumericalRecipes() const
Definition: matrix1d.h:844
int getIntParam(const char *param, int arg=0)
void generateMask(MultidimArray< double > &v)
#define STARTINGZ(v)
int * n
double fitness(double *p)
FileName fnVolOut
Output Volume (deformed input volume)
#define LOWPASS
void addParamsLine(const String &line)
void applyMaskSpace(MultidimArray< double > &v)
#define Dz(V)