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>