Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
xray_scattering.cc
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 
15 #include <basic/Tracer.hh>
16 #include <basic/options/option.hh>
17 
18 // AUTO-REMOVED #include <numeric/xyzMatrix.hh>
19 // AUTO-REMOVED #include <numeric/xyzVector.hh>
20 // AUTO-REMOVED #include <numeric/xyz.functions.hh>
21 // AUTO-REMOVED #include <numeric/xyzVector.io.hh>
22 
23 #include <basic/options/keys/edensity.OptionKeys.gen.hh>
24 
25 #include <iostream>
26 #include <map>
27 
28 #include <utility/vector1.hh>
29 
30 
31 // C++ Headers
32 
33 using basic::T;
34 using basic::Tracer;
35 static basic::Tracer TR("core.scoring.electron_density.xray_scattering");
36 
37 
38 namespace core {
39 namespace scoring {
40 namespace electron_density {
41 
42 // x mod y, returns z in [0,y-1]
43 inline int pos_mod(int x,int y) {
44  int r=x%y; if (r<0) r+=y;
45  return r;
46 }
47 inline float pos_mod(float x,float y) {
48  float r=std::fmod(x,y); if (r<0) r+=y;
49  return r;
50 }
51 inline double pos_mod(double x,double y) {
52  double r=std::fmod(x,y); if (r<0) r+=y;
53  return r;
54 }
55 inline float square(float x) { return (x*x); }
56 inline double square(double x) { return (x*x); }
57 
58 // weight from scattering factors
59 // single-gaussian approx
61  static std::map< std::string, OneGaussianScattering > elt_db;
62 
63  //fpd these parameters were tuned by fitting a single gaussian
64  // to the 4-gaussian parameters in R^-1 space from 2-20A res
65  if (elt_db.size() == 0) {
66  elt_db["C"] = OneGaussianScattering( 6, 4.88284);
67  elt_db["N"] = OneGaussianScattering( 7, 5.08287);
68  elt_db["O"] = OneGaussianScattering( 8, 4.92989);
69  elt_db["F"] = OneGaussianScattering( 9, 4.58837);
70  elt_db["NA"] = OneGaussianScattering(11, 3.53389);
71  elt_db["MG"] = OneGaussianScattering(12, 3.11868);
72  elt_db["AL"] = OneGaussianScattering(13, 2.87655);
73  elt_db["P"] = OneGaussianScattering(15, 2.89121);
74  elt_db["S"] = OneGaussianScattering(16, 3.03242);
75  elt_db["K"] = OneGaussianScattering(19, 3.32675);
76  elt_db["FE"] = OneGaussianScattering(26, 3.10519);
77 
78  elt_db["X"] = OneGaussianScattering(
79  (int)(6*basic::options::option[ basic::options::OptionKeys::edensity::centroid_density_mass ]()) , 4.88284); // centroid
80  }
81 
82  if (elt_db.find( elt ) == elt_db.end()) {
83  // default to C
84  TR.Warning << "[ WARNING ] Unknown atom " << elt << std::endl;
85  return elt_db["C"];
86  } else {
87  return elt_db[ elt ];
88  }
89 }
90 
91 // weight from scattering factors
93  static std::map< std::string, KromerMann > elt_db;
94 
95  if (elt_db.size() == 0) {
96  elt_db["C"] = KromerMann( 0.215600, 2.310000, 1.020000, 1.588600, 0.865000, 20.843899, 10.207500, 0.568700, 51.651199);
97  elt_db["N"] = KromerMann(-11.528999, 12.212600, 3.132200, 2.012500, 1.166300, 0.005700, 9.893300, 28.997499, 0.582600);
98  elt_db["O"] = KromerMann( 0.250800, 3.048500, 2.286800, 1.546300, 0.867000, 13.277100, 5.701100, 0.323900, 32.908897);
99  elt_db["F"] = KromerMann( 0.277600, 3.539200, 2.641200, 1.517000, 1.024300, 10.282499, 4.294400, 0.261500, 26.147600);
100  elt_db["NA"] = KromerMann( 0.676000, 4.762600, 3.173600, 1.267400, 1.112800, 3.285000, 8.842199, 0.313600, 129.423996);
101  elt_db["MG"] = KromerMann( 0.858400, 5.420400, 2.173500, 1.226900, 2.307300, 2.827500, 79.261101, 0.380800, 7.193700);
102  elt_db["AL"] = KromerMann( 1.115100, 6.420200, 1.900200, 1.593600, 1.964600, 3.038700, 0.742600, 31.547199, 85.088600);
103  elt_db["P"] = KromerMann( 1.114900, 6.434500, 4.179100, 1.780000, 1.490800, 1.906700, 27.157000, 0.526000, 68.164497);
104  elt_db["S"] = KromerMann( 0.866900, 6.905300, 5.203400, 1.437900, 1.586300, 1.467900, 22.215099, 0.253600, 56.172001);
105  elt_db["K"] = KromerMann( 1.422800, 8.218599 ,7.439800, 1.051900, 0.865900,12.794900, 0.774800 ,213.186996, 41.684097);
106  elt_db["FE"] = KromerMann( 1.036900, 11.769500, 7.357300, 3.522200, 2.304500, 4.761100, 0.307200, 15.353500, 76.880501 );
107  elt_db["X"] = KromerMann(); // centroid
108  }
109 
110  if (elt_db.find( elt ) == elt_db.end()) {
111  // default to C
112  TR.Warning << "[ WARNING ] Unknown atom " << elt << std::endl;
113  return elt_db["C"];
114  } else {
115  return elt_db[ elt ];
116  }
117 }
118 
119 /////////////////////////////////////////////////////////
120 /////////////////////////////////////////////////////////
121 /////////////////////////////////////////////////////////
122 
123 
124 // AtomScattering::AtomScattering() { }
125 //
126 //
127 // // mask scattering
128 // AtomScattering::AtomScattering( core::Real mask, core::Real reso ) {
129 // init( mask, reso );
130 // numeric::xyzVector< core::Real > atm_j;
131 //
132 // // ??? should there be a resolution-based sigma on the mask?
133 //
134 // for (int z=1; z<=data.u3(); ++z) {
135 // atm_j[2] = (z-1)*i2c[2];
136 // for (int y=1; y<=data.u2(); ++y) {
137 // atm_j[1] = (y-1)*i2c[1];
138 // for (int x=1; x<=data.u1(); ++x) {
139 // atm_j[0] = (x-1)*i2c[0];
140 // core::Real d2 = atm_j.length_squared();
141 // core::Real inv_msk = 1/(1+exp( d2 - (mask*mask) ));
142 // data(x,y,z) = inv_msk;
143 // }
144 // }
145 // }
146 // }
147 //
148 // // atom scattering
149 // AtomScattering::AtomScattering( core::Real a, core::Real B, core::Real mask, core::Real reso ) {
150 // init( mask, reso );
151 //
152 // // 1-gaussian approx
153 // core::Real k = (B<=0) ? square(M_PI/reso) : std::min( square(M_PI/reso) , 0.5/square(0.6+0.006*B) );
154 // core::Real C = pow(k/M_PI,1.5);
155 // numeric::xyzVector< core::Real > atm_j;
156 //
157 // for (int z=1; z<=data.u3(); ++z) {
158 // atm_j[2] = (z-1)*i2c[2];
159 // for (int y=1; y<=data.u2(); ++y) {
160 // atm_j[1] = (y-1)*i2c[1];
161 // for (int x=1; x<=data.u1(); ++x) {
162 // atm_j[0] = (x-1)*i2c[0];
163 // core::Real d2 = atm_j.length_squared();
164 // core::Real atm = C*a*exp(-k*d2);
165 // data(x,y,z) = atm;
166 // }
167 // }
168 // }
169 // }
170 //
171 //
172 // // common init
173 // void AtomScattering::init( core::Real mask, core::Real reso ) {
174 // this->reso = reso;
175 //
176 // // extent is max(mask+1,3xreso) <<< should this be a function of atom mask
177 // core::Real extent = std::max( mask+1.0, 3*reso );
178 //
179 // // grid sampling (A/pt) 1/8 reso
180 // core::Real sampling = reso/8;
181 // core::Size ngrid = (core::Size) std::floor(extent/sampling+0.5);
182 // sampling = extent / (double) ngrid;
183 //
184 // grid[0] = grid[1] = grid[2] = ngrid;
185 // c2i[0] = c2i[1] = c2i[2] = 1/sampling;
186 // i2c[0] = i2c[1] = i2c[2] = sampling;
187 // data.dimension( (int)grid[0] , (int)grid[1] , (int)grid[2] );
188 // }
189 //
190 //
191 // // interp at a Cartesian point X
192 // core::Real AtomScattering::interp_linear( numeric::xyzVector< core::Real > const & X ) const {
193 // numeric::xyzVector< core::Real > idxX(X[0]*c2i[0],X[1]*c2i[1],X[2]*c2i[2]); // cart -> idx
194 //
195 // // only compute density over one octant
196 // if (idxX[0] < 0) idxX[0] *= -1;
197 // if (idxX[1] < 0) idxX[1] *= -1;
198 // if (idxX[2] < 0) idxX[2] *= -1;
199 //
200 // int pt000[3], pt111[3];
201 // core::Real fpart[3],neg_fpart[3];
202 //
203 // // check for out of bounds
204 // if (idxX[0] >= grid[0] || idxX[1] >= grid[1] || idxX[2] >= grid[2]) return 0.0;
205 //
206 // // find bounding grid points
207 // pt000[0] = (int)(floor(idxX[0]))+1; pt111[0] = (pt000[0]+1);
208 // pt000[1] = (int)(floor(idxX[1]))+1; pt111[1] = (pt000[1]+1);
209 // pt000[2] = (int)(floor(idxX[2]))+1; pt111[2] = (pt000[2]+1);
210 //
211 // // interpolation coeffs
212 // fpart[0] = idxX[0]-floor(idxX[0]); neg_fpart[0] = 1-fpart[0];
213 // fpart[1] = idxX[1]-floor(idxX[1]); neg_fpart[1] = 1-fpart[1];
214 // fpart[2] = idxX[2]-floor(idxX[2]); neg_fpart[2] = 1-fpart[2];
215 //
216 // assert( pt000[0] >= 1 && pt000[0] <= data.u1() );
217 // assert( pt000[1] >= 1 && pt000[1] <= data.u2() );
218 // assert( pt000[2] >= 1 && pt000[2] <= data.u3() );
219 // assert( pt111[0] >= 1 && pt111[0] <= data.u1() );
220 // assert( pt111[1] >= 1 && pt111[1] <= data.u2() );
221 // assert( pt111[2] >= 1 && pt111[2] <= data.u3() );
222 //
223 //
224 // // interpolate
225 // core::Real retval = 0.0;
226 // retval += neg_fpart[0]*neg_fpart[1]*neg_fpart[2] * data(pt000[0],pt000[1],pt000[2]);
227 // retval += neg_fpart[0]*neg_fpart[1]* fpart[2] * data(pt000[0],pt000[1],pt111[2]);
228 // retval += neg_fpart[0]* fpart[1]*neg_fpart[2] * data(pt000[0],pt111[1],pt000[2]);
229 // retval += neg_fpart[0]* fpart[1]* fpart[2] * data(pt000[0],pt111[1],pt111[2]);
230 // retval += fpart[0]*neg_fpart[1]*neg_fpart[2] * data(pt111[0],pt000[1],pt000[2]);
231 // retval += fpart[0]*neg_fpart[1]* fpart[2] * data(pt111[0],pt000[1],pt111[2]);
232 // retval += fpart[0]* fpart[1]*neg_fpart[2] * data(pt111[0],pt111[1],pt000[2]);
233 // retval += fpart[0]* fpart[1]* fpart[2] * data(pt111[0],pt111[1],pt111[2]);
234 //
235 // return retval;
236 // }
237 //
238 
239 
240 
241 /////////////////////////////////////////////////////////
242 /////////////////////////////////////////////////////////
243 /////////////////////////////////////////////////////////
244 
245 
246 //
247 bool factorsLTE5(int X) {
248  while (X != 1 && X%2 == 0) X /= 2;
249  while (X != 1 && X%3 == 0) X /= 3;
250  while (X != 1 && X%5 == 0) X /= 5;
251 
252  return (X == 1);
253 }
254 
255 //
256 bool factorsLTE19(int X) {
257  while (X != 1 && X%2 == 0) X /= 2;
258  while (X != 1 && X%3 == 0) X /= 3;
259  while (X != 1 && X%5 == 0) X /= 5;
260  while (X != 1 && X%7 == 0) X /= 7;
261  while (X != 1 && X%11 == 0) X /= 11;
262  while (X != 1 && X%13 == 0) X /= 13;
263  while (X != 1 && X%17 == 0) X /= 17;
264  while (X != 1 && X%19 == 0) X /= 19;
265 
266  return (X == 1);
267 }
268 
269 //
270 int findSampling5(double MINSMP, int NMUL) {
271  if (MINSMP <= 0) return NMUL;
272 
273  // multiple of nmul nearest minsmp
274  int N = (int) floor( MINSMP/NMUL + 0.5 ) * NMUL;
275 
276  // increment until no factors >= 5
277  while (!factorsLTE5(N))
278  N += NMUL;
279 
280  return N;
281 }
282 
283 //
284 int findSampling(double MINSMP, int NMUL) {
285  if (MINSMP <= 0) return NMUL;
286 
287  // multiple of nmul nearest minsmp
288  int N = (int) floor( MINSMP/NMUL + 0.5 ) * NMUL;
289 
290  // increment until no factors >= 19
291  while (!factorsLTE19(N))
292  N += NMUL;
293 
294  return N;
295 }
296 
297 
298 } // namespace constraints
299 } // namespace scoring
300 } // namespace core