def test_leaf(self): """ leaf without lateral leafs """ ons = pb.Matrix3d(pb.Vector3d(0., 0., 1.), pb.Vector3d(0., 1., 0.), pb.Vector3d(1., 0., 0.)) plant = pb.Plant() # store organism (not owned by Organ, or OrganRandomParameter) p0 = pb.LeafRandomParameter(plant) p0.name, p0.subType, p0.la, p0.lb, p0.lmax, p0.ln, p0.r, p0.dx = "leaf", 1, 3.5, 1., 7.5, 3, 1, 0.1 phi = np.array([-90, -45, 0., 45, 90]) / 180. * np.pi l = np.array([3, 2.2, 1.7, 2, 3.5]) N = 100 # N is rather high for testing p0.createLeafRadialGeometry(phi, l, N) # y = np.array([-3, -3 * 0.7, 0., 3.5 * 0.7, 3.5]) # l = np.array([0., 2.2 * 0.7, 1.7, 1.8 * 0.7, 0.]) # N = 105 # N is rather high for testing # p0.createLeafGeometry(y, l, N) plant.setOrganRandomParameter(p0) # the organism manages the type parameters and takes ownership plant.setOrganRandomParameter(pb.SeedRandomParameter(plant)) # because we cannot pass a nullptr to pb.Leaf(...) L48 param0 = p0.realize() # set up leaf by hand (without a leaf syleaf) param0.la, param0.lb = 0, 0 # its important parent has zero length, otherwise creation times are messed up parentleaf = pb.Leaf(1, param0, True, True, 0., 0., ons, 0, False, 0) # takes ownership of param0 parentleaf.setOrganism(plant) parentleaf.addNode(pb.Vector3d(0, 0, -3), 0) # there is no nullptr in Python leaf = pb.Leaf(plant, p0.subType, ons, 0, parentleaf , 0) leaf.setOrganism(plant) leaf.simulate(7) vp.plot_leaf(leaf)
def test_CPlantBox(self): """tests the functions needed by CPlantBox defined in CPlantBox_PiafMunch.py""" p = pb.Plant() p.openXML(path + "Heliantus_Pagès_2013.xml") seeds = p.getOrganRandomParameter(pb.OrganTypes.seed) roots = p.getOrganRandomParameter(pb.OrganTypes.root) stems = p.getOrganRandomParameter(pb.OrganTypes.stem) leafs = p.getOrganRandomParameter(pb.OrganTypes.leaf) # for p_ in seeds: # print(p_) # for p_ in roots[1:]: # print(p_) # for p_ in stems[1:]: # print(p_) # for p_ in leafs[1:]: # print(p_) self.assertEqual( [len(seeds), len(roots[1:]), len(stems[1:]), len(leafs[1:])], [1, 3, 3, 1], "test_CPlantBox: read wrong number of random parameter from xml") p.initialize(True) p.simulate(76) p.write("morningglory.vtp")
def test_CPlantBox_analysis(self): """tests the functions needed by CPlantBox_analysis defined in CPlantBox_PiafMunch.py""" p = pb.Plant() p.openXML(path + "Heliantus_Pagès_2013.xml") p.initialize() p.simulate(76) ana = pb.SegmentAnalyser(p) ana.write("morningglory_ama.vtp")
def CPlantBox_analysis(name, time, output = "output"): #define a function, in line 20, we can run it in one line of code plant = pb.Plant() plant.openXML("../../modelparameter/plant/" + name) plant.initialize(True) plant.simulate(time) #plant.write("../../results/{}.vtp".format(output),15) ana = pb.SegmentAnalyser(plant) ana.write("{}.vtp".format(str(output))) ana.write("{}.txt".format(str(output))) return plant;
def CPlantBox(name, time, output = "output"): #define a function, in line 20, we can run it in one line of code plant = pb.Plant() plant.openXML('../../modelparameter/plant/'+name) seeds = plant.getOrganRandomParameter(pb.OrganTypes.seed) roots = plant.getOrganRandomParameter(pb.OrganTypes.root) stems = plant.getOrganRandomParameter(pb.OrganTypes.stem) leafs = plant.getOrganRandomParameter(pb.OrganTypes.leaf) plant.initialize(True) plant.simulate(time) plant.write("{}.vtp".format(str(output))) return plant;
def __init__(self): self.rsmls = [] # list of rsml data to analyse, rsml_data.RsmlData self.estimates = [{}] # list of dictionary of parameters per root self.plant = pb.Plant() # to own the CPlantBox parameters self.parameters = [ ] # list of CPlantBox parameters of type , index = subType, max = 10 self.times = [] self.base_root_indices = [] # tap roots and basal roots self.tap_root_indices = [] self.basal_root_indices = [] # includes shoot bornes self.root_indices = [] # all roots self.folder_name = "" self.file_names = [] # for debugging
def CPlantBox_PiafMunch(name, time, output = "test_output"): plant = pb.Plant() plant.openXML("../../modelparameter/plant/" + name) seeds = plant.getOrganRandomParameter(pb.OrganTypes.seed) roots = plant.getOrganRandomParameter(pb.OrganTypes.root) stems = plant.getOrganRandomParameter(pb.OrganTypes.stem) leafs = plant.getOrganRandomParameter(pb.OrganTypes.leaf) plant.initialize(True) plant.simulate(time) plant.write("{}.vtp".format(str(output))) dict_all = convert( plant ) write_PiafMunch_parameter(dict_all['node_connection'], dict_all['nodes_organtype'], dict_all['nodes_r_st'], dict_all['unq_cnt'], name) return dict_all ;
def stem_example_rtp(self, phytomereGrowth = "sequential"): """ an example used in the tests below, a main stem with laterals """ self.plant = pb.Plant() # store organism (not owned by Organ, or OrganRandomParameter) p0 = pb.StemRandomParameter(self.plant) p0.name, p0.subType, p0.la, p0.lb, p0.lmax, p0.ln, p0.r, p0.dx, p0.dxMin = "main", 1, 10., 10., 100., 1., 1.5, 1, 0.5 p0.delayLat = 1. p0.delayNG = 2. p0.successor = [5] p0.successorP = [1.] if phytomereGrowth == "sequential": p0.nodalGrowth = 0 if phytomereGrowth == "equal": p0.nodalGrowth = 1 p1 = pb.StemRandomParameter(self.plant) p1.name, p1.subType, p1.lmax, p1.r, p1.dx, p1.dxMin = "lateral", 5, 5., 2., 1, 0.5 self.p0, self.p1 = p0, p1 # needed at later point self.plant.setOrganRandomParameter(p0) # the organism manages the type parameters and takes ownership self.plant.setOrganRandomParameter(p1) srp = pb.SeedRandomParameter(self.plant) self.plant.setOrganRandomParameter(srp) # creates seed organ (otherwise throws error in plant::simulate()) # test == True => no need to give root parameter self.plant.initialize(verbose = False, test = True) param0 = p0.realize() # set up stem by hand (without a stem system) param0.la, param0.lb = 0, 0 # its important parent has zero length, otherwise creation times are messed up self.ons = pb.Matrix3d(pb.Vector3d(0., 0., 1.), pb.Vector3d(0., 1., 0.), pb.Vector3d(1., 0., 0.)) parentstem = pb.Stem(1, param0, True, True, 0., 0., self.ons, 0, False, 0) # takes ownership of param0 parentstem.setOrganism(self.plant) parentstem.addNode(pb.Vector3d(0, 0, -3), 0) # there is no nullptr in Python self.parentstem = parentstem # store parent (not owned by child Organ) self.stem = pb.Stem(self.plant, p0.subType, self.ons, 0, self.parentstem , 0) self.stem.setOrganism(self.plant)
def test_convert(self): """tests the functions needed by the convert function of CPlantBox_PiafMunch.py""" p = pb.Plant() p.openXML(path + "Heliantus_Pagès_2013.xml") p.initialize() p.simulate(76) nodes = np.array([np.array(a) / 100 for a in p.getNodes() ]) # convert to numpy array, and from cm to m print(nodes.shape) rseg = np.array([ np.array(s) for s in p.getSegments(pb.OrganTypes.root) ]) # root system segments print(rseg.shape) sseg = np.array([ np.array(s) for s in p.getSegments(pb.OrganTypes.stem) ]) # stem system segments print(sseg.shape) # lseg = v2ai(plant.getNodesOrganType()) l = np.array( [o.getParameter("organType") for o in p.getSegmentOrigins()]) print(l.shape) # plant_ana = pb.SegmentAnalyser(p) # node_connection_o = seg2a(p.getSegments(15)) # plant segments pass
"""plant example""" import sys sys.path.append("../../..") sys.path.append("../../../src/python_modules") import numpy as np import plantbox as pb import vtk_plot as vp plant = pb.Plant() # Open plant and root parameter from a file path = "../../../modelparameter/plant/" name = "0" # 0 , CPlantBox_test_leaf_tree00 # LEAFS smallPlant_mgiraud "manyleaves" # NO LEAFS "CPlantBox_test_leaf_tree22" # "chicon_entire" # "Anagallis_femina_leaf_shape" # "Anagallis_femina_Leitner_2010" # BREAKS MY COMPUTER Swiss_chard plant.readParameters(path + name + ".xml") # print radii print("leafs") for p in plant.getOrganRandomParameter(pb.leaf): p.a = 0.05 p.a_s = 0 if (p.subType > 0): print(p.subType, "radius", p.a, "lmax", p.lmax, p.ln, p.lb, p.successor, p.nob()) if (p.subType > 2):
def create_basil(): plant = pb.Plant() p0 = pb.RootRandomParameter(plant) # with default values, p1 = pb.RootRandomParameter(plant) # all standard deviations are 0 s2 = pb.StemRandomParameter(plant) s3 = pb.StemRandomParameter(plant) l1 = pb.LeafRandomParameter(plant) p0.name = "taproot" p0.a = 0.2 # [cm] radius p0.subType = 1 # [-] index starts at 1 p0.lb = 5 # [cm] basal zone p0.la = 10 # [cm] apical zone p0.lmax = 30 # [cm] maximal root length, number of lateral branching nodes = round((lmax-lb-la)/ln) + 1 p0.ln = 1. # [cm] inter-lateral distance (16 branching nodes) p0.theta = 0. # [rad] p0.r = 1 # [cm/day] initial growth rate p0.dx = 10 # [cm] axial resolution p0.successor = [2] # add successors p0.successorP = [1] # probability that successor emerges p0.tropismT = pb.TropismType.gravi # p0.tropismN = 1.8 # [-] strength of tropism p0.tropismS = 0.2 # [rad/cm] maximal bending p1.name = "lateral" p1.a = 0.1 # [cm] radius p1.subType = 2 # [1] index starts at 1 p1.lmax = 15 # # [cm] apical zone p1.lmaxs = 0.15 # [cm] standard deviation of the apical zone p1.theta = 90. / 180. * np.pi # [rad] p1.r = 2 # initial growth rate p1.dx = 1 # [cm] axial resolution p1.tropismT = pb.TropismType.gravi # exo p1.tropismN = 2 # [-] strength of tropism p1.tropismS = 0.1 # [rad/cm] maximal bending s2.name = "mainstem" s2.subType = 1 s2.lmax = 25 # s2.lmaxs = 1 s2.lb = 3 s2.la = 0 s2.ln = 3 # This value is normally the Inter-lateral distance [cm], but with decussate plant, this value is # multiplied by 2 s2.lnf = 5 # This value means "successors in a decussate position" s2.RotBeta = 1 s2.BetaDev = 0 s2.InitBeta = 0 s2.gf = 1 s2.successor = [2] s2.successorP = [1] s2.tropismT = 4 # s2.theta = 1/6 s2.theta = 0 s2.tropismN = 18 s2.tropismS = 0.01 s3.name = "invisible" # The invisible stem representing the bud of the leaf s3.subType = 2 s3.la = 0 s3.ln = 0 s3.lmax = 5 s3.RotBeta = 1 s3.BetaDev = 0 s3.InitBeta = 0.5 s3.tropismS = 0 s3.lnf = 5 l1.name = 'basil' l1.subType = 2 l1.lb = 2 l1.la = 0.2 l1.lmax = 5 l1.r = 0.5 l1.RotBeta = 0.5 l1.BetaDev = 0 l1.InitBeta = 0.5 l1.tropismT = 1 l1.tropismN = 5 l1.tropismS = 0.1 l1.theta = 0.35 l1.thetas = 0.05 l1.gf = 1 l1.lnf = 5 # If not precised, it will not be possible to do the opposite decussate arrangement plant.setOrganRandomParameter(p0) plant.setOrganRandomParameter(p1) plant.setOrganRandomParameter(s2) plant.setOrganRandomParameter(s3) plant.setOrganRandomParameter(l1) srp = pb.SeedRandomParameter(plant) # with default values # srp.seedPos = pb.Vector3d(10, 10, -3.) # [cm] seed position srp.seedPos = pb.Vector3d(0, 0, -3.) # [cm] seed position srp.maxB = 0 # [-] number of basal roots (neglecting basal roots and shoot borne) srp.firstB = 10. # [day] first emergence of a basal root srp.delayB = 3. # [day] delay between the emergence of basal roots plant.setOrganRandomParameter(srp) return plant
def create_arabidopsis(): plant = pb.Plant() p0 = pb.RootRandomParameter(plant) # with default values, p1 = pb.RootRandomParameter(plant) # all standard deviations are 0 s1 = pb.StemRandomParameter(plant) s2 = pb.StemRandomParameter(plant) s3 = pb.StemRandomParameter(plant) s4 = pb.StemRandomParameter(plant) l1 = pb.LeafRandomParameter(plant) p0.name = "taproot" p0.a = 0.2 # [cm] radius p0.subType = 1 # [-] index starts at 1 p0.lb = 5 # [cm] basal zone p0.la = 10 # [cm] apical zone p0.lmax = 30 # [cm] maximal root length, number of lateral branching nodes = round((lmax-lb-la)/ln) + 1 p0.ln = 1. # [cm] inter-lateral distance (16 branching nodes) p0.theta = 0. # [rad] p0.r = 1 # [cm/day] initial growth rate p0.dx = 10 # [cm] axial resolution p0.successor = [2] # add successors p0.successorP = [1] # probability that successor emerges p0.tropismT = pb.TropismType.gravi # p0.tropismN = 1.8 # [-] strength of tropism p0.tropismS = 0.2 # [rad/cm] maximal bending p1.name = "lateral" p1.a = 0.1 # [cm] radius p1.subType = 2 # [1] index starts at 1 p1.lmax = 15 # # [cm] apical zone p1.lmaxs = 0.15 # [cm] standard deviation of the apical zone p1.theta = 90. / 180. * np.pi # [rad] p1.r = 2 # initial growth rate p1.dx = 1 # [cm] axial resolution p1.tropismT = pb.TropismType.gravi # exo p1.tropismN = 2 # [-] strength of tropism p1.tropismS = 0.1 # [rad/cm] maximal bending s1.name = "mainstem" s1.subType = 1 s1.lmax = 25 s1.lmaxs = 1 s1.lb = 0 s1.lbs = 0.1 s1.la = 3 s1.las = 0.1 s1.ln = 3 s1.lns = 0.2 s1.lnf = 0 # 1 peut être cool s1.RotBeta = 0 s1.BetaDev = 0 s1.InitBeta = 0 s1.gf = 1 s1.successor = [3, 2] s1.successorP = [0.3, 0.7] # s1.successor = [3] # s1.successorP = [1] s1.tropismT = 1 s1.theta = 0. s1.thetas = 0.05 s1.tropismN = 2 s1.tropismS = 0.005 s1.r = 1 s1.rs = 0.05 s2.name = "secondary_stem" s2.subType = 3 s2.lmax = 7 s2.lmaxs = 0.2 s2.lb = 0 s2.la = 2 s2.ln = 2 s2.lns = 0.1 s2.lnf = 0 s2.RotBeta = 2 / 3 s2.BetaDev = 0.1 s2.InitBeta = 0 s2.gf = 1 s2.successor = [2] s2.successorP = [1] s2.tropismT = 4 s2.theta = 0.3 s2.thetas = 0.02 s2.tropismN = 18 s2.tropismS = 0.01 s2.r = 0.5 s2.rs = 0.02 s3.name = "invisible stem" s3.subType = 2 s3.lmax = 5 s3.la = 0 s3.ln = 0 s3.RotBeta = 2/3 s3.BetaDev = 0 s3.InitBeta = 0. s3.lb = 0 s3.la = 0 s3.ln = 0 s3.lnf = 0 s3.RotBeta = 2 / 3 s3.BetaDev = 0 s3.InitBeta = 0 s3.gf = 1 s3.tropismT = 1 s3.theta = 0.3 s3.tropismN = 18 s3.tropismS = 0.01 s3.r = 1 l1.name = 'leaf_under_second_stem' l1.subType = 2 l1.lb = 2 l1.la = 0.2 l1.lmax = 5 l1.lmaxs = 0.1 l1.r = 0.5 l1.rs = 0.02 l1.RotBeta = 0.5 l1.BetaDev = 0 l1.InitBeta = 0. l1.tropismT = 1 l1.tropismN = 5 l1.tropismS = 0.15 l1.theta = 0.35 l1.gf = 1 s4.name = "rosette" # Cannot be a leaf organ because we can only create 1 leaf organ subType s4.subType = 4 s4.lmax = 10 s4.lmaxs = 0.2 s4.lb = 1 s4.la = 0 s4.ln = 2 s4.lnf = 0 s4.RotBeta = 3 / 5 s4.BetaDev = 0.02 s4.InitBeta = 0 s4.gf = 1 s4.tropismT = 1 s4.theta = 0.3 s4.thetas = 0.02 s4.tropismN = 18 s4.tropismS = 0.01 s4.r = 0.5 s4.rs = 0.02 plant.setOrganRandomParameter(p0) plant.setOrganRandomParameter(p1) plant.setOrganRandomParameter(s1) plant.setOrganRandomParameter(s2) plant.setOrganRandomParameter(s3) plant.setOrganRandomParameter(s4) plant.setOrganRandomParameter(l1) srp = pb.SeedRandomParameter(plant) # with default values srp.seedPos = pb.Vector3d(0., 0., -3.) # [cm] seed position srp.maxB = 0 # [-] number of basal roots (neglecting basal roots and shoot borne) srp.firstB = 10. # [day] first emergence of a basal root srp.delayB = 3. # [day] delay between the emergence of basal roots srp.maxTil = 10 plant.setOrganRandomParameter(srp) return plant