Exemple #1
0
def add_default_flux_bounds(doc, lower=0.0, upper=100.0, unit='mole_per_s'):
    """ Adds default flux bounds to SBMLDocument.

    :param doc:
    :type doc:
    :param lower:
    :type lower:
    :param upper:
    :type upper:
    """
    # FIXME: overwrites lower/upper parameter (check if existing)
    # TODO: the units are very specific (more generic)
    warnings.warn('Adding default flux bounds', UserWarning)
    model = doc.getModel()
    parameters = [
        factory.Parameter(sid='upper', value=upper, unit=unit),
        factory.Parameter(sid='lower', value=lower, unit=unit),
    ]
    factory.create_objects(model, parameters)
    for r in model.reactions:
        rfbc = r.getPlugin("fbc")
        if not rfbc.isSetLowerFluxBound():
            rfbc.setLowerFluxBound('lower')
        if not rfbc.isSetUpperFluxBound():
            rfbc.setUpperFluxBound('upper')
Exemple #2
0
def add_default_flux_bounds(doc, lower=0.0, upper=100.0, unit='mole_per_s'):
    """ Adds default flux bounds to SBMLDocument.

    :param doc:
    :type doc:
    :param lower:
    :type lower:
    :param upper:
    :type upper:
    """
    # FIXME: overwrites lower/upper parameter (check if existing)
    # TODO: the units are very specific (more generic)
    warnings.warn('Adding default flux bounds', UserWarning)
    model = doc.getModel()
    parameters = [
        factory.Parameter(sid='upper', value=upper, unit=unit),
        factory.Parameter(sid='lower', value=lower, unit=unit),
    ]
    factory.create_objects(model, parameters)
    for r in model.reactions:
        rfbc = r.getPlugin("fbc")
        if not rfbc.isSetLowerFluxBound():
            rfbc.setLowerFluxBound('lower')
        if not rfbc.isSetUpperFluxBound():
            rfbc.setUpperFluxBound('upper')
Exemple #3
0
def create_dummy_reactions(model, model_fba, unit_flux=None):
    """ Creates the dummy reactions.
    This also creates the corresponding flux parameters and flux assignments.

    :param model:
    :param model_fba:
    :param unit_flux:
    :return:
    """
    ex_rids = utils.find_exchange_reactions(model_fba)
    objects = []
    for ex_rid, sid in ex_rids.items():

        pid_flux = FLUX_PARAMETER_PREFIX + sid
        rid_flux = DUMMY_REACTION_PREFIX + sid

        objects.append(
            # flux parameter: fluxe from fba (rate of reaction)
            fac.Parameter(sid=pid_flux, value=1.0, constant=True, unit=unit_flux, sboTerm=FLUX_PARAMETER_SBO),
        )

        # dummy reaction (pseudoreaction)
        fac.create_reaction(model, rid=rid_flux, reversible=False,
                            products={DUMMY_SPECIES_ID: 1}, sboTerm=DUMMY_REACTION_SBO,
                            formula='0 {}'.format(unit_flux))

        # flux assignment rule
        objects.append(
            fac.AssignmentRule(pid_flux, value=rid_flux, sboTerm=FLUX_ASSIGNMENTRULE_SBO),
        )
    fac.create_objects(model, objects)
Exemple #4
0
def set_units(model, units):
    """ Set units information on model.

    :param model: Model
    :param units: units info
    """
    factory.create_objects(model, units)
Exemple #5
0
def template_doc_bounds(model_id, create_min_max=True):
    """ Create template bounds model.

    Adds min and max functions

    :param create_min_max:
    :param model_id: model identifier
    :return: SBMLDocument
    """
    sbmlns = libsbml.SBMLNamespaces(SBML_LEVEL, SBML_VERSION, 'comp',
                                    SBML_COMP_VERSION)
    doc = libsbml.SBMLDocument(sbmlns)
    doc.setPackageRequired(SBML_COMP_NAME, True)
    model = doc.createModel()
    model.setId("{}_bounds".format(model_id))
    model.setName("{} (BOUNDS)".format(model_id))
    model.setSBOTerm(comp.SBO_CONTINOUS_FRAMEWORK)

    if create_min_max:
        objects = [
            # definition of min and max
            Function('max', 'lambda(x,y, piecewise(x,gt(x,y),y) )',
                     name='min'),
            Function('min', 'lambda(x,y, piecewise(x,lt(x,y),y) )',
                     name='max'),
        ]
        factory.create_objects(model, objects)

    return doc
Exemple #6
0
def set_units(model, units):
    """ Set units information on model.

    :param model: Model
    :param units: units info
    """
    factory.create_objects(model, units)
Exemple #7
0
def template_doc_bounds(model_id, create_min_max=True):
    """ Create template bounds model.

    Adds min and max functions

    :param create_min_max:
    :param model_id: model identifier
    :return: SBMLDocument
    """
    sbmlns = libsbml.SBMLNamespaces(SBML_LEVEL, SBML_VERSION, 'comp', SBML_COMP_VERSION)
    doc = libsbml.SBMLDocument(sbmlns)
    doc.setPackageRequired(SBML_COMP_NAME, True)
    model = doc.createModel()
    model.setId("{}_bounds".format(model_id))
    model.setName("{} (BOUNDS)".format(model_id))
    model.setSBOTerm(comp.SBO_CONTINOUS_FRAMEWORK)

    if create_min_max:
        objects = [
            # definition of min and max
            fac.Function('max', 'lambda(x,y, piecewise(x,gt(x,y),y) )', name='min'),
            fac.Function('min', 'lambda(x,y, piecewise(x,lt(x,y),y) )', name='max'),
        ]
        fac.create_objects(model, objects)

    return doc
Exemple #8
0
def create_dfba_species(model, model_fba, compartment_id, hasOnlySubstanceUnits=False, unit_amount=None, create_port=True,
                        exclude_sids=[]):
    """ Add DFBA species and compartments from fba model to model.
    Creates the dynamic species and respetive compartments with
    the necessary ports.
    This is used in the bounds submodel, update submodel and the
    and top model.

    :param model:
    :param model_fba:
    :return:
    """
    objects = []
    port_sids = []
    ex_rids = utils.find_exchange_reactions(model_fba)
    for ex_rid in ex_rids:

        r = model_fba.getReaction(ex_rid)
        sid = r.getReactant(0).getSpecies()
        if sid in exclude_sids:
            continue

        s = model_fba.getSpecies(sid)
        # exchange species to create
        objects.append(
            fac.Species(sid=sid, name=s.getName(), initialConcentration=1.0, substanceUnit=unit_amount,
                        hasOnlySubstanceUnits=hasOnlySubstanceUnits, compartment=compartment_id)
        )
        # port of exchange species
        port_sids.append(sid)

    fac.create_objects(model, objects)
    if create_port:
        comp.create_ports(model, idRefs=port_sids)
Exemple #9
0
def create_dynamic_bounds(model_bounds, model_fba, unit_flux=None):
    """ Creates the dynamic bounds for the model.

    It is necessary to create copies of the fixed bounds from the fba model
    which are subsequently used in the dynamic bounds calculation.

    :return:
    """
    fba_suffix = "_fba"
    objects = []
    ex_rids = utils.find_exchange_reactions(model_fba)
    for ex_rid, sid in ex_rids.items():
        r = model_fba.getReaction(ex_rid)
        r_fbc = r.getPlugin(SBML_FBC_NAME)

        # get compartment from species
        s = model_bounds.getSpecies(sid)
        cid = s.getCompartment()

        # upper bound parameter (export from FBA, i.e increase concentration)
        ub_id = r_fbc.getUpperFluxBound()
        fba_ub_id = ub_id + fba_suffix
        ub_value = model_fba.getParameter(ub_id).getValue()
        ub_formula = "{}".format(fba_ub_id)
        objects.extend([
            Parameter(sid=fba_ub_id,
                      value=ub_value,
                      unit=unit_flux,
                      constant=True,
                      sboTerm=FLUX_BOUND_SBO),
            AssignmentRule(sid=ub_id,
                           value=ub_formula,
                           name="fba export bound ({})".format(sid)),
        ])

        # lower bound parameter (import to FBA, i.e decrease concentration)
        lb_id = r_fbc.getLowerFluxBound()
        fba_lb_id = lb_id + fba_suffix
        lb_value = model_fba.getParameter(lb_id).getValue()
        # concentration/amount formula for import depending on available species

        if s.getHasOnlySubstanceUnits():
            lb_formula = "max({}, -{}/dt)".format(fba_lb_id, sid)
        else:
            lb_formula = "max({}, -{}*{}/dt)".format(fba_lb_id, cid, sid)

        objects.extend([
            # default bounds from fba
            Parameter(sid=fba_lb_id,
                      value=lb_value,
                      unit=unit_flux,
                      constant=False,
                      sboTerm=FLUX_BOUND_SBO),
            # uptake bounds (lower bound)
            AssignmentRule(sid=lb_id,
                           value=lb_formula,
                           name="dfba import bound ({})".format(sid)),
        ])
    factory.create_objects(model_bounds, objects)
Exemple #10
0
def create_exchange_reaction(model,
                             species_id,
                             exchange_type=EXCHANGE,
                             flux_unit=None):
    """ Factory method to create exchange reactions for species in the FBA model.

    Creates the exchange reaction, the upper and lower bounds,
    and the ports.

    :param model:
    :param species_id:
    :param exchange_type:
    :param flux_unit:

    :return:
    """
    if exchange_type not in [EXCHANGE, EXCHANGE_IMPORT, EXCHANGE_EXPORT]:
        raise ValueError("Wrong exchange_type: {}".format(exchange_type))

    # id (e.g. EX_A)
    ex_rid = EXCHANGE_REACTION_PREFIX + species_id
    lb_id = LOWER_BOUND_PREFIX + ex_rid
    ub_id = UPPER_BOUND_PREFIX + ex_rid

    lb_value = LOWER_BOUND_DEFAULT
    ub_value = UPPER_BOUND_DEFAULT
    if exchange_type == EXCHANGE_IMPORT:
        # negative flux through exchange reaction
        ub_value = ZERO_BOUND
    if exchange_type == EXCHANGE_EXPORT:
        lb_value = ZERO_BOUND

    parameters = [
        Parameter(sid=lb_id,
                  value=lb_value,
                  unit=flux_unit,
                  constant=True,
                  sboTerm=FLUX_BOUND_SBO,
                  port=True),
        Parameter(sid=ub_id,
                  value=ub_value,
                  unit=flux_unit,
                  constant=True,
                  sboTerm=FLUX_BOUND_SBO,
                  port=True),
    ]
    factory.create_objects(model, parameters)

    reactions = [
        ExchangeReaction(species_id,
                         reversible=True,
                         lowerFluxBound=lb_id,
                         upperFluxBound=ub_id,
                         port=True)
    ]
    ex_reactions = factory.create_objects(model, reactions)
    # only one element in dictionary, get first value
    return next(iter(ex_reactions.values()))
def bounds_model(sbml_file, directory, doc_fba=None):
    """"
    Submodel for dynamically calculating the flux bounds.

    The dynamically changing flux bounds are the input to the
    FBA model.
    """
    doc = builder.template_doc_bounds(settings.MODEL_ID)
    model = doc.getModel()

    bounds_notes = notes.format("""
    <h2>BOUNDS submodel</h2>
    <p>Submodel for dynamically calculating the flux bounds.
    The dynamically changing flux bounds are the input to the
    FBA model.</p>
    """)
    utils.set_model_info(model, notes=bounds_notes, creators=creators, units=units, main_units=main_units)

    # dt
    compartment_id = "blood"
    builder.create_dfba_dt(model, time_unit=UNIT_TIME, create_port=True)

    # compartment
    builder.create_dfba_compartment(model, compartment_id=compartment_id, unit_volume=UNIT_VOLUME, create_port=True)

    # dynamic species
    model_fba = doc_fba.getModel()
    builder.create_dfba_species(model, model_fba, compartment_id=compartment_id, unit_amount=UNIT_AMOUNT,
                                create_port=True)

    # bounds
    builder.create_exchange_bounds(model, model_fba=model_fba, unit_flux=UNIT_FLUX, create_ports=True)

    # bounds
    fba_prefix = "fba"
    model_fba = doc_fba.getModel()
    objects = []
    ex_rids = utils.find_exchange_reactions(model_fba)
    for ex_rid, sid in ex_rids.items():
        r = model_fba.getReaction(ex_rid)

        # lower & upper bound parameters
        r_fbc = r.getPlugin(builder.SBML_FBC_NAME)
        lb_id = r_fbc.getLowerFluxBound()
        fba_lb_id = fba_prefix + lb_id
        lb_value = model_fba.getParameter(lb_id).getValue()

        objects.extend([
            # default bounds from fba
            mc.Parameter(sid=fba_lb_id, value=lb_value, unit=UNIT_FLUX, constant=False),
            # uptake bounds (lower bound)
            mc.AssignmentRule(sid=lb_id, value="max({}, -{}*{}/dt)".format(fba_lb_id, compartment_id, sid)),
        ])
    mc.create_objects(model, objects)

    sbmlio.write_sbml(doc, filepath=pjoin(directory, sbml_file), validate=True)
def bounds_model(sbml_file, directory, doc_fba=None):
    """"
    Submodel for dynamically calculating the flux bounds.

    The dynamically changing flux bounds are the input to the
    FBA model.
    """
    doc = builder.template_doc_bounds(settings.MODEL_ID)
    model = doc.getModel()

    bounds_notes = notes.format("""
    <h2>BOUNDS submodel</h2>
    <p>Submodel for dynamically calculating the flux bounds.
    The dynamically changing flux bounds are the input to the
    FBA model.</p>
    """)
    utils.set_model_info(model, notes=bounds_notes, creators=creators, units=units, main_units=main_units)

    # dt
    compartment_id = "blood"
    builder.create_dfba_dt(model, time_unit=UNIT_TIME, create_port=True)

    # compartment
    builder.create_dfba_compartment(model, compartment_id=compartment_id, unit_volume=UNIT_VOLUME, create_port=True)

    # dynamic species
    model_fba = doc_fba.getModel()
    builder.create_dfba_species(model, model_fba, compartment_id=compartment_id, unit_amount=UNIT_AMOUNT,
                                create_port=True)

    # bounds
    builder.create_exchange_bounds(model, model_fba=model_fba, unit_flux=UNIT_FLUX, create_ports=True)

    # bounds
    fba_prefix = "fba"
    model_fba = doc_fba.getModel()
    objects = []
    ex_rids = utils.find_exchange_reactions(model_fba)
    for ex_rid, sid in ex_rids.items():
        r = model_fba.getReaction(ex_rid)

        # lower & upper bound parameters
        r_fbc = r.getPlugin(builder.SBML_FBC_NAME)
        lb_id = r_fbc.getLowerFluxBound()
        fba_lb_id = fba_prefix + lb_id
        lb_value = model_fba.getParameter(lb_id).getValue()

        objects.extend([
            # default bounds from fba
            mc.Parameter(sid=fba_lb_id, value=lb_value, unit=UNIT_FLUX, constant=False),
            # uptake bounds (lower bound)
            mc.AssignmentRule(sid=lb_id, value="max({}, -{}*{}/dt)".format(fba_lb_id, compartment_id, sid)),
        ])
    mc.create_objects(model, objects)

    sbmlio.write_sbml(doc, filepath=pjoin(directory, sbml_file), validate=True)
def bounds_model(sbml_file, directory, doc_fba, annotations=None):
    """"
    Bounds model.
    """
    bounds_notes = notes.format("""
    <h2>BOUNDS submodel</h2>
    <p>Submodel for dynamically calculating the flux bounds.
    The dynamically changing flux bounds are the input to the
    FBA model.</p>
    """)
    doc = builder.template_doc_bounds(settings.MODEL_ID)
    model = doc.getModel()
    utils.set_model_info(model,
                         notes=bounds_notes,
                         creators=creators,
                         units=units, main_units=main_units)

    builder.create_dfba_dt(model, step_size=DT_SIM, time_unit=UNIT_TIME, create_port=True)

    # compartment
    compartment_id = 'extern'
    builder.create_dfba_compartment(model, compartment_id=compartment_id, unit_volume=UNIT_VOLUME,
                                    create_port=True)

    # species
    model_fba = doc_fba.getModel()
    builder.create_dfba_species(model, model_fba, compartment_id=compartment_id, unit_amount=UNIT_AMOUNT,
                                hasOnlySubstanceUnits=True, create_port=True)

    # exchange bounds
    builder.create_exchange_bounds(model, model_fba=model_fba, unit_flux=UNIT_FLUX, create_ports=True)


    objects = [
        # exchange bounds
        # FIXME: readout the FBA network bounds
        mc.Parameter(sid="lb_default", value=builder.LOWER_BOUND_DEFAULT, unit=UNIT_FLUX, constant=True),

        # kinetic bound parameter & calculation
        mc.Parameter(sid='ub_R1', value=1.0, unit=UNIT_FLUX, constant=False, sboTerm="SBO:0000625"),
        mc.Parameter(sid='k1', value=-0.2, unit="per_s", name="k1", constant=False),
        mc.RateRule(sid="ub_R1", value="k1*ub_R1"),

        # bound assignment rules
        mc.AssignmentRule(sid="lb_EX_A", value='max(lb_default, -A/dt)'),
        mc.AssignmentRule(sid="lb_EX_C", value='max(lb_default, -C/dt)'),
    ]
    mc.create_objects(model, objects)

    # ports
    comp.create_ports(model, portType=comp.PORT_TYPE_PORT,
                      idRefs=["ub_R1"])
    if annotations:
        annotation.annotate_sbml_doc(doc, annotations)
    sbmlio.write_sbml(doc, filepath=os.path.join(directory, sbml_file), validate=True)
Exemple #14
0
def bounds_model(sbml_file, directory, doc_fba, annotations=None):
    """"
    Bounds model.
    """
    bounds_notes = notes.format("""
    <h2>BOUNDS submodel</h2>
    <p>Submodel for dynamically calculating the flux bounds.
    The dynamically changing flux bounds are the input to the
    FBA model.</p>
    """)
    doc = builder.template_doc_bounds(settings.MODEL_ID)
    model = doc.getModel()
    utils.set_model_info(model,
                         notes=bounds_notes,
                         creators=creators,
                         units=units, main_units=main_units)

    builder.create_dfba_dt(model, step_size=DT_SIM, time_unit=UNIT_TIME, create_port=True)

    # compartment
    compartment_id = 'extern'
    builder.create_dfba_compartment(model, compartment_id=compartment_id, unit_volume=UNIT_VOLUME,
                                    create_port=True)

    # species
    model_fba = doc_fba.getModel()
    builder.create_dfba_species(model, model_fba, compartment_id=compartment_id, unit_amount=UNIT_AMOUNT,
                                hasOnlySubstanceUnits=True, create_port=True)

    # exchange bounds
    builder.create_exchange_bounds(model, model_fba=model_fba, unit_flux=UNIT_FLUX, create_ports=True)


    objects = [
        # exchange bounds
        # FIXME: readout the FBA network bounds
        mc.Parameter(sid="lb_default", value=builder.LOWER_BOUND_DEFAULT, unit=UNIT_FLUX, constant=True),

        # kinetic bound parameter & calculation
        mc.Parameter(sid='ub_R1', value=1.0, unit=UNIT_FLUX, constant=False, sboTerm="SBO:0000625"),
        mc.Parameter(sid='k1', value=-0.2, unit="per_s", name="k1", constant=False),
        mc.RateRule(sid="ub_R1", value="k1*ub_R1"),

        # bound assignment rules
        mc.AssignmentRule(sid="lb_EX_A", value='max(lb_default, -A/dt)'),
        mc.AssignmentRule(sid="lb_EX_C", value='max(lb_default, -C/dt)'),
    ]
    mc.create_objects(model, objects)

    # ports
    comp.create_ports(model, portType=comp.PORT_TYPE_PORT,
                      idRefs=["ub_R1"])
    if annotations:
        annotator.annotate_sbml_doc(doc, annotations)
    sbmlio.write_sbml(doc, filepath=os.path.join(directory, sbml_file), validate=True)
Exemple #15
0
def create_exchange_reaction(model, species_id, exchange_type=EXCHANGE, flux_unit=None):
    """ Factory method to create exchange reactions for species in the FBA model.

    Creates the exchange reaction, the upper and lower bounds,
    and the ports.

    :param model:
    :param species_id:
    :param exchange_type:
    :param flux_unit:

    :return:
    """
    if exchange_type not in [EXCHANGE, EXCHANGE_IMPORT, EXCHANGE_EXPORT]:
        raise ValueError("Wrong exchange_type: {}".format(exchange_type))

    # id (e.g. EX_A)
    ex_rid = EXCHANGE_REACTION_PREFIX + species_id
    lb_id = LOWER_BOUND_PREFIX + ex_rid
    ub_id = UPPER_BOUND_PREFIX + ex_rid

    lb_value = LOWER_BOUND_DEFAULT
    ub_value = UPPER_BOUND_DEFAULT
    if exchange_type == EXCHANGE_IMPORT:
        # negative flux through exchange reaction
        ub_value = ZERO_BOUND
    if exchange_type == EXCHANGE_EXPORT:
        lb_value = ZERO_BOUND

    parameters = [
        fac.Parameter(sid=lb_id,
                      value=lb_value,
                      unit=flux_unit, constant=True, sboTerm=FLUX_BOUND_SBO),
        fac.Parameter(sid=ub_id,
                      value=ub_value,
                      unit=flux_unit, constant=True, sboTerm=FLUX_BOUND_SBO),
    ]
    fac.create_objects(model, parameters)

    # exchange reactions are all reversible (it depends on the bounds in which direction they operate)
    ex_r = fac.create_reaction(model, rid=ex_rid, reversible=True,
                               reactants={species_id: 1}, sboTerm=EXCHANGE_REACTION_SBO)

    # exchange bounds
    fbc.set_flux_bounds(ex_r, lb=lb_id, ub=ub_id)

    # create ports
    comp.create_ports(model, portType=comp.PORT_TYPE_PORT,
                      idRefs=[ex_rid, lb_id, ub_id])

    return ex_r
Exemple #16
0
def create_dfba_dt(model, step_size=DT_SIM, time_unit=None, create_port=True):
    """ Creates the dt parameter in the model.

    :param model:
    :param create_port:
    :param step_size:
    :param time_unit:
    :return:
    """
    objects = [
        fac.Parameter(sid=DT_ID, value=step_size, unit=time_unit, constant=True, sboTerm=DT_SBO)
    ]
    fac.create_objects(model, objects)
    if create_port:
        comp.create_ports(model, idRefs=[DT_ID])
def bounds_model(sbml_file, directory, doc_fba=None):
    """"
    Submodel for dynamically calculating the flux bounds.

    The dynamically changing flux bounds are the input to the
    FBA model.

    The units of the exchange fluxes must fit to the transported species.
    """
    doc = builder.template_doc_bounds("ecoli")
    model = doc.getModel()

    bounds_notes = notes.format("""
    <h2>BOUNDS submodel</h2>
    <p>Submodel for dynamically calculating the flux bounds.
    The dynamically changing flux bounds are the input to the
    FBA model.</p>
    """)
    utils.set_model_info(model, notes=bounds_notes, creators=creators, units=units, main_units=main_units)

    # dt
    compartment_id = "bioreactor"
    builder.create_dfba_dt(model, time_unit=UNIT_TIME, create_port=True)

    # compartment
    builder.create_dfba_compartment(model, compartment_id=compartment_id, unit_volume=UNIT_VOLUME, create_port=True)

    # dynamic species
    model_fba = doc_fba.getModel()
    builder.create_dfba_species(model, model_fba, compartment_id=compartment_id, unit_amount=UNIT_AMOUNT, create_port=True,
                                exclude_sids=['X'])
    # FIXME: define biomass separately, also port needed for biomass
    mc.create_objects(model, [
        mc.Parameter(sid='cf_X', value=1.0, unit="g_per_mmol", name="biomass conversion factor", constant=True),
        mc.Species(sid='X', initialAmount=0.001, compartment=compartment_id, name='biomass', substanceUnit='g', hasOnlySubstanceUnits=True,
                   conversionFactor='cf_X')
    ])


    # exchange & dynamic bounds
    if not biomass_weighting:
        builder.create_exchange_bounds(model, model_fba=model_fba, unit_flux=UNIT_FLUX, create_ports=True)
        builder.create_dynamic_bounds(model, model_fba, unit_flux=UNIT_FLUX)
    else:
        builder.create_exchange_bounds(model, model_fba=model_fba, unit_flux=UNIT_FLUX_PER_G, create_ports=True)
        builder.create_dynamic_bounds(model, model_fba, unit_flux=UNIT_FLUX_PER_G)

    sbmlio.write_sbml(doc, filepath=pjoin(directory, sbml_file), validate=True)
Exemple #18
0
    def create_sbml(self, model):
        from sbmlutils.factory import create_objects
        # parameters and rules
        create_objects(model, self.pars, key='parameters')
        create_objects(model, self.rules, key='rules')

        # reaction
        r = model.createReaction()  # type: libsbml.Reaction
        r.setId(self.rid)
        if self.name:
            r.setName(self.name)
        else:
            r.setName(self.rid)
        if self.compartment:
            r.setCompartment(self.compartment)
        if self.sboTerm:
            r.setSBOTerm(self.sboTerm)
        r.setReversible(self.equation.reversible)
        r.setFast(self.fast)

        # equation
        for reactant in self.equation.reactants:  # type: libsbml.SpeciesReference
            sref = r.createReactant()
            sref.setSpecies(reactant.sid)
            sref.setStoichiometry(reactant.stoichiometry)
            sref.setConstant(True)
        for product in self.equation.products:  # type: libsbml.SpeciesReference
            sref = r.createProduct()
            sref.setSpecies(product.sid)
            sref.setStoichiometry(product.stoichiometry)
            sref.setConstant(True)
        for modifier in self.equation.modifiers:
            sref = r.createModifier()
            sref.setSpecies(modifier)

        # kinetics
        if self.formula:
            ReactionTemplate.set_kinetic_law(model, r, self.formula.value)

        # add fbc bounds
        if self.upperFluxBound or self.lowerFluxBound:
            r_fbc = r.getPlugin("fbc")  # type: libsbml.FbcReactionPlugin
            if self.upperFluxBound:
                r_fbc.setUpperFluxBound(self.upperFluxBound)
            if self.lowerFluxBound:
                r_fbc.setLowerFluxBound(self.lowerFluxBound)

        return r
Exemple #19
0
def create_dummy_species(model, compartment_id, unit_amount=None, hasOnlySubstanceUnits=False):
    """ Creates the dummy species in the top model.
    Adds a deletion in the top model which removes the object again.

    :param model: SBML model
    :param compartment_id: compartment
    :param unit_amount: unit
    :param hasOnlySubstanceUnits: switch if amount or concentration
    :return:
    """
    # dummy species for dummy reactions (empty set)
    fac.create_objects(model,
                       [fac.Species(sid=DUMMY_SPECIES_ID, name=DUMMY_SPECIES_ID, initialConcentration=0, substanceUnit=unit_amount,
                                    hasOnlySubstanceUnits=hasOnlySubstanceUnits,
                                    compartment=compartment_id, sboTerm=DUMMY_SPECIES_SBO),
                        ])
Exemple #20
0
def create_dynamic_bounds(model_bounds, model_fba, unit_flux=None):
    """ Creates the dynamic bounds for the model.

    It is necessary to create copies of the fixed bounds from the fba model
    which are subsequently used in the dynamic bounds calculation.

    :return:
    """
    fba_suffix = "_fba"
    objects = []
    ex_rids = utils.find_exchange_reactions(model_fba)
    for ex_rid, sid in ex_rids.items():
        r = model_fba.getReaction(ex_rid)
        r_fbc = r.getPlugin(SBML_FBC_NAME)

        # get compartment from species
        s = model_bounds.getSpecies(sid)
        cid = s.getCompartment()

        # upper bound parameter (export from FBA, i.e increase concentration)
        ub_id = r_fbc.getUpperFluxBound()
        fba_ub_id = ub_id + fba_suffix
        ub_value = model_fba.getParameter(ub_id).getValue()
        ub_formula = "{}".format(fba_ub_id)
        objects.extend([
            fac.Parameter(sid=fba_ub_id, value=ub_value, unit=unit_flux, constant=True, sboTerm=FLUX_BOUND_SBO),
            fac.AssignmentRule(sid=ub_id, value=ub_formula, name="fba export bound ({})".format(sid)),
        ])

        # lower bound parameter (import to FBA, i.e decrease concentration)
        lb_id = r_fbc.getLowerFluxBound()
        fba_lb_id = lb_id + fba_suffix
        lb_value = model_fba.getParameter(lb_id).getValue()
        # concentration/amount formula for import depending on available species

        if s.getHasOnlySubstanceUnits():
            lb_formula = "max({}, -{}/dt)".format(fba_lb_id, sid)
        else:
            lb_formula = "max({}, -{}*{}/dt)".format(fba_lb_id, cid, sid)

        objects.extend([
            # default bounds from fba
            fac.Parameter(sid=fba_lb_id, value=lb_value, unit=unit_flux, constant=False, sboTerm=FLUX_BOUND_SBO),
            # uptake bounds (lower bound)
            fac.AssignmentRule(sid=lb_id, value=lb_formula, name="dfba import bound ({})".format(sid)),
        ])
    fac.create_objects(model_bounds, objects)
Exemple #21
0
def create_exchange_bounds(model_bounds,
                           model_fba,
                           unit_flux=None,
                           create_ports=True):
    """ Creates the exchange reaction flux bounds in the bounds model.

    :param model_bounds: the bounds model submodel
    :param model_fba: the fba submodel
    :param unit_flux: unit of fluxes
    :param create_ports: should ports be created.
    :return:
    """
    ex_rids = utils.find_exchange_reactions(model_fba)
    objects = []
    port_sids = []
    for ex_rid, sid in ex_rids.items():
        r = model_fba.getReaction(ex_rid)

        # lower & upper bound parameters
        r_fbc = r.getPlugin(SBML_FBC_NAME)
        lb_id = r_fbc.getLowerFluxBound()
        lb_value = model_fba.getParameter(lb_id).getValue()
        ub_id = r_fbc.getUpperFluxBound()
        ub_value = model_fba.getParameter(ub_id).getValue()

        # This creates the dynamical flux bound variables which are initialized with the
        # constant fba bounds
        objects.extend([
            # for assignments
            Parameter(sid=lb_id,
                      value=lb_value,
                      unit=unit_flux,
                      constant=False,
                      sboTerm=FLUX_BOUND_SBO),
            Parameter(sid=ub_id,
                      value=ub_value,
                      unit=unit_flux,
                      constant=False,
                      sboTerm=FLUX_BOUND_SBO),
        ])
        port_sids.extend([lb_id, ub_id])

    # create bounds
    factory.create_objects(model_bounds, objects)
    # create ports
    if create_ports:
        comp.create_ports(model_bounds, idRefs=port_sids)
Exemple #22
0
def test_event() -> None:
    objects = [
        Parameter(sid="p1", value=0.0, constant=False),
        Event(sid="e1", trigger="time >= 10", assignments={"p1": 10.0}),
    ]

    doc = libsbml.SBMLDocument(3, 1)
    model = doc.createModel()
    factory.create_objects(model, obj_iter=objects)

    events = model.getListOfEvents()
    assert len(events) == 1
    e = model.getEvent("e1")
    assert e is not None
    assert e.getId() == "e1"
    assignments = e.getListOfEventAssignments()
    assert len(assignments) == 1
def test_event():
    objects = [
        fac.Parameter(sid="p1", value=0.0, constant=False),
        fac.Event(sid="e1", trigger='time >= 10', assignments={'p1': 10.0})
    ]

    doc = libsbml.SBMLDocument(3, 1)
    model = doc.createModel()
    fac.create_objects(model, obj_iter=objects)

    events = model.getListOfEvents()
    assert len(events) == 1
    e = model.getEvent("e1")
    assert e is not None
    assert e.getId() == "e1"
    assignments = e.getListOfEventAssignments()
    assert len(assignments) == 1
Exemple #24
0
def create_biomass_species(model, sid, unit, cf_unit, compartment_id, create_port=True):
    """ Creates the biomass species.

    :param model:
    :return:
    """
    # FIXME: implement
    raise NotImplementedError
    pass

    fac.create_objects(model, [
        fac.Parameter(sid='cf_X', value=1.0, unit="g_per_mmol", name="biomass conversion factor", constant=True),
        fac.Species(sid='X', value=0.001, compartment='c', name='biomass', substanceUnit='g', hasOnlySubstanceUnits=True,
                    conversionFactor='cf_biomass')
    ])
    if create_port:
        comp.create_ports(model, idRefs=['X'])
Exemple #25
0
def create_port_doc():
    sbmlns = libsbml.SBMLNamespaces(3, 1, 'comp', 1)
    doc = libsbml.SBMLDocument(sbmlns)
    doc.setPackageRequired("comp", True)
    model = doc.createModel()
    model.setId("toy_update")
    model.setName("toy (UPDATE submodel)")
    model.setSBOTerm(comp.SBO_CONTINOUS_FRAMEWORK)

    objects = [
        fac.Compartment(sid='extern', value=1.0, unit="m3", constant=True, name='external compartment'),
        fac.Species(sid='A', name="A", initialConcentration=10.0, hasOnlySubstanceUnits=True, compartment="extern"),
        fac.Species(sid='C', name="C", initialConcentration=0, hasOnlySubstanceUnits=True, compartment="extern"),
        fac.Parameter(sid="EX_A", value=1.0, constant=False, sboTerm="SBO:0000613"),
        fac.Parameter(sid="EX_C", value=1.0, constant=False, sboTerm="SBO:0000613"),
    ]
    fac.create_objects(model, obj_iter=objects)
    return doc
Exemple #26
0
def create_dfba_dt(model, step_size=DT_SIM, time_unit=None, create_port=True):
    """ Creates the dt parameter in the model.

    :param model:
    :param create_port:
    :param step_size:
    :param time_unit:
    :return:
    """
    objects = [
        Parameter(sid=DT_ID,
                  value=step_size,
                  unit=time_unit,
                  constant=True,
                  sboTerm=DT_SBO,
                  port=create_port)
    ]
    factory.create_objects(model, objects)
Exemple #27
0
def create_port_doc():
    sbmlns = libsbml.SBMLNamespaces(3, 1, "comp", 1)
    doc = libsbml.SBMLDocument(sbmlns)
    doc.setPackageRequired("comp", True)
    model = doc.createModel()
    model.setId("toy_update")
    model.setName("toy (UPDATE submodel)")
    model.setSBOTerm(SBO_CONTINOUS_FRAMEWORK)

    objects = [
        fac.Compartment(
            sid="extern",
            value=1.0,
            unit="m3",
            constant=True,
            name="external compartment",
        ),
        fac.Species(
            sid="A",
            name="A",
            initialConcentration=10.0,
            hasOnlySubstanceUnits=True,
            compartment="extern",
        ),
        fac.Species(
            sid="C",
            name="C",
            initialConcentration=0,
            hasOnlySubstanceUnits=True,
            compartment="extern",
        ),
        fac.Parameter(sid="EX_A",
                      value=1.0,
                      constant=False,
                      sboTerm="SBO:0000613"),
        fac.Parameter(sid="EX_C",
                      value=1.0,
                      constant=False,
                      sboTerm="SBO:0000613"),
    ]
    fac.create_objects(model, obj_iter=objects)
    return doc
Exemple #28
0
def create_fba_doc():
    sbmlns = libsbml.SBMLNamespaces(3, 1)
    sbmlns.addPackageNamespace("fbc", 2)
    sbmlns.addPackageNamespace("comp", 1)

    doc = libsbml.SBMLDocument(sbmlns)
    doc.setPackageRequired("comp", True)
    doc.setPackageRequired("fbc", False)
    model = doc.createModel()
    mplugin = model.getPlugin("fbc")
    mplugin.setStrict(True)

    objects = [
        fac.Compartment(sid='cell', value=1.0),
        fac.Species(sid='A', initialConcentration=0, compartment="cell"),
        fac.Species(sid='B', initialConcentration=0, compartment="cell"),
    ]
    fac.create_objects(model, objects)

    return doc
def test_event2():
    objects = [
        fac.Compartment('c', value=1.0),
        fac.Species('S1', initialAmount=1.0, compartment='c'),
        fac.Parameter(sid="p1", value=0.0, constant=False),

        fac.Event(sid="e1", trigger='time >= 100', assignments={'p1': 10.0, 'S1': "p1 + 10"})
    ]

    doc = libsbml.SBMLDocument(3, 1)
    model = doc.createModel()
    fac.create_objects(model, obj_iter=objects)

    events = model.getListOfEvents()
    assert len(events) == 1
    e = model.getEvent("e1")
    assert e is not None
    assert e.getId() == "e1"
    assignments = e.getListOfEventAssignments()
    assert len(assignments) == 2
def create_fba_doc():
    sbmlns = libsbml.SBMLNamespaces(3, 1)
    sbmlns.addPackageNamespace("fbc", 2)
    sbmlns.addPackageNamespace("comp", 1)

    doc = libsbml.SBMLDocument(sbmlns)
    doc.setPackageRequired("comp", True)
    doc.setPackageRequired("fbc", False)
    model = doc.createModel()
    mplugin = model.getPlugin("fbc")
    mplugin.setStrict(True)

    objects = [
        fac.Compartment(sid='cell', value=1.0),
        fac.Species(sid='A', initialConcentration=0, compartment="cell"),
        fac.Species(sid='B', initialConcentration=0, compartment="cell"),
    ]
    fac.create_objects(model, objects)

    return doc
Exemple #31
0
def create_update_parameter(model, sid, unit_flux):
    """ Creates the update parameter.
    The update parameter correspond to the flux parameters
    in the top model.

    :param model:
    :type model:
    :param sid:
    :type sid:
    :param unit_flux:
    :type unit_flux:
    :return:
    :rtype:
    """
    pid = FLUX_PARAMETER_PREFIX + sid
    parameter = fac.Parameter(sid=pid, value=1.0, constant=True, unit=unit_flux, sboTerm=UPDATE_PARAMETER_SBO)
    fac.create_objects(model, [parameter])
    # create port
    comp.create_ports(model, portType=comp.PORT_TYPE_PORT,
                      idRefs=[pid])
    return pid
Exemple #32
0
def test_event2() -> None:
    objects = [
        Compartment("c", value=1.0),
        Species("S1", initialAmount=1.0, compartment="c"),
        Parameter(sid="p1", value=0.0, constant=False),
        Event(
            sid="e1", trigger="time >= 100", assignments={"p1": 10.0, "S1": "p1 + 10"}
        ),
    ]

    doc = libsbml.SBMLDocument(3, 1)
    model = doc.createModel()
    factory.create_objects(model, obj_iter=objects)

    events = model.getListOfEvents()
    assert len(events) == 1
    e = model.getEvent("e1")
    assert e is not None
    assert e.getId() == "e1"
    assignments = e.getListOfEventAssignments()
    assert len(assignments) == 2
def update_model(sbml_file, directory, doc_fba=None):
    """
        Submodel for dynamically updating the metabolite count/concentration.
        This updates the ode model based on the FBA fluxes.
    """
    doc = builder.template_doc_update("ecoli")
    model = doc.getModel()
    update_notes = notes.format("""
        <h2>UPDATE submodel</h2>
        <p>Submodel for dynamically updating the metabolite count.
        This updates the ode model based on the FBA fluxes.</p>
        """)
    utils.set_model_info(model, notes=update_notes, creators=creators, units=units, main_units=main_units)

    # compartment
    compartment_id = "bioreactor"
    builder.create_dfba_compartment(model, compartment_id=compartment_id, unit_volume=UNIT_VOLUME, create_port=True)

    # dynamic species
    model_fba = doc_fba.getModel()


    # creates all the exchange reactions, biomass must be handeled separately
    builder.create_dfba_species(model, model_fba, compartment_id=compartment_id, unit_amount=UNIT_AMOUNT, create_port=True)

    # FIXME: biomass via function
    mc.create_objects(model, [
        mc.Parameter(sid='cf_biomass', value=1.0, unit="g_per_mmol", name="biomass conversion factor", constant=True),
        mc.Species(sid='X', initialAmount=0.001, compartment='c', name='biomass', substanceUnit='g', hasOnlySubstanceUnits=True,
                   conversionFactor='cf_biomass')
    ])


    # update reactions
    # FIXME: weight with X (biomass)
    builder.create_update_reactions(model, model_fba=model_fba, formula="-{}", unit_flux=UNIT_FLUX,
                                    modifiers=[])

    # write SBML file
    sbmlio.write_sbml(doc, filepath=pjoin(directory, sbml_file), validate=True)
Exemple #34
0
def create_dfba_species(model,
                        model_fba,
                        compartment_id,
                        hasOnlySubstanceUnits=False,
                        unit_amount=None,
                        create_port=True,
                        exclude_sids=[]):
    """ Add DFBA species and compartments from fba model to model.
    Creates the dynamic species and respetive compartments with
    the necessary ports.
    This is used in the bounds submodel, update submodel and the
    and top model.

    :param model:
    :param model_fba:
    :return:
    """
    objects = []
    ex_rids = utils.find_exchange_reactions(model_fba)
    for ex_rid in ex_rids:

        r = model_fba.getReaction(ex_rid)
        sid = r.getReactant(0).getSpecies()
        if sid in exclude_sids:
            continue

        # exchange species
        s = model_fba.getSpecies(sid)
        objects.append(
            Species(sid=sid,
                    name=s.getName(),
                    initialConcentration=1.0,
                    substanceUnit=unit_amount,
                    hasOnlySubstanceUnits=hasOnlySubstanceUnits,
                    compartment=compartment_id,
                    port=create_port))

    factory.create_objects(model, objects)
Exemple #35
0
def create_dummy_reactions(model, model_fba, unit_flux=None):
    """ Creates the dummy reactions.
    This also creates the corresponding flux parameters and flux assignments.

    :param model:
    :param model_fba:
    :param unit_flux:
    :return:
    """
    ex_rids = utils.find_exchange_reactions(model_fba)
    objects = []
    for ex_rid, sid in ex_rids.items():

        pid_flux = FLUX_PARAMETER_PREFIX + sid
        rid_flux = DUMMY_REACTION_PREFIX + sid

        objects = [
            # flux parameter: flux from fba (rate of reaction)
            Parameter(sid=pid_flux,
                      value=1.0,
                      constant=True,
                      unit=unit_flux,
                      sboTerm=FLUX_PARAMETER_SBO),

            # dummy reaction (pseudoreaction)
            Reaction(sid=rid_flux,
                     reversible=False,
                     equation=" -> {}".format(DUMMY_SPECIES_ID),
                     sboTerm=DUMMY_REACTION_SBO,
                     formula=('0 {}'.format(unit_flux), unit_flux)),

            # flux assignment rule
            AssignmentRule(pid_flux,
                           value=rid_flux,
                           sboTerm=FLUX_ASSIGNMENTRULE_SBO),
        ]
    factory.create_objects(model, objects)
Exemple #36
0
def create_exchange_bounds(model_bounds, model_fba, unit_flux=None, create_ports=True):
    """ Creates the exchange reaction flux bounds in the bounds model.

    :param model_bounds: the bounds model submodel
    :param model_fba: the fba submodel
    :param unit_flux: unit of fluxes
    :param create_ports: should ports be created.
    :return:
    """
    ex_rids = utils.find_exchange_reactions(model_fba)
    objects = []
    port_sids = []
    for ex_rid, sid in ex_rids.items():
        r = model_fba.getReaction(ex_rid)

        # lower & upper bound parameters
        r_fbc = r.getPlugin(SBML_FBC_NAME)
        lb_id = r_fbc.getLowerFluxBound()
        lb_value = model_fba.getParameter(lb_id).getValue()
        ub_id = r_fbc.getUpperFluxBound()
        ub_value = model_fba.getParameter(ub_id).getValue()

        # This creates the dynamical flux bound variables which are initialized with the
        # constant fba bounds
        objects.extend([
            # for assignments
            fac.Parameter(sid=lb_id, value=lb_value, unit=unit_flux, constant=False, sboTerm=FLUX_BOUND_SBO),
            fac.Parameter(sid=ub_id, value=ub_value, unit=unit_flux, constant=False, sboTerm=FLUX_BOUND_SBO),
        ])
        port_sids.extend([lb_id, ub_id])

    # create bounds
    fac.create_objects(model_bounds, objects)
    # create ports
    if create_ports:
        comp.create_ports(model_bounds, idRefs=port_sids)
Exemple #37
0
def create_update_reaction(model, sid, modifiers=None, formula="-{}"):
    """ Creates the update reaction for a given species.
    Creates the update parameter in the process.

    :param model:
    :param sid:
    :param modifiers:
    :param formula:
    :return:
    :rtype:
    """
    if modifiers is None:
        modifiers = []
    rid_update = UPDATE_REACTION_PREFIX + sid

    # format the formula
    formula = formula.format(FLUX_PARAMETER_PREFIX + sid)

    factory.create_objects(model, [
        Reaction(sid=rid_update,
                 sboTerm=UPDATE_REACTION_SBO,
                 equation="{} -> {}".format(sid, modifiers),
                 formula=(formula, None))
    ])
Exemple #38
0
def create_dummy_species(model,
                         compartment_id,
                         unit_amount=None,
                         hasOnlySubstanceUnits=False):
    """ Creates the dummy species in the top model.
    Adds a deletion in the top model which removes the object again.

    :param model: SBML model
    :param compartment_id: compartment
    :param unit_amount: unit
    :param hasOnlySubstanceUnits: switch if amount or concentration
    :return:
    """
    # dummy species for dummy reactions (empty set)
    objects = [
        Species(sid=DUMMY_SPECIES_ID,
                name=DUMMY_SPECIES_ID,
                initialConcentration=0,
                substanceUnit=unit_amount,
                hasOnlySubstanceUnits=hasOnlySubstanceUnits,
                compartment=compartment_id,
                sboTerm=DUMMY_SPECIES_SBO),
    ]
    factory.create_objects(model, objects)
Exemple #39
0
def create_update_parameter(model, sid, unit_flux):
    """ Creates the update parameter.
    The update parameter correspond to the flux parameters
    in the top model.

    :param model:
    :type model:
    :param sid:
    :type sid:
    :param unit_flux:
    :type unit_flux:
    :return: id of parameter
    :rtype:
    """
    pid = FLUX_PARAMETER_PREFIX + sid
    factory.create_objects(model, [
        Parameter(sid=pid,
                  value=1.0,
                  constant=True,
                  unit=unit_flux,
                  sboTerm=UPDATE_PARAMETER_SBO,
                  port=True)
    ])
    return pid
Exemple #40
0
def create_dfba_compartment(model, compartment_id, unit_volume=None, create_port=True):
    """ Creates the main compartment for the dynamic species.

    :param model:
    :param compartment_id: id
    :param unit_volume: unit
    :param create_port: flag to create port
    :return: created libsbml.Compartment
    """
    objects = [
        fac.Compartment(sid=compartment_id, value=1.0, unit=unit_volume, constant=True, name=compartment_id,
                        spatialDimensions=3),
    ]
    c = fac.create_objects(model, objects)
    if create_port:
        comp.create_ports(model, idRefs=[compartment_id])
    return c
Exemple #41
0
def create_dfba_compartment(model,
                            compartment_id,
                            unit_volume=None,
                            create_port=True):
    """ Creates the main compartment for the dynamic species.

    :param model:
    :param compartment_id: id
    :param unit_volume: unit
    :param create_port: flag to create port
    :return: created libsbml.Compartment
    """
    objects = [
        Compartment(sid=compartment_id,
                    value=1.0,
                    unit=unit_volume,
                    constant=True,
                    name=compartment_id,
                    spatialDimensions=3,
                    port=create_port),
    ]
    sbml_objects = factory.create_objects(model, objects)
    return next(iter(sbml_objects.values()))
Exemple #42
0
def update_exchange_reactions(model, flux_unit):
    """ Updates existing exchange reaction in FBA model.

    Sets all the necessary information and checks that correct.
    This is mainly used to prepare the exchange reactions of metabolites.

    :param flux_unit:
    :param model:
    :return:
    """

    # mapping of bounds to reactions
    bounds_dict = dict()

    ex_rids = utils.find_exchange_reactions(model)
    for ex_rid in ex_rids:
        r = model.getReaction(ex_rid)

        # make reversible
        if not r.getReversible():
            r.setReversible(True)
            logging.info("Exchange reaction set reversible: {}".format(r.getId()))

        # fix ids for exchange reactions
        sref = r.getReactant(0)
        sid = sref.getSpecies()
        rid = r.getId()
        if rid != EXCHANGE_REACTION_PREFIX + sid:
            r.setId(EXCHANGE_REACTION_PREFIX + sid)
            logging.warning("Exchange reaction fixd id: {} -> {}".format(rid, EXCHANGE_REACTION_PREFIX + sid))

    # new lookup necessary, due to possible changed ids
    ex_rids = utils.find_exchange_reactions(model)
    for ex_rid in ex_rids:
        r = model.getReaction(ex_rid)
        fbc_r = r.getPlugin(SBML_FBC_NAME)
        # store bounds in dictionary for value lookup
        for f_bound in ["getLowerFluxBound", "getUpperFluxBound"]:
            bound_id = getattr(fbc_r, f_bound).__call__()
            bound = model.getParameter(bound_id)
            bounds_dict[bound_id] = bound.getValue()

    # create unique bounds for exchange reactions
    for ex_rid in ex_rids:
        r = model.getReaction(ex_rid)
        fbc_r = r.getPlugin(SBML_FBC_NAME)
        lb_value = model.getParameter(fbc_r.getLowerFluxBound()).getValue()
        ub_value = model.getParameter(fbc_r.getUpperFluxBound()).getValue()

        lb_id = LOWER_BOUND_PREFIX + ex_rid
        ub_id = UPPER_BOUND_PREFIX + ex_rid

        parameters = [
            fac.Parameter(sid=lb_id,
                          value=lb_value,
                          unit=flux_unit, constant=True, sboTerm=FLUX_BOUND_SBO),
            fac.Parameter(sid=ub_id,
                          value=ub_value,
                          unit=flux_unit, constant=True, sboTerm=FLUX_BOUND_SBO),
        ]
        fac.create_objects(model, parameters)

        # set bounds
        fbc.set_flux_bounds(r, lb=lb_id, ub=ub_id)

        # create ports for bounds and reaction
        comp.create_ports(model, portType=comp.PORT_TYPE_PORT,
                          idRefs=[ex_rid, lb_id, ub_id])

    # check all the exchange reactions
    for ex_rid in ex_rids:
        check_exchange_reaction(model, ex_rid)
def fba_model(sbml_file, directory, annotations=None):
    """ FBA model
    
    :param sbml_file: output file name 
    :param directory: output directory
    :return: SBMLDocument
    """
    fba_notes = notes.format("""
    <h2>FBA submodel</h2>
    <p>DFBA fba submodel. Unbalanced metabolites are encoded via exchange fluxes.</p>
    """)
    doc = builder.template_doc_fba(settings.MODEL_ID)
    model = doc.getModel()
    utils.set_model_info(model,
                         notes=fba_notes,
                         creators=creators,
                         units=units,
                         main_units=main_units)

    objects = [
        # compartments
        mc.Compartment(sid='cell',
                       value=1.0,
                       unit=UNIT_VOLUME,
                       constant=True,
                       name='cell',
                       spatialDimensions=3),

        # exchange species
        mc.Species(sid='atp',
                   name="ATP",
                   initialConcentration=0,
                   substanceUnit=UNIT_AMOUNT,
                   hasOnlySubstanceUnits=False,
                   compartment="cell"),
        mc.Species(sid='adp',
                   name="ADP",
                   initialConcentration=0,
                   substanceUnit=UNIT_AMOUNT,
                   hasOnlySubstanceUnits=False,
                   compartment="cell"),
        mc.Species(sid='glc',
                   name="Glucose",
                   initialConcentration=0,
                   substanceUnit=UNIT_AMOUNT,
                   hasOnlySubstanceUnits=False,
                   compartment="cell"),
        mc.Species(sid='pyr',
                   name='Pyruvate',
                   initialConcentration=0,
                   substanceUnit=UNIT_AMOUNT,
                   hasOnlySubstanceUnits=False,
                   compartment="cell"),

        # internal species
        mc.Species(sid='fru16bp',
                   name='Fructose 1,6-bisphospate',
                   initialConcentration=0,
                   substanceUnit=UNIT_AMOUNT,
                   hasOnlySubstanceUnits=False,
                   compartment="cell"),
        mc.Species(sid='pg2',
                   name='2-Phosphoglycerate',
                   initialConcentration=0,
                   substanceUnit=UNIT_AMOUNT,
                   hasOnlySubstanceUnits=False,
                   compartment="cell"),

        # bounds
        mc.Parameter(sid="ub_R3",
                     value=1.0,
                     unit=UNIT_FLUX,
                     constant=True,
                     sboTerm=builder.FLUX_BOUND_SBO),
        mc.Parameter(sid="zero",
                     value=0.0,
                     unit=UNIT_FLUX,
                     constant=True,
                     sboTerm=builder.FLUX_BOUND_SBO),
        mc.Parameter(sid="ub_default",
                     value=builder.UPPER_BOUND_DEFAULT,
                     unit=UNIT_FLUX,
                     constant=True,
                     sboTerm=builder.FLUX_BOUND_SBO),
    ]
    mc.create_objects(model, objects)

    # reactions
    r1 = mc.create_reaction(model,
                            rid="R1",
                            name="glu + 2 atp -> fru16bp + 2 adp",
                            fast=False,
                            reversible=False,
                            reactants={
                                "glc": 1,
                                "atp": 2
                            },
                            products={
                                "fru16bp": 1,
                                'adp': 2
                            },
                            compartment='cell')
    r2 = mc.create_reaction(model,
                            rid="R2",
                            name="fru16bp -> 2 pg2",
                            fast=False,
                            reversible=False,
                            reactants={"fru16bp": 1},
                            products={"pg2": 2},
                            compartment='cell')
    r3 = mc.create_reaction(model,
                            rid="R3",
                            name="pg2 + adp -> pyr + atp",
                            fast=False,
                            reversible=False,
                            reactants={
                                "pg2": 1,
                                "adp": 2
                            },
                            products={
                                "pyr": 1,
                                "atp": 2
                            },
                            compartment='cell')

    # flux bounds
    fbc.set_flux_bounds(r1, lb="zero", ub="ub_default")
    fbc.set_flux_bounds(r2, lb="zero", ub="ub_default")
    fbc.set_flux_bounds(r3, lb="zero", ub="ub_R3")
    # fbc.set_flux_bounds(ratp, lb="zero", ub="ub_RATP")

    # exchange reactions
    for sid in ['atp', 'adp', 'glc', 'pyr']:
        builder.create_exchange_reaction(model,
                                         species_id=sid,
                                         flux_unit=UNIT_FLUX)

    # objective function
    model_fbc = model.getPlugin("fbc")
    fbc.create_objective(model_fbc,
                         oid="RATP_maximize",
                         otype="maximize",
                         fluxObjectives={"R3": 1.0},
                         active=True)

    if annotations:
        annotator.annotate_sbml_doc(doc, annotations)

    # write SBML
    sbmlio.write_sbml(doc,
                      filepath=os.path.join(directory, sbml_file),
                      validate=True)
    return doc
def top_model(sbml_file, directory, emds, doc_fba, annotations=None):
    """ Create top comp model.

    Creates full comp model by combining fba, update and bounds
    model with additional kinetics in the top model.
    """
    top_notes = notes.format("""
        <h2>TOP model</h2>
        <p>Main comp DFBA model by combining fba, update and bounds
            model with additional kinetics in the top model.</p>
        """)
    working_dir = os.getcwd()
    os.chdir(directory)

    doc = builder.template_doc_top(settings.MODEL_ID, emds)
    model = doc.getModel()
    utils.set_model_info(model,
                         notes=top_notes,
                         creators=creators, units=units, main_units=main_units)

    # dt
    builder.create_dfba_dt(model, step_size=DT_SIM, time_unit=UNIT_TIME, create_port=False)

    # compartment
    compartment_id = "extern"
    builder.create_dfba_compartment(model, compartment_id=compartment_id, unit_volume=UNIT_VOLUME, create_port=False)

    # dynamic species
    model_fba = doc_fba.getModel()
    builder.create_dfba_species(model, model_fba, compartment_id=compartment_id, hasOnlySubstanceUnits=True,
                                unit_amount=UNIT_AMOUNT, create_port=False)
    # dummy species
    builder.create_dummy_species(model, compartment_id=compartment_id, hasOnlySubstanceUnits=True,
                                 unit_amount=UNIT_AMOUNT)

    # exchange flux bounds
    builder.create_exchange_bounds(model, model_fba=model_fba, unit_flux=UNIT_FLUX, create_ports=False)

    # dummy reactions & flux assignments
    builder.create_dummy_reactions(model, model_fba=model_fba, unit_flux=UNIT_FLUX)

    # replacedBy (fba reactions)
    builder.create_top_replacedBy(model, model_fba=model_fba)

    # replaced
    builder.create_top_replacements(model, model_fba, compartment_id=compartment_id)

    # initial concentrations for fba exchange species
    initial_c = {
        'A': 10.0,
        'C': 0.0,
    }
    for sid, value in initial_c.items():
        species = model.getSpecies(sid)
        species.setInitialConcentration(value)

    # kinetic model
    mc.create_objects(model, [
        # kinetic species
        mc.Species(sid='D', initialConcentration=0, substanceUnit=UNIT_AMOUNT,
                   hasOnlySubstanceUnits=True, compartment="extern"),

        # kinetic
        mc.Parameter(sid="k_R4", value=0.1, constant=True, unit="per_s", sboTerm="SBO:0000009"),

        # bounds parameter
        mc.Parameter(sid='ub_R1', value=1.0, unit=UNIT_FLUX, constant=False, sboTerm="SBO:0000625"),
    ])
    # kinetic reaction (MMK)
    mc.create_reaction(model, rid="R4", name="R4: C -> D", fast=False, reversible=False,
                       reactants={"C": 1}, products={"D": 1}, formula="k_R4*C", compartment="extern")

    # kinetic flux bounds
    comp.replace_elements(model, 'ub_R1', ref_type=comp.SBASE_REF_TYPE_PORT,
                          replaced_elements={'bounds': ['ub_R1_port'],
                                             'fba': ['ub_R1_port']})

    # write SBML file
    if annotations:
        annotation.annotate_sbml_doc(doc, annotations)
    sbmlio.write_sbml(doc, filepath=os.path.join(directory, sbml_file), validate=True)

    # change back the working dir
    os.chdir(working_dir)
def bounds_model(sbml_file, directory, doc_fba=None, annotations=None):
    """"
    Submodel for dynamically calculating the flux bounds.

    The dynamically changing flux bounds are the input to the
    FBA model.
    """
    # TODO: the bounds model should be created based on the FBA model (i.e. use the exchange reactions
    # to create the bounds info.

    bounds_notes = notes.format("""
    <h2>BOUNDS submodel</h2>
    <p>Submodel for dynamically calculating the flux bounds.
    The dynamically changing flux bounds are the input to the
    FBA model.</p>
    """)
    doc = builder.template_doc_bounds(settings.MODEL_ID)
    model = doc.getModel()
    utils.set_model_info(model, notes=bounds_notes, creators=creators, units=units, main_units=main_units)

    # dt
    compartment_id = "bioreactor"
    builder.create_dfba_dt(model, time_unit=UNIT_TIME, create_port=True)

    # compartment
    builder.create_dfba_compartment(model, compartment_id=compartment_id, unit_volume=UNIT_VOLUME, create_port=True)

    # dynamic species
    model_fba = doc_fba.getModel()
    builder.create_dfba_species(model, model_fba, compartment_id=compartment_id, unit_amount=UNIT_AMOUNT,
                                create_port=True)
    # bounds
    builder.create_exchange_bounds(model, model_fba=model_fba, unit_flux=UNIT_FLUX, create_ports=True)

    # bounds
    fba_infix = "fba_"
    model_fba = doc_fba.getModel()
    objects = []
    ex_rids = utils.find_exchange_reactions(model_fba)
    for ex_rid, sid in ex_rids.items():
        r = model_fba.getReaction(ex_rid)

        # lower & upper bound parameters
        r_fbc = r.getPlugin(builder.SBML_FBC_NAME)
        lb_id = r_fbc.getLowerFluxBound()
        fba_lb_id = builder.LOWER_BOUND_PREFIX + fba_infix + ex_rid
        lb_value = model_fba.getParameter(lb_id).getValue()

        objects.extend([
            # default bounds from fba
            mc.Parameter(sid=fba_lb_id, value=lb_value, unit=UNIT_FLUX, constant=False),
        ])
    mc.create_objects(model, objects)

    objects = [

        # kinetic lower bounds
        mc.Parameter(sid="lb_kin_EX_Glcxt", value=builder.LOWER_BOUND_DEFAULT, unit=UNIT_FLUX, constant=False,
                     sboTerm="SBO:0000612"),
        mc.Parameter(sid="lb_kin_EX_O2", value=builder.LOWER_BOUND_DEFAULT, unit=UNIT_FLUX, constant=False,
                     sboTerm="SBO:0000612"),

        # parameters for kinetic bounds
        mc.Parameter(sid='Vmax_EX_O2', value=15, unit=UNIT_FLUX, constant=True),
        mc.Parameter(sid='Vmax_EX_Glcxt', value=10, unit=UNIT_FLUX, constant=True),
        mc.Parameter(sid='Km_EX_Glcxt', value=0.015, unit=UNIT_CONCENTRATION, name="Km_vGlcxt", constant=True),

        # kinetic bounds (unintuitive direction due to the identical concentrations in bioreactor and model)
        mc.AssignmentRule(sid="lb_kin_EX_Glcxt", value="-Vmax_EX_Glcxt * Glcxt/(Km_EX_Glcxt + Glcxt)"),
        mc.AssignmentRule(sid="lb_kin_EX_O2", value="-Vmax_EX_O2"),

        # exchange reaction bounds
        # uptake bounds (lower bound)
        # TODO: FIXME the X hack
        # the bounds for the fba model have to be in mmol/h/gdw
        mc.AssignmentRule(sid="lb_EX_Ac", value="max(lb_fba_EX_Ac, -Ac/X/1 l_per_mmol*bioreactor/dt)"),
        mc.AssignmentRule(sid="lb_EX_X", value="max(lb_fba_EX_X, -X/X/1 l_per_mmol*bioreactor/dt)"),
        mc.AssignmentRule(sid="lb_EX_Glcxt", value="max(lb_kin_EX_Glcxt, -Glcxt/X/1 l_per_mmol*bioreactor/dt)"),
        mc.AssignmentRule(sid="lb_EX_O2", value="max(lb_kin_EX_O2, -O2/X/1 l_per_mmol*bioreactor/dt)"),
    ]
    mc.create_objects(model, objects)

    if annotations:
        annotation.annotate_sbml_doc(doc, annotations)
    sbmlio.write_sbml(doc, filepath=pjoin(directory, sbml_file), validate=True)
Exemple #46
0
def fba_model(sbml_file, directory, annotations=None):
    """ FBA model
    
    :param sbml_file: output file name 
    :param directory: output directory
    :return: SBMLDocument
    """
    fba_notes = notes.format("""
    <h2>FBA submodel</h2>
    <p>DFBA fba submodel. Unbalanced metabolites are encoded via exchange fluxes.</p>
    """)
    doc = builder.template_doc_fba(settings.MODEL_ID)
    model = doc.getModel()
    utils.set_model_info(model,
                         notes=fba_notes,
                         creators=creators,
                         units=units,
                         main_units=main_units)

    objects = [
        # compartments
        mc.Compartment(sid='extern',
                       value=1.0,
                       unit=UNIT_VOLUME,
                       constant=True,
                       name='external compartment',
                       spatialDimensions=3),
        mc.Compartment(sid='cell',
                       value=1.0,
                       unit=UNIT_VOLUME,
                       constant=True,
                       name='cell',
                       spatialDimensions=3),
        mc.Compartment(sid='membrane',
                       value=1.0,
                       unit=UNIT_AREA,
                       constant=True,
                       name='membrane',
                       spatialDimensions=2),

        # exchange species
        mc.Species(sid='A',
                   name="A",
                   initialConcentration=0,
                   substanceUnit=UNIT_AMOUNT,
                   hasOnlySubstanceUnits=True,
                   compartment="extern"),
        mc.Species(sid='C',
                   name="C",
                   initialConcentration=0,
                   substanceUnit=UNIT_AMOUNT,
                   hasOnlySubstanceUnits=True,
                   compartment="extern"),

        # internal species
        mc.Species(sid='B1',
                   name="B1",
                   initialConcentration=0,
                   substanceUnit=UNIT_AMOUNT,
                   hasOnlySubstanceUnits=True,
                   compartment="cell"),
        mc.Species(sid='B2',
                   name="B2",
                   initialConcentration=0,
                   substanceUnit=UNIT_AMOUNT,
                   hasOnlySubstanceUnits=True,
                   compartment="cell"),

        # bounds
        mc.Parameter(sid="ub_R1",
                     value=1.0,
                     unit=UNIT_FLUX,
                     constant=True,
                     sboTerm=builder.FLUX_BOUND_SBO),
        mc.Parameter(sid="zero",
                     value=0.0,
                     unit=UNIT_FLUX,
                     constant=True,
                     sboTerm=builder.FLUX_BOUND_SBO),
        mc.Parameter(sid="ub_default",
                     value=builder.UPPER_BOUND_DEFAULT,
                     unit=UNIT_FLUX,
                     constant=True,
                     sboTerm=builder.FLUX_BOUND_SBO),
    ]
    mc.create_objects(model, objects)

    # reactions
    r1 = mc.create_reaction(model,
                            rid="R1",
                            name="A import (R1)",
                            fast=False,
                            reversible=True,
                            reactants={"A": 1},
                            products={"B1": 1},
                            compartment='membrane')
    r2 = mc.create_reaction(model,
                            rid="R2",
                            name="B1 <-> B2 (R2)",
                            fast=False,
                            reversible=True,
                            reactants={"B1": 1},
                            products={"B2": 1},
                            compartment='cell')
    r3 = mc.create_reaction(model,
                            rid="R3",
                            name="B2 export (R3)",
                            fast=False,
                            reversible=True,
                            reactants={"B2": 1},
                            products={"C": 1},
                            compartment='membrane')

    # flux bounds
    fbc.set_flux_bounds(r1, lb="zero", ub="ub_R1")
    fbc.set_flux_bounds(r2, lb="zero", ub="ub_default")
    fbc.set_flux_bounds(r3, lb="zero", ub="ub_default")

    # exchange reactions
    builder.create_exchange_reaction(model,
                                     species_id="A",
                                     flux_unit=UNIT_FLUX)
    builder.create_exchange_reaction(model,
                                     species_id="C",
                                     flux_unit=UNIT_FLUX)

    # objective function
    model_fbc = model.getPlugin("fbc")
    fbc.create_objective(model_fbc,
                         oid="R3_maximize",
                         otype="maximize",
                         fluxObjectives={"R3": 1.0},
                         active=True)

    # create ports for kinetic bounds
    comp.create_ports(model, portType=comp.PORT_TYPE_PORT, idRefs=["ub_R1"])

    # write SBML
    if annotations:
        annotator.annotate_sbml_doc(doc, annotations)
    sbml.write_sbml(doc,
                    filepath=os.path.join(directory, sbml_file),
                    validate=True)
    return doc
Exemple #47
0
def update_exchange_reactions(model, flux_unit):
    """ Updates existing exchange reaction in FBA model.

    Sets all the necessary information and checks that correct.
    This is mainly used to prepare the exchange reactions of metabolites.

    :param flux_unit:
    :param model:
    :return:
    """

    # mapping of bounds to reactions
    bounds_dict = dict()

    ex_rids = utils.find_exchange_reactions(model)
    for ex_rid in ex_rids:
        r = model.getReaction(ex_rid)

        # make reversible
        if not r.getReversible():
            r.setReversible(True)
            logging.info("Exchange reaction set reversible: {}".format(
                r.getId()))

        # fix ids for exchange reactions
        sref = r.getReactant(0)
        sid = sref.getSpecies()
        rid = r.getId()
        if rid != EXCHANGE_REACTION_PREFIX + sid:
            r.setId(EXCHANGE_REACTION_PREFIX + sid)
            logging.warning("Exchange reaction fixd id: {} -> {}".format(
                rid, EXCHANGE_REACTION_PREFIX + sid))

    # new lookup necessary, due to possible changed ids
    ex_rids = utils.find_exchange_reactions(model)
    for ex_rid in ex_rids:
        r = model.getReaction(ex_rid)
        fbc_r = r.getPlugin(SBML_FBC_NAME)
        # store bounds in dictionary for value lookup
        for f_bound in ["getLowerFluxBound", "getUpperFluxBound"]:
            bound_id = getattr(fbc_r, f_bound).__call__()
            bound = model.getParameter(bound_id)
            bounds_dict[bound_id] = bound.getValue()

    # create unique bounds for exchange reactions
    for ex_rid in ex_rids:
        r = model.getReaction(ex_rid)
        fbc_r = r.getPlugin(SBML_FBC_NAME)
        lb_value = model.getParameter(fbc_r.getLowerFluxBound()).getValue()
        ub_value = model.getParameter(fbc_r.getUpperFluxBound()).getValue()

        lb_id = LOWER_BOUND_PREFIX + ex_rid
        ub_id = UPPER_BOUND_PREFIX + ex_rid

        parameters = [
            Parameter(sid=lb_id,
                      value=lb_value,
                      unit=flux_unit,
                      constant=True,
                      sboTerm=FLUX_BOUND_SBO),
            Parameter(sid=ub_id,
                      value=ub_value,
                      unit=flux_unit,
                      constant=True,
                      sboTerm=FLUX_BOUND_SBO),
        ]
        factory.create_objects(model, parameters)

        # set bounds
        fbc.set_flux_bounds(r, lb=lb_id, ub=ub_id)

        # create ports for bounds and reaction
        comp.create_ports(model,
                          portType=comp.PORT_TYPE_PORT,
                          idRefs=[ex_rid, lb_id, ub_id])

    # check all the exchange reactions
    for ex_rid in ex_rids:
        check_exchange_reaction(model, ex_rid)
def top_model(sbml_file, directory, emds, doc_fba=None, annotations=None):
    """
    Create diauxic comp model.
    Test script for working with the comp extension in SBML.

    One model composition combines all the kinetic models,
    in addition the higher level comp model is created which combines everything (i.e. the FBA & ODE models).
    For the simulation of the full combined model the tools have to figure out the subparts which are
    simulated with which simulation environment.
    Creates the full comp model as combination of FBA and comp models.

    The submodels must already exist in the given directory
    """
    top_notes = notes.format("""
    <h2>TOP model</h2>
    <p>Main comp DFBA model by combining fba, update and bounds
        model with additional kinetics in the top model.</p>
    """)
    # Necessary to change into directory with submodel files
    working_dir = os.getcwd()
    os.chdir(directory)

    doc = builder.template_doc_top(settings.MODEL_ID, emds)
    model = doc.getModel()
    utils.set_model_info(model, notes=top_notes,
                         creators=creators, units=units, main_units=main_units)

    # dt
    builder.create_dfba_dt(model, time_unit=UNIT_TIME, create_port=False)

    # compartment
    compartment_id = "bioreactor"
    builder.create_dfba_compartment(model, compartment_id=compartment_id, unit_volume=UNIT_VOLUME, create_port=False)

    # dynamic species
    model_fba = doc_fba.getModel()
    builder.create_dfba_species(model, model_fba, compartment_id=compartment_id, unit_amount=UNIT_AMOUNT,
                                create_port=False)

    # dummy species
    builder.create_dummy_species(model, compartment_id=compartment_id, unit_amount=UNIT_AMOUNT)

    # exchange flux bounds
    builder.create_exchange_bounds(model, model_fba=model_fba, unit_flux=UNIT_FLUX, create_ports=False)

    # dummy reactions & flux assignments
    builder.create_dummy_reactions(model, model_fba=model_fba, unit_flux=UNIT_FLUX)

    # replacedBy (fba reactions)
    builder.create_top_replacedBy(model, model_fba=model_fba)

    # replaced
    builder.create_top_replacements(model, model_fba, compartment_id=compartment_id)

    # initial kinetic concentrations
    initial_c = {
        'Glcxt': 10.8,
        'Ac': 0.4,
        'O2': 0.21,
        'X': 0.001,
    }
    for sid, value in initial_c.items():
        species = model.getSpecies(sid)
        species.setInitialConcentration(value)

    objects = [
        # biomass conversion factor
        # mc.Parameter(sid="Y", name="biomass [g_per_l]", value=1.0, unit="g_per_l"),
        # oxygen exchange parameters
        mc.Parameter(sid="O2_ref", name="O2 reference", value=0.21, unit=UNIT_CONCENTRATION),
        mc.Parameter(sid="kLa", name="O2 mass transfer", value=7.5, unit='per_h'),
    ]
    mc.create_objects(model, objects)

    # oxygen transfer reaction
    mc.create_reaction(model, rid="vO2_transfer", name="oxygen transfer", reversible=True,
                       reactants={}, products={"O2": 1}, formula="kLa * (O2_ref-O2) * bioreactor",
                       compartment="bioreactor")

    # write SBML file
    if annotations:
        annotation.annotate_sbml_doc(doc, annotations)
    sbmlio.write_sbml(doc, filepath=os.path.join(directory, sbml_file), validate=True)

    # change back into working dir
    os.chdir(working_dir)
def fba_model(sbml_file, directory, annotations=None):
    """ FBA model
    
    :param sbml_file: output file name 
    :param directory: output directory
    :return: SBMLDocument
    """
    fba_notes = notes.format("""
    <h2>FBA submodel</h2>
    <p>DFBA fba submodel. Unbalanced metabolites are encoded via exchange fluxes.</p>
    """)
    doc = builder.template_doc_fba(settings.MODEL_ID)
    model = doc.getModel()
    utils.set_model_info(model,
                         notes=fba_notes,
                         creators=creators,
                         units=units, main_units=main_units)

    objects = [
        # compartments
        mc.Compartment(sid='extern', value=1.0, unit=UNIT_VOLUME, constant=True, name='external compartment',
                       spatialDimensions=3),
        mc.Compartment(sid='cell', value=1.0, unit=UNIT_VOLUME, constant=True, name='cell', spatialDimensions=3),
        mc.Compartment(sid='membrane', value=1.0, unit=UNIT_AREA, constant=True, name='membrane', spatialDimensions=2),

        # exchange species
        mc.Species(sid='A', name="A", initialConcentration=0, substanceUnit=UNIT_AMOUNT, hasOnlySubstanceUnits=True,
                   compartment="extern"),
        mc.Species(sid='C', name="C", initialConcentration=0, substanceUnit=UNIT_AMOUNT, hasOnlySubstanceUnits=True,
                   compartment="extern"),

        # internal species
        mc.Species(sid='B1', name="B1", initialConcentration=0, substanceUnit=UNIT_AMOUNT, hasOnlySubstanceUnits=True,
                   compartment="cell"),
        mc.Species(sid='B2', name="B2", initialConcentration=0, substanceUnit=UNIT_AMOUNT, hasOnlySubstanceUnits=True,
                   compartment="cell"),

        # bounds
        mc.Parameter(sid="ub_R1", value=1.0, unit=UNIT_FLUX, constant=True, sboTerm=builder.FLUX_BOUND_SBO),
        mc.Parameter(sid="zero", value=0.0, unit=UNIT_FLUX, constant=True, sboTerm=builder.FLUX_BOUND_SBO),
        mc.Parameter(sid="ub_default", value=builder.UPPER_BOUND_DEFAULT, unit=UNIT_FLUX, constant=True,
                     sboTerm=builder.FLUX_BOUND_SBO),
    ]
    mc.create_objects(model, objects)

    # reactions
    r1 = mc.create_reaction(model, rid="R1", name="A import (R1)", fast=False, reversible=True,
                            reactants={"A": 1}, products={"B1": 1}, compartment='membrane')
    r2 = mc.create_reaction(model, rid="R2", name="B1 <-> B2 (R2)", fast=False, reversible=True,
                            reactants={"B1": 1}, products={"B2": 1}, compartment='cell')
    r3 = mc.create_reaction(model, rid="R3", name="B2 export (R3)", fast=False, reversible=True,
                            reactants={"B2": 1}, products={"C": 1}, compartment='membrane')

    # flux bounds
    fbc.set_flux_bounds(r1, lb="zero", ub="ub_R1")
    fbc.set_flux_bounds(r2, lb="zero", ub="ub_default")
    fbc.set_flux_bounds(r3, lb="zero", ub="ub_default")

    # exchange reactions
    builder.create_exchange_reaction(model, species_id="A", flux_unit=UNIT_FLUX)
    builder.create_exchange_reaction(model, species_id="C", flux_unit=UNIT_FLUX)

    # objective function
    model_fbc = model.getPlugin("fbc")
    fbc.create_objective(model_fbc, oid="R3_maximize", otype="maximize",
                        fluxObjectives={"R3": 1.0}, active=True)

    # create ports for kinetic bounds
    comp.create_ports(model, portType=comp.PORT_TYPE_PORT,
                      idRefs=["ub_R1"])

    # write SBML
    if annotations:
        annotation.annotate_sbml_doc(doc, annotations)
    sbmlio.write_sbml(doc, filepath=os.path.join(directory, sbml_file), validate=True)
    return doc
def fba_model(sbml_file, directory):
    """ Create FBA submodel.
    """
    # Read the model
    fba_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data/ecoli_fba.xml')
    doc_fba = sbmlio.read_sbml(fba_path)

    # add comp
    doc_fba.enablePackage("http://www.sbml.org/sbml/level3/version1/comp/version1", "comp", True)
    doc_fba.setPackageRequired("comp", True)

    # add notes
    model = doc_fba.getModel()
    fba_notes = notes.format("""DFBA FBA submodel.""")
    utils.set_model_info(model, notes=fba_notes,
                         creators=None, units=units, main_units=main_units)

    # clip R_ reaction and M_ metabolite prefixes
    utils.clip_prefixes_in_model(model)

    # set id & framework
    model.setId('ecoli_fba')
    model.setName('ecoli (FBA)')
    model.setSBOTerm(comp.SBO_FLUX_BALANCE_FRAMEWORK)

    # add units and information
    for species in model.getListOfSpecies():
        species.setInitialConcentration(0.0)
        species.setHasOnlySubstanceUnits(False)
        species.setUnits(UNIT_AMOUNT)
    for compartment in model.getListOfCompartments():
        compartment.setUnits(UNIT_VOLUME)


    # The ATPM (atp maintainance reactions creates many problems in the DFBA)
    # mainly resulting in infeasible solutions when some metabolites run out.
    # ATP -> ADP is part of the biomass, so we set the lower bound to zero
    r_ATPM = model.getReaction('ATPM')
    r_ATPM_fbc = r_ATPM.getPlugin(builder.SBML_FBC_NAME)
    lb_id = r_ATPM_fbc.getLowerFluxBound()
    model.getParameter(lb_id).setValue(0.0)  # 8.39 before

    # make unique upper and lower bounds for exchange reaction
    if not biomass_weighting:
        builder.update_exchange_reactions(model=model, flux_unit=UNIT_FLUX)
    else:
        builder.update_exchange_reactions(model=model, flux_unit=UNIT_FLUX_PER_G)

    # add exchange reaction for biomass (X)
    # we are adding the biomass component to the biomass function and create an
    # exchange reaction for it
    r_biomass = model.getReaction('BIOMASS_Ecoli_core_w_GAM')

    # FIXME: refactor in function
    # FIXME: annotate biomass species (SBO for biomass missing)
    mc.create_objects(model, [
        mc.Parameter(sid='cf_X', value=1.0, unit="g_per_mmol", name="biomass conversion factor", constant=True),
        mc.Species(sid='X', initialAmount=0.001, compartment='c', name='biomass', substanceUnit='g', hasOnlySubstanceUnits=True,
                   conversionFactor='cf_X')
    ])


    pr_biomass = r_biomass.createProduct()
    pr_biomass.setSpecies('X')
    pr_biomass.setStoichiometry(1.0)
    pr_biomass.setConstant(True)
    # FIXME: the flux units must fit to the species units.
    if not biomass_weighting:
        builder.create_exchange_reaction(model, species_id='X', flux_unit=UNIT_FLUX, exchange_type=builder.EXCHANGE_EXPORT)
    else:
        builder.create_exchange_reaction(model, species_id='X', flux_unit=UNIT_FLUX_PER_G, exchange_type=builder.EXCHANGE_EXPORT)
    # write SBML file
    sbmlio.write_sbml(doc_fba, filepath=pjoin(directory, sbml_file), validate=True)

    # Set kinetic laws to zero for kinetic simulation
    '''
    for reaction in model.getListOfReactions():
        ast_node = mc.ast_node_from_formula(model=model, formula='0 {}'.format(UNIT_FLUX))
        law = reaction.createKineticLaw()
        law.setMath(ast_node)
    '''

    return doc_fba
def top_model(sbml_file, directory, emds, doc_fba=None, annotations=None):
    """
    Create diauxic comp model.
    Test script for working with the comp extension in SBML.

    One model composition combines all the kinetic models,
    in addition the higher level comp model is created which combines everything (i.e. the FBA & ODE models).
    For the simulation of the full combined model the tools have to figure out the subparts which are
    simulated with which simulation environment.
    Creates the full comp model as combination of FBA and comp models.

    The submodels must already exist in the given directory
    """
    top_notes = notes.format("""
    <h2>TOP model</h2>
    <p>Main comp DFBA model by combining fba, update and bounds
        model with additional kinetics in the top model.</p>
    """)
    # Necessary to change into directory with submodel files
    working_dir = os.getcwd()
    os.chdir(directory)

    doc = builder.template_doc_top(settings.MODEL_ID, emds)
    model = doc.getModel()
    utils.set_model_info(model,
                         notes=top_notes,
                         creators=creators,
                         units=units,
                         main_units=main_units)

    # dt
    builder.create_dfba_dt(model, time_unit=UNIT_TIME, create_port=False)

    # compartment
    compartment_id = "bioreactor"
    builder.create_dfba_compartment(model,
                                    compartment_id=compartment_id,
                                    unit_volume=UNIT_VOLUME,
                                    create_port=False)

    # dynamic species
    model_fba = doc_fba.getModel()
    builder.create_dfba_species(model,
                                model_fba,
                                compartment_id=compartment_id,
                                unit_amount=UNIT_AMOUNT,
                                create_port=False)

    # dummy species
    builder.create_dummy_species(model,
                                 compartment_id=compartment_id,
                                 unit_amount=UNIT_AMOUNT)

    # exchange flux bounds
    builder.create_exchange_bounds(model,
                                   model_fba=model_fba,
                                   unit_flux=UNIT_FLUX,
                                   create_ports=False)

    # dummy reactions & flux assignments
    builder.create_dummy_reactions(model,
                                   model_fba=model_fba,
                                   unit_flux=UNIT_FLUX)

    # replacedBy (fba reactions)
    builder.create_top_replacedBy(model, model_fba=model_fba)

    # replaced
    builder.create_top_replacements(model,
                                    model_fba,
                                    compartment_id=compartment_id)

    # initial kinetic concentrations
    initial_c = {
        'Glcxt': 10.8,
        'Ac': 0.4,
        'O2': 0.21,
        'X': 0.001,
    }
    for sid, value in initial_c.items():
        species = model.getSpecies(sid)
        species.setInitialConcentration(value)

    objects = [
        # biomass conversion factor
        # Parameter(sid="Y", name="biomass [g_per_l]", value=1.0, unit="g_per_l"),
        # oxygen exchange parameters
        Parameter(sid="O2_ref",
                  name="O2 reference",
                  value=0.21,
                  unit=UNIT_CONCENTRATION),
        Parameter(sid="kLa", name="O2 mass transfer", value=7.5, unit='per_h'),
    ]
    factory.create_objects(model, objects)

    # oxygen transfer reaction
    create_reaction(model,
                    rid="vO2_transfer",
                    name="oxygen transfer",
                    reversible=True,
                    reactants={},
                    products={"O2": 1},
                    formula="kLa * (O2_ref-O2) * bioreactor",
                    compartment="bioreactor")

    # write SBML file
    if annotations:
        annotator.annotate_sbml_doc(doc, annotations)
    sbmlio.write_sbml(doc,
                      filepath=os.path.join(directory, sbml_file),
                      validate=True)

    # change back into working dir
    os.chdir(working_dir)
Exemple #52
0
def xpp2sbml(
    xpp_file: Path,
    sbml_file: Path,
    force_lower: bool = False,
    validate: bool = True,
    debug: bool = False,
):
    """Reads given xpp_file and converts to SBML file.

    :param xpp_file: xpp input ode file
    :param sbml_file: sbml output file
    :param force_lower: force lower case for all lines
    :param validate: perform validation on the generated SBML file
    :return:
    """
    print("-" * 80)
    print("xpp2sbml: ", xpp_file, "->", sbml_file)
    print("-" * 80)
    doc = libsbml.SBMLDocument(3, 1)
    model = doc.createModel()

    parameters = []
    initial_assignments = []
    rate_rules = []
    assignment_rules = []
    functions = [
        # definition of min and max
        fac.Function("max",
                     "lambda(x,y, piecewise(x,gt(x,y),y) )",
                     name="minimum"),
        fac.Function("min",
                     "lambda(x,y, piecewise(x,lt(x,y),y) )",
                     name="maximum"),
        # heav (heavyside)
        fac.Function(
            "heav",
            "lambda(x, piecewise(0,lt(x,0), 0.5, eq(x, 0), 1,gt(x,0), 0))",
            name="heavyside",
        ),
        # mod (modulo)
        fac.Function("mod", "lambda(x,y, x % y)", name="modulo"),
    ]
    function_definitions = []
    events = []

    def replace_fdef():
        """ Replace all arguments within the formula definitions."""
        changes = False
        for k, fdata in enumerate(function_definitions):
            for i in range(len(function_definitions)):
                if i != k:
                    # replace i with k
                    formula = function_definitions[i]["formula"]
                    new_formula = xpp_helpers.replace_formula(
                        formula,
                        fid=function_definitions[k]["fid"],
                        old_args=function_definitions[k]["old_args"],
                        new_args=function_definitions[k]["new_args"],
                    )
                    if new_formula != formula:
                        function_definitions[i]["formula"] = new_formula
                        function_definitions[i]["new_args"] = list(
                            sorted(
                                set(function_definitions[i]["new_args"] +
                                    function_definitions[k]["new_args"])))
                        changes = True

        return changes

    def create_initial_assignment(sid, value):
        """ Helper for creating initial assignments """
        # check if valid identifier
        if "(" in sid:
            warnings.warn(
                "sid is not valid: {}. Initial assignment is not generated".
                format(sid))
            return

        try:
            f_value = float(value)
            parameters.append(
                fac.Parameter(
                    sid=sid,
                    value=f_value,
                    name="{} = {}".format(sid, value),
                    constant=False,
                ))
        except ValueError:
            """
            Initial data are optional, XPP sets them to zero by default (many xpp model don't write the p(0)=0.
            """
            parameters.append(
                fac.Parameter(sid=sid, value=0.0, name=sid, constant=False))
            initial_assignments.append(
                fac.InitialAssignment(sid=sid,
                                      value=value,
                                      name="{} = {}".format(sid, value)))

    ###########################################################################
    # First iteration to parse relevant lines and get the replacement patterns
    ###########################################################################
    parsed_lines = []
    # with open(xpp_file, encoding="utf-8") as f:
    with open(xpp_file) as f:
        lines = f.readlines()

        # add info to sbml
        text = escape_string("".join(lines))
        fac.set_notes(model, NOTES.format(text))

        old_line = None
        for line in lines:
            if force_lower:
                line = line.lower()

            # clean up the ends
            line = line.rstrip("\n").strip()
            # handle douple continuation characters in some models
            line = line.replace("\\\\", "\\")
            # handle semicolons
            line = line.rstrip(";")

            # join continuation
            if old_line:
                line = old_line + line
                old_line = None

            # empty line
            if len(line) == 0:
                continue
            # comment line
            if line[0] in XPP_COMMENT_CHARS:
                continue
            # xpp setting
            if line.startswith(XPP_SETTING_CHAR):
                continue
            # end word
            if line == XPP_END_WORD:
                continue
            # line continuation
            if line.endswith(XPP_CONTINUATION_CHAR):
                old_line = line.rstrip(XPP_CONTINUATION_CHAR)
                continue

            # handle the power function
            line = line.replace("**", "^")

            # handle if(...)then(...)else()
            pattern_ite = re.compile(
                r"if\s*\((.*)\)\s*then\s*\((.*)\)\s*else\s*\((.*)\)")
            pattern_ite_sub = re.compile(
                r"if\s*\(.*\)\s*then\s*\(.*\)\s*else\s*\(.*\)")
            groups = re.findall(pattern_ite, line)
            for group in groups:
                condition = group[0]
                assignment = group[1]
                otherwise = group[2]
                f_piecewise = "piecewise({}, {}, {})".format(
                    assignment, condition, otherwise)
                line = re.sub(pattern_ite_sub, f_piecewise, line)

            ################################
            # Function definitions
            ################################
            """ Functions are defined in xpp via fid(arguments) = formula
            f(x,y) = x^2/(x^2+y^2)
            They can have up to 9 arguments.
            The difference to SBML functions is that xpp functions have access to the global parameter values
            """
            f_pattern = re.compile(r"(.*)\s*\((.*)\)\s*=\s*(.*)")
            groups = re.findall(f_pattern, line)
            if groups:
                # function definitions found
                fid, args, formula = groups[0]
                # handles the initial assignments which look like function definitions
                if args == "0":
                    parsed_lines.append(line)
                    continue

                # necessary to find the additional arguments from the ast_node
                ast = libsbml.parseL3Formula(formula)
                names = set(xpp_helpers.find_names_in_ast(ast))
                old_args = [t.strip() for t in args.split(",")]
                new_args = [a for a in names if a not in old_args]

                # handle special functions
                if fid == "power":
                    warnings.warn(
                        "power function cannot be added to model, rename function."
                    )
                else:
                    # store functions with additional arguments
                    function_definitions.append({
                        "fid": fid,
                        "old_args": old_args,
                        "new_args": new_args,
                        "formula": formula,
                    })
                # don't append line, function definition has been handeled
                continue

            parsed_lines.append(line)
    if debug:
        print("\n\nFUNCTION_DEFINITIONS")
        pprint(function_definitions)

    # functions can use functions so this also must be replaced
    changes = True
    while changes:
        changes = replace_fdef()

    # clean the new arguments
    for fdata in function_definitions:
        fdata["new_args"] = list(sorted(set(fdata["new_args"])))

    if debug:
        print("\nREPLACED FUNCTION_DEFINITIONS")
        pprint(function_definitions)

    # Create function definitions
    for k, fdata in enumerate(function_definitions):
        fid = fdata["fid"]
        formula = fdata["formula"]
        arguments = ",".join(fdata["old_args"] + fdata["new_args"])
        functions.append(
            fac.Function(fid, "lambda({}, {})".format(arguments, formula)), )

    ###########################################################################
    # Second iteration
    ###########################################################################
    if debug:
        print("\nPARSED LINES")
        pprint(parsed_lines)
        print("\n\n")
    for line in parsed_lines:

        # replace function definitions in lines
        new_line = line
        for fdata in function_definitions:
            new_line = xpp_helpers.replace_formula(new_line, fdata["fid"],
                                                   fdata["old_args"],
                                                   fdata["new_args"])

        if new_line != line:
            if False:
                print("\nReplaced FD", fdata["fid"], ":", new_line)
                print("->", new_line, "\n")
            line = new_line

        if debug:
            # line after function replacements
            print("*" * 3, line, "*" * 3)

        ################################
        # Start parsing the given line
        ################################
        # check for the equal sign
        tokens = line.split("=")
        tokens = [t.strip() for t in tokens]

        #######################
        # Line without '=' sign
        #######################
        # wiener
        if len(tokens) == 1:
            items = [t.strip() for t in tokens[0].split(" ") if len(t) > 0]
            # keyword, value
            if len(items) == 2:
                xid, sid = items[0], items[1]
                xpp_type = parse_keyword(xid)

                # wiener
                if xpp_type == XPP_WIE:
                    """Wiener parameters are normally distributed numbers with zero mean
                    and unit standard deviation. They are useful in stochastic simulations since
                    they automatically scale with change in the integration time step.
                    Their names are listed separated by commas or spaces."""
                    # FIXME: this should be encoded using dist
                    parameters.append(fac.Parameter(sid=sid, value=0.0))
                    continue  # line finished
            else:
                warnings.warn("XPP line not parsed: '{}'".format(line))

        #####################
        # Line with '=' sign
        #####################
        # parameter, aux, ode, initial assignments
        elif len(tokens) >= 2:
            left = tokens[0]
            items = [t.strip() for t in left.split(" ") if len(t) > 0]
            # keyword based information, i.e 2 items are on the left of the first '=' sign
            if len(items) == 2:
                xid = items[0]  # xpp keyword
                xpp_type = parse_keyword(xid)
                expression = (" ".join(items[1:]) + "=" + "=".join(tokens[1:])
                              )  # full expression after keyword
                parts = parts_from_expression(expression)
                if False:
                    print("xid:", xid)
                    print("expression:", expression)
                    print("parts:", parts)

                # parameter & numbers
                if xpp_type in [XPP_PAR, XPP_NUM]:
                    """Parameter values are optional; if not they are set to zero.
                    Number declarations are like parameter declarations, except that they cannot be
                    changed within the program and do not appear in the parameter window."""
                    for part in parts:
                        sid, value = sid_value_from_part(part)
                        create_initial_assignment(sid, value)

                # aux
                elif xpp_type == XPP_AUX:
                    """Auxiliary quantities are expressions that depend on all of your dynamic
                    variables which you want to keep track of. Energy is one such example. They are declared
                    like fixed quantities, but are prefaced by aux ."""
                    for part in parts:
                        sid, value = sid_value_from_part(part)
                        if sid == value:
                            # avoid circular dependencies (no information in statement)
                            pass
                        else:
                            assignment_rules.append(
                                fac.AssignmentRule(sid=sid, value=value))

                # init
                elif xpp_type == XPP_INIT:
                    for part in parts:
                        sid, value = sid_value_from_part(part)
                        create_initial_assignment(sid, value)

                # table
                elif xpp_type == XPP_TAB:
                    """The Table declaration allows the user to specify a function of 1 variable in terms
                    of a lookup table which uses linear interpolation. The name of the function follows the
                    declaration and this is followed by (i) a filename (ii) or a function of "t"."""
                    warnings.warn(
                        "XPP_TAB not supported: XPP line not parsed: '{}'".
                        format(line))

                else:
                    warnings.warn("XPP line not parsed: '{}'".format(line))

            elif len(items) >= 2:
                xid = items[0]
                xpp_type = parse_keyword(xid)
                # global
                if xpp_type == XPP_GLO:
                    """Global flags are expressions that signal events when they change sign, from less than
                    to greater than zero if sign=1 , greater than to less than if sign=-1 or either way
                    if sign=0. The condition should be delimited by braces {} The events are of the form
                    variable=expression, are delimited by braces, and separated by semicolons. When the
                    condition occurs all the variables in the event set are changed possibly discontinuously.
                    """

                    # global sign {condition} {name1 = form1; ...}
                    pattern_global = re.compile(
                        r"([+,-]{0,1}\d{1})\s+\{{0,1}(.*)\{{0,1}\s+\{(.*)\}")
                    groups = re.findall(pattern_global, line)
                    if groups:
                        g = groups[0]
                        sign = int(g[0])
                        trigger = g[1]
                        # FIXME: handle sign=-1, sign=0, sign=+1
                        if sign == -1:
                            trigger = g[1] + ">= 0"
                        elif sign == 1:
                            trigger = g[1] + ">= 0"
                        elif sign == 0:
                            trigger = g[1] + ">= 0"

                        assignment_parts = [t.strip() for t in g[2].split(";")]
                        assignments = {}
                        for p in assignment_parts:
                            key, value = p.split("=")
                            assignments[key] = value

                        events.append(
                            fac.Event(
                                sid="e{}".format(len(events)),
                                trigger=trigger,
                                assignments=assignments,
                            ))

                    else:
                        warnings.warn(
                            "global expression could not be parsed: {}".format(
                                line))
                else:
                    warnings.warn("XPP line not parsed: '{}'".format(line))

            # direct assignments
            elif len(items) == 1:
                right = tokens[1]

                # init
                if left.endswith("(0)"):
                    sid, value = left[0:-3], right
                    create_initial_assignment(sid, value)

                # difference equations
                elif left.endswith("(t+1)"):
                    warnings.warn(
                        "Difference Equations not supported: XPP line not parsed: '{}'"
                        .format(line))

                # ode
                elif left.endswith("'"):
                    sid = left[0:-1]
                    rate_rules.append(fac.RateRule(sid=sid, value=right))
                elif left.endswith("/dt"):
                    sid = left[1:-3]
                    rate_rules.append(fac.RateRule(sid=sid, value=right))
                # assignment rules
                else:
                    assignment_rules.append(
                        fac.AssignmentRule(sid=left, value=right))
            else:
                warnings.warn("XPP line not parsed: '{}'".format(line))

    # add time
    assignment_rules.append(
        fac.AssignmentRule(sid="t", value="time", name="model time"))

    # create SBML objects
    objects = (parameters + initial_assignments + functions + rate_rules +
               assignment_rules + events)
    fac.create_objects(model, obj_iter=objects, debug=False)
    """
    Parameter values are optional; if not they are set to zero in xpp.
    Many models do not encode the initial zeros.
    """
    for p in doc.getModel().getListOfParameters():
        if not p.isSetValue():
            p.setValue(0.0)

    sbml.write_sbml(
        doc,
        sbml_file,
        validate=validate,
        program_name="sbmlutils",
        program_version=__version__,
        units_consistency=False,
    )
Exemple #53
0
    def create_sbml(self, sbml_level=SBML_LEVEL, sbml_version=SBML_VERSION):
        """ Create the SBML model

        :return:
        :rtype:
        """
        from sbmlutils.validation import check

        logging.info('*'*40)
        logging.info(self.model_id)
        logging.info('*' * 40)

        # create core model
        sbmlns = libsbml.SBMLNamespaces(sbml_level, sbml_version)

        # add all the packages
        # FIXME: only add packages which are required for the model

        sbmlns.addPackageNamespace("fbc", 2)
        sbmlns.addPackageNamespace("comp", 1)
        # sbmlns.addPackageNamespace("distrib", 1)

        self.doc = libsbml.SBMLDocument(sbmlns)
        self.doc.setPackageRequired("comp", True)
        self.doc.setPackageRequired("fbc", False)
        # self.doc.setPackageRequired("distrib", True)

        self.model = self.doc.createModel()
        fbc_plugin = self.model.getPlugin("fbc")
        fbc_plugin.setStrict(False)

        # name & id
        check(self.model.setId(self.model_id), 'set id')
        check(self.model.setName(self.model_id), 'set name')
        # notes
        if hasattr(self, 'notes') and self.notes is not None:
            factory.set_notes(self.model, self.notes)
        # history
        if hasattr(self, 'creators'):
            history.set_model_history(self.model, self.creators)

        # model units
        if hasattr(self, 'model_units'):
            factory.set_model_units(self.model, self.model_units)

        # lists ofs
        for attr in [
            'externalModelDefinitions',
            'submodels',
            'units',
            'functions',
            'parameters',
            'compartments',
            'species',
            'assignments',
            'rules',
            'rate_rules',
            'reactions',
            'events',
            'constraints',
            'ports',
            'replacedElements',
            'deletions',
            'objectives',
            'layouts'
        ]:
            # create the respective objects
            if hasattr(self, attr):
                objects = getattr(self, attr)
                if objects:
                    factory.create_objects(self.model, obj_iter=objects, key=attr)
                else:
                    logging.warning("Not defined: <{}> ".format(attr))
Exemple #54
0
def top_model(sbml_file, directory, emds, doc_fba, annotations=None):
    """ Create top comp model.

    Creates full comp model by combining fba, update and bounds
    model with additional kinetics in the top model.
    """
    top_notes = notes.format("""
        <h2>TOP model</h2>
        <p>Main comp DFBA model by combining fba, update and bounds
            model with additional kinetics in the top model.</p>
        """)
    working_dir = os.getcwd()
    os.chdir(directory)

    doc = builder.template_doc_top(settings.MODEL_ID, emds)
    model = doc.getModel()
    utils.set_model_info(model,
                         notes=top_notes,
                         creators=creators,
                         units=units,
                         main_units=main_units)

    # dt
    builder.create_dfba_dt(model,
                           step_size=DT_SIM,
                           time_unit=UNIT_TIME,
                           create_port=False)

    # compartment
    compartment_id = "extern"
    builder.create_dfba_compartment(model,
                                    compartment_id=compartment_id,
                                    unit_volume=UNIT_VOLUME,
                                    create_port=False)

    # dynamic species
    model_fba = doc_fba.getModel()
    builder.create_dfba_species(model,
                                model_fba,
                                compartment_id=compartment_id,
                                hasOnlySubstanceUnits=True,
                                unit_amount=UNIT_AMOUNT,
                                create_port=False)
    # dummy species
    builder.create_dummy_species(model,
                                 compartment_id=compartment_id,
                                 hasOnlySubstanceUnits=True,
                                 unit_amount=UNIT_AMOUNT)

    # exchange flux bounds
    builder.create_exchange_bounds(model,
                                   model_fba=model_fba,
                                   unit_flux=UNIT_FLUX,
                                   create_ports=False)

    # dummy reactions & flux assignments
    builder.create_dummy_reactions(model,
                                   model_fba=model_fba,
                                   unit_flux=UNIT_FLUX)

    # replacedBy (fba reactions)
    builder.create_top_replacedBy(model, model_fba=model_fba)

    # replaced
    builder.create_top_replacements(model,
                                    model_fba,
                                    compartment_id=compartment_id)

    # initial concentrations for fba exchange species
    initial_c = {
        'A': 10.0,
        'C': 0.0,
    }
    for sid, value in initial_c.items():
        species = model.getSpecies(sid)
        species.setInitialConcentration(value)

    # kinetic model
    mc.create_objects(
        model,
        [
            # kinetic species
            mc.Species(sid='D',
                       initialConcentration=0,
                       substanceUnit=UNIT_AMOUNT,
                       hasOnlySubstanceUnits=True,
                       compartment="extern"),

            # kinetic
            mc.Parameter(sid="k_R4",
                         value=0.1,
                         constant=True,
                         unit="per_s",
                         sboTerm="SBO:0000009"),

            # bounds parameter
            mc.Parameter(sid='ub_R1',
                         value=1.0,
                         unit=UNIT_FLUX,
                         constant=False,
                         sboTerm="SBO:0000625"),
        ])
    # kinetic reaction (MMK)
    mc.create_reaction(model,
                       rid="R4",
                       name="R4: C -> D",
                       fast=False,
                       reversible=False,
                       reactants={"C": 1},
                       products={"D": 1},
                       formula="k_R4*C",
                       compartment="extern")

    # kinetic flux bounds
    comp.replace_elements(model,
                          'ub_R1',
                          ref_type=comp.SBASE_REF_TYPE_PORT,
                          replaced_elements={
                              'bounds': ['ub_R1_port'],
                              'fba': ['ub_R1_port']
                          })

    # write SBML file
    if annotations:
        annotator.annotate_sbml_doc(doc, annotations)
    sbml.write_sbml(doc,
                    filepath=os.path.join(directory, sbml_file),
                    validate=True)

    # change back the working dir
    os.chdir(working_dir)
def top_model(sbml_file, directory, emds, doc_fba, annotations=None):
    """ Create top comp model.

    Creates full comp model by combining fba, update and bounds
    model with additional kinetics in the top model.
    """
    top_notes = notes.format("""
        <h2>TOP model</h2>
        <p>Main comp DFBA model by combining fba, update and bounds
            model with additional kinetics in the top model.</p>
        """)
    working_dir = os.getcwd()
    os.chdir(directory)

    doc = builder.template_doc_top(settings.MODEL_ID, emds)
    model = doc.getModel()
    utils.set_model_info(model,
                         notes=top_notes,
                         creators=creators,
                         units=units,
                         main_units=main_units)

    # dt
    builder.create_dfba_dt(model,
                           step_size=DT_SIM,
                           time_unit=UNIT_TIME,
                           create_port=False)

    # compartment
    compartment_id = "cell"
    builder.create_dfba_compartment(model,
                                    compartment_id=compartment_id,
                                    unit_volume=UNIT_VOLUME,
                                    create_port=False)

    # dynamic species
    model_fba = doc_fba.getModel()
    builder.create_dfba_species(model,
                                model_fba,
                                compartment_id=compartment_id,
                                hasOnlySubstanceUnits=False,
                                unit_amount=UNIT_AMOUNT,
                                create_port=False)
    # dummy species
    builder.create_dummy_species(model,
                                 compartment_id=compartment_id,
                                 hasOnlySubstanceUnits=False,
                                 unit_amount=UNIT_AMOUNT)

    # exchange flux bounds
    builder.create_exchange_bounds(model,
                                   model_fba=model_fba,
                                   unit_flux=UNIT_FLUX,
                                   create_ports=False)

    # dummy reactions & flux assignments
    builder.create_dummy_reactions(model,
                                   model_fba=model_fba,
                                   unit_flux=UNIT_FLUX)

    # replacedBy (fba reactions)
    builder.create_top_replacedBy(model, model_fba=model_fba)

    # replaced
    builder.create_top_replacements(model,
                                    model_fba,
                                    compartment_id=compartment_id)

    objects = [
        # kinetic parameters
        mc.Parameter(sid="Vmax_RATP", value=1, unit=UNIT_FLUX, constant=True),
        mc.Parameter(sid='k_RATP',
                     value=0.1,
                     unit=UNIT_CONCENTRATION,
                     constant=True),

        # balancing rules
        mc.AssignmentRule(sid="atp_tot",
                          value="atp + adp",
                          unit=UNIT_CONCENTRATION),
        mc.AssignmentRule(sid="c3_tot",
                          value="2 dimensionless * glc + pyr",
                          unit="mM")
    ]
    mc.create_objects(model, objects)

    ratp = mc.create_reaction(model,
                              rid="RATP",
                              name="atp -> adp",
                              fast=False,
                              reversible=False,
                              reactants={"atp": 1},
                              products={"adp": 1},
                              compartment=compartment_id,
                              formula='Vmax_RATP * atp/(k_RATP + atp)')

    # initial concentrations for fba exchange species
    initial_c = {'atp': 2.0, 'adp': 1.0, 'glc': 5.0, 'pyr': 0.0}
    for sid, value in initial_c.items():
        species = model.getSpecies(sid)
        species.setInitialConcentration(value)

    # write SBML file
    if annotations:
        annotator.annotate_sbml_doc(doc, annotations)
    sbmlio.write_sbml(doc,
                      filepath=os.path.join(directory, sbml_file),
                      validate=True)

    # change back the working dir
    os.chdir(working_dir)
def bounds_model(sbml_file, directory, doc_fba=None, annotations=None):
    """"
    Submodel for dynamically calculating the flux bounds.

    The dynamically changing flux bounds are the input to the
    FBA model.
    """
    # TODO: the bounds model should be created based on the FBA model (i.e. use the exchange reactions
    # to create the bounds info.

    bounds_notes = notes.format("""
    <h2>BOUNDS submodel</h2>
    <p>Submodel for dynamically calculating the flux bounds.
    The dynamically changing flux bounds are the input to the
    FBA model.</p>
    """)
    doc = builder.template_doc_bounds(settings.MODEL_ID)
    model = doc.getModel()
    utils.set_model_info(model,
                         notes=bounds_notes,
                         creators=creators,
                         units=units,
                         main_units=main_units)

    # dt
    compartment_id = "bioreactor"
    builder.create_dfba_dt(model, time_unit=UNIT_TIME, create_port=True)

    # compartment
    builder.create_dfba_compartment(model,
                                    compartment_id=compartment_id,
                                    unit_volume=UNIT_VOLUME,
                                    create_port=True)

    # dynamic species
    model_fba = doc_fba.getModel()
    builder.create_dfba_species(model,
                                model_fba,
                                compartment_id=compartment_id,
                                unit_amount=UNIT_AMOUNT,
                                create_port=True)
    # bounds
    builder.create_exchange_bounds(model,
                                   model_fba=model_fba,
                                   unit_flux=UNIT_FLUX,
                                   create_ports=True)

    # bounds
    fba_infix = "fba_"
    model_fba = doc_fba.getModel()
    objects = []
    ex_rids = utils.find_exchange_reactions(model_fba)
    for ex_rid, sid in ex_rids.items():
        r = model_fba.getReaction(ex_rid)

        # lower & upper bound parameters
        r_fbc = r.getPlugin(builder.SBML_FBC_NAME)
        lb_id = r_fbc.getLowerFluxBound()
        fba_lb_id = builder.LOWER_BOUND_PREFIX + fba_infix + ex_rid
        lb_value = model_fba.getParameter(lb_id).getValue()

        objects.extend([
            # default bounds from fba
            Parameter(sid=fba_lb_id,
                      value=lb_value,
                      unit=UNIT_FLUX,
                      constant=False),
        ])
    factory.create_objects(model, objects)

    objects = [

        # kinetic lower bounds
        Parameter(sid="lb_kin_EX_Glcxt",
                  value=builder.LOWER_BOUND_DEFAULT,
                  unit=UNIT_FLUX,
                  constant=False,
                  sboTerm="SBO:0000612"),
        Parameter(sid="lb_kin_EX_O2",
                  value=builder.LOWER_BOUND_DEFAULT,
                  unit=UNIT_FLUX,
                  constant=False,
                  sboTerm="SBO:0000612"),

        # parameters for kinetic bounds
        Parameter(sid='Vmax_EX_O2', value=15, unit=UNIT_FLUX, constant=True),
        Parameter(sid='Vmax_EX_Glcxt', value=10, unit=UNIT_FLUX,
                  constant=True),
        Parameter(sid='Km_EX_Glcxt',
                  value=0.015,
                  unit=UNIT_CONCENTRATION,
                  name="Km_vGlcxt",
                  constant=True),

        # kinetic bounds (unintuitive direction due to the identical concentrations in bioreactor and model)
        AssignmentRule(sid="lb_kin_EX_Glcxt",
                       value="-Vmax_EX_Glcxt * Glcxt/(Km_EX_Glcxt + Glcxt)"),
        AssignmentRule(sid="lb_kin_EX_O2", value="-Vmax_EX_O2"),

        # exchange reaction bounds
        # uptake bounds (lower bound)
        # TODO: FIXME the X hack
        # the bounds for the fba model have to be in mmol/h/gdw
        AssignmentRule(
            sid="lb_EX_Ac",
            value="max(lb_fba_EX_Ac, -Ac/X/1 l_per_mmol*bioreactor/dt)"),
        AssignmentRule(
            sid="lb_EX_X",
            value="max(lb_fba_EX_X, -X/X/1 l_per_mmol*bioreactor/dt)"),
        AssignmentRule(
            sid="lb_EX_Glcxt",
            value="max(lb_kin_EX_Glcxt, -Glcxt/X/1 l_per_mmol*bioreactor/dt)"),
        AssignmentRule(
            sid="lb_EX_O2",
            value="max(lb_kin_EX_O2, -O2/X/1 l_per_mmol*bioreactor/dt)"),
    ]
    factory.create_objects(model, objects)

    if annotations:
        annotator.annotate_sbml_doc(doc, annotations)
    sbmlio.write_sbml(doc, filepath=pjoin(directory, sbml_file), validate=True)
def fba_model(sbml_file, directory, annotations=None):
    """ Create FBA submodel.

    FBA submodel in sbml:fbc-version 2.
    """
    fba_notes = notes.format("""
    <h2>FBA submodel</h2>
    <p>DFBA fba submodel. Unbalanced metabolites are encoded via exchange fluxes.</p>
    """)
    doc = builder.template_doc_fba(settings.MODEL_ID)
    model = doc.getModel()
    utils.set_model_info(model, notes=fba_notes, creators=creators, units=units, main_units=main_units)

    objects = [
        # compartments
        mc.Compartment(sid='bioreactor', value=1.0, unit=UNIT_VOLUME, constant=True, name='bioreactor',
                       spatialDimensions=3),

        # species
        mc.Species(sid='Glcxt', name="glucose", initialConcentration=0.0, substanceUnit=UNIT_AMOUNT, hasOnlySubstanceUnits=False,
                   compartment="bioreactor"),
        mc.Species(sid='Ac', name="acetate", initialConcentration=0.0, substanceUnit=UNIT_AMOUNT, hasOnlySubstanceUnits=False,
                   compartment="bioreactor"),
        mc.Species(sid='O2', name="oxygen", initialConcentration=0.0, substanceUnit=UNIT_AMOUNT, hasOnlySubstanceUnits=False,
                   compartment="bioreactor"),
        mc.Species(sid='X', name="biomass", initialConcentration=0.0, substanceUnit=UNIT_AMOUNT, hasOnlySubstanceUnits=False,
                   compartment="bioreactor"),

        # bounds
        mc.Parameter(sid="zero", name="zero bound", value=0.0, unit=UNIT_FLUX_PER_G, constant=True, sboTerm="SBO:0000612"),
        mc.Parameter(sid="ub_default", name="default upper bound", value=builder.UPPER_BOUND_DEFAULT, unit=UNIT_FLUX_PER_G,
                     constant=True, sboTerm="SBO:0000612"),
    ]
    mc.create_objects(model, objects)

    # reactions
    r_v1 = mc.create_reaction(model, rid="v1", name="v1 (39.43 Ac + 35 O2 -> X)", reversible=False,
                              reactants={"Ac": 39.43, "O2": 35}, products={"X": 1}, compartment='bioreactor')
    r_v2 = mc.create_reaction(model, rid="v2", name="v2 (9.46 Glcxt + 12.92 O2 -> X)", reversible=False,
                              reactants={"Glcxt": 9.46, "O2": 12.92}, products={"X": 1}, compartment='bioreactor')
    r_v3 = mc.create_reaction(model, rid="v3", name="v3 (9.84 Glcxt + 12.73 O2 -> 1.24 Ac + X)", reversible=False,
                              reactants={"Glcxt": 9.84, "O2": 12.73}, products={"Ac": 1.24, "X": 1},
                              compartment='bioreactor')
    r_v4 = mc.create_reaction(model, rid="v4", name="v4 (19.23 Glcxt -> 12.12 Ac + X)", reversible=False,
                              reactants={"Glcxt": 19.23}, products={"Ac": 12.12, "X": 1}, compartment='bioreactor')

    # flux bounds: internal fluxes
    fbc.set_flux_bounds(r_v1, lb="zero", ub="ub_default")
    fbc.set_flux_bounds(r_v2, lb="zero", ub="ub_default")
    fbc.set_flux_bounds(r_v3, lb="zero", ub="ub_default")
    fbc.set_flux_bounds(r_v4, lb="zero", ub="ub_default")

    # reactions: exchange reactions (this species can be changed by the FBA)
    for sid in ['Ac', 'Glcxt', 'O2', 'X']:
        builder.create_exchange_reaction(model, species_id=sid, flux_unit=UNIT_FLUX_PER_G,
                                         exchange_type=builder.EXCHANGE)
    # set bounds for the exchange reactions
    p_lb_O2 = model.getParameter("lb_EX_O2")
    p_lb_O2.setValue(-15.0)  # FIXME: this is in mmol/gdw/h (biomass weighting of FBA)
    p_lb_Glcxt = model.getParameter("lb_EX_Glcxt")
    p_lb_Glcxt.setValue(-10.0)  # FIXME: this is in mmol/gdw/h

    # objective function
    model_fba = model.getPlugin(builder.SBML_FBC_NAME)
    fbc.create_objective(model_fba, oid="biomass_max", otype="maximize",
                        fluxObjectives={"v1": 1.0, "v2": 1.0, "v3": 1.0, "v4": 1.0})

    # write SBML file
    if annotations:
        annotation.annotate_sbml_doc(doc, annotations)
    sbmlio.write_sbml(doc, filepath=pjoin(directory, sbml_file), validate=True)

    return doc
Exemple #58
0
def fba_model(sbml_file, directory):
    """ Create FBA submodel.
    """
    # Read the model
    fba_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                            'data/ecoli_fba.xml')
    doc_fba = sbml.read_sbml(fba_path)

    # add comp
    doc_fba.enablePackage(
        "http://www.sbml.org/sbml/level3/version1/comp/version1", "comp", True)
    doc_fba.setPackageRequired("comp", True)

    # add notes
    model = doc_fba.getModel()
    fba_notes = notes.format("""DFBA FBA submodel.""")
    utils.set_model_info(model,
                         notes=fba_notes,
                         creators=None,
                         units=units,
                         main_units=main_units)

    # clip R_ reaction and M_ metabolite prefixes
    utils.clip_prefixes_in_model(model)

    # set id & framework
    model.setId('ecoli_fba')
    model.setName('ecoli (FBA)')
    model.setSBOTerm(comp.SBO_FLUX_BALANCE_FRAMEWORK)

    # add units and information
    for species in model.getListOfSpecies():
        species.setInitialConcentration(0.0)
        species.setHasOnlySubstanceUnits(False)
        species.setUnits(UNIT_AMOUNT)
    for compartment in model.getListOfCompartments():
        compartment.setUnits(UNIT_VOLUME)

    # The ATPM (atp maintainance reactions creates many problems in the DFBA)
    # mainly resulting in infeasible solutions when some metabolites run out.
    # ATP -> ADP is part of the biomass, so we set the lower bound to zero
    r_ATPM = model.getReaction('ATPM')
    r_ATPM_fbc = r_ATPM.getPlugin(builder.SBML_FBC_NAME)
    lb_id = r_ATPM_fbc.getLowerFluxBound()
    model.getParameter(lb_id).setValue(0.0)  # 8.39 before

    # make unique upper and lower bounds for exchange reaction
    if not biomass_weighting:
        builder.update_exchange_reactions(model=model, flux_unit=UNIT_FLUX)
    else:
        builder.update_exchange_reactions(model=model,
                                          flux_unit=UNIT_FLUX_PER_G)

    # add exchange reaction for biomass (X)
    # we are adding the biomass component to the biomass function and create an
    # exchange reaction for it
    r_biomass = model.getReaction('BIOMASS_Ecoli_core_w_GAM')

    # FIXME: refactor in function
    # FIXME: annotate biomass species (SBO for biomass missing)
    mc.create_objects(model, [
        mc.Parameter(sid='cf_X',
                     value=1.0,
                     unit="g_per_mmol",
                     name="biomass conversion factor",
                     constant=True),
        mc.Species(sid='X',
                   initialAmount=0.001,
                   compartment='c',
                   name='biomass',
                   substanceUnit='g',
                   hasOnlySubstanceUnits=True,
                   conversionFactor='cf_X')
    ])

    pr_biomass = r_biomass.createProduct()
    pr_biomass.setSpecies('X')
    pr_biomass.setStoichiometry(1.0)
    pr_biomass.setConstant(True)
    # FIXME: the flux units must fit to the species units.
    if not biomass_weighting:
        builder.create_exchange_reaction(model,
                                         species_id='X',
                                         flux_unit=UNIT_FLUX,
                                         exchange_type=builder.EXCHANGE_EXPORT)
    else:
        builder.create_exchange_reaction(model,
                                         species_id='X',
                                         flux_unit=UNIT_FLUX_PER_G,
                                         exchange_type=builder.EXCHANGE_EXPORT)
    # write SBML file
    sbml.write_sbml(doc_fba,
                    filepath=pjoin(directory, sbml_file),
                    validate=True)

    # Set kinetic laws to zero for kinetic simulation
    '''
    for reaction in model.getListOfReactions():
        ast_node = mc.ast_node_from_formula(model=model, formula='0 {}'.format(UNIT_FLUX))
        law = reaction.createKineticLaw()
        law.setMath(ast_node)
    '''

    return doc_fba