hazus-loss
基于 HAZUS 6.1 的单次地震逐层条件期望损失评估程序。结构和非结构构件均逐层计算,之后叠加金额与伤亡期望人数;不进行蒙特卡洛模拟。
安装与示例
从 PyPI 安装(1.0.0 发布后可用;Python 3.10 及以上):
pip install hazus-loss==1.0.0
发行包名为 hazus-loss,Python 导入名为 hazus_loss。从源码开发和运行示例:
uv sync --group dev
uv run python -X utf8 examples/single_event.py
uv run pytest -q
uv run python -X utf8 main.py 运行相同示例。示例会打印重置成本与损失,生成 output/single_event.html 网页报告。示例费用均为调用脚本给定的演示数值,正式计算时应替换为项目数据。-X utf8 避免 Windows 重定向输出时的中文编码差异。
在脚本中给定费用并计算
所有费用由调用者明确给定,不读取用途费用预设。整栋建筑重置成本通过 BuildingInput.replacement_cost 一次性传入,需在调用 evaluate_loss 前计算好。程序不根据面积、单位价或支撑价格推算重置成本,仅按成本权重分摊到各层。每层内容物价值也由调用者明确给定。
from hazus_loss import (
BuildingInput, CasualtyUnitCosts, CollapseFragility, DemolitionFragility, EconomicParameters,
FloorInput, evaluate_loss, print_loss_summary,
)
# 以下是演示费用,正式使用时替换为项目数据。
economics = EconomicParameters(
rent_per_m2_day=0.5,
disruption_cost_per_m2=2.0,
owner_occupied_fraction=0.6,
income_per_m2_day=3.0,
recapture_fraction=0.2,
occupants_per_m2=0.1,
casualty_unit_costs=CasualtyUnitCosts(
severity_2=100.0, severity_3=1000.0, severity_4=10000.0,
),
)
areas_m2 = [1200, 1200, 1000, 800]
peak_drifts = [0.008, 0.012, 0.010, 0.006]
accelerations_g = [0.35, 0.45, 0.60, 0.75]
# 重置成本在调用程序之前计算。可按自己的计价方式包含结构、非结构及支撑。
unit_cost = 2000.0
brace_costs = [50000, 50000, 50000, 50000]
building_replacement_cost = sum(area * unit_cost + brace
for area, brace in zip(areas_m2, brace_costs, strict=True))
contents_values = [600000, 600000, 500000, 400000]
floors = [
FloorInput(
area_m2=area,
peak_drift=drift, peak_floor_acceleration_g=acceleration,
contents_value=contents,
)
for area, drift, acceleration, contents in zip(
areas_m2, peak_drifts, accelerations_g,
contents_values, strict=True,
)
]
building = BuildingInput(
structural_type="S2M", design_level="high", occupancy="COM4",
floors=floors, max_residual_drift=0.004,
demolition_fragility=DemolitionFragility(median_residual_drift=0.005, beta=0.3),
collapse_fragility=CollapseFragility(median_peak_drift=0.05, beta=0.4),
economics=economics,
replacement_cost=building_replacement_cost,
# 不传则各层成本权重相同。可选:
# floor_cost_weights=[0.3, 0.3, 0.2, 0.2],
)
# 不传 output_path 时,只计算并返回结果,不创建文件。
result = evaluate_loss(building, output_path="output/building_report.html")
print_loss_summary(result)
print(result.replacement_cost) # 调用者传入的整栋重置成本
snapshot = result.to_dict()
输入单位为:位移角小数(0.01 表示 1%)、峰值绝对楼面加速度 g、面积 m²、租金与收入为金额/(m²·日)、人员密度为人/m²。beta 是自然对数空间标准差。楼层从底层向顶层排列,每层记录对应其顶部楼面的绝对加速度。
FloorInput.economics 可覆盖该层费用与人员参数;occupants 可直接给该层人数,否则按面积与明确给定的人员密度计算。所有金额由调用者在输入前统一计价单位与价格基础,程序不接收币种、价格年份或费用来源说明,也不进行换算。楼层按输入顺序自动标识为 1F、2F 等,无需填写名称。费用参数不依赖 COM4,对数据库支持的其他用途也使用同一输入方式。
COM4 是建筑用途,只用于查询损失比例、恢复时间等 HAZUS 参数。结构类型(例如 S2M)和设计等级必须另行提供。
楼层成本占比权重
默认每层权重均为 1 / 楼层数,与面积无关。可在 BuildingInput 中传入 floor_cost_weights,例如四层建筑使用 [0.3, 0.3, 0.2, 0.2]。权重按楼层输入顺序排列,必须与楼层数量一致,每项为有限非负数,合计为 1(浮点容差 1e-10);不符合要求时报错,不自动将任意权重归一化。
每层计损用的重置成本为“整栋重置成本 × 该层权重”,分摊金额之和保持整栋输入总额。结果中的 floor.cost_weight 与 floor.replacement_cost 分别为实际权重及分摊金额。该权重只用于分摊建筑重置成本,不修改楼层面积、内容物价值、人数或其他明确给定的费用。
网页报告与打印输出
evaluate_loss(building, output_path=...) 的 output_path 为可选参数:
- 传入
.html或.htm文件路径时写入该文件;父目录自动创建。 - 传入目录(包括尚不存在且没有扩展名的路径)时生成其中的
index.html。 - 不传或传
None时不生成文件。
返回结果的 report_path 为报告绝对路径。报告是独立 UTF-8 HTML 文件,内嵌图表和样式,不依赖联网或额外图片文件,包含:
- 建筑总重置成本、期望损失及损失/重置成本比例。
- 八类损失金额和占比条形图,以及各楼层的损失分类对比图。
- 建筑用途、结构分类、设计等级、地震响应、楼层成本权重、分摊重置成本与内容物价值。
- 各层实际使用的费用、人员及易损性参数。
- 损伤、倒塌、拆除、伤亡结果及完整可核查的 JSON 快照。
print_loss_summary(result) 显式打印整栋重置成本和各层分摊金额、八类损失、合计、伤亡期望人数和报告路径。计算函数本身不隐式打印。已有结果也可通过 write_html_report(result, "output/another.html") 单独输出报告。
结果字段
| 字段 | 含义 |
|---|---|
result.replacement_cost |
调用者直接输入的整栋重置成本 |
result.contents_value |
各层输入内容物价值之和 |
result.losses.structural_repair |
三种整栋分支加权后的结构损失 |
result.losses.nonstructural_drift_repair |
位移敏感非结构损失 |
result.losses.nonstructural_acceleration_repair |
加速度敏感非结构损失 |
result.losses.contents |
内容物损失 |
result.losses.relocation |
搬迁费用 |
result.losses.income |
营业收入损失 |
result.losses.rental |
租金收入损失 |
result.losses.casualties |
严重度 2/3/4 的伤亡货币损失 |
result.losses.total |
上述八项之和 |
result.losses.direct |
结构、两类非结构及内容物损失之和 |
result.floors 仅包含“整栋未倒塌且未拆除”分支的逐层计算:conditional_losses 为给定该分支时的条件损失,losses 为乘以整栋分支概率后的贡献;不再有楼层倒塌或拆除概率。result.casualties 是三种整栋分支加权后的分级人数与金额。to_dict() 包含输入快照、实际参数及 HAZUS 来源,可直接 JSON 序列化。
整栋倒塌、拆除与逐层计算
CollapseFragility(median_peak_drift=..., beta=...) 必须由用户提供。中值为小数位移角,beta 是自然对数标准差。倒塌需求取所有楼层 peak_drift 的最大值,不取平均、不按楼层独立判定,也不再使用 HAZUS 完全损伤条件倒塌比例。
三个互斥的整栋分支为:
Pc = collapse_probability(max(peak_drifts), collapse_fragility)。q = demolition_probability(max_residual_drift, demolition_fragility),表示未倒塌条件下的拆除概率。- 整栋拆除概率
Pd = (1-Pc)*q。 - 未倒塌且未拆除概率
Pr = (1-Pc)*(1-q);Pc + Pd + Pr = 1。
只有 Pr > 0 时才进行 HAZUS 逐层损伤与损失计算,所有楼层使用相同的 Pr。若 Pr == 0,跳过逐层易损性查询和计算,楼层 damage、conditional_losses 为 None,楼层 losses 为零。
整栋总损失为 Pc*L_collapse + Pd*L_demolition + Pr*sum(L_floor_given_no_event),不会将倒塌/拆除损失重复计入各层。
整栋倒塌和拆除分支采用建筑完全重置损失,结构与两类非结构完全损伤比例之和为 1;内容物损失采用 HAZUS 完全损伤比例(50%),间接损失采用完全损伤恢复时间。倒塌伤亡按全楼人员和倒塌伤亡率计算;拆除分支不新增伤亡。无倒塌、无拆除分支中的结构完全损伤伤亡率使用“未倒塌完全损伤”一列,不再二次划分倒塌。
结果通过 result.events 返回整栋概率,通过 result.branches['collapse'/'demolition'/'repair'] 返回各分支的条件损失、加权贡献与伤亡。网页及终端将整栋事件概率和逐层贡献分开显示。
HAZUS 参数查询
from hazus_loss import HazusDatabase
db = HazusDatabase()
print(db.list_structural_types())
print(db.list_occupancies())
print(db.list_design_levels())
print(db.get_fragility("S2M", "high", "structural").to_dict())
print(db.get_consequence("COM4", "recovery_days").to_dict())
# db.get_collapse("S2M") 仅查询历史 HAZUS 表值,当前评估不使用该比例。
数据库包含一般建筑模型的 36 种结构、33 种用途、六个等级:severe、very_high、high、moderate、low、pre,共 648 组易损性。高度分类按整栋层数选择(例如 S2L 为1–3层、S2M 为4–7层、S2H 为8层及以上),不会将每层都改为低层类型。原表不适用组合保留并在计算时拒绝使用,可通过 get_fragility(..., allow_unavailable=True) 审查原始记录。
易损性采用 HAZUS 表中总对数标准差。不同损伤状态的曲线可能在尾部交叉:负概率不超过 1e-12 时进行数值修正并写入该层诊断,实质性交叉抛出 FragilityCrossingError。其他输入与查询错误分别为 InputValidationError、ParameterLookupError、UnsupportedCombinationError,均继承 HazusLossError。
数据审查与维护
可审查的 CSV/JSON、原始行、来源 SHA-256 与勘误同 SQLite 一并分发。运行时不依赖 dev 文件夹或原始 PDF。
- 易损性:HAZUS 表 5-17 至 5-34,非结构位移阈值见表 5-23。
- 损失与时间:表 11-2 至 11-5、11-7 至 11-9;搬迁排除规则见 §11.2.5。
- 伤亡与条件倒塌:表 12-3 至 12-8。
从数据重建 SQLite:
uv run python tools/build_database.py
维护数据时从对应版本手册重新提取:
uv sync --group data
uv run --group data python tools/extract_hazus_tables.py "dev/fema_hazus-earthquake-model-technical-manual-6-1.pdf"
uv run python tools/build_database.py
uv run pytest -q
提取器针对本次提供的477页 July 2024修订手册;维护时应审查 CSV 与勘误差异。公式与边界详见 计算方法,独立手算例见 数值核验。
与旧项目比较
使用当前四层示例的相同响应和费用,对比另一个项目的原始计算类:
uv run --group comparison python -X utf8 tools/compare_projects.py --legacy-project "F:/Projects/HAZUS-loss-assessment"
旧项目保持只读。输出位于 output/project_comparison/:comparison.md 提供逐项金额、参数与公式差异、顺序差额分解及代码定位;metrics.csv 和 results.json 保存可复核数值;current_building.html 为当前项目的完整网页结果。比较保留双方各自易损性参数,并另行统一参数核验计算公式;旧项目缺少的指标标为“未实现”。
Python 版本兼容性
第三方库最低支持 Python 3.10,由 pyproject.toml 的 requires-python = ">=3.10" 声明。计算、数据库查询和离线报告只使用 Python 标准库,不需要安装 NumPy、SciPy、pandas 或 matplotlib。旧项目对比工具单独使用 comparison 依赖组,不影响第三方库用户安装。
最低版本依据包括 Python 3.10 引入的 zip(strict=True)、itertools.pairwise 和 dataclass(kw_only=True)。如需继续兼容 Python 3.9 或更旧版本,必须先替换这些接口并重新测试,不能只修改版本声明。Ruff 的目标版本同步设为 py310。
已在 Windows 的 Python 3.10、3.11、3.12、3.13 和 3.14 上分别运行现有完整测试,每个版本均为 81 项通过,覆盖计算、数据库、报告及输入校验。测试直接加载源码,没有执行项目打包或发布。复核某个版本时可运行下面的 PowerShell 命令,并替换 --python 后的版本号:
$env:PYTHONPATH = (Join-Path $PWD "src")
uv run --isolated --no-project --python 3.10 --with "pytest>=8.4" python -m pytest -q
.python-version 保留为 3.14,仅指定本项目默认的开发解释器;发布脚本同样使用 Python 3.14 构建。生成的是纯 Python 的 py3-none-any wheel,用户安装时受 requires-python 约束,不需要与构建时使用相同的 Python 小版本。发布校验工具使用 Python 3.11 才提供的 tomllib,由脚本通过 Python 3.14 运行,不属于第三方库的运行模块。
双击打包并发布到 PyPI
双击项目根目录的 publish_pypi.bat。脚本固定发布 hazus-loss 1.0.0 到正式 PyPI;它会构建、校验并上传,不需要先激活虚拟环境。首次运行需要联网下载构建工具。
- 只使用 PATH 中支持
build/publish的 uv:uv build通过 Hatchling 生成 wheel 和源码包,uv publish上传到 PyPI。uv 可按需下载构建所用的 Python 3.14;找不到可用 uv 时直接停止并提示。 - 每次在
dist/release-1.0.0-随机数-随机数/中生成新文件,不删除原有产物,只上传本次的hazus_loss-1.0.0-py3-none-any.whl和hazus_loss-1.0.0.tar.gz。 - 发布前检查包名和版本、锁文件版本及 Python 范围、数据库完整性,以及两个归档内的 Python 模块、SQLite、CSV/JSON 和
py.typed;通过uv tool run执行twine check --strict检查 PyPI 描述和元数据,twine 仅用于校验。任一步失败即停止,窗口会保留错误信息。
先在 PyPI 准备账号并开启双重验证,在 API tokens 创建有相应发布权限的 token。首次创建项目可使用账号级 token,项目创建后可改用项目级 token。出现认证提示时,用户名填写 __token__,密码处粘贴完整的 pypi-... token(输入不回显)。也可预先设置 UV_PUBLISH_TOKEN;不要将 token 写入脚本、源码或提交到版本库。
将 PyPI token 保存到 Windows 环境变量
uv publish 原生读取 UV_PUBLISH_TOKEN,无需在批处理中手动展开 token 或添加 --token 参数。脚本只提示是否检测到该变量,不打印 token 内容。
为了后续双击发布时自动认证,可设置当前用户的永久环境变量:按 Win + R,输入 sysdm.cpl,选择“高级 → 环境变量”,在“用户变量”中新建 UV_PUBLISH_TOKEN,值填写完整的 pypi-... token。保存后,新启动的程序读取新变量;已打开的终端需要关闭重开。如果双击脚本仍提示未检测到变量,可注销并重新登录 Windows 后再运行。环境变量以明文保存,只在自己的受信任电脑上配置,不要截图或共享其值。
也可以在 PowerShell 中执行以下配置命令;token 在隐藏输入提示中粘贴,不会成为命令历史的一部分。这些命令仅保存配置,不执行打包或上传:
$secret = Read-Host "请输入完整的 PyPI API token" -AsSecureString
$token = [System.Net.NetworkCredential]::new("", $secret).Password
[Environment]::SetEnvironmentVariable("UV_PUBLISH_TOKEN", $token, "User")
$env:UV_PUBLISH_TOKEN = $token
Remove-Variable secret, token
这同时设置永久用户变量和当前 PowerShell 的环境变量。若稍后从该 PowerShell 启动 publish_pypi.bat,会立即继承变量;资源管理器中双击启动时,须确保资源管理器已取得更新后的环境。发布时无需另外设置用户名或密码变量。
只检查是否配置成功、不显示 token 内容:
if ($env:UV_PUBLISH_TOKEN) { "当前窗口已配置 token" } else { "当前窗口未配置 token" }
PyPI 上的 hazus-loss 名称必须可用,或属于有权发布的账号;已有同名项目且无权限时不能发布。同一版本的文件不能覆盖。若上传中途失败,请先查看 PyPI 上该版本的文件状态再处理;脚本不会忽略上传失败。脚本只做发布所需的归档与元数据检查,不自动运行计算测试;维护者可在发布前自行运行上文的测试命令。
Metadata
Release files for hazus-loss 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| hazus_loss-1.0.0.tar.gz | 178.4 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hazus_loss-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 278.7 kB
Release files / hazus_loss-1.0.0.tar.gz
| Download URL | hazus_loss-1.0.0.tar.gz |
|---|---|
| Size | 178.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2b5dde7439a98cc980525c8a22cdde9d3e2526765cb74aa16cd4bc262b7ba26f
|
|
BLAKE2b-256 checksum How to use checksums |
ec9a643b37a279e14256c09aa630e116e6bd73358e149234ce16275d26a7a563
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / hazus_loss-1.0.0-py3-none-any.whl
| Download URL | hazus_loss-1.0.0-py3-none-any.whl |
|---|---|
| Size | 100.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4731da623125add7e2837ab98be3e64e231358f116cd23379710d5eb3a1a57f5
|
|
BLAKE2b-256 checksum How to use checksums |
54e78d43fb64a6c453c2e709caaa5df1c4d7682666e04597f53b4285059c0334
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for hazus-loss 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.