Esempio n. 1
0
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"
Esempio n. 2
0
 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
Esempio n. 3
0
    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)
Esempio n. 4
0
 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
Esempio n. 5
0
    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
Esempio n. 6
0
    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)