Example #1
0
def figure8d(rs, N):
    col = 'r', 'g', 'b'
    zz = 1  # mean layer thickness (cm)

    # root length distributions
    rld = np.zeros((3 * N, int(140 / zz)))
    for j in range(0, N):
        for i in range(0, 3):
            ana = rb.SegmentAnalyser(rs[i + j * 3])
            rld[i + j * 3, :] = np.transpose(
                v2a(ana.distribution("length", 0, 140, int(140 / zz),
                                     True))) / (zz * 75. * 15.)  # cm /cm^3
    # mean
    rld_mean = np.zeros((3, int(140 / zz)))
    for j in range(0, N):
        for i in range(0, 3):
            rld_mean[i, :] += rld[i + j * 3, :] / N


#     # error TDOO
#     rld_sd = np.zeros((3, int(140 / zz)))
#     for j in range(0, N):
#         for i in range(0, 3):
#             rld_sd[i, :] += np.square(rld[i + j * 3, :] - rld_mean[i, :])
#     for i in range(0, 3):
#         rld_sd[i, :] = np.sqrt(rld_sd[i, :] / N) / np.sqrt(N)

    z_ = np.linspace(-140, 0, int(140 / zz) + 1)
    #     for i in range(0, 3):
    #         plt.errorbar(rld_mean[i][::-1], 0.5 * (z_[:-1] + z_[1:]), xerr = rld_sd[i][::-1], color = col[i], ecolor = col[i])
    for i in range(0, 3):
        plt.plot(rld_mean[i][::-1], 0.5 * (z_[:-1] + z_[1:]), col[i])
Example #2
0
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()
Example #3
0
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()
Example #4
0
# Soil core analysis
r, depth, layers = 10, 100., 100
soilcolumn = rb.SDF_PlantContainer(r, r, depth, False)  # in the center of the root
soilcolumn2 = rb.SDF_RotateTranslate(soilcolumn, 0, 0, rb.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 = 4, figsize = (16, 8))
for a in axes:
    a.set_xlabel('RLD (cm/cm)')
    a.set_ylabel('Depth (cm)')

# Make a root length distribution
ana = rb.SegmentAnalyser(rs)
rl_ = ana.distribution("length", 0., depth, layers, True)
axes[0].set_title('All roots (120 days)')
axes[0].plot(rl_, z_)

# Make a root length distribution along the soil core
ana = rb.SegmentAnalyser(rs)
# ana.crop(geom)
ana.pack()
rl_ = ana.distribution("length", 0., depth, layers, True)
axes[1].set_title('Soil core (120 days)')
axes[1].plot(rl_, z_)

# How it looked after 30 days?
ana = rb.SegmentAnalyser(rs)
ana.filter("creationTime", 0, 30)
Example #5
0
# p.nob = p.nob*5
# p = rs.getRootTypeParameter(3)
# p.sbp = soilprop2

# simulation
rs.initialize()
simtime = 120.
dt = 1.
N = 120 / dt
for i in range(0, round(N)):
    rs.simulate(dt, True)

# analyse
print()
print("Left compartment: ")
al = rb.SegmentAnalyser(rs)
al.crop(left)
ll = al.getSummed(rb.ScalarType.length)
print('Total root length', ll, 'cm')
lmct = al.getSummed(rb.ScalarType.time) / al.getSummed(rb.ScalarType.one)
print('Mean age', simtime - lmct, 'days')
lroots = al.getRoots()
lm_theta = 0
for r in lroots:
    lm_theta += r.param.theta
lm_theta /= len(lroots)
print('Mean insertion angle is ', lm_theta / math.pi * 180, 'degrees')
print()

print("Right compartment: ")
ar = rb.SegmentAnalyser(rs)
Example #6
0
for rs in allRS:
    c += 1  # root system number
    vtpname = "results/" + name + str(c) + ".vtp"
    rs.write(vtpname, rb.OutputType.polylines)

#
# Compute vertical RLD distribution in layers
#
nl = 20
# number of layers
vRLD = np.zeros((N, nl))
# N rows, nl columns
depth = 100.
c = 0
for rs in allRS:
    analysis = rb.SegmentAnalyser(rs)
    RLD = analysis.distribution(rb.ScalarType.length, 0, depth, nl, True)
    vRLD[c, :] = RLD
    vRLD[c, :] /= (depth / nl)
    c += 1  # root system number

z = np.linspace(0, depth * (-1), nl)  # depth*-1 is the (negativ) z coordinate
mean = np.mean(vRLD, axis=0)
std = np.std(vRLD, axis=0)
#plt.figure(figsize=(3.8,3))
plt.plot(mean, z, 'k-', color="blue", linewidth=2)
plt.fill_betweenx(z,
                  mean + std,
                  mean - std,
                  color="blue",
                  edgecolor='',
Example #7
0
# 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_()
y_ = ( -30, -18, -6, 6, 18, 30 )
z_ = ( -10, -20, -40, -60, -80, -120 )
tube = [] 
for i in range(0,len(y_)):
    v = rb.Vector3d(0,y_[i],z_[i])
    tube.append(rb.SDF_RotateTranslate(rhizoX, v))
    rhizotubes_.append(tube[i])    
    
rhizotubes = rb.SDF_Union(rhizotubes_)
rhizoTube = rb.SDF_Difference(box, rhizotubes)

# Simulate
rs.setGeometry(rotatedRhizotron) # rotatedRhizotron, splitBox, or rhizoTube
rs.initialize() 
rs.simulate(60) # days   

# Export results as segments     
rb.SegmentAnalyser(rs).write("results/example_3e.vtp")

# Export container geometry as Paraview Python script 
rs.write("results/example_3e.py")



Example #8
0
for i in range(0,N):
    for j in range(0,N):
         rs = rb.RootSystem()
         rs.openFile(name) 
         rs.getRootSystemParameter().seedPos = rb.Vector3d(dist*i,dist*j,-3) # set position of seed [cm]
         allRS.append(rs)
         rs.initialize()

# Simulate parallel
simtime = 120
def simulate(i):
    allRS[i].simulate(simtime)
     
pool = Pool()
param_space = range(0,len(allRS))   
d = [1 for res in pool.imap(simulate,param_space)] 

# Export results as single vtp files (as polylines)
c = 0
ana = rb.SegmentAnalyser() # see example 3b
for rs in allRS:
      c += 1 # root system number
      vtpname = "results/example_2b_"+str(c)+".vtp"
      rs.write(vtpname)
      ana.addSegments(rs) # collect all
       
# Write all into single file (segments)
ana.write("results/example_2b_all.vtp") 
      
      
      
Example #9
0
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")
Example #10
0
#         rld_sd[i, :] = np.sqrt(rld_sd[i, :] / N) / np.sqrt(N)

    z_ = np.linspace(-140, 0, int(140 / zz) + 1)
    #     for i in range(0, 3):
    #         plt.errorbar(rld_mean[i][::-1], 0.5 * (z_[:-1] + z_[1:]), xerr = rld_sd[i][::-1], color = col[i], ecolor = col[i])
    for i in range(0, 3):
        plt.plot(rld_mean[i][::-1], 0.5 * (z_[:-1] + z_[1:]), col[i])

names = ["maize_p1_zero_std", "maize_p2_zero_std", "maize_p3_zero_std"]
ages = [63.5, 55.5, 58.5]

N = 100
rs = []
for j in range(0, N):
    for i in range(0, 3):
        rs.append(simulate(names[i], ages[i]))

names = ["P1", "P2", "P3"]

tv0 = 1
for i in range(0, 3):
    if i == 0:  # reference volume (P1)
        ana = rb.SegmentAnalyser(rs[0])
        tv0 = ana.getSummed("volume")
    analyse(rs[i], names[i], ages[i], tv0)

figure8d(rs, N)
plt.grid(True)
plt.xlabel("Root Length Density $[cm/cm^3]$")
plt.show()
Example #11
0
depth = 100.
layers = 100
soilcolumn = rb.SDF_PlantContainer(r, r, depth,
                                   False)  # in the center of the root
soilcolumn2 = rb.SDF_RotateTranslate(soilcolumn, 0, 0,
                                     rb.Vector3d(10, 0, 0))  # shift 10 cm
geom = soilcolumn2

z_ = np.linspace(0, -1 * depth, layers)
fig, axes = plt.subplots(nrows=1, ncols=4, figsize=(16, 8))
for a in axes:
    a.set_xlabel('RLD (cm/cm)')
    a.set_ylabel('Depth (cm)')

# make a root length distribution
ana = rb.SegmentAnalyser(rootsystem)
rl_ = ana.distribution(rb.ScalarType.length, 0., depth, layers, True)
axes[0].set_title('All roots (120 days)')
axes[0].plot(rl_, z_)

# make a root length distribution along the soil core
ana = rb.SegmentAnalyser(rootsystem)
ana.crop(geom)
ana.pack()
rl_ = ana.distribution(rb.ScalarType.length, 0., depth, layers, True)
axes[1].set_title('Soil core (120 days)')
axes[1].plot(rl_, z_)

# how it looked after 30 days?
ana = rb.SegmentAnalyser(rootsystem)
ana.filter(rb.ScalarType.time, 0, 30)