Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DynamicAggregateFunction.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 protocols/pack_daemon/DynamicAggregateFunction.cc
11 /// @brief
12 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com)
13 
14 #ifdef USEMPI
15 // MPI Headers
16 #include <mpi.h>
17 #endif
18 
19 // Unit headers
21 
22 // Project headers
23 #include <core/types.hh>
24 // AUTO-REMOVED #include <core/pack/task/PackerTask.hh>
25 #include <core/pose/Pose.hh>
27 // AUTO-REMOVED #include <core/io/pdb/pose_io.hh>
28 #include <basic/Tracer.hh>
29 #include <numeric/expression_parser/Arithmetic.hh>
31 // AUTO-REMOVED #include <protocols/multistate_design/SingleState.hh> // REQUIRED FOR WINDOWS (APL NOTE: why?)
32 
33 // Utility headers
34 #include <utility/exit.hh>
35 #include <utility/string_util.hh>
36 #include <utility/vector1.functions.hh>
37 #include <utility/mpi_util.hh>
38 #include <utility/excn/Exceptions.hh>
39 // AUTO-REMOVED #include <utility/io/izstream.hh>
40 
41 // C++ headers
42 // AUTO-REMOVED #include <cmath>
43 // AUTO-REMOVED #include <cctype>
44 
47 #include <utility/vector0.hh>
48 #include <utility/vector1.hh>
49 
50 
51 namespace protocols {
52 namespace pack_daemon {
53 
54 static basic::Tracer TR( "protocols.pack_daemon.DynamicAggregateFunction" );
55 
56 using namespace numeric::expression_parser;
57 
58 ///// class VectorExpression : public Expression
59 
60 VectorExpression::VectorExpression( std::string const & name ) : parent(), name_( name ) {}
62 
65 {
66  utility_exit_with_message( "Illegal call to operator() on VectorExpression named " + name() );
67  return 0.0;
68 }
69 
70 ExpressionCOP
72 {
73  utility_exit_with_message( "Illegal call to differentiate() on VectorExpression named " + name() );
74  return 0;
75 }
76 
77 std::string const &
79 {
80  return name_;
81 }
82 
83 /////// class VariableVectorExpression
84 
86  std::string const & name,
87  VariableExpressions const & vars
88 ) :
89  parent( name ),
90  vars_( vars )
91 {}
92 
94 
97  values vals( vars_.size() );
98  for ( Size ii = 1; ii <= vars_.size(); ++ii ) {
99  vals[ ii ] = (*vars_[ ii ])();
100  }
101  return vals;
102 }
103 
106  return vars_.size();
107 }
108 
109 /// @brief DO NOT call this funcion.
110 std::list< std::string >
112 {
113  utility_exit_with_message( "VariableVectorExpression::active_variables should not be called" );
114  return std::list< std::string >();
115 }
116 
119 {
120  utility::vector1< std::list< std::string > > active_vars_vector( size() );
121  for ( Size ii = 1; ii <= vars_.size(); ++ii ) {
122  active_vars_vector[ ii ] = vars_[ ii ]->active_variables();
123  //for ( std::list< std::string >::const_iterator
124  // iter = active_vars_vector[ ii ].begin(), iter_end = active_vars_vector[ ii ].end();
125  // iter != iter_end; ++iter ) {
126  // TR << "DEBUG: active_variables_vector() " << ii << " includes " << *iter << std::endl;
127  //}
128  }
129  return active_vars_vector;
130 }
131 
132 ///////// class VectorFunction
135 
137 
138 
140  vec_ex1_( ex1 ),
141  vec_ex2_( ex2 )
142 {}
143 
145 
148 
149 
150 
152 
154 
156  std::map< std::string, VectorExpressionCOP > const & vector_varnames,
157  ArithmeticASTExpression const & expresion_ast,
158  VectorExpressionCreator & expression_creator // holds a reference to my owning DynamicAggregateFunction
159 )
160 {
161  Size s = vector_varnames.size();
162  input_vector_expressions_.resize( s );
163  local_variables_.resize( s );
164  Size count = 0;
165  for ( std::map< std::string, VectorExpressionCOP >::const_iterator
166  iter = vector_varnames.begin(), iter_end = vector_varnames.end();
167  iter != iter_end; ++iter ) {
168  ++count;
169  VariableExpressionOP varex = new VariableExpression( iter->first, 0.0 );
170  input_vector_expressions_[ count ] = iter->second;
171  local_variables_[ count ] = varex;
172  local_variable_map_[ iter->first ] = varex;
173  }
174  for ( Size ii = 2; ii <= s; ++ii ) {
175  if ( input_vector_expressions_[ ii ]->size() != input_vector_expressions_[ ii - 1 ]->size() ) {
176  utility_exit_with_message( "IterativeVectorExpression " + name() + " initialized with vector-expressions of uneven sizes: "
177  + input_vector_expressions_[ ii ]->name() + " with size of " + utility::to_string( input_vector_expressions_[ ii ]->size()) + ", and "
178  + input_vector_expressions_[ ii-1 ]->name() + " with size of " + utility::to_string( input_vector_expressions_[ ii ]->size()) );
179  }
180  }
181 
182  /// This call will construct an expression tree from the ExpressionAST. Control of flow
183  /// will actually return to this object when the expression_creator encounters local variables.
184  /// The expression_creator will hand control of flow to its owning DynamicAggregateFunction,
185  /// and the DAF will hand control of flow to this object. A pre-condition of this
186  /// function call is that the DAF which is initializing this object must point to it with its
187  /// focused_iterative_vector_expression_ member variable.
188 
189  expression_ = expression_creator.create_expression_tree( expresion_ast );
190 
191 }
192 
195 {
196  Size s = size();
197  if ( s == 0 ) { values empty; return empty; }
198 
199  utility::vector1< values > vec_of_values( s );
200 
201  for ( Size ii = 1; ii <= s; ++ii ) {
202  vec_of_values[ ii ] = input_vector_expressions_[ ii ]->vector_values();
203  if ( ii != 1 ) {
204  if ( vec_of_values[ ii ].size() != vec_of_values[ ii - 1 ].size() ) {
205  utility_exit_with_message( "IterativeVectorExpression " + name() + " recieved vectors of uneven sizes from its children: "
206  + input_vector_expressions_[ ii ]->name() + " with " + utility::to_string( vec_of_values[ ii ].size()) + " values, and "
207  + input_vector_expressions_[ ii-1 ]->name() + " with " + utility::to_string( vec_of_values[ ii-1 ].size()) + " values." );
208  }
209  }
210  }
211  values return_vals( vec_of_values[ 1 ].size(), 0.0 );
212  for ( Size ii = 1; ii <= return_vals.size(); ++ii ) {
213  for ( Size jj = 1; jj <= s; ++jj ) {
214  local_variables_[ jj ]->set_value( vec_of_values[ jj ][ ii ] );
215  }
216  return_vals[ ii ] = (*expression_)();
217  }
218  return return_vals;
219 }
220 
223 {
224  if ( input_vector_expressions_.size() == 0 ) {
225  return 0;
226  }
227  return input_vector_expressions_[ 1 ]->size();
228 }
229 
230 /// @details returns 0 if there is no local variable with name varname.
231 /// Do not throw an error if there is no such local variable -- the
232 /// initializing DAF will check its set of variable names after this object has
233 /// looked through its set of local variables.
234 VariableExpressionCOP
236 {
237  std::map< std::string, VariableExpressionCOP >::const_iterator varit = local_variable_map_.find( varname );
238  if ( varit != local_variable_map_.end() ) {
239  return varit->second;
240  }
241  return 0;
242 }
243 
244 std::list< std::string >
246 {
247  utility_exit_with_message( "IterativeVectorExpression::active_variables should not be called" );
248  return std::list< std::string >();
249 }
250 
253 {
254  utility::vector1< std::list< std::string > > active_varibles_vector( size() );
255  //for ( Size ii = 1; ii <= vars_.size(); ++ii ) {
256  // active_varibles_vector[ ii ] = vars_->active_variables();
257  //}
258  utility_exit_with_message( "IterativeVectorExpression::active_variables_vector has not yet been implemented. Email Andrew");
259  return active_varibles_vector;
260 }
261 
262 
263 /////// class VMax : public VectorFunction
264 
267 
270 {
271  VectorExpression::values vals = vec_ex()->vector_values();
272  return utility::max( vals );
273 }
274 
275 ExpressionCOP
277 {
278  utility_exit_with_message( "VMax cannot be differentiated" );
279  return 0;
280 }
281 
282 std::list< std::string >
284 {
285  utility::vector1< std::list< std::string > > act_vars_vect = vec_ex()->active_variables_vector();
286  VectorExpression::values vals = vec_ex()->vector_values();
287  Size index = utility::arg_max( vals );
288  return act_vars_vect[ index ];
289 }
290 
291 /////// class VMin : public VectorFunction
292 
294 
296 
299 {
300  VectorExpression::values vals = vec_ex()->vector_values();
301  return utility::min( vals );
302 }
303 
304 ExpressionCOP
306 {
307  utility_exit_with_message( "VMin cannot be differentiated" );
308  return 0;
309 }
310 
311 std::list< std::string >
313 {
314  utility::vector1< std::list< std::string > > act_vars_vect = vec_ex()->active_variables_vector();
315  VectorExpression::values vals = vec_ex()->vector_values();
316  Size index = utility::arg_min( vals );
317  //for ( std::list< std::string >::const_iterator iter = act_vars_vect[ index ].begin(),
318  // iter_end = act_vars_vect[ index ].end(); iter != iter_end; ++iter ) {
319  // TR << "DEBUG Vmin active variables for index " << index << " " << *iter << std::endl;
320  //}
321  //TR << "DEBUG Vmin end active variables" << std::endl;
322  return act_vars_vect[ index ];
323 }
324 
325 
328 {}
329 
332 {
333  VectorExpression::values vals1 = vec_ex1()->vector_values();
334  VectorExpression::values vals2 = vec_ex2()->vector_values();
335  assert( vals2.size() == vals1.size() );
336 
337  Size index = utility::arg_max( vals1 );
338  return vals2[ index ];
339 }
340 
341 ExpressionCOP
343 {
344  utility_exit_with_message( "VMaxBy cannot be differentiated" );
345  return 0;
346 }
347 
348 std::list< std::string >
350 {
351  VectorExpression::values vals1 = vec_ex1()->vector_values();
352  utility::vector1< std::list< std::string > > act_vars_vect2 = vec_ex2()->active_variables_vector();
353  assert( vals1.size() == act_vars_vect2.size() );
354 
355  Size index = utility::arg_max( vals1 );
356  return act_vars_vect2[ index ];
357 
358 }
359 
361 
363 
366 {
367  VectorExpression::values vals1 = vec_ex1()->vector_values();
368  VectorExpression::values vals2 = vec_ex2()->vector_values();
369  assert( vals1.size() == vals2.size() );
370 
371  Size index = utility::arg_min( vals1 );
372  return vals2[ index ];
373 }
374 
375 ExpressionCOP
377 {
378  utility_exit_with_message( "VMinBy cannot be differentiated" );
379  return 0;
380 }
381 
382 std::list< std::string >
384 {
385  VectorExpression::values vals1 = vec_ex1()->vector_values();
386  utility::vector1< std::list< std::string > > act_vars_vect2 = vec_ex2()->active_variables_vector();
387  assert( vals1.size() == act_vars_vect2.size() );
388 
389  Size index = utility::arg_min( vals1 );
390  return act_vars_vect2[ index ];
391 
392 }
393 
394 /////// class PowExpression : public BinaryExpression
395 
396 PowExpression::PowExpression( ExpressionCOP base, ExpressionCOP exponent ) : parent( base, exponent ) {}
398 
401 {
402  return std::pow( (*e1())(), (*e2())() );
403 }
404 
405 ExpressionCOP
407 {
408  utility_exit_with_message( "PowExpression::diffrentiate is unimplemented!" );
409  return 0;
410 }
411 
412 /////// class ExpExpression : public UnaryExpression
413 
416 
419 {
420  return std::exp( (*ex())() );
421 }
422 
423 ExpressionCOP
425 {
426  utility_exit_with_message( "ExpExpression::diffrentiate is unimplemented!" );
427  return 0;
428 }
429 
430 
431 /////// class LnExpression : public UnaryExpression
432 
435 
438 {
439  return std::log( (*ex())() );
440 }
441 
442 ExpressionCOP
444 {
445  utility_exit_with_message( "LnExpression::diffrentiate is unimplemented!" );
446  return 0;
447 }
448 
449 
452 
454 {
455  value_set_ = values;
456 }
457 
460 {
461  core::Real val = (*ex())();
462  for ( Size ii = 1; ii <= value_set_.size(); ++ii ) {
463  if ( val == value_set_[ ii ] ) {
464  return 1.0;
465  }
466  }
467  return 0.0;
468 }
469 
470 ExpressionCOP
472 {
473  utility_exit_with_message( "InSetExpression::diffrentiate is unimplemented!" );
474  return 0;
475 }
476 
477 
478 /////// class VectorExpressionCreator : public ExpressionCreator
479 
482 
484 VectorExpressionCreator::handle_variable_expression( ArithmeticASTValue const & node )
485 {
486  return owner_.variable_expression( node );
487 }
488 
491  FunctionTokenCOP function,
493 )
494 {
495  ExpressionCOP parent_expression = parent::handle_function_expression( function, args );
496  if ( parent_expression ) {
497  return parent_expression; // handles sqrt only
498  }
499  return owner_.function_expression( function, args );
500 }
501 
502 
503 ///////
504 
506  std::string const & name
507 ) :
508  parent( name ),
509  root_expression_( 0 )
510 {}
511 
513  std::string const & name,
514  core::Real value
515 ) :
516  parent( name, value ),
517  root_expression_( 0 )
518 {}
519 
520 /// @details If you don't want to consider any of the variables
521 /// to be active in a SurrogateVariableExpression, then do not
522 /// set the root_expression_ for the SurrogateVariableExpression.
523 /// This allows non-expressions (e.g. the EntityFuncs) to still
524 /// contribute to the FITNESS without having to correspond to a
525 /// particular state.
526 std::list< std::string >
528 {
529  if ( root_expression_ ) {
530  return root_expression_->active_variables();
531  } else {
532  std::list< std::string > empty_list;
533  return empty_list;
534  }
535 }
536 
537 void
539 {
540  root_expression_ = setting;
541 }
542 
543 ExpressionCOP
545 {
546  return root_expression_->differentiate( varname );
547 }
548 
549 ///////
550 
553 
554 void
556  if ( setting == 0 ) {
557  throw utility::excn::EXCN_Msg_Exception( "DynamicAggregateFunction::set_num_entity_elements may not be"
558  "passed a number of entity elements == 0" );
559  }
560  if ( num_entity_elements_ != 0 ) {
561  throw utility::excn::EXCN_Msg_Exception( "DynamicAggregateFunction::set_num_entity_elements may only"
562  "be called once" );
563  }
564 
565  // set this once
566  num_entity_elements_ = setting;
567 }
568 
569 /// @details Required for processing the POSE_ENERGY and POSE_ENERGY_VECTOR commands
570 void
572 {
573  sfxn_ = sfxn.clone();
574 }
575 
576 
579 {
580  return variable_expressions_for_states_.size();
581 }
582 
585 {
587 }
588 
590 DynamicAggregateFunction::evaluate( StateEnergies const & state_energies, StateEnergies const & npd_properties, Entity const & entity )
591 {
592  /// Assign all variables, evaluate scalar_expressions and vector expressions, then evaluate the final fitness expression
593  if ( TR.visible( basic::t_debug )) {
594  TR.Debug << "DAF::eval";
595  for ( Size ii = 1; ii <= state_energies.size(); ++ii ) {
596  TR.Debug << " " << state_energies[ ii ];
597  }
598  }
599  assign_state_energies_to_variables_and_subexpressions( state_energies, npd_properties, entity );
600  //TR << "Finished sub expression assignment " << std::endl;
601  //TR << "Fitness expression " << fitness_exp_() << std::endl;
602 
603  core::Real score = (*fitness_exp_)();
604  if ( TR.visible( basic::t_debug )) {
605  TR.Debug << " s: " << score << std::endl;
606  }
607 
608  return score;
609 }
610 
611 /// @details Relies on the Expression "active_variables" method
612 /// to determine which variables are selected and contribute to
613 /// the fitness function
616  StateEnergies const & state_energies,
617  StateEnergies const & npd_properties,
618  Entity const & entity
619 )
620 {
621  /// return them all for now.
622  //StateIndices indices( variable_expressions_for_states_.size() );
623  //for ( Size ii = 1; ii <= indices.size(); ++ii ) {
624  // indices[ ii ] = ii;
625  //}
626  //return indices;
627  TR << "Recovering relevant states" << std::endl;
628  assign_state_energies_to_variables_and_subexpressions( state_energies, npd_properties, entity, true );
629  std::list< std::string > active_varnames = fitness_exp_->active_variables();
630  StateIndices active_indices; active_indices.reserve( active_varnames.size() );
631  for ( std::list< std::string >::const_iterator
632  iter = active_varnames.begin(), iter_end = active_varnames.end();
633  iter != iter_end; ++iter ) {
635  /// Ignore active variables that are not in the state_varialbe_2_state_index_ map
636  /// These include POSE_ENERGY and POSE_ENERGY_VECTOR variables as well as
637  /// SCALAR_EXPRESSION variables that simply hold constants (e.g. "SCALAR_EXPRESSION five = 2 + 3" )
638  TR << "The variable named '" << *iter << "' contributes to the fitness but does not correspond to a state." << std::endl;
639  continue;
640  }
641  TR << " fitness_exp_ identifies active variable: " << *iter << " " << state_variable_name_2_state_index_.find( *iter )->second << std::endl;
642  active_indices.push_back( state_variable_name_2_state_index_.find( *iter )->second );
643  }
644  std::sort( active_indices.begin(), active_indices.end() );
645  StateIndices::const_iterator end_iter = std::unique( active_indices.begin(), active_indices.end() );
646  StateIndices return_indices; return_indices.reserve( active_indices.size() );
647  StateIndices::const_iterator iter = active_indices.begin();
648  while ( iter != end_iter ) {
649  return_indices.push_back( *iter );
650  ++iter;
651  }
652  for ( core::Size ii = 1; ii <= return_indices.size(); ++ii ) {
653  TR << " FitnessFunction relevant state indices " << return_indices[ ii ] << std::endl;
654  }
655  return return_indices;
656 }
657 
659  DaemonSetOP daemon_set,
660  std::istream & input
661 )
662 {
663  try {
665  } catch ( utility::excn::EXCN_Msg_Exception & e ) {
667  TR << "Initialization from input file failed with exception: " << e.msg() << std::endl;
668  TR << "Remote daemon sets are spinning down" << std::endl;
669  throw e;
670  }
671  initialize_pack_daemons( daemon_set );
672 }
673 
674 /// @details returns a VariableExpressionOP or VectorVariableExpressionOP given a particular
675 /// variable. Throws an exception if a variable is requested that is not a member of
676 /// any of the following maps: named_state_expression_map_, state_vector_variables_, or
677 /// sub_expression_map_.
678 ExpressionCOP
679 DynamicAggregateFunction::variable_expression( ArithmeticASTValue const & var_node ) const
680 {
681  if ( var_node.is_literal() ) {
682  utility_exit_with_message( "Error in DynamicAggregateFunction::variable_expression; non-variable (literal) node recieved" +
683  utility::to_string( var_node.literal_value() ));
684  }
685 
687  ExpressionCOP iterative_vector_expression_local_variable =
688  focused_iterative_vector_expression_->local_variable( var_node.variable_name() );
689  if ( iterative_vector_expression_local_variable ) return iterative_vector_expression_local_variable;
690  }
691 
692  std::map< std::string, ExpressionCOP >::const_iterator named_state_iter =
693  named_state_expression_map_.find( var_node.variable_name() );
694  if ( named_state_iter != named_state_expression_map_.end() ) {
695  return named_state_iter->second;
696  }
697 
698  std::map< std::string, VariableVectorExpressionOP >::const_iterator vector_variable_iter =
699  state_vector_variables_.find( var_node.variable_name() );
700  if ( vector_variable_iter != state_vector_variables_.end() ) {
701  return vector_variable_iter->second;
702  }
703 
704  std::map< std::string, VariableExpressionCOP >::const_iterator scalar_expression_iter =
705  scalar_expression_map_.find( var_node.variable_name() );
706  if ( scalar_expression_iter != scalar_expression_map_.end() ) {
707  return scalar_expression_iter->second;
708  }
709 
710  std::map< std::string, VectorExpressionCOP >::const_iterator vector_expression_iter =
711  vector_expression_map_.find( var_node.variable_name() );
712  if ( vector_expression_iter != vector_expression_map_.end() ) {
713  return vector_expression_iter->second;
714  }
715 
716  std::map< std::string, std::pair< EntityFuncOP, VariableExpressionOP > >::const_iterator
717  entity_funcs_iter = entity_funcs_.find( var_node.variable_name() );
718  if ( entity_funcs_iter != entity_funcs_.end() ) {
719  return entity_funcs_iter->second.second;
720  }
721 
722  throw utility::excn::EXCN_Msg_Exception( "Unexpected variable expression encountered while "
723  "forming an expression from an ExpressionAST (after scanning/parsing completed!): " + var_node.variable_name() );
724 
725  return 0;
726 }
727 
728 /// @details Handles the functions that the ExpressionCreator base class does not.
729 /// Ensures that the functions that are expecting vector arguments are actually given
730 /// vector arguments. This is not guaranteed by the scanning or parsing of the input
731 /// file.
732 ExpressionCOP
734  FunctionTokenCOP function,
736 ) const
737 {
738 
739  std::string const fname = function->name();
740  if ( fname == "vmax" ) {
741  utility::vector1< VectorExpressionCOP > vector_expressions = verify_vector_arguments( fname, args, 1 );
742  return new VMax( vector_expressions[1] );
743  } else if ( fname == "vmin" ) {
744  utility::vector1< VectorExpressionCOP > vector_expressions = verify_vector_arguments( fname, args, 1 );
745  return new VMin( vector_expressions[1] );
746  } else if ( fname == "vmax_by" ) {
747  utility::vector1< VectorExpressionCOP > vector_expressions = verify_vector_arguments( fname, args, 2 );
748  return new VMaxBy( vector_expressions[1], vector_expressions[2] );
749  } else if ( fname == "vmin_by" ) {
750  utility::vector1< VectorExpressionCOP > vector_expressions = verify_vector_arguments( fname, args, 2 );
751  return new VMinBy( vector_expressions[1], vector_expressions[2] );
752  } else if ( fname == "exp" ) {
753  if ( args.size() != 1 ) {
754  throw utility::excn::EXCN_Msg_Exception( "exp expression construction requested with more than one argument: " + utility::to_string( args.size() ) );
755  }
756  return new ExpExpression( args[ 1 ] );
757  } else if ( fname == "ln" ) {
758  if ( args.size() != 1 ) {
759  throw utility::excn::EXCN_Msg_Exception( "ln expression construction requested with more than one argument: " + utility::to_string( args.size() ) );
760  }
761  return new LnExpression( args[ 1 ] );
762  } else if ( fname == "pow" ) {
763  if ( args.size() != 2 ) {
764  throw utility::excn::EXCN_Msg_Exception( "pow expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
765  }
766  return new PowExpression( args[ 1 ], args[ 2 ] );
767  } else if ( fname == "ite" ) {
768  if ( args.size() != 3 ) {
769  throw utility::excn::EXCN_Msg_Exception( "ite expression construction requested with nargs != 3. Nargs= " + utility::to_string( args.size() ) );
770  }
771  return new ITEExpression( args[ 1 ], args[ 2 ], args[ 3 ] );
772  } else if ( fname == "abs" ) {
773  if ( args.size() != 1 ) {
774  throw utility::excn::EXCN_Msg_Exception( "abs expression construction requested with nargs != 1. Nargs= " + utility::to_string( args.size() ) );
775  }
776  return new AbsoluteValueExpression( args[ 1 ] );
777  } else if ( fname == "gt" ) {
778  if ( args.size() != 2 ) {
779  throw utility::excn::EXCN_Msg_Exception( "gt expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
780  }
781  return new GT_Expression( args[ 1 ], args[ 2 ] );
782  } else if ( fname == "lt" ) {
783  if ( args.size() != 2 ) {
784  throw utility::excn::EXCN_Msg_Exception( "lt expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
785  }
786  return new LT_Expression( args[ 1 ], args[ 2 ] );
787  } else if ( fname == "gte" ) {
788  if ( args.size() != 2 ) {
789  throw utility::excn::EXCN_Msg_Exception( "gte expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
790  }
791  return new GTE_Expression( args[ 1 ], args[ 2 ] );
792  } else if ( fname == "lte" ) {
793  if ( args.size() != 2 ) {
794  throw utility::excn::EXCN_Msg_Exception( "lte expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
795  }
796  return new LTE_Expression( args[ 1 ], args[ 2 ] );
797  } else if ( fname == "and" ) {
798  if ( args.size() != 2 ) {
799  throw utility::excn::EXCN_Msg_Exception( "and expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
800  }
801  return new AndExpression( args[ 1 ], args[ 2 ] );
802  } else if ( fname == "or" ) {
803  if ( args.size() != 2 ) {
804  throw utility::excn::EXCN_Msg_Exception( "or expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
805  }
806  return new OrExpression( args[ 1 ], args[ 2 ] );
807  } else if ( fname == "not" ) {
808  if ( args.size() != 1 ) {
809  throw utility::excn::EXCN_Msg_Exception( "not expression construction requested with nargs != 1. Nargs= " + utility::to_string( args.size() ) );
810  }
811  return new NotExpression( args[ 1 ] );
812  }
813  throw utility::excn::EXCN_Msg_Exception( "Unrecognized function requested of DynamicAggregateFunction: " + fname );
814  return 0;
815 }
816 
818  std::string const & fname,
819  std::string const & contents
820 ){
821  file_contents_[ fname ] = contents;
822 }
823 
826 {
827  return variable_expressions_for_states_[ state_index ]->name();
828 }
829 
830 
831 
833 {
834 
836 
837  function_names_.clear();
838  function_names_.insert( "vmax" );
839  function_names_.insert( "vmin" );
840  function_names_.insert( "vmax_by" );
841  function_names_.insert( "vmin_by" );
842  function_names_.insert( "ln" );
843  function_names_.insert( "pow" );
844  function_names_.insert( "exp" );
845  function_names_.insert( "sqrt" );
846  function_names_.insert( "ite" );
847  function_names_.insert( "abs" );
848  function_names_.insert( "gt" );
849  function_names_.insert( "lt" );
850  function_names_.insert( "gte" );
851  function_names_.insert( "lte" );
852  function_names_.insert( "and" );
853  function_names_.insert( "or" );
854  function_names_.insert( "not" );
855 
856  illegal_variable_names_.clear();
857  illegal_variable_names_.insert( "min" );
858  illegal_variable_names_.insert( "max" );
859 
861  std::map< std::string, ArithmeticASTExpressionOP > scalar_expression_asts;
862  std::map< std::string, std::list< std::string > > vector_variables;
863  std::map< std::string, std::pair< std::map< std::string, std::string >, ArithmeticASTExpressionOP > > vector_expression_asts;
864 
865  ArithmeticASTExpressionOP fitness_expression_ast( 0 );
866 
869 
870  Size count_line( 0 );
871  while ( input ) {
872  ++count_line;
873  std::string line;
874  std::getline( ( std::istream & ) input, line );
875  if ( line.size() == 0 ) continue; // skip blank lines
876 
877  std::istringstream input_line( line );
878  if ( input_line.peek() == '#' ) continue; // skip comment lines
879 
880  std::string command;
881  input_line >> command;
882  if ( command == "STATE" ) {
883  process_STATE_line( line, count_line, input_line );
884  } else if ( command == "STATE_VECTOR" ) {
885  process_STATE_VECTOR_line( line, count_line, input_line, strucvec_filenames );
886  } else if ( command == "POSE_ENERGY" ) {
887  process_POSE_ENERGY_line( line, count_line, input_line );
888  } else if ( command == "POSE_ENERGY_VECTOR" ) {
889  process_POSE_ENERGY_VECTOR_line( line, count_line, input_line );
890  } else if ( command == "NPD_PROPERTY" ) {
891  process_NPD_PROPERTY_line( line, count_line, input_line );
892  } else if ( command == "VECTOR_VARIABLE" ) {
893  process_VECTOR_VARIABLE_line( line, count_line, input_line, vector_variables );
894  } else if ( command == "SCALAR_EXPRESSION" ) {
895  process_SCALAR_EXPRESSION_line( line, count_line, input_line, scalar_expression_asts );
896  } else if ( command == "VECTOR_EXPRESSION" ) {
897  process_VECTOR_EXPRESSION_line( line, count_line, input_line, vector_expression_asts );
898  } else if ( command == "ENTITY_FUNCTION" ) {
899  process_ENTITY_FUNCTION_line( line, count_line, input_line );
900  } else if ( command == "FITNESS" ) {
901  process_FITNESS_line( line, count_line, input_line, fitness_expression_ast );
902  } else {
903  throw utility::excn::EXCN_Msg_Exception( "Unable to recognize command '" + command + "' while reading DynamicAggregateFunction file" );
904  }
905  }
906 
907  if ( ! fitness_expression_ast ) {
908  throw utility::excn::EXCN_Msg_Exception( "Unable to find FITNESS command in the file describing the DynamicAggretateFunction.\n"
909  "The FITNESS command must exist " );
910  }
911 
912  /// NOW:
913  /// 1. Read the STATE_VECTOR input files into the state_vector_data_file_names_ variable.
914  /// Make sure that each input file is properly formatted.
915  /// 2. Turn the ExpressionASTs into Expressions.
916  /// a. Count the numer of states (structures)
917  /// b. Create variables for the scalar- and vector-expressions.
918  /// c. Create Expression trees for the scalar- and vector-expressions in the order they were defined.
919  /// d. Create the FITNESS expression.
920 
921  Size n_vector_states( 0 );
922  for ( Size ii = 1; ii <= strucvec_filenames.size(); ++ii ) {
923  read_state_vector_file( strucvec_filenames[ ii ].first, strucvec_filenames[ ii ].second, n_vector_states );
924  }
925 
926  Size const n_states = named_state_data_file_names_.size() + n_vector_states;
927  Size const n_npd_properties = count_num_npd_properties();
928  Size const n_variables = n_states + n_npd_properties + scalar_expression_asts.size();
929 
930  //state_names_.resize( n_states );
931  variable_expressions_for_states_.resize( n_states );
932  npd_variable_indices_for_states_.resize( n_states );
933  variable_expressions_for_npd_properties_.resize( n_npd_properties );
934  files_for_state_.resize( n_states );
935  variable_expressions_.resize( n_variables );
936 
937  Size count_state( 0 ), count_npd_index( 0 ), count_variable_index( 0 );
938  create_state_variable_expressions( count_state, count_npd_index, count_variable_index );
939  create_variable_vector_expressions( count_state, count_npd_index, count_variable_index );
940  create_scalar_and_vector_expression_variable_expressions( scalar_expression_asts, vector_variables, count_variable_index );
941 
942  turn_expression_ASTs_into_expressions( scalar_expression_asts, vector_expression_asts, fitness_expression_ast );
943 
944  /// Basically done.
945  /// At this point, I should verify that the expressions can be evaulated -- that is,
946  /// that the vector-variables are only handed to vector functions.
947  /// I don't know the best way to do that.
948 }
949 
950 void
952 {
953  scanner_ = new ArithmeticScanner( false ); /// constructor without adding the "standard" functions
954  scanner_->add_function( "sqrt", 1 ); // neiter min nor max are allowed functions.
955  scanner_->add_function( "vmax", 1 );
956  scanner_->add_function( "vmin", 1 );
957  scanner_->add_function( "vmax_by", 2 );
958  scanner_->add_function( "vmin_by", 2 );
959  scanner_->add_function( "exp", 1 );
960  scanner_->add_function( "pow", 2 );
961  scanner_->add_function( "ite", 3 );
962  scanner_->add_function( "ln", 1 );
963  scanner_->add_function( "abs", 1 );
964  scanner_->add_function( "gt", 2 );
965  scanner_->add_function( "lt", 2 );
966  scanner_->add_function( "gte", 2 );
967  scanner_->add_function( "lte", 2 );
968  scanner_->add_function( "and", 2 );
969  scanner_->add_function( "or", 2 );
970  scanner_->add_function( "not", 1 );
971 }
972 
973 /// @details Reads the contents of the line which should include four things:
974 /// 1. an as-of-yet unused variable name to identify this state,
975 /// 2. a pdb name giving the file containing the state to be redesigned
976 /// 3. a correspondence file name which describes the connection between residues
977 /// in the state from 2. which should correspond to particular residues
978 /// that are being designed.
979 /// 4. a secondary resfile that describes how other residues in 2. should be repacked
980 /// or redesigned.
981 /// The variable name in 1. is checked against the variable_names_dec_line_ member variable,
982 /// and, if it is absent, be added to both variable_names_dec_line_ and scanner_. This method
983 /// then adds the file names from 2, 3, and 4 to the named_state_data_file_names_
984 /// map.
985 void
987  std::string const & line,
988  Size line_number,
989  std::istream & input_line
990 )
991 {
992  std::string state_name, structure_file, correspondence_file, secondary_resfile;
993  if ( ! input_line ) {
994  throw utility::excn::EXCN_Msg_Exception( "Expected to read state name in the DynamicAggregateFunction"
995  " input file after reading STATE on line " + utility::to_string( line_number ) + "\n" + line );
996  }
997  input_line >> state_name;
998  if ( ! input_line ) {
999  throw utility::excn::EXCN_Msg_Exception( "Expected to read state variable name in the DynamicAggregateFunction"
1000  " input file after reading STATE name on line " + utility::to_string( line_number ) + "\n" + line );
1001  }
1002  if ( state_name.size() == 0 ) {
1003  throw utility::excn::EXCN_Msg_Exception( "Expected to read state variable name in the DynamicAggregateFunction"
1004  " input file after reading STATE on line " + utility::to_string( line_number ) + "\n" + line );
1005  }
1006 
1007  verify_variable_name_or_throw( state_name, "STATE", line, line_number );
1008 
1009  input_line >> structure_file;
1010  if ( ! input_line ) {
1011  throw utility::excn::EXCN_Msg_Exception( "Expected to read pdb file name in the DynamicAggregateFunction"
1012  " input file after reading STATE pdb file on line " + utility::to_string( line_number ) + "\n" + line );
1013  }
1014  if ( structure_file.size() == 0 ) {
1015  throw utility::excn::EXCN_Msg_Exception( "Expected to read pdb file name in the DynamicAggregateFunction"
1016  " input file after reading STATE name on line " + utility::to_string( line_number ) + "\n" + line );
1017  }
1018  input_line >> correspondence_file;
1019  if ( ! input_line ) {
1020  throw utility::excn::EXCN_Msg_Exception( "Expected to read secondary resfile name in the DynamicAggregateFunction"
1021  " input file after reading STATE correspondence file on line " + utility::to_string( line_number ) + "\n" + line );
1022  }
1023  if ( correspondence_file.size() == 0 ) {
1024  throw utility::excn::EXCN_Msg_Exception( "Expected to read correspondence file name in the DynamicAggregateFunction"
1025  " input file after reading STATE pdb file on line " + utility::to_string( line_number ) + "\n" + line );
1026  }
1027  input_line >> secondary_resfile;
1028  if ( secondary_resfile.size() == 0 ) {
1029  throw utility::excn::EXCN_Msg_Exception( "Expected to read secondary resfile name in the DynamicAggregateFunction"
1030  " input file after reading STATE correspondence file on line " + utility::to_string( line_number ) + "\n" + line );
1031  }
1032 
1033  // Success.
1034  TR << "Read STATE line. Name= " << state_name
1035  << " PDB= " << structure_file << " Corr= " << correspondence_file
1036  << " 2RF= " << secondary_resfile << std::endl;
1037 
1038  scanner_->add_variable( state_name );
1039  variable_names_dec_line_[ state_name ] = line_number;
1041 
1042  StructureFileNames sfn;
1043  sfn.pdb_name_ = structure_file;
1044  sfn.correspondence_file_name_ = correspondence_file;
1045  sfn.resfile_name_ = secondary_resfile;
1046 
1047  state_variable_names_.insert( state_name );
1049 
1050 }
1051 
1052 /// @details This method reads a line beginning with the command
1053 /// STATE_VECTOR looking for two things on this line:
1054 /// 1. an as-of-yet unused variable name identifying the vector
1055 /// 2. a file name which contains a list of states.
1056 /// If the variable name is absent from the variables_ set, then
1057 /// this method appends the name to the variables_ set and to the
1058 /// scanner_, and appends the pair (1,2) to the input
1059 /// strucvec_filenames parameter. No other member variables are modified.
1060 void
1062  std::string const & line,
1063  Size line_number,
1064  std::istream & input_line,
1065  utility::vector1< std::pair< std::string, std::string > > & strucvec_filenames
1066 )
1067 {
1068  std::string state_vector_variable_name, state_vector_filename;
1069  if ( ! input_line ) {
1070  throw utility::excn::EXCN_Msg_Exception( "Expected to read state-vector variable name in the DynamicAggregateFunction"
1071  " input file after reading STATE_VECTOR on line " + utility::to_string( line_number ) + "\n" + line );
1072  }
1073  input_line >> state_vector_variable_name;
1074  if ( state_vector_variable_name.size() == 0 ) {
1075  throw utility::excn::EXCN_Msg_Exception( "Expected to read state-vector variable name in the DynamicAggregateFunction"
1076  " input file after reading STATE_VECTOR on line " + utility::to_string( line_number ) + "\n" + line );
1077  }
1078  if ( ! input_line ) {
1079  throw utility::excn::EXCN_Msg_Exception( "Expected to read state-vector file name in the DynamicAggregateFunction"
1080  " input file after reading STATE_VECTOR variable name on line " + utility::to_string( line_number ) + "\n" + line );
1081  }
1082 
1083  verify_variable_name_or_throw( state_vector_variable_name, "STATE_VECTOR", line, line_number );
1084 
1085  input_line >> state_vector_filename;
1086  if ( state_vector_filename.size() == 0 ) {
1087  throw utility::excn::EXCN_Msg_Exception( "Expected to read state-vector file name in the DynamicAggregateFunction"
1088  " input file after reading STATE_VECTOR variable name on line " + utility::to_string( line_number ) + "\n" + line );
1089  }
1090 
1091  // Success
1092  TR << "Read STATE_VECTOR line. Name= " << state_vector_variable_name
1093  << " File= " << state_vector_filename << std::endl;
1094 
1095  variable_names_dec_line_[ state_vector_variable_name ] = line_number;
1096  state_vector_variable_names_.insert( state_vector_variable_name );
1097  vector_variable_names_dec_line_[ state_vector_variable_name ] = line_number;
1098  scanner_->add_variable( state_vector_variable_name );
1099 
1100  strucvec_filenames.push_back( std::make_pair( state_vector_variable_name, state_vector_filename ) );
1101 }
1102 
1103 void
1105  std::string const & line,
1106  Size line_number,
1107  std::istream & input_line
1108 )
1109 {
1110  if ( ! input_line ) {
1111  throw utility::excn::EXCN_Msg_Exception( "Expected to read variable name in the DynamicAggregateFunction"
1112  " input file after reading POSE_ENERGY on line " + utility::to_string( line_number ) + "\n" + line );
1113  }
1114  // 1. read the new variable name that's being declared on this line
1115  std::string varname;
1116  input_line >> varname;
1117  if ( varname.size() == 0 ) {
1118  throw utility::excn::EXCN_Msg_Exception( "Expected to read variable name in the DynamicAggregateFunction"
1119  " input file after reading POSE_ENERGY on line " + utility::to_string( line_number ) + "\n" + line );
1120  }
1121  if ( ! input_line ) {
1122  throw utility::excn::EXCN_Msg_Exception( "Expected to read a PDB name in the DynamicAggregateFunction"
1123  " input file after reading the variable name '" + varname + "' on line " + utility::to_string( line_number ) + "\n" + line );
1124  }
1125  verify_variable_name_or_throw( varname, "POSE_ENERGY", line, line_number );
1126 
1127  std::string pdb_name;
1128  input_line >> pdb_name;
1129 
1130  TR << " Importing pose from pdb file '" << pdb_name << "'" << std::endl;
1131  //core::import_pose::pose_from_pdb( pose, pdb_name );
1132  std::string pdb_string;
1133  if ( file_contents_.find( pdb_name ) != file_contents_.end() ) {
1134  pdb_string = file_contents_[ pdb_name ];
1135  } else {
1136  try {
1137  pdb_string = utility::file_contents( pdb_name );
1138  } catch ( utility::excn::EXCN_Msg_Exception & e ) {
1139  throw utility::excn::EXCN_Msg_Exception( "Failed to open pdb file named '"
1140  + pdb_name + "' given in the POSE_ENERGY command on line " + utility::to_string( line_number)
1141  + "of the DynamicAggregateFunction fitness file" );
1142  }
1143  }
1144 
1145  core::pose::Pose pose;
1146  core::import_pose::pose_from_pdbstring( pose, pdb_string, pdb_name );
1147 
1148  if ( pose.total_residue() == 0 ) {
1149  throw utility::excn::EXCN_Msg_Exception( "Input pose given in file '"
1150  + pdb_name + "' has zero residues. Encountered while processing the '" + varname + "' variable in the DynamicAggregateFunction"
1151  " input file on line " + utility::to_string( line_number ) + "\n" + line );
1152  }
1153 
1154  // ok -- go ahead and score the pose
1155  TR << " Scoring pose from pdb file '" << pdb_name << "'" << std::endl;
1156  core::Real score = (*sfxn_)( pose );
1157  scanner_->add_variable( varname );
1158  scalar_expression_map_[ varname ] = new VariableExpression( varname, score );
1159  TR << "Saving POSE_ENERGY of " << score << " in variable " << varname << std::endl;
1160 }
1161 
1162 void
1164  std::string const & line,
1165  Size line_number,
1166  std::istream & input_line
1167 )
1168 {
1169  if ( ! input_line ) {
1170  throw utility::excn::EXCN_Msg_Exception( "Expected to read variable name in the DynamicAggregateFunction"
1171  " input file after reading POSE_ENERGY_VECTOR on line " + utility::to_string( line_number ) + "\n" + line );
1172  }
1173  // 1. read the new variable name that's being declared on this line
1174  std::string varname;
1175  input_line >> varname;
1176  if ( varname.size() == 0 ) {
1177  throw utility::excn::EXCN_Msg_Exception( "Expected to read variable name in the DynamicAggregateFunction"
1178  " input file after reading POSE_ENERGY_VECTOR on line " + utility::to_string( line_number ) + "\n" + line );
1179  }
1180  if ( ! input_line ) {
1181  throw utility::excn::EXCN_Msg_Exception( "Expected to read the name of a list file in the DynamicAggregateFunction"
1182  " input file after reading the variable name '" + varname + "' on line " + utility::to_string( line_number ) + "\n" + line );
1183  }
1184  verify_variable_name_or_throw( varname, "POSE_ENERGY_VECTOR", line, line_number );
1185 
1186  std::string fname;
1187  input_line >> fname;
1188 
1189  std::istringstream pdbvec_file;
1190  if ( file_contents_.find( fname ) != file_contents_.end() ) {
1191  pdbvec_file.str( file_contents_[ fname ] );
1192  } else {
1193  try {
1194  std::string fc = utility::file_contents( fname );
1195  pdbvec_file.str( fc );
1196  } catch ( utility::excn::EXCN_Msg_Exception & e ) {
1197  throw utility::excn::EXCN_Msg_Exception( "Failed to open pdb list file named '"
1198  + fname + "' given in the POSE_ENERGY_VECTOR command on line " + utility::to_string( line_number)
1199  + "of the DynamicAggregateFunction fitness file" );
1200  }
1201  }
1202 
1203  std::list< std::string > pdb_names;
1204  Size count_pdbs = 0;
1205  Size pdbvec_linenum = 0;
1206  while ( pdbvec_file ) {
1207  ++pdbvec_linenum;
1208  std::string line;
1209  std::getline( (std::istream &) (pdbvec_file), line );
1210  if ( line.size() == 0 ) continue;
1211 
1212  std::istringstream input_line( line );
1213  if ( input_line.peek() == '#' ) continue; // allow lines beginning with # to be commented out
1214  std::string pdbname;
1215  input_line >> pdbname;
1216  ++count_pdbs;
1217  pdb_names.push_back( pdbname );
1218  }
1219 
1220  utility::vector1< VariableExpressionOP > pose_energy_variables( count_pdbs );
1221  count_pdbs = 0;
1222  for ( std::list< std::string >::const_iterator iter = pdb_names.begin(), iter_end = pdb_names.end(); iter != iter_end; ++iter ) {
1223  ++count_pdbs;
1224  assert( count_pdbs <= pose_energy_variables.size() );
1225  TR << " Importing pose from pdb file " << *iter << std::endl;
1226  //core::import_pose::pose_from_pdb( pose, pdb_name );
1227  std::string pdb_string;
1228  if ( file_contents_.find( *iter ) != file_contents_.end() ) {
1229  pdb_string = file_contents_[ *iter ];
1230  } else {
1231  try {
1232  pdb_string = utility::file_contents( *iter );
1233  } catch ( utility::excn::EXCN_Msg_Exception & e ) {
1234  throw utility::excn::EXCN_Msg_Exception( "Failed to open pdb file named '"
1235  + *iter + "' given in the POSE_ENERGY_VECTOR command on line " + utility::to_string( line_number)
1236  + "of the DynamicAggregateFunction fitness file" );
1237  }
1238  }
1239  core::pose::Pose pose;
1240  core::import_pose::pose_from_pdbstring( pose, pdb_string, *iter );
1241 
1242  if ( pose.total_residue() == 0 ) {
1243  throw utility::excn::EXCN_Msg_Exception( "Input pose given in file '"
1244  + *iter + "' has zero residues. Encountered while processing the '" + varname + "' variable in the DynamicAggregateFunction"
1245  " input file on line " + utility::to_string( line_number ) + "\n" + line );
1246  }
1247 
1248  TR << " Scoring pose from pdb file '" << *iter << std::endl;
1249  core::Real score = (*sfxn_)( pose );
1250  std::string newvar = varname + "_" + *iter;
1251  TR << " Saving score of " << score << " in variable " << newvar << std::endl;
1252  pose_energy_variables[ count_pdbs ] = new VariableExpression( newvar, score );;
1253  }
1254  scanner_->add_variable( varname );
1255  vector_expression_map_[ varname ] = new VariableVectorExpression( varname, pose_energy_variables );
1256 
1257 
1258 }
1259 
1260 
1261 void
1263  std::string const & line,
1264  Size line_number,
1265  std::istream & input_line
1266 )
1267 {
1268  if ( ! input_line ) {
1269  throw utility::excn::EXCN_Msg_Exception( "Expected to read variable name in the DynamicAggregateFunction"
1270  " input file after reading NPD_PROPERTY on line " + utility::to_string( line_number ) + "\n" + line );
1271  }
1272  // 1. read the new variable name that's being declared on this line
1273  std::string varname;
1274  input_line >> varname;
1275  if ( varname.size() == 0 ) {
1276  throw utility::excn::EXCN_Msg_Exception( "Expected to read variable name in the DynamicAggregateFunction"
1277  " input file after reading NPD_PROPERTY on line " + utility::to_string( line_number ) + "\n" + line );
1278  }
1279  if ( ! input_line ) {
1280  throw utility::excn::EXCN_Msg_Exception( "Expected to read an existing state- or state-vector "
1281  " variable name in the DynamicAggregateFunction"
1282  " input file after reading NPD_PROPERTY on line " + utility::to_string( line_number ) + "\n" + line );
1283  }
1284  verify_variable_name_or_throw( varname, "NPD_PROPERTY", line, line_number );
1285 
1286  // 2. Read the name of the existing state or state-vector variable
1287  std::string original_varname;
1288  input_line >> original_varname;
1289  if ( original_varname.size() == 0 ) {
1290  throw utility::excn::EXCN_Msg_Exception( "Expected to read an existing state- or state-vector"
1291  " variable in the DynamicAggregateFunction"
1292  " input file after reading the new variable name on line " + utility::to_string( line_number ) + "\n" + line );
1293  }
1294  bool original_was_state_vector( false );
1295  if ( state_variable_names_.find( original_varname ) != state_variable_names_.end() ) {
1296  /// we have a state-variable, so we will add a new scalar variable to
1297  } else if ( state_vector_variable_names_.find( original_varname ) != state_vector_variable_names_.end() ) {
1298  /// OK we have a state-vector variable so we will add a new vector variable
1299  original_was_state_vector = true;
1300  } else {
1301  /// Error condition: the user has given a variable name that does not correspond to
1302  /// either a state or a state vector.
1303  if ( variable_names_dec_line_.find( original_varname ) != variable_names_dec_line_.end() ) {
1304  throw utility::excn::EXCN_Msg_Exception( "Expected to read the name for the existing state or state vector"
1305  " in the DynamicAggregateFunction input file, but instead was given the name of a non-state variable, "
1306  + original_varname + " that had previously been declared on line " +
1307  utility::to_string( variable_names_dec_line_[ original_varname ] ) +
1308  ".\n Error while processing line " + utility::to_string( line_number ) + "\n" + line );
1309  } else {
1310  throw utility::excn::EXCN_Msg_Exception( "Read the name '" + original_varname + "' but "
1311  " expected to read the variable name for the existing state- or state-vector"
1312  " variable in the DynamicAggregateFunction"
1313  " input file after reading the new variable name on line " + utility::to_string( line_number ) + "\n" + line );
1314  }
1315  }
1316 
1317  // 3. Read the NPD property that will be calculated
1318  std::string npd_property;
1319  if ( ! input_line ) {
1320  throw utility::excn::EXCN_Msg_Exception( "Expected to read a non-pairwise decomposable property"
1321  " name after reading the existing state- or state-vector"
1322  " variable name in the DynamicAggregateFunction"
1323  " input file on line " + utility::to_string( line_number ) + "\n" + line );
1324  }
1325  input_line >> npd_property;
1326  if ( npd_property.size() == 0 ) {
1327  throw utility::excn::EXCN_Msg_Exception( "Expected to read a non-pairwise decomposable property"
1328  " name after reading the existing state- or state-vector"
1329  " variable name in the DynamicAggregateFunction"
1330  " input file on line " + utility::to_string( line_number ) + "\n" + line );
1331  }
1332  // TO DO. Error check: is this a supported property?
1333 
1334  // what to do now?
1335  variable_names_dec_line_[ varname ] = line_number;
1336  scanner_->add_variable( varname );
1337  if ( original_was_state_vector ) {
1338  // create a new vector variable
1339  vector_variable_names_dec_line_[ varname ] = line_number;
1340  } else {
1341  // create a new scalar variable
1342  scalar_variable_names_dec_line_[ varname ] = line_number;
1343  }
1344 
1345  npd_properties_for_state_variables_[ original_varname ].push_back( std::make_pair( npd_property, varname ) );
1346 }
1347 
1348 void
1350  std::string const & line,
1351  Size line_number,
1352  std::istream & input_line,
1353  std::map< std::string, std::list< std::string > > & vector_variables
1354 )
1355 {
1356  std::string vector_variable_name, equals_sign, scalar_variable_name;
1357  if ( ! input_line ) {
1358  throw utility::excn::EXCN_Msg_Exception( "Expected to read vector variable name in the DynamicAggregateFunction"
1359  " input file after reading VECTOR_VARIABLE on line " + utility::to_string( line_number ) + "\n" + line );
1360  }
1361  input_line >> vector_variable_name;
1362  if ( vector_variable_name.size() == 0 ) {
1363  throw utility::excn::EXCN_Msg_Exception( "Expected to read vector variable name in the DynamicAggregateFunction"
1364  " input file after reading VECTOR_VARIABLE on line " + utility::to_string( line_number ) + "\n" + line );
1365  }
1366 
1367  verify_variable_name_or_throw( vector_variable_name, "VECTOR_VARIABLE", line, line_number );
1368 
1369  if ( ! input_line ) {
1370  throw utility::excn::EXCN_Msg_Exception( "Expected to read equals sign in the DynamicAggregateFunction"
1371  " input file after reading " + vector_variable_name + " varname in the VECTOR_VARIABLE command on line " + utility::to_string( line_number ) + "\n" + line );
1372  }
1373  input_line >> equals_sign;
1374  if ( equals_sign != "=" ) {
1375  throw utility::excn::EXCN_Msg_Exception( "Expected to read equals sign in the DynamicAggregateFunction"
1376  " input file after reading " + vector_variable_name + " varname, but found '" + equals_sign + "' instead in the VECTOR_VARIABLE command on line " + utility::to_string( line_number ) + "\n" + line );
1377  }
1378 
1379  std::list< std::string > varname_list;
1380  while ( input_line ) {
1381  input_line >> scalar_variable_name;
1382  if ( scalar_variable_name.size() == 0 ) continue;
1383  if ( scalar_variable_names_dec_line_.find( scalar_variable_name ) == scalar_variable_names_dec_line_.end() ) {
1384  if ( vector_variable_names_dec_line_.find( scalar_variable_name ) != vector_variable_names_dec_line_.end() ) {
1385  throw utility::excn::EXCN_Msg_Exception( "Variable '" + scalar_variable_name + "' is a vector variable and"
1386  " cannot be listed in the scalar-variable list in a VECTOR_VARIABLE command.\n"
1387  "Error processing VECTOR_VARIABLE command on line " + utility::to_string( line_number ) + "\n" + line );
1388 
1389  } else {
1390  throw utility::excn::EXCN_Msg_Exception( "Unknown variable '" + scalar_variable_name + "' requested"
1391  " in the VECTOR_VARIABLE command on line " + utility::to_string( line_number ) + "\n" + line );
1392  }
1393  } else {
1394  varname_list.push_back( scalar_variable_name );
1395  }
1396  }
1397 
1398  variable_names_dec_line_[ vector_variable_name ] = line_number;
1399  vector_variable_names_dec_line_[ vector_variable_name ] = line_number;
1400  scanner_->add_variable( vector_variable_name );
1401 
1402  vector_variables[ vector_variable_name ] = varname_list;
1403 }
1404 
1405 
1406 /// @details This methods reads the line beginning with the command SCALAR_EXPRESSION
1407 /// which should be in the following format ( items in <> are explained below)
1408 /// SCALAR_EXPRESSION <varname> = <expression>
1409 /// 1. varname must be an as-of-yet unused varible name.
1410 /// 2. The form of expression must return a value (it should not be a vector expression). It
1411 /// may contain functions and variables so long as those variables have been declared
1412 /// earlier in the file.
1413 /// After the expression has been tokenized, it's abstract syntax tree (ast) is created and
1414 /// appended to the input parameter scalar_expression_asts in tandem with the variable name.
1415 /// The variable name is appended to the variables_ and scanner_ member variables. No other
1416 /// member variables are modified in this function.
1417 void
1419  std::string const & line,
1420  Size line_number,
1421  std::istream & input_line,
1422  std::map< std::string, ArithmeticASTExpressionOP > & scalar_expression_asts
1423 )
1424 {
1425  std::string vname, equals_sign, restofline;
1426  if ( ! input_line ) {
1427  throw utility::excn::EXCN_Msg_Exception( "Expected to read variable name in the DynamicAggregateFunction"
1428  " input file after reading SCALAR_EXPRESSION command on line " + utility::to_string( line_number ) + "\n" + line );
1429  }
1430  input_line >> vname;
1431  if ( ! input_line ) {
1432  throw utility::excn::EXCN_Msg_Exception( "Expected to read equals sign in the DynamicAggregateFunction"
1433  " input file after reading SCALAR_EXPRESSION variable name on line " + utility::to_string( line_number ) + "\n" + line );
1434  }
1435 
1436  verify_variable_name_or_throw( vname, "SCALAR_EXPRESSION", line, line_number );
1437 
1438  input_line >> equals_sign;
1439  if ( equals_sign != "=" ) {
1440  throw utility::excn::EXCN_Msg_Exception( "Expected to read equals sign in the DynamicAggregateFunction"
1441  " input file after reading SCALAR_EXPRESSION variable name on line " + utility::to_string( line_number )
1442  + "\n" + line + "\nbut encountered " + equals_sign + " instead." );
1443  }
1444  if ( ! input_line ) {
1445  throw utility::excn::EXCN_Msg_Exception( "Expected to read an expression in the DynamicAggregateFunction"
1446  " input file after reading SCALAR_EXPRESSION equals sign on line " + utility::to_string( line_number ) + "\n" + line );
1447  }
1448 
1449  std::string rest_of_line;
1450  std::getline( input_line, rest_of_line );
1451 
1452  TR << "On line " << line_number << ", attempting to tokenize scalar expression: " << rest_of_line << std::endl;
1453  TokenSetOP tokens = scanner_->scan( rest_of_line );
1454  TR << "On line " << line_number << ", attempting to parse scalar expression: " << rest_of_line << std::endl;
1455  ArithmeticASTExpressionOP expression_ast = new ArithmeticASTExpression;
1456  expression_ast->parse( *tokens );
1457 
1458  // Assuming we made it here, the AST has been correctly parsed.
1459  scalar_expression_asts[ vname ] = expression_ast;
1460  variable_names_dec_line_[ vname ] = line_number;
1461  scalar_variable_names_dec_line_[ vname ] = line_number;
1462  scanner_->add_variable( vname );
1463  expression_evaluation_order_by_name_.push_back( std::make_pair( 1, vname ));
1464  TR << "SCALAR_EXPRESSION on line " << line_number << " successfully parsed" << std::endl;
1465 }
1466 
1467 void
1469  std::string const & line,
1470  Size line_number,
1471  std::istream & input_line,
1472  std::map< std::string, std::pair< std::map< std::string, std::string >, ArithmeticASTExpressionOP > > & vector_expression_asts
1473 )
1474 {
1475  std::string for_string, local_var, in_string, existing_vector_varname,
1476  comma_or_colon_string, vector_varname, equals_sign, rest_of_line;
1477 
1478  std::map< std::string, std::string > localvar_map;
1479  /// make a local copy and add variables to this local copy. Local variables declared in
1480  /// a single VECTOR_EXPRESSION line do not cary ovr into other lines.
1481  ArithmeticScanner local_scanner( *scanner_ );
1482 
1483  if ( ! input_line ) {
1484  throw utility::excn::EXCN_Msg_Exception( "Expected to read FOR in the DynamicAggregateFunction"
1485  " input file after reading VECTOR_EXPRESSION command on line " + utility::to_string( line_number ) + "\n" + line );
1486  }
1487  input_line >> for_string;
1488  if ( for_string != "FOR" ) {
1489  throw utility::excn::EXCN_Msg_Exception( "Expected to read FOR in the DynamicAggregateFunction"
1490  " input file after reading VECTOR_EXPRESSION command, but read '" + for_string + "' on line "
1491  + utility::to_string( line_number ) + "\n" + line );
1492  }
1493  if ( ! input_line ) {
1494  throw utility::excn::EXCN_Msg_Exception( "Expected to read local variable name in the DynamicAggregateFunction"
1495  " input file after reading FOR on a VECTOR_EXPRESSION command on line "
1496  + utility::to_string( line_number ) + "\n" + line );
1497  }
1498  bool colon_found = false;
1499  while ( ! colon_found ) {
1500  if ( ! input_line ) {
1501  throw utility::excn::EXCN_Msg_Exception( "Expected to read local variable name in the DynamicAggregateFunction input file"
1502  " while processing multiple local variables on a VECTOR_EXPRESSION command on line "
1503  + utility::to_string( line_number ) + "\n" + line );
1504  }
1505  input_line >> local_var;
1506 
1507  verify_variable_name_or_throw( local_var, "VECTOR_EXPRESSION", line, line_number );
1508 
1509  if ( localvar_map.find( local_var ) != localvar_map.end() ) {
1510  throw utility::excn::EXCN_Msg_Exception( "Local variable, '" + local_var + "' in VECTOR_EXPRESSION command appears multiple times on line "
1511  + utility::to_string( line_number ) + "\n" + line );
1512  }
1513 
1514  if ( ! input_line ) {
1515  throw utility::excn::EXCN_Msg_Exception( "Expected to read 'IN' in the DynamicAggregateFunction input file"
1516  " following the declaration of local variable '" + local_var + "' on a VECTOR_EXPRESSION command on line "
1517  + utility::to_string( line_number ) + "\n" + line );
1518  }
1519  input_line >> in_string;
1520  if ( in_string != "IN" ) {
1521  throw utility::excn::EXCN_Msg_Exception( "Expected to read 'IN' in the DynamicAggregateFunction input file"
1522  " following the declaration of local variable '" + local_var + "', but read '" + in_string + "' in the VECTOR_EXPRESSION command on line "
1523  + utility::to_string( line_number ) + "\n" + line );
1524  }
1525  if ( ! input_line ) {
1526  throw utility::excn::EXCN_Msg_Exception( "Expected to read a vector-variable name in the DynamicAggregateFunction input file"
1527  " following '" + local_var + " IN' in the VECTOR_EXPRESSION command on line "
1528  + utility::to_string( line_number ) + "\n" + line );
1529  }
1530  input_line >> existing_vector_varname;
1531 
1532  if ( vector_variable_names_dec_line_.find( existing_vector_varname ) == vector_variable_names_dec_line_.end() ) {
1533  throw utility::excn::EXCN_Msg_Exception( "The vector-variable name '" + existing_vector_varname
1534  + "' given for local-variable '" + local_var + "' does not belong to an already-declared vector variable"
1535  + ". Error in the VECTOR_EXPRESSION command on line "
1536  + utility::to_string( line_number ) + "\n" + line );
1537  }
1538  localvar_map[ local_var ] = existing_vector_varname;
1539  local_scanner.add_variable( local_var );
1540  if ( ! input_line ) {
1541  throw utility::excn::EXCN_Msg_Exception( "Expected to read a colon or a comma following"
1542  " the declaration of local variable " + local_var + " in the VECTOR_EXPRESSION command on line "
1543  + utility::to_string( line_number ) + "\n" + line );
1544  }
1545  input_line >> comma_or_colon_string;
1546  if ( comma_or_colon_string == "," ) {
1547  continue;
1548  }
1549  if ( comma_or_colon_string == ":" ) {
1550  break;
1551  }
1552  throw utility::excn::EXCN_Msg_Exception( "Expected to read a colon or a comma following"
1553  " the declaration of local variable " + local_var + ", but found '" + comma_or_colon_string + "' instead."
1554  "\nError in the VECTOR_EXPRESSION command on line "
1555  + utility::to_string( line_number ) + "\n" + line );
1556  }
1557  /// OK -- we've gotten this far. Now we can read the vector-variable name, the equals sign, and the
1558  /// rest of the expression describing how to compute that vector variable.
1559 
1560  if ( ! input_line ) {
1561  throw utility::excn::EXCN_Msg_Exception( "Expected to read a variable name"
1562  " following the colon in the VECTOR_EXPRESSION command on line "
1563  + utility::to_string( line_number ) + "\n" + line );
1564  }
1565  input_line >> vector_varname;
1566 
1567  /// Now check, do we have a valid variable name?
1568  verify_variable_name_or_throw( vector_varname, "VECTOR_EXPRESSION", line, line_number );
1569  if ( localvar_map.find( vector_varname ) != localvar_map.end() ) {
1570  throw utility::excn::EXCN_Msg_Exception( "Vector variable, '" + vector_varname + "' in VECTOR_EXPRESSION command appears first as a local variable\n.Line "
1571  + utility::to_string( line_number ) + "\n" + line );
1572  }
1573 
1574 
1575  if ( ! input_line ) {
1576  throw utility::excn::EXCN_Msg_Exception( "Expected to read an equals sign after reading variable-vector name '"
1577  + vector_varname + "' in the VECTOR_EXPRESSION command on line "
1578  + utility::to_string( line_number ) + "\n" + line );
1579  }
1580 
1581  input_line >> equals_sign;
1582  if ( equals_sign != "=" ) {
1583  throw utility::excn::EXCN_Msg_Exception( "Expected to read an equals sign after reading variable-vector name '"
1584  + vector_varname + "' in the VECTOR_EXPRESSION command on line "
1585  + utility::to_string( line_number ) + " but found '" + equals_sign + "' instead\n" + line );
1586  }
1587  std::getline( input_line, rest_of_line );
1588  TR << "On line " << line_number << ", attempting to tokenize VECTOR_EXPRESSION expression: " << rest_of_line << std::endl;
1589  TokenSetOP tokens = local_scanner.scan( rest_of_line );
1590  TR << "On line " << line_number << ", attempting to parse expression: " << rest_of_line << std::endl;
1591  ArithmeticASTExpressionOP vector_expression_ast = new ArithmeticASTExpression;
1592  vector_expression_ast->parse( *tokens );
1593  TR << "VECTOR_EXPRESSION on line " << line_number << " successfully parsed" << std::endl;
1594 
1595  variable_names_dec_line_[ vector_varname ] = line_number;
1596  vector_variable_names_dec_line_[ vector_varname ] = line_number;
1597  scanner_->add_variable( vector_varname );
1598  expression_evaluation_order_by_name_.push_back( std::make_pair( 2, vector_varname ));
1599 
1600  vector_expression_asts[ vector_varname ] = std::make_pair( localvar_map, vector_expression_ast );
1601 }
1602 
1603 void
1605  std::string const & line,
1606  Size line_number,
1607  std::istream & input_line
1608 )
1609 {
1610  std::string entityfunc_name, entityfunc_file;
1611  if ( ! input_line ) {
1612  throw utility::excn::EXCN_Msg_Exception( "Expected to read state name in the DynamicAggregateFunction"
1613  " input file after reading ENTITY_FUNCTION command on line " + utility::to_string( line_number ) + "\n" + line );
1614  }
1615  input_line >> entityfunc_name;
1616  if ( ! input_line ) {
1617  throw utility::excn::EXCN_Msg_Exception( "Expected to EnitytFunc file name in the DynamicAggregateFunction"
1618  " input file after reading ENTITY_FUNCTION command on line " + utility::to_string( line_number ) + "\n" + line );
1619  }
1620  if ( entityfunc_name.size() == 0 ) {
1621  throw utility::excn::EXCN_Msg_Exception( "Expected to read EntityFunc variable name in the DynamicAggregateFunction"
1622  " input file after reading ENTITY_FUNCTION command on line " + utility::to_string( line_number ) + "\n" + line );
1623  }
1624 
1625  verify_variable_name_or_throw( entityfunc_name, "ENTITY_FUNCTION", line, line_number );
1626 
1627  input_line >> entityfunc_file;
1628  if ( ! input_line ) {
1629  throw utility::excn::EXCN_Msg_Exception( "Expected to read correspondence file name in the DynamicAggregateFunction"
1630  " input file after reading ENTITY_FUNCTION pdb file on line " + utility::to_string( line_number ) + "\n" + line );
1631  }
1632  if ( entityfunc_file.size() == 0 ) {
1633  throw utility::excn::EXCN_Msg_Exception( "Expected to read pdb file name in the DynamicAggregateFunction"
1634  " input file after reading ENTITY_FUNCTION variable named " + entityfunc_name +
1635  " on line " + utility::to_string( line_number ) + "\n" + line );
1636  }
1637 
1638  /// Double check that the number of entity elements has been set
1639  if ( num_entity_elements_ == 0 ) {
1640  throw utility::excn::EXCN_Msg_Exception( "DynamicAggregateFunction::set_num_entity_elements must be called before EntityFuncs may be created" );
1641  }
1642 
1643 
1644  EntityFuncOP entfunc = new EntityFunc;
1645  entfunc->set_num_entity_elements( num_entity_elements_ );
1646  std::string entfunc_contents;
1647 
1648  std::map< std::string, std::string >::const_iterator fc_iter = file_contents_.find( entityfunc_file );
1649  if ( fc_iter == file_contents_.end() ) {
1650  entfunc_contents = utility::file_contents( entityfunc_file );
1651  } else {
1652  entfunc_contents = fc_iter->second;
1653  }
1654 
1655  std::istringstream iss( entfunc_contents );
1656  entfunc->initialize_from_input_file( iss );
1657 
1658  entity_funcs_[ entityfunc_name ] = std::make_pair( entfunc, new SurrogateVariableExpression( entityfunc_name ) );
1659  entity_funcs_dec_line_[ entityfunc_name ] = line_number;
1660  scanner_->add_variable( entityfunc_name );
1661 }
1662 
1663 
1664 /// @details This method reads the line of the input file beginning with the command FITNESS.
1665 /// Each DynamicAggregateFunction input file should contain exactly one FITNESS command.
1666 /// The fitness line should be of the form:
1667 /// FITNESS <expression>
1668 /// where the expression must return a value (it should not be a vector expression) and
1669 /// may refer to functions and variables so long as those variables have been declared
1670 /// earlier in the file. The abstract syntax tree (ast) for the fitness expression
1671 /// is returned in the input parameter, fitness_expression_ast.
1672 void
1674  std::string const & line,
1675  Size line_number,
1676  std::istream & input_line,
1677  ArithmeticASTExpressionOP & fitness_expression_ast
1678 )
1679 {
1680  if ( fitness_expression_ast ) {
1681  throw utility::excn::EXCN_Msg_Exception( "FITNESS command appears multiple"
1682  " times in the DynamicAggregateFunction file.\nSecond occurrance found while reading\n"
1683  + line + "\nLine # " + utility::to_string( line_number ) );
1684  }
1685  std::string rest_of_line;
1686  std::getline( input_line, rest_of_line );
1687  TR << "On line " << line_number << ", attempting to tokenize FITNESS expression: " << rest_of_line << std::endl;
1688  TokenSetOP tokens = scanner_->scan( rest_of_line );
1689  TR << "On line " << line_number << ", attempting to parse expression: " << rest_of_line << std::endl;
1690  fitness_expression_ast = new ArithmeticASTExpression;
1691  fitness_expression_ast->parse( *tokens );
1692  TR << "FITNESS on line " << line_number << " successfully parsed" << std::endl;
1693 }
1694 
1695 /// @details This function reads the contents of a state-vector file. The input
1696 /// parameter vec_varname refers to the variable name associated with the file named
1697 /// by the second input parameter -- this pairing occurred somewhere in the
1698 /// DynamicAggregateFunction input file in a STATE_VECTOR command. The format
1699 /// of the state vector should be a series of lines each with three strings.
1700 /// String 1: the name of the pdb file containing a state that should be repacked.
1701 /// String 2: the name of the correspondence file mapping residues in the input pdb
1702 /// to the shared residues.
1703 /// String 3: the name of the secondary resfile describing how the packer should treat
1704 /// residues other than the correspondence residues in the protein.
1705 /// Lines beginning with "#" are ignored.
1706 /// The triples read from this file are appended to the state_vector_data_file_names_
1707 /// member variable. The method increments the input variable n_vector_states for
1708 /// each triple that it reads from the state-vector file.
1709 void
1711  std::string const & vec_varname,
1712  std::string const & fname,
1713  Size & n_vector_states
1714 )
1715 {
1716  std::istringstream strucvec_file;
1717  if ( file_contents_.find( fname ) != file_contents_.end() ) {
1718  strucvec_file.str( file_contents_[ fname ] );
1719  } else {
1720  try {
1721  std::string fc = utility::file_contents( fname );
1722  strucvec_file.str( fc );
1723  } catch ( utility::excn::EXCN_Msg_Exception & e ) {
1724  throw utility::excn::EXCN_Msg_Exception( "Failed to open state vector file named '" + fname + "' which was listed on line " + utility::to_string( variable_names_dec_line_[ vec_varname ] ) );
1725  }
1726  }
1727  Size svline_num( 0 );
1729  while ( strucvec_file ) {
1730  ++svline_num;
1731  std::string line;
1732  std::getline( (std::istream &) ( strucvec_file ), line );
1733  if ( line.size() == 0 ) continue;
1734 
1735  std::istringstream input_line( line );
1736  if ( input_line.peek() == '#' ) continue;
1737 
1738  std::string structure_file, correspondence_file, secondary_resfile;
1739  if ( ! input_line ) {
1740  throw utility::excn::EXCN_Msg_Exception( "Expected to read pdb file name as the first argument on line "
1741  + utility::to_string( svline_num ) + " of the state-vector file" + fname + "\n" + line );
1742  }
1743  input_line >> structure_file;
1744  if ( ! input_line ) {
1745  throw utility::excn::EXCN_Msg_Exception( "Expected to read correspondence file name as the second argument on line "
1746  + utility::to_string( svline_num ) + " of the state-vector file" + fname + "\n" + line );
1747  }
1748  input_line >> correspondence_file;
1749  if ( ! input_line ) {
1750  throw utility::excn::EXCN_Msg_Exception( "Expected to read secondary resfile name as the third argument on line "
1751  + utility::to_string( svline_num ) + " of the state-vector file" + fname + "\n" + line );
1752  }
1753  input_line >> secondary_resfile;
1754 
1755  StructureFileNames sfn;
1756  sfn.pdb_name_ = structure_file;
1757  sfn.correspondence_file_name_ = correspondence_file;
1758  sfn.resfile_name_ = secondary_resfile;
1759  state_triples.push_back( sfn );
1760  TR << "Read state from " << fname << " PDB= " << structure_file
1761  << " Corr= " << correspondence_file << " 2RF= " << secondary_resfile << std::endl;
1762  ++n_vector_states;
1763  }
1764  if ( state_triples.size() == 0 ) {
1765  throw utility::excn::EXCN_Msg_Exception( "Failed to find any states in state-vector file " + fname );
1766  }
1767  state_vector_data_file_names_[ vec_varname ] = state_triples;
1768 
1769 }
1770 
1771 /// @details For each element of the named_state_data_file_names_ data member,
1772 /// creates a VariableExpression (named with the variable name given in the STATE
1773 /// command from the DynamicAggregateFunction input file). This variable expression
1774 /// is put into three member variables:
1775 /// the variable_expressions_for_states_ vector,
1776 /// the variable_expressions_ vector, and
1777 /// the named_state_expression_map_.
1778 /// This method increments the count_states input parameter for each VariableExpression
1779 /// that it processes, pairing the value of the count_states variable with the index
1780 /// for this VariableExpression in both the variable_expressions_for_states_ vector and
1781 /// in the variable_expressions_ vector.
1782 void
1784  Size & count_state,
1785  Size & count_npd_index,
1786  Size & count_variable_index
1787 )
1788 {
1789  for ( std::map< std::string, StructureFileNames >::const_iterator
1790  iter = named_state_data_file_names_.begin(), iter_end = named_state_data_file_names_.end();
1791  iter != iter_end; ++iter ) {
1792  ++count_state;
1793  ++count_variable_index;
1794  variable_expressions_for_states_[ count_state ] = new VariableExpression( iter->first, 0.0 );
1795  variable_expressions_[ count_variable_index ] = variable_expressions_for_states_[ count_state ];
1796  files_for_state_[ count_state ] = iter->second;
1797  named_state_expression_map_[ iter->first ] = variable_expressions_for_states_[ count_state ];
1798  scalar_expression_map_[ iter->first ] = variable_expressions_for_states_[ count_state ];
1799  state_variable_name_2_state_index_[ iter->first ] = count_state;
1800 
1801  if ( npd_properties_for_state_variables_.find( iter->first ) != npd_properties_for_state_variables_.end() ) {
1802  std::list< std::pair< std::string, std::string > > const & npdlist( npd_properties_for_state_variables_[ iter->first ]);
1803  for ( std::list< std::pair< std::string, std::string > >::const_iterator
1804  npditer = npdlist.begin(), npditer_end = npdlist.end();
1805  npditer != npditer_end; ++npditer ) {
1806  ++count_npd_index;
1807  ++count_variable_index;
1808  SurrogateVariableExpressionOP surrogate = new SurrogateVariableExpression( npditer->second, 0.0 );
1809  surrogate->root_expression( variable_expressions_for_states_[ count_state ] );
1810 
1811  npd_variable_indices_for_states_[ count_state ].push_back( std::make_pair( count_npd_index, npditer->first ) );
1812  variable_expressions_for_npd_properties_[ count_npd_index ] =
1813  variable_expressions_[ count_variable_index ] = surrogate;
1814  variable_name_2_variable_exp_index_[ npditer->second ] = count_variable_index;
1815  scalar_expression_map_[ npditer->second ] = variable_expressions_[ count_variable_index ];
1816  }
1817  }
1818 
1819  }
1820 }
1821 
1822 /// @details This method iterates across state_vector_data_file_names_ map,
1823 /// and creates a VariableVectorExpression for each entry. It adds this VariableVectorExpression
1824 /// to the state_vector_variables_ map. For each element in the state_vector_data_file_names_
1825 /// map, and for each state-file-triple held in each particular element, it creates
1826 /// a VariableExpression and pairs the index in the input count_state vector. This
1827 /// VariableExpression is added to three member variables:
1828 /// the variable_expressions_for_states_ vector,
1829 /// the variable_expressions_ vector.
1830 /// Each VariableVectorExpression is given a vector of its set of VariableExpressions
1831 /// in its constructor. It will access these variables directly when it is queried for
1832 /// its vector_values. The indices of the state varaibles are inserted into the
1833 /// state_indices_for_state_vector_ map.
1834 void
1836  Size & count_state,
1837  Size & count_npd_index,
1838  Size & count_variable_index
1839 )
1840 {
1841  for ( std::map< std::string, utility::vector1< StructureFileNames > >::const_iterator
1842  iter = state_vector_data_file_names_.begin(), iter_end = state_vector_data_file_names_.end();
1843  iter != iter_end; ++iter ) {
1844  utility::vector1< Size > indices( iter->second.size() );
1845  utility::vector1< VariableExpressionCOP > variables( iter->second.size() );
1846  std::map< std::string, utility::vector1< VariableExpressionCOP > > npd_property_variables;
1847  bool has_npd_properties = npd_properties_for_state_variables_.find( iter->first ) != npd_properties_for_state_variables_.end();
1848 
1849  for ( Size ii = 1; ii <= iter->second.size(); ++ii ) {
1850  ++count_state;
1851  ++count_variable_index;
1852  std::string ii_varname( iter->first + "_" + utility::to_string( ii ) );
1853  TR << "Adding state " << ii_varname << " with state index " << count_state << std::endl;
1854  variable_expressions_for_states_[ count_state ] =
1855  new VariableExpression( ii_varname, 0.0 );
1856  indices[ ii ] = count_state;
1857  variable_expressions_[ count_variable_index ] = variable_expressions_for_states_[ count_state ];
1858  files_for_state_[ count_state ] = iter->second[ ii ];
1859  variables[ ii ] = variable_expressions_for_states_[ count_state ];
1860  state_variable_name_2_state_index_[ ii_varname ] = count_state;
1861  variable_name_2_variable_exp_index_[ ii_varname ] = count_variable_index;
1862 
1863  /// Create vector expressions for this state and store them in the variable_expressions_for_npd_properties_ array
1864  if ( has_npd_properties ) {
1865  std::list< std::pair< std::string, std::string > > const & npdlist( npd_properties_for_state_variables_[ iter->first ]);
1866  for ( std::list< std::pair< std::string, std::string > >::const_iterator
1867  npditer = npdlist.begin(), npditer_end = npdlist.end();
1868  npditer != npditer_end; ++npditer ) {
1869  ++count_npd_index;
1870  ++count_variable_index;
1871  npd_variable_indices_for_states_[ count_state ].push_back( std::make_pair( count_npd_index, npditer->first ) );
1872  std::string ii_npd_varname = npditer->second + "_" + utility::to_string( ii );
1873  SurrogateVariableExpressionOP surrogate = new SurrogateVariableExpression( ii_npd_varname, 0.0 );
1874  surrogate->root_expression( variable_expressions_for_states_[ count_state ] );
1875  variable_expressions_for_npd_properties_[ count_npd_index ] =
1876  variable_expressions_[ count_variable_index ] = surrogate;
1877  npd_property_variables[ npditer->first ].push_back( variable_expressions_[ count_variable_index ] );
1878  variable_name_2_variable_exp_index_[ ii_npd_varname ] = count_variable_index;
1879  }
1880  }
1881  }
1882  vector_expression_map_[ iter->first ] = state_vector_variables_[ iter->first ] =
1883  new VariableVectorExpression( iter->first, variables );
1884  if ( has_npd_properties ) {
1885  std::list< std::pair< std::string, std::string > > const & npdlist( npd_properties_for_state_variables_[ iter->first ]);
1886  for ( std::list< std::pair< std::string, std::string > >::const_iterator
1887  npditer = npdlist.begin(), npditer_end = npdlist.end();
1888  npditer != npditer_end; ++npditer ) {
1889  //std::string ii_npd_varname = npditer->second + "_" + utility::to_string( ii );
1890  //npd_property_variables[ npditer->first ].push_back( new VariableExpressin( ii_npd_varname, 0.0 ) );
1891  vector_expression_map_[ npditer->second ] = new VariableVectorExpression( npditer->second, npd_property_variables[ npditer->first ] );
1892  }
1893  }
1894  state_indices_for_state_vector_[ iter->first ] = indices;
1895  }
1896 
1897 }
1898 
1899 /// @details creates a variable expression for each sub-expression that will hold the
1900 /// intermediate result of a sub-expression. Increments the count_variable_index input parameter
1901 /// and places the VariableExpression into the variable_expressions_ array into position
1902 /// count_variable_index.
1903 void
1905  std::map< std::string, ArithmeticASTExpressionOP > const & scalar_expression_asts,
1906  std::map< std::string, std::list< std::string > > const & vector_variables,
1907  Size & count_variable_index
1908 )
1909 {
1910  for ( std::map< std::string, ArithmeticASTExpressionOP >::const_iterator
1911  iter = scalar_expression_asts.begin(), iter_end = scalar_expression_asts.end();
1912  iter != iter_end; ++iter ) {
1913  ++count_variable_index;
1914  SurrogateVariableExpressionOP surrogate = new SurrogateVariableExpression( iter->first, 0.0 );
1915  variable_expressions_[ count_variable_index ] = surrogate;
1916  surrogate_expression_map_[ count_variable_index ] = surrogate;
1917  variable_name_2_variable_exp_index_[ iter->first ] = count_variable_index;
1918  scalar_expression_map_[ iter->first ] = variable_expressions_[ count_variable_index ];
1919  }
1920 
1921  for ( std::map< std::string, std::list< std::string > >::const_iterator
1922  vvar_iter = vector_variables.begin(), vvar_iter_end = vector_variables.end();
1923  vvar_iter != vvar_iter_end; ++vvar_iter ) {
1925  variables.reserve( vvar_iter->second.size() );
1926  for ( std::list< std::string >::const_iterator
1927  scalvar_iter = vvar_iter->second.begin(), scalvar_iter_end = vvar_iter->second.end();
1928  scalvar_iter != scalvar_iter_end; ++scalvar_iter ) {
1929  std::map< std::string, VariableExpressionCOP >::const_iterator scvar = scalar_expression_map_.find( *scalvar_iter );
1930  if ( scvar == scalar_expression_map_.end() ) {
1931  throw utility::excn::EXCN_Msg_Exception( "Internal error: could not locate requested scalar variable '"
1932  + *scalvar_iter + "' when constructing the VECTOR_VARIABLE '" + vvar_iter->first );
1933  }
1934  variables.push_back( scvar->second );
1935  }
1936  vector_expression_map_[ vvar_iter->first ] = new VariableVectorExpression( vvar_iter->first, variables );
1937  }
1938 }
1939 
1940 /// @details Turns expression abstract-syntax trees into Expression objects. The
1941 /// VectorExpressionCreator keeps a reference to me so that it can pass control of
1942 /// flow to me when processing variable- and function-construction events.
1943 /// The scalar_expressions_ array is updated to hold the ExpressionOPs for these sub-expressions
1944 /// as pairs each Expression with the corresponding index of its VariableExpression
1945 /// so that I can later update that VariableExpression (held in the variable_expressions_ array)
1946 /// when evaluating that sub-expression.
1947 /// The fitness_exp_ is assigned to the Expression coming from the fitness_expression_ast.
1948 void
1950  std::map< std::string, ArithmeticASTExpressionOP > const & scalar_expression_asts,
1951  std::map< std::string, std::pair< std::map< std::string, std::string >, ArithmeticASTExpressionOP > > const & vector_expression_asts,
1952  ArithmeticASTExpressionOP fitness_expression_ast
1953 )
1954 {
1955  VectorExpressionCreator expression_creator( *this );
1956  // start counting from the number of states (states) -- the sub-expressions start indexing
1957  // at num-states + 1.
1958  //Size count_variable_index = variable_expressions_for_states_.size();
1959  scalar_expressions_.clear();
1960 
1961  ASTPrinter printer;
1962  //printer.pretty( false );
1963 
1964  for( std::list< std::pair< Size, std::string > >::const_iterator
1966  iter != iter_end; ++iter ) {
1967  if ( iter->first == 1 ) {
1968  TR << "Creating scalar expression for " << iter->second << std::endl;
1969  std::map< std::string, ArithmeticASTExpressionOP >::const_iterator ast_iter = scalar_expression_asts.find( iter->second );
1970  if ( ast_iter == scalar_expression_asts.end() ) {
1971  throw utility::excn::EXCN_Msg_Exception( "Internal error. Unable to find scalar expression named '" + iter->second + "' in the scalar_expression_asts map" );
1972  }
1973  TR << "Creating expression from AST:\n" << printer.ast_string( *(ast_iter->second) ) << std::endl;
1974 
1975  ExpressionCOP var_expr = expression_creator.create_expression_tree( *(ast_iter->second) );
1976  Size const variable_index = variable_name_2_variable_exp_index_[ iter->second ];
1977  //++count_variable_index;
1978  scalar_expressions_.push_back( std::make_pair( variable_index, var_expr ));
1979  surrogate_expression_map_[ variable_index ]->root_expression( var_expr );
1980  } else if ( iter->first == 2 ) {
1981  TR << "Creating vector expression for " << iter->second << std::endl;
1982  std::map< std::string, std::pair< std::map< std::string, std::string >, ArithmeticASTExpressionOP > >::const_iterator
1983  ast_iter = vector_expression_asts.find( iter->second );
1984  if ( ast_iter == vector_expression_asts.end() ) {
1985  throw utility::excn::EXCN_Msg_Exception( "Internal error. Unable to find vector expression named '" + iter->second + "' in the vector_expression_asts map" );
1986  }
1987 
1988  std::pair< std::map< std::string, std::string >, ArithmeticASTExpressionOP > const & itvecexp_data =
1989  ast_iter->second;
1990 
1991  /// Create a mapping between the local-variable names and the vector-expression COPs
1992  /// that the local variables are intended to refer to.
1993  std::map< std::string, VectorExpressionCOP > vector_varnames;
1994  for ( std::map< std::string, std::string >::const_iterator
1995  vec_iter = itvecexp_data.first.begin(), vec_iter_end = itvecexp_data.first.end();
1996  vec_iter != vec_iter_end; ++vec_iter ) {
1997  //std::cout << "VectorExpression map: " << vec_iter->first << " " << vec_iter->second << std::endl;
1998  if ( vector_expression_map_.find( vec_iter->second ) == vector_expression_map_.end() ) {
1999  throw utility::excn::EXCN_Msg_Exception( "Variable " + vec_iter->second + " absent from the IterativeVectorExpression name map" );
2000  }
2001  vector_varnames[ vec_iter->first ] = vector_expression_map_[ vec_iter->second ];
2002  }
2003  IterativeVectorExpressionOP ivec_exp = new IterativeVectorExpression( iter->second );
2004 
2005  TR << "Creating expression from AST:\n" << printer.ast_string( *itvecexp_data.second ) << std::endl;
2006 
2007  /// Before initializing the iterative vector expression, I must hold a pointer to it.
2008  /// This allows me to pass control of flow to the iterative vector expression when I
2009  /// am asked to process variable expressions from the expression_creator.
2011  ivec_exp->initialize( vector_varnames, *itvecexp_data.second, expression_creator );
2013 
2014  vector_expression_map_[ iter->second ] = ivec_exp;
2015  }
2016  }
2017 
2018  TR << "Creating fitness expression from AST:\n" << printer.ast_string( *fitness_expression_ast ) << std::endl;
2019  fitness_exp_ = expression_creator.create_expression_tree( *fitness_expression_ast );
2020 
2021 }
2022 
2023 
2024 /// @details Verifies that the args array for a vector function has size 1, and that the sole
2025 /// element is a VectorExpression. Returns an owning-pointer to the downcasted VectorExpression,
2026 /// or throws an exception if the downcast fails.
2029  std::string const & fname,
2030  utility::vector1< ExpressionCOP > const & args,
2031  Size expected_nargs
2032 ) const
2033 {
2034  if ( args.size() != expected_nargs ) {
2035  throw utility::excn::EXCN_Msg_Exception( "vector function expression " + fname + " construction requested with nargs != 1. Nargs= " + utility::to_string( args.size() ) );
2036  }
2037  utility::vector1< VectorExpressionCOP > vector_expressions( expected_nargs );
2038  for ( Size ii = 1; ii <= expected_nargs; ++ii ) {
2039  VectorExpressionCOP vec_ptr = dynamic_cast< VectorExpression const * > ( args[ ii ].get() );
2040  if ( ! vec_ptr ) {
2041  VariableExpressionCOP var_ptr = dynamic_cast< VariableExpression const * > ( args[ ii ].get() );
2042  if ( var_ptr ) {
2043  throw utility::excn::EXCN_Msg_Exception( "vector function expression " + fname + " can only be constructed from a vector expression.\n"
2044  "Variable " + var_ptr->name() + " is not a vector variable." );
2045  } else {
2046  throw utility::excn::EXCN_Msg_Exception( "vector function expression " + fname + " can only be constructed from a vector expression." );
2047  }
2048  }
2049  vector_expressions[ ii ] = vec_ptr;
2050  }
2051  return vector_expressions;
2052 }
2053 
2054 void
2056  std::string const & vname,
2057  std::string const & command_name,
2058  std::string const & line,
2059  Size line_number
2060 )
2061 {
2062  if ( variable_names_dec_line_.find( vname ) != variable_names_dec_line_.end() ) {
2063  throw utility::excn::EXCN_Msg_Exception( "Variable name " + vname + " appears multiple"
2064  " times in the DynamicAggregateFunction file.\nSecond occurrance found while reading a " +
2065  command_name + " command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2066  }
2067  if ( function_names_.find( vname ) != function_names_.end() ) {
2068  throw utility::excn::EXCN_Msg_Exception( "Declaration of variable '" + vname + "' in " + command_name + " command conflicts with a function name. Line "
2069  + utility::to_string( line_number ) + "\n" + line );
2070  }
2071  if ( entity_funcs_.find( vname ) != entity_funcs_.end() ) {
2072  throw utility::excn::EXCN_Msg_Exception( "Declaration of variable '" + vname + "' in " + command_name + " command conflicts"
2073  " with a previously declared EntityFunc variable.\nPrevious declaration was on line "
2074  + utility::to_string( entity_funcs_dec_line_[ vname ] ) + ".\nLine "
2075  + utility::to_string( line_number ) + "\n" + line );
2076 
2077  }
2078  if ( illegal_variable_names_.find( vname ) != illegal_variable_names_.end() ) {
2079  throw utility::excn::EXCN_Msg_Exception( "Illegal name for variable, '" + vname + "' in the " +
2080  command_name + " command on line " + utility::to_string( line_number ) + "\n" + line );
2081  }
2082 
2083 }
2084 
2085 
2086 void
2088 {
2089  /// Look at all the files that need to be read. If any file needs to be read
2090  /// multiple times, then keep the contents of that file in memory until its no longer needed.
2091 
2092  std::map< std::string, Size > total_read_counts_for_files;
2093  std::map< std::string, Size > read_counts_for_files;
2094  count_file_reads( total_read_counts_for_files, read_counts_for_files );
2095 
2096  std::map< std::string, std::string > file_contents;
2097 
2098  /// Distribute the states across the nodes available for this job. Some states will be assigned to this
2099  /// pack daemon, unless there are more nodes than states.
2100 
2101 #ifdef USEMPI
2102  distribute_jobs_to_remote_daemons( daemon_set, total_read_counts_for_files, read_counts_for_files );
2103 #else
2104  initialize_daemon_with_all_states( daemon_set, total_read_counts_for_files, read_counts_for_files );
2105 #endif
2106  daemon_set->setup_daemons();
2107 }
2108 
2109 void
2111  std::map< std::string, Size > & total_reads,
2112  std::map< std::string, Size > & reads_completed
2113 ) const
2114 {
2115  for ( std::map< std::string, StructureFileNames >::const_iterator
2116  iter = named_state_data_file_names_.begin(), iter_end = named_state_data_file_names_.end();
2117  iter != iter_end; ++iter ) {
2118  StructureFileNames const & sfn = iter->second;
2119  increment_total_read_count_for_file( sfn.pdb_name_, total_reads, reads_completed );
2120  increment_total_read_count_for_file( sfn.correspondence_file_name_, total_reads, reads_completed );
2121  increment_total_read_count_for_file( sfn.resfile_name_, total_reads, reads_completed );
2122  }
2123  for ( std::map< std::string, utility::vector1< StructureFileNames > >::const_iterator
2124  iter = state_vector_data_file_names_.begin(), iter_end = state_vector_data_file_names_.end();
2125  iter != iter_end; ++iter ) {
2126  for ( Size ii = 1; ii <= iter->second.size(); ++ii ) {
2127  StructureFileNames const & sfn = iter->second[ ii ];
2128  increment_total_read_count_for_file( sfn.pdb_name_, total_reads, reads_completed );
2129  increment_total_read_count_for_file( sfn.correspondence_file_name_, total_reads, reads_completed );
2130  increment_total_read_count_for_file( sfn.resfile_name_, total_reads, reads_completed );
2131  }
2132  }
2133 
2134 }
2135 
2136 void
2138  std::string const & fname,
2139  std::map< std::string, Size > & total_reads,
2140  std::map< std::string, Size > & reads_completed
2141 ) const
2142 {
2143  std::map< std::string, Size >::iterator iter = total_reads.find( fname );
2144  if ( iter == total_reads.end() ) {
2145  total_reads[ fname ] = 1;
2146  reads_completed[ fname ] = 0;
2147  } else {
2148  ++( iter->second );
2149  }
2150 }
2151 
2154  std::string const & filename,
2155  std::map< std::string, Size > const & total_reads,
2156  std::map< std::string, Size > & reads_completed,
2157  std::map< std::string, std::string > & file_contents_map
2158 ) const
2159 {
2160  std::map< std::string, Size >::const_iterator tr_iter = total_reads.find( filename );
2161  std::map< std::string, Size >::iterator rc_iter = reads_completed.find( filename );
2162  if ( tr_iter == total_reads.end() ) {
2163  throw utility::excn::EXCN_Msg_Exception( "Unexpected file read requested: " + filename );
2164  }
2165  if ( rc_iter == reads_completed.end() ) {
2166  throw utility::excn::EXCN_Msg_Exception( "Reads-completed map does not contain an entry for file: " + filename );
2167  }
2168 
2169  if ( tr_iter->second == 1 ) {
2170  ++reads_completed[ filename ];
2171  std::map< std::string, std::string >::const_iterator fc_iter = file_contents_.find( filename );
2172  if ( fc_iter == file_contents_.end() ) {
2173  return utility::file_contents( filename );
2174  } else {
2175  return fc_iter->second;
2176  }
2177  } else if ( tr_iter->second == rc_iter->second ) {
2178  std::map< std::string, std::string >::iterator fc_iter = file_contents_map.find( filename );
2179  if ( fc_iter == file_contents_map.end() ) {
2180  throw utility::excn::EXCN_Msg_Exception( "file-contents map does not contain an entry for file that has been read before: " + filename );
2181  }
2182  std::string fc = fc_iter->second;
2183  file_contents_map.erase( fc_iter );
2184  return fc;
2185  }
2186 
2187  // else
2188  std::map< std::string, std::string >::const_iterator fc_iter = file_contents_.find( filename );
2189 
2190  std::string fc = ( fc_iter == file_contents_.end() ? utility::file_contents( filename ) : fc_iter->second);
2191  file_contents_map[ filename ] = fc;
2192  ++(rc_iter->second);
2193  return fc;
2194 
2195 }
2196 
2197 void
2199  DaemonSetOP daemon_set,
2200  std::map< std::string, Size > const & total_reads,
2201  std::map< std::string, Size > & reads_completed
2202 )
2203 {
2204  int nstructs = variable_expressions_for_states_.size();
2205  std::list< int > joblist;
2206  for ( int ii = 1; ii <= nstructs; ++ii ) joblist.push_back( ii );
2207  std::map< std::string, std::string > file_contents_map;
2208 
2209  // move to try-catch block --- assign_jobs_to_local_daemon_set( joblist, daemon_set, total_reads, reads_completed, file_contents_map );
2210 
2211  try {
2212  assign_jobs_to_local_daemon_set( joblist, daemon_set, total_reads, reads_completed, file_contents_map );
2213  } catch ( utility::excn::EXCN_Msg_Exception & e ) {
2214  TR << "Error from daemon-set initialization \n";
2215  TR << e.msg();
2216  TR << std::endl;
2217  throw e;
2218  }
2219 
2220 
2221 }
2222 
2223 
2224 void
2226  DaemonSetOP daemon_set,
2227  std::map< std::string, Size > const & total_reads,
2228  std::map< std::string, Size > & reads_completed
2229 )
2230 {
2231  std::map< std::string, std::string > file_contents_map;
2232 
2233  int MPI_nprocs = utility::mpi_nprocs();
2234  int nstructs = variable_expressions_for_states_.size();
2235 
2236  int njobs_per_cpu = static_cast< int > ( std::ceil( (double) nstructs / MPI_nprocs ));
2237  /// Assign myself fewer states than to all other nodes if the number of states is not evenly divisible
2238  /// by the number of processors.
2239 
2240  int overhang = njobs_per_cpu * MPI_nprocs - nstructs;
2241 
2242  utility::vector0< std::list< int > > job_assignments( MPI_nprocs );
2243  if ( overhang == 0 ) {
2244  int state_count = 0;
2245  for ( int ii = 0; ii < MPI_nprocs; ++ii ) {
2246  for ( int jj = 1; jj <= njobs_per_cpu; ++jj ) {
2247  ++state_count;
2248  job_assignments[ ii ].push_back( state_count );
2249  }
2250  }
2251  } else if ( overhang == 1 && njobs_per_cpu == 1 ) {
2252  int state_count = 0;
2253  for ( int ii = 1; ii < MPI_nprocs; ++ii ) {
2254  ++state_count;
2255  job_assignments[ ii ].push_back( state_count );
2256  }
2257  } else {
2258  int state_count = 0;
2259  for ( int ii = 0; ii < MPI_nprocs; ++ii ) {
2260  int ii_n_jobs = ii < overhang ? njobs_per_cpu - 1 : njobs_per_cpu;
2261  for ( int jj = 1; jj <= ii_n_jobs; ++jj ) {
2262  ++state_count;
2263  job_assignments[ ii ].push_back( state_count );
2264  }
2265  }
2266  }
2267 
2268  // Now assign jobs to nodes.
2269  for ( int ii = 1; ii < MPI_nprocs; ++ii ) {
2270  assign_jobs_to_remote_daemon_sets( ii, job_assignments[ ii ], total_reads, reads_completed, file_contents_map );
2271  }
2272  bool jobs_successfully_initialized( true );
2273 
2275 
2276  try {
2277  assign_jobs_to_local_daemon_set( job_assignments[ 0 ], daemon_set, total_reads, reads_completed, file_contents_map );
2278  } catch ( utility::excn::EXCN_Msg_Exception & e ) {
2279  error_message += "Error from node 0\n";
2280  error_message += e.msg();
2281  TR << e.msg() << std::endl;
2282  jobs_successfully_initialized = false;
2283  }
2284 
2285  for ( int ii = 1; ii < MPI_nprocs; ++ii ) {
2287  error_message += "Error from node " + utility::to_string( ii ) + "\n";
2288  std::string remote_message = utility::receive_string_from_node( ii );
2289  error_message += remote_message + "\n";
2290  TR << remote_message << std::endl;
2291  jobs_successfully_initialized = false;
2292  }
2293  }
2294 
2295  if ( jobs_successfully_initialized ) {
2296  for ( int ii = 1; ii < MPI_nprocs; ++ii ) {
2298  }
2299  } else {
2301 #ifdef USEMPI
2302  MPI_Finalize();
2303 #endif
2304  utility_exit_with_message( error_message );
2305  }
2306 }
2307 
2308 StructureFileNames const &
2310 {
2311  return files_for_state_[ job_index ];
2312 }
2313 
2314 
2315 void
2317  std::list< int > const & job_indices,
2318  DaemonSetOP daemon_set,
2319  std::map< std::string, Size > const & tr /*total_reads*/,
2320  std::map< std::string, Size > & rc /*reads_completed*/,
2321  std::map< std::string, std::string > & fcm /*file_contents_map*/
2322 ) const
2323 {
2324  for ( std::list< int >::const_iterator iter = job_indices.begin(),
2325  iter_end = job_indices.end(); iter != iter_end; ++iter ) {
2326  int state_id = *iter;
2327  StructureFileNames const & sfn = file_inputs_for_job( state_id );
2328  core::pose::Pose pose;
2330  std::istringstream corr_stream( get_file_contents( sfn.correspondence_file_name_, tr, rc, fcm ) );
2331  std::istringstream resfile_stream( get_file_contents( sfn.resfile_name_, tr, rc, fcm ) );
2332  daemon_set->add_pack_daemon(
2333  state_id,
2334  sfn.pdb_name_,
2335  pose,
2337  corr_stream,
2338  sfn.resfile_name_,
2339  resfile_stream );
2340  for ( std::list< std::pair< Size, std::string > >::const_iterator
2341  npditer = npd_variable_indices_for_states_[ state_id ].begin(),
2342  npditer_end = npd_variable_indices_for_states_[ state_id ].end();
2343  npditer != npditer_end; ++npditer ) {
2344  daemon_set->add_npd_property_calculator_for_state( state_id, npditer->second, npditer->first );
2345  }
2346  }
2347 
2348 }
2349 
2350 void
2352  int proc_id,
2353  std::list< int > const & job_indices,
2354  std::map< std::string, Size > const & tr /*total_reads*/,
2355  std::map< std::string, Size > & rc /*reads_completed*/,
2356  std::map< std::string, std::string > & fcm /*file_contents_map*/
2357 ) const
2358 {
2359  utility::send_integer_to_node( proc_id, add_daemon );
2360 
2361  int ndaemons = job_indices.size();
2362  utility::send_integer_to_node( proc_id, ndaemons );
2363  for ( std::list< int >::const_iterator iter = job_indices.begin(),
2364  iter_end = job_indices.end(); iter != iter_end; ++iter ) {
2365  int state_id = *iter;
2366  StructureFileNames const & sfn = file_inputs_for_job( state_id );
2367  utility::send_integer_to_node( proc_id, state_id );
2368  utility::send_string_to_node( proc_id, sfn.pdb_name_ );
2369  utility::send_string_to_node( proc_id, get_file_contents( sfn.pdb_name_, tr, rc, fcm ));
2370  utility::send_string_to_node( proc_id, sfn.correspondence_file_name_ );
2371  utility::send_string_to_node( proc_id, get_file_contents( sfn.correspondence_file_name_, tr, rc, fcm ));
2372  utility::send_string_to_node( proc_id, sfn.resfile_name_ );
2373  utility::send_string_to_node( proc_id, get_file_contents( sfn.resfile_name_, tr, rc, fcm ));
2374  int n_npd_properties_to_send = npd_variable_indices_for_states_[ state_id ].size();
2375  utility::send_integer_to_node( proc_id, n_npd_properties_to_send );
2376  //int count_npd = 0;
2377  for ( std::list< std::pair< Size, std::string > >::const_iterator
2378  npditer = npd_variable_indices_for_states_[ state_id ].begin(),
2379  npditer_end = npd_variable_indices_for_states_[ state_id ].end();
2380  npditer != npditer_end; ++npditer) {
2381  //++count_npd;
2382  utility::send_integer_to_node( proc_id, npditer->first );
2383  utility::send_string_to_node( proc_id, npditer->second );
2384  }
2385  }
2386 
2387 }
2388 
2390 {
2391  int message = utility::receive_integer_from_node( proc_id );
2392  if ( message == success_message ) return true;
2393  if ( message == error_message ) return false;
2394 
2395  throw utility::excn::EXCN_Msg_Exception( "Expected either a success_message or an error_message "
2396  "after initializing remote daemon sets from process " +
2397  utility::to_string( proc_id ) + " but received " + utility::to_string( message ) );
2398  return false;
2399 }
2400 
2401 
2403 {
2404  utility::send_integer_to_node( proc_id, success_message );
2405 }
2406 
2408 {
2409  int MPI_nprocs = utility::mpi_nprocs();
2410  for ( int ii = 1; ii < MPI_nprocs; ++ii ) {
2411  utility::send_integer_to_node( ii, error_message );
2412  }
2413 }
2414 
2415 void
2417  StateEnergies const & state_energies,
2418  StateEnergies const & npd_properties,
2419  Entity const & entity,
2420  bool verbose
2421 )
2422 {
2423  for ( std::map< std::string, std::pair< EntityFuncOP, VariableExpressionOP > >::const_iterator
2424  iter = entity_funcs_.begin(), iter_end = entity_funcs_.end();
2425  iter != iter_end; ++iter ) {
2426  core::Real entity_func_value = iter->second.first->evaluate( entity, verbose );
2427  iter->second.second->set_value( entity_func_value );
2428  if ( verbose ) {
2429  TR << "EntityFunc:: total for " << iter->second.second->name() << " " << entity_func_value << std::endl;
2430  }
2431  }
2432 
2433  for ( Size ii = 1; ii <= variable_expressions_for_states_.size(); ++ii ) {
2434  if ( verbose ) {
2435  TR << "Assigning value " << state_energies[ ii ] << " to VariableExpression " << ii << std::endl;
2436  }
2437  variable_expressions_for_states_[ ii ]->set_value( state_energies[ ii ] );
2438  }
2439  for ( Size ii = 1; ii <= npd_properties.size(); ++ii ) {
2440  variable_expressions_for_npd_properties_[ ii ]->set_value( npd_properties[ ii ] );
2441  }
2442 
2443  //TR << "Finished variable expression assignment " << std::endl;
2444  for ( Size ii = 1; ii <= scalar_expressions_.size(); ++ii ) {
2445  //TR << "Sub expression index " << ii << std::endl;
2446  //TR << "At " << scalar_expressions_[ ii ].second() << std::endl;
2447  //TR << "Evaluating sub_expression " << scalar_expressions_[ ii ].second->name() << std::endl;
2448  variable_expressions_[ scalar_expressions_[ ii ].first ]->set_value( (*(scalar_expressions_[ ii ].second))() );
2449  if ( verbose ) {
2450  TR << "sub expression " << variable_expressions_[ scalar_expressions_[ ii ].first ]->name()
2451  << " evaluated to " << (*variable_expressions_[ scalar_expressions_[ ii ].first ]) () << std::endl;
2452  }
2453  }
2454 }
2455 
2456 
2457 core::Size
2459 {
2460  Size count( 0 );
2461  /// 1. count the npd properties for states declared with the STATE command
2462  for ( std::map< std::string, StructureFileNames >::const_iterator
2463  iter = named_state_data_file_names_.begin(), iter_end = named_state_data_file_names_.end();
2464  iter != iter_end; ++iter ) {
2465  if ( npd_properties_for_state_variables_.find( iter->first ) != npd_properties_for_state_variables_.end() ) {
2466  count += npd_properties_for_state_variables_.find( iter->first )->second.size();
2467  }
2468  }
2469  /// 2. count the npd properties for the states decalred with the STATE_VECTOR command
2470  for ( std::map< std::string, utility::vector1< StructureFileNames > >::const_iterator
2471  iter = state_vector_data_file_names_.begin(), iter_end = state_vector_data_file_names_.end();
2472  iter != iter_end; ++iter ) {
2473  if ( npd_properties_for_state_variables_.find( iter->first ) != npd_properties_for_state_variables_.end() ) {
2474  count += npd_properties_for_state_variables_.find( iter->first )->second.size() * iter->second.size();
2475  }
2476  }
2477  return count;
2478 }
2479 
2480 ////////////////////////////////////////////////
2481 ///////// EntityFuncExpressionCreator //////////
2482 ////////////////////////////////////////////////
2483 
2485  EntityFunc const & owner
2486 ) :
2487  owner_( owner )
2488 {}
2489 
2491 {}
2492 
2493 ExpressionCOP
2495  ArithmeticASTValue const & node
2496 )
2497 {
2498  return owner_.variable_expression( node );
2499 }
2500 
2501 ExpressionCOP
2503  FunctionTokenCOP function,
2505 )
2506 {
2507  return owner_.function_expression( function, args );
2508 }
2509 
2510 
2511 ////////////////////////////////////////////////
2512 ////////////////// Entity Funct ////////////////
2513 ////////////////////////////////////////////////
2514 
2516  num_entity_elements_( 0 )
2517 {}
2518 
2520 {
2521 }
2522 
2524 {
2525  num_entity_elements_ = num_ees;
2526 }
2527 
2528 void EntityFunc::initialize_from_input_file( std::istream & input )
2529 {
2530  if ( num_entity_elements_ == 0 ) {
2531  throw utility::excn::EXCN_Msg_Exception( "EntityFunc::initialize_from_input_file cannot be called without EntityFunc::set_num_entity_elements having first been called." );
2532  }
2533 
2535  std::map< std::string, ArithmeticASTExpressionOP > expression_asts;
2536  ArithmeticASTExpressionOP score_expression_ast( 0 );
2537  Size count_line( 0 );
2538 
2539  while ( input ) {
2540  ++count_line;
2541  std::string line;
2542  std::getline( ( std::istream & ) input, line );
2543  if ( line.size() == 0 ) continue; // skip blank lines
2544 
2545  std::istringstream input_line( line );
2546  if ( input_line.peek() == '#' ) continue; // skip comment lines
2547  std::string command;
2548  input_line >> command;
2549  if ( command == "AA_SET" ) {
2550  process_AA_SET_line( line, count_line, input_line );
2551  } else if ( command == "SET_CONDITION" ) {
2552  process_SET_CONDITION_line( line, count_line, input_line );
2553  } else if ( command == "SUB_EXPRESSION" ) {
2554  process_SUB_EXPRESSION_line( line, count_line, input_line, expression_asts );
2555  } else if ( command == "SCORE" ) {
2556  process_SCORE_line( line, count_line, input_line, score_expression_ast );
2557  } else {
2558  throw utility::excn::EXCN_Msg_Exception( "Unable to recognize command '" + command + "' while reading EntityFunc file" );
2559  }
2560  }
2561 
2562  if ( ! score_expression_ast ) {
2563  throw utility::excn::EXCN_Msg_Exception( "SCORE command was not found in EntityFunc file." );
2564  }
2565  turn_expression_ASTs_into_expressions( expression_asts, score_expression_ast );
2566 
2567 }
2568 
2569 core::Real
2570 EntityFunc::evaluate( Entity const & entity, bool verbose )
2571 {
2573  for ( Size ii = 1; ii <= expression_evaluation_order_.size(); ++ii ) {
2574  core::Real iival = (*expression_evaluation_order_[ ii ].first )();
2575  expression_evaluation_order_[ ii ].second->set_value( iival );
2576  if ( verbose ) {
2577  TR << "EntityFunc::evaluate " << expression_evaluation_order_[ ii ].second->name() << " " << iival << std::endl;
2578  }
2579  }
2580  return (*score_expression_)();
2581 }
2582 
2583 ExpressionCOP
2584 EntityFunc::variable_expression( ArithmeticASTValue const & var_node ) const
2585 {
2586  if ( var_node.is_literal() ) {
2587  utility_exit_with_message( "Error in EntityFunc::variable_expression; non-variable (literal) node recieved" +
2588  utility::to_string( var_node.literal_value() ));
2589  }
2590 
2591  std::map< std::string, VariableExpressionOP >::const_iterator var_iter =
2592  variable_expression_map_.find( var_node.variable_name() );
2593  if ( var_iter != variable_expression_map_.end() ) {
2594  return var_iter->second;
2595  }
2596 
2597  throw utility::excn::EXCN_Msg_Exception( "Unable to find variable with name " + var_node.variable_name() + " in"
2598  " EntityFunc while trying to build expression trees for the expressions already tokenized and parsed.\n"
2599  "Cannot continue. Contact Andrew Leaver-Fay (aleaverfay@gmail.com)" );
2600  return 0;
2601 }
2602 
2603 ExpressionCOP
2605  FunctionTokenCOP function,
2607 ) const
2608 {
2609  std::string const fname = function->name();
2610  if ( fname == "max" ) {
2611  return new MaxExpression( args[ 1 ], args[ 2 ] );
2612  } else if ( fname == "min" ) {
2613  return new MinExpression( args[ 1 ], args[ 2 ] );
2614  } else if ( fname == "exp" ) {
2615  if ( args.size() != 1 ) {
2616  throw utility::excn::EXCN_Msg_Exception( "exp expression construction requested with more than one argument: " + utility::to_string( args.size() ) );
2617  }
2618  return new ExpExpression( args[ 1 ] );
2619  } else if ( fname == "ln" ) {
2620  if ( args.size() != 1 ) {
2621  throw utility::excn::EXCN_Msg_Exception( "ln expression construction requested with more than one argument: " + utility::to_string( args.size() ) );
2622  }
2623  return new LnExpression( args[ 1 ] );
2624  } else if ( fname == "pow" ) {
2625  if ( args.size() != 2 ) {
2626  throw utility::excn::EXCN_Msg_Exception( "pow expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
2627  }
2628  return new PowExpression( args[ 1 ], args[ 2 ] );
2629  } else if ( fname == "ite" ) {
2630  if ( args.size() != 3 ) {
2631  throw utility::excn::EXCN_Msg_Exception( "ite expression construction requested with nargs != 3. Nargs= " + utility::to_string( args.size() ) );
2632  }
2633  return new ITEExpression( args[ 1 ], args[ 2 ], args[ 3 ] );
2634  } else if ( fname == "abs" ) {
2635  if ( args.size() != 1 ) {
2636  throw utility::excn::EXCN_Msg_Exception( "abs expression construction requested with nargs != 1. Nargs= " + utility::to_string( args.size() ) );
2637  }
2638  return new AbsoluteValueExpression( args[ 1 ] );
2639  } else if ( fname == "gt" ) {
2640  if ( args.size() != 2 ) {
2641  throw utility::excn::EXCN_Msg_Exception( "gt expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
2642  }
2643  return new GT_Expression( args[ 1 ], args[ 2 ] );
2644  } else if ( fname == "lt" ) {
2645  if ( args.size() != 2 ) {
2646  throw utility::excn::EXCN_Msg_Exception( "lt expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
2647  }
2648  return new LT_Expression( args[ 1 ], args[ 2 ] );
2649  } else if ( fname == "gte" ) {
2650  if ( args.size() != 2 ) {
2651  throw utility::excn::EXCN_Msg_Exception( "gte expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
2652  }
2653  return new GTE_Expression( args[ 1 ], args[ 2 ] );
2654  } else if ( fname == "lte" ) {
2655  if ( args.size() != 2 ) {
2656  throw utility::excn::EXCN_Msg_Exception( "lte expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
2657  }
2658  return new LTE_Expression( args[ 1 ], args[ 2 ] );
2659  } else if ( fname == "eq" ) {
2660  if ( args.size() != 2 ) {
2661  throw utility::excn::EXCN_Msg_Exception( "eq expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
2662  }
2663  return new EqualsExpression( args[ 1 ], args[ 2 ] );
2664  } else if ( fname == "and" ) {
2665  if ( args.size() != 2 ) {
2666  throw utility::excn::EXCN_Msg_Exception( "and expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
2667  }
2668  return new AndExpression( args[ 1 ], args[ 2 ] );
2669  } else if ( fname == "or" ) {
2670  if ( args.size() != 2 ) {
2671  throw utility::excn::EXCN_Msg_Exception( "or expression construction requested with nargs != 2. Nargs= " + utility::to_string( args.size() ) );
2672  }
2673  return new OrExpression( args[ 1 ], args[ 2 ] );
2674  } else if ( fname == "not" ) {
2675  if ( args.size() != 1 ) {
2676  throw utility::excn::EXCN_Msg_Exception( "not expression construction requested with nargs != 1. Nargs= " + utility::to_string( args.size() ) );
2677  }
2678  return new NotExpression( args[ 1 ] );
2679  }
2680 
2681  throw utility::excn::EXCN_Msg_Exception( "Unable to find function with name " + fname + " in"
2682  " EntityFunc while trying to build expression trees for the expressions already tokenized and parsed.\n"
2683  "Cannot continue. Contact Andrew Leaver-Fay (aleaverfay@gmail.com)" );
2684  return 0;
2685 
2686 }
2687 
2688 void
2690 {
2691  scanner_ = new ArithmeticScanner( false );
2692  scanner_->add_function( "sqrt", 1 );
2693  scanner_->add_function( "max", 2 );
2694  scanner_->add_function( "min", 2 );
2695  scanner_->add_function( "exp", 1 );
2696  scanner_->add_function( "pow", 2 );
2697  scanner_->add_function( "ite", 3 );
2698  scanner_->add_function( "ln", 1 );
2699  scanner_->add_function( "abs", 1 );
2700  scanner_->add_function( "gt", 2 );
2701  scanner_->add_function( "lt", 2 );
2702  scanner_->add_function( "gte", 2 );
2703  scanner_->add_function( "lte", 2 );
2704  scanner_->add_function( "eq", 2 );
2705  scanner_->add_function( "and", 2 );
2706  scanner_->add_function( "or", 2 );
2707  scanner_->add_function( "not", 1 );
2708 
2709  function_names_.clear();
2710  function_names_.insert( "max" );
2711  function_names_.insert( "min" );
2712  function_names_.insert( "ln" );
2713  function_names_.insert( "pow" );
2714  function_names_.insert( "exp" );
2715  function_names_.insert( "sqrt" );
2716  function_names_.insert( "ite" );
2717  function_names_.insert( "abs" );
2718  function_names_.insert( "gt" );
2719  function_names_.insert( "lt" );
2720  function_names_.insert( "gte" );
2721  function_names_.insert( "lte" );
2722  function_names_.insert( "eq" );
2723  function_names_.insert( "and" );
2724  function_names_.insert( "or" );
2725  function_names_.insert( "not" );
2726 
2727  illegal_variable_names_.clear();
2728  illegal_variable_names_.insert( "in" );
2729  //illegal_variable_names_.insert( "" ); // what else don't I want to exclude?
2730 
2731  // Add variable names for the entity elements
2733  for ( Size ii = 1; ii <= num_entity_elements_; ++ii ) {
2734  std::string ii_name = "ee_" + utility::to_string( ii );
2735  scanner_->add_variable( ii_name );
2736  VariableExpressionOP ee_var_expression = new VariableExpression( ii_name, 0.0 );
2737  entity_aas_[ ii ] = ee_var_expression;
2738  variable_expression_map_[ ii_name ] = ee_var_expression;
2739  subexpression_name_map_[ ii_name ] = ee_var_expression;
2740  subexpression_name_dec_line_[ ii_name ] = 0;
2741  }
2742 }
2743 
2744 void
2746  std::string const & line,
2747  Size line_number,
2748  std::istream & input_line
2749 )
2750 {
2751  if ( ! input_line ) {
2752  throw utility::excn::EXCN_Msg_Exception( "Expected to read amino acid set name in the EntityFunc"
2753  " input file after reading AA_SET on line " + utility::to_string( line_number ) + "\n" + line );
2754  }
2755  std::string aa_setname;
2756  input_line >> aa_setname;
2757  if ( aa_setname.size() == 0 ) {
2758  throw utility::excn::EXCN_Msg_Exception( "Expected to read amino acid set name in the EntityFunc"
2759  " input file after reading AA_SET on line " + utility::to_string( line_number ) + "\n" + line );
2760  }
2761  if ( aa_sets_name_map_.find( aa_setname ) != aa_sets_name_map_.end() ) {
2762  throw utility::excn::EXCN_Msg_Exception( "Amino-acid-set name '" + aa_setname + "' appears multiple"
2763  " times in the EntityFunc file.\nFirst occurrance was found on line " +
2764  utility::to_string( aa_sets_dec_line_[ aa_setname ] ) +
2765  ". Second occurrance found while reading"
2766  " AA_SET command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2767  }
2768 
2769  if ( subexpression_name_map_.find( aa_setname ) != subexpression_name_map_.end() ) {
2770  if ( subexpression_name_dec_line_[ aa_setname ] != 0 ) {
2771  throw utility::excn::EXCN_Msg_Exception( "Illegal amino-acid-set name '" + aa_setname + "' which was previously"
2772  " declared in the EntityFunc file as a sub-expression.\nFirst occurrance was found on line " +
2773  utility::to_string( subexpression_name_dec_line_[ aa_setname ] ) +
2774  ". Second occurrance found while reading"
2775  " AA_SET command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2776  } else {
2777  throw utility::excn::EXCN_Msg_Exception( "Illegal amino-acid-set name '" + aa_setname + "' which is reserved"
2778  " as a name for an entity-element variable.\nError found while reading"
2779  " AA_SET command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2780  }
2781  }
2782 
2783  if ( function_names_.find( aa_setname ) != function_names_.end() ) {
2784  throw utility::excn::EXCN_Msg_Exception( "Illegal amino-acid-set name '" + aa_setname + "' which is reserved"
2785  " as a name for an funcion.\nError encountered while reading"
2786  " AA_SET command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2787  }
2788 
2789  if ( illegal_variable_names_.find( aa_setname ) != illegal_variable_names_.end() ) {
2790  throw utility::excn::EXCN_Msg_Exception( "Illegal amino-acid-set name '" + aa_setname + "' which is a reserved"
2791  " word for this input file format.\nError encountered while reading"
2792  " AA_SET command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2793  }
2794 
2795  /// whitespace is fine to separate the aaset from the equals sign.
2796  char equals_sign( ' ' );
2797  while ( equals_sign == ' ' || equals_sign == '\t' ) {
2798  if ( !input_line ) {
2799  throw utility::excn::EXCN_Msg_Exception( "Expected to read an equals sign after reading amino-acid-set name'"
2800  + aa_setname + "' but found an end-of-line.\nError encountered while reading"
2801  " AA_SET command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2802  }
2803  input_line.get( equals_sign );
2804  }
2805  if ( equals_sign != '=' ) {
2806  throw utility::excn::EXCN_Msg_Exception( "Expected to read an equals sign after reading amino-acid-set name'"
2807  + aa_setname + "' but found '" + equals_sign + "'\nError encountered while reading"
2808  " AA_SET command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2809  }
2810 
2811  /// whitespace is fine to separate the equals sign from the left curly bracket.
2812  char lcurly = ' ';
2813  while ( lcurly == ' ' || lcurly == '\t' ) {
2814  if ( !input_line ) {
2815  throw utility::excn::EXCN_Msg_Exception( "Expected to read a left curly bracket ('{') after reading"
2816  " an equals sign, but found an end-of-line.\nError encountered while reading"
2817  " AA_SET command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2818  }
2819  input_line.get( lcurly );
2820  }
2821  if ( lcurly != '{' ) {
2822  throw utility::excn::EXCN_Msg_Exception( "Expected to read a left curly bracket ('{') after reading"
2823  " an equals sign, but found '" + utility::to_string( lcurly ) + "'\nError encountered while reading"
2824  " AA_SET command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2825  }
2826 
2827  utility::vector1< core::Real > aas_in_set;
2828 
2829  char next_aa = ' ';
2830  while ( next_aa != '}' ) {
2831  while ( next_aa == ' ' || next_aa == '\t' ) {
2832  if ( !input_line ) {
2833  throw utility::excn::EXCN_Msg_Exception( "Expected to read a right curly bracket ('}') or a 1-letter"
2834  " amino acid code, but found an end-of-line.\nError encountered while reading"
2835  " AA_SET command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2836  }
2837  input_line.get( next_aa );
2838  }
2839  if ( next_aa == '}' ) break;
2840  if ( core::chemical::oneletter_code_specifies_aa( toupper( next_aa )) ) {
2841  aas_in_set.push_back( core::chemical::aa_from_oneletter_code( toupper( next_aa )) );
2842  } else {
2843  /// maybe later, if we want to include ncaa's then they're parsing will happen right here.
2844  /// but for now, no go.
2845  throw utility::excn::EXCN_Msg_Exception( "Expected to read a 1-letter"
2846  " amino acid code or a right curly brace, but found '" + utility::to_string( next_aa ) + "'.\n"
2847  "Error encountered while reading AA_SET command\n" + line + "\n"
2848  "Line # " + utility::to_string( line_number ) );
2849  }
2850  next_aa = ' ';
2851  while ( next_aa == ' ' || next_aa == '\t' ) {
2852  if ( !input_line ) {
2853  throw utility::excn::EXCN_Msg_Exception( "Expected to read a right curly bracket ('}') or a 1-letter"
2854  " amino acid code, but found an end-of-line.\nError encountered while reading"
2855  " AA_SET command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2856  }
2857  input_line.get( next_aa );
2858  }
2859  if ( next_aa == '}' ) break;
2860  if ( next_aa == ',' ) {
2861  next_aa = ' ';
2862  continue;
2863  }
2864  throw utility::excn::EXCN_Msg_Exception( "Expected to read comma"
2865  " or a right curly brace, but found '" + utility::to_string( next_aa ) + "'.\n"
2866  "Error encountered while reading AA_SET command\n" + line + "\n"
2867  "Line # " + utility::to_string( line_number ) );
2868  }
2869 
2870  /// The rest of the line is ignored.
2871 
2872  /// OK we made it this far -- now keep track of the aas that define this set.
2873  aa_sets_name_map_[ aa_setname ] = aas_in_set;
2874  aa_sets_dec_line_[ aa_setname ] = line_number;
2875 }
2876 
2877 void
2879  std::string const & line,
2880  Size line_number,
2881  std::istream & input_line
2882 )
2883 {
2884  if ( ! input_line ) {
2885  throw utility::excn::EXCN_Msg_Exception( "Expected to read a set-condition name in the EntityFunc"
2886  " input file after reading SET_CONDITION on line " + utility::to_string( line_number ) + "\n" + line );
2887  }
2888  std::string condition_name;
2889  input_line >> condition_name;
2890  if ( condition_name.size() == 0 ) {
2891  throw utility::excn::EXCN_Msg_Exception( "Expected to read a set-condition name in the EntityFunc"
2892  " input file after reading SET_CONDITION on line " + utility::to_string( line_number ) + "\n" + line );
2893  }
2894  if ( aa_sets_name_map_.find( condition_name ) != aa_sets_name_map_.end() ) {
2895  throw utility::excn::EXCN_Msg_Exception( "Set-condition name '" + condition_name + "' appears multiple"
2896  " times in the EntityFunc file.\nFirst occurrance was found on line " +
2897  utility::to_string( aa_sets_dec_line_[ condition_name ] ) +
2898  ". Second occurrance found while reading"
2899  " SET_CONDITION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2900  }
2901 
2902  if ( subexpression_name_map_.find( condition_name ) != subexpression_name_map_.end() ) {
2903  if ( subexpression_name_dec_line_[ condition_name ] != 0 ) {
2904  throw utility::excn::EXCN_Msg_Exception( "Illegal set-condition name '" + condition_name + "' which was previously"
2905  " declared in the EntityFunc file as a sub-expression.\nFirst occurrance was found on line " +
2906  utility::to_string( subexpression_name_dec_line_[ condition_name ] ) +
2907  ". Second occurrance found while reading"
2908  " SET_CONDITION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2909  } else {
2910  throw utility::excn::EXCN_Msg_Exception( "Illegal set-condition name '" + condition_name + "' which is reserved"
2911  " as a name for an entity-element variable.\nError found while reading"
2912  " SET_CONDITION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2913  }
2914  }
2915 
2916  if ( function_names_.find( condition_name ) != function_names_.end() ) {
2917  throw utility::excn::EXCN_Msg_Exception( "Illegal set-condition name '" + condition_name + "' which is reserved"
2918  " as a name for an funcion.\nError encountered while reading"
2919  " SET_CONDITION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2920  }
2921 
2922  if ( illegal_variable_names_.find( condition_name ) != illegal_variable_names_.end() ) {
2923  throw utility::excn::EXCN_Msg_Exception( "Illegal set-condition name '" + condition_name + "' which is a reserved"
2924  " word for this input file format.\nError encountered while reading"
2925  " SET_CONDITION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2926  }
2927  /// now read an equals sign.
2928  /// whitespace is fine to separate the set-condition name from the equals sign.
2929  char equals_sign( ' ' );
2930  while ( equals_sign == ' ' || equals_sign == '\t' ) {
2931  if ( !input_line ) {
2932  throw utility::excn::EXCN_Msg_Exception( "Expected to read an equals sign after reading the set-condition name'"
2933  + condition_name + "' but found an end-of-line.\nError encountered while reading"
2934  " SET_CONDITION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2935  }
2936  input_line >> equals_sign;
2937  }
2938  if ( equals_sign != '=' ) {
2939  throw utility::excn::EXCN_Msg_Exception( "Expected to read an equals sign after reading amino-acid-set name'"
2940  + condition_name + "' but found '" + utility::to_string( equals_sign ) + "'\nError encountered while reading"
2941  " SET_CONDITION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2942  }
2943 
2944  /// now read the name of the entity-element that we're going to be examining.
2945  if ( ! input_line ) {
2946  throw utility::excn::EXCN_Msg_Exception( "Expected to read the entity-element name in the EntityFunc"
2947  " input file after reading the set condition name, \"" + condition_name + ",\" but found an end-of-line.\n"
2948  "Error encountered while reading SET_CONDITION command on line " + utility::to_string( line_number ) + "\n" + line );
2949  }
2950  std::string eename;
2951  input_line >> eename;
2952  if ( subexpression_name_dec_line_.find( eename ) == subexpression_name_dec_line_.end() ) {
2953  throw utility::excn::EXCN_Msg_Exception( "Expected to read an entity-element name in the EntityFunc"
2954  " input file after reading an equals sign, while processing the set-condition named \"" + condition_name + ",\" but"
2955  " found \"" + eename +"\" which is not a valid entity element name.\n"
2956  "There are " + utility::to_string( num_entity_elements_ ) + " defined for this EntityFunc.\n"
2957  "Entity-element variables should be named ee_1 through ee_" + utility::to_string( num_entity_elements_ ) + ".\n"
2958  "Error encountered while reading SET_CONDITION command on line " + utility::to_string( line_number ) + "\n" + line );
2959  }
2960  if ( subexpression_name_dec_line_[ eename ] != 0 ) {
2961  throw utility::excn::EXCN_Msg_Exception( "Expected to read an entity-element name in the EntityFunc"
2962  " input file after reading an equals sign, while processing the set-condition named \"" + condition_name + ",\" but"
2963  " found the named subexpression \"" + eename +"\" instead.\n"
2964  "Error encountered while reading SET_CONDITION command on line " + utility::to_string( line_number ) + "\n" + line );
2965  }
2966 
2967  if ( ! input_line ) {
2968  throw utility::excn::EXCN_Msg_Exception( "Expected to read the string \"in\" in the EntityFunc"
2969  " input file after reading the set condition name, \"" + condition_name + ",\" but found an end-of-line.\n"
2970  "Error encountered while reading SET_CONDITION command on line " + utility::to_string( line_number ) + "\n" + line );
2971  }
2972 
2973  /// now read the "in" string
2974  std::string in_string;
2975  input_line >> in_string;
2976  if ( in_string != "in" ) {
2977  throw utility::excn::EXCN_Msg_Exception( "Expected to read the string \"in\" in the EntityFunc"
2978  " input file after reading the set condition name, \"" + condition_name + ",\" but found \"" +
2979  in_string + "\" instead.\n"
2980  "Error encountered while reading SET_CONDITION command on line " + utility::to_string( line_number ) + "\n" + line );
2981  }
2982 
2983  char next_char = ' ';
2984  while ( input_line.peek() == ' ' || input_line.peek() == '\t' ) {
2985  if ( !input_line ) {
2986  throw utility::excn::EXCN_Msg_Exception( "Expected to read a left curly bracket ('}') or an"
2987  " amino acid set name, but found an end-of-line.\nError encountered while reading"
2988  " SET_CONDITION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
2989  }
2990  input_line.get( next_char );
2991  }
2992 
2993  // Now we either read an amino-acid-set name, or we read a '{'
2994  utility::vector1< core::Real > aas_in_set;
2995 
2996  if ( input_line.peek() == '{' ) {
2997  char next_aa;
2998  input_line.get( next_aa ); // wipe away the left-curly bracket
2999  next_aa = ' ';
3000  while ( next_aa != '}' ) {
3001  while ( next_aa == ' ' || next_aa == '\t' ) {
3002  if ( !input_line ) {
3003  throw utility::excn::EXCN_Msg_Exception( "Expected to read a right curly bracket ('}') or a 1-letter"
3004  " amino acid code, but found an end-of-line.\nError encountered while reading"
3005  " SET_CONDITION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
3006  }
3007  input_line.get( next_aa );
3008  }
3009  if ( next_aa == '}' ) break;
3010  if ( core::chemical::oneletter_code_specifies_aa( toupper( next_aa ) ) ) {
3011  aas_in_set.push_back( core::chemical::aa_from_oneletter_code( toupper( next_aa )) );
3012  } else {
3013  /// maybe later, if we want to include ncaa's then they're parsing will happen right here.
3014  /// but for now, no go.
3015  throw utility::excn::EXCN_Msg_Exception( "Expected to read a 1-letter"
3016  " amino acid code or a right curly brace, but found '" + utility::to_string( next_aa ) + "'.\n"
3017  "Error encountered while reading SET_CONDITION command\n" + line + "\n"
3018  "Line # " + utility::to_string( line_number ) );
3019  }
3020  next_aa = ' ';
3021  while ( next_aa == ' ' || next_aa == '\t' ) {
3022  if ( !input_line ) {
3023  throw utility::excn::EXCN_Msg_Exception( "Expected to read a right curly bracket ('}') or a 1-letter"
3024  " amino acid code, but found an end-of-line.\nError encountered while reading"
3025  " SET_CONDITION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
3026  }
3027  input_line.get( next_aa );
3028  }
3029  if ( next_aa == '}' ) { break; }
3030  if ( next_aa == ',' ) {
3031  next_aa = ' ';
3032  continue;
3033  }
3034 
3035  throw utility::excn::EXCN_Msg_Exception( "Expected to read comma"
3036  " or a right curly brace, but found '" + utility::to_string( next_aa ) + "'.\n"
3037  "Error encountered while reading SET_CONDITION command\n" + line + "\n"
3038  "Line # " + utility::to_string( line_number ) );
3039  }
3040 
3041  } else {
3042  std::string aa_setname;
3043  input_line >> aa_setname;
3044  if ( aa_sets_name_map_.find( aa_setname ) == aa_sets_name_map_.end() ) {
3045  throw utility::excn::EXCN_Msg_Exception( "Amino-acid-set name '" + aa_setname +
3046  "' has not previously been declared.\nError encountered while reading"
3047  " SET_CONDITION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
3048  }
3049  aas_in_set = aa_sets_name_map_[ aa_setname ];
3050  }
3051 
3052  /// Alright -- we've made it this far. Therefore, we're now ready to create a set condition expression.
3053  InSetExpressionOP inset_expression = new InSetExpression( subexpression_name_map_[ eename ] );
3054  inset_expression->value_set( aas_in_set );
3055 
3056  SurrogateVariableExpressionOP surrogate_expression = new SurrogateVariableExpression( condition_name );
3057  surrogate_expression->root_expression( inset_expression );
3058  expression_evaluation_order_.push_back( std::make_pair( inset_expression, surrogate_expression ) );
3059 
3060  variable_expression_map_[ condition_name ] = surrogate_expression;
3061  subexpression_name_map_[ condition_name ] = inset_expression;
3062  subexpression_name_dec_line_[ condition_name ] = line_number;
3063  scanner_->add_variable( condition_name );
3064 }
3065 
3066 void
3068  std::string const & line,
3069  Size line_number,
3070  std::istream & input_line,
3071  std::map< std::string, ArithmeticASTExpressionOP > & expression_asts
3072 )
3073 {
3074  if ( ! input_line ) {
3075  throw utility::excn::EXCN_Msg_Exception( "Expected to read a sub-expression name in the EntityFunc"
3076  " input file after reading SUB_EXPRESSION on line " + utility::to_string( line_number ) + "\n" + line );
3077  }
3078  std::string subexpression_name;
3079  input_line >> subexpression_name;
3080  if ( subexpression_name.size() == 0 ) {
3081  throw utility::excn::EXCN_Msg_Exception( "Expected to read a sub-expression name in the EntityFunc"
3082  " input file after reading SUB_EXPRESSION on line " + utility::to_string( line_number ) + "\n" + line );
3083  }
3084  if ( aa_sets_name_map_.find( subexpression_name ) != aa_sets_name_map_.end() ) {
3085  throw utility::excn::EXCN_Msg_Exception( "Sub-expression name '" + subexpression_name + "' appears multiple"
3086  " times in the EntityFunc file.\nFirst occurrance was found on line " +
3087  utility::to_string( aa_sets_dec_line_[ subexpression_name ] ) +
3088  ". Second occurrance found while reading"
3089  " SUB_EXPRESSION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
3090  }
3091 
3092  if ( subexpression_name_map_.find( subexpression_name ) != subexpression_name_map_.end() ) {
3093  if ( subexpression_name_dec_line_[ subexpression_name ] != 0 ) {
3094  throw utility::excn::EXCN_Msg_Exception( "Illegal sub-expression name '" + subexpression_name + "' which was previously"
3095  " declared in the EntityFunc file as a sub-expression.\nFirst occurrance was found on line " +
3096  utility::to_string( subexpression_name_dec_line_[ subexpression_name ] ) +
3097  ". Second occurrance found while reading"
3098  " SUB_EXPRESSION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
3099  } else {
3100  throw utility::excn::EXCN_Msg_Exception( "Illegal sub-expression name '" + subexpression_name + "' which is reserved"
3101  " as a name for an entity-element variable.\nError found while reading"
3102  " SUB_EXPRESSION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
3103  }
3104  }
3105 
3106  if ( function_names_.find( subexpression_name ) != function_names_.end() ) {
3107  throw utility::excn::EXCN_Msg_Exception( "Illegal sub-expression name '" + subexpression_name + "' which is reserved"
3108  " as a name for an funcion.\nError encountered while reading"
3109  " SUB_EXPRESSION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
3110  }
3111 
3112  if ( illegal_variable_names_.find( subexpression_name ) != illegal_variable_names_.end() ) {
3113  throw utility::excn::EXCN_Msg_Exception( "Illegal sub-expression name '" + subexpression_name + "' which is a reserved"
3114  " word for this input file format.\nError encountered while reading"
3115  " SUB_EXPRESSION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
3116  }
3117  /// now read an equals sign.
3118  /// whitespace is fine to separate the set-condition name from the equals sign.
3119  char equals_sign( ' ' );
3120  while ( equals_sign == ' ' || equals_sign == '\t' ) {
3121  if ( !input_line ) {
3122  throw utility::excn::EXCN_Msg_Exception( "Expected to read an equals sign after reading the sub-expression name '"
3123  + subexpression_name + "' but found an end-of-line.\nError encountered while reading"
3124  " SUB_EXPRESSION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
3125  }
3126  input_line >> equals_sign;
3127  }
3128  if ( equals_sign != '=' ) {
3129  throw utility::excn::EXCN_Msg_Exception( "Expected to read an equals sign after reading the sub-expression name '"
3130  + subexpression_name + "' but found '" + utility::to_string( equals_sign ) + "'\nError encountered while reading"
3131  " SUB_EXPRESSION command\n" + line + "\nLine # " + utility::to_string( line_number ) );
3132  }
3133 
3134  std::string rest_of_line;
3135  std::getline( input_line, rest_of_line );
3136 
3137  TR << "On line " << line_number << ", attempting to tokenize scalar expression: " << rest_of_line << std::endl;
3138  TokenSetOP tokens = scanner_->scan( rest_of_line );
3139  TR << "On line " << line_number << ", attempting to parse scalar expression: " << rest_of_line << std::endl;
3140  ArithmeticASTExpressionOP expression_ast = new ArithmeticASTExpression;
3141  expression_ast->parse( *tokens );
3142 
3143  expression_asts[ subexpression_name ] = expression_ast;
3144  SurrogateVariableExpressionOP surrogate_expression = new SurrogateVariableExpression( subexpression_name );
3145  expression_evaluation_order_.push_back( std::make_pair( ExpressionCOP( 0 ), surrogate_expression ) );
3146 
3147  variable_expression_map_[ subexpression_name ] = surrogate_expression;
3148  subexpression_name_map_[ subexpression_name ] = 0;
3149  subexpression_name_dec_line_[ subexpression_name ] = line_number;
3150  scanner_->add_variable( subexpression_name );
3151 
3152 }
3153 
3154 void
3156  std::string const & line,
3157  Size line_number,
3158  std::istream & input_line,
3159  ArithmeticASTExpressionOP & score_expression_ast
3160 )
3161 {
3162  if ( score_expression_ast ) {
3163  throw utility::excn::EXCN_Msg_Exception( "Encountered a second SCORE line"
3164  "while processing the EntityFunc file\n"
3165  + line + "\nLine # " + utility::to_string( line_number ) );
3166  }
3167 
3168  std::string rest_of_line;
3169  std::getline( input_line, rest_of_line );
3170 
3171  TR << "On line " << line_number << ", attempting to tokenize score expression: " << rest_of_line << std::endl;
3172  TokenSetOP tokens = scanner_->scan( rest_of_line );
3173  TR << "On line " << line_number << ", attempting to parse score expression: " << rest_of_line << std::endl;
3174  score_expression_ast = new ArithmeticASTExpression;
3175  score_expression_ast->parse( *tokens );
3176 
3177 }
3178 
3179 void
3181  std::map< std::string, ArithmeticASTExpressionOP > const & expression_asts,
3182  ArithmeticASTExpressionOP score_expression_ast
3183 )
3184 {
3185  EntityFuncExpressionCreator expression_creator( *this );
3186  for ( Size ii = 1; ii <= expression_evaluation_order_.size(); ++ii ) {
3187  if ( expression_evaluation_order_[ ii ].first == 0 ) {
3188  std::string ii_name = expression_evaluation_order_[ ii ].second->name();
3189  std::map< std::string, ArithmeticASTExpressionOP >::const_iterator iter = expression_asts.find( ii_name );
3190  ExpressionCOP var_expr = expression_creator.create_expression_tree( * iter->second );
3191  subexpression_name_map_[ ii_name ] = var_expr;
3192  expression_evaluation_order_[ ii ].first = var_expr;
3193  expression_evaluation_order_[ ii ].second->root_expression( var_expr );
3194  }
3195  }
3196 
3197  score_expression_ = expression_creator.create_expression_tree( * score_expression_ast );
3198 }
3199 
3201 {
3202  using namespace protocols::multistate_design;
3203 
3204  runtime_assert( entity.traits().size() == num_entity_elements_ );
3205  for ( Size ii = 1; ii <= entity.traits().size(); ++ii ) {
3206  PosType const & pt_ptr( dynamic_cast< PosType const & > ( * entity.traits()[ ii ] ));
3207  core::chemical::AA entity_aa( pt_ptr.type() );
3208  entity_aas_[ ii ]->set_value( entity_aa );
3209  }
3210 }
3211 
3212 
3213 }
3214 }