import numpy as np
import pandas as pd
from functools import partial
from openalea.mtg import turtle as turt
from openalea.mtg.plantframe.turtle import visitor
from openalea.plantgl import all as pgl
from openalea.colzette.geometry import RapeseedVisitor, FababeanVisitor, CamelinaVisitor, LentilVisitor
from openalea.colzette.geometry import (LegumeVisitor,
make_leaflet_shape_fababean,
make_leaflet_shape_lentil,
BrassicaVisitor,
make_leafshape_rapeseed,
make_leafshape_camelina)
[docs]
def create_scene_one_species(list_of_MTGs, list_of_positions, visitor = RapeseedVisitor):
# function 2 to compute final scene and new indices
# We initialize additional properties of scene_information:
list_rotation = []
# We initialize an indexer that will record the correspondance between the initial vid of the MTG and the new,
# unique indices of the scene:
shapes_indexer = {}
# We initialize a unique shape ID for new indexing across all plants in the scene
unique_shape_id = 1
# We initialize a turtle in PlantGL:
turtle = turt.PglTurtle()
# We initialize the final scene:
final_scene = pgl.Scene()
for plant_index in range(0,len(list_of_positions)):
#print(plant_index)
# We access the MTG corresponding to the current plant index:
new_MTG = list_of_MTGs[plant_index]
# We initialize the indexer for the current plant:
shapes_indexer[plant_index] = {}
# We first define the seed of random, depending on the index of the plant:
np.random.seed(int(2.0 * plant_index))
# We then modify the angle of the plant, so that leaves are not oriented the same way within the population:
angle_roll = abs(np.random.normal(180, 180))
# We record this rotation in the scene information:
list_rotation.append(angle_roll)
# We reset the turtle:
turtle.reset()
# And we reposition the turtle from there:
turtle.move(list_of_positions[plant_index])
turtle.rollR(angle_roll)
# We create a scene for one plant by moving the turtle along the MTG:
scene = turt.TurtleFrame(new_MTG,
visitor=visitor,
turtle=turtle, gc=False)
scene_dict = scene.todict()
dict_organs = {}
for old_shape_id in scene_dict.keys():
shapes = scene_dict[old_shape_id]
if len(shapes)==1:
# internode shape
shape = shapes[0]
dict_organs[unique_shape_id] = 'Internode'
shapes_indexer[plant_index][unique_shape_id] = old_shape_id
shape.id = unique_shape_id
final_scene += shape
unique_shape_id += 1
elif len(shapes)==2:
# leaf shape with leaf + petiole
shape1 = shapes[0] # leaf
dict_organs[unique_shape_id] = 'Leaf'
shapes_indexer[plant_index][unique_shape_id] = old_shape_id
shape1.id = unique_shape_id
final_scene += shape1
unique_shape_id += 1
shape2 = shapes[1] # petiole
dict_organs[unique_shape_id] = 'Petiole'
shapes_indexer[plant_index][unique_shape_id] = old_shape_id
shape2.id = unique_shape_id
final_scene += shape2
unique_shape_id += 1
return final_scene, shapes_indexer
[docs]
def create_scene(list_of_MTGs, list_of_positions, sowing_pattern, ustride=9, vstride=2):
list_rotation = []
shapes_indexer = {}
unique_shape_id = 1
turtle = turt.PglTurtle()
final_scene = pgl.Scene()
for plant_index in range(0,len(list_of_positions)):
# print(plant_index)
new_MTG = list_of_MTGs[plant_index]
shapes_indexer[plant_index] = {}
np.random.seed(int(2.0 * plant_index))
angle_roll = abs(np.random.normal(180, 180))
list_rotation.append(angle_roll)
turtle.reset()
turtle.move(list_of_positions[plant_index])
turtle.rollR(angle_roll)
if sowing_pattern['species'][plant_index] == "Fababean":
visitor = partial(LegumeVisitor,make_leaflet_shape=make_leaflet_shape_fababean, ustride=ustride, vstride=vstride)
elif sowing_pattern['species'][plant_index] == "Lentil":
visitor = partial(LegumeVisitor, make_leaflet_shape=make_leaflet_shape_lentil,ustride=ustride, vstride=vstride)
elif sowing_pattern['species'][plant_index] == "Rapeseed":
visitor = partial(BrassicaVisitor, make_leafshape=make_leafshape_rapeseed,ustride=ustride, vstride=vstride)
elif sowing_pattern['species'][plant_index] == "Camelina":
visitor = partial(BrassicaVisitor, make_leafshape=make_leafshape_camelina,ustride=ustride, vstride=vstride)
scene = turt.TurtleFrame(new_MTG,
visitor=visitor,
turtle=turtle, gc=False)
scene_dict = scene.todict()
dict_organs = {}
for old_shape_id in scene_dict.keys():
shapes = scene_dict[old_shape_id]
if len(shapes)==1:
# internode shape
shape = shapes[0]
dict_organs[unique_shape_id] = 'Internode'
shapes_indexer[plant_index][unique_shape_id] = old_shape_id
shape.id = unique_shape_id
final_scene += shape
unique_shape_id += 1
elif len(shapes)==2:
# leaf shape with leaf + petiole
shape1 = shapes[0] # leaf
dict_organs[unique_shape_id] = 'Leaf'
shapes_indexer[plant_index][unique_shape_id] = old_shape_id
shape1.id = unique_shape_id
final_scene += shape1
unique_shape_id += 1
shape2 = shapes[1] # petiole
dict_organs[unique_shape_id] = 'Petiole'
shapes_indexer[plant_index][unique_shape_id] = old_shape_id
shape2.id = unique_shape_id
final_scene += shape2
unique_shape_id += 1
return final_scene, shapes_indexer
[docs]
def get_domain(density, nb_plantes):
inter_row = np.sqrt(1 / density)
inter_plant = 1. / inter_row / density
if nb_plantes == 1:
nrow = 1
else:
nrow = np.max([1, int(np.sqrt(nb_plantes))])
dx = inter_plant * 100
dy = inter_row * 100
nx = int(nb_plantes / nrow)
ny = nrow
domain = ((0, 0), (nx * dx, ny * dy))
return domain
[docs]
def sowing_map_monocrop(
length,
width,
density,
species):
"""
length, width : plot dimensions (m)
density : plants per m²
species : names of the species
"""
pas = np.sqrt(1 / density)
xs = np.arange(pas / 2, length, pas)
ys = np.arange(pas / 2, width, pas)
data = []
for i, y in enumerate(ys):
for x in xs:
data.append((x, y, species))
data2 = pd.DataFrame(data, columns=["x", "y", "species"])
return data2
[docs]
def sowing_map_intercrop(
length,
width,
density,
species_brassica,
species_legume,
sowing_option):
"""
length, width : plot dimensions (m)
density : plants per m²
species1, species2 : names of the two species
"""
pas = np.sqrt(1 / density)
xs = np.arange(pas / 2, length, pas)
ys = np.arange(pas / 2, width, pas)
data = []
if sowing_option == "rows":
for i, y in enumerate(ys):
species = species_brassica if i % 2 == 0 else species_legume
for x in xs:
data.append((x, y, species))
elif sowing_option == "mixed":
for i, y in enumerate(ys):
for j,x in enumerate(xs):
if (j+1) % 2 == 1 and (i+1) % 2 == 1:
species = species_brassica
elif (j+1) % 2 == 0 and (i+1) % 2 == 1:
species = species_legume
elif (j+1) % 2 == 1 and (i+1) % 2 == 0:
species = species_legume
elif (j+1) % 2 == 0 and (i+1) % 2 == 0:
species = species_brassica
data.append((x, y, species))
data2 = pd.DataFrame(data, columns=["x", "y", "species"])
return data2
[docs]
def scene3d(g, select_visitor):
"""
calls a PlantGL turtle to generate a 3D scene
g is an MTG file
"""
t = pgl.PglTurtle()
# set colors
colors = dict()
colors['Internode'] = (100, 100, 80)
colors['Petiole'] = (100, 100, 80)
colors['Leaf'] = (9, 82, 40)
color = pgl.Color3(*colors['Internode'])
t.setColorAt(1, color)
color = pgl.Color3(*colors['Petiole'])
t.setColorAt(2, color)
color = pgl.Color3(*colors['Leaf'])
t.setColorAt(3, color)
max_scale = g.max_scale()
vid = next(g.component_roots_at_scale_iter(g.root, scale=max_scale))
scene = turtle.TurtleFrame(
g,
visitor=select_visitor, turtle=t, gc=False, all_roots=True)
return scene
# backward compatibility
create_rapeseed_scene=create_scene_one_species
create_fababean_scene = partial(create_scene_one_species, visitor = FababeanVisitor)
create_mixture_scene = create_scene