Load and validate an OED exposure

Run this tutorial yourself

This page is a Jupyter notebook, executed when the docs are built. Download load-validate-oed.ipynb

Set up an environment and open it in Jupyter:

python -m venv venv && source venv/bin/activate
pip install oasislmf jupyterlab matplotlib
jupyter lab load-validate-oed.ipynb

The example data ships in the ODS_Tools repository (under docs/source/tutorials/); tutorials that run a model need that model’s data and the loss engine — follow the prerequisites described on this page.

ods_tools reads OED (Open Exposure Data) files into typed pandas DataFrames and validates them against the OED standard. This notebook loads a location file, runs validation, catches an issue, fixes it, and re-validates.

Note

Executable notebook — the cells below run the ods_tools library at docs-build time (fast, no model run), so the outputs always reflect the current code and OED schema.

import warnings; warnings.filterwarnings("ignore")
from pathlib import Path
import ods_tools.oed as oed

_c = [Path("data/oed"), Path("tutorials/data/oed"), Path("docs/source/tutorials/data/oed")]
DATA = next((c for c in _c if c.exists()), None)
assert DATA is not None, "OED example data not found"
LOCATION = DATA / "SourceLocOEDPiWind10Currency.csv"

Load an OED location file

OedExposure loads each OED source (location, account, reinsurance) into a typed DataFrame — column data types follow the OED specification.

exposure = oed.OedExposure(location=str(LOCATION))
loc = exposure.location.dataframe
print(f"{loc.shape[0]} locations, {loc.shape[1]} columns")
loc[["PortNumber", "AccNumber", "LocNumber", "CountryCode",
     "OccupancyCode", "ConstructionCode", "BuildingTIV"]].head()
10 locations, 25 columns
PortNumber AccNumber LocNumber CountryCode OccupancyCode ConstructionCode BuildingTIV
0 1 A11111 10002082046 GB 1050 5000 220000.0
1 1 A11111 10002082047 GB 1050 5000 790000.0
2 1 A11111 10002082048 GB 1050 5000 160000.0
3 1 A11111 10002082049 GB 1050 5000 30000.0
4 1 A11111 10002082050 GB 1050 5000 250000.0

Validate against the OED standard

ods_tools ships the OED validation rules (required/conditional fields, valid code lists, peril codes, …). We run them in return mode so the findings come back as data instead of raising:

from ods_tools.oed.common import DEFAULT_VALIDATION_CONFIG

return_config = [{**check, "on_error": "return"} for check in DEFAULT_VALIDATION_CONFIG]
findings = exposure.check(return_config)
print(f"{len(findings)} validation finding(s)")
for f in findings:
    print(f"- [{f['name']}] {f['msg'].splitlines()[0]}")
1 validation finding(s)
- [location] Conditionally required column missing.

This example file is missing a conditionally required column: OED requires a peril to be specified (LocPeril) when perils-related terms are present.

Fix and re-validate

Add the missing peril (PiWind is a windstorm model, peril WW1) and re-run validation:

exposure.location.dataframe["LocPeril"] = "WW1"
findings = exposure.check(return_config)
print(f"{len(findings)} validation finding(s) after fix")
0 validation finding(s) after fix

Enforcing validation

Passing check_oed=True (or on_error='raise' in the config) makes ods_tools raise on the first failing check instead of returning — this is what the CLI does:

ods_tools check --location SourceLocOEDPiWind10Currency.csv

Where next

  • ODTF — transform other exposure formats (e.g. AIR CEDE) into OED.

  • Currency conversion — convert a multi-currency exposure to a reporting currency.

  • The OED field definitions and code lists (the standard) are single-sourced in the ODS_OpenExposureData repository.