10 #ifndef IMPNPCTRANSPORT_SLAB_WITH_TOROIDAL_PORE_PAIR_SCORE_H 
   11 #define IMPNPCTRANSPORT_SLAB_WITH_TOROIDAL_PORE_PAIR_SCORE_H 
   13 #include "npctransport_config.h" 
   22 IMPNPCTRANSPORT_BEGIN_NAMESPACE
 
   32   mutable double bottom_; 
 
   37   mutable bool is_pore_radius_optimized_;
 
   69      unsigned int lower_bound,
 
   70      unsigned int upper_bound,
 
   71      bool all_indexes_checked=
false) 
const override final;
 
   87       unsigned int lower_bound,
 
   88       unsigned int upper_bound,
 
   89       bool all_indexes_checked=
false) 
const override 
   93     for (
unsigned int i = lower_bound; i < upper_bound; ++i) {
 
   95       if (ret > max) 
return std::numeric_limits<double>::max();
 
  122     get_sphere_ellipsoid_penetration_depth
 
  137   inline double get_sphere_penetration_depth
 
  143   void update_cached_slab_params
 
  148 SlabWithToroidalPorePairScore::update_cached_slab_params
 
  154   bottom_= -0.5*thickness;
 
  157   rh_= slab.get_horizontal_minor_radius();
 
  158   rv_= slab.get_vertical_minor_radius();
 
  159   is_pore_radius_optimized_= slab.get_pore_radius_is_optimized();
 
  165 SlabWithToroidalPorePairScore::evaluate_index
 
  172   update_cached_slab_params(slab);
 
  178   double score=get_sphere_penetration_depth(d.
get_sphere(),
 
  179                                da ? &displacement : 
nullptr);
 
  185     if(is_pore_radius_optimized_){
 
  186       double radial_displacement= displacement[0]*d_sphere[0]+displacement[1]*d_sphere[1]; 
 
  196 SlabWithToroidalPorePairScore::evaluate_indexes
 
  200      unsigned int lower_bound,
 
  201      unsigned int upper_bound, 
bool) 
const 
  203   IMP_LOG_TERSE(
"SlabWithToroidalPore singleton - evaluate indexes" 
  205   if(upper_bound<lower_bound){
 
  209     double radial_displacements(0.0); 
 
  211     m->access_spheres_data();
 
  213     m->access_sphere_derivatives_data();
 
  214   IMP::internal::BoolAttributeTableTraits::Container 
const&
 
  215     is_optimizable_table= m->access_optimizeds_data
 
  216     (core::XYZ::get_coordinate_key(0)); 
 
  219   update_cached_slab_params(slab);
 
  222   for (
unsigned int i = lower_bound; i < upper_bound; ++i) {
 
  224     int pi_index=pi.get_index();
 
  228                            "All particles are assumed to be evaluated against" 
  233                            "optimable table inconsistent with d.get_coordinates_are_optimized for particle " << d);
 
  235                            "Different coords for particle " << d << 
" *** " 
  238                            "Different radii for particle " << d << 
" *** " 
  239                            << d.get_radius() << 
" vs. " << s.get_radius());
 
  241     if(!is_optimizable_table[pi]) {
 
  245     double cur_score = get_sphere_penetration_depth(spheres_table[pi_index],
 
  246                                         da ? &displacement : 
nullptr);
 
  247     IMP_LOG_TERSE(
"SlabWithToroidalPore singleton score for sphere / displacement " 
  248             << spheres_table[pi_index] << 
" is " << cur_score << 
" / " 
  249             << displacement << std::endl);
 
  251     if(cur_score>0.0 && da) {
 
  254       for(
unsigned int j=0; j<3; j++) {
 
  255         sphere_derivatives_table[pi_index][j] += (*da)(derivative_vector[j]);
 
  258       radial_displacements+= displacement[0]*s[0] + displacement[1]*s[1]; 
 
  262   if(da && is_pore_radius_optimized_){
 
  271 SlabWithToroidalPorePairScore::
 
  272 get_sphere_ellipsoid_penetration_depth
 
  277   const double eps= 1e-9;
 
  279   double dXY2= v[0]*v[0]+v[1]*v[1];
 
  280   double dZ2= v[2]*v[2];
 
  281   double dv2= dXY2 + dZ2 + eps;
 
  283   double sinTheta2= dXY2/dv2;
 
  284   double cosTheta2= dZ2/dv2;
 
  285   double cur_r= std::sqrt(rv_*rv_*cosTheta2 + rh_*rh_*sinTheta2);
 
  286   double dv=std::sqrt(dv2);
 
  287   double surface_distance= dv - sphere.get_radius() - cur_r;
 
  288   if(surface_distance>=0 ){
 
  296     (*out_translation)= v.get_unit_vector();
 
  298   return -surface_distance; 
 
  306 SlabWithToroidalPorePairScore::get_sphere_penetration_depth
 
  310   double const x=sphere[0];
 
  311   double const y=sphere[1];
 
  312   double const z=sphere[2];
 
  313   double const sr=sphere.get_radius();
 
  314   double sphere_dz_top= (z - sr) - top_;
 
  315   double sphere_dz_bottom = (z + sr) - bottom_;
 
  316   bool is_above_top=sphere_dz_top>0;
 
  317   bool is_below_bottom=sphere_dz_bottom<0;
 
  318   if(is_above_top || is_below_bottom) {
 
  325   double d_xy2 = x*x + y*y; 
 
  326   bool is_closer_to_top= (sphere_dz_bottom > -sphere_dz_top);
 
  327   double abs_sphere_dz =
 
  328     is_closer_to_top ? -sphere_dz_top : sphere_dz_bottom; 
 
  334     return abs_sphere_dz;
 
  336   double d_xy = std::sqrt(d_xy2);
 
  338   const double eps = 1e-9;
 
  341     double scale= R_/d_xy;
 
  343     ret= get_sphere_ellipsoid_penetration_depth
 
  344       (sphere, origin, out_translation );
 
  347     ret= get_sphere_ellipsoid_penetration_depth
 
  348       (sphere, origin, out_translation );
 
  355 IMPNPCTRANSPORT_END_NAMESPACE
 
void add_to_derivatives(const algebra::Vector3D &v, DerivativeAccumulator &d)
Add the vector v to the derivative vector of the x,y,z coordinates. 
 
void add_to_pore_radius_derivative(double v, DerivativeAccumulator &d)
 
Abstract class for scoring object(s) of type ParticleIndexPair. 
 
SphereD< 3 > Sphere3D
Typedef for Python. 
 
Macros for various classes. 
 
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object. 
 
#define IMP_OBJECT_LOG
Set the log level to the object's log level. 
 
Storage of a model, its restraints, constraints and particles. 
 
bool get_coordinates_are_optimized() const 
Get whether the coordinates are optimized. 
 
A more IMP-like version of the std::vector. 
 
#define IMP_LOG_TERSE(expr)
 
#define IMP_INTERNAL_CHECK(expr, message)
An assertion to check for internal errors in IMP. An IMP::ErrorException will be thrown. 
 
Class for storing model, its restraints, constraints, and particles. 
 
const algebra::Sphere3D & get_sphere() const 
Return a sphere object. 
 
virtual double evaluate_if_good_indexes(Model *m, const ParticleIndexPairs &o, DerivativeAccumulator *da, double max, unsigned int lower_bound, unsigned int upper_bound, bool all_indexes_checked=false) const 
 
Float get_pore_radius() const 
get cylindrical pore radius 
 
#define IMP_UNUSED(variable)
 
virtual ModelObjectsTemp do_get_inputs(Model *m, const ParticleIndexes &pis) const =0
Overload this method to specify the inputs. 
 
Score for a slab with a toroidal pore. 
 
const algebra::Vector3D & get_coordinates() const 
Convert it to a vector. 
 
#define IMP_CHECK_CODE(expr)
Only compile the code if checks are enabled. 
 
A nullptr-initialized pointer to an IMP Object. 
 
Float get_thickness() const 
returns whether the particle last entered the transport moiety from its 
 
virtual double evaluate_indexes(Model *m, const ParticleIndexPairs &o, DerivativeAccumulator *da, unsigned int lower_bound, unsigned int upper_bound, bool all_indexes_checked=false) const 
Compute the score and the derivative if needed over a set. 
 
Helper macros for throwing and handling exceptions. 
 
A decorator for a particle that's a slab with a toroidal pore. 
 
virtual double evaluate_if_good_index(Model *m, const ParticleIndexPair &vt, DerivativeAccumulator *da, double max) const 
Compute the score and the derivative if needed, only if "good". 
 
Decorator for a sphere-like particle. 
 
virtual double evaluate_index(Model *m, const ParticleIndexPair &vt, DerivativeAccumulator *da) const =0
Compute the score and the derivative if needed. 
 
Class for adding derivatives from restraints to the model. 
 
A decorator for a particle with x,y,z coordinates and a radius.