Exemple #1
0
def get_source_leaf_and_max_height(g,
                                   position='center',
                                   relative_height=2. / 3):
    tesselator = pgl.Tesselator()
    bbc = pgl.BBoxComputer(tesselator)
    leaves = get_leaves(g, label='LeafElement')
    centroids = g.property('centroid')
    geometries = g.property('geometry')
    targets = list(leaf for leaf in leaves if leaf in geometries.iterkeys())
    for vid in targets:
        if is_iterable(geometries[vid]):
            bbc.process(pgl.Scene(geometries[vid]))
        else:
            bbc.process(pgl.Scene([pgl.Shape(geometries[vid])]))
        center = bbc.result.getCenter()
        centroids[vid] = center
    zmax = max(centroids.items(), key=lambda x: x[1][2])[1][2]
    distances = {
        vid: pgl.norm(centroids[vid] - (0, 0, relative_height * zmax))
        for vid in centroids
    }
    if position == 'center':
        return min(distances.items(), key=lambda x: x[1])[0], zmax
    elif position == 'border':
        return max(distances.items(), key=lambda x: x[1])[0], zmax
Exemple #2
0
 def get_leaf_height(self, leaf_geom):
     from openalea.plantgl import all as pgl
     tesselator = pgl.Tesselator()
     bbc = pgl.BBoxComputer(tesselator)
     if self.is_iterable(leaf_geom):
         bbc.process(pgl.Scene(leaf_geom))
     else:
         bbc.process(pgl.Scene([pgl.Shape(leaf_geom)]))
     return bbc.result.getCenter()[2]
Exemple #3
0
def domain3D(domain2D, scene):
    t = pgl.Tesselator()
    bbc = pgl.BBoxComputer(t)
    bbc.process(scene)
    bbox = bbc.result

    z_base = bbox.getZMin()
    z_top = bbox.getZMax()
    domain3D = (domain2D[0] + (z_base, ), domain2D[1] + (z_top, ))
    return domain3D
Exemple #4
0
def get_source_leaf(g, position_source=2./3):
    tesselator = pgl.Tesselator()
    bbc = pgl.BBoxComputer(tesselator)
    leaves = get_leaves(g, label='LeafElement')
    centroids = g.property('centroid')
    geometries = g.property('geometry')
    targets = list(leaf for leaf in leaves if leaf in geometries.iterkeys())
    for vid in targets:
        if isinstance(geometries[vid], collections.Iterable):
            bbc.process(pgl.Scene(geometries[vid]))
        else:
            bbc.process(pgl.Scene([pgl.Shape(geometries[vid])]))
        center = bbc.result.getCenter()
        centroids[vid] = center
    zmax = max(centroids.items(), key=lambda x:x[1][2])[1][2]
    distances = {vid:pgl.norm(centroids[vid]-(0,0,position_source*zmax)) for vid in centroids}
    return min(distances.items(), key=lambda x:x[1])[0]
Exemple #5
0
def bbox(pgl_scene, scene_unit='m'):
    """ Bounding box of a pgl scene"""
    tesselator = pgl.Tesselator()
    bbc = pgl.BBoxComputer(tesselator)
    bbc.process(pgl_scene)
    box = bbc.result
    xmin, ymin, zmin = box.getXMin(), box.getYMin(), box.getZMin()
    xmax, ymax, zmax = box.getXMax(), box.getYMax(), box.getZMax()
    if scene_unit != 'm':
        units = {'mm': 0.001, 'cm': 0.01, 'dm': 0.1, 'm': 1, 'dam': 10,
                 'hm': 100,
                 'km': 1000}
        convert = units.get(scene_unit, 1)
        xmin, ymin, zmin = numpy.array((xmin, ymin, zmin)) * convert
        xmax, ymax, zmax = numpy.array((xmax, ymax, zmax)) * convert

    return (xmin, ymin, zmin), (xmax, ymax, zmax)
Exemple #6
0
    def leaves_in_grid(self, g, label='LeafElement'):
        geometries = g.property('geometry')
        centroids = g.property('centroid')
        tesselator = pgl.Tesselator()
        bbc = pgl.BBoxComputer(tesselator)
        leaves = get_leaves(g, label=label)
        leaves = [l for l in leaves if l in geometries]

        # Get centroids
        def centroid(vid):
            if is_iterable(geometries[vid]):
                bbc.process(pgl.Scene(geometries[vid]))
            else:
                bbc.process(pgl.Scene([pgl.Shape(geometries[vid])]))
            center = bbc.result.getCenter()
            centroids[vid] = center

        if len(leaves) > 0:
            for vid in leaves:
                centroid(vid)

            # Define grid (horizontal layers)
            zs = [c[2] for c in centroids.itervalues()]
            minz = min(zs)
            maxz = max(zs) + self.layer_thickness
            layers = {
                l: []
                for l in np.arange(minz, maxz, self.layer_thickness)
            }

            # Distribute leaves in layers
            for vid, coords in centroids.iteritems():
                z = coords[2]
                ls = layers.keys()
                i_layer = np.where(
                    map(
                        lambda x: x <= z < x + self.layer_thickness
                        if z != maxz - self.layer_thickness else x <= z <= x +
                        self.layer_thickness, ls))[0]
                if len(i_layer) > 0.:
                    layers[ls[i_layer]].append(vid)

            self.layers = layers
        else:
            self.layers = {}
Exemple #7
0
def test_pgl_scene():
    g = potted_syrah()
    bc = pgl.BBoxComputer(pgl.Tesselator())

    s = energy.pgl_scene(g)
    bc.process(s)
    bbox = bc.boundingbox
    zmin, zmax = bbox.getZMin(),bbox.getZMax()
    assert zmax > zmin > 0

    s = energy.pgl_scene(g, flip=True)
    bc.process(s)
    bbox = bc.boundingbox
    zmin, zmax = bbox.getZMin(),bbox.getZMax()
    assert 0 > zmax > zmin

    # check that original scene is still z >0
    s = energy.pgl_scene(g)
    bc.process(s)
    bbox = bc.boundingbox
    zmin, zmax = bbox.getZMin(), bbox.getZMax()
    assert zmax > zmin > 0
Exemple #8
0
    def fit_grid(self, z_adaptive=False):
        """ Find grid parameters that fit the scene in the RATP grid
        """

        # fit regular grid to scene
        if self.scene is None:
            nbx, nby, nbz = self.grid_shape
            dx, dy, dz = self.grid_resolution  # already in meter
            xo, yo, zo = 0, 0, 0  # origin
        else:
            # Find the bounding box that fit the scene
            tesselator = pgl.Tesselator()
            bbc = pgl.BBoxComputer(tesselator)
            bbc.process(self.scene)
            bbox = bbc.result
            zsoil = self.z_soil
            if zsoil is None:
                zsoil = bbox.getZMin()

            if self.domain is None:
                xo = bbox.getXMin() * self.convert  # origin
                yo = bbox.getYMin() * self.convert
            else:
                xo = self.domain[0][0] * self.convert
                yo = self.domain[0][1] * self.convert
            zo = zsoil * self.convert

            if self.grid_resolution is not None and self.grid_shape is not None:
                nbx, nby, nbz = self.grid_shape
                dx, dy, dz = self.grid_resolution  # already in meter
            else:
                if self.domain is None:
                    xmax = bbox.getXMax() * self.convert
                    ymax = bbox.getYMax() * self.convert
                else:
                    xmax = self.domain[1][0] * self.convert
                    ymax = self.domain[1][1] * self.convert
                zmax = bbox.getZMax() * self.convert
                if self.grid_resolution is None:
                    nbx, nby, nbz = self.grid_shape
                    if self.domain is None:
                        if nbx > 1:
                            dx = (xmax - xo) / float(
                                nbx - 1
                            )  # use nbx -1 to ensure min and max are in the grid
                        else:
                            dx = (xmax - xo) * 1.01
                        if nby > 1:
                            dy = (ymax - yo) / float(nby - 1)
                        else:
                            dy = (ymax - yo) * 1.01
                    else:
                        dx = (xmax - xo) / float(
                            nbx
                        )  #toric canopies allows coordinate outside the pattern
                        dy = (ymax - yo) / float(nby)
                    if nbz > 1:
                        dz = (zmax - zo) / float(nbz - 1)
                    else:
                        dz = (zmax - zo) * 1.01
                    # try to accomodate flat scene
                    if dz == 0:
                        dz = (dx + dy) / 2.
                    if dx == 0:
                        dx = (dy + dz) / 2.
                    if dy == 0:
                        dy = (dx + dz) / 2.
                if self.grid_shape is None:
                    dx, dy, dz = self.grid_resolution
                    if self.domain is None:
                        nbx = int(numpy.ceil((xmax - xo) / float(dx)))
                        nby = int(numpy.ceil((ymax - yo) / float(dy)))
                    else:  #dx,dy,dz are adjusted to fit the domain exactly
                        nbx = int((xmax - xo) / float(dx))
                        nby = int((ymax - yo) / float(dy))
                        dx = (xmax - xo) / float(nbx)
                        dy = (ymax - yo) / float(nby)
                    nbz = int(numpy.ceil((zmax - zo) / float(dz)))
                # balance extra-space between both sides of the grid (except z i zsoil has been set)
                extrax = dx * nbx - (xmax - xo)
                xo -= (extrax / 2.)
                extray = dy * nby - (ymax - yo)
                yo -= (extray / 2.)
                if self.z_soil is None:
                    extraz = dz * nbz - (zmax - zo)
                    zo -= (extraz / 2.)

        # dz for all voxels
        if self.z_resolution is not None:
            dz = self.z_resolution[::-1]  # dz is from top to base for ratp
            nbz = len(dz)
        else:
            dz = [dz] * nbz

        grid_pars = {
            'njx': nbx,
            'njy': nby,
            'njz': nbz,
            'dx': dx,
            'dy': dy,
            'dz': dz,
            'xorig': xo,
            'yorig': yo,
            'zorig': -zo
        }  # zorig is a z offset in grid.py (grid_z = z + zo)

        return grid_pars
Exemple #9
0
def my_distance(n, sectors):
    """ Compute the distance with infectable sectors. """
    if 'distance' not in n._g._properties:
        n._g.add_property('distance')
    tesselator = pgl.Tesselator()
    bbc = pgl.BBoxComputer(tesselator)

    def base(geom):
        if geom:
            pts = geom.pointList
            if pts:
                n = len(pts)
                assert n % 2 == 0
                return 1 / 2 * (pts[0] + pts[n / 2])

    def top(geom):
        if geom:
            pts = geom.pointList
            if pts:
                n = len(pts)
                assert n % 2 == 0
                return 1 / 2 * (pts[n / 2 - 1] + pts[-1])

    def bbox_distance(g1, g2):

        bbc.process(pgl.Scene([g1]))
        bbox1 = bbc.result
        bbc.process(pgl.Scene([g2]))
        bbox2 = bbc.result

        # TODO bbox.lowerLeftCorner, bbox.upperRightCorner
        return bbox1.distance(bbox2)

    def mesh_distance(g1, g2):
        pts1 = g1.pointList
        pts2 = g2.pointList
        if pts1 and pts2:
            d = maxint
            for pt in pts2:
                p1, i = pts1.findClosest(pt)
                # TODO: To Fix
                d = pgl.norm(pt - p1)
                return d
        else:
            return maxint

    def lovel_distance(g1, g2):
        p1 = base(g1)
        p2 = top(g2)
        return pgl.norm(p2 - p1)

    def opt_distance(n1, n2):
        g1 = n1.geometry
        g2 = n2.geometry
        if not g1 or not g2:
            return maxint
        if DISTANCE == 'BOX':
            return bbox_distance(g1, g2)
        elif DISTANCE == 'LOVEL':
            return lovel_distance(g1, g2)
        elif DISTANCE == 'MESH':
            return mesh_distance(g1, g2)

    dists = [opt_distance(n, source) for source in sectors]
    dist = min(dists) if dists else maxint

    if not n.distance:
        n.distance = []
    if dist != maxint:
        n.distance.append((n.age, dist))

    print n, dist
    if dist <= 1:
        n.color = 0, 0, 255
Exemple #10
0
""" Gather different strategies for modeling dispersal of fungus propagules.