def read_rsml(file_name:str, verbose=True): """ reads an RSML file and converts to MappedSegments with units [cm] @file_name the file name of the rsml, including file extension (e.g. "test.rsml" ) @return a CPlantBox MappedSegments object """ polylines, props, funcs = rsml.read_rsml(file_name) bn = 0 # count base roots for i, _ in enumerate(polylines): if props["parent-poly"][i] < 0: bn += 1 if bn > 1: polylines, props, funcs = rsml.artificial_shoot(polylines, props, funcs) if verbose: print("XylemFluxPython.read_rsml: added an artificial shoot") nodes, segs = rsml.get_segments(polylines, props) radii, seg_ct, types = rsml.get_parameter(polylines, funcs, props) if verbose: print("XylemFluxPython.read_rsml: read rsml with", len(nodes), "nodes and", len(segs), "segments") nodes = np.array(nodes) # for slicing in the plots nodes2 = [] # Conversions... for n in nodes: nodes2.append(pb.Vector3d(n[0] , n[1] , n[2])) segs2 = [] nodeCTs = np.zeros((len(nodes), 1)) # we need node creation times for i, s in enumerate(segs): nodeCTs[s[1]] = seg_ct[i] segs2.append(pb.Vector2i(int(s[0]), int(s[1]))) radii = np.array(radii) types = np.array(types, dtype=np.int64) - 1 # index must start with 0 if verbose: print(" nodeCTs [{:g}, {:g}] days".format(np.min(nodeCTs), np.max(nodeCTs))) print(" raddii [{:g}, {:g}] cm".format(np.min(radii), np.max(radii))) print(" subTypes [{:g}, {:g}] ".format(np.min(types), np.max(types))) return pb.MappedSegments(nodes2, nodeCTs, segs2, radii, types) # root system grid
def parse_rsml(rsml_name: list, time: list): """ creates a root dictionary from a rsml file @param rsml_name file name @param time measurement time """ roots = {} poly, prop, fun = rsml.read_rsml(rsml_name) assert len(poly) == len( prop['parent-poly']), "parse_rsml: wrong number of parent-poly tags" if not 'parent-node' in prop: # reconstruct... print("parse_rsml: no parent-node tag found, reconstructing...") prop['parent-node'] = [] for i in range(0, len(poly)): if prop['parent-poly'][i] >= 0: pni = connect(np.array(poly[i][0]), poly[prop['parent-poly'][i]]) else: pni = -1 # print("parent", prop['parent-poly'][i], "pni", pni) prop['parent-node'].append(pni) nopn = len(prop['parent-node']) assert len(poly) == nopn, "parse_rsml: wrong number of parent-node tags" for i in range(0, len(poly)): r = Root() r.add_measurement(time, i, poly, prop, fun, roots) initialize_roots(roots) return roots
def read_rsml(file_name: str): """ Reads an RSML file and converts to MappedSegments with units [cm] """ polylines, props, funcs = rsml.read_rsml(file_name) assert len(polylines) == len( props['parent-poly'] ), "XylemFluxPython.read_rsml: wrong number of parent-poly tags" if not 'parent-node' in props: # reconstruct... print("parse_rsml: no parent-node tag found, reconstructing...") props['parent-node'] = [] for i in range(0, len(polylines)): if props['parent-poly'][i] >= 0: pni = XylemFluxPython.connect( np.array(polylines[i][0]), polylines[props['parent-poly'][i]]) else: pni = -1 # print("parent", props['parent-poly'][i], "pni", pni) props['parent-node'].append(pni) assert len(polylines) == len( props['parent-node'] ), "XylemFluxPython.read_rsml: wrong number of parent-node tags" nodes, segs = rsml.get_segments(polylines, props) print("Read rsml:", len(nodes), "segs", len(segs), "segs") nodes2 = [pb.Vector3d(n[0], n[1], n[2]) for n in nodes] # convert to plantbox types segs2 = [pb.Vector2i(int(s[0]), int(s[1])) for s in segs] radii_, nodeCTs_, types_ = [], [], [] for i, p in enumerate(polylines): for j in range(0, len(p)): if 'diameter' in funcs: radii_.append(funcs['diameter'][i][j] / 2) else: print("XylemFluxPython.read_rsml: no diameter tag found") radii_.append(0.) if 'emergence_time' in funcs: nodeCTs_.append(funcs['emergence_time'][i][j]) else: print( "XylemFluxPython.read_rsml: no emergence_time tag found" ) nodeCTs_.append(0.) if 'type' in funcs: types_.append(funcs["type"][i][j]) elif 'type' in props: types_.append(props["type"][i]) else: print("XylemFluxPython.read_rsml: no type tag found") types_.append(0) nodeCTs = np.array(nodeCTs_) # creation times per node radii = np.zeros((len(segs), 1)) # radii per segment types = np.ones((len(segs), 1), dtype=np.int64) # types per semgent for i, s in enumerate(segs): radii[i] = radii_[s[1]] types[i] = types_[s[1]] - 1 # index must start with 0 return pb.MappedSegments(nodes2, nodeCTs, segs2, radii, types) # root system grid
def open_rsml(self, fname, shift_z=False): """ opens an rsml file into self.data, using rsml_reader (in CPlantBox/src/python_modules) converts units to cm and day if necessary converts 2d -> 3d, """ polylines, properties, functions, metadata = rsml_reader.read_rsml(fname) print("DataModel.open_rsml(): scale to cm", metadata.scale_to_cm) self.set_rsml(polylines, properties, functions, metadata) self.scale_polylines_() # converts units self.check_polylines_2d_(shift_z) # 2d -> 3d radii, cts, types, tagnames = rsml_reader.get_parameter(polylines, functions, properties) # paramter per node self.set_selected(radii, cts, types, tagnames) self.scale_selected_() # converts units of special fields radii, cts, types
def read_rsml(file_name: str, verbose=True): """ reads an RSML file and converts to MappedSegments with units [cm] @file_name the file name of the rsml, including file extension (e.g. "test.rsml" ) @return a CPlantBox MappedSegments object """ polylines, props, funcs, _ = rsml.read_rsml(file_name) bn = 0 # count base roots for i, _ in enumerate(polylines): if props["parent-poly"][i] < 0: bn += 1 if bn > 1: rsml.artificial_shoot(polylines, props, funcs) if verbose: print("XylemFluxPython.read_rsml: added an artificial shoot") nodes, segs = rsml.get_segments(polylines, props) if verbose: print("XylemFluxPython.read_rsml: read rsml with", len(nodes), "nodes and", len(segs), "segments") nodes2 = [pb.Vector3d(n[0], n[1], n[2]) for n in nodes] # Conversions to PlantBox types segs2 = [pb.Vector2i(int(s[0]), int(s[1])) for s in segs] radii, cts, types, tag_names = rsml.get_parameter( polylines, funcs, props) segRadii = np.zeros( (segs.shape[0], 1)) # convert to paramter per segment segTypes = np.zeros((segs.shape[0], 1)) for i, s in enumerate(segs): segRadii[i] = radii[s[1]] # seg to node index segTypes[i] = types[s[1]] if verbose: print(" cts [{:g}, {:g}] days".format( np.min(cts), np.max(cts))) print(" raddii [{:g}, {:g}] cm".format( np.min(radii), np.max(radii))) print(" subTypes [{:g}, {:g}] ".format( np.min(types), np.max(types))) print() return pb.MappedSegments(nodes2, cts, segs2, segRadii, segTypes) # root system grid
def read_rsml(file_name: str): """ Reads an RSML file and converts to MappedSegments with units [cm] """ polylines, props, funcs = rsml.read_rsml(file_name) nodes, segs = rsml.get_segments(polylines, props) radii, seg_ct, types = rsml.get_parameter(polylines, funcs, props) print("Read rsml:", len(nodes), "nodes", len(radii), "radii") nodes = np.array(nodes) # for slicing in the plots nodes2 = [] # Conversions... for n in nodes: nodes2.append(pb.Vector3d(n[0], n[1], n[2])) segs2 = [] nodeCTs = np.zeros((len(nodes), 1)) # we need node creation times for i, s in enumerate(segs): nodeCTs[s[1]] = seg_ct[i] segs2.append(pb.Vector2i(int(s[0]), int(s[1]))) radii = np.array(radii) types = np.array(types, dtype=np.int64) - 1 # index must start with 0 return pb.MappedSegments(nodes2, nodeCTs, segs2, radii, types) # root system grid
fixed_k = 150. # for the fits based on a literature value times = [7, 11, 15] # measurement times (not in the rsml) names = [ "Faba_12/DAP15.rsml", "Faba_14/DAP15.rsml", "Faba_16/DAP15.rsml", "Faba_20/DAP15.rsml", "Faba_24/DAP15.rsml" ] """ open all files, and split into measurent times""" polylines = [[[] for t in times] for i in range(0, len(names))] properties = [[[] for t in times] for i in range(0, len(names))] functions = [[[] for t in times] for i in range(0, len(names))] for i in range(0, len(names)): print(names[i]) j = len(times) - 1 p, properties[i][j], functions[i][j] = rsml.read_rsml( "RSML/" + names[i]) # read file to final time step print(properties[i][j].keys()) print(functions[i][j].keys()) p = [[ np.array([p[i][j][k] / 10 for k in range(0, 3)]) for j in range(0, len(p[i])) ] for i in range(0, len(p))] # mm -> cm polylines[i][j] = p for k in range(0, j): # truncate the others polylines[i][k], properties[i][k], functions[i][ k] = es.measurement_time(polylines[i][j], properties[i][j], functions[i][j], times[k]) # polylines[i][j] contains i-th plant, j-th measurement time """ find all base roots """ base_polylines = [[[] for t in times] for i in range(0, len(names))] base_properties = [[[] for t in times] for i in range(0, len(names))]
import sys sys.path.append("../..") import plantbox as pb import rsml_reader as rsml import estimate_params as es import math import numpy as np # times = [11, 15, 19] # not in the rsml # polylines, properties, functions = rsml.read_rsml("RSML/Maize2/DAP19.rsml") times = [7, 11, 15] # not in the rsml polylines, properties, functions = rsml.read_rsml("RSML/Faba_12/DAP15.rsml") polylines = [[ np.array([polylines[i][j][k] / 10 for k in range(0, 3)]) for j in range(0, len(polylines[i])) ] for i in range(0, len(polylines))] # mm -> cm print("Summary\n*******") print("Number of roots", len(polylines)) print("\nproperties") for key in properties.keys(): print(key) print("\nfunctions") for key in functions.keys(): print(key) print() fet = functions["emergence_time"]
import sys sys.path.append("../..") import plantbox as pb import rsml_reader as rsml import estimate_params_fibrous as es import math import numpy as np import matplotlib.pyplot as plt fixed_k = 150. # for the fits based on a literature value name = "Maize_Kutschera.rsml" polylines, properties, functions = rsml.read_rsml(name) # read rsml file """ recalculate length (should not alter anything) and add order as property""" es.create_length(polylines, properties) es.create_order(polylines, properties) # for i,p in enumerate(polylines): # print(properties["parent-node"][i]) # plot root system # pp=properties["parent-node"] # rsml.plot_rsml(polylines,pp) # print(properties["length"][0]) """ find all base roots """ base_polylines, base_properties = es.base_roots(polylines, properties) pp = base_properties['parent-poly']
import sys sys.path.append("../../.."); sys.path.append("../../../src/python_modules") import plantbox as pb import numpy as np import matplotlib.pyplot as plt import rsml_reader as rsml import math from xylem_flux import XylemFluxPython # Python hybrid solver import vtk_plot as vp """ root problem """ r = XylemFluxPython("RootSystem.rsml") r.test() polylines, props, funcs = rsml.read_rsml("RootSystem.rsml") print(len(polylines), "roots") # print(props["parent-poly"]) # print(props["parent-node"]) print("Tap root number of nodes", len(polylines[0])) for i in range(1, len(polylines)): pp = int(props["parent-poly"][i]) pn = int(props["parent-node"][i]) try: n0 = polylines[pp][pn] n1 = polylines[i][0] print("root", i, np.linalg.norm(np.array(n1) - np.array(n0))) except: print("root", i, "index out of range", "parent-node", pn, "length", len(polylines[pp])) ana = pb.SegmentAnalyser(r.rs)