def distribute_lesions(g, nb_lesions=1, disease_model='septoria_exchanging_rings', initiation_model=RandomInoculation(), label="LeafElement"): """ Distribute lesions on the MTG. Parameters ---------- g: MTG MTG representing the canopy nb_lesions: int Number of lesions to distribute on the MTG disease_model: model Type of model to compute disease lesion development initiation_model: model Model that sets the position of each DU/lesion in stock on g Requires a method named 'allocate' (see doc) Returns ------- g: MTG Updated MTG with dispersal units or lesions """ distribute_disease(g, fungal_object='lesion', nb_objects=nb_lesions, disease_model=disease_model, initiation_model=initiation_model, label=label)
def distribute_dispersal_units(g, nb_dus=1, model="SeptoriaWithRings"): """ Distribute new dispersal units on g. Call the method 'initiate' from the protocol with dispersal units. Parameters ---------- g: MTG MTG representing the canopy nb_dus: int Number of dispersal units to put on g Returns ------- g: MTG Updated MTG representing the canopy """ fungus = septoria(model=model) fungus = septoria(model=model) SeptoriaDU.fungus = fungus dispersal_units = ([SeptoriaDU(nb_spores=rd.randint(1,100), status='emitted') for i in range(nb_dus)]) inoculator = RandomInoculation() initiate(g, dispersal_units, inoculator) return g
def test_initiate(model="septoria_exchanging_rings"): """ Check if 'initiate' from 'protocol.py' deposits dispersal units on the MTG. Generate a wheat MTG and distribute dispersal units randomly on leaf elements. Check that all the stock of DU is distributed in properties of leaf elements. Parameters ---------- model: model One version of the model of septoria lesion among: 'septoria_exchanging_rings', 'septoria_with_rings', 'septoria_continuous' """ # Generate a wheat MTG g = adel_one_leaf_element() set_properties(g, label='LeafElement', area=5., green_area=5., position_senescence=None) # Generate a stock of septoria dispersal units and distribute it on g nb_initial_dus = 100 distribute_dispersal_units(g, nb_dus=nb_initial_dus, disease_model=model, initiation_model=RandomInoculation(), label='LeafElement') # Check that all the DUs that were in the stock are now instantiated # on leaf elements : dispersal_units = g.property('dispersal_units') nb_dus_on_leaves = sum(len(dus) for dus in dispersal_units.itervalues()) assert nb_dus_on_leaves == nb_initial_dus
def distribute_lesions(g, nb_lesions=1, model="SeptoriaWithRings"): """ Distribute new lesions on g. Call the method 'initiate' from the protocol with lesions. Parameters ---------- g: MTG MTG representing the canopy nb_lesions: int Number of lesions to put on g model: str Type of model of septoria lesion Returns ------- g: MTG Updated MTG representing the canopy """ fungus = septoria(model=model) models = ({"SeptoriaExchangingRings":SeptoriaExchangingRings, "SeptoriaWithRings":SeptoriaWithRings, "ContinuousSeptoria":ContinuousSeptoria}) if model in models: models[model].fungus = fungus lesions = [models[model](nb_spores=rd.randint(1,100)) for i in range(nb_lesions)] inoculator = RandomInoculation() initiate(g, lesions, inoculator) return g
def distribute_lesions(g, nb_objects=1, disease_model='powdery_mildew', initiation_model=RandomInoculation()): """ Use the method 'distribute_disease' to distribute lesions on g. Parameters ---------- g: MTG MTG representing the canopy nb_objects: int Number of dispersal units or lesions to distribute on the MTG disease_model: model Type of model to compute disease lesion development initiation_model: model Model that sets the position of each DU/lesion in stock on g Requires a method named 'allocate' (see doc) Returns ------- g: MTG Updated MTG with lesions """ distribute_disease(g, fungal_object='lesion', nb_objects=nb_objects, disease_model=disease_model, initiation_model=initiation_model)
def test_update(): """ Check if 'update' from 'protocol.py' provokes the growth of a lesion instantiated on the MTG. """ g = adel_mtg2() set_properties(g, area=20., green_area=20.) septoria = plugin_septoria() SeptoriaDU = septoria.dispersal_unit() stock = [SeptoriaDU(nb_spores=random.randint(1,100), status='emitted') for i in range(100)] inoculator = RandomInoculation() initiate(g, stock, inoculator) controler = NoPriorityGrowthControl() dt = 1 nb_steps = 750 nb_les_inc = numpy.zeros(nb_steps) # nb_les_chlo = numpy.array([0. for i in range(nb_steps)]) # nb_les_nec = numpy.array([0. for i in range(nb_steps)]) nb_les_spo = numpy.zeros(nb_steps) # nb_les_empty = numpy.array([0. for i in range(nb_steps)]) nb_les = 0. for i in range(nb_steps): ts = time.clock() #print('time step %d' % i) update_climate_all(g) #grow(g) update_healthy_area(g, label = 'LeafElement') infect(g, dt) update(g,dt, growth_control_model=controler) # control_growth(g, controler) # Count of lesions : nb_les_inc[i] = count_lesions_in_state(g, state = 0) # nb_les_chlo[i] = count_lesions_in_state(g, state = 1) # nb_les_nec[i] = count_lesions_in_state(g, state = 2) nb_les_spo[i] = count_lesions_in_state(g, state = 3) # nb_les_empty[i] = count_lesions_in_state(g, state = 4) te = time.clock() #print "time ", i, " : ", te-ts # Display results plot(nb_les_inc) plot(nb_les_spo) ylabel('Nombre de lesions dans cet etat sur le MTG') xlabel('Pas de temps de simulation') ylim([0, 120]) # displayer = DisplayLesions() # displayer.print_all_lesions(g) # plot_lesions(g) return g
def test_growth_control(): g = adel_mtg() set_initial_properties_g(g, surface_leaf_element=5.) fungus = septoria(); SeptoriaDU.fungus = fungus stock = [SeptoriaDU(nb_spores=random.randint(1,100), status='emitted') for i in range(1000)] inoculator = RandomInoculation() initiate(g, stock, inoculator) controler = NoPriorityGrowthControl() # compute infection: nb_steps_inf = 11 for i in range(nb_steps_inf): print('time step %d' % i) update_climate_all(g) #grow(g) infect(g, dt=1.) lesions = g.property('lesions') if lesions: # compute competition dt = 50 nb_steps = 500 dates = range(0,nb_steps,dt) sum_surface = numpy.array([0. for i in dates]) for i in dates: print('time step %d' % i) update_climate_all(g) #grow(g) update(g,dt, growth_control_model=controler) # control_growth(g, controler) vids = [v for v in g if g.label(v).startswith("LeafElement")] count_surf = 0. for v in vids: leaf = g.node(v) count_surf += leaf.healthy_surface # if 'lesions' in leaf.properties(): # count_surf += sum([l.surface for l in leaf.lesions]) # print('leaf element %d - ' % v + 'Healthy surface : %f' % leaf.healthy_surface) index = i/dt sum_surface[index] = count_surf # Display results: plot(dates, sum_surface) ylabel('Surface saine totale sur le MTG') xlabel('Pas de temps de simulation') show() return g
def test_initiate(): """ Check if 'initiate' from 'protocol.py' deposits dispersal units on the MTG. """ g = adel_mtg2() set_initial_properties_g(g, surface_leaf_element=5.) fungus = septoria() SeptoriaDU.fungus = fungus stock = [SeptoriaDU(nb_spores=random.randint(1,100), status='emitted') for i in range(100)] inoculator = RandomInoculation() initiate(g, stock, inoculator) plot_DU(g) return g
def test_washing(): """ Check if 'washing' from 'protocol.py' washes dispersal units out of the MTG. """ g = adel_mtg() set_initial_properties_g(g, surface_leaf_element=5.) fungus = septoria(); SeptoriaDU.fungus = fungus stock = [SeptoriaDU(nb_spores=random.randint(1,100), status='emitted') for i in range(100)] inoculator = RandomInoculation() initiate(g, stock, inoculator) washor = RapillyWashing() dt = 1 nb_steps = 100 nb_DU = numpy.array([0. for i in range(nb_steps)]) for i in range(nb_steps): # Update climate and force rain occurences if i>2 and i%5 == 0 or (i-1)%5 == 0: global_rain_intensity = 4. else: global_rain_intensity = 0. update_climate_all(g, wetness=True, temp=22., rain_intensity = global_rain_intensity*0.75) # Compute washing # (needs to be done even if no rain to update variables in the washing model) wash(g, washor, global_rain_intensity, DU_status='deposited') # Count of DU : nb_DU[i] = count_DU(g) # Display results if global_rain_intensity != 0. : print('\n') print(' _ _ _') print(' (pluie)') print(' (_ _ _ _)') print(' | |') print(' | | ') print('\n') print('Sur le MTG il y a %d DU actives en tout' % nb_DU[i]) # Display results plot(nb_DU) ylim([0, 120]) ylabel('Nombre de DU sur le MTG') xlabel('Pas de temps de simulation') show() return g
def test_disperse(): """ Check if 'disperse' from 'protocol.py' disperse new dispersal units on the MTG. """ g = adel_mtg2() set_initial_properties_g(g, surface_leaf_element=5.) fungus = septoria(); SeptoriaDU.fungus = fungus stock = [SeptoriaDU(nb_spores=random.randint(1,100), status='emitted') for i in range(10)] inoculator = RandomInoculation() initiate(g, stock, inoculator) controler = NoPriorityGrowthControl() dt = 1 nb_steps = 750 nb_les = numpy.array([0 for i in range(nb_steps)]) for i in range(nb_steps): print('time step %d' % i) # Update climate and force rain occurences if i>400 and i%100 == 0: global_rain_intensity = 4. else: global_rain_intensity = 0. update_climate_all(g, wetness=True, temp=22., rain_intensity = global_rain_intensity*0.75) # grow(g) infect(g, dt) update(g,dt, growth_control_model=controler) # control_growth(g, controler) if global_rain_intensity != 0.: scene = plot3d(g) disperse(g, scene, dispersor(), "Septoria") # Count of lesions : nb_les[i] = count_lesions(g) # Display results plot_lesions(g) # displayer = DisplayLesions() # displayer.print_new_lesions(g) plot(nb_les) ylabel('Nombre de lesions sur le MTG') xlabel('Pas de temps de simulation') show() return g
def test_all(model="SeptoriaExchangingRings"): # Generate a MTG with required properties : g = adel_mtg2() set_initial_properties_g(g, surface_leaf_element=5.) # Deposit first dispersal units on the MTG : fungus = septoria(model=model); SeptoriaDU.fungus = fungus stock = [SeptoriaDU(nb_spores=rd.randint(1,100), status='emitted') for i in range(10)] inoculator = RandomInoculation() initiate(g, stock, inoculator) # Call the models that will be used during the simulation : controler = NoPriorityGrowthControl() washor = RapillyWashing() dispersor = RandomDispersal() position_checker = BiotrophDUProbaModel() # Prepare the simulation loop dt = 1 nb_steps = 750 nb_max_les = 0. nb_les = 0. for i in range(0,nb_steps,dt): # Update climate and force rain occurences if i>400 and i%100 == 0: global_rain_intensity = 4. else: global_rain_intensity = 0. update_climate_all(g, wetness=True, temp=22., rain_intensity = global_rain_intensity*0.75) # grow(g) infect(g, dt, position_checker) update(g,dt, growth_control_model=controler) if global_rain_intensity != 0.: scene = plot3d(g) disperse(g, scene, dispersor, "Septoria") wash(g, washor, global_rain_intensity, DU_status='deposited') # Count how many lesions are simultaneously active on the MTG at maximum charge nb_les = count_lesions(g) if nb_les > nb_max_les: nb_max_les = nb_les print('max number lesions %d' % nb_max_les) return g
def test_infect(model="septoria_exchanging_rings"): """ Check if 'infect' from 'protocol.py' leads to infection by dispersal units on the MTG. Generate a wheat MTG and distribute dispersal units randomly on leaf elements. Run a short loop to compute infection. Check that all the stock of DU caused appearance of a lesion on leaf elements. Parameters ---------- model: model One version of the model of septoria lesion among: 'septoria_exchanging_rings', 'septoria_with_rings', 'septoria_continuous' """ # Generate a wheat MTG g = adel_one_leaf_element() set_properties(g, label='LeafElement', area=5., green_area=5., healthy_area=5., position_senescence=None) # Generate a stock of septoria dispersal units and distribute it on g nb_dus = 100 distribute_dispersal_units(g, nb_dus=nb_dus, disease_model=model, initiation_model=RandomInoculation(), label='LeafElement') # Loop of simulation septo_timing = TimeControl(delay=1, steps=10) timer = TimeControler(disease=septo_timing) for t in timer: # Offer good conditions for at least 10h set_properties(g, label='LeafElement', wetness=True, temp=20.) # Infect infect(g, t['disease'].dt, label='LeafElement') # Check that all the DUs that were in the stock are now lesions on leaf elements lesions = g.property('lesions') nb_lesions_on_leaves = sum(len(l) for l in lesions.itervalues()) assert nb_lesions_on_leaves == nb_dus
def distribute_disease(g, fungal_object='lesion', nb_objects=1, disease_model='powdery_mildew', initiation_model=RandomInoculation(), label="LeafElement"): """ Distribute fungal objects on the MTG. Parameters ---------- g: MTG MTG representing the canopy fungal_object: str Type of fungal object. Choose between : 'dispersal_unit' or 'lesion' nb_objects: int Number of dispersal units or lesions to distribute on the MTG disease_model: model Type of model to compute disease lesion development initiation_model: model Model that sets the position of each DU/lesion in stock on g Requires a method named 'allocate' (see doc) Returns ------- g: MTG Updated MTG with dispersal units or lesions """ # Create a pool of dispersal units (DU) diseases = plugin.discover('alep.disease') disease = diseases[disease_model].load() if fungal_object == 'dispersal_unit': objects = generate_stock_du(nb_dus=nb_objects, disease=disease) elif fungal_object == 'lesion': objects = generate_stock_lesions(nb_lesions=nb_objects, disease=disease) else: raise Exception('fungal object is not valid: choose between ' 'dispersal_unit' ' or ' 'lesion') # Distribute the DU initiate(g, objects, initiation_model, label=label) return g
def test_infect(): """ Check if 'infect' from 'protocol.py' leads to infection by dispersal units on the MTG. """ g = adel_mtg2() set_initial_properties_g(g, surface_leaf_element=5.) fungus = septoria(); SeptoriaDU.fungus = fungus stock = [SeptoriaDU(nb_spores=random.randint(1,100), status='emitted') for i in range(100)] inoculator = RandomInoculation() initiate(g, stock, inoculator) dt = 1 nb_steps = 100 plot_DU(g) for i in range(nb_steps): update_climate_all(g) infect(g, dt) plot_lesions(g) return g
def run_simulation_septoria(): # Initialization ##################################################### # Set the seed of the simulation rd.seed(0) np.random.seed(0) # Choose dates of simulation and initialize the value of date start_date = datetime(2000, 10, 1, 1, 00, 00) end_date = datetime(2001, 07, 01, 00, 00) date = None # Read weather and adapt it to septoria (add wetness) weather = get_septoria_weather(data_file='meteo01.csv') # Initialize a wheat canopy g, wheat, domain_area, domain = initialize_stand(age=0., length=0.1, width=0.2, sowing_density=150, plant_density=150, inter_row=0.12) # Initialize the models for septoria septoria = plugin_septoria() inoculator = RandomInoculation() growth_controler = NoPriorityGrowthControl() infection_controler = BiotrophDUPositionModel() sen_model = WheatSeptoriaPositionedSenescence(g, label='LeafElement') emitter = SeptoriaRainEmission() transporter = Septo3DSplash(reference_surface=domain_area) washor = RapillyWashing() # Define the schedule of calls for each model nb_steps = len(pandas.date_range(start_date, end_date, freq='H')) weather_timing = TimeControl(delay=1, steps=nb_steps) wheat_timing = TimeControl(delay=24, steps=nb_steps, model=wheat, weather=weather, start_date=start_date) septo_timing = TimeControl(delay=1, steps=nb_steps) timer = TimeControler(weather=weather_timing, wheat=wheat_timing, disease=septo_timing) # Call leaf inspectors for target blades (top 3) inspectors = {} # for rank in range(1,3): # inspectors[rank] = LeafInspector(g, blade_id=find_blade_id(g, leaf_rank = rank, only_visible=False)) inspectors[1] = LeafInspector(g, blade_id=96) inspectors[2] = LeafInspector(g, blade_id=88) inspectors[3] = LeafInspector(g, blade_id=80) inspectors[4] = LeafInspector(g, blade_id=72) dates = [] # Simulation ######################################################### for t in timer: # print(timer.numiter) # Update date date = (weather.next_date(t['weather'].dt, date) if date != None else start_date) dates.append(date) print(date) # Get weather for date and add it as properties on leaves _, data = weather.get_weather(t['weather'].dt, date) set_properties(g, label='LeafElement', wetness=data.wetness.values[0], temp=data.temperature_air.values[0], rain_intensity=data.rain.values[0], rain_duration=data.rain_duration.values[0], relative_humidity=data.relative_humidity.values[0], wind_speed=data.wind_speed.values[0]) # Grow wheat canopy grow_canopy(g, wheat, t['wheat']) update_healthy_area(g, label='LeafElement') # Note : The position of senescence goes back to its initial value after # a while for undetermined reason # --> temporary hack for keeping senescence position low when it is over positions = g.property('position_senescence') are_green = g.property('is_green') leaves = get_leaves(g, label='LeafElement') vids = [leaf for leaf in leaves if leaf in g.property('geometry')] positions.update({ vid: (0 if positions[vid] == 1 and not are_green[vid] else positions[vid]) for vid in vids }) # Develop disease if data.dispersal_event.values[ 0] == True and timer.numiter >= 1000 and timer.numiter <= 2000: # Refill pool of initial inoculum to simulate differed availability dispersal_units = generate_stock_du(nb_dus=10, disease=septoria) initiate(g, dispersal_units, inoculator) infect(g, t['disease'].dt, infection_controler, label='LeafElement') update(g, t['disease'].dt, growth_controler, sen_model, label='LeafElement') for inspector in inspectors.itervalues(): inspector.compute_severity(g) inspector.update_disease_area(g) inspector.update_green_area(g) inspector.update_area(g) if data.dispersal_event.values[0] == True: disperse(g, emitter, transporter, "septoria", label='LeafElement') wash(g, washor, data.rain.values[0], label='LeafElement') # if timer.numiter%24 == 0: # update_plot(g) # Tout stocker dans un dataframe avec les dates en index outputs = {} for id, inspector in inspectors.iteritems(): outs = { 'severity': inspectors[id].severity, 'disease_area': inspectors[id].leaf_disease_area, 'green_area': inspectors[id].leaf_green_area, 'total_area': inspectors[id].leaf_area } outputs[id] = pandas.DataFrame(data=outs, index=dates) return outputs
def test_senescence(status='CHLOROTIC', model="septoria_exchanging_rings"): """ Check if 'senescence' from 'protocol.py' compute the effects of senescence on the lesions of the MTG Generate a wheat MTG and distribute 2 DUs with know position on leaf elements. Make them grow into lesions until chosen status, then stop updating them. Set senescence on first lesion. Check that the activity of this lesion is reduced by senescence comparatively to the other lesion, but not the stock of spores. Parameters ---------- status: str: 'CHLOROTIC' or 'SPORULATING' Status of the lesion when touched by senescence. model: model One version of the model of septoria lesion among: 'septoria_exchanging_rings', 'septoria_with_rings', 'septoria_continuous' """ # Generate a wheat MTG g = adel_one_leaf_element() set_properties(g, label='LeafElement', area=5., green_area=5., healthy_area=5., position_senescence=None) # Generate a stock of septoria dispersal units and distribute it on g distribute_lesions(g, nb_lesions=2, disease_model=model, initiation_model=RandomInoculation(), label='LeafElement') # create a flat list of lesions and fix their position lesions = g.property('lesions') les = sum(lesions.values(), []) les[0].position = [0.3, 0] les[1].position = [0.7, 0] # Call a models growth control and senescence controler = NoPriorityGrowthControl() senescence_model = WheatSeptoriaPositionedSenescence(g) # Test if lesion is CHLOROTIC when senescence occur if status == "CHLOROTIC": if model != "septoria_exchanging_rings": dt = 300 set_properties(g, label='LeafElement', wetness=True, temp=22., rain_intensity=0.) # Simulation to obtain a lesion in chosen status update(g, dt=dt, growth_control_model=controler, senescence_model=senescence_model) else: dt = 1 nb_steps = 300 for i in range(0, nb_steps, dt): # Simulation to obtain a lesion in chosen status set_properties(g, label='LeafElement', wetness=True, temp=22., rain_intensity=0.) update(g, dt=dt, growth_control_model=controler, senescence_model=senescence_model) # 1. Compare lesions before senescence # Compute variables of interest l = g.property('lesions') l = sum(l.values(), []) lesion1 = l[0] lesion1.compute_all_surfaces() lesion2 = l[1] lesion2.compute_all_surfaces() # Compare the two lesions assert lesion1.status == lesion2.status == 1 assert lesion1.surface_alive == lesion2.surface_alive assert lesion1.surface_dead == lesion2.surface_dead == 0. # 2. Set senescence, update lesion so they know they # are on a senescent tissue and compare lesions set_properties(g, label='LeafElement', position_senescence=0.6) update(g, dt=0., growth_control_model=controler, senescence_model=senescence_model) # Compute variables of interest l = g.property('lesions') l = sum(l.values(), []) lesion1 = l[0] lesion1.compute_all_surfaces() lesion2 = l[1] lesion2.compute_all_surfaces() # Compare the two lesions assert lesion2.growth_is_active == False assert lesion2.is_active == False assert lesion1.surface_alive > lesion2.surface_alive assert lesion2.surface_alive == 0. assert lesion1.surface_dead == 0. assert lesion2.surface_dead > 0. assert lesion2.surface == lesion2.surface_dead # Test if lesion is SPORULATING when senescence occur elif status == "SPORULATING": if model != "septoria_exchanging_rings": dt = 400 set_properties(g, label='LeafElement', wetness=True, temp=22., rain_intensity=0.) # Simulation to obtain a lesion in chosen status update(g, dt=dt, growth_control_model=controler, senescence_model=senescence_model) else: dt = 1 nb_steps = 400 for i in range(0, nb_steps, dt): # Simulation to obtain a lesion in chosen status set_properties(g, label='LeafElement', wetness=True, temp=22., rain_intensity=0.) update(g, dt=dt, growth_control_model=controler, senescence_model=senescence_model) # 1. Compare lesions before senescence # Compute variables of interest l = g.property('lesions') l = sum(l.values(), []) lesion1 = l[0] lesion1.compute_all_surfaces() lesion2 = l[1] lesion2.compute_all_surfaces() # Compare the two lesions assert lesion1.status == lesion2.status == 3 assert lesion1.surface_alive == lesion2.surface_alive assert lesion1.surface_dead == lesion2.surface_dead == 0. assert lesion1.stock_spores == lesion2.stock_spores > 0. # 2. Set senescence, update lesion so they know they # are on a senescent tissue and compare lesions set_properties(g, label='LeafElement', position_senescence=0.6) update(g, dt=0., growth_control_model=controler, senescence_model=senescence_model) # Compute variables of interest l = g.property('lesions') l = sum(l.values(), []) lesion1 = l[0] lesion1.compute_all_surfaces() lesion2 = l[1] lesion2.compute_all_surfaces() # Compare the two lesions assert lesion2.growth_is_active == False assert lesion2.is_active == True assert lesion1.surface_alive > lesion2.surface_alive assert lesion2.surface_alive > 0. assert lesion1.surface_dead == 0. assert lesion2.surface_dead > 0. assert lesion2.surface > lesion2.surface_dead assert lesion1.stock_spores == lesion2.stock_spores > 0. # if __name__ == '__main__': # g=test_growth_control()
def test_disperse(model="septoria_exchanging_rings"): """ Check if 'disperse' from 'protocol.py' disperse new dispersal units on the MTG. Generate a wheat MTG and distribute lesions randomly on leaf elements. Run a loop to compute infection and update. Create artificial rains in the loop on a regular basis. Check that the number of lesions on the MTG increases. Parameters ---------- model: model One version of the model of septoria lesion among: 'septoria_exchanging_rings', 'septoria_with_rings', 'septoria_continuous' """ # Generate a wheat MTG g = adel_one_leaf() set_properties(g, label='LeafElement', area=5., green_area=5., healthy_area=5., position_senescence=None) # Generate a stock of septoria dispersal units and distribute it on g distribute_lesions(g, nb_lesions=1, disease_model=model, initiation_model=RandomInoculation(), label='LeafElement') # Call models of growth control and dispersal controler = NoPriorityGrowthControl() emitter = SeptoriaRainEmission() transporter = Septo3DSplash() # Loop of simulation septo_timing = TimeControl(delay=1, steps=1000) timer = TimeControler(disease=septo_timing) for t in timer: # Update climate and force rain occurences if timer.numiter > 400 and timer.numiter % 100 == 0: rain_intensity = 3. else: rain_intensity = 0. set_properties(g, label='LeafElement', wetness=True, temp=22., relative_humidity=85., rain_intensity=rain_intensity) # Update update(g, t['disease'].dt, controler, senescence_model=None, label='LeafElement') # Force rain occurences if rain_intensity != 0: # Count objects on the MTG before dispersal event lesions = g.property('lesions') dispersal_units = g.property('dispersal_units') total_stock_spores_before = sum(l.stock_spores for les in lesions.values() for l in les) total_DUs_before = sum( len(du) for du in dispersal_units.itervalues()) # Dispersal event disperse(g, dispersor, "septoria", label='LeafElement') # Check that stocks of spores on lesions decrease if total_stock_spores_before != 0.: total_stock_spores_after = sum(l.stock_spores for les in lesions.values() for l in les) # print(total_stock_spores_after) assert total_stock_spores_after < total_stock_spores_before # Check that new DUs are deposited on the MTG total_DUs_after = sum( len(du) for du in dispersal_units.itervalues()) if total_DUs_after != 0: assert total_DUs_after >= total_DUs_before
def inoculator(): """ Instantiate the class RandomInoculation(). """ inoculator = RandomInoculation() return inoculator
def test_growth_control(model="septoria_exchanging_rings"): """ Check if 'control_growth' from 'protocol.py' limits the lesion growth up to available surface on the leaf. Generate a wheat MTG and deposit sumultaneously 1000 lesions on a leaf element. Run a loop to compute update and growth. Check that the healthy surface of the leaf decreases up to 0. Check that lesion growth is stopped after this point. Parameters ---------- model: model One version of the model of septoria lesion among: 'septoria_exchanging_rings', 'septoria_with_rings', 'septoria_continuous' """ # Generate a wheat MTG g = adel_one_leaf() initial_leaf_area = 5. set_properties(g, label='LeafElement', area=initial_leaf_area, green_area=initial_leaf_area, healthy_area=initial_leaf_area, position_senescence=None) labels = g.property('label') total_initial_area = sum( g.node(vid).area for vid in labels.iterkeys() if labels[vid].startswith('LeafElement')) # Generate a stock of septoria dispersal units and distribute it on g distribute_lesions(g, nb_lesions=1000, disease_model=model, initiation_model=RandomInoculation(), label='LeafElement') # Call model of growth control controler = NoPriorityGrowthControl() # Initiation of healthy area the day before healthy_area_before = [] # Loop of simulation septo_timing = TimeControl(delay=1, steps=100) timer = TimeControler(disease=septo_timing) for t in timer: # print(timer.numiter) # After infection, the lesion 'age_dday' will be added 1 DD by time step # Note : base temperature for septoria = -2 degrees celsius set_properties(g, label='LeafElement', wetness=True, temp=22., rain_intensity=0.) # Update update(g, t['disease'].dt, controler, senescence_model=None, label='LeafElement') update_healthy_area(g, label='LeafElement') # Find the value of interest on the MTG (total healthy area of the leaf) lesions = g.property('lesions') healthy_areas = g.property('healthy_area') bids = (v for v, l in labels.iteritems() if l.startswith('blade')) for blade in bids: leaf = [ vid for vid in g.components(blade) if labels[vid].startswith('LeafElement') ] leaf_healthy_area = sum(healthy_areas[lf] for lf in leaf) print(leaf_healthy_area) # Check that healthy area + lesion surface = initial healthy surface if lesions: leaf_lesion_area = sum(l.surface for les in lesions.itervalues() for l in les) assert round(leaf_healthy_area, 6) + round( leaf_lesion_area, 6) == round(total_initial_area, 6) # Check that healthy area decreases after emergence of the first lesion if lesions and not healthy_area_before: # Emergence of the first lesion healthy_area_before.append(leaf_healthy_area) elif lesions and healthy_area_before[0] > 0.: # Check that healthy area decreases assert leaf_healthy_area < healthy_area_before # Update of 'healthy_area_before' for next step healthy_area_before[0] = leaf_healthy_area elif lesions and healthy_area_before[0] == 0.: # Check that healthy area stays null assert leaf_healthy_area == 0. # Update of 'healthy_surface_before' for next step healthy_area_before[0] = leaf_healthy_area
def run_simulation(): # Initialization ##################################################### # Set the seed of the simulation rd.seed(0) np.random.seed(0) # Read weather and adapt it to septoria (add wetness) meteo_path = shared_data(alinea.septo3d, 'meteo98-99.txt') weather = Weather(data_file=meteo_path) weather.check(varnames=['wetness'], models={'wetness': wetness_rapilly}) seq = pandas.date_range(start="1998-10-01 01:00:00", end="1999-07-01 01:00:00", freq='H') # Initialize a wheat canopy g, wheat, domain_area, domain = initialize_stand(age=0., length=0.1, width=0.2, sowing_density=150, plant_density=150, inter_row=0.12, seed=8) # Initialize the models for septoria # septoria = new_septoria(senescence_treshold=senescence_treshold) septoria = plugin_septoria() inoculator = RandomInoculation() growth_controler = NoPriorityGrowthControl() infection_controler = BiotrophDUPositionModel() sen_model = WheatSeptoriaPositionedSenescence(g, label='LeafElement') emitter = SeptoriaRainEmission(domain_area=domain_area) transporter = Septo3DSplash(reference_surface=domain_area) washor = RapillyWashing() # Define the schedule of calls for each model every_h = time_filter(seq, delay=1) every_24h = time_filter(seq, delay=24) every_rain = rain_filter(seq, weather) weather_timing = IterWithDelays(*time_control(seq, every_h, weather.data)) wheat_timing = IterWithDelays(*time_control(seq, every_24h, weather.data)) septo_timing = IterWithDelays(*time_control(seq, every_h, weather.data)) rain_timing = IterWithDelays(*time_control(seq, every_rain, weather.data)) # Call leaf inspectors for target blades (top 3) inspectors = {} # for rank in range(1,3): # inspectors[rank] = LeafInspector(g, blade_id=find_blade_id(g, leaf_rank = rank, only_visible=False)) inspectors[1] = LeafInspector(g, blade_id=96) # inspectors[2] = LeafInspector(g, blade_id=88) # inspectors[3] = LeafInspector(g, blade_id=80) dates = [] # Simulation ######################################################### for i, controls in enumerate( zip(weather_timing, wheat_timing, septo_timing, rain_timing)): weather_eval, wheat_eval, septo_eval, rain_eval = controls # Update date date = weather_eval.value.index[0] dates.append(date) # Get weather for date and add it as properties on leaves if weather_eval: set_properties( g, label='LeafElement', temp=weather_eval.value.temperature_air[0], wetness=weather_eval.value.wetness[0], relative_humidity=weather_eval.value.relative_humidity[0], wind_speed=weather_eval.value.wind_speed[0]) if rain_eval: set_properties(g, label='LeafElement', rain_intensity=rain_eval.value.rain.mean(), rain_duration=len(rain_eval.value.rain) if rain_eval.value.rain.sum() > 0 else 0.) # Grow wheat canopy if wheat_eval: print(date) g, _ = grow_canopy(g, wheat, wheat_eval.value) # Note : The position of senescence goes back to its initial value after # a while for undetermined reason # --> temporary hack for keeping senescence position low when it is over positions = g.property('position_senescence') are_green = g.property('is_green') areas = g.property('area') senesced_areas = g.property('senesced_area') leaves = get_leaves(g, label='LeafElement') vids = [leaf for leaf in leaves if leaf in g.property('geometry')] positions.update({ vid: (0 if (positions[vid] == 1 and not are_green[vid]) or (positions[vid] > 0 and round(areas[vid], 5) == round( senesced_areas[vid], 5)) else positions[vid]) for vid in vids }) # Develop disease if septo_eval: sen_model.find_senescent_lesions(g, label='LeafElement') update_healthy_area(g, label='LeafElement') if rain_eval and i <= 500: # Refill pool of initial inoculum to simulate differed availability dispersal_units = generate_stock_du(nb_dus=rd.randint(0, 5), disease=septoria) initiate(g, dispersal_units, inoculator) infect(g, septo_eval.dt, infection_controler, label='LeafElement') update(g, septo_eval.dt, growth_controler, sen_model, label='LeafElement') if rain_eval: if rain_eval.value.rain.mean() > 0: g, nb = disperse(g, emitter, transporter, "septoria", label='LeafElement') for inspector in inspectors.itervalues(): inspector.update_du_variables(g) wash(g, washor, rain_eval.value.rain.mean(), label='LeafElement') # Save outputs after washing infection_controler.control_position(g) for inspector in inspectors.itervalues(): inspector.update_du_variables(g) inspector.update_green_area(g) inspector.update_healthy_area(g) else: for inspector in inspectors.itervalues(): inspector.nb_dus += [0, 0] inspector.nb_dus_on_green += [0, 0] inspector.nb_dus_on_healthy += [0, 0] inspector.update_green_area(g) inspector.update_healthy_area(g) else: for inspector in inspectors.itervalues(): inspector.nb_dus += [0, 0] inspector.nb_dus_on_green += [0, 0] inspector.nb_dus_on_healthy += [0, 0] inspector.update_green_area(g) inspector.update_healthy_area(g) for inspector in inspectors.itervalues(): inspector.compute_nb_infections(g) if wheat_eval: update_plot(g) # scene = plot3d(g) # index = i/24 # if index < 10 : # image_name='./images_septo2/image0000%d.png' % index # elif index < 100 : # image_name='./images_septo2/image000%d.png' % index # elif index < 1000 : # image_name='./images_septo2/image00%d.png' % index # elif index < 10000 : # image_name='./images_septo2/image0%d.png' % index # else : # image_name='./images_septo/image%d.png' % index # save_image(scene, image_name=image_name) # Tout stocker dans un dataframe avec les dates en index outs = { 'nb_dus': inspectors[1].nb_dus[::2], 'nb_unwashed_dus': inspectors[1].nb_dus[1::2], 'nb_dus_on_healthy': inspectors[1].nb_dus_on_healthy[1::2], 'nb_infections': inspectors[1].nb_infections, 'green_area': inspectors[1].leaf_green_area, 'healthy_area': inspectors[1].leaf_healthy_area } outputs = pandas.DataFrame(data=outs, index=dates) return outputs
def test_update(model="septoria_exchanging_rings"): """ Check if 'update' from 'protocol.py' provokes the growth of a lesion instantiated on the MTG. Generate a wheat MTG and deposit 1 lesion on a leaf element. Run a loop to compute update and growth. Check that all the stages of a lesion of septoria have been reached eventually. Check that the lesion size does not exceed Smax. Parameters ---------- model: model One version of the model of septoria lesion among: 'septoria_exchanging_rings', 'septoria_with_rings', 'septoria_continuous' """ # Generate a wheat MTG g = adel_one_leaf_element() set_properties(g, label='LeafElement', area=5., green_area=5., healthy_area=5., position_senescence=None) # Generate a stock of septoria dispersal units and distribute it on g distribute_lesions(g, nb_lesions=1, disease_model=model, initiation_model=RandomInoculation(), label='LeafElement') # Call model of growth control controler = NoPriorityGrowthControl() # Loop of simulation septo_timing = TimeControl(delay=1, steps=1000) timer = TimeControler(disease=septo_timing) for t in timer: # print(timer.numiter) # After infection, the lesion 'age_dday' will be added 1 DD by time step # Note : base temperature for septoria = -2 degrees celsius set_properties(g, label='LeafElement', wetness=True, temp=22., rain_intensity=0.) # Update update(g, t['disease'].dt, controler, senescence_model=None, label='LeafElement') # Check that the lesion is in the right status and has the right surface lesion = g.property('lesions') if lesion: assert sum(len(l) for l in lesion.itervalues()) == 1 l = lesion.values()[0][0] assert l.age_dday == timer.numiter f = l.fungus print('lesion surface: %f' % round(l.surface, 6)) if l.age_dday < 220.: assert l.status == 0 assert round(l.surface, 6) < round(f.Smin, 6) if 220. <= l.age_dday < 330.: assert l.status == 1 assert round(f.Smin, 6) <= round(l.surface, 6) assert round(l.surface, 6) < round( f.Smin + f.growth_rate * f.degree_days_to_necrosis, 6) elif 330. <= l.age_dday < 350.: assert l.status == 2 assert round( f.Smin + f.growth_rate * f.degree_days_to_necrosis, 6) <= round(l.surface, 6) assert round(l.surface, 6) < round( f.Smin + f.growth_rate * (f.degree_days_to_necrosis + f.degree_days_to_sporulation), 6) elif l.age_dday >= 350.: assert l.status == 3 assert round( f.Smin + f.growth_rate * f.degree_days_to_sporulation, 6) <= round(l.surface, 6) assert round(l.surface, 6) <= round(l.fungus.Smax, 6)
# Initialize a wheat canopy g, wheat, domain_area, domain = initialize_stand(age=0., length=1, width=1, sowing_density=250, plant_density=250, inter_row=0.12, seed=3) # Choose source leaf in canopy # (Here the value of the leaf is known but it changes with another initialize_stand) source_leaf = g.node(21943) # Initialize the models for septoria septoria = plugin_septoria() inoculator = RandomInoculation() growth_controler = NoPriorityGrowthControl() infection_controler = BiotrophDUPositionModel() sen_model = WheatSeptoriaPositionedSenescence(g, label='LeafElement') emitter = SeptoriaRainEmission(domain_area=domain_area) transporter = SeptoriaRainDispersal() washor = RapillyWashing() # Define the schedule of calls for each model every_h = time_filter(seq, delay=1) every_24h = time_filter(seq, delay=24) every_rain = rain_filter(seq, weather) weather_timing = IterWithDelays(*time_control(seq, every_h, weather.data)) wheat_timing = IterWithDelays(*time_control(seq, every_24h, weather.data)) septo_timing = IterWithDelays(*time_control(seq, every_h, weather.data)) rain_timing = IterWithDelays(*time_control(seq, every_rain, weather.data))
def run_simulation(start_year, variability=True, **kwds): # Set the seed of the simulation rd.seed(0) np.random.seed(0) # Read weather and adapt it to septoria (add wetness) weather_file = 'meteo' + str(start_year)[-2:] + '-' + str(start_year + 1)[-2:] + '.txt' meteo_path = shared_data(alinea.septo3d, weather_file) weather = Weather(data_file=meteo_path) weather.check(varnames=['wetness'], models={'wetness': wetness_rapilly}) seq = pandas.date_range(start=str(start_year) + "-10-01 01:00:00", end=str(start_year + 1) + "-07-01 01:00:00", freq='H') # Initialize a wheat canopy g, wheat, domain_area, domain = initialize_stand(age=0., length=0.1, width=0.2, sowing_density=150, plant_density=150, inter_row=0.12, seed=3) # Initialize the models for septoria if 'alinea.alep.septoria_age_physio' in sys.modules: del (sys.modules['alinea.alep.septoria_age_physio']) if variability == True: septoria = variable_septoria(**kwds) else: septoria = plugin_septoria(model="septoria_age_physio") DU = septoria.dispersal_unit() inoculator = RandomInoculation() growth_controler = NoPriorityGrowthControl() infection_controler = BiotrophDUPositionModel() sen_model = WheatSeptoriaPositionedSenescence(g, label='LeafElement') emitter = SeptoriaRainEmission(domain_area=domain_area) transporter = Septo3DSplash(reference_surface=domain_area) washor = RapillyWashing() # Define the schedule of calls for each model every_h = time_filter(seq, delay=1) every_24h = time_filter(seq, delay=24) every_rain = rain_filter(seq, weather) weather_timing = IterWithDelays(*time_control(seq, every_h, weather.data)) wheat_timing = IterWithDelays(*time_control(seq, every_24h, weather.data)) septo_timing = IterWithDelays(*time_control(seq, every_h, weather.data)) rain_timing = IterWithDelays(*time_control(seq, every_rain, weather.data)) # Call leaf inspectors for target blades (top 3) inspectors = {} first_blade = 80 ind = 4. for blade in range(first_blade, 104, 8): ind -= 1 inspectors[ind] = LeafInspector(g, blade_id=blade) # Simulation loop for i, controls in enumerate( zip(weather_timing, wheat_timing, septo_timing, rain_timing)): weather_eval, wheat_eval, septo_eval, rain_eval = controls # Update date date = weather_eval.value.index[0] # Get weather for date and add it as properties on leaves if weather_eval: set_properties( g, label='LeafElement', temp=weather_eval.value.temperature_air[0], wetness=weather_eval.value.wetness[0], relative_humidity=weather_eval.value.relative_humidity[0], wind_speed=weather_eval.value.wind_speed[0]) if rain_eval: set_properties(g, label='LeafElement', rain_intensity=rain_eval.value.rain.mean(), rain_duration=len(rain_eval.value.rain) if rain_eval.value.rain.sum() > 0 else 0.) # Grow wheat canopy if wheat_eval: print(date) g, _ = grow_canopy(g, wheat, wheat_eval.value) # Note : The position of senescence goes back to its initial value after # a while for undetermined reason # --> temporary hack for keeping senescence position low when it is over positions = g.property('position_senescence') are_green = g.property('is_green') leaves = get_leaves(g, label='LeafElement') positions.update({ leaf: (0 if positions[leaf] == 1 and not are_green[leaf] else positions[leaf]) for leaf in leaves }) # Develop disease if septo_eval: sen_model.find_senescent_lesions(g, label='LeafElement') update_healthy_area(g, label='LeafElement') if rain_eval and i <= 500: # Refill pool of initial inoculum to simulate differed availability if rd.random() < 0.4: dispersal_units = [ DU(nb_spores=rd.randint(1, 100), status='emitted') for i in range(rd.randint(0, 3)) ] initiate(g, dispersal_units, inoculator) infect(g, septo_eval.dt, infection_controler, label='LeafElement') update(g, septo_eval.dt, growth_controler, sen_model, label='LeafElement') les = g.property('lesions') lesions = sum([l for l in les.values()], []) print([l.fungus.degree_days_to_chlorosis for l in lesions]) # if len(lesions)>10: # import pdb # pdb.set_trace() if rain_eval: g, nb = disperse(g, emitter, transporter, "septoria", label='LeafElement') wash(g, washor, rain_eval.value.rain.mean(), label='LeafElement') # Save outputs for inspector in inspectors.itervalues(): inspector.update_variables(g) inspector.update_du_variables(g) if wheat_eval: plot_severity_by_leaf(g) return inspectors