Scoring & Priority Classification
How TerraGuard computes severity scores and assigns priority levels to disaster events -- the system that determines alerting thresholds and response urgency.
Overview
Every disaster event in TerraGuard receives a numerical severity score and a categorical priority level. This scoring system is life-critical -- it directly determines which events trigger notifications to response teams and at what urgency level.
The scoring formula is deterministic, auditable, and fully configurable via scoring.yaml. There are no black boxes. Every point in the score can be traced to a specific input: the source alert level, physical measurements, population exposure, or deployment context.
Local-First Architecture
Scoring uses data already stored in PostgreSQL — no external API calls in the critical path.
| Source | Primary Data | Enrichment (non-green only) |
|---|---|---|
| USGS | raw_event_records.raw_data (full GeoJSON) + GeoPop | USGS PAGER products (economic losses, MMI exposure) |
| GDACS | raw_event_records.raw_data + normalized_event_records + GeoPop | None — fully local |
The Go event processor stores the complete raw payload from each source during ingestion. The Python scoring service reads this stored data and combines it with real-time GeoPop population analysis to compute severity scores.
For green alert events (~90% of all events): scoring completes in ~200ms with zero external HTTP calls.
For non-green events (yellow/orange/red): USGS PAGER products are fetched as best-effort enrichment for better economic impact data. If the PAGER API is unavailable, the local score stands.
Code: app/apis/internal_evaluate/services/usgs/event_evaluate.py (USGS), app/apis/internal_evaluate/services/gdacs/event_evaluate.py (GDACS)
Unified Scoring Formula
SCORE = BASE + PHYSICAL (cap +2.0) + POPULATION (cap +1.5) + CONTEXT (cap +1.0)The maximum possible score is 12.0 (7.5 base + 2.0 physical + 1.5 population + 1.0 context). In practice, scores above 10.0 are rare and represent catastrophic events in densely populated areas with high deployment likelihood.
Base Scores
The base score is derived from the alert level reported by the data source. This is the single largest contributor to the final score.
| Source Alert Level | Base Score | Typical Meaning |
|---|---|---|
| RED | 7.5 | Severe event, likely humanitarian impact |
| ORANGE | 5.5 | Moderate event, potential humanitarian impact |
| GREEN | 3.0 | Minor event, limited impact expected |
| UNKNOWN | 2.0 | Source did not provide an alert level |
GDACS provides color-coded alert levels for all event types. USGS maps magnitude ranges to equivalent levels. NHC maps Saffir-Simpson categories to alert levels.
Physical Modifiers
Physical modifiers add up to +2.0 based on the measurable characteristics of the event. Each event type has its own modifier curve.
Earthquakes
| Magnitude | Modifier |
|---|---|
| < 5.0 | +0.0 |
| 5.0 - 5.9 | +0.3 |
| 6.0 - 6.4 | +0.7 |
| 6.5 - 6.9 | +1.2 |
| 7.0 - 7.4 | +1.6 |
| 7.5+ | +2.0 |
Additional earthquake factors:
- Depth < 10km: +0.3 (shallow earthquakes cause more surface damage)
- Depth < 30km: +0.1
Tropical Cyclones
| Sustained Wind Speed | Modifier |
|---|---|
| < 63 km/h (Tropical Depression) | +0.0 |
| 63 - 118 km/h (Tropical Storm) | +0.5 |
| 119 - 153 km/h (Category 1) | +0.8 |
| 154 - 177 km/h (Category 2) | +1.2 |
| 178 - 208 km/h (Category 3) | +1.5 |
| 209 - 251 km/h (Category 4) | +1.8 |
| 252+ km/h (Category 5) | +2.0 |
Floods
| Severity Indicator | Modifier |
|---|---|
| Minor flooding | +0.0 |
| Moderate flooding | +0.5 |
| Major flooding | +1.0 |
| Record-level flooding | +1.5 |
| Catastrophic / dam failure | +2.0 |
Volcanoes
| VEI (Volcanic Explosivity Index) | Modifier |
|---|---|
| VEI 0-1 | +0.0 |
| VEI 2 | +0.5 |
| VEI 3 | +1.0 |
| VEI 4 | +1.5 |
| VEI 5+ | +2.0 |
Population Modifier
The population modifier adds up to +1.5 based on GeoPop exposure data. The GeoPop API returns estimated population counts within configurable radii of the event epicenter.
| Affected Population | Modifier |
|---|---|
| < 10,000 | +0.0 |
| 10,000 - 100,000 | +0.3 |
| 100,000 - 500,000 | +0.6 |
| 500,000 - 1,000,000 | +0.9 |
| 1,000,000 - 5,000,000 | +1.2 |
| 5,000,000+ | +1.5 |
Events in ocean areas (detected via GeoPop's land/sea classification) receive a population modifier of +0.0 regardless of the calculated radius, since there is no exposed population.
Context Modifier
The context modifier adds up to +1.0 based on organizational deployment data. If the event occurs in a country where the organization has a high deployment likelihood, the score increases.
| Deployment Likelihood | Modifier |
|---|---|
| HIGH | +1.0 |
| MEDIUM | +0.5 |
| LOW | +0.2 |
| NONE | +0.0 |
This modifier is organization-specific. The same earthquake will receive different context modifiers for different organizations based on their country configurations.
Physical Floors
Certain physical measurements are so significant that they override the scoring formula to guarantee a minimum score. This prevents a strong earthquake from being classified as low-priority simply because it occurred in a sparsely populated area with no organizational presence.
| Condition | Minimum Score |
|---|---|
| Earthquake M7.0+ | 6.0 |
| Earthquake M7.5+ | 7.5 |
| Tropical Cyclone Category 4+ | 6.0 |
| Tropical Cyclone Category 5 | 7.5 |
| VEI 4+ Eruption | 6.0 |
If the computed score is below the physical floor, it is raised to the floor value. Floors are applied after all modifiers are summed.
Source Floor Rule
In addition to physical floors, there is a source-level floor that guarantees minimum priority levels based on the data source's own assessment:
| Source Alert Level | Minimum Priority |
|---|---|
| RED | Always HIGH |
| ORANGE | Always MEDIUM |
| GREEN | No floor |
| UNKNOWN | No floor |
This means a GDACS RED alert will never be classified below HIGH priority, even if the scoring formula would produce a lower result. The rationale: if GDACS -- which has its own sophisticated alerting criteria -- flags something as RED, TerraGuard should trust that assessment as a floor.
Priority Thresholds
The final severity score maps to a priority level using simple thresholds:
| Priority | Score Range | Meaning |
|---|---|---|
| HIGH | >= 8.0 | Immediate attention required. Triggers real-time notifications. |
| MEDIUM | >= 5.0 | Significant event. Triggers standard notifications. |
| LOW | >= 2.5 | Notable event. Visible on dashboard but no notifications. |
| NOISE | < 2.5 | Below threshold. Stored in database but hidden from default views. |
Lifecycle Statuses
Beyond priority, each disaster event has a lifecycle status that tracks its progression:
| Status | Description |
|---|---|
| MONITORING | Default for new actionable events. Actively tracked. |
| ACTIVE | Organization has acknowledged and is tracking the event. |
| ARCHIVED | Auto-set after 4 days without source updates. Can be reactivated. |
| RESPONDING | Organization has deployed resources. |
| RESOLVED | Response operations concluded. |
| CLOSED | Event fully resolved and archived for historical record. |
The auto-archive rule is critical for operational hygiene. Without it, the dashboard would accumulate stale events indefinitely. The 4-day window is configurable in scoring.yaml.
Configuration
All scoring parameters are defined in scoring.yaml:
scoring:
base_scores:
RED: 7.5
ORANGE: 5.5
GREEN: 3.0
UNKNOWN: 2.0
priority_thresholds:
HIGH: 8.0
MEDIUM: 5.0
LOW: 2.5
physical_floors:
earthquake:
- { min_magnitude: 7.0, floor: 6.0 }
- { min_magnitude: 7.5, floor: 7.5 }
tropical_cyclone:
- { min_category: 4, floor: 6.0 }
- { min_category: 5, floor: 7.5 }
source_floors:
RED: HIGH
ORANGE: MEDIUM
auto_archive_days: 4Changes to this file take effect on the next scoring run without requiring a code deployment.
Note: The
scoring.yamlconfiguration is loaded by the Go event processor for reference, but the actual scoring calculations are performed by the Python backend's per-source scorers (USGS and GDACS). The Python scorers implement the formula described above with source-specific variations. See the Architecture section for details.
Scoring Example
Consider a magnitude 6.8 earthquake in central Turkey, reported by both GDACS (ORANGE alert) and USGS:
| Component | Value | Reasoning |
|---|---|---|
| Base | 5.5 | ORANGE alert level |
| Physical | +1.2 | M6.8 earthquake |
| Depth bonus | +0.3 | 8km depth (shallow) |
| Population | +1.2 | ~3.2M within 50km |
| Context | +1.0 | HIGH deployment likelihood for Turkey |
| Raw total | 9.2 | |
| Physical floor | 6.0 | M6.8 does not trigger M7.0 floor |
| Source floor | MEDIUM | ORANGE alert |
| Final score | 9.2 | No floors applied (raw score exceeds both) |
| Priority | HIGH | Score >= 8.0 |
This event would trigger immediate HIGH-priority notifications to all teams configured for earthquake alerts.
Event Processing Pipeline
The deterministic event processing pipeline at the core of TerraGuard -- how raw disaster data from GDACS, USGS, and NHC is normalized, deduplicated, correlated, and persisted.
Notification Engine
How TerraGuard's multi-gate notification system determines who gets alerted, when, and why -- including organization matrices, country configurations, and the full decision audit trail.