Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AssignOrbitals.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 #include <core/chemical/Atom.hh>
12 #include <map>
16 #include <utility/vector1.hh>
17 #include <utility/string_util.hh>
18 #include <numeric/xyz.functions.hh>
19 #include <ObjexxFCL/string.functions.hh>
20 #include <numeric/conversions.hh>
21 #include <numeric/constants.hh>
22 #include <numeric/NumericTraits.hh>
23 
24 namespace ObjexxFCL { namespace fmt { } } using namespace ObjexxFCL::fmt; // AUTO USING NS
25 
26 
27 namespace core{
28 namespace chemical{
29 namespace orbitals{
30 
31 using namespace ObjexxFCL;
32 using namespace ObjexxFCL::fmt;
33 
34 inline
37 {
38  std::string trimmed_name( name );
39  left_justify( trimmed_name ); trim( trimmed_name ); // simpler way to do this?
40  return trimmed_name;
41 }
42 AssignOrbitals::AssignOrbitals(core::chemical::ResidueTypeOP const restype) :
43  restype_(restype),
44  n_orbitals_(0)
45 
46 {
47 
48 }
49 
51 {
53  core::chemical::AtomTypeSetCAP atom_type_set = chemical_manager->atom_type_set("fa_standard");
54  if(restype_->aa() == aa_tyr || restype_->aa() == aa_phe || restype_->aa() == aa_trp){
55  if(restype_->actcoord_atoms().size() != 0){
56 
57  utility::vector1<Size> act_atoms =restype_->actcoord_atoms();
58  /* for(Size x=1; x<= restype_->actcoord_atoms().size(); ++x){
59 
60  std::cout << restype_->name3() << " " << restype_->atom_name(restype_->actcoord_atoms()[x]) << std::endl;
61  }*/
62  Aindex_ = restype_->actcoord_atoms()[2];
63  core::chemical::AtomType const & atmtype(restype_->atom_type(Aindex_));
64  if(!atmtype.is_virtual()){
65 
66 
67  core::Size atm_index2 = restype_->bonded_neighbor(Aindex_)[1];
68  core::Size atm_index3= restype_->bonded_neighbor(Aindex_)[2];
69  AOdist_ =0.7;
71  numeric::xyzVector<core::Real> acct_coord = ((restype_->atom(Aindex_).ideal_xyz() - restype_->atom(atm_index2).ideal_xyz())/2);
72 
73  //std::cout << restype_->name3() << " " << restype_->atom_name(Aindex_) << " " << restype_->atom_name(atm_index2) << " " << restype_->atom_name(atm_index3) << std::endl;
74  //std::cout << acct_coord.x() << " " << acct_coord.y() << " " << acct_coord.z() << std::endl;
75 
77  new_action.zero();
78  for ( Size ii = 1; ii <= restype_->actcoord_atoms().size(); ++ii )
79  {
80  new_action += restype_->atom(restype_->actcoord_atoms()[ii]).ideal_xyz();
81  }
82  new_action.x() /= restype_->actcoord_atoms().size();
83  new_action.y() /= restype_->actcoord_atoms().size();
84  new_action.z() /= restype_->actcoord_atoms().size();
85 
86 
87 
88 
89  numeric::xyzVector<core::Real> vector_d( new_action - restype_->atom(atm_index2).ideal_xyz());
90  numeric::xyzVector<core::Real> vector_f( new_action - restype_->atom(atm_index3).ideal_xyz());
91 
92  //Create an object of Class utility::vector1 to hold the xyz coordinates of orbitals(e.g., cross products)
93  //Get two cross products of the two vectors, one is above, the other is below the plane defined by the two vectors
95  numeric::xyzVector<core::Real> xyz_right = cross_product(vector_d, vector_f);
96  numeric::xyzVector<core::Real> xyz_left = cross_product(-vector_d, vector_f);
97  pi_orbital_xyz_vector.push_back((xyz_left.normalized() * AOdist_) + restype_->atom(atm_index3).ideal_xyz());
98  pi_orbital_xyz_vector.push_back((xyz_right.normalized() * AOdist_) + restype_->atom(atm_index3).ideal_xyz());
99 
100 
101  for(core::Size vector_index = 1; vector_index <= pi_orbital_xyz_vector.size(); ++vector_index){
102  std::string p_orbital_type_full_name(make_orbital_type_name(atmtype, "pi", AOhybridization_) );
103  std::string p_orbital_element_name( make_orbital_element_name() );
104  set_orbital_type_and_bond(Aindex_, p_orbital_element_name, p_orbital_type_full_name);
105 
106  Vector const stub1_xyz = restype_->atom(Aindex_).ideal_xyz();
107  Vector const stub2_xyz = restype_->atom(atm_index2).ideal_xyz();
108  Vector const stub3_xyz = restype_->atom(atm_index3).ideal_xyz();
109 
110  core::Real const distance(pi_orbital_xyz_vector[vector_index].distance(stub1_xyz) );
111 
112  core::Real theta(0.0);
113  core::Real phi(0.0);
114 
115  if(distance <1e-2)
116  {
117  std::cout << "WARNING: extremely small distance=" << distance << " for " <<
118  p_orbital_element_name << " ,using 0.0 for theta and phi."<<
119  " If you were not expecting this warning, something is very wrong" <<std::endl;
120  }else
121  {
122  theta = numeric::angle_radians<core::Real>(pi_orbital_xyz_vector[vector_index],stub1_xyz,stub2_xyz);
123  if( (theta < 1e-2) || (theta > numeric::NumericTraits<Real>::pi()-1e-2) )
124  {
125  phi = 0.0;
126  }else
127  {
128  phi = numeric::dihedral_radians<core::Real>(pi_orbital_xyz_vector[vector_index],stub1_xyz,stub2_xyz,stub3_xyz);
129  }
130 
131  }
132 
133  std::string const stub1(strip_whitespace(restype_->atom_name(Aindex_)));
134  std::string const stub2(strip_whitespace(restype_->atom_name(atm_index2)));
135  std::string const stub3(strip_whitespace(restype_->atom_name(atm_index3)));
136  core::Real const const_theta(theta);
137  core::Real const const_phi(phi);
138  std::string const const_name(p_orbital_element_name);
139  restype_->set_orbital_icoor_id( const_name,const_phi,const_theta,distance,stub1,stub2,stub3);
140 
141  }
142  }
143  }
144 
145  }
146  // Get the chemical atom_type for each atom by it index number in this residue
147  for (core::Size atm_index = 1; atm_index <= restype_->natoms(); ++atm_index ){
148  /*OrbInfo orbital_info;*/
149  core::chemical::AtomType const & atmtype(restype_->atom_type(atm_index));
150 
151 
152  // determine if atom has an orbital, if yes,
153  if (atmtype.atom_has_orbital()){
154  //get hybridization state of atom_type and orbital type associated with atom type
155  core::Size atom_type_index = atom_type_set->atom_type_index(atmtype.atom_type_name());
156  core::Size parameter_hybridization = atom_type_set->extra_parameter_index("ORBITAL_HYBRIDIZATION");
157  core::Size parameter_orbitaltypes = atom_type_set->extra_parameter_index("ORBITAL_TYPES");
158  core::Size parameter_bohrradius = atom_type_set->extra_parameter_index("BOHR_RADIUS");
159 
160  Aindex_ = atm_index;
161  AOhybridization_ = (core::Size)( atom_type_set->operator[](atom_type_index ).extra_parameter(parameter_hybridization) );
162  Orbtype_ = (core::Size)( atom_type_set->operator[](atom_type_index).extra_parameter(parameter_orbitaltypes) );
163  AOdist_ = atom_type_set->operator[](atom_type_index).extra_parameter(parameter_bohrradius);
164  AObondedatoms_ = restype_->bonded_neighbor(atm_index);
165 
166  //very crappy hack. This whole code sucks. WTF? Needs to be rewritten!
167  if(atmtype.name() == "Nhis"){
168  core::Size atm_index2(AObondedatoms_[2]);//atom index of the only bonded neighbor.
169  //get the atom indices of the bonded neighbors of atm_index2.
170  utility::vector1<core::Size> neighbor_bonded_atms2(restype_->bonded_neighbor(atm_index2));
171  core::Size atm_index3(AObondedatoms_[1]);
172 /*
173  for(core::Size x=1; x<= neighbor_bonded_atms2.size(); ++x){
174  //if atm_index is not equal to the index in neighbor bonded atoms to C2,do nothing,continue the loop.
175  //crappy hack and causes the neighbor_bonded_atms2 to be somewhat random according to index
176  //makes for hard debugging
177  if(Aindex_ != neighbor_bonded_atms2[x])
178  {
179  atm_index3 = neighbor_bonded_atms2[x];
180  }
181  }
182 */
183 
184 
185  numeric::xyzVector<core::Real> vector_a(restype_->atom(Aindex_).ideal_xyz() - restype_->atom(atm_index2).ideal_xyz() );
186  numeric::xyzVector<core::Real> vector_b( restype_->atom(Aindex_).ideal_xyz() - restype_->atom(atm_index3).ideal_xyz() );
187  numeric::xyzVector<core::Real> vector_ab_norm = vector_a.normalized()+vector_b.normalized();
188 
190  orbital_xyz_vectors.push_back((vector_ab_norm.normalized()*AOdist_)+restype_->atom(Aindex_).ideal_xyz());
191 
192  //utility::vector1< numeric::xyzVector<core::Real> > orbital_xyz_vectors = cross_product_helper(Aindex_,atm_index2,atm_index3,AOdist_);
193  //add_orbitals_to_restype(atm_index2, atm_index3, /*orbital_info,*/ atmtype, "p", orbital_xyz_vectors);
194 
195  core::Real const phi(numeric::conversions::radians(180.0));
196  core::Real const theta(numeric::conversions::radians(54.365));
197 
198  //core::Real const phi_De(numeric::conversions::radians(180.0));
199  //core::Real const theta_De(numeric::conversions::radians(70.0));
200 
201  std::string orbital_type_full_name(make_orbital_type_name(atmtype, "p",AOhybridization_) );
202  std::string const orbital_element_name( make_orbital_element_name() );
203 
204  set_orbital_type_and_bond(Aindex_, orbital_element_name, orbital_type_full_name);
205  //set_orbital_type_and_bond(atm_index, orbital_element_name3, orbital_type_full_name);
206 
207 
208  std::string const stub1(strip_whitespace(restype_->atom_name(Aindex_)));
209  std::string const stub2(strip_whitespace(restype_->atom_name(atm_index2)));
210  std::string const stub3(strip_whitespace(restype_->atom_name(atm_index3)));
211 
212 
213  restype_->set_orbital_icoor_id( orbital_element_name,phi,theta,AOdist_,stub1,stub2,stub3);
214 
215 
216 
217  }
218 
219 
220 
221  //std::cout << Aindex_ << " " << AOhybridization_ <<" " << Orbtype_ << " " << AOdist_ << std::endl;
222  if(AObondedatoms_.size()== 1 && AOhybridization_ == 2){
223  if(Orbtype_ == 1){
224  // assign_only_pi_orbitals_to_atom(orbital_info, atmtype);
225  }else if(Orbtype_ == 4){
226  assign_sp2_sp_orbitals_to_one_bonded_atom(/*orbital_info,*/ atmtype);
227  }else {//if orbitaltypes == 2
228  assign_sp2_orbitals_to_one_bonded_atom(/*orbital_info,*/ atmtype);
229  //utility_exit_with_message("Both P and Pi orbitals exist if # bonded atoms=1 and hybridization = 2 in case of C=0");
230  }
231  }
232  if(AObondedatoms_.size()== 2 && AOhybridization_ == 2){
233  //Consider this situation C=N-H, the C-N,N-H sigma bonds and the nitrogen lone-pair hybrid orbital are coplanar.
234  //the un-hybridazed p orbital at a right anlge to the plane forming a pi bond.
235  //utility_exit_with_message("Both P and Pi orbitals exist if # bonded atoms=2 and hybridization = 2, as seen in >C=N-");
236  if (Orbtype_ == 1){
237  assign_only_pi_orbitals_to_atom(/*orbital_info,*/ atmtype);
238  }
239  if (Orbtype_ == 4){
240  //Currently, the atm_index is N1 which is sp2 hybridized and bonded to 2 atoms.N1 has both P and Pi orbitals.
241  //Now we need to determine neighbor atoms in order to define a plane to place the orbitals.
242  core::Size atm_index2(AObondedatoms_[1]);
243  core::Size atm_index3(AObondedatoms_[2]);
244 
245  //We first want to add pi orbitals to the Nitrogen,
246  assign_only_pi_orbitals_to_atom(/*orbital_info,*/ atmtype);
247 
248  //Place one lone pair of P orbitals on sp2 hybridized Nhis atom, which are bonded to two atoms.
249  std::string const stub1(strip_whitespace(restype_->atom_name(atm_index)));
250  std::string const stub2(strip_whitespace(restype_->atom_name(atm_index2)));
251  std::string const stub3(strip_whitespace(restype_->atom_name(atm_index3)));
252 
253  core::Real const phi(numeric::conversions::radians(180.0));
254  core::Real const theta(numeric::conversions::radians(54.0));
255 
256  std::string orbital_type_full_name(make_orbital_type_name(atmtype, "p", AOhybridization_) );
257  std::string const orbital_element_name( make_orbital_element_name() );
258  set_orbital_type_and_bond(atm_index, orbital_element_name, orbital_type_full_name);
259  restype_->set_orbital_icoor_id( orbital_element_name,phi,theta,AOdist_,stub1,stub2,stub3);
260  }
261  }
262  if(AObondedatoms_.size()== 3 && AOhybridization_== 2){//as seen in COO,NH2O and aroC.
263  if (Orbtype_ == 1 || Orbtype_ == 3){ //Assign pi orbitals
264  core::Size atm_index2(AObondedatoms_[1]);
265  core::Size atm_index3(AObondedatoms_[2]);
266  utility::vector1< numeric::xyzVector<core::Real> > orbital_xyz_vectors = cross_product_helper(atm_index,atm_index2,atm_index3,AOdist_);
267  add_orbitals_to_restype(atm_index2, atm_index3, /*orbital_info,*/ atmtype, "pi",orbital_xyz_vectors);
268  }
269 /* if (Orbtype_ == 2){
270  utility_exit_with_message("P orbital does not exist if # bonded atoms=3 and hybridization = 2, as seen in >C=C<");
271  }*/
272  }
273  if(AObondedatoms_.size()== 1 && AOhybridization_== 3){
274  //this instance exists in PO4-, which has one P=O double bond and then three P-O single bonds.
275  // The oxygens that are singly bonded have 3 sets of lone pairs and each has a -1 charge.
276 
277  }
278  //sp3 hybrdization
279  if(AObondedatoms_.size()== 2 && AOhybridization_== 3){
280 /* if(Orbtype_ != 2){
281  utility_exit_with_message("Pi orbital does not exist if # bonded atoms=3 and hybridization = 3");
282  }*/
283 
284  if(Orbtype_ == 3){//assign P orbitals to -O-, or -S-, such as -OH
285  core::Size atm_index2(AObondedatoms_[1]);
286  core::Size atm_index3(AObondedatoms_[2]);
287 
288  std::string const stub1(strip_whitespace(restype_->atom_name(atm_index)));
289  std::string const stub2(strip_whitespace(restype_->atom_name(atm_index2)));
290  std::string const stub3(strip_whitespace(restype_->atom_name(atm_index3)));
291 
292  core::Real const phi(numeric::conversions::radians(120.0));
293  core::Real const theta(numeric::conversions::radians(70.0));
294 
295  //core::Real const phi_De(numeric::conversions::radians(180.0));
296  //core::Real const theta_De(numeric::conversions::radians(70.0));
297 
298  std::string orbital_type_full_name(make_orbital_type_name(atmtype, "p",AOhybridization_) );
299  std::string const orbital_element_name( make_orbital_element_name() );
300  std::string const orbital_element_name2( make_orbital_element_name() );
301  std::string const orbital_element_name3( make_orbital_element_name() );
302 
303  set_orbital_type_and_bond(atm_index, orbital_element_name, orbital_type_full_name);
304  set_orbital_type_and_bond(atm_index, orbital_element_name2, orbital_type_full_name);
305  //set_orbital_type_and_bond(atm_index, orbital_element_name3, orbital_type_full_name);
306 
307  restype_->set_orbital_icoor_id( orbital_element_name,phi,theta,AOdist_,stub1,stub2,stub3);
308  restype_->set_orbital_icoor_id( orbital_element_name2,-phi,theta,AOdist_,stub1,stub2,stub3);
309  //restype_->set_orbital_icoor_id( orbital_element_name3,phi_De,theta_De,AOdist_,stub1,stub2,stub3);
310 
311  }
312  }
313  if(AObondedatoms_.size()== 3 && AOhybridization_ == 3){
314 /* if(Orbtype_ != 2){
315  utility_exit_with_message("Pi orbital does not exist if # bonded atoms=3 and hybridization = 3");
316  }*/
317 
318  if(Orbtype_ == 2){// assign one p orbital to a sp3 N bonded to 3 atoms, as seen in -NH-
319  core::Size atm_index2(AObondedatoms_[1]);
320  core::Size atm_index3(AObondedatoms_[2]);
321  core::Size atm_index4(AObondedatoms_[3]);
322 
323  utility::vector1< numeric::xyzVector<core::Real> > orbital_xyz_vector = Coordinates_Tetrahedral_bondedto3atoms_helper(atm_index, atm_index2, atm_index3, atm_index4, AOdist_);
324  for(core::Size vector_index = 1; vector_index <= orbital_xyz_vector.size(); ++vector_index){
325  //std::cout << "orb_index=" << vector_index << " x=" << orbital_xyz_vector[vector_index].x() << " y="<< orbital_xyz_vector[vector_index].y() << " z="<< orbital_xyz_vector[vector_index].z() << std::endl;
326  std::string orbital_type_full_name(make_orbital_type_name(atmtype, "p", AOhybridization_) );
327  std::string orbital_element_name( make_orbital_element_name() );
328  set_orbital_type_and_bond(atm_index, orbital_element_name, orbital_type_full_name);
329  calculate_orbital_icoor(orbital_xyz_vector[vector_index], atm_index, atm_index2,atm_index3, orbital_element_name);
330  }
331  }
332  }
333 
334  }
335 
336 
337 
338 
339 
340 
341  }
342  restype_->finalize();
343 }
344 
345 
346 
347 void AssignOrbitals::assign_only_pi_orbitals_to_atom(/*OrbInfo const & orbital_info,*/ core::chemical::AtomType const & atmtype){
348  core::Size atm_index2(AObondedatoms_[1]);//atom index of the only bonded neighbor.
349  //get the atom indices of the bonded neighbors of atm_index2.
350  utility::vector1<core::Size> neighbor_bonded_atms2(restype_->bonded_neighbor(atm_index2));
351 
352  core::Size atm_index3(500);
353 
354  for(core::Size x=1; x<= neighbor_bonded_atms2.size(); ++x){
355  //if atm_index is not equal to the index in neighbor bonded atoms to C2,do nothing,continue the loop.
356  //crappy hack and causes the neighbor_bonded_atms2 to be somewhat random according to index
357  //makes for hard debugging
358  if(Aindex_ != neighbor_bonded_atms2[x])
359  {
360  atm_index3 = neighbor_bonded_atms2[x];
361  }
362  }
363 
364  utility::vector1< numeric::xyzVector<core::Real> > orbital_xyz_vectors = cross_product_helper(Aindex_,atm_index2,atm_index3,AOdist_);
365  add_orbitals_to_restype(atm_index2, atm_index3, /*orbital_info,*/ atmtype, "pi", orbital_xyz_vectors);
366 }
367 
368 void AssignOrbitals::assign_sp2_sp_orbitals_to_one_bonded_atom(/*OrbInfo const & orbital_info,*/ core::chemical::AtomType const & atmtype){
369  //Consider this situation. >C1-C2=O1 (C single bond C double bond O). O1 needs two Pi and three P orbitals,
370  core::Size atm_index2(AObondedatoms_[1]);//atom index of the only bonded neighbor.
371  //get the atom indices of the bonded neighbors of atm_index2.
372  utility::vector1<core::Size> neighbor_bonded_atms2(restype_->bonded_neighbor(atm_index2));
373 
374  core::Size atm_index3(500);
375 
376  for(core::Size x=1; x<= neighbor_bonded_atms2.size(); ++x){
377  //if atm_index is not equal to the index in neighbor bonded atoms to C2,do nothing,continue the loop, .
378  if(Aindex_ != neighbor_bonded_atms2[x])
379  {
380  atm_index3 = neighbor_bonded_atms2[x];
381  }
382  }
383  utility::vector1< numeric::xyzVector<core::Real> > orbital_xyz_vectors = cross_product_helper(Aindex_,atm_index2,atm_index3,AOdist_);
384  add_orbitals_to_restype(atm_index2, atm_index3, /*orbital_info,*/ atmtype, "pi", orbital_xyz_vectors);
385 
386 
387  //Place two lone pair of P orbitals on sp2 hybridized O atom, which are bonded to one atoms.
388  orbital_xyz_vectors = Coordinates_TriganolPlanar_bondedto1atom_helper(Aindex_,atm_index2,atm_index3,AOdist_);
389  add_orbitals_to_restype(atm_index2, atm_index3, /*orbital_info,*/ atmtype, "p", orbital_xyz_vectors);
390 }
391 
392 void AssignOrbitals::assign_sp2_orbitals_to_one_bonded_atom(/*OrbInfo const & orbital_info,*/ core::chemical::AtomType const & atmtype){
393  //Consider this situation. >C1-C2=O1 (C single bond C double bond O). O1 needs two Pi and three P orbitals,
394  core::Size atm_index2(AObondedatoms_[1]);//atom index of the only bonded neighbor.
395  //get the atom indices of the bonded neighbors of atm_index2.
396  utility::vector1<core::Size> neighbor_bonded_atms2(restype_->bonded_neighbor(atm_index2));
397 
398  core::Size atm_index3(500);
399 
400  for(core::Size x=1; x<= neighbor_bonded_atms2.size(); ++x){
401  //if atm_index is not equal to the index in neighbor bonded atoms to C2,do nothing,continue the loop, .
402  if(Aindex_ != neighbor_bonded_atms2[x])
403  {
404  atm_index3 = neighbor_bonded_atms2[x];
405  }
406  }
407  //Place two lone pair of P orbitals on sp2 hybridized O atom, which are bonded to one atoms.
409  add_orbitals_to_restype(atm_index2, atm_index3, /*orbital_info,*/ atmtype, "p", orbital_xyz_vectors);
410 }
411 
412 
413 
414 // To get a pair of pi orbitals, we calculate the cross products of two vectors both pointing towards the atom with an index of atm_index1.
415 // The two cross products are perpendicular to the plane; one is above and the other is below the plane.
416 // core::Real dist is the Bohr radius of H plus the Bohr radius of the first atom with atm_index1
418 (
419  core::Size const atm_index1,
420  core::Size const atm_index2,
421  core::Size const atm_index3,
422  core::Real const dist
423 )
424 {
425 
426  //std::cout << "atm_index1: " << atm_index1 << " index 2: " << atm_index2 << " index3 " << atm_index3 << std::endl;
427 
428  //define two vectors, both pointing back to the central atom with atm_index2
429  numeric::xyzVector<core::Real> vector_d( restype_->atom(atm_index1).ideal_xyz() - restype_->atom(atm_index2).ideal_xyz());
430  numeric::xyzVector<core::Real> vector_f( restype_->atom(atm_index1).ideal_xyz() - restype_->atom(atm_index3).ideal_xyz());
431 
432  //Create an object of Class utility::vector1 to hold the xyz coordinates of orbitals(e.g., cross products)
433  //Get two cross products of the two vectors, one is above, the other is below the plane defined by the two vectors
434  utility::vector1< numeric::xyzVector<core::Real> > pi_orbital_xyz_vector;
435  numeric::xyzVector<core::Real> xyz_right = cross_product(vector_d, vector_f);
436  numeric::xyzVector<core::Real> xyz_left = cross_product(-vector_d, vector_f);
437 
438  //Normalize the two new vectors, xyz_right and xyz_left to get a unit vector.
439  //pi_orbital_xyz_vector now stores the new xyz coordinates of the pi orbitals.
440  pi_orbital_xyz_vector.push_back((xyz_right.normalized() * dist) + restype_->atom(atm_index1).ideal_xyz());
441  pi_orbital_xyz_vector.push_back((xyz_left.normalized() * dist) + restype_->atom(atm_index1).ideal_xyz());
442 
443  return pi_orbital_xyz_vector;
444 
445 }
446 
447 
449  core::Size const atm_index2,
450  core::Size const atm_index3,
451  //OrbInfo const & orbital_info,
452  core::chemical::AtomType const & atmtype,
453  std::string const atom_hybridization,
454  utility::vector1< numeric::xyzVector<core::Real> > const orbital_xyz_vectors
455 ){
456  for(core::Size vector_index = 1; vector_index <= orbital_xyz_vectors.size(); ++vector_index){
457  std::string p_orbital_type_full_name(make_orbital_type_name(atmtype, atom_hybridization, AOhybridization_) );
458  std::string p_orbital_element_name( make_orbital_element_name() );
459  set_orbital_type_and_bond(Aindex_, p_orbital_element_name, p_orbital_type_full_name);
460  calculate_orbital_icoor(orbital_xyz_vectors[vector_index],Aindex_, atm_index2, atm_index3, p_orbital_element_name);
461  }
462 }
463 
465 (
466  AtomType const & atmtype,
467  std::string const orbitaltype,
468  core::Size const hybridization
469 )
470 {
471  std::string atm_element( atmtype.element() );
472 
473  std::string hyb;
474  if(hybridization == 1 ){
475  hyb = "sp";
476  }else if(hybridization ==2 ){
477  hyb="sp2";
478  }else if(hybridization ==3 ){
479  hyb="sp3";
480  }
481 
482  std::string orbital_type_full_name(atm_element+"."+orbitaltype+"."+hyb);
483  return orbital_type_full_name;
484 }
485 
487 {
488  ++n_orbitals_;
489  std::string orbital_name("LP");
490  std::string orb_index_string = utility::to_string<core::Size>(n_orbitals_) ;
491  std::string orbital_element_name(orbital_name+orb_index_string);
492  return orbital_element_name;
493 }
494 
495 
496 //Assign orbital types and bond information which will be passed to the function restype_->set_orbital_icoor_id to get
497 //icoord for all orbitals.
499  core::Size atom_index,
500  std::string orbital_element_name,
501  std::string orbital_type_full_name
502 
503 ){
504  // Orbital names are given by concatenate two strings:'LP" and the indices of the orbitals on the residue(restype);
505  std::string atm_name(strip_whitespace(restype_->atom_name(atom_index)));
506 
507  restype_->add_orbital(orbital_element_name, orbital_type_full_name);
508  restype_->add_orbital_bond(atm_name, orbital_element_name);
509 
510 }
511 
512 
513 
515  numeric::xyzVector<core::Real> const orbital_xyz,
516  core::Size const atm_index1,
517  core::Size const atm_index2,
518  core::Size const atm_index3,
519  std::string const orbital_element_name
520 )
521 {
522  Vector const stub1_xyz = restype_->atom(atm_index1).ideal_xyz();
523  Vector const stub2_xyz = restype_->atom(atm_index2).ideal_xyz();
524  Vector const stub3_xyz = restype_->atom(atm_index3).ideal_xyz();
525 
526  core::Real const distance(orbital_xyz.distance(stub1_xyz) );
527 
528  core::Real theta(0.0);
529  core::Real phi(0.0);
530 
531  if(distance <1e-2)
532  {
533  std::cout << "WARNING: extremely small distance=" << distance << " for " <<
534  orbital_element_name << " ,using 0.0 for theta and phi."<<
535  " If you were not expecting this warning, something is very wrong" <<std::endl;
536  }else
537  {
538  theta = numeric::angle_radians<core::Real>(orbital_xyz,stub1_xyz,stub2_xyz);
539  if( (theta < 1e-2) || (theta > numeric::NumericTraits<Real>::pi()-1e-2) )
540  {
541  phi = 0.0;
542  }else
543  {
544  phi = numeric::dihedral_radians<core::Real>(orbital_xyz,stub1_xyz,stub2_xyz,stub3_xyz);
545  }
546 
547  }
548 
549  std::string const stub1(strip_whitespace(restype_->atom_name(atm_index1)));
550  std::string const stub2(strip_whitespace(restype_->atom_name(atm_index2)));
551  std::string const stub3(strip_whitespace(restype_->atom_name(atm_index3)));
552  core::Real const const_theta(theta);
553  core::Real const const_phi(phi);
554  std::string const const_name(orbital_element_name);
555 
556 
557  //restype_->add_orbital( orbital_element_name, );
558  //restype_->add_orbital_bond(stub1, orbital_element_name);
559 
560 
561 
562  //tr << orbital << " " << stub_atom1 << " "<< stub_atom2 << " " <<stub_atom3 << " " <<distance << " " << phi << " " << theta <<std::endl;
563  restype_->set_orbital_icoor_id( const_name,const_phi,const_theta,distance,stub1,stub2,stub3);
564 }
565 
566 
568  core::Size const atm_index1,
569  core::Size const atm_index2,
570  core::Size const atm_index3,
571  core::Real const dist
572 
573 ){
574 
575  //create a new vector to hold coordinates of P orbitals.
577 
578  numeric::xyzVector<core::Real> vector_a = restype_->atom(atm_index1).ideal_xyz();
579  numeric::xyzVector<core::Real> vector_b = restype_->atom(atm_index2).ideal_xyz();
580  numeric::xyzVector<core::Real> vector_c = restype_->atom(atm_index3).ideal_xyz();
581 
582  //core::Real distance_xa = 01.0;
583  core::Real angle_xab = numeric::constants::r::pi_over_3; //60 degrees
584  //for one point it should be 180 for another it should be 0
585  //core::Real dihedral_xabc = numeric::constants::r::pi;
586 
587  numeric::xyzVector<core::Real> a( (vector_a - vector_b).normalized());
588  numeric::xyzVector<core::Real> b((vector_b - vector_c).normalized());
589  numeric::xyzVector<core::Real> c(cross_product(a,b).normalized());
590  numeric::xyzVector<core::Real> d(cross_product(a,c).normalized());
591 
592  core::Real dihedral_xabc1 = numeric::constants::r::pi;
593  core::Real dihedral_xabc2 = 0;
594 
595  numeric::xyzVector<core::Real> v1 = a * std::cos(numeric::constants::r::pi - angle_xab);
596  numeric::xyzVector<core::Real> v2 = c * std::sin(numeric::constants::r::pi - angle_xab);
597  numeric::xyzVector<core::Real> v3 = d * std::sin(numeric::constants::r::pi - angle_xab);
598 
600  (
601  (
602  v1 - v2 * std::sin(dihedral_xabc1) + v3 * std::cos(dihedral_xabc1)
603  ) * dist
604  );
605 
607  (
608  (
609  v1 - v2 * std::sin(dihedral_xabc2) + v3 * std::cos(dihedral_xabc2)
610  ) * dist
611  );
612 
613 /*
614  //add the degenerative orbital. Currently commented out as it screws with correct geometry
615  numeric::xyzVector<core::Real> x3
616  (
617  (
618  -(vector_a - vector_b).normalized()
619  ) * dist
620  );
621 */
622 
623  orbital_xyz_vector.push_back(vector_a+x1);
624  orbital_xyz_vector.push_back(vector_a+x2);
625  //orbital_xyz_vector.push_back(vector_a+x3);
626 
627  return orbital_xyz_vector;
628 }
629 
630 
631 // Get the coordinates of one P orbital (x1)attached to a sp3 hybridized atom which is bonded to three atoms (e.g. -NH-).
633  core::Size const atm_index1,
634  core::Size const atm_index2,
635  core::Size const atm_index3,
636  core::Size const atm_index4,
637  core::Real const dist
638 
639  ){
640 
642 
643  numeric::xyzVector<core::Real> vector_a = restype_->atom(atm_index1).ideal_xyz();
644  numeric::xyzVector<core::Real> vector_b = restype_->atom(atm_index2).ideal_xyz();
645  numeric::xyzVector<core::Real> vector_c = restype_->atom(atm_index3).ideal_xyz();
646  numeric::xyzVector<core::Real> vector_d = restype_->atom(atm_index4).ideal_xyz();
647 
649  (
650  ( ( vector_a - vector_b).normalized()
651  + ( vector_a - vector_c).normalized() + ( vector_a - vector_d).normalized()).normalized() * dist
652  );
653 
654 
655  orbital_xyz_vector.push_back(vector_a+x);
656 
657  return orbital_xyz_vector;
658  }
659 
660 
661 
662 }//namespace
663 }//namespace
664 }//namespace
665 
666 
667 
668