API Reference
This page is a compact guide to the public entry points of ArchimedLight.jl. For normal use, create a LightSimulation and call run_light.
API Stability
Version 0.1.3 is the compatibility baseline for ArchimedLight's first release in Julia's General registry. Earlier 0.1.x tags were development snapshots and are not covered by this stability promise. Starting with 0.1.3, the supported public API is the set of names exported by ArchimedLight. This includes the high-level simulation workflow, input readers, model helpers, validation helpers, user-facing result containers, attachment/output helpers, visualization helpers, and concrete backend selectors. Patch releases after 0.1.3 are expected to preserve those names; incompatible changes will use a new minor version and include migration notes.
Some lower-level stage functions are available as qualified calls such as ArchimedLight.compute_sky(...). These are intended for debugging, research, and parity work. They are not exported, and their exact arguments, return containers, and cache internals may be refined before 1.0.
LightStepResult and LightBudget are public result containers. It is fine to read their fields in analysis code, but user code should normally construct results through run_light rather than calling result constructors directly.
LightSimulation owns internal preparation and cache state. Use update_scene!, update_models!, update_options!, and cache_summary rather than relying on the cache field or cache object layout.
Main Workflow
File-based run:
using ArchimedLight
repo_root = normpath(joinpath(dirname(pathof(ArchimedLight)), ".."))
config = joinpath(repo_root, "example_2", "config.yml")
sim, meteo = read_simulation(config)
step = run_light(sim, first(meteo))
series = run_light(sim, meteo);2-element Vector{LightStepResult}:
LightStepResult(PAR=3.724 MJ, NIR=9.594 MJ, sky=463.139 W m^-2 PAR / 501.734 W m^-2 NIR, sectors=16 [sky=16, sun=0], scattering=13 iters, converged)
LightStepResult(PAR=3.628 MJ, NIR=9.443 MJ, sky=448.777 W m^-2 PAR / 486.175 W m^-2 NIR, sectors=16 [sky=16, sun=0], scattering=13 iters, converged)Interactive run. This is a schematic API shape because it assumes that the host application provides plant.opf and meteo_row; see the checked Interactive Workflow page for a fully executable in-memory scene.
using PlantGeom
scene = make_scene(domain=(-1.0, -1.0, 1.0, 1.0)) do s
add_plant!(s, "plant.opf"; group="coffee", id=1)
add_ground!(s; group="soil", type="ground")
end
models = models_for(
"coffee" => ("Leaf" => translucent(par=0.15, nir=0.90),),
"soil" => ("ground" => translucent(par=0.10, nir=0.40),),
)
sim = LightSimulation(scene, models; options=LightOptions())
step = run_light(sim, meteo_row)For host-model coupling, this schematic loop assumes your host model provides the meteo rows and a later new_scene:
for row in rows
light = run_light(sim, row)
end
update_scene!(sim, new_scene)Input Loading
Use these when your workflow starts from files or existing tables. The names in this block are schematic placeholders for your actual paths and tables.
read_simulation(path)
read_scene(path)
read_models(path_or_paths)
read_options(path)
read_meteo(path_or_table)Scene And Model Helpers
Use these when inputs are built in Julia. This block lists call signatures and is intentionally schematic.
PlantGeom.make_scene(f; domain, source_path="interactive.scene", kwargs...)
PlantGeom.add_plant!(builder, mtg_or_path; group, id, at=(0, 0, 0), scale=1.0, rotate=(0, 0, 0))
PlantGeom.add_object!(builder, mtg_mesh_or_path; group, id, type="object", at=(0, 0, 0), scale=1.0, rotate=(0, 0, 0))
PlantGeom.add_ground!(builder; z=0.0, nx=9, ny=9, group="pavement", type="Cobblestone")
PlantGeom.prepare_scene(mtg; source_path="interactive.opf", scene_xy_bounds=nothing, relabel_ids=false)
models_for(group => (type => model, ...), ...)
translucent(; par, nir, transparency=0.0)
virtual_sensor()
emitter(; radiance, par=0.48, nir=0.52)PlantGeom.add_plant! is the plant-named wrapper. PlantGeom.add_object! is the general placement helper for MTGs, GeometryBasics meshes, .opf, and .gwa files. For mesh files such as .obj or .ply, use MeshIO/FileIO to load the mesh first. This snippet is schematic because it depends on your local mesh file and builder:
using FileIO, MeshIO
mesh = load("sensor.obj")
PlantGeom.add_object!(builder, mesh; group="sensor", type="panel", id=10)Both placement helpers accept at, scale, rotate, deg, and OPS-style rotation, inclination_azimut, and inclination_angle placement keywords.
Tuple rotations use fixed X, then Y, then Z order. This is a schematic call shape:
PlantGeom.add_object!(builder, mesh; group="sensor", type="panel", id=10, rotate=(10, 20, 30), deg=true)Named-tuple rotations preserve the field order, which is useful when you need a specific Euler sequence. This is a schematic call shape:
PlantGeom.add_object!(builder, mesh; group="sensor", type="panel", id=10, rotate=(y=20, z=30, x=10), deg=true)PlantGeom.add_ground! and write_scene also work on prepared scenes. This snippet is schematic because it assumes an existing scene and output path:
PlantGeom.add_ground!(scene; z=0.0, nx=9, ny=9, xy_bounds=nothing, group="pavement", type="Cobblestone")
write_scene(path, scene)Validation
Use these to diagnose inputs before running. This block is schematic and uses placeholder inputs already introduced above:
check_scene(scene)
check_models(scene, models)
check_meteo(meteo; options=LightOptions())
check_simulation(sim)
check_simulation(scene, meteo; models, options=LightOptions())
summarize_scene(scene; models=nothing)
summarize_meteo(meteo; options=LightOptions())Each function returns a ValidationReport with errors, warnings, and infos. Meteo-aware checks and execution methods accept check_boundaries=false as a one-call override; derivability, duration, and finite-input consistency checks remain enabled.
The summarize_* helpers return structured summaries and print compact diagnostics for humans. Use them when you are not sure what ArchimedLight sees. This schematic snippet assumes scene, models, meteo, and options exist:
summarize_scene(scene; models=models)
summarize_meteo(meteo; options=options)Simulation Cache
LightSimulation owns preparation and cache state. These helpers update inputs and invalidate cached data. This block is schematic and assumes existing replacement inputs:
update_scene!(sim, scene)
update_models!(sim, models)
update_options!(sim, options)
cache_summary(sim)update_scene! immediately releases old scene-dependent prepared data and cache entries. The cache object itself is an implementation detail; use cache_summary(sim) when you need to inspect cache behavior. Its node_metadata_count and node_metadata_bytes fields report the size of the current lightweight metadata snapshot independently of the radiation-response cache budget.
Advanced Light Pipeline
The explicit stage API is available as qualified, advanced API for debugging, research, and parity workflows. These calls may return stage containers such as ArchimedLight.TurtleGrid or ArchimedLight.FirstOrderResult, which are not exported in 0.1.x. This block is schematic because it assumes all previous stage inputs have already been prepared:
ArchimedLight.compute_sky(row, options)
ArchimedLight.build_turtle(options, sky)
ArchimedLight.compute_directional_fluxes(row, sky, turtle, options)
ArchimedLight.compute_first_order(scene, models, turtle, fluxes, options)
ArchimedLight.compute_scattering(scene, models, turtle, first, options)
ArchimedLight.integrate_light(scene, models, first, scattering, options; meteo_row=row)These functions and stage containers are intentionally not exported in 0.1.x. Prefer run_light for application code unless you need to inspect or replace individual pipeline stages.
For interactive synthetic scenes, run_light also accepts a prebuilt sky state. This block is schematic because it assumes an existing scene, models, options, and sky:
sim = LightSimulation(scene, models; options=options)
step = run_light(sim, sky; step_duration_seconds=1800.0)A vector of sky states runs as a series. Supply either one duration shared by all states or one duration per state:
series = run_light(sim, skies; step_duration_seconds=1800.0)
series = run_light(sim, skies; step_duration_seconds=[900.0, 1800.0, 900.0])The result order matches skies, and the prepared scene and radiation cache are reused throughout the series.
The low-level cache functions are still available for advanced work, but their cache object layout is internal. This block is schematic and uses placeholders:
cache = ArchimedLight.prepare_light_cache(scene, models, options; ...)
ArchimedLight.run_light_step(cache, meteo_row)
ArchimedLight.run_light_series(cache, meteo)prepare_light_cache uses a tiered policy internally:
:fullkeeps all seen turtle responses in memory:partialkeeps a bounded LRU cache for large moving-sun series:topology_fallbackreuses prepared geometry/topology only when a full-response cache would be too large or unsupported
Scene Attachment Helpers
These functions attach computed values back onto the MTG using ARCHIMED attribute names. This block lists schematic call shapes:
attach_node_values!(scene, attr, values; fill_value=nothing)
attach_light_step!(scene, step; fields=[:incident_par_flux], names=Dict(), fill_value=nothing)
attach_light_series!(scene, steps; fields=[:incident_par_flux], names=Dict(), fill_value=NaN)attach_light_step! attaches scalar values for one step. attach_light_series! attaches Vector{Float64} values, ordered like steps, for each selected field. The supported fields selectors are:
| Selector | Default MTG attribute |
|---|---|
:area | area |
:incident_par_initial_flux | Ri_PAR_0_f |
:incident_nir_initial_flux | Ri_NIR_0_f |
:incident_par_flux | Ri_PAR_f |
:incident_nir_flux | Ri_NIR_f |
:incident_par_initial_energy | Ri_PAR_0_q |
:incident_nir_initial_energy | Ri_NIR_0_q |
:incident_par_energy | Ri_PAR_q |
:incident_nir_energy | Ri_NIR_q |
:absorbed_par_initial_flux | Ra_PAR_0_f |
:absorbed_nir_initial_flux | Ra_NIR_0_f |
:absorbed_par_flux | Ra_PAR_f |
:absorbed_nir_flux | Ra_NIR_f |
:absorbed_par_initial_energy | Ra_PAR_0_q |
:absorbed_nir_initial_energy | Ra_NIR_0_q |
:absorbed_par_energy | Ra_PAR_q |
:absorbed_nir_energy | Ra_NIR_q |
:sky_fraction | sky_fraction |
For :area, attach_light_step! attaches one scalar surface area per node, while attach_light_series! repeats that area once per step so the attached attribute has the same vector shape as the light fields.
Use names=Dict(selector => attr) to override default attribute names, for example Dict(:absorbed_nir_flux => :Ra_SW_f).
Scene-Aware Light Queries
Use these functions to select geometric nodes and query a step or complete series without first attaching values to the MTG:
light_node_ids(
scene_or_sim;
node_ids=nothing,
source_topology_id=nothing,
group=nothing,
species=nothing,
object_id=nothing,
symbol=nothing,
scale=nothing,
type=nothing,
attributes=NamedTuple(),
inherit_attributes=false,
where=nothing,
)
light_metric_values(
scene_or_sim,
step_or_series,
selector;
# the same node filters
reduce=nothing,
by=nothing,
sink=nothing,
)The default result is a Tables.jl-compatible long-form column table. A reducer without by returns one scalar for a step or one value per timestep for a series. A reducer with by returns a grouped table. Native selectors and ARCHIMED names are interchangeable, for example :absorbed_par_energy and :Ra_PAR_q.
group/species and object_id inherit metadata from scene object roots. Arbitrary attributes are node-local unless inherit_attributes=true. Explicit node_ids are runtime identifiers in one prepared scene. source_topology_id identifies the source topology component; combine it with object_id when the same source plant is instantiated more than once.
Results retain a lightweight metadata snapshot by default. Consequently, light_metric_values(sim, dynamic_series, ...) applies semantic filters to each step's own scene version after update_scene!, even when runtime node ids changed. light_node_ids(step; ...) queries one retained snapshot directly.
Configure retention with:
LightOptions(
store_node_metadata=true,
node_metadata_attributes=(:organ_id, :cohort),
)Extra attributes must be lightweight scalar values. Set store_node_metadata=false to minimize retained results; those results must be queried with their original live scene. A custom where predicate also needs a live MTG, so dynamic-series queries should capture its scalar inputs through node_metadata_attributes and use attributes=(...) instead.
Visualization Helpers
These helpers expose direct mesh coloring and the Makie package extension. This block lists schematic call shapes:
light_render_geometry(scene, models, options)
light_render_geometry(step)
light_render_geometry(steps)
tile_light_geometry(scene, geometry; nx=1, ny=1, centered=true, xperiod=nothing, yperiod=nothing)
tile_light_geometry(scene, step; nx=1, ny=1, centered=true, xperiod=nothing, yperiod=nothing)
tile_light_geometry(scene, steps; nx=1, ny=1, centered=true, xperiod=nothing, yperiod=nothing)
tile_light_geometry(scene, models, options; nx=1, ny=1, centered=true, xperiod=nothing, yperiod=nothing)
light_metric_values(step, selector)
light_metric_values(steps, selector; timestep=1)
light_face_values(data; color=:incident_par_flux, timestep=1, fill_value=NaN)
light_vertex_values(data; color=:incident_par_flux, timestep=1, fill_value=NaN)
light_face_values(scene, models, options, data; color=:incident_par_flux, timestep=1, fill_value=NaN)
light_vertex_values(scene, models, options, data; color=:incident_par_flux, timestep=1, fill_value=NaN)
lightplot(geometry, data; color=:incident_par_flux, timestep=1, interpolate=false, ...)
lightplot!(axis, geometry, data; color=:incident_par_flux, timestep=1, interpolate=false, ...)
lightplot(step; color=:incident_par_flux, timestep=1, interpolate=false, ...)
lightplot(steps; color=:incident_par_flux, timestep=1, interpolate=false, ...)
lightplot!(axis, step; color=:incident_par_flux, timestep=1, interpolate=false, ...)
lightplot!(axis, steps; color=:incident_par_flux, timestep=1, interpolate=false, ...)
lightplot(scene, models, options, data; color=:incident_par_flux, timestep=1, interpolate=false, ...)
lightplot!(axis, scene, models, options, data; color=:incident_par_flux, timestep=1, interpolate=false, ...)For lightplot(steps; colorrange=automatic), the Makie extension keeps a single color range across the whole series so animated timesteps remain comparable.
Backend Types
The current public backend selectors are:
This block lists schematic constructor calls:
RasterCPUBackend()
RaycastScatteringBackend()They can be passed explicitly to the pipeline helpers when you want to control the implementation used for interception or scattering. Only the concrete selectors are exported in 0.1.x; the backend supertypes are internal, and defining new backend subtypes is not yet a supported extension interface.
Recommended Starting Points
- read Getting Started for the shortest runnable workflow
- read Composable Stages if you want the stage-by-stage pattern
- read Outputs for the mapping between
LightBudgetfields and ARCHIMED attribute names
API List
ArchimedLight.EmitterModel — Type
EmitterModel(; model="LambertianEmitter", radiance=0.0, gamma=OpticalProperties(0.48, 0.52), extras=...)Emission model for artificial or diagnostic light sources.
radiance is the Lambertian radiance L emitted by each matching surface, in power per emitting area per steradian (for example W m^-2 sr^-1). gamma contains independent dimensionless spectral coefficients which are applied exactly as configured; they are not normalized to sum to one. PAR and NIR use the named fields, while additional coefficients in gamma.extras retain their uppercased band names. For a component with emitting surface area A, the hemispherical power in band b is pi * A * L * gamma[b]. The current model is one-sided and assumes a horizontal surface emitting into the downward hemisphere.
Most canopy simulations do not need explicit emitters and rely only on sky and sun forcing, but emitters are useful for artificial lighting setups, synthetic tests, or debugging scenes.
ArchimedLight.GroupModel — Type
GroupModel(group; types=OrderedDict(), extras=...)Model definition for one functional group, keyed by component type.
group should match the functional-group name carried by the prepared scene geometry, for example "coffee" or "pavement".
types maps scene type names such as "Leaf", "Metamer", or "Cobblestone" to TypeModel values.
Wildcard support:
- an exact type key such as
"Leaf"applies only to that type - the wildcard key
"*"acts as a fallback for any type in the group
This allows compact interactive setups such as:
GroupModel(
"coffee";
types=OrderedDict(
"*" => TypeModel(
interception=InterceptionModel(
model="Translucent",
optical_properties=OpticalProperties(0.15, 0.90),
),
),
"Stem" => TypeModel(
interception=InterceptionModel(
model="Translucent",
transparency=0.2,
optical_properties=OpticalProperties(0.10, 0.50),
),
),
),
)In that example, all coffee components use the wildcard model except "Stem", which is overridden explicitly.
ArchimedLight.InterceptionModel — Type
InterceptionModel(; model="Translucent", sensor=false, transparency=0.0, optical_properties=nothing, use=nothing, variants=..., extras=...)Radiative behavior attached to one scene component type.
This stores the interception model name, transparency, optical coefficients, and optional named variants from historical ARCHIMED model files.
Main fields:
model: historical ARCHIMED interception model name. The common runtime case is"Translucent".sensor: marks the type as a virtual sensor. Virtual sensors receive light diagnostics but remain transparent in the transfer logic.transparency: first-order transmitted fraction. Typical values are in[0, 1], with0.0for fully intercepting surfaces and larger values for partially transmitting components.optical_properties: waveband-dependent scattering coefficients used by the scattering stage.useandvariants: preserved support for historical YAML files that define several named parameter sets under oneInterceptionblock.
Typical pattern for ordinary canopy elements:
InterceptionModel(model="Translucent", transparency=0.0, optical_properties=OpticalProperties(0.15, 0.90))
ArchimedLight.LightBudget — Type
LightBudgetPer-node light budget for one simulation step, storing incident and absorbed fluxes and energies for PAR, NIR, and optional extra wavebands. Escaped artificial-emitter energy is stored by waveband and emitting source node.
ArchimedLight.LightModels — Type
LightModels(groups)Top-level collection of all functional-group models used by one simulation.
This is the object passed to run_light_step, run_light_series, and the lower level interception/scattering functions.
groups maps functional-group names to GroupModel values. The special group key "*" is also supported as a global fallback.
When the solver resolves a scene node (group, type), it matches models with the following precedence:
- exact group and exact type
- exact group and wildcard type
"*" - wildcard group
"*"and exact type - wildcard group
"*"and wildcard type"*"
This makes LightModels convenient for:
- precise canopy parameterizations with several plant groups
- synthetic scenes where one default model should cover many node types
- gradual interactive workflows where you start with fallback models and then add explicit overrides
Examples:
LightModels([GroupModel("coffee"; ...), GroupModel("pavement"; ...)])LightModels([GroupModel("*"; types=OrderedDict("*" => default_type_model))])
ArchimedLight.LightNodeMetadata — Type
LightNodeMetadataLightweight columnar scene-node metadata captured for one prepared scene. Every LightStepResult computed from the same simulation cache shares the same snapshot, so semantic queries remain valid after update_scene!.
attributes stores requested node-local scalar attributes, while inherited_attributes stores their nearest inherited values.
ArchimedLight.LightOptions — Type
LightOptionsRuntime controls for interception, scattering, and caching.
Fields:
all_in_turtle: iffalse, keep the direct beam as a separate sun sector; iftrue, redistribute it into the turtle sectors.turtle_sectors: number of diffuse sky sectors. Common values are16,46, or denser grids for smoother angular resolution.pixel_size: raster pixel size in meters. Smaller values improve geometric fidelity but increase runtime and memory use.area_ratio: enable the ARCHIMED projected-area correction used for parity with the historical implementation.scattering: enable multiple scattering after first-order interception.scattering_max_iter: maximum number of scattering iterations.scattering_stop_ratio: stop scattering when the current scattered energy is below this fraction of the initial intercepted energy.scattering_coeff_par: fallback PAR scattering coefficient when the model has no PAROpticalProperties.scattering_coeff_nir: fallback NIR scattering coefficient when the model has no NIROpticalProperties.cache_radiation: reuse directional responses across series steps when possible.include_sky_fraction: store the per-nodesky_fractionmap in eachLightStepResult. Leavefalseunless downstream code needs it. When options are read from a config file, this is enabled by requestingsky_fractionincomponent_variablesoropf_variables.store_node_metadata: retain a lightweight per-scene node metadata snapshot shared by all results computed from that scene. This keeps queries valid afterupdate_scene!.node_metadata_attributes: optional scalar MTG attribute names to add to the standard node metadata snapshot. Standard identity and group/type fields are always included whenstore_node_metadata=true.cache_pixel_table: cache raster pixel tables for repeated projections.pixel_hit_stack_mode: storage mode for per-pixel hit stacks. Supported values are"auto","small", and"vector".toricity: enable horizontal periodic wrapping of the simulated plot.radiation_timestep_minutes: internal radiative substep used when a meteo row covers a coarser interval.radiation_input_semantics: interpretation of supplied irradiances.:interval_meanpreserves the supplied full-timestep mean, while:sunlit_intensitytreats it as an intensity that applies only while the sun is above the horizon (the historical Java behavior).scene_rotation_deg: clockwise rotation, in degrees, from geographic north to the scene's local coordinates. The geographic sun is transformed into the fixed local turtle basis before directional weights are computed.check_meteo_boundaries: validate physical ranges for meteorological inputs before preparation or execution. Derivability and conflicting-input checks remain enabled even when this isfalse.allow_overlapping_meteo_steps: keep overlapping meteo intervals instead of rejecting the series during meteo preparation.nir_interception: include NIR in directional fluxes and first-order interception.nir_scattering: include NIR in the multiple-scattering stage. This has no effect ifnir_interception=false.java_logged_turtle_dirs: use the Java-compatibility turtle direction path used in parity/debug workflows.meteo_range: optional historical range selector applied during meteo preparation, for example"2, 5"or a datetime range.debug: enable debug-only compatibility hooks.log_debug: emit additional debug logging where implemented.debug_drop_leading_hit: optional(node_id, x, y)hook used to remove a leading raster hit at one pixel for parity debugging.
Typical starting point for simple runs:
LightOptions(turtle_sectors=46, pixel_size=0.0025, scattering=true)
Constructor keywords are the field names above. LightOptions(old; kwargs...) copies an existing options value and overrides only the supplied keywords.
ArchimedLight.LightRenderGeometry — Type
LightRenderGeometryRender-ready geometry used to visualize one simulated light result.
This stores the exact face subset and face-to-node mapping used by the light solver after model-dependent filtering has been applied.
ArchimedLight.LightSimulation — Method
LightSimulation(scene, models; options=LightOptions(), kwargs...)Create a reusable light simulation. Expensive geometry preparation and radiation caches are built lazily by run_light.
Arguments:
scene: preparedPlantGeom.SceneGeometryused by the solver.models: model specification accepted byprepare_models.
Keywords:
options:LightOptionscontrolling interception, scattering, and caching.interception_backend: interception backend selector or backend instance. The default is:raster_cpu.scattering_mode: scattering algorithm selector. The default is:raycast.scattering_backend: optional scattering backend instance.memory_limit_bytes: optional limit for resident directional-response cache data.nothinguses the package default.
ArchimedLight.LightStepResult — Type
LightStepResultComplete result of one light simulation step, including the sky state, turtle, directional fluxes, first-order interception, optional scattering, and the integrated LightBudget. When requested, the result can also store a per-node sky_fraction map. Results returned by run_light_step and run_light_series also carry the render geometry needed by lightplot. By default they retain a shared LightNodeMetadata snapshot for scene-aware queries across dynamic scene updates.
ArchimedLight.MeteoSummary — Type
MeteoSummaryStructured meteo overview returned by summarize_meteo.
ArchimedLight.OpticalProperties — Type
OpticalProperties(par=0.0, nir=0.0)Per-waveband scattering coefficients for a component or emitter.
par and nir are the built-in ARCHIMED bands. Additional coefficients can be stored in extras.
For plant components, these coefficients are typically used as the scattered fraction in each waveband. Expected values are usually in [0, 1].
Typical values:
- leaves in PAR: often around
0.05-0.25 - leaves in NIR: often around
0.4-0.9 - emitters:
gammaoften usesPAR=0.48,NIR=0.52as independent spectral coefficients for the built-in bands; the values are not normalized
Examples:
OpticalProperties(0.15, 0.90)for a strongly NIR-scattering leafOpticalProperties(0.48, 0.52)for PAR/NIR emitter coefficients
ArchimedLight.RasterCPUBackend — Type
RasterCPUBackend()Reference interception backend based on CPU raster projection.
ArchimedLight.RaycastScatteringBackend — Type
RaycastScatteringBackend()Scattering backend that reconstructs transfer topology from directional ray-visibility stacks.
ArchimedLight.SceneSummary — Type
SceneSummaryStructured scene overview returned by summarize_scene.
ArchimedLight.SkyState — Type
SkyState(sun_azimuth_deg, sun_elevation_deg, ri_par_f, ri_nir_f, direct_fraction, diffuse_fraction)Radiative forcing state used to build the turtle and directional fluxes for one light step. When produced by compute_sky, its irradiance fields are effective means over the complete meteo interval, after applying radiation_input_semantics.
Arguments:
sun_azimuth_deg: sun azimuth in degrees on the horizontal plane. The package uses0°along+y,90°along+x,180°along-y, and270°along-x. If your scene uses the commonx=east,y=northconvention, this means0°=north,90°=east,180°=south,270°=west.sun_elevation_deg: sun elevation in degrees above the horizon. Typical daylight values are between5and80. Use90for a sun at zenith; in simple examples,89is often a good practical choice when you want a nearly vertical beam.ri_par_f: incident PAR irradiance inW m^-2on a horizontal plane. Typical daylight values are often in the100-600range. Clear midday conditions are often around300-500.ri_nir_f: incident NIR irradiance inW m^-2on a horizontal plane. Typical daylight values are often in the100-700range, commonly of the same order as or slightly larger than PAR.direct_fraction: fraction of the shortwave forcing treated as direct beam. Expected range is[0, 1]. Typical values are near0.8-1.0for clear-sky conditions, around0.3-0.7for mixed conditions, and0.0for a fully diffuse sky.diffuse_fraction: fraction of the shortwave forcing treated as diffuse sky radiation. Expected range is[0, 1]. In most use cases, it should satisfydirect_fraction + diffuse_fraction == 1.
This six-argument constructor stores ri_sw_f = ri_par_f + ri_nir_f automatically.
Examples:
- Nearly zenith, mostly direct forcing:
SkyState(180.0, 89.0, 350.0, 250.0, 0.95, 0.05) - Lower sun with mixed direct and diffuse light:
SkyState(135.0, 35.0, 200.0, 180.0, 0.5, 0.5) - Fully diffuse overcast step:
SkyState(180.0, 45.0, 120.0, 130.0, 0.0, 1.0)
ArchimedLight.TypeModel — Type
TypeModel(; interception=nothing, light_emitter=nothing, extras=...)Model definition for one component type inside a functional group.
This is the level that corresponds to one entry under the Type: block in a historical YAML model file.
Typical contents:
interception: how this component intercepts, transmits, and scatters lightlight_emitter: optional emission model for artificial sourcesextras: preserved non-light metadata from input files
Examples:
- a leaf type with only interception behavior
- a lamp type with only
light_emitter - a diagnostic sensor type with
interception=InterceptionModel(sensor=true, ...)
ArchimedLight.ValidationReport — Type
ValidationReport(errors, warnings, infos)Structured validation result returned by check_scene, check_models, check_meteo, and check_simulation.
ArchimedLight.attach_light_series! — Method
attach_light_series!(scene, steps; fields=[:incident_par_flux], names=Dict(), fill_value=NaN)Attach a time series of LightStepResult values to the scene MTG.
Arguments:
scene: MTG-backedPlantGeom.SceneGeometryto mutate.steps: ordered vector ofLightStepResultvalues to attach.
Keywords:
fields: budget or metadata selectors to attach.names: optional mapping from selectors infieldsto custom MTG attribute names.fill_value: value stored for geometry nodes absent from a selected step dictionary.
For each selected field, every geometry node receives a vector ordered like steps, which is convenient for downstream plotting or coupled simulations. For example, with the default field, each geometry node gets node[:Ri_PAR_f]::Vector{Float64} with one value per light step.
fields accepts the same selectors as attach_light_step!:
:area=>area:incident_par_initial_flux=>Ri_PAR_0_f:incident_nir_initial_flux=>Ri_NIR_0_f:incident_par_flux=>Ri_PAR_f:incident_nir_flux=>Ri_NIR_f:incident_par_initial_energy=>Ri_PAR_0_q:incident_nir_initial_energy=>Ri_NIR_0_q:incident_par_energy=>Ri_PAR_q:incident_nir_energy=>Ri_NIR_q:absorbed_par_initial_flux=>Ra_PAR_0_f:absorbed_nir_initial_flux=>Ra_NIR_0_f:absorbed_par_flux=>Ra_PAR_f:absorbed_nir_flux=>Ra_NIR_f:absorbed_par_initial_energy=>Ra_PAR_0_q:absorbed_nir_initial_energy=>Ra_NIR_0_q:absorbed_par_energy=>Ra_PAR_q:absorbed_nir_energy=>Ra_NIR_q:sky_fraction=>sky_fraction
For :area, series attachment stores the same area value repeated once per step so the result has the same vector shape as the light fields.
Use names to override attached attribute names. This is useful for downstream packages that expect different names:
attach_light_series!(
scene,
steps;
fields=[:area, :absorbed_par_flux, :absorbed_nir_flux, :sky_fraction],
names=Dict(:absorbed_nir_flux => :Ra_SW_f),
)fill_value is used for geometry nodes that are missing from a given step dictionary. The default is NaN, so missing values remain visible in the attached vectors.
sky_fraction is only available when each step was produced with LightOptions(include_sky_fraction=true), or from a config that requests sky_fraction: true in component_variables or opf_variables.
ArchimedLight.attach_light_step! — Method
attach_light_step!(scene, step; fields=[:incident_par_flux], names=Dict(), fill_value=nothing)Attach one LightStepResult back onto the scene MTG using ARCHIMED-style attribute names such as Ri_PAR_f and Ra_PAR_q.
Arguments:
scene: MTG-backedPlantGeom.SceneGeometryto mutate.step: oneLightStepResultwhose node-level values will be attached.
Keywords:
fields: budget or metadata selectors to attach.names: optional mapping from selectors infieldsto custom MTG attribute names.fill_value: value written for geometry nodes absent from a selected step dictionary.
fields selects which budget components to export. Each selected field is attached as one scalar MTG attribute per geometry node. Supported selectors are:
:incident_par_initial_flux=>Ri_PAR_0_f:incident_nir_initial_flux=>Ri_NIR_0_f:incident_par_flux=>Ri_PAR_f:incident_nir_flux=>Ri_NIR_f:incident_par_initial_energy=>Ri_PAR_0_q:incident_nir_initial_energy=>Ri_NIR_0_q:incident_par_energy=>Ri_PAR_q:incident_nir_energy=>Ri_NIR_q:absorbed_par_initial_flux=>Ra_PAR_0_f:absorbed_nir_initial_flux=>Ra_NIR_0_f:absorbed_par_flux=>Ra_PAR_f:absorbed_nir_flux=>Ra_NIR_f:absorbed_par_initial_energy=>Ra_PAR_0_q:absorbed_nir_initial_energy=>Ra_NIR_0_q:absorbed_par_energy=>Ra_PAR_q:absorbed_nir_energy=>Ra_NIR_q:sky_fraction=>sky_fraction:area=>area
Selector naming follows the budget hierarchy:
incidentmeans intercepted radiation, corresponding to historicalRiabsorbedmeans absorbed radiation, corresponding to historicalRainitialmeans first-order only, corresponding to historical_0_- no
initialmeans first-order plus scattering fluxmeansW m^-2, corresponding to historical_fenergymeansJper component and per step, corresponding to historical_qareameans the prepared object surface area inm^2
names is an optional dictionary that remaps those exported fields to custom MTG attribute names. For example:
attach_light_step!(
scene,
step;
fields=[:incident_par_flux, :absorbed_par_energy],
names=Dict(
:incident_par_flux => :my_par_flux,
:absorbed_par_energy => :my_par_energy,
),
)With that override, the values are attached on :my_par_flux and :my_par_energy instead of the default ARCHIMED names.
To expose the sky-view fraction or PlantBiophysics-specific names, you can mix selectors and overrides:
attach_light_step!(
scene,
step;
fields=[:area, :absorbed_par_flux, :absorbed_nir_flux, :sky_fraction],
names=Dict(:absorbed_nir_flux => :Ra_SW_f),
)sky_fraction is only available when the step was produced with LightOptions(include_sky_fraction=true), or from a config that requests sky_fraction: true in component_variables or opf_variables.
ArchimedLight.attach_node_values! — Method
attach_node_values!(scene, attr, values; fill_value=nothing)Attach a dictionary of per-node values to the MTG stored in scene.
Only geometry nodes present in the prepared scene are updated. Missing node ids receive fill_value.
Arguments:
scene: MTG-backedPlantGeom.SceneGeometryto mutate.attr: MTG attribute name to write on each geometry node.values: dictionary keyed by node id, containing values to attach.
Keywords:
fill_value: value written for geometry nodes absent fromvalues.
ArchimedLight.cache_summary — Method
cache_summary(sim)Return a named tuple summarizing the current radiation cache state for a LightSimulation.
Arguments:
sim: simulation whose prepared cache should be summarized. If no cache has been prepared yet, the summary reportsmode=:unprepared.
ArchimedLight.check_meteo — Method
check_meteo(meteo; options=LightOptions(), check_boundaries=options.check_meteo_boundaries)::ValidationReportValidate meteo rows for required solar geometry, radiation inputs, and timestep duration data.
Arguments:
meteo: a meteo row,PlantMeteo.TimeStepTable, or Tables.jl-compatible table.
Keywords:
options:LightOptionsused for checks that depend on runtime meteo handling.check_boundaries: check physical ranges for used meteo values. Missing, nonfinite, derivability, and conflicting-input checks are always performed.
ArchimedLight.check_models — Method
check_models(scene, models)::ValidationReportValidate that models cover the geometric group/type pairs present in scene.
Arguments:
scene:PlantGeom.SceneGeometrywhose geometric nodes define the required group/type pairs.models: model specification accepted byprepare_models.
ArchimedLight.check_scene — Method
check_scene(scene)::ValidationReportValidate basic scene readiness for light interception.
Arguments:
scene:PlantGeom.SceneGeometryto check for geometry nodes, faces, and a valid xy domain.
ArchimedLight.check_simulation — Method
check_simulation(sim)::ValidationReport
check_simulation(scene, meteo; models, options=LightOptions(), check_boundaries=options.check_meteo_boundaries)::ValidationReportValidate a reusable simulation or the separate inputs needed to build and run one.
Arguments:
sim:LightSimulationto validate.scene:PlantGeom.SceneGeometryto validate when checking separate inputs.meteo: meteo row or table to validate when checking separate inputs.
Keywords:
models: required model specification when checking separate inputs.options:LightOptionsused for meteo validation.check_boundaries: check physical ranges for used meteo values.
ArchimedLight.emitter — Method
emitter(; radiance, par=0.48, nir=0.52)Build a TypeModel for an emitting component.
Keywords:
radiance: Lambertian radiance per emitting area per steradian.par: unnormalized PAR spectral coefficient. The default is0.48.nir: unnormalized NIR spectral coefficient. The default is0.52.
ArchimedLight.light_face_values — Method
light_face_values(scene, models, options, data; color=:incident_par_flux, timestep=1, fill_value=NaN)
light_face_values(data; color=:incident_par_flux, timestep=1, fill_value=NaN)Return one scalar color value per rendered face for direct Makie mesh coloring.
Arguments:
geometry:LightRenderGeometrywhose faces receive values.scene: preparedPlantGeom.SceneGeometryused when deriving geometry from simulation inputs.models:LightModelsused when deriving geometry from simulation inputs.options:LightOptionsused when deriving geometry from simulation inputs.data: oneLightStepResult, a vector of results, a node-value dictionary, a vector of dictionaries, or explicit numeric color values.
Keywords:
color: metric selector, node-value dictionary, or explicit numeric color vector.timestep: one-based index used for series data.fill_value: value used for nodes/faces without finite data.
When data is a LightStepResult or a series of steps returned by run_light_step / run_light_series, the stored render geometry is used and no scene or model inputs are needed.
ArchimedLight.light_metric_values — Method
light_metric_values(scene_or_sim, step_or_series, metric; filters..., reduce=nothing, by=nothing, sink=nothing)Return a filtered, Tables.jl-compatible column table for one light metric. metric accepts package selectors such as :absorbed_par_energy and historical ARCHIMED names such as :Ra_PAR_q.
The node filters are the same as light_node_ids. Without reduce, the result contains step_number, scene and output node identifiers, group/type and MTG metadata, requested attribute columns, and value. A series is returned in long form with one-based step numbers.
With reduce=sum, a single step returns a scalar and a series returns one value per timestep. Pass by to obtain a grouped table instead; series grouping always retains step_number. sink optionally materializes table results with a Tables.jl-compatible sink such as DataFrames.DataFrame.
Summing component energy metrics is physically meaningful. Component fluxes are area-normalized, so summing them generally is not a scene-scale energy total.
ArchimedLight.light_metric_values — Method
light_metric_values(step, selector)
light_metric_values(steps, selector; timestep=1)Return the per-node metric map selected by selector.
Arguments:
step: oneLightStepResultto read.steps: vector ofLightStepResultvalues to index withtimestep.selector: metric selector symbol, either package-native or ARCHIMED-style.
Keywords:
timestep: one-based index used whenstepsis a series.
selector may be either a runtime budget field such as :incident_par_flux or the corresponding ARCHIMED attribute name such as :Ri_PAR_f.
ArchimedLight.light_node_ids — Method
light_node_ids(scene_or_sim; filters...)Return the sorted runtime node ids of geometric scene components matching all requested filters. Pass the returned ids back through node_ids= to reuse a selection across light metrics or timesteps.
Standard filters are node_ids, source_topology_id, group (or its alias species), object_id, symbol, scale, and type. Scalar filters use equality; collections use membership. attributes accepts a named tuple or dictionary of exact attribute matches. Arbitrary attributes are node-local unless inherit_attributes=true. The optional where predicate receives the corresponding MTG node.
group/species and object_id use inherited scene metadata, matching the way OPS object roots identify their descendant geometry.
ArchimedLight.light_render_geometry — Method
light_render_geometry(scene, models, options)
light_render_geometry(step)
light_render_geometry(steps)Return the render-ready geometry associated with a light simulation.
Arguments:
scene: preparedPlantGeom.SceneGeometryused when deriving geometry from simulation inputs.models:LightModelsused to apply solver-visible filtering.options:LightOptionsused to match the solver geometry.step: oneLightStepResultwhose stored render geometry is returned.steps: non-empty vector ofLightStepResultvalues. The first step supplies the geometry.
For a scene, this applies the same model-dependent filtering as the solver. For results returned by run_light_step or run_light_series, it returns the stored render geometry directly.
ArchimedLight.light_vertex_values — Method
light_vertex_values(scene, models, options, data; color=:incident_par_flux, timestep=1, fill_value=NaN)
light_vertex_values(data; color=:incident_par_flux, timestep=1, fill_value=NaN)Return one scalar color value per rendered vertex, obtained by averaging the values of adjacent faces.
Arguments:
geometry:LightRenderGeometrywhose vertices receive values.scene: preparedPlantGeom.SceneGeometryused when deriving geometry from simulation inputs.models:LightModelsused when deriving geometry from simulation inputs.options:LightOptionsused when deriving geometry from simulation inputs.data: oneLightStepResult, a vector of results, a node-value dictionary, a vector of dictionaries, or explicit numeric color values.
Keywords:
color: metric selector, node-value dictionary, or explicit numeric color vector.timestep: one-based index used for series data.fill_value: value used for nodes/vertices without finite data.
When data is a LightStepResult or a series of steps returned by run_light_step / run_light_series, the stored render geometry is used and no scene or model inputs are needed.
ArchimedLight.lightplot — Function
lightplotMakie plotting entry point provided by the Makie package extension. Load Makie or CairoMakie before calling it. The preferred API is lightplot(step; ...) or lightplot(steps; ...).
Arguments:
data: oneLightStepResultor a vector of results with stored render geometry.geometry: optionalLightRenderGeometrywhen plotting explicit geometry/data pairs.scene: preparedPlantGeom.SceneGeometryused when deriving geometry from simulation inputs.models:LightModelsused when deriving geometry from simulation inputs.options:LightOptionsused when deriving geometry from simulation inputs.
Keywords:
kwargs...: Makie plot attributes, including ArchimedLight-specificcolor,timestep,interpolate, andfill_value.
ArchimedLight.lightplot! — Function
lightplot!In-place Makie plotting entry point provided by the Makie package extension. Load Makie or CairoMakie before calling it. The preferred API is lightplot!(axis, step; ...) or lightplot!(axis, steps; ...).
Arguments:
axis: Makie axis or scene-like parent to plot into.data: oneLightStepResultor a vector of results with stored render geometry.geometry: optionalLightRenderGeometrywhen plotting explicit geometry/data pairs.scene: preparedPlantGeom.SceneGeometryused when deriving geometry from simulation inputs.models:LightModelsused when deriving geometry from simulation inputs.options:LightOptionsused when deriving geometry from simulation inputs.
Keywords:
kwargs...: Makie plot attributes, including ArchimedLight-specificcolor,timestep,interpolate, andfill_value.
ArchimedLight.models_for — Method
models_for(group_specs...)::LightModelsCreate LightModels from compact (group => (type => model, ...)) pairs. Group and type names are matched against geometric scene nodes.
Arguments:
group_specs...: one or more pairs where the left side is a scene group name and the right side is an iterable oftype => TypeModelpairs.
Example:
julia> models = models_for(
"coffee" => (
"Leaf" => translucent(par=0.15, nir=0.90),
"Stem" => translucent(par=0.20, nir=0.50),
),
"soil" => (
"ground" => translucent(par=0.10, nir=0.40),
),
);
julia> (collect(keys(models)), models["coffee"].types["Leaf"].interception.model)
(["coffee", "soil"], "Translucent")ArchimedLight.prepare_meteo — Method
prepare_meteo(meteo, options; check_boundaries=options.check_meteo_boundaries)::PlantMeteo.TimeStepTableReturn the effective meteo table after Java-like meteo controls are applied: sequence validation, optional meteo_range, and optional active filtering.
Arguments:
meteo: aPlantMeteo.TimeStepTableor Tables.jl-compatible table of meteo rows.options:LightOptionscontrolling overlap validation,meteo_range, and active-row filtering.
Keywords:
check_boundaries: check physical ranges for used meteo values. Missing, nonfinite, derivability, and conflicting-input checks always remain enabled.
ArchimedLight.prepare_models — Method
prepare_models(models)Normalize in-memory model definitions into a LightModels object.
Arguments:
models: an in-memory model specification.
Accepted inputs are an existing LightModels, a single GroupModel, a vector of groups, or an OrderedDict{String,GroupModel}.
ArchimedLight.read_meteo — Method
read_meteo(path)::PlantMeteo.TimeStepTable
read_meteo(data)::PlantMeteo.TimeStepTableRead a meteorological forcing table from path and return it as a PlantMeteo.TimeStepTable.
The resulting table keeps available metadata such as latitude, longitude, altitude, and source file path.
Arguments:
path: path to a meteorological forcing file readable by PlantMeteo.data: alternatively, a Tables.jl-compatible table or an existingPlantMeteo.TimeStepTable.
ArchimedLight.read_models — Method
read_models(path_or_paths)::LightModelsRead one or more ARCHIMED model YAML files and return them as a LightModels collection.
Arguments:
path_or_paths: a model source to read.
path_or_paths can be:
- the path to a single model YAML file containing a
Group - the path to a config YAML file containing a
models:list - a vector of explicit model-file paths
ArchimedLight.read_options — Method
read_options(path)::LightOptionsRead runtime light options from a config YAML file.
This parses the ARCHIMED configuration keys such as sky_sectors, pixel_size, toricity, scattering controls, and meteo-range options into a LightOptions instance.
Arguments:
path: path to an ARCHIMED-style configuration YAML file.
ArchimedLight.read_scene — Method
read_scene(path)::PlantGeom.SceneGeometryRead a scene file (.ops, .opf, or .gwa) and return a prepared PlantGeom.SceneGeometry.
The scene is relabelled into a dense node-id space and immediately converted to the merged-mesh representation expected by the interception pipeline.
Arguments:
path: path to an.ops,.opf, or.gwascene file.
Keywords:
plantgeom_backend: reserved PlantGeom backend selector. The current default is:auto.
ArchimedLight.read_simulation — Method
read_simulation(path; plot_paving_override=nothing, check_boundaries=nothing, kwargs...)Read a complete file-based light simulation and return (sim, meteo), where sim is a LightSimulation.
Arguments:
path: path to the ARCHIMED-style configuration YAML file.
Keywords:
plot_paving_override: optional replacement paving count used when materializing model-declared ground geometry.check_boundaries: optional boundary-validation policy applied while reading meteo and stored in the returned simulation. Derivability and conflict checks are always performed.kwargs...: keyword arguments forwarded toLightSimulation, such asinterception_backend,scattering_mode,scattering_backend, andmemory_limit_bytes.
This smoke example uses coarse, non-scattering options so it remains quick:
julia> repo_root = normpath(joinpath(dirname(pathof(ArchimedLight)), ".."));
julia> config = joinpath(repo_root, "example_2", "config.yml");
julia> sim, meteo = read_simulation(config; plot_paving_override=0);
julia> update_options!(
sim,
LightOptions(
sim.options;
turtle_sectors=1,
pixel_size=0.1,
area_ratio=false,
scattering=false,
toricity=false,
),
);
julia> step = run_light(sim, first(meteo));
julia> println(step)
LightStepResult(PAR=291.777 kJ, NIR=316.092 kJ, sky=463.139 W m^-2 PAR / 501.734 W m^-2 NIR, sectors=1 [sky=1, sun=0], scattering=off)ArchimedLight.run_light — Method
run_light(sim, skies::AbstractVector{<:SkyState}; step_duration_seconds)Run a series of already computed sky states. The step duration is required because sky states do not contain timing metadata.
step_duration_seconds may be either one positive duration shared by every state or a vector of positive durations with the same length as skies. The results are returned as a Vector{LightStepResult} in input order, while the simulation's prepared scene and radiation cache are reused across the series.
Examples
series = run_light(sim, skies; step_duration_seconds=1800.0)
series = run_light(sim, skies; step_duration_seconds=[900.0, 1800.0, 900.0])ArchimedLight.run_light — Method
run_light(sim, meteo_or_row; check_boundaries=sim.options.check_meteo_boundaries)Run one light step for a meteo row, or a full series for a meteo table.
Arguments:
sim:LightSimulationcontaining the scene, models, options, and lazy cache.meteo_or_row: either a single meteo row for one step, or aPlantMeteo.TimeStepTable/Tables.jl-compatible table for a series.
Keywords:
check_boundaries: check physical ranges for used meteo values. Derivability and conflicting-input checks are always performed.
ArchimedLight.run_light — Method
run_light(sim, sky::SkyState; step_duration_seconds)Run one light step from an already computed sky state. The step duration is required because there is no meteo row from which to infer it.
Arguments:
sim:LightSimulationcontaining the scene, models, options, and lazy cache.sky: precomputedSkyStateused for one light step.
Keywords:
step_duration_seconds: duration of the step in seconds. This is required for energy integration.
ArchimedLight.summarize_meteo — Method
summarize_meteo(meteo; options=LightOptions(), check_boundaries=options.check_meteo_boundaries)Return a MeteoSummary describing row count, columns, timestep duration, radiation inputs, and the detected solar-geometry path for a meteo table or row.
Arguments:
meteo: a meteo row,PlantMeteo.TimeStepTable, or Tables.jl-compatible table.
Keywords:
options:LightOptionsused for checks that depend on runtime meteo handling.check_boundaries: check physical ranges while resolving the summary.
ArchimedLight.summarize_scene — Method
summarize_scene(scene; models=nothing)Return a SceneSummary describing the prepared scene domain, geometric nodes, faces, group/type pairs, object ids, and missing model pairs.
Pass models to include a model coverage check in the summary.
Arguments:
scene:PlantGeom.SceneGeometryto summarize.
Keywords:
models: optional model specification used to report missing group/type coverage.
ArchimedLight.tile_light_geometry — Method
tile_light_geometry(scene, geometry; nx=1, ny=1, centered=true, xperiod=nothing, yperiod=nothing)
tile_light_geometry(scene, step; nx=1, ny=1, centered=true, xperiod=nothing, yperiod=nothing)
tile_light_geometry(scene, steps; nx=1, ny=1, centered=true, xperiod=nothing, yperiod=nothing)
tile_light_geometry(scene, models, options; nx=1, ny=1, centered=true, xperiod=nothing, yperiod=nothing)Repeat a render geometry nx times along x and ny times along y for visualizing toric or repeated scenes.
Arguments:
scene: preparedPlantGeom.SceneGeometryused to infer tile spacing when periods are not provided.geometry:LightRenderGeometryto repeat.step: oneLightStepResultwhose stored geometry is repeated.steps: non-empty vector ofLightStepResultvalues whose first step supplies the geometry.models:LightModelsused when deriving geometry from simulation inputs.options:LightOptionsused when deriving geometry from simulation inputs.
Keywords:
nx: number of repetitions along x.ny: number of repetitions along y.centered: center tile offsets around the original geometry whentrue.xperiod: optional explicit x tile period.yperiod: optional explicit y tile period.
By default, the tile period comes from the scene xy bounds, so the visual repetition matches the simulation plot box. Pass xperiod and yperiod explicitly to override that spacing.
ArchimedLight.translucent — Method
translucent(; par, nir, transparency=0.0)Build a TypeModel for an ordinary translucent component.
Keywords:
par: PAR scattering fraction for the component.nir: NIR scattering fraction for the component.transparency: intercepted-light transparency fraction. The default0.0makes the component opaque to interception.
par and nir are scattering fractions for the built-in ARCHIMED wavebands. The absorbed fraction is therefore 1 - scattering_fraction.
julia> model = translucent(par=0.15, nir=0.90, transparency=0.1);
julia> (model.interception.model, model.interception.transparency, model.interception.optical_properties.par)
("Translucent", 0.1, 0.15)ArchimedLight.update_models! — Method
update_models!(sim, new_models)Replace the model specification in sim and release all prepared cache data. The next run_light call prepares the new models lazily.
Arguments:
sim:LightSimulationto update in place.new_models: replacement model specification accepted byprepare_models.
ArchimedLight.update_options! — Method
update_options!(sim, new_options)Replace the runtime options in sim and release all prepared cache data. The next run_light call prepares data using the new options.
Arguments:
sim:LightSimulationto update in place.new_options: replacementLightOptions.
ArchimedLight.update_scene! — Method
update_scene!(sim, new_scene)Replace the scene and immediately release all prepared data tied to the old scene. The next run_light call prepares the new scene lazily.
Arguments:
sim:LightSimulationto update in place.new_scene: replacementPlantGeom.SceneGeometry.
ArchimedLight.virtual_sensor — Method
virtual_sensor()Build a TypeModel for virtual sensors. Virtual sensors receive light diagnostics while remaining transparent in interception and scattering logic.
Arguments: none.
ArchimedLight.write_component_values — Method
write_component_values(path::AbstractString, sim::LightSimulation, series; step_index_base::Integer=1)Write an ARCHIMED-style component_values.csv file from already-computed LightStepResult values.
series may be a single LightStepResult or a collection of them. The function serializes the supplied results only; it does not run the simulation. Step numbers are 1-based by default. Use step_index_base=0 only for historical harness compatibility.
Arguments:
path: destination CSV file path.sim:LightSimulationthat supplies scene, model, and option context for component rows.series: oneLightStepResultor a collection of results to serialize.
Keywords:
step_index_base: first step number written to the CSV. The default is1.
ArchimedLight.write_scene — Method
write_scene(path, scene)Write an MTG-backed PlantGeom.SceneGeometry to path.
Supported output formats are .ops, .opf, and .gwa. The function refreshes the reference-mesh registry and normalizes topology ids before export.
Arguments:
path: output path ending in.ops,.opf, or.gwa.scene: MTG-backedPlantGeom.SceneGeometryto write.