Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
util.hh
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file
11 /// @brief
12 /// @author
13 
14 #ifndef INCLUDED_core_scoring_electron_density_util_hh
15 #define INCLUDED_core_scoring_electron_density_util_hh
16 
17 #include <core/types.hh>
19 
20 #include <numeric/xyzMatrix.fwd.hh>
21 #include <numeric/xyzVector.hh>
22 #include <numeric/fourier/FFT.hh>
23 
24 #include <ObjexxFCL/FArray3D.hh>
25 
26 #include <basic/Tracer.hh>
27 
28 #include <iostream>
29 #include <complex>
30 
31 
32 namespace core {
33 namespace scoring {
34 namespace electron_density {
35 
36 /// @brief update scorefxn with density scores from commandline
38 
39 /// @brief trilinear interpolation with periodic boundaries
40 template <class S>
42  ObjexxFCL::FArray3D< S > const & data ,
43  numeric::xyzVector< core::Real > const & idxX) {
44 
45  int pt000[3], pt111[3];
46  core::Real fpart[3],neg_fpart[3];
47  int grid[3];
48  grid[0] = data.u1(); grid[1] = data.u2(); grid[2] = data.u3();
49 
50  // find bounding grid points
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;
57 
58  // interpolation coeffs
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];
62 
63  S retval = (S)0.0;
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]);
72 
73  return retval;
74 }
75 
76 /// @brief spline interpolation with periodic boundaries
77 core::Real interp_spline( ObjexxFCL::FArray3D< double > & coeffs ,
78  numeric::xyzVector<core::Real> const & idxX );
79 
80 /// @brief precompute spline coefficients (float array => double coeffs)
81 void spline_coeffs( ObjexxFCL::FArray3D< double > &data, ObjexxFCL::FArray3D< double > & coeffs);
82 
83 /// @brief precompute spline coefficients (double array => double coeffs)
84 void spline_coeffs( ObjexxFCL::FArray3D< float > &data, ObjexxFCL::FArray3D< double > & coeffs);
85 
86 ///@brief templated helper function to FFT resample a map
87 template<class S, class T>
88 void resample(
89  ObjexxFCL::FArray3D< S > const &density,
90  ObjexxFCL::FArray3D< T > &newDensity,
91  numeric::xyzVector< int > newDims ) {
92  if (density.u1() == newDims[0] && density.u2() == newDims[1] && density.u3() == newDims[2]) {
93  newDensity = density;
94  return;
95  }
96 
97  newDensity.dimension( newDims[0], newDims[1], newDims[2] );
98 
99  // convert map to complex<double>
100  ObjexxFCL::FArray3D< std::complex<double> > Foldmap, Fnewmap;
101  Fnewmap.dimension( newDims[0], newDims[1], newDims[2] );
102 
103  // fft
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);
108 
109  // reshape (handles both shrinking and growing in each dimension)
110  for (int i=0; i<Fnewmap.u1()*Fnewmap.u2()*Fnewmap.u3(); ++i) Fnewmap[i] = std::complex<double>(0,0);
111 
112  numeric::xyzVector<int> nyq( std::min(Foldmap.u1(), Fnewmap.u1())/2,
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++) {
124  if (i-1<=nyq[0]) {
125  if (j-1<=nyq[1]) {
126  if (k-1<=nyq[2])
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]);
130 
131  } else if (j-1>=nyqplus1_new[1]) {
132  if (k-1<=nyq[2])
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]);
136  }
137  } else if (i-1>=nyqplus1_new[0]) {
138  if (j-1<=nyq[1]) {
139  if (k-1<=nyq[2])
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]);
143 
144  } else if (j-1>=nyqplus1_new[1]){
145  if (k-1<=nyq[2])
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]);
151  }
152  }
153  }
154 
155  // ifft
156  numeric::fourier::ifft3(Fnewmap, newDensity);
157 }
158 
159 
160 
161 } // namespace constraints
162 } // namespace scoring
163 } // namespace core
164 
165 #endif