Skip to content

Commit

Permalink
Merge pull request #13 from zoltuz/master
Browse files Browse the repository at this point in the history
adding some reporting
  • Loading branch information
murrayrm committed Sep 13, 2018
2 parents 23e20ec + 137d18f commit 9df2fcb
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 32 deletions.
7 changes: 5 additions & 2 deletions examples/geneexpr_3tube.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
tube3 = txtl.newtube('geneexpr')

# Define a DNA strand using strings (ala MATLAB)
gene1 = txtl.assemble_dna('ptet(50)', 'BCD2(20)', 'tetR(1200)')
txtl.add_dna(tube3, gene1, 1, 'plasmid')
gene1 = txtl.assemble_dna(prom='ptet(50)', utr5='BCD2(20)', cds='tetR(1200)')
txtl.add_dna(mixture=tube3, dna=gene1, conc=1, type='plasmid')

#
# Assemble a DNA strand using objects (semi-pythonic)
Expand Down Expand Up @@ -51,3 +51,6 @@

# Create an SBML file containing the model
txtl.write_sbml(well1, 'geneexpr.xml')

# print out a basic report about the content of the well
well1.print_report()
9 changes: 9 additions & 0 deletions txtl/dna.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ def update_reactions(self, mixture, debug=False):
for dna in [self.promoter, self.utr5, self.cds, self.ctag, self.utr3]:
if dna != None:
dna.update_reactions(mixture)

def __str__(self):
return 'DNA Assembly: ' + self.name

#
# DNA component
Expand Down Expand Up @@ -212,6 +215,9 @@ def update_species(self, mixture, conc):
def update_reactions(self, mixture):
return None

def __str__(self):
return self.name

#
# Promoter subclasses
#
Expand Down Expand Up @@ -251,6 +257,9 @@ def __init__(
# Fill in any missing parameter values with defaults
update_missing(self.parameters, Promoter.default_parameters)

def __str__(self):
return self.prefix + self.name

def update_species(self, mixture, conc, parameters={}):
assy = self.assy # Get the DNA assembly we are part of

Expand Down
6 changes: 4 additions & 2 deletions txtl/extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def __init__(self, name, parameters={}):
self.parameters = get_parameters(self.config_file, parameters)

class StandardExtract(Extract):
mechanisms = {
default_mechanisms = {
'transcription' : transcription.basic(),
'translation' : translation.basic(),
'DNA_degradation' : degradation.dna_basic(),
Expand Down Expand Up @@ -125,6 +125,8 @@ def update_reactions(self, mixture):
#! TODO: add reactions that are instantiated by extract
# mechanism['RNA_degradation'].update_reactions(mixture, mechanisms)
None
def __str__(self):
return "StandardExtract with %d mechanisms" % len(self.default_mechanisms)

# Create a mixture containing extract
def create_extract(name, type=StandardExtract, mechanisms={}):
Expand All @@ -150,7 +152,7 @@ def create_extract(name, type=StandardExtract, mechanisms={}):
mixture.concentrations = [10.0/(10.0/3.0)]

# Store default mechanisms and custom mechanisms
mixture.default_mechanisms = extract.mechanisms
mixture.default_mechanisms = extract.default_mechanisms
mixture.custom_mechanisms = mechanisms

# Store the parameters in the mixture so that components can access them
Expand Down
7 changes: 6 additions & 1 deletion txtl/mechanism.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,15 @@ class Mechanism:
derived from this class.
"""
def __init__(self): return None
def __init__(self,name=''):
self.name = name

def update_species(self, mixture, component, conc): return None
def update_reactions(self, mixture, component): return None

def __str__(self):
return self.name

# Utility function to retrieve mechanism list
def get_mechanisms(mixture, component, custom={}):
mechanisms = {} # initalize mechanism
Expand Down
8 changes: 8 additions & 0 deletions txtl/mechanisms/degradation.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,25 @@

class dna_basic(Mechanism):
"Basic DNA degradation"
def __init__(self):
self.name = 'Basic DNA degradation'

#! TODO: not implemented

class rna_basic(Mechanism):
"Basic RNA degradation"
def __init__(self):
self.name = 'Basic RNA degradation'

def update_reactions(self, mixture, assy):
parameters = mixture.parameters # get parameter values
add_reaction(mixture, [assy.rna], [], kf=parameters['RNA_deg'],
prefix="degradation_rna_basic_")

class protein_basic(Mechanism):
"Basic protein degradation"
def __init__(self):
self.name = 'Basic protein degradation'
#! TODO: not implemented


3 changes: 3 additions & 0 deletions txtl/mechanisms/maturation.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

class protein_basic(Mechanism):
"Basic protein maturation"
def __init__(self):
self.name = 'Basic protein maturation'

def update_reactions(self, mixture, assy, debug=False):
#! TODO: See if this protein is subject to maturation
#! TODO: Create maturation reaction
Expand Down
4 changes: 4 additions & 0 deletions txtl/mechanisms/transcription.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
# Convert DNA to RNA
class basic(Mechanism):
"Basic transcription mechanism"

def __init__(self):
self.name = 'Basic Transcription'

def update_reactions(self, mixture, assy, debug=False):
parameters = assy.promoter.parameters # get parameter values

Expand Down
3 changes: 3 additions & 0 deletions txtl/mechanisms/translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

class basic(Mechanism):
"Basic translation mechanism"
def __init__(self):
self.name = 'Basic Translation'

def update_reactions(self, mixture, assy, debug=False):
parameters = assy.utr5.parameters # get parameter values

Expand Down
56 changes: 37 additions & 19 deletions txtl/mixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def __init__(self, name=None, mechanisms={}, config_file=None):
document, model, compartment = create_sbml_model()

# Initialize instance variables
self.name = name; # Save the name of the mixture
self.name = name # Save the name of the mixture
self._SBMLdoc = document # SBML document container
self.model = model # SBML model object
self.compartment = compartment # SBML compartment
Expand All @@ -82,28 +82,43 @@ def __init__(self, name=None, mechanisms={}, config_file=None):
if (config_file != None):
self.parameters.update(load_config(config_file))

def write_sbml(self, filename):
"Generate an SBML file for the current mixture (model)"

def _update_sbml_model(self):
"""Updating the internal SBML representation"""
# Update all species in the mixture to make sure everything exists
for i in range(len(self.components)):
concentration = self.concentrations[i]
component = self.components[i]

assert (len(self.concentrations) == len(self.components))
for component, concentration in zip(self.components, self.concentrations):
# Create all (global) parameters for this component
#! TODO: need to document this better; see extract.py
# ! TODO: need to document this better; see extract.py
component.update_parameters(self)

# Create all of the species for this component
component.update_species(self, concentration)



# Now go through and add all of the reactions that are required
for component in self.components:
component.update_reactions(self)

def print_report(self):
self._update_sbml_model()
# Now go through and add all of the reactions that are required
for component in self.components:
print(component)
for mechanism_name, mechanism_implementation in component.default_mechanisms.items():
print('\t' + mechanism_name + ": " + str(mechanism_implementation))

def write_sbml(self, filename):
"Generate an SBML file for the current mixture (model)"
self._update_sbml_model()

# Write the model to a file
libsbml.writeSBMLToFile(self._SBMLdoc, filename)

def __str__(self):
"""Returning the name of the mixture"""
return self.name

#
# Functions for interacting with mixtures
#
Expand Down Expand Up @@ -132,34 +147,37 @@ def add_dna(mixture, dna, conc, type=None):
# Combine the components of two more more mixtures
def combine_mixtures(mixtures, volumes=None, name=None):
# Create a name if we were sent done
#! TODO: concatenate names of mixtures

# Create a mixture for the results
if name is None:
name = 'Mix_of'

outmixture = Mixture(name)

# Keep track of the total amount of mixture we are creating (for scaling)
# If no volumes are given, assume equal volumes of 1 unit each
total_volume = sum(volumes) if volumes != None else len(mixtures)
total_volume = sum(volumes) if volumes is not None else len(mixtures)

# Add the components (and concentrations) of inputs to the output
for i in range(len(mixtures)):
for i, mixture in enumerate(mixtures):
# Combine the mechanisms
#! TODO: issue a warning if there are conflicting mechanisms
outmixture.default_mechanisms.update(mixtures[i].default_mechanisms)
outmixture.custom_mechanisms.update(mixtures[i].custom_mechanisms)

outmixture.default_mechanisms.update(mixture.default_mechanisms)
outmixture.custom_mechanisms.update(mixture.custom_mechanisms)
outmixture.name += '_' + str(mixture) # getting the name of a mixture
# Components of new mixture are concatenation of mixture components
outmixture.components += mixtures[i].components
outmixture.components += mixture.components

# Concentrations are scaled by the volume
scale = volume[i]/total_volume if volumes != None else 1/total_volume
for j in range(len(mixtures[i].concentrations)):
outmixture.concentrations += [mixtures[i].concentrations[j] * scale]
scale = volumes[i]/total_volume if volumes is not None else 1/total_volume
for concentration in mixture.concentrations:
outmixture.concentrations += [concentration * scale]

# Combine parameter dictionaries from each mixture
#! TODO: issue a warning if there are conflicting parameters
outmixture.parameters.update(mixtures[i].parameters)

assert len(outmixture.concentrations) == len(outmixture.components)
return outmixture

# Write out the SBML description of the contexts of a mixture
Expand Down
15 changes: 7 additions & 8 deletions txtl/sbmlutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,17 @@ def add_species(mixture, type, name, ic=None, debug=False):
model = mixture.model # Get the model where we will store results

# Construct the species name
prefix = type + " " if type != None else ""
prefix = type + " " if type is not None else ""
species_name = prefix + name

# Construct the species ID
species_id = _id_from_name(species_name)

# Check to see if this species is already present
species = find_species(model, species_id)
if species == None:
if species is None:
if debug: print("Adding species %s" % species_name)
species = model.createSpecies()
prefix = type + " " if type != None else ""
species.setName(species_name)
species.setId(species_id)
species.setCompartment(mixture.compartment.getId())
Expand Down Expand Up @@ -89,13 +88,13 @@ def find_species(mixture, species_name):
#! TODO: Add error checking
return model.getSpecies(species_id)

# Helper function to add a pameter to the model
# Helper function to add a parameter to the model
def add_parameter(mixture, name, value=0, debug=False):
model = mixture.model # Get the model where we will store results

# Check to see if this parameter is already present
parameter = find_parameter(mixture, name) #! TODO: add error checking
if parameter == None:
if parameter is None:
if debug: print("Adding parameter %s" % name)
parameter = model.createParameter()
parameter.setId(name) #! TODO: add error checking
Expand Down Expand Up @@ -218,11 +217,11 @@ def add_reaction(mixture, reactants, products, kf, kr=None, id=None,
param.setValue(float(kf))
ratelaw.setFormula(ratestring);

# If the reverse rate is given, switch things around create reverse raaction
if (kr != None):
# If the reverse rate is given, switch things around create reverse reaction
if kr is not None:
revreaction = add_reaction(mixture, products, reactants, kr, None,
prefix=prefix)
return (reaction, revreaction)
return reaction, revreaction

return reaction

Expand Down

0 comments on commit 9df2fcb

Please sign in to comment.