VertiStratInsights Main website ↗

How to Use the Process-Safety Design Toolkit: A Complete Walkthrough, Command by Command

Thursday, November 05, 2026

Install it, learn the habits that keep a screening result honest, then work through every command with a real output and what to do with it, from a relief valve to a full quantitative risk study.

Engineering Tools · Process Safety · User Guide

How to Use the Process-Safety Design Toolkit: A Complete Walkthrough, Command by Command

Skip to article content
Text Size

Revised · v1.4.0 · what changed

35Command-line commands, from relief valves to a full risk study
173Automated tests that pass on the current branch
0Dependencies to install (Python standard library only)
7JSON study tools: bow-tie, SIL, fire and gas, thermal runaway, ATEX, RAM, PHA

This is the long version of the guide. It installs the toolkit, explains the few habits that keep a screening result honest, and then goes through the commands by job: relief and venting, fire and explosion, functional safety, regulation, electrical, and the quantitative risk study. Every output below was produced by running the command on 5 November 2026 with illustrative inputs. An asset-specific walk-through of an LPG terminal, with every result, is in section 16.

Try it in the browser first. A clickable design demo, Process Safety Studio, walks through five tasks in the same five steps the command line uses: choose a task, enter inputs with units, run, read the result with its notes and limits, and export. The tasks are a gas relief valve sized to API 520, OSHA PSM applicability, LNG terminal basics, PSM revalidation due dates and fire-and-gas detector coverage. Its results are outputs captured from the command line, not live calculations, so use it to see the workflow and install the toolkit to run your own numbers.

It is a screen, not a safety case. Most of the governing standards are paywalled and were not read. Equations are derived from first principles where possible and tested against the standards’ own constants, and every remaining coefficient is flagged in the module’s docstring. A qualified engineer owns any result, and validated software should decide real designs.
Updated 10 November 2026. This guide now includes the LPG-terminal worked example as section 16. It was previously a separate post, “Screen an LPG Terminal Before the Workshop, and See the Dense-Gas Gap It Cannot Close”, which has been retired; its results, the dense-gas warning and its table of matching consultancy projects are all here now.

1. Install and orient

git clone https://github.com/herrrickshaw/process-safety-design-toolkit
cd process-safety-design-toolkit
git checkout feature/ifluids-service-map   # until the two open pull requests merge
python3 -m unittest discover tests         # 173 tests should pass
python3 -m process_safety coverage         # every topic, its standards, and what is NOT implemented
pip install -e .                           # optional: lets you run it from any folder

Run coverage first and read the lines that say “not implemented”. If you skip the install step and run from another folder, Python answers No module named process_safety; either install it with pip install -e . or run the commands from the repository folder.

2. Six habits that keep a screen honest

  1. Know which numbers are yours. Latent heat, set pressure, fill rate, failure frequencies and acceptance criteria are inputs. The toolkit will not invent them, and a diesel specific fuel consumption has no default for that reason.
  2. Check units on the command line. They are in each command’s help: --p0 and --set-g are kPa, blowdown --hole-d is metres, --wall-mm is millimetres.
  3. Read the note and warnings fields. They carry the limits of the result, such as the neutral-plume warning in plume.
  4. Trust the refusals. The toolkit declines to answer outside a method’s range instead of returning a number (examples below).
  5. Sample before you scale. For the risk study, run --sample first.
  6. Verify against the standard you are held to. The module docstring names it; coverage says whether its text was read.

Here are two refusals, both real outputs. The arc-flash command only answers for open-air three-phase cases, and says so for enclosed equipment; the worst-case toxic release tells you when the neutral-plume model is outside its validity.

$ python3 -m process_safety arc-flash --kv 0.48 --ka 20 --t 0.2 --dist-mm 455 --enclosed
{
  "applicability": {
    "ok": false,
    "why": "enclosed three-phase equipment (switchgear, MCC, panels): use IEEE 1584"
  }
}
$ python3 -m process_safety rmp-worst chlorine --kg 1200
  "release_rate_kg_s": 2.0,
  "beyond_model_range": true,
  "warning": "neutral-gas Gaussian screening is outside its validity at 1.5 m/s F-stability ..."

3. Relief and venting

The workflow is a chain. Work out the load for the scenario, then size the valve for that load. Here is a fire on a horizontal vessel (2.5 m by 8 m, liquid level 1.5 m, latent heat 330 kJ/kg), then the relief rate fed straight into the gas valve calculation for propane at 400 K and a 1,000 kPag set pressure.

$ python3 -m process_safety relief-fire --D 2.5 --L 8 --level 1.5 --latent 330
  wetted_area_m2:   43.9
  heat_input_kW:    960.6
  relief_rate_kg_h: 10,480

$ python3 -m process_safety relief-gas --W 10480 --T 400 --set-g 1000 --case fire --M 44 --k 1.13 --Z 0.9
  required_area_mm2: 935.8
  orifice:           K   (API 526 letter)
  regime:            critical

The note on the fire result is a reminder that the fire relieving pressure is 1.21 times the set pressure plus atmospheric. The area is the minimum; pick the next API 526 orifice up.

TaskCommand (shortened)Key outputs (illustrative inputs)Read it like this
Steam valverelief-steam --W 5000 --set-g 1500Area 557.8 mm², orifice J, regime napierNote says saturated steam is assumed
Liquid valverelief-liquid --Q 50 --rho 700 --set-g 1000 --back-g 100Area 399.7 mm², orifice H, Re 548,689Re shows the viscosity correction is near 1
Atmospheric tank, normal ventingtank-normal --volume 5000 --fill 500 --empty 400 --volatileOutbreathing 1,797 Nm³/h, inbreathing 1,163 Nm³/hAPI 2000 5th edition; the notes flag cases that need engineering review
Atmospheric tank, firetank-fire --shape vertical --D 40 --L 16 --F bare --normal-capacity 1500Wetted area 1,149 m², emergency venting 19,897 Nm³/h, extra 18,397 beyond the normal ventsExtra vent capacity is what you must add
Vapour-filled vessel in a firevapour-fire --volume 15 --area 36 --D 2 --wall-mm 20 --M 20 --k 1.3 --p0-g 1000 --psv-area 500 --psv-set-g 1500Rupture at 701 s, relief starts 319 s, peak 1,502 kPag, protected: falseThe note says a valve alone is not enough: the wall weakens, so add depressuring or fire protection
Depressuringdepressure --volume 30 --p0 5000 --pt 1000 --T0 300 --M 20 --k 1.3 --area 800301 s isothermal, 255 s adiabatic, minimum gas temperature 207 KTwo bounds; the temperature is a screen for minimum design metal temperature, not metal temperature
Blowdown through a holeblowdown --volume 20 --p0 2000 --T0 300 --M 20 --k 1.3 --hole-d 0.025Initial rate 1.58 kg/s, 288 of 321 kg released in the 600 s windowPressure in kPa absolute, hole diameter in metres

4. Fire, explosion and dispersion

These give you distances to harm levels so you can place people and equipment. All are screening models.

TaskCommand (shortened)Key outputs (illustrative inputs)Read it like this
Pool firepool-fire --area 300 --hc 44000 --hv 350 --cp 2.2 --tb 400Pool diameter 19.5 m, flame height 30.9 m, heat release 1,012 MW, 37.5 kW/m² at 17.3 m, 12.5 at 37.0 mPoint-source distances; wind tilt and spreading are not modelled
BLEVE fireballfireball --mass 20000 --hc 46Diameter 157 m, duration 12.2 s, 37.5 kW/m² at 196 m, 4.0 at 663 mRadiation only; blast and fragments are not covered
Flare radiationflare --mass 20 --lhv 46 --mw 30 --flame-length 40Heat release 920 MW, 4.73 kW/m² at about 63.8 mIt warns when a distance is under two flame lengths: the point-source result is unreliable there
Gas plumeplume --Q 100 --u 3 --H 2 --stability D --threshold-ppm 50 --M 34Peak ground concentration at 24 m, above 50 ppm out to 187 mNeutral-buoyancy only; dense gases need a dense-gas model
Steel in a firesteel-fire --am-v 150Steel reaches 550 °C in about 4 min in a hydrocarbon fireUnprotected steel fails fast; shows why passive protection is specified

5. Functional safety and reliability

Layer-of-protection analysis (LOPA) tells you how much risk reduction a safety function must deliver. The probability-of-failure command then checks an architecture against it.

$ python3 -m process_safety lopa --ie 0.1 --ipl 0.1 0.01 --target 1e-6
  unmitigated_per_yr: 0.1   mitigated_per_yr: 0.0001   tolerable_per_yr: 1e-06
  required_rrf: 100   sil_needed: SIL 1

$ python3 -m process_safety pfd --arch 1oo2 --lambda-du 2e-6 --ti-years 1 --beta 0.05
  pfd_avg: 5.30e-04   rrf: 1,886   achieves: SIL 3

A hazard of 0.1 per year with two independent layers still leaves 1e-4 per year against a 1e-6 target, so a safety function with a risk reduction of 100 is required. A 1oo2 architecture with a dangerous undetected failure rate of 2e-6 per hour, a yearly proof test and a 5% common-cause factor gives a probability of failure of 5.3e-4, which meets the need on probability. Probability is not the whole test: the SIL tool also checks the architecture limits, and that is where a single valve usually fails (see section 9).

6. Regulation and management systems

TaskCommand (shortened)Key outputs (illustrative inputs)Read it like this
OSHA PSM applicabilitypsm-check --chemical chlorine --kg 700Threshold 680 kg, quantity 700 kg, covered: trueLooks the chemical up in the 134-chemical Appendix A
PSM due datespsm-due --pha 2021-03-15 --audit 2023-06-01 --today 2026-11-05PHA revalidation overdue by 235 days, compliance audit overdue by 157 daysFive-year and three-year cadences from the OSHA text
Seveso classificationseveso Chlorine:H=6 'Hydrogen sulphide:H=3'Tier: lower-tier, sum 1.2 against the lower thresholdEU thresholds only; the Indian MSIHC schedules are not implemented
US EPA RMP thresholdrmp-check chlorine --kg 1200Threshold 1,134 kg, covered: trueThe 77 toxics and 63 flammables are parsed from the rule
Gas pipeline designpipeline --smys 448 --wall 12.7 --od 610 --buildings 25Design pressure 134.3 bar, impact radius 223 mUS 49 CFR 192 basis, natural gas only
LNG terminallng --tanks 160000 --heat-kw 4000 --regas-kg-s 50 --sw-dT 5Impoundment 176,000 m³, boil-off 7.8 kg/s (1.0% a day), regas 44.4 MW, seawater 2.17 m³/sImpoundment follows the US rule; siting models are not reproduced
LPG propertieslpg propane --fill-C 15 --max-C 501,616 kPag at 50 °C, density 506 kg/m³, fill ceiling 88%Codes (API 2510, OISD, IS 2825) set the practical fill limit
Peroxide decompositionh2o2 --kg-h 500Oxygen 235 kg/h, heat 401 kW, up to 640 kg/h steamPure H₂O₂ basis; a first look at a tank failure case

7. Electrical, noise and machinery

TaskCommand (shortened)Key outputs (illustrative inputs)Read it like this
Arc flash, open airarc-flash --kv 0.48 --ka 20 --t 0.2 --dist-mm 4554.7 cal/cm², boundary 905 mmLee method; enclosed equipment is refused and sent to IEEE 1584
Relay operating timeidmt --i 3000 --pickup 400 --tms 0.2 --curve very_inverseOperates in 0.42 s at 7.5× pickupCurve arithmetic; a coordination study is separate
Touch and step voltageearthing --rho-s 3000 --t 0.5Touch 902 V, step 3,117 V for a 50 kg personIEEE 80 tolerable limits; grid design is not implemented
Safeguard distancesafeguard --stop-s 0.5 --d-mm 14Minimum distance 800 mmPre-2024 ISO 13855 form; check your edition
Noise exposurenoise 90:8 95:2Dose 150%, time-weighted average 92.9 dBA, exceeds limit: trueItems are LEVEL_dBA:HOURS; OSHA 1910.95 basis

8. The risk study (qra)

The risk study chains six steps: hazard identification, frequency, consequence, risk, evaluation against criteria, and mitigation. Everything is driven by one JSON file. Copy the worked example and edit it.

python3 -m process_safety qra example --out study.json       # copy the worked example
python3 -m process_safety qra validate study.json            # units, sums to 1, references, provenance
python3 -m process_safety qra hazid study.json --out hazid/  # registers for the workshop
python3 -m process_safety qra run study.json --sample 3 --out sample/
python3 -m process_safety qra run study.json --out qra_out/
python3 -m process_safety qra buildings study.json --out qra_out/
python3 -m process_safety qra emergency study.json --out qra_out/

The study file has these top-level blocks:

KeyWhat it holds
materialsProperties per substance (molar mass, k, liquid density, boiling point, heat of vaporisation, heat of combustion, lower flammable limit, toxic component)
sectionsIsolatable sections with inventory, pressure, temperature, coordinates, and equipment lists; each equipment item with its hole sizes and frequencies and the source of each
extra_scenariosScenarios that are not parts-count, such as a tanker loading failure
ignition, conventionsIgnition model and the immediate-ignition fraction (a study assumption, not data), thermal exposure time, explosion yield
weather, wind_roseStability class, wind speed and probability for each weather case, and the wind direction probabilities
grid, receptors, populationThe calculation area and step, named receptors with occupancy, and population zones
indoor_vulnerability, buildingsHow indoor occupants are protected, and each building with occupants and a target individual risk
criteria, alarpThe acceptance preset (UK R2P2, Dutch Bevi or custom) and the cost-benefit settings, including an illustrative value of a prevented fatality
mitigationCandidate measures, each with a cost and the change it makes to the study
emergencyCredible-case frequency cut-off, unit radius, site boundary and toxic levels
The example’s numbers are placeholders. The file says so in plain words: pump frequencies, weather, wind rose, population, indoor vulnerability, the value of a prevented fatality and measure costs are illustrative. Replace them with site data before any decision.

On the worked example the full run takes about 13 seconds and finds 18 loss-of-containment scenarios with a total frequency of 0.0435 per year. Open qra_report.html first, then use the CSV files in Excel.

Output fileWhat it tells you
qra_report.htmlThe summary report: risk map, F-N curve, receptors, mitigation
receptors.csvIndividual risk per named receptor and whether it is in the intolerable, ALARP or broadly acceptable region
fn_curve.csv, lsir_grid.csvThe F-N curve data and the location-specific individual risk grid
scenarios.csvEvery loss-of-containment scenario with its frequency
qra_buildings.*Occupant risk, overpressure and heat exceedance per building
qra_mcls.csv, qra_emergency.htmlWorst-case and credible distances and the emergency zones
mitigation.csvFatalities prevented, cost-benefit ratio and decision for each measure
hazid_register.csv, hazop_worksheet.csvStarting registers for the workshop

How to read the headline results on the example: the loading-bay operator has the highest individual risk (6.0e-4 per year), every receptor is tolerable if ALARP, yet the F-N curve is in the intolerable region against the UK preset. The mitigation table then says what to do: a loading-hose release coupling prevents 0.046 fatalities a year at a cost-benefit ratio of 0.033, so implement; extra shutdown valves and relocating a building are not justified on cost-benefit alone.

Sample first. --sample N runs N scenarios on a coarser grid, re-runs them at double angular resolution to test convergence, and projects the full-run time. The study found two of its own bugs this way.

9. The JSON study tools

Seven further tools each read a JSON file, run input checks, and write CSV or HTML with a checks list. Copy an example with tool example NAME, run it with tool NAME file.json --out folder/.

ToolWhat it doesResult on the shipped example
bowtieThreats, prevention barriers, top event, mitigation barriers, consequences; barrier importance and the safety-critical element listTop event 1.7e-4 per year; the independent high-high level trip is the safety-critical element
sifSIL from risk reduction, architecture limits (IEC 61511 and 61508 Route 1H), probability of failure, spurious trips, risk graphTarget SIL 2; probability meets SIL 2 but one valve with 40% safe-failure fraction caps it at SIL 1, so it fails
fg2D fire and gas detector coverage and a placement optimiserBullet area 2-detector coverage 1.8% against 90%; optimiser adds 18 detectors and reaches 68.7%, still short
thermalRunaway screening: time to maximum rate, Stoessel class, storage safety marginNitration batch class 3; 53.9 K margin at 35 °C storage
atexZone, equipment protection level and category by release grade; dust classPowder charging room: zone 21, EPL Db, category 2D, dust class St2
ramMonte Carlo reliability and availability of a production trainProduction availability about 97.5% on the example; 574 runs set by the target precision
phaCHAZOP, what-if and SWIFT worksheets, action register, revalidation datesAction closure 33%, one overdue action, one high-risk action still open

10. Use it from Python

Every module is importable. This is useful for loops, spreadsheets and your own checks.

$ python3 -c "from process_safety import datacentre as dc; print(round(dc.pue(13000, 10000), 2)); print(round(dc.k_of_n_availability(3, 4, 0.99), 6))"
1.3
0.999408

$ python3 -c "from process_safety import hydraulics as h; a=h.wave_speed_m_s(1.0e9, 560, 0.35, 0.0095, 2.0e11); print(round(a,1)); print(h.surge_screen(L_m=300000, a_m_s=a, closure_s=30, rho=560, dv_m_s=1.5))"
1228.0
{'critical_time_s': 488.60704262757326, 'joukowsky_kPa': 1031.5037566582102, 'estimated_kPa': 1031.5037566582102, 'rapid_closure': True}

The second example is a surge screen: a 30-second valve closure on a long liquid line with assumed fluid and wall properties. It reports the wave speed, the critical time (489 s), and a Joukowsky pressure rise of about 1,032 kPa, in the rapid-closure regime. It is a screen, not a transient simulator.

11. When it goes wrong

What you seeWhyFix
No module named process_safetyYou ran it outside the repository folder without installing itpip install -e . or run from the repository folder
KeyError: 'flow' from hazop-csvHAZOP parameters are case-sensitiveUse Flow Pressure Temperature Level (also Composition, Phase, Reaction, Utilities, Operation/Maintenance)
An absurd rate from blowdown (a million kg/s)Pressure is in kPa absolute and the hole diameter is in metres; millimetres inflate it a thousandfoldPass --hole-d 0.025 for 25 mm
ok: false from arc-flashEnclosed equipment or higher voltage is outside the methodUse an IEEE 1584 study
--gen-hours needs --sfcDiesel fuel consumption is vendor data with no defaultSupply --sfc in g/kWh
A result that looks too cleanInputs are placeholdersRun coverage and read the module docstring before relying on it

12. Limits, and where to go next

  • No dense-gas model. Propane and chlorine clouds spread differently from the neutral plume. Feed validated footprints from a tool such as DNV Phast or RISKCURVES through the overrides hook. Section 16 shows what this means for a propane terminal.
  • Paywalled standards. API 752/753, IEC 60079-10-1 and IEEE 1584 were not read, so building-damage curves, zone extents and enclosed arc flash are inputs or refusals.
  • No default Indian criteria. The risk study ships UK and Dutch presets; supply a custom criterion for an Indian site.
  • Software-class studies. Load flow, harmonics, transient stability, pulsation and illumination are listed as not implemented.

Read next in the repository: docs/QRA.md (the study file and models), docs/STUDIES.md (the seven JSON tools), docs/ELECTRICAL_MECHANICAL.md (what was read versus corroborated), docs/DATACENTRE.md (data-centre helpers) and docs/IFLUIDS_SERVICES.md (consultancy services mapped to modules).

13. What is new in version 0.10

Version 0.10 is on pull request 3, stacked on the two earlier pull requests, and is not yet merged: install from that branch to try it. It adds input checks, a glossary, a restructured command line and an independent cross-check. The short video shows each of them running.

Inputs are checked against ranges

Each numeric input has a hard range (physically impossible outside it: the run stops with exit code 2) and a soft range (atypical: a warning on the error stream, and the run continues). The soft ranges are engineering judgement, there to catch unit slips; they are not a standard’s limits. --no-range-check skips both for a deliberate extreme case.

$ python3 -m process_safety relief-gas --W 5000 --T 300 --set-g 1000 --M 30 --k 2.5
warning: --k=2.5 is outside the typical range (-inf, 1.67] for Cp/Cv (isentropic exponent) (1.67 is monatomic; most process gases are 1.1 to 1.4): check the value
{ "required_area_mm2": 415.42616954563, "orifice": "H", ... }     (exit code 0)

$ python3 -m process_safety relief-gas --W 5000 --T -5 --set-g 1000 --M 30 --k 1.3
process_safety: error: --T=-5 K is outside the possible range (0, inf) for absolute temperature     (exit code 2, no result)

$ python3 -m process_safety ranges heat_capacity_ratio
{
  "name": "heat_capacity_ratio",
  "unit": "-",
  "description": "Cp/Cv (isentropic exponent)",
  "hard_range": "(1, inf)",
  "soft_range": "(-inf, 1.67]",
  "note": "1.67 is monatomic; most process gases are 1.1 to 1.4"
}

A glossary in the command line

python3 -m process_safety glossary TERM searches about 115 terms and abbreviations; the same table generates docs/GLOSSARY.md. These are working definitions for orientation: the standard named in each entry governs.

$ python3 -m process_safety glossary BLEVE
BLEVE (Boiling-liquid expanding-vapour explosion)
    Sudden rupture of a vessel holding liquid above its atmospheric boiling point, usually ending in a fireball.
    [Fire, explosion and dispersion; fireball]
Fireball
    The rising ball of burning vapour after a BLEVE or a large flash release; harm is by thermal radiation.
    [Fire, explosion and dispersion; fireball]

Cleaner structure, same numbers

The command line is now a registry with one class per command instead of a 34-branch conditional. Forty outputs captured before the change are compared after it, within 1e-9, because the last digit of a float differs between platforms. Continuous integration runs on Python 3.10 to 3.13. The lint step found two real bugs, both fixed: an f-string that was a syntax error on Python 3.10 and 3.11, and a missing import in the PSM module.

124 cross-checks, and the differences that remain

$ python3 -m unittest discover tests
Ran 192 tests in 7.346s

OK
$ python3 tests/crosscheck/validate.py
checks: 124  within tolerance: 124  outside: 0  not computed: 0

The references are the fluids, thermo and CoolProp libraries and closed-form formulas from the open literature. Agreement shows the toolkit matches other implementations; it does not show a result is right for your plant. Known differences: liquid relief area runs about 4.7% below fluids in both cases checked and the cause is not resolved, so confirm it against vendor sizing; steam area uses the older Napier constant; and the API 2000 fire heat input has a boundary at 0.07 barg. The full list is in docs/VALIDATION.md.

14. What is new since 0.10: derogations, EU impact, insurance and legal clauses

These additions are on pull request 4, stacked on the earlier pull requests and not yet merged. The command line now has 47 commands, 342 automated tests pass and the cross-check suite has grown to 186 checks, all within tolerance. The new work answers one question: when a design departs from a must clause, who approves it, what does it cost the business, what does European law say about it, what does it do to the insurance, and where does the law set the limit? Every default below (tiers, approval levels, thresholds) is editable and is not any company’s rule.

Must, should, can, and the derogation

Each clause in a standard is graded from its modal verb. A must (shall, must, shall not) is complied with or formally derogated. A should is comply-or-explain. A can is optional, and you record whether you adopted it. A derogation is a formal, approved departure from a must. It needs a justification, a risk assessment reference, at least one compensating measure, an expiry date, a consequence assessment and the sign-offs the matrix requires. A statutory clause cannot be derogated by company sign-off at all; only the regulator can exempt.

$ python3 -m process_safety compliance process_safety/examples/compliance.json --as-of 2026-11-06
  "by_tier":  MUST  complied 1, derogated 3, open 0
              SHOULD complied 0, derogated 1, open 1
              CAN    adopted 0, not-adopted 1
  "must_compliance": 1 of 4 satisfied (25.0%)
  "ready_for_gate": false          (condensed from the JSON)

The example register is deliberately faulty, so that it fails the gate and shows each failure code. A gate that cannot fail would tell you nothing.

The approval matrix: TA1, TA2 and TA3

The class of a derogation is the highest of its safety severity and six management ratings (next section). The class then sets who must sign.

Tierlowmediumhighsevere
MUSTTA2TA2TA1TA1 + TA2
SHOULDTA3TA3TA2TA1

TA1 is taken as the most senior level and TA3 the least: that ordering is an assumption you can edit. A higher level can stand in for a lower one, and each sign-off must come from a different person. With no consequence assessment the class defaults to severe. In the example, clause 4.2.2 is a medium must that needs TA2 but carries only a TA3 sign-off, so the review reports unmet: TA2 and the issue approval-insufficient.

PESTLE: mapping the management consequence

For each derogation the assessor rates six lenses from 0 to 5: political, economic, social, technological, legal and environmental. 0 to 2 is low, 3 medium, 4 high and 5 severe. A rating of 3 or more needs a written management action, and a must derogation must address all six factors and describe the scenario if the derogated clause fails. In the example, clause 4.1.3 rates the economic factor 3 (a pump-house outage of about ten days) and records its action: a spare pump on site and business-interruption cover confirmed. The tool enforces completeness; the ratings themselves are the assessor’s judgement.

EU impact: Seveso III

A company derogation never waives an EU or national requirement. A clause can be marked as restating an EU provision (non-derogable) or implementing one (it needs an equivalence argument and is floored to the high class). The register also records the Seveso tier and screens each derogation against the Article 11 question: is the change significant, was the authority informed, and were the notification, the major-accident prevention policy, the safety management system and, for an upper-tier site, the safety report updated?

"eu_compliance": { "seveso_tier": "upper", "non_derogable_eu_clauses": ["9.1"],
  "art11_significant": ["4.1.3"], "art11_unassessed": ["4.2.2"], ... }
issues: 4.1.3 seveso-documents-not-updated, 4.2.2 seveso-not-assessed,
        9.1 statutory-no-exemption                       (condensed from the JSON)

Only the Seveso III articles are encoded. ATEX, the Pressure Equipment Directive, the Industrial Emissions Directive and your member state’s transposition are separate checks.

Insurance impact, from an actuarial perspective

insurance takes an exposure rating, scenario frequencies, loss distributions with an uncertainty (error) factor, and the deductible and limit. It computes the expected loss in the layer, its variance, a technical premium and the retained loss. Each case scales the scenario frequencies by the probability of failure on demand of the derogated safeguard. With the invented inputs shipped as an example:

Case (USD)Technical premiumChangeRetained expected loss
baseline3,128,8100%40,346
derogated6,639,142+112.2%133,464
derogated with compensating measure4,205,767+34.4%63,617

In that illustration the present value of the saving from the compensating measure is about 16.8 million dollars against a measure cost of 2.5 million. The inputs are invented, so read this as a method, not a finding. A modelled premium is not a quotation, and no market rates or loss data are shipped.

Legal clauses across eight regimes

legal-clauses searches 55 provisions from eight regimes: India (15), Australia at Commonwealth level (13), Singapore (6), Canada at federal level (6), South Korea (6), the EU (5), the US (3) and Great Britain (1). Each is filed under one of four topics: general duty, change, notify and exemption. Grade A (40 clauses) means the legal text was read. Grade B (15 clauses) means only guidance, a mirror or an OCR copy was seen: confirm it against the legislation. For India, the Manufacture, Storage and Import of Hazardous Chemical Rules 1989 treat a modification likely to cover major accident hazards as a new activity (rule 6) and need a further safety report at least 90 days before a material modification (rule 11), which is the central constraint on a derogation there.

$ python3 -m process_safety legal-clauses --region India --topic change
IN-FA-41A    [India; change; grade A]  The Factories Act, 1948, s. 41A(1), (2), (5)
IN-MSIHC-6   [India; change; grade B]  MSIHC Rules 1989, r. 6(2)(a)(ii)
IN-MSIHC-11  [India; change; grade B]  MSIHC Rules 1989, r. 11(1)-(2)
IN-MSIHC-13  [India; change; grade B]  MSIHC Rules 1989, r. 13(1)-(3)          (condensed)

Not yet read: China, Japan, Brazil, Norway, the Gulf states, and state or provincial law. The entries are paraphrased and are not legal advice.

15. What is new on 6 and 7 November: US units, input templates, a scenario suite, cost and plant tools

These are also on pull request 4, now at version 0.11.0 and still not merged. The command line has 52 commands, 364 automated tests pass, and a new official scenario suite runs 159 scenarios with 787 checks, all passing. Every output below was produced by running the command on 7 November 2026 with illustrative inputs; long JSON is condensed. The rule that runs through all of it is the same as before: no remembered number is typed into the code. Walking speeds, lux targets, unit rates, cost indices and discharge coefficients are inputs, not defaults.

US-customary units, and why gauge and absolute pressure will not convert

Put --units us before any command and type every number in US units: psig, °F, ft, in, lb/h, gpm, Btu/lb. Each is converted to the command’s working unit before the range check, and the result gains US sibling keys next to the SI ones. Every conversion factor is a legal definition (the inch, the pound, standard gravity, the 231 in³ gallon, the International Table Btu), not a remembered number.

$ python3 -m process_safety --units us relief-gas --W 22000 --T 140 --set-g 250 --M 44.1 --k 1.13 --Z 0.85
  "required_area_mm2": 518.3,
  "required_area_in2": 0.803,
  "orifice": "J",  "regime": "critical"          (condensed)

That is 22,000 lb/h of propane-like vapour at 140 °F and a 250 psig set pressure. Two deliberate refusals protect against the commonest unit mistakes in relief work. A gauge pressure will not convert to an absolute one unless you say so, because the difference is the atmosphere:

$ python3 -m process_safety convert 250 psig psia
error: cannot convert psig (pressure_gauge) to psia (pressure_abs)
$ python3 -m process_safety convert 250 psig psia --across-atmosphere
  "result": 264.70

Temperature rises are a separate dimension (dK, dF), so they cannot be pushed through the °F offset by mistake, and standard volumes (scf, Nm³) are not converted at all, because sources use different reference temperatures: give a mass flow instead. docs/UNITS.md lists the ten differences that cause mistakes.

Input templates: fill in a file instead of typing flags

template writes a fill-in JSON (or CSV) for any command, in SI or US units, with each argument’s unit, whether it is required and its valid range. run executes the filled file, and the file’s own units field decides how its numbers are read.

$ python3 -m process_safety template relief-gas --system us > relief_us.json
   ... fill W, T, set_g, M, k, Z ...
$ python3 -m process_safety run relief_us.json
  "required_area_in2": 0.803,  "orifice": "J"     (same answer as the flags above)

The templates are generated from the command definitions themselves and a test keeps them in step, so a new argument appears in its template the moment it is added.

Two-phase relief from real fluid data

twophase sizes flashing relief by the omega method, and --fluid now reads saturated-liquid properties from a bundled table of 18 fluids at 14 pressures generated with CoolProp. fluid-data shows what is in it.

$ python3 -m process_safety twophase --P0 1500 --fluid propane
  "G_kg_m2_s": 9025,  "omega": 5.38,  "regime": "choked",
  "G_hem_reference_kg_m2_s": 9018
  "note": "homogeneous equilibrium; Kb/Kc not applied; subcooled and reactive (DIERS) cases need other methods"

The omega flux for saturated propane at 1,500 kPa absolute is within 0.1% of a direct homogeneous-equilibrium integration; across all 252 rows of the table the two agree within 2.2%. There is no default discharge coefficient for two-phase service: to get an area you must give --Kd from your valve data, alongside the relief rate --W. Near the critical point the single-point omega degrades, and the command now warns above half the critical pressure.

Flame radiation by view factor

flame-flux integrates the view factor from a target to a flat, vertical rectangular flame face and multiplies by the surface emissive power you supply.

$ python3 -m process_safety flame-flux --width 10 --height 15 --distance 25 --sep 60
  "view_factor": 0.061,  "incident_kW_m2": 3.66

A 10 m by 15 m flame face at 60 kW/m², seen from 25 m, delivers about 3.7 kW/m². The toolkit’s own use cases found that its point-source pool-fire distances and this solid-flame method disagree by about four times in the far field, because they imply different radiant fractions. That disagreement is documented, not hidden: use both and say which you relied on.

Escape time and lighting

egress compares the required safe escape time (detection, pre-movement, then travel or queuing at the narrowest exit, whichever is longer) with the available time from your fire or toxic study. illumination applies the lumen method.

$ python3 -m process_safety egress --distance 120 --speed 1.0 --people 40 --width 1.2 \
    --specific-flow 1.3 --detect-s 60 --premove-s 90 --aset-s 420
  "governing": "travel distance",  "rset_s": 270,  "margin_s": 150,  "escape_before_untenable": true

$ python3 -m process_safety illumination --area 600 --flux 9000 --uf 0.55 --mf 0.8 --target 200
  "n_luminaires": 31,  "achieved_lux": 204.6

Walking speed, flow per metre of exit, detection and response times, utilisation and maintenance factors and the lux target are all yours to supply. They depend on the occupants and on the standard the site follows, so the toolkit does not guess them.

From recommendations to money: shutdown, cost and LNG capex

Four new studies follow a safety recommendation through to cost and schedule. Each takes an input JSON and ships a worked example (tool example <name> copies it), and every rate, margin and cost index in the examples is a labelled placeholder: the toolkit ships no cost data.

  • Shutdown risk (tool shutdown): schedule and cost risk for a turnaround by Monte Carlo on a critical-path network, with the opportunity cost of lost operating days. Worked example: a 25-day base plan comes out at 31.5 days at P50 and 35.6 days at P80. A 500-run sample was not stable enough, so the tool ran 5,753 runs; the biggest driver is activity A6.
  • Recommendation cost (tool recs): the cost of implementing study recommendations by discipline, with contingency, the effect on the shutdown and an ALARP cost-benefit test. Worked example: six recommendations, capex 616 at P50 and 656 at P80 (in cost units); the independent high-level shutdown on the feed drum passes the ALARP test; the shutdown items add about 0.1 day at P80.
  • Design workflow (tool workflow): relief screening, resizing, a bill of quantities, capex, opex and ALARP chained in one run. Worked example: the V-101 fire case needs 664 mm² against 506 mm² installed, so the PSV is resized to a J orifice, and the package passes ALARP (cost-benefit ratio 2.5 against a disproportion factor of 3).
  • LNG capex (tool lngcost): concept-stage liquefaction capex from public analogs (24 plants used, 2 excluded). Worked example: an illustrative 5 MTPA greenfield train comes out at about $11.1 billion at P50, or $2.2 billion per MTPA. A reference notebook’s unsourced shortcut gives $5.9 billion, below every analog.

The LNG figure is an AACE Class 5 screening number, not a budget. The cost index and location factors are the largest judgements in it, so change them and look at the sensitivity. An optional script, scripts/openpytea_bridge.py, turns equipment you have sized into purchased and installed cost using the open OpenPyTEA correlations, and flags sizes outside a correlation’s range, which OpenPyTEA itself costs without warning. The package stays standard-library only; the bridge sits outside it.

Reading a plant: heat and mass balance, P&ID registers and the PHA

tool plant reads stream tables, equipment and instrument registers (as CSV or Proteus XML) and a PHA register, then runs six scenario types with the existing models and checks the registers against seven P&ID rules. Where an input is missing it reports cannot_assess and names the input, instead of guessing. In the worked example it finds:

  • a blocked outlet on V-101 that needs 4,398 mm² of relief area (a Q orifice) against 830 mm² installed;
  • depressuring V-101 to atmosphere could chill the gas to about −105 °C against a minimum design metal temperature of −20 °C;
  • drum V-102 has no relief device in the register;
  • tank T-201’s PSV vents propane and butane to atmosphere.

Each finding is tied to a recommendation type, and gaps that the PHA register does not already cover are listed separately.

Your own documents, incidents and sources

requirements pulls the shall, should and must statements out of standards and specifications you hold (text, Word, or PDF via pdftotext), classifies them and compares them with a PHA register. Because those documents are usually someone else’s copyright, it prints counts unless you ask for the statements, writes only to a file you name, and refuses to write inside a git repository unless the path is ignored. incidents searches 17 U.S. Chemical Safety Board investigations mapped to the toolkit’s modules, and literature searches an index of 93 sources, each marked with whether its content was actually read.

$ python3 -m process_safety incidents --module overfill
2005-03-23  BP America Texas City refinery explosion (Texas City, TX, 15 killed)
2009-10-23  Caribbean Petroleum (CAPECO) refinery tank explosion and fire (Bayamon, PR)
2022-09-20  BP-Husky Oregon (Toledo) refinery chemical release and fire (Oregon, OH, 2 killed)
                                                         (condensed: each entry also gives the lesson and the CSB link)

The scenario suite: how the toolkit checks itself

scripts/run_scenarios.py runs 159 scenarios covering 72 of the 77 topics in the coverage map. Each scenario carries up to five kinds of check:

  • Bounds: a physical or logical limit holds.
  • Oracles: an independent recomputation from first principles agrees.
  • Metamorphic relations: doubling the flow doubles the relief area, for example.
  • SI against US: the same case typed in both unit systems gives the same answer.
  • Regression snapshot: current values are unchanged.

The report says plainly that the snapshot only detects drift and is not evidence of correctness. The five topics without scenarios are the ones still marked not implemented. Writing the suite found a real trap: blowdown --hole-d is in metres, so a hole typed as “25” meaning millimetres was accepted as 25 m and gave a 0.4 ms blowdown. The help text now says metres.

16. Worked example: an LPG terminal, start to finish

An LPG storage and loading terminal is a good test of the toolkit: pressurised propane bullets, transfer pumps, a road-tanker loading bay, a flare, and a control room and village close enough to matter. This section walks that asset through the commands above with the actual outputs, asking the questions a process-safety workshop asks first: how big is the fire relief load, is the overfill trip good enough, where does the risk come from, and how far must emergency planning reach. The individual-risk, F-N and cost-benefit results of the same study are read in section 8.

The terminal is hypothetical. It is the toolkit’s worked example: four sections (a propane bullet with pumps, a road-tanker loading bay, a sour fuel-gas header, a diesel tank in a bund), 60,000 kg of propane at 750 kPag and 303 K in the bullet. Pump failure frequencies, weather, wind rose, population, building vulnerability, the value of a prevented fatality and mitigation costs are illustrative placeholders; replace every one with site data before any decision.
  • How much vapour must the bullet relieve in a pool fire?
    relief-fire --D 3.5 --L 14 --level 2.5 --latent 330
    Wetted area 119 m², heat input 2,174 kW, relief rate 23,720 kg/h. The geometry and the 330 kJ/kg latent heat are inputs.
  • What pressure and fill limit does propane set?
    lpg propane --fill-C 15 --max-C 50
    Vapour pressure 1,616 kPag at 50 °C, liquid density 506 kg/m³ at 15 °C, a thermodynamic fill ceiling of 88%. Codes set the practical limit.
  • Is the overfill trip good enough?
    tool sif sif.json
    Target SIL 2. The PFDavg of 6.6e-3 (risk reduction 151) meets SIL 2 by probability, but a single type-A inlet shutdown valve with 40% safe-failure fraction caps the architecture at SIL 1. It fails.
  • Which barriers carry the risk?
    tool bowtie bowtie.json
    Top event 1.7e-4 per year. Given a loss of containment: 69% unignited, 21% vapour-cloud explosion or flash fire, 9% jet fire, 1% BLEVE. The independent high-high level trip is the safety-critical element.
  • Where does individual risk come from?
    qra run study.json
    Highest location risk 0.012 per year at (120, 40) m; population risk (PLL) 0.051 per year.
  • How exposed are the buildings?
    (same run as above)
    Occupant risk per year: control room 5.0e-4, admin building 9.7e-5, loading-bay shelter 6.1e-3.
  • How far must emergency planning reach?
    (same run as above)
    Credible case (4-inch line rupture, jet and pool fire): 58, 102 and 179 m to 37.5, 12.5 and 4 kW/m². Worst case (bullet fireball): 296, 551 and 996 m. Vapour-cloud explosion: 621 m to 0.3 bar, 786 m to 0.1 bar.

One reading is worth pausing on. The overfill function passes on probability and fails on architecture, so the fix is a redundant or higher-integrity final element, not a shorter proof-test interval. That comes from a check the toolkit runs, not from judgement added afterwards.

The limit that matters most for propane. The toolkit warns on this very study: propane is heavier than air, and the flash-fire and toxic footprints use a neutral Gaussian plume, so consider a dense-gas override. Dense clouds spread along the ground and reach further than a neutral plume. The vapour-cloud and flash-fire distances above (0.3 bar at 621 m, 0.1 bar at 786 m) and the risk that depends on them should therefore be treated as optimistic until footprints from a validated dense-gas tool such as DNV Phast or RISKCURVES are fed in through the overrides hook. The toolkit then still does the frequency, individual-risk, ALARP and mitigation bookkeeping.

The same questions in real projects

iFluids Engineering, a Chennai consultancy, publishes case studies and an all-projects list. Several entries are the same questions the terminal raised. The list below matches each to the toolkit module that screens it, with a real output on illustrative inputs. No result, input or design from any listed project is shown or implied: only the client, title and scope as the iFluids pages state them, and the toolkit is not iFluids’ method.

  • GSPL: integrated QRA for LNG transport routes and regasification
    Question screened: Impoundment, boil-off and regas duty at a terminal (lng, qra)
    Toolkit output (illustrative inputs): For a 160,000 m³ tank, 4,000 kW heat ingress, 50 kg/s regas and 5 K seawater rise: impoundment 176,000 m³, boil-off 7.8 kg/s (1.0% a day), regas duty 44.4 MW, seawater 2.17 m³/s
    Where the toolkit stops: Impoundment follows the US rule (49 CFR 193.2181). Siting models and road-transport route risk are not implemented
  • Kuwait Oil Company thermal testing facility; Jafurah downstream pipeline Phase II: fire and gas mapping
    Question screened: Detector coverage of a hazard zone (fg_mapping)
    Toolkit output (illustrative inputs): On the toolkit’s example bullet area, two-detector coverage as drawn is 1.8% against a 90% target. The optimiser adds 18 gas detectors and reaches 68.7%, still short
    Where the toolkit stops: 2D geographic coverage only. 3D mapping and scenario-based coverage are not implemented
  • CPCL Manali refinery: PSM gap assessment against the 20 CCPS RBPS elements
    Question screened: Scoring and tracking a management system (psm)
    Toolkit output (illustrative inputs): Gap scoring (0 to 4 per element) and weakest-element ranking for the 14 OSHA PSM elements and AIGA 99; for dates, a PHA last done 15 Mar 2021 is overdue by 235 days on 5 Nov 2026
    Where the toolkit stops: The 20-element RBPS scoring itself is not implemented, only the element list and a crosswalk
  • NGL pipeline surge analysis (14-inch, about 300 km, in the projects list)
    Question screened: Surge pressure on a fast valve closure (hydraulics.surge_screen)
    Toolkit output (illustrative inputs): Assuming density 560 kg/m³, bulk modulus 1 GPa and a 9.5 mm wall: wave speed 1,228 m/s, critical time 489 s, a 1.5 m/s stop in 30 s gives 1,032 kPa (Joukowsky)
    Where the toolkit stops: A screen, not a transient simulator: no pump trips, column separation or full pipeline model
  • IOCL Mathura tank conversion (20,000 KL and 5,000 KL tanks)
    Question screened: Fire venting of an atmospheric tank (tank_venting)
    Toolkit output (illustrative inputs): A bare vertical tank, 40 m by 16 m (about 20,000 m³): wetted area 1,149 m², emergency venting 19,897 Nm³/h, of which 18,397 Nm³/h is beyond a 1,500 Nm³/h normal capacity
    Where the toolkit stops: API 2000 5th edition (1998) only; the 7th edition and vent hardware sizing are not implemented
  • Essar re-HAZOP of P&IDs; Oil India HAZOP and QRA; Qatar Petroleum bow-tie development
    Question screened: Registers, revalidation and barrier ranking (hazop, pha, bowtie, qra)
    Toolkit output (illustrative inputs): The terminal study above: HAZOP worksheets, barrier importance and the safety-critical element, QRA individual and societal risk
    Where the toolkit stops: The study itself is a team exercise; the tools keep the records
  • HAZID for mining standpipe infrastructure (Pilbara)
    Question screened: Hazard identification checklist (qra.hazid)
    Toolkit output (illustrative inputs): A HAZID register by section and a loss-of-containment list
    Where the toolkit stops: Generic prompts, not standard text; not an oil and gas asset
Not computational, so not covered. The iFluids pages also list safety-culture perception surveys and a behaviour-based safety programme (BCPL, Assam), an external safety audit of paint plants (Berger Paints), and an ammonia-ingress control-room pressurisation design (IFFCO Kalol). These are surveys, audits and ventilation design. The toolkit does not attempt them, and it has no indoor toxic model.

What this terminal needs next

  • Replace the placeholders. Pump and equipment frequencies from a source such as the OGP 434-1 data or the UK HSE FRED rows, local weather and wind data, and the actual population around the site.
  • Add a dense-gas footprint. Run the propane releases in a validated tool and feed the footprints through overrides.
  • Choose the criteria deliberately. This run used the UK R2P2 preset; no single Indian tolerable-risk criterion exists in the public documents the toolkit read, so an Indian site should supply a custom one.
  • Do what the toolkit lists as not implemented. Layout and separation distances, hazardous-area classification extents, and fire-water design to the governing standards remain manual work.
  • Hold the workshop. The HAZID and HAZOP registers are a starting point; the studies are a team exercise.

The same flow applies to other oil and gas assets, a gas processing plant, a refinery unit or an offshore platform, with different modules in play (relief and flare systems, hydrocarbon fire, explosion). The terminal here is only the asset the toolkit ships a worked example for.

Sources: the toolkit and its documentation, github.com/herrrickshaw/process-safety-design-toolkit; the browser demo, process-safety-studio-demo.lovable.app (captured outputs, not live calculations) (open pull requests 1 and 2 hold the risk-study, study-tool and data-centre additions; pull request 3 holds version 0.10; pull request 4 holds the derogation, EU, insurance and legal-clause additions and the 6 and 7 November work in section 15). Every output above comes from running the command on 5 November 2026 (section 14: 6 November 2026; section 15: 7 November 2026, at commit b2561ae) with illustrative inputs; results are screening arithmetic and modelled, not measured, and are not a safety case. Section 16: outputs from running the commands on 5 November 2026 on the toolkit’s hypothetical LPG terminal; client names and project scopes as stated on ifluids.com/case-studies and ifluids.com/all-projects, read on 5 November 2026 (the projects page was only partly read).

Revision history.
  • v1.4.0 — 10 November 2026 — added section 16, the LPG-terminal worked example (relief, propane limits, the overfill trip, bow-tie, location and building risk, emergency distances, the dense-gas limit and matching consultancy projects), merged in from a separate post that has been retired.
  • v1.3.0 — 7 November 2026 — added section 15: US-customary units and the gauge/absolute pressure guard, input templates, two-phase relief from bundled fluid data, view-factor flame radiation, escape-time and lighting checks, the shutdown, recommendation-cost, design-workflow and LNG-capex studies, plant and P&ID ingestion, the requirements extractor, incident and literature search, and the 159-scenario self-check; and a link to the Process Safety Studio browser demo near the top. The toolkit is now at version 0.11.0 with 52 commands and 364 tests; counts quoted in earlier sections and the summary tiles describe the versions those sections were written for.
  • v1.2.0 — 6 November 2026 — added section 14: derogations and compliance tiers, the TA1/TA2/TA3 approval matrix, PESTLE consequence rating, EU (Seveso III) impact, actuarial insurance impact and a 55-clause legal index, with a demo video. Sections 1 to 13 are unchanged, so counts quoted there (35 commands, 173 and 192 tests, 124 cross-checks) describe the earlier versions.
  • v1.1.0 — 5 November 2026 — added section 13: version 0.10 (input ranges, glossary, restructured command line, 124 cross-checks) with a demo video. The earlier sections describe version 0.9 and are unchanged.
  • v1.0.0 — 5 November 2026 — first published (complete walkthrough).

About this article: Researched, written and edited by Umashankar Triplicane Dwarakanathan, with AI research assistance; every figure is meant to trace to the primary source cited. See the Editorial Policy for how sourcing, AI use and corrections work.

Umashankar Triplicane Dwarakanathan
Contact Us
Umashankar Triplicane Dwarakanathan
Investment Promotion & Energy-Sector Leader · Chennai, Tamil Nadu, India
LinkedIn → GitHub → Email +91 78273 81696
How this site works

Data-led analysis of India's trade, currency and industrial policy. Every article is built from primary official sources, and every figure links back to the release, table or filing it came from.

Sources. DGCI&S TradeStat (imports/exports, HSN-wise) · PIB (government press releases, January 2017 to today, refreshed daily) · RBI (circulars, balance of payments) · MoSPI (CPI/WPI, IIP) · PARIVESH (environmental clearances) · CCIL (bond yields) · BIS (policy rates) · SEBI, NSE/BSE and SEC filings for company data.

Interpretation. Figures carry their vintage and retrieval date; estimates and press-reported numbers are labelled as such; where sources disagree, both are shown. Corrections are made visibly, never silently. Articles are written with AI assistance from the cited sources — AI-generated text can misstate figures even when working from real material, so verify any number that matters to a decision against the linked primary source.

footer

Browse all articles by topic

Every piece on this blog, grouped. Or read the full index.

Agriculture & FertilisersAI ToolsChemicalsClimate & CarbonEnergy & FuelsGas & LNGImport SubstitutionIndustrial PolicyMarkets & FinanceMobility & EVPrices & InflationTextilesTrade & Tariffs

Each topic is a live archive page that updates itself as pieces are labelled. It replaces a hand-kept list that had fallen 18 articles behind.