Metadata-Version: 2.4
Name: urbirrad
Version: 0.1.1
Summary: Annual solar-radiation calculations on sensor meshes
License: MIT License
        
        Copyright (c) 2026 urbirrad contributors
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Classifier: License :: OSI Approved :: MIT License
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: THIRD_PARTY_NOTICES.md
Requires-Dist: numpy>=2.0
Requires-Dist: pandas>=2.2
Requires-Dist: h5py>=3.11
Requires-Dist: pyradiance>=1.3
Requires-Dist: pyvista>=0.46
Requires-Dist: PyYAML>=6.0
Requires-Dist: tqdm>=4.66
Provides-Extra: test
Requires-Dist: pytest>=8; extra == "test"
Dynamic: license-file

<p align="center">
  <img src="https://arep-dev.gitlab.io/urbirrad/assets/urbirrad-logo-horizontal.png" width="520"
       alt="UrbIrrad — solar irradiance calculation">
</p>

<p align="center">
  <a href="https://gitlab.com/arep-dev/urbirrad/-/releases"><img src="https://gitlab.com/arep-dev/urbirrad/-/badges/release.svg" alt="Latest release"></a>
  <a href="https://gitlab.com/arep-dev/urbirrad/-/blob/main/pyproject.toml"><img src="https://img.shields.io/badge/Python-3.12%2B-0a6b88" alt="Python 3.12 or newer"></a>
  <a href="https://gitlab.com/arep-dev/urbirrad/-/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-008160" alt="License: MIT"></a>
  <a href="https://gitlab.com/arep-dev/urbirrad/-/blob/main/roadmap.md"><img src="https://img.shields.io/badge/Status-active%20development-fbdb12" alt="Status: active development"></a>
</p>

# UrbIrrad

Source code: [arep-dev/urbirrad on GitLab](https://gitlab.com/arep-dev/urbirrad).

Documentation: [UrbIrrad user guide](https://arep-dev.gitlab.io/urbirrad/).

_Have you wrestled with [Radiance](https://www.radiance-online.org/) command-line options, or explored [Honeybee](https://www.ladybug.tools/honeybee-radiance/docs/),
and wished for a focused way to calculate solar exposure in a building or urban scene?_

**UrbIrrad** offers a `Python`/`YAML` workflow:

* Provide geometry and weather,
* Choose the radiation components,
* Run a case.

You do not need to assemble the Radiance command pipeline yourself. It is a standalone tool.

UrbIrrad calculates solar irradiance on a triangular sensor mesh using
[Radiance](https://www.radiance-online.org/) through
[PyRadiance](https://lbnl-eta.github.io/pyradiance/).

**The default example calculates only the direct beam on one
upward-facing plane, without reflections.** Diffuse sky, six receiving
directions and reflected direct sunlight are optional additions described below.
It stores the time series in a compressed `HDF5`
file and creates an `XDMF` companion file for visualization in ParaView.

**Not just outdoors.** 

The "Urb" in UrbIrrad reflects its urban-study context,
not a restriction to exterior sensors. Calculate direct and diffuse solar
irradiance outdoors (streets, courtyards, public spaces), indoors through
modelled openings and glazing, or in open and semi-open spaces such as
covered walkways, terraces and atria. The same workflow applies: where you
place the sensors and which geometry you model determine the exposure.
There is no separate indoor/outdoor switch.

The included Montauban case evaluates sensors **inside the modelled building**,
with surrounding urban geometry providing the wider shading context. It is
an indoor solar-exposure example in an urban setting, not just an outdoor
sunlight map. Interior walls, openings and glazing must be represented
appropriately; the tool reports solar irradiance, not illuminance in lux or
an artificial-lighting calculation.

For diffuse sky and reflected sunlight, reusable scene-to-sky matrices avoid
repeating the full ray trace for each weather interval. The direct beam uses
a separate batch of exact solar positions. See
[how Radiance calculations work](https://arep-dev.gitlab.io/urbirrad/radiance-workflow/) for the engines,
matrix method and caching limits.

Coordinates use **X = East, Y = North, Z = Up**, geometry is expressed in
metres, and irradiance results are expressed in `W/m²`.

**Mesh inputs:** 

`STL`, `VTP`, `VTK`, `OBJ` and `PLY` are supported for both scene
surfaces and sensor meshes. Inputs must be triangular surfaces, not volume
meshes or point clouds. No automatic triangulation/repair is performed;
solar material properties remain in the YAML, not file colors or textures.
See [surface-mesh formats](https://arep-dev.gitlab.io/urbirrad/configuration/#surface-mesh-formats).

**Scope: shortwave solar radiation only.** UrbIrrad will not calculate
longwave thermal radiation or overall mean radiant temperature (MRT).
A future post-processing option may estimate the shortwave solar contribution
to MRT; any complete MRT calculation belongs in an external comfort workflow.

## Development status

UrbIrrad is under active development. Configuration, APIs and result formats
may evolve as new options are developed and validated. See the
[roadmap](https://gitlab.com/arep-dev/urbirrad/-/blob/main/roadmap.md) for completed milestones, next priorities and proposals.

## Installation

### Install a released version from PyPI

Python 3.12 or newer is required. With
[Miniforge](https://github.com/conda-forge/miniforge) or another Conda distribution:

```powershell
conda create -n rad python=3.12 -y
conda activate rad
python -m pip install urbirrad
```

If you already have a suitable Python environment, just run
`python -m pip install urbirrad`. Git is not required to install the package.

The package does not include the example geometry or weather files. To run
the included example, install [Git](https://git-scm.com/) and download the repository:

```powershell
git clone https://gitlab.com/arep-dev/urbirrad.git
cd urbirrad
```

Alternatively, download and extract the repository archive from GitLab.

### Install from source for development

To work on the code rather than use a released version:

```powershell
git clone https://gitlab.com/arep-dev/urbirrad.git
cd urbirrad
conda create -n rad python=3.12 -y
conda activate rad
python -m pip install -e .
```

PyRadiance provides the Radiance executables needed on Windows; no separate
Radiance installation is required for the included example.

Official resources:

- Radiance: [website](https://www.radiance-online.org/) and
  [source code](https://github.com/LBNL-ETA/Radiance).
- PyRadiance: [documentation](https://lbnl-eta.github.io/pyradiance/) and
  [source code](https://github.com/LBNL-ETA/pyradiance).

## Run the included example

The [Montauban example](https://gitlab.com/arep-dev/urbirrad/-/blob/main/examples/template_case/README.md) contains weather,
a triangular sensor surface, two wall families, two glazing families, ground
and surrounding urban geometry. It covers **1–15 July** by default.

From the repository root:

```powershell
conda activate rad
python -m urbirrad.cli check examples/template_case/case.yaml
python -m urbirrad.cli run examples/template_case/case.yaml --nproc 4
```

The default calculates **direct irradiance only on an upward-facing horizontal
plane, without surface reflections**. Sensors are placed at triangle centers
with a 0.05 m upward offset; triangle normals do not define their orientation.
The terminal shows progress and stage timings.

<p align="center">
  <img src="https://arep-dev.gitlab.io/urbirrad/assets/montauban-site-overview.png" width="720"
       alt="Montauban example site and surrounding geometry">
</p>

Choose a separate YAML to increase complexity without extra mode arguments:

| YAML in `examples/template_case/` | Calculation | Result folder |
| --- | --- | --- |
| `case.yaml` | Direct only, one horizontal plane | `results/` |
| `case_01_diffuse.yaml` | Direct + original diffuse sky, Radiance `-ab 3` | `results/01_diffuse/` |
| `case_02_six_directions.yaml` | Direct + diffuse sky in six directions | `results/02_six_directions/` |
| `case_03_reflected_direct.yaml` | Also add diffuse reflections of direct sunlight, six directions | `results/03_reflected_direct/` |

Six directions are intended especially for thermal-comfort studies, bringing
solar outputs closer to six-direction MRT measurement/modelling approaches.
**They are not an overall MRT calculation.** Future body weighting and optical
properties may support a shortwave solar contribution to MRT only; longwave
radiation remains outside UrbIrrad's scope. Purely specular solar reflections
are not included in the reflected-direct component.
See [methods and limitations](https://arep-dev.gitlab.io/urbirrad/methods/#option-2-calculate-diffuse-sky-in-six-directions).

For a finer sky representation, set `simulation.sky_subdivision: 2` in the
YAML. The default remains MF=1. This affects diffuse sky and reflected direct,
not the exact direct beam; caches are separated by resolution. See
[sky subdivision](https://arep-dev.gitlab.io/urbirrad/configuration/#sky-subdivision-mf) before comparing
accuracy and cost.

Each run saves `annual_solar.h5` and its `annual_solar.xmf` companion. Open
the XMF in ParaView 6.1 with **XDMF Reader**, not Xdmf3 Reader or Xdmf3 Reader T,
click **Apply**, and color by `solar_direct` for the default case.

To clean generated outputs and rerun, preserving caches:

```powershell
python -m urbirrad.cli clean examples/template_case/case.yaml
python -m urbirrad.cli run examples/template_case/case.yaml --nproc 4
```

Alternatively, use `run --force` to overwrite results. Configure dates,
components, geometry and materials in the YAML. See the
[getting-started guide](https://arep-dev.gitlab.io/urbirrad/getting-started/) for copying and adapting a case.

## Documentation

### Potential sunshine, without weather irradiance

And while we're at it: Radiance may feel a little overkill for a simple shadow
count, but you can also get **potential sunshine hours on your sensor plane**,
using the geometry you've already prepared.

A separate geometric mode counts **potential direct-sun exposure hours**:
opaque obstacles cast shadows, glazing is removed, and clouds/DNI/DHI are
ignored. It does not calculate W/m². Run the dedicated example:

```powershell
python -m urbirrad.cli run examples/template_case/case_potential_sunshine.yaml --nproc 4
```

Set `simulation.timestep_minutes` to `60` (default) or `30` in that YAML.
Open `results/potential_sunshine_static/potential_sunshine.xmf` with
**XDMF Reader** and color by `sunshine_hours`. See the
[potential-sunshine guide](https://arep-dev.gitlab.io/urbirrad/potential-sunshine/) for sampling conventions
and limitations. This is one static field on the mesh,
without timesteps. To add the same static information to a direct-irradiance
run, set `output.save_sunshine_hours: true`; `annual_sunshine.xmf` then opens
the cumulative field stored alongside irradiance in `annual_solar.h5`.

### User guides

For glazing data, a separate utility can prepare `solar_transmittance` from
a manufacturer value or, when unavailable, an explicit EnergyPlus-based
Ug/g estimate. It supports glazing alone or a complete glazing + film assembly;
TL is optional information, not an input to the solar correlation. It does
not modify cases or run simulations. See
[glazing solar properties](https://arep-dev.gitlab.io/urbirrad/glazing-properties/) for equations and limits.

```bash
python -m urbirrad.glazing --ug 1.0 --g 0.35 --tl 0.70
```

Read the [online documentation](https://arep-dev.gitlab.io/urbirrad/), or browse
the [Markdown documentation](https://gitlab.com/arep-dev/urbirrad/-/blob/main/docs/index.md) directly in GitLab. The site is
built with MkDocs and the Read the Docs theme.

- [Getting started](https://arep-dev.gitlab.io/urbirrad/getting-started/): installation, example, case adaptation.
- [YAML configuration](https://arep-dev.gitlab.io/urbirrad/configuration/): supported keys and actual defaults.
- [Methods and limitations](https://arep-dev.gitlab.io/urbirrad/methods/): direct, diffuse, directions and reflections.
- [How Radiance calculations work](https://arep-dev.gitlab.io/urbirrad/radiance-workflow/): ray tracing, commands, matrices and reuse.
- [Potential sunshine hours](https://arep-dev.gitlab.io/urbirrad/potential-sunshine/): geometric exposure duration, no weather intensity.
- [Results and ParaView](https://arep-dev.gitlab.io/urbirrad/results/): files, fields, caching and troubleshooting.
- [Python API essentials](https://arep-dev.gitlab.io/urbirrad/python-api/): run, load, select directions and export.
- [HDF5 reference](https://arep-dev.gitlab.io/urbirrad/HDF5_SCHEMA/): dataset layout and schema compatibility.
- [Documentation maintenance](https://arep-dev.gitlab.io/urbirrad/documentation/): MkDocs preview/build and GitLab Pages publishing.

To preview the documentation in your browser:

```powershell
python -m pip install -r requirements-docs.txt
python -m mkdocs serve
```

The GitLab CI/CD configuration builds the documentation strictly and publishes
it to GitLab Pages from the default branch. See
[publication instructions](https://arep-dev.gitlab.io/urbirrad/documentation/#gitlab-pages-publication)
for GitLab settings and how to find the deployed URL.

## Developer tests

Tests are optional for normal use:

```powershell
python -m pip install -e ".[test]"
python -m pytest -q
```

## License

This project is distributed under the [MIT License](https://gitlab.com/arep-dev/urbirrad/-/blob/main/LICENSE).
Dependencies retain their own licenses; see [third-party notices](https://gitlab.com/arep-dev/urbirrad/-/blob/main/THIRD_PARTY_NOTICES.md).

## Repository layout

```text
urbirrad/                 Python package
tests/                    automated tests
examples/template_case/   runnable example and copyable project structure
docs/                     user guides, reference, validation and image assets
mkdocs.yml                documentation navigation and build configuration
.gitlab-ci.yml            documentation checks and GitLab Pages deployment
requirements-docs.txt     optional documentation builder
roadmap.md                development priorities and future proposals
```
