Occupational Noise Exposure (ISO 9612)
Standards: ISO 9612Directive 2003/10/ECDHHS/NIOSH Publication No. 98-126
A working day is rarely measured in one take: the daily exposure level a
regulation acts on has to be assembled from samples of a real shift, and
reported with an uncertainty a hygienist can defend. lex_8h (in
Levels) turns one recording into a daily level. ISO 9612:2009,
the engineering method (accuracy grade 2), is the survey design around that
primitive: how to sample a real working day, how to combine the pieces, and how
to attach the normative uncertainty every occupational-hygiene report needs. The
occupational_exposure module adds the three measurement strategies and the
Annex C uncertainty budget on top of the energy-average machinery.
How do I compute ISO 9612 daily noise exposure LEX,8h in Python?
Section titled “How do I compute ISO 9612 daily noise exposure LEX,8h in Python?”Describe each activity as a hearing.Task with its samples and duration, then
call hearing.task_based_exposure(tasks). For the Annex D welder’s day below
it returns lex_8h = 84.3 dB with an expanded uncertainty = 2.7 dB, so the
one-sided 95 % upper_limit is 87.0 dB. Unstructured days use
job_based_exposure() or full_day_exposure() on random samples instead.
1. The three measurement strategies (Clauses 9-11)
Section titled “1. The three measurement strategies (Clauses 9-11)”The task-based strategy (Clause 9) splits the nominal day into tasks, takes samples per task, and energy-sums the task contributions
so a loud but short task contributes little. The job-based (Clause 10) and full-day (Clause 11) strategies instead take (or three whole-day) random samples over a homogeneous exposure group and normalise the effective-day duration. The daily level is the same either way; the strategies differ in how the uncertainty is built.
Choosing a strategy. ISO 9612 Table B.1 picks the strategy from the work pattern, not from convenience, and the trade-off is coverage against effort. The task-based strategy is the recommended default when the day decomposes into a small number of well-defined tasks: because it measures each task separately, it explains where the dose comes from (the per-task breakdown above) and lets a short, loud task be sampled properly without dragging out the whole survey, but it needs a reliable work analysis, and its uncertainty grows if the task durations are themselves uncertain. The job-based strategy suits a mobile worker with an unpredictable pattern or a homogeneous group doing “the same job”: random samples across the group average over the variability instead of resolving it, which is robust when the day cannot be cleanly cut into tasks but blind to which activity dominates. The full-day strategy (a worn dosimeter capturing the entire shift, repeated on several days) needs the least analysis and captures everything including the unexpected, at the cost of the most wearer-days and the weakest diagnostic value (one number per day, no breakdown, and false contributions like knocks on the microphone are hard to spot). As a rule: resolve the dose with task-based when you can, fall back to job-based for irregular work, and use full-day when the pattern defies description or an independent whole-shift check is wanted.
from phonometry import hearing
# ISO 9612 Annex D — a welder's day split into three tasks. Each task level is# the energy average of its Lp,A,eqT samples; durations carry a measured range.tasks = [ hearing.Task(samples=(70.0,), duration_hours=1.5, label="planning/breaks"), hearing.Task(samples=(80.1, 82.2, 79.6), duration_hours=5.0, duration_range=(4.0, 6.0), label="welding"), hearing.Task(samples=(86.5, 92.4, 89.3, 93.2, 87.8, 86.2), duration_hours=1.5, duration_range=(1.0, 2.0), label="cutting/grinding"),]res = hearing.task_based_exposure(tasks, include_duration_uncertainty=False, warn=False)print(f"LEX,8h = {res.lex_8h:.1f} dB U = {res.expanded_uncertainty:.1f} dB")# LEX,8h = 84.3 dB U = 2.7 dBprint(f"one-sided 95 % upper limit LEX,8h + U = {res.upper_limit:.1f} dB") # 87.0 dBfor t in res.tasks: print(f" {t.label:<16} Lp,A,eqT = {t.lp_aeqt:5.1f} contributes {t.lex_8h_contribution:5.1f} dB")# planning/breaks Lp,A,eqT = 70.0 contributes 62.7 dB# welding Lp,A,eqT = 80.8 contributes 78.7 dB# cutting/grinding Lp,A,eqT = 90.1 contributes 82.8 dB
# The same shift measured job-based (Annex E) and full-day (Annex F): both use# the Eq C.9 / Table C.4 sampling budget with k = 1.65 (one-sided 95 %).job = hearing.job_based_exposure([88.1, 86.1, 89.7, 86.5, 91.1, 86.7], effective_duration_hours=7.5)full = hearing.full_day_exposure([88.0, 91.9, 87.6, 90.4, 89.0, 88.4], effective_duration_hours=9.25)print(f"job LEX,8h = {job.lex_8h:.1f} dB U = {job.expanded_uncertainty:.1f} dB")# job LEX,8h = 88.2 dB U = 3.8 dBprint(f"full-day LEX,8h = {full.lex_8h:.1f} dB U = {full.expanded_uncertainty:.1f} dB")# full-day LEX,8h = 90.1 dB U = 3.4 dB
res.plot() # the figure below: task contributions with LEX,8h and LEX,8h + UShow the code for this figure
import matplotlib.pyplot as pltfrom phonometry import hearing
# The ISO 9612 Annex D welder's day of the previous snippet.tasks = [ hearing.Task(samples=(70.0,), duration_hours=1.5, label="planning/breaks"), hearing.Task(samples=(80.1, 82.2, 79.6), duration_hours=5.0, duration_range=(4.0, 6.0), label="welding"), hearing.Task(samples=(86.5, 92.4, 89.3, 93.2, 87.8, 86.2), duration_hours=1.5, duration_range=(1.0, 2.0), label="cutting/grinding"),]res = hearing.task_based_exposure(tasks, include_duration_uncertainty=False, warn=False)
# One line: task contribution bars plus the LEX,8h and LEX,8h + U lines.res.plot()plt.show()2. The Annex C uncertainty budget
Section titled “2. The Annex C uncertainty budget”Two subtleties are worth spelling out. First, the coverage factor is
for a one-sided 95 % interval (Clause 14), because a hygienist
cares only about the upper bound: res.upper_limit = is the
value 95 % of measurements fall below, the number compared against an action
limit. Second, the task and job methods weight the same spread of samples
differently. The task sampling uncertainty (Eq. C.6) divides the summed
squared deviations by (the standard error of the mean, smaller by a
factor ), whereas the job/full-day sampling uncertainty (Eq. C.12)
is the plain sample standard deviation with denominator , whose contribution
is then read from Table C.4 as a function of . The same
raw scatter therefore inflates the job estimate more, which is the standard’s
built-in penalty for coarser, fewer samples. (The printed job is
dB where Annex E reports : the standard rounds the effective-day
level to before the duration normalisation; the library keeps it
unrounded.)
What dominates the budget. Annex C combines four sources in quadrature (Table C.1): the sampling uncertainty (/), the duration uncertainty (, task-based only), the instrument (, Table C.5) and the microphone position (, Clause C.6). The last two are small and roughly fixed ( dB for a class 1 sound level meter, 1.5 dB for a class 2 meter or a personal exposimeter, and dB by default), so in practice the sampling term almost always dominates: it scales with the scatter of the measured levels, which in a real workplace easily reaches several decibels and, entered in quadrature, swamps the sub-decibel instrument and position terms. The practical consequence: a quadrature budget is set by its largest term, so tightening the instrument grade buys little once sampling scatter is large; the productive move is more samples (the standard error falls as or ), which is exactly what the Clause 9.3 / 10.4 advisories nudge you toward. Because peak carries no Annex C sampling model (Table C.5, Note 1), it is reported without an uncertainty, not with a zero one.
When a task’s samples span 3 dB or more (Clause 9.3), or the job contribution
exceeds 3.5 dB (Clause 10.4), or too few workers are covered
(Table 1 cumulative-duration), the result sets sampling_advisory=True and, with
warn=True, emits an OccupationalExposureWarning recommending more measurements. Peak
levels are reported without an uncertainty: Annex C gives no
method for them (Table C.5, Note 1), so peak-uncertainty is out of scope. The
three Annex D/E/F worked examples above are reproduced to the standard’s printed
precision (Annex E’s final rounding is disclosed above), and the theory is
derived on the Theory page.
task_based_exposure() / job_based_exposure() / full_day_exposure() parameters
Section titled “task_based_exposure() / job_based_exposure() / full_day_exposure() parameters”| Parameter | Applies to | Type | Units | Range / default | Notes |
|---|---|---|---|---|---|
tasks | task | list of Task | — | ≥ 1 | Each Task has samples, duration_hours, optional duration_range/duration_samples, label, instrument |
samples | job / full-day | sequence | dB | ≥ 2 (≥ 5 / ≥ 3 advised) | Random Lp,A,eqT samples |
effective_duration_hours | job / full-day | float | h | > 0 | Effective working-day duration |
instrument | all | str | — | 'class1', 'class2', 'personal_exposimeter' (default) | Selects (Table C.5) |
u3 | all | float | dB | default 1.0 | Microphone-position uncertainty (Clause C.6) |
include_duration_uncertainty | task | bool | — | default True | False omits the term (Annex D case a) |
n_workers / sample_duration_hours | job | int / float | — / h | default None | Table 1 cumulative-duration check |
warn | all | bool | — | default True | Emit OccupationalExposureWarning for the sampling advisories |
All three return an ExposureResult with lex_8h, combined_standard_uncertainty
, expanded_uncertainty , upper_limit = ,
sampling_advisory, and (task-based) the per-task tasks breakdown; the
result’s .plot() draws the per-task contribution bars with the
and upper-limit lines (task-based results only, since the other strategies
carry no per-task breakdown).
3. The measurement report (Clause 15)
Section titled “3. The measurement report (Clause 15)”An exposure determination ends as a document: ISO 9612 Clause 15 lists what
the measurement report shall state, from the strategy that was applied and the
work analysis down to the requirement that the noise exposure level and the
measurement uncertainty be reported as separate values, each rounded to one
decimal place. ExposureResult.report() writes that report as a one-page PDF
fiche laid out like a prevention-service measurement sheet: the standard-basis
line naming the applied strategy, a header grid (company, worker(s)/job,
workplace, and the Clause 15 c instrumentation and calibration traceability),
the work analysis (the per-task table of durations, levels
and contributions for a task-based result with its contribution
chart, or the sampling summary with the Formula C.9 budget for a job-based or
full-day result) and the boxed with , and the one-sided
95 % upper limit.
Because the number exists to be compared with the law, the fiche then assesses
the result against Directive 2003/10/EC (Article 3): the lower and upper
exposure action values (80 and 85 dB(A)) and the exposure limit value
(87 dB(A)), each marked exceeded / not exceeded on the value exactly as
displayed, with a PASS/FAIL verdict against the limit value. A printed note
records that the limit value applies to the effective exposure, with the
attenuation of the worn hearing protectors taken into account, which the
measured does not include. verbose=True adds the per-task
Annex C uncertainty columns (, , ), and language="es"
renders the Spanish fiche (the vocabulary of the Spanish transposition,
RD 286/2006: nivel de exposición diario equivalente, valor límite de
exposición, with comma decimals).
from phonometry import hearing, ReportMetadata
# The Annex D welders' day from section 1, with duration uncertainty.res = hearing.task_based_exposure(tasks, warn=False)
res.report( "lex8h.pdf", metadata=ReportMetadata( client="Example fabrication works", specimen="Welders (homogeneous exposure group, 4 workers)", test_room="Steel assembly hall, line 2", instrumentation="Personal sound exposure meter (IEC 61252), s/n 0042", calibration="Calibrator IEC 60942 class 1; field checks within 0.3 dB", test_date="2026-07-20", laboratory="Phonometry reference example", report_id="EXAMPLE-9612", ),) # LEX,8h = 84.3 dB, U = 3.2 dB -> lower action value exceeded, limit PASSThe example fiche is regenerated with make reports and kept rendered in the
repository; click the preview to open the PDF.

One-page ISO 9612 occupational noise-exposure fiche: a header with the company, the welders exposure group, the workplace and the instrumentation and calibration traceability, the task-based work-analysis table (planning/breaks, welding, cutting/grinding with durations, sample counts, task levels and LEX,8h contributions closed by the nominal-day totals row), the per-task contribution chart, the boxed LEX,8h = 84.3 dB with U = 3.2 dB, k = 1.65 and the 87.5 dB upper limit, and the Directive 2003/10/EC assessment table where the 80 dB(A) lower action value is exceeded, the 85 dB(A) upper action value and the 87 dB(A) limit value are not, ending in a PASS verdict.
See also
Section titled “See also”- Levels: the
lex_8h/sound_exposuredose primitives (IEC 61252) and the LCpeak these strategies report alongside. - Measurement uncertainty: the GUM machinery behind combined and expanded uncertainties.
- Theory: the derivation of the strategy formulas and the Annex C budget.
- API reference:
hearing.occupational_exposure.
References
Section titled “References”- European Parliament and Council. (2003). Directive 2003/10/EC on the minimum health and safety requirements regarding the exposure of workers to the risks arising from physical agents (noise) (Directive 2003/10/EC). Official Journal of the European Union. The EU exposure action values (80/85 dB) and limit value (87 dB) that the LEX,8h and its upper limit are assessed against.
- International Organization for Standardization. (2009). Acoustics — Determination of occupational noise exposure — Engineering method (ISO 9612:2009). The implemented method: the task-based (Clause 9), job-based (Clause 10) and full-day (Clause 11) strategies, the microphone placement of Clause 12.3, the Annex C uncertainty budget (Formulae C.6, C.9 and C.12, Tables C.4/C.5) and the one-sided coverage factor k = 1.65 (Clause 14), validated against the worked examples of Annexes D, E and F; the Clause 15 measurement report is written by ExposureResult.report().
- National Institute for Occupational Safety and Health. (1998). Criteria for a recommended standard: Occupational noise exposure — Revised criteria 1998 (DHHS/NIOSH Publication No. 98-126). https://doi.org/10.26616/NIOSHPUB98126The freely available criteria document (the linked PDF is the free download) behind the 85 dB(A) recommended exposure limit and the hearing-conservation rationale for measuring the daily dose.