Ejemplo n.º 1
0
def test_materials():
    can = data_path('filterT.can')
    cscene = read_can(can)
    path = data_path('par.opt')
    n, s, opts = read_opt(path)
    materials = build_materials(cscene.keys(), opts, s)
    assert len(materials) == len(cscene)
    assert materials[materials.keys()[0]] == (0.1, 0.05)
    return materials
Ejemplo n.º 2
0
def test_opt():
    path = data_path('par.opt')
    n, s, opts = read_opt(path)

    assert n == 2
    assert s == 0.15
    assert opts[1] == (0.1, 0.1, 0.05, 0.1, 0.05)

    return n, s, opts
Ejemplo n.º 3
0
def run_caribu(sources, scene, opticals='stem', optical_properties=None, output_by_triangle=False, domain=None,
               zsoil=None):
    """ 
    Calls Caribu for differents energy sources

    :Parameters:
    ------------
    - `sources` (int)
    - `scene` : any scene format accepted by CaribuScene. This will be cast to a list of plantGL shapes
    - opticals : a list of optical property labels ('leaf', 'soil', 'stem', 'ear' or 'awn') for all shapes in scene. If a shorter opticale list is provided, it will be recycled to match eength of shape list
    - `optical_properties`: a filename (*.opt).
    - `output_by_triangle` (bool)
        Default 'False'. Return is done by id of geometry. If 'True', return is done by triangle. 

    :Returns:
    ---------
    - 'out_moy' (dict)
        A dict of intercepted variable (energy) per id
    - 'out_tri' (dict) only if output_by_triangle = True, return a tuple (out_moy, out_tri)
        A dict of intercepted variable (energy) per triangle
    """

    raise DeprecationWarning('This function is deprecated, use CaribuScene / caribu_star instead')

    from alinea.caribu.label import simple_canlabel
    from alinea.caribu.file_adaptor import read_opt, build_materials

    n, soil_reflectance, po = read_opt(optical_properties)
    if not isinstance(opticals, list):
        opticals = [opticals]
    if len(opticals) < len(scene):
        opticals = opticals * (len(scene) / len(opticals)) + [opticals[i] for i in range(len(scene) % len(opticals))]
    labels = [simple_canlabel(opt) for opt in opticals]
    materials = build_materials(labels, po, soil_reflectance)
    band = CaribuScene.default_band

    c_scene = CaribuScene(scene=scene, light=sources, pattern=domain, opt={band: materials},
                          soil_reflectance={band: soil_reflectance})

    ifty = False
    if domain is not None:
        ifty = True
        # if zsoil is not None:
        #    idmap_soil = c_scene.addSoil(zsoil=zsoil)
        #    idmap.update(idmap_soil)

    raw, aggregated = c_scene.run(direct=True, infinite=ifty, simplify=True)

    if output_by_triangle:
        out = raw
    else:
        out = aggregated
    return out
Ejemplo n.º 4
0
    def __init__(self, scene=None, light=None, pattern=None, opt=None,
                 soil_reflectance=None, soil_mesh=None, z_soil=None,
                 scene_unit='m'):
        """ Initialise a CaribuScene

        Args:
            scene (dict): a {primitive_id: [triangles,]} dict.A triangle is a
                    list of 3-tuples points coordinates
                    Alternatively, scene can be a *.can file or a mtg with
                    'geometry' property or a plantGL scene.
                    For the later case, shape.id are used as primitive_id.
            light (list): a list of (Energy, (vx, vy, vz)) tuples defining light
                    sources
                    Alternatively,  a *.light file
                    If None (default), a unit energy vertical light is used.
                    Energy unit should be given per square-meter (m-2)
            pattern (tuple): 2D Coordinates of the domain bounding the scene for
                    its replication.
                     (xmin, ymin, xmax, ymax) scene is not bounded along z axis.
                     Alternatively a *.8 file.
                     if None (default), scene is not repeated
            opt (dict): a {band_name: {primitive_id: material}} dict of dict
                        or a {band_name: material} dict of tuples.
                        In the second form the material is used for all primitives.
                    A material is a 1-, 2- or 4-tuple depending on its optical behavior.
                    A 1-tuple encode an opaque material characterised by its reflectance
                    A 2-tuple encode a symmetric translucent material defined
                    by a reflectance and a transmittance
                    A 4-tuple encode an asymmetric translucent material defined
                    the reflectance and transmittance
                    of the upper and lower side respectively
                    Alternatively, a list of band_name.opt files (require scene
                    to be given as a *.can file)
                    If None (default), all primitive are associated to the
                    default material of the class.
            soil_reflectance (dict): a {band_name: reflectance} dict.
                    If None (default) class default soil reflectance is used for all bands
                    If *.opt files are provided, the values in opt files are used in priority
            soil_mesh (int): a flag triggering for the creation of a soil mesh
            in the scene during computations
                    If None (default) or -1, no soil is added
                    If an int (n), a soil is added to the scene, with n subdivisions
            z_soil (float): the altitude of the soil.
                    If None (default), the soil is placed at the bottom of
                    the scene bounding box
            scene_unit (str): the unit of length used for scene coordinate
            and for pattern (should be one of class.units default)
                    By default, scene_unit is considered to be 'm' (meter).

        Returns:
            A CaribuScene instance

        Note:
            File format specifications (*.can, *.light, *.8, *.opt) can be found in data/CanestraDoc.pdf
        """

        if scene_unit not in self.units:
            raise ValueError('unrecognised scene unit: ' + scene_unit)
        self.conv_unit = self.units[scene_unit]

        self.scene = None
        if scene is not None:
            if isinstance(scene, dict):
                elt = scene[scene.keys()[0]]
                try:
                    assert isinstance(elt, list)
                    assert isinstance(elt[0], list)
                    assert isinstance(elt[0][0], tuple)
                except:
                    raise ValueError('Unrecognised scene format')
                self.scene = scene
            elif isinstance(scene, str):
                self.scene = read_can(scene)
            elif isinstance(scene, MTG):
                self.scene = mtg_to_cscene(scene)
            elif isinstance(scene, pglScene):
                self.scene = scene_to_cscene(scene)
            else:
                raise ValueError('Unrecognised scene format')

        self.light = [self.default_light]
        if light is not None:
            if isinstance(light, list):
                elt = light[0]
                try:
                    assert isinstance(elt, tuple)
                    assert isinstance(elt[1], tuple)
                except:
                    raise ValueError('Unrecognised light format')
                self.light = light
            elif isinstance(light, str):
                self.light = read_light(light)
            else:
                raise ValueError('Unrecognised light format')

        self.pattern = None
        if pattern is not None:
            if isinstance(pattern, tuple):
                if len(pattern) == 2:
                    pattern = sum(pattern, ())
                if len(pattern) != 4:
                    raise ValueError('Unrecognised pattern format')
                self.pattern = pattern
            elif isinstance(pattern, str):
                self.pattern = read_pattern(pattern)
            else:
                raise ValueError('Unrecognised pattern format')

        self.material = None
        if opt is None:
            if soil_reflectance is None:
                self.soil_reflectance = {
                    self.default_band: self.default_soil_reflectance}
                bands = [self.default_band]
            else:
                self.soil_reflectance = soil_reflectance
                bands = soil_reflectance.keys()
            if self.scene is not None:
                self.material = {}
                for band in bands:
                    self.material[band] = {pid: self.default_material for pid in
                                           self.scene}
        else:
            if isinstance(opt, list):
                if not isinstance(opt[0], str):
                    raise ValueError('Unrecognised opt format')
                if not isinstance(scene, str):
                    raise ValueError(
                        'un-compatible inputs types: opt file and scene not a can file')
                if self.scene is not None:
                    self.material = {}
                    self.soil_reflectance = {}
                    for path in opt:
                        band = os.path.basename(path).split('.')[0]
                        n, ro_soil, po = read_opt(path)
                        self.material[band] = build_materials(self.scene.keys(),
                                                              po, ro_soil)
                        self.soil_reflectance[band] = ro_soil
            elif isinstance(opt, dict):
                elt = opt[opt.keys()[0]]
                if not isinstance(elt, dict):
                    if isinstance(elt, tuple):
                        self.material = {}
                        if self.scene is not None:
                            for band in opt:
                                self.material[band] = {pid: opt[band] for pid in
                                                       self.scene}
                    else:
                        raise ValueError('Unrecognised opt format')
                else:
                    self.material = opt
                if soil_reflectance is None:
                    self.soil_reflectance = {band: self.default_soil_reflectance
                                             for band in self.material}
                else:
                    if isinstance(soil_reflectance, dict):
                        if not len(soil_reflectance) == len(opt):
                            raise ValueError(
                                'the number of bands for optical properties and soil reflectance should match')
                        self.soil_reflectance = soil_reflectance
                    else:
                        raise ValueError('Unrecognised soil_reflectance format')
            else:
                raise ValueError('Unrecognised opt format')

        self.soil = None
        if soil_mesh is not None:
            if soil_mesh != -1:
                if self.pattern is None:
                    raise ValueError(
                        'Adding a soil needs the scene domain to be defined')
                if z_soil is None:
                    if self.scene is None:
                        z_soil = 0
                    else:
                        triangles = reduce(lambda x, y: x + y,
                                           self.scene.values())
                        z = (pt[2] for tri in triangles for pt in tri)
                        z_soil = min(z)
                self.soil = domain_mesh(self.pattern, z_soil, soil_mesh)
Ejemplo n.º 5
0
    def __init__(self,
                 scene=None,
                 light=None,
                 pattern=None,
                 opt=None,
                 soil_reflectance=None,
                 soil_mesh=None,
                 z_soil=None,
                 scene_unit='m',
                 debug=False,
                 filecache=True):
        """ Initialise a CaribuScene

        Args:
            scene (dict): a {primitive_id: [triangles,]} dict.A triangle is a
                    list of 3-tuples points coordinates
                    Alternatively, scene can be a *.can file or a mtg with
                    'geometry' property or a plantGL scene.
                    For the later case, shape.id are used as primitive_id.
            light (list): a list of (Energy, (vx, vy, vz)) tuples defining light
                    sources
                    Alternatively,  a *.light file
                    If None (default), a unit energy vertical light is used.
                    Energy unit should be given per square-meter (m-2)
            pattern (tuple): 2D Coordinates of the domain bounding the scene for
                    its replication.
                     (xmin, ymin, xmax, ymax) scene is not bounded along z axis.
                     Alternatively a *.8 file.
                     if None (default), scene is not repeated
            opt (dict): a {band_name: {primitive_id: material}} dict of dict
                        or a {band_name: material} dict of tuples.
                        In the second form the material is used for all primitives.
                    A material is a 1-, 2- or 4-tuple depending on its optical behavior.
                    A 1-tuple encode an opaque material characterised by its reflectance
                    A 2-tuple encode a symmetric translucent material defined
                    by a reflectance and a transmittance
                    A 4-tuple encode an asymmetric translucent material defined
                    the reflectance and transmittance
                    of the upper and lower side respectively
                    Alternatively, a list of band_name.opt files (require scene
                    to be given as a *.can file)
                    If None (default), all primitive are associated to the
                    default material of the class.
            soil_reflectance (dict): a {band_name: reflectance} dict.
                    If None (default) class default soil reflectance is used for all bands
                    If *.opt files are provided, the values in opt files are used in priority
            soil_mesh (int): a flag triggering for the creation of a soil mesh
            in the scene during computations
                    If None (default) or -1, no soil is added
                    If an int (n), a soil is added to the scene, with n subdivisions
            z_soil (float): the altitude of the soil.
                    If None (default), the soil is placed at the bottom of
                    the scene bounding box
            scene_unit (str): the unit of length used for scene coordinate
            and for pattern (should be one of class.units default)
                    By default, scene_unit is considered to be 'm' (meter).

        Returns:
            A CaribuScene instance

        Note:
            File format specifications (*.can, *.light, *.8, *.opt) can be found in data/CanestraDoc.pdf
        """

        self.debug = debug

        if scene_unit not in self.units:
            raise ValueError('unrecognised scene unit: ' + scene_unit)
        self.conv_unit = self.units[scene_unit]

        self.scene = None
        if scene is not None:
            if isinstance(scene, dict):
                elt = scene[list(scene.keys())[0]]
                try:
                    assert isinstance(elt, list)
                    assert isinstance(elt[0], list)
                    assert isinstance(elt[0][0], tuple)
                except:
                    raise ValueError('Unrecognised scene format')
                self.scene = CaribuTriangleSet(scene)
            elif isinstance(scene, str):
                self.scene = CaribuTriangleSet(read_can(scene))
            elif isinstance(scene, MTG):
                self.scene = CaribuTriangleSet(mtg_to_cscene(scene))
            elif isinstance(scene, pglScene):
                self.scene = CaribuTriangleSet(scene_to_cscene(scene))
            elif isinstance(scene, AbstractCaribuTriangleSet):
                self.scene = scene
            else:
                raise ValueError('Unrecognised scene format')

        self.light = [self.default_light]
        if light is not None:
            self.setLight(light)

        self.pattern = None
        if pattern is not None:
            if isinstance(pattern, tuple):
                if len(pattern) == 2:
                    pattern = sum(pattern, ())
                if len(pattern) != 4:
                    raise ValueError('Unrecognised pattern format')
                self.pattern = pattern
            elif isinstance(pattern, str):
                self.pattern = read_pattern(pattern)
            else:
                raise ValueError('Unrecognised pattern format')

        self.material = None
        if opt is None:
            if soil_reflectance is None:
                self.soil_reflectance = {
                    self.default_band: self.default_soil_reflectance
                }
                bands = [self.default_band]
            else:
                self.soil_reflectance = soil_reflectance
                bands = list(soil_reflectance.keys())
            if self.scene is not None:
                self.material = {}
                for band in bands:
                    self.material[band] = {
                        pid: self.default_material
                        for pid in self.scene.keys()
                    }
        else:
            if isinstance(opt, list):
                if not isinstance(opt[0], str):
                    raise ValueError('Unrecognised opt format')
                if not isinstance(scene, str):
                    raise ValueError(
                        'un-compatible inputs types: opt file and scene not a can file'
                    )
                if self.scene is not None:
                    self.material = {}
                    self.soil_reflectance = {}
                    for path in opt:
                        band = os.path.basename(path).split('.')[0]
                        n, ro_soil, po = read_opt(path)
                        self.material[band] = build_materials(
                            list(self.scene.keys()), po, ro_soil)
                        self.soil_reflectance[band] = ro_soil
            elif isinstance(opt, dict):
                elt = opt[list(opt.keys())[0]]
                if not isinstance(elt, dict):
                    if isinstance(elt, tuple):
                        self.material = {}
                        if self.scene is not None:
                            for band in opt:
                                self.material[band] = {
                                    pid: opt[band]
                                    for pid in self.scene.keys()
                                }
                    else:
                        raise ValueError('Unrecognised opt format')
                else:
                    self.material = opt
                if soil_reflectance is None:
                    self.soil_reflectance = {
                        band: self.default_soil_reflectance
                        for band in self.material
                    }
                else:
                    if isinstance(soil_reflectance, dict):
                        if not len(soil_reflectance) == len(opt):
                            raise ValueError(
                                'the number of bands for optical properties and soil reflectance should match'
                            )
                        self.soil_reflectance = soil_reflectance
                    else:
                        raise ValueError(
                            'Unrecognised soil_reflectance format')
            else:
                raise ValueError('Unrecognised opt format')

        self.soil = None
        if soil_mesh is not None:
            if soil_mesh != -1:
                if self.pattern is None:
                    raise ValueError(
                        'Adding a soil needs the scene domain to be defined')
                if z_soil is None:
                    if self.scene is None:
                        z_soil = 0
                    else:
                        z_soil = self.scene.getZmin()
                self.soil = domain_mesh(self.pattern, z_soil, soil_mesh)

        self.tempdir = None
        if filecache:
            self.tempdir = tempfile.mkdtemp(
            ) if not debug else './caribuscene_' + str(id(self))
        self.canfile = None
        self.optfile = None