This release brings the component library up to the current ATC-138 fragility set, raises the safety class assigned to the third damage state of gravity shear tabs, and corrects defects in the red-tag and fire-suppression logic. The applied methodology changes alter simulated recovery times; the Methodology entries below state the scope of each. The packaging configuration is committed, so the published package can be rebuilt from the repository, and releases now go to PyPI automatically.
Methodology
-
Gravity shear tab damage state 3 raised to Safety Class 3. The third damage state of the bolted shear tab gravity connections, matched by the pattern
B1031\.00\w+and coveringB1031.001in the packaged component table, now maps to safety class 3 instead of safety class 2 indamage_state_attribute_mapping.csv.Why: the damage state is described as "complete separation of shear tab, close to complete loss of vertical load resistance", which matches the safety class 3 definition of severe damage that compromises both the lateral and the vertical load carrying capacity of the component. The proposal for the change cites the experimental work behind the FEMA P-58 fragility, which consistently reports complete fracture of the tab at the median drift assigned to this damage state, which implies a significant loss of vertical load carrying capacity (Deierlein and Victorsson 2008, FEMA P-58/BD-3.8.3; Liu and Astaneh-Asl 2000, Journal of Structural Engineering 126(1), 32-39). The same mapping was applied during development of the 2026 NEHRP Seismic Provisions Appendix A, where the component was used in its updated state to prequalify several lateral force-resisting systems (Pham et al. 2026, Functional Recovery Design Parameters for Five Additional Seismic Force-Resisting Systems in the 2026 NEHRP Recommended Provisions, Earthquake Spectra, in review).
Scope: safety class filters are cumulative, since
red_tag.pyselects every component at or above the class being evaluated, so this damage state now counts toward the safety class 3 tally as well as the classes below it. The share of the shear tab population that has to be damaged before the system trips a red tag therefore falls from 25% to 10%, and the inspection trigger, set at half the red tag thresholds, falls from 12.5% to 5%. The change author's assessment is that the upgrade occurs at a drift demand that would generally already trigger red-tagging through other global consequences such as residual drift, so a large shift in outcomes is not expected. -
Component library updated to the current ATC-138 fragility set. 326 entries were retired from
component_attributes.csvand 42 were added, with 16 new rows indamage_state_attribute_mapping.csvcovering the added components.Why: The retired entries are product-specific component attributes for proprietary systems that are not included in the official ATC-138 methodology. The added component and damage state attributes reflect new functional recovery damage state attributes added by the ATC-138 project to extend the fault trees to better cover generic steel buckling-restrained braces and load bearing vs non-load bearing RC shear walls.
Scope: a model that references a retired fragility id now prints
Warning: skipping components with missing component attributes: <ids>and leaves those components out of the assessment. The run completes and does not fail, so recovery times will be shorter than they were at v1.3. Check the run log if you have v1.3 results to compare. Anyone who holds the supporting data for a retired component can restore it by placing an editedcomponent_attributes.csvin the model directory, which overrides the packaged table; see "Customizing Static Tables" in the README.
NOTE - This project only performs the functional recovery assessment on damage simulated by an external engine. Therefore, no fragility information (e.g., damage state fragility medians) is represented in thecomponent_attributes.csvanddamage_state_attribute_mapping.csv. These data sets only contain the component-specific functional consequence and repair information needed to carry out the functional performance and repair scheduling performed as part of the ATC-138 methodology.
Added
- Damage consequences in the recovery output. The recovery output file now carries the damage consequences alongside the functionality results, as additional top-level keys:
red_tag,red_tag_impact,inspection_trigger,repair_cost_ratio_total,repair_cost_ratio_engineering,simulated_replacement_time, and the door-racking counts. At v1.3 these were computed and then discarded. Existing keys are unchanged, so a consumer that reads the file today keeps working. - Custom output file name.
run_analysis()takes anoutput_fileargument and the CLI exposes it as--output_file. The default remainsrecovery_outputs.json. - Duplicate-input validation on the Pelicun path.
convert_pelicun()now stops with an explicit message when the damage or loss tables contain duplicate location-direction-damage-state rows distinguished by auidsuffix. Previously the duplicates were carried through silently. - Two more reference models in the test suite. The suite grew from two archetypes to four, adding a one-story reinforced concrete shear wall model and a twelve-story reinforced concrete moment frame, each with a 20-run reference set. The test itself runs each model once with a fixed seed and compares it against that reference; the pass criteria are in
tests/compare_runs.py. - Automated PyPI publishing. Publishing a GitHub Release builds the wheel and sdist, verifies that the release tag and the version in
pyproject.tomlagree, checks the package metadata, and uploads to PyPI through Trusted Publishing after a maintainer approves the deployment. No API token is stored in the repository. The README's "Releases" section describes the flow. - An MIT
LICENSEfile and aCITATION.cff. The citation file declarescff-version1.2.0 andtype: software, and both DOI fields carry a bare DOI as the schema requires. The software DOI is now the Zenodo concept DOI,10.5281/zenodo.20045327, which resolves to the newest release. A citation generated from this file therefore points at the current release; the v1.3 file named that one version specifically.
Changed
- Output serialization. Recovery outputs are converted from NumPy types with a recursive routine that handles arbitrary nesting depth and descends into lists and tuples, replacing hand-written loops that stopped at five dictionary levels and descended only into dictionaries. All four reference models still match their references. The new routine also converts NumPy scalar types that the old loops passed through untouched.
- Reference comparison for the two new models. The one-story shear wall and twelve-story moment frame models are compared against seeded Python runs; their MATLAB reference output was removed. The two original archetypes keep their MATLAB comparison, so parity with the MATLAB implementation is still covered by the suite, on those two models.
- High-level comparison tolerance. The high-level metric now passes when the relative difference is within 4% or the absolute difference is within 2 days; before, only the relative check applied.
tests/detailed_inspection_guide.mdwas renamed totests/README.md. - README. Import examples updated for installed-package usage, a stale testing link corrected, and new pointers to the changelog and to the release process.
- Packaging. The build backend is now hatchling, and the wheel and sdist exclude cache and Finder metadata files. License metadata is declared as the SPDX expression
MITtogether withlicense-files, matching theLICENSEfile the repository carries; the published 1.3.0 package declared no license. The project URLs now properly point at the OpenPBEE repository. - Version numbering. The version in
pyproject.tomlandCITATION.cffnow uses two segments,1.4, so it matches thev1.4tag exactly.
Fixed
-
Red-tag evaluation failed on components with an alternate structural system. A component's primary and alternate structural system identifiers were added together instead of being collected into one set, so a component assigned to structural system 5 with 6 as its alternate contributed a phantom system 11 to the list of systems to evaluate. No component matches system 11, so the tool raised
ValueError: zero-size array to reduction operation fmax which has no identity. The next entry's empty-series guard is the other half of this defect.Scope: models containing any of the six components that carry a non-zero alternate structural system, namely the steel column base plates (
B1031.011a-c) and the welded column splices (B1031.021a-c), each assigned to structural system 5 with 6 as the alternate, and with red-tag calculation enabled, which is the default. Such a model produced no results at all at v1.3, so there are no wrong numbers to re-check, only runs that could not complete. Components with no alternate system were unaffected. -
Non-numeric replacement times could fail the red-tag and recovery-metric calculations.
simulated_replacement_timeis now coerced to a numeric type before it reaches the red-tag logic, the recovery-metric extraction and the repair-schedule helpers. The red-tag path also gained guards for a structural series that matched no components and for division by a zero component count; that case is now treated as not tagged.Scope: runs whose replacement time reached these functions as a non-numeric value, and red-tag runs with an empty structural series. Both previously raised or produced
NaN. -
Fire suppression recovery read the wrong quantity. The building-wide fire suppression branch read a dictionary key that does not exist, and a second call passed an array where NumPy expected an axis, which raises a
TypeError. Neither path produced a wrong number; both stopped the run.Scope: runs with the fire watch option disabled and fire sprinkler components present. The fire watch option is enabled by default, so a default run never reached this code.
-
Component list built from named columns instead of positions. The input builder identified the metadata columns of
comp_population.csvby position, so a file whosestoryanddircolumns sat elsewhere produced a corrupted component list. The component list is now built by matching those names. The column-filtering step further down still assumes the metadata columns come first, so such a file is not yet handled end to end. -
np.row_stackreplaced withnp.vstack. The two are aliases, so results are unchanged; the former is deprecated in current NumPy. -
Recovery trajectory plots. Line styles and draw order were adjusted so overlapping trajectories stay legible.
Removed
requirements.txt. Every dependency it listed is declared inpyproject.toml, which has been the single source of truth since v1.3. Install withpip install -e .orpip install atc138.