Metadata-Version: 2.4
Name: lwbgt
Version: 1.1.0
Summary: Reference-compatible Liljegren outdoor wet bulb globe temperature (WBGT) kernel with C/FFI, Python, and R APIs
Keywords: wet bulb globe temperature,WBGT,Liljegren,heat stress,occupational heat stress,meteorology,biometeorology,scientific computing,FFI
Author: Yifei Zheng
License-Expression: Apache-2.0 AND LicenseRef-UChicago-Argonne-WBGT-1.1
License-File: LICENSE
License-File: NOTICE
License-File: src/LicenseRef-UChicago-Argonne-WBGT-1.1.txt
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: C
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
Project-URL: Homepage, https://github.com/zyf0717/lwbgt
Project-URL: Documentation, https://github.com/zyf0717/lwbgt/blob/main/docs/README.md
Project-URL: Source, https://github.com/zyf0717/lwbgt
Project-URL: Issues, https://github.com/zyf0717/lwbgt/issues
Project-URL: Changelog, https://github.com/zyf0717/lwbgt/blob/main/CHANGELOG.md
Project-URL: Citation, https://github.com/zyf0717/lwbgt/blob/main/CITATION.cff
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# lwbgt

[![PyPI](https://img.shields.io/pypi/v/lwbgt.svg)](https://pypi.org/project/lwbgt/)
[![CRAN](https://img.shields.io/cran/v/lwbgt.svg)](https://cran.r-project.org/web/packages/lwbgt/index.html)
[![R-universe](https://zyf0717.r-universe.dev/lwbgt/badges/version)](https://zyf0717.r-universe.dev/lwbgt)

[![Native CI](https://github.com/zyf0717/lwbgt/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/zyf0717/lwbgt/actions/workflows/ci.yml)
[![Wheel CI](https://github.com/zyf0717/lwbgt/actions/workflows/wheels.yml/badge.svg?branch=main)](https://github.com/zyf0717/lwbgt/actions/workflows/wheels.yml)
[![R package CI](https://github.com/zyf0717/lwbgt/actions/workflows/r.yml/badge.svg?branch=main)](https://github.com/zyf0717/lwbgt/actions/workflows/r.yml)

`lwbgt` computes outdoor wet bulb globe temperature (WBGT) using the original
Argonne Liljegren C calculation. One optimized C kernel serves the C/FFI,
Python, R, Julia, and SwiftPM interfaces.

## Compatibility and performance

**Version: v1.1.0.** Reference comparisons reproduce WBGT and its component
temperatures bit for bit under matched compiler and floating-point settings.
The v1 calculation remains the default throughout 1.x; future numerical
revisions will use explicit versioned APIs while preserving v1. See the
[compatibility policy](https://github.com/zyf0717/lwbgt/blob/main/docs/COMPATIBILITY.md)
for the scope, documented corrections, and platform limits.

The kernel reuses intermediate results and avoids redundant work, preserving
the original numerical precision. Our
[scalar benchmark](https://github.com/zyf0717/lwbgt/blob/main/benchmarks/README.md)
measures about **1.6× the original throughput** on one CPU. Performance depends
on the compiler, hardware, and inputs.

## Input assumptions

When some inputs are unavailable, use explicit, recorded assumptions. The
library does not fill in defaults automatically.

| Field | Suggested assumption |
|---|---|
| `pressure_hpa` | Prefer an estimate from site elevation. `1013.25` hPa is a sea-level screening assumption. |
| `wind_height_m` | Use `10` only when the source specifies wind measured at 10 m; otherwise use instrument metadata. |
| `vertical_temperature_difference_c` | `1` assumes a nighttime inversion. Only negative versus nonnegative matters. |
| `urban` | Use `0` for rural or `1` for urban. If unknown, calculate both and retain the higher WBGT for screening. |
| `averaging_minutes` | Use the source averaging interval; `0` is appropriate only for instantaneous or already centered observations. |

Air temperature, humidity, wind speed, and daytime solar radiation have no
general fallback. See the
[input guide](https://github.com/zyf0717/lwbgt/blob/main/docs/INPUTS.md) for units,
timestamp conventions, and when these assumptions affect the calculation.

## Python

```sh
python -m pip install lwbgt
```

```python
from lwbgt import Input, calculate, calculate_batch, esat

weather = Input(
    year=2024, month=4, day=15, hour=14, minute=30,
    gmt_offset_hours=8, averaging_minutes=60, urban=1,
    latitude_deg_north=1.3521, longitude_deg_east=103.8198,
    solar_w_m2=742.0, pressure_hpa=1008.4,
    air_temperature_c=32.1, relative_humidity_percent=68.0,
    wind_speed_m_s=2.8, wind_height_m=10.0,
    vertical_temperature_difference_c=1,
)

result = calculate(weather)
assert result.status == 0
print(result.wbgt_c)

results = calculate_batch([weather, weather])
print(esat(273.15, phase=0))
```

`Input` and `Result` are immutable typed records. Field names, units, status
codes, and failure behaviour are defined by the
[ABI contract](https://github.com/zyf0717/lwbgt/blob/main/docs/ABI.md). See the
[input assumptions](https://github.com/zyf0717/lwbgt/blob/main/docs/INPUTS.md)
before substituting unavailable observations.

## R

Install from CRAN:

```r
install.packages("lwbgt")
```

If CRAN is unavailable, use R-universe:

```r
install.packages("lwbgt", repos = "https://zyf0717.r-universe.dev")
```

```r
library(lwbgt)

weather <- lwbgt_input(
    year = 2024, month = 4, day = 15, hour = 14, minute = 30,
    gmt_offset_hours = 8, averaging_minutes = 60, urban = 1,
    latitude_deg_north = 1.3521, longitude_deg_east = 103.8198,
    solar_w_m2 = 742.0, pressure_hpa = 1008.4,
    air_temperature_c = 32.1, relative_humidity_percent = 68.0,
    wind_speed_m_s = 2.8, wind_height_m = 10.0,
    vertical_temperature_difference_c = 1
)

result <- calculate(weather)
stopifnot(result$status == 0)
print(result$wbgt_c)
print(esat(273.15, phase = 0))
```

The R API provides `lwbgt_input()`, `calculate()`, and `esat()`. It returns
ordinary data frames, recycles scalar constructor arguments, and isolates
invalid or non-convergent rows. See the
[R quick start](https://github.com/zyf0717/lwbgt/blob/main/r/README.md).

## Julia

`LWBGT` lives in this repository's `julia/` subdirectory and exposes `Input`,
`Result`, `calculate`, `calculate_batch`, and `esat` through the native v1 ABI.
Julia ≥1.10 is supported. The first binary-artifact release and General
registration are pending; see the [Julia guide](julia/README.md) for development
installation and usage. Published releases will install the native library
automatically, without a compiler or a separate JLL package.

## SwiftPM

Add `CLWBGT` as a target dependency in `Package.swift`:

```swift
// swift-tools-version: 5.9
import PackageDescription

let package = Package(
    name: "WeatherService",
    dependencies: [
        .package(url: "https://github.com/zyf0717/lwbgt.git", from: "1.0.0"),
    ],
    targets: [
        .executableTarget(
            name: "WeatherService",
            dependencies: [
                .product(name: "CLWBGT", package: "lwbgt"),
            ]
        ),
    ]
)
```

In `Sources/WeatherService/main.swift`:

```swift
import CLWBGT

var weather = lwbgt_input_v1(
    year: 2024, month: 4, day: 15, hour: 14, minute: 30,
    gmt_offset_hours: 8, averaging_minutes: 60, urban: 1,
    latitude_deg_north: 1.3521, longitude_deg_east: 103.8198,
    solar_w_m2: 742.0, pressure_hpa: 1008.4,
    air_temperature_c: 32.1, relative_humidity_percent: 68.0,
    wind_speed_m_s: 2.8, wind_height_m: 10.0,
    vertical_temperature_difference_c: 1
)
var result = lwbgt_output_v1()
let status = lwbgt_calc_batch_v1(&weather, &result, 1)
precondition(status == Int32(LWBGT_BATCH_OK))
precondition(result.status == 0)
print(result.wbgt_c)
print(esat(273.15, 0))
```

`CLWBGT` exposes the C structs and functions directly. Check both the call's
return code and the result's status. SwiftPM builds the canonical C sources;
downstream consumption is tested on Linux and macOS in release mode.

## Native C

```sh
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
ctest --test-dir build --output-on-failure
cmake --install build --prefix /desired/prefix
```

The install provides static and shared libraries, `lwbgt.h`, CMake package
metadata, and `pkg-config` metadata. CMake consumers can select
`lwbgt::static` or `lwbgt::shared` after `find_package(lwbgt CONFIG REQUIRED)`.
GCC, Clang/AppleClang, and MinGW GCC are supported. MSVC is available for
[experimental compatibility testing](docs/ABI.md#platforms-and-bindings)
with `-DLWBGT_EXPERIMENTAL_MSVC=ON`.

## Documentation

| Topic | Document |
|---|---|
| Inputs, units, layouts, status codes, and concurrency | [ABI contract](https://github.com/zyf0717/lwbgt/blob/main/docs/ABI.md) |
| Numerical compatibility and measured performance | [Compatibility and performance](https://github.com/zyf0717/lwbgt/blob/main/docs/COMPATIBILITY.md) |
| Scope and common integration questions | [FAQ](https://github.com/zyf0717/lwbgt/blob/main/docs/FAQ.md) |
| Package selection | [lwbgt vs pywbgt vs thermofeel](https://github.com/zyf0717/lwbgt/blob/main/docs/COMPARISON.md) |
| Source lineage | [Upstream provenance](https://github.com/zyf0717/lwbgt/blob/main/docs/UPSTREAM.md) |
| Source changes | [Deviations from original Liljegren C](https://github.com/zyf0717/lwbgt/blob/main/docs/DEVIATIONS.md) |
| Release history | [Changelog](https://github.com/zyf0717/lwbgt/blob/main/CHANGELOG.md) |
| Release procedure | [Maintainer guide](https://github.com/zyf0717/lwbgt/blob/main/docs/RELEASING.md) |
