def illuminate(g, isolated=True, density=9, clear_sky=False, daydate=_daydate, longitude=_longitude, latitude=_latitude, altitude=_altitude, timezone=_timezone): """ Illuminate a plant Args: isolated : is the plant isolated or within a canopy ? clear_sky: use clear_sky (homogeneous sky is used otherwise) irradiance: (float) sum of horizontal irradiance of all sources. If None diffuse horizontal clear_sky irradiance are used for clear_sky type and 20% attenuated clear_sky global horizontal irradiances are used for soc and uoc types. dates: A pandas datetime index (as generated by pandas.date_range). If None, hourly values for daydate are used. daydate: (str) yyyy-mm-dd (not used if dates is not None). longitude: (float) in degrees latitude: (float) in degrees altitude: (float) in meter timezone:(str) the time zone (not used if dates are already localised) Returns: elevation (degrees), azimuth (degrees, from North positive clockwise), and horizontal irradiance of sources """ if not clear_sky: light = light_sources(*sky_sources()) else: sun, sky = sun_sky_sources(daydate=daydate, longitude=longitude, latitude=latitude, altitude=altitude, timezone=timezone, normalisation=1) light = light_sources(*sun) + light_sources(*sky) inter_row = 80 inter_plant = 1. / density / (inter_row / 100.) * 100 pattern = (-0.5 * inter_row, -0.5 * inter_plant, 0.5 * inter_row, 0.5 * inter_plant) cs = CaribuScene(g, light=light, pattern=pattern, scene_unit='cm') raw, agg = cs.run(direct=True, simplify=True, infinite=not isolated) return cs, raw, agg
def test_instantiation_from_files(): can = str(data_path('filterT.can')) sky = str(data_path('Turtle16soc.light')) opts = map(str, [data_path('par.opt'), data_path('nir.opt')]) pattern = str(data_path('filter.8')) # defaults cs = CaribuScene() assert cs.scene is None assert cs.light == [cs.default_light] assert cs.pattern is None assert cs.material is None assert cs.soil_reflectance[ cs.default_band] == cs.default_soil_reflectance # complete set of files cs = CaribuScene(scene=can, light=sky, opt=opts, pattern=pattern) assert len(cs.scene) == 1 assert len(cs.scene[cs.scene.keys()[0]]) == 192 assert len(cs.light) == 16 for band in ('nir', 'par'): assert band in cs.material assert len(cs.material[band]) == len(cs.scene) assert cs.soil_reflectance['par'] != cs.soil_reflectance['nir'] assert len(cs.pattern) == 4 # incomplete set of files cs = CaribuScene(scene=can) assert len(cs.material[cs.default_band]) == len(cs.scene) return cs
def illuminate(scene, light=None, pattern=None, scene_unit='cm', north=0): """Illuminate scene Args: scene: the scene (plantgl) light: lights. If None a vertical light is used pattern: the toric canopy pattern. If None, no pattern is used scene_unit: string indicating length unit in the scene (eg 'cm') north: the angle (deg, positive clockwise) from X+ to North (default: 0) Returns: """ infinite = False if pattern is not None: infinite = True if light is not None: light = light_sources(*light, orientation=north) cs = CaribuScene(scene, light=light, scene_unit=scene_unit, pattern=pattern) raw, agg = cs.run(direct=True, simplify=True, infinite=infinite) return cs, raw['Ei'], pandas.DataFrame(agg)
def test_run_monochrome(): pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 1, 0), (0, 1, 0)] sensors = {'solem': [[(0, 0, 2), (1, 0, 2), (0, 1, 2)], [(1, 0, 2), (1, 1, 2), (0, 1, 2)]], 'kipp': [[(0, 0, 3), (1, 0, 3), (0, 1, 3)]]} pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain) # raycasting out, agg = cscene.run(direct=True, infinite=False, sensors=sensors) assert len(out) == 1 assert len(out[cscene.default_band]['Eabs']) == 2 assert len(out[cscene.default_band]['Eabs']['lower']) == 2 assert len(out[cscene.default_band]['Eabs']['upper']) == 1 assert len(out[cscene.default_band]['sensors']['Ei']) == 2 # radiosity out, agg = cscene.run(direct=False, infinite=False) assert len(out) == 1 assert len(out[cscene.default_band]['Eabs']) == 2 assert len(out[cscene.default_band]['Eabs']['lower']) == 2 assert len(out[cscene.default_band]['Eabs']['upper']) == 1 # mixed radiosity out, agg = cscene.run(direct=False, infinite=True) assert len(out) == 1 assert len(out[cscene.default_band]['Eabs']) == 2 assert len(out[cscene.default_band]['Eabs']['lower']) == 2 assert len(out[cscene.default_band]['Eabs']['upper']) == 1 return out, agg
def illuminate(g, isolated=True): light = light_sources(*sky_sources()) # density =9 pl/m2 density = 9 inter_row = 80 inter_plant = 1. / density / (inter_row / 100.) * 100 pattern = (-0.5 * inter_row, -0.5 * inter_plant, 0.5 * inter_row, 0.5 * inter_plant) cs = CaribuScene(g, light=light, pattern=pattern, scene_unit='cm') raw, agg = cs.run(direct=True, simplify=True, infinite=not isolated) return cs, raw, agg
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
def test_bbox(): s = pgl.Scene() s.add(pgl.Sphere()) cs = CaribuScene(scene=s) bbox = cs.bbox() assert bbox == ((-0.5, -0.5, -0.5), (0.5, 0.5, 0.5)) points = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] triangles = [points] pyscene = {'t1': triangles} cs = CaribuScene(scene=pyscene) bbox = cs.bbox() assert bbox == ((0, 0, 0), (1, 1, 0))
def test_autoscreen(): s = pgl.Scene() s.add(pgl.Sphere()) cs = CaribuScene(scene=s) npix = cs.auto_screen(0.01) assert npix == 173 points = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] triangles = [points] pyscene = {'t1': triangles} cs = CaribuScene(scene=pyscene) npix = cs.auto_screen(0.01) assert npix == 141
def test_run_polychrome(): pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 1, 0), (0, 1, 0)] sensors = { 'solem': [[(0, 0, 2), (1, 0, 2), (0, 1, 2)], [(1, 0, 2), (1, 1, 2), (0, 1, 2)]], 'kipp': [[(0, 0, 3), (1, 0, 3), (0, 1, 3)]] } pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} opt = { 'par': { 'lower': (0.1, ), 'upper': (0.1, ) }, 'nir': { 'lower': (0.5, ), 'upper': (0.5, ) } } domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain, opt=opt) # raycasting out, agg = cscene.run(direct=True, infinite=False, sensors=sensors) assert 'par' in out.keys() assert 'nir' in out.keys() assert len(out['par']['Eabs']) == 2 assert len(out['par']['Eabs']['lower']) == 2 assert len(out['nir']['Eabs']) == 2 assert out['par']['Eabs']['upper'][0] != out['nir']['Eabs']['upper'][0] # radiosity out, agg = cscene.run(direct=False, infinite=False) assert 'par' in out.keys() assert 'nir' in out.keys() assert len(out['par']['Eabs']) == 2 assert len(out['par']['Eabs']['lower']) == 2 assert len(out['nir']['Eabs']) == 2 assert out['par']['Eabs']['upper'][0] != out['nir']['Eabs']['upper'][0] # mixed radiosity out, agg = cscene.run(direct=False, infinite=True) assert 'par' in out.keys() assert 'nir' in out.keys() assert len(out['par']['Eabs']) == 2 assert len(out['par']['Eabs']['lower']) == 2 assert len(out['nir']['Eabs']) == 2 assert out['par']['Eabs']['upper'][0] != out['nir']['Eabs']['upper'][0] return out, agg
def illuminate(scene, sky=None, sun=None, pattern=None): if sky is None and sun is None: sky = sky_sources() light = [] if sky is not None: light += light_sources(*sky) if sun is not None: light += light_sources(*sun) infinite = False if pattern is not None: infinite = True cs = CaribuScene(scene, light=light, scene_unit='cm', pattern=pattern) raw, agg = cs.run(direct=True, simplify=True, infinite=infinite) return cs, raw, agg
def run_caribu(sources, scene_geometry, output_by_triangle=False): """ Calls Caribu for differents energy sources :Parameters: ------------ - `sources` (int) - `scene_geometry` - `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 """ c_scene = CaribuScene() shapes = [geom2shape(k, v) for k, v in scene_geometry.items()] idmap = c_scene.add_Shapes(shapes) c_scene.addSources(sources) output = c_scene.runCaribu(infinity=False) out_moy = c_scene.output_by_id(output, idmap) if output_by_triangle: out_tri = c_scene.output_by_id(output, idmap, aggregate=False) indices = c_scene.scene_ids return out_moy, out_tri, indices else: return out_moy
def test_instantiation_from_python(): s = pgl.Scene() s.add(pgl.Sphere()) points = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] triangles = [points] pyscene = {'t1': triangles} sky = [(0, (0, 0, -1)), (1, (0, 0, -1))] pattern = (0, 0, 20, 20) pattern_old_style = ((0, 0), (20, 20)) materials = {'par': {'t1': (0.3, )}} simplified_materials = {'par': (0.3, )} soil_reflectance = {'par': 0} cs = CaribuScene(scene=s, light=sky, pattern=pattern) assert len(cs.scene) == 1 assert len(list(cs.scene.values())[0]) == 112 assert len(cs.light) == 2 assert len(cs.pattern) == 4 assert list( cs.material[cs.default_band].values())[0] == cs.default_material assert cs.soil_reflectance[ cs.default_band] == cs.default_soil_reflectance cs = CaribuScene(scene=pyscene, opt=materials, pattern=pattern_old_style) assert len(cs.scene) == 1 assert len(cs.scene['t1']) == 1 assert cs.material == materials assert cs.soil_reflectance['par'] == cs.default_soil_reflectance assert len(cs.pattern) == 4 cs = CaribuScene(scene=pyscene, soil_reflectance=soil_reflectance) assert 'par' in cs.material assert cs.soil_reflectance == soil_reflectance cs = CaribuScene(scene=pyscene, opt=materials, soil_reflectance=soil_reflectance) assert 'par' in cs.material assert cs.soil_reflectance == soil_reflectance cs = CaribuScene(scene=pyscene, opt=simplified_materials, soil_reflectance=soil_reflectance) assert 'par' in cs.material assert cs.soil_reflectance == soil_reflectance return cs
def test_soil(): pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 1, 0), (0, 1, 0)] pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain, soil_mesh=1) out, agg = cscene.run(direct=True, infinite=False, simplify=True) assert_almost_equal(agg['area']['lower'], 1, 0) assert_almost_equal(agg['Ei']['lower'], 0.5, 1) assert_almost_equal(agg['Ei']['upper'], 1, 0) assert len(cscene.soil) == 2 assert len(cscene.soil_raw[cscene.default_band]['Ei']) == 2 soil = cscene.soil_aggregated[cscene.default_band] assert_almost_equal(soil['Ei'], 0, 1) assert_almost_equal(soil['area'], 1, 1)
def test_soil(): pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 1, 0), (0, 1, 0)] pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain, soil_mesh=1) out, agg = cscene.run(direct=True, infinite=False, simplify=True) assert_almost_equal(agg['area']['lower'], 1, 0) assert_almost_equal(agg['Ei']['lower'], 0.5, 1) assert_almost_equal(agg['Ei']['upper'], 1, 0) assert len(cscene.soil) == 2 assert len(cscene.soil_raw[cscene.default_band]['Ei']) == 2 soil = cscene.soil_aggregated[cscene.default_band] assert_almost_equal(soil['Ei'], 0, 1) assert_almost_equal(soil['area'], 1, 1)
def _caribu_call(scene, directions, opt=None, domain=None, convUnit=None): """ adaptor for backward compatibility of macros calling caribu """ energie, emission, direction, elevation, azimuth = turtle(sectors=str(directions), energy=1) sources = zip(energie, direction) c_scene = CaribuScene(scene=scene, light=sources, opt=opt, pattern=domain) if convUnit is not None: c_scene.conv_unit = convUnit ifty = False if domain is not None: ifty = True raw, aggregated = c_scene.run(direct=True, infinite=ifty, simplify=True) return c_scene, raw, aggregated
def caribu(scene, source=(1, (0, 0, -1)), infinity=False): c_scene = CaribuScene() idmap = c_scene.add_Shapes(scene) c_scene.addSources(source) output = c_scene.runCaribu(infinity=infinity) results = c_scene.output_by_id(output, idmap)['Eabsm2'] return c_scene, results
def run_caribu(sources, scene_geometry, output_by_triangle = False): """ Calls Caribu for differents energy sources :Parameters: ------------ - `sources` (int) - `scene_geometry` - `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 """ c_scene = CaribuScene() shapes=[geom2shape(k,v) for k,v in scene_geometry.iteritems()] idmap = c_scene.add_Shapes(shapes) c_scene.addSources(sources) output = c_scene.runCaribu(infinity=False) out_moy = c_scene.output_by_id(output, idmap) if output_by_triangle: out_tri = c_scene.output_by_id(output, idmap, aggregate = False) indices = c_scene.scene_ids return out_moy, out_tri, indices else: return out_moy
def caribu(scene, source = (1,(0,0,-1)), infinity=False): c_scene = CaribuScene() idmap = c_scene.add_Shapes(scene) c_scene.addSources(source) output = c_scene.runCaribu(infinity=infinity) results = c_scene.output_by_id(output, idmap)['Eabsm2'] return c_scene, results
def test_run_polychrome(): pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 1, 0), (0, 1, 0)] sensors = {'solem': [[(0, 0, 2), (1, 0, 2), (0, 1, 2)], [(1, 0, 2), (1, 1, 2), (0, 1, 2)]], 'kipp': [[(0, 0, 3), (1, 0, 3), (0, 1, 3)]]} pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} opt = {'par': {'lower': (0.1,), 'upper': (0.1,)}, 'nir': {'lower': (0.5,), 'upper': (0.5,)}} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain, opt=opt) # raycasting out, agg = cscene.run(direct=True, infinite=False,sensors=sensors) assert 'par' in out.keys() assert 'nir' in out.keys() assert len(out['par']['Eabs']) == 2 assert len(out['par']['Eabs']['lower']) == 2 assert len(out['nir']['Eabs']) == 2 assert out['par']['Eabs']['upper'][0] != out['nir']['Eabs']['upper'][0] # radiosity out, agg = cscene.run(direct=False, infinite=False) assert 'par' in out.keys() assert 'nir' in out.keys() assert len(out['par']['Eabs']) == 2 assert len(out['par']['Eabs']['lower']) == 2 assert len(out['nir']['Eabs']) == 2 assert out['par']['Eabs']['upper'][0] != out['nir']['Eabs']['upper'][0] # mixed radiosity out, agg = cscene.run(direct=False, infinite=True) assert 'par' in out.keys() assert 'nir' in out.keys() assert len(out['par']['Eabs']) == 2 assert len(out['par']['Eabs']['lower']) == 2 assert len(out['nir']['Eabs']) == 2 assert out['par']['Eabs']['upper'][0] != out['nir']['Eabs']['upper'][0] return out, agg
def test_display(): # standard scene pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 1, 0), (0, 1, 0)] pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain) cscene.plot(display=False) out, agg = cscene.run(direct=True, infinite=False, simplify=True) cscene.plot(agg['Ei'], display=False) cscene.plot(out['Ei'], display=False) # include null triangle pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 0, 0), (0, 1, 0)] pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain) out, agg = cscene.run(direct=True, infinite=False, simplify=True) cscene.plot(out['Ei'], display=False)
def test_unit(): # scene in meter pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 1, 0), (0, 1, 0)] pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain) out, agg = cscene.run(direct=True, infinite=False, simplify=True) assert_almost_equal(sum(out['area']['lower']), 1, 0) assert_almost_equal(sum(out['Ei']['upper']), 1, 0) # same scene but now in centimeter pts_1 = [(0, 0, 0), (100, 0, 0), (0, 100, 0)] pts_2 = [(0, 0, 1e-3), (1, 0, 1e-3), (0, 1, 1e-3)] pts_3 = [(100, 0, 0), (100, 100, 0), (0, 100, 0)] pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 100, 100) cscene = CaribuScene(pyscene, pattern=domain, scene_unit='cm') out, agg = cscene.run(direct=True, infinite=False, simplify=True) assert_almost_equal(sum(out['area']['lower']), 1, 0) assert_almost_equal(sum(out['Ei']['upper']), 1, 0)
def test_run_monochrome(): pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 1, 0), (0, 1, 0)] sensors = { 'solem': [[(0, 0, 2), (1, 0, 2), (0, 1, 2)], [(1, 0, 2), (1, 1, 2), (0, 1, 2)]], 'kipp': [[(0, 0, 3), (1, 0, 3), (0, 1, 3)]] } pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain) # raycasting out, agg = cscene.run(direct=True, infinite=False, sensors=sensors) assert len(out) == 1 assert len(out[cscene.default_band]['Eabs']) == 2 assert len(out[cscene.default_band]['Eabs']['lower']) == 2 assert len(out[cscene.default_band]['Eabs']['upper']) == 1 assert len(out[cscene.default_band]['sensors']['Ei']) == 2 # radiosity out, agg = cscene.run(direct=False, infinite=False) assert len(out) == 1 assert len(out[cscene.default_band]['Eabs']) == 2 assert len(out[cscene.default_band]['Eabs']['lower']) == 2 assert len(out[cscene.default_band]['Eabs']['upper']) == 1 # mixed radiosity out, agg = cscene.run(direct=False, infinite=True) assert len(out) == 1 assert len(out[cscene.default_band]['Eabs']) == 2 assert len(out[cscene.default_band]['Eabs']['lower']) == 2 assert len(out[cscene.default_band]['Eabs']['upper']) == 1 return out, agg
def test_aggregation(): # simple case pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 1, 0), (0, 1, 0)] pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain) out, agg = cscene.run(direct=True, infinite=False, simplify=True) assert_almost_equal(agg['area']['lower'], 1, 0) assert_almost_equal(agg['Ei']['lower'], 0.5, 1) assert_almost_equal(agg['Ei']['upper'], 1, 0) # pts3 now define a null triangle pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 0, 0), (0, 1, 0)] pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain) out, agg = cscene.run(direct=True, infinite=False, simplify=True) assert_almost_equal(agg['area']['lower'], 0.5, 0) assert_almost_equal(agg['Ei']['lower'], 0, 1) assert_almost_equal(agg['Ei']['upper'], 1, 0)
def compute_exposed_area(slices): cyl = Cylinder(radius, height, False, slices) cyl_rotated = AxisRotated((0, 1, 0), pi / 2., cyl) scene = {1: cyl_rotated} sources = diffuse_source(1) c_scene = CaribuScene() idmap = c_scene.add_Shapes(scene) c_scene.addSources(sources) output = c_scene.runCaribu(infinity=False) out = c_scene.output_by_id(output, idmap) star = out['Ei'].values()[0] area = out['Area'].values()[0] exposed_area = star * area return exposed_area
def test_bbox(): s = pgl.Scene() s.add(pgl.Sphere()) cs = CaribuScene(scene=s) bbox = cs.bbox() assert bbox == ((-0.5, -0.5, -0.5), (0.5, 0.5, 0.5)) points = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] triangles = [points] pyscene = {'t1': triangles} cs = CaribuScene(scene=pyscene) bbox = cs.bbox() assert bbox == ((0, 0, 0), (1, 1, 0))
def test_autoscreen(): s = pgl.Scene() s.add(pgl.Sphere()) cs = CaribuScene(scene=s) npix = cs.auto_screen(0.01) assert npix == 173 points = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] triangles = [points] pyscene = {'t1': triangles} cs = CaribuScene(scene=pyscene) npix = cs.auto_screen(0.01) assert npix == 141
def newCaribuScene(scene=None, light=[(1, (0, 0, -1))], pattern=None, opt={'band1': (0.06, 0.07)}, soil_reflectance={'band1': 0.15}, soil_mesh=-1, z_soil=0., scene_unit='cm'): # backward compatibility for opt file if isinstance(opt, str): opt = [opt] return CaribuScene(scene=scene, light=light, pattern=pattern, opt=opt, soil_reflectance=soil_reflectance, soil_mesh=soil_mesh, z_soil=z_soil, scene_unit=scene_unit)
def compute_exposed_area(slices): cyl = Cylinder(radius, height, False, slices) cyl_rotated = AxisRotated((0,1,0), pi/2., cyl) scene = {1: cyl_rotated} sources = diffuse_source(1) c_scene = CaribuScene() idmap = c_scene.add_Shapes(scene) c_scene.addSources(sources) output = c_scene.runCaribu(infinity=False) out = c_scene.output_by_id(output, idmap) star = out['Ei'].values()[0] area = out['Area'].values()[0] exposed_area = star * area return exposed_area
def test_unit(): # scene in meter pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 1, 0), (0, 1, 0)] pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain) out, agg = cscene.run(direct=True, infinite=False, simplify=True) assert_almost_equal(sum(out['area']['lower']), 1, 0) assert_almost_equal(sum(out['Ei']['upper']), 1, 0) # same scene but now in centimeter pts_1 = [(0, 0, 0), (100, 0, 0), (0, 100, 0)] pts_2 = [(0, 0, 1e-3), (1, 0, 1e-3), (0, 1, 1e-3)] pts_3 = [(100, 0, 0), (100, 100, 0), (0, 100, 0)] pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 100, 100) cscene = CaribuScene(pyscene, pattern=domain, scene_unit='cm') out, agg = cscene.run(direct=True, infinite=False, simplify=True) assert_almost_equal(sum(out['area']['lower']), 1, 0) assert_almost_equal(sum(out['Ei']['upper']), 1, 0)
def test_aggregation(): # simple case pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 1, 0), (0, 1, 0)] pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain) out, agg = cscene.run(direct=True, infinite=False, simplify=True) assert_almost_equal(agg['area']['lower'], 1, 0) assert_almost_equal(agg['Ei']['lower'], 0.5, 1) assert_almost_equal(agg['Ei']['upper'], 1, 0) # pts3 now define a null triangle pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 0, 0), (0, 1, 0)] pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain) out, agg = cscene.run(direct=True, infinite=False, simplify=True) assert_almost_equal(agg['area']['lower'], 0.5, 0) assert_almost_equal(agg['Ei']['lower'], 0, 1) assert_almost_equal(agg['Ei']['upper'], 1, 0)
def test_display(): # standard scene pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 1, 0), (0, 1, 0)] pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain) cscene.plot(display=False) out, agg = cscene.run(direct=True, infinite=False, simplify=True) cscene.plot(agg['Ei'], display=False) cscene.plot(out['Ei'], display=False) # include null triangle pts_1 = [(0, 0, 0), (1, 0, 0), (0, 1, 0)] pts_2 = [(0, 0, 1e-5), (1, 0, 1e-5), (0, 1, 1e-5)] pts_3 = [(1, 0, 0), (1, 0, 0), (0, 1, 0)] pyscene = {'lower': [pts_1, pts_3], 'upper': [pts_2]} domain = (0, 0, 1, 1) cscene = CaribuScene(pyscene, pattern=domain) out, agg = cscene.run(direct=True, infinite=False, simplify=True) cscene.plot(out['Ei'], display=False)
"""Functional Interfaces to CaribuScene class methods Theses interfaces are mainly tageted for building visualea nodes They generally have an additional copyscene argument, that pass caribuscene by copy instead of by reference """ from alinea.caribu.CaribuScene import CaribuScene from alinea.caribu.display import generate_scene from alinea.caribu.caribu import opt_string_and_labels, triangles_string # caribuscene instance used to access doc strings of class methods cdoc = CaribuScene() def newCaribuScene(scene=None, light=[(1, (0, 0, -1))], pattern=None, opt={'band1': (0.06, 0.07)}, soil_reflectance={'band1': 0.15}, soil_mesh=-1, z_soil=0., scene_unit='cm'): # backward compatibility for opt file if isinstance(opt, str): opt = [opt] return CaribuScene(scene=scene, light=light, pattern=pattern, opt=opt, soil_reflectance=soil_reflectance, soil_mesh=soil_mesh,
def hsCaribu(mtg, unit_scene_length, geometry='geometry', opticals='opticals', consider=None, source=None, direct=True, infinite=False, nz=50, ds=0.5, pattern=None, soil_reflectance=0.15): """Calculates intercepted and absorbed irradiance flux densities by the plant canopy. Args: mtg (MTG): plant Multiscale Tree Graph unit_scene_length (str): the unit of length used for scene coordinate and for pattern (should be one of `CaribuScene.units` default) geometry (str): the name of the property to use for computing scene geometry from the mtg opticals (str): the name of the property to use for caribu optical properties consider (list(int)): vertices to be considered for the computation, if None (default) all vertices with a geometry are considered source (list): a tuple of tuples, giving energy unit and sky coordinates, if None, a unit zenital source is used direct: see :func:`runCaribu` from `CaribuScene` package infinite: see :func:`runCaribu` from `CaribuScene` package nz: see :func:`runCaribu` from `CaribuScene` package ds: see :func:`runCaribu` from `CaribuScene` package pattern: see :func:`runCaribu` from `CaribuScene` package soil_reflectance (float): [-] the reflectance of the soil (between 0 and 1) Returns: mtg object with the incident irradiance (`Ei`) and absorbed irradiance (`Eabs`), both in [umol m-2 s-1], attached to mtg vertices as properties. Notes: `Ei` and `Eabs` units are returned in [umol m-2 s-1] **REGARDLESS** of the `unit_scence_length` type. """ assert geometry in mtg.property_names() assert opticals in mtg.property_names() # Currently used as a dummy variable wave_band = 'SW' if source is None: source = [(1, (0, 0, -1))] # Hack : would be much better to have geometry as a caribuscene args directly geom0 = mtg.property(geometry) geometry0 = {} remove_geometry = 'geometry' not in mtg.property_names() if consider is not None: geom0 = {k: v for k, v in mtg.property(geometry).items()} mtg.properties()[geometry] = { k: v for k, v in mtg.property(geometry).items() if k in consider } if geometry != 'geometry' and 'geometry' in mtg.property_names(): geometry0 = {k: v for k, v in mtg.property('geometry').items()} mtg.properties()['geometry'] = mtg.property(geometry) caribu_scene = None # Use a try/except/finally block to allow restoring geometry if block fails try: # Run caribu only if irradiance is greater that 0 if sum([x[0] for x in source]) == 0.: mtg.properties()['Ei'] = {k: 0. for k in mtg.property('geometry')} mtg.properties()['Eabs'] = { k: 0. for k in mtg.property('geometry') } else: # Attaching optical properties to each organ of the plant mock-up opts = {wave_band: mtg.property(opticals)} # Setup CaribuScene caribu_scene = CaribuScene( mtg, light=source, opt=opts, soil_reflectance={wave_band: soil_reflectance}, scene_unit=unit_scene_length, pattern=pattern) # Run caribu raw, aggregated = caribu_scene.run(direct=direct, infinite=infinite, d_sphere=ds, layers=nz, split_face=False) # Attaching output to MTG mtg.properties()['Ei'] = aggregated[wave_band]['Ei'] mtg.properties()['Eabs'] = aggregated[wave_band]['Eabs'] except: pass finally: mtg.properties()[geometry] = geom0 if remove_geometry: mtg.remove_property('geometry') else: if len(geometry0) > 0: mtg.properties()['geometry'] = geometry0 return mtg, caribu_scene
def _initialize_model(self, energy, diffuse_model, azimuts, zenits, DOY, hourTU, latitude, heterogeneous_canopy, plant_density, inter_row): """ Initialize the inputs of the model from the MTG shared :param float energy: The incident PAR above the canopy (µmol m-2 s-1) :param string diffuse_model: The kind of diffuse model, either 'soc' or 'uoc'. :param int azimuts: The number of azimutal positions. :param int zenits: The number of zenital positions. :param int DOY: Day Of the Year to be used for solar sources :param int hourTU: Hour to be used for solar sources (Universal Time) :param float latitude: latitude to be used for solar sources (°) :param bool heterogeneous_canopy: Whether to create a duplicated heterogeneous canopy from the initial mtg. :return: A tuple of Caribu scenes instantiated for sky and sun sources, respectively. :rtype: (CaribuScene, CaribuScene) """ #: Diffuse light sources : Get the energy and positions of the source for each sector as a string sky_string = GetLight.GetLight( GenSky.GenSky()(energy, diffuse_model, azimuts, zenits)) #: (Energy, soc/uoc, azimuts, zenits) # Convert string to list in order to be compatible with CaribuScene input format sky = [] for string in sky_string.split('\n'): if len(string) != 0: string_split = string.split(' ') t = tuple((float(string_split[0]), tuple( (float(string_split[1]), float(string_split[2]), float(string_split[3]))))) sky.append(t) #: Direct light sources (sun positions) sun = Gensun.Gensun()(energy, DOY, hourTU, latitude) sun = GetLightsSun.GetLightsSun(sun) sun_str_split = sun.split(' ') sun = [ tuple((float(sun_str_split[0]), tuple((float(sun_str_split[1]), float(sun_str_split[2]), float(sun_str_split[3]))))) ] #: Optical properties opt = {'par': {}} geom = self._shared_mtg.property('geometry') for vid in geom.keys(): if self._shared_mtg.class_name(vid) in ('LeafElement1', 'LeafElement'): opt['par'][vid] = ( 0.10, 0.05 ) #: (reflectance, transmittance) of the adaxial side of the leaves elif self._shared_mtg.class_name(vid) == 'StemElement': opt['par'][vid] = (0.10, ) #: (reflectance,) of the stems else: warnings.warn( 'Warning: unknown element type {}, vid={}'.format( self._shared_mtg.class_name(vid), vid)) #: Generates CaribuScenes if not heterogeneous_canopy: # TODO: adapt the domain to plant_density c_scene_sky = CaribuScene(scene=self._shared_mtg, light=sky, pattern=self._geometrical_model.domain, opt=opt) c_scene_sun = CaribuScene(scene=self._shared_mtg, light=sun, pattern=self._geometrical_model.domain, opt=opt) else: duplicated_scene, domain = self._create_heterogeneous_canopy( plant_density=plant_density, inter_row=inter_row) c_scene_sky = CaribuScene(scene=duplicated_scene, light=sky, pattern=domain, opt=opt) c_scene_sun = CaribuScene(scene=duplicated_scene, light=sun, pattern=domain, opt=opt) return c_scene_sky, c_scene_sun
def form_factors_simplified(g, pattern=None, infinite=False, leaf_lbl_prefix='L', turtle_sectors='46', icosphere_level=3, unit_scene_length='cm'): """Computes sky and soil contribution factors (resp. k_sky and k_soil) to the energy budget equation. Both factors are calculated and attributed to each element of the scene. Args: g: a multiscale tree graph object 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 infinite (bool): Whether the scene should be considered as infinite (see :func:`runCaribu` from `CaribuScene` package) leaf_lbl_prefix (str): the prefix of the leaf label turtle_sectors (str): number of turtle sectors (see :func:`turtle` from `sky_tools` package) icosphere_level (int): the level of refinement of the dual icosphere (see :func:`alinea.astk.icosphere.turtle_dome` for details) unit_scene_length (str): the unit of length used for scene coordinate and for pattern (should be one of `CaribuScene.units` default) Returns: Notes: This function is a simplified approximation of the form factors matrix which is calculated by the function :func:`form_factors_matrix`. The canopy is turned upside-down and light is projected in each case to estimate the respective contribution of the sky ({z}>=0) and soil ({z}<=0) to energy budget calculations. This is printed as pirouette-cacahuete in the console! When **icosphere_level** is defined, **turtle_sectors** is ignored. """ geom = g.property('geometry') label = g.property('label') opts = { 'SW': { vid: ((0.001, 0) if label[vid].startswith(leaf_lbl_prefix) else (0.001, )) for vid in geom } } if not icosphere_level: energy, emission, direction, elevation, azimuth = turtle.turtle( sectors=turtle_sectors, format='uoc', energy=1.) else: vert, fac = ico.turtle_dome(icosphere_level) direction = ico.sample_faces(vert, fac, iter=None, spheric=False).values() direction = [i[0] for i in direction] direction = map(lambda x: tuple(list(x[:2]) + [-x[2]]), direction) caribu_source = zip(len(direction) * [1. / len(direction)], direction) k_soil, k_sky, k_leaves = {}, {}, {} for s in ('pirouette', 'cacahuete'): print '... %s' % s if s == 'pirouette': scene = pgl_scene(g, flip=True) else: scene = pgl_scene(g) caribu_scene = CaribuScene(scene, light=caribu_source, opt=opts, scene_unit=unit_scene_length, pattern=pattern) # Run caribu raw, aggregated = caribu_scene.run(direct=True, infinite=infinite, split_face=False, simplify=True) if s == 'pirouette': k_soil_dict = aggregated['Ei'] max_k_soil = float(max(k_soil_dict.values())) k_soil = { vid: k_soil_dict[vid] / max_k_soil for vid in k_soil_dict } elif s == 'cacahuete': k_sky_dict = aggregated['Ei'] max_k_sky = float(max(k_sky_dict.values())) k_sky = {vid: k_sky_dict[vid] / max_k_sky for vid in k_sky_dict} for vid in aggregated['Ei']: k_leaves[vid] = max(0., 2. - (k_soil[vid] + k_sky[vid])) return k_soil, k_sky, k_leaves