36 addUsageLine(
"Compute the deformation that properly fits two volumes using spherical harmonics");
39 addParamsLine(
" [-o <volume=\"\">] : Output volume which is the deformed input volume");
40 addParamsLine(
" [--oroot <rootname=\"Volumes\">] : Root name for output files");
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");
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)
71 return std::stod(val);
86 m_threadPool.
resize(threads);
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
100 <<
"Regularization: " <<
lambda << std::endl
105 void ProgVolDeformSph::computeShift(
int k) {
106 const auto &mVR =
VR();
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;
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) {
122 r_vals.jr, r_vals.ir, r_vals.kr, r_vals.rr);
123 auto &
c = clnm_c[idx];
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;
148 const auto &
g = m_shifts[vec_idx];
149 if (APPLY_TRANSFORM) {
151 double voxelI = VI_c().interpolatedElement3D(
j+
g.x,
i+
g.y,
k+
g.z);
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);
160 for (
int idv=0; idv<volumesR_c.size(); idv++) {
162 double voxelI = volumesI_c[idv]().interpolatedElement3D(
j+
g.x,
i+
g.y,
k+
g.z);
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);
171 if (SAVE_DEFORMATION) {
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));
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);
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);
204 ProgVolDeformSph::Distance_vals ProgVolDeformSph::computeDistance() {
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());
214 auto usual_routine = [
this, &vals](
int thrId,
int k) {
216 computeDistance(
k, vals[thrId]);
220 auto special_routine = [
this](
int thrId,
int k) {
225 futures.emplace_back(m_threadPool.
push(usual_routine,
k));
227 futures.emplace_back(m_threadPool.
push(special_routine,
k));
231 for (
auto &
f : futures) {
238 computeDistance<true, true>(vals[0]);
240 computeDistance<true, false>(vals[0]);
244 computeDistance<false, true>(vals[0]);
246 computeDistance<false, false>(vals[0]);
251 return std::accumulate(vals.begin(), vals.end(), Distance_vals());
260 VO().initZeros(
VR());
261 VO().setXmippOrigin();
265 const size_t size = m_clnm.size();
266 for (
size_t i = 0;
i < size; ++
i) {
269 p.y = pclnm[
i + size + 1];
270 p.z = pclnm[
i + size + size + 1];
273 const auto distance_vals = computeDistance();
275 sumVD = distance_vals.VD;
288 return prm->distance(p);
301 VI().setXmippOrigin();
302 VR().setXmippOrigin();
331 for (
int ids=0; ids<
sigma.size(); ids++)
365 for (
int h=0;h<=
L2;h++)
371 std::cout<<std::endl;
372 std::cout<<
"-------------------------- Basis Degrees: ("<<
L1<<
","<<h<<
") --------------------------"<<std::endl;
395 0.01, fitness, iter, steps,
true);
397 std::cout<<std::endl;
398 std::cout <<
"Deformation " <<
deformation << std::endl;
399 std::ofstream deformFile;
400 deformFile.open (
fnRoot+
"_deformation.txt");
413 std::cout <<
"Error=" << deformation << std::endl;
414 std::cout <<
"Press any key\n";
415 char c; std::cin >>
c;
430 Gx().initZeros(
VR());
431 Gy().initZeros(
VR());
432 Gz().initZeros(
VR());
433 Gx().setXmippOrigin();
434 Gy().setXmippOrigin();
435 Gz().setXmippOrigin();
443 save.write(
fnRoot+
"_PPPGx.vol");
445 save.write(
fnRoot+
"_PPPGy.vol");
447 save.write(
fnRoot+
"_PPPGz.vol");
458 auto totalSize = (int)(steps.
size()/3);
459 for (
int idx=0; idx<size; idx++)
463 VEC_ELEM(steps,idx+2*totalSize) = 1;
471 for (
int h=0; h<=l2; h++)
477 int numEven=(count>>1)+(count&1 && !(h&1));
480 nc += numSPH*numEven;
482 nc += numSPH*(l1-h+1-numEven);
490 for (
int h=0; h<=l2; h++)
492 int totalSPH = 2*h+1;
494 for (
int l=h; l<=l1; l+=2)
496 for (
int m=0;
m<totalSPH;
m++)
498 auto &t = m_zshVals[idx];
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 517 LS().initZeros(
Gx());
518 LR().initZeros(
Gx());
539 std::vector< std::complex<double> > eigs;
579 for (
size_t n=0;
n < eigs.size();
n++)
581 double imagabs=fabs(eigs[
n].imag());
598 std::ofstream outFile;
600 outFile.open(outPath, std::ios_base::app);
602 outFile.open(outPath);
605 outFile << std::endl;
double getDoubleParam(const char *param, int arg=0)
__host__ __device__ float2 floor(const float2 v)
void resizeNoCopy(const MultidimArray< T1 > &v)
auto push(F &&f, Rest &&... rest) -> std::future< decltype(f(0, rest...))>
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)
void abs(Image< double > &op)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(V)
static unsigned findCores()
void resize(int nThreads)
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 MAT_ELEM(m, i, j)
#define A3D_ELEM(V, k, i, j)
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
const char * getParam(const char *param, int arg=0)
void normalize_Robust(MultidimArray< double > &I, const MultidimArray< int > &bg_mask, bool clip)
void addExampleLine(const char *example, bool verbatim=true)
int verbose
Verbosity level.
#define DIRECT_A3D_ELEM(v, k, i, j)
void allEigs(const Matrix2D< double > &A, std::vector< std::complex< double > > &eigs)
FileName withoutExtension() const
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)
T * adaptForNumericalRecipes() const
int getIntParam(const char *param, int arg=0)
void generateMask(MultidimArray< double > &v)
double fitness(double *p)
void addParamsLine(const String &line)
void applyMaskSpace(MultidimArray< double > &v)