def analyse(rs, name, simtime, tv0): top = rb.SDF_PlantBox(1e6, 1e6, 42) bot = rb.SDF_Complement(top) ana = rb.SegmentAnalyser(rs) print() print(name, ", age", simtime, "days") print("======================================") print() print("Number of ----------------------------") na = len(rs.getBaseRoots()) print("Axes ", na) nr = rs.getNumberOfRoots() print("Roots ", nr) ns = rs.getNumberOfSegments() print("Segments ", ns) print("\nLength (cm) --------------------------") tl = ana.getSummed("length") print("L0 ", round(tl)) tl_top = ana.getSummed("length", top) tl_bot = ana.getSummed("length", bot) print("Lcomp (top) ", round(tl_top), "(", round(100 * (tl_top / tl)), "%)") print("Lcomp (bot) ", round(tl_bot), "(", round(100 * (tl_bot / tl)), "%)") a = rb.SegmentAnalyser( rs ) # copyFor the record, I had already simulated the RSWMS scenarios with a single root and a large domain (see attached) but I think our parameterization is different as the results loo pretty dissimilar (did you really use 1.8e-5 for kr? Not 1.8e-4? the RS conductance is very small then: 0.0023cm3/hPa/d which explain the stress) a.filter("order", 0) l0 = a.getSummed("length") a = rb.SegmentAnalyser(rs) # copy a.filter("order", 1) l1 = a.getSummed("length") print("Lord (zero) ", round(l0), "(", round(100 * (l0 / tl)), "%)") print("Lord (first)", round(l1), "(", round(100 * (l1 / tl)), "%)") print("\nVolume -------------------------------") tv = ana.getSummed("volume") print("V0 (cm^3) ", tv) print("rVol ", tv / tv0) print()
def analyse(rs, name, simtime, tv0): top = rb.SDF_PlantBox(1e6, 1e6, 42) bot = rb.SDF_Complement(top) ana = rb.SegmentAnalyser(rs) print() print(name, ", age", simtime, "days") print("======================================") print() print("Number of ----------------------------") na = len(rs.getBaseRoots()) print("Axes ", na) nr = rs.getNumberOfRoots() print("Roots ", nr) ns = rs.getNumberOfSegments() print("Segments ", ns) print("\nLength (cm) --------------------------") tl = ana.getSummed(rb.ScalarType.length) print("L0 ", round(tl)) tl_top = ana.getSummed(rb.ScalarType.length, top) tl_bot = ana.getSummed(rb.ScalarType.length, bot) print("Lcomp (top) ", round(tl_top), "(", round(100 * (tl_top / tl)), "%)") print("Lcomp (bot) ", round(tl_bot), "(", round(100 * (tl_bot / tl)), "%)") a = rb.SegmentAnalyser(rs) # copy a.filter(rb.ScalarType.order, 0) l0 = a.getSummed(rb.ScalarType.length) a = rb.SegmentAnalyser(rs) # copy a.filter(rb.ScalarType.order, 1) l1 = a.getSummed(rb.ScalarType.length) print("Lord (zero) ", round(l0), "(", round(100 * (l0 / tl)), "%)") print("Lord (first)", round(l1), "(", round(100 * (l1 / tl)), "%)") print("\nVolume -------------------------------") tv = ana.getSummed(rb.ScalarType.volume) print("V0 (cm^3) ", tv) print("rVol ", tv / tv0) print()
rs.openFile(name) # Manually set tropism to hydrotropism for the first ten root types sigma = [0.4, 1., 1., 1., 1. ] * 2 for i in range(0,10): p = rs.getRootTypeParameter(i+1) p.dx = 0.25 # adjust resolution p.tropismT = rb.TropismType.hydro p.tropismN = 2 # strength of tropism p.tropismS = sigma[i] # Static soil property maxS = 0.7 # maximal minS = 0.1 # minimal slope = 5 # linear gradient between min and max (cm) box = rb.SDF_PlantBox(30,30,2) # cm layer = rb.SDF_RotateTranslate(box, rb.Vector3d(0,0,-16)) soil_prop = rb.SoilPropertySDF(layer, maxS, minS, slope) # Set the soil properties before calling initialize rs.setSoil(soil_prop) # Initialize rs.initialize() # Simulate simtime = 100 # e.g. 30 or 60 days dt = 1 N = round(simtime/dt) for _ in range(0,N): # in a dynamic soil setting you would need to update soil_prop
rs = rb.RootSystem() # Open plant and root parameter from a file name = "Zea_mays_4_Leitner_2014" rs.openFile(name) # 1. Creates a square rhizotron r*r, with height h, rotated around the x-axis r, h, alpha = 20, 4, 45 rhizotron2 = rb.SDF_PlantContainer(r,r,h,True) posA = rb.Vector3d(0,r,-h/2) # origin before rotation A = rb.Matrix3d.rotX(alpha/180.*math.pi) posA = A.times(posA) # origin after rotation rotatedRhizotron = rb.SDF_RotateTranslate(rhizotron2,alpha,0,posA.times(-1)) # 2. A split pot experiment topBox = rb.SDF_PlantBox(22,20,5) sideBox = rb.SDF_PlantBox(10,20,35) left = rb.SDF_RotateTranslate(sideBox, rb.Vector3d(-6,0,-5)) right = rb.SDF_RotateTranslate(sideBox, rb.Vector3d(6,0,-5)) box_ = rb.std_vector_SDF_() box_.append(topBox) box_.append(left) box_.append(right) splitBox = rb.SDF_Union(box_) # 3. Rhizotubes as obstacles box = rb.SDF_PlantBox(96,126,130) # box rhizotube = rb.SDF_PlantContainer(6.4,6.4,96,False) # a single rhizotube rhizoX = rb.SDF_RotateTranslate(rhizotube, 90, rb.SDF_Axis.yaxis, rb.Vector3d(96/2,0,0)) rhizotubes_ = rb.std_vector_SDF_()
import py_rootbox as rb import math rs = rb.RootSystem() name = "Anagallis_femina_Leitner_2010" rs.openFile(name) # box with a left and a right compartment for analysis sideBox = rb.SDF_PlantBox(10, 20, 50) left = rb.SDF_RotateTranslate(sideBox, rb.Vector3d(-4.99, 0, 0)) right = rb.SDF_RotateTranslate(sideBox, rb.Vector3d(4.99, 0, 0)) leftright = rb.SDF_Union(left, right) rs.setGeometry(leftright) # left compartment has a minimum of 0.01, 1 elsewhere maxS = 1. # maximal minS = 0.01 # minimal slope = 1. # [cm] linear gradient between min and max leftC = rb.SDF_Complement(left) soilprop = rb.SoilLookUpSDF(leftC, maxS, minS, slope) # for root elongation soilprop2 = rb.SoilLookUpSDF(left, 1., 0.002, slope) # for branching # Manually set scaling function and tropism parameters sigma = [0.4, 1., 1., 1., 1.] * 2 for i in range(0, 10): p = rs.getRootTypeParameter(i + 1) p.dx = 0.25 # adjust resolution p.tropismS = sigma[i] # 1. Scale elongation p.se = soilprop
import py_rootbox as rb import sys import numpy as np import matplotlib.pyplot as plt rs = rb.RootSystem() # name = "Triticum_aestivum_a_Bingham_2011" # is this the same as your wheat, Shehan? name = "Zea_mays_1_Leitner_2010" rs.openFile(name) # Pore Geometry x_ = (-10, -5, 1, 15) # not 0, otherwise we start in crack y_ = (0, 0, 0, 0) crack = rb.SDF_PlantBox(0.25, 100, 160) # cm cracks_ = rb.std_vector_SDF_() py_cracks = [] for i in range(0, len(y_)): v = rb.Vector3d(x_[i], y_[i], 0) py_cracks.append(rb.SDF_RotateTranslate(crack, v)) cracks_.append(py_cracks[-1]) cracks = rb.SDF_Union(cracks_) rs.setPoreGeometry(cracks) # Increased elongation within the pores maxS = 2 # twice the elongation rate within the pore minS = 1 # normal elongation rate slope = 0 soil_prop = rb.SoilLookUpSDF(cracks, maxS, minS, slope)
for i in range(0,10): rootsystem.getRootTypeParameter(i+1).dx = 0.25; # they seem to coarse rootsystem.getRootTypeParameter(i+1).tropismT = rb.TropismType.hydro; rootsystem.getRootTypeParameter(i+1).tropismN = 3; # N rootsystem.getRootTypeParameter(i+1).tropismS = sigma[i]; # sigma # check if it worked # for i in range(0,10): # print(rootsystem.getRootTypeParameter(i+1)) print (rootsystem.getRootSystemParameter().seedPos) # # Static soil property # box = rb.SDF_PlantBox(100,100,2) layer = rb.SDF_RotateTranslate(box, rb.Vector3d(0,0,-16)) maxS = 0.7 # maximal minS = 0.1 # minimal slope = 5 # [cm] linear gradient between min and ma soilprop = rb.SoilPropertySDF(layer, maxS, minS, slope) # set the soil properties before calling initialize rootsystem.setSoil(soilprop); # # Initialize # rootsystem.initialize(4,5); # it is important to call initialize() after setGeometry()
"""small example in a container""" import py_rootbox as rb rootsystem = rb.RootSystem() # Open plant and root parameter from a file name = "Anagallis_femina_Leitner_2010" rootsystem.readParameters("modelparameter/" + name + ".xml") # Create and set geometry # 1.creates a cylindrical soil core with top radius 5 cm, bot radius 5 cm, height 50 cm, not square but circular soilcore = rb.SDF_PlantContainer(5, 5, 40, False) # 2. creates a square 27*27 cm containter with height 1.4 cm rhizotron = rb.SDF_PlantBox(1.4, 27, 27) # Pick 1, or 2 rootsystem.setGeometry(soilcore) # soilcore, or rhizotron # Initialize rootsystem.initialize() # Simulate rootsystem.simulate(60) # days # Export final result (as vtp) rootsystem.write("../results/example_1b.vtp") # Export container geometry as Paraview Python script rootsystem.write("../results/example_1b.py")
# Additionally, exports the line segments as .txt file to import into Matlab for postprocessing # import py_rootbox as rb import math import random import numpy as np import matplotlib.pyplot as plt rootsystem = rb.RootSystem() name = "Anagallis_femina_Leitner_2010" nameOutputFile = "RLD_Anagallis_femina_Leitner_2010" allRS = [] soilcore = rb.SDF_PlantContainer(5, 5, 40, False) rhizotron = rb.SDF_PlantBox(900, 900, 900) # # Creates N root systems # N = 100 for i in range(0, N - 1): rs = rb.RootSystem() rs.openFile(name) rs.setGeometry(rhizotron) allRS.append(rs) # # Simulate # simtime = 21
def call(cc): rs = rb.RootSystem() #name = "Triticum_aestivum_a_Bingham_2011" # is this the same as your wheat, Shehan? name = "wheat" rs.openFile(name) # Pore Geometry x_ = (-10, -5, 5, 15) # not 0, otherwise we start in crack y_ = (0, 0, 0, 0) #x_=(-10, -5) #y_=(0,0) crack = rb.SDF_PlantBox(1.0, 100, 160) # cm cracks_ = rb.std_vector_SDF_() py_cracks = [] for i in range(0, len(y_)): v = rb.Vector3d(x_[i], y_[i], 0) py_cracks.append(rb.SDF_RotateTranslate(crack, v)) cracks_.append(py_cracks[-1]) cracks = rb.SDF_Union(cracks_) rs.setPoreGeometry(cracks) # Increased elongation within the pores maxS = 2 # twice the elongation rate within the pore minS = 1 # normal elongation rate slope = 0 soil_prop = rb.SoilLookUpSDF(cracks, maxS, minS, slope) # Adjust Tropism sigma = [0.4] * 10 for i in range(0, 10): p = rs.getRootTypeParameter(i + 1) p.dx = 0.25 # adjust resolution p.tropismT = rb.TropismType.gravi p.tropismN = 1 # strength of tropism p.tropismS = sigma[i] p.se = soil_prop # Pore Local Axes v1 = rb.Vector3d(0.67, 0, 0) v2 = rb.Vector3d(0, 0.67, 0) v3 = rb.Vector3d(0, 0, 0.67) rs.setPoreLocalAxes(rb.Matrix3d(v1, v2, v3)) # Pore Conductivity Tensor t1 = rb.Vector3d(1.33, 0, 0) t2 = rb.Vector3d(0, 50.33, 0) t3 = rb.Vector3d(0, 0, 50.33) rs.setPoreConductivity(rb.Matrix3d(t1, t2, t3)) # Set up depth dependent elongation scaling function scale_elongation = rb.EquidistantGrid1D( 0, -160, 17) # todo: replace this by reading in data from CSV file scales = np.zeros( len(scale_elongation.grid) ) + 0.1 # scales from some equation (scale = function(soil_strength) ), where scale in (0,1) scale_elongation.data = a2v(scales) # set proportionality factors # Proportionally scale this function se2 = rb.ProportionalElongation() se2.setBaseLookUp(scale_elongation) # multiply the scale elongation functions se3 = rb.MultiplySoilLookUps(se2, soil_prop) # Manually set scaling function for i in range(0, 10): p = rs.getRootTypeParameter(i + 1) p.se = se3 # Initialize rs.initialize() # Simulate simtime = 30 * 8 # e.g. 30 or 60 days dt = 1 #0.5 * 1./24. N = round(simtime / dt) for i in range(0, N): # time-dependent and depth-dependent scaling function scales = np.loadtxt('W2.csv', delimiter=';', usecols=i) # reading in ith column from CSV file scale_elongation.data = a2v(scales * 1.00) # set the data of scale elongation rs.simulate(dt) # Export results (as vtp) #rs.write("../results/crack.vtp") # Export cracks #rs.setGeometry(cracks) # just for vizualisation #rs.write("../results/crack.py") z_ = np.linspace(0, -1 * 160, 160) # Make a root length distribution ana = rb.SegmentAnalyser(rs) rl_ = ana.distribution(rb.ScalarType.length, 0, 160, 160, True) np.set_printoptions(precision=4) np.savetxt("cw_" + str(cc) + ".txt", rl_, fmt="%.2f")
from matplotlib import ticker import matplotlib.colors as colors rs = rb.RootSystem() # Open plant and root parameter from a file name = "Anagallis_femina_Leitner_2010" rs.openFile(name) # Create and set geometry # 1.creates a cylindrical soil core with top radius 5 cm, bot radius 5 cm, height 50 cm, not square but circular soilcore = rb.SDF_PlantContainer(5, 5, 40, False) # 2. creates a square 27*27 cm containter with height 1.4 cm rhizotron = rb.SDF_PlantBox(0.5, 27, 27) # Pick 1, or 2 rs.setGeometry(rhizotron) # soilcore, or rhizotron # Initialize rs.initialize() # Simulate rs.simulate(60) # days # Root system distance function ana = rb.SegmentAnalyser(rs) radii = ana.getParameter("radius") print(radii[10])
import sys import numpy as np import matplotlib.pyplot as plt import csv rs = rb.RootSystem() #name = "Triticum_aestivum_a_Bingham_2011" # is this the same as your wheat, Shehan? name = "Zea_mays_1_Leitner_2010" rs.openFile(name) # Pore Geometry x_ = (-10, -5, 1, 15) # not 0, otherwise we start in crack y_ = (0, 0, 0, 0) x_ = (-10, -5) y_ = (0, 0) crack = rb.SDF_PlantBox(1.0, 100, 160) # cm cracks_ = rb.std_vector_SDF_() py_cracks = [] for i in range(0, len(y_)): v = rb.Vector3d(x_[i], y_[i], 0) py_cracks.append(rb.SDF_RotateTranslate(crack, v)) cracks_.append(py_cracks[-1]) cracks = rb.SDF_Union(cracks_) rs.setPoreGeometry(cracks) # Increased elongation within the pores maxS = 20 # twice the elongation rate within the pore minS = 1 # normal elongation rate slope = 0