コード例 #1
0
 def setUp(self):
     self.parameter = Parameter(name="test_parameter", expression="0.5")
コード例 #2
0
ファイル: model.py プロジェクト: clorton/GillesPy2
    def to_model(self, name):
        """ Instantiates a Model object from a StochMLDocument. """

        # Empty model
        model = Model(name=name)
        root = self.document

        # Try to set name from document
        if model.name == "":
            name = root.find('Name')
            if name.text is None:
                raise NameError("The Name cannot be none")
            else:
                model.name = name.text

        # Set annotiation
        ann = root.find('Description')
        if ann is not None:
            units = ann.get('units')

            if units:
                units = units.strip().lower()

            if units == "concentration":
                model.units = "concentration"
            elif units == "population":
                model.units = "population"
            else:  # Default
                model.units = "population"

            if ann.text is None:
                model.annotation = ""
            else:
                model.annotation = ann.text

        # Set units
        units = root.find('Units')
        if units is not None:
            if units.text.strip().lower() == "concentration":
                model.units = "concentration"
            elif units.text.strip().lower() == "population":
                model.units = "population"
            else:  # Default
                model.units = "population"

        # Create parameters
        for px in root.iter('Parameter'):
            name = px.find('Id').text
            expr = px.find('Expression').text
            if name.lower() == 'vol' or name.lower() == 'volume':
                model.volume = float(expr)
            else:
                p = Parameter(name, expression=expr)
                # Try to evaluate the expression in the empty namespace
                # (if the expr is a scalar value)
                p.evaluate()
                model.add_parameter(p)

        # Create species
        for spec in root.iter('Species'):
            name = spec.find('Id').text
            val = spec.find('InitialPopulation').text
            if '.' in val:
                val = float(val)
            else:
                val = int(val)
            s = Species(name, initial_value=val)
            model.add_species([s])

        # The namespace_propensity for evaluating the propensity function
        # for reactions must contain all the species and parameters.
        namespace_propensity = OrderedDict()
        all_species = model.get_all_species()
        all_parameters = model.get_all_parameters()

        for param in all_species:
            namespace_propensity[param] = all_species[param].initial_value

        for param in all_parameters:
            namespace_propensity[param] = all_parameters[param].value

        # Create reactions
        for reac in root.iter('Reaction'):
            try:
                name = reac.find('Id').text
            except:
                raise InvalidStochMLError("Reaction has no name.")

            reaction = Reaction(name=name, reactants={}, products={})

            # Type may be 'mass-action','customized'
            try:
                type = reac.find('Type').text
            except:
                raise InvalidStochMLError("No reaction type specified.")

            reactants = reac.find('Reactants')
            try:
                for ss in reactants.iter('SpeciesReference'):
                    specname = ss.get('id')
                    # The stochiometry should be an integer value, but some
                    # exising StoxhKit models have them as floats. This is
                    # why we need the slightly odd conversion below.
                    stoch = int(float(ss.get('stoichiometry')))
                    # Select a reference to species with name specname
                    sref = model.listOfSpecies[specname]
                    try:
                        # The sref list should only contain one element if
                        # the XML file is valid.
                        reaction.reactants[sref] = stoch
                    except Exception as e:
                        StochMLImportError(e)
            except:
                # Yes, this is correct. 'reactants' can be None
                pass

            products = reac.find('Products')
            try:
                for ss in products.iter('SpeciesReference'):
                    specname = ss.get('id')
                    stoch = int(float(ss.get('stoichiometry')))
                    sref = model.listOfSpecies[specname]
                    try:
                        # The sref list should only contain one element if
                        # the XML file is valid.
                        reaction.products[sref] = stoch
                    except Exception as e:
                        raise StochMLImportError(e)
            except:
                # Yes, this is correct. 'products' can be None
                pass

            if type == 'mass-action':
                reaction.massaction = True
                reaction.type = 'mass-action'
                # If it is mass-action, a parameter reference is needed.
                # This has to be a reference to a species instance. We
                # explicitly disallow a scalar value to be passed as the
                # parameter.
                try:
                    ratename = reac.find('Rate').text
                    try:
                        reaction.marate = model.listOfParameters[ratename]
                    except KeyError as k:
                        # No paramter name is given. This is a valid use case
                        # in StochKit. We generate a name for the paramter,
                        # and create a new parameter instance. The parameter's
                        # value should now be found in 'ratename'.
                        generated_rate_name = "Reaction_" + name + \
                                              "_rate_constant"
                        p = Parameter(name=generated_rate_name,
                                      expression=ratename)
                        # Try to evaluate the parameter to set its value
                        p.evaluate()
                        model.add_parameter(p)
                        reaction.marate = model.listOfParameters[
                            generated_rate_name]

                    reaction.__create_mass_action()
                except Exception as e:
                    raise
            elif type == 'customized':
                try:
                    propfunc = reac.find('PropensityFunction').text
                except Exception as e:
                    raise InvalidStochMLError(
                        "Found a customized propensity function, but no expression was given. {}"
                        .format(e))
                reaction.propensity_function = propfunc
            else:
                raise InvalidStochMLError(
                    "Unsupported or no reaction type given for reaction" +
                    name)

            model.add_reaction(reaction)

        return model
コード例 #3
0
class TestParameter(unittest.TestCase):
    '''
    ################################################################################################
    Unit tests for gillespy2.Parameter.
    ################################################################################################
    '''
    def setUp(self):
        self.parameter = Parameter(name="test_parameter", expression="0.5")

    def test_constructor(self):
        """ Test the Parameter constructor. """
        parameter = Parameter(name="test_parameter", expression="0.5")
        self.assertEqual(parameter.name, "test_parameter")
        self.assertEqual(parameter.expression, "0.5")

    def test_constructor__no_name(self):
        """ Test the Parameter constructor without name. """
        with self.assertRaises(ParameterError):
            Parameter(expression="0.5")

    def test_constructor__invalid_name(self):
        """ Test the Parameter constructor with non-str name. """
        test_names = ["", None, 0, 0.5, [0]]
        for test_name in test_names:
            with self.subTest(name=test_name):
                with self.assertRaises(ParameterError):
                    Parameter(name=test_name, expression="0.5")

    def test_constructor__no_expression(self):
        """ Test the Parameter constructor without expression. """
        with self.assertRaises(ParameterError):
            Parameter(name="test_parameter")

    def test_constructor__int_expression(self):
        """ Test the Parameter constructor with int expression. """
        parameter = Parameter(name="test_parameter", expression=1)
        self.assertEqual(parameter.expression, "1")

    def test_constructor__float_expression(self):
        """ Test the Parameter constructor with float expression. """
        parameter = Parameter(name="test_parameter", expression=0.5)
        self.assertEqual(parameter.expression, "0.5")

    def test_constructor__invaild_expression(self):
        """ Test the Parameter constructor with an invalid expression. """
        test_exps = [None, "", [2]]
        for test_exp in test_exps:
            with self.subTest(expression=test_exp):
                with self.assertRaises(ParameterError):
                    Parameter(name="test_name", expression=test_exp)

    def test___str__(self):
        """ Test Parameter.__str__ method. """
        self.assertIsInstance(str(self.parameter), str)

    def test__evaluate(self):
        """ Test Parameter._evaluate method. """
        self.parameter._evaluate()
        self.assertEqual(self.parameter.value, 0.5)

    def test__evaluate__int_expression(self):
        """ Test Parameter._evaluate method with int expression. """
        self.parameter.expression = 5
        self.parameter._evaluate()
        self.assertEqual(self.parameter.value, 5)

    def test__evaluate__float_expression(self):
        """ Test Parameter._evaluate method with float expression. """
        self.parameter.expression = 0.5
        self.parameter._evaluate()
        self.assertEqual(self.parameter.value, 0.5)

    def test__evaluate__improper_expression(self):
        """ Test Parameter._evaluate method with invalid expression. """
        self.parameter.expression = "[0.5]"
        with self.assertRaises(ParameterError):
            self.parameter._evaluate()

    def test__evaluate__invaild_expression(self):
        """ Test Parameter._evaluate with an invalid expression. """
        test_exps = [None, "", []]
        for test_exp in test_exps:
            with self.subTest(expression=test_exp):
                with self.assertRaises(ParameterError):
                    self.parameter.expression = test_exp
                    self.parameter._evaluate()

    def test__evaluate__parameter_in_namespace(self):
        """ Test Parameter._evaluate method with parameter in namespace. """
        self.parameter.expression = "k1 + 0.5"
        self.parameter._evaluate(namespace={"k1": 3})
        self.assertEqual(self.parameter.value, 3.5)

    def test__evaluate__species_in_namespace(self):
        """ Test Parameter._evaluate method with species in namespace. """
        self.parameter.expression = "S0 + 0.5"
        self.parameter._evaluate(namespace={"S0": 100})
        self.assertEqual(self.parameter.value, 100.5)

    def test__evaluate__component_not_in_namespace(self):
        """ Test Parameter._evaluate method with component missing from namespace. """
        test_comps = ["SO", "k1"]
        for test_comp in test_comps:
            with self.subTest(component=test_comp):
                self.parameter.expression = f"{test_comp} + 0.5"
                with self.assertRaises(ParameterError):
                    self.parameter._evaluate()

    def test_validate__invalid_name(self):
        """ Test Parameter.validate with non-str name. """
        test_names = ["", None, 0, 0.5, [0]]
        for test_name in test_names:
            with self.subTest(name=test_name):
                with self.assertRaises(ParameterError):
                    self.parameter.name = test_name
                    self.parameter.validate()

    def test_validate__invaild_expression(self):
        """ Test Parameter.validate with an invalid expression. """
        test_exps = [None, "", [2]]
        for test_exp in test_exps:
            with self.subTest(expression=test_exp):
                with self.assertRaises(ParameterError):
                    self.parameter.expression = test_exp
                    self.parameter.validate()

    def test_comp_time_of_validate(self):
        """ Check the computation time of validate. """
        import time
        from datetime import datetime
        start = time.time()
        self.parameter.validate()
        tic = datetime.utcfromtimestamp(time.time() - start)
        print(
            f"Total time to run validate: {tic.strftime('%M mins %S secs %f msecs')}"
        )
コード例 #4
0
ファイル: model.py プロジェクト: clorton/GillesPy2
    def from_model(cls, model):
        """
        Creates an StochKit XML document from an exisiting Mdoel object.
        This method assumes that all the parameters in the model are already
        resolved to scalar floats (see Model.resolveParamters).

        Note, this method is intended to be used interanally by the models
        'serialization' function, which performs additional operations and
        tests on the model prior to writing out the XML file. You should NOT \
        do:

        document = StochMLDocument.fromModel(model)
        print document.toString()

        You SHOULD do

        print model.serialize()

        """

        # Description
        md = cls()

        d = eTree.Element('Description')

        #
        if model.units.lower() == "concentration":
            d.set('units', model.units.lower())

        d.text = model.annotation
        md.document.append(d)

        # Number of Reactions
        nr = eTree.Element('NumberOfReactions')
        nr.text = str(len(model.listOfReactions))
        md.document.append(nr)

        # Number of Species
        ns = eTree.Element('NumberOfSpecies')
        ns.text = str(len(model.listOfSpecies))
        md.document.append(ns)

        # Species
        spec = eTree.Element('SpeciesList')
        for sname in model.listOfSpecies:
            spec.append(md.__species_to_element(model.listOfSpecies[sname]))
        md.document.append(spec)

        # Parameters
        params = eTree.Element('ParametersList')
        for pname in model.listOfParameters:
            params.append(
                md.__parameter_to_element(model.listOfParameters[pname]))

        params.append(
            md.__parameter_to_element(
                Parameter(name='vol', expression=model.volume)))

        md.document.append(params)

        # Reactions
        reacs = eTree.Element('ReactionsList')
        for rname in model.listOfReactions:
            reacs.append(
                md.__reaction_to_element(model.listOfReactions[rname],
                                         model.volume))
        md.document.append(reacs)

        return md