Guest User

ps8_help for shedskinning

a guest
Jan 1st, 2013
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 15.54 KB | None | 0 0
  1. #Set 8: Simulating the Spread of Disease and Virus Population Dynamics
  2. import time
  3. import random
  4.  
  5. '''
  6. Begin helper code
  7. '''
  8.  
  9. class NoChildException(Exception):
  10.     """
  11.    NoChildException is raised by the reproduce() method in the SimpleVirus
  12.    and ResistantVirus classes to indicate that a virus particle does not
  13.    reproduce. You can use NoChildException as is, you do not need to
  14.    modify/add any code.
  15.    """
  16.  
  17. '''
  18. End helper code
  19. '''
  20.  
  21. #
  22. # PROBLEM 2
  23. #
  24. from copy import copy
  25.  
  26. class SimpleVirus(object):
  27.  
  28.     """
  29.    Representation of a simple virus (does not model drug effects/resistance).
  30.    """
  31.     def __init__(self, maxBirthProb, clearProb):
  32.         """
  33.        Initialize a SimpleVirus instance, saves all parameters as attributes
  34.        of the instance.        
  35.        maxBirthProb: Maximum reproduction probability (a float between 0-1)        
  36.        clearProb: Maximum clearance probability (a float between 0-1).
  37.        """
  38.  
  39.         self.max_birth_prob, self.clear_prob = maxBirthProb, clearProb
  40.  
  41.     def getMaxBirthProb(self):
  42.         """
  43.        Returns the max birth probability.
  44.        """
  45.         return self.max_birth_prob
  46.  
  47.     def getClearProb(self):
  48.         """
  49.        Returns the clear probability.
  50.        """
  51.         return self.clear_prob
  52.  
  53.     def doesClear(self):
  54.         """ Stochastically determines whether this virus particle is cleared from the
  55.        patient's body at a time step.
  56.        returns: True with probability self.getClearProb and otherwise returns
  57.        False.
  58.        """
  59.         return random.random() < self.getClearProb()
  60.  
  61.  
  62.     def reproduce(self, popDensity):
  63.         """
  64.        Stochastically determines whether this virus particle reproduces at a
  65.        time step. Called by the update() method in the Patient and
  66.        TreatedPatient classes. The virus particle reproduces with probability
  67.        self.getMaxBirthProb * (1 - popDensity).
  68.        
  69.        If this virus particle reproduces, then reproduce() creates and returns
  70.        the instance of the offspring SimpleVirus (which has the same
  71.        maxBirthProb and clearProb values as its parent).        
  72.  
  73.        popDensity: the population density (a float), defined as the current
  74.        virus population divided by the maximum population.        
  75.        
  76.        returns: a new instance of the SimpleVirus class representing the
  77.        offspring of this virus particle. The child should have the same
  78.        maxBirthProb and clearProb values as this virus. Raises a
  79.        NoChildException if this virus particle does not reproduce.              
  80.        """
  81.         if random.random() < self.getMaxBirthProb() * (1 - popDensity):
  82.             return copy(self)
  83.         else:
  84.             raise NoChildException
  85.  
  86.  
  87.  
  88. class Patient(object):
  89.     """
  90.    Representation of a simplified patient. The patient does not take any drugs
  91.    and his/her virus populations have no drug resistance.
  92.    """    
  93.  
  94.     def __init__(self, viruses, maxPop):
  95.         """
  96.        Initialization function, saves the viruses and maxPop parameters as
  97.        attributes.
  98.  
  99.        viruses: the list representing the virus population (a list of
  100.        SimpleVirus instances)
  101.  
  102.        maxPop: the maximum virus population for this patient (an integer)
  103.        """
  104.  
  105.         self.viruses, self.maximum_population = viruses, maxPop
  106.  
  107.     def getViruses(self):
  108.         """
  109.        Returns the viruses in this Patient.
  110.        """
  111.         return self.viruses
  112.  
  113.  
  114.     def getMaxPop(self):
  115.         """
  116.        Returns the max population.
  117.        """
  118.         return self.maximum_population
  119.  
  120.  
  121.     def getTotalPop(self):
  122.         """
  123.        Gets the size of the current total virus population.
  124.        returns: The total virus population (an integer)
  125.        """
  126.         return len(self.getViruses())
  127.  
  128.     def _new_viruses(self):
  129.         """
  130.        - Determine whether each virus particle survives and updates the list
  131.        of virus particles accordingly.
  132.        """
  133.         new_viruses = []
  134.  
  135.         for virus in self.getViruses():
  136.             if not virus.doesClear():
  137.                 new_viruses.append(virus)
  138.         return new_viruses
  139.  
  140.  
  141.     def _try_reproduce(self, population_density):
  142.         """
  143.        - Based on this value of population density, determine whether each
  144.          virus particle should reproduce and add offspring virus particles to
  145.          the list of viruses in this patient.
  146.        """
  147.         new_viruses = []
  148.  
  149.         for virus in self.viruses:
  150.             try:
  151.                 new_viruses.append(virus.reproduce(population_density))
  152.             except NoChildException:
  153.                 pass
  154.         return new_viruses
  155.  
  156.     def update(self):
  157.         """
  158.        Update the state of the virus population in this patient for a single
  159.        time step. update() should execute the following steps in this order:
  160.        
  161.        - Determine whether each virus particle survives and updates the list
  162.        of virus particles accordingly.  
  163.        
  164.        - The current population density is calculated. This population density
  165.          value is used until the next call to update()
  166.        
  167.        - Based on this value of population density, determine whether each
  168.          virus particle should reproduce and add offspring virus particles to
  169.          the list of viruses in this patient.                    
  170.  
  171.        returns: The total virus population at the end of the update (an
  172.        integer)
  173.        """
  174.  
  175.         self.viruses = self._new_viruses()
  176.         max_population = float(self.getMaxPop())
  177.         #print len(self.viruses), 'survive'
  178.         self.viruses.extend(self._try_reproduce(self.getTotalPop() / max_population))
  179.         return self.getTotalPop()
  180.    
  181. class ResistantVirus(SimpleVirus):
  182.     """
  183.    Representation of a virus which can have drug resistance.
  184.    """  
  185.  
  186.     def __init__(self, maxBirthProb, clearProb, resistances, mutProb):
  187.         """
  188.        Initialize a ResistantVirus instance, saves all parameters as attributes
  189.        of the instance.
  190.  
  191.        maxBirthProb: Maximum reproduction probability (a float between 0-1)      
  192.  
  193.        clearProb: Maximum clearance probability (a float between 0-1).
  194.  
  195.        resistances: A dictionary of drug names (strings) mapping to the state
  196.        of this virus particle's resistance (either True or False) to each drug.
  197.        e.g. {'guttagonol':False, 'srinol':False}, means that this virus
  198.        particle is resistant to neither guttagonol nor srinol.
  199.  
  200.        mutProb: Mutation probability for this virus particle (a float). This is
  201.        the probability of the offspring acquiring or losing resistance to a drug.
  202.        """
  203.         SimpleVirus.__init__(self, maxBirthProb, clearProb)
  204.         self.resistances, self.mutProb = resistances, mutProb
  205.  
  206.     def isResistantTo(self, drug):
  207.         """
  208.        Get the state of this virus particle's resistance to a drug. This method
  209.        is called by getResistPop() in TreatedPatient to determine how many virus
  210.        particles have resistance to a drug.      
  211.  
  212.        drug: The drug (a string)
  213.  
  214.        returns: True if this virus instance is resistant to the drug, False
  215.        otherwise.
  216.        """      
  217.         return self.resistances.get(drug, False)
  218.  
  219.  
  220.     def reproduce(self, popDensity, activeDrugs):
  221.         """
  222.        Stochastically determines whether this virus particle reproduces at a
  223.        time step. Called by the update() method in the TreatedPatient class.
  224.  
  225.        A virus particle will only reproduce if it is resistant to ALL the drugs
  226.        in the activeDrugs list. For example, if there are 2 drugs in the
  227.        activeDrugs list, and the virus particle is resistant to 1 or no drugs,
  228.        then it will NOT reproduce.
  229.  
  230.        Hence, if the virus is resistant to all drugs
  231.        in activeDrugs, then the virus reproduces with probability:      
  232.  
  233.        self.getMaxBirthProb * (1 - popDensity).                      
  234.  
  235.        If this virus particle reproduces, then reproduce() creates and returns
  236.        the instance of the offspring ResistantVirus (which has the same
  237.        maxBirthProb and clearProb values as its parent). The offspring virus
  238.        will have the same maxBirthProb, clearProb, and mutProb as the parent.
  239.  
  240.        For each drug resistance trait of the virus (i.e. each key of
  241.        self.resistances), the offspring has probability 1-mutProb of
  242.        inheriting that resistance trait from the parent, and probability
  243.        mutProb of switching that resistance trait in the offspring.      
  244.  
  245.        For example, if a virus particle is resistant to guttagonol but not
  246.        srinol, and self.mutProb is 0.1, then there is a 10% chance that
  247.        that the offspring will lose resistance to guttagonol and a 90%
  248.        chance that the offspring will be resistant to guttagonol.
  249.        There is also a 10% chance that the offspring will gain resistance to
  250.        srinol and a 90% chance that the offspring will not be resistant to
  251.        srinol.
  252.  
  253.        popDensity: the population density (a float), defined as the current
  254.        virus population divided by the maximum population      
  255.  
  256.        activeDrugs: a list of the drug names acting on this virus particle
  257.        (a list of strings).
  258.  
  259.        returns: a new instance of the ResistantVirus class representing the
  260.        offspring of this virus particle. The child should have the same
  261.        maxBirthProb and clearProb values as this virus. Raises a
  262.        NoChildException if this virus particle does not reproduce.
  263.        """
  264.  
  265.         if (all(self.isResistantTo(drug) for drug in activeDrugs) and
  266.             random.random() < self.getMaxBirthProb() * (1 - popDensity)):
  267.             resistances = copy(self.resistances)
  268.             for drug in self.resistances:
  269.                 if random.random() < self.mutProb:
  270.                     resistances[drug] = not resistances[drug]
  271.             return ResistantVirus(self.getMaxBirthProb(), self.getClearProb(), resistances, self.mutProb)
  272.         raise NoChildException
  273.  
  274.                
  275.            
  276.  
  277. class TreatedPatient(Patient):
  278.     """
  279.    Representation of a patient. The patient is able to take drugs and his/her
  280.    virus population can acquire resistance to the drugs he/she takes.
  281.    """
  282.  
  283.     def __init__(self, viruses, maxPop):
  284.         """
  285.        Initialization function, saves the viruses and maxPop parameters as
  286.        attributes. Also initializes the drugs being administered
  287.        (which should initially include no drugs).              
  288.  
  289.        viruses: The list representing the virus population (a list of
  290.        virus instances)
  291.  
  292.        maxPop: The  maximum virus population for this patient (an integer)
  293.        """
  294.  
  295.         Patient.__init__(self, viruses, maxPop)
  296.         self.drugs = set()
  297.  
  298.     def addPrescription(self, newDrug):
  299.         """
  300.        Administer a drug to this patient. After a prescription is added, the
  301.        drug acts on the virus population for all subsequent time steps. If the
  302.        newDrug is already prescribed to this patient, the method has no effect.
  303.  
  304.        newDrug: The name of the drug to administer to the patient (a string).
  305.  
  306.        postcondition: The drugs being administered to a patient is updated
  307.        """
  308.  
  309.         self.drugs.add(newDrug)
  310.  
  311.  
  312.     def getPrescriptions(self):
  313.         """
  314.        Returns the drugs that are being administered to this patient.
  315.  
  316.        returns: The drug names (strings) being administered to this
  317.        patient.
  318.        """
  319.  
  320.         return self.drugs
  321.  
  322.  
  323.     def getResistPop(self, drugResist):
  324.         """
  325.        Get the population of virus particles resistant to the drugs listed in
  326.        drugResist.      
  327.  
  328.        drugResist: Which drug resistances to include in the population (a list
  329.        of strings - e.g. ['guttagonol'] or ['guttagonol', 'srinol'])
  330.  
  331.        returns: The population of viruses (an integer) with resistances to all
  332.        drugs in the drugResist list.
  333.        """
  334.         return sum(1 for virus in self.viruses if all(virus.isResistantTo(drug)
  335.                                                        for drug in drugResist))
  336.  
  337.     def _try_reproduce(self, population_density):
  338.         """
  339.        - Based on this value of population density, determine whether each
  340.          virus particle should reproduce and add offspring virus particles to
  341.          the list of viruses in this patient.
  342.          The list of drugs being administered should be accounted for in the
  343.          determination of whether each virus particle reproduces.
  344.        """
  345.         new_viruses = []
  346.         for virus in self.viruses:
  347.             try:
  348.                 new_viruses.append(virus.reproduce(population_density, self.getPrescriptions()))
  349.             except NoChildException:
  350.                 pass
  351.         return new_viruses
  352.  
  353. def col(mat,j):
  354.      v=[]
  355.      rows=len(mat)
  356.      for i in xrange(rows):
  357.           v.append(mat[i][j])
  358.      return v
  359.    
  360. def transpose(m):
  361.      n = []
  362.      cols=len(m[0])
  363.      for i in xrange(cols):
  364.           n.append(col(m,i))
  365.      return n
  366.            
  367.  
  368. #
  369. # PROBLEM 5
  370. #
  371. def simulationWithDrug(numViruses, maxPop, maxBirthProb, clearProb, resistances,
  372.                        mutProb, numTrials, start=150, timing=False):
  373.     """
  374.    Runs simulations and plots graphs for problem 5.
  375.  
  376.    For each of numTrials trials, instantiates a patient, runs a simulation for
  377.    150 timesteps, adds guttagonol, and runs the simulation for an additional
  378.    150 timesteps.  At the end plots the average virus population size
  379.    (for both the total virus population and the guttagonol-resistant virus
  380.    population) as a function of time.
  381.  
  382.    numViruses: number of ResistantVirus to create for patient (an integer)
  383.    maxPop: maximum virus population for patient (an integer)
  384.    maxBirthProb: Maximum reproduction probability (a float between 0-1)        
  385.    clearProb: maximum clearance probability (a float between 0-1)
  386.    resistances: a dictionary of drugs that each ResistantVirus is resistant to
  387.                 (e.g., {'guttagonol': False})
  388.    mutProb: mutation probability for each ResistantVirus particle
  389.             (a float between 0-1).
  390.    numTrials: number of simulation runs to execute (an integer)
  391.    
  392.    """
  393.     simulations = []
  394.     resistant_pop =[]
  395.     if timing:
  396.         t0 = time.clock()
  397.     for trial in range(numTrials):
  398.         population = [ResistantVirus(maxBirthProb, clearProb, resistances, mutProb) for _ in range(numViruses)]
  399.         patient = TreatedPatient(population, maxPop)
  400.         current =  []
  401.         resistant = []
  402.         if not trial % 10: print trial,
  403.         for simulation in range(300):
  404.             if simulation == start:
  405.                 patient.addPrescription("guttagonol")
  406. ##                for drug in resistances:
  407. ##                    patient.addPrescription(drug)
  408.             current.append(float(patient.update()))
  409.             resistant.append(float(patient.getResistPop(['guttagonol'])))
  410.         simulations.append(current)
  411.         resistant_pop.append(resistant)
  412.     if timing:
  413.         print time.clock() - t0, 's'
  414.     else:
  415.         print
  416.     x = [sum(step)/len(step) for step in transpose(simulations)]
  417.     y = [sum(resist)/len(resist) for resist in transpose(resistant_pop)]
  418.     return x,y
  419. ##    print x
  420. ##    print y
  421.  
  422. if __name__ == '__main__':
  423.     random.seed(0)
  424.     x, y = simulationWithDrug(100, 1000, 0.1, 0.05,
  425.                     {'guttagonol': False}, 0.005, 100, timing=True)
  426.     print x
  427.     print y
Advertisement
Add Comment
Please, Sign In to add comment