def initialize_mtg(root, nodelabel = 'N'): from openalea.mtg import MTG mtg = MTG() plantroot = mtg.root branchroot = mtg.add_component(plantroot,label='P') noderoot = mtg.add_component(branchroot,label=nodelabel) mtg.property('position')[noderoot] = root mtg.property('radius')[noderoot] = None assert len(mtg.property('position')) == 1 return mtg
def initialize_mtg(root, nodelabel='N'): from openalea.mtg import MTG mtg = MTG() plantroot = mtg.root branchroot = mtg.add_component(plantroot, label='P') noderoot = mtg.add_component(branchroot, label=nodelabel) mtg.property('position')[noderoot] = root mtg.property('radius')[noderoot] = None assert len(mtg.property('position')) == 1 return mtg
def test_insert_elements(): g = MTG() labels = g.property('label') add_plant(g) elts = [{'label': 'elt1'}, {'label': 'elt2'}] collar = find_label('collar', g)[0] insert_elements(g, collar, elts) elt1 = find_label('elt1', g)[0] assert labels[g.parent(elt1)] == 'baseElement' assert labels[g.children(elt1)[0]] == 'elt2'
def test_add_axe(): g = MTG() labels = g.property('label') p1 = add_plant(g) p2 = add_plant(g) vid_axe = add_axe(g, 'T0') assert g.complex(vid_axe) == p1 assert labels[g.parent(vid_axe)] == 'MS' vid_axe = add_axe(g, 'T1.3', plant_number=2) assert g.complex(vid_axe) == p2 assert labels[g.parent(vid_axe)] == 'T1' vid_metamer0 = g.component_roots_at_scale(vid_axe, 3)[0] assert labels[g.parent(vid_metamer0)] == "metamer3"
def test_extract_at_plant_scale(): files = shared_data(openalea.strawberry).glob('*.mtg') mtg_path = dict((name(f), f) for f in files) mtg = MTG() for k, genotype in enumerate(mtg_path): if (genotype=="Sicile") or (genotype=="Nils") or (genotype=='origine_stolon_gariguetteDV_6novembre2018') \ or (genotype=='friendlyfruit_varieties'): pass else: mtg = union(mtg, read_mtg_file(mtg_path[genotype])) genotypes = mtg.property('Genotype') for geno in set(genotypes.values()): vids = [ vid for vid in mtg.vertices(scale=1) if genotypes.get(vid) == geno ] df = extract_at_plant_scale(mtg, vids) assert not df.empty assert set(df['Genotype']) == {geno}
def read_lsystem_string( string, symbol_at_scale, functional_symbol={}, mtg=None ): """Read a string generated by a lsystem. :Parameters: - `string`: The lsystem string representing the axial tree. - `symbol_at_scale`: A dict containing the scale for each symbol name. :Optional parameters: - `functional_symbol`: A dict containing a function for specific symbols. The args of the function have to be coherent with those in the string. The return type of the functions have to be a dictionary of properties: dict(name, value) :Return: MTG object """ import openalea.plantgl.all as pgl s = string def transform(turtle, mesh): x = turtle.getUp() z = turtle.getHeading() bo = pgl.BaseOrientation(x, z^x) matrix = pgl.Transform4(bo.getMatrix()) matrix.translate(turtle.getPosition()) mesh = mesh.transform(matrix) return mesh # 1. Create the mtg structure. if mtg is None: mtg = MTG() # 2. add some properties to the MTG mtg.add_property('index') mtg.add_property('can_label') mtg.add_property('geometry') mtg.add_property('tissue_type') vid = mtg.root # vid of the support tree, i.e. at the finest scale current_vertex = mtg.root branching_stack = [] pending_edge = '' # edge type for the next edge to be created scale = 0 lsys_symbols = ['[', ']', '/', '+', '^', 'f'] modules = symbol_at_scale.keys() symbols = lsys_symbols + modules index = dict(zip(symbol_at_scale.keys(), [0]*len(symbol_at_scale))) is_ramif = False # 2. Create a PlantGL Turtle... turtle = pgl.Turtle() max_scale = max(symbol_at_scale.values()) for edge_type in symbols: if edge_type != 'f': s = s.replace(edge_type, '\n%s'%edge_type) else: s = s.replace('f(', '\nf(') l = s.split() try: plant_name = [s for s in symbol_at_scale.keys() if 'plant' in s.lower()][0] except: ValueError("""Incorrect plant name (should be plant)""") for node in l: # Check if node is a module tag = node[0] if tag == '[': branching_stack.append(vid) turtle.push() is_ramif = True elif tag == ']': vid = branching_stack.pop() current_vertex = vid scale = mtg.scale(vid) turtle.pop() is_ramif = False elif tag == '/': args = get_args(node[1:]) if args: angle = get_float(args[1:-1]) turtle.rollR(angle) else: turtle.rollR() elif tag == '+': args = get_args(node[1:]) if args: angle = get_float(args[1:-1]) turtle.left(angle) else: turtle.left() elif tag == '^': args = get_args(node[1:]) if args: angle = get_float(args[1:-1]) turtle.up(angle) else: turtle.up() elif tag == 'f' and node[1] == '(': args = get_args(node[1:]) if args: length = get_float(args[1:-1]) if length > 0: turtle.f(length) else: turtle.f() else: # add new modules to the mtg (i.e. add nodes) name = get_name(node) if name not in modules: print 'Unknow element %s'% name continue module_scale = symbol_at_scale[name] if is_ramif: edge_type = '+' else: edge_type = '<' log(node, module_scale, edge_type ) if module_scale == scale: if mtg.scale(vid) == scale: vid = mtg.add_child(vid, edge_type=edge_type, label=name) current_vertex = vid pending_edge = '' log('','Cas 1.1', scale, 'mtg.scale(vid)', mtg.scale(vid), 'generated vertex', vid) assert mtg.scale(vid) == module_scale else: # add the edge to the current vertex current_vertex = mtg.add_child(current_vertex, edge_type=edge_type, label=name) log('', 'Cas 1.2', scale, 'mtg.scale(vid)', mtg.scale(vid), 'generated vertex', current_vertex) assert mtg.scale(current_vertex) == module_scale is_ramif = False elif module_scale > scale: log('', 'Cas 2', scale, 'mtg.scale(vid)', mtg.scale(vid)) old_current_vertex = current_vertex while module_scale > scale: if mtg.scale(vid) == scale: assert vid == current_vertex vid = mtg.add_component(vid) current_vertex = vid log('', '', 'Cas 2.1', scale, 'generate new component', current_vertex) scale += 1 if module_scale == scale: assert mtg.scale(current_vertex) == module_scale mtg.property('label')[current_vertex] = name break else: scale += 1 current_vertex = mtg.add_component(current_vertex) else: log(node, 'add_child(%d, child=%d)'%(old_current_vertex, current_vertex)) mtg.property('label')[current_vertex] = name if mtg.scale(vid) == scale: vid = mtg.add_child(vid, child=current_vertex, edge_type=edge_type) is_ramif = False else: assert module_scale < scale while module_scale < scale: scale -= 1 current_vertex = mtg.complex(current_vertex) else: current_vertex = mtg.add_child(current_vertex, edge_type=edge_type, label=name) assert mtg.scale(current_vertex) == module_scale # MANAGE the properties, the geometry and the indices!!! index[name] += 1 if name == plant_name: for k in index.keys(): if k != name: index[k] = 0 mtg.property('index')[current_vertex] = index[name] if name in functional_symbol: features = eval(node, functional_symbol) geom = features.get('geometry') canlabel = features.get('label') ttype = features.get('tissue_type') if geom: # get the transformation from the turtle geom = transform(turtle, geom) mtg.property('geometry')[current_vertex] = geom if name == 'StemElement': # parse args to know how the turtle has to move . args = get_args(node)[1:-1] list_args= args.split(',') length = float(list_args[1]) # 2nd arg if length > 0: turtle.f(length) if canlabel: canlabel.elt_id = index[name] plant_id = mtg.complex_at_scale(current_vertex, scale=1) canlabel.plant_id = mtg.property('index')[plant_id] mtg.property('can_label')[current_vertex] = canlabel if ttype: mtg.property('tissue_type')[current_vertex] = ttype mtg = fat_mtg(mtg) return mtg
def new_mtg_factory(parameters, metamer_factory=adel_metamer, leaf_sectors=1, leaves=None, stand=None, axis_dynamics=None, add_elongation=False, topology=('plant', 'axe_id', 'numphy'), split=False, aborting_tiller_reduction=1.0, leaf_db=None): """A 'clone' of mtg_factory that uses mtg_edition functions """ if leaf_db is not None: raise AdelDeprecationError( 'leaf_db argument is deprecated, use leaves argument instead') if leaves is None: dynamic_leaf_db = {0: False} leaves = {0: None} else: dynamic_leaf_db = {k: leaves[k].dynamic for k in leaves} g = MTG() # buffers # for detection of newplant/newaxe prev_plant = 0 prev_axe = -1 dp = parameters nrow = len(dp['plant']) species = 0 for i in range(nrow): plant, num_metamer = [int(convert(dp.get(x)[i], undef=None)) for x in [topology[e] for e in [0, 2]]] axe = dp.get(topology[1])[i] args = properties_from_dict(dp, i, exclude=topology) # Add plant if new if plant != prev_plant: if axe != 'MS': raise ValueError('Main stem is expected first when a new plant ' 'is declared') position, azimuth = (0, 0, 0), 0 if stand and len(stand) >= plant: position, azimuth = stand[plant - 1] plant_properties = {'position': position, 'azimuth': azimuth, 'refplant_id': args.get('refplant_id'), 'species': species} timetable = None if axis_dynamics: timetable = axis_dynamics[str(plant)][str(axe)] mainstem_properties = dict(timetable=timetable, HS_final=args.get('HS_final'), nff=args.get('nff'), hasEar=args.get('hasEar'), azimuth=args.get('az_insertion')) add_plant(g, plant_number=plant, plant_properties=plant_properties, axis_properties=mainstem_properties) prev_plant = plant # Add axis if axe != prev_axe and axe != 'MS': timetable = None if axis_dynamics: timetable = axis_dynamics[str(plant)][str(axe)] axe_properties = dict(timetable=timetable, HS_final=args.get('HS_final'), nff=args.get('nff'), hasEar=args.get('hasEar'), azimuth=args.get('az_insertion')) add_axe(g, axe, plant, axis_properties=axe_properties) prev_axe = axe # Add metamer assert num_metamer > 0 # args are added to metamers only if metamer_factory is none, # otherwise compute metamer components components = [] if metamer_factory: xysr_key = None if leaves[species] is not None and 'LcType' in args and 'LcIndex' in args: lctype = int(args['LcType']) lcindex = int(args['LcIndex']) if lctype != -999 and lcindex != -999: age = None if dynamic_leaf_db[species]: age = float(args[ 'rph']) - 0.3 # age_db = HS - rank + 1 = ph - 1.3 - rank +1 = rph - .3 if age != 'NA': age = max(0, int(float(age))) xysr_key = leaves[species].get_leaf_key(lctype, lcindex, age) elongation = None if add_elongation: startleaf = -.4 endleaf = 1.6 stemleaf = 1.2 startE = endleaf endE = startE + (endleaf - startleaf) / stemleaf endBlade = endleaf if args['Gl'] > 0: endBlade = args['Ll'] / args['Gl'] * (endleaf - startleaf) elongation = {'startleaf': startleaf, 'endBlade': endBlade, 'endleaf': endleaf, 'endE': endE} if not 'ntop' in args: args.update({'ntop': None}) if not 'Gd' in args: args.update({'Gd': 0.19}) args.update({'split': split}) if args.get('HS_final') < args.get('nff'): for what in ( 'Ll', 'Lv', 'Lr', 'Lsen', 'L_shape', 'Lw_shape', 'Gl', 'Gv', 'Gsen', 'Gd', 'El', 'Ev', 'Esen', 'Ed'): args.update( {what: args.get(what) * aborting_tiller_reduction}) components = metamer_factory(Lsect=leaf_sectors, shape_key=xysr_key, elongation=elongation, leaves=leaves[species], **args) args = {'L_shape': args.get('L_shape')} # metamer_properties = args internode, sheath, blade = None, None, None elts = {k: [] for k in ('internode', 'sheath', 'blade')} if len(components) > 0: internode, sheath, blade = components internode.pop('label') sheath.pop('label') blade.pop('label') elts['internode'] = internode.pop('elements') elts['sheath'] = sheath.pop('elements') elts['blade'] = blade.pop('elements') vid_metamer = add_vegetative_metamer(g, plant, axe, metamer_properties=metamer_properties, internode_properties=internode, sheath_properties=sheath, blade_properties=blade) for organ in g.components(vid_metamer): label = g.property('label')[organ] if label in elts and len(elts[label]) > 0: insert_elements(g, organ, elts[label]) return fat_mtg(g)