def test_transcription(): parameters = { '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 } chromosome = Chromosome(toy_chromosome_config) transcription = Transcription(parameters) experiment = process_in_experiment( transcription, { 'initial_state': { 'chromosome': chromosome.to_dict(), 'molecules': {nucleotide: 10 for nucleotide in transcription.monomer_ids}, 'proteins': { UNBOUND_RNAP_KEY: 10 }, 'factors': { 'tfA': 0.2, 'tfB': 0.7 } } }) pp(experiment.state.get_value()) experiment.update(10.0) pp(experiment.state.get_value()) print('complete!')
def next_update(self, timestep, states): chromosome_state = states['chromosome'] # chromosome_state['rnaps'] = list(chromosome_state['rnaps'].values()) original_rnap_keys = [ rnap['id'] for rnap in chromosome_state['rnaps'].values() ] chromosome = Chromosome(self.chromosome_config(chromosome_state)) molecules = states['molecules'] proteins = states['proteins'] factors = states['factors'] # as concentrations promoter_rnaps = chromosome.promoter_rnaps() promoter_domains = chromosome.promoter_domains() # Find out how many promoters are currently blocked by a # newly initiated or occluding rnap promoter_count = len(chromosome.promoter_order) blocked_promoters = np.zeros(promoter_count, dtype=np.int64) open_domains = {} bound_domains = {} for promoter_index, promoter_key in enumerate( chromosome.promoter_order): domains = [] for rnap in promoter_rnaps.get(promoter_key, {}).values(): if rnap.is_occluding(): domains.append(rnap.domain) blocked_promoters[promoter_index] += 1 bound_domains[promoter_key] = set(domains) open_domains[promoter_key] = promoter_domains[ promoter_key] - bound_domains[promoter_key] blocked_promoters = np.array(blocked_promoters) # Make the state for a gillespie simulation out of total number of each # promoter by copy number not blocked by initiated rnap, # concatenated with the number of each promoter that is bound by rnap. # These are the two states for each promoter the simulation # will operate on, essentially going back and forth between # bound and unbound states. copy_numbers = chromosome.promoter_copy_numbers() original_unbound_rnaps = proteins[UNBOUND_RNAP_KEY] monomer_limits = { monomer: molecules[monomer] for monomer in self.monomer_ids } unbound_rnaps = original_unbound_rnaps time = 0 now = 0 elongation = Elongation(self.sequences, chromosome.promoters, monomer_limits, self.symbol_to_monomer, self.elongation) initiation_affinity = self.build_affinity_vector( chromosome.promoters, factors) while time < timestep: # build the state vector for the gillespie simulation substrate = np.concatenate([ copy_numbers - blocked_promoters, blocked_promoters, [unbound_rnaps] ]) log.debug('transcription substrate: {}'.format(substrate)) log.debug('blocked promoters: {}'.format(blocked_promoters)) # find number of monomers until next terminator distance = 1 / self.elongation_rate # chromosome.terminator_distance() # find interval of time that elongates to the point of the next terminator interval = min(distance, timestep - time) if interval == distance: # perform the elongation until the next event terminations, monomer_limits, chromosome.rnaps = elongation.step( interval, monomer_limits, chromosome.rnaps) unbound_rnaps += terminations else: elongation.store_partial(interval) terminations = 0 log.debug('time: {} --- interval: {}'.format(time, interval)) log.debug('monomer limits: {}'.format(monomer_limits)) log.debug('terminations: {}'.format(terminations)) # run simulation for interval of time to next terminator result = self.initiation.evolve(interval, substrate, initiation_affinity) log.debug('result: {}'.format(result)) # perform binding for now, event in zip(result['time'], result['events']): # RNAP has bound the promoter promoter_key = chromosome.promoter_order[event] promoter = chromosome.promoters[promoter_key] domains = open_domains[promoter_key] domain = choose_element(domains) blocked_promoters[event] += 1 bound_domains[promoter_key].add(domain) open_domains[promoter_key].remove(domain) # create a new bound RNAP and add it to the chromosome. new_rnap = chromosome.bind_rnap(event, domain) new_rnap.start_polymerizing() log.debug('newly bound RNAP: {}'.format(new_rnap)) unbound_rnaps -= 1 # deal with occluding rnap for rnap in chromosome.rnaps.values(): if rnap.is_unoccluding(self.polymerase_occlusion): log.debug('RNAP unoccluding: {}'.format(rnap)) blocked_promoters[rnap.template_index] -= 1 bound_domains[rnap.template].remove(rnap.domain) open_domains[rnap.template].add(rnap.domain) rnap.unocclude() log.debug('rnap: {}'.format(rnap)) log.debug('complete: {}'.format(elongation.complete_polymers)) time += interval # track how far elongation proceeded to start from next iteration self.elongation = elongation.elongation - int(elongation.elongation) proteins = {UNBOUND_RNAP_KEY: unbound_rnaps - original_unbound_rnaps} molecules = { key: count * -1 for key, count in elongation.monomers.items() } # 1 ATP hydrolysis cost per nucleotide elongation molecules['ATP'] = 0 molecules['ADP'] = 0 for count in elongation.monomers.values(): molecules['ATP'] -= count molecules['ADP'] += count chromosome_dict = chromosome.to_dict() rnaps = chromosome_dict['rnaps'] original = set(original_rnap_keys) current = set(rnaps.keys()) bound_rnaps = current - original completed_rnaps = original - current continuing_rnaps = original - completed_rnaps rnap_updates = { rnap_id: rnaps[rnap_id] for rnap_id in continuing_rnaps } add_rnaps = [{ 'path': (bound, ), 'state': rnaps[bound] } for bound in bound_rnaps] delete_rnaps = [(completed, ) for completed in completed_rnaps] rnap_updates['_add'] = add_rnaps rnap_updates['_delete'] = delete_rnaps chromosome_dict['rnaps'] = rnap_updates update = { 'chromosome': {key: chromosome_dict[key] for key in self.chromosome_ports}, 'proteins': proteins, 'molecules': molecules, 'transcripts': elongation.complete_polymers } log.debug('molecules update: {}'.format(update['molecules'])) return update