Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RNA_CS_MagneticAnisotropy.cc
Go to the documentation of this file.
1 // (c) Copyright Rosetta Commons Member Institutions.
2 // (c) This file is part of the Rosetta software suite and is made available under license.
3 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
4 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
5 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
6 
7 
8 /// @file core/scoring/rna/chemical_shift/MagneticAnisotropy.cc
9 /// @brief
10 /// @author Parin Sripakdeevong (sripakpa@stanford.edu)
11 
12 
13 
16 #include <ObjexxFCL/format.hh>
17 #include <numeric/xyzMatrix.hh>
18 #include <math.h>
19 //////////////////////////////////////////////////////////////////////////////////
20 //////////////////////////////////////////////////////////////////////////////////
21 //////////////////////////////////////////////////////////////////////////////////
22 
23 namespace core {
24 namespace scoring {
25 namespace rna {
26 namespace chemical_shift {
27 
28 ///////////////////////////////////////////////////////////////
29 ///The magnetic_anisotropy contribution of heavy-base atom at src_xyz to the chemqical_shift at CS_data_atom_xyz
30 Real
32  numeric::xyzVector<core::Real> const & source_atom_xyz,
33  numeric::xyzMatrix< core::Real > const & base_coordinate_matrix,
34  RNA_CS_residue_parameters const & source_rsd_CS_params,
35  Size const realatomdata_index){
36 
37 
38  numeric::xyzVector<core::Real> const r_vector = CS_data_atom_xyz - source_atom_xyz;
39 
40  Real const r_length = r_vector.length();
41 
42  Real const r_length2 = r_length * r_length;
43 
44  Real const r_length5 = std::pow(r_length,5);
45 
46  Real const x_length = dot(r_vector , base_coordinate_matrix.col_x());
47  Real const y_length = dot(r_vector , base_coordinate_matrix.col_y());
48  Real const z_length = dot(r_vector , base_coordinate_matrix.col_z());
49 
50  Real const ma_r = source_rsd_CS_params.magentic_anisotropy_r_coeff(); //diamagnetic component coefficient
51  Real const ma_q = source_rsd_CS_params.magentic_anisotropy_q_coeff(); //paramagnetic component coefficient
52 
53  Real const coeff_xx = ( ma_r * source_rsd_CS_params.atom_data(realatomdata_index, marx) ) - ( ma_q * source_rsd_CS_params.atom_data(realatomdata_index, maqx) );
54 
55  Real const coeff_yy = ( ma_r * source_rsd_CS_params.atom_data(realatomdata_index, mary) ) - ( ma_q * source_rsd_CS_params.atom_data(realatomdata_index, maqy) );
56 
57  Real const coeff_zz = ( ma_r * source_rsd_CS_params.atom_data(realatomdata_index, marz) ) - ( ma_q * source_rsd_CS_params.atom_data(realatomdata_index, maqz) );
58 
59  Real const coeff_xy = 0.0 - ( ma_q * source_rsd_CS_params.atom_data(realatomdata_index, maqw) );
60 
61  //xx component
62  Real const termxx = ( ( 3.0 * x_length * x_length ) - r_length2 ) * ( coeff_xx );
63 
64  //yy component
65  Real const termyy = ( ( 3.0 * y_length * y_length ) - r_length2 ) * ( coeff_yy );
66 
67  //zz componenet
68  Real const termzz = ( ( 3.0 * z_length * z_length ) - r_length2 ) * ( coeff_zz );
69 
70  //xy component
71  Real const termxy = ( ( 3.0 * x_length * y_length ) ) * ( coeff_xy );
72 
73  //
74  Real const termr = -1.0 / (3.0 * r_length5);
75 
76 
77  Real const chem_shift_MA = ( termr ) * ( termxx + termyy + termzz + termxy ); //Definition uses opposite sign compare to NUCHEMICS!
78 
79  return chem_shift_MA;
80 }
81 
82 
83 ///////////////////////////////////////////////////////////////
84 //The gradient of delta_magnetic_anisotropy() with respect to r_vector ( r_vector = CS_data_atom_xyz - source_atom_xyz )
85 //OK RIGHT NOW CONCERN WITH GETTING THIS FUNCTION RIGHT. OPTIMIZE LATER if NECESSARY!
86 
89  numeric::xyzVector<core::Real> const & source_atom_xyz,
90  numeric::xyzMatrix< core::Real > const & base_coordinate_matrix,
91  RNA_CS_residue_parameters const & source_rsd_CS_params,
92  Size const realatomdata_index){
93 
94  //Use Cartesian coordinate. magentic_anisotropy is a function of x, y and z.
95  //chem_shift_MA = ( termr ) * ( termxx + termyy + termzz + termxy );
96 
97  //INCORRECT gradient = (dchem_shift_MA_dx * x_norm) + (dchem_shift_MA_dy * y_norm) + (dchem_shift_MA_dz * z_norm)
98  //REASON: base_coordinate_matrix.col_x() and base_coordinate_matrix.col_y() are not entirely orthogonal! (THIS IS DUE TO DEFINITION USED IN NUCNEMICS!)
99 
100  //TO ENSURE THAT THE basis are orthogonal:
101  //Define yprime_norm=cross(z_norm, x_norm) so that x_norm, yprime_norm and z_norm forms a orthonormal basis of R3. Then:
102  //gradient = (dchem_shift_MA_dx * x_norm) + (dchem_shift_MA_dyprime * yprime_norm) + (dchem_shift_MA_dz * z_norm)
103  //The crucial thing to remember is to treat y as f(x, y').
104 
105 
106  numeric::xyzVector<core::Real> const r_vector = CS_data_atom_xyz - source_atom_xyz;
107 
108  Real const r_length = r_vector.length();
109 
110  Real const r_length2 = r_length * r_length;
111 
112  Real const r_length5 = std::pow(r_length,5);
113 
114 
115 
116  numeric::xyzVector<core::Real> const x_norm = base_coordinate_matrix.col_x();
117  numeric::xyzVector<core::Real> const y_norm = base_coordinate_matrix.col_y();
118  numeric::xyzVector<core::Real> const z_norm = base_coordinate_matrix.col_z();
119  numeric::xyzVector<core::Real> const yprime_norm=cross(z_norm, x_norm);
120 
121  Real const x_length = dot(r_vector , x_norm);
122  Real const y_length = dot(r_vector , y_norm);
123  Real const z_length = dot(r_vector , z_norm);
124  Real const yprime_length = dot(r_vector , yprime_norm);
125 
126  //Note that r_length^2= x_length^2 + yprime_length^2 + z_length^2
127 
128  Real const ma_r = source_rsd_CS_params.magentic_anisotropy_r_coeff(); //diamagnetic component coefficient
129  Real const ma_q = source_rsd_CS_params.magentic_anisotropy_q_coeff(); //paramagnetic component coefficient
130 
131 
132  Real const coeff_xx = ( ma_r * source_rsd_CS_params.atom_data(realatomdata_index, marx) ) - ( ma_q * source_rsd_CS_params.atom_data(realatomdata_index, maqx) );
133 
134  Real const coeff_yy = ( ma_r * source_rsd_CS_params.atom_data(realatomdata_index, mary) ) - ( ma_q * source_rsd_CS_params.atom_data(realatomdata_index, maqy) );
135 
136  Real const coeff_zz = ( ma_r * source_rsd_CS_params.atom_data(realatomdata_index, marz) ) - ( ma_q * source_rsd_CS_params.atom_data(realatomdata_index, maqz) );
137 
138  Real const coeff_xy = 0.0 - ( ma_q * source_rsd_CS_params.atom_data(realatomdata_index, maqw) );
139 
140  //xx component
141  Real const termxx = ( ( 3.0 * x_length * x_length ) - r_length2 ) * ( coeff_xx );
142 
143  //yy component
144  Real const termyy = ( ( 3.0 * y_length * y_length ) - r_length2 ) * ( coeff_yy );
145 
146  //zz componenet
147  Real const termzz = ( ( 3.0 * z_length * z_length ) - r_length2 ) * ( coeff_zz );
148 
149  //xy component
150  Real const termxy = ( ( 3.0 * x_length * y_length ) ) * ( coeff_xy );
151 
152  //
153  Real const termr = -1.0 / (3.0 * r_length5);
154 
155  Real const dtermr_dr = ( -5.0 / r_length ) * (termr);
156 
157  //Projection of r_vector onto y-axis gives y= dot(y_norm, r_vector) = dot(y_norm, yprime_norm) * y_prime + dot(y_norm, xprime_norm) * x
158 
159  Real const dy_dx = dot(y_norm, x_norm);
160 
161  Real const dy_dyprime=dot(y_norm, yprime_norm);
162 
163  /////////////////////////////////
164  //dchem_shift_MA_dx
165  /////////////////////////////////
166 
167  //dchem_shift_MA_dx = ( (dtermr_dx) * (termxx + termyy + termzz + termxy ) ) + ( (termr) * (dtermxx_dx + dtermyy_dx + dtermzz_dx + dtermxy_dx) ) //Chain rule.
168 
169  Real const dr_dx = ( x_length / r_length );
170 
171  Real const dtermr_dx = dr_dx * dtermr_dr;
172 
173  Real const dtermxx_dx = ( ( 6.0 * x_length ) - ( 2.0 * x_length ) ) * ( coeff_xx );
174 
175  Real const dtermyy_dx = ( ( 6.0 * y_length * dy_dx ) - ( 2.0 * x_length ) ) * ( coeff_yy );
176 
177  Real const dtermzz_dx = ( ( 0.0 ) - ( 2.0 * x_length ) ) * ( coeff_zz );
178 
179  Real const dtermxy_dx = ( ( ( 3.0 * y_length ) + ( 3.0 * x_length * dy_dx) ) - ( 0.0 ) ) * ( coeff_xy );
180 
181  Real const dchem_shift_MA_dx = ( (dtermr_dx) * (termxx + termyy + termzz + termxy ) ) + ( (termr) * (dtermxx_dx + dtermyy_dx + dtermzz_dx + dtermxy_dx) );
182 
183  /////////////////////////////////
184  //dchem_shift_MA_dyprime
185  /////////////////////////////////
186 
187  //dchem_shift_MA_dyprime = ( (dtermr_dyprime) * (termxx + termyy + termzz + termxy ) )
188  // + ( (termr) * (dtermxx_dyprime + dtermyy_dyprime + dtermzz_dyprime + dtermxy_dyprime) ) //Chain rule.
189 
190  Real const dr_dyprime = ( yprime_length / r_length );
191 
192  Real const dtermr_dyprime = dr_dyprime * dtermr_dr;
193 
194  Real const dtermxx_dyprime = ( ( 0.0 ) - ( 2.0 * yprime_length ) ) * ( coeff_xx );
195 
196  Real const dtermyy_dyprime = ( ( 6.0 * y_length * dy_dyprime ) - ( 2.0 * yprime_length ) ) * ( coeff_yy );
197 
198  Real const dtermzz_dyprime = ( ( 0.0 ) - ( 2.0 * yprime_length ) ) * ( coeff_zz );
199 
200  Real const dtermxy_dyprime = ( ( 3.0 * x_length * dy_dyprime ) - ( 0.0 ) ) * ( coeff_xy );
201 
202  Real const dchem_shift_MA_dyprime = ( (dtermr_dyprime) * (termxx + termyy + termzz + termxy ) ) + ( (termr) * (dtermxx_dyprime + dtermyy_dyprime + dtermzz_dyprime + dtermxy_dyprime) );
203 
204  /////////////////////////////////
205  //dchem_shift_MA_dz
206  /////////////////////////////////
207 
208  //dchem_shift_MA_dz = ( (dtermr_dz) * (termxx + termyy + termzz + termxy ) ) + ( (termr) * (dtermxx_dz + dtermyy_dz + dtermzz_dz + dtermxy_dz) ) //Chain rule.
209 
210  Real const dr_dz = ( z_length / r_length );
211 
212  Real const dtermr_dz = dr_dz * dtermr_dr;
213 
214  Real const dtermxx_dz = ( ( 0.0 ) - ( 2.0 * z_length ) ) * ( coeff_xx );
215 
216  Real const dtermyy_dz = ( ( 0.0 ) - ( 2.0 * z_length ) ) * ( coeff_yy );
217 
218  Real const dtermzz_dz = ( ( 6.0 * z_length ) - ( 2.0 * z_length ) ) * ( coeff_zz );
219 
220  Real const dtermxy_dz = ( ( 0.0 ) - ( 0.0 ) ) * ( coeff_xy );
221 
222  Real const dchem_shift_MA_dz = ( (dtermr_dz) * (termxx + termyy + termzz + termxy ) ) + ( (termr) * (dtermxx_dz + dtermyy_dz + dtermzz_dz + dtermxy_dz) );
223 
224 
225  /////////////////////////////////////////////////////////////////////
226 
227  numeric::xyzVector<core::Real> const analytical_gradient=(dchem_shift_MA_dx * x_norm) + (dchem_shift_MA_dyprime * yprime_norm) + (dchem_shift_MA_dz * z_norm);
228 
229  /////////////////////////////////////////////////////////////////////
230 
231  return analytical_gradient;
232 
233  /*
234  //AN ALTERNATIVE (indirect) WAY IS TO COMPUTE first dchem_shift_MA_dy and then determine dchem_shift_MA_dyprime from it.
235  /////////////////////////////////
236  //dchem_shift_MA_dy
237  /////////////////////////////////
238 
239  //dchem_shift_MA_dy = ( (dtermr_dy) * (termxx + termyy + termzz + termxy ) ) + ( (termr) * (dtermxx_dy + dtermyy_dy + dtermzz_dy + dtermxy_dy) ) //Chain rule.
240 
241  Real const dr_dy = ( y_length / r_length );
242 
243  Real const dtermr_dy = dr_dy * dtermr_dr;
244 
245  Real const dtermxx_dy = ( ( 0.0 ) - ( 2.0 * y_length ) ) * ( coeff_xx );
246 
247  Real const dtermyy_dy = ( ( 6.0 * y_length ) - ( 2.0 * y_length ) ) * ( coeff_yy );
248 
249  Real const dtermzz_dy = ( ( 0.0 ) - ( 2.0 * y_length ) ) * ( coeff_zz );
250 
251  Real const dtermxy_dy = ( ( 3.0 * x_length ) - ( 0.0 ) ) * ( coeff_xy );
252 
253  Real const dchem_shift_MA_dy = ( (dtermr_dy) * (termxx + termyy + termzz + termxy ) ) + ( (termr) * (dtermxx_dy + dtermyy_dy + dtermzz_dy + dtermxy_dy) );
254 
255  /////////////////////////////////
256  //dchem_shift_MA_dyprime
257  /////////////////////////////////
258  //dchem_shift_MA_dy = y_norm * gradient = ( dot(y_norm, x_norm) * dchem_shift_MA_dx ) + ( dot(y_norm, yprime_norm) * dchem_shift_MA_dyprime )
259  //dchem_shift_MA_dyprime = ( 1/ dot(y_norm, yprime_norm) ) * ( dchem_shift_MA_dy - ( dot(y_norm, x_norm) * dchem_shift_MA_dx ) )
260  //NOTE: this assumes dot(z_norm, y_norm)=0 which is true since in RNA_CS_Util.cc z_norm = cross(x_norm, y_norm);
261  // Real const dchem_shift_MA_dyprime = ( 1 / dot(y_norm, yprime_norm) ) * ( dchem_shift_MA_dy - ( dot(y_norm, x_norm) * dchem_shift_MA_dx ) );
262  */
263 
264  /*
265  bool const numerical_check=false;
266 
267  if(numerical_check){
268 
269  bool const use_numerical_deriv=false;
270 
271  Real const increment = 0.0000005;
272 
273  numeric::xyzVector<core::Real> const rosetta_frame_x_vector(1.0, 0.0, 0.0);
274  numeric::xyzVector<core::Real> const rosetta_frame_y_vector(0.0, 1.0, 0.0);
275  numeric::xyzVector<core::Real> const rosetta_frame_z_vector(0.0, 0.0, 1.0);
276 
277  numeric::xyzVector<core::Real> const rosetta_frame_x_plus_xyz= CS_data_atom_xyz + (rosetta_frame_x_vector*increment);
278  numeric::xyzVector<core::Real> const rosetta_frame_x_minus_xyz= CS_data_atom_xyz - (rosetta_frame_x_vector*increment);
279 
280  Real const rosetta_frame_x_plus_effect = delta_magnetic_anisotropy( rosetta_frame_x_plus_xyz, source_atom_xyz, base_coordinate_matrix, source_rsd_CS_params, realatomdata_index);
281  Real const rosetta_frame_x_minus_effect = delta_magnetic_anisotropy( rosetta_frame_x_minus_xyz, source_atom_xyz, base_coordinate_matrix, source_rsd_CS_params, realatomdata_index);
282 
283  Real const deffect_drosettax_numerical = (rosetta_frame_x_plus_effect - rosetta_frame_x_minus_effect ) / ( 2 * increment );
284 
285  /////////////
286  numeric::xyzVector<core::Real> const rosetta_frame_y_plus_xyz= CS_data_atom_xyz + (rosetta_frame_y_vector*increment);
287  numeric::xyzVector<core::Real> const rosetta_frame_y_minus_xyz= CS_data_atom_xyz - (rosetta_frame_y_vector*increment);
288 
289  Real const rosetta_frame_y_plus_effect = delta_magnetic_anisotropy( rosetta_frame_y_plus_xyz, source_atom_xyz, base_coordinate_matrix, source_rsd_CS_params, realatomdata_index);
290  Real const rosetta_frame_y_minus_effect = delta_magnetic_anisotropy( rosetta_frame_y_minus_xyz, source_atom_xyz, base_coordinate_matrix, source_rsd_CS_params, realatomdata_index);
291 
292  Real const deffect_drosettay_numerical = (rosetta_frame_y_plus_effect - rosetta_frame_y_minus_effect ) / ( 2 * increment );
293 
294  /////////////
295  numeric::xyzVector<core::Real> const rosetta_frame_z_plus_xyz= CS_data_atom_xyz + (rosetta_frame_z_vector*increment);
296  numeric::xyzVector<core::Real> const rosetta_frame_z_minus_xyz= CS_data_atom_xyz - (rosetta_frame_z_vector*increment);
297 
298  Real const rosetta_frame_z_plus_effect = delta_magnetic_anisotropy( rosetta_frame_z_plus_xyz, source_atom_xyz, base_coordinate_matrix, source_rsd_CS_params, realatomdata_index);
299  Real const rosetta_frame_z_minus_effect = delta_magnetic_anisotropy( rosetta_frame_z_minus_xyz, source_atom_xyz, base_coordinate_matrix, source_rsd_CS_params, realatomdata_index);
300 
301  Real const deffect_drosettaz_numerical = (rosetta_frame_z_plus_effect - rosetta_frame_z_minus_effect ) / ( 2 * increment );
302  /////////////
303 
304  numeric::xyzVector<core::Real> const numerical_gradient=(deffect_drosettax_numerical * rosetta_frame_x_vector) + (deffect_drosettay_numerical * rosetta_frame_y_vector) + (deffect_drosettaz_numerical * rosetta_frame_z_vector);
305 
306  std::cout << "---------------------------------------------------------------------" << std::endl;
307  std::cout << " | x_norm =(" << x_norm.x() << ", " << x_norm.y() << ", " << x_norm.z() << ") x_norm.length()=" << x_norm.length();
308  std::cout << " | yprime_norm =(" << yprime_norm.x() << ", " << yprime_norm.y() << ", " << yprime_norm.z() << ") yprime_norm.length()=" << yprime_norm.length();
309  std::cout << " | z_norm =(" << z_norm.x() << ", " << z_norm.y() << ", " << z_norm.z() << ") z_norm.length()=" << z_norm.length();
310  std::cout << " | dot(x_norm, yprime_norm)= " << dot(x_norm, yprime_norm);
311  std::cout << " | dot(x_norm, z_norm)= " << dot(x_norm, z_norm);
312  std::cout << " | dot(yprime_norm, z_norm)= " << dot(yprime_norm, z_norm) << std::endl;
313 
314  std::cout << "analytical_gradient=( " << analytical_gradient.x() << " , " << analytical_gradient.y() << " , " << analytical_gradient.z() << " )";
315  std::cout << " | numerical_gradient=( " << numerical_gradient.x() << " , " << numerical_gradient.y() << " , " << numerical_gradient.z() << " )" << std::endl;
316  std::cout << "---------------------------------------------------------------------" << std::endl;
317 
318  if(use_numerical_deriv) return numerical_gradient;
319 
320  }
321  */
322 
323 }
324 ///////////////////////////////////////////////////////////////
325 ///The magnetic_anisotropy contribution of source_rsd to the chemical_shift at atom_xyz
326 Real
327 magnetic_anisotropy_effect(numeric::xyzVector<core::Real> const & atom_xyz, conformation::Residue const & source_rsd, RNA_CS_residue_parameters const & source_rsd_CS_params){
328 
329  if( source_rsd.aa()!= source_rsd_CS_params.aa() ) utility_exit_with_message("rsd.aa()!= source_rsd_CS_params.aa()!");
330 
331  Real ma_effect = 0.0;
332 
333  Size const maxatoms=source_rsd_CS_params.get_atomnames_size();
334 
335  numeric::xyzMatrix< core::Real > const base_coordinate_matrix =get_rna_base_coordinate_system_from_CS_params(source_rsd, source_rsd_CS_params);
336 
337  for (Size realatomdata_index = 1; realatomdata_index < maxatoms; realatomdata_index++){
338 
339  if( dround(source_rsd_CS_params.atom_data(realatomdata_index, maca)) != 1 ) continue;
340 
341  Size const atom_index=source_rsd.atom_index( source_rsd_CS_params.get_atomname(realatomdata_index) );
342 
343  ma_effect += delta_magnetic_anisotropy(atom_xyz, source_rsd.xyz(atom_index), base_coordinate_matrix, source_rsd_CS_params, realatomdata_index);
344 
345  }
346 
347  return ma_effect;
348 
349 }
350 ///////////////////////////////////////////////////////////////
351 
352 
353 
354 } // chemical_shift
355 } // rna
356 } // scoring
357 } // core
358 
359