Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LeeRichards.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 /// @file core/scoring/packstat/LeeRichards.cc
11 ///
12 /// @brief
13 /// @author will sheffler
14 
15 
16 // Unit header or inline function header
18 #include <core/pose/Pose.hh>
19 
21 // AUTO-REMOVED #include <core/scoring/packstat/compute_sasa.hh>
23 #include <utility/exit.hh>
24 
25 // AUTO-REMOVED #include <numeric/xyz.io.hh>
26 
27 // AUTO-REMOVED #include <time.h>
28 
30 #include <core/pose/util.hh>
31 #include <utility/vector1.hh>
32 #include <ObjexxFCL/Fmath.hh>
33 
34 //Auto Headers
35 #include <core/pose/util.tmpl.hh>
36 //Auto using namespaces
37 namespace ObjexxFCL { } using namespace ObjexxFCL; // AUTO USING NS
38 //Auto using namespaces end
39 
40 
41 namespace core {
42 namespace scoring {
43 namespace packstat {
44 
45 using core::Real;
46 using utility::vector1;
47 using core::id::AtomID;
48 
49 core::Size const N_PROBES = 20;
50 
51 LeeRichards::LeeRichards(
52  PosePackDataOP pd,
53  AccumulatorOP accum,
54  core::Real spacing,
55  core::Real probe_radius,
56  bool csa,
58 ) {
59  compute( pd->spheres, accum, spacing, probe_radius, csa, plane );
60 }
61 
62 LeeRichards::LeeRichards(
63  core::pose::Pose & pose,
64  AccumulatorOP accum,
65  core::Real spacing,
66  core::Real probe_radius,
67  bool csa,
69 ) {
70  Spheres spheres;
71  for( int ir = 1; ir <= (int)pose.total_residue(); ++ir ) {
72  for( int ia = 1; ia <= (int)pose.residue(ir).nheavyatoms(); ++ia ) {
73  core::id::AtomID aid(ia,ir);
74  spheres.push_back(
75  Sphere( pose.xyz(aid), pose.residue(ir).atom_type(ia).lj_radius(), aid )
76  );
77  }
78  }
79  compute( spheres, accum, spacing, probe_radius, csa, plane );
80 }
81 
82 void
83 LeeRichards::compute(
84  Spheres & spheres,
85  AccumulatorOP accum,
86  core::Real spacing,
87  core::Real probe_radius,
88  bool csa,
90 ) {
91 
92  // time_t t = clock();
93 
94  // Spheres & spheres(pd->spheres);
95 
96  // get coord system for slices
97  plane.normalize();
98  numeric::xyzVector<Real> xunit(1,0,0),yunit;
99  if( xunit == plane ) xunit.y(1); // make sure isn't lin. dep.
100  xunit -= plane * xunit.dot(plane);
101  xunit.normalize();
102  yunit = plane.cross(xunit);
103  assert( abs( 0.0 - xunit.dot(yunit) ) < 1e-9 );
104  assert( abs( 0.0 - xunit.dot(plane) ) < 1e-9 );
105  assert( abs( 0.0 - plane.dot(yunit) ) < 1e-9 );
106  assert( abs( 1.0 - xunit.length() ) < 1e-9 );
107  assert( abs( 1.0 - yunit.length() ) < 1e-9 );
108  assert( abs( 1.0 - plane.length() ) < 1e-9 );
109  // std::cerr << xunit << std::endl;
110  // std::cerr << yunit << std::endl;
111  // std::cerr << plane << std::endl;
112  // std::exit(-1);
113 
114  // compute slice coords
115  Real mx=-9e9,mn=9e9;
116  for( SphereIter i = spheres.begin(); i != spheres.end(); ++i ) {
117  Real const d = plane.dot(i->xyz);
118  if( d - i->radius - probe_radius < mn ) mn = d - i->radius-probe_radius;
119  if( d + i->radius + probe_radius > mx ) mx = d + i->radius+probe_radius;
120  }
121  int Nslice = int( (mx-mn) / spacing );
122  Real st = mn + ((mx-mn)-Nslice*spacing)/2.0;
123  for( core::Real r = st; r <= mx; r += spacing ){
124  slice_coords_.push_back(r);
125  }
126 
127  // create Slices
128  // std::cerr << "LeeRichards " << mn << " " << mx << " " << spacing << " " << st << std::endl;
129  for( RealCIter i = slice_coords_.begin(); i != slice_coords_.end(); ++i ) {
130  // std::cerr << "slice at: " << *i << std::endl;
131  bool internal_allowed = true;//*i-4.0 > mn && *i+4 < mx; // not worth trouble
132  slices_.push_back( new Slice(accum,spacing,internal_allowed) );
133  }
134 
135  int count = 0;
136  for( Size i = 1; i <= spheres.size(); ++i ) {
137  Sphere & s(spheres[i]);
138  if( s.aid.rsd() == 0 ) s.aid.rsd() = i;
139  Real const crd = plane.dot(s.xyz), x = xunit.dot(s.xyz), y = yunit.dot(s.xyz);
140  Real const rad = s.radius + probe_radius;
141  Size first = find_first_slice(crd-rad);
142  if( 0 == first ) continue;
143  Real const stop = crd+rad;
144  // std::cerr << "sph " << crd << " " << rad << " " << stop << std::endl;
145  while( first <= slice_coords_.size() && slice_coords_[first] < stop ) {
146  // std::cerr << slice_coords_[first] << " ";
147  Real d = crd - slice_coords_[first];
148  if( fabs(d) >= rad ) continue;
149  Real r = sqrt(rad*rad - d*d);
150  Real drdz = d/r;
151  Real dada = spacing*rad;
152  if( csa ) {
153  drdz = d / r * (s.radius/(s.radius+probe_radius)); // for CSA not SASA
154  dada = spacing*s.radius * (s.radius/(s.radius+probe_radius)); // for CSA not SASA
155  }
156  // std::cerr << "circ param dsdl " << dada << " "
157  // << fmin( 1.0,-d/rad+spacing/2.0) << " "
158  // << fmax(-1.0,-d/rad-spacing/2.0) << std::endl;
159  slices_[first]->add_circle( new Circle(x,y,r,drdz,dada,s.aid) );
160  ++count;
161  ++first;
162  }
163  // std::cerr << " " << std::endl;
164  }
165  // std::cerr << "added " << count << " circles in " << slices_.size() << " slices" << std::endl;
166 
167  // for( CircleIter i = slices_[58]->circles_.begin(); i != slices_[58]->circles_.end(); ++i ) {
168  // Circle *c(*i);
169  // std::cerr << " circles.append( cpp.Circle( 200+20*" << c->x << " , 200+20*" << c->y << " , 20*" << c->r << ") )" << std::endl;
170  // }
171 
172  for( Size i = 1; i <= slices_.size(); ++i ) {
173  // Real prev = dynamic_cast<AreaAccumulator*>(accum())->total_area;
174  // std::cerr << "slice " << i << " " << slices_[i]->circles_.size() << std::endl;
175  slices_[i]->compute();
176  // std::cerr << "computing area for slice " << i << " " << slice_coords_[i] << " " << dynamic_cast<AreaAccumulator*>(accum())->total_area - prev << std::endl;
177 
178  }
179 
180  // std::cerr << "slices " << slices_.size() << " area " << dynamic_cast<AreaAccumulator*>(accum())->total_area << " " << clock()-t << std::endl;
181 
182 }
183 
184 MultiProbePoseAccumulator::MultiProbePoseAccumulator(
185  core::pose::Pose & _pose,
186  std::string tag
187 ) : pr_idx_(1), pose_(_pose), tag_(tag)
188 {
190 }
191 
192 void
193 MultiProbePoseAccumulator::show( std::ostream & out ) {
194  Reals tot(N_PROBES,0.0),btot(N_PROBES,0.0);
195  for( Size ir = 1; ir <= pose_.total_residue(); ++ir ) {
196  out << "RES_DAT " << pose_.residue(ir).name3() << " " << tag_ << " " << ir << " ";
197  for( Size ia = 1; ia <= pose_.residue(ir).nheavyatoms(); ++ia ) {
198  core::id::AtomID aid(ia,ir);
199  LR_MP_AtomData & dat(atom_map_[aid]);
200  // out << pose_.residue(ir).atom_type_index(ia) << " ";
201  for( Size i = 1; i <= N_PROBES; ++i ) {
202  out << dat.area[i] << " " << dat.barea[i] << " ";
203  tot[i] += dat.area[i];
204  btot[i] += dat.barea[i];
205  }
206  }
207  out << std::endl;
208  }
209  out << "TOT_DAT " << tag_ << " " << pose_.total_residue() << " ";
210  for( Size i = 1; i <= N_PROBES; ++i ) {
211  out << tot[i] << " " << btot[i] << " ";
212  }
213  out << std::endl;
214 }
215 
216 
217 struct HTL_EventX { bool operator()( Event const *a, Event const *b ) {
218  if( a->x==b->x ) return a->y > b->y;
219  else return a->x > b->x;
220 } };
221 
222 // struct OrderArc { bool operator()( Arc const *a, Arc const *b ) {
223 // if( a->circle == b->circle ) {
224 // return fmin(a->start_angle,a->end_angle) < fmin(b->start_angle,b->end_angle);
225 // } else {
226 // return a->circle < b->circle;
227 // }
228 // } };
229 
230 
231 PointPair
233  Circle *other
234 ) {
235  Real r0 = r;
236  Real r1 = other->r;
237  Real x0 = x;
238  Real y0 = y;
239  Real x1 = other->x;
240  Real y1 = other->y;
241  Real d = sqrt((x0-x1)*(x0-x1) + (y0-y1)*(y0-y1));
242  // if( d == 0.0 ) {
243  // return; // don't error anymode
244  // std::cerr << "overlap(_a,other), _a/other same point" << std::endl;
245  // std::exit(-1);
246  // }
247  if( d >= r0+r1 || d <= fabs(r0-r1) ) return PointPair(0.0,0.0,0.0,0.0);
248  Real _a = (r0*r0 - r1*r1 + d*d ) / (2*d);
249  if( r0*r0 < _a*_a ) {
250  std::cerr << "r0*r0 < _a*_a: \n" << x << " " << y << " " << r << " \n" << other->x << " " << other->y << " " << other->r << " " << d << std::endl;
251  std::cerr << "abs(r0-r1) " << fabs(r0-r1) << std::endl;
252  utility_exit_with_message( "Circle::overlap error" );
253  }
254  Real h = sqrt(r0*r0 - _a*_a);
255  Real x2 = x0 + _a * ( x1 - x0 ) / d;
256  Real y2 = y0 + _a * ( y1 - y0 ) / d;
257  Real x3 = x2 + h * ( y1 - y0 ) / d;
258  Real y3 = y2 - h * ( x1 - x0 ) / d;
259  Real x4 = x2 - h * ( y1 - y0 ) / d;
260  Real y4 = y2 + h * ( x1 - x0 ) / d;
261  // # if x3 > x4: x3,y3,x4,y4 = x4,y4,x3,y3
262  return PointPair(x3,y3,x4,y4);
263 }
264 
265 std::ostream &
266 operator<< ( std::ostream & out, Circle & circle ) {
267  out << "Circle( " << circle.x << " " << circle.y << " " << circle.r << " )";
268  return out;
269 }
270 
272  for( EventIter i = events_.begin(); i != events_.end(); ++i ) delete *i;
273  for( CircleIter i = circles_.begin(); i != circles_.end(); ++i ) delete *i;
274  for( traceIter i = traces_.begin(); i != traces_.end(); ++i ) delete *i;
275 }
276 
277 
278 void
280 {
281 
282  Octree2D nbr(circles_);
283 
284  for( CircleIter ia = circles_.begin(); ia != circles_.end(); ia++ ) {
285  Circle *circle(*ia);
286 
287  if( !nbr.contains(circle->x+circle->r,circle->y,2,circle) ) {
288  events_.push_back( new Event( circle->x + circle->r, circle->y, ENTER, circle, NULL ) );
289  }
290  if( !nbr.contains(circle->x-circle->r,circle->y,2,circle) ) {
291  events_.push_back( new Event( circle->x - circle->r, circle->y, EXIT , circle, NULL ) );
292  }
293 
294  int I = nbr.get_i(circle->x);
295  int J = nbr.get_j(circle->y);
296  for( int i = std::max(I-2,0); i <= std::min(I+2,(int)nbr.Xdim_); ++i ) {
297  for( int j = std::max(J-2,0); j <= std::min(J+2,(int)nbr.Ydim_); ++j ) {
298  for( CircleIter ja = nbr.cubes(i,j).begin(); ja != nbr.cubes(i,j).end(); ja++ ) {
299  Circle *circle2(*ja);
300  if( circle <= circle2 ) continue;
301  if( ! circle->does_overlap(circle2) ) continue;
302 
303  PointPair pp = circle->overlap(circle2);
304  if( 0.0==pp.a.x && 0.0==pp.a.y && 0.0==pp.b.x && 0.0==pp.b.y ) continue;
305 
306  if( !nbr.contains(pp.a.x,pp.a.y,1,circle,circle2) ) {
307  events_.push_back( new Event(pp.a.x,pp.a.y,ISECT,circle,circle2) );
308  }
309  if( !nbr.contains(pp.b.x,pp.b.y,1,circle,circle2) ) {
310  events_.push_back( new Event(pp.b.x,pp.b.y,ISECT,circle2,circle) );
311  }
312 
313  }
314  }
315  }
316  }
317  std::sort( events_.begin(), events_.end(), HTL_EventX() );
318  // std::cerr << "DONE " << events_.size() << std::endl;
319 
320  return;
321 }
322 
323 
324 
325 void
327 {
328  for( EventIter ie = events_.begin(); ie != events_.end(); ++ie ) {
329  Event *e = *ie;
330  // std::cerr << "EVENT " << e << " " << e->x << " " << e->y << " " << e->kind << std::endl;
331  Circle *circle = e->circle;
332  if ( circle->tcw ) e->trace_ = circle->tcw;
333  else if( circle->tccw ) e->trace_ = circle->tccw;
334  if( e->kind == ENTER ) {
335  traces_.push_back( new trace( accum_, e, false, circle, 0.0, NULL ) );
336  traces_.push_back( new trace( accum_, e, true , circle, 0.0, traces_.back() ) );
337  } else if( e->kind == EXIT ) {
338  circle->tcw ->end( circle->tccw );
339  circle->tccw->end( circle->tcw );
340  } else if( e->kind == ISECT ) {
341  Circle *ccwcircle = e->ccw;
342  if ( ccwcircle->tcw ) e->trace_ = ccwcircle->tcw;
343  else if( ccwcircle->tccw ) e->trace_ = ccwcircle->tccw;
344  bool have_cw_trace = ( circle->tcw != NULL && e->y > circle->y );
345  bool have_ccw_trace = ( ccwcircle->tccw != NULL && e->y < ccwcircle->y );
346  if( have_cw_trace && have_ccw_trace ) {
347  circle ->tcw ->end( ccwcircle->tccw, e->cw_angle );
348  ccwcircle->tccw->end( circle->tcw , e->ccw_angle );
349  } else if( !have_cw_trace && !have_ccw_trace ) {
350  traces_.push_back( new trace( accum_, e, true , circle, e->cw_angle , NULL ) );
351  traces_.push_back( new trace( accum_, e, false, e->ccw, e->ccw_angle, traces_.back() ) );
352  } else if( have_cw_trace ) {
353  circle->tcw->next_circle(ccwcircle,e->cw_angle,e->ccw_angle);
354  } else if( have_ccw_trace ) {
355  ccwcircle->tccw->next_circle(circle,e->ccw_angle,e->cw_angle);
356  } else {
357  utility_exit_with_message( "Slice::compute_surface()" );
358  }
359  }
360  }
361 
362  for( traceIter i = traces_.begin(); i != traces_.end(); ++i ) {
363  trace *t(*i);
364  if( t->next_trace_ ) {
365  t->start_ = t->next_trace_->get_first(t);
366  t->next_trace_->set_first(t,t->start_); // sets next_trace_ to NULL for all
367  }
368  bool is_internal = ( t->start_->kind == ISECT ) && internal_allowed_;
369  // for debugging
370  // if( is_internal ) {
371  // for( CircleIter ic = circles_.begin(); ic != circles_.end(); ++ic ) {
372  // Circle *c(*ic);
373  // std::cerr << " circles.append( cpp.Circle( " << c->x << "," << c->y << "," << c->r << "));" << std::endl;
374  // }
375  // std::exit(-1);
376  // }
377  for( ArcIter ia = t->arcs_.begin(); ia != t->arcs_.end(); ++ia ) {
378  accum_->accumulate_area(ia->first,ia->second,is_internal);
379  }
380  }
381 
382  // std::sort( arcs_.begin(), arcs_.end(), OrderArc() ); // TODO: take out for speed
383 }
384 
385 void
387 {
388  // std::cerr << "compute_derivatives" << std::endl;
389  for( EventIter ie = events_.begin(); ie != events_.end(); ++ie ) {
390  Event *e(*ie);
391  if( e->kind != ISECT ) continue;
392  bool is_internal = ( e->trace_->start_->kind == ISECT ) && internal_allowed_;
393  Real mg = 1.0 / sin( ( e->cw_angle - e->ccw_angle + numeric::constants::d::pi ) / 2.0 );
394  mg = min(mg,100.0);
395  mg = mg * (( e->circle->dada / e->circle->r ) + ( e->ccw->dada / e->ccw->r ))/2.0;
396  // Real mg1 = mg * ( e->circle->dada / e->circle->r );
397  // Real mg2 = mg * ( e->ccw->dada / e->ccw->r );
398  // std::cerr << "mg1/mg2 " << mg1 << " " << mg2 << std::endl;
399  // assert( fabs(mg) < 100.0 );
400  Real dir = (e->cw_angle + e->ccw_angle) / 2.0 + numeric::constants::d::pi/2.0;
401  accum_->accumulate_dxdy( e->circle->atom, mg*cos(dir), -mg*sin(dir), is_internal );
402  accum_->accumulate_dxdy( e->ccw ->atom, -mg*cos(dir), mg*sin(dir), is_internal );
403  //dz// accum_->accumulate_dz ( e->circle->atom, mg1*cos(dir-e->cw_angle ) * e->circle->drdz );
404  //dz// accum_->accumulate_dz ( e->ccw ->atom, -mg2*cos(dir-e->ccw_angle) * e->ccw ->drdz );
405  // e->circle->dx += mg * cos/*360*/(dir);
406  // e-> ccw->dx -= mg * cos/*360*/(dir);
407  // e->circle->dy += mg * -sin/*360*/(dir);
408  // e-> ccw->dy -= mg * -sin/*360*/(dir);
409  // e->circle->dr += mg * cos/*360*/(dir - e->cw_angle);
410  // e-> ccw->dr -= mg * cos/*360*/(dir - e->ccw_angle);
411  }
412  // for( ArcIter ia = arcs_.begin(); ia != arcs_.end(); ++ia ) {
413  // Arc *a(*ia);
414  // a->circle->dr += fabs(a->start_angle-a->end_angle);///180.0*3.14159265;
415  // }
416 
417 }
418 
419 
422 {
423  using namespace utility;
424  using namespace numeric;
425 
426  size_t Nprobes = 31;
427  size_t Nshells = 7;
428  PackingScoreResDataOP psrdOP( new PackingScoreResData(Nshells,Nprobes) );
429  for( size_t is = 1; is <= pd_->spheres.size(); ++is ) {
430  Sphere const & sphere( pd_->spheres[is] );
431  //if( sphere.xyz.x() > xyz.x() + dist_th ) break;
432  PackstatReal dist = xyz.distance( sphere.xyz );
433  for( size_t id = 1; id <= Nshells; ++id ) {
434  if( dist <= (PackstatReal)id ) {
435  for( size_t pr = 1; pr <= Nprobes; ++pr ) {
436  psrdOP->msa(id,pr) += atom_map_[AtomID(1,is)].area[pr];
437  }
438  break;
439  }
440  }
441  }
442 
443  PackingScoreResDataOP rtn( new PackingScoreResData(Nshells,Nprobes-1) );
444  for( size_t id = 1; id <= Nshells; ++id ) {
445  for( size_t pr = 2; pr <= Nprobes; ++pr ) {
446  rtn->msa(id,pr-1) = psrdOP->msa(id,pr) - psrdOP->msa(id,1); // stupid reverse indicies...
447  }
448  }
449 
450  return rtn;
451 
452 }
453 
454 
455 Real
457  Real & buried_area_out,
458  PosePackDataOP pd,
459  Real slicesize,
460  Real pr,
461  bool csa,
463 ) {
464  if( plane.length() > 0 ) {
466  AccumulatorOP accumOP(accum);
467  LeeRichards lr( pd, accumOP, slicesize, pr, csa, plane );
468  buried_area_out = accum->buried_area;
469  return accum->total_area;
470  } else {
471  Real area = 0.0;
472  {
474  AccumulatorOP accumOP(accum);
475  LeeRichards lr( pd, accumOP, slicesize, pr, csa, XYZ(1,0,0) );
476  buried_area_out += accum->buried_area;
477  area += accum->total_area / 3.0;
478  }
479  {
481  AccumulatorOP accumOP(accum);
482  LeeRichards lr( pd, accumOP, slicesize, pr, csa, XYZ(0,1,0) );
483  buried_area_out += accum->buried_area;
484  area += accum->total_area / 3.0;
485  }
486  {
488  AccumulatorOP accumOP(accum);
489  LeeRichards lr( pd, accumOP, slicesize, pr, csa, XYZ(0,0,1) );
490  buried_area_out += accum->buried_area;
491  area += accum->total_area / 3.0;
492  }
493  return area;
494  }
495 }
496 
497 Real
499  PosePackDataOP pd,
500  Real slicesize,
501  Real pr,
502  bool csa,
504 ) {
505  Real dummy = 0.0;
506  return compute_surface_area_leerichards(dummy,pd,slicesize,pr,csa,plane);
507 }
508 
509 XYZs
511  PosePackDataOP pd,
512  Real slicesize,
513  Real pr,
514  bool csa//,
515  // numeric::xyzVector<Real> plane
516 ) {
517  XYZs rtn(pd->spheres.size(),XYZ(0.0,0.0,0.0));
518  {
519  PerSphereAccumulatorOP accum = new PerSphereAccumulator(pd->spheres);
520  AccumulatorOP accumOP(accum);
521  LeeRichards lr( pd, accumOP, slicesize, pr, csa, XYZ(1,0,0) );
522  for( Size i = 1; i <= pd->spheres.size(); ++i ) {
523  rtn[i].y() += accum->atom_map_[AtomID(1,i)].dx / 2.0;
524  rtn[i].z() += accum->atom_map_[AtomID(1,i)].dy / 2.0;
525  }
526  }
527  {
528  PerSphereAccumulatorOP accum = new PerSphereAccumulator(pd->spheres);
529  AccumulatorOP accumOP(accum);
530  LeeRichards lr( pd, accumOP, slicesize, pr, csa, XYZ(0,1,0) );
531  for( Size i = 1; i <= pd->spheres.size(); ++i ) {
532  rtn[i].x() += accum->atom_map_[AtomID(1,i)].dx / 2.0;
533  rtn[i].z() -= accum->atom_map_[AtomID(1,i)].dy / 2.0;
534  }
535  }
536  {
537  PerSphereAccumulatorOP accum = new PerSphereAccumulator(pd->spheres);
538  AccumulatorOP accumOP(accum);
539  LeeRichards lr( pd, accumOP, slicesize, pr, csa, XYZ(0,0,1) );
540  for( Size i = 1; i <= pd->spheres.size(); ++i ) {
541  rtn[i].x() += accum->atom_map_[AtomID(1,i)].dx / 2.0;
542  rtn[i].y() += accum->atom_map_[AtomID(1,i)].dy / 2.0;
543  }
544  }
545  return rtn;
546 }
547 
548 XYZs
550  PosePackDataOP pd,
551  Real slicesize,
552  Real pr,
553  bool csa,
554  Size max_num
555  // numeric::xyzVector<Real> plane
556 ) {
557 
558  Real D = 0.000001;
559 
560  Real new_area1, new_area2;
561  Real orig_area_x = compute_surface_area_leerichards(pd,slicesize,pr,csa,XYZ(1,0,0));
562  Real orig_area_y = compute_surface_area_leerichards(pd,slicesize,pr,csa,XYZ(0,1,0));
563  Real orig_area_z = compute_surface_area_leerichards(pd,slicesize,pr,csa,XYZ(0,0,1));
564 
565  Size N = min((Size)max_num,pd->spheres.size());
566  XYZs rtn(N);
567 
568  for( Size i = 1; i <= N; ++i ) {
569  std::cerr << "check_surface_area_leerichards_deriv " << i << std::endl;
570 
571  pd->spheres[i].xyz.x() += D;
572  new_area1 = compute_surface_area_leerichards(pd,slicesize,pr,csa,XYZ(0,1,0));
573  new_area2 = compute_surface_area_leerichards(pd,slicesize,pr,csa,XYZ(0,0,1));
574  rtn[i].x( ((new_area1+new_area2)/2.0-(orig_area_y+orig_area_z)/2.0) / D );
575  pd->spheres[i].xyz.x() -= D;
576 
577  pd->spheres[i].xyz.y() += D;
578  new_area1 = compute_surface_area_leerichards(pd,slicesize,pr,csa,XYZ(1,0,0));
579  new_area2 = compute_surface_area_leerichards(pd,slicesize,pr,csa,XYZ(0,0,1));
580  rtn[i].y( ((new_area1+new_area2)/2.0-(orig_area_x+orig_area_z)/2.0) / D );
581  pd->spheres[i].xyz.y() -= D;
582 
583  pd->spheres[i].xyz.z() += D;
584  new_area1 = compute_surface_area_leerichards(pd,slicesize,pr,csa,XYZ(1,0,0));
585  new_area2 = compute_surface_area_leerichards(pd,slicesize,pr,csa,XYZ(0,1,0));
586  rtn[i].z( ((new_area1+new_area2)/2.0-(orig_area_x+orig_area_y)/2.0) / D );
587  pd->spheres[i].xyz.z() -= D;
588 
589  }
590  return rtn;
591 }
592 
593 
594 Real
596  PosePackDataOP pd,
597  Real slicesize,
599 ) {
601  AccumulatorOP accumOP = accum;
602  for( Size pri = 1; pri <= 31; pri++ ) {
603  Real pr = Real(31-pri)/10.0;
604  // std::cerr << "pr: " << pr << " ";
605  accum->set_pr_idx(pri);
606  LeeRichards lr( pd, accumOP, slicesize, pr, true, plane );
607  }
609  for( Size i = 1; i <= pd->centers.size(); ++i ) {
610  PackingScoreResDataOP psrd = accum->compute_surrounding_sasa(pd->centers[i]);
611  // std::cerr << "LeeRichardsRAW " << i << " " << pd->labels[i] << " " << *psrd << std::endl;
612  psrds.push_back(psrd);
613  }
614  PackingScore ps_discrim(7,30,true);
615  init_packing_score_discrim( ps_discrim );
616  return ps_discrim.score( psrds );
617 
618  // accum->show(std::cerr);
619 }
620 
621 
622 
623 
624 } // namespace packstat
625 } // namespace scoring
626 } // namespace core