@@ -38,8 +38,34 @@ def md(input_file, output_file, engine, ensemble, nsteps, init_frame):
3838 initial_frame = INIT_SNAP .get (storage , init_frame )
3939 )
4040
41+ class ProgressReporter (object ):
42+ def __init__ (self , timestep , update_freq ):
43+ self .timestep = timestep
44+ self .update_freq = update_freq
4145
42- class EnsembleSatisfiedContinueConditions (object ):
46+ def steps_progress_string (self , n_steps ):
47+ report_str = "Ran {n_steps} frames"
48+ if self .timestep is not None :
49+ report_str += " [{}]" .format (str (n_steps * timestep ))
50+ report_str += '.'
51+ return report_str
52+
53+ def progress_string (self , n_steps ):
54+ report_str = self .steps_progress_string (n_steps ) + "\n "
55+ return report_str .format (n_steps = n_steps )
56+
57+
58+ def report_progress (self , n_steps ):
59+ import openpathsampling as paths
60+ if n_steps % self .update_freq == 0 :
61+ string = self .progress_string (n_steps )
62+ paths .tools .refresh_output (string )
63+
64+ def __call__ (self , trajectory , trusted = False ):
65+ raise NotImplementedError ()
66+
67+
68+ class EnsembleSatisfiedContinueConditions (ProgressReporter ):
4369 """Continuation condition for including subtrajs for each ensemble.
4470
4571 This object creates a continuation condition (a callable) analogous with
@@ -52,9 +78,24 @@ class EnsembleSatisfiedContinueConditions(object):
5278 ensembles: List[:class:`openpathsampling.Ensemble`]
5379 the ensembles to satisfy
5480 """
55- def __init__ (self , ensembles ):
81+ def __init__ (self , ensembles , timestep = None , update_freq = 10 ):
82+ super ().__init__ (timestep , update_freq )
5683 self .satisfied = {ens : False for ens in ensembles }
5784
85+ def progress_string (self , n_steps ):
86+ report_str = self .steps_progress_string (n_steps )
87+ report_str += (" Found ensembles [{found}]. "
88+ "Looking for [{missing}].\n " )
89+ found = [ens .name for ens , done in self .satisfied .items () if done ]
90+ missing = [ens .name for ens , done in self .satisfied .items ()
91+ if not done ]
92+ found_str = "," .join (found )
93+ missing_str = "," .join (missing )
94+ return report_str .format (n_steps = n_steps ,
95+ found = found_str ,
96+ missing = missing_str )
97+
98+
5899 def _check_previous_frame (self , trajectory , start , unsatisfied ):
59100 if - start > len (trajectory ):
60101 # we've done the whole traj; don't keep going
@@ -81,6 +122,8 @@ def __call__(self, trajectory, trusted=False):
81122 return self ._call_untrusted (trajectory )
82123
83124 # below here, trusted is True
125+ self .report_progress (len (trajectory ) - 1 )
126+
84127 unsatisfied = [ens for ens , done in self .satisfied .items ()
85128 if not done ]
86129 # TODO: update on how many ensembles left, what frame number we are
@@ -92,6 +135,20 @@ def __call__(self, trajectory, trusted=False):
92135 return not all (self .satisfied .values ())
93136
94137
138+ class FixedLengthContinueCondition (ProgressReporter ):
139+ """
140+ """
141+ def __init__ (self , length , timestep = None , update_freq = 10 ):
142+ super ().__init__ (timestep , update_freq )
143+ self .length = length
144+
145+ def __call__ (self , trajectory , trusted = False ):
146+ len_traj = len (trajectory )
147+ self .report_progress (len_traj - 1 )
148+ return len_traj < self .length
149+
150+
151+
95152def md_main (output_storage , engine , ensembles , nsteps , initial_frame ):
96153 import openpathsampling as paths
97154 if nsteps is not None and ensembles :
@@ -101,7 +158,7 @@ def md_main(output_storage, engine, ensembles, nsteps, initial_frame):
101158 if ensembles :
102159 continue_cond = EnsembleSatisfiedContinueConditions (ensembles )
103160 else :
104- continue_cond = paths . LengthEnsemble (nsteps ). can_append
161+ continue_cond = FixedLengthContinueCondition (nsteps )
105162
106163 trajectory = engine .generate (initial_frame , running = continue_cond )
107164 paths_cli .utils .tag_final_result (trajectory , output_storage ,
0 commit comments