From 436d211c7a8ad3ba3725a55de5cd31fef7ac2b34 Mon Sep 17 00:00:00 2001 From: Martin PELLEMOINE Date: Wed, 12 Jun 2024 10:24:41 +0200 Subject: [PATCH 01/14] add pyproject.toml --- pyproject.toml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..d749165 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,29 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "openalea.mtg" +version = "0.1.0" # Remplacer par la version réelle +description = "Multiscale Tree Graph datastructure and interfaces" +readme = "README.rst" +authors = [ + { name = "Christophe Pradal", email = "christophe.pradal@cirad.fr" } +] +license = { text = "CeCILL-C" } +keywords = ["OpenAlea", "MTG", "Plant Architecture", "Tree Graph"] +dependencies = [] + +[project.urls] +homepage = "http://github.com/openalea/mtg" + +[tool.setuptools] +packages = ["find_namespace:src"] +namespace_packages = ["openalea"] +package_dir = {"" = "src"} + +[tool.setuptools.dynamic] +version = {file = "src/openalea/mtg/version.py"} + +[tool.setuptools.entry-points.wralea] +mtg = "openalea.mtg_wralea" From dbfc48472a01868f7805da5c3e7aefec727f6e03 Mon Sep 17 00:00:00 2001 From: Martin PELLEMOINE Date: Wed, 12 Jun 2024 11:06:25 +0200 Subject: [PATCH 02/14] update meta.yaml --- conda/meta.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/conda/meta.yaml b/conda/meta.yaml index ad97af7..14e5d9c 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -12,6 +12,7 @@ build: preserve_egg_dir: True number: 2 script: {{PYTHON}} setup.py install #--single-version-externally-managed --record=record.txt + #script: {{ PYTHON }} -m pip install . requirements: build: @@ -42,5 +43,12 @@ test: about: home: {{ data.get('url') }} license: CeCILL-C + license_family: CeCILL summary: {{ data.get('description') }} + description: {{ data.get('long_description') }} + doc_url: http://github.com/openalea/mtg + dev_url: http://github.com/openalea/mtg +extra: + recipe-maintainers: + - https://github.com/pradal \ No newline at end of file From 5d3cddc6228097f376b020cc7a22937fd289fb0e Mon Sep 17 00:00:00 2001 From: Martin PELLEMOINE Date: Wed, 12 Jun 2024 14:09:15 +0200 Subject: [PATCH 03/14] update meta.yaml --- conda/meta.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conda/meta.yaml b/conda/meta.yaml index 14e5d9c..8f8db7a 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -43,7 +43,7 @@ test: about: home: {{ data.get('url') }} license: CeCILL-C - license_family: CeCILL + #license_family: summary: {{ data.get('description') }} description: {{ data.get('long_description') }} doc_url: http://github.com/openalea/mtg From d4915bbcca5304ecf96b295b24df69884eb3ff5d Mon Sep 17 00:00:00 2001 From: Martin PELLEMOINE Date: Wed, 12 Jun 2024 14:13:59 +0200 Subject: [PATCH 04/14] meta.yaml update --- conda/meta.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/conda/meta.yaml b/conda/meta.yaml index 8f8db7a..8e6be18 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -34,10 +34,10 @@ test: - openalea.mtg source_files: - share/data/** - - test/** - - test/data/** + - tests/** + - tests/data/** commands: - - cd test + - cd tests - pytest -v --ignore=test_aml.py --ignore=test_stat.py about: @@ -45,10 +45,10 @@ about: license: CeCILL-C #license_family: summary: {{ data.get('description') }} - description: {{ data.get('long_description') }} + #description: {{ data.get('long_description') }} doc_url: http://github.com/openalea/mtg dev_url: http://github.com/openalea/mtg extra: recipe-maintainers: - - https://github.com/pradal \ No newline at end of file + - pradal \ No newline at end of file From 0cc0df6341013329aee75d232fdf2bb08e17378a Mon Sep 17 00:00:00 2001 From: Martin PELLEMOINE Date: Wed, 12 Jun 2024 16:39:10 +0200 Subject: [PATCH 05/14] update pyproject.toml --- pyproject.toml | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d749165..c314d21 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openalea.mtg" -version = "0.1.0" # Remplacer par la version réelle +version = "0.1.0" description = "Multiscale Tree Graph datastructure and interfaces" readme = "README.rst" authors = [ @@ -17,13 +17,16 @@ dependencies = [] [project.urls] homepage = "http://github.com/openalea/mtg" -[tool.setuptools] -packages = ["find_namespace:src"] -namespace_packages = ["openalea"] -package_dir = {"" = "src"} +[tool.setuptools.packages.find] +where = ["src"] -[tool.setuptools.dynamic] -version = {file = "src/openalea/mtg/version.py"} +#[tool.setuptools] +#packages = ["find_namespace:src"] +#namespace_packages = ["openalea"] +#package_dir = {"" = "src"} -[tool.setuptools.entry-points.wralea] -mtg = "openalea.mtg_wralea" +#[tool.setuptools.dynamic] +#version = {file = "src/openalea/mtg/version.py"} + +#[tool.setuptools.entry-points.wralea] +#mtg = "openalea.mtg_wralea" From 7d626d0769310bf1af7eeb149324ca6d0ce5b38a Mon Sep 17 00:00:00 2001 From: Martin PELLEMOINE Date: Thu, 13 Jun 2024 09:25:27 +0200 Subject: [PATCH 06/14] meta.yaml python version --- conda/meta.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conda/meta.yaml b/conda/meta.yaml index 8e6be18..0111dc5 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -20,7 +20,7 @@ requirements: - setuptools - openalea.deploy run: - - python >=3.6 + - python >=3.10 - openalea.plantgl - matplotlib - pandas From 87f7de5236557ada4f8d111b753d32e17cfd2279 Mon Sep 17 00:00:00 2001 From: Martin PELLEMOINE Date: Thu, 13 Jun 2024 10:21:53 +0200 Subject: [PATCH 07/14] moved from "test" to "tests" --- {test => tests}/__init__.py | 0 {test => tests}/data/agraf.drf | 108 +- {test => tests}/data/leaf_axis.drf | 18 +- {test => tests}/data/monopodial_plant.mtg | 0 {test => tests}/data/mtg1.mtg | 0 {test => tests}/data/mtg2.mtg | 0 {test => tests}/data/mtg3.mtg | 0 {test => tests}/data/mtg4.mtg | 0 {test => tests}/data/mtg5.mtg | 0 {test => tests}/data/mtg51.mtg | 0 {test => tests}/data/mtg_dynamic.mtg | 0 {test => tests}/data/noyer.drf | 18 +- {test => tests}/data/oaktree.drf | 44 +- {test => tests}/data/origin.drf | 14 +- .../data/reconstructed_appletree.mtg | 962 +++++++++--------- {test => tests}/data/test10_agraf.mtg | 0 {test => tests}/data/test11_wij10.mtg | 0 {test => tests}/data/test12_wij10.mtg | 0 {test => tests}/data/test6_apricot2.mtg | 0 {test => tests}/data/test7.mtg | 0 {test => tests}/data/test8_boutdenoylum2.mtg | 0 {test => tests}/data/test9_noylum2.mtg | 0 {test => tests}/data/walnut.drf | 24 +- {test => tests}/data/wij10.drf | 92 +- {test => tests}/debug.py | 48 +- {test => tests}/eurograph.py | 68 +- {test => tests}/random_mtg.py | 112 +- {test => tests}/simple.lpy | 138 +-- {test => tests}/test_aml.py | 358 +++---- {test => tests}/test_dresser.py | 64 +- {test => tests}/test_edition.py | 0 {test => tests}/test_lsystem.py | 528 +++++----- {test => tests}/test_mtg.py | 454 ++++----- {test => tests}/test_operation.py | 0 {test => tests}/test_parsing.py | 226 ++-- {test => tests}/test_parsing_axialtree.py | 280 ++--- {test => tests}/test_parsing_mtg.py | 156 +-- {test => tests}/test_plantframe1.py | 442 ++++---- {test => tests}/test_proxynode.py | 0 {test => tests}/test_rewriting.py | 0 {test => tests}/test_stat.py | 0 {test => tests}/test_traversal.py | 0 {test => tests}/test_tree.py | 102 +- {test => tests}/test_tulip.py | 0 {test => tests}/test_turtle.py | 50 +- {test => tests}/test_writing_mtg.py | 144 +-- {test => tests}/test_writing_mtg2.py | 0 {test => tests}/toto.xls | 0 {test => tests}/visu3d.py | 244 ++--- 49 files changed, 2347 insertions(+), 2347 deletions(-) rename {test => tests}/__init__.py (100%) rename {test => tests}/data/agraf.drf (94%) rename {test => tests}/data/leaf_axis.drf (96%) rename {test => tests}/data/monopodial_plant.mtg (100%) rename {test => tests}/data/mtg1.mtg (100%) rename {test => tests}/data/mtg2.mtg (100%) rename {test => tests}/data/mtg3.mtg (100%) rename {test => tests}/data/mtg4.mtg (100%) rename {test => tests}/data/mtg5.mtg (100%) rename {test => tests}/data/mtg51.mtg (100%) rename {test => tests}/data/mtg_dynamic.mtg (100%) rename {test => tests}/data/noyer.drf (95%) rename {test => tests}/data/oaktree.drf (93%) rename {test => tests}/data/origin.drf (90%) rename {test => tests}/data/reconstructed_appletree.mtg (97%) rename {test => tests}/data/test10_agraf.mtg (100%) rename {test => tests}/data/test11_wij10.mtg (100%) rename {test => tests}/data/test12_wij10.mtg (100%) rename {test => tests}/data/test6_apricot2.mtg (100%) rename {test => tests}/data/test7.mtg (100%) rename {test => tests}/data/test8_boutdenoylum2.mtg (100%) rename {test => tests}/data/test9_noylum2.mtg (100%) rename {test => tests}/data/walnut.drf (95%) rename {test => tests}/data/wij10.drf (94%) rename {test => tests}/debug.py (92%) rename {test => tests}/eurograph.py (93%) rename {test => tests}/random_mtg.py (95%) rename {test => tests}/simple.lpy (96%) rename {test => tests}/test_aml.py (95%) rename {test => tests}/test_dresser.py (94%) rename {test => tests}/test_edition.py (100%) rename {test => tests}/test_lsystem.py (97%) rename {test => tests}/test_mtg.py (96%) rename {test => tests}/test_operation.py (100%) rename {test => tests}/test_parsing.py (97%) rename {test => tests}/test_parsing_axialtree.py (96%) rename {test => tests}/test_parsing_mtg.py (95%) rename {test => tests}/test_plantframe1.py (96%) rename {test => tests}/test_proxynode.py (100%) rename {test => tests}/test_rewriting.py (100%) rename {test => tests}/test_stat.py (100%) rename {test => tests}/test_traversal.py (100%) rename {test => tests}/test_tree.py (95%) rename {test => tests}/test_tulip.py (100%) rename {test => tests}/test_turtle.py (95%) rename {test => tests}/test_writing_mtg.py (95%) rename {test => tests}/test_writing_mtg2.py (100%) rename {test => tests}/toto.xls (100%) rename {test => tests}/visu3d.py (96%) diff --git a/test/__init__.py b/tests/__init__.py similarity index 100% rename from test/__init__.py rename to tests/__init__.py diff --git a/test/data/agraf.drf b/tests/data/agraf.drf similarity index 94% rename from test/data/agraf.drf rename to tests/data/agraf.drf index 6a2157b..a0613e3 100644 --- a/test/data/agraf.drf +++ b/tests/data/agraf.drf @@ -1,54 +1,54 @@ -# Dressing file for apple trees - -#SMBPath = D:/Documents/pradal/devlp/vplants/aml/databases/SMBFiles -SMBPath = ../../../databases/SMBFiles - -SMBModel entrenoeud = nentn105 -SMBModel entrenoeud2 = nentn104 -SMBModel Feuille = feui146 #feui113 -SMBModel Fruit = pommecyl - -Class U = entrenoeud -Class B = entrenoeud -Class E = entrenoeud - -Class Z = Feuille -Class A = Fruit - -LeafClass = Z -FruitClass = A - -LeafAlpha = 45 -LeafBeta = 120 -LeafLength = 100 -LeafTopDiameter = 1000 -LeafBottomDiameter = 1000 - - -Phyllotaxy = 150 - -MinTopDiameter I = 50 -MinBottomDiameter I = 50 - -MinTopDiameter U = 500 -MinBottomDiameter U = 500 - -MinTopDiameter E = 500 -MinBottomDiameter E = 500 - -MinTopDiameter B = 1 -MinBottomDiameter B = 1 - -MinLength C = 5 -MinLength E = 1 -MinLength F = 0 -MinLength B = 5 -MinLength I = 5 -MinLength U = 5 - - -DiameterUnit = 10 -LengthUnit = 1 - -Alpha = Relative - +# Dressing file for apple trees + +#SMBPath = D:/Documents/pradal/devlp/vplants/aml/databases/SMBFiles +SMBPath = ../../../databases/SMBFiles + +SMBModel entrenoeud = nentn105 +SMBModel entrenoeud2 = nentn104 +SMBModel Feuille = feui146 #feui113 +SMBModel Fruit = pommecyl + +Class U = entrenoeud +Class B = entrenoeud +Class E = entrenoeud + +Class Z = Feuille +Class A = Fruit + +LeafClass = Z +FruitClass = A + +LeafAlpha = 45 +LeafBeta = 120 +LeafLength = 100 +LeafTopDiameter = 1000 +LeafBottomDiameter = 1000 + + +Phyllotaxy = 150 + +MinTopDiameter I = 50 +MinBottomDiameter I = 50 + +MinTopDiameter U = 500 +MinBottomDiameter U = 500 + +MinTopDiameter E = 500 +MinBottomDiameter E = 500 + +MinTopDiameter B = 1 +MinBottomDiameter B = 1 + +MinLength C = 5 +MinLength E = 1 +MinLength F = 0 +MinLength B = 5 +MinLength I = 5 +MinLength U = 5 + + +DiameterUnit = 10 +LengthUnit = 1 + +Alpha = Relative + diff --git a/test/data/leaf_axis.drf b/tests/data/leaf_axis.drf similarity index 96% rename from test/data/leaf_axis.drf rename to tests/data/leaf_axis.drf index 4052caa..c7acde0 100644 --- a/test/data/leaf_axis.drf +++ b/tests/data/leaf_axis.drf @@ -1,9 +1,9 @@ -SMBPath = D:/Documents/pradal/devlp/vplants/aml/databases/SMBFiles -#SMBPath = ../../../databases/SMBFiles - -SMBModel feuille = feui136 #feui113 - -# Geometry = ../../../databases/GEOMFiles/leaf.geom -# contains symbol a_leaf - -Class F = feuille +SMBPath = D:/Documents/pradal/devlp/vplants/aml/databases/SMBFiles +#SMBPath = ../../../databases/SMBFiles + +SMBModel feuille = feui136 #feui113 + +# Geometry = ../../../databases/GEOMFiles/leaf.geom +# contains symbol a_leaf + +Class F = feuille diff --git a/test/data/monopodial_plant.mtg b/tests/data/monopodial_plant.mtg similarity index 100% rename from test/data/monopodial_plant.mtg rename to tests/data/monopodial_plant.mtg diff --git a/test/data/mtg1.mtg b/tests/data/mtg1.mtg similarity index 100% rename from test/data/mtg1.mtg rename to tests/data/mtg1.mtg diff --git a/test/data/mtg2.mtg b/tests/data/mtg2.mtg similarity index 100% rename from test/data/mtg2.mtg rename to tests/data/mtg2.mtg diff --git a/test/data/mtg3.mtg b/tests/data/mtg3.mtg similarity index 100% rename from test/data/mtg3.mtg rename to tests/data/mtg3.mtg diff --git a/test/data/mtg4.mtg b/tests/data/mtg4.mtg similarity index 100% rename from test/data/mtg4.mtg rename to tests/data/mtg4.mtg diff --git a/test/data/mtg5.mtg b/tests/data/mtg5.mtg similarity index 100% rename from test/data/mtg5.mtg rename to tests/data/mtg5.mtg diff --git a/test/data/mtg51.mtg b/tests/data/mtg51.mtg similarity index 100% rename from test/data/mtg51.mtg rename to tests/data/mtg51.mtg diff --git a/test/data/mtg_dynamic.mtg b/tests/data/mtg_dynamic.mtg similarity index 100% rename from test/data/mtg_dynamic.mtg rename to tests/data/mtg_dynamic.mtg diff --git a/test/data/noyer.drf b/tests/data/noyer.drf similarity index 95% rename from test/data/noyer.drf rename to tests/data/noyer.drf index 4893131..6996b10 100644 --- a/test/data/noyer.drf +++ b/tests/data/noyer.drf @@ -1,9 +1,9 @@ -# Dressing file for WalnuTree trees - -#SMBPath = D:/Documents/pradal/devlp/vplants/aml/databases/SMBFiles -#SMBPath = ../../databases/SMBFiles - -#SMBModel entrenoeud = nentn105 - -DiameterUnit = 10 - +# Dressing file for WalnuTree trees + +#SMBPath = D:/Documents/pradal/devlp/vplants/aml/databases/SMBFiles +#SMBPath = ../../databases/SMBFiles + +#SMBModel entrenoeud = nentn105 + +DiameterUnit = 10 + diff --git a/test/data/oaktree.drf b/tests/data/oaktree.drf similarity index 93% rename from test/data/oaktree.drf rename to tests/data/oaktree.drf index 2ada80f..2e4b715 100644 --- a/test/data/oaktree.drf +++ b/tests/data/oaktree.drf @@ -1,22 +1,22 @@ -# Dressing file for oak trees - -SMBPath = D:/Documents/pradal/devlp/vplants/aml/databases/SMBFiles -#SMBPath = ../../databases/SMBFiles - -SMBModel node = nentn105 -SMBModel leaf = fchene - -Class Z = leaf - -LeafClass = Z - -MinTopDiameter E = 1 -MinBottomDiameter E = 1 - -MinLength E = 10 - -DiameterUnit = 10 -LengthUnit = 1 - - - +# Dressing file for oak trees + +SMBPath = D:/Documents/pradal/devlp/vplants/aml/databases/SMBFiles +#SMBPath = ../../databases/SMBFiles + +SMBModel node = nentn105 +SMBModel leaf = fchene + +Class Z = leaf + +LeafClass = Z + +MinTopDiameter E = 1 +MinBottomDiameter E = 1 + +MinLength E = 10 + +DiameterUnit = 10 +LengthUnit = 1 + + + diff --git a/test/data/origin.drf b/tests/data/origin.drf similarity index 90% rename from test/data/origin.drf rename to tests/data/origin.drf index 34c5d57..3fa1f87 100644 --- a/test/data/origin.drf +++ b/tests/data/origin.drf @@ -1,7 +1,7 @@ -MinTopDiameter E = 10 -MinBottomDiameter E = 10 -MinLength E = 10 - - - - +MinTopDiameter E = 10 +MinBottomDiameter E = 10 +MinLength E = 10 + + + + diff --git a/test/data/reconstructed_appletree.mtg b/tests/data/reconstructed_appletree.mtg similarity index 97% rename from test/data/reconstructed_appletree.mtg rename to tests/data/reconstructed_appletree.mtg index 0439667..fe4b44f 100644 --- a/test/data/reconstructed_appletree.mtg +++ b/tests/data/reconstructed_appletree.mtg @@ -1,481 +1,481 @@ -CODE : FORM-A - -CLASSES : -SYMBOL SCALE DECOMPOSITION INDEXATION DEFINITION -$ 0 FREE FREE IMPLICIT -P 1 FREE FREE EXPLICIT -B 2 FREE FREE EXPLICIT -S 3 FREE FREE EXPLICIT - -DESCRIPTION : -LEFT RIGHT RELTYPE MAX -P P < ? -P P + ? -B B < ? -B B + ? -S S < ? -S S + ? - -FEATURES : -NAME TYPE -XX REAL -YY REAL -ZZ REAL - -MTG : -ENTITY-CODE XX YY ZZ -/P1 - /B1 - /S1 0.109826 0.0258136 -0.359779 - ^ s2: - # v1 is not an ancestor of v2 (resp v2, v1) - return iter([]) - - return iter(l1[:l1.index(v2)]) - -def edge_type(g,v): - return g.property('edge_type').get(v) - -def order(g, v1, v2=None): - return sum(1 for v in path(g,v1,v2) if edge_type(g,v)=='+') - -def rank(g, v1, v2=None): - return sum(1 for v in path(g,v1,v2) if edge_type(g,v)=='<') - -def height(g, v1, v2=None): - return sum(1 for v in path(g,v1,v2)) - -def reindex(g): - vtxs = list(traversal.iter_mtg2(g,g.root)) - mapping = dict(list(zip(vtxs, list(range(len(g)))))) - return g.reindex(mapping, copy=True) - + +import os, sys + +from openalea.mtg import * + + +g = MTG() +v = random_tree(g, g.root, 3, 900) +g = random_mtg(g, 4) + +# Question +# order: + +def ancestors(g, v1): + " Return the vertices from v1 to the root. " + v = v1 + while v is not None: + yield v + v = g.parent(v) + +def path(g, v1, v2=None): + if v2 is None: + return ancestors(g,v1) + + l1= list(ancestors(g,v1)) + l2 = list(ancestors(g,v2)) + s1 = set(l1) + s2 = set(l2) + + if s1 < s2: + l1, l2 = l2, l1 + s1, s2 = s2, s1 + v1, v2 = v2, v1 + elif not s1 > s2: + # v1 is not an ancestor of v2 (resp v2, v1) + return iter([]) + + return iter(l1[:l1.index(v2)]) + +def edge_type(g,v): + return g.property('edge_type').get(v) + +def order(g, v1, v2=None): + return sum(1 for v in path(g,v1,v2) if edge_type(g,v)=='+') + +def rank(g, v1, v2=None): + return sum(1 for v in path(g,v1,v2) if edge_type(g,v)=='<') + +def height(g, v1, v2=None): + return sum(1 for v in path(g,v1,v2)) + +def reindex(g): + vtxs = list(traversal.iter_mtg2(g,g.root)) + mapping = dict(list(zip(vtxs, list(range(len(g)))))) + return g.reindex(mapping, copy=True) + diff --git a/test/simple.lpy b/tests/simple.lpy similarity index 96% rename from test/simple.lpy rename to tests/simple.lpy index 9729f46..f9813a0 100644 --- a/test/simple.lpy +++ b/tests/simple.lpy @@ -1,69 +1,69 @@ -import openalea.plantgl.all as pgl -import random -def bezier_leaf(): - Vector4 = pgl.Vector4 - l= [] - l.append( [ Vector4(-0.00170203,0.00487903,-0.00155362,1), - Vector4(-0.00946124,0.0267487,0.00857975,1), - Vector4(-0.0145598,0.0310762,0.0565383,1), - Vector4(-0.00422035,0.0237428,0.101953,1) ]) - l.append( [ Vector4(3.9604e-05,0.0019996,5.60056e-06,1), - Vector4(-0.00466331,0.00703859,0.0339818,1), - Vector4(-0.00868596,0.00523895,0.076457,1), - Vector4(0.00379859,0.00943444,0.154352,1) ]) - l.append([ Vector4( -3.9604e-05,-0.0019996,-5.60056e-06,1), - Vector4(-0.00493527,0.00263947,0.0352765,1), - Vector4(-0.00867663,0.00259947,0.0760139,1), - Vector4(0.00447972,0.00923447,0.156651,1) ]) - l.append([Vector4(-0.00218137,-0.00475904,0.000459084,1), - Vector4(-0.0120507,-0.0206578,0.0115464,1), - Vector4(-0.0150292,-0.0230562,0.0604107,1), - Vector4(-0.00608397,-0.0102688,0.102558,1)]) - - matrix= pgl.Point4Matrix(4,4) - for i,row in enumerate(l): - for j,pt in enumerate(row): - pt= pt*9 - pt.w=1 - matrix[i,j] = pt - - leaf= pgl.Scaled(pgl.Vector3(1,1,1)*1.5,pgl.BezierPatch(matrix,4,4)) - - leaf.name='leaf' - - return leaf - -leaf = bezier_leaf() - -phi=120 -alpha = 0 -Axiom: PA - -derivation length: 6 -production: -A : - global phi - produce AN[/(phi)+ANL][/(2*phi)+ANL][/(3*phi)+ANL]AL - phi+=20 - -N: - a0 = 120* random.random() - a1= 120+a0 - a2 = a1+120 - a3=a2+120 - produce N[/(a1)+L][/(a2)+L][/(a3)+L]N - - -homomorphism: -N: - produce ;(1)F - -L: - produce ;(2)@g(leaf) - -endlsystem -###### INITIALISATION ###### - -def __initialiseContext__(context): - from openalea.plantgl.all import Material,Color3 - context.options.setSelection("Selection Required",0) +import openalea.plantgl.all as pgl +import random +def bezier_leaf(): + Vector4 = pgl.Vector4 + l= [] + l.append( [ Vector4(-0.00170203,0.00487903,-0.00155362,1), + Vector4(-0.00946124,0.0267487,0.00857975,1), + Vector4(-0.0145598,0.0310762,0.0565383,1), + Vector4(-0.00422035,0.0237428,0.101953,1) ]) + l.append( [ Vector4(3.9604e-05,0.0019996,5.60056e-06,1), + Vector4(-0.00466331,0.00703859,0.0339818,1), + Vector4(-0.00868596,0.00523895,0.076457,1), + Vector4(0.00379859,0.00943444,0.154352,1) ]) + l.append([ Vector4( -3.9604e-05,-0.0019996,-5.60056e-06,1), + Vector4(-0.00493527,0.00263947,0.0352765,1), + Vector4(-0.00867663,0.00259947,0.0760139,1), + Vector4(0.00447972,0.00923447,0.156651,1) ]) + l.append([Vector4(-0.00218137,-0.00475904,0.000459084,1), + Vector4(-0.0120507,-0.0206578,0.0115464,1), + Vector4(-0.0150292,-0.0230562,0.0604107,1), + Vector4(-0.00608397,-0.0102688,0.102558,1)]) + + matrix= pgl.Point4Matrix(4,4) + for i,row in enumerate(l): + for j,pt in enumerate(row): + pt= pt*9 + pt.w=1 + matrix[i,j] = pt + + leaf= pgl.Scaled(pgl.Vector3(1,1,1)*1.5,pgl.BezierPatch(matrix,4,4)) + + leaf.name='leaf' + + return leaf + +leaf = bezier_leaf() + +phi=120 +alpha = 0 +Axiom: PA + +derivation length: 6 +production: +A : + global phi + produce AN[/(phi)+ANL][/(2*phi)+ANL][/(3*phi)+ANL]AL + phi+=20 + +N: + a0 = 120* random.random() + a1= 120+a0 + a2 = a1+120 + a3=a2+120 + produce N[/(a1)+L][/(a2)+L][/(a3)+L]N + + +homomorphism: +N: + produce ;(1)F + +L: + produce ;(2)@g(leaf) + +endlsystem +###### INITIALISATION ###### + +def __initialiseContext__(context): + from openalea.plantgl.all import Material,Color3 + context.options.setSelection("Selection Required",0) diff --git a/test/test_aml.py b/tests/test_aml.py similarity index 95% rename from test/test_aml.py rename to tests/test_aml.py index 4759751..cf1035e 100644 --- a/test/test_aml.py +++ b/tests/test_aml.py @@ -1,179 +1,179 @@ -# -*- python -*- -# -# OpenAlea.mtg -# -# Copyright 2008 INRIA - CIRAD - INRA -# -# File author(s): Christophe Pradal -# -# Distributed under the Cecill-C License. -# See accompanying file LICENSE.txt or copy at -# http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html -# -# OpenAlea WebSite : http://openalea.gforge.inria.fr -# -################################################################################ - -from glob import glob -from os.path import basename - -from openalea.mtg.mtg import * -import openalea.mtg.aml as wrap -import openalea.aml as aml - - -excludes = """ -mtg51.mtg:Descendants -mtg51.mtg:Extremities -mtg51.mtg:Sons -mtg51.mtg:Height -mtg51.mtg:Order -mtg51.mtg:Father -mtg51.mtg:Ancestors -mtg51.mtg:Root -test11_wij10.mtg:Sons -test11_wij10.mtg:Descendants -test11_wij10.mtg:Extremities -test11_wij10.mtg:Height -test11_wij10.mtg:Order -test11_wij10.mtg:Father -test11_wij10.mtg:Ancestors -test11_wij10.mtg:Root -test11_wij10.mtg:Axis -test11_wij10.mtg:Successor -test11_wij10.mtg:Rank -test11_wij10.mtg:Predecessor - -""".split() -excludes = [l.split(':') for l in excludes] -excludes = [] - -def compare(func_name, *args, **kwds): - """Apply the same function to the two modules with the same args. - TODO: Add customizable comment, and a cmp function. - """ - rnew = wrap.__dict__[func_name](*args, **kwds) - raml = aml.__dict__[func_name](*args, **kwds) - - params = [] - if args: - params.extend((str(x) for x in args)) - if kwds: - params.extend(('%s=%s'%(k,v) for k, v in kwds.items())) - - f = func_name+'('+','.join(params)+')' - try: - assert (rnew == raml) or set(rnew) == set(raml) , 'Method %s -> %s != %s'%(f,rnew,raml) - except: - assert (rnew == raml), 'Method %s -> %s != %s'%(f,rnew,raml) - -def check(fn): - " Compare result with the AML library. " - - g = wrap.MTG(fn) - g1 = aml.MTG(fn) - - # Test root - compare('MTGRoot') - - nb_scales = g.nb_scales() - - # Test VtxList at each scale - for scale in range(1,nb_scales): - compare('VtxList', Scale=scale) - - # Test VtxList at all scales - compare('VtxList') - - vtxs = aml.VtxList() - - methods = """ - Class - Index - Scale - - Rank - Height - Order - - Defined - Father - Successor - Predecessor - Complex - Sons - Ancestors - ComponentRoots - Descendants - Extremities - Root - Axis - Components - """.split() - - methods = [ m for m in methods if [basename(fn), m] not in excludes] - - """ - Trunk - Location - Path # require 2 arguments - """ - i= vtxs.index(g.root) - del vtxs[i] - for v in vtxs: - for m in methods: - compare(m,v) - return g - -def test1(): - fn='data/mtg1.mtg' - g = wrap.MTG(fn) - - root = wrap.MTGRoot() - assert root == 0 - - g1 = wrap.Activate(g) - assert g1 is g - - g1 = wrap.Active() - assert g1 is g - - vtxs = wrap.VtxList(Scale=0) - assert len(vtxs) == 1, "The root node 0" - - vtxs = wrap.VtxList(Scale=1) - assert len(vtxs) == 6 - - for vtx in vtxs: - assert wrap.Class(vtx) == 'A' - assert wrap.Index(vtx) == 1 - assert wrap.Scale(vtx) == 1 - - props = ['diam', 'nbEl'] - for vid in vtxs: - for p in props: - wrap.Feature(vid,p) - - for i in range(len(vtxs)-1): - assert wrap.EdgeType(vtxs[i],vtxs[i+1]) == '<' - - for vid in vtxs: - assert wrap.Defined(vid) - assert wrap.Order(vid) == 0 - assert wrap.AlgOrder(1,vid) == 0 - - for i, vid in enumerate(vtxs): - assert wrap.Rank(vid) == wrap.Height(vid) == i - - for i, vid in enumerate(vtxs): - assert wrap.AlgRank(1,vid) == - wrap.AlgRank(vid,1) == i - -def test(): - files = glob('data/*.mtg') - exclude = ''' - reconstructed_appletree.mtg - '''.split() - files = [f for f in files for e in exclude if e not in f] - for fn in files: - yield check, fn - +# -*- python -*- +# +# OpenAlea.mtg +# +# Copyright 2008 INRIA - CIRAD - INRA +# +# File author(s): Christophe Pradal +# +# Distributed under the Cecill-C License. +# See accompanying file LICENSE.txt or copy at +# http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html +# +# OpenAlea WebSite : http://openalea.gforge.inria.fr +# +################################################################################ + +from glob import glob +from os.path import basename + +from openalea.mtg.mtg import * +import openalea.mtg.aml as wrap +import openalea.aml as aml + + +excludes = """ +mtg51.mtg:Descendants +mtg51.mtg:Extremities +mtg51.mtg:Sons +mtg51.mtg:Height +mtg51.mtg:Order +mtg51.mtg:Father +mtg51.mtg:Ancestors +mtg51.mtg:Root +test11_wij10.mtg:Sons +test11_wij10.mtg:Descendants +test11_wij10.mtg:Extremities +test11_wij10.mtg:Height +test11_wij10.mtg:Order +test11_wij10.mtg:Father +test11_wij10.mtg:Ancestors +test11_wij10.mtg:Root +test11_wij10.mtg:Axis +test11_wij10.mtg:Successor +test11_wij10.mtg:Rank +test11_wij10.mtg:Predecessor + +""".split() +excludes = [l.split(':') for l in excludes] +excludes = [] + +def compare(func_name, *args, **kwds): + """Apply the same function to the two modules with the same args. + TODO: Add customizable comment, and a cmp function. + """ + rnew = wrap.__dict__[func_name](*args, **kwds) + raml = aml.__dict__[func_name](*args, **kwds) + + params = [] + if args: + params.extend((str(x) for x in args)) + if kwds: + params.extend(('%s=%s'%(k,v) for k, v in kwds.items())) + + f = func_name+'('+','.join(params)+')' + try: + assert (rnew == raml) or set(rnew) == set(raml) , 'Method %s -> %s != %s'%(f,rnew,raml) + except: + assert (rnew == raml), 'Method %s -> %s != %s'%(f,rnew,raml) + +def check(fn): + " Compare result with the AML library. " + + g = wrap.MTG(fn) + g1 = aml.MTG(fn) + + # Test root + compare('MTGRoot') + + nb_scales = g.nb_scales() + + # Test VtxList at each scale + for scale in range(1,nb_scales): + compare('VtxList', Scale=scale) + + # Test VtxList at all scales + compare('VtxList') + + vtxs = aml.VtxList() + + methods = """ + Class + Index + Scale + + Rank + Height + Order + + Defined + Father + Successor + Predecessor + Complex + Sons + Ancestors + ComponentRoots + Descendants + Extremities + Root + Axis + Components + """.split() + + methods = [ m for m in methods if [basename(fn), m] not in excludes] + + """ + Trunk + Location + Path # require 2 arguments + """ + i= vtxs.index(g.root) + del vtxs[i] + for v in vtxs: + for m in methods: + compare(m,v) + return g + +def test1(): + fn='data/mtg1.mtg' + g = wrap.MTG(fn) + + root = wrap.MTGRoot() + assert root == 0 + + g1 = wrap.Activate(g) + assert g1 is g + + g1 = wrap.Active() + assert g1 is g + + vtxs = wrap.VtxList(Scale=0) + assert len(vtxs) == 1, "The root node 0" + + vtxs = wrap.VtxList(Scale=1) + assert len(vtxs) == 6 + + for vtx in vtxs: + assert wrap.Class(vtx) == 'A' + assert wrap.Index(vtx) == 1 + assert wrap.Scale(vtx) == 1 + + props = ['diam', 'nbEl'] + for vid in vtxs: + for p in props: + wrap.Feature(vid,p) + + for i in range(len(vtxs)-1): + assert wrap.EdgeType(vtxs[i],vtxs[i+1]) == '<' + + for vid in vtxs: + assert wrap.Defined(vid) + assert wrap.Order(vid) == 0 + assert wrap.AlgOrder(1,vid) == 0 + + for i, vid in enumerate(vtxs): + assert wrap.Rank(vid) == wrap.Height(vid) == i + + for i, vid in enumerate(vtxs): + assert wrap.AlgRank(1,vid) == - wrap.AlgRank(vid,1) == i + +def test(): + files = glob('data/*.mtg') + exclude = ''' + reconstructed_appletree.mtg + '''.split() + files = [f for f in files for e in exclude if e not in f] + for fn in files: + yield check, fn + diff --git a/test/test_dresser.py b/tests/test_dresser.py similarity index 94% rename from test/test_dresser.py rename to tests/test_dresser.py index 8f4be21..eb4ae9e 100644 --- a/test/test_dresser.py +++ b/tests/test_dresser.py @@ -1,32 +1,32 @@ -from openalea.mtg.plantframe.dresser import * -import pytest - -def test1(): - fn = r'data/wij10.drf' - f = open(fn) - - dr = dressing_data(f) - - f.close() - return dr - -def files_to_check(): - try: - from path import Path as path - except: - from openalea.core.path import path - dir = path('data') - files = dir.glob('*.drf') - return files - -@pytest.mark.parametrize('fn', list(files_to_check())) -def test_create_dressing_data(fn): - f = open(fn) - - dr = dressing_data(f) - - f.close() - assert dr - - - +from openalea.mtg.plantframe.dresser import * +import pytest + +def test1(): + fn = r'data/wij10.drf' + f = open(fn) + + dr = dressing_data(f) + + f.close() + return dr + +def files_to_check(): + try: + from path import Path as path + except: + from openalea.core.path import path + dir = path('data') + files = dir.glob('*.drf') + return files + +@pytest.mark.parametrize('fn', list(files_to_check())) +def test_create_dressing_data(fn): + f = open(fn) + + dr = dressing_data(f) + + f.close() + assert dr + + + diff --git a/test/test_edition.py b/tests/test_edition.py similarity index 100% rename from test/test_edition.py rename to tests/test_edition.py diff --git a/test/test_lsystem.py b/tests/test_lsystem.py similarity index 97% rename from test/test_lsystem.py rename to tests/test_lsystem.py index a35dc31..10f18c0 100644 --- a/test/test_lsystem.py +++ b/tests/test_lsystem.py @@ -1,264 +1,264 @@ -import openalea.mtg.io as io -import openalea.plantgl.all as pgl - -symbols = {'newPlant' : 1, 'newAxe' : 2, 'newMetamer' :3, 'StemElement':4, 'LeafElement':4} -functions = {} - - -def StemElement(optical_species, length, diameter_base, diameter_top ): - mesh = None - if length > 0 and diameter_base > 0: - cylinder = pgl.Cylinder(height = length, radius = diameter_base/2.) - tess = pgl.Tesselator() - cylinder.apply(tess) - mesh = tess.triangulation - return {'geometry':mesh} - -def LeafElement(optical_species, final_length, radius_max, s_base, s_top, leaf_rank, seed ): - mesh = None - length = final_length * (s_top - s_base) - if length > 0 and radius_max > 0: - cylinder = pgl.Cylinder(height = length, radius = radius_max) - tess = pgl.Tesselator() - cylinder.apply(tess) - mesh = tess.triangulation - return {'geometry':mesh} - -functions['StemElement'] = StemElement -functions['LeafElement'] = LeafElement - - -def check_connectivity(g): - for scale in g.scales(): - assert len(list(g.roots(scale=scale))) == 1, 'g.roots(scale=%d) != %d'%(scale, len(list(g.roots(scale=scale)))) - -def test0(): - # simple set of two successives axes - s = """ -newPlant -[+(45)newAxe -] -""" - g = io.read_lsystem_string(s, symbols) - assert len(g) == 3 - assert g.nb_vertices(scale=1)==1 - assert g.nb_vertices(scale=2)==1 - check_connectivity(g) - -def test1(): - s = """ -newPlant -[+(45)newAxe -newMetamer -StemElement(1,0.000000,0.04,0.04) - [+(45)newAxe - ] -StemElement(1,0.436111,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,7.665278,0.346528,0.000000,1,10,0.5)] -newMetamer -StemElement(1,0.000000,0.04,0.04) - [+(45)newAxe - ] -StemElement(1,0.000000,0.04,0.04)[/(0.000000)+(0.631719)LeafElement(1,10.050000,0.383524,0.368281,1,9,0.5)] -newMetamer -StemElement(1,0.000000,0.04,0.04) - [+(45)newAxe - ] -StemElement(1,0.000000,0.04,0.04)[/(180.000000)+(0.000000)LeafElement(1,7.900000,0.455263,1.000000,1,8,0.5)] -] -""" - g = io.read_lsystem_string(s, symbols) - assert len(g) == 18 - assert g.nb_scales() == 5 - assert g.max_scale() == 4 - assert g.nb_vertices(scale=1)==1 - assert g.nb_vertices(scale=2)==4 - assert g.nb_vertices(scale=3)==3 - assert g.nb_vertices(scale=4)==9 - check_connectivity(g) - -def test2(): - s = """ -newPlant -[+(45)newAxe -newMetamer -StemElement(1,0.000000,0.04,0.04) - [+(45)newAxe - ] -StemElement(1,0.436111,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,7.665278,0.346528,0.000000,1,10,0.5)] -""" - g = io.read_lsystem_string(s, symbols) - assert len(g) == 8 - assert g.nb_scales() == 5 - assert g.max_scale() == 4 - assert g.nb_vertices(scale=1)==1 - assert g.nb_vertices(scale=2)==2 - assert g.nb_vertices(scale=3)==1 - assert g.nb_vertices(scale=4)==3 - check_connectivity(g) - -def test3(): - s = """ -newPlant -[+(45)newAxe -newMetamer -StemElement(1,0.000000,0.04,0.04) - [+(45)newAxe - ] -StemElement(1,0.436111,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,7.665278,0.346528,0.000000,1,10,0.5)] -newMetamer - -""" - g = io.read_lsystem_string(s, symbols) - assert len(g) == 9 - assert g.nb_scales() == 5 - assert g.max_scale() == 4 - assert g.nb_vertices(scale=1)==1 - assert g.nb_vertices(scale=2)==2 - assert g.nb_vertices(scale=3)==2 - assert g.nb_vertices(scale=4)==3 - check_connectivity(g) - -def test4(): - s = """ -newPlant -[+(45)newAxe -newMetamer -StemElement(1,0.000000,0.04,0.04) - [+(45)newAxe - ] -StemElement(1,0.436111,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,7.665278,0.346528,0.000000,1,10,0.5)] -newMetamer -StemElement(1,0.000000,0.04,0.04) - [+(45)newAxe - ] -StemElement(1,0.000000,0.04,0.04)[/(0.000000)+(0.631719)LeafElement(1,10.050000,0.383524,0.368281,1,9,0.5)] -""" - g = io.read_lsystem_string(s, symbols) - assert len(g) ==13 - assert g.nb_scales() == 5 - assert g.max_scale() == 4 - assert g.nb_vertices(scale=1)==1 - assert g.nb_vertices(scale=2)==3 - assert g.nb_vertices(scale=3)==2 - assert g.nb_vertices(scale=4)==6 - check_connectivity(g) - -def test5(): - s=""" -newPlant -[+(45)newAxe -newMetamer -StemElement(1,0.000000,0.04,0.04) - [+(45)newAxe - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,0.540000,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,5.095000,0.308000,0.000000,1,7,0.5)]]] -""" - g = io.read_lsystem_string(s, symbols) - assert len(g) ==10 - assert g.nb_scales() == 5 - assert g.max_scale() == 4 - assert g.nb_vertices(scale=1)==1 - assert g.nb_vertices(scale=2)==2 - assert g.nb_vertices(scale=3)==2 - assert g.nb_vertices(scale=4)==4 - check_connectivity(g) - -def test6(): - s=""" -newPlant -[+(45)newAxe -newMetamer -StemElement(1,0.000000,0.04,0.04) - [+(45)newAxe - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,0.540000,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,5.095000,0.308000,0.000000,1,7,0.5)]]] -""" - s = s+s+s - g = io.read_lsystem_string(s, symbols) - - #assert len(g) ==10 - assert g.nb_scales() == 5 - assert g.max_scale() == 4 - assert g.nb_vertices(scale=1)==1*3 - assert g.nb_vertices(scale=2)==2*3 - assert g.nb_vertices(scale=3)==2*3 - assert g.nb_vertices(scale=4)==4*3 - assert g.nb_vertices(scale=1) == len(list(g.roots(scale=4))) - - -def test_full(): - s=""" -newPlant -[newAxe -newMetamer -StemElement(1,0.000000,0.04,0.04) - [+(45)newAxe - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,0.540000,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,5.095000,0.308000,0.000000,1,7,0.5)] - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,0.559999,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,7.075000,0.401579,0.000000,1,6,0.5)] - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,1.361539,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,9.000000,0.522500,0.000000,1,5,0.5)] - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,3.838462,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,11.800000,0.766154,0.000000,1,4,0.5)] - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,6.982353,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,17.000000,1.015882,0.000000,1,3,0.5)] - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,6.417647,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,18.900000,1.062400,0.000000,1,2,0.5)] - newMetamer - StemElement(1,1.300000,0.04,0.04)StemElement(1,12.999998,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,20.647058,1.135625,0.000000,1,1,0.5)] - newMetamer - StemElement(1,4.700003,0.04,0.04)StemElement(1,14.000000,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,20.799999,1.235000,0.000000,1,0,0.5)] - ] -StemElement(1,0.436111,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,7.665278,0.346528,0.000000,1,10,0.5)] -newMetamer -StemElement(1,0.000000,0.04,0.04) - [+(-45)newAxe - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,0.398890,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,5.525000,0.312500,0.000000,1,7,0.5)] - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,0.588077,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,7.850000,0.424400,0.000000,1,6,0.5)] - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,3.448352,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,9.750000,0.640714,0.000000,1,5,0.5)] - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,3.323809,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,14.100000,0.900952,0.000000,1,4,0.5)] - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,3.104762,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,17.500000,1.037917,0.000000,1,3,0.5)] - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,10.650002,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,19.900000,1.116250,0.000000,1,2,0.5)] - newMetamer - StemElement(1,0.000000,0.04,0.04)StemElement(1,13.549996,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,22.100000,1.195714,0.000000,1,1,0.5)] - newMetamer - StemElement(1,3.200003,0.04,0.04)StemElement(1,16.500000,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,16.500000,1.325714,0.000000,1,0,0.5)] - ] -StemElement(1,0.000000,0.04,0.04)[/(0.000000)+(0.993730)LeafElement(1,10.050000,0.383524,0.006270,1,9,0.5)] -newMetamer -StemElement(1,0.000000,0.04,0.04)StemElement(1,0.000000,0.04,0.04)[/(180.000000)+(0.999426)LeafElement(1,7.900000,0.455263,0.000574,1,8,0.5)] -newMetamer -StemElement(1,0.000000,0.04,0.04)StemElement(1,0.743889,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,7.800000,0.358000,0.000000,1,7,0.5)] -newMetamer -StemElement(1,0.000000,0.04,0.04)StemElement(1,0.679999,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,8.550000,0.523333,0.000000,1,6,0.5)] -newMetamer -StemElement(1,0.000000,0.04,0.04)StemElement(1,2.518572,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,9.700000,0.714286,0.000000,1,5,0.5)] -newMetamer -StemElement(1,0.000000,0.04,0.04)StemElement(1,3.344506,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,13.100000,1.014286,0.000000,1,4,0.5)] -newMetamer -StemElement(1,0.000000,0.04,0.04)StemElement(1,3.076922,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,17.400000,1.104286,0.000000,1,3,0.5)] -newMetamer -StemElement(1,0.000000,0.04,0.04)StemElement(1,10.900000,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,20.200001,1.196552,0.000000,1,2,0.5)] -newMetamer -StemElement(1,0.000000,0.04,0.04)StemElement(1,13.800000,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,23.216667,1.302667,0.000000,1,1,0.5)] -newMetamer -StemElement(1,3.200001,0.04,0.04)StemElement(1,16.250000,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,19.549999,1.438667,0.000000,1,0,0.5)] -] -""" - g = io.read_lsystem_string(s, symbols, functions) - assert len(g) ==113 - assert g.nb_scales() == 5 - assert g.max_scale() == 4 - assert g.nb_vertices(scale=1)==1 - assert g.nb_vertices(scale=2)==3 - assert g.nb_vertices(scale=3)==27 - assert g.nb_vertices(scale=4)==81 - check_connectivity(g) - +import openalea.mtg.io as io +import openalea.plantgl.all as pgl + +symbols = {'newPlant' : 1, 'newAxe' : 2, 'newMetamer' :3, 'StemElement':4, 'LeafElement':4} +functions = {} + + +def StemElement(optical_species, length, diameter_base, diameter_top ): + mesh = None + if length > 0 and diameter_base > 0: + cylinder = pgl.Cylinder(height = length, radius = diameter_base/2.) + tess = pgl.Tesselator() + cylinder.apply(tess) + mesh = tess.triangulation + return {'geometry':mesh} + +def LeafElement(optical_species, final_length, radius_max, s_base, s_top, leaf_rank, seed ): + mesh = None + length = final_length * (s_top - s_base) + if length > 0 and radius_max > 0: + cylinder = pgl.Cylinder(height = length, radius = radius_max) + tess = pgl.Tesselator() + cylinder.apply(tess) + mesh = tess.triangulation + return {'geometry':mesh} + +functions['StemElement'] = StemElement +functions['LeafElement'] = LeafElement + + +def check_connectivity(g): + for scale in g.scales(): + assert len(list(g.roots(scale=scale))) == 1, 'g.roots(scale=%d) != %d'%(scale, len(list(g.roots(scale=scale)))) + +def test0(): + # simple set of two successives axes + s = """ +newPlant +[+(45)newAxe +] +""" + g = io.read_lsystem_string(s, symbols) + assert len(g) == 3 + assert g.nb_vertices(scale=1)==1 + assert g.nb_vertices(scale=2)==1 + check_connectivity(g) + +def test1(): + s = """ +newPlant +[+(45)newAxe +newMetamer +StemElement(1,0.000000,0.04,0.04) + [+(45)newAxe + ] +StemElement(1,0.436111,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,7.665278,0.346528,0.000000,1,10,0.5)] +newMetamer +StemElement(1,0.000000,0.04,0.04) + [+(45)newAxe + ] +StemElement(1,0.000000,0.04,0.04)[/(0.000000)+(0.631719)LeafElement(1,10.050000,0.383524,0.368281,1,9,0.5)] +newMetamer +StemElement(1,0.000000,0.04,0.04) + [+(45)newAxe + ] +StemElement(1,0.000000,0.04,0.04)[/(180.000000)+(0.000000)LeafElement(1,7.900000,0.455263,1.000000,1,8,0.5)] +] +""" + g = io.read_lsystem_string(s, symbols) + assert len(g) == 18 + assert g.nb_scales() == 5 + assert g.max_scale() == 4 + assert g.nb_vertices(scale=1)==1 + assert g.nb_vertices(scale=2)==4 + assert g.nb_vertices(scale=3)==3 + assert g.nb_vertices(scale=4)==9 + check_connectivity(g) + +def test2(): + s = """ +newPlant +[+(45)newAxe +newMetamer +StemElement(1,0.000000,0.04,0.04) + [+(45)newAxe + ] +StemElement(1,0.436111,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,7.665278,0.346528,0.000000,1,10,0.5)] +""" + g = io.read_lsystem_string(s, symbols) + assert len(g) == 8 + assert g.nb_scales() == 5 + assert g.max_scale() == 4 + assert g.nb_vertices(scale=1)==1 + assert g.nb_vertices(scale=2)==2 + assert g.nb_vertices(scale=3)==1 + assert g.nb_vertices(scale=4)==3 + check_connectivity(g) + +def test3(): + s = """ +newPlant +[+(45)newAxe +newMetamer +StemElement(1,0.000000,0.04,0.04) + [+(45)newAxe + ] +StemElement(1,0.436111,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,7.665278,0.346528,0.000000,1,10,0.5)] +newMetamer + +""" + g = io.read_lsystem_string(s, symbols) + assert len(g) == 9 + assert g.nb_scales() == 5 + assert g.max_scale() == 4 + assert g.nb_vertices(scale=1)==1 + assert g.nb_vertices(scale=2)==2 + assert g.nb_vertices(scale=3)==2 + assert g.nb_vertices(scale=4)==3 + check_connectivity(g) + +def test4(): + s = """ +newPlant +[+(45)newAxe +newMetamer +StemElement(1,0.000000,0.04,0.04) + [+(45)newAxe + ] +StemElement(1,0.436111,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,7.665278,0.346528,0.000000,1,10,0.5)] +newMetamer +StemElement(1,0.000000,0.04,0.04) + [+(45)newAxe + ] +StemElement(1,0.000000,0.04,0.04)[/(0.000000)+(0.631719)LeafElement(1,10.050000,0.383524,0.368281,1,9,0.5)] +""" + g = io.read_lsystem_string(s, symbols) + assert len(g) ==13 + assert g.nb_scales() == 5 + assert g.max_scale() == 4 + assert g.nb_vertices(scale=1)==1 + assert g.nb_vertices(scale=2)==3 + assert g.nb_vertices(scale=3)==2 + assert g.nb_vertices(scale=4)==6 + check_connectivity(g) + +def test5(): + s=""" +newPlant +[+(45)newAxe +newMetamer +StemElement(1,0.000000,0.04,0.04) + [+(45)newAxe + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,0.540000,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,5.095000,0.308000,0.000000,1,7,0.5)]]] +""" + g = io.read_lsystem_string(s, symbols) + assert len(g) ==10 + assert g.nb_scales() == 5 + assert g.max_scale() == 4 + assert g.nb_vertices(scale=1)==1 + assert g.nb_vertices(scale=2)==2 + assert g.nb_vertices(scale=3)==2 + assert g.nb_vertices(scale=4)==4 + check_connectivity(g) + +def test6(): + s=""" +newPlant +[+(45)newAxe +newMetamer +StemElement(1,0.000000,0.04,0.04) + [+(45)newAxe + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,0.540000,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,5.095000,0.308000,0.000000,1,7,0.5)]]] +""" + s = s+s+s + g = io.read_lsystem_string(s, symbols) + + #assert len(g) ==10 + assert g.nb_scales() == 5 + assert g.max_scale() == 4 + assert g.nb_vertices(scale=1)==1*3 + assert g.nb_vertices(scale=2)==2*3 + assert g.nb_vertices(scale=3)==2*3 + assert g.nb_vertices(scale=4)==4*3 + assert g.nb_vertices(scale=1) == len(list(g.roots(scale=4))) + + +def test_full(): + s=""" +newPlant +[newAxe +newMetamer +StemElement(1,0.000000,0.04,0.04) + [+(45)newAxe + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,0.540000,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,5.095000,0.308000,0.000000,1,7,0.5)] + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,0.559999,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,7.075000,0.401579,0.000000,1,6,0.5)] + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,1.361539,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,9.000000,0.522500,0.000000,1,5,0.5)] + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,3.838462,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,11.800000,0.766154,0.000000,1,4,0.5)] + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,6.982353,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,17.000000,1.015882,0.000000,1,3,0.5)] + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,6.417647,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,18.900000,1.062400,0.000000,1,2,0.5)] + newMetamer + StemElement(1,1.300000,0.04,0.04)StemElement(1,12.999998,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,20.647058,1.135625,0.000000,1,1,0.5)] + newMetamer + StemElement(1,4.700003,0.04,0.04)StemElement(1,14.000000,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,20.799999,1.235000,0.000000,1,0,0.5)] + ] +StemElement(1,0.436111,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,7.665278,0.346528,0.000000,1,10,0.5)] +newMetamer +StemElement(1,0.000000,0.04,0.04) + [+(-45)newAxe + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,0.398890,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,5.525000,0.312500,0.000000,1,7,0.5)] + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,0.588077,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,7.850000,0.424400,0.000000,1,6,0.5)] + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,3.448352,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,9.750000,0.640714,0.000000,1,5,0.5)] + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,3.323809,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,14.100000,0.900952,0.000000,1,4,0.5)] + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,3.104762,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,17.500000,1.037917,0.000000,1,3,0.5)] + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,10.650002,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,19.900000,1.116250,0.000000,1,2,0.5)] + newMetamer + StemElement(1,0.000000,0.04,0.04)StemElement(1,13.549996,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,22.100000,1.195714,0.000000,1,1,0.5)] + newMetamer + StemElement(1,3.200003,0.04,0.04)StemElement(1,16.500000,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,16.500000,1.325714,0.000000,1,0,0.5)] + ] +StemElement(1,0.000000,0.04,0.04)[/(0.000000)+(0.993730)LeafElement(1,10.050000,0.383524,0.006270,1,9,0.5)] +newMetamer +StemElement(1,0.000000,0.04,0.04)StemElement(1,0.000000,0.04,0.04)[/(180.000000)+(0.999426)LeafElement(1,7.900000,0.455263,0.000574,1,8,0.5)] +newMetamer +StemElement(1,0.000000,0.04,0.04)StemElement(1,0.743889,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,7.800000,0.358000,0.000000,1,7,0.5)] +newMetamer +StemElement(1,0.000000,0.04,0.04)StemElement(1,0.679999,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,8.550000,0.523333,0.000000,1,6,0.5)] +newMetamer +StemElement(1,0.000000,0.04,0.04)StemElement(1,2.518572,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,9.700000,0.714286,0.000000,1,5,0.5)] +newMetamer +StemElement(1,0.000000,0.04,0.04)StemElement(1,3.344506,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,13.100000,1.014286,0.000000,1,4,0.5)] +newMetamer +StemElement(1,0.000000,0.04,0.04)StemElement(1,3.076922,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,17.400000,1.104286,0.000000,1,3,0.5)] +newMetamer +StemElement(1,0.000000,0.04,0.04)StemElement(1,10.900000,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,20.200001,1.196552,0.000000,1,2,0.5)] +newMetamer +StemElement(1,0.000000,0.04,0.04)StemElement(1,13.800000,0.04,0.04)[/(0.000000)+(45.000000)LeafElement(1,23.216667,1.302667,0.000000,1,1,0.5)] +newMetamer +StemElement(1,3.200001,0.04,0.04)StemElement(1,16.250000,0.04,0.04)[/(180.000000)+(45.000000)LeafElement(1,19.549999,1.438667,0.000000,1,0,0.5)] +] +""" + g = io.read_lsystem_string(s, symbols, functions) + assert len(g) ==113 + assert g.nb_scales() == 5 + assert g.max_scale() == 4 + assert g.nb_vertices(scale=1)==1 + assert g.nb_vertices(scale=2)==3 + assert g.nb_vertices(scale=3)==27 + assert g.nb_vertices(scale=4)==81 + check_connectivity(g) + diff --git a/test/test_mtg.py b/tests/test_mtg.py similarity index 96% rename from test/test_mtg.py rename to tests/test_mtg.py index 03622f7..6d2022d 100644 --- a/test/test_mtg.py +++ b/tests/test_mtg.py @@ -1,227 +1,227 @@ -# -*- python -*- -# -# OpenAlea.mtg -# -# Copyright 2008 INRIA - CIRAD - INRA -# -# File author(s): Christophe Pradal -# -# Distributed under the Cecill-C License. -# See accompanying file LICENSE.txt or copy at -# http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html -# -# OpenAlea WebSite : http://openalea.gforge.inria.fr -# -################################################################################ - -from openalea.mtg.mtg import * -from openalea.mtg.io import * -from openalea.mtg.traversal import * - -def test_mtg_api(): - mtg = MTG() - - root = mtg.root - assert root is not None - assert root == 0, 'default root id (%d) is not 0'%root - - # scale 1 - root1 = mtg.add_component(root) - v1 = mtg.add_child(root1) - v2 = mtg.add_child(root1) - v3 = mtg.add_child(root1) - v4 = mtg.add_child(v1) - v5 = mtg.add_child(v1) - - assert mtg.complex(root1) == root - assert mtg.complex(v1) == root - assert mtg.complex(v2) == root - assert mtg.complex(v3) == root - assert mtg.complex(v4) == root - assert mtg.complex(v5) == root - - assert mtg.parent(v5) == v1 - assert mtg.parent(v4) == v1 - assert mtg.parent(v3) == root1 - assert mtg.parent(v2) == root1 - assert mtg.parent(v1) == root1 - - assert [v1,v2,v3] == list(mtg.children(root1)) - assert [v4,v5] == list(mtg.children(v1)) - assert list(mtg.children(v2)) == list(mtg.children(v3)) == list(mtg.children(v4)) == list(mtg.children(v5)) == [] - - assert len(mtg) == 7, 'len(mtg) == %d'%len(mtg) - -def test_api2(): - mtg = MTG() - root = mtg.root - # scale 1 - root1 = mtg.add_component(root) - v1 = mtg.add_child(root1) - v2 = mtg.add_child(root1) - v3 = mtg.add_child(root1) - v4 = mtg.add_child(v1) - v5 = mtg.add_child(v1) - - assert mtg.nb_components(root) == 6, "nb_components = %d"%(mtg.nb_components(root)) - assert set([root1, v1, v2, v3, v4, v5]) == set(mtg.components(root)) - assert mtg.nb_components(root1) == mtg.nb_components(v1) == mtg.nb_components(v2) == 0 - - -def test_mtg_edition(): - mtg = MTG() - root = mtg.root - - # scale 1, 2 - root1 = mtg.add_component(root) - root2 = mtg.add_component(root1) - v12 = mtg.add_child(root2) - v22 = mtg.add_child(v12) - - v32, v32_complex = mtg.add_child_and_complex(v22) - - assert len(mtg) == 7 - assert v32 in mtg.children(v22) - assert v32_complex in mtg.children(root1) - - -def test_mtg_random(): - g = MTG() - root = g.root - - root1 = g.add_component(root) - root1 = g.add_component(root1) - vid = random_tree(g, root1, nb_vertices=18) - - v1, complex1 = g.add_child_and_complex(vid) - vid = random_tree(g, v1, nb_vertices=18) - - v1, complex1 = g.add_child_and_complex(vid) - vid = random_tree(g, v1, nb_vertices=18) - assert len(g)==61 - -def test_api3(): - ''' Test clear function. ''' - mtg = MTG() - assert len(mtg) == 1, 'len(mtg) == %d'%len(mtg) - v1 = mtg.add_component(mtg.root) - mtg.clear() - assert len(mtg) == 1, 'len(mtg) == %d'%len(mtg) - - v2 = mtg.add_component(mtg.root) - assert v1 == v2 - -def test_traversal(): - mtg = MTG() - mtg = simple_tree(mtg, mtg.root) - - s1 = set(pre_order(mtg, mtg.root)) - s2 = set(post_order(mtg, mtg.root)) - assert len(mtg) == len(s1) == len(s2) - assert s1 == s2 - -def test_components(): - g = MTG() # root = 0 - r1 = g.add_component(g.root) # scale= 1, v=1 - r2 = g.add_component(r1) # scale= 1, v=2 - v, c = g.add_child_and_complex(r2, edge_type='+') - v, c = g.add_child_and_complex(r2) - v1, c1 = g.add_child_and_complex(v, edge_type='+') - v = g.add_child(v) - v1, c1 = g.add_child_and_complex(v, edge_type='+') - v = g.add_child(v) - - -def test_properties(): - mtg = MTG() - root = mtg.root - - root1 = mtg.add_component(root) - vid = random_tree(mtg, root1, nb_vertices=18) - v1, complex1 = mtg.add_child_and_complex(vid) - vid = random_tree(mtg, v1, nb_vertices=18) - v1, complex1 = mtg.add_child_and_complex(vid) - vid = random_tree(mtg, v1, nb_vertices=18) - - assert 'edge_type' in mtg.property_names() - assert len(mtg.property('edge_type')) == 18*3, \ - 'len(mtg.property("edge_type")) == %d'%len(mtg.property('edge_type')) - -def test_edition(): - s = '/A/a +# +# Distributed under the Cecill-C License. +# See accompanying file LICENSE.txt or copy at +# http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html +# +# OpenAlea WebSite : http://openalea.gforge.inria.fr +# +################################################################################ + +from openalea.mtg.mtg import * +from openalea.mtg.io import * +from openalea.mtg.traversal import * + +def test_mtg_api(): + mtg = MTG() + + root = mtg.root + assert root is not None + assert root == 0, 'default root id (%d) is not 0'%root + + # scale 1 + root1 = mtg.add_component(root) + v1 = mtg.add_child(root1) + v2 = mtg.add_child(root1) + v3 = mtg.add_child(root1) + v4 = mtg.add_child(v1) + v5 = mtg.add_child(v1) + + assert mtg.complex(root1) == root + assert mtg.complex(v1) == root + assert mtg.complex(v2) == root + assert mtg.complex(v3) == root + assert mtg.complex(v4) == root + assert mtg.complex(v5) == root + + assert mtg.parent(v5) == v1 + assert mtg.parent(v4) == v1 + assert mtg.parent(v3) == root1 + assert mtg.parent(v2) == root1 + assert mtg.parent(v1) == root1 + + assert [v1,v2,v3] == list(mtg.children(root1)) + assert [v4,v5] == list(mtg.children(v1)) + assert list(mtg.children(v2)) == list(mtg.children(v3)) == list(mtg.children(v4)) == list(mtg.children(v5)) == [] + + assert len(mtg) == 7, 'len(mtg) == %d'%len(mtg) + +def test_api2(): + mtg = MTG() + root = mtg.root + # scale 1 + root1 = mtg.add_component(root) + v1 = mtg.add_child(root1) + v2 = mtg.add_child(root1) + v3 = mtg.add_child(root1) + v4 = mtg.add_child(v1) + v5 = mtg.add_child(v1) + + assert mtg.nb_components(root) == 6, "nb_components = %d"%(mtg.nb_components(root)) + assert set([root1, v1, v2, v3, v4, v5]) == set(mtg.components(root)) + assert mtg.nb_components(root1) == mtg.nb_components(v1) == mtg.nb_components(v2) == 0 + + +def test_mtg_edition(): + mtg = MTG() + root = mtg.root + + # scale 1, 2 + root1 = mtg.add_component(root) + root2 = mtg.add_component(root1) + v12 = mtg.add_child(root2) + v22 = mtg.add_child(v12) + + v32, v32_complex = mtg.add_child_and_complex(v22) + + assert len(mtg) == 7 + assert v32 in mtg.children(v22) + assert v32_complex in mtg.children(root1) + + +def test_mtg_random(): + g = MTG() + root = g.root + + root1 = g.add_component(root) + root1 = g.add_component(root1) + vid = random_tree(g, root1, nb_vertices=18) + + v1, complex1 = g.add_child_and_complex(vid) + vid = random_tree(g, v1, nb_vertices=18) + + v1, complex1 = g.add_child_and_complex(vid) + vid = random_tree(g, v1, nb_vertices=18) + assert len(g)==61 + +def test_api3(): + ''' Test clear function. ''' + mtg = MTG() + assert len(mtg) == 1, 'len(mtg) == %d'%len(mtg) + v1 = mtg.add_component(mtg.root) + mtg.clear() + assert len(mtg) == 1, 'len(mtg) == %d'%len(mtg) + + v2 = mtg.add_component(mtg.root) + assert v1 == v2 + +def test_traversal(): + mtg = MTG() + mtg = simple_tree(mtg, mtg.root) + + s1 = set(pre_order(mtg, mtg.root)) + s2 = set(post_order(mtg, mtg.root)) + assert len(mtg) == len(s1) == len(s2) + assert s1 == s2 + +def test_components(): + g = MTG() # root = 0 + r1 = g.add_component(g.root) # scale= 1, v=1 + r2 = g.add_component(r1) # scale= 1, v=2 + v, c = g.add_child_and_complex(r2, edge_type='+') + v, c = g.add_child_and_complex(r2) + v1, c1 = g.add_child_and_complex(v, edge_type='+') + v = g.add_child(v) + v1, c1 = g.add_child_and_complex(v, edge_type='+') + v = g.add_child(v) + + +def test_properties(): + mtg = MTG() + root = mtg.root + + root1 = mtg.add_component(root) + vid = random_tree(mtg, root1, nb_vertices=18) + v1, complex1 = mtg.add_child_and_complex(vid) + vid = random_tree(mtg, v1, nb_vertices=18) + v1, complex1 = mtg.add_child_and_complex(vid) + vid = random_tree(mtg, v1, nb_vertices=18) + + assert 'edge_type' in mtg.property_names() + assert len(mtg.property('edge_type')) == 18*3, \ + 'len(mtg.property("edge_type")) == %d'%len(mtg.property('edge_type')) + +def test_edition(): + s = '/A/a F', 0) - geom_tree = l.homomorphism(tree) - scene = l.sceneInterpretation(geom_tree) - scale = dict(list(zip(('P','A','N', 'L', 'F'),(1,2,3,3,3)))) - mtg = axialtree2mtg(tree, scale, scene) - return tree, mtg, scene - - - -def str2mss(s, envelop): - tree, mtg, scene = str2mtg(s) - return mtg2mss('test', mtg, scene, envelop), mtg, tree, s - -def check(tree, mtg, scene): - s = str(tree) - n1, n2 = [s.count(char) for char in ['P', 'A']] - n3 = s.count('N') + s.count('L') + s.count('F') - assert mtg.nb_vertices(scale=1) == n1, '%d, %d'%(mtg.nb_vertices(scale=1), n1 ) - assert mtg.nb_vertices(scale=2) == n2, '%d, %d'%(mtg.nb_vertices(scale=2), n2 ) - assert mtg.nb_vertices(scale=3) == n3, '%d, %d'%(mtg.nb_vertices(scale=3), n3) - v3 = set(mtg.vertices(scale=3)) - geom3 = set((sh.id for sh in scene)) - assert v3 == geom3, str(v3)+'!='+str(geom3) - -def check_mss(mss, mtg, tree, s=None): - if not mss: print(tree) - assert mss.depth == mtg.max_scale() - for scale in range(1,mss.depth+1): - assert len(set(mss.get1Scale(scale))) == len(set(mtg.vertices(scale=scale))), (str(set(mss.get1Scale(scale)))+' !='+ str(set(mtg.vertices(scale=scale))),s) - - -def test0(): - # simple set of two successives axes - trees = ''' -PANNN[+ANNN][-ANNN]AN -PANNN[+ANNN][-ANNN]NNNANAN -PANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]AN -PANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]ANPANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]ANPANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]AN -PANNN[+ANNN[+ANNN[+ANNN][-ANNN]NNNANAN]][-ANNN[+ANNN[-ANNN]]NN]NANAN -''' - for s in trees.split(): - check( *str2mtg(s) ) - -def test1(): - # simple set of two successives axes - trees = ''' -PANNN[+(+30)ANNN][-ANNN]AN -PANNN[+(-30)ANNN][-(2)ANNN]AN -''' - for s in trees.split(): - check( *str2mtg(s) ) - -def test2(): - # simple set of two successives axes - trees = ''' -PA(9)N -''' - for s in trees.split(): - check( *str2mtg(s) ) - -def _test_mss(): - trees = ''' -PANNN[+ANNN][-ANNN]AN -PANNN[+ANNN][-ANNN]NNNANAN -PANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]AN -PANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]ANPANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]ANPANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]AN -PANNN[+ANNN[+ANNN[+ANNN][-ANNN]NNNANAN]][-ANNN[+ANNN[-ANNN]]NN]NANAN -''' - envelop = ['CvxHull', 'Box', 'Sphere'] - for s in trees.split(): - print(s) - for env in envelop: - print(env) - check_mss( *str2mss(s, env) ) - -def test_mtglpy(): - fn = path('ex_luz4.lpy') - if not fn.exists(): - return - - l = Lsystem('ex_luz4.lpy') - - tree = l.iterate() - - scene = l.sceneInterpretation(tree) - - mtg = lpy2mtg(tree, l, scene) - print(len(mtg)) - axial_tree = AxialTree() - axial_tree = mtg2lpy(mtg, l, axial_tree) - print(len(axial_tree)) - #axial_tree = mtg2axialtree(mtg, scale, parameters, axial_tree) - - # Check - assert True - return mtg, tree - -def test_mtglpy_topvine(): - fn = path('vinemtg_n.lpy') - if not fn.exists(): - return - - l = Lsystem(str(fn)) - parameters = {} - parameters['carto_file'] = 'geom_n.dat' - parameters['picle_file'] = 'vine_n.dat' - parameters['TTfin'] = None - - #l.context().updateNamespace(parameters) - - c_iter = l.getLastIterationNb() - nbstep = l.derivationLength - c_iter - tree = l.iterate(l.axiom,c_iter,nbstep) - - scene = l.sceneInterpretation(tree) - - mtg = lpy2mtg(tree, l, scene) - - print(len(mtg)) - axial_tree = AxialTree() - axial_tree = mtg2lpy(mtg, l, axial_tree) - - g = lpy2mtg(axial_tree, l, scene) - - assert len(g) == len(mtg) - #axial_tree = mtg2axialtree(mtg, scale, parameters, axial_tree) - - # Check - assert True - return mtg, tree, axial_tree - +from openalea.mtg.io import axialtree2mtg, mtg2mss , lpy2mtg, mtg2lpy +from openalea.lpy import AxialTree, generateScene, Lsystem +from openalea.plantgl.all import Scene, Viewer +from path import Path as path + +def str2mtg(s): + #s = s.replace('N', 'F') + tree = AxialTree(s) + l = Lsystem() + l.addInterpretationRule('N --> F', 0) + geom_tree = l.homomorphism(tree) + scene = l.sceneInterpretation(geom_tree) + scale = dict(list(zip(('P','A','N', 'L', 'F'),(1,2,3,3,3)))) + mtg = axialtree2mtg(tree, scale, scene) + return tree, mtg, scene + + + +def str2mss(s, envelop): + tree, mtg, scene = str2mtg(s) + return mtg2mss('test', mtg, scene, envelop), mtg, tree, s + +def check(tree, mtg, scene): + s = str(tree) + n1, n2 = [s.count(char) for char in ['P', 'A']] + n3 = s.count('N') + s.count('L') + s.count('F') + assert mtg.nb_vertices(scale=1) == n1, '%d, %d'%(mtg.nb_vertices(scale=1), n1 ) + assert mtg.nb_vertices(scale=2) == n2, '%d, %d'%(mtg.nb_vertices(scale=2), n2 ) + assert mtg.nb_vertices(scale=3) == n3, '%d, %d'%(mtg.nb_vertices(scale=3), n3) + v3 = set(mtg.vertices(scale=3)) + geom3 = set((sh.id for sh in scene)) + assert v3 == geom3, str(v3)+'!='+str(geom3) + +def check_mss(mss, mtg, tree, s=None): + if not mss: print(tree) + assert mss.depth == mtg.max_scale() + for scale in range(1,mss.depth+1): + assert len(set(mss.get1Scale(scale))) == len(set(mtg.vertices(scale=scale))), (str(set(mss.get1Scale(scale)))+' !='+ str(set(mtg.vertices(scale=scale))),s) + + +def test0(): + # simple set of two successives axes + trees = ''' +PANNN[+ANNN][-ANNN]AN +PANNN[+ANNN][-ANNN]NNNANAN +PANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]AN +PANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]ANPANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]ANPANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]AN +PANNN[+ANNN[+ANNN[+ANNN][-ANNN]NNNANAN]][-ANNN[+ANNN[-ANNN]]NN]NANAN +''' + for s in trees.split(): + check( *str2mtg(s) ) + +def test1(): + # simple set of two successives axes + trees = ''' +PANNN[+(+30)ANNN][-ANNN]AN +PANNN[+(-30)ANNN][-(2)ANNN]AN +''' + for s in trees.split(): + check( *str2mtg(s) ) + +def test2(): + # simple set of two successives axes + trees = ''' +PA(9)N +''' + for s in trees.split(): + check( *str2mtg(s) ) + +def _test_mss(): + trees = ''' +PANNN[+ANNN][-ANNN]AN +PANNN[+ANNN][-ANNN]NNNANAN +PANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]AN +PANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]ANPANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]ANPANNN[+ANNN][-ANNN]AN[+ANNN][-ANNN]ANNN[+ANNN][-ANNN]AN +PANNN[+ANNN[+ANNN[+ANNN][-ANNN]NNNANAN]][-ANNN[+ANNN[-ANNN]]NN]NANAN +''' + envelop = ['CvxHull', 'Box', 'Sphere'] + for s in trees.split(): + print(s) + for env in envelop: + print(env) + check_mss( *str2mss(s, env) ) + +def test_mtglpy(): + fn = path('ex_luz4.lpy') + if not fn.exists(): + return + + l = Lsystem('ex_luz4.lpy') + + tree = l.iterate() + + scene = l.sceneInterpretation(tree) + + mtg = lpy2mtg(tree, l, scene) + print(len(mtg)) + axial_tree = AxialTree() + axial_tree = mtg2lpy(mtg, l, axial_tree) + print(len(axial_tree)) + #axial_tree = mtg2axialtree(mtg, scale, parameters, axial_tree) + + # Check + assert True + return mtg, tree + +def test_mtglpy_topvine(): + fn = path('vinemtg_n.lpy') + if not fn.exists(): + return + + l = Lsystem(str(fn)) + parameters = {} + parameters['carto_file'] = 'geom_n.dat' + parameters['picle_file'] = 'vine_n.dat' + parameters['TTfin'] = None + + #l.context().updateNamespace(parameters) + + c_iter = l.getLastIterationNb() + nbstep = l.derivationLength - c_iter + tree = l.iterate(l.axiom,c_iter,nbstep) + + scene = l.sceneInterpretation(tree) + + mtg = lpy2mtg(tree, l, scene) + + print(len(mtg)) + axial_tree = AxialTree() + axial_tree = mtg2lpy(mtg, l, axial_tree) + + g = lpy2mtg(axial_tree, l, scene) + + assert len(g) == len(mtg) + #axial_tree = mtg2axialtree(mtg, scale, parameters, axial_tree) + + # Check + assert True + return mtg, tree, axial_tree + diff --git a/test/test_parsing_mtg.py b/tests/test_parsing_mtg.py similarity index 95% rename from test/test_parsing_mtg.py rename to tests/test_parsing_mtg.py index 32da94a..4e55df0 100644 --- a/test/test_parsing_mtg.py +++ b/tests/test_parsing_mtg.py @@ -1,78 +1,78 @@ -from openalea.mtg.io import * -import openalea.mtg.aml as aml - -def check(fn): - g = read_mtg_file(fn) - g1 = aml.MTG(fn) - - assert list(g.vertices()) == aml.VtxList() - for scale in range(1,g.nb_scales()): - assert list(g.vertices(scale=scale)) == aml.VtxList(Scale=scale), set(g.vertices(scale=scale)).difference(aml.VtxList(Scale=scale)) - - l = aml.VtxList(Scale=g.max_scale()) - for vid in l: - assert g.parent(vid) == aml.Father(vid), 'vertex %d has not the same parent at scale %d'%(vid, g.max_scale()) - - return g - -def test1(): - fn = r'data/mtg1.mtg' - g = check(fn) - assert len(g) == 7 - assert g.nb_vertices(scale=1) == 6 - -def test2(): - fn = r'data/mtg2.mtg' - g = check(fn) - assert len(g) == 6 - assert g.nb_vertices(scale=1) == 5 - -def test3(): - fn = r'data/mtg3.mtg' - g = check(fn) - assert len(g) == 13 - assert g.nb_vertices(scale=1) == 12 - -def test4(): - fn = r'data/mtg4.mtg' - g = check(fn) - assert len(g) == 47 - assert g.nb_scales() == 4 - assert g.nb_vertices(scale=1) == 1 - assert g.nb_vertices(scale=2) == 6 - assert g.nb_vertices(scale=3) == 39 - -def test5(): - fn = r'data/mtg51.mtg' - #g = check(fn) - -def test6(): - fn = r'data/test6_apricot2.mtg' - g = check(fn) - assert len(g) == 97 - assert g.nb_scales() == 5 - assert g.nb_vertices(scale=1) == 1 - assert g.nb_vertices(scale=2) == 10 - assert g.nb_vertices(scale=3) == 20 - assert g.nb_vertices(scale=4) == 65 - -def test7(): - fn = r'data/test7.mtg' - g = check(fn) - -def test8(): - fn = r'data/test8_boutdenoylum2.mtg' - g = check(fn) - -def test9(): - fn = r'data/test9_noylum2.mtg' - g = check(fn) - -def test10(): - fn = r'data/test10_agraf.mtg' - g = check(fn) - -def test11(): - fn = r'data/test11_wij10.mtg' - #g = check(fn) - +from openalea.mtg.io import * +import openalea.mtg.aml as aml + +def check(fn): + g = read_mtg_file(fn) + g1 = aml.MTG(fn) + + assert list(g.vertices()) == aml.VtxList() + for scale in range(1,g.nb_scales()): + assert list(g.vertices(scale=scale)) == aml.VtxList(Scale=scale), set(g.vertices(scale=scale)).difference(aml.VtxList(Scale=scale)) + + l = aml.VtxList(Scale=g.max_scale()) + for vid in l: + assert g.parent(vid) == aml.Father(vid), 'vertex %d has not the same parent at scale %d'%(vid, g.max_scale()) + + return g + +def test1(): + fn = r'data/mtg1.mtg' + g = check(fn) + assert len(g) == 7 + assert g.nb_vertices(scale=1) == 6 + +def test2(): + fn = r'data/mtg2.mtg' + g = check(fn) + assert len(g) == 6 + assert g.nb_vertices(scale=1) == 5 + +def test3(): + fn = r'data/mtg3.mtg' + g = check(fn) + assert len(g) == 13 + assert g.nb_vertices(scale=1) == 12 + +def test4(): + fn = r'data/mtg4.mtg' + g = check(fn) + assert len(g) == 47 + assert g.nb_scales() == 4 + assert g.nb_vertices(scale=1) == 1 + assert g.nb_vertices(scale=2) == 6 + assert g.nb_vertices(scale=3) == 39 + +def test5(): + fn = r'data/mtg51.mtg' + #g = check(fn) + +def test6(): + fn = r'data/test6_apricot2.mtg' + g = check(fn) + assert len(g) == 97 + assert g.nb_scales() == 5 + assert g.nb_vertices(scale=1) == 1 + assert g.nb_vertices(scale=2) == 10 + assert g.nb_vertices(scale=3) == 20 + assert g.nb_vertices(scale=4) == 65 + +def test7(): + fn = r'data/test7.mtg' + g = check(fn) + +def test8(): + fn = r'data/test8_boutdenoylum2.mtg' + g = check(fn) + +def test9(): + fn = r'data/test9_noylum2.mtg' + g = check(fn) + +def test10(): + fn = r'data/test10_agraf.mtg' + g = check(fn) + +def test11(): + fn = r'data/test11_wij10.mtg' + #g = check(fn) + diff --git a/test/test_plantframe1.py b/tests/test_plantframe1.py similarity index 96% rename from test/test_plantframe1.py rename to tests/test_plantframe1.py index bbcf35e..aefe6ff 100644 --- a/test/test_plantframe1.py +++ b/tests/test_plantframe1.py @@ -1,221 +1,221 @@ -from openalea.mtg.io import * -import openalea.mtg.plantframe as plantframe -import openalea.mtg.algo as algo -from openalea.mtg import aml, dresser - -from time import perf_counter as clock -from collections import defaultdict - -def test1(): - fn = r'data/test12_wij10.mtg' - drf = r'data/wij10.drf' - - length = lambda x: g.property('longueur').get(x) - botdia = lambda x: g.property('diabase').get(x) - topdia = lambda x: g.property('diasom').get(x) - - g = read_mtg_file(fn) - - dressing_data = dresser.dressing_data_from_file(drf) - pf = plantframe.PlantFrame(g, Length=length, - TopDiameter=topdia, - BottomDiameter=botdia, - DressingData = dressing_data) - - # axes are linear and diameter are defined on axes. - assert len(pf.top_diameter) == 16 - assert len(pf.bottom_diameter) == 16 - - for v in g.vertices(scale=3): - assert pf.is_linear(g, v) - - diameters = pf.algo_diameter() - assert len(diameters) == g.nb_vertices(scale=4) - - length = pf.algo_length() - - return pf - -def __test2(): - fn = r'data/hetre.mtg' - - g = read_mtg_file(fn) - param = dresser.DressingData() - - et = g.property('edge_type') - split_axe = lambda v: et.get(v) == '+' - - pf = plantframe.PlantFrame(g, Axe=split_axe, DressingData=param) - - diameters = pf.algo_diameter() - length = pf.algo_length() - - - return pf - -def test3(): - fn = r'data/test12_wij10.mtg' - drf = r'data/wij10.drf' - - g = read_mtg_file(fn) - dressing_data = dresser.dressing_data_from_file(drf) - - et = g.property('edge_type') - split_axe = lambda v: et.get(v) == '+' - - pf = plantframe.PlantFrame(g, Axe=split_axe, - DressingData=dressing_data) - - diameters = pf.algo_diameter() - length = pf.algo_length() - - - return pf - - - -def test4(): - fn = r'data/test9_noylum2.mtg' - drf = r'data/walnut.drf' - - t=clock() - - g = read_mtg_file(fn) - - t1=clock(); t, dt = t1, t1-t - print('readmtg in ', dt) - - topdia = lambda x: g.property('TopDia').get(x) - - dressing_data = dresser.dressing_data_from_file(drf) - pf = plantframe.PlantFrame(g, - TopDiameter=topdia, - DressingData = dressing_data) - pf.propagate_constraints() - - t1=clock(); t, dt = t1, t1-t - print('empty plantframe in ', dt) - - diameters = pf.algo_diameter() - - t1=clock(); t, dt = t1, t1-t - print('diameter in ', dt) - - axes = plantframe.compute_axes(g,3, pf.points, pf.origin) - #axes[0][0].insert(0,pf.origin) - - t1=clock(); t, dt = t1, t1-t - print('points in ', dt) - - scene=plantframe.build_scene(pf.g, pf.origin, axes, pf.points, diameters, 10000) - - t1=clock(); t, dt = t1, t1-t - print('scene in ', dt) - return scene, pf - -def test5(): - fn = r'data/test10_agraf.mtg' - drf = r'data/agraf.drf' - - t=clock() - - g = read_mtg_file(fn) - - t1=clock(); t, dt = t1, t1-t - print('readmtg in ', dt) - - topdia = lambda x: g.property('TopDia').get(x) - - dressing_data = dresser.dressing_data_from_file(drf) - pf = plantframe.PlantFrame(g, - TopDiameter=topdia, - DressingData = dressing_data) - pf.propagate_constraints() - - t1=clock(); t, dt = t1, t1-t - print('empty plantframe in ', dt) - - diameters = pf.algo_diameter() - - t1=clock(); t, dt = t1, t1-t - print('diameter in ', dt) - - root = next(g.roots_iter(scale=g.max_scale())) - axes = plantframe.compute_axes(g,root, pf.points, pf.origin) - axes[0][0].insert(0,pf.origin) - - t1=clock(); t, dt = t1, t1-t - print('points in ', dt) - - scene=plantframe.build_scene(pf.g, pf.origin, axes, pf.points, diameters, 10000, option='cylinder') - - t1=clock(); t, dt = t1, t1-t - print('scene in ', dt) - - return scene, pf - -def walnut(): - fn = r'data/test9_noylum2.mtg' - drf = r'data/walnut.drf' - - g = read_mtg_file(fn) - - topdia = lambda x: g.property('TopDia').get(x) - - dressing_data = dresser.dressing_data_from_file(drf) - pf = plantframe.PlantFrame(g, - TopDiameter=topdia, - DressingData = dressing_data) - pf.propagate_constraints() - - return pf - - -def test_colors(): - pf = walnut() - axes = plantframe.compute_axes(pf.g,3, pf.points, pf.origin) - axes[0][0].insert(0,pf.origin) - diameters = pf.algo_diameter() - - g = pf.g - colors =defaultdict(lambda x: (0,255,0), - list(zip(list(range(8)), [ ((i&2**0)*255, ((i&2**1)>>1)*255, ((i&2**2)>>2)*255) for i in range(8)]))) - def my_color(vid): - return colors[g.order(vid)] - - scene=plantframe.build_scene(pf.g, pf.origin, axes, pf.points, diameters, 10000, option='cylinder', colors = my_color) - return scene - - - - - - - - - -def fun3(): - import numpy as np - import matplotlib.pyplot as plt - import matplotlib.mlab as mlab - import matplotlib.ticker as ticker - import pylab as P - - g, pf = test2() - P.figure() - - lengths = [] - for root in g.vertices(scale=1): - vr = next(g.component_roots_at_scale_iter(root,scale=2)) - h = aml.Height(vr) - lv = [v for v in algo.trunk(g,vr, RestrictedTo='SameComplex', ConatinedIn=root) if v in pf.length] - P.plot([aml.Height(v)-h for v in lv], [pf.length.get(v) for v in lv], 'o-') - #lengths.append([pf.length.get(v) for v in lv if v in pf.length]) - - - #n, bins, patches = P.hist( lengths, 4, histtype='bar') - - return lengths - # Compute a reference axis - - +from openalea.mtg.io import * +import openalea.mtg.plantframe as plantframe +import openalea.mtg.algo as algo +from openalea.mtg import aml, dresser + +from time import perf_counter as clock +from collections import defaultdict + +def test1(): + fn = r'data/test12_wij10.mtg' + drf = r'data/wij10.drf' + + length = lambda x: g.property('longueur').get(x) + botdia = lambda x: g.property('diabase').get(x) + topdia = lambda x: g.property('diasom').get(x) + + g = read_mtg_file(fn) + + dressing_data = dresser.dressing_data_from_file(drf) + pf = plantframe.PlantFrame(g, Length=length, + TopDiameter=topdia, + BottomDiameter=botdia, + DressingData = dressing_data) + + # axes are linear and diameter are defined on axes. + assert len(pf.top_diameter) == 16 + assert len(pf.bottom_diameter) == 16 + + for v in g.vertices(scale=3): + assert pf.is_linear(g, v) + + diameters = pf.algo_diameter() + assert len(diameters) == g.nb_vertices(scale=4) + + length = pf.algo_length() + + return pf + +def __test2(): + fn = r'data/hetre.mtg' + + g = read_mtg_file(fn) + param = dresser.DressingData() + + et = g.property('edge_type') + split_axe = lambda v: et.get(v) == '+' + + pf = plantframe.PlantFrame(g, Axe=split_axe, DressingData=param) + + diameters = pf.algo_diameter() + length = pf.algo_length() + + + return pf + +def test3(): + fn = r'data/test12_wij10.mtg' + drf = r'data/wij10.drf' + + g = read_mtg_file(fn) + dressing_data = dresser.dressing_data_from_file(drf) + + et = g.property('edge_type') + split_axe = lambda v: et.get(v) == '+' + + pf = plantframe.PlantFrame(g, Axe=split_axe, + DressingData=dressing_data) + + diameters = pf.algo_diameter() + length = pf.algo_length() + + + return pf + + + +def test4(): + fn = r'data/test9_noylum2.mtg' + drf = r'data/walnut.drf' + + t=clock() + + g = read_mtg_file(fn) + + t1=clock(); t, dt = t1, t1-t + print('readmtg in ', dt) + + topdia = lambda x: g.property('TopDia').get(x) + + dressing_data = dresser.dressing_data_from_file(drf) + pf = plantframe.PlantFrame(g, + TopDiameter=topdia, + DressingData = dressing_data) + pf.propagate_constraints() + + t1=clock(); t, dt = t1, t1-t + print('empty plantframe in ', dt) + + diameters = pf.algo_diameter() + + t1=clock(); t, dt = t1, t1-t + print('diameter in ', dt) + + axes = plantframe.compute_axes(g,3, pf.points, pf.origin) + #axes[0][0].insert(0,pf.origin) + + t1=clock(); t, dt = t1, t1-t + print('points in ', dt) + + scene=plantframe.build_scene(pf.g, pf.origin, axes, pf.points, diameters, 10000) + + t1=clock(); t, dt = t1, t1-t + print('scene in ', dt) + return scene, pf + +def test5(): + fn = r'data/test10_agraf.mtg' + drf = r'data/agraf.drf' + + t=clock() + + g = read_mtg_file(fn) + + t1=clock(); t, dt = t1, t1-t + print('readmtg in ', dt) + + topdia = lambda x: g.property('TopDia').get(x) + + dressing_data = dresser.dressing_data_from_file(drf) + pf = plantframe.PlantFrame(g, + TopDiameter=topdia, + DressingData = dressing_data) + pf.propagate_constraints() + + t1=clock(); t, dt = t1, t1-t + print('empty plantframe in ', dt) + + diameters = pf.algo_diameter() + + t1=clock(); t, dt = t1, t1-t + print('diameter in ', dt) + + root = next(g.roots_iter(scale=g.max_scale())) + axes = plantframe.compute_axes(g,root, pf.points, pf.origin) + axes[0][0].insert(0,pf.origin) + + t1=clock(); t, dt = t1, t1-t + print('points in ', dt) + + scene=plantframe.build_scene(pf.g, pf.origin, axes, pf.points, diameters, 10000, option='cylinder') + + t1=clock(); t, dt = t1, t1-t + print('scene in ', dt) + + return scene, pf + +def walnut(): + fn = r'data/test9_noylum2.mtg' + drf = r'data/walnut.drf' + + g = read_mtg_file(fn) + + topdia = lambda x: g.property('TopDia').get(x) + + dressing_data = dresser.dressing_data_from_file(drf) + pf = plantframe.PlantFrame(g, + TopDiameter=topdia, + DressingData = dressing_data) + pf.propagate_constraints() + + return pf + + +def test_colors(): + pf = walnut() + axes = plantframe.compute_axes(pf.g,3, pf.points, pf.origin) + axes[0][0].insert(0,pf.origin) + diameters = pf.algo_diameter() + + g = pf.g + colors =defaultdict(lambda x: (0,255,0), + list(zip(list(range(8)), [ ((i&2**0)*255, ((i&2**1)>>1)*255, ((i&2**2)>>2)*255) for i in range(8)]))) + def my_color(vid): + return colors[g.order(vid)] + + scene=plantframe.build_scene(pf.g, pf.origin, axes, pf.points, diameters, 10000, option='cylinder', colors = my_color) + return scene + + + + + + + + + +def fun3(): + import numpy as np + import matplotlib.pyplot as plt + import matplotlib.mlab as mlab + import matplotlib.ticker as ticker + import pylab as P + + g, pf = test2() + P.figure() + + lengths = [] + for root in g.vertices(scale=1): + vr = next(g.component_roots_at_scale_iter(root,scale=2)) + h = aml.Height(vr) + lv = [v for v in algo.trunk(g,vr, RestrictedTo='SameComplex', ConatinedIn=root) if v in pf.length] + P.plot([aml.Height(v)-h for v in lv], [pf.length.get(v) for v in lv], 'o-') + #lengths.append([pf.length.get(v) for v in lv if v in pf.length]) + + + #n, bins, patches = P.hist( lengths, 4, histtype='bar') + + return lengths + # Compute a reference axis + + diff --git a/test/test_proxynode.py b/tests/test_proxynode.py similarity index 100% rename from test/test_proxynode.py rename to tests/test_proxynode.py diff --git a/test/test_rewriting.py b/tests/test_rewriting.py similarity index 100% rename from test/test_rewriting.py rename to tests/test_rewriting.py diff --git a/test/test_stat.py b/tests/test_stat.py similarity index 100% rename from test/test_stat.py rename to tests/test_stat.py diff --git a/test/test_traversal.py b/tests/test_traversal.py similarity index 100% rename from test/test_traversal.py rename to tests/test_traversal.py diff --git a/test/test_tree.py b/tests/test_tree.py similarity index 95% rename from test/test_tree.py rename to tests/test_tree.py index 659461a..bb5239d 100644 --- a/test/test_tree.py +++ b/tests/test_tree.py @@ -1,51 +1,51 @@ -# -*- python -*- -# -# OpenAlea.mtg -# -# Copyright 2008 INRIA - CIRAD - INRA -# -# File author(s): Christophe Pradal -# -# Distributed under the Cecill-C License. -# See accompanying file LICENSE.txt or copy at -# http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html -# -# OpenAlea WebSite : http://openalea.gforge.inria.fr -# -################################################################################ - -from openalea.mtg.tree import * -from openalea.mtg.traversal import * - -def check(tree): - """ Traverse the tree to see if all the children have at most one parent. - TODO - """ - - parents = tree._parent - kids = tree._children - - sons = set(v for v in l for l in kids.values()) - vtx = set(v for v in parents.values() if v is not None) - - - -def test_tree_api(): - tree = Tree() - - root = tree.root - assert root is not None - assert root == 0, 'default root id (%d) is not 0'%root - - # scale 1 - v1 = tree.add_child(root) - v2 = tree.add_child(v1) - assert len(tree) == 3 - - v3 = tree.insert_parent(v2) - assert len(tree) == 4 - - tree.replace_parent(v2,v1) - assert len(tree) == 4 - - +# -*- python -*- +# +# OpenAlea.mtg +# +# Copyright 2008 INRIA - CIRAD - INRA +# +# File author(s): Christophe Pradal +# +# Distributed under the Cecill-C License. +# See accompanying file LICENSE.txt or copy at +# http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html +# +# OpenAlea WebSite : http://openalea.gforge.inria.fr +# +################################################################################ + +from openalea.mtg.tree import * +from openalea.mtg.traversal import * + +def check(tree): + """ Traverse the tree to see if all the children have at most one parent. + TODO + """ + + parents = tree._parent + kids = tree._children + + sons = set(v for v in l for l in kids.values()) + vtx = set(v for v in parents.values() if v is not None) + + + +def test_tree_api(): + tree = Tree() + + root = tree.root + assert root is not None + assert root == 0, 'default root id (%d) is not 0'%root + + # scale 1 + v1 = tree.add_child(root) + v2 = tree.add_child(v1) + assert len(tree) == 3 + + v3 = tree.insert_parent(v2) + assert len(tree) == 4 + + tree.replace_parent(v2,v1) + assert len(tree) == 4 + + diff --git a/test/test_tulip.py b/tests/test_tulip.py similarity index 100% rename from test/test_tulip.py rename to tests/test_tulip.py diff --git a/test/test_turtle.py b/tests/test_turtle.py similarity index 95% rename from test/test_turtle.py rename to tests/test_turtle.py index 9ae4dff..9e0f574 100644 --- a/test/test_turtle.py +++ b/tests/test_turtle.py @@ -1,25 +1,25 @@ -from openalea.mtg.plantframe.turtle import * - -def test1(): - fn = r'data/mtg1.mtg' - g = read_mtg_file(fn) - return TurtleFrame(g) - -def test2(): - fn = r'data/monopodial_plant.mtg' - g = read_mtg_file(fn) - return TurtleFrame(g) - -def test3(): - fn = r'data/monopodial_plant.mtg' - g = read_mtg_file(fn) - - def visitor(g, v, turtle): - if g.edge_type(v) == '+': - turtle.down(90) - - turtle.F() - turtle.rollL() - - return TurtleFrame(g, visitor) - +from openalea.mtg.plantframe.turtle import * + +def test1(): + fn = r'data/mtg1.mtg' + g = read_mtg_file(fn) + return TurtleFrame(g) + +def test2(): + fn = r'data/monopodial_plant.mtg' + g = read_mtg_file(fn) + return TurtleFrame(g) + +def test3(): + fn = r'data/monopodial_plant.mtg' + g = read_mtg_file(fn) + + def visitor(g, v, turtle): + if g.edge_type(v) == '+': + turtle.down(90) + + turtle.F() + turtle.rollL() + + return TurtleFrame(g, visitor) + diff --git a/test/test_writing_mtg.py b/tests/test_writing_mtg.py similarity index 95% rename from test/test_writing_mtg.py rename to tests/test_writing_mtg.py index 73bcfb7..f107b7e 100644 --- a/test/test_writing_mtg.py +++ b/tests/test_writing_mtg.py @@ -1,72 +1,72 @@ -# -*- python -*- -# -# OpenAlea.mtg -# -# Copyright 2008 INRIA - CIRAD - INRA -# -# File author(s): Christophe Pradal -# -# Distributed under the Cecill-C License. -# See accompanying file LICENSE.txt or copy at -# http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html -# -# OpenAlea WebSite : http://openalea.gforge.inria.fr -# -################################################################################ - -import os -from itertools import repeat -from glob import glob -import pytest - -from openalea.mtg import * -from openalea.mtg.io import * - -def files_to_check(): - files = glob('data/*.mtg') - exclude = set(''' - reconstructed_appletree.mtg - test6_apricot2.mtg - mtg_dynamic.mtg - '''.split()) - files = [f for f in files if os.path.basename(f) not in exclude] - - #files = list(glob('data/test13*.mtg')) - print(files) - return files - - -def build_mtg_and_check(fn): - g = read_mtg_file(fn) - - props = (p for p in g.property_names() if p not in ['edge_type', 'index', 'label']) - props = list(zip(props, repeat('REAL'))) - - # Write it on a string - #try: - s = write_mtg(g, props) - """ - except Exception, e: - print e - #assert False, 'MTG %s can not be written'%fn - """ - return g, s - -def check(g, s, fn): - from openalea.mtg import MTG - f = open('tmp.mtg', 'w') - f.write(s) - f.close() - try: - g1 = MTG('tmp.mtg') - except Exception as e: - os.remove('tmp.mtg') - assert False, fn - - os.remove('tmp.mtg') - -@pytest.mark.parametrize('fn', files_to_check()) -def test_files(fn): - g, s = build_mtg_and_check(fn) - check(g, s, fn) - +# -*- python -*- +# +# OpenAlea.mtg +# +# Copyright 2008 INRIA - CIRAD - INRA +# +# File author(s): Christophe Pradal +# +# Distributed under the Cecill-C License. +# See accompanying file LICENSE.txt or copy at +# http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html +# +# OpenAlea WebSite : http://openalea.gforge.inria.fr +# +################################################################################ + +import os +from itertools import repeat +from glob import glob +import pytest + +from openalea.mtg import * +from openalea.mtg.io import * + +def files_to_check(): + files = glob('data/*.mtg') + exclude = set(''' + reconstructed_appletree.mtg + test6_apricot2.mtg + mtg_dynamic.mtg + '''.split()) + files = [f for f in files if os.path.basename(f) not in exclude] + + #files = list(glob('data/test13*.mtg')) + print(files) + return files + + +def build_mtg_and_check(fn): + g = read_mtg_file(fn) + + props = (p for p in g.property_names() if p not in ['edge_type', 'index', 'label']) + props = list(zip(props, repeat('REAL'))) + + # Write it on a string + #try: + s = write_mtg(g, props) + """ + except Exception, e: + print e + #assert False, 'MTG %s can not be written'%fn + """ + return g, s + +def check(g, s, fn): + from openalea.mtg import MTG + f = open('tmp.mtg', 'w') + f.write(s) + f.close() + try: + g1 = MTG('tmp.mtg') + except Exception as e: + os.remove('tmp.mtg') + assert False, fn + + os.remove('tmp.mtg') + +@pytest.mark.parametrize('fn', files_to_check()) +def test_files(fn): + g, s = build_mtg_and_check(fn) + check(g, s, fn) + diff --git a/test/test_writing_mtg2.py b/tests/test_writing_mtg2.py similarity index 100% rename from test/test_writing_mtg2.py rename to tests/test_writing_mtg2.py diff --git a/test/toto.xls b/tests/toto.xls similarity index 100% rename from test/toto.xls rename to tests/toto.xls diff --git a/test/visu3d.py b/tests/visu3d.py similarity index 96% rename from test/visu3d.py rename to tests/visu3d.py index 8f108b9..fb7b307 100644 --- a/test/visu3d.py +++ b/tests/visu3d.py @@ -1,123 +1,123 @@ - -import os, sys - -from openalea.mtg import * -from openalea.mtg.io import * -from openalea.mtg.traversal import * -import openalea.mtg.util as util -from openalea.plantgl.all import * -from math import sqrt + +import os, sys + +from openalea.mtg import * +from openalea.mtg.io import * +from openalea.mtg.traversal import * +import openalea.mtg.util as util +from openalea.plantgl.all import * +from math import sqrt import importlib - -importlib.reload(util) - -#io.debug = 1 -fn = r'data/mtg5.mtg' -fn = r'data/reconstructed_appletree.mtg' -fn = r'data/test9_noylum2.mtg' - -g = read_mtg_file(fn) - -# 1. Read all the points and draw it -xx = g.property('XX') -yy = g.property('YY') -zz = g.property('ZZ') - -scale = 3 -points = {} - -factor = 100 -factor = 1 -for vid in g.vertices(scale=scale): - try: - points[vid] = xx[vid]*factor, yy[vid]*factor, zz[vid]*factor - except: - continue - -scene = Scene() - -# Create all the edges with only tree info -#segments = [(points[g.parent(vid)], points[vid]) for vid in pre_order(g,3) if vid in points and g.parent(vid)] -#[scene.add(Polyline(s)) for s in segments] -#Viewer.display(scene) - -# Build all the axes at a given order - -def compute_axes(g, v): - marked = {} - axes = {} - for vid in post_order(g,v): - if vid in marked: - continue - _axe = list(simple_axe(g,vid, marked)) - _axe.reverse() - axes.setdefault(g.order(_axe[0]),[]).append(_axe) - return axes - -def simple_axe(g, v, marked): - edge_type = g.property('edge_type') - - while v is not None: - if v in points: - yield v - - assert v not in marked - marked[v] = True - - if g.parent(v) is None or edge_type[v] == '+': - break - v = g.parent(v) - -def compute_radius(g, v, last_radius): - all_r2 = {} - for vid in post_order(g, v): - r2 = max(sum([all_r2[c] for c in g.children(vid)]), last_radius) - all_r2[vid] = r2 - for k, v in all_r2.items(): - all_r2[k] = sqrt(v) - return all_r2 - -def compute_diameter(g, v, diameter_property): - radius = {} - #for vid in - -axes = compute_axes(g,3) -rad = compute_radius(g,3, 0.07) - -scene.clear() -polylines = [] -radius_law = [] -for order in axes: - for axe in axes[order]: - parent = g.parent(axe[0]) - if order > 0 and parent and parent in points: - axe.insert(0,parent) - polylines.append((Polyline([points[vid] for vid in axe]), [[rad[vid]]*2 for vid in axe])) - -sf = 0.01 -p= [Vector2(0.5,0), Vector2( 0,0.5), Vector2(-0.05,0), Vector2(0,-0.5), Vector2(0.5,0)] -#p= map(lambda x: x*sf, p) -section= Polyline2D(p) -section = Polyline2D.Circle(0.5,10) -scene.clear() -for axe, radius in polylines: - radius[0] = radius[1] - scene+= Extrusion(axe,section,radius) - -""" -Algo: - - compute all the axes - - compute the points for each element of the axes - - compute the radius - - compute a section - - display it - -Proposal: - 1. remove noise from measured points on axes: - * given points do not represent the skeleton but are exterior points. - * some points may be aligned (guideline) - but branching points are on a spiral. - -> these points may provide usefull info on radius. - RMF may be used to found a better axis for the skeleton. - 2. Create factories for curves -""" + +importlib.reload(util) + +#io.debug = 1 +fn = r'data/mtg5.mtg' +fn = r'data/reconstructed_appletree.mtg' +fn = r'data/test9_noylum2.mtg' + +g = read_mtg_file(fn) + +# 1. Read all the points and draw it +xx = g.property('XX') +yy = g.property('YY') +zz = g.property('ZZ') + +scale = 3 +points = {} + +factor = 100 +factor = 1 +for vid in g.vertices(scale=scale): + try: + points[vid] = xx[vid]*factor, yy[vid]*factor, zz[vid]*factor + except: + continue + +scene = Scene() + +# Create all the edges with only tree info +#segments = [(points[g.parent(vid)], points[vid]) for vid in pre_order(g,3) if vid in points and g.parent(vid)] +#[scene.add(Polyline(s)) for s in segments] +#Viewer.display(scene) + +# Build all the axes at a given order + +def compute_axes(g, v): + marked = {} + axes = {} + for vid in post_order(g,v): + if vid in marked: + continue + _axe = list(simple_axe(g,vid, marked)) + _axe.reverse() + axes.setdefault(g.order(_axe[0]),[]).append(_axe) + return axes + +def simple_axe(g, v, marked): + edge_type = g.property('edge_type') + + while v is not None: + if v in points: + yield v + + assert v not in marked + marked[v] = True + + if g.parent(v) is None or edge_type[v] == '+': + break + v = g.parent(v) + +def compute_radius(g, v, last_radius): + all_r2 = {} + for vid in post_order(g, v): + r2 = max(sum([all_r2[c] for c in g.children(vid)]), last_radius) + all_r2[vid] = r2 + for k, v in all_r2.items(): + all_r2[k] = sqrt(v) + return all_r2 + +def compute_diameter(g, v, diameter_property): + radius = {} + #for vid in + +axes = compute_axes(g,3) +rad = compute_radius(g,3, 0.07) + +scene.clear() +polylines = [] +radius_law = [] +for order in axes: + for axe in axes[order]: + parent = g.parent(axe[0]) + if order > 0 and parent and parent in points: + axe.insert(0,parent) + polylines.append((Polyline([points[vid] for vid in axe]), [[rad[vid]]*2 for vid in axe])) + +sf = 0.01 +p= [Vector2(0.5,0), Vector2( 0,0.5), Vector2(-0.05,0), Vector2(0,-0.5), Vector2(0.5,0)] +#p= map(lambda x: x*sf, p) +section= Polyline2D(p) +section = Polyline2D.Circle(0.5,10) +scene.clear() +for axe, radius in polylines: + radius[0] = radius[1] + scene+= Extrusion(axe,section,radius) + +""" +Algo: + - compute all the axes + - compute the points for each element of the axes + - compute the radius + - compute a section + - display it + +Proposal: + 1. remove noise from measured points on axes: + * given points do not represent the skeleton but are exterior points. + * some points may be aligned (guideline) + but branching points are on a spiral. + -> these points may provide usefull info on radius. + RMF may be used to found a better axis for the skeleton. + 2. Create factories for curves +""" From 1ccd1d89a346c9e422781579d7637352cdbe91a5 Mon Sep 17 00:00:00 2001 From: Martin PELLEMOINE Date: Thu, 13 Jun 2024 10:31:26 +0200 Subject: [PATCH 08/14] update meta.yaml to user pip instead of setup.py --- conda/meta.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conda/meta.yaml b/conda/meta.yaml index 0111dc5..60e121c 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -11,8 +11,8 @@ build: noarch: python preserve_egg_dir: True number: 2 - script: {{PYTHON}} setup.py install #--single-version-externally-managed --record=record.txt - #script: {{ PYTHON }} -m pip install . + #script: {{PYTHON}} setup.py install #--single-version-externally-managed --record=record.txt + script: {{ PYTHON }} -m pip install . requirements: build: From 9b81518b0ea78436176ebceb4d654f71ca49bf4e Mon Sep 17 00:00:00 2001 From: Martin PELLEMOINE Date: Thu, 13 Jun 2024 11:50:03 +0200 Subject: [PATCH 09/14] pyproject.toml: dynamic version --- pyproject.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c314d21..0ef0630 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openalea.mtg" -version = "0.1.0" +dynamic = ["version"] description = "Multiscale Tree Graph datastructure and interfaces" readme = "README.rst" authors = [ @@ -20,6 +20,8 @@ homepage = "http://github.com/openalea/mtg" [tool.setuptools.packages.find] where = ["src"] +#ADD ENTRY POINTS + #[tool.setuptools] #packages = ["find_namespace:src"] #namespace_packages = ["openalea"] From 7b01804347a0f41039050c9466350eed31a1606d Mon Sep 17 00:00:00 2001 From: Martin PELLEMOINE Date: Thu, 13 Jun 2024 11:50:33 +0200 Subject: [PATCH 10/14] meta.yaml: pip flag --no-deps --- conda/meta.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conda/meta.yaml b/conda/meta.yaml index 60e121c..0b73e93 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -12,7 +12,7 @@ build: preserve_egg_dir: True number: 2 #script: {{PYTHON}} setup.py install #--single-version-externally-managed --record=record.txt - script: {{ PYTHON }} -m pip install . + script: {{ PYTHON }} -m pip install . --no-deps requirements: build: @@ -20,7 +20,7 @@ requirements: - setuptools - openalea.deploy run: - - python >=3.10 + - python - openalea.plantgl - matplotlib - pandas From 9f3eab36b9481af9039a190dd08faa3816ca119d Mon Sep 17 00:00:00 2001 From: Martin PELLEMOINE Date: Thu, 13 Jun 2024 13:38:52 +0200 Subject: [PATCH 11/14] pyproject.toml: added dependencies --- pyproject.toml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0ef0630..6dae0f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,19 @@ authors = [ ] license = { text = "CeCILL-C" } keywords = ["OpenAlea", "MTG", "Plant Architecture", "Tree Graph"] -dependencies = [] + +dependencies = [ + "openalea.plantgl", + "matplotlib", + "pandas" +] + +[project.optional-dependencies] +test = [ + "pytest", + "path", + "openalea.lpy" +] [project.urls] homepage = "http://github.com/openalea/mtg" From bb761f995c027e369196fe83d7b158884632463a Mon Sep 17 00:00:00 2001 From: Martin PELLEMOINE Date: Thu, 13 Jun 2024 13:59:22 +0200 Subject: [PATCH 12/14] test update version --- src/openalea/mtg/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openalea/mtg/version.py b/src/openalea/mtg/version.py index 15d5f2e..dd20995 100644 --- a/src/openalea/mtg/version.py +++ b/src/openalea/mtg/version.py @@ -4,7 +4,7 @@ major = 2 """(int) Version major component.""" -minor = 2 +minor = 3 """(int) Version minor component.""" post = 0 From 8e485dc626685d993ac56a2b7f27f626b4528bc7 Mon Sep 17 00:00:00 2001 From: Martin PELLEMOINE Date: Thu, 13 Jun 2024 14:57:57 +0200 Subject: [PATCH 13/14] added namespaces to pyproject.toml --- pyproject.toml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6dae0f6..446fdba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,16 +31,15 @@ homepage = "http://github.com/openalea/mtg" [tool.setuptools.packages.find] where = ["src"] - -#ADD ENTRY POINTS +namespaces = true #[tool.setuptools] #packages = ["find_namespace:src"] #namespace_packages = ["openalea"] #package_dir = {"" = "src"} -#[tool.setuptools.dynamic] -#version = {file = "src/openalea/mtg/version.py"} - #[tool.setuptools.entry-points.wralea] #mtg = "openalea.mtg_wralea" + +#[tool.setuptools.dynamic] +#version = {file = "src/openalea/mtg/version.py"} From 4796c7e71d9585189ef909a3849a98ce943bc1b0 Mon Sep 17 00:00:00 2001 From: Martin PELLEMOINE Date: Thu, 13 Jun 2024 15:20:02 +0200 Subject: [PATCH 14/14] tests => test --- conda/meta.yaml | 6 +++--- src/openalea/mtg/version.py | 2 +- {tests => test}/__init__.py | 0 {tests => test}/data/agraf.drf | 0 {tests => test}/data/leaf_axis.drf | 0 {tests => test}/data/monopodial_plant.mtg | 0 {tests => test}/data/mtg1.mtg | 0 {tests => test}/data/mtg2.mtg | 0 {tests => test}/data/mtg3.mtg | 0 {tests => test}/data/mtg4.mtg | 0 {tests => test}/data/mtg5.mtg | 0 {tests => test}/data/mtg51.mtg | 0 {tests => test}/data/mtg_dynamic.mtg | 0 {tests => test}/data/noyer.drf | 0 {tests => test}/data/oaktree.drf | 0 {tests => test}/data/origin.drf | 0 {tests => test}/data/reconstructed_appletree.mtg | 0 {tests => test}/data/test10_agraf.mtg | 0 {tests => test}/data/test11_wij10.mtg | 0 {tests => test}/data/test12_wij10.mtg | 0 {tests => test}/data/test6_apricot2.mtg | 0 {tests => test}/data/test7.mtg | 0 {tests => test}/data/test8_boutdenoylum2.mtg | 0 {tests => test}/data/test9_noylum2.mtg | 0 {tests => test}/data/walnut.drf | 0 {tests => test}/data/wij10.drf | 0 {tests => test}/debug.py | 0 {tests => test}/eurograph.py | 0 {tests => test}/random_mtg.py | 0 {tests => test}/simple.lpy | 0 {tests => test}/test_aml.py | 0 {tests => test}/test_dresser.py | 0 {tests => test}/test_edition.py | 0 {tests => test}/test_lsystem.py | 0 {tests => test}/test_mtg.py | 0 {tests => test}/test_operation.py | 0 {tests => test}/test_parsing.py | 0 {tests => test}/test_parsing_axialtree.py | 0 {tests => test}/test_parsing_mtg.py | 0 {tests => test}/test_plantframe1.py | 0 {tests => test}/test_proxynode.py | 0 {tests => test}/test_rewriting.py | 0 {tests => test}/test_stat.py | 0 {tests => test}/test_traversal.py | 0 {tests => test}/test_tree.py | 0 {tests => test}/test_tulip.py | 0 {tests => test}/test_turtle.py | 0 {tests => test}/test_writing_mtg.py | 0 {tests => test}/test_writing_mtg2.py | 0 {tests => test}/toto.xls | 0 {tests => test}/visu3d.py | 0 51 files changed, 4 insertions(+), 4 deletions(-) rename {tests => test}/__init__.py (100%) rename {tests => test}/data/agraf.drf (100%) rename {tests => test}/data/leaf_axis.drf (100%) rename {tests => test}/data/monopodial_plant.mtg (100%) rename {tests => test}/data/mtg1.mtg (100%) rename {tests => test}/data/mtg2.mtg (100%) rename {tests => test}/data/mtg3.mtg (100%) rename {tests => test}/data/mtg4.mtg (100%) rename {tests => test}/data/mtg5.mtg (100%) rename {tests => test}/data/mtg51.mtg (100%) rename {tests => test}/data/mtg_dynamic.mtg (100%) rename {tests => test}/data/noyer.drf (100%) rename {tests => test}/data/oaktree.drf (100%) rename {tests => test}/data/origin.drf (100%) rename {tests => test}/data/reconstructed_appletree.mtg (100%) rename {tests => test}/data/test10_agraf.mtg (100%) rename {tests => test}/data/test11_wij10.mtg (100%) rename {tests => test}/data/test12_wij10.mtg (100%) rename {tests => test}/data/test6_apricot2.mtg (100%) rename {tests => test}/data/test7.mtg (100%) rename {tests => test}/data/test8_boutdenoylum2.mtg (100%) rename {tests => test}/data/test9_noylum2.mtg (100%) rename {tests => test}/data/walnut.drf (100%) rename {tests => test}/data/wij10.drf (100%) rename {tests => test}/debug.py (100%) rename {tests => test}/eurograph.py (100%) rename {tests => test}/random_mtg.py (100%) rename {tests => test}/simple.lpy (100%) rename {tests => test}/test_aml.py (100%) rename {tests => test}/test_dresser.py (100%) rename {tests => test}/test_edition.py (100%) rename {tests => test}/test_lsystem.py (100%) rename {tests => test}/test_mtg.py (100%) rename {tests => test}/test_operation.py (100%) rename {tests => test}/test_parsing.py (100%) rename {tests => test}/test_parsing_axialtree.py (100%) rename {tests => test}/test_parsing_mtg.py (100%) rename {tests => test}/test_plantframe1.py (100%) rename {tests => test}/test_proxynode.py (100%) rename {tests => test}/test_rewriting.py (100%) rename {tests => test}/test_stat.py (100%) rename {tests => test}/test_traversal.py (100%) rename {tests => test}/test_tree.py (100%) rename {tests => test}/test_tulip.py (100%) rename {tests => test}/test_turtle.py (100%) rename {tests => test}/test_writing_mtg.py (100%) rename {tests => test}/test_writing_mtg2.py (100%) rename {tests => test}/toto.xls (100%) rename {tests => test}/visu3d.py (100%) diff --git a/conda/meta.yaml b/conda/meta.yaml index 0b73e93..b1d752a 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -34,10 +34,10 @@ test: - openalea.mtg source_files: - share/data/** - - tests/** - - tests/data/** + - test/** + - test/data/** commands: - - cd tests + - cd test - pytest -v --ignore=test_aml.py --ignore=test_stat.py about: diff --git a/src/openalea/mtg/version.py b/src/openalea/mtg/version.py index dd20995..d72c00e 100644 --- a/src/openalea/mtg/version.py +++ b/src/openalea/mtg/version.py @@ -7,7 +7,7 @@ minor = 3 """(int) Version minor component.""" -post = 0 +post = 1 """(int) Version post or bugfix component.""" __version__ = ".".join([str(s) for s in (major, minor, post)]) diff --git a/tests/__init__.py b/test/__init__.py similarity index 100% rename from tests/__init__.py rename to test/__init__.py diff --git a/tests/data/agraf.drf b/test/data/agraf.drf similarity index 100% rename from tests/data/agraf.drf rename to test/data/agraf.drf diff --git a/tests/data/leaf_axis.drf b/test/data/leaf_axis.drf similarity index 100% rename from tests/data/leaf_axis.drf rename to test/data/leaf_axis.drf diff --git a/tests/data/monopodial_plant.mtg b/test/data/monopodial_plant.mtg similarity index 100% rename from tests/data/monopodial_plant.mtg rename to test/data/monopodial_plant.mtg diff --git a/tests/data/mtg1.mtg b/test/data/mtg1.mtg similarity index 100% rename from tests/data/mtg1.mtg rename to test/data/mtg1.mtg diff --git a/tests/data/mtg2.mtg b/test/data/mtg2.mtg similarity index 100% rename from tests/data/mtg2.mtg rename to test/data/mtg2.mtg diff --git a/tests/data/mtg3.mtg b/test/data/mtg3.mtg similarity index 100% rename from tests/data/mtg3.mtg rename to test/data/mtg3.mtg diff --git a/tests/data/mtg4.mtg b/test/data/mtg4.mtg similarity index 100% rename from tests/data/mtg4.mtg rename to test/data/mtg4.mtg diff --git a/tests/data/mtg5.mtg b/test/data/mtg5.mtg similarity index 100% rename from tests/data/mtg5.mtg rename to test/data/mtg5.mtg diff --git a/tests/data/mtg51.mtg b/test/data/mtg51.mtg similarity index 100% rename from tests/data/mtg51.mtg rename to test/data/mtg51.mtg diff --git a/tests/data/mtg_dynamic.mtg b/test/data/mtg_dynamic.mtg similarity index 100% rename from tests/data/mtg_dynamic.mtg rename to test/data/mtg_dynamic.mtg diff --git a/tests/data/noyer.drf b/test/data/noyer.drf similarity index 100% rename from tests/data/noyer.drf rename to test/data/noyer.drf diff --git a/tests/data/oaktree.drf b/test/data/oaktree.drf similarity index 100% rename from tests/data/oaktree.drf rename to test/data/oaktree.drf diff --git a/tests/data/origin.drf b/test/data/origin.drf similarity index 100% rename from tests/data/origin.drf rename to test/data/origin.drf diff --git a/tests/data/reconstructed_appletree.mtg b/test/data/reconstructed_appletree.mtg similarity index 100% rename from tests/data/reconstructed_appletree.mtg rename to test/data/reconstructed_appletree.mtg diff --git a/tests/data/test10_agraf.mtg b/test/data/test10_agraf.mtg similarity index 100% rename from tests/data/test10_agraf.mtg rename to test/data/test10_agraf.mtg diff --git a/tests/data/test11_wij10.mtg b/test/data/test11_wij10.mtg similarity index 100% rename from tests/data/test11_wij10.mtg rename to test/data/test11_wij10.mtg diff --git a/tests/data/test12_wij10.mtg b/test/data/test12_wij10.mtg similarity index 100% rename from tests/data/test12_wij10.mtg rename to test/data/test12_wij10.mtg diff --git a/tests/data/test6_apricot2.mtg b/test/data/test6_apricot2.mtg similarity index 100% rename from tests/data/test6_apricot2.mtg rename to test/data/test6_apricot2.mtg diff --git a/tests/data/test7.mtg b/test/data/test7.mtg similarity index 100% rename from tests/data/test7.mtg rename to test/data/test7.mtg diff --git a/tests/data/test8_boutdenoylum2.mtg b/test/data/test8_boutdenoylum2.mtg similarity index 100% rename from tests/data/test8_boutdenoylum2.mtg rename to test/data/test8_boutdenoylum2.mtg diff --git a/tests/data/test9_noylum2.mtg b/test/data/test9_noylum2.mtg similarity index 100% rename from tests/data/test9_noylum2.mtg rename to test/data/test9_noylum2.mtg diff --git a/tests/data/walnut.drf b/test/data/walnut.drf similarity index 100% rename from tests/data/walnut.drf rename to test/data/walnut.drf diff --git a/tests/data/wij10.drf b/test/data/wij10.drf similarity index 100% rename from tests/data/wij10.drf rename to test/data/wij10.drf diff --git a/tests/debug.py b/test/debug.py similarity index 100% rename from tests/debug.py rename to test/debug.py diff --git a/tests/eurograph.py b/test/eurograph.py similarity index 100% rename from tests/eurograph.py rename to test/eurograph.py diff --git a/tests/random_mtg.py b/test/random_mtg.py similarity index 100% rename from tests/random_mtg.py rename to test/random_mtg.py diff --git a/tests/simple.lpy b/test/simple.lpy similarity index 100% rename from tests/simple.lpy rename to test/simple.lpy diff --git a/tests/test_aml.py b/test/test_aml.py similarity index 100% rename from tests/test_aml.py rename to test/test_aml.py diff --git a/tests/test_dresser.py b/test/test_dresser.py similarity index 100% rename from tests/test_dresser.py rename to test/test_dresser.py diff --git a/tests/test_edition.py b/test/test_edition.py similarity index 100% rename from tests/test_edition.py rename to test/test_edition.py diff --git a/tests/test_lsystem.py b/test/test_lsystem.py similarity index 100% rename from tests/test_lsystem.py rename to test/test_lsystem.py diff --git a/tests/test_mtg.py b/test/test_mtg.py similarity index 100% rename from tests/test_mtg.py rename to test/test_mtg.py diff --git a/tests/test_operation.py b/test/test_operation.py similarity index 100% rename from tests/test_operation.py rename to test/test_operation.py diff --git a/tests/test_parsing.py b/test/test_parsing.py similarity index 100% rename from tests/test_parsing.py rename to test/test_parsing.py diff --git a/tests/test_parsing_axialtree.py b/test/test_parsing_axialtree.py similarity index 100% rename from tests/test_parsing_axialtree.py rename to test/test_parsing_axialtree.py diff --git a/tests/test_parsing_mtg.py b/test/test_parsing_mtg.py similarity index 100% rename from tests/test_parsing_mtg.py rename to test/test_parsing_mtg.py diff --git a/tests/test_plantframe1.py b/test/test_plantframe1.py similarity index 100% rename from tests/test_plantframe1.py rename to test/test_plantframe1.py diff --git a/tests/test_proxynode.py b/test/test_proxynode.py similarity index 100% rename from tests/test_proxynode.py rename to test/test_proxynode.py diff --git a/tests/test_rewriting.py b/test/test_rewriting.py similarity index 100% rename from tests/test_rewriting.py rename to test/test_rewriting.py diff --git a/tests/test_stat.py b/test/test_stat.py similarity index 100% rename from tests/test_stat.py rename to test/test_stat.py diff --git a/tests/test_traversal.py b/test/test_traversal.py similarity index 100% rename from tests/test_traversal.py rename to test/test_traversal.py diff --git a/tests/test_tree.py b/test/test_tree.py similarity index 100% rename from tests/test_tree.py rename to test/test_tree.py diff --git a/tests/test_tulip.py b/test/test_tulip.py similarity index 100% rename from tests/test_tulip.py rename to test/test_tulip.py diff --git a/tests/test_turtle.py b/test/test_turtle.py similarity index 100% rename from tests/test_turtle.py rename to test/test_turtle.py diff --git a/tests/test_writing_mtg.py b/test/test_writing_mtg.py similarity index 100% rename from tests/test_writing_mtg.py rename to test/test_writing_mtg.py diff --git a/tests/test_writing_mtg2.py b/test/test_writing_mtg2.py similarity index 100% rename from tests/test_writing_mtg2.py rename to test/test_writing_mtg2.py diff --git a/tests/toto.xls b/test/toto.xls similarity index 100% rename from tests/toto.xls rename to test/toto.xls diff --git a/tests/visu3d.py b/test/visu3d.py similarity index 100% rename from tests/visu3d.py rename to test/visu3d.py