A header-only C++ library to build, convert, and validate avalanche hazard assessments across international standards.
Hazard provides type-safe, programmatic access to avalanche hazard assessments in C++. It uses C++20 concepts and phantom types to prevent schema mixing at compile time while maintaining the performance of raw integer representations. This enables developers to build tools that work with hazard data—from analysis pipelines to automated forecasting systems—while catching errors before runtime.
The library supports both North American (CMAH) and European (EAWS) standards, allowing code to work generically across geographies or convert between them.
- C++ developers building avalanche forecasting or analysis tools
- Avalanche forecasters who want to automate parts of their workflow
- Snow science researchers analyzing hazard assessment data programmatically
- Type-safe schemas - C++20 concepts prevent accidentally mixing CMAH and EAWS standards
- Fluent builder API - Expressive, chainable methods for constructing assessments
- Cross-geographic support - Work with US, Canadian, and European standards
- Bidirectional conversion - Lossless conversion between CMAH and EAWS (≤3 problems)
- Compile-time validation - Catch schema mismatches and invalid operations at compile time
- Building automated avalanche forecasting systems
- Analyzing historical assessment data across different regions
- Creating tools for avalanche educators and trainers
- Implementing danger matrix calculators
- Developing cross-border avalanche information sharing systems
#include <iostream>
#include <ak/hazard/hazard.hpp>
using namespace ak::hazard;
int main() {
// Create a CMAH assessment with Considerable danger
Assessment<CMAH> assessment(CMAH::DangerLevel::Considerable);
// Add a storm slab problem on north-facing alpine slopes
Problem<CMAH> storm_slab(ProblemType::StormSlab);
storm_slab.on(Aspect::N | Aspect::NE | Aspect::E)
.at(ElevationBand::Upper)
.with_likelihood(CMAH::LikelihoodLevel::VeryLikely)
.with_size(CMAH::SizeLevel::Large, CMAH::SizeLevel::VeryLarge);
assessment.add_problem(storm_slab);
// Query the assessment
std::cout << "Danger: " << assessment.overall_danger().name() << "\n";
std::cout << "Problems: " << assessment.problem_count() << "\n";
// Iterate over problems
for (const auto& problem : assessment) {
std::cout << " - " << problem_name(problem.type()) << "\n";
}
// Convert to EAWS schema
auto eaws_assessment = convert::assessment<EAWS>(assessment);
return 0;
}Build problems with chainable method calls:
using namespace ak::hazard;
// Create a wind slab problem with fluent API
auto wind_problem = Problem<CMAH>(ProblemType::WindSlab)
.on(Aspect::N | Aspect::NE | Aspect::NW)
.at(ElevationBand::Upper)
.with_likelihood(CMAH::LikelihoodLevel::Likely)
.with_size(CMAH::SizeLevel::Medium, CMAH::SizeLevel::Large);
// Build assessment with danger rating
Assessment<CMAH> forecast(CMAH::DangerLevel::Considerable);
forecast.with_confidence(CMAH::ConfidenceLevel::High);
forecast.add_problem(wind_problem);Phantom types enforce schema compatibility at compile time:
Assessment<CMAH> cmah_assessment;
Assessment<EAWS> eaws_assessment;
// Compiler prevents schema mixing
// cmah_assessment = eaws_assessment; // ❌ Type error: incompatible schemas
// Explicit conversion is type-safe and lossless (≤3 problems)
cmah_assessment = convert::assessment<CMAH>(eaws_assessment); // ✅Danger matrix lookups and validation work in constant expressions:
// Compute danger rating at compile time
constexpr auto rating = DangerMatrix<CMAH>::lookup(
/* likelihood = */ 4, // Very Likely
/* size = */ 3 // Large
);
static_assert(rating.as_int() == 4); // Verifies High danger at compile time