Example #1
0
 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
Example #2
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()
Example #3
0
 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
Example #4
0
    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
Example #5
0
 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
Example #6
0
 def check_polylines_2d_(self, shift_z=False):
     """  converts 2d image coordinates to 3d coordinates
         shift_z determines if the roots system seed is shifted to -3 cm
     """
     nodes, segs = rsml_reader.get_segments(self.polylines, self.properties)  # fetch nodes and segments
     maxz = np.max(nodes[:, 2])
     minz = np.min(nodes[:, 2])
     if maxz >= 0 and minz >= 0:  # image coordinates in px often start in lower left corner
         print("DataModel.check_polylines_2d_(): assuming image coordinates, y-centered and z-flipped ")
         miny = np.min(nodes[:, 1])
         yy = np.max(nodes[:, 1]) - miny
         for pl in self.polylines:  # both (pl and node) are references
             for node in pl:
                 node[2] = -node[2]
                 node[1] = node[1] - miny - yy / 2
     if shift_z:
         print("DataModel.check_polylines_2d_(): root system seed is shifted to (x,y,-3) ")
         z = self.polylines[0][0][2]
         print("z", z)
         for pl in self.polylines:  # both (pl and node) are references
             for node in pl:
                 node[2] = node[2] - z + (-3)