5. Tutorial: Create MTG file from scratch

This tutorial briefly introduces the main features of the package and should show you the contents and potential of the openalea.mtg library.

All the examples can be tested in a Python interpreter.

5.1. MTG creation

Let us consider the following example:

 1import openalea.mtg as mtg
 2
 3g = mtg.MTG()
 4
 5print len(g)
 6print g.nb_vertices()
 7print g.nb_scales()
 8
 9root = g.root
10print g.scale(root)
  • First, the package is imported (line 1).

  • Then, a mtg is instantiated without parameters (line 3).

  • However, as for a Tree, the mtg is not empty (line 5-7).

  • There is always a root node at scale 0 (line 9-10).

5.2. Simple edition

We add a component root1 to the root node, which will be the root node of the tree at the scale 1.

 1root1 = g.add_component(root)
 2
 3# Edit the tree at scale 1 by adding three children
 4# to the vertex `root1`.
 5v1 = g.add_child(root1)
 6v2 = g.add_child(root1)
 7v3 = g.add_child(root1)
 8
 9g.parent(v1) == root1
10g.complex(v1) == root
11v3 in g.siblings(v1)

5.3. Traversing the mtg at one scale

The mtg can be traversed at any scales like a regular tree. Their are three traversal algorithms working on Tree data structures (container_algo_traversal):

  • pre_order

  • post_order

  • level_order

These methods take as parameters a tree like data structure, and a vertex. They will traverse the subtree rooted on this vertex in a specific order. They will return an iterator on the traversed vertices.

1from openalea.container.traversal.tree import *
2
3print list(g.components(root))
4
5print list(pre_order(g, root1))
6print list(post_order(g, root1))
7print list(level_order(g, root1))

Warning

On MTG data structure, methods that return collection of vertices always return an iterator rather than list, array, or set.

You have to convert the iterator into a list if you want to display it, or compute its length.

>>> print len(g.components(root)) 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'generator' has no len()

Use rather:

>>> components = list(g.components(root)) 
>>> print components 
[1, 2, 3, 4]

5.4. Full example: how to create an MTG

../_images/fig3_4.png

Figure 1: Graphical representation of the MTG file code_file2.mtg used as an input file to all examples contained in this page

 1from openalea.mtg.mtg import *
 2from openalea.mtg.aml import *
 3
 4
 5g = mtg.MTG()
 6plant_id = g.add_component(g.root, label='P1')
 7
 8#first u1
 9u1 = g.add_component(plant_id, label='U1', Length=10, Diameter=5.9)
10i = g.add_component(u1,label='I1' )
11i = g.add_child(i,label='I2', edge_type='<' )
12i = g.add_child(i,label='I3', edge_type='<' )
13i = g.add_child(i,label='I4', edge_type='<' )
14i = g.add_child(i,label='I5', edge_type='<' )
15i6 = i = g.add_child(i,label='I6', edge_type='<' )
16
17#u2 branch
18i,u2 = g.add_child_and_complex(i6,label='I20', edge_type='+', Length=7, Diameter=3.5 )
19g.node(u2).label='U2'
20g.node(u2).edge_type='+'
21i = g.add_child(i,label='I21', edge_type='<' )
22i = g.add_child(i,label='I22', edge_type='<' )
23i = g.add_child(i,label='I23', edge_type='<' )
24i = g.add_child(i,label='I24', edge_type='<' )
25
26#u3 branch
27i,u3 = g.add_child_and_complex(i,label='I25', edge_type='<', Length=4, Diameter=2.1)
28g.node(u3).label='U3'
29g.node(u3).edge_type='<'
30i = g.add_child(i,label='I25', edge_type='<' )
31i = g.add_child(i,label='I26', edge_type='<' )
32i = g.add_child(i,label='I27', edge_type='<' )
33i = g.add_child(i,label='I28', edge_type='<' )
34i = g.add_child(i,label='I29', edge_type='<' )
35
36#continue u1
37i = g.add_child(i6,label='I7', edge_type='<' )
38i = g.add_child(i,label='I8', edge_type='<' )
39i = g.add_child(i,label='I9', edge_type='<' )
40
41# u2 main axe
42i,c = g.add_child_and_complex(i,label='I10', edge_type='<' , Length=8, Diameter=4.3)
43g.node(c).label='U2'
44g.node(c).edge_type='<'
45i = g.add_child(i,label='I11', edge_type='<' )
46i = g.add_child(i,label='I12', edge_type='<' )
47i = g.add_child(i,label='I13', edge_type='<' )
48i = g.add_child(i,label='I14', edge_type='<' )
49i = g.add_child(i,label='I15', edge_type='<' )
50
51
52# u3 main axe
53i,c = g.add_child_and_complex(i,label='I16', edge_type='<', Length=7.5, diameter=3.9 )
54g.node(c).label='U3'
55g.node(c).edge_type='<'
56i = g.add_child(i,label='I17', edge_type='<' )
57i = g.add_child(i,label='I18', edge_type='<' )
58i = g.add_child(i,label='I19', edge_type='<' )
59
60
61#fat_mtg(g)
62
63print g.is_valid()
64print g
65
66for id in g.vertices():
67    print g[id]
68from openalea.mtg.io import *
69
70print list(g.property_names())
71properties = [(p, 'REAL') for p in g.property_names() if p not in ['edge_type', 'index', 'label']]
72print properties
73mtg_lines = write_mtg(g, properties)
74f = open('test.mtg', 'w')
75f.write(mtg_lines)
76f.close()
77
Authors:

Christophe Pradal <christophe pradal __at__ cirad fr>, Thomas Cokelaer <thomas cokelaer __at__ sophia inria fr>