def valid_graph_params(live_output_options): if live_output_options['type'] not in ['progress', 'graph', 'text']: from gillespy2.core.gillespyError import SimulationError raise SimulationError( "Invalid input to 'live_output', please check spelling and ensure input is" " lower case.") if 'interval' not in live_output_options: live_output_options['interval'] = 1 elif live_output_options['interval'] < 0: log.warning( "In LiveGraphing live_output_options, got \"interval\" = \"{0}\". setting interval = 1" .format(live_output_options['interval'])) live_output_options['interval'] = 1 if live_output_options[ 'type'] == "graph" and live_output_options['interval'] < 1: log.warning( "In LiveGraphing live_output_options, got \"interval\" = \"{0}\". Consider using an interval >= 1 " "when displaying graphs".format(live_output_options['interval'])) if 'clear_output' not in live_output_options: if live_output_options['type'] == "graph" or live_output_options[ 'type'] == "progress": live_output_options['clear_output'] = True else: live_output_options['clear_output'] = False if 'file_path' not in live_output_options: live_output_options['file_path'] = None elif live_output_options['type'] == "graph" and live_output_options[ 'file_path'] is not None: live_output_options['type'] = "figure"
def get_trajectories(cls, out_dir, debug=False, show_labels=False): if debug: print("StochKitSolver.get_trajectories(out_dir={0}".format(out_dir)) # Collect all the output data trajectories = [] trajectory_directory = os.path.join(out_dir, 'trajectories') for filename in os.listdir(trajectory_directory): if 'trajectory' in filename: filename = os.path.join(trajectory_directory, filename) trajectories.append(np.loadtxt(filename, skiprows=1)) else: raise SimulationError("Couldn't identify file '{0}' found in \ output folder".format(filename)) if show_labels: with open(os.path.join(trajectory_directory, 'trajectory0.txt'), 'r') as fd: headers = fd.readline() return headers.split(), trajectories return trajectories
def run(cls, model, t=20, number_of_trajectories=1, increment=0.05, seed=None, stochkit_home=None, algorithm='ssa', job_id=None, method=None, debug=False, show_labels=False, profile=False, processes=1, **kwargs): # all this is specific to StochKit if model.units == "concentration": raise SimulationError("StochKit can only simulate population \ models, please convert to population-based model for \ stochastic simulation. Use solver = StochKitODESolver \ instead to simulate a concentration model deterministically." ) seed = super().process_seed(seed) # We keep all the trajectories by default. args = ' -p {0} --keep-trajectories --label --seed {1} --realizations {2}'.format( processes, seed, number_of_trajectories) if method is not None: # This only works for StochKit 2.1 args += ' --method ' + str(method) return super().run(model=model, t=t, number_of_trajectories=number_of_trajectories, increment=increment, seed=seed, stochkit_home=stochkit_home, algorithm=algorithm, job_id=job_id, debug=debug, show_labels=show_labels, extra_args=args)
def locate_executable(stochkit_home=None, algorithm=None): # Algorithm, SSA or Tau-leaping? executable = None if stochkit_home is not None: if os.path.isfile(os.path.join(stochkit_home, algorithm)): executable = os.path.join(stochkit_home, algorithm) else: raise SimulationError("stochkit executable '{0}' not found \ stochkit_home={1}".format(algorithm, stochkit_home)) elif os.environ.get('STOCHKIT_HOME') is not None: if os.path.isfile(os.path.join(os.environ.get('STOCHKIT_HOME'), algorithm)): executable = os.path.join(os.environ.get('STOCHKIT_HOME'), algorithm) if executable is None: # try to find the executable in the path if os.environ.get('PATH') is not None: for directory in os.environ.get('PATH').split(os.pathsep): if os.path.isfile(os.path.join(directory, algorithm)): executable = os.path.join(directory, algorithm) break return executable
def use_rate_rule(self, rate_rule: "RateRule") -> "SanitizedModel": """ Attach the given rate rule to the sanitized model. The rate rule will automatically be validated and sanitized before being applied. :param rate_rule: GillesPy2 RateRule object to attach to the sanitized model. :type rate_rule: gillespy2.RateRule :returns: Pass-through of sanitized model object. :rtype: SanitizedModel """ if isinstance(rate_rule.variable, Species): variable = rate_rule.variable elif not isinstance(rate_rule.variable, Parameter) and \ rate_rule.variable in self.model.listOfSpecies.keys(): variable = self.model.get_species(rate_rule.variable) else: errmsg = """ Parameters are not valid variables for the TauHybridCSolver. In order to use this variable it will need to be a gillespy2.Species. """ raise SimulationError(errmsg) if variable.name in self.species_names: sanitized_name = self.species_names.get(variable.name) if sanitized_name in self.rate_rules: log.warning( f"Duplicate rate rule variable found in C++ solver: {variable}" ) rr_sanitized = self.expr.getexpr_cpp(rate_rule.formula) if rr_sanitized is not None: self.rate_rules[sanitized_name] = rr_sanitized else: log.warning( f"Could not sanitize rate rule formula expression: {rate_rule.formula}" ) return self
def run(cls, model, t=20, number_of_trajectories=1, increment=0.05, seed=None, stochkit_home=None, algorithm=None, job_id=None, extra_args='', debug=False, profile=False, show_labels=False, **kwargs): """ Call out and run the solver. Collect the results. """ if len(kwargs) > 0: for key in kwargs: log.warning('Unsupported keyword argument to solver: {0}'.format(key)) if algorithm is None: raise SimulationError("No algorithm selected") # We write all StochKit input and output files to a temporary folder prefix_base_dir = tempfile.mkdtemp() prefix_out_dir = os.path.join(prefix_base_dir, 'output') os.mkdir(prefix_out_dir) if job_id is None: job_id = str(uuid.uuid4()) if isinstance(model, Model): # Write a temporary StochKit2 input file. outfile = os.path.join(prefix_base_dir, "temp_input_{0}.xml".format(job_id)) with open(outfile, 'w') as model_file_handle: model_file_handle.write(model.serialize()) elif isinstance(model, str): outfile = model else: raise InvalidModelError('Model must be either a GillesPy Model instance or an xml file name.') executable = cls.locate_executable(stochkit_home=stochkit_home, algorithm=algorithm) if executable is None: raise SimulationError("stochkit executable '{0}' not found. \ Make sure it is your path, or set STOCHKIT_HOME environment \ variable'".format(algorithm)) # Assemble argument list for StochKit out_dir = os.path.join(prefix_out_dir, job_id) if increment is None: increment = t / 20.0 num_output_points = round(t / increment) # Assemble the argument list args = '--model {0} --out-dir {1} -t {2} -i {3}'.format(outfile, out_dir, t, int(num_output_points)) directories = os.listdir(prefix_out_dir) if os.path.isdir(out_dir): if debug: print('Ensemble {0} already existed, using --force.'.format(job_id)) args += ' --force' # If we are using local mode, shell out and run StochKit # (SSA or Tau-leaping or ODE) cmd = ' '.join([executable, args, extra_args]) if debug: print("cmd: {0}".format(cmd)) # Execute try: handle = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) return_code = handle.wait() except OSError as e: raise SimulationError("Solver execution failed: {0}\n{1}".format(cmd, e)) try: stderr = handle.stderr.read() except Exception as e: stderr = 'Error reading stderr: {0}'.format(e) try: stdout = handle.stdout.read() except Exception as e: stdout = 'Error reading stdout: {0}'.format(e) if return_code != 0: raise SimulationError("Solver execution failed: '{0}' output: {1}{2}".format(cmd, stdout, stderr)) try: # Get data using solver specific function trajectories = cls.get_trajectories(out_dir, debug=debug, show_labels=show_labels) if len(trajectories) == 0: raise SimulationError("Solver execution failed: '{0}' output: {1}{2}".format(cmd, stdout, stderr)) if show_labels: labels, trajectories = trajectories trajectories = cls.label_trajectories(trajectories, labels) return trajectories except Exception as e: compile_log_file = os.path.join(prefix_base_dir, 'temp_input_{0}_generated_code'.format(job_id), 'compile-log.txt') log_file = os.path.join(prefix_out_dir, job_id, 'log.txt') for file_name in [compile_log_file, log_file]: if os.path.isfile(file_name): with open(file_name) as f: error = f.read() raise SimulationError("Error running simulation: {0}\n{1}\n".format(file_name, error)) raise SimulationError("Error using solver.get_trajectories('{0}'): {1}".format(out_dir, e)) finally: # Clean up if debug: print("prefix_base_dir={0}".format(prefix_base_dir)) print("STDOUT: {0}".format(stdout)) print("STDERR: {0}".format(stderr)) else: shutil.rmtree(prefix_base_dir)