예제 #1
0
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;
예제 #2
0
rs.readParameters(path + name + ".xml")

# Manually set tropism to hydrotropism for the first ten root types
sigma = [0.4, 1., 1., 1., 1.] * 2
for p in rs.getRootRandomParameter():
    p.dx = 0.25  # adjust resolution
    p.tropismT = pb.TropismType.hydro
    p.tropismN = 2  # strength of tropism
    p.tropismS = sigma[p.subType - 1]

# Static soil property in a thin layer
maxS = 0.7  # maximal
minS = 0.1  # minimal
slope = 5  # linear gradient between min and max (cm)
box = pb.SDF_PlantBox(30, 30, 2)  # cm
layer = pb.SDF_RotateTranslate(box, pb.Vector3d(0, 0, -16))
soil_prop = pb.SoilLookUpSDF(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 the soil properties (soil_prop)
    rs.simulate(dt)
"""scales insertion angle"""
import sys
sys.path.append("../../..")
import numpy as np
import plantbox as pb
import vtk_plot as vp

rs = pb.RootSystem()
path = "../../../modelparameter/rootsystem/"
name = "Anagallis_femina_Leitner_2010"
rs.readParameters(path + name + ".xml")

# box with a left and a right compartment for analysis
sideBox = pb.SDF_PlantBox(10, 20, 50)
left = pb.SDF_RotateTranslate(sideBox, pb.Vector3d(-4.99, 0, 0))
right = pb.SDF_RotateTranslate(sideBox, pb.Vector3d(4.99, 0, 0))
leftright = pb.SDF_Union(left, right)
rs.setGeometry(leftright)

# left compartment has a minimum of 0.01, 1 elsewhere
maxS = 1.  # maximal
minS = 0.1  # minimal
slope = 1.  # [cm] linear gradient between min and max
leftC = pb.SDF_Complement(left)
soilprop = pb.SoilLookUpSDF(leftC, maxS, minS, slope)

# Manually set scaling function and tropism parameters
sigma = [0.4, 1., 1., 1., 1.] * 2
for p in rs.getRootRandomParameter():
    if p.subType > 2:
        p.dx = 0.25  # adjust resolution
예제 #4
0
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_)

# 3. Rhizotubes as obstacles
box = pb.SDF_PlantBox(96, 126, 130)  # box
rhizotube = pb.SDF_PlantContainer(6.4, 6.4, 96, False)  # a single rhizotube
예제 #5
0
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]
ana = pb.SegmentAnalyser(rs)
ana.cropDomain(20, 20, depth)  # ana.mapPeriodic(20, 20)
예제 #6
0
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