21 #include <basic/database/open.hh>
27 #include <basic/Tracer.hh>
30 #include <ObjexxFCL/ubyte.hh>
31 #include <ObjexxFCL/FArray2D.hh>
32 #include <ObjexxFCL/Fmath.hh>
33 #include <ObjexxFCL/format.hh>
36 #include <numeric/constants.hh>
37 #include <numeric/trig.functions.hh>
40 #include <utility/io/izstream.hh>
49 #include <utility/vector1.hh>
57 static basic::Tracer
TR(
"core.scoring.sasa");
60 using namespace ObjexxFCL::fmt;
71 0,1,1,2,1,2,2,3, 1,2,2,3,2,3,3,4, 1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5,
72 1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6,
73 1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6,
74 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7,
75 1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6,
76 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7,
77 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7,
78 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7, 4,5,5,6,5,6,6,7, 5,6,6,7,6,7,7,8,
111 static bool init =
false;
117 utility::io::izstream masks_stream( basic::database::full_name(
"sampling/SASA-masks.dat" ) );
125 for (
int jj = 1; jj <=
num_bytes; ++jj ) {
129 masks(jj,ii) =
static_cast< unsigned char >( tmp );
131 masks_stream >> skip;
133 masks_stream.close();
137 utility::io::izstream angles_stream( basic::database::full_name(
"sampling/SASA-angles.dat" ) );
139 for (
int ii = 1; ii <=
num_phi; ++ii ) {
140 for (
int jj = 1; jj <=
num_theta; ++jj ) {
141 angles_stream >>
angles( ii, jj );
143 angles_stream >> skip;
145 angles_stream.close();
177 if ( distance_ijxyz < epsilon ) {
180 if ( radius_a < radius_b ) {
181 degree_of_overlap = 100;
183 degree_of_overlap = 1;
186 }
else if ( radius_b + distance_ijxyz <= radius_a ) {
188 degree_of_overlap = 1;
190 }
else if ( radius_a + distance_ijxyz <= radius_b ) {
192 degree_of_overlap = 100;
197 Real cosine_theta_iq = ( ( radius_a*radius_a ) + ( distance_ijxyz*distance_ijxyz ) - ( radius_b*radius_b ) ) / ( 2 * radius_a * distance_ijxyz );
204 degree_of_overlap =
static_cast< int >( (1.0f - cosine_theta_iq) * 50 ) + 1;
206 if ( degree_of_overlap > 100 ) {
207 degree_of_overlap = 100;
209 }
else if ( degree_of_overlap < 0 ) {
212 std::cout <<
"Problem in calculating overlap between atoms. Terminating calculation.\n";
213 std::cout <<
"radius_a: " << SS( radius_a ) <<
", radius_b: " << SS( radius_b )
214 <<
", distance_ijxyz: " << SS( distance_ijxyz ) <<
", cosine theta: " << SS( cosine_theta_iq ) << std::endl;
215 utility::exit( EXIT_FAILURE, __FILE__, __LINE__);
265 using namespace numeric::constants::d;
266 using numeric::sin_cos_range;
270 Vector ab_diff( ( a_xyz - b_xyz ) / distance_ijxyz );
278 Real phi = std::acos( sin_cos_range( ab_diff(3) ) );
296 phi_index =
static_cast< int >(
phi );
309 Real theta = std::atan2( ab_diff(2), ab_diff(1) );
311 Real temp_theta = theta;
316 Real precasted_theta = theta;
318 theta_index =
static_cast< int >( theta );
320 if ( theta_index < 1 ) {
356 using namespace numeric::constants::d;
357 using numeric::sin_cos_range;
361 Vector ab_diff( ( a_xyz - b_xyz ) / distance_ijxyz );
369 Real phi_a2b = std::acos( sin_cos_range( ab_diff(3) ) );
371 Real temp_phi_a2b = phi_a2b;
383 phi_a2b = phi_a2b * (
num_phi / pi_2 );
385 Real precasted_phi_a2b = phi_a2b;
387 phi_a2b_index =
static_cast< int >( phi_a2b );
395 Real temp_phi_b2a = phi_b2a;
397 phi_b2a_index =
static_cast< int >( phi_b2a );
411 Real theta_a2b = std::atan2( ab_diff(2), ab_diff(1) );
413 Real temp_theta_a2b = theta_a2b;
416 theta_a2b = theta_a2b * (
num_theta / pi_2 );
418 Real precasted_theta_a2b = theta_a2b;
420 theta_a2b_index =
static_cast< int >( theta_a2b );
422 if ( theta_a2b_index < 1 ) {
424 }
else if ( theta_a2b_index >
num_theta ) {
433 Real temp_theta_b2a = theta_b2a;
436 theta_b2a_index =
static_cast< int >( theta_b2a );
438 if ( theta_b2a_index < 1 ) {
440 }
else if ( theta_b2a_index >
num_theta ) {
473 Real const probe_radius,
bool const use_big_polar_H ) {
479 return calc_per_atom_sasa( pose, atom_sasa, rsd_sasa, probe_radius, use_big_polar_H, atom_subset );
488 Real const probe_radius,
489 bool const use_big_polar_H,
491 bool const use_naccess_sasa_radii ,
492 bool const expand_polar_radii ,
493 Real const polar_expansion_radius ,
494 bool const include_probe_radius_in_atom_radii,
495 bool const use_lj_radii
508 Real const big_polar_H_radius( 1.08 );
516 if ( use_naccess_sasa_radii ) {
524 for (
core::Size ii=1; ii <= radii.size(); ++ii ) {
527 if ( use_lj_radii ) {
528 radii[ii] = atom_type_set[ii].lj_radius();
534 radii[ii] = atom_type_set[ii].extra_parameter( SASA_RADIUS_INDEX );
536 if ( use_big_polar_H && at.
is_polar_hydrogen() && big_polar_H_radius > radii[ii] ) {
537 std::cout <<
"Using " << big_polar_H_radius <<
" instead of " << radii[ii] <<
" for atomtype " << at.
name() <<
" in sasa calculation!\n";
538 radii[ii] = big_polar_H_radius;
541 if ( expand_polar_radii && ( at.
element() ==
"N" || at.
element() ==
"O" ) ) {
543 std::cout <<
"Using " << radii[ii] + polar_expansion_radius <<
" instead of " << radii[ii] <<
" for atomtype " << at.
name() <<
" in sasa calculation!\n";
545 radii[ii] = radii[ii] + polar_expansion_radius;
563 for (
Size jj=1; jj <= rsd.natoms(); ++jj ) {
564 max_radius = std::max( max_radius, radii[ rsd.atom(jj).type() ] );
567 runtime_assert( std::abs( atom_masks[ AtomID(jj,ii) ][1] + atom_masks[ AtomID(jj,ii) ][
num_bytes] ) < 1e-3 );
572 cutoff_distance = 2 * ( max_radius + probe_radius );
586 probe_radius, cutoff_distance, radii,
594 Real total_sasa( 0.0 );
602 Real const four_pi = 4.0f *
Real( numeric::constants::d::pi );
607 rsd_sasa[ ii ] = 0.0;
610 TR <<
"sasa dots: res: " << rsd.name3() << pose.
pdb_info()->number(ii) << std::endl;
612 for (
Size iia = 1; iia <= rsd.natoms(); ++iia ) {
614 AtomID
const id( iia, ii );
615 if ( ! atom_subset[
id ] )
618 Real iia_rad = radii[ rsd.atom(iia).type() ];
619 if ( include_probe_radius_in_atom_radii ) iia_rad += probe_radius;
628 for (
int bb = 1; bb <=
num_bytes; ++bb ) {
634 Real const total_sa = four_pi * ( iia_rad * iia_rad );
635 Real const area_exposed = ( 1.0f - fraction_ones ) * total_sa;
638 std::cout <<
"atom: " << rsd.atom_name( iia ) <<
", rad: " << ObjexxFCL::fmt::F(4,2,radii[ rsd.atom(iia).type() ])
639 <<
", covered: " << ObjexxFCL::fmt::I(3,ctr) <<
", counts: ";
640 print_dot_bit_string( atom_masks[
id ] );
642 atom_sasa[ id ] = area_exposed;
644 if ( ! rsd.atom_type(iia).is_h2o() ) {
645 rsd_sasa[ ii ] += area_exposed;
646 total_sasa += area_exposed;
651 std::cout <<
"num_ones: " << num_ones <<
", sasa: " << rsd_sasa[ ii ] << std::endl;
678 Real const probe_radius,
679 Real const cutoff_distance,
699 for (
Size iia=1; iia <= irsd.
natoms(); ++iia ) {
703 AtomID
const iia_atomid( iia, ii );
704 if ( ! atom_subset[ iia_atomid ] )
708 Atom const & iia_atom( irsd.
atom( iia ) );
709 Vector const & iia_atom_xyz = iia_atom.xyz();
710 Real const iia_atom_radius = radii[ iia_atom.type() ] + probe_radius;
712 for (
Size jja = 1; jja <= jrsd.
natoms(); ++jja ) {
715 AtomID
const jji_atomid( jja, jj );
716 if ( ! atom_subset[ jji_atomid ] )
719 Atom const & jja_atom( jrsd.
atom( jja ) );
720 Vector const & jja_atom_xyz = jja_atom.xyz();
721 Real const jja_atom_radius = radii[ jja_atom.type() ] + probe_radius;
723 Real const distance_ijxyz( iia_atom_xyz.distance( jja_atom_xyz ) );
724 if ( distance_ijxyz <= iia_atom_radius + jja_atom_radius ) {
726 if ( distance_ijxyz <= 0.0 )
731 int degree_of_overlap, aphi, theta, point, masknum;
734 get_overlap( iia_atom_radius, jja_atom_radius, distance_ijxyz, degree_of_overlap );
741 get_orientation( iia_atom_xyz, jja_atom_xyz, aphi, theta, distance_ijxyz );
742 point =
angles( aphi, theta );
743 masknum = point * 100 + degree_of_overlap;
758 for (
int bb = 1, m =
masks.index( bb, masknum ); bb <=
num_bytes; ++bb, ++m ) {
759 iia_bit_values[ bb ] = ObjexxFCL::bit::bit_or( iia_bit_values[ bb ],
masks[ m ] );
784 get_overlap( jja_atom_radius, iia_atom_radius, distance_ijxyz, degree_of_overlap );
791 get_orientation( jja_atom_xyz, iia_atom_xyz, aphi, theta, distance_ijxyz );
792 point =
angles( aphi, theta );
793 masknum = point * 100 + degree_of_overlap;
805 for (
int bb = 1, m =
masks.index(bb,masknum); bb <=
num_bytes; ++bb, ++m ) {
806 jja_bit_values[ bb ] = ObjexxFCL::bit::bit_or( jja_bit_values[ bb ],
masks[ m ] );
881 bool use_naccess_sasa_radii ) {
908 atom_subset[ ii ][ jj ] =
true;
915 TR.Debug <<
"total_sasa: " << total_sasa << std::endl;
922 rsd_hydrophobic_sasa.clear();
938 res_hsasa += atom_sasa[ atid ];
942 rsd_hydrophobic_sasa[ ii ] = res_hsasa;
943 total_hydrophobic_sasa += res_hsasa;
949 TR <<
"residue " << rsd.
name3() << ii <<
" atom_sasas: [ ";
954 TR <<
"], total hydrophobic SASA: " << rsd_hydrophobic_sasa[ ii ] << std::endl;
958 return total_hydrophobic_sasa;
969 for (
int bb = 1; bb <=
num_bytes; ++bb ) {
972 if ( (bb-1)*8 % 16 == 0 ) std::cout << (bb-1) * 8 <<
":";
974 for (
int index=7; index >= 0; index-- ) {
975 bit = ( ( (
int)values[ bb ] >> index ) & 1 );
985 std::cout << std::endl;