Beispiel #1
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 #2
0
soil_index = lambda x, y, z: int(-10 * z
                                 )  # maps to p_s (hydrostatic equilibirum)
rs.setSoilGrid(soil_index)

path = "../../../modelparameter/rootsystem/"
name = "Anagallis_femina_Leitner_2010"  # Zea_mays_1_Leitner_2010
rs.setSeed(1)
rs.readParameters(path + name + ".xml")
rs.initialize()
rs.simulate(simtime, False)
p_s = np.linspace(-200, -400, 2001)  # 2 meter down, resolution in mm
""" set up xylem parameters """
r = XylemFluxPython(rs)
r.setKr([kr])  # or use setKrTables, see XylemFlux.h
r.setKx([kz])
""" numerical solution of transpiration -1 cm3/day"""
rx = r.solve_neumann(
    simtime, -1, p_s,
    True)  # True: matric potential given per cell (not per segment)
print("solved")

fluxes = r.segFluxes(simtime, rx, p_s, False,
                     True)  # cm3/day (double simTime,  rx,  sx,  approx, cells
print("Transpiration", r.collar_flux(simtime, rx, p_s), np.sum(fluxes),
      "cm3/day")
suf = np.array(fluxes) / -1.  # [1]
""" Additional vtk plot """
ana = pb.SegmentAnalyser(r.rs)
ana.addData("SUF", np.minimum(suf, 1.e-2))  # cut off for vizualisation
vp.plot_roots(ana, "SUF", "Soil uptake fraction (cm3 day)")  # "fluxes"
Beispiel #3
0
print("\n2. Simulate")
rs.simulate(simtime, True)

print("\n3. SegmentAnalyser and artificial shoot")
ana = pb.SegmentAnalyser(rs)
aseg = rs.getShootSegments(
)  # if there are no shoot borne roots, it is only one segment
for s in aseg:
    print("Shoot segment", s)
    ana.addSegment(s, 0., 0.1, True)
ana.write("results/Moraes2018_{:s}days.dgf".format(str(simtime)))
# r = XylemFluxPython(rs)  # just for test
# r.test()

nodes = ana.nodes
segs = ana.segments
print("Number of nodes", len(nodes))
print("Number of segments", len(segs))
minx = np.min([n.x for n in nodes])
maxx = np.max([n.x for n in nodes])
miny = np.min([n.y for n in nodes])
maxy = np.max([n.y for n in nodes])
minz = np.min([n.z for n in nodes])
maxz = np.max([n.z for n in nodes])
print("Bounding box", minx, maxx, miny, maxy, minz, maxz)

# Plot, using vtk
print("\n4. Plot")
vp.plot_roots(rs, "subType")
# vp.plot_roots(ana, "subType")  # DOES NOT WORK (TODO)
N = 3  # number of columns and rows
dist = 40  # distance between the root systems [cm]

# Initializes N*N root systems
allRS = []
for i in range(0, N):
    for j in range(0, N):
        rs = pb.RootSystem()
        rs.readParameters(path + name + ".xml")
        rs.getRootSystemParameter().seedPos = pb.Vector3d(
            dist * i, dist * j, -3.)  # cm
        rs.initialize(False)  # verbose = False
        allRS.append(rs)

# Simulate
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/example_1d_" + str(i) + ".vtp"
    rs.write(vtpname)
    ana.addSegments(rs)  # collect all

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

# Plot, using vtk
vp.plot_roots(ana, "radius")
Beispiel #5
0
        else:
            return self.gravi.tropismObjective(pos, old, a, b, dx, root)


# set up the root system
rs = pb.RootSystem()
path = "../../../modelparameter/rootsystem/"
name = "Zea_mays_1_Leitner_2010"
rs.readParameters(path + name + ".xml")
rs.initialize()

# Set useer defined after initialize
mytropism1 = My_Info_Tropism(rs)
mytropism1.setTropismParameter(2., 0.2)
mytropism2 = My_Age_Tropism(
    rs, 1.5, 0.5, 5)  # after 5 days switch from plagio- to gravitropism
rs.setTropism(mytropism2, 4)  # 4 for base roots, -1 for all root types

# Simulate
simtime = 100  # e.g. 30 or 60 days
dt = 1
N = round(simtime / dt)
for _ in range(0, N):
    rs.simulate(dt)

# Export results (as vtp)
rs.write("results/example_4b.vtp")

# Plot, using vtk
vp.plot_roots(rs, "age", True, 'oblique')
    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
vp.plot_roots(rs, "theta")  # press 'y'
Beispiel #7
0
 def view_vtk_plot(self, name):
     """ vtk plot coloring name """
     if self.data.exists():
         vp.plot_roots(self.data.analyser, name)
     else:
         tkinter.messagebox.showwarning("Warning", "Open RSML file first")
Beispiel #8
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

ana = pb.SegmentAnalyser(r.rs)
ana.addData("linear_index", x)  # node data are converted to segment data
ana.addData("zebra", y)
pd = vp.segs_to_polydata(ana, 1., ["radius", "subType", "creationTime", "linear_index", "zebra"])
rootActor, rootCBar = vp.plot_roots(pd, "zebra", False)

""" Mesh """
width_ = max_ - min_
ind_ = res_ / width_
print("min    ", min_)
print("max    ", max_)
print("width  ", width_)
print("cuboids", 1 / ind_)
grid = vp.uniform_grid(min_, max_, res_)
meshActor, meshCBar = vp.plot_mesh(grid, "", "", False)

vp.render_window([meshActor, rootActor], "Test mapping", rootCBar).Start()

"""small example"""
import sys
sys.path.append("../../..")
import plantbox as pb
import vtk_plot as vp

rs = pb.RootSystem()

# Open plant and root parameter from a file
path = "../../../modelparameter/rootsystem/"
name = "Anagallis_femina_Leitner_2010"
rs.readParameters(path + name + ".xml")

# Initialize
rs.initializeDB(1, 4)  # numbers indicate basal and shoot borne root types

# Simulate
rs.simulate(30, True)

# Export final result (as vtp)
rs.write("results/example_1a.vtp")

# Plot, using vtk
vp.plot_roots(rs, "creationTime")
Beispiel #10
0
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_)
print("cuboids", 1 / ind_)
grid = vp.uniform_grid(min_, max_, res_)
meshActor, meshCBar = vp.plot_mesh(grid, "", "", False)

# vp.render_window([meshActor, rootActor], "Test mapping", rootCBar).Start()
grid = vp.uniform_grid(min_, max_, res_)
actors = vp.plot_mesh_cuts(pd, "linear_index")
print(actors)
print(len(actors))
Beispiel #11
0
                      True)  # cut and map segments
""" add segment indices """
segs = rs.segments
x = np.zeros(len(segs))
for i, s in enumerate(segs):
    try:
        x[i] = rs.seg2cell[i]
    except:  # in case the segment is not within the domain
        x[i] = -1
""" infos on a specific cell"""
ci = rs.soil_index(0, 0, -7)
print("Cell at [0,0,-7] has index", ci)
try:
    print(len(rs.cell2seg[ci]), "segments in this cell:")
    print(rs.cell2seg[ci])
except:
    print("There are no segments in this cell")
""" vizualise roots """
# ana = pb.SegmentAnalyser(rs)  # <---- wrong!
ana = pb.SegmentAnalyser(rs.mappedSegments())
ana.addData("linear_index", x)
pd = vp.segs_to_polydata(ana, 1.,
                         ["radius", "subType", "creationTime", "linear_index"])
rootActor, rootCBar = vp.plot_roots(pd, "linear_index", "segment index plot",
                                    False)
"""  vizualise soil  """
grid = vp.uniform_grid(min_, max_, res_)  # for visualization
meshActor, meshCBar = vp.plot_mesh(grid, "", "", False)
vp.render_window([meshActor, rootActor], "Test mapping", rootCBar,
                 grid.GetBounds()).Start()
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")

# Modify axial resolution
for p in rs.getRootRandomParameter():
    p.dx = 0.1  # adjust resolution

# Simulate
rs.initialize()
rs.simulate(60)  # days

# Export results as segments
ana = pb.SegmentAnalyser(rs)
ana.write("results/example_3e.vtp")

ana.mapPeriodic(15, 10)
ana.write("results/example_3e_periodic.vtp")

# Export geometry as Paraview Python script
box = pb.SDF_PlantBox(15, 10, 35)
rs.setGeometry(box)
rs.write("results/example_3e_periodic.py")

# Plot final (periodic) image, using vtk
vp.plot_roots(ana, "creationTime", True, 'oblique')
Beispiel #13
0
p_s = np.linspace(-14000, -10000, 3001)
p_s[0:10] = -300
# 3 meter down, resolution in mm, dry with moist top
soil_index = lambda x, y, z: int(-10 * z)
r.rs.setSoilGrid(soil_index)
""" Numerical solution"""
rx = r.solve_neumann(
    simtime, -0., p_s,
    True)  # True: matric potential given per cell (not per segment)

print("Transpiration", r.collar_flux(0., rx, [p_s]), "cm3/day")
eswp = 0.
n = len(r.rs.segments)
seg2cell = r.rs.seg2cell
for i in range(0, n):
    eswp += suf[i] * p_s[seg2cell[i]]

print()
print("Equivalent soil water potential", eswp)

z = r.rs.nodes[1].z
print("Root collar potential          ", rx[1], "node z", z, "psi",
      p_s[soil_index(0, 0, z)])
print()
""" Additional vtk plot """
ana = pb.SegmentAnalyser(r.rs)
ana.addData("rx", rx)  # node data are converted to segment data
pd = vp.segs_to_polydata(
    ana, 1., ["radius", "subType", "creationTime", "length", "rx", "suf"])
vp.plot_roots(pd, "rx")
Beispiel #14
0
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")

# Modify axial resolution
for p in rs.getRootRandomParameter():
    p.dx = 0.1  # adjust resolution

# Simulate
rs.initialize()
rs.simulate(60)  # days

# Export results as segments
ana = pb.SegmentAnalyser(rs)
ana.write("results/example_3e.vtp")

ana.mapPeriodic(15, 10)
ana.write("results/example_3e_periodic.vtp")

# Export geometry as Paraview Python script
box = pb.SDF_PlantBox(15, 10, 35)
rs.setGeometry(box)
rs.write("results/example_3e_periodic.py")

# Plot final (periodic) image, using vtk
vp.plot_roots(ana, "creationTime")
simtime = 14  # [day] for task b
""" root system """
rs = pb.MappedRootSystem()
path = "../../../modelparameter/rootsystem/"
name = "Anagallis_femina_Leitner_2010"  # Zea_mays_1_Leitner_2010
rs.readParameters(path + name + ".xml")
rs.initialize()
rs.simulate(simtime, False)
""" root problem """
r = XylemFluxPython(rs)
r.setKr([kr])
r.setKx([kz])
nodes = r.get_nodes()
soil_index = lambda x, y, z: 0
r.rs.setSoilGrid(soil_index)
""" Numerical solution """
rx = r.solve_dirichlet(0., p0, p_s, [p_s], True)
fluxes = r.segFluxes(simtime, rx, -200 * np.ones(rx.shape), False)  # cm3/day
print("Transpiration", r.collar_flux(simtime, rx, [p_s]), "cm3/day")
""" plot results """
plt.plot(rx, nodes[:, 2], "r*")
plt.xlabel("Xylem pressure (cm)")
plt.ylabel("Depth (m)")
plt.title("Xylem matric potential (cm)")
plt.show()
""" Additional vtk plot """
ana = pb.SegmentAnalyser(r.rs)
ana.addData("rx", rx)
ana.addData("fluxes", np.maximum(fluxes, -1.e-3))  # cut off for vizualisation
vp.plot_roots(ana, "rx", "Xylem matric potential (cm)")  # "fluxes"
Beispiel #16
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
Beispiel #17
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')
Beispiel #18
0
"""

name = "soybean_Honly-00001"
# name = "dumux_c12_2cm"  # to not convert m->cm for this file
# name = "Glycine_max_154days" # consists of polylines, cannot written as rsml

pd = vp.read_vtp(name + ".vtp")
print(pd.GetBounds())  # xmin, xmax, ymin, ymax, zmin, zmax

# Rename radius for plot_roots
radius = pd.GetPointData().GetAbstractArray("radius [m]")
radius.SetName("radius")

# Convert from m to cm
np_points = vt.np_points(pd)
# np_points = np_points * 100  # m -> cm
points = vt.vtk_points(np_points)
pd.SetPoints(points)
print("Number of points opened: ", np_points.shape[0])

vp.plot_roots(pd, "p xylem [cm]")  # "p xylem [cm]", "subType"

# write RSML - this will only work for non-periodic vtp
# roots of periodic vtp will end at domain boundary (since no connection is defined in the vtp)
meta = rsml_writer.Metadata()
vt.write_rsml(
    name + ".rsml", pd, meta,
    2)  # 6 is the data index of root order; 2 for Glycine_max_154days

print("fin")
for p in rs.getRootRandomParameter():
    p.dx = 0.25  # adjust resolutionx
    p.tropismS = sigma[p.subType - 1]
    p.f_se = soilprop  # 1. Scale elongation

# simulation
rs.initialize()
simtime = 60.
dt = 1.
for i in range(0, round(simtime / dt)):
    # in a dynamic setting change soilprop here
    rs.simulate(dt, False)

# analysis
l = rs.getSummed("length")
al = pb.SegmentAnalyser(rs)
al.crop(left)
ll = al.getSummed("length")
ar = pb.SegmentAnalyser(rs)
ar.crop(right)
lr = ar.getSummed("length")
print('\nLeft  compartment total root length {:g} cm, {:g}%'.format(ll, 100 * ll / l))
print('\nRight compartment total root length {:g} cm, {:g}% \n'.format(lr, 100 * lr / l))

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

# plot, using vtk
vp.plot_roots(rs, "rootLength")  # press 'y'
Beispiel #20
0
        p.las = p.la * s
        p.lns = p.ln * s
        p.rs = p.r * s
        p.a_s = p.a * s


rs = pb.RootSystem()
# set_all_sd(rs, 0.)

# Open plant and root parameter from a file
path = ""
name = "m1_maize"
rs.readParameters(path + name + ".xml")
print(rs.getRootRandomParameter(1))

# Initialize
rs.initializeLB(1, 5)  # change basal to tap
# rs.initialize()

# Simulate
rs.simulate(8, True)
ana = pb.SegmentAnalyser(rs)
# ana.filter("subType", 1)
ana.map2D()

# Export final result (as vtp)
ana.write("m1_maize.vtp")

# Plot, using vtk
vp.plot_roots(ana, "subType")  # "creationTime", "subType"
Beispiel #21
0
def vector_3d(a):
    return pb.Vector3d(a[0], a[1], a[2])


""" root problem """
r = XylemFluxPython("RootSystem.rsml")  # returns a MappedSegments object
segs = r.rs.segments

nodes = r.rs.nodes
for i in range(0, len(nodes)):
    nodes[i] = vector_3d(np.array(nodes[i]) / 100.)
r.rs.nodes = nodes
""" Mixed plot """
ana = pb.SegmentAnalyser(r.rs)
pd = vp.segs_to_polydata(ana, 1.e-2, ["radius", "subType", "creationTime"])
print("Root system bounds", pd.GetBounds())
rootActor, rootCBar = vp.plot_roots(pd, "creationTime", False)

ug = vp.read_vtu("benchmark3d_2-00001.vtu")
print("Mesh bounds", ug.GetBounds())
meshActor, meshCBar = vp.plot_mesh(
    ug, "water content", "",
    False)  # "pressure head"  # e.g. "S_liq" "water content"

vp.render_window([rootActor, meshActor], "mixed fun", meshCBar).Start()

# # Plot, using vtk
# rootActor, cBar = vp.plot_roots(rs, "creationTime", False)
# rootActor.RotateX(90) # to look at it from top
# vp.render_window(rootActor,"top view", cBar).Start()
ana = pb.SegmentAnalyser(rs)
anim = vp.AnimateRoots(ana)
anim.root_name = "creationTime"
anim.file = "example5b"
anim.min = np.array([-10, -10, -50])
anim.max = np.array([10, 10, 0.])
anim.res = np.array([1, 1, 1])
anim.start()

simtime = 60.
dt = 0.1  # small, for animation
for i in range(0, round(simtime / dt)):  # Simulation

    # update soil model (e.g. soil_strength)

    # update scales (e.g. from water content, soil_strength)
    scales = np.exp(-0.4 * soil_strength)  # (TODO)

    # copy scales into scaling funciton
    scale_elongation.data = scales

    rs.simulate(dt, False)

    ana = pb.SegmentAnalyser(rs)
    anim.rootsystem = ana
    anim.update()

rs.write("../results/example_5b.vtp")
vp.plot_roots(rs, "age")
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)

# Export results (as vtp)
rs.write("results/example_4a.vtp")

# Export geometry of static soil
rs.setGeometry(layer)  # just for vizualisation
rs.write("results/example_4a.py")

# Plot, using vtk
vp.plot_roots(rs, "type")
rhizoX = pb.SDF_RotateTranslate(rhizotube, 90, pb.SDF_Axis.yaxis,
                                pb.Vector3d(96 / 2, 0, 0))

rhizotubes_ = []
y_ = (-30, -18, -6, 6, 18, 30)
z_ = (-10, -20, -40, -60, -80, -120)
tube = []
for i in range(0, len(y_)):
    v = pb.Vector3d(0, y_[i], z_[i])
    tube.append(pb.SDF_RotateTranslate(rhizoX, v))
    rhizotubes_.append(tube[i])

rhizotubes = pb.SDF_Union(rhizotubes_)
rhizoTube = pb.SDF_Difference(box, rhizotubes)

# Set geometry: rotatedRhizotron, splitBox, or rhizoTube
rs.setGeometry(rotatedRhizotron)

# Simulate
rs.initialize()
rs.simulate(90)  # days

# Export results (as vtp)
rs.write("results/example_1c.vtp")

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

# Plot, using vtk
vp.plot_roots(rs, "type", True, 'oblique')