Beispiel #1
0
 def convert_to_xylem_flux_(self):
     """  converts the polylines to a SegmentAnalyser and a MappedSegments object, and stores max_ct   
     
     uses:
     properties["parent-poly"], properties["parent-nodes"]
     radii, cts, types                    
     """
     nodes, segs = rsml_reader.get_segments(self.polylines, self.properties)  # fetch nodes and segments
     segRadii = np.zeros((segs.shape[0], 1))  # convert to paramter per segment
     segCTs = np.zeros((segs.shape[0], 1))
     subTypes = np.zeros((segs.shape[0], 1))
     for i, s in enumerate(segs):
         segRadii[i] = self.radii[s[1]]  # seg to node index            
         segCTs[i] = self.cts[s[1]]
         subTypes[i] = self.types[s[1]]
     if np.isnan(subTypes[0]):
         subTypes = np.ones((len(segs),), dtype=np.int64)
     segs_ = [pb.Vector2i(s[0], s[1]) for s in segs]  # convert to CPlantBox types
     nodes_ = [pb.Vector3d(n[0], n[1], n[2]) for n in nodes]
     self.analyser = pb.SegmentAnalyser(nodes_, segs_, segCTs, segRadii)
     self.analyser.addData("subType", subTypes)
     ms = pb.MappedSegments(self.analyser.nodes, np.array(self.cts), segs_, np.array(segRadii), np.array(subTypes))
     self.xylem_flux = xylem_flux.XylemFluxPython(ms)
     self.base_nodes = self.get_base_node_indices_()
     self.xylem_flux.neumann_ind = self.base_nodes  # needed for suf
     self.xylem_flux.dirichlet_ind = self.base_nodes  # needed for krs
     self.base_segs = self.xylem_flux.find_base_segments()
Beispiel #2
0
def plot_depth_profile(analyser, ax, j: int):
    """ 
    analyser     pb.SegmentAnalyser class
    ax           matplotlib axis
    j            type of plot (0: "length", 1: "surface", 2: "volume")
    """
    type_str = ["length", "surface", "volume"]
    unit_str = ["(cm)", "(cm$^2$)", "(cm$^3$)"]
    ax.clear()
    n = int(np.ceil(-analyser.getMinBounds().z))
    z_ = np.linspace(-0.5, -n + 0.5, n)
    d = analyser.distribution(type_str[j], 0., float(-n), int(n), True)
    ax.plot(d, z_, "-*", label="total")
    max_type = int(np.max(analyser.data["subType"]))
    for i in range(0, max_type + 1):
        ana = pb.SegmentAnalyser(analyser)  # copy
        ana.filter("subType", i)
        segn = len(ana.segments)
        if segn > 0:
            d = ana.distribution(type_str[j], 0., float(-n), int(n), True)
            ax.plot(d, z_, "-*", label="type {:g}".format(i))
    ax.set_ylabel("Depth (cm)")
    ax.set_xlabel("Root system " + type_str[j] + " per 1 cm layer " +
                  unit_str[j])
    ax.legend()
Beispiel #3
0
 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")
Beispiel #4
0
def get_result(allRS: list, time: float):
    """ 
    Retrieves a the state of the root systems at a certain time 
    in a single SegmentAnalyser object
    
    @param allRS     list of root systems 
    @param time      of the simulation result (days)
    @return SegmentAnalyser object conaining the segments of 
    all root sytstems at the specific time 
    """
    a = pb.SegmentAnalyser()
    for rs in allRS:
        a_ = pb.SegmentAnalyser(rs)
        a_.filter("creationTime", 0., time)
        a_.pack()
        a.addSegments(a_)
    return a
Beispiel #5
0
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;
Beispiel #6
0
def plot_roots_and_soil(rs,
                        pname: str,
                        rp,
                        s,
                        periodic: bool,
                        min_b,
                        max_b,
                        cell_number,
                        filename: str,
                        sol_ind=0):
    """ Plots soil slices and roots, additionally saves both grids as files
    @param rs            some Organism (e.g. RootSystem, MappedRootSystem, ...) or MappedSegments
    @param pname         root and soil parameter that will be visualized ("pressure head", or "water content")
    @param s
    @param rp            root parameter segment data (will be added)
    @param periodic      if yes the root system will be mapped into the domain 
    @param min_b         minimum of domain boundaries
    @param max_b         maximum of domain boundaries    
    @param cell_number   domain resolution
    @param filename      file name (without extension)
    """
    ana = pb.SegmentAnalyser(rs)
    ana.addData(pname, rp)
    if periodic:
        w = np.array(max_b) - np.array(min_b)
        ana.mapPeriodic(w[0], w[1])
    pd = segs_to_polydata(ana, 1.,
                          ["radius", "subType", "creationTime", pname])

    pname_mesh = pname
    soil_grid = uniform_grid(np.array(min_b), np.array(max_b),
                             np.array(cell_number))
    soil_water_content = vtk_data(np.array(s.getWaterContent()))
    soil_water_content.SetName("water content")
    soil_grid.GetCellData().AddArray(soil_water_content)
    soil_pressure = vtk_data(np.array(s.getSolutionHead()))
    soil_pressure.SetName("pressure head")  # in macroscopic soil
    soil_grid.GetCellData().AddArray(soil_pressure)
    if sol_ind > 0:
        d = vtk_data(np.array(s.getSolution(sol_ind)))
        pname_mesh = "solute" + str(sol_ind)
        d.SetName(pname_mesh)  # in macroscopic soil
        soil_grid.GetCellData().AddArray(d)

    rootActor, rootCBar = plot_roots(pd, pname, "", False)
    meshActors, meshCBar = plot_mesh_cuts(soil_grid, pname_mesh, 7, "", False)
    lut = meshActors[-1].GetMapper().GetLookupTable()  # same same
    rootActor.GetMapper().SetLookupTable(lut)
    meshActors.extend([rootActor])
    render_window(meshActors, filename, meshCBar, pd.GetBounds()).Start()

    if filename:
        path = "results/"
        write_vtp(path + filename + ".vtp", pd)
        write_vtu(path + filename + ".vtu", soil_grid)
Beispiel #7
0
def plot_suf(data, ax3, j):
    """ 
    plots suf versus depth per root type 
    
    data                 DataModel (in viewer_data.poy)
    ax3                  matplotlib axis
    j                    scenario hard coded in viewer_conductivities.py
    """
    ax3.clear()
    if j == 0:
        viewer_conductivities.init_constant_scenario1(data.xylem_flux)
    elif j == 1:
        viewer_conductivities.init_constant_scenario2(data.xylem_flux)
    elif j == 2:
        viewer_conductivities.init_dynamic_scenario1(data.xylem_flux)
    elif j == 3:
        viewer_conductivities.init_dynamic_scenario2(data.xylem_flux)

    print(data.max_ct)
    print(data.base_segs)
    krs, _ = data.xylem_flux.get_krs(data.max_ct, data.base_segs)
    suf = data.xylem_flux.get_suf(data.max_ct)
    data.analyser.addData("SUF", suf)
    n = int(np.ceil(-data.analyser.getMinBounds().z))
    z_ = np.linspace(-0.5, -n + 0.5, n)
    d = data.analyser.distribution("SUF", 0., float(-n), int(n),
                                   False)  # False!!!
    print("SUF total", np.min(d), np.max(d), np.mean(d))
    ax3.plot(d, z_, "-*", label="total")
    max_type = int(np.max(data.analyser.data["subType"]))
    for i in range(0, max_type + 1):
        ana = pb.SegmentAnalyser(data.analyser)  # copy
        ana.filter("subType", i)
        segn = len(ana.segments)
        if segn > 0:
            d = ana.distribution("SUF", 0., float(-n), int(n), False)
            ax3.plot(d, z_, "-*", label="type {:g}".format(i))
            print("SUF", i, np.min(d), np.max(d), np.mean(d))
    ax3.set_title("Root system krs {:g}".format(krs))
    ax3.set_ylabel("Depth (cm)")
    ax3.set_xlabel(
        "Root system surface uptake fraction (SUF) per 1 cm layer (1)")
    ax3.legend()
Beispiel #8
0
def segs_to_polydata(rs,
                     zoom_factor=10.,
                     param_names=["radius", "type", "creationTime"]):
    """ Creates vtkPolydata from a RootSystem or Plant using segments 
    @param rs             A RootSystem, Plant, or SegmentAnalyser
    @param zoom_factor    The radial zoom factor, since root are sometimes too thin for vizualisation
    @param param_names    Parameter names of scalar fields, that are copied to the polydata    
    @return A vtkPolydata object of the root system
    """
    if isinstance(rs, pb.Organism):
        ana = pb.SegmentAnalyser(rs)  # for Organism like Plant or RootSystem
    else:
        ana = rs
    nodes = np_convert(ana.nodes)
    segs = np_convert(ana.segments)
    points = vtk_points(nodes)
    cells = vtk_cells(segs)
    pd = vtk.vtkPolyData()
    pd.SetPoints(points)
    pd.SetLines(cells)  # check SetPolys
    for n in param_names:
        param = np.array(ana.getParameter(n))
        if param.shape[0] == segs.shape[0]:
            if n == "radius":
                param *= zoom_factor
            data = vtk_data(param)
            data.SetName(n)
            pd.GetCellData().AddArray(data)
        else:
            print(
                "segs_to_polydata: Warning parameter " + n +
                " is sikpped because of wrong size", param.shape[0],
                "instead of", segs.shape[0])

    c2p = vtk.vtkCellDataToPointData()
    c2p.SetPassCellData(True)
    c2p.SetInputData(pd)
    c2p.Update()
    return c2p.GetPolyDataOutput()
Beispiel #9
0
def timer_callback_(obj, ev):
    """ animation call back function (called every 0.1 second) """
    global rootActor
    global c

    c += 1
    print("hello", c)
    rs.simulate(1)
    ana = pb.SegmentAnalyser(rs)
    pd = vp.segs_to_polydata(ana, 1., ["radius", "subType", "creationTime"])
    newRootActor, rootCBar = vp.plot_roots(pd, "creationTime", False)
    renWin = iren.GetRenderWindow()
    ren = renWin.GetRenderers().GetFirstRenderer()
    ren.RemoveActor(rootActor)
    newRootActor.RotateX(-90)
    ren.AddActor(newRootActor)
    ren.ResetCamera()
    rootActor = newRootActor
    iren.Render()

    if c >= max_age:
        c = 0
        rs.initialize()
Beispiel #10
0
""" nodes and segments from measurements """
import sys
sys.path.append("../../..")
import plantbox as pb

# Data from any source, as Python types
nodes = [
    [0, 1, 0],
    [0, 1, -1],
    [0, 1, -2],
    [0, 1, -3],
]
segs = [[0, 1], [1, 2], [2, 3]]
cts = [0., 0., 0.]
radii = [0.1, 0.1, 0.1]

# convert from Python to C++ binding types
nodes = [pb.Vector3d(n[0], n[1], n[2]) for n in nodes]
segs = [pb.Vector2i(s[0], s[1]) for s in segs]

# create the SegmentAnalyser without underlying RootSystem
ana = pb.SegmentAnalyser(nodes, segs, cts, radii)

print("length", ana.getSummed("length"))
ana.write("results/example_3d.vtp", ["creationTime", "radius"])
Beispiel #11
0
# Soil core analysis
depth, layers = 100., 20
interrow = 1  # inter-row spacing
row = 1  # row spacing
layerVolume = depth / layers * interrow * row
simtime = 200
dt = 0.5
N = round(simtime / dt)
z_ = np.linspace(0, -1 * depth, layers)

rs.initialize()
time = np.linspace(0, simtime - 1, N)
rld = np.zeros(N)
for i in range(0, N):
    rs.simulate(dt, True)
    ana = pb.SegmentAnalyser(rs)
    rl = ana.distribution("length", 0., -depth, layers, True)
    rl = np.array(rl)
    rld[i] = rl[2] / layerVolume
rs.write("RAC_unimpeded.vtp")
fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(16, 8))
axes.plot(time, rld)
axes.set_title('RAC')

#################################################################################

rs = pb.RootSystem()
rs.readParameters(path + name + ".xml")
rs.setSeed(1)
# Manually set scale elongation function
scale_elongation = pb.EquidistantGrid1D(
Beispiel #12
0
def plot_rootsystem_development(analyser, ax2, j):
    """ 
    analyser     pb.SegmentAnalyser class
    ax2           matplotlib axis
    j            type of plot (0: "length", 1: "surface", 2: "volume")
    """
    type_str = ["length", "surface", "volume"]
    unit_str = ["(cm)", "(cm$^2$)", "(cm$^3$)"]
    ax2.clear()
    radii = analyser.data["radius"]  # copy once
    if j == 0:
        weights = [
            analyser.getSegmentLength(i)
            for i in range(0, len(analyser.segments))
        ]
    elif j == 1:
        weights = [
            2 * np.pi * radii[i] * analyser.getSegmentLength(i)
            for i in range(0, len(analyser.segments))
        ]
    elif j == 2:
        weights = [
            np.pi * radii[i] * radii[i] * analyser.getSegmentLength(i)
            for i in range(0, len(analyser.segments))
        ]
    cts = np.array(analyser.data["creationTime"])
    try:
        l_, t_ = np.histogram(cts, 100, weights=weights)
        ax2.plot(0.5 * (t_[1:] + t_[:-1]), np.cumsum(l_), "-", label="total")
        max_type = int(np.max(analyser.data["subType"]))
        for i in range(0, max_type + 1):
            ana = pb.SegmentAnalyser(analyser)  # copy
            ana.filter("subType", i)
            n = len(ana.segments)
            if n > 0:
                radii = ana.data["radius"]  # copy once
                if j == 0:
                    weights = [
                        ana.getSegmentLength(i)
                        for i in range(0, len(ana.segments))
                    ]
                elif j == 1:
                    weights = [
                        2 * np.pi * radii[i] * ana.getSegmentLength(i)
                        for i in range(0, len(ana.segments))
                    ]
                elif j == 2:
                    weights = [
                        np.pi * radii[i] * radii[i] * ana.getSegmentLength(i)
                        for i in range(0, len(ana.segments))
                    ]
                cts = np.array(ana.data["creationTime"])
                l_, t_ = np.histogram(cts, 100, weights=weights)
                ax2.plot(0.5 * (t_[1:] + t_[:-1]),
                         np.cumsum(l_),
                         "-",
                         label="type {:g}".format(i))
        ax2.legend()
    except:
        pass
    ax2.set_xlabel("Time (days)")
    ax2.set_ylabel("Root system " + type_str[j] + " " + unit_str[j])
Beispiel #13
0
distp = 6  # inter-plant distance within the rows [cm]

# 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")
        rs.getRootSystemParameter().seedPos = pb.Vector3d(
            distp * i, dist * j, -3.)  # cm
        rs.initialize(False)  # verbose = False
        allRS.append(rs)

# Simulate
rs.setSeed(2)
for rs in allRS:
    rs.simulate(simtime, False)  # verbose = False

# Export results as single vtp files (as polylines)
ana = pb.SegmentAnalyser()  # see example 3b
for i, rs in enumerate(allRS):
    vtpname = "results/" + name + "/" + str(i) + ".vtp"
    rs.write(vtpname)
    ana.addSegments(rs)  # collect all

# Write all into single file (segments)
ana.write("results/" + name + "/" + "soybean_all.vtp")

# Plot, using vtk
vp.plot_roots(ana, "radius", True, 'oblique')
 simDuration += dt
 if step *dt % (60) == 0: #choose how often get output       
     ####
     #
     # copy of phi
     #
     ####
     
     reorderedPhi = np.array([x for _,x in sorted(zip(phl.cellsID,phl.phi.value))])
     reorderedOutFlow = np.array([x for _,x in sorted(zip(phl.cellsID,cumulOut))])
     reorderedRm = np.array([x for _,x in sorted(zip(phl.cellsID,cumulRm))])
     reorderedGrSink = np.array([x for _,x in sorted(zip(phl.cellsID,cumulGr))])
     orgNum = np.array([phl.newCell2organID[xi] for xi in phl.newCell2organID])
     reorderedorgNum = np.array([x for _,x in sorted(zip(phl.cellsID,orgNum))])
     reorderedVolume = np.array([x for _,x in sorted(zip(phl.cellsID,phl.mesh.cellVolumes))])
     ana = pb.SegmentAnalyser(phl.rs)
     ana.addData("phi",  np.around(reorderedPhi, 5))
     ana.addData("outFlow",  np.around(reorderedOutFlow/reorderedVolume, 5))
     ana.addData("Rm",  np.around(reorderedRm/reorderedVolume, 5))
     ana.addData("GrSink",  np.around(reorderedGrSink/reorderedVolume, 5))
     ana.addData("rx", phl.Px)
     ana.addData("fluxes", fluxes) 
     ana.addData("orgNr", reorderedorgNum) 
     ana.write("results/%s_example9a.vtp" %(step), ["radius", "surface", "phi", "outFlow", "Rm", "GrSink", "rx","fluxes","orgNr"])
     
 if step  % 1 == 0: #choose how often get output    
     ####
     #
     # check balance
     #
     ####
Beispiel #15
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")

ana = pb.SegmentAnalyser(plant)
ana.write("results/example_plant_segs.vtp")

# Plot, using vtk
vp.plot_plant(plant, "organType")
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)
rl_ = []
axes[0].set_title('All roots in 20*20*100')
for t in times:
    ana.filter("creationTime", 0, t)
    rl_.append(ana.distribution("length", 0., -depth, layers, True))
    axes[0].plot(np.array(rl_[-1]) / layerVolume, z_)
axes[0].legend(["10 days", "30 days", "60 days", "120 days"])

# Make a root length distribution along the soil core
layerVolume = depth / layers * r * r * np.pi
ana = pb.SegmentAnalyser(rs)
ana.crop(geom)
ana.pack()
rl_ = []
sigma = [0.4, 1., 1., 1., 1.] * 2
for p in rs.getRootRandomParameter():
    if p.subType > 2:
        p.dx = 0.25  # adjust resolution
        p.f_sa = soilprop  # Scale insertion angle
        p.lmax = 2 * p.lmax  # make second order laterals longer

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

# analysis
al = pb.SegmentAnalyser(rs)
al.crop(left)
lm_theta = np.mean(al.getParameter("theta"))
ar = pb.SegmentAnalyser(rs)
ar.crop(right)
rm_theta = np.mean(ar.getParameter("theta"))
print('\nLeft  compartment mean insertion angle is {:g} degrees'.format(
    lm_theta))
print('\nRight compartment mean insertion angle is {:g} degrees\n'.format(
    rm_theta))

# write results
rs.write("results/example_5c.py")  # compartment geometry
rs.write("results/example_5c.vtp")  # root system

# plot, using vtk
Beispiel #18
0
min_ = np.array([-5, -5, -15])
max_ = np.array([5, 5, 0.])
res_ = np.array([1, 3, 5])
if not periodic:
    sdf = pb.SDF_PlantBox(0.99 * (max_[0] - min_[0]),
                          0.99 * (max_[1] - min_[1]),
                          0.99 * (max_[2] - min_[2]))
    rs.setGeometry(sdf)
rs.setRectangularGrid(pb.Vector3d(min_), pb.Vector3d(max_), pb.Vector3d(res_),
                      False)  # cut and map segments

rs.initialize()
rs.simulate(rs_age, False)
N = round(sim_time / dt)

ana = pb.SegmentAnalyser(rs.mappedSegments())
anim = vp.AnimateRoots(ana)
anim.min = min_
anim.max = max_
anim.res = res_
anim.file = "results/example7a"
anim.start()

for i in range(0, N):

    rs.simulate(dt, False)
    """ add segment indices """
    segs = rs.segments
    x = np.zeros(len(segs))
    for i, s in enumerate(segs):
        try:
Beispiel #19
0
    try:
        x[c] = rs.seg2cell[s.y - 1]
    except:
        x[c] = -1

y = np.zeros(x.shape[0])
for i in range(0, x.shape[0]):
    y[i] = i % 2 if x[i] >= 0 else i % 2 - 2  #

for i in range(0, x.shape[0]):
    x[i] = x[i] if x[i] >= 0 else -1

print("RS number of segments (mapped)", len(rs.segments), "(rs)",
      rs.getNumberOfSegments())  # shoot segments are mapped
ana = pb.SegmentAnalyser(
    rs.mappedSegments()
)  # rs is MappedSegments and RootSystem. So passing rs it is not unique which constructor is called.
print("Number of segments", len(ana.segments), "x", len(x), "and", len(y))
ana.addData("linear_index", x)  # node data are converted to segment data
ana.addData("zebra", y)
ana.mapPeriodic(max_[0] - min_[0], max_[1] - min_[1])  # data are also split

pd = vp.segs_to_polydata(
    ana, 1., ["radius", "subType", "creationTime", "linear_index", "zebra"])
rootActor, rootCBar = vp.plot_roots(pd, "linear_index", False)
""" Mesh """
width_ = max_ - min_
ind_ = res_ / width_
print("min    ", min_)
print("max    ", max_)
print("width  ", width_)
Beispiel #20
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
Beispiel #21
0
plt.show()

fig, ax = plt.subplots()
name = ["root", "stem", "leaf"]
color = ['tab:blue', 'tab:orange', 'tab:green']
for ndType in [2, 3, 4]:
    segIdx = r.get_segments_index(ndType)
    nodesy = segIdx + np.ones(segIdx.shape, dtype=np.int64)
    y = nodes[nodesy]  #coordinates
    x = fluxes[segIdx]
    ax.scatter(x,
               y[:, 2],
               c=color[ndType - 2],
               label=name[ndType - 2],
               alpha=0.3,
               edgecolors='none')

ax.legend()
ax.grid(True)
plt.xlabel("Fluxes (cm3/day)")
plt.ylabel("Depth (cm)")
plt.title("water fluxes")
plt.show()

#Additional vtk plot
ana = pb.SegmentAnalyser(r.rs)
ana.addData("rx", rx)
ana.addData("fluxes", fluxes)  # cut off for vizualisation
ana.write("results/example_6f.vtp", ["radius", "surface", "rx", "fluxes"])  #
#vp.plot_roots(ana, "rx", "Xylem matric potential (cm)")  # "fluxes"
Beispiel #22
0
import rsml_reader as rsml
import estimate_root_params as es
from xylem_flux import XylemFluxPython
import vtk_plot as vp
import plantbox as pb

time = range(1, 3)  # measurement times (not in the rsml)
name = ["RSML/m1/dicot/lupin/lupin_d{:g}.rsml".format(a) for a in range(1, 10)]

# time = range(1, 3)  # measurement times (not in the rsml)
# name = ["RSML/m1/monocot/maize/PL0{:g}_DAS0{:g}.rsml".format(1, a) for a in range(1, 8)]

# time = [75]  # measurement times (not in the rsml)
# name = ["RSML/Maize_Kutschera.rsml"]

rs = XylemFluxPython(
    name[0])  # parses rsml, XylemFluxPython.rs is of type MappedRootSegments
ana = pb.SegmentAnalyser(
    rs.rs)  # convert MappedRootSegments to a SegmentAnalyser

# radii = ana.data["radius"]  # DOES NOT WORK (why?)
# for i in range(0, len(radii)):
#     radii[i] /= 116.93
# ana.data["radius"] = radii

pd = vp.segs_to_polydata(
    ana, 1. /
    116.93)  # makes a vtkPolydata (to save as .vtp, or visualize with vtk)
vp.plot_roots(pd, "radius")  # plots vtkPolydata into an interactive window