Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OrbitalsStatistics.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 /// @begin OrbitalStatistics
11 ///
12 /// @brief
13 /// A class for generating statistics from orbitals
14 ///
15 /// @detailed
16 /// This is an attempt to be transparent in how the orbital-hydrogen interactions were converted into
17 /// a KBP. In general terms, a set of proteins from PDB were taken and the shortest distance from an
18 /// orbital to a polar or aromatic hydrogen was recorded and binned. In addition to the shortest distance,
19 /// an angle was taken. The angle considered is the angle between the base atom that contains the orbital, the
20 /// orbital, and the hydrogen. For polar hydrogens, only sidechain polar hydrogens were considered.
21 ///
22 /// For protein interactions, there are 7 classes (orbital types) of orbitals that statistics are generated.
23 /// These 7 types are mapped using a map to enum data structure. For each sidechain interaction, only the shortest
24 /// distance between any given orbital type to a hydrogen is calculated. That means, that for each sidechain interaction
25 /// only 1 distance, 1 angle, and 1 class is recorded.
26 ///
27 /// Bin sizes were calculated by .1A for distance and cos of 1 for angles. See below:
28 ///
29 /// angle
30 /// -1 -.9 -.8 -.7..........
31 /// d .1 | 0 0 0 0
32 /// i .2 | 500 0 0 0
33 /// s .3 | 25 0 0 0
34 /// t .4 | 0 30 5 0
35 ///
36 /// This is not the original code that was used to generate the statistics. The original code was much more
37 /// convoluted than this because I had no idea how to program. I wrote this piece for clarity. I have tested
38 /// it and it produces the same results.
39 ///
40 /// @authors
41 /// Steven Combs
42 ///
43 ///
44 /////////////////////////////////////////////////////////////////////////
45 
47 #include <core/pose/Pose.hh>
48 #include <numeric/histograms/TwoDHistogram.hh>
50 #include <numeric/xyzVector.hh>
52 #include <core/pose/PDBInfo.hh>
53 
54 
55 //utility headers
56 #include <utility/vector1.hh>
57 
58 
59 // AUTO-REMOVED #include <math.h> // REQUIRED FOR WINDOWS
60 
61 #include <map>
62 
63 
64 //option headers
65 #include <basic/options/option.hh>
66 #include <basic/options/keys/orbitals.OptionKeys.gen.hh>
67 
68 
69 namespace core{
70 namespace scoring{
71 namespace orbitals{
72 
73 // REQUIRED FOR WINDOWS
74 #ifdef _WIN32 // REQUIRED FOR WINDOWS
75  double round( double d ) { // REQUIRED FOR WINDOWS
76  return (d > 0.0) ? floor(d + 0.5) : ceil(d - 0.5); // REQUIRED FOR WINDOWS
77  } // REQUIRED FOR WINDOWS
78 #endif // REQUIRED FOR WINDOWS
79 // REQUIRED FOR WINDOWS
80 
82 {
83  if(
84  basic::options::option[basic::options::OptionKeys::orbitals::Haro] ||
85  basic::options::option[basic::options::OptionKeys::orbitals::Hpol])
86  {
88  }
89  for(core::Size i=0; i <= 100; ++i){
90  for(core::SSize j=-10; j<= 10; ++j){
91  std::pair<core::Size, core::SSize> pair(i,j);
92  twoD_histogram_.insert_data(pair, 0);
93 
94  }
95  }
96 
97  //map orbial type to enum
98  orbital_type_2_enum_["C.pi.sp2"]=C_pi_sp2;
99  orbital_type_2_enum_["N.pi.sp2"]=N_pi_sp2;
100  orbital_type_2_enum_["N.p.sp2"]=N_p_sp2;
101  orbital_type_2_enum_["O.pi.sp2"]=O_pi_sp2;
102  orbital_type_2_enum_["O.p.sp2"]=O_p_sp2;
103  orbital_type_2_enum_["O.p.sp3"]=O_p_sp3;
104  orbital_type_2_enum_["S.p.sp3"]=S_p_sp3;
105 
106 
107 
108 }
109 
110 
111 
112 
113 numeric::histograms::TwoDHistogram<core::Size, core::SSize> OrbitalsStatistics::get_2D_histogram()
114 {
115  return twoD_histogram_;
116 }
117 
119 {
120  return histogram_vector_;
121 }
122 
124 {
125  return number_of_histograms_;
126 }
127 
128 
129 ///@brief increment the orbital histogram bin based upon a distance and angle.
130 /// Currently the statistics are best with .1 incremented bins
133  core::Real & angle,
134  numeric::histograms::TwoDHistogram<core::Size, core::SSize> & histogram
135 )
136 {
137 
138  if(angle >= -1 && angle <= -.9){
139  angle = -.95;
140  }
141  if(angle >= -.89 && angle <= -.8){
142  angle = -.85;
143  }
144  if(angle >= -.79 && angle <= -.7){
145  angle = -.75;
146  }
147  if(angle >= -.69 && angle <= -.6){
148  angle = -.65;
149  }
150  if(angle >= -.59 && angle <= -.5){
151  angle = -.55;
152  }
153  if(angle >= -.49 && angle <= -.4){
154  angle = -.45;
155  }
156  if(angle >= -.39 && angle <= -.3){
157  angle = -.35;
158  }
159  if(angle >= -.29 && angle <= -.2){
160  angle = -.25;
161  }
162  if(angle >= -.19 && angle <= -.1){
163  angle = -.15;
164  }
165  if(angle >= -.09 && angle <= 0){
166  angle = -.05;
167  }
168  if(angle >= 0.01 && angle <= .1){
169  angle = .05;
170  }
171  if(angle >= .11 && angle <= .2){
172  angle = .15;
173  }
174  if(angle >= .21 && angle <= .3){
175  angle = .25;
176  }
177  if(angle >= .31 && angle <= .4){
178  angle = .35;
179  }
180  if(angle >= .41 && angle <= .5){
181  angle = .45;
182  }
183  if(angle >= .51 && angle <= .6){
184  angle = .55;
185  }
186  if(angle >= .61 && angle <= .7){
187  angle = .65;
188  }
189  if(angle >= .71 && angle <= .8){
190  angle = .75;
191  }
192  if(angle >= .81 && angle <= .9){
193  angle = .85;
194  }
195  if(angle >= .91 && angle <= 1){
196  angle = .95;
197  }
198  core::SSize new_angle= static_cast<core::SSize> (round(angle/.1));
199  core::Size new_dist= static_cast<core::Size> (round(distance/.1));
200  std::pair< core::Size, core::SSize> new_pair(new_dist, new_angle);
201  histogram.increase_count(new_pair);
202  //++histogram[new_pair];
203 // std::cout << " outputing paired distance that was put in increment_histogram_bind "<<histogram.lookup_counts(new_pair) << std::endl;;
204 }
205 
206 
207 ///@brief get statistics based upon hydrogen to orbital distance/angle
209  core::pose::Pose & pdb
210 ){
211  //std::cout << "Made it to the sc_H_orbital function!!!!!" << std::endl;
212  numeric::histograms::TwoDHistogram<core::Size, core::SSize> histogram=twoD_histogram_;
213 
214  //a vector that will contain all the histograms.
216 
217  //add histograms to the previously created vector. Notice that the number created is based
218  //upon number_of_histograms_ which is constructed in the
219  for(core::Size x=1; x<= number_of_histograms_; ++x){
220  histogram_vector.push_back(histogram);
221  }
222 
223  //Let the magic begin!
224  for(core::Size res_num1 = 1; res_num1 <= pdb.n_residue(); ++res_num1){
225  core::conformation::Residue resid1 = pdb.residue(res_num1);
226  if(resid1.has_sc_orbitals()){
227  numeric::xyzVector<core::Real> final_orb_xyz;
228  core::Real low_D = 11;
230  std::string orbital_type("");
231  core::Real angle=2;
232  core::Size atom_index_min_dist(0);
233  core::Size res2seqpos(0);
234  std::string res2name;
235  core::Real angle2=2;
236 
237 
238  //std::cout << "inside the resid1.has_sc_orbitals()!" << std::endl;
239  for(core::Size res_num2 = 1; res_num2 <= pdb.n_residue(); ++res_num2){
240  core::conformation::Residue resid2 = pdb.residue(res_num2);
241  if(resid1.seqpos() != resid2.seqpos()){
242  if(resid1.nbr_atom_xyz().distance(resid2.nbr_atom_xyz()) <= 10.0)
243  {
245  //iterate through atoms with orbitals
246  for ( core::chemical::AtomIndices::const_iterator
247  atom_index = resid1.atoms_with_orb_index().begin(),
248  atom_end = resid1.atoms_with_orb_index().end();
249  atom_index != atom_end; ++atom_index
250  ){
251  if(!resid1.atom_is_backbone(*atom_index)){
252 
253 
254  utility::vector1<core::Size> const & orbital_indices(resid1.bonded_orbitals(*atom_index));
255  //iterate through the orbitals
256  for(
258  orbital_index = orbital_indices.begin(),
259  orbital_end = orbital_indices.end();
260  orbital_index != orbital_end; ++orbital_index
261  ){
262 
263  numeric::xyzVector<core::Real> orb_xyz = resid1.orbital_xyz(*orbital_index);
264  numeric::xyzVector<core::Real> bonded_atom_xyz(resid1.atom(*atom_index).xyz());
265  if(
266  basic::options::option[basic::options::OptionKeys::orbitals::Hpol]
267  ){
268 
269  //iterate only throught the sidechain polar hydrogens
270  for(
271  core::chemical::AtomIndices::const_iterator
272  hpol_index = resid2.Hpol_index().begin(),
273  hpol_end = resid2.Hpol_index().end(); hpol_index != hpol_end; ++hpol_index
274  )
275  {
276  res2_H_xyz = resid2.atom( *hpol_index ).xyz();
277  numeric::xyzVector<core::Real> DHO_atom_xyz(resid2.atom(resid2.bonded_neighbor(*hpol_index)[1]).xyz() );
278  core::Real container = orb_xyz.distance( res2_H_xyz );
279  if(container <= low_D){
280  final_orb_xyz = orb_xyz;
281  angle = cos_of(bonded_atom_xyz, orb_xyz, res2_H_xyz );
282  angle2 = cos_of(DHO_atom_xyz, res2_H_xyz, orb_xyz);
283  low_D = container;
284  orbital_type = resid1.orbital_type(*orbital_index).name();
285  res2name= resid2.name3();
286  res2seqpos=resid2.seqpos();
287  atom_index_min_dist=*hpol_index;
288 
289  }
290  }
291 
292  }
293  //haro
294  if(basic::options::option[basic::options::OptionKeys::orbitals::Haro]){
295  for(core::chemical::AtomIndices::const_iterator
296  haro_index = resid2.Haro_index().begin(),
297  haro_end = resid2.Haro_index().end(); haro_index != haro_end; ++haro_index)
298  {
299  res2_H_xyz = resid2.atom( *haro_index ).xyz();
300  numeric::xyzVector<core::Real> DHO_atom_xyz(resid2.atom(resid2.bonded_neighbor(*haro_index)[1]).xyz() );
301  core::Real container = orb_xyz.distance( res2_H_xyz );
302  if(container <= low_D){
303  angle = cos_of(bonded_atom_xyz, orb_xyz, res2_H_xyz );
304  angle2 = cos_of(DHO_atom_xyz, res2_H_xyz, orb_xyz);
305  orbital_type = resid1.orbital_type(*orbital_index).name();
306  low_D = container;
307  res2name= resid2.name3();
308  res2seqpos=resid2.seqpos();
309  atom_index_min_dist=*haro_index;
310  }
311  }
312  }
313  }
314  }
315  }
316  }
317  }
318  }// end for resid2
319 
320  if(low_D <= 10){
321  core::conformation::Residue res2 = pdb.residue(res2seqpos);
322  //std::cout << low_D << " angle: " << angle << std::endl;
323  //decompose_score(resid1, resid2, pdb, low_D, angle, electron_name);
324  if(orbital_type=="O.p.sp3" && res2.atom_is_backbone(res2.bonded_neighbor(atom_index_min_dist)[1])){
325  statistics_output_.open("O.p.sp3.backbone", std::ios_base::app);
326 
327  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " "<< pdb.pdb_info()->name() << " " << final_orb_xyz.x() << " " << final_orb_xyz.y() << " " << final_orb_xyz.z() << std::endl;
328  statistics_output_.close();
329  }else if(orbital_type=="S.p.sp3" && res2.atom_is_backbone(res2.bonded_neighbor(atom_index_min_dist)[1])) {
330  statistics_output_.open("S.p.sp3.backbone", std::ios_base::app);
331  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
332  statistics_output_.close();
333  }else if(orbital_type=="C.pi.sp2" && res2.atom_is_backbone(res2.bonded_neighbor(atom_index_min_dist)[1])) {
334  statistics_output_.open("C.pi.sp2.backbone", std::ios_base::app);
335  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
336  statistics_output_.close();
337  }
338  else if(orbital_type=="N.pi.sp2" && res2.atom_is_backbone(res2.bonded_neighbor(atom_index_min_dist)[1])) {
339  statistics_output_.open("N.pi.sp2.backbone", std::ios_base::app);
340  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
341  statistics_output_.close();
342  }else if(orbital_type=="N.p.sp2" && res2.atom_is_backbone(res2.bonded_neighbor(atom_index_min_dist)[1])) {
343  statistics_output_.open("N.p.sp2.backbone", std::ios_base::app);
344  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
345  statistics_output_.close();
346  }else if(orbital_type=="O.pi.sp2" && res2.atom_is_backbone(res2.bonded_neighbor(atom_index_min_dist)[1])) {
347  statistics_output_.open("O.pi.sp2.backbone", std::ios_base::app);
348  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
349  statistics_output_.close();
350  }else if(orbital_type=="O.p.sp2" && res2.atom_is_backbone(res2.bonded_neighbor(atom_index_min_dist)[1])) {
351  statistics_output_.open("O.p.sp2.backbone", std::ios_base::app);
352  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
353  statistics_output_.close();
354  }else {
355  statistics_output_.open(orbital_type.c_str(), std::ios_base::app);
356  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
357  statistics_output_.close();
358  //core::Size index_of_histogram(orbital_type_2_enum_.find(orbital_type)->second);
359  //std::cout << "index of histogram " << index_of_histogram << std::endl;
360  //increment_histogram_bin(low_D, angle, histogram_vector[ index_of_histogram ]);
361  }
362 
363  }
364 
365  }//end if resid1
366 
367 
368  }
369  histogram_vector_=histogram_vector;
370 }
371 
372 
373 
375  core::pose::Pose & pdb
376 ){
377  //std::cout << "Made it to the sc_H_orbital function!!!!!" << std::endl;
378  numeric::histograms::TwoDHistogram<core::Size, core::SSize> histogram=twoD_histogram_;
379 
380  //a vector that will contain all the histograms.
382 
383  //add histograms to the previously created vector. Notice that the number created is based
384  //upon number_of_histograms_ which is constructed in the
385  for(core::Size x=1; x<= number_of_histograms_; ++x){
386  histogram_vector.push_back(histogram);
387  }
388 
389  //Let the magic begin!
390  for(core::Size res_num1 = 1; res_num1 <= pdb.n_residue(); ++res_num1){
391  core::conformation::Residue resid1 = pdb.residue(res_num1);
392 
393  core::Real low_D = 11;
395  std::string orbital_type("");
396  core::Real angle=2;
397  core::Size atom_index_min_dist(0);
398  core::Size res2seqpos(0);
399  std::string res2name;
400  core::Real angle2=2;
401 
402  //std::cout << "inside the resid1.has_sc_orbitals()!" << std::endl;
403  for(core::Size res_num2 = 1; res_num2 <= pdb.n_residue(); ++res_num2){
404  core::conformation::Residue resid2 = pdb.residue(res_num2);
405  if(resid1.seqpos() != resid2.seqpos()){
406  if(resid1.nbr_atom_xyz().distance(resid2.nbr_atom_xyz()) <= 10.0)
407  {
409  //iterate through atoms with orbitals
410  for ( core::chemical::AtomIndices::const_iterator
411  atom_index = resid1.atoms_with_orb_index().begin(),
412  atom_end = resid1.atoms_with_orb_index().end();
413  atom_index != atom_end; ++atom_index
414  ){
415  if(resid1.atom_is_backbone(*atom_index)){
416 
417  utility::vector1<core::Size> const & orbital_indices(resid1.bonded_orbitals(*atom_index));
418  //iterate through the orbitals
419  for(
421  orbital_index = orbital_indices.begin(),
422  orbital_end = orbital_indices.end();
423  orbital_index != orbital_end; ++orbital_index
424  ){
425 
426  numeric::xyzVector<core::Real> orb_xyz = resid1.orbital_xyz(*orbital_index);
427  numeric::xyzVector<core::Real> bonded_atom_xyz(resid1.atom(*atom_index).xyz());
428  if(
429  basic::options::option[basic::options::OptionKeys::orbitals::Hpol]
430  ){
431 
432  //iterate only throught the sidechain polar hydrogens
433  for(
434  core::chemical::AtomIndices::const_iterator
435  hpol_index = resid2.Hpol_index().begin(),
436  hpol_end = resid2.Hpol_index().end(); hpol_index != hpol_end; ++hpol_index
437  )
438  {
439  res2_H_xyz = resid2.atom( *hpol_index ).xyz();
440  core::Real container = orb_xyz.distance( res2_H_xyz );
441  numeric::xyzVector<core::Real> DHO_atom_xyz(resid2.atom(resid2.bonded_neighbor(*hpol_index)[1]).xyz() );
442  if(container <= low_D){
443  angle = cos_of(bonded_atom_xyz, orb_xyz, res2_H_xyz );
444  angle2 = cos_of(DHO_atom_xyz, res2_H_xyz, orb_xyz);
445  low_D = container;
446  orbital_type = resid1.orbital_type(*orbital_index).name();
447  res2name= resid2.name3();
448  res2seqpos=resid2.seqpos();
449  atom_index_min_dist=*hpol_index;
450  }
451  }
452  }
453  //haro
454  if(basic::options::option[basic::options::OptionKeys::orbitals::Haro]){
455  for(core::chemical::AtomIndices::const_iterator
456  haro_index = resid2.Haro_index().begin(),
457  haro_end = resid2.Haro_index().end(); haro_index != haro_end; ++haro_index)
458  {
459  res2_H_xyz = resid2.atom( *haro_index ).xyz();
460  core::Real container = orb_xyz.distance( res2_H_xyz );
461  numeric::xyzVector<core::Real> DHO_atom_xyz(resid2.atom(resid2.bonded_neighbor(*haro_index)[1]).xyz() );
462  if(container <= low_D){
463  angle = cos_of(bonded_atom_xyz, orb_xyz, res2_H_xyz );
464  angle2 = cos_of(DHO_atom_xyz, res2_H_xyz, orb_xyz);
465  orbital_type = resid1.orbital_type(*orbital_index).name();
466  low_D = container;
467  res2name= resid2.name3();
468  res2seqpos=resid2.seqpos();
469  atom_index_min_dist=*haro_index;
470  }
471  }
472  }
473  }
474  }
475  }
476  }
477  }
478  }// end for resid2
479 
480  if(low_D <= 10){
481  core::conformation::Residue res2 = pdb.residue(res2seqpos);
482  //std::cout << low_D << " angle: " << angle << std::endl;
483  //decompose_score(resid1, resid2, pdb, low_D, angle, electron_name);
484  if(orbital_type=="O.p.sp3" && res2.atom_is_backbone(res2.bonded_neighbor(atom_index_min_dist)[1])){
485  statistics_output_.open("O.p.sp3.backbone", std::ios_base::app);
486  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
487  statistics_output_.close();
488  }else if(orbital_type=="S.p.sp3" && res2.atom_is_backbone(res2.bonded_neighbor(atom_index_min_dist)[1])) {
489  statistics_output_.open("S.p.sp3.backbone", std::ios_base::app);
490  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
491  statistics_output_.close();
492  }else if(orbital_type=="C.pi.sp2" && res2.atom_is_backbone(res2.bonded_neighbor(atom_index_min_dist)[1])) {
493  statistics_output_.open("C.pi.sp2.backbone", std::ios_base::app);
494  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
495  statistics_output_.close();
496  }
497  else if(orbital_type=="N.pi.sp2" && res2.atom_is_backbone(res2.bonded_neighbor(atom_index_min_dist)[1])) {
498  statistics_output_.open("N.pi.sp2.backbone", std::ios_base::app);
499  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
500  statistics_output_.close();
501  }else if(orbital_type=="N.p.sp2" && res2.atom_is_backbone(res2.bonded_neighbor(atom_index_min_dist)[1])) {
502  statistics_output_.open("N.p.sp2.backbone", std::ios_base::app);
503  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
504  statistics_output_.close();
505  }else if(orbital_type=="O.pi.sp2" && res2.atom_is_backbone(res2.bonded_neighbor(atom_index_min_dist)[1])) {
506  statistics_output_.open("O.pi.sp2.backbone", std::ios_base::app);
507  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
508  statistics_output_.close();
509  }else if(orbital_type=="O.p.sp2" && res2.atom_is_backbone(res2.bonded_neighbor(atom_index_min_dist)[1])) {
510  statistics_output_.open("O.p.sp2.backbone", std::ios_base::app);
511  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
512  statistics_output_.close();
513  }else {
514  statistics_output_.open(orbital_type.c_str(), std::ios_base::app);
515  statistics_output_ << resid1.name3() << resid1.seqpos() << " " << res2name << res2seqpos << " "<< low_D << " " << angle << " " << angle2 << " " << pdb.pdb_info()->name() << std::endl;
516  statistics_output_.close();
517  }
518  }
519  }
520  histogram_vector_=histogram_vector;
521 }
522 
523 
524 }
525 }
526 }