14 #ifndef INCLUDED_core_scoring_electron_density_util_hh
15 #define INCLUDED_core_scoring_electron_density_util_hh
20 #include <numeric/xyzMatrix.fwd.hh>
21 #include <numeric/xyzVector.hh>
22 #include <numeric/fourier/FFT.hh>
24 #include <ObjexxFCL/FArray3D.hh>
26 #include <basic/Tracer.hh>
34 namespace electron_density {
42 ObjexxFCL::FArray3D< S >
const & data ,
45 int pt000[3], pt111[3];
48 grid[0] = data.u1(); grid[1] = data.u2(); grid[2] = data.u3();
51 pt000[0] = (
int)(floor(idxX[0])) % grid[0];
if (pt000[0] <= 0) pt000[0]+= grid[0];
52 pt000[1] = (
int)(floor(idxX[1])) % grid[1];
if (pt000[1] <= 0) pt000[1]+= grid[1];
53 pt000[2] = (
int)(floor(idxX[2])) % grid[2];
if (pt000[2] <= 0) pt000[2]+= grid[2];
54 pt111[0] = (pt000[0]+1);
if (pt111[0]>grid[0]) pt111[0] = 1;
55 pt111[1] = (pt000[1]+1);
if (pt111[1]>grid[1]) pt111[1] = 1;
56 pt111[2] = (pt000[2]+1);
if (pt111[2]>grid[2]) pt111[2] = 1;
59 fpart[0] = idxX[0]-floor(idxX[0]); neg_fpart[0] = 1-fpart[0];
60 fpart[1] = idxX[1]-floor(idxX[1]); neg_fpart[1] = 1-fpart[1];
61 fpart[2] = idxX[2]-floor(idxX[2]); neg_fpart[2] = 1-fpart[2];
64 retval+= neg_fpart[0]*neg_fpart[1]*neg_fpart[2] * data(pt000[0],pt000[1],pt000[2]);
65 retval+= neg_fpart[0]*neg_fpart[1]* fpart[2] * data(pt000[0],pt000[1],pt111[2]);
66 retval+= neg_fpart[0]* fpart[1]*neg_fpart[2] * data(pt000[0],pt111[1],pt000[2]);
67 retval+= neg_fpart[0]* fpart[1]* fpart[2] * data(pt000[0],pt111[1],pt111[2]);
68 retval+= fpart[0]*neg_fpart[1]*neg_fpart[2] * data(pt111[0],pt000[1],pt000[2]);
69 retval+= fpart[0]*neg_fpart[1]* fpart[2] * data(pt111[0],pt000[1],pt111[2]);
70 retval+= fpart[0]* fpart[1]*neg_fpart[2] * data(pt111[0],pt111[1],pt000[2]);
71 retval+= fpart[0]* fpart[1]* fpart[2] * data(pt111[0],pt111[1],pt111[2]);
81 void spline_coeffs( ObjexxFCL::FArray3D< double > &data, ObjexxFCL::FArray3D< double > & coeffs);
84 void spline_coeffs( ObjexxFCL::FArray3D< float > &data, ObjexxFCL::FArray3D< double > & coeffs);
87 template<
class S,
class T>
89 ObjexxFCL::FArray3D< S >
const &density,
90 ObjexxFCL::FArray3D< T > &newDensity,
92 if (density.u1() == newDims[0] && density.u2() == newDims[1] && density.u3() == newDims[2]) {
97 newDensity.dimension( newDims[0], newDims[1], newDims[2] );
100 ObjexxFCL::FArray3D< std::complex<double> > Foldmap, Fnewmap;
101 Fnewmap.dimension( newDims[0], newDims[1], newDims[2] );
104 ObjexxFCL::FArray3D< std::complex<double> > cplx_density;
105 cplx_density.dimension( density.u1() , density.u2() , density.u3() );
106 for (
int i=0; i<density.u1()*density.u2()*density.u3(); ++i) cplx_density[i] = (
double)density[i];
107 numeric::fourier::fft3(cplx_density, Foldmap);
110 for (
int i=0; i<Fnewmap.u1()*Fnewmap.u2()*Fnewmap.u3(); ++i) Fnewmap[i] = std::complex<double>(0,0);
113 std::min(Foldmap.u2(), Fnewmap.u2())/2,
114 std::min(Foldmap.u3(), Fnewmap.u3())/2 );
115 numeric::xyzVector<int> nyqplus1_old( std::max(Foldmap.u1() - (std::min(Foldmap.u1(),Fnewmap.u1())-nyq[0]) + 1 , nyq[0]+1) ,
116 std::max(Foldmap.u2() - (std::min(Foldmap.u2(),Fnewmap.u2())-nyq[1]) + 1 , nyq[1]+1) ,
117 std::max(Foldmap.u3() - (std::min(Foldmap.u3(),Fnewmap.u3())-nyq[2]) + 1 , nyq[2]+1) );
118 numeric::xyzVector<int> nyqplus1_new( std::max(Fnewmap.u1() - (std::min(Foldmap.u1(),Fnewmap.u1())-nyq[0]) + 1 , nyq[0]+1) ,
119 std::max(Fnewmap.u2() - (std::min(Foldmap.u2(),Fnewmap.u2())-nyq[1]) + 1 , nyq[1]+1) ,
120 std::max(Fnewmap.u3() - (std::min(Foldmap.u3(),Fnewmap.u3())-nyq[2]) + 1 , nyq[2]+1) );
121 for (
int i=1; i<=Fnewmap.u1(); i++)
122 for (
int j=1; j<=Fnewmap.u2(); j++)
123 for (
int k=1; k<=Fnewmap.u3(); k++) {
127 Fnewmap(i,j,k) = Foldmap(i, j, k);
128 else if (k-1>=nyqplus1_new[2])
129 Fnewmap(i,j,k) = Foldmap(i, j, k-nyqplus1_new[2]+nyqplus1_old[2]);
131 }
else if (j-1>=nyqplus1_new[1]) {
133 Fnewmap(i,j,k) = Foldmap(i, j-nyqplus1_new[1]+nyqplus1_old[1], k);
134 else if (k-1>=nyqplus1_new[2])
135 Fnewmap(i,j,k) = Foldmap(i, j-nyqplus1_new[1]+nyqplus1_old[1], k-nyqplus1_new[2]+nyqplus1_old[2]);
137 }
else if (i-1>=nyqplus1_new[0]) {
140 Fnewmap(i,j,k) = Foldmap(i-nyqplus1_new[0]+nyqplus1_old[0],j,k);
141 else if (k-1>=nyqplus1_new[2])
142 Fnewmap(i,j,k) = Foldmap(i-nyqplus1_new[0]+nyqplus1_old[0],j, k-nyqplus1_new[2]+nyqplus1_old[2]);
144 }
else if (j-1>=nyqplus1_new[1]){
146 Fnewmap(i,j,k) = Foldmap(i-nyqplus1_new[0]+nyqplus1_old[0],j-nyqplus1_new[1]+nyqplus1_old[1],k);
147 else if (k-1>=nyqplus1_new[2])
148 Fnewmap(i,j,k) = Foldmap(i-nyqplus1_new[0]+nyqplus1_old[0],
149 j-nyqplus1_new[1]+nyqplus1_old[1],
150 k-nyqplus1_new[2]+nyqplus1_old[2]);
156 numeric::fourier::ifft3(Fnewmap, newDensity);