Exemple #1
0
    def test_polymerize_functionCall(self):
        sequences = np.array([[0, 1, 0, 1], [3, 1, 0, 2], [2, 2, 1, 1]])
        baseAmounts = np.array([9, 9, 9, 9])
        energy = 100

        # Good calls test
        polymerize(sequences, baseAmounts, energy, np.random.RandomState())
Exemple #2
0
    def test_polymerize_testVariableSequenceLength(self):
        sequences = np.array([[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 1, 1], [3] * 12,
                              [2] * 12, [1, 1, 1] + [P] * 9])
        baseAmounts = np.array([30] * 4)
        energy = 50

        result = polymerize(sequences, baseAmounts, energy,
                            np.random.RandomState())

        assert_equal(result.sequenceElongation, np.array([12, 12, 12, 3]))
Exemple #3
0
    def test_polymerize_testEnergyLimited(self):
        sequences = np.array([[0, 1, 0, 1], [1, 1, 1, 1]])
        baseAmounts = np.array([9, 9])
        energy = 6

        result = polymerize(sequences, baseAmounts, energy,
                            np.random.RandomState())

        assert_equal(result.sequenceElongation, np.array([3, 3]))
        assert_equal(result.monomerUsages, np.array([2, 4]))
        self.assertEqual(6, result.nReactions)
Exemple #4
0
    def test_polymerize_testAllAvailableBases(self):
        sequences = np.array([[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 1, 1], [3] * 12,
                              [2] * 12, [P] * 12])
        baseAmounts = np.array([11] * 4)
        energy = 30

        result = polymerize(sequences, baseAmounts, energy,
                            np.random.RandomState())

        assert_equal(result.sequenceElongation, np.array([12, 9, 9, 0]))
        assert_equal(result.monomerUsages, np.array([3, 5, 11, 11]))
        self.assertEqual(30, result.nReactions)
Exemple #5
0
    def test_polymerize_testFairness(self):
        sequences = np.array([[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3], [3] * 12,
                              [2] * 12, [P] * 12])
        baseAmounts = np.array([11] * 4)
        baseAmountsOriginal = baseAmounts.copy()
        energy = 30

        result = polymerize(sequences, baseAmounts, energy,
                            np.random.RandomState())

        assert_equal(result.sequenceElongation, np.array([10, 9, 9, 0]))
        assert_equal(result.monomerUsages, np.array([3, 3, 11, 11]))
        self.assertEqual(28, result.nReactions)
        self.assertTrue((baseAmounts == baseAmountsOriginal).all(),
                        'should not modify monomerLimits')
def _fullProfile():
    np.random.seed(0)

    sequences, monomerLimits, reactionLimit, randomState = _setupRealExample()

    # Recipe from https://docs.python.org/2/library/profile.html#module-cProfile
    pr = cProfile.Profile()
    pr.enable()

    sequenceElongation, monomerUsages, nReactions = polymerize(
        sequences, monomerLimits, reactionLimit, randomState)

    pr.disable()
    s = StringIO.StringIO()
    sortby = 'cumulative'
    ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
    ps.print_stats()
    print s.getvalue()
	def test_polymerize_testVariableElongation(self):
		sequences = np.array([
			[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 1, 1],
			[3] * 12,
			[2] * 12,
			[1, 1, 1] + [P] * 9])
		baseAmounts = np.array([30] * 4)
		energy = 20

		rates = np.array([4, 3, 2, 1])
		result = polymerize(
			sequences,
			baseAmounts,
			energy,
			np.random.RandomState(),
			rates,
			variable_elongation=True)

		assert_equal(result.sequenceElongation, np.array([8, 6, 4, 2]))
def _simpleProfile():
    np.random.seed(0)

    sequences, monomerLimits, reactionLimit, randomState = _setupExample()

    nSequences, length = sequences.shape
    nMonomers = monomerLimits.size
    sequenceLengths = (sequences != PAD_VALUE).sum(axis=1)

    t = time.time()
    sequenceElongation, monomerUsages, nReactions = polymerize(
        sequences, monomerLimits, reactionLimit, randomState)
    evalTime = time.time() - t

    assert (sequenceElongation <= sequenceLengths + 1).all()
    assert (monomerUsages <= monomerLimits).all()
    assert nReactions <= reactionLimit
    assert nReactions == monomerUsages.sum()

    print """
Polymerize function report:

For {} sequences of {} different monomers elongating by at most {}:

{:0.1f} ms to evaluate
{} polymerization reactions
{:0.1f} average elongations per sequence
{:0.1%} monomer utilization
{:0.1%} energy utilization
{:0.1%} fully elongated
{:0.1%} completion
""".format(nSequences, nMonomers, length, evalTime * 1000, nReactions,
           sequenceElongation.mean(),
           monomerUsages.sum() / monomerLimits.sum(),
           nReactions / reactionLimit,
           (sequenceElongation == sequenceLengths).sum() / nSequences,
           sequenceElongation.sum() / sequenceLengths.sum())
    def evolveState(self):

        ## Module 1: Replication initiation
        # Get number of active DNA polymerases and oriCs
        activeDnaPoly = self.activeDnaPoly.molecules()
        activePolymerasePresent = (len(activeDnaPoly) > 0)
        oriCs = self.oriCs.molecules()
        n_oric = len(oriCs)
        n_chromosomes = self.full_chromosome.total()[0]

        # If there are no chromosomes and oriC's, return immediately
        if n_oric == 0 and n_chromosomes == 0:
            return

        # Get cell mass
        cellMass = (self.readFromListener("Mass", "cellMass") * units.fg)

        # Get critical initiation mass for simulation medium environment
        current_nutrients = self._external_states['Environment'].nutrients
        self.criticalInitiationMass = self.getDnaCriticalMass(
            self.nutrientToDoublingTime[current_nutrients])

        # Calculate mass per origin of replication, and compare to critical
        # initiation mass. This is a rearrangement of the equation:
        # 	(Cell Mass)/(Number of origins) > Critical mass
        # If the above inequality holds true, initiate a round of chromosome
        # replication for every origin of replication
        massFactor = cellMass / self.criticalInitiationMass
        massPerOrigin = massFactor / n_oric
        replication_initiated = False

        # If conditions are true, initiate a round of replication on every
        # origin of replication
        if massPerOrigin >= 1.0 and self.partialChromosomes.counts().sum(
        ) == 0:
            replication_initiated = True

            # Get replication round indexes of active DNA polymerases
            if activePolymerasePresent:
                replicationRound = activeDnaPoly.attr('replicationRound')
            else:
                # Set to -1 to set values for new polymerases to 0
                replicationRound = np.array([-1])

            # Get chromosome indexes of current oriCs
            chromosomeIndexOriC = oriCs.attr('chromosomeIndex')

            # Calculate number of new DNA polymerases required (4 per origin)
            n_new_polymerase = 4 * n_oric

            # Add new polymerases and oriC's
            activeDnaPolyNew = self.activeDnaPoly.moleculesNew(
                "dnaPolymerase", n_new_polymerase)
            oriCsNew = self.oriCs.moleculesNew("originOfReplication", n_oric)

            # Calculate and set attributes of newly created polymerases
            sequenceIdx = np.tile(np.array([0, 1, 2, 3]), n_oric)
            sequenceLength = np.zeros(n_new_polymerase, dtype=np.int)
            replicationRound = np.ones(
                n_new_polymerase, dtype=np.int) * (replicationRound.max() + 1)

            # Polymerases inherit index of the OriC's they were initiated from
            chromosomeIndexPolymerase = np.repeat(chromosomeIndexOriC, 4)

            activeDnaPolyNew.attrIs(
                sequenceIdx=sequenceIdx,
                sequenceLength=sequenceLength,
                replicationRound=replicationRound,
                chromosomeIndex=chromosomeIndexPolymerase,
            )

            # Calculate and set attributes of newly created oriCs
            # New OriC's share the index of the old OriC's they were
            # replicated from
            oriCsNew.attrIs(chromosomeIndex=chromosomeIndexOriC)

        # Write data from this module to a listener
        self.writeToListener("ReplicationData", "criticalMassPerOriC",
                             massPerOrigin)
        self.writeToListener("ReplicationData", "criticalInitiationMass",
                             self.criticalInitiationMass.asNumber(units.fg))

        ## Module 2: replication elongation
        # If no active polymerases are present, return immediately
        # Note: the new DNA polymerases activated in the previous module are
        # not elongated until the next timestep.
        if len(activeDnaPoly) == 0:
            return

        # Build sequences to polymerize
        dNtpCounts = self.dntps.counts()
        sequenceIdx, sequenceLengths, massDiffDna = activeDnaPoly.attrs(
            'sequenceIdx', 'sequenceLength', 'massDiff_DNA')

        sequences = buildSequences(self.sequences, sequenceIdx,
                                   sequenceLengths,
                                   self._dnaPolymeraseElongationRate())

        # Use polymerize algorithm to quickly calculate the number of
        # elongations each "polymerase" catalyzes
        reactionLimit = dNtpCounts.sum()

        result = polymerize(sequences, dNtpCounts, reactionLimit,
                            self.randomState)

        sequenceElongations = result.sequenceElongation
        dNtpsUsed = result.monomerUsages

        # Compute mass increase for each polymerizing chromosome
        massIncreaseDna = computeMassIncrease(
            sequences, sequenceElongations,
            self.polymerized_dntp_weights.asNumber(units.fg))

        updatedMass = massDiffDna + massIncreaseDna

        # Update positions of each "polymerase"
        updatedLengths = sequenceLengths + sequenceElongations

        activeDnaPoly.attrIs(sequenceLength=updatedLengths,
                             massDiff_DNA=updatedMass)

        # Update counts of polymerized metabolites
        self.dntps.countsDec(dNtpsUsed)
        self.ppi.countInc(dNtpsUsed.sum())

        ## Module 3: replication termination
        # Determine if any polymerases reached the end of their sequences. If
        # so, terminate replication and update the attributes of the remaining
        # polymerases and OriC's to reflect the new chromosome structure.
        terminalLengths = self.sequenceLengths[sequenceIdx]
        didTerminate = (updatedLengths == terminalLengths)

        terminatedChromosomes = np.bincount(sequenceIdx[didTerminate],
                                            minlength=self.sequences.shape[0])

        # If any of the polymerases were terminated, check if all polymerases
        # initiated the same round as the terminated polymerases has already
        # been removed - if they have, update attributes of the remaining
        # polymerases and oriC's, and remove the polymerases. This is not done
        # when some polymerases were initiated in the same timestep, as the
        # attributes for these new polymerases cannot be updated in the same
        # timestep.
        if didTerminate.sum() > 0 and replication_initiated == False:
            # Get attributes from active DNA polymerases and oriC's
            sequenceIdx, chromosomeIndexPolymerase, replicationRound = activeDnaPoly.attrs(
                'sequenceIdx', 'chromosomeIndex', 'replicationRound')
            chromosomeIndexOriC = oriCs.attr('chromosomeIndex')

            # Check that all terminated polymerases were initiated in the same
            # replication round
            assert np.unique(replicationRound[didTerminate]).size == 1

            # Get chromosome indexes of the terminated polymerases
            chromosomeIndexesTerminated = np.unique(
                chromosomeIndexPolymerase[didTerminate])
            newChromosomeIndex = chromosomeIndexPolymerase.max() + 1

            # Get replication round index of the terminated polymerases
            terminatedRound = replicationRound[didTerminate][0]

            for chromosomeIndexTerminated in chromosomeIndexesTerminated:
                # Get all remaining active polymerases initiated in the same
                # replication round and in the given chromosome
                replicationRoundMatch = (replicationRound == terminatedRound)
                chromosomeMatch = (
                    chromosomeIndexPolymerase == chromosomeIndexTerminated)
                remainingPolymerases = np.logical_and(replicationRoundMatch,
                                                      chromosomeMatch)

                # Get all terminated polymerases in the given chromosome
                terminatedPolymerases = np.logical_and(didTerminate,
                                                       chromosomeMatch)

                # If all active polymerases are terminated polymerases, we are
                # ready to split the chromosome and update the attributes.
                if remainingPolymerases.sum() == terminatedPolymerases.sum():

                    # For each set of polymerases initiated in the same
                    # replication round, update the chromosome indexes to a new
                    # index for half of the polymerases.
                    for roundIdx in np.arange(terminatedRound + 1,
                                              replicationRound.max() + 1):
                        replicationRoundMatch = (replicationRound == roundIdx)
                        polymerasesToSplit = np.logical_and(
                            replicationRoundMatch, chromosomeMatch)

                        n_matches = polymerasesToSplit.sum()

                        # Number of polymerases initiated in a single round
                        # must be a multiple of eight.
                        assert n_matches % 8 == 0

                        # Update the chromosome indexes for half of the polymerases
                        secondHalfIdx = np.where(polymerasesToSplit)[0][(
                            n_matches // 2):]
                        chromosomeIndexPolymerase[
                            secondHalfIdx] = newChromosomeIndex

                    # Reset chromosomeIndex for active DNA polymerases
                    activeDnaPoly.attrIs(
                        chromosomeIndex=chromosomeIndexPolymerase)

                    # Get oriC's in the chromosome getting divided
                    chromosomeMatchOriC = (
                        chromosomeIndexOriC == chromosomeIndexTerminated)
                    n_matches = chromosomeMatchOriC.sum()

                    # Number of OriC's in a dividing chromosome should be even
                    assert n_matches % 2 == 0

                    # Update the chromosome indexes for half of the OriC's
                    secondHalfIdx = np.where(chromosomeMatchOriC)[0][(
                        n_matches // 2):]
                    chromosomeIndexOriC[secondHalfIdx] = newChromosomeIndex

                    # Reset chromosomeIndex for oriC's
                    oriCs.attrIs(chromosomeIndex=chromosomeIndexOriC)

                    # Increment the new chromosome index in case another
                    # chromosome needs to be split
                    newChromosomeIndex += 1

            # Delete terminated polymerases
            activeDnaPoly.delByIndexes(np.where(didTerminate)[0])

            # Update counts of newly created chromosome halves. These will be
            # "stitched" together in the ChromosomeFormation process
            self.partialChromosomes.countsInc(terminatedChromosomes)
Exemple #10
0
	def evolveState(self):
		ntpCounts = self.ntps.counts()
		self.writeToListener("GrowthLimits", "ntpAllocated", ntpCounts)

		activeRnaPolys = self.activeRnaPolys.molecules()
		if len(activeRnaPolys) == 0:
			return

		# Determine sequences that can be elongated
		rnaIndexes, transcriptLengths, massDiffRna = activeRnaPolys.attrs('rnaIndex', 'transcriptLength', 'massDiff_mRNA')
		sequences = buildSequences(self.rnaSequences, rnaIndexes, transcriptLengths, self.rnapElngRate)
		ntpCountInSequence = np.bincount(sequences[sequences != polymerize.PAD_VALUE], minlength = 4)

		# Polymerize transcripts based on sequences and available nucleotides
		reactionLimit = ntpCounts.sum()
		result = polymerize(sequences, ntpCounts, reactionLimit, self.randomState)
		sequenceElongations = result.sequenceElongation
		ntpsUsed = result.monomerUsages
		nElongations = result.nReactions

		# Calculate changes in mass associated with polymerization and update active polymerases
		massIncreaseRna = computeMassIncrease(sequences, sequenceElongations, self.ntWeights)
		updatedMass = massDiffRna + massIncreaseRna
		didInitialize = (transcriptLengths == 0) & (sequenceElongations > 0)
		updatedLengths = transcriptLengths + sequenceElongations
		updatedMass[didInitialize] += self.endWeight
		activeRnaPolys.attrIs(transcriptLength = updatedLengths, massDiff_mRNA = updatedMass)

		# Determine if transcript has reached the end of the sequence
		terminalLengths = self.rnaLengths[rnaIndexes]
		didTerminate = (updatedLengths == terminalLengths)
		terminatedRnas = np.bincount(rnaIndexes[didTerminate], minlength = self.rnaSequences.shape[0])

		# Remove polymerases that have finished transcription from unique molecules
		activeRnaPolys.delByIndexes(np.where(didTerminate)[0])

		nTerminated = didTerminate.sum()
		nInitialized = didInitialize.sum()
		nElongations = ntpsUsed.sum()

		# Update bulk molecule counts
		self.ntps.countsDec(ntpsUsed)
		self.bulkRnas.countsIs(terminatedRnas)
		self.inactiveRnaPolys.countInc(nTerminated)
		self.ppi.countInc(nElongations - nInitialized)

		# Calculate stalls
		expectedElongations = np.fmin(self.rnapElngRate, terminalLengths - transcriptLengths)
		rnapStalls = expectedElongations - sequenceElongations

		# Write outputs to listeners
		self.writeToListener("TranscriptElongationListener", "countRnaSynthesized", terminatedRnas)
		self.writeToListener("TranscriptElongationListener", "countNTPsUSed", nElongations)
		self.writeToListener("GrowthLimits", "ntpUsed", ntpsUsed)
		self.writeToListener("RnapData", "rnapStalls", rnapStalls)
		self.writeToListener("RnapData", "ntpCountInSequence", ntpCountInSequence)
		self.writeToListener("RnapData", "ntpCounts", ntpCounts)
		self.writeToListener("RnapData", "expectedElongations", expectedElongations.sum())
		self.writeToListener("RnapData", "actualElongations", sequenceElongations.sum())
		self.writeToListener("RnapData", "didTerminate", didTerminate.sum())
		self.writeToListener("RnapData", "terminationLoss", (terminalLengths - transcriptLengths)[didTerminate].sum())
    def evolveState(self):
        # Write allocation data to listener
        self.writeToListener("GrowthLimits", "gtpAllocated", self.gtp.count())
        self.writeToListener("GrowthLimits", "aaAllocated", self.aas.counts())

        # Get number of active ribosomes
        activeRibosomes = self.activeRibosomes.molecules()

        self.writeToListener("GrowthLimits", "activeRibosomeAllocated",
                             len(activeRibosomes))

        if len(activeRibosomes) == 0:
            return

        # Build amino acids sequences for each ribosome to polymerize
        proteinIndexes, peptideLengths, massDiffProtein = activeRibosomes.attrs(
            'proteinIndex', 'peptideLength', 'massDiff_protein')

        sequences = buildSequences(self.proteinSequences, proteinIndexes,
                                   peptideLengths, self.ribosomeElongationRate)

        if sequences.size == 0:
            return

        # Calculate elongation resource capacity
        aaCountInSequence = np.bincount(
            sequences[(sequences != polymerize.PAD_VALUE)])
        aaCounts = self.aas.counts()

        # Using polymerization algorithm elongate each ribosome up to the limits
        # of amino acids, sequence, and GTP
        result = polymerize(
            sequences,
            aaCounts,
            10000000,  # Set to a large number, the limit is now taken care of in metabolism
            self.randomState)

        sequenceElongations = result.sequenceElongation
        aasUsed = result.monomerUsages
        nElongations = result.nReactions

        # Update masses of ribosomes attached to polymerizing polypeptides
        massIncreaseProtein = computeMassIncrease(sequences,
                                                  sequenceElongations,
                                                  self.aaWeightsIncorporated)

        updatedLengths = peptideLengths + sequenceElongations

        didInitialize = ((sequenceElongations > 0) & (peptideLengths == 0))

        updatedMass = massDiffProtein + massIncreaseProtein

        updatedMass[didInitialize] += self.endWeight

        # Write current average elongation to listener
        currElongRate = (sequenceElongations.sum() /
                         len(activeRibosomes)) / self.timeStepSec()
        self.writeToListener("RibosomeData", "effectiveElongationRate",
                             currElongRate)

        # Update active ribosomes, terminating if neccessary
        activeRibosomes.attrIs(peptideLength=updatedLengths,
                               massDiff_protein=updatedMass)

        # Ribosomes that reach the end of their sequences are terminated and
        # dissociated into 30S and 50S subunits. The polypeptide that they are polymerizing
        # is converted into a protein in BulkMolecules
        terminalLengths = self.proteinLengths[proteinIndexes]

        didTerminate = (updatedLengths == terminalLengths)

        terminatedProteins = np.bincount(
            proteinIndexes[didTerminate],
            minlength=self.proteinSequences.shape[0])

        activeRibosomes.delByIndexes(np.where(didTerminate)[0])
        self.bulkMonomers.countsInc(terminatedProteins)

        nTerminated = didTerminate.sum()
        nInitialized = didInitialize.sum()

        self.ribosome30S.countInc(nTerminated)
        self.ribosome50S.countInc(nTerminated)

        # Update counts of amino acids and water to reflect polymerization reactions
        self.aas.countsDec(aasUsed)
        self.h2o.countInc(nElongations - nInitialized)

        # Report stalling information
        expectedElongations = np.fmin(self.ribosomeElongationRate,
                                      terminalLengths - peptideLengths)

        ribosomeStalls = expectedElongations - sequenceElongations

        # Write data to listeners
        self.writeToListener("GrowthLimits", "aasUsed", aasUsed)
        self.writeToListener("GrowthLimits", "gtpUsed", self.gtpUsed)

        self.writeToListener("RibosomeData", "ribosomeStalls", ribosomeStalls)
        self.writeToListener("RibosomeData", "aaCountInSequence",
                             aaCountInSequence)
        self.writeToListener("RibosomeData", "aaCounts", aaCounts)

        self.writeToListener("RibosomeData", "expectedElongations",
                             expectedElongations.sum())
        self.writeToListener("RibosomeData", "actualElongations",
                             sequenceElongations.sum())
        self.writeToListener(
            "RibosomeData", "actualElongationHist",
            np.histogram(sequenceElongations, bins=np.arange(0, 23))[0])
        self.writeToListener(
            "RibosomeData", "elongationsNonTerminatingHist",
            np.histogram(sequenceElongations[~didTerminate],
                         bins=np.arange(0, 23))[0])

        self.writeToListener("RibosomeData", "didTerminate",
                             didTerminate.sum())
        self.writeToListener("RibosomeData", "terminationLoss",
                             (terminalLengths -
                              peptideLengths)[didTerminate].sum())
        self.writeToListener("RibosomeData", "numTrpATerminated",
                             terminatedProteins[self.trpAIndex])

        self.writeToListener("RibosomeData", "processElongationRate",
                             self.ribosomeElongationRate / self.timeStepSec())