def get_source_leaf_and_max_height(g, position='center', relative_height=2. / 3): tesselator = pgl.Tesselator() bbc = pgl.BBoxComputer(tesselator) leaves = get_leaves(g, label='LeafElement') centroids = g.property('centroid') geometries = g.property('geometry') targets = list(leaf for leaf in leaves if leaf in geometries.iterkeys()) for vid in targets: if is_iterable(geometries[vid]): bbc.process(pgl.Scene(geometries[vid])) else: bbc.process(pgl.Scene([pgl.Shape(geometries[vid])])) center = bbc.result.getCenter() centroids[vid] = center zmax = max(centroids.items(), key=lambda x: x[1][2])[1][2] distances = { vid: pgl.norm(centroids[vid] - (0, 0, relative_height * zmax)) for vid in centroids } if position == 'center': return min(distances.items(), key=lambda x: x[1])[0], zmax elif position == 'border': return max(distances.items(), key=lambda x: x[1])[0], zmax
def test_infection_impossible_on_senescence(): g = get_small_g() set_properties(g, label='LeafElement', senesced_length=1.) leaves = get_leaves(g) # Individual dispersal unit leaf1 = leaves[0] leaf = g.node(leaf1) brown_rust = BrownRustFungus() du1 = brown_rust.dispersal_unit(mutable=True, group_dus=False) du1.set_position([np.random.random(), np.random.random()]) leaf.dispersal_units = [du1] assert du1.is_active du1.disable() assert du1.is_active == False # Cohort leaf2 = leaves[1] leaf = g.node(leaf2) du2 = brown_rust.dispersal_unit(mutable=True, group_dus=True) du2.set_position([[np.random.random(), np.random.random()] for i in range(20)]) g.node(leaf2).dispersal_units = [du2] assert du2.is_active du2.disable() assert du2.is_active == False
def update_plot(g): from alinea.alep.architecture import set_property_on_each_id from alinea.alep.disease_outputs import compute_severity_by_leaf from alinea.adel.mtg_interpreter import plot3d from openalea.plantgl.all import Viewer # Compute severity by leaf severity_by_leaf = compute_severity_by_leaf(g, label='LeafElement') set_property_on_each_id(g, 'severity', severity_by_leaf, label='LeafElement') # Visualization g = alep_colormap(g, 'severity', cmap=green_yellow_red(levels=100), lognorm=False, zero_to_one=False, vmax=100) leaves = get_leaves(g, label='LeafElement') pos_sen = g.property('position_senescence') for leaf in leaves: if pos_sen[leaf] == 0.: g.node(leaf).color = (157, 72, 7) scene = plot3d(g) Viewer.display(scene) return scene
def update_plot(g): # Compute severity by leaf severity_by_leaf = compute_severity_by_leaf(g, label='LeafElement') set_property_on_each_id(g, 'severity', severity_by_leaf, label='LeafElement') # Visualization g = alep_colormap(g, 'severity', cmap=green_yellow_red(levels=100), lognorm=False, zero_to_one=False, vmax=100) leaves = get_leaves(g, label='LeafElement') pos_sen = g.property('position_senescence') for leaf in leaves: if pos_sen[leaf] == 0.: g.node(leaf).color = (157, 72, 7) scene = plot3d(g) Viewer.display(scene) return scene
def allocate(self, g, inoculum, label='LeafElement'): """ Select lower elements of the MTG and allocate them a random part of the inoculum. Parameters ---------- g: MTG MTG representing the canopy (and the soil) inoculum: list of dispersal units OR list of lesions Source of fungal objects to distribute on the MTG label: str Label of the part of the MTG concerned by the calculation Returns ------- None Update directly the MTG """ from alinea.alep.architecture import get_leaves leaves = get_leaves(g, label='LeafElement') geometries = g.property('geometry') vids = list( leaf for leaf in leaves if leaf in geometries.iterkeys() and self.get_leaf_height(geometries[leaf]) <= self.max_height) n = len(vids) if n > 0: for i in inoculum: idx = random.randint(0, n - 1) v = vids[idx] leaf = g.node(v) # Set a position for i : i.position = [0, 0] # TODO : improve # Attach it to the leaf if isinstance(i, Lesion): try: leaf.lesions.append(i) except: leaf.lesions = [i] elif isinstance(i, DispersalUnit): #i.deposited() try: leaf.dispersal_units.append(i) except: leaf.dispersal_units = [i]
def get_source_leaf(g, position_source=2./3): tesselator = pgl.Tesselator() bbc = pgl.BBoxComputer(tesselator) leaves = get_leaves(g, label='LeafElement') centroids = g.property('centroid') geometries = g.property('geometry') targets = list(leaf for leaf in leaves if leaf in geometries.iterkeys()) for vid in targets: if isinstance(geometries[vid], collections.Iterable): bbc.process(pgl.Scene(geometries[vid])) else: bbc.process(pgl.Scene([pgl.Shape(geometries[vid])])) center = bbc.result.getCenter() centroids[vid] = center zmax = max(centroids.items(), key=lambda x:x[1][2])[1][2] distances = {vid:pgl.norm(centroids[vid]-(0,0,position_source*zmax)) for vid in centroids} return min(distances.items(), key=lambda x:x[1])[0]
def update_plot(g): # Compute severity by leaf severity_by_leaf = compute_severity_by_leaf(g, label = 'LeafElement') set_property_on_each_id(g, 'severity', severity_by_leaf, label = 'LeafElement') # Visualization g = alep_colormap(g, 'severity', cmap=green_yellow_red(levels=100), lognorm=False, zero_to_one=False, vmax=100) leaves = get_leaves(g, label='LeafElement') pos_sen = g.property('position_senescence') for leaf in leaves: if pos_sen[leaf]==0.: g.node(leaf).color = (157, 72, 7) scene = plot3d(g) Viewer.display(scene) return scene
def leaves_in_grid(self, g, label='LeafElement'): geometries = g.property('geometry') centroids = g.property('centroid') tesselator = pgl.Tesselator() bbc = pgl.BBoxComputer(tesselator) leaves = get_leaves(g, label=label) leaves = [l for l in leaves if l in geometries] # Get centroids def centroid(vid): if is_iterable(geometries[vid]): bbc.process(pgl.Scene(geometries[vid])) else: bbc.process(pgl.Scene([pgl.Shape(geometries[vid])])) center = bbc.result.getCenter() centroids[vid] = center if len(leaves) > 0: for vid in leaves: centroid(vid) # Define grid (horizontal layers) zs = [c[2] for c in centroids.itervalues()] minz = min(zs) maxz = max(zs) + self.layer_thickness layers = { l: [] for l in np.arange(minz, maxz, self.layer_thickness) } # Distribute leaves in layers for vid, coords in centroids.iteritems(): z = coords[2] ls = layers.keys() i_layer = np.where( map( lambda x: x <= z < x + self.layer_thickness if z != maxz - self.layer_thickness else x <= z <= x + self.layer_thickness, ls))[0] if len(i_layer) > 0.: layers[ls[i_layer]].append(vid) self.layers = layers else: self.layers = {}
def view_distri_layers(self, g, density_dispersal_units=1000., vmax=None): from alinea.alep.architecture import set_property_on_each_id from alinea.alep.alep_color import alep_colormap, green_yellow_red from alinea.alep.disease_outputs import plot3d_transparency from openalea.plantgl.all import Viewer import matplotlib.pyplot as plt # Compute severity by leaf nb_dus = density_dispersal_units * self.domain_area deposits = { k: sum([du.nb_dispersal_units for du in v]) for k, v in self.contaminate(g, nb_dus).iteritems() } set_property_on_each_id(g, 'nb_dispersal_units', deposits) # Visualization if vmax is None: vmax = 2 * max(deposits.values()) / 3 g = alep_colormap(g, 'nb_dispersal_units', cmap=green_yellow_red(), lognorm=False, zero_to_one=False) d = [np.arange(vmax)] fig, ax = plt.subplots() ax.imshow(d, cmap=green_yellow_red()) geometries = g.property('geometry') leaves = get_leaves(g, label='LeafElement') leaves = [l for l in leaves if l in geometries] transp = {vid: 0. for k, v in self.layers.iteritems() for vid in v} set_property_on_each_id(g, 'transparency', transp) for id in g: if not id in deposits: g.node(id).color = (1, 1, 1) g.node(id).transparency = 0.7 elif deposits[id] == 0.: g.node(id).color = (1, 1, 1) g.node(id).transparency = 0.7 else: g.node(id).transparency = 0. scene = plot3d_transparency(g) Viewer.display(scene)
def get_source_leaf_and_max_height(g, position='center', relative_height=2./3): tesselator = pgl.Tesselator() bbc = pgl.BBoxComputer(tesselator) leaves = get_leaves(g, label='LeafElement') centroids = g.property('centroid') geometries = g.property('geometry') targets = list(leaf for leaf in leaves if leaf in geometries.iterkeys()) for vid in targets: if is_iterable(geometries[vid]): bbc.process(pgl.Scene(geometries[vid])) else: bbc.process(pgl.Scene([pgl.Shape(geometries[vid])])) center = bbc.result.getCenter() centroids[vid] = center zmax = max(centroids.items(), key=lambda x:x[1][2])[1][2] distances = {vid:pgl.norm(centroids[vid]-(0,0,relative_height*zmax)) for vid in centroids} if position=='center': return min(distances.items(), key=lambda x:x[1])[0], zmax elif position=='border': return max(distances.items(), key=lambda x:x[1])[0], zmax
def leaves_in_grid(self, g, label = 'LeafElement'): geometries = g.property('geometry') centroids = g.property('centroid') areas = g.property('area') tesselator = pgl.Tesselator() bbc = pgl.BBoxComputer(tesselator) leaves = get_leaves(g, label=label) leaves = [l for l in leaves if l in geometries] # Get centroids def centroid(vid): if is_iterable(geometries[vid]): bbc.process(pgl.Scene(geometries[vid])) else: bbc.process(pgl.Scene([pgl.Shape(geometries[vid])])) center = bbc.result.getCenter() centroids[vid] = center if len(leaves)>0: for vid in leaves: centroid(vid) # Define grid (horizontal layers) zs = [c[2] for c in centroids.itervalues()] minz = min(zs) maxz = max(zs) + self.layer_thickness layers = {l:[] for l in np.arange(minz, maxz, self.layer_thickness)} # Distribute leaves in layers for vid, coords in centroids.iteritems(): z = coords[2] ls = layers.keys() i_layer = np.where(map(lambda x: x<=z<x+self.layer_thickness if z!=maxz - self.layer_thickness else x<=z<=x+self.layer_thickness , ls))[0] if len(i_layer) > 0. and areas[vid]>1e-10: layers[ls[i_layer]].append(vid) self.layers = layers else: self.layers = {}
def plot_layers(self, g): from alinea.alep.architecture import set_property_on_each_id from alinea.alep.alep_color import alep_colormap from alinea.alep.disease_outputs import plot3d_transparency from openalea.plantgl.all import Viewer # Compute severity by leaf self.leaves_in_grid(g) layers = self.layers layer_by_leaf = {vid:k for k,v in layers.iteritems() for vid in v} set_property_on_each_id(g, 'height', layer_by_leaf) # Visualization g = alep_colormap(g, 'height', cmap='prism', lognorm=False, zero_to_one=False) geometries = g.property('geometry') leaves = get_leaves(g, label='LeafElement') leaves = [l for l in leaves if l in geometries] transp = {vid:0. for k,v in layers.iteritems() for vid in v} set_property_on_each_id(g, 'transparency', transp) scene = plot3d_transparency(g) Viewer.display(scene)
def update_plot(g): from alinea.alep.architecture import set_property_on_each_id from alinea.alep.disease_outputs import compute_severity_by_leaf from alinea.adel.mtg_interpreter import plot3d from openalea.plantgl.all import Viewer # Compute severity by leaf severity_by_leaf = compute_severity_by_leaf(g, label = 'LeafElement') set_property_on_each_id(g, 'severity', severity_by_leaf, label = 'LeafElement') # Visualization g = alep_colormap(g, 'severity', cmap=green_yellow_red(levels=100), lognorm=False, zero_to_one=False, vmax=100) leaves = get_leaves(g, label='LeafElement') pos_sen = g.property('position_senescence') for leaf in leaves: if pos_sen[leaf]==0.: g.node(leaf).color = (157, 72, 7) scene = plot3d(g) Viewer.display(scene) return scene
def test_infection_impossible_on_senescence(): g = get_small_g() set_properties(g, label = 'LeafElement', senesced_length = 1.) leaves = get_leaves(g) # Individual dispersal unit leaf1 = leaves[0] leaf = g.node(leaf1) brown_rust = BrownRustFungus() du1 = brown_rust.dispersal_unit(mutable = True, group_dus = False) du1.set_position([np.random.random(), np.random.random()]) leaf.dispersal_units = [du1] assert du1.is_active du1.disable_if_senescent(leaf) assert du1.is_active == False # Cohort leaf2 = leaves[1] leaf = g.node(leaf2) du2 = brown_rust.dispersal_unit(mutable = True, group_dus = True) du2.set_position([[np.random.random(), np.random.random()] for i in range(20)]) g.node(leaf2).dispersal_units = [du2] assert du2.is_active du2.disable_if_senescent(leaf) assert du2.is_active == False
def get_one_leaf(): g = get_small_g() leaves = get_leaves(g) return g.node(leaves[0])
def get_dispersal_units(self, g, fungus_name="septoria", label='LeafElement', weather_data=None): leaves = get_leaves(g) du = plugin_septoria().dispersal_unit(**self.kwds) du.position=[[10.,0.] for i in range(100)] return {lf:[du] for lf in leaves}
def run_simulation(start_year=1998, **kwds): # Initiation of the simulation ########################################## # 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}) start_date = str(start_year)+"-10-01 01:00:00" weather.check(varnames=['degree_days'], models={'degree_days':basic_degree_days}, start_date=start_date) weather.check(varnames=['septo_degree_days'], models={'septo_degree_days':basic_degree_days}, start_date=start_date, base_temp=-2.) seq = pandas.date_range(start = start_date, end = str(start_year+1)+"-07-01 01:00:00", freq='H') print start_year # seq = pandas.date_range(start = str(start_year)+"-10-01 01:00:00", # end = str(start_year)+"-12-31 01:00:00", # freq='H') # g, wheat, domain_area, domain = initialize_stand(age=1250., length=0.1, width=0.1, # sowing_density=150, plant_density=150, inter_row=0.12, nsect=5, seed=3) # Initialize a wheat canopy nsect=5 g, wheat, domain_area, domain = initialize_stand(age=0., length=0.1, width=0.1, sowing_density=150, plant_density=150, inter_row=0.12, nsect=nsect, seed=3) # Initialize the models for septoria if 'alinea.alep.septoria_age_physio' in sys.modules: del(sys.modules['alinea.alep.septoria_age_physio']) septoria = plugin_septoria() # generator = DU_Generator(septoria, group_dus=True, **kwds) # generator = DU_Generator(septoria, group_dus=True, nb_rings_by_state=1, **kwds) # generator = DU_Generator(septoria, group_dus=False) if 'sporulating_fraction' in kwds: frac = kwds['sporulating_fraction'] del kwds['sporulating_fraction'] else: # See Baccar et al. for parameters # frac = 0.65e-4 frac = 0.01 septoria.parameters(group_dus=True, nb_rings_by_state=1, **kwds) inoc = SoilInoculum(septoria, sporulating_fraction=frac, domain_area=domain_area) contaminator = Septo3DSoilContamination(domain=domain, domain_area=domain_area) growth_controler = PriorityGrowthControl() infection_controler = BiotrophDUPositionModel() # sen_model = WheatSeptoriaPositionedSenescence(g, label='LeafElement') # emitter = SeptoriaRainEmission(domain_area=domain_area) # transporter = Septo3DSplash() emitter = PopDropsEmission(domain=domain) transporter = PopDropsTransport(domain=domain, domain_area=domain_area) # emitter = DummyEmission(group_dus=True, **kwds) # transporter = DummyTransport() # transporter = Septo3DTransport(wash=True) # washor = RapillyWashing() # Temp inoculator = InoculationLowerLeaves() # 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)) # Prepare saving of outputs recorders = {} ind=4 for blade in [116, 128, 140]: ind -= 1 recorders['F%d' % ind] = SeptoRecorder(vids=[blade+2+sect for sect in range(nsect)],group_dus=True) recorders['rosette'] = SeptoRecorder(vids=[8+2+sect for sect in range(nsect)],group_dus=True) # Simulation ############################################################ for i, controls in enumerate(zip(weather_timing, wheat_timing, septo_timing, rain_timing)): weather_eval, wheat_eval, septo_eval, rain_eval = controls date = weather_eval.value.index[0] # if wheat_eval: # print date # dates.append(date) # Get weather for date and add it as properties on leaves if weather_eval: set_properties(g,label = 'LeafElement', temperature_sequence = weather_eval.value.temperature_air, 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: 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') greens = 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 greens[vid]) or (positions[vid]>0 and round(areas[vid],5)==round(senesced_areas[vid],5)) else positions[vid]) for vid in vids}) # Update g for the disease: if septo_eval: #sen_model.find_senescent_lesions(g, label = 'LeafElement') update_healthy_area(g, label = 'LeafElement') # External contamination if rain_eval: if rain_eval.value.rain.mean()>0. and rain_eval.value.degree_days[-1]<1000: g = external_contamination(g, inoc, contaminator, weather_eval.value) # Develop disease if septo_eval: # Update dispersal units and lesions infect(g, septo_eval.dt, infection_controler, label='LeafElement') update(g, septo_eval.dt, growth_controler, senescence_model=None, label='LeafElement') # Disperse and wash if rain_eval: if rain_eval.value.rain.mean()>0.: g = disperse(g, emitter, transporter, "septoria", label='LeafElement', weather_data=weather_eval.value) # wash(g, washor, rain_eval.value.rain.mean(), label='LeafElement') # if wheat_eval: # scene = plot_severity_by_leaf(g) # print 'nb lesions %d' % count_lesions(g) # Save outputs for recorder in recorders.itervalues(): recorder.record(g, date) for recorder in recorders.itervalues(): recorder.get_complete_dataframe() recorder.get_audpc() return g, recorders
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 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
""" Gather different strategies for modeling dispersal of fungus propagules.
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: 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') greens = 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 greens[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: # Update g for the disease sen_model.find_senescent_lesions(g, label = 'LeafElement') update_healthy_area(g, label = 'LeafElement') # Possibly refill pool of initial inoculum to simulate differed availability if rain_eval and i <= 700 and source_leaf.geometry!=None: dus = generate_stock_du(nb_dus=rd.randint(0,5), disease=septoria) try:
def disperse(self, g, dispersal_units, time_control = None): """ Compute dispersal of spores of powdery mildew by wind in a cone. For each source of dispersal units, create a cone of dispersal in which target leaves are sorted: 1. according to the wind direction 2. according to the angle a0 3. according to the distance from the source Then distribute dispersal units from the closer target to the more far. The number of dispersal units by target leaf is computed as in Calonnec et al. 2008. Parameters ---------- g: MTG MTG representing the canopy (and the soil) dispersal_units : dict Dispersal units emitted by the lesions on leaves Returns ------- deposits : dict Dispersal units deposited on new position on leaves """ try: dt = time_control.dt except: dt = 1 deposits = {} if dt > 0: from alinea.alep.architecture import get_leaves from openalea.plantgl import all as pgl from random import shuffle from math import degrees, exp, tan, pi, radians from collections import OrderedDict geometries = g.property('geometry') centroids = g.property('centroid') areas = g.property('area') wind_directions = g.property('wind_direction') tesselator = pgl.Tesselator() bbc = pgl.BBoxComputer(tesselator) leaves = get_leaves(g, label=self.label) def centroid(vid): if is_iterable(geometries[vid]): bbc.process(pgl.Scene(geometries[vid])) else: bbc.process(pgl.Scene([pgl.Shape(geometries[vid])])) center = bbc.result.getCenter() centroids[vid] = center def area(vid): # areas[vid] = pgl.surface(geometries[vid][0])*1000 areas[vid] = pgl.surface(geometries[vid][0]) for source, dus in dispersal_units.iteritems(): # TODO: Special computation for interception by source leaf # All other leaves are potential targets targets = list(leaf for leaf in leaves if leaf in geometries.iterkeys()) targets.remove(source) # Compute centroids centroid(source) for vid in targets: centroid(vid) # surface(vid) # Sort the vids based on the direction Origin = centroids[source] vects = {vid:(centroids[vid]-Origin) for vid in targets if (centroids[vid]-Origin)*wind_directions[source] >= 0} # Sort the vids based on the angle angles = {vid:degrees(pgl.angle(vect, wind_directions[source])) for vid, vect in vects.iteritems() if degrees(pgl.angle(vect, wind_directions[source]))<= self.a0} # Sort the vids based on the distance distances = {vid:pgl.norm(vects[vid]) for vid in angles} distances = OrderedDict(sorted(distances.iteritems(), key=lambda x: x[1])) # Beer law inside cone to take into account leaf coverage shuffle(dus) n = len(dus) if len(distances.values())>0: for leaf in distances: # qc = min(n, (n * (areas[leaf]/self.reduction) * # exp(-self.cid * distances[leaf]) * # (self.a0 - angles[leaf])/self.a0)) surf_base_cone = pi*(tan(radians(self.a0))*distances[leaf])**2 area_factor = min(1, areas[leaf]/surf_base_cone) # import pdb # pdb.set_trace() qc = min(n, (n * area_factor * exp(-self.cid * distances[leaf]) * (self.a0 - angles[leaf])/self.a0)) # if qc < 1: # for d in dus: # d.disable() # break deposits[leaf] = dus[:int(qc)] del dus[:int(qc)] # if len(dus) < 1 or len(deposits[leaf]) < 1: if len(dus) < 1: for d in dus: d.disable() break return deposits
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 get_source_leaf(g): leaves = get_leaves(g) geometries = g.property('geometry') leaves = [lf for lf in leaves if lf in geometries] return g.node(leaves[2])
def disperse(self, g, dispersal_units, time_control = None): """ Compute distribution of dispersal units by rain splash. 1. Upward dispersal: For each source of dispersal units, create a semi-sphere of dispersal normal to the surface of source leaf. In the semi-sphere, target leaves are sorted according to the distance from the source. Then distribute dispersal units from the closer target to the more far. The number of dispersal units by target leaf is computed as in Robert et al. 2008 2. Downward dispersal: Get leaves in a cylinder whose dimensions are related to the dimesions of the semi-sphere in step 1. Then distribute dispersal units from top to bottom. Parameters ---------- g: MTG MTG representing the canopy (and the soil) dispersal_units : dict Dispersal units emitted by the lesions on leaves Returns ------- deposits : dict Dispersal units deposited on new position on leaves """ try: dt = time_control.dt except: dt = 1 deposits = {} if dt>0: from alinea.astk.plantgl_utils import get_area_and_normal from alinea.alep.architecture import get_leaves from openalea.plantgl import all as pgl from collections import OrderedDict from math import exp, pi, cos, sin, tan from random import shuffle import numpy as np from copy import copy dmax = self.distance_max tesselator = pgl.Tesselator() bbc = pgl.BBoxComputer(tesselator) leaves = get_leaves(g, label=self.label) centroids = g.property('centroid') geometries = g.property('geometry') _, norm = get_area_and_normal(geometries) areas = g.property('area') def centroid(vid): if is_iterable(geometries[vid]): bbc.process(pgl.Scene(geometries[vid])) else: bbc.process(pgl.Scene([pgl.Shape(geometries[vid])])) center = bbc.result.getCenter() centroids[vid] = center for source, dus in dispersal_units.iteritems(): nb_tri = len(norm[source]) borders = np.linspace(0,1,num=nb_tri) dus_by_tri = {k:filter(lambda x: borders[k]<x.position[0]<=borders[k+1], dus) for k in range(nb_tri-1) if len(filter(lambda x: borders[k]<x.position[0]<=borders[k+1], dus))>0.} for k,v in dus_by_tri.iteritems(): source_normal = norm[source][k] ## UPWARD ## # All leaves except the source are potential targets targets = list(leaf for leaf in leaves if leaf in geometries.iterkeys()) targets.remove(source) # Compute centroids centroid(source) for vid in targets: centroid(vid) # Sort the vids based on the direction # TODO : modify source angle Origin = centroids[source] vects = {vid:(centroids[vid]-Origin) for vid in targets if (centroids[vid]-Origin)*source_normal >= 0} # Sort the vids based on the distance distances = {vid:pgl.norm(vects[vid]) for vid in vects if pgl.norm(vects[vid])<dmax} distances = OrderedDict(sorted(distances.iteritems(), key=lambda x: x[1])) # Distribute the dispersal units if len(distances.values())>0: shuffle(v) n = len(v) sphere_area = 2*pi*distances.values()[-1]**2 for leaf_id in distances: area_factor = areas[leaf_id]/sphere_area distance_factor = exp(-self.k * distances[leaf_id]) qc = min(n, (n * area_factor * distance_factor)) deposits[leaf_id] = v[:int(qc)] del v[:int(qc)] # if len(dus) < 1 or len(deposits[leafid]) < 1: if len(v) < 1: for d in v: d.disable() # break ## DOWNWARD ## vects2 = {vid:(centroids[vid]-Origin) for vid in targets if not vid in vects} projection = {} alpha = pgl.angle(source_normal, (1,0,0)) if alpha>=pi/2. or (alpha<pi/2. and source_normal[2]>=0): alpha+=pi/2. beta = pgl.angle(source_normal, (0,0,1)) a = dmax b = dmax*cos(beta) for leaf in vects2: if (centroids[leaf]-Origin)*(source_normal[0], source_normal[1], 0) >= 0: # Big side of the projection semi circle copy_centroid = copy(centroids[leaf]) copy_origin = copy(Origin) copy_centroid[2] = 0. copy_origin[2] = 0. if pgl.norm(copy_centroid-copy_origin) < dmax: projection[leaf] = vects2[leaf] else: # Small side of the projection semi ellipse x = vects2[leaf][0] y = vects2[leaf][1] x2 = x*cos(alpha)+y*sin(alpha) y2 = -x*sin(alpha)+y*cos(alpha) if (x2**2)/(a**2) + (y2**2)/(b**2) < 1 : projection[leaf] = vects2[leaf] projection = OrderedDict(sorted(projection.items(), key=lambda x:x[1][2], reverse=True)) if len(projection)>0: shuffle(v) n = len(v) n_big = int(n*(beta+pi/2.)/pi) n_small = n - n_big for leaf in projection: copy_centroid = copy(centroids[leaf]) copy_origin = copy(Origin) copy_centroid[2] = 0. copy_origin[2] = 0. if (centroids[leaf]-Origin)*(source_normal[0],source_normal[1],0) >= 0: area_factor = areas[leaf]/(pi*dmax**2/2.) dist = pgl.norm(copy_centroid-copy_origin) distance_factor = exp(-self.k * dist) qc = min(n_big, (n_big * area_factor * distance_factor)) g.node(leaf).color = (0, 180, 0) else: area_factor = areas[leaf]/(pi*a*b/2.) dist = pgl.norm(copy_centroid-copy_origin)/abs(cos(pgl.angle(source_normal, (1,0,0))+pi/2.)) distance_factor = exp(-self.k * dist) qc = min(n_small, (n_small * area_factor * distance_factor)) g.node(leaf).color = (0, 0, 180) # import pdb # pdb.set_trace() deposits[leaf] = v[:int(qc)] del v[:int(qc)] for leaf in distances: g.node(leaf).color = (180, 0, 0) # Temp # from alinea.adel.mtg_interpreter import plot3d # from openalea.plantgl.all import Viewer # g.node(source).color=(230, 62, 218) # scene = plot3d(g) # Viewer.display(scene) # import pdb # pdb.set_trace() return deposits
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 plot_severity_rust_by_leaf(g, senescence=True, transparency=None, label='LeafElement'): """ Display the MTG with colored leaves according to disease severity Parameters ---------- g: MTG MTG representing the canopy senescence: bool True if senescence must be displayed, False otherwise transparency: float[0:1] Transparency of the part of the MTG without lesion label: str Label of the part of the MTG concerned by the calculation Returns ------- scene: Scene containing the MTG attacked by the disease """ from alinea.alep.architecture import set_property_on_each_id, get_leaves from alinea.alep.alep_color import alep_colormap, green_yellow_red from alinea.adel.mtg_interpreter import plot3d from alinea.alep.disease_outputs import plot3d_transparency from openalea.plantgl.all import Viewer # Visualization lesions = g.property('lesions') leaves = get_leaves(g, label=label) severity_by_leaf = {} for lf in leaves: if lf in lesions: leaf = g.node(lf) severity_by_leaf[lf] = sum([l.surface for l in leaf.lesions])*100./leaf.area if leaf.area>0 else 0. else: severity_by_leaf[lf] = 0. set_property_on_each_id(g, 'severity', severity_by_leaf, label=label) g = alep_colormap(g, 'severity', cmap=green_yellow_red(levels=100), lognorm=False, zero_to_one=False, vmax=100) if senescence==True: leaves = get_leaves(g, label=label) sen_lengths = g.property('senesced_length') green_lengths = g.property('green_length') for leaf in leaves: if sen_lengths[leaf]>0. and round(green_lengths[leaf],15)==0.: g.node(leaf).color = (157, 72, 7) if transparency!=None: for id in g: if not id in severity_by_leaf: g.node(id).color = (255,255,255) g.node(id).transparency = 0.9 elif severity_by_leaf[id]==0.: g.node(id).color = (255,255,255) g.node(id).transparency = transparency else: g.node(id).transparency = 0. scene = plot3d_transparency(g) else: scene = plot3d_transparency(g) Viewer.display(scene) return scene
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
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
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: 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') greens = 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 greens[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: # Update g for the disease sen_model.find_senescent_lesions(g, label='LeafElement') update_healthy_area(g, label='LeafElement') # Possibly refill pool of initial inoculum to simulate differed availability
def plot_severity_rust_by_leaf(g, senescence=True, transparency=None, label='LeafElement'): """ Display the MTG with colored leaves according to disease severity Parameters ---------- g: MTG MTG representing the canopy senescence: bool True if senescence must be displayed, False otherwise transparency: float[0:1] Transparency of the part of the MTG without lesion label: str Label of the part of the MTG concerned by the calculation Returns ------- scene: Scene containing the MTG attacked by the disease """ from alinea.alep.architecture import set_property_on_each_id, get_leaves from alinea.alep.alep_color import alep_colormap, green_yellow_red from alinea.adel.mtg_interpreter import plot3d from alinea.alep.disease_outputs import plot3d_transparency from openalea.plantgl.all import Viewer # Visualization lesions = g.property('lesions') leaves = get_leaves(g, label=label) severity_by_leaf = {} for lf in leaves: if lf in lesions: leaf = g.node(lf) severity_by_leaf[lf] = sum([ l.surface for l in leaf.lesions ]) * 100. / leaf.area if leaf.area > 0 else 0. else: severity_by_leaf[lf] = 0. set_property_on_each_id(g, 'severity', severity_by_leaf, label=label) g = alep_colormap(g, 'severity', cmap=green_yellow_red(levels=100), lognorm=False, zero_to_one=False, vmax=100) if senescence == True: leaves = get_leaves(g, label=label) sen_lengths = g.property('senesced_length') green_lengths = g.property('green_length') for leaf in leaves: if sen_lengths[leaf] > 0. and round(green_lengths[leaf], 15) == 0.: g.node(leaf).color = (157, 72, 7) if transparency != None: for id in g: if not id in severity_by_leaf: g.node(id).color = (255, 255, 255) g.node(id).transparency = 0.9 elif severity_by_leaf[id] == 0.: g.node(id).color = (255, 255, 255) g.node(id).transparency = transparency else: g.node(id).transparency = 0. scene = plot3d_transparency(g) else: scene = plot3d_transparency(g) Viewer.display(scene) return scene