Esempio n. 1
0
double get_close_pairs_range(const ::npctransport_proto::Assignment& config) {
  double max_range= config.interaction_range().value();
  UPDATE_MAX(range, config.nonspecific_range);
  double max_range_factor= 1;
  for ( int i=0; i< config.fgs_size(); ++i) {
    UPDATE_MAX(range_factor, config.fgs(i).interaction_range_factor);
  }
  for ( int i=0; i< config.floaters_size(); ++i) {
    UPDATE_MAX(range_factor, config.floaters(i).interaction_range_factor);
  }
  for ( int i=0; i< config.interactions_size(); ++i) {
    if (config.interactions(i).has_interaction_range()) {
      UPDATE_MAX(range, config.interactions(i).interaction_range);
    }
  }
  return get_close_pairs_range(max_range, max_range_factor);
}
double get_time_step(const ::npctransport_proto::Assignment& a,
                     double max_trans_relative_to_radius)
{
  // NOTE: this is not a tight bound - a tight bound would involve
  // computing time step for each interactions (factored by relevant
  // constants and accounting for particle radii and interaction range
  // / k). So this is a conservative time step choice in that respect.
  double time_step_factor = a.time_step_factor().value();
  double max_d_factor = 1.0;
  double min_radius = std::numeric_limits<double>::max(); // in A
  double min_range = std::numeric_limits<double>::max(); // in A
  double max_k = 0.0; // in kcal/mol/A

  UPDATE_MAX(k, a.backbone_k);  // TODO: is this valid for harmonic k?
  if(a.nonspecific_range().value()>0.0 &&
     a.nonspecific_k().value()>0.0) {
    UPDATE_MAX(k, a.nonspecific_k);
    UPDATE_MIN(range, a.nonspecific_range);
  }
  UPDATE_MAX(k, a.excluded_volume_k);
  for (int i = 0; i < a.fgs_size(); ++i) {
    UPDATE_MAX(d_factor, a.fgs(i).d_factor);
    UPDATE_MIN(radius, a.fgs(i).radius);
  }
  for (int i = 0; i < a.floaters_size(); ++i) {
    UPDATE_MAX(d_factor, a.floaters(i).d_factor);
    UPDATE_MIN(radius, a.floaters(i).radius);
  }
  double base_k = a.interaction_k().value();
  double base_range = a.interaction_range().value();

  // go over all interaction and compute their maximal k (in kcal/mol/A)
  // and minimum range (in A)
  for (int i = 0; i < a.interactions_size(); ++i) {
    double k=base_k;
    double range=base_range;
    if (a.interactions(i).has_interaction_k()) {
      k=a.interactions(i).interaction_k().value();
    }
    if (a.interactions(i).has_interaction_range()) {
      range=a.interactions(i).interaction_range().value();
    }
    // factor k and range + retrieve particles radii
    std::string type0=a.interactions(i).type0();
    std::string type1=a.interactions(i).type1();
    double R0(-1.0);
    double R1(-1.0);
    bool is_found0= false;
    bool is_found1= false;
    for(int ii=0; ii<a.floaters_size(); ii++){
      if(a.floaters(ii).type()==type0){
        if(a.floaters(ii).interactions().value()==0){
          range=0.0; // skip
          continue;
        }
        k*=a.floaters(ii).interaction_k_factor().value();
        range*=a.floaters(ii).interaction_range_factor().value();
        R0=a.floaters(ii).radius().value();
        is_found0= true;
      }
      if(a.floaters(ii).type()==type1){
        if(a.floaters(ii).interactions().value()==0){
          range=0.0; // skip
          continue;
        }
        k*=a.floaters(ii).interaction_k_factor().value();
        range*=a.floaters(ii).interaction_range_factor().value();
        R1=a.floaters(ii).radius().value();
        is_found1= true;
      }
    }
    for(int ii=0; ii<a.fgs_size(); ii++){
      if(is_fg_type_match(type0, a.fgs(ii))){
        if(a.fgs(ii).interactions().value()==0){
          range=0.0; // skip
          continue;
        }
        k*=a.fgs(ii).interaction_k_factor().value();
        range*=a.fgs(ii).interaction_range_factor().value();
        R0=a.fgs(ii).radius().value();
        is_found0= true;
      }
      if(is_fg_type_match(type1, a.fgs(ii))){
        if(a.fgs(ii).interactions().value()==0){
          range=0.0; // skip
          continue;
        }
        k*=a.fgs(ii).interaction_k_factor().value();
        range*=a.fgs(ii).interaction_range_factor().value();
        R1=a.fgs(ii).radius().value();
        is_found1= true;
      }
    }
    if(!is_found0 || !is_found1){
      IMP_LOG(TERSE, "get_time_step() - ignoring interaction "
                << type0 << "-" << type1
                << " since no particles of one these types are defined"
                << std::endl);
      continue;
    }
    // compute skewed range if needed
    bool is_orientational=false;
    if(a.interactions(i).has_range_sigma0_deg() &&
       a.interactions(i).has_range_sigma1_deg()) {
      if(a.interactions(i).range_sigma0_deg().value()!=0.0 &&
         a.interactions(i).range_sigma1_deg().value()!=0.0) {
        is_orientational=true;
      }
    }
    if(is_orientational && range > 0.0 && is_found0 && is_found1){
      IMP_USAGE_CHECK(R0>0.0 && R1>0.0,
                      "R0 or R1 could not be found for type " << type0
                      << " or type " << type1 << std::endl);
      k*=0.5*range; // the maximal force for this interction
      const double pi = 3.1415926535897;
      double range_sigma0_rad=a.interactions(i).range_sigma0_deg().value()*pi/180.0;
      double range_sigma1_rad=a.interactions(i).range_sigma1_deg().value()*pi/180.0;
      double chord0=2*R0*std::sin(range_sigma0_rad/2.0);
      double chord1=2*R1*std::sin(range_sigma1_rad/2.0);
      double min_chord=std::min(chord0,chord1);
      range=std::min(range, min_chord);
    } // if is_orientation
    if(range>0.0 && k>0.0) {
      max_k=std::max(max_k, k);
      min_range=std::min(min_range, range);
    }
  } // for interactions(i)

  IMP_LOG(VERBOSE, "get_time_step(): "
            << " max_d_factor " << max_d_factor
            << " max-k " << max_k
            << " min-range " << min_range
            << " max-trans-relative-to-R " << max_trans_relative_to_radius
            << " time-step-factor " << time_step_factor
            << std::endl);
  double dT_fs= get_time_step(max_d_factor, max_k, min_radius, min_range,
                              max_trans_relative_to_radius, time_step_factor);
  IMP_LOG(VERBOSE, "dT = " << dT_fs << " [fs]" << std::endl);
  return dT_fs;

}