# hsnterp/jormungandr architecture

> Architecture diagram of the GitHub repository hsnterp/jormungandr, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/hsnterp/jormungandr
- Repository: https://github.com/hsnterp/jormungandr

## Overview

Jormungandr is an edge-oriented seismic detector and P/S phase picker. Its workflow prepares STEAD waveforms and labels, trains a compact U-Net (including EQTransformer knowledge distillation), exports an INT8 ONNX model, then scores continuous sensor data in windows and turns detection probabilities into event triggers for transmission gating. The README also describes evaluation against STA/LTA and other pickers, plus zero-shot evaluation. Some subsystems are documented but their source was not sampled, so their internal wiring is not expanded.

Main entry points: [`src/seismic_edge_picker/dataset.py`](https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/dataset.py) (Dataset loader), [`src/seismic_edge_picker/model.py`](https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/model.py) (1D U-Net picker), [`scripts/stream_infer.py`](https://github.com/hsnterp/jormungandr/blob/main/scripts/stream_infer.py) (Streaming inference entry), [`scripts/demo_edge.py`](https://github.com/hsnterp/jormungandr/blob/main/scripts/demo_edge.py) (Transmission gate demo)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_data["Data preparation"]
  node_dataset["Dataset loader<br/>[dataset.py]"]
  node_splits["Leakage-safe splits<br/>[splits.py]"]
  node_preprocess["Waveform preprocessing<br/>[preprocessing.py]"]
  node_augment["Training augmentation<br/>[augment.py]"]
  node_labels["Target labels<br/>[labels.py]"]
end

subgraph group_learning["Model training"]
  node_student["1D U-Net picker<br/>[model.py]"]
  node_train["Student training<br/>[train.py]"]
  node_distill["Distillation utilities<br/>[distill.py]"]
  node_train_distill["Distillation training<br/>[train_distill.py]"]
end

subgraph group_runtime["Edge inference"]
  node_export["ONNX INT8 export<br/>[export_onnx.py]"]
  node_stream["Windowed streaming<br/>[streaming.py]"]
  node_preprocess_stream["Causal preprocessing<br/>[preprocessing.py]"]
  node_infer["Streaming inference entry<br/>[stream_infer.py]"]
  node_gate["Transmission gate demo<br/>[demo_edge.py]"]
end

subgraph group_assessment["Evaluation"]
  node_stead_eval["Model evaluation<br/>[evaluate.py]"]
  node_baselines["Picker baselines<br/>[fair_comparison.py]"]
  node_falsealarms["False-alarm analysis"]
end

node_sensor(("Waveform source"))
node_stead[("STEAD / SeisBench")]
node_teacher["EQTransformer teacher"]
node_sta["STA/LTA detector"]
node_transmit(("Reported event packets"))

node_stead -->|"provides traces"| node_dataset
node_dataset -->|"splits metadata"| node_splits
node_dataset -->|"preprocesses traces"| node_preprocess
node_dataset -->|"augments training"| node_augment
node_dataset -->|"builds targets"| node_labels
node_train -->|"loads batches"| node_dataset
node_train -->|"trains model"| node_student
node_teacher -.->|"provides soft targets"| node_distill
node_distill -->|"wraps train data"| node_dataset
node_train_distill -->|"uses cache utilities"| node_distill
node_train_distill -->|"trains student"| node_student
node_export -->|"exports model"| node_student
node_sensor -->|"streams waveform"| node_infer
node_infer -->|"preprocesses chunks"| node_preprocess_stream
node_infer -->|"windows and merges"| node_stream
node_infer -->|"loads ONNX model"| node_export
node_stream -->|"emits probabilities"| node_gate
node_gate -->|"selects packets"| node_transmit
node_stead_eval -->|"loads test split"| node_dataset
node_stead_eval -->|"scores predictions"| node_student
node_baselines -.->|"compares picker"| node_teacher
node_baselines -->|"compares metrics"| node_stead_eval
node_falsealarms -->|"benchmarks against"| node_sta
node_falsealarms -->|"measures triggers"| node_student
node_gate -.->|"compares trigger"| node_sta
node_sta -.->|"selects packets"| node_transmit

click node_dataset "https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/dataset.py"
click node_splits "https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/splits.py"
click node_preprocess "https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/preprocessing.py"
click node_augment "https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/augment.py"
click node_labels "https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/labels.py"
click node_student "https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/model.py"
click node_train "https://github.com/hsnterp/jormungandr/blob/main/scripts/train.py"
click node_distill "https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/distill.py"
click node_train_distill "https://github.com/hsnterp/jormungandr/blob/main/scripts/train_distill.py"
click node_export "https://github.com/hsnterp/jormungandr/blob/main/scripts/export_onnx.py"
click node_stream "https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/streaming.py"
click node_preprocess_stream "https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/preprocessing.py"
click node_infer "https://github.com/hsnterp/jormungandr/blob/main/scripts/stream_infer.py"
click node_gate "https://github.com/hsnterp/jormungandr/blob/main/scripts/demo_edge.py"
click node_stead_eval "https://github.com/hsnterp/jormungandr/blob/main/scripts/evaluate.py"
click node_baselines "https://github.com/hsnterp/jormungandr/blob/main/scripts/fair_comparison.py"
click node_falsealarms "https://github.com/hsnterp/jormungandr/blob/main/scripts/false_alarm_rate.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_dataset,node_splits,node_preprocess,node_augment,node_labels toneBlue
class node_student,node_train,node_distill,node_train_distill,node_stead toneAmber
class node_export,node_stream,node_preprocess_stream,node_infer,node_gate toneMint
class node_stead_eval,node_baselines,node_falsealarms toneRose
class node_sensor,node_teacher,node_sta,node_transmit toneIndigo
```

## Components

### Data preparation

- [Dataset loader](https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/dataset.py): `src/seismic_edge_picker/dataset.py`
- [Leakage-safe splits](https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/splits.py): `src/seismic_edge_picker/splits.py`
- [Waveform preprocessing](https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/preprocessing.py): `src/seismic_edge_picker/preprocessing.py`
- [Training augmentation](https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/augment.py): `src/seismic_edge_picker/augment.py`
- [Target labels](https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/labels.py): `src/seismic_edge_picker/labels.py`

### Model training

- [1D U-Net picker](https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/model.py): `src/seismic_edge_picker/model.py`
- [Student training](https://github.com/hsnterp/jormungandr/blob/main/scripts/train.py): `scripts/train.py`
- [Distillation utilities](https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/distill.py): `src/seismic_edge_picker/distill.py`
- [Distillation training](https://github.com/hsnterp/jormungandr/blob/main/scripts/train_distill.py): `scripts/train_distill.py`

### Edge inference

- [ONNX INT8 export](https://github.com/hsnterp/jormungandr/blob/main/scripts/export_onnx.py): `scripts/export_onnx.py`
- [Windowed streaming](https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/streaming.py): `src/seismic_edge_picker/streaming.py`
- [Causal preprocessing](https://github.com/hsnterp/jormungandr/blob/main/src/seismic_edge_picker/preprocessing.py): `src/seismic_edge_picker/preprocessing.py`
- [Streaming inference entry](https://github.com/hsnterp/jormungandr/blob/main/scripts/stream_infer.py): `scripts/stream_infer.py`
- [Transmission gate demo](https://github.com/hsnterp/jormungandr/blob/main/scripts/demo_edge.py): `scripts/demo_edge.py`

### Evaluation

- [Model evaluation](https://github.com/hsnterp/jormungandr/blob/main/scripts/evaluate.py): `scripts/evaluate.py`
- [Picker baselines](https://github.com/hsnterp/jormungandr/blob/main/scripts/fair_comparison.py): `scripts/fair_comparison.py`
- [False-alarm analysis](https://github.com/hsnterp/jormungandr/blob/main/scripts/false_alarm_rate.py): `scripts/false_alarm_rate.py`

### Other components

- **Waveform source**
- **STEAD / SeisBench**
- **EQTransformer teacher**
- **STA/LTA detector**
- **Reported event packets**

## Connections

- STEAD / SeisBench → Dataset loader: provides traces
- Dataset loader → Leakage-safe splits: splits metadata
- Dataset loader → Waveform preprocessing: preprocesses traces
- Dataset loader → Training augmentation: augments training
- Dataset loader → Target labels: builds targets
- Student training → Dataset loader: loads batches
- Student training → 1D U-Net picker: trains model
- EQTransformer teacher → Distillation utilities: provides soft targets
- Distillation utilities → Dataset loader: wraps train data
- Distillation training → Distillation utilities: uses cache utilities
- Distillation training → 1D U-Net picker: trains student
- ONNX INT8 export → 1D U-Net picker: exports model
- Waveform source → Streaming inference entry: streams waveform
- Streaming inference entry → Causal preprocessing: preprocesses chunks
- Streaming inference entry → Windowed streaming: windows and merges
- Streaming inference entry → ONNX INT8 export: loads ONNX model
- Windowed streaming → Transmission gate demo: emits probabilities
- Transmission gate demo → Reported event packets: selects packets
- Model evaluation → Dataset loader: loads test split
- Model evaluation → 1D U-Net picker: scores predictions
- Picker baselines → EQTransformer teacher: compares picker
- Picker baselines → Model evaluation: compares metrics
- False-alarm analysis → STA/LTA detector: benchmarks against
- False-alarm analysis → 1D U-Net picker: measures triggers
- Transmission gate demo → STA/LTA detector: compares trigger
- STA/LTA detector → Reported event packets: selects packets
