def get_flagella_initial_state(ports={}): flagella_data = FlagellaChromosome() chromosome_config = flagella_data.chromosome_config molecules = {} for nucleotide in nucleotides.values(): molecules[nucleotide] = 5000000 for amino_acid in amino_acids.values(): molecules[amino_acid] = 1000000 return { ports.get('molecules', 'molecules'): molecules, ports.get('transcripts', 'transcripts'): {gene: 0 for gene in chromosome_config['genes'].keys()}, ports.get('proteins', 'proteins'): { 'CpxR': 10, 'CRP': 10, 'Fnr': 10, 'endoRNAse': 1, 'flagella': 8, UNBOUND_RIBOSOME_KEY: 200, # e. coli has ~ 20000 ribosomes UNBOUND_RNAP_KEY: 200 } }
def run_flagella_compartment( compartment, initial_state=None, out_dir='out'): # get flagella data flagella_data = FlagellaChromosome() # run simulation settings = { # a cell cycle of 2520 sec is expected to express 8 flagella. # 2 flagella expected in approximately 630 seconds. 'total_time': 2520, 'emit_step': COMPARTMENT_TIMESTEP, 'verbose': True, 'initial_state': initial_state} timeseries = simulate_compartment_in_experiment(compartment, settings) # save reference timeseries save_timeseries(timeseries, out_dir) plot_config = { 'name': 'flagella_expression', 'ports': { 'transcripts': 'transcripts', 'proteins': 'proteins', 'molecules': 'molecules'}} plot_gene_expression_output( timeseries, plot_config, out_dir) # just-in-time figure plot_config2 = plot_config.copy() plot_config2.update({ 'name': 'flagella', 'plot_ports': { 'transcripts': list(flagella_data.chromosome_config['genes'].keys()), 'proteins': flagella_data.complexation_monomer_ids + flagella_data.complexation_complex_ids, 'molecules': list(nucleotides.values()) + list(amino_acids.values())}}) plot_timeseries_heatmaps( timeseries, plot_config2, out_dir) # make a basic sim output plot_settings = { 'max_rows': 30, 'remove_zeros': True, 'skip_ports': ['chromosome', 'ribosomes']} plot_simulation_output( timeseries, plot_settings, out_dir)
def test_gene_expression(total_time=10): # load the compartment compartment_config = { 'external_path': ('external', ), 'global_path': ('global', ), 'agents_path': ( '..', '..', 'cells', ), 'transcription': { 'sequence': toy_chromosome_config['sequence'], 'templates': toy_chromosome_config['promoters'], 'genes': toy_chromosome_config['genes'], 'promoter_affinities': toy_chromosome_config['promoter_affinities'], 'transcription_factors': ['tfA', 'tfB'], 'elongation_rate': 10.0 }, # 'complexation': { # 'monomer_ids': [], # 'complex_ids': [], # 'stoichiometry': {}} } compartment = GeneExpression(compartment_config) molecules = {nt: 1000 for nt in nucleotides.values()} molecules.update({aa: 1000 for aa in amino_acids.values()}) proteins = { polymerase: 100 for polymerase in [UNBOUND_RNAP_KEY, UNBOUND_RIBOSOME_KEY] } proteins.update({factor: 1 for factor in ['tfA', 'tfB']}) # simulate settings = { 'timestep': 1, 'total_time': total_time, 'initial_state': { 'proteins': proteins, 'molecules': molecules } } return simulate_compartment_in_experiment(compartment, settings)
def plot_gene_expression_output(timeseries, config, out_dir='out'): name = config.get('name', 'gene_expression') ports = config.get('ports', {}) molecules = timeseries[ports['molecules']] transcripts = timeseries[ports['transcripts']] proteins = timeseries[ports['proteins']] time = timeseries['time'] # make figure and plot n_cols = 1 n_rows = 5 plt.figure(figsize=(n_cols * 6, n_rows * 1.5)) # define subplots ax1 = plt.subplot(n_rows, n_cols, 1) ax2 = plt.subplot(n_rows, n_cols, 2) ax3 = plt.subplot(n_rows, n_cols, 3) ax4 = plt.subplot(n_rows, n_cols, 4) ax5 = plt.subplot(n_rows, n_cols, 5) polymerase_ids = [UNBOUND_RNAP_KEY, UNBOUND_RIBOSOME_KEY] amino_acid_ids = list(amino_acids.values()) nucleotide_ids = list(nucleotides.values()) # plot polymerases for poly_id in polymerase_ids: ax1.plot(time, proteins[poly_id], label=poly_id) ax1.legend(loc='center left', bbox_to_anchor=(1.0, 0.5)) ax1.title.set_text('polymerases') # plot nucleotides for nuc_id in nucleotide_ids: ax2.plot(time, molecules[nuc_id], label=nuc_id) ax2.legend(loc='center left', bbox_to_anchor=(1.0, 0.5)) ax2.title.set_text('nucleotides') # plot molecules for aa_id in amino_acid_ids: ax3.plot(time, molecules[aa_id], label=aa_id) ax3.legend(loc='center left', bbox_to_anchor=(2.0, 0.5)) ax3.title.set_text('amino acids') # plot transcripts for transcript_id, series in transcripts.items(): ax4.plot(time, series, label=transcript_id) ax4.legend(loc='center left', bbox_to_anchor=(1.0, 0.5)) ax4.title.set_text('transcripts') # plot proteins for protein_id in sorted(proteins.keys()): if protein_id != UNBOUND_RIBOSOME_KEY: ax5.plot(time, proteins[protein_id], label=protein_id) ax5.legend(loc='center left', bbox_to_anchor=(1.5, 0.5)) ax5.title.set_text('proteins') # adjust axes for axis in [ax1, ax2, ax3, ax4, ax5]: axis.spines['right'].set_visible(False) axis.spines['top'].set_visible(False) ax1.set_xticklabels([]) ax2.set_xticklabels([]) ax3.set_xticklabels([]) ax4.set_xticklabels([]) ax5.set_xlabel('time (s)', fontsize=12) # save figure fig_path = os.path.join(out_dir, name) plt.subplots_adjust(wspace=0.3, hspace=0.5) plt.savefig(fig_path, bbox_inches='tight')
def __init__(self, initial_parameters=None): '''A stochastic translation model .. WARNING:: Vivarium's knowledge base uses the gene name to name the protein. This means that for a gene acrA that codes for protein ArcA, you must refer to the gene, transcript, and protein each as acrA. .. DANGER:: This documentation will need to be updated to reflect the changes in `#185 <https://github.com/CovertLab/vivarium/pull/185>`_ :term:`Ports`: * **ribosomes**: Expects the ``ribosomes`` variable, whose value is a list of the configurations of the ribosomes currently active. * **molecules**: Expects variables for each of the RNA nucleotides. * **transcripts**: Expects variables for each transcript to translate. Translation will read transcripts from this port. * **proteins**: Expects variables for each protein product. The produced proteins will be added to this port as counts. * **concentrations**: Expects variables for each key in ``concentration_keys``. This will be used by a :term:`deriver` to convert counts to concentrations. Arguments: initial_parameters: A dictionary of configuration options. Accepts the following keys: * **sequences** (:py:class:`dict`): Maps from operon name to the RNA sequence of the operon, as a :py:class:`str`. * **templates** (:py:class:`dict`): Maps from the name of an transcript to a :term:`template specification`. The template specification may be generated by :py:func:`vivarium.library.polymerize.generate_template` like so: >>> from vivarium.library.polymerize import ( ... generate_template) >>> from vivarium.library.pretty import format_dict >>> terminator_index = 5 >>> template = generate_template( ... 'oA', terminator_index, ['product1']) >>> print(format_dict(template)) { "direction": 1, "id": "oA", "position": 0, "sites": [], "terminators": [ { "position": 5, "products": [ "product1" ], "strength": 1.0 } ] } * **transcript_affinities** (:py:class:`dict`): A map from the name of a transcript to the binding affinity (a :py:class:`float`) of the ribosome for the transcript. * **elongation_rate** (:py:class:`float`): The elongation rate of the ribosome. .. todo:: Units of elongation rate * **polymerase_occlusion** (:py:class:`int`): The number of base pairs behind the polymerase where another polymerase is occluded and so cannot bind. * **symbol_to_monomer** (:py:class:`dict`): Maps from the symbols used to represent monomers in the RNA sequence to the name of the free monomer. This should generally be :py:data:`vivarium.data.amino_acids.amino_acids`. * **monomer_ids** (:py:class:`list`): A list of the names of the free monomers consumed by translation. This can generally be computed as: >>> import pprint >>> >>> from vivarium.data.amino_acids import amino_acids >>> monomer_ids = amino_acids.values() >>> pp = pprint.PrettyPrinter() >>> pp.pprint(list(monomer_ids)) ['Alanine', 'Arginine', 'Asparagine', 'Aspartate', 'Cysteine', 'Glutamate', 'Glutamine', 'Glycine', 'Histidine', 'Isoleucine', 'Leucine', 'Lysine', 'Methionine', 'Phenylalanine', 'Proline', 'Serine', 'Threonine', 'Tryptophan', 'Tyrosine', 'Valine'] Note that we only included the `list()` transformation to make the output prettier. The `dict_values` object returned by `.values()` is sufficiently list-like for use here. Also note that :py:mod:`pprint` just makes the output prettier. * **concentration_keys** (:py:class:`list`): A list of variables you want to be able to access as concentrations from the *concentrations* port. The actual conversion is handled by a deriver. Example configuring the process (uses :py:func:vivarium.library.pretty.format_dict): >>> from vivarium.library.pretty import format_dict >>> from vivarium.data.amino_acids import amino_acids >>> from vivarium.library.polymerize import generate_template >>> random.seed(0) # Needed because process is stochastic >>> np.random.seed(0) >>> configurations = { ... 'sequences': { ... ('oA', 'eA'): 'AWDPT', ... ('oAZ', 'eZ'): 'YVEGELENGGMFISC', ... }, ... 'templates': { ... ('oA', 'eA'): generate_template(('oA', 'eA'), 5, ['eA']), ... ('oAZ', 'eZ'): generate_template(('oAZ', 'eZ'), 15, ['eA', 'eZ']), ... }, ... 'transcript_affinities': { ... ('oA', 'eA'): 1.0, ... ('oAZ', 'eZ'): 1.0, ... }, ... 'elongation_rate': 10.0, ... 'polymerase_occlusion': 10, ... 'symbol_to_monomer': amino_acids, ... 'monomer_ids': amino_acids.values(), ... 'concentration_keys': [] ... } >>> # make the translation process, and initialize the states >>> translation = Translation(configurations) # doctest:+ELLIPSIS >>> states = { ... 'ribosomes': {}, ... 'molecules': {}, ... 'proteins': {UNBOUND_RIBOSOME_KEY: 2}, ... 'transcripts': { ... 'oA': 10, ... 'oAZ': 10, ... } ... } >>> states['molecules'].update( ... { ... molecule_id: 100 ... for molecule_id in translation.monomer_ids ... } ... ) >>> update = translation.next_update(1, states) >>> print(update['ribosomes']) {1: <class 'vivarium.processes.translation.Ribosome'>: {'id': 1, 'state': 'occluding', 'position': 9, 'template': ('oAZ', 'eZ'), 'template_index': 0, 'terminator': 0}, 2: <class 'vivarium.processes.translation.Ribosome'>: {'id': 2, 'state': 'occluding', 'position': 9, 'template': ('oAZ', 'eZ'), 'template_index': 0, 'terminator': 0}, '_delete': []} ''' if not initial_parameters: initial_parameters = {} self.monomer_symbols = list(amino_acids.keys()) self.monomer_ids = list(amino_acids.values()) self.default_parameters = copy.deepcopy(self.defaults) templates = self.or_default(initial_parameters, 'templates') self.default_parameters['protein_ids'] = all_products( {key: Template(config) for key, config in templates.items()}) self.default_parameters['transcript_order'] = list( initial_parameters.get( 'transcript_affinities', self.default_parameters['transcript_affinities']).keys()) self.default_parameters['molecule_ids'] = self.monomer_ids self.parameters = copy.deepcopy(self.default_parameters) self.parameters.update(initial_parameters) self.sequences = self.parameters['sequences'] self.templates = self.parameters['templates'] self.transcript_affinities = self.parameters['transcript_affinities'] self.operons = gather_genes(self.transcript_affinities) self.operon_order = list(self.operons.keys()) self.transcript_order = self.parameters['transcript_order'] self.transcript_count = len(self.transcript_order) self.monomer_ids = self.parameters['monomer_ids'] self.molecule_ids = self.parameters['molecule_ids'] self.protein_ids = self.parameters['protein_ids'] self.symbol_to_monomer = self.parameters['symbol_to_monomer'] self.elongation = 0 self.elongation_rate = self.parameters['elongation_rate'] self.polymerase_occlusion = self.parameters['polymerase_occlusion'] self.concentration_keys = self.parameters['concentration_keys'] self.affinity_vector = np.array([ self.transcript_affinities[transcript_key] for transcript_key in self.transcript_order ], dtype=np.float64) self.stoichiometry = build_stoichiometry(self.transcript_count) self.initiation = StochasticSystem(self.stoichiometry) self.ribosome_id = 0 self.protein_keys = self.concentration_keys + self.protein_ids self.all_protein_keys = self.protein_keys + [UNBOUND_RIBOSOME_KEY] self.mass_deriver_key = self.or_default(initial_parameters, 'mass_deriver_key') self.concentrations_deriver_key = self.or_default( initial_parameters, 'concentrations_deriver_key') log.info('translation parameters: {}'.format(self.parameters)) super(Translation, self).__init__(self.parameters)