def soil_cores(x :list, y :list, r :float, h :float): """ A lsit of soil core geometries with a fixed location in the field @param x x coordinates of the soil cores (cm) @param y y coordinates of the soil cores (cm) @param r radius of the soil core (cm) @param h height of the soil core (cm) """ assert len(x) == len(y), "coordinate length must be equal" core = pb.SDF_PlantContainer(r, r, h, False) cores = [] for i in range(0, len(x)): cores.append(pb.SDF_RotateTranslate(core, 0., pb.SDF_Axis.xaxis, pb.Vector3d(x[i], y[i], 0.))) # just translate return cores;
simtime_ = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] for st in simtime_: # # Root system # rs = rb.RootSystem() path = "../../../modelparameter/rootsystem/" name = "test_root" rs.readParameters(path + name + ".xml") #set geometry width = 4 # cm depth = 15 soilcore = rb.SDF_PlantContainer(width, width, depth, True) rs.setGeometry(soilcore) rs.setSeed(0) rs.initialize() for ii in range(0, st): simtime = 1 rs.simulate(simtime, True) rs.write("vtp/day_" + str(ii + 1) + ".vtp") # # Grid parameter # nodes = np.array([np.array(n) for n in rs.getNodes()]) np.save("nodes/day" + str(ii + 1), nodes) xres = 0.1
print(p.subType, "radius", p.a, "lmax", p.lmax, p.ln, p.lb, p.successor, p.nob()) p.a = p.a / 2 p.a = 0.2 p.a_s = 0 print("roots") for p in plant.getOrganRandomParameter(pb.root): if (p.subType > 0): print(p.subType, p.a, p.successor) if p.subType == 1: # taproot p.theta = 0. p.a = 0.05 p.a_s = 0 soil = pb.SDF_PlantContainer(1.e6, 1.e6, 1.e6, False) # plant.setGeometry(soil) # increase resolution for p in plant.getOrganRandomParameter(pb.root): p.dx = 0.2 # Initialize plant.initialize() # Simulate plant.simulate(30, True) # Export final result (as vtp) plant.write("results/example_plant.vtp")
import sys sys.path.append("../../..") import plantbox as pb import vtk_plot as vp import math rs = pb.RootSystem() # Open plant and root parameter from a file path = "../../../modelparameter/rootsystem/" name = "Zea_mays_4_Leitner_2014" rs.readParameters(path + name + ".xml") # 1. Creates a square rhizotron r*r, with height h, rotated around the x-axis r, h, alpha = 20, 4, 45 rhizotron2 = pb.SDF_PlantContainer(r, r, h, True) posA = pb.Vector3d(0, r, -h / 2) # origin before rotation A = pb.Matrix3d.rotX(alpha / 180. * math.pi) posA = A.times(posA) # origin after rotation rotatedRhizotron = pb.SDF_RotateTranslate(rhizotron2, alpha, 0, posA.times(-1)) # 2. A split pot experiment topBox = pb.SDF_PlantBox(22, 20, 5) sideBox = pb.SDF_PlantBox(10, 20, 35) left = pb.SDF_RotateTranslate(sideBox, pb.Vector3d(-6, 0, -5)) right = pb.SDF_RotateTranslate(sideBox, pb.Vector3d(6, 0, -5)) box_ = [] box_.append(topBox) box_.append(left) box_.append(right) splitBox = pb.SDF_Union(box_)
import numpy as np import matplotlib.pyplot as plt import plantbox as pb path = "../../../modelparameter/rootsystem/" name = "Zea_mays_1_Leitner_2010" # Zea_mays_1_Leitner_2010, Brassica_napus_a_Leitner_2010 rs = pb.RootSystem() rs.readParameters(path + name + ".xml") rs.initialize() rs.simulate(120) rs.write("results/example_3b.vtp") r, depth, layers = 5, 100., 100 # Soil core analysis soilcolumn = pb.SDF_PlantContainer(r, r, depth, False) # in the center of the root soilcolumn2 = pb.SDF_RotateTranslate(soilcolumn, 0, 0, pb.Vector3d(10, 0, 0)) # shift 10 cm # pick one geometry for further analysis geom = soilcolumn z_ = np.linspace(0, -1 * depth, layers) fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(16, 8)) for a in axes: a.set_xlabel('RLD (cm/cm^3)') # layer size is 1 cm a.set_ylabel('Depth (cm)') # Make a root length distribution layerVolume = depth / layers * 20 * 20 times = [120, 60, 30, 10]
import sys sys.path.append("..") import plantbox as pb from rb_tools import * # set up simulation rs = pb.RootSystem() name = "Zea_mays_4_Leitner_2014" rs.openFile(name) soilcore = pb.SDF_PlantContainer(5, 5, 40, False) rs.setGeometry(soilcore) # soilcore, or rhizotron rs.initialize() # test push and pop rs.simulate(20) nodes0a = vv2a(rs.getNodes()) rs.push() # push simualtion at time 20 rs.simulate(100) nodes1a = vv2a(rs.getNodes()) rs.pop() # should be at state 20 again nodes0b = vv2a(rs.getNodes()) stime0 = rs.getSimTime() rs.simulate(100) nodes1b = vv2a(rs.getNodes()) stime1 = rs.getSimTime() # check print("\nResults ")
def err (fitparams): #parameters to be optimized lmaxp=fitparams[0] tropismNp=fitparams[1] tropismSp=fitparams[2] rp=fitparams[3] simtime = 120 M = 4 # number of plants in rows N = 2 # number of rows distp = 3 # distance between the root systems along row[cm] distr =12 # distance between the rows[cm] interrow=N*distr # inter-row spacing row=M*distp # row spacing r, depth, layers = 5, 100., 11 # Soil core analysis layerVolume = depth / layers * r * r * np.pi z_ = np.linspace(0, -1 * depth, layers) times = [120, 60, 30, 10] soilcolumn = pb.SDF_PlantContainer(r, r, depth, False) # in the center of the root soilcolumn1 = pb.SDF_RotateTranslate(soilcolumn, 0, 0, pb.Vector3d(-6, 0, 0)) soilcolumn2 = pb.SDF_RotateTranslate(soilcolumn, 0, 0, pb.Vector3d(6, 0, 0)) soilcolumns=[soilcolumn1,soilcolumn, soilcolumn2] with open('rld.pkl','rb') as f: measured_RLD = pkl.load(f) real_RLD=np.reshape(measured_RLD,(measured_RLD.shape[0]*measured_RLD.shape[1]*measured_RLD.shape[2],1)) rld=np.zeros([measured_RLD.shape[0],measured_RLD.shape[1],measured_RLD.shape[2]]) # rld=np.zeros([len(soilcolumns),len(times),layers]) path = "../../modelparameter/rootsystem/" name = "wheat" # fig, axes = plt.subplots(nrows = 1, ncols = len(soilcolumns), figsize = (16, 8)) # Make a root length distribution along the soil cores for k in range(len(soilcolumns)): # Initializes N*M root systems allRS = [] for i in range(0, N): for j in range(0, M): rs = pb.RootSystem() rs.readParameters(path + name + ".xml") p1 = rs.getRootRandomParameter(1) # tap and basal root type p1.lmax = lmaxp p1.tropismN=tropismNp p1.tropismS=tropismSp p1.r=rp for p in rs.getRootRandomParameter(): p.lns = 0 p.rs = 0 p.lmaxs = 0 p.thetas = 0 p.las = 0 p.lbs=0 rs.setSeed(1) rs.getRootSystemParameter().seedPos = pb.Vector3d(distr * i, distp * j, -3.) # cm rs.initialize() allRS.append(rs) # Simulate for rs in allRS: rs.simulate(simtime) # Export results as single vtp files (as polylines) ana = pb.SegmentAnalyser() # see example 3b for z, rs in enumerate(allRS): # vtpname = "results/rlds/plant_" + str(z) + ".vtp" # rs.write(vtpname) ana.addSegments(rs) # collect all # Write all into single file (segments) # ana.write("results/rlds/all_plants.vtp") ana.mapPeriodic(interrow, row) # ana.write("results/rlds/plant_periodic.vtp") rl_ = [] ana.crop(soilcolumns[k]) ana.pack() # ana.write("results/rlds/core"+str(k+1)+".vtp") # axes[k].set_title('Soil core'+' ' +str(k+1)) for j in range(len(times)): ana.filter("creationTime", 0, times[j]) rl_.append(ana.distribution("length", 0., -depth, layers, True)) # axes[k].plot(np.array(rl_[-1]) / layerVolume, z_) # axes[k].legend(["120 days", "60 days", "30 days", "15 days"]) rld[k]=np.array(rl_)/layerVolume # for a in axes: # a.set_xlabel('RLD $(cm/cm^3)$') # a.set_ylabel('Depth $(cm)$') # a.set_xlim(0,np.max(rld)) # fig.subplots_adjust() # plt.savefig("results/rlds/rld_plot.png") # plt.show() RLD=np.reshape(rld,(rld.shape[0]*rld.shape[1]*rld.shape[2],1)) # print(rld) # with open('results/rlds/rld.pkl','wb') as f: # pkl.dump(rld, f) # sys.exit() err = math.sqrt(sum(((np.subtract(RLD,real_RLD)))**2)/len(RLD)) #NRMSE return err