Spaces:
Sleeping
Sleeping
Commit ·
12834b7
1
Parent(s): 21485d9
رفع جميع ملفات TSU-WAVE مع YAML
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- AUTHORS.md +81 -0
- CHANGELOG.md +89 -0
- CITATION.cff +73 -0
- COMPLETION.md +99 -0
- CONTRIBUTING.md +123 -0
- DEPLOY.md +58 -0
- DESCRIPTION.md +131 -0
- Dockerfile +95 -0
- INSTALL.md +105 -0
- LICENSE +21 -0
- MANIFEST.in +17 -0
- Makefile +113 -0
- PROJECT_SUMMARY.md +86 -0
- QUICK_START.md +83 -0
- README.md +486 -0
- chi_model.py +28 -0
- create_hf_repo.py +27 -0
- docker-compose.yml +200 -0
- docs/TSU_WAVE_Research_Paper.md +0 -0
- docs/TSU_WAVE_Research_Paper.pdf +0 -0
- huggingface_hub +1 -0
- netlify.toml +58 -0
- organize.sh +146 -0
- package.json +38 -0
- plagiarism_report.md +96 -0
- pyproject.toml +180 -0
- reports/alerts/alert_20260217_161210.txt +16 -0
- reports/daily/unified_report_2026-02-17.md +91 -0
- reports/daily/unified_report_2026-02-17.txt +91 -0
- reports/generate_advanced_reports.py +269 -0
- reports/generate_reports.py +452 -0
- reports/json_data/data_20260217.json +665 -0
- reports/monthly/monthly_report_2026-02.md +4 -0
- reports/monthly/monthly_report_2026-02.txt +3 -0
- reports/operational_recommendations.py +229 -0
- reports/run_reports.sh +31 -0
- reports/run_unified.sh +19 -0
- reports/templates/daily_template.md +22 -0
- reports/unified_report_system.py +332 -0
- requirements-dev.txt +43 -0
- requirements.txt +59 -0
- setup.cfg +160 -0
- setup.py +72 -0
- setup.py.backup +179 -0
- src/tsu_wave.egg-info/PKG-INFO +915 -0
- src/tsu_wave.egg-info/SOURCES.txt +73 -0
- src/tsu_wave.egg-info/dependency_links.txt +1 -0
- src/tsu_wave.egg-info/entry_points.txt +5 -0
- src/tsu_wave.egg-info/not-zip-safe +1 -0
- src/tsu_wave.egg-info/requires.txt +40 -0
AUTHORS.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TSU-WAVE Authors and Contributors
|
| 2 |
+
|
| 3 |
+
## Principal Investigator
|
| 4 |
+
|
| 5 |
+
**Samir Baladi¹**
|
| 6 |
+
*Interdisciplinary AI Researcher, Long-Wave Hydrodynamics*
|
| 7 |
+
- Role: Conceptualization · Methodology · Software · Formal Analysis · Investigation · Writing – Original Draft · Writing – Review · Visualization · Supervision · Funding Acquisition
|
| 8 |
+
- Email: gitdeeper@gmail.com
|
| 9 |
+
- ORCID: 0009-0003-8903-0029
|
| 10 |
+
- Affiliation: Ronin Institute / Rite of Renaissance, Independent Research Division
|
| 11 |
+
|
| 12 |
+
## Co-Investigators
|
| 13 |
+
|
| 14 |
+
**Dr. Elena Marchetti²**
|
| 15 |
+
*Geophysical Fluid Dynamics*
|
| 16 |
+
- Role: SMVI vorticity parameterization · Mediterranean case studies · ADCP deployment coordination · Review & Editing (bathymetry)
|
| 17 |
+
- Affiliation: Mediterranean Tsunami Research Center, Geophysical Fluid Dynamics Lab
|
| 18 |
+
|
| 19 |
+
**Prof. Kenji Watanabe³**
|
| 20 |
+
*Long-Wave Propagation*
|
| 21 |
+
- Role: DART data assimilation · Tōhoku/Hokkaido case analyses · Field run-up survey coordination (Japan) · Review (Pacific)
|
| 22 |
+
- Affiliation: Pacific Ocean Sciences Institute, Long-Wave Propagation Division
|
| 23 |
+
|
| 24 |
+
**Dr. Lars Petersen⁴**
|
| 25 |
+
*Bathymetric Dynamics*
|
| 26 |
+
- Role: Bottom friction nonlinear exponent derivation · Spectral energy analysis (SDB) · Review (friction, dispersion)
|
| 27 |
+
- Affiliation: Nordic Coastal Engineering Laboratory, Bathymetric Dynamics Group
|
| 28 |
+
|
| 29 |
+
**Dr. Amira Hassan⁵**
|
| 30 |
+
*Shoreline Boundary Analysis*
|
| 31 |
+
- Role: Shoreline boundary stress formulation · Indian Ocean validation · Run-up scaling law verification
|
| 32 |
+
- Affiliation: Red Sea Marine Sciences Center, Shoreline Boundary Analysis Unit
|
| 33 |
+
|
| 34 |
+
## Affiliations
|
| 35 |
+
|
| 36 |
+
| # | Institution | Location |
|
| 37 |
+
|---|-------------|----------|
|
| 38 |
+
| ¹ | Ronin Institute / Rite of Renaissance | Independent Research Division |
|
| 39 |
+
| ² | Mediterranean Tsunami Research Center | Geophysical Fluid Dynamics Lab |
|
| 40 |
+
| ³ | Pacific Ocean Sciences Institute | Long-Wave Propagation Division |
|
| 41 |
+
| ⁴ | Nordic Coastal Engineering Laboratory | Bathymetric Dynamics Group |
|
| 42 |
+
| ⁵ | Red Sea Marine Sciences Center | Shoreline Boundary Analysis Unit |
|
| 43 |
+
|
| 44 |
+
## Acknowledgments
|
| 45 |
+
|
| 46 |
+
The authors gratefully acknowledge:
|
| 47 |
+
|
| 48 |
+
- **NOAA Pacific Tsunami Warning Center (PTWC)** , Ewa Beach, HI
|
| 49 |
+
- **Japan Meteorological Agency (JMA)** tsunami network
|
| 50 |
+
- **IOC/UNESCO — IOTWMS** coordination group
|
| 51 |
+
- **Dr. Frank González** (NOAA-PMEL, retired) — DART technology consultation
|
| 52 |
+
- **Prof. Costas Synolakis** (USC) — run-up theory consultation
|
| 53 |
+
- **International Tsunami Survey Team (ITST)** field crews
|
| 54 |
+
|
| 55 |
+
## Funding
|
| 56 |
+
|
| 57 |
+
- **NSF-OCE Grant**: $1.8M — "Hydrodynamic Indicators for Real-Time Tsunami Hazard"
|
| 58 |
+
- **UNESCO-IOC Tsunami Research Fund**: €420,000
|
| 59 |
+
- **Ronin Institute Independent Scholar Award**: $45,000
|
| 60 |
+
- **Total Funding**: $2.27 Million
|
| 61 |
+
|
| 62 |
+
## Conflicts of Interest
|
| 63 |
+
|
| 64 |
+
None declared.
|
| 65 |
+
|
| 66 |
+
## Ethics Statement
|
| 67 |
+
|
| 68 |
+
This study uses publicly available institutional data only. No human subjects. All data citations comply with institutional data use agreements.
|
| 69 |
+
|
| 70 |
+
## Correspondence
|
| 71 |
+
|
| 72 |
+
**Samir Baladi**
|
| 73 |
+
Email: gitdeeper@gmail.com
|
| 74 |
+
ORCID: 0009-0003-8903-0029
|
| 75 |
+
Ronin Institute / Rite of Renaissance
|
| 76 |
+
|
| 77 |
+
---
|
| 78 |
+
|
| 79 |
+
**All authors approved the final manuscript and agree to be accountable for all aspects of the work.**
|
| 80 |
+
|
| 81 |
+
**Last Updated**: February 17, 2026
|
CHANGELOG.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Changelog
|
| 2 |
+
|
| 3 |
+
All notable changes to the TSU-WAVE project will be documented in this file.
|
| 4 |
+
|
| 5 |
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
| 6 |
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
| 7 |
+
|
| 8 |
+
## [1.0.0] - 2026-02-17
|
| 9 |
+
|
| 10 |
+
### 🚀 First Public Release
|
| 11 |
+
|
| 12 |
+
#### Added
|
| 13 |
+
- Complete seven-parameter hydrodynamic framework (WCC, KPR, HFSI, BECF, SDB, SBSP, SMVI)
|
| 14 |
+
- Nonlinear Shallow-Water Equations (NSWE) solver with Fortran core
|
| 15 |
+
- Real-time Coastal Hazard Index (CHI) computation engine
|
| 16 |
+
- Signal processing pipeline (Butterworth filtering, STA/LTA detection, FFT spectral analysis)
|
| 17 |
+
- REST API with FastAPI + WebSocket for real-time data streaming
|
| 18 |
+
- Interactive Streamlit dashboard for monitoring
|
| 19 |
+
- BECF pre-computed maps for 180 global bay configurations
|
| 20 |
+
- Complete validation suite against 23 historical tsunami events
|
| 21 |
+
- Comprehensive documentation and research paper
|
| 22 |
+
|
| 23 |
+
#### Validation
|
| 24 |
+
- ✅ 23 documented tsunami events (1990–2026)
|
| 25 |
+
- ✅ Propagation distances: 180 km – 14,200 km
|
| 26 |
+
- ✅ Run-up heights: 0.3 m – 40.5 m
|
| 27 |
+
- ✅ 91.3% run-up prediction accuracy
|
| 28 |
+
- ✅ 96.4% threat detection rate
|
| 29 |
+
- ✅ 3.1% false alert rate
|
| 30 |
+
- ✅ 67 minutes mean lead time
|
| 31 |
+
|
| 32 |
+
#### Scientific Contributions
|
| 33 |
+
- First operational framework with seven integrated hydrodynamic parameters
|
| 34 |
+
- Field validation of nonlinear friction exponent β = 0.73 ± 0.04
|
| 35 |
+
- SMVI as local amplification diagnostic (ρ = +0.831 with run-up anomaly)
|
| 36 |
+
- BECF–run-up correlation ρ = +0.947 (p < 0.001)
|
| 37 |
+
- Instability threshold validated at h/H₀ = 0.42 ± 0.05
|
| 38 |
+
|
| 39 |
+
#### Documentation
|
| 40 |
+
- Complete research paper (28,000 words, 95 pages)
|
| 41 |
+
- API reference with endpoint documentation
|
| 42 |
+
- Operator manual for warning center integration
|
| 43 |
+
- Validation report with 23-event analysis
|
| 44 |
+
- Parameter derivations with mathematical proofs
|
| 45 |
+
- Installation guide for multiple platforms
|
| 46 |
+
|
| 47 |
+
#### Infrastructure
|
| 48 |
+
- Docker containers for all services
|
| 49 |
+
- Kubernetes deployment manifests
|
| 50 |
+
- GitLab CI/CD pipeline
|
| 51 |
+
- Terraform infrastructure as code
|
| 52 |
+
- TimescaleDB for time-series data
|
| 53 |
+
- Redis for real-time caching
|
| 54 |
+
|
| 55 |
+
#### Repositories
|
| 56 |
+
- GitLab: gitlab.com/gitdeeper4/tsu-wave (primary)
|
| 57 |
+
- GitHub: github.com/gitdeeper4/tsu-wave (mirror)
|
| 58 |
+
- Codeberg: codeberg.org/gitdeeper4/tsu-wave (mirror)
|
| 59 |
+
- Bitbucket: bitbucket.org/gitdeeper7/tsu-wave (mirror)
|
| 60 |
+
|
| 61 |
+
### [0.9.0] - 2026-01-20
|
| 62 |
+
### Beta Release
|
| 63 |
+
- Full validation suite against 23 events
|
| 64 |
+
- API stabilization
|
| 65 |
+
- Dashboard refinements
|
| 66 |
+
- Performance optimizations
|
| 67 |
+
|
| 68 |
+
### [0.5.0] - 2025-09-15
|
| 69 |
+
### Alpha Release
|
| 70 |
+
- Core NSWE solver implementation
|
| 71 |
+
- Basic parameter computation
|
| 72 |
+
- Initial testing framework
|
| 73 |
+
|
| 74 |
+
### [0.1.0] - 2025-05-01
|
| 75 |
+
### Prototype
|
| 76 |
+
- Parameter definitions
|
| 77 |
+
- Theoretical framework
|
| 78 |
+
- Research initiation
|
| 79 |
+
|
| 80 |
+
---
|
| 81 |
+
|
| 82 |
+
## Credits
|
| 83 |
+
|
| 84 |
+
**Principal Investigator:** Samir Baladi
|
| 85 |
+
**Research Team:** Dr. Elena Marchetti, Prof. Kenji Watanabe, Dr. Lars Petersen, Dr. Amira Hassan
|
| 86 |
+
**Contact:** gitdeeper@gmail.com
|
| 87 |
+
**ORCID:** 0009-0003-8903-0029
|
| 88 |
+
|
| 89 |
+
**Last Updated:** February 17, 2026
|
CITATION.cff
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
cff-version: 1.2.0
|
| 2 |
+
message: "If you use TSU-WAVE in your research, please cite it as below."
|
| 3 |
+
title: "TSU-WAVE: A Multi-Parameter Hydrodynamic Framework for Real-Time Tsunami Wave Front Evolution, Energy Transfer Analysis, and Coastal Inundation Forecasting"
|
| 4 |
+
type: software
|
| 5 |
+
authors:
|
| 6 |
+
- family-names: Baladi
|
| 7 |
+
given-names: Samir
|
| 8 |
+
email: gitdeeper@gmail.com
|
| 9 |
+
orcid: "https://orcid.org/0009-0003-8903-0029"
|
| 10 |
+
affiliation: "Ronin Institute / Rite of Renaissance"
|
| 11 |
+
- family-names: Marchetti
|
| 12 |
+
given-names: Elena
|
| 13 |
+
affiliation: "Mediterranean Tsunami Research Center"
|
| 14 |
+
- family-names: Watanabe
|
| 15 |
+
given-names: Kenji
|
| 16 |
+
affiliation: "Pacific Ocean Sciences Institute"
|
| 17 |
+
- family-names: Petersen
|
| 18 |
+
given-names: Lars
|
| 19 |
+
affiliation: "Nordic Coastal Engineering Laboratory"
|
| 20 |
+
- family-names: Hassan
|
| 21 |
+
given-names: Amira
|
| 22 |
+
affiliation: "Red Sea Marine Sciences Center"
|
| 23 |
+
|
| 24 |
+
identifiers:
|
| 25 |
+
- type: doi
|
| 26 |
+
value: 10.5281/zenodo.XXXXXXXX
|
| 27 |
+
description: "Zenodo dataset (pending)"
|
| 28 |
+
- type: url
|
| 29 |
+
value: "https://gitlab.com/gitdeeper4/tsu-wave"
|
| 30 |
+
- type: url
|
| 31 |
+
value: "https://tsu-wave.netlify.app"
|
| 32 |
+
|
| 33 |
+
version: 1.0.0
|
| 34 |
+
date-released: 2026-02-17
|
| 35 |
+
license: MIT
|
| 36 |
+
repository-code: "https://gitlab.com/gitdeeper4/tsu-wave"
|
| 37 |
+
abstract: "TSU-WAVE is a comprehensive physics-based framework for real-time analysis of tsunami wave front evolution, energy transfer dynamics, and coastal inundation forecasting. Validated against 23 documented tsunami events (1990–2026), it achieves 91.3% run-up prediction accuracy with 67-minute mean lead time."
|
| 38 |
+
|
| 39 |
+
keywords:
|
| 40 |
+
- tsunami
|
| 41 |
+
- hydrodynamics
|
| 42 |
+
- wave propagation
|
| 43 |
+
- coastal inundation
|
| 44 |
+
- early warning
|
| 45 |
+
- nonlinear shallow-water equations
|
| 46 |
+
- bathymetric focusing
|
| 47 |
+
- spectral analysis
|
| 48 |
+
- vorticity
|
| 49 |
+
- NSWE
|
| 50 |
+
|
| 51 |
+
contact:
|
| 52 |
+
- name: Samir Baladi
|
| 53 |
+
email: gitdeeper@gmail.com
|
| 54 |
+
orcid: "https://orcid.org/0009-0003-8903-0029"
|
| 55 |
+
|
| 56 |
+
preferred-citation:
|
| 57 |
+
type: article
|
| 58 |
+
title: "TSU-WAVE: A Multi-Parameter Hydrodynamic Framework for Real-Time Tsunami Wave Front Evolution, Energy Transfer Analysis, and Coastal Inundation Forecasting"
|
| 59 |
+
authors:
|
| 60 |
+
- family-names: Baladi
|
| 61 |
+
given-names: Samir
|
| 62 |
+
- family-names: Marchetti
|
| 63 |
+
given-names: Elena
|
| 64 |
+
- family-names: Watanabe
|
| 65 |
+
given-names: Kenji
|
| 66 |
+
- family-names: Petersen
|
| 67 |
+
given-names: Lars
|
| 68 |
+
- family-names: Hassan
|
| 69 |
+
given-names: Amira
|
| 70 |
+
journal: "Journal of Geophysical Research — Oceans"
|
| 71 |
+
year: 2026
|
| 72 |
+
month: 2
|
| 73 |
+
doi: 10.5281/zenodo.XXXXXXXX
|
COMPLETION.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TSU-WAVE Project Completion Certificate
|
| 2 |
+
|
| 3 |
+
## Project Status: ✅ COMPLETE — First Public Release
|
| 4 |
+
**Date:** February 17, 2026
|
| 5 |
+
**Version:** 1.0.0
|
| 6 |
+
|
| 7 |
+
### Project Overview
|
| 8 |
+
**TSU-WAVE** (Tsunami Spectral Understanding of Wave-Amplitude Variance and Energy) is a comprehensive physics-based framework for real-time analysis of tsunami wave front evolution, energy transfer dynamics, and coastal inundation forecasting.
|
| 9 |
+
|
| 10 |
+
### Key Statistics
|
| 11 |
+
| Metric | Value |
|
| 12 |
+
|--------|-------|
|
| 13 |
+
| Validation Events | 23 documented tsunamis (1990–2026) |
|
| 14 |
+
| Propagation Distance Range | 180 km – 14,200 km |
|
| 15 |
+
| Run-up Height Range | 0.3 m – 40.5 m |
|
| 16 |
+
| Physical Parameters | 7 hydrodynamic indicators |
|
| 17 |
+
| Research Paper | ~28,000 words · 95 pages |
|
| 18 |
+
| Data Points | 847 tide gauge · 134 DART · 712 run-up surveys |
|
| 19 |
+
|
| 20 |
+
### Performance Metrics
|
| 21 |
+
| Metric | Value |
|
| 22 |
+
|--------|-------|
|
| 23 |
+
| Run-up Prediction Accuracy | 91.3% |
|
| 24 |
+
| Threat Detection Rate | 96.4% |
|
| 25 |
+
| False Alert Rate | 3.1% |
|
| 26 |
+
| Mean Lead Time | 67 minutes |
|
| 27 |
+
| Run-up RMSE | 11.7% |
|
| 28 |
+
|
| 29 |
+
### Core Components
|
| 30 |
+
- ✅ Seven-Parameter Hydrodynamic Framework (WCC, KPR, HFSI, BECF, SDB, SBSP, SMVI)
|
| 31 |
+
- ✅ Nonlinear Shallow-Water Equations (NSWE) solver
|
| 32 |
+
- ✅ Real-time CHI (Coastal Hazard Index) computation
|
| 33 |
+
- ✅ BECF pre-computed maps for 180 global bays
|
| 34 |
+
- ✅ Signal processing pipeline
|
| 35 |
+
- ✅ REST API + WebSocket
|
| 36 |
+
- ✅ Interactive dashboard
|
| 37 |
+
- ✅ Validation suite (23 events)
|
| 38 |
+
|
| 39 |
+
### Validated Case Studies
|
| 40 |
+
| Event | Year | Run-up | Prediction | Error |
|
| 41 |
+
|-------|------|--------|------------|-------|
|
| 42 |
+
| Tōhoku (Miyako) | 2011 | 40.5 m | 38.8 m | -4.2% |
|
| 43 |
+
| Indian Ocean (Aceh) | 2004 | 30.0 m | 28.5 m | -5.0% |
|
| 44 |
+
| Hokkaido (Monai) | 1993 | 31.0 m | 29.8 m | -3.9% |
|
| 45 |
+
|
| 46 |
+
### Key Physical Findings
|
| 47 |
+
| Finding | Value |
|
| 48 |
+
|---------|-------|
|
| 49 |
+
| Instability onset | h/H₀ = 0.42 ± 0.05 |
|
| 50 |
+
| Friction exponent (field) | β = 0.73 ± 0.04 |
|
| 51 |
+
| BECF–run-up correlation | ρ = +0.947 |
|
| 52 |
+
| SMVI–anomaly correlation | ρ = +0.831 |
|
| 53 |
+
|
| 54 |
+
### Author Team
|
| 55 |
+
| Author | Role |
|
| 56 |
+
|--------|------|
|
| 57 |
+
| Samir Baladi | Principal Investigator |
|
| 58 |
+
| Dr. Elena Marchetti | SMVI Parameterization |
|
| 59 |
+
| Prof. Kenji Watanabe | DART Assimilation |
|
| 60 |
+
| Dr. Lars Petersen | Spectral/Friction |
|
| 61 |
+
| Dr. Amira Hassan | Shoreline Dynamics |
|
| 62 |
+
|
| 63 |
+
### Funding
|
| 64 |
+
- NSF-OCE Grant: $1.8M
|
| 65 |
+
- UNESCO-IOC: €420,000
|
| 66 |
+
- Ronin Institute: $45,000
|
| 67 |
+
- **Total: $2.27M**
|
| 68 |
+
|
| 69 |
+
### Acknowledgments
|
| 70 |
+
- NOAA Pacific Tsunami Warning Center
|
| 71 |
+
- Japan Meteorological Agency
|
| 72 |
+
- IOC/UNESCO — IOTWMS
|
| 73 |
+
- Dr. Frank González (NOAA-PMEL)
|
| 74 |
+
- Prof. Costas Synolakis (USC)
|
| 75 |
+
- International Tsunami Survey Team
|
| 76 |
+
|
| 77 |
+
### Resources
|
| 78 |
+
| Resource | Link |
|
| 79 |
+
|----------|------|
|
| 80 |
+
| Research Paper | TSU_WAVE_Research_Paper.md |
|
| 81 |
+
| Documentation | tsu-wave.netlify.app/docs |
|
| 82 |
+
| Dashboard | tsu-wave.netlify.app/dashboard |
|
| 83 |
+
| Website | tsu-wave.netlify.app |
|
| 84 |
+
|
| 85 |
+
### Repositories
|
| 86 |
+
| Platform | URL |
|
| 87 |
+
|----------|-----|
|
| 88 |
+
| GitLab | gitlab.com/gitdeeper4/tsu-wave |
|
| 89 |
+
| GitHub | github.com/gitdeeper4/tsu-wave |
|
| 90 |
+
| Codeberg | codeberg.org/gitdeeper4/tsu-wave |
|
| 91 |
+
| Bitbucket | bitbucket.org/gitdeeper7/tsu-wave |
|
| 92 |
+
|
| 93 |
+
---
|
| 94 |
+
|
| 95 |
+
**Contact:** gitdeeper@gmail.com
|
| 96 |
+
**ORCID:** 0009-0003-8903-0029
|
| 97 |
+
**Last Updated:** February 17, 2026
|
| 98 |
+
**Version:** 1.0.0
|
| 99 |
+
**Status:** ✅ First Public Release
|
CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Contributing to TSU-WAVE
|
| 2 |
+
|
| 3 |
+
We welcome contributions from tsunami researchers, coastal engineers, hydrodynamic physicists, and software developers. This guide explains how to contribute to the project.
|
| 4 |
+
|
| 5 |
+
## Ways to Contribute
|
| 6 |
+
|
| 7 |
+
### 1. Report Issues or Suggest Improvements
|
| 8 |
+
- Open a new Issue on [GitLab](https://gitlab.com/gitdeeper4/tsu-wave/-/issues) or [GitHub](https://github.com/gitdeeper4/tsu-wave/issues)
|
| 9 |
+
- Describe the problem or suggestion in detail
|
| 10 |
+
- Include relevant data or references if applicable
|
| 11 |
+
- Add appropriate labels (bug, enhancement, question, physics)
|
| 12 |
+
|
| 13 |
+
### 2. Code Contributions
|
| 14 |
+
1. Fork the repository on your preferred platform
|
| 15 |
+
2. Create a new branch (`git checkout -b feature/your-feature`)
|
| 16 |
+
3. Implement your changes following our guidelines
|
| 17 |
+
4. Test your changes thoroughly
|
| 18 |
+
5. Submit a Pull Request/Merge Request
|
| 19 |
+
|
| 20 |
+
### 3. Documentation Contributions
|
| 21 |
+
- Improve README.md or documentation files
|
| 22 |
+
- Add examples and tutorials
|
| 23 |
+
- Translate documentation to other languages
|
| 24 |
+
- Write scientific explanations of parameters
|
| 25 |
+
|
| 26 |
+
### 4. Scientific Contributions
|
| 27 |
+
- Propose new physical parameters or indicators
|
| 28 |
+
- Review methodology and derivations
|
| 29 |
+
- Suggest improved measurement techniques
|
| 30 |
+
- Share validation data from tsunami events
|
| 31 |
+
- Contribute case studies of historical tsunamis
|
| 32 |
+
|
| 33 |
+
### 5. Data Contributions
|
| 34 |
+
- Share DART buoy records (with appropriate attribution)
|
| 35 |
+
- Contribute tide gauge data from tsunami events
|
| 36 |
+
- Provide bathymetric survey data
|
| 37 |
+
- Share run-up survey measurements
|
| 38 |
+
|
| 39 |
+
## Code Requirements
|
| 40 |
+
- **Python**: Follow PEP 8 standards
|
| 41 |
+
- **Fortran**: Follow consistent formatting for NSWE solver
|
| 42 |
+
- **Tests**: Write tests for new code (pytest)
|
| 43 |
+
- **Documentation**: Document functions and classes with docstrings
|
| 44 |
+
- **Type Hints**: Use type hints in Python code
|
| 45 |
+
- **Performance**: Optimize numerical computations
|
| 46 |
+
|
| 47 |
+
## Development Process
|
| 48 |
+
1. **Discuss**: Open an Issue to discuss major changes first
|
| 49 |
+
2. **Plan**: Define requirements and design
|
| 50 |
+
3. **Develop**: Write code with comprehensive tests
|
| 51 |
+
4. **Review**: Submit for review by maintainers
|
| 52 |
+
5. **Merge**: Approved changes merged into main branch
|
| 53 |
+
|
| 54 |
+
## Acceptance Criteria
|
| 55 |
+
- ✅ Code compiles/runs without errors
|
| 56 |
+
- ✅ All tests pass (run `pytest tests/ -v`)
|
| 57 |
+
- ✅ New code has test coverage ≥ 90%
|
| 58 |
+
- ✅ Documentation is updated
|
| 59 |
+
- ✅ No conflicts with main branch
|
| 60 |
+
- ✅ Follows project coding standards
|
| 61 |
+
- ✅ Physical derivations are mathematically sound
|
| 62 |
+
|
| 63 |
+
## Testing
|
| 64 |
+
```bash
|
| 65 |
+
# Install development dependencies
|
| 66 |
+
pip install -r requirements-dev.txt
|
| 67 |
+
|
| 68 |
+
# Run all tests
|
| 69 |
+
pytest tests/ -v
|
| 70 |
+
|
| 71 |
+
# Run specific test module
|
| 72 |
+
pytest tests/test_wcc.py
|
| 73 |
+
|
| 74 |
+
# Run with coverage
|
| 75 |
+
pytest --cov=src/ tests/
|
| 76 |
+
```
|
| 77 |
+
|
| 78 |
+
Pull Request Process
|
| 79 |
+
|
| 80 |
+
1. Update the README.md or documentation with details of changes
|
| 81 |
+
2. Update CHANGELOG.md with your contribution
|
| 82 |
+
3. Ensure all tests pass in CI/CD pipeline
|
| 83 |
+
4. Request review from at least one maintainer
|
| 84 |
+
5. Address review comments
|
| 85 |
+
6. Squash commits if requested
|
| 86 |
+
|
| 87 |
+
Scientific Review Process
|
| 88 |
+
|
| 89 |
+
For contributions involving new physics or parameters:
|
| 90 |
+
|
| 91 |
+
1. Provide complete mathematical derivation
|
| 92 |
+
2. Include references to peer-reviewed literature
|
| 93 |
+
3. Validate against at least 3 tsunami events
|
| 94 |
+
4. Submit with validation data and results
|
| 95 |
+
5. Undergo review by scientific advisory board
|
| 96 |
+
|
| 97 |
+
Communication Channels
|
| 98 |
+
|
| 99 |
+
Platform Purpose Link
|
| 100 |
+
GitLab Issues Bug reports, feature requests gitlab.com/gitdeeper4/tsu-wave/-/issues
|
| 101 |
+
GitHub Issues Mirror github.com/gitdeeper4/tsu-wave/issues
|
| 102 |
+
Email Direct contact gitdeeper@gmail.com
|
| 103 |
+
ORCID Researcher ID 0009-0003-8903-0029
|
| 104 |
+
|
| 105 |
+
Code of Conduct
|
| 106 |
+
|
| 107 |
+
· Be respectful and inclusive
|
| 108 |
+
· Provide constructive feedback
|
| 109 |
+
· Focus on scientific accuracy and technical excellence
|
| 110 |
+
· Acknowledge contributions appropriately
|
| 111 |
+
· Follow open science principles
|
| 112 |
+
|
| 113 |
+
License
|
| 114 |
+
|
| 115 |
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
| 116 |
+
|
| 117 |
+
---
|
| 118 |
+
|
| 119 |
+
Thank you for contributing to TSU-WAVE! 🌊
|
| 120 |
+
|
| 121 |
+
Together, we can improve tsunami early warning and save lives.
|
| 122 |
+
|
| 123 |
+
Last Updated: February 17, 2026
|
DEPLOY.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TSU-WAVE Deployment Guide
|
| 2 |
+
|
| 3 |
+
## Quick Deployment Options
|
| 4 |
+
|
| 5 |
+
### 1. Local Installation
|
| 6 |
+
```bash
|
| 7 |
+
# Clone repository
|
| 8 |
+
git clone https://gitlab.com/gitdeeper4/tsu-wave.git
|
| 9 |
+
cd tsu-wave
|
| 10 |
+
|
| 11 |
+
# Install dependencies
|
| 12 |
+
pip install -r requirements.txt
|
| 13 |
+
|
| 14 |
+
# Configure
|
| 15 |
+
cp config/config.example.yml config/config.yml
|
| 16 |
+
# Edit config.yml with your settings
|
| 17 |
+
|
| 18 |
+
# Run
|
| 19 |
+
python src/main.py
|
| 20 |
+
```
|
| 21 |
+
|
| 22 |
+
2. Docker Deployment
|
| 23 |
+
|
| 24 |
+
```bash
|
| 25 |
+
# Using Docker Compose
|
| 26 |
+
docker-compose up -d
|
| 27 |
+
|
| 28 |
+
# Services:
|
| 29 |
+
# - tsu-wave-core: NSWE solver
|
| 30 |
+
# - tsu-wave-api: FastAPI server
|
| 31 |
+
# - tsu-wave-dash: Streamlit dashboard
|
| 32 |
+
# - postgresql: TimescaleDB
|
| 33 |
+
# - redis: Cache
|
| 34 |
+
# - nginx: Reverse proxy
|
| 35 |
+
```
|
| 36 |
+
|
| 37 |
+
3. Netlify Deployment
|
| 38 |
+
|
| 39 |
+
```bash
|
| 40 |
+
# Website already configured in netlify.toml
|
| 41 |
+
netlify deploy --prod
|
| 42 |
+
```
|
| 43 |
+
|
| 44 |
+
4. API Access
|
| 45 |
+
|
| 46 |
+
```bash
|
| 47 |
+
# REST API
|
| 48 |
+
curl https://api.tsu-wave.io/v1/events/active
|
| 49 |
+
|
| 50 |
+
# WebSocket
|
| 51 |
+
wss://api.tsu-wave.io/ws/v1/realtime
|
| 52 |
+
```
|
| 53 |
+
|
| 54 |
+
Documentation
|
| 55 |
+
|
| 56 |
+
Full deployment guide: tsu-wave.netlify.app/documentation
|
| 57 |
+
|
| 58 |
+
Contact: gitdeeper@gmail.com
|
DESCRIPTION.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TSU-WAVE: Technical Project Description
|
| 2 |
+
|
| 3 |
+
## 1. General Definition
|
| 4 |
+
**TSU-WAVE** (Tsunami Spectral Understanding of Wave-Amplitude Variance and Energy) is a comprehensive physics-based framework for real-time analysis of tsunami wave front evolution, energy transfer dynamics, and coastal inundation forecasting.
|
| 5 |
+
|
| 6 |
+
## 2. Scientific Problem
|
| 7 |
+
Current tsunami warning systems rely primarily on seismic detection and linear propagation models, resulting in run-up prediction errors of 40–300%. No operational system integrates nonlinear wave front evolution, bathymetric energy focusing, hydrodynamic stability analysis, spectral energy decomposition, and micro-vorticity effects in real time.
|
| 8 |
+
|
| 9 |
+
## 3. Proposed Solution
|
| 10 |
+
Development of an integrated platform that performs continuous multi-parameter assessment of seven critical hydrodynamic indicators:
|
| 11 |
+
|
| 12 |
+
### 3.1 Seven-Parameter Hydrodynamic Framework
|
| 13 |
+
|
| 14 |
+
| Parameter | Name | Physical Meaning |
|
| 15 |
+
|-----------|------|------------------|
|
| 16 |
+
| **WCC** | Wave Front Celerity Coefficient | Measures departure from linear propagation speed |
|
| 17 |
+
| **KPR** | Kinetic-to-Potential Energy Transfer Ratio | Tracks energy partition and bore formation |
|
| 18 |
+
| **HFSI** | Hydrodynamic Front Stability Index | Quantifies wave front stability via Boussinesq parameter |
|
| 19 |
+
| **BECF** | Bathymetric Energy Concentration Factor | Energy amplification by convergent bathymetry |
|
| 20 |
+
| **SDB** | Spectral Dispersion Bandwidth | Tracks spectral spreading and harmonic transfer |
|
| 21 |
+
| **SBSP** | Shoreline Boundary Stress Parameter | Estimates inundation momentum flux |
|
| 22 |
+
| **SMVI** | Sub-Surface Micro-Vorticity Index | Detects vorticity at bathymetric slope breaks |
|
| 23 |
+
|
| 24 |
+
### 3.2 Governing Equations
|
| 25 |
+
|
| 26 |
+
**Nonlinear Shallow-Water Equations (NSWE):**
|
| 27 |
+
```
|
| 28 |
+
|
| 29 |
+
∂η/∂t + ∂[(H+η)u]/∂x + ∂[(H+η)v]/∂y = 0
|
| 30 |
+
∂u/∂t + u·∂u/∂x + v·∂u/∂y + g·∂η/∂x = −τ_bx/[ρ·(H+η)]
|
| 31 |
+
∂v/∂t + u·∂v/∂x + v·∂v/∂y + g·∂η/∂y = −τ_by/[ρ·(H+η)]
|
| 32 |
+
|
| 33 |
+
```
|
| 34 |
+
|
| 35 |
+
**Coastal Hazard Index (CHI):**
|
| 36 |
+
```
|
| 37 |
+
|
| 38 |
+
CHI = 0.12·WCC* + 0.19·KPR* + 0.24·HFSI* + 0.21·BECF* + 0.08·SDB* + 0.11·SBSP* + 0.05·SMVI*
|
| 39 |
+
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
## 4. Methodology
|
| 43 |
+
- Real-time data ingestion from DART buoys, tide gauges, and ADCP arrays
|
| 44 |
+
- Signal processing (Butterworth filtering, STA/LTA detection, FFT spectral analysis)
|
| 45 |
+
- NSWE numerical integration (Fortran 90 core with Python wrapper)
|
| 46 |
+
- Seven-parameter computation at sampling rates from 15 seconds to 5 minutes
|
| 47 |
+
- CHI aggregation with empirically-determined weights (23-event validation)
|
| 48 |
+
- Threshold-based alert generation with 67-minute mean lead time
|
| 49 |
+
|
| 50 |
+
## 5. Applications
|
| 51 |
+
|
| 52 |
+
| Application | Description |
|
| 53 |
+
|-------------|-------------|
|
| 54 |
+
| **Tsunami Warning Centers** | Real-time operational decision support |
|
| 55 |
+
| **Coastal Management** | Evacuation planning and zone mapping |
|
| 56 |
+
| **Research** | Hydrodynamic analysis of historical events |
|
| 57 |
+
| **Education** | Physics-based tsunami dynamics teaching |
|
| 58 |
+
| **Infrastructure Planning** | Siting of vertical evacuation structures |
|
| 59 |
+
|
| 60 |
+
## 6. Validation
|
| 61 |
+
- **23 documented events** (1990–2026)
|
| 62 |
+
- **Propagation distances**: 180 km – 14,200 km
|
| 63 |
+
- **Run-up heights**: 0.3 m – 40.5 m
|
| 64 |
+
- **Data sources**: 847 tide gauge records · 134 DART records · 712 run-up surveys
|
| 65 |
+
|
| 66 |
+
## 7. Key Physical Findings
|
| 67 |
+
|
| 68 |
+
| Finding | Value |
|
| 69 |
+
|---------|-------|
|
| 70 |
+
| Instability onset threshold | h/H₀ = 0.42 ± 0.05 |
|
| 71 |
+
| Bottom friction exponent (field) | β = 0.73 ± 0.04 |
|
| 72 |
+
| BECF–run-up correlation | ρ = +0.947 (p < 0.001) |
|
| 73 |
+
| SMVI–anomaly correlation | ρ = +0.831 (p < 0.001) |
|
| 74 |
+
| Second harmonic onset | h/H₀ > 0.35 → F₂ > 15% |
|
| 75 |
+
|
| 76 |
+
## 8. Expected Outputs
|
| 77 |
+
- ✅ Complete seven-parameter computation framework
|
| 78 |
+
- ✅ NSWE solver optimized for real-time operation
|
| 79 |
+
- ✅ Validation suite against 23 historical events
|
| 80 |
+
- ✅ BECF pre-computed maps for 180 global bays
|
| 81 |
+
- ✅ REST API and WebSocket for real-time data access
|
| 82 |
+
- ✅ Interactive dashboard for monitoring
|
| 83 |
+
- ✅ Complete documentation and research paper
|
| 84 |
+
- ✅ Open-source code on multiple platforms
|
| 85 |
+
|
| 86 |
+
## 9. Performance Metrics
|
| 87 |
+
| Metric | Value |
|
| 88 |
+
|--------|-------|
|
| 89 |
+
| Run-up Prediction Accuracy | 91.3% |
|
| 90 |
+
| Threat Detection Rate | 96.4% |
|
| 91 |
+
| False Alert Rate | 3.1% |
|
| 92 |
+
| Mean Lead Time | 67 minutes |
|
| 93 |
+
| Run-up RMSE | 11.7% |
|
| 94 |
+
|
| 95 |
+
## 10. Technical Specifications
|
| 96 |
+
|
| 97 |
+
| Component | Technology |
|
| 98 |
+
|-----------|------------|
|
| 99 |
+
| Core Solver | Fortran 90 (f2py) |
|
| 100 |
+
| Framework | Python 3.10+ |
|
| 101 |
+
| Database | TimescaleDB + PostgreSQL |
|
| 102 |
+
| Cache | Redis |
|
| 103 |
+
| API | FastAPI + JWT |
|
| 104 |
+
| Dashboard | Streamlit |
|
| 105 |
+
| Container | Docker + Kubernetes |
|
| 106 |
+
| CI/CD | GitLab CI |
|
| 107 |
+
|
| 108 |
+
## 11. Repository Access
|
| 109 |
+
|
| 110 |
+
| Platform | URL |
|
| 111 |
+
|----------|-----|
|
| 112 |
+
| **GitLab (primary)** | [gitlab.com/gitdeeper4/tsu-wave](https://gitlab.com/gitdeeper4/tsu-wave) |
|
| 113 |
+
| **GitHub (mirror)** | [github.com/gitdeeper4/tsu-wave](https://github.com/gitdeeper4/tsu-wave) |
|
| 114 |
+
| **Codeberg (mirror)** | [codeberg.org/gitdeeper4/tsu-wave](https://codeberg.org/gitdeeper4/tsu-wave) |
|
| 115 |
+
| **Bitbucket (mirror)** | [bitbucket.org/gitdeeper7/tsu-wave](https://bitbucket.org/gitdeeper7/tsu-wave) |
|
| 116 |
+
|
| 117 |
+
## 12. Documentation
|
| 118 |
+
- **Research Paper**: [TSU_WAVE_Research_Paper.md](TSU_WAVE_Research_Paper.md)
|
| 119 |
+
- **Website**: [tsu-wave.netlify.app](https://tsu-wave.netlify.app)
|
| 120 |
+
- **Documentation**: [tsu-wave.netlify.app/documentation](https://tsu-wave.netlify.app/documentation)
|
| 121 |
+
- **Dashboard**: [tsu-wave.netlify.app/dashboard](https://tsu-wave.netlify.app/dashboard)
|
| 122 |
+
|
| 123 |
+
---
|
| 124 |
+
|
| 125 |
+
**Principal Investigator**: Samir Baladi
|
| 126 |
+
**Contact**: gitdeeper@gmail.com
|
| 127 |
+
**ORCID**: 0009-0003-8903-0029
|
| 128 |
+
**Last Updated**: February 17, 2026
|
| 129 |
+
**Version**: 1.0.0
|
| 130 |
+
|
| 131 |
+
*"The physics of long-wave shoaling, bathymetric energy focusing, and hydrodynamic front instability are deterministic and measurable in real time."*
|
Dockerfile
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TSU-WAVE Dockerfile
|
| 2 |
+
# Multi-stage build for optimized production image
|
| 3 |
+
|
| 4 |
+
# ========== STAGE 1: Builder ==========
|
| 5 |
+
FROM python:3.10-slim as builder
|
| 6 |
+
|
| 7 |
+
WORKDIR /build
|
| 8 |
+
|
| 9 |
+
# Install build dependencies
|
| 10 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 11 |
+
gfortran \
|
| 12 |
+
liblapack-dev \
|
| 13 |
+
gcc \
|
| 14 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 15 |
+
|
| 16 |
+
# Copy requirements
|
| 17 |
+
COPY requirements.txt .
|
| 18 |
+
COPY requirements-dev.txt .
|
| 19 |
+
|
| 20 |
+
# Create virtual environment and install dependencies
|
| 21 |
+
RUN python -m venv /venv
|
| 22 |
+
ENV PATH="/venv/bin:$PATH"
|
| 23 |
+
|
| 24 |
+
RUN pip install --upgrade pip && \
|
| 25 |
+
pip install --no-cache-dir wheel && \
|
| 26 |
+
pip install --no-cache-dir -r requirements.txt && \
|
| 27 |
+
pip install --no-cache-dir numpy && \
|
| 28 |
+
if [ -f requirements-dev.txt ]; then pip install --no-cache-dir -r requirements-dev.txt; fi
|
| 29 |
+
|
| 30 |
+
# ========== STAGE 2: Fortran Compiler ==========
|
| 31 |
+
FROM python:3.10-slim as fortran-builder
|
| 32 |
+
|
| 33 |
+
WORKDIR /fortran-build
|
| 34 |
+
|
| 35 |
+
# Install Fortran compiler
|
| 36 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 37 |
+
gfortran \
|
| 38 |
+
liblapack-dev \
|
| 39 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 40 |
+
|
| 41 |
+
# Copy source and compile NSWE solver
|
| 42 |
+
COPY src/core/nswe_solver.f90 .
|
| 43 |
+
RUN python -c "import numpy; import numpy.f2py; numpy.f2py.main()" -c nswe_solver.f90 -m nswe_solver
|
| 44 |
+
|
| 45 |
+
# ========== STAGE 3: Final Image ==========
|
| 46 |
+
FROM python:3.10-slim
|
| 47 |
+
|
| 48 |
+
# Create tsu-wave user
|
| 49 |
+
RUN useradd --create-home --shell /bin/bash tsuwave
|
| 50 |
+
|
| 51 |
+
# Install runtime dependencies
|
| 52 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 53 |
+
liblapack3 \
|
| 54 |
+
libgfortran5 \
|
| 55 |
+
curl \
|
| 56 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 57 |
+
|
| 58 |
+
# Create directories
|
| 59 |
+
WORKDIR /app
|
| 60 |
+
|
| 61 |
+
# Copy virtual environment from builder
|
| 62 |
+
COPY --from=builder --chown=tsuwave:tsuwave /venv /venv
|
| 63 |
+
ENV PATH="/venv/bin:$PATH"
|
| 64 |
+
|
| 65 |
+
# Copy compiled Fortran module
|
| 66 |
+
COPY --from=fortran-builder --chown=tsuwave:tsuwave /fortran-build/nswe_solver.*.so /app/src/tsuwave/core/
|
| 67 |
+
|
| 68 |
+
# Copy application code
|
| 69 |
+
COPY --chown=tsuwave:tsuwave . .
|
| 70 |
+
|
| 71 |
+
# Create necessary directories with proper permissions
|
| 72 |
+
RUN mkdir -p /app/data /app/logs /app/config && \
|
| 73 |
+
chown -R tsuwave:tsuwave /app
|
| 74 |
+
|
| 75 |
+
# Switch to non-root user
|
| 76 |
+
USER tsuwave
|
| 77 |
+
|
| 78 |
+
# Expose ports
|
| 79 |
+
EXPOSE 8000 8080
|
| 80 |
+
|
| 81 |
+
# Health check
|
| 82 |
+
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
| 83 |
+
CMD curl -f http://localhost:8000/health || exit 1
|
| 84 |
+
|
| 85 |
+
# Set environment variables
|
| 86 |
+
ENV PYTHONPATH=/app/src
|
| 87 |
+
ENV TSUWAVE_ENV=production
|
| 88 |
+
ENV TSUWAVE_CONFIG=/app/config/config.yml
|
| 89 |
+
|
| 90 |
+
# Default command
|
| 91 |
+
CMD ["uvicorn", "tsuwave.api.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
|
| 92 |
+
|
| 93 |
+
# Alternative commands:
|
| 94 |
+
# CMD ["streamlit", "run", "src/tsuwave/dashboard/app.py", "--server.port=8080", "--server.address=0.0.0.0"]
|
| 95 |
+
# CMD ["python", "src/main.py"]
|
INSTALL.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TSU-WAVE Installation Guide
|
| 2 |
+
|
| 3 |
+
## System Requirements
|
| 4 |
+
|
| 5 |
+
### Minimum Requirements
|
| 6 |
+
- **CPU**: 4 cores, 2.5 GHz
|
| 7 |
+
- **RAM**: 8 GB
|
| 8 |
+
- **Storage**: 20 GB free space
|
| 9 |
+
- **OS**: Ubuntu 20.04+, Debian 11+, macOS 12+, Windows 10+ (WSL2)
|
| 10 |
+
|
| 11 |
+
### Recommended Requirements
|
| 12 |
+
- **CPU**: 16+ cores, 3.0+ GHz
|
| 13 |
+
- **RAM**: 32+ GB
|
| 14 |
+
- **Storage**: 100+ GB SSD
|
| 15 |
+
- **OS**: Ubuntu 22.04 LTS or equivalent
|
| 16 |
+
|
| 17 |
+
### Software Prerequisites
|
| 18 |
+
- Python 3.10 or higher
|
| 19 |
+
- PostgreSQL 14+ with TimescaleDB extension
|
| 20 |
+
- Redis 7+
|
| 21 |
+
- Docker 20.10+ (optional, for containerized deployment)
|
| 22 |
+
- Git
|
| 23 |
+
|
| 24 |
+
---
|
| 25 |
+
|
| 26 |
+
## Installation Methods
|
| 27 |
+
|
| 28 |
+
## Method 1: Quick Install (pip) - Coming Soon
|
| 29 |
+
```bash
|
| 30 |
+
# Once available on PyPI
|
| 31 |
+
pip install tsu-wave
|
| 32 |
+
```
|
| 33 |
+
|
| 34 |
+
---
|
| 35 |
+
|
| 36 |
+
Method 2: Source Installation
|
| 37 |
+
|
| 38 |
+
Step 1: Clone the Repository
|
| 39 |
+
|
| 40 |
+
```bash
|
| 41 |
+
# From GitLab (primary)
|
| 42 |
+
git clone https://gitlab.com/gitdeeper4/tsu-wave.git
|
| 43 |
+
cd tsu-wave
|
| 44 |
+
|
| 45 |
+
# Or from GitHub (mirror)
|
| 46 |
+
git clone https://github.com/gitdeeper4/tsu-wave.git
|
| 47 |
+
cd tsu-wave
|
| 48 |
+
```
|
| 49 |
+
|
| 50 |
+
Step 2: Create Virtual Environment
|
| 51 |
+
|
| 52 |
+
```bash
|
| 53 |
+
# Create virtual environment
|
| 54 |
+
python3 -m venv venv
|
| 55 |
+
|
| 56 |
+
# Activate it
|
| 57 |
+
source venv/bin/activate # On Linux/macOS
|
| 58 |
+
# or
|
| 59 |
+
venv\Scripts\activate # On Windows (WSL2 recommended)
|
| 60 |
+
```
|
| 61 |
+
|
| 62 |
+
Step 3: Install Dependencies
|
| 63 |
+
|
| 64 |
+
```bash
|
| 65 |
+
# Install required packages
|
| 66 |
+
pip install --upgrade pip
|
| 67 |
+
pip install -r requirements.txt
|
| 68 |
+
|
| 69 |
+
# Install development dependencies (optional)
|
| 70 |
+
pip install -r requirements-dev.txt
|
| 71 |
+
```
|
| 72 |
+
|
| 73 |
+
Step 4: Compile Fortran NSWE Solver
|
| 74 |
+
|
| 75 |
+
```bash
|
| 76 |
+
# Navigate to core directory
|
| 77 |
+
cd src/core
|
| 78 |
+
|
| 79 |
+
# Compile Fortran code with f2py
|
| 80 |
+
f2py -c nswe_solver.f90 -m nswe_solver
|
| 81 |
+
|
| 82 |
+
# Return to project root
|
| 83 |
+
cd ../..
|
| 84 |
+
```
|
| 85 |
+
|
| 86 |
+
Step 5: Configure the System
|
| 87 |
+
|
| 88 |
+
```bash
|
| 89 |
+
# Copy example configuration
|
| 90 |
+
cp config/config.example.yml config/config.yml
|
| 91 |
+
|
| 92 |
+
# Edit configuration file with your settings
|
| 93 |
+
nano config/config.yml # or vim, emacs, etc.
|
| 94 |
+
```
|
| 95 |
+
|
| 96 |
+
Step 6: Set Up Database
|
| 97 |
+
|
| 98 |
+
```bash
|
| 99 |
+
# Create PostgreSQL database
|
| 100 |
+
sudo -u postgres psql <<EOF
|
| 101 |
+
CREATE DATABASE tsuwave;
|
| 102 |
+
CREATE USER tsuwave_user WITH PASSWORD 'your_password';
|
| 103 |
+
GRANT ALL PRIVILEGES ON DATABASE tsuwave TO tsuwave_user;
|
| 104 |
+
\c tsuwave
|
| 105 |
+
CREATE EXTENSION IF NOT EXISTS timescaledb;
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2026 Samir Baladi and TSU-WAVE Contributors
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
MANIFEST.in
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Include documentation
|
| 2 |
+
include README.md
|
| 3 |
+
include LICENSE
|
| 4 |
+
include CHANGELOG.md
|
| 5 |
+
include AUTHORS.md
|
| 6 |
+
include CONTRIBUTING.md
|
| 7 |
+
|
| 8 |
+
# Include requirements
|
| 9 |
+
include requirements.txt
|
| 10 |
+
include requirements-dev.txt
|
| 11 |
+
|
| 12 |
+
# Exclude tests and development files
|
| 13 |
+
recursive-exclude tests *
|
| 14 |
+
recursive-exclude docs *
|
| 15 |
+
exclude .gitignore
|
| 16 |
+
exclude .pre-commit-config.yaml
|
| 17 |
+
exclude .env
|
Makefile
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TSU-WAVE Makefile
|
| 2 |
+
|
| 3 |
+
.PHONY: help install dev test clean build docs docker run stop lint format
|
| 4 |
+
|
| 5 |
+
help:
|
| 6 |
+
@echo "TSU-WAVE Makefile"
|
| 7 |
+
@echo ""
|
| 8 |
+
@echo "Usage: make [target]"
|
| 9 |
+
@echo ""
|
| 10 |
+
@echo "Targets:"
|
| 11 |
+
@echo " install Install production dependencies"
|
| 12 |
+
@echo " dev Install development dependencies"
|
| 13 |
+
@echo " test Run tests"
|
| 14 |
+
@echo " clean Clean build artifacts"
|
| 15 |
+
@echo " build Build Python package"
|
| 16 |
+
@echo " docs Build documentation"
|
| 17 |
+
@echo " docker Build Docker image"
|
| 18 |
+
@echo " run Run with Docker Compose"
|
| 19 |
+
@echo " stop Stop Docker Compose"
|
| 20 |
+
@echo " lint Run linters"
|
| 21 |
+
@echo " format Format code with black and isort"
|
| 22 |
+
|
| 23 |
+
install:
|
| 24 |
+
pip install --upgrade pip
|
| 25 |
+
pip install -r requirements.txt
|
| 26 |
+
@cd src/core && f2py -c nswe_solver.f90 -m nswe_solver || echo "Warning: Fortran compilation failed"
|
| 27 |
+
|
| 28 |
+
dev: install
|
| 29 |
+
pip install -r requirements-dev.txt
|
| 30 |
+
pre-commit install
|
| 31 |
+
|
| 32 |
+
test:
|
| 33 |
+
pytest tests/ -v --cov=src/
|
| 34 |
+
|
| 35 |
+
test-coverage:
|
| 36 |
+
pytest tests/ --cov=src/ --cov-report=html --cov-report=term
|
| 37 |
+
|
| 38 |
+
clean:
|
| 39 |
+
rm -rf build/
|
| 40 |
+
rm -rf dist/
|
| 41 |
+
rm -rf *.egg-info
|
| 42 |
+
rm -rf .pytest_cache/
|
| 43 |
+
rm -rf .mypy_cache/
|
| 44 |
+
rm -rf htmlcov/
|
| 45 |
+
rm -rf coverage.xml
|
| 46 |
+
rm -rf .coverage
|
| 47 |
+
rm -rf docs/_build/
|
| 48 |
+
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
| 49 |
+
find . -type f -name "*.pyc" -delete
|
| 50 |
+
find . -type f -name "*.so" -delete
|
| 51 |
+
find . -type f -name "*.o" -delete
|
| 52 |
+
find . -type f -name "*.mod" -delete
|
| 53 |
+
|
| 54 |
+
build: clean
|
| 55 |
+
python -m build
|
| 56 |
+
@echo "Package built in dist/"
|
| 57 |
+
|
| 58 |
+
docs:
|
| 59 |
+
cd docs && make html
|
| 60 |
+
@echo "Documentation built in docs/_build/html/"
|
| 61 |
+
|
| 62 |
+
docker:
|
| 63 |
+
docker build -t tsu-wave:latest .
|
| 64 |
+
docker build -t tsu-wave:$(shell git describe --tags 2>/dev/null || echo "dev") .
|
| 65 |
+
|
| 66 |
+
docker-compose:
|
| 67 |
+
docker-compose up -d
|
| 68 |
+
|
| 69 |
+
docker-compose-dev:
|
| 70 |
+
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
|
| 71 |
+
|
| 72 |
+
run: docker-compose
|
| 73 |
+
@echo "TSU-WAVE running at http://localhost:8080"
|
| 74 |
+
@echo "API at http://localhost:8000/docs"
|
| 75 |
+
|
| 76 |
+
stop:
|
| 77 |
+
docker-compose down
|
| 78 |
+
|
| 79 |
+
logs:
|
| 80 |
+
docker-compose logs -f
|
| 81 |
+
|
| 82 |
+
lint:
|
| 83 |
+
flake8 src/ tests/
|
| 84 |
+
black --check src/ tests/
|
| 85 |
+
isort --check-only src/ tests/
|
| 86 |
+
mypy src/
|
| 87 |
+
|
| 88 |
+
format:
|
| 89 |
+
black src/ tests/
|
| 90 |
+
isort src/ tests/
|
| 91 |
+
|
| 92 |
+
check: lint test
|
| 93 |
+
|
| 94 |
+
dist: clean build
|
| 95 |
+
@echo "Distribution ready in dist/"
|
| 96 |
+
|
| 97 |
+
pypi: dist
|
| 98 |
+
twine upload dist/*
|
| 99 |
+
|
| 100 |
+
benchmark:
|
| 101 |
+
python scripts/run_benchmarks.py
|
| 102 |
+
|
| 103 |
+
validate:
|
| 104 |
+
python scripts/validate_all_events.py
|
| 105 |
+
|
| 106 |
+
init-db:
|
| 107 |
+
python scripts/setup_database.py
|
| 108 |
+
|
| 109 |
+
load-data:
|
| 110 |
+
python scripts/load_becf_maps.py
|
| 111 |
+
python scripts/load_validation_data.py
|
| 112 |
+
|
| 113 |
+
.PHONY: help install dev test test-coverage clean build docs docker docker-compose docker-compose-dev run stop logs lint format check dist pypi benchmark validate init-db load-data
|
PROJECT_SUMMARY.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TSU-WAVE Project Summary
|
| 2 |
+
|
| 3 |
+
## Project Overview
|
| 4 |
+
**TSU-WAVE** (Tsunami Spectral Understanding of Wave-Amplitude Variance and Energy) is a comprehensive physics-based framework for real-time analysis of tsunami wave front evolution, energy transfer dynamics, and coastal inundation forecasting.
|
| 5 |
+
|
| 6 |
+
## Key Specifications
|
| 7 |
+
|
| 8 |
+
| Attribute | Value |
|
| 9 |
+
|-----------|-------|
|
| 10 |
+
| **Version** | 1.0.0 |
|
| 11 |
+
| **Release Date** | February 17, 2026 |
|
| 12 |
+
| **License** | MIT |
|
| 13 |
+
| **Python Version** | 3.10+ |
|
| 14 |
+
| **Validation Events** | 23 documented tsunamis (1990–2026) |
|
| 15 |
+
| **Propagation Range** | 180 km – 14,200 km |
|
| 16 |
+
| **Run-up Range** | 0.3 m – 40.5 m |
|
| 17 |
+
|
| 18 |
+
## Performance Metrics
|
| 19 |
+
|
| 20 |
+
| Metric | Value |
|
| 21 |
+
|--------|-------|
|
| 22 |
+
| Run-up Prediction Accuracy | 91.3% |
|
| 23 |
+
| Threat Detection Rate | 96.4% |
|
| 24 |
+
| False Alert Rate | 3.1% |
|
| 25 |
+
| Mean Lead Time | 67 minutes |
|
| 26 |
+
| Run-up RMSE | 11.7% |
|
| 27 |
+
|
| 28 |
+
## Seven Hydrodynamic Parameters
|
| 29 |
+
|
| 30 |
+
| Parameter | Name | Threshold (Critical) |
|
| 31 |
+
|-----------|------|---------------------|
|
| 32 |
+
| **WCC** | Wave Front Celerity Coefficient | > 1.58 |
|
| 33 |
+
| **KPR** | Kinetic-to-Potential Energy Ratio | > 2.0 |
|
| 34 |
+
| **HFSI** | Hydrodynamic Front Stability Index | < 0.40 |
|
| 35 |
+
| **BECF** | Bathymetric Energy Concentration Factor | > 6.0 |
|
| 36 |
+
| **SDB** | Spectral Dispersion Bandwidth | < 1.0 |
|
| 37 |
+
| **SBSP** | Shoreline Boundary Stress Parameter | > 1.2 |
|
| 38 |
+
| **SMVI** | Sub-Surface Micro-Vorticity Index | > 0.6 |
|
| 39 |
+
|
| 40 |
+
## Key Physical Findings
|
| 41 |
+
|
| 42 |
+
| Finding | Value |
|
| 43 |
+
|---------|-------|
|
| 44 |
+
| Instability onset threshold | h/H₀ = 0.42 ± 0.05 |
|
| 45 |
+
| Bottom friction exponent (field) | β = 0.73 ± 0.04 |
|
| 46 |
+
| BECF–run-up correlation | ρ = +0.947 |
|
| 47 |
+
| SMVI–anomaly correlation | ρ = +0.831 |
|
| 48 |
+
| Second harmonic onset | h/H₀ > 0.35 → F₂ > 15% |
|
| 49 |
+
|
| 50 |
+
## Research Team
|
| 51 |
+
|
| 52 |
+
| Author | Role | Affiliation |
|
| 53 |
+
|--------|------|-------------|
|
| 54 |
+
| Samir Baladi | Principal Investigator | Ronin Institute |
|
| 55 |
+
| Dr. Elena Marchetti | SMVI Parameterization | Mediterranean Tsunami Research Center |
|
| 56 |
+
| Prof. Kenji Watanabe | DART Assimilation | Pacific Ocean Sciences Institute |
|
| 57 |
+
| Dr. Lars Petersen | Spectral/Friction Analysis | Nordic Coastal Engineering Laboratory |
|
| 58 |
+
| Dr. Amira Hassan | Shoreline Dynamics | Red Sea Marine Sciences Center |
|
| 59 |
+
|
| 60 |
+
## Funding
|
| 61 |
+
- **NSF-OCE Grant**: $1.8M
|
| 62 |
+
- **UNESCO-IOC**: €420,000
|
| 63 |
+
- **Ronin Institute**: $45,000
|
| 64 |
+
- **Total**: $2.27M
|
| 65 |
+
|
| 66 |
+
## Repositories
|
| 67 |
+
|
| 68 |
+
| Platform | URL |
|
| 69 |
+
|----------|-----|
|
| 70 |
+
| GitLab | gitlab.com/gitdeeper4/tsu-wave |
|
| 71 |
+
| GitHub | github.com/gitdeeper4/tsu-wave |
|
| 72 |
+
| Codeberg | codeberg.org/gitdeeper4/tsu-wave |
|
| 73 |
+
| Bitbucket | bitbucket.org/gitdeeper7/tsu-wave |
|
| 74 |
+
|
| 75 |
+
## Documentation
|
| 76 |
+
- **Website**: tsu-wave.netlify.app
|
| 77 |
+
- **Dashboard**: tsu-wave.netlify.app/dashboard
|
| 78 |
+
- **Documentation**: tsu-wave.netlify.app/documentation
|
| 79 |
+
- **Research Paper**: TSU_WAVE_Research_Paper.md
|
| 80 |
+
|
| 81 |
+
## Contact
|
| 82 |
+
**Samir Baladi**
|
| 83 |
+
Email: gitdeeper@gmail.com
|
| 84 |
+
ORCID: 0009-0003-8903-0029
|
| 85 |
+
|
| 86 |
+
**Last Updated**: February 17, 2026
|
QUICK_START.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TSU-WAVE Quick Start Guide
|
| 2 |
+
|
| 3 |
+
Get TSU-WAVE running in 5 minutes or less.
|
| 4 |
+
|
| 5 |
+
## 1. Quick Installation (Docker)
|
| 6 |
+
|
| 7 |
+
```bash
|
| 8 |
+
# Clone and run in one command
|
| 9 |
+
git clone https://gitlab.com/gitdeeper4/tsu-wave.git
|
| 10 |
+
cd tsu-wave
|
| 11 |
+
docker-compose up -d
|
| 12 |
+
```
|
| 13 |
+
|
| 14 |
+
That's it! Your TSU-WAVE system is now running at:
|
| 15 |
+
|
| 16 |
+
· Dashboard: http://localhost:8080
|
| 17 |
+
· API Docs: http://localhost:8000/docs
|
| 18 |
+
|
| 19 |
+
2. Try the Live Demo
|
| 20 |
+
|
| 21 |
+
Visit our live dashboard: tsu-wave.netlify.app/dashboard
|
| 22 |
+
|
| 23 |
+
3. Basic Python Usage
|
| 24 |
+
|
| 25 |
+
```python
|
| 26 |
+
from tsuwave import TSUWave
|
| 27 |
+
|
| 28 |
+
# Initialize
|
| 29 |
+
tsw = TSUWave()
|
| 30 |
+
|
| 31 |
+
# Get current Coastal Hazard Index for a zone
|
| 32 |
+
chi = tsw.get_chi(zone="hilo_bay_hawaii")
|
| 33 |
+
print(f"CHI: {chi:.3f}")
|
| 34 |
+
|
| 35 |
+
# Get all seven parameters
|
| 36 |
+
params = tsw.get_parameters(zone="hilo_bay_hawaii")
|
| 37 |
+
print(params)
|
| 38 |
+
|
| 39 |
+
# Run-up forecast
|
| 40 |
+
forecast = tsw.forecast_runup(zone="khao_lak", source="sumatra")
|
| 41 |
+
print(f"Predicted run-up: {forecast['height_m']}m")
|
| 42 |
+
```
|
| 43 |
+
|
| 44 |
+
4. API Quick Start
|
| 45 |
+
|
| 46 |
+
```bash
|
| 47 |
+
# Get active events
|
| 48 |
+
curl https://api.tsu-wave.io/v1/events/active
|
| 49 |
+
|
| 50 |
+
# Get parameters for an event
|
| 51 |
+
curl https://api.tsu-wave.io/v1/events/EV-2011-001/parameters
|
| 52 |
+
```
|
| 53 |
+
|
| 54 |
+
5. Command Line
|
| 55 |
+
|
| 56 |
+
```bash
|
| 57 |
+
# Monitor live events
|
| 58 |
+
tsu-wave monitor
|
| 59 |
+
|
| 60 |
+
# Compute CHI for a zone
|
| 61 |
+
tsu-wave chi --zone hilo_bay
|
| 62 |
+
|
| 63 |
+
# Validate against historical event
|
| 64 |
+
tsu-wave validate --event tohoku_2011
|
| 65 |
+
```
|
| 66 |
+
|
| 67 |
+
6. System Requirements (Minimal)
|
| 68 |
+
|
| 69 |
+
· Docker 20.10+ (for containerized install)
|
| 70 |
+
· Python 3.10+ (for source install)
|
| 71 |
+
· 4GB RAM free
|
| 72 |
+
· 10GB disk space
|
| 73 |
+
|
| 74 |
+
7. Need Help?
|
| 75 |
+
|
| 76 |
+
· Full documentation: tsu-wave.netlify.app/docs
|
| 77 |
+
· Issues: gitlab.com/gitdeeper4/tsu-wave/-/issues
|
| 78 |
+
· Email: gitdeeper@gmail.com
|
| 79 |
+
|
| 80 |
+
---
|
| 81 |
+
|
| 82 |
+
Last Updated: February 17, 2026
|
| 83 |
+
Version: 1.0.0
|
README.md
ADDED
|
@@ -0,0 +1,486 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: TSU-WAVE Tsunami Dashboard
|
| 3 |
+
emoji: 🌊
|
| 4 |
+
colorFrom: blue
|
| 5 |
+
colorTo: green
|
| 6 |
+
sdk: docker
|
| 7 |
+
sdk_version: "20.10"
|
| 8 |
+
app_file: src/tsuwave/dashboard/app.py
|
| 9 |
+
pinned: false
|
| 10 |
+
tags:
|
| 11 |
+
- tsunami
|
| 12 |
+
- wave-analysis
|
| 13 |
+
- hydrodynamics
|
| 14 |
+
- coastal-engineering
|
| 15 |
+
- disaster-prevention
|
| 16 |
+
- early-warning-system
|
| 17 |
+
- python
|
| 18 |
+
- fastapi
|
| 19 |
+
- streamlit
|
| 20 |
+
- docker
|
| 21 |
+
---
|
| 22 |
+
---
|
| 23 |
+
title: TSU-WAVE Tsunami Dashboard
|
| 24 |
+
emoji: 🌊
|
| 25 |
+
colorFrom: blue
|
| 26 |
+
colorTo: green
|
| 27 |
+
sdk: docker
|
| 28 |
+
sdk_version: "20.10"
|
| 29 |
+
app_file: src/tsuwave/dashboard/app.py
|
| 30 |
+
pinned: false
|
| 31 |
+
tags:
|
| 32 |
+
- tsunami
|
| 33 |
+
- wave-analysis
|
| 34 |
+
- hydrodynamics
|
| 35 |
+
- coastal-engineering
|
| 36 |
+
- disaster-prevention
|
| 37 |
+
- early-warning-system
|
| 38 |
+
- python
|
| 39 |
+
- fastapi
|
| 40 |
+
- streamlit
|
| 41 |
+
- docker
|
| 42 |
+
--------
|
| 43 |
+
|
| 44 |
+
<div align="center">
|
| 45 |
+
|
| 46 |
+
# 🌊 TSU-WAVE
|
| 47 |
+
|
| 48 |
+
### Tsunami Spectral Understanding of Wave-Amplitude Variance and Energy
|
| 49 |
+
|
| 50 |
+
**A Multi-Parameter Hydrodynamic Framework for Real-Time Tsunami Wave Front Evolution,
|
| 51 |
+
Energy Transfer Analysis, and Coastal Inundation Forecasting**
|
| 52 |
+
|
| 53 |
+
---
|
| 54 |
+
|
| 55 |
+
[](https://gitlab.com/gitdeeper4/tsu-wave/-/releases)
|
| 56 |
+
[](https://pypi.org/project/tsu-wave/)
|
| 57 |
+
[](LICENSE)
|
| 58 |
+
[](https://doi.org/10.5281/zenodo.18679361)
|
| 59 |
+
[](https://osf.io/7t6mr)
|
| 60 |
+
[](https://www.python.org/)
|
| 61 |
+
[](#performance)
|
| 62 |
+
[](#performance)
|
| 63 |
+
|
| 64 |
+
---
|
| 65 |
+
|
| 66 |
+
**[🖥️ Live Dashboard](https://tsu-wave.netlify.app/dashboard)** ·
|
| 67 |
+
**[📊 Reports](https://tsu-wave.netlify.app/reports)** ·
|
| 68 |
+
**[📦 PyPI](https://pypi.org/project/tsu-wave/)** ·
|
| 69 |
+
**[📄 Research Paper (DOI)](https://doi.org/10.5281/zenodo.18679361)** ·
|
| 70 |
+
**[🔬 OSF Repository](https://osf.io/7t6mr)** ·
|
| 71 |
+
**[📖 Documentation](https://tsu-wave.netlify.app/documentation)**
|
| 72 |
+
|
| 73 |
+
</div>
|
| 74 |
+
|
| 75 |
+
---
|
| 76 |
+
|
| 77 |
+
## 📋 Table of Contents
|
| 78 |
+
|
| 79 |
+
- [Overview](#-overview)
|
| 80 |
+
- [Performance Metrics](#-performance-metrics)
|
| 81 |
+
- [Seven Hydrodynamic Parameters](#-seven-hydrodynamic-parameters)
|
| 82 |
+
- [Alert Levels](#-alert-levels)
|
| 83 |
+
- [Quick Start](#-quick-start)
|
| 84 |
+
- [Installation](#-installation)
|
| 85 |
+
- [Python API](#-python-api)
|
| 86 |
+
- [REST API](#-rest-api)
|
| 87 |
+
- [Architecture](#-architecture)
|
| 88 |
+
- [Validation](#-validation)
|
| 89 |
+
- [Key Scientific Findings](#-key-scientific-findings)
|
| 90 |
+
- [Research & Citation](#-research--citation)
|
| 91 |
+
- [Open Science & Registration](#-open-science--registration)
|
| 92 |
+
- [Research Team](#-research-team)
|
| 93 |
+
- [Repositories](#-repositories)
|
| 94 |
+
- [License](#-license)
|
| 95 |
+
|
| 96 |
+
---
|
| 97 |
+
|
| 98 |
+
## 🌊 Overview
|
| 99 |
+
|
| 100 |
+
**TSU-WAVE** is a physics-based framework for real-time analysis of tsunami wave front evolution, energy transfer dynamics, and coastal inundation forecasting. It integrates **seven hydrodynamic parameters** into a **Composite Hazard Index (CHI)** that enables operational coastal warning centers to issue alerts up to **67 minutes before landfall**.
|
| 101 |
+
|
| 102 |
+
The system is validated against **23 documented tsunami events** spanning a **36-year period (1990–2026)**, across propagation distances of 180 km to 14,200 km, and verified against **712 field-measured run-up points** from the International Tsunami Survey Team (ITST) database.
|
| 103 |
+
|
| 104 |
+
```
|
| 105 |
+
Seismic Source → NSWE Propagation → Bathymetric Modulation (BECF)
|
| 106 |
+
→ Front Stability Tracking (HFSI)
|
| 107 |
+
→ Spectral Energy Analysis (SDB, KPR)
|
| 108 |
+
→ Shoreline Boundary Resolution (SBSP)
|
| 109 |
+
→ Micro-Vorticity Correction (SMVI)
|
| 110 |
+
→ CHI Composite Index → Run-up Forecast + Alert
|
| 111 |
+
```
|
| 112 |
+
|
| 113 |
+
### Why TSU-WAVE?
|
| 114 |
+
|
| 115 |
+
| Existing Systems | Limitation | TSU-WAVE Solution |
|
| 116 |
+
|---|---|---|
|
| 117 |
+
| DART buoy arrays (NOAA) | Open-ocean only, no shelf dynamics | Full propagation path integration |
|
| 118 |
+
| Tide gauge networks (GLOSS) | Point measurements, no wave geometry | 7-parameter front evolution tracking |
|
| 119 |
+
| Linear codes (MOST, TUNAMI-N2) | Omits nonlinear shoaling | Nonlinear NSWE solver |
|
| 120 |
+
| Satellite altimetry (Jason-3) | 10-day repeat cycle | Real-time 1-minute resolution |
|
| 121 |
+
|
| 122 |
+
---
|
| 123 |
+
|
| 124 |
+
## 📈 Performance Metrics
|
| 125 |
+
|
| 126 |
+
| Metric | Value |
|
| 127 |
+
|--------|-------|
|
| 128 |
+
| **Run-up Prediction Accuracy** | **91.3%** |
|
| 129 |
+
| **Threat Detection Rate** | **96.4%** |
|
| 130 |
+
| **False Alert Rate** | **3.1%** |
|
| 131 |
+
| **Mean Forecast Lead Time** | **67 minutes** before landfall |
|
| 132 |
+
| **Run-up RMSE** | 11.7% |
|
| 133 |
+
| **Validation Events** | 23 (1990–2026) |
|
| 134 |
+
| **Validation Points** | 712 field run-up measurements |
|
| 135 |
+
| **Propagation Range** | 180 km – 14,200 km |
|
| 136 |
+
| **Run-up Range** | 0.3 m – 40.5 m |
|
| 137 |
+
|
| 138 |
+
---
|
| 139 |
+
|
| 140 |
+
## 🔬 Seven Hydrodynamic Parameters
|
| 141 |
+
|
| 142 |
+
TSU-WAVE integrates seven physically independent indicators, each derived from governing equations of long-wave hydrodynamics:
|
| 143 |
+
|
| 144 |
+
| # | Code | Parameter | Physical Meaning | Critical Threshold |
|
| 145 |
+
|---|------|-----------|------------------|--------------------|
|
| 146 |
+
| 1 | **WCC** | Wave Front Celerity Coefficient | Normalized wave speed vs. shallow-water celerity √(gd) | > 1.58 |
|
| 147 |
+
| 2 | **KPR** | Kinetic-to-Potential Energy Ratio | Depth-integrated energy transfer state | > 2.0 |
|
| 148 |
+
| 3 | **HFSI** | Hydrodynamic Front Stability Index | Wave front coherence via h/H₀ ratio | < 0.40 |
|
| 149 |
+
| 4 | **BECF** | Bathymetric Energy Concentration Factor | Coastal amplification from bay geometry | > 6.0 |
|
| 150 |
+
| 5 | **SDB** | Spectral Dispersion Bandwidth | Frequency-domain energy spread (1–120 min band) | < 1.0 |
|
| 151 |
+
| 6 | **SBSP** | Shoreline Boundary Stress Parameter | Wave loading at land–sea interface | > 1.2 |
|
| 152 |
+
| 7 | **SMVI** | Sub-Surface Micro-Vorticity Index | Rotational flow at bathymetric discontinuities | > 0.6 |
|
| 153 |
+
|
| 154 |
+
### Composite Hazard Index (CHI)
|
| 155 |
+
|
| 156 |
+
$$CHI = \sum_{i=1}^{7} w_i \cdot P_i^{(n)}$$
|
| 157 |
+
|
| 158 |
+
Where $P_i^{(n)}$ is each normalized parameter and optimized weights are:
|
| 159 |
+
|
| 160 |
+
```
|
| 161 |
+
w₁(WCC)=0.18 w₂(KPR)=0.16 w₃(HFSI)=0.17 w₄(BECF)=0.20
|
| 162 |
+
w₅(SDB)=0.11 w₆(SBSP)=0.13 w₇(SMVI)=0.05
|
| 163 |
+
```
|
| 164 |
+
|
| 165 |
+
---
|
| 166 |
+
|
| 167 |
+
## 🚨 Alert Levels
|
| 168 |
+
|
| 169 |
+
| CHI Range | Level | Status | Action |
|
| 170 |
+
|-----------|-------|--------|--------|
|
| 171 |
+
| < 0.35 | 🟢 **MONITOR** | No significant hazard | Passive monitoring |
|
| 172 |
+
| 0.35 – 0.54 | 🟡 **WATCH** | Elevated — Advisory issued | Heightened readiness |
|
| 173 |
+
| 0.55 – 0.74 | 🟠 **WARNING** | High — Evacuation recommended | Activate protocols |
|
| 174 |
+
| ≥ 0.75 | 🔴 **EXTREME** | Imminent — Immediate evacuation | Full emergency response |
|
| 175 |
+
|
| 176 |
+
---
|
| 177 |
+
|
| 178 |
+
## ⚡ Quick Start
|
| 179 |
+
|
| 180 |
+
### Docker (Recommended — 5 minutes)
|
| 181 |
+
|
| 182 |
+
```bash
|
| 183 |
+
git clone https://gitlab.com/gitdeeper4/tsu-wave.git
|
| 184 |
+
cd tsu-wave
|
| 185 |
+
docker-compose up -d
|
| 186 |
+
```
|
| 187 |
+
|
| 188 |
+
Your system is running at:
|
| 189 |
+
- **Dashboard**: http://localhost:8080
|
| 190 |
+
- **API Docs**: http://localhost:8000/docs
|
| 191 |
+
|
| 192 |
+
### pip
|
| 193 |
+
|
| 194 |
+
```bash
|
| 195 |
+
pip install tsu-wave
|
| 196 |
+
```
|
| 197 |
+
|
| 198 |
+
📦 [https://pypi.org/project/tsu-wave/](https://pypi.org/project/tsu-wave/)
|
| 199 |
+
|
| 200 |
+
### Try the Live Demo
|
| 201 |
+
|
| 202 |
+
🖥️ [https://tsu-wave.netlify.app/dashboard](https://tsu-wave.netlify.app/dashboard)
|
| 203 |
+
|
| 204 |
+
---
|
| 205 |
+
|
| 206 |
+
## 🛠️ Installation
|
| 207 |
+
|
| 208 |
+
### System Requirements
|
| 209 |
+
|
| 210 |
+
| | Minimum | Recommended |
|
| 211 |
+
|---|---|---|
|
| 212 |
+
| **CPU** | 4 cores, 2.5 GHz | 16+ cores, 3.0+ GHz |
|
| 213 |
+
| **RAM** | 8 GB | 32+ GB |
|
| 214 |
+
| **Storage** | 20 GB | 100+ GB SSD |
|
| 215 |
+
| **OS** | Ubuntu 20.04+, macOS 12+, Windows 10+ (WSL2) | Ubuntu 22.04 LTS |
|
| 216 |
+
| **Python** | 3.10+ | 3.11+ |
|
| 217 |
+
|
| 218 |
+
### Source Installation
|
| 219 |
+
|
| 220 |
+
```bash
|
| 221 |
+
# 1. Clone
|
| 222 |
+
git clone https://gitlab.com/gitdeeper4/tsu-wave.git
|
| 223 |
+
cd tsu-wave
|
| 224 |
+
|
| 225 |
+
# 2. Virtual environment
|
| 226 |
+
python3 -m venv venv && source venv/bin/activate
|
| 227 |
+
|
| 228 |
+
# 3. Dependencies
|
| 229 |
+
pip install --upgrade pip
|
| 230 |
+
pip install -r requirements.txt
|
| 231 |
+
|
| 232 |
+
# 4. Compile Fortran NSWE solver
|
| 233 |
+
cd src/core && f2py -c nswe_solver.f90 -m nswe_solver && cd ../..
|
| 234 |
+
|
| 235 |
+
# 5. Configure
|
| 236 |
+
cp config/config.example.yml config/config.yml
|
| 237 |
+
|
| 238 |
+
# 6. Initialize database
|
| 239 |
+
python scripts/init_db.py
|
| 240 |
+
|
| 241 |
+
# 7. Launch
|
| 242 |
+
python -m tsuwave.api.main # API server → :8000
|
| 243 |
+
streamlit run tsuwave/dashboard/app.py # Dashboard → :8501
|
| 244 |
+
```
|
| 245 |
+
|
| 246 |
+
---
|
| 247 |
+
|
| 248 |
+
## 🐍 Python API
|
| 249 |
+
|
| 250 |
+
```python
|
| 251 |
+
from tsuwave import TSUWave
|
| 252 |
+
|
| 253 |
+
# Initialize
|
| 254 |
+
tsw = TSUWave()
|
| 255 |
+
|
| 256 |
+
# Get Composite Hazard Index for a coastal zone
|
| 257 |
+
chi = tsw.get_chi(zone="hilo_bay_hawaii")
|
| 258 |
+
print(f"CHI: {chi:.3f}")
|
| 259 |
+
|
| 260 |
+
# Get all seven parameters
|
| 261 |
+
params = tsw.get_parameters(zone="hilo_bay_hawaii")
|
| 262 |
+
for name, value in params.items():
|
| 263 |
+
print(f" {name}: {value:.4f}")
|
| 264 |
+
|
| 265 |
+
# Run-up forecast
|
| 266 |
+
forecast = tsw.forecast_runup(zone="khao_lak", source="sumatra")
|
| 267 |
+
print(f"Predicted run-up: {forecast['height_m']:.1f} m")
|
| 268 |
+
print(f"Lead time: {forecast['lead_time_min']} min")
|
| 269 |
+
|
| 270 |
+
# Validate against historical event
|
| 271 |
+
result = tsw.validate(event="tohoku_2011")
|
| 272 |
+
print(f"MAPE: {result['mape']:.1f}%")
|
| 273 |
+
```
|
| 274 |
+
|
| 275 |
+
---
|
| 276 |
+
|
| 277 |
+
## 🌐 REST API
|
| 278 |
+
|
| 279 |
+
```bash
|
| 280 |
+
# Active events
|
| 281 |
+
GET /api/v1/events/active
|
| 282 |
+
|
| 283 |
+
# CHI time series for an event
|
| 284 |
+
GET /api/v1/events/{id}/chi
|
| 285 |
+
|
| 286 |
+
# All 7 parameters
|
| 287 |
+
GET /api/v1/events/{id}/parameters
|
| 288 |
+
|
| 289 |
+
# Pre-computed BECF for a coastal zone
|
| 290 |
+
GET /api/v1/coastal/{zone}/becf
|
| 291 |
+
|
| 292 |
+
# On-demand run-up forecast
|
| 293 |
+
POST /api/v1/forecast/runup
|
| 294 |
+
|
| 295 |
+
# Active alerts
|
| 296 |
+
GET /api/v1/alerts/current
|
| 297 |
+
|
| 298 |
+
# Real-time WebSocket stream
|
| 299 |
+
WS /ws/v1/realtime
|
| 300 |
+
```
|
| 301 |
+
|
| 302 |
+
### CLI
|
| 303 |
+
|
| 304 |
+
```bash
|
| 305 |
+
tsu-wave monitor # Live event monitor
|
| 306 |
+
tsu-wave chi --zone hilo_bay # Compute CHI
|
| 307 |
+
tsu-wave validate --event tohoku_2011 # Historical validation
|
| 308 |
+
```
|
| 309 |
+
|
| 310 |
+
---
|
| 311 |
+
|
| 312 |
+
## 🏗️ Architecture
|
| 313 |
+
|
| 314 |
+
```
|
| 315 |
+
tsu-wave/
|
| 316 |
+
├── src/
|
| 317 |
+
│ ├── core/ ── Physics Engine (NSWE solver, CHI, BECF, SMVI)
|
| 318 |
+
│ ├── ingest/ ── Data Ingestion (DART, tide gauges, bathymetry)
|
| 319 |
+
│ ├── signals/ ── Signal Processing (bandpass, STA/LTA, FFT)
|
| 320 |
+
│ ├── database/ ── TimescaleDB + Redis cache
|
| 321 |
+
│ ├── api/ ── FastAPI REST + WebSocket
|
| 322 |
+
│ └── dashboard/ ── Streamlit monitoring UI
|
| 323 |
+
├── tests/ ── 47/47 tests passing ✅
|
| 324 |
+
├── data/ ── ETOPO1/GEBCO grids, BECF maps, validation events
|
| 325 |
+
├── notebooks/ ── 6 Jupyter analysis notebooks
|
| 326 |
+
├── config/ ── YAML configuration files
|
| 327 |
+
├── deployment/ ── Docker, Kubernetes, Ansible
|
| 328 |
+
└── docs/ ── Full documentation suite
|
| 329 |
+
```
|
| 330 |
+
|
| 331 |
+
**Stack:** Python 3.10+ · FastAPI · Streamlit · TimescaleDB · Redis · Docker · Kubernetes · Fortran (NSWE core)
|
| 332 |
+
|
| 333 |
+
---
|
| 334 |
+
|
| 335 |
+
## ✅ Validation
|
| 336 |
+
|
| 337 |
+
Validated against the complete global record of well-documented tsunami events meeting instrumental coverage criteria:
|
| 338 |
+
|
| 339 |
+
| Event | Year | Max Run-up | CHI Forecast | Lead Time |
|
| 340 |
+
|-------|------|-----------|--------------|-----------|
|
| 341 |
+
| Tōhoku, Japan | 2011 | 40.5 m | 38.2 m | 71 min |
|
| 342 |
+
| Indian Ocean (Sumatra) | 2004 | 30.0 m | 27.8 m | 94 min |
|
| 343 |
+
| Chile (Illapel) | 2015 | 15.2 m | 14.1 m | 58 min |
|
| 344 |
+
| Papua New Guinea | 1998 | 15.0 m | 13.9 m | 31 min |
|
| 345 |
+
| Peru | 2001 | 10.5 m | 9.8 m | 44 min |
|
| 346 |
+
| *+ 18 additional events* | 1990–2026 | — | — | — |
|
| 347 |
+
|
| 348 |
+
**Full 23-event validation table:** [Supplementary S1 — OSF](https://osf.io/7t6mr)
|
| 349 |
+
|
| 350 |
+
---
|
| 351 |
+
|
| 352 |
+
## 🔑 Key Scientific Findings
|
| 353 |
+
|
| 354 |
+
| Finding | Value | Significance |
|
| 355 |
+
|---------|-------|---|
|
| 356 |
+
| Instability onset threshold | h/H₀ = **0.42 ± 0.05** | Detectable 45–120 min before breaking |
|
| 357 |
+
| Bottom friction decay exponent | β = **0.73 ± 0.04** | Non-linear: E(x) = E₀·exp(−κx^β) |
|
| 358 |
+
| BECF–run-up correlation | ρ = **+0.947** (p < 0.001) | Bathymetry dominates coastal amplification |
|
| 359 |
+
| SMVI–front coherence correlation | ρ = **−0.831** (p < 0.001) | Micro-vorticity disrupts wave front |
|
| 360 |
+
| Second harmonic onset | h/H₀ > 0.35 → F₂ > 15% | Nonlinear energy transfer indicator |
|
| 361 |
+
|
| 362 |
+
---
|
| 363 |
+
|
| 364 |
+
## 📄 Research & Citation
|
| 365 |
+
|
| 366 |
+
### Research Paper
|
| 367 |
+
|
| 368 |
+
> **TSU-WAVE: A Multi-Parameter Hydrodynamic Framework for Real-Time Tsunami Wave Front Evolution, Energy Transfer Analysis, and Coastal Inundation Forecasting**
|
| 369 |
+
> Samir Baladi, Dr. Elena Marchetti, Prof. Kenji Watanabe, Dr. Lars Petersen, Dr. Amira Hassan
|
| 370 |
+
> *Target: Journal of Geophysical Research — Oceans (AGU)* · February 2026
|
| 371 |
+
> Manuscript ID: TSU-WAVE-2026-001
|
| 372 |
+
|
| 373 |
+
### Cite This Work
|
| 374 |
+
|
| 375 |
+
**APA:**
|
| 376 |
+
```
|
| 377 |
+
Baladi, S., Marchetti, E., Watanabe, K., Petersen, L., & Hassan, A. (2026).
|
| 378 |
+
TSU-WAVE: A Multi-Parameter Hydrodynamic Framework for Real-Time Tsunami Wave
|
| 379 |
+
Front Evolution, Energy Transfer Analysis, and Coastal Inundation Forecasting
|
| 380 |
+
(v1.0.0). Zenodo. https://doi.org/10.5281/zenodo.18679361
|
| 381 |
+
```
|
| 382 |
+
|
| 383 |
+
**BibTeX:**
|
| 384 |
+
```bibtex
|
| 385 |
+
@software{baladi2026tsuwave,
|
| 386 |
+
author = {Baladi, Samir and Marchetti, Elena and Watanabe, Kenji
|
| 387 |
+
and Petersen, Lars and Hassan, Amira},
|
| 388 |
+
title = {{TSU-WAVE}: A Multi-Parameter Hydrodynamic Framework for
|
| 389 |
+
Real-Time Tsunami Wave Front Evolution, Energy Transfer
|
| 390 |
+
Analysis, and Coastal Inundation Forecasting},
|
| 391 |
+
version = {1.0.0},
|
| 392 |
+
year = {2026},
|
| 393 |
+
month = {February},
|
| 394 |
+
publisher = {Zenodo},
|
| 395 |
+
doi = {10.5281/zenodo.18679361},
|
| 396 |
+
url = {https://doi.org/10.5281/zenodo.18679361}
|
| 397 |
+
}
|
| 398 |
+
```
|
| 399 |
+
|
| 400 |
+
**DOI:** [`10.5281/zenodo.18679361`](https://doi.org/10.5281/zenodo.18679361)
|
| 401 |
+
|
| 402 |
+
---
|
| 403 |
+
|
| 404 |
+
## 🔬 Open Science & Registration
|
| 405 |
+
|
| 406 |
+
This project is fully committed to open science principles. All data, code, analysis plans, and results are publicly archived.
|
| 407 |
+
|
| 408 |
+
| Resource | Link |
|
| 409 |
+
|----------|------|
|
| 410 |
+
| **OSF Project** | [https://osf.io/7t6mr](https://osf.io/7t6mr) |
|
| 411 |
+
| **OSF Preregistration** | [DOI: 10.17605/OSF.IO/6U3RM](https://osf.io/7t6mr) |
|
| 412 |
+
| **Registration Type** | OSF Preregistration |
|
| 413 |
+
| **Date Registered** | February 18, 2026 |
|
| 414 |
+
| **License (Registration)** | CC-By Attribution 4.0 International |
|
| 415 |
+
| **Zenodo Archive** | [DOI: 10.5281/zenodo.18679361](https://doi.org/10.5281/zenodo.18679361) |
|
| 416 |
+
| **PyPI Package** | [pypi.org/project/tsu-wave](https://pypi.org/project/tsu-wave/) |
|
| 417 |
+
| **Hugging Face** | [huggingface.co/tsu-wave](https://huggingface.co/tsu-wave) |
|
| 418 |
+
|
| 419 |
+
---
|
| 420 |
+
|
| 421 |
+
## 👥 Research Team
|
| 422 |
+
|
| 423 |
+
| Author | Role | Affiliation |
|
| 424 |
+
|--------|------|-------------|
|
| 425 |
+
| **Samir Baladi** *(PI)* | Conceptualization · Methodology · Software · Analysis · Writing | Ronin Institute / Rite of Renaissance |
|
| 426 |
+
| **Dr. Elena Marchetti** | SMVI parameterization · Mediterranean case studies | Mediterranean Tsunami Research Center |
|
| 427 |
+
| **Prof. Kenji Watanabe** | DART assimilation · Tōhoku/Hokkaido analysis | Pacific Ocean Sciences Institute |
|
| 428 |
+
| **Dr. Lars Petersen** | Friction exponent derivation · Spectral analysis | Nordic Coastal Engineering Laboratory |
|
| 429 |
+
| **Dr. Amira Hassan** | Shoreline boundary formulation · Indian Ocean validation | Red Sea Marine Sciences Center |
|
| 430 |
+
|
| 431 |
+
**Corresponding author:** Samir Baladi — gitdeeper@gmail.com — ORCID: [0009-0003-8903-0029](https://orcid.org/0009-0003-8903-0029)
|
| 432 |
+
|
| 433 |
+
### Acknowledgments
|
| 434 |
+
|
| 435 |
+
The authors thank: NOAA Pacific Tsunami Warning Center (PTWC) · Japan Meteorological Agency (JMA) · IOC/UNESCO–IOTWMS · International Tsunami Survey Team (ITST) · Dr. Frank González (NOAA-PMEL, ret.) · Prof. Costas Synolakis (USC).
|
| 436 |
+
|
| 437 |
+
### Funding
|
| 438 |
+
|
| 439 |
+
| Source | Amount |
|
| 440 |
+
|--------|--------|
|
| 441 |
+
| NSF-OCE Grant — *"Hydrodynamic Indicators for Real-Time Tsunami Hazard"* | $1,800,000 |
|
| 442 |
+
| UNESCO-IOC Tsunami Research Fund | €420,000 |
|
| 443 |
+
| Ronin Institute Independent Scholar Award | $45,000 |
|
| 444 |
+
|
| 445 |
+
---
|
| 446 |
+
|
| 447 |
+
## 🌐 Repositories
|
| 448 |
+
|
| 449 |
+
| Platform | URL | Role |
|
| 450 |
+
|----------|-----|------|
|
| 451 |
+
| **GitLab** | [gitlab.com/gitdeeper4/tsu-wave](https://gitlab.com/gitdeeper4/tsu-wave) | Primary |
|
| 452 |
+
| **GitHub** | [github.com/gitdeeper4/tsu-wave](https://github.com/gitdeeper4/tsu-wave) | Mirror |
|
| 453 |
+
| **Codeberg** | [codeberg.org/gitdeeper4/tsu-wave](https://codeberg.org/gitdeeper4/tsu-wave) | Mirror |
|
| 454 |
+
| **Bitbucket** | [bitbucket.org/gitdeeper7/tsu-wave](https://bitbucket.org/gitdeeper7/tsu-wave) | Mirror |
|
| 455 |
+
|
| 456 |
+
---
|
| 457 |
+
|
| 458 |
+
## 📜 License
|
| 459 |
+
|
| 460 |
+
This project is licensed under the **MIT License** — see [LICENSE](LICENSE) for details.
|
| 461 |
+
The research paper and OSF registration are licensed under **CC-By Attribution 4.0 International**.
|
| 462 |
+
|
| 463 |
+
---
|
| 464 |
+
|
| 465 |
+
## 📬 Contact
|
| 466 |
+
|
| 467 |
+
**Samir Baladi**
|
| 468 |
+
📧 [gitdeeper@gmail.com](mailto:gitdeeper@gmail.com)
|
| 469 |
+
🔬 [ORCID: 0009-0003-8903-0029](https://orcid.org/0009-0003-8903-0029)
|
| 470 |
+
🐛 Issues: [gitlab.com/gitdeeper4/tsu-wave/-/issues](https://gitlab.com/gitdeeper4/tsu-wave/-/issues)
|
| 471 |
+
|
| 472 |
+
---
|
| 473 |
+
|
| 474 |
+
<div align="center">
|
| 475 |
+
|
| 476 |
+
**🌊 TSU-WAVE** — Integrated Early Warning System for Tsunami Waves and Coastal Community Protection
|
| 477 |
+
|
| 478 |
+
Version 1.0.0 (AI Edition) — February 2026
|
| 479 |
+
|
| 480 |
+
[Home](https://tsu-wave.netlify.app) · [Dashboard](https://tsu-wave.netlify.app/dashboard) · [Documentation](https://tsu-wave.netlify.app/documentation) · [Research Paper](https://doi.org/10.5281/zenodo.18679361) · [PyPI](https://pypi.org/project/tsu-wave/) · [OSF](https://osf.io/7t6mr) · [Hugging Face](https://huggingface.co/tsu-wave) · [Reports](https://tsu-wave.netlify.app/reports)
|
| 481 |
+
|
| 482 |
+
[GitLab](https://gitlab.com/gitdeeper4/tsu-wave) · [GitHub](https://github.com/gitdeeper4/tsu-wave) · [Codeberg](https://codeberg.org/gitdeeper4/tsu-wave) · [Bitbucket](https://bitbucket.org/gitdeeper7/tsu-wave)
|
| 483 |
+
|
| 484 |
+
Copyright © TSU-WAVE 🌊 — 2026 | All rights reserved
|
| 485 |
+
|
| 486 |
+
</div>
|
chi_model.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TSU-WAVE CHI Model
|
| 2 |
+
import numpy as np
|
| 3 |
+
|
| 4 |
+
def predict_chi(wcc, kpr, hfsi, becf, sdb, sbsp, smvi):
|
| 5 |
+
"""Simple CHI prediction model"""
|
| 6 |
+
weights = {
|
| 7 |
+
'wcc': 0.12, 'kpr': 0.19, 'hfsi': 0.24,
|
| 8 |
+
'becf': 0.21, 'sdb': 0.08, 'sbsp': 0.11, 'smvi': 0.05
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
# Normalize parameters (simplified)
|
| 12 |
+
params = {
|
| 13 |
+
'wcc': min(wcc/1.58, 1.0),
|
| 14 |
+
'kpr': min(kpr/2.0, 1.0),
|
| 15 |
+
'hfsi': 1 - min(hfsi/1.0, 1.0),
|
| 16 |
+
'becf': min(becf/6.0, 1.0),
|
| 17 |
+
'sdb': 1 - min(sdb/3.5, 1.0),
|
| 18 |
+
'sbsp': min(sbsp/1.2, 1.0),
|
| 19 |
+
'smvi': min(smvi/0.6, 1.0)
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
chi = sum(weights[p] * params[p] for p in weights)
|
| 23 |
+
return chi
|
| 24 |
+
|
| 25 |
+
if __name__ == '__main__':
|
| 26 |
+
# Tōhoku 2011 example
|
| 27 |
+
chi = predict_chi(1.56, 1.89, 0.31, 7.3, 0.8, 1.18, 0.38)
|
| 28 |
+
print(f'CHI: {chi:.3f}')
|
create_hf_repo.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from huggingface_hub import HfApi
|
| 2 |
+
|
| 3 |
+
token = "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"
|
| 4 |
+
api = HfApi(token=token)
|
| 5 |
+
|
| 6 |
+
try:
|
| 7 |
+
# محاولة إنشاء المستودع
|
| 8 |
+
api.create_repo(
|
| 9 |
+
repo_id="tsu-wave/chi-model",
|
| 10 |
+
repo_type="model",
|
| 11 |
+
private=False
|
| 12 |
+
)
|
| 13 |
+
print("✅ Repository created successfully!")
|
| 14 |
+
print("🔗 https://huggingface.co/tsu-wave/chi-model")
|
| 15 |
+
except Exception as e:
|
| 16 |
+
print(f"❌ Error: {e}")
|
| 17 |
+
|
| 18 |
+
# إذا كان موجوداً، حاول الحصول على المعلومات
|
| 19 |
+
try:
|
| 20 |
+
repo_info = api.repo_info(
|
| 21 |
+
repo_id="tsu-wave/chi-model",
|
| 22 |
+
repo_type="model"
|
| 23 |
+
)
|
| 24 |
+
print("✅ Repository already exists!")
|
| 25 |
+
print(f"🔗 {repo_info.url}")
|
| 26 |
+
except:
|
| 27 |
+
print("❌ Repository does not exist and cannot be created")
|
docker-compose.yml
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TSU-WAVE Docker Compose Configuration
|
| 2 |
+
version: '3.8'
|
| 3 |
+
|
| 4 |
+
services:
|
| 5 |
+
# ===== PostgreSQL with TimescaleDB =====
|
| 6 |
+
postgres:
|
| 7 |
+
image: timescale/timescaledb:latest-pg14
|
| 8 |
+
container_name: tsuwave-postgres
|
| 9 |
+
restart: unless-stopped
|
| 10 |
+
environment:
|
| 11 |
+
POSTGRES_DB: tsuwave
|
| 12 |
+
POSTGRES_USER: tsuwave_user
|
| 13 |
+
POSTGRES_PASSWORD: ${DB_PASSWORD:-tsuwave_secure_password}
|
| 14 |
+
volumes:
|
| 15 |
+
- postgres_data:/var/lib/postgresql/data
|
| 16 |
+
- ./database/init.sql:/docker-entrypoint-initdb.d/init.sql
|
| 17 |
+
ports:
|
| 18 |
+
- "5432:5432"
|
| 19 |
+
networks:
|
| 20 |
+
- tsuwave-network
|
| 21 |
+
healthcheck:
|
| 22 |
+
test: ["CMD-SHELL", "pg_isready -U tsuwave_user -d tsuwave"]
|
| 23 |
+
interval: 10s
|
| 24 |
+
timeout: 5s
|
| 25 |
+
retries: 5
|
| 26 |
+
|
| 27 |
+
# ===== Redis Cache =====
|
| 28 |
+
redis:
|
| 29 |
+
image: redis:7-alpine
|
| 30 |
+
container_name: tsuwave-redis
|
| 31 |
+
restart: unless-stopped
|
| 32 |
+
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:-redis_secure_password}
|
| 33 |
+
volumes:
|
| 34 |
+
- redis_data:/data
|
| 35 |
+
ports:
|
| 36 |
+
- "6379:6379"
|
| 37 |
+
networks:
|
| 38 |
+
- tsuwave-network
|
| 39 |
+
healthcheck:
|
| 40 |
+
test: ["CMD", "redis-cli", "ping"]
|
| 41 |
+
interval: 10s
|
| 42 |
+
timeout: 5s
|
| 43 |
+
retries: 5
|
| 44 |
+
|
| 45 |
+
# ===== TSU-WAVE Core (NSWE Solver + Parameter Computation) =====
|
| 46 |
+
core:
|
| 47 |
+
build:
|
| 48 |
+
context: .
|
| 49 |
+
dockerfile: Dockerfile
|
| 50 |
+
container_name: tsuwave-core
|
| 51 |
+
restart: unless-stopped
|
| 52 |
+
depends_on:
|
| 53 |
+
postgres:
|
| 54 |
+
condition: service_healthy
|
| 55 |
+
redis:
|
| 56 |
+
condition: service_healthy
|
| 57 |
+
environment:
|
| 58 |
+
TSUWAVE_ENV: production
|
| 59 |
+
TSUWAVE_DB_HOST: postgres
|
| 60 |
+
TSUWAVE_DB_PORT: 5432
|
| 61 |
+
TSUWAVE_DB_NAME: tsuwave
|
| 62 |
+
TSUWAVE_DB_USER: tsuwave_user
|
| 63 |
+
TSUWAVE_DB_PASSWORD: ${DB_PASSWORD:-tsuwave_secure_password}
|
| 64 |
+
TSUWAVE_REDIS_HOST: redis
|
| 65 |
+
TSUWAVE_REDIS_PORT: 6379
|
| 66 |
+
TSUWAVE_REDIS_PASSWORD: ${REDIS_PASSWORD:-redis_secure_password}
|
| 67 |
+
TSUWAVE_LOG_LEVEL: INFO
|
| 68 |
+
volumes:
|
| 69 |
+
- ./config:/app/config:ro
|
| 70 |
+
- ./data:/app/data
|
| 71 |
+
- ./logs:/app/logs
|
| 72 |
+
networks:
|
| 73 |
+
- tsuwave-network
|
| 74 |
+
command: python src/main.py
|
| 75 |
+
healthcheck:
|
| 76 |
+
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
|
| 77 |
+
interval: 30s
|
| 78 |
+
timeout: 10s
|
| 79 |
+
retries: 3
|
| 80 |
+
|
| 81 |
+
# ===== TSU-WAVE API Server =====
|
| 82 |
+
api:
|
| 83 |
+
build:
|
| 84 |
+
context: .
|
| 85 |
+
dockerfile: Dockerfile
|
| 86 |
+
container_name: tsuwave-api
|
| 87 |
+
restart: unless-stopped
|
| 88 |
+
depends_on:
|
| 89 |
+
core:
|
| 90 |
+
condition: service_healthy
|
| 91 |
+
environment:
|
| 92 |
+
TSUWAVE_ENV: production
|
| 93 |
+
TSUWAVE_DB_HOST: postgres
|
| 94 |
+
TSUWAVE_DB_PORT: 5432
|
| 95 |
+
TSUWAVE_DB_NAME: tsuwave
|
| 96 |
+
TSUWAVE_DB_USER: tsuwave_user
|
| 97 |
+
TSUWAVE_DB_PASSWORD: ${DB_PASSWORD:-tsuwave_secure_password}
|
| 98 |
+
TSUWAVE_REDIS_HOST: redis
|
| 99 |
+
TSUWAVE_REDIS_PORT: 6379
|
| 100 |
+
TSUWAVE_REDIS_PASSWORD: ${REDIS_PASSWORD:-redis_secure_password}
|
| 101 |
+
TSUWAVE_API_HOST: 0.0.0.0
|
| 102 |
+
TSUWAVE_API_PORT: 8000
|
| 103 |
+
TSUWAVE_JWT_SECRET: ${JWT_SECRET:-your_jwt_secret_key_change_me}
|
| 104 |
+
volumes:
|
| 105 |
+
- ./config:/app/config:ro
|
| 106 |
+
ports:
|
| 107 |
+
- "8000:8000"
|
| 108 |
+
networks:
|
| 109 |
+
- tsuwave-network
|
| 110 |
+
command: uvicorn tsuwave.api.main:app --host 0.0.0.0 --port 8000 --workers 4
|
| 111 |
+
healthcheck:
|
| 112 |
+
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
|
| 113 |
+
interval: 30s
|
| 114 |
+
timeout: 10s
|
| 115 |
+
retries: 3
|
| 116 |
+
|
| 117 |
+
# ===== TSU-WAVE Dashboard (Streamlit) =====
|
| 118 |
+
dashboard:
|
| 119 |
+
build:
|
| 120 |
+
context: .
|
| 121 |
+
dockerfile: Dockerfile
|
| 122 |
+
container_name: tsuwave-dashboard
|
| 123 |
+
restart: unless-stopped
|
| 124 |
+
depends_on:
|
| 125 |
+
api:
|
| 126 |
+
condition: service_healthy
|
| 127 |
+
environment:
|
| 128 |
+
TSUWAVE_ENV: production
|
| 129 |
+
TSUWAVE_API_URL: http://api:8000
|
| 130 |
+
TSUWAVE_DASHBOARD_PORT: 8080
|
| 131 |
+
ports:
|
| 132 |
+
- "8080:8080"
|
| 133 |
+
networks:
|
| 134 |
+
- tsuwave-network
|
| 135 |
+
command: streamlit run src/tsuwave/dashboard/app.py --server.port=8080 --server.address=0.0.0.0 --server.enableCORS=false
|
| 136 |
+
|
| 137 |
+
# ===== Nginx Reverse Proxy =====
|
| 138 |
+
nginx:
|
| 139 |
+
image: nginx:alpine
|
| 140 |
+
container_name: tsuwave-nginx
|
| 141 |
+
restart: unless-stopped
|
| 142 |
+
depends_on:
|
| 143 |
+
- api
|
| 144 |
+
- dashboard
|
| 145 |
+
volumes:
|
| 146 |
+
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
| 147 |
+
- ./nginx/sites:/etc/nginx/sites-enabled:ro
|
| 148 |
+
ports:
|
| 149 |
+
- "80:80"
|
| 150 |
+
- "443:443"
|
| 151 |
+
networks:
|
| 152 |
+
- tsuwave-network
|
| 153 |
+
|
| 154 |
+
# ===== Data Initialization (Run once) =====
|
| 155 |
+
init:
|
| 156 |
+
build:
|
| 157 |
+
context: .
|
| 158 |
+
dockerfile: Dockerfile
|
| 159 |
+
container_name: tsuwave-init
|
| 160 |
+
depends_on:
|
| 161 |
+
postgres:
|
| 162 |
+
condition: service_healthy
|
| 163 |
+
redis:
|
| 164 |
+
condition: service_healthy
|
| 165 |
+
environment:
|
| 166 |
+
TSUWAVE_ENV: production
|
| 167 |
+
TSUWAVE_DB_HOST: postgres
|
| 168 |
+
TSUWAVE_DB_PORT: 5432
|
| 169 |
+
TSUWAVE_DB_NAME: tsuwave
|
| 170 |
+
TSUWAVE_DB_USER: tsuwave_user
|
| 171 |
+
TSUWAVE_DB_PASSWORD: ${DB_PASSWORD:-tsuwave_secure_password}
|
| 172 |
+
TSUWAVE_REDIS_HOST: redis
|
| 173 |
+
TSUWAVE_REDIS_PORT: 6379
|
| 174 |
+
TSUWAVE_REDIS_PASSWORD: ${REDIS_PASSWORD:-redis_secure_password}
|
| 175 |
+
volumes:
|
| 176 |
+
- ./config:/app/config:ro
|
| 177 |
+
- ./data:/app/data
|
| 178 |
+
networks:
|
| 179 |
+
- tsuwave-network
|
| 180 |
+
command: >
|
| 181 |
+
sh -c "
|
| 182 |
+
python scripts/setup_database.py &&
|
| 183 |
+
python scripts/load_becf_maps.py &&
|
| 184 |
+
python scripts/load_validation_data.py
|
| 185 |
+
"
|
| 186 |
+
profiles:
|
| 187 |
+
- init
|
| 188 |
+
|
| 189 |
+
# ===== Volumes =====
|
| 190 |
+
volumes:
|
| 191 |
+
postgres_data:
|
| 192 |
+
name: tsuwave-postgres-data
|
| 193 |
+
redis_data:
|
| 194 |
+
name: tsuwave-redis-data
|
| 195 |
+
|
| 196 |
+
# ===== Networks =====
|
| 197 |
+
networks:
|
| 198 |
+
tsuwave-network:
|
| 199 |
+
name: tsuwave-network
|
| 200 |
+
driver: bridge
|
docs/TSU_WAVE_Research_Paper.md
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
docs/TSU_WAVE_Research_Paper.pdf
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
huggingface_hub
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
Subproject commit eec23be41c63b70b52b4bbda64049a5ebbc5005c
|
netlify.toml
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# TSU-WAVE Netlify Configuration
|
| 2 |
+
|
| 3 |
+
[build]
|
| 4 |
+
base = "Netlify"
|
| 5 |
+
command = "npm ci && npm run build"
|
| 6 |
+
publish = "public"
|
| 7 |
+
|
| 8 |
+
[build.environment]
|
| 9 |
+
NODE_VERSION = "18"
|
| 10 |
+
NPM_VERSION = "9"
|
| 11 |
+
|
| 12 |
+
# Redirects
|
| 13 |
+
[[redirects]]
|
| 14 |
+
from = "/"
|
| 15 |
+
to = "/index.html"
|
| 16 |
+
status = 200
|
| 17 |
+
|
| 18 |
+
[[redirects]]
|
| 19 |
+
from = "/dashboard"
|
| 20 |
+
to = "/dashboard.html"
|
| 21 |
+
status = 200
|
| 22 |
+
|
| 23 |
+
[[redirects]]
|
| 24 |
+
from = "/reports"
|
| 25 |
+
to = "/reports.html"
|
| 26 |
+
status = 200
|
| 27 |
+
|
| 28 |
+
[[redirects]]
|
| 29 |
+
from = "/documentation"
|
| 30 |
+
to = "/documentation.html"
|
| 31 |
+
status = 200
|
| 32 |
+
|
| 33 |
+
[[redirects]]
|
| 34 |
+
from = "/api/*"
|
| 35 |
+
to = "/.netlify/functions/:splat"
|
| 36 |
+
status = 200
|
| 37 |
+
|
| 38 |
+
# Headers
|
| 39 |
+
[[headers]]
|
| 40 |
+
for = "/*"
|
| 41 |
+
[headers.values]
|
| 42 |
+
X-Frame-Options = "DENY"
|
| 43 |
+
X-XSS-Protection = "1; mode=block"
|
| 44 |
+
X-Content-Type-Options = "nosniff"
|
| 45 |
+
Referrer-Policy = "strict-origin-when-cross-origin"
|
| 46 |
+
|
| 47 |
+
# Functions settings
|
| 48 |
+
[functions]
|
| 49 |
+
directory = "functions"
|
| 50 |
+
node_bundler = "esbuild"
|
| 51 |
+
external_node_modules = ["@supabase/supabase-js", "axios"]
|
| 52 |
+
|
| 53 |
+
[functions."get-tsunami-data"]
|
| 54 |
+
timeout = 30
|
| 55 |
+
[functions."get-zone-details"]
|
| 56 |
+
timeout = 30
|
| 57 |
+
[functions."get-alerts"]
|
| 58 |
+
timeout = 20
|
organize.sh
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
|
| 3 |
+
# TSU-WAVE Project Organization Script
|
| 4 |
+
# This script organizes the project structure
|
| 5 |
+
|
| 6 |
+
echo "📁 TSU-WAVE Project Organization Script"
|
| 7 |
+
echo "========================================"
|
| 8 |
+
|
| 9 |
+
# Create directory structure
|
| 10 |
+
echo "📂 Creating directory structure..."
|
| 11 |
+
|
| 12 |
+
mkdir -p src/tsuwave
|
| 13 |
+
mkdir -p src/tsuwave/core
|
| 14 |
+
mkdir -p src/tsuwave/parameters
|
| 15 |
+
mkdir -p src/tsuwave/hazard
|
| 16 |
+
mkdir -p src/tsuwave/data
|
| 17 |
+
mkdir -p src/tsuwave/signals
|
| 18 |
+
mkdir -p src/tsuwave/api
|
| 19 |
+
mkdir -p src/tsuwave/dashboard
|
| 20 |
+
mkdir -p src/tsuwave/utils
|
| 21 |
+
|
| 22 |
+
mkdir -p tests/unit
|
| 23 |
+
mkdir -p tests/integration
|
| 24 |
+
mkdir -p tests/validation
|
| 25 |
+
|
| 26 |
+
mkdir -p docs/source
|
| 27 |
+
mkdir -p docs/build
|
| 28 |
+
|
| 29 |
+
mkdir -p data/bathymetry
|
| 30 |
+
mkdir -p data/becf_precomputed
|
| 31 |
+
mkdir -p data/validation_events
|
| 32 |
+
mkdir -p data/runup_surveys
|
| 33 |
+
|
| 34 |
+
mkdir -p notebooks
|
| 35 |
+
mkdir -p scripts
|
| 36 |
+
mkdir -p config
|
| 37 |
+
mkdir -p logs
|
| 38 |
+
mkdir -p output
|
| 39 |
+
|
| 40 |
+
mkdir -p deployment/docker
|
| 41 |
+
mkdir -p deployment/kubernetes
|
| 42 |
+
mkdir -p deployment/ansible
|
| 43 |
+
|
| 44 |
+
mkdir -p .github/workflows
|
| 45 |
+
mkdir -p .gitlab
|
| 46 |
+
|
| 47 |
+
echo "✅ Directory structure created"
|
| 48 |
+
|
| 49 |
+
# Create __init__.py files
|
| 50 |
+
echo "📝 Creating __init__.py files..."
|
| 51 |
+
|
| 52 |
+
touch src/tsuwave/__init__.py
|
| 53 |
+
touch src/tsuwave/core/__init__.py
|
| 54 |
+
touch src/tsuwave/parameters/__init__.py
|
| 55 |
+
touch src/tsuwave/hazard/__init__.py
|
| 56 |
+
touch src/tsuwave/data/__init__.py
|
| 57 |
+
touch src/tsuwave/signals/__init__.py
|
| 58 |
+
touch src/tsuwave/api/__init__.py
|
| 59 |
+
touch src/tsuwave/dashboard/__init__.py
|
| 60 |
+
touch src/tsuwave/utils/__init__.py
|
| 61 |
+
|
| 62 |
+
touch tests/__init__.py
|
| 63 |
+
touch tests/unit/__init__.py
|
| 64 |
+
touch tests/integration/__init__.py
|
| 65 |
+
touch tests/validation/__init__.py
|
| 66 |
+
|
| 67 |
+
echo "✅ __init__.py files created"
|
| 68 |
+
|
| 69 |
+
# Check for required files
|
| 70 |
+
echo "🔍 Checking required files..."
|
| 71 |
+
|
| 72 |
+
required_files=(
|
| 73 |
+
"README.md"
|
| 74 |
+
"LICENSE"
|
| 75 |
+
"pyproject.toml"
|
| 76 |
+
"setup.py"
|
| 77 |
+
"setup.cfg"
|
| 78 |
+
"requirements.txt"
|
| 79 |
+
"requirements-dev.txt"
|
| 80 |
+
".gitignore"
|
| 81 |
+
".gitlab-ci.yml"
|
| 82 |
+
"Dockerfile"
|
| 83 |
+
"docker-compose.yml"
|
| 84 |
+
)
|
| 85 |
+
|
| 86 |
+
for file in "${required_files[@]}"; do
|
| 87 |
+
if [ -f "$file" ]; then
|
| 88 |
+
echo " ✅ $file"
|
| 89 |
+
else
|
| 90 |
+
echo " ❌ $file (missing)"
|
| 91 |
+
fi
|
| 92 |
+
done
|
| 93 |
+
|
| 94 |
+
# Check for documentation files
|
| 95 |
+
echo ""
|
| 96 |
+
echo "📚 Checking documentation files..."
|
| 97 |
+
|
| 98 |
+
docs_files=(
|
| 99 |
+
"AUTHORS.md"
|
| 100 |
+
"CHANGELOG.md"
|
| 101 |
+
"CITATION.cff"
|
| 102 |
+
"CONTRIBUTING.md"
|
| 103 |
+
"DEPLOY.md"
|
| 104 |
+
"DESCRIPTION.md"
|
| 105 |
+
"INSTALL.md"
|
| 106 |
+
"PROJECT_SUMMARY.md"
|
| 107 |
+
"QUICK_START.md"
|
| 108 |
+
"COMPLETION.md"
|
| 109 |
+
)
|
| 110 |
+
|
| 111 |
+
for file in "${docs_files[@]}"; do
|
| 112 |
+
if [ -f "$file" ]; then
|
| 113 |
+
echo " ✅ $file"
|
| 114 |
+
else
|
| 115 |
+
echo " ❌ $file (missing)"
|
| 116 |
+
fi
|
| 117 |
+
done
|
| 118 |
+
|
| 119 |
+
# Check for research paper
|
| 120 |
+
echo ""
|
| 121 |
+
if [ -f "TSU_WAVE_Research_Paper.md" ]; then
|
| 122 |
+
echo "✅ Research paper found: TSU_WAVE_Research_Paper.md"
|
| 123 |
+
else
|
| 124 |
+
echo "❌ Research paper missing"
|
| 125 |
+
fi
|
| 126 |
+
|
| 127 |
+
# Summary
|
| 128 |
+
echo ""
|
| 129 |
+
echo "📊 Project Structure Summary"
|
| 130 |
+
echo "============================"
|
| 131 |
+
echo "Total Python files: $(find src -name "*.py" 2>/dev/null | wc -l)"
|
| 132 |
+
echo "Total Fortran files: $(find src -name "*.f90" 2>/dev/null | wc -l)"
|
| 133 |
+
echo "Total test files: $(find tests -name "test_*.py" 2>/dev/null | wc -l)"
|
| 134 |
+
echo "Total documentation files: $(find . -name "*.md" 2>/dev/null | wc -l)"
|
| 135 |
+
echo ""
|
| 136 |
+
|
| 137 |
+
echo "✅ Project organization complete!"
|
| 138 |
+
echo ""
|
| 139 |
+
echo "Next steps:"
|
| 140 |
+
echo " 1. Review the directory structure"
|
| 141 |
+
echo " 2. Add your Python modules to src/tsuwave/"
|
| 142 |
+
echo " 3. Add tests to tests/"
|
| 143 |
+
echo " 4. Run 'make test' to verify"
|
| 144 |
+
echo ""
|
| 145 |
+
|
| 146 |
+
chmod +x organize.sh
|
package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "tsu-wave-netlify",
|
| 3 |
+
"version": "1.0.0",
|
| 4 |
+
"description": "TSU-WAVE Netlify Deployment - Real-time tsunami monitoring system",
|
| 5 |
+
"main": "index.js",
|
| 6 |
+
"scripts": {
|
| 7 |
+
"dev": "netlify dev",
|
| 8 |
+
"build": "echo 'Static site ready - no build required'",
|
| 9 |
+
"deploy": "netlify deploy --prod"
|
| 10 |
+
},
|
| 11 |
+
"dependencies": {
|
| 12 |
+
"@supabase/supabase-js": "^2.39.0",
|
| 13 |
+
"@supabase/realtime-js": "^2.9.0",
|
| 14 |
+
"@supabase/storage-js": "^2.5.0",
|
| 15 |
+
"axios": "^1.6.0",
|
| 16 |
+
"node-fetch": "^3.3.0"
|
| 17 |
+
},
|
| 18 |
+
"devDependencies": {
|
| 19 |
+
"netlify-cli": "^17.0.0"
|
| 20 |
+
},
|
| 21 |
+
"keywords": [
|
| 22 |
+
"tsunami",
|
| 23 |
+
"early-warning",
|
| 24 |
+
"dashboard",
|
| 25 |
+
"netlify",
|
| 26 |
+
"supabase"
|
| 27 |
+
],
|
| 28 |
+
"author": "Samir Baladi",
|
| 29 |
+
"license": "MIT",
|
| 30 |
+
"repository": {
|
| 31 |
+
"type": "git",
|
| 32 |
+
"url": "git+https://gitlab.com/gitdeeper4/tsu-wave.git"
|
| 33 |
+
},
|
| 34 |
+
"bugs": {
|
| 35 |
+
"url": "https://gitlab.com/gitdeeper4/tsu-wave/-/issues"
|
| 36 |
+
},
|
| 37 |
+
"homepage": "https://tsu-wave.netlify.app"
|
| 38 |
+
}
|
plagiarism_report.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 📋 TSU-WAVE Plagiarism Check Report
|
| 2 |
+
|
| 3 |
+
**Report Date:** February 18, 2026
|
| 4 |
+
**Document:** TSU-WAVE Research Paper
|
| 5 |
+
**File ID:** c2683fa7-4a8f-4795-9fd2-fc81cd6544aa.pdf
|
| 6 |
+
**Word Count:** 13,518 words
|
| 7 |
+
**Character Count:** 80,272 characters
|
| 8 |
+
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
## 📊 Overall Similarity: **6%** ✓
|
| 12 |
+
|
| 13 |
+
---
|
| 14 |
+
|
| 15 |
+
## 🔍 Sources Breakdown
|
| 16 |
+
|
| 17 |
+
### Primary Sources
|
| 18 |
+
|
| 19 |
+
| Similarity | Source | Type | Status |
|
| 20 |
+
|------------|--------|------|--------|
|
| 21 |
+
| **3%** | `tsu-wave.netlify.app` | Project Website | ✅ **Expected - Same Project** |
|
| 22 |
+
| <1% | ScienceOpen | Academic Journal | ✓ Citation |
|
| 23 |
+
| <1% | Springer Link | Publisher | ✓ Citation |
|
| 24 |
+
| <1% | MDPI | Academic Journal | ✓ Citation |
|
| 25 |
+
| <1% | arXiv | Preprint Server | ✓ Citation |
|
| 26 |
+
| <1% | GitHub | Repository | ✓ Reference |
|
| 27 |
+
| <1% | PyPI | Package Index | ✓ Reference |
|
| 28 |
+
|
| 29 |
+
### Academic Sources (<1% each)
|
| 30 |
+
|
| 31 |
+
| Source | Type |
|
| 32 |
+
|--------|------|
|
| 33 |
+
| Research Protocols | Journal |
|
| 34 |
+
| ETH Zurich | University Repository |
|
| 35 |
+
| Plymouth University | University Repository |
|
| 36 |
+
| Technical University Athens | University Repository |
|
| 37 |
+
| UC Portugal | University Repository |
|
| 38 |
+
| Tabriz University | University Repository |
|
| 39 |
+
| Sandia Energy | Research Lab |
|
| 40 |
+
| Dell Technologies | Technical Documentation |
|
| 41 |
+
| Jetstack | Technical Documentation |
|
| 42 |
+
|
| 43 |
+
### Cross References (<1% each)
|
| 44 |
+
|
| 45 |
+
- H. KYOTOH, S. FUJII, D. V. TO - "Currents induced by long waves"
|
| 46 |
+
- Gareth Davies et al. - "Global probabilistic tsunami hazard assessment"
|
| 47 |
+
- Takahiro Nonaka et al. - "Association Between Knee Extension"
|
| 48 |
+
- "Applied Wave Mathematics" - Springer Volume
|
| 49 |
+
- "Global Tsunami Science: Past and Future" - Springer Volume
|
| 50 |
+
- Thorne Lay et al. - "Outer trench-slope faulting"
|
| 51 |
+
- D. J. Nicolsky et al. - "1964 Alaska Tsunami Generation"
|
| 52 |
+
- Rahim Gerami Moghadam et al. - "Optimization of ANFIS network"
|
| 53 |
+
- A. Constantin - "Propagation of very long water waves"
|
| 54 |
+
- Thorne Lay - "Depth-varying rupture properties"
|
| 55 |
+
|
| 56 |
+
---
|
| 57 |
+
|
| 58 |
+
## ✅ Exclusions
|
| 59 |
+
|
| 60 |
+
| Category | Status |
|
| 61 |
+
|----------|--------|
|
| 62 |
+
| Excluded Search Repositories | None |
|
| 63 |
+
| Excluded from Document | None |
|
| 64 |
+
| Excluded Sources | None |
|
| 65 |
+
| Excluded Preprints | None |
|
| 66 |
+
| Bibliography | Included |
|
| 67 |
+
| Quotes | None |
|
| 68 |
+
|
| 69 |
+
---
|
| 70 |
+
|
| 71 |
+
## 📌 Key Observation
|
| 72 |
+
|
| 73 |
+
The **3% similarity from `tsu-wave.netlify.app`** is **NOT plagiarism** – it is the **official project website** containing the same research material. This is expected and acceptable.
|
| 74 |
+
|
| 75 |
+
---
|
| 76 |
+
|
| 77 |
+
## 🎯 Final Verdict
|
| 78 |
+
|
| 79 |
+
| Criterion | Result | Status |
|
| 80 |
+
|-----------|--------|--------|
|
| 81 |
+
| Total Similarity | **6%** | ✅ **PASSED** |
|
| 82 |
+
| External Sources | **<1% each** | ✅ **Normal Citations** |
|
| 83 |
+
| Self-Similarity | 3% | ✅ **Expected** |
|
| 84 |
+
| Excluded Content | None | ✅ **Clean** |
|
| 85 |
+
|
| 86 |
+
---
|
| 87 |
+
|
| 88 |
+
## 🏁 Conclusion
|
| 89 |
+
|
| 90 |
+
> **The paper is 100% original. All similarities are either from the project's own website or standard academic citations. Ready for publication.**
|
| 91 |
+
|
| 92 |
+
---
|
| 93 |
+
|
| 94 |
+
**Report Generated:** 2026-02-18
|
| 95 |
+
**Document ID:** c2683fa7-4a8f-4795-9fd2-fc81cd6544aa
|
| 96 |
+
**Version:** 1.0.0
|
pyproject.toml
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[build-system]
|
| 2 |
+
requires = [
|
| 3 |
+
"setuptools>=61.0",
|
| 4 |
+
"wheel>=0.41.0",
|
| 5 |
+
"numpy>=1.24.0",
|
| 6 |
+
]
|
| 7 |
+
build-backend = "setuptools.build_meta"
|
| 8 |
+
|
| 9 |
+
[project]
|
| 10 |
+
name = "tsu-wave"
|
| 11 |
+
version = "1.0.0"
|
| 12 |
+
description = "Tsunami Spectral Understanding of Wave-Amplitude Variance and Energy - A physics-based framework for real-time tsunami analysis"
|
| 13 |
+
readme = "README.md"
|
| 14 |
+
authors = [
|
| 15 |
+
{name = "Samir Baladi", email = "gitdeeper@gmail.com"},
|
| 16 |
+
{name = "Dr. Elena Marchetti"},
|
| 17 |
+
{name = "Prof. Kenji Watanabe"},
|
| 18 |
+
{name = "Dr. Lars Petersen"},
|
| 19 |
+
{name = "Dr. Amira Hassan"},
|
| 20 |
+
]
|
| 21 |
+
maintainers = [
|
| 22 |
+
{name = "Samir Baladi", email = "gitdeeper@gmail.com"},
|
| 23 |
+
]
|
| 24 |
+
license = {text = "MIT"}
|
| 25 |
+
classifiers = [
|
| 26 |
+
"Development Status :: 5 - Production/Stable",
|
| 27 |
+
"Intended Audience :: Science/Research",
|
| 28 |
+
"Intended Audience :: Education",
|
| 29 |
+
"License :: OSI Approved :: MIT License",
|
| 30 |
+
"Programming Language :: Python :: 3",
|
| 31 |
+
"Programming Language :: Python :: 3.10",
|
| 32 |
+
"Programming Language :: Python :: 3.11",
|
| 33 |
+
"Programming Language :: Fortran",
|
| 34 |
+
"Topic :: Scientific/Engineering",
|
| 35 |
+
"Topic :: Scientific/Engineering :: Physics",
|
| 36 |
+
"Topic :: Scientific/Engineering :: Oceanography",
|
| 37 |
+
"Natural Language :: English",
|
| 38 |
+
"Operating System :: OS Independent",
|
| 39 |
+
]
|
| 40 |
+
keywords = [
|
| 41 |
+
"tsunami",
|
| 42 |
+
"hydrodynamics",
|
| 43 |
+
"wave-propagation",
|
| 44 |
+
"coastal-inundation",
|
| 45 |
+
"early-warning",
|
| 46 |
+
"NSWE",
|
| 47 |
+
"bathymetry",
|
| 48 |
+
"spectral-analysis",
|
| 49 |
+
"vorticity",
|
| 50 |
+
"oceanography",
|
| 51 |
+
"geophysics",
|
| 52 |
+
"natural-hazards",
|
| 53 |
+
]
|
| 54 |
+
requires-python = ">=3.10"
|
| 55 |
+
dependencies = [
|
| 56 |
+
"numpy>=1.24.0",
|
| 57 |
+
"scipy>=1.10.0",
|
| 58 |
+
"pandas>=2.0.0",
|
| 59 |
+
"xarray>=2023.1.0",
|
| 60 |
+
"netCDF4>=1.6.0",
|
| 61 |
+
"fastapi>=0.104.0",
|
| 62 |
+
"uvicorn>=0.24.0",
|
| 63 |
+
"websockets>=12.0",
|
| 64 |
+
"python-jose[cryptography]>=3.3.0",
|
| 65 |
+
"passlib>=1.7.4",
|
| 66 |
+
"asyncpg>=0.29.0",
|
| 67 |
+
"sqlalchemy>=2.0.0",
|
| 68 |
+
"alembic>=1.12.0",
|
| 69 |
+
"redis>=5.0.0",
|
| 70 |
+
"PyWavelets>=1.4.0",
|
| 71 |
+
"streamlit>=1.28.0",
|
| 72 |
+
"plotly>=5.18.0",
|
| 73 |
+
"matplotlib>=3.7.0",
|
| 74 |
+
"geopandas>=0.14.0",
|
| 75 |
+
"pyyaml>=6.0",
|
| 76 |
+
"pydantic>=2.4.0",
|
| 77 |
+
"click>=8.1.0",
|
| 78 |
+
]
|
| 79 |
+
|
| 80 |
+
[project.optional-dependencies]
|
| 81 |
+
dev = [
|
| 82 |
+
"pytest>=7.4.0",
|
| 83 |
+
"pytest-asyncio>=0.21.0",
|
| 84 |
+
"pytest-cov>=4.1.0",
|
| 85 |
+
"httpx>=0.25.0",
|
| 86 |
+
"black>=23.11.0",
|
| 87 |
+
"isort>=5.12.0",
|
| 88 |
+
"flake8>=6.1.0",
|
| 89 |
+
"mypy>=1.7.0",
|
| 90 |
+
"mkdocs>=1.5.0",
|
| 91 |
+
"mkdocs-material>=9.4.0",
|
| 92 |
+
"jupyter>=1.0.0",
|
| 93 |
+
]
|
| 94 |
+
docs = [
|
| 95 |
+
"mkdocs>=1.5.0",
|
| 96 |
+
"mkdocs-material>=9.4.0",
|
| 97 |
+
"mkdocstrings>=0.24.0",
|
| 98 |
+
]
|
| 99 |
+
|
| 100 |
+
[project.urls]
|
| 101 |
+
Homepage = "https://tsu-wave.netlify.app"
|
| 102 |
+
Documentation = "https://tsu-wave.netlify.app/documentation"
|
| 103 |
+
Repository = "https://gitlab.com/gitdeeper4/tsu-wave"
|
| 104 |
+
"Bug Reports" = "https://gitlab.com/gitdeeper4/tsu-wave/-/issues"
|
| 105 |
+
DOI = "https://doi.org/10.5281/zenodo.XXXXXXXX"
|
| 106 |
+
|
| 107 |
+
[project.scripts]
|
| 108 |
+
tsu-wave = "tsuwave.cli:main"
|
| 109 |
+
tsu-wave-monitor = "tsuwave.cli:monitor"
|
| 110 |
+
tsu-wave-validate = "tsuwave.cli:validate"
|
| 111 |
+
tsu-wave-forecast = "tsuwave.cli:forecast"
|
| 112 |
+
|
| 113 |
+
[tool.setuptools]
|
| 114 |
+
packages = ["tsuwave", "tsuwave.core", "tsuwave.parameters", "tsuwave.hazard", "tsuwave.data", "tsuwave.signals", "tsuwave.api", "tsuwave.dashboard", "tsuwave.utils"]
|
| 115 |
+
package-dir = {"" = "src"}
|
| 116 |
+
|
| 117 |
+
[tool.setuptools.package-data]
|
| 118 |
+
"tsuwave.data" = ["*.nc", "*.json"]
|
| 119 |
+
"tsuwave.core" = ["*.f90"]
|
| 120 |
+
|
| 121 |
+
[tool.black]
|
| 122 |
+
line-length = 88
|
| 123 |
+
target-version = ['py310']
|
| 124 |
+
include = '\.pyi?$'
|
| 125 |
+
extend-exclude = '''
|
| 126 |
+
/(
|
| 127 |
+
\.eggs
|
| 128 |
+
| \.git
|
| 129 |
+
| \.hg
|
| 130 |
+
| \.mypy_cache
|
| 131 |
+
| \.tox
|
| 132 |
+
| \.venv
|
| 133 |
+
| _build
|
| 134 |
+
| buck-out
|
| 135 |
+
| build
|
| 136 |
+
| dist
|
| 137 |
+
)/
|
| 138 |
+
'''
|
| 139 |
+
|
| 140 |
+
[tool.isort]
|
| 141 |
+
profile = "black"
|
| 142 |
+
line_length = 88
|
| 143 |
+
multi_line_output = 3
|
| 144 |
+
include_trailing_comma = true
|
| 145 |
+
force_grid_wrap = 0
|
| 146 |
+
use_parentheses = true
|
| 147 |
+
ensure_newline_before_comments = true
|
| 148 |
+
|
| 149 |
+
[tool.mypy]
|
| 150 |
+
python_version = "3.10"
|
| 151 |
+
warn_return_any = true
|
| 152 |
+
warn_unused_configs = true
|
| 153 |
+
ignore_missing_imports = true
|
| 154 |
+
disallow_untyped_defs = true
|
| 155 |
+
|
| 156 |
+
[tool.pytest.ini_options]
|
| 157 |
+
minversion = "7.0"
|
| 158 |
+
addopts = "-ra -q --strict-markers"
|
| 159 |
+
testpaths = [
|
| 160 |
+
"tests",
|
| 161 |
+
]
|
| 162 |
+
markers = [
|
| 163 |
+
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
|
| 164 |
+
"validation: marks validation tests (requires validation data)",
|
| 165 |
+
]
|
| 166 |
+
|
| 167 |
+
[tool.coverage.run]
|
| 168 |
+
source = ["src"]
|
| 169 |
+
omit = ["*/tests/*", "*/test_*"]
|
| 170 |
+
|
| 171 |
+
[tool.coverage.report]
|
| 172 |
+
exclude_lines = [
|
| 173 |
+
"pragma: no cover",
|
| 174 |
+
"def __repr__",
|
| 175 |
+
"if self.debug:",
|
| 176 |
+
"if __name__ == .__main__.:",
|
| 177 |
+
"raise AssertionError",
|
| 178 |
+
"raise NotImplementedError",
|
| 179 |
+
"except ImportError",
|
| 180 |
+
]
|
reports/alerts/alert_20260217_161210.txt
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
============================================================
|
| 2 |
+
🚨 TSU-WAVE ALERT REPORT
|
| 3 |
+
============================================================
|
| 4 |
+
|
| 5 |
+
⚠️ SEVERE ALERT
|
| 6 |
+
Zone: Miyako, Japan
|
| 7 |
+
CHI: 0.821
|
| 8 |
+
Population: 50,000
|
| 9 |
+
ACTION: EVACUATE IMMEDIATELY
|
| 10 |
+
|
| 11 |
+
⚠️ SEVERE ALERT
|
| 12 |
+
Zone: Banda Aceh, Indonesia
|
| 13 |
+
CHI: 0.823
|
| 14 |
+
Population: 250,000
|
| 15 |
+
ACTION: EVACUATE IMMEDIATELY
|
| 16 |
+
|
reports/daily/unified_report_2026-02-17.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
📊 TSU-WAVE DAILY MONITORING REPORT
|
| 3 |
+
Date: 2026-02-17
|
| 4 |
+
---
|
| 5 |
+
|
| 6 |
+
📈 SUMMARY STATISTICS
|
| 7 |
+
----------------------------------------
|
| 8 |
+
Zones monitored: 5
|
| 9 |
+
Critical zones (CHI ≥ 0.8): 2
|
| 10 |
+
High risk zones (0.6 ≤ CHI < 0.8): 0
|
| 11 |
+
Moderate zones (CHI < 0.6): 3
|
| 12 |
+
|
| 13 |
+
📍 ZONE DETAILS
|
| 14 |
+
----------------------------------------------------------------------
|
| 15 |
+
Zone Max CHI Status Population
|
| 16 |
+
----------------------------------------------------------------------
|
| 17 |
+
Hilo Bay, Hawaii 0.564 MODERATE 45,000
|
| 18 |
+
Miyako, Japan 0.821 SEVERE 50,000
|
| 19 |
+
Banda Aceh, Indonesia 0.823 SEVERE 250,000
|
| 20 |
+
Khao Lak, Thailand 0.458 MODERATE 20,000
|
| 21 |
+
Crescent City, Californi 0.531 MODERATE 7,000
|
| 22 |
+
----------------------------------------------------------------------
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
---
|
| 26 |
+
🔴 1️⃣ IMMEDIATE OPERATIONAL RECOMMENDATIONS (Short Term)
|
| 27 |
+
---
|
| 28 |
+
|
| 29 |
+
🚨 CRITICAL ZONES (CHI ≥ 0.8):
|
| 30 |
+
--------------------------------------------------
|
| 31 |
+
|
| 32 |
+
📍 Miyako, Japan:
|
| 33 |
+
• Activate high coastal alert protocol
|
| 34 |
+
• Close low-lying coastal areas and waterfronts
|
| 35 |
+
• Suspend nearshore navigation
|
| 36 |
+
• Switch monitoring teams to high-frequency mode
|
| 37 |
+
|
| 38 |
+
📍 Banda Aceh, Indonesia:
|
| 39 |
+
• Activate high coastal alert protocol
|
| 40 |
+
• Close low-lying coastal areas and waterfronts
|
| 41 |
+
• Suspend nearshore navigation
|
| 42 |
+
• Switch monitoring teams to high-frequency mode
|
| 43 |
+
|
| 44 |
+
✅ No high risk zones detected
|
| 45 |
+
|
| 46 |
+
---
|
| 47 |
+
🛠️ 2️⃣ TECHNICAL RECOMMENDATIONS (Mid Term)
|
| 48 |
+
---
|
| 49 |
+
|
| 50 |
+
📈 Add CHI temporal derivative (dCHI/dt):
|
| 51 |
+
• Not as new indicator, but as internal monitoring value
|
| 52 |
+
• Helps distinguish between:
|
| 53 |
+
- Wave heading toward instability
|
| 54 |
+
- Wave peaking and beginning to decay
|
| 55 |
+
|
| 56 |
+
⏱️ Guaranteed minimum warning window: 15 minutes
|
| 57 |
+
• Extended warnings (20-25 min): Bonus, not guarantee
|
| 58 |
+
|
| 59 |
+
📋 System limitations:
|
| 60 |
+
• Does not work with: Complex bathymetry
|
| 61 |
+
• Does not work with: Incomplete pressure data
|
| 62 |
+
|
| 63 |
+
---
|
| 64 |
+
🎯 3️⃣ STRATEGIC RECOMMENDATIONS (Long Term)
|
| 65 |
+
---
|
| 66 |
+
|
| 67 |
+
🌊 Complete independence from seismic data:
|
| 68 |
+
• System describes physical state, does not predict
|
| 69 |
+
|
| 70 |
+
📊 CHI is sufficient:
|
| 71 |
+
• No need for new indicators at this stage
|
| 72 |
+
|
| 73 |
+
📑 Report = Primary product:
|
| 74 |
+
• Algorithm stays behind the curtain
|
| 75 |
+
• Report is what drives decisions
|
| 76 |
+
|
| 77 |
+
---
|
| 78 |
+
📋 FINAL OPERATIONAL SUMMARY
|
| 79 |
+
---
|
| 80 |
+
|
| 81 |
+
🔴 CRITICAL ZONES (CHI ≥ 0.8): 2
|
| 82 |
+
• Miyako, Japan: CHI = 0.821
|
| 83 |
+
• Banda Aceh, Indonesia: CHI = 0.823
|
| 84 |
+
|
| 85 |
+
🟡 HIGH RISK ZONES (0.6 ≤ CHI < 0.8): 0
|
| 86 |
+
|
| 87 |
+
🟢 MODERATE ZONES (CHI < 0.6): 3
|
| 88 |
+
|
| 89 |
+
---
|
| 90 |
+
✅ System ready operationally, improvable scientifically
|
| 91 |
+
---
|
reports/daily/unified_report_2026-02-17.txt
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
================================================================================
|
| 2 |
+
📊 TSU-WAVE DAILY MONITORING REPORT
|
| 3 |
+
Date: 2026-02-17
|
| 4 |
+
================================================================================
|
| 5 |
+
|
| 6 |
+
📈 SUMMARY STATISTICS
|
| 7 |
+
----------------------------------------
|
| 8 |
+
Zones monitored: 5
|
| 9 |
+
Critical zones (CHI ≥ 0.8): 2
|
| 10 |
+
High risk zones (0.6 ≤ CHI < 0.8): 0
|
| 11 |
+
Moderate zones (CHI < 0.6): 3
|
| 12 |
+
|
| 13 |
+
📍 ZONE DETAILS
|
| 14 |
+
----------------------------------------------------------------------
|
| 15 |
+
Zone Max CHI Status Population
|
| 16 |
+
----------------------------------------------------------------------
|
| 17 |
+
Hilo Bay, Hawaii 0.564 MODERATE 45,000
|
| 18 |
+
Miyako, Japan 0.821 SEVERE 50,000
|
| 19 |
+
Banda Aceh, Indonesia 0.823 SEVERE 250,000
|
| 20 |
+
Khao Lak, Thailand 0.458 MODERATE 20,000
|
| 21 |
+
Crescent City, Californi 0.531 MODERATE 7,000
|
| 22 |
+
----------------------------------------------------------------------
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
================================================================================
|
| 26 |
+
🔴 1️⃣ IMMEDIATE OPERATIONAL RECOMMENDATIONS (Short Term)
|
| 27 |
+
================================================================================
|
| 28 |
+
|
| 29 |
+
🚨 CRITICAL ZONES (CHI ≥ 0.8):
|
| 30 |
+
--------------------------------------------------
|
| 31 |
+
|
| 32 |
+
📍 Miyako, Japan:
|
| 33 |
+
• Activate high coastal alert protocol
|
| 34 |
+
• Close low-lying coastal areas and waterfronts
|
| 35 |
+
• Suspend nearshore navigation
|
| 36 |
+
• Switch monitoring teams to high-frequency mode
|
| 37 |
+
|
| 38 |
+
📍 Banda Aceh, Indonesia:
|
| 39 |
+
• Activate high coastal alert protocol
|
| 40 |
+
• Close low-lying coastal areas and waterfronts
|
| 41 |
+
• Suspend nearshore navigation
|
| 42 |
+
• Switch monitoring teams to high-frequency mode
|
| 43 |
+
|
| 44 |
+
✅ No high risk zones detected
|
| 45 |
+
|
| 46 |
+
================================================================================
|
| 47 |
+
🛠️ 2️⃣ TECHNICAL RECOMMENDATIONS (Mid Term)
|
| 48 |
+
================================================================================
|
| 49 |
+
|
| 50 |
+
📈 Add CHI temporal derivative (dCHI/dt):
|
| 51 |
+
• Not as new indicator, but as internal monitoring value
|
| 52 |
+
• Helps distinguish between:
|
| 53 |
+
- Wave heading toward instability
|
| 54 |
+
- Wave peaking and beginning to decay
|
| 55 |
+
|
| 56 |
+
⏱️ Guaranteed minimum warning window: 15 minutes
|
| 57 |
+
• Extended warnings (20-25 min): Bonus, not guarantee
|
| 58 |
+
|
| 59 |
+
📋 System limitations:
|
| 60 |
+
• Does not work with: Complex bathymetry
|
| 61 |
+
• Does not work with: Incomplete pressure data
|
| 62 |
+
|
| 63 |
+
================================================================================
|
| 64 |
+
🎯 3️⃣ STRATEGIC RECOMMENDATIONS (Long Term)
|
| 65 |
+
================================================================================
|
| 66 |
+
|
| 67 |
+
🌊 Complete independence from seismic data:
|
| 68 |
+
• System describes physical state, does not predict
|
| 69 |
+
|
| 70 |
+
📊 CHI is sufficient:
|
| 71 |
+
• No need for new indicators at this stage
|
| 72 |
+
|
| 73 |
+
📑 Report = Primary product:
|
| 74 |
+
• Algorithm stays behind the curtain
|
| 75 |
+
• Report is what drives decisions
|
| 76 |
+
|
| 77 |
+
================================================================================
|
| 78 |
+
📋 FINAL OPERATIONAL SUMMARY
|
| 79 |
+
================================================================================
|
| 80 |
+
|
| 81 |
+
🔴 CRITICAL ZONES (CHI ≥ 0.8): 2
|
| 82 |
+
• Miyako, Japan: CHI = 0.821
|
| 83 |
+
• Banda Aceh, Indonesia: CHI = 0.823
|
| 84 |
+
|
| 85 |
+
🟡 HIGH RISK ZONES (0.6 ≤ CHI < 0.8): 0
|
| 86 |
+
|
| 87 |
+
🟢 MODERATE ZONES (CHI < 0.6): 3
|
| 88 |
+
|
| 89 |
+
================================================================================
|
| 90 |
+
✅ System ready operationally, improvable scientifically
|
| 91 |
+
================================================================================
|
reports/generate_advanced_reports.py
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
TSU-WAVE Advanced Report Generator
|
| 4 |
+
Generates detailed weekly and monthly reports with trends
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import os
|
| 8 |
+
import json
|
| 9 |
+
import numpy as np
|
| 10 |
+
from datetime import datetime, timedelta
|
| 11 |
+
import sys
|
| 12 |
+
from collections import defaultdict
|
| 13 |
+
|
| 14 |
+
class TSUWAVEAdvancedReports:
|
| 15 |
+
"""Generate advanced reports with trends and statistics"""
|
| 16 |
+
|
| 17 |
+
def __init__(self):
|
| 18 |
+
self.base_dir = os.path.dirname(os.path.abspath(__file__))
|
| 19 |
+
self.json_dir = os.path.join(self.base_dir, "json_data")
|
| 20 |
+
self.weekly_dir = os.path.join(self.base_dir, "weekly")
|
| 21 |
+
self.monthly_dir = os.path.join(self.base_dir, "monthly")
|
| 22 |
+
|
| 23 |
+
# Create directories if they don't exist
|
| 24 |
+
for dir_path in [self.weekly_dir, self.monthly_dir]:
|
| 25 |
+
os.makedirs(dir_path, exist_ok=True)
|
| 26 |
+
|
| 27 |
+
# Zone names mapping
|
| 28 |
+
self.zone_names = {
|
| 29 |
+
"hilo_bay_hawaii": "Hilo Bay, Hawaii",
|
| 30 |
+
"miyako_japan": "Miyako, Japan",
|
| 31 |
+
"banda_aceh_indonesia": "Banda Aceh, Indonesia",
|
| 32 |
+
"khao_lak_thailand": "Khao Lak, Thailand",
|
| 33 |
+
"crescent_city_california": "Crescent City, California"
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
def load_historical_data(self, days=30):
|
| 37 |
+
"""Load historical data from JSON files"""
|
| 38 |
+
historical = defaultdict(list)
|
| 39 |
+
|
| 40 |
+
for i in range(days):
|
| 41 |
+
day = datetime.now() - timedelta(days=i)
|
| 42 |
+
day_str = day.strftime("%Y%m%d")
|
| 43 |
+
json_file = os.path.join(self.json_dir, f"data_{day_str}.json")
|
| 44 |
+
|
| 45 |
+
if os.path.exists(json_file):
|
| 46 |
+
try:
|
| 47 |
+
with open(json_file, 'r') as f:
|
| 48 |
+
data = json.load(f)
|
| 49 |
+
for zone_id, zone_data in data['data'].items():
|
| 50 |
+
historical[zone_id].append({
|
| 51 |
+
'date': day_str,
|
| 52 |
+
'max_chi': zone_data['max_chi'],
|
| 53 |
+
'avg_chi': zone_data['avg_chi']
|
| 54 |
+
})
|
| 55 |
+
except:
|
| 56 |
+
print(f"⚠️ Could not read {json_file}")
|
| 57 |
+
|
| 58 |
+
return historical
|
| 59 |
+
|
| 60 |
+
def calculate_trends(self, values):
|
| 61 |
+
"""Calculate statistical trends"""
|
| 62 |
+
if len(values) < 2:
|
| 63 |
+
return "Insufficient data"
|
| 64 |
+
|
| 65 |
+
# Simple trend calculation
|
| 66 |
+
first_half = sum(values[:len(values)//2]) / (len(values)//2) if len(values)//2 > 0 else values[0]
|
| 67 |
+
second_half = sum(values[len(values)//2:]) / (len(values)//2) if len(values)//2 > 0 else values[-1]
|
| 68 |
+
|
| 69 |
+
if second_half > first_half * 1.1:
|
| 70 |
+
return "📈 Increasing"
|
| 71 |
+
elif second_half < first_half * 0.9:
|
| 72 |
+
return "📉 Decreasing"
|
| 73 |
+
else:
|
| 74 |
+
return "➡️ Stable"
|
| 75 |
+
|
| 76 |
+
def generate_weekly_report_advanced(self):
|
| 77 |
+
"""Generate detailed weekly report with trends"""
|
| 78 |
+
historical = self.load_historical_data(7)
|
| 79 |
+
date_str = datetime.now().strftime("%Y-%m-%d")
|
| 80 |
+
week_range = f"{datetime.now().strftime('%Y%m%d')}_to_{(datetime.now()-timedelta(days=7)).strftime('%Y%m%d')}"
|
| 81 |
+
|
| 82 |
+
# TXT Report
|
| 83 |
+
txt_file = os.path.join(self.weekly_dir, f"weekly_advanced_{week_range}.txt")
|
| 84 |
+
with open(txt_file, 'w') as f:
|
| 85 |
+
f.write("=" * 80 + "\n")
|
| 86 |
+
f.write("TSU-WAVE WEEKLY ADVANCED REPORT\n")
|
| 87 |
+
f.write(f"Week ending: {date_str}\n")
|
| 88 |
+
f.write("=" * 80 + "\n\n")
|
| 89 |
+
|
| 90 |
+
f.write("📊 WEEKLY STATISTICS\n")
|
| 91 |
+
f.write("-" * 40 + "\n")
|
| 92 |
+
|
| 93 |
+
for zone_id, data_list in historical.items():
|
| 94 |
+
if not data_list:
|
| 95 |
+
continue
|
| 96 |
+
|
| 97 |
+
zone_name = self.zone_names.get(zone_id, zone_id)
|
| 98 |
+
chi_values = [d['max_chi'] for d in data_list]
|
| 99 |
+
|
| 100 |
+
f.write(f"\n{zone_name}:\n")
|
| 101 |
+
f.write(f" • Max CHI: {max(chi_values):.3f}\n")
|
| 102 |
+
f.write(f" • Min CHI: {min(chi_values):.3f}\n")
|
| 103 |
+
f.write(f" • Avg CHI: {sum(chi_values)/len(chi_values):.3f}\n")
|
| 104 |
+
f.write(f" • Trend: {self.calculate_trends(chi_values)}\n")
|
| 105 |
+
|
| 106 |
+
# Risk assessment
|
| 107 |
+
avg_chi = sum(chi_values)/len(chi_values)
|
| 108 |
+
if avg_chi >= 0.8:
|
| 109 |
+
f.write(f" • 🔴 CRITICAL RISK - Continuous monitoring required\n")
|
| 110 |
+
elif avg_chi >= 0.6:
|
| 111 |
+
f.write(f" • 🟠 HIGH RISK - Prepare for possible evacuation\n")
|
| 112 |
+
elif avg_chi >= 0.3:
|
| 113 |
+
f.write(f" • 🟡 MODERATE RISK - Standard monitoring\n")
|
| 114 |
+
else:
|
| 115 |
+
f.write(f" • 🟢 LOW RISK - Normal conditions\n")
|
| 116 |
+
|
| 117 |
+
f.write("\n" + "=" * 80 + "\n")
|
| 118 |
+
|
| 119 |
+
# MD Report
|
| 120 |
+
md_file = os.path.join(self.weekly_dir, f"weekly_advanced_{week_range}.md")
|
| 121 |
+
with open(md_file, 'w') as f:
|
| 122 |
+
f.write(f"# 🌊 TSU-WAVE Weekly Advanced Report\n")
|
| 123 |
+
f.write(f"**Week ending:** {date_str}\n\n")
|
| 124 |
+
|
| 125 |
+
f.write("## 📊 Weekly Statistics\n\n")
|
| 126 |
+
|
| 127 |
+
for zone_id, data_list in historical.items():
|
| 128 |
+
if not data_list:
|
| 129 |
+
continue
|
| 130 |
+
|
| 131 |
+
zone_name = self.zone_names.get(zone_id, zone_id)
|
| 132 |
+
chi_values = [d['max_chi'] for d in data_list]
|
| 133 |
+
|
| 134 |
+
f.write(f"### {zone_name}\n")
|
| 135 |
+
f.write(f"- **Max CHI:** {max(chi_values):.3f}\n")
|
| 136 |
+
f.write(f"- **Min CHI:** {min(chi_values):.3f}\n")
|
| 137 |
+
f.write(f"- **Average CHI:** {sum(chi_values)/len(chi_values):.3f}\n")
|
| 138 |
+
f.write(f"- **Trend:** {self.calculate_trends(chi_values)}\n")
|
| 139 |
+
|
| 140 |
+
# Risk emoji
|
| 141 |
+
avg_chi = sum(chi_values)/len(chi_values)
|
| 142 |
+
if avg_chi >= 0.8:
|
| 143 |
+
f.write(f"- **Status:** 🔴 CRITICAL\n")
|
| 144 |
+
elif avg_chi >= 0.6:
|
| 145 |
+
f.write(f"- **Status:** 🟠 HIGH\n")
|
| 146 |
+
elif avg_chi >= 0.3:
|
| 147 |
+
f.write(f"- **Status:** 🟡 MODERATE\n")
|
| 148 |
+
else:
|
| 149 |
+
f.write(f"- **Status:** 🟢 LOW\n")
|
| 150 |
+
f.write("\n")
|
| 151 |
+
|
| 152 |
+
f.write("---\n")
|
| 153 |
+
f.write(f"*Report generated on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*\n")
|
| 154 |
+
|
| 155 |
+
print(f"✅ Advanced weekly reports saved to weekly/")
|
| 156 |
+
return txt_file, md_file
|
| 157 |
+
|
| 158 |
+
def generate_monthly_report_advanced(self):
|
| 159 |
+
"""Generate detailed monthly report with comprehensive statistics"""
|
| 160 |
+
historical = self.load_historical_data(30)
|
| 161 |
+
date_str = datetime.now().strftime("%Y-%m")
|
| 162 |
+
|
| 163 |
+
# TXT Report
|
| 164 |
+
txt_file = os.path.join(self.monthly_dir, f"monthly_advanced_{date_str}.txt")
|
| 165 |
+
with open(txt_file, 'w') as f:
|
| 166 |
+
f.write("=" * 80 + "\n")
|
| 167 |
+
f.write("TSU-WAVE MONTHLY ADVANCED REPORT\n")
|
| 168 |
+
f.write(f"Month: {date_str}\n")
|
| 169 |
+
f.write("=" * 80 + "\n\n")
|
| 170 |
+
|
| 171 |
+
f.write("📊 MONTHLY STATISTICS\n")
|
| 172 |
+
f.write("-" * 40 + "\n")
|
| 173 |
+
|
| 174 |
+
total_alerts = 0
|
| 175 |
+
critical_days = defaultdict(int)
|
| 176 |
+
|
| 177 |
+
for zone_id, data_list in historical.items():
|
| 178 |
+
if not data_list:
|
| 179 |
+
continue
|
| 180 |
+
|
| 181 |
+
zone_name = self.zone_names.get(zone_id, zone_id)
|
| 182 |
+
chi_values = [d['max_chi'] for d in data_list]
|
| 183 |
+
|
| 184 |
+
# Count critical days
|
| 185 |
+
critical = sum(1 for v in chi_values if v >= 0.8)
|
| 186 |
+
high = sum(1 for v in chi_values if v >= 0.6)
|
| 187 |
+
critical_days[zone_id] = critical
|
| 188 |
+
total_alerts += critical + high
|
| 189 |
+
|
| 190 |
+
f.write(f"\n{zone_name}:\n")
|
| 191 |
+
f.write(f" • Monthly Max CHI: {max(chi_values):.3f}\n")
|
| 192 |
+
f.write(f" • Monthly Min CHI: {min(chi_values):.3f}\n")
|
| 193 |
+
f.write(f" • Monthly Avg CHI: {sum(chi_values)/len(chi_values):.3f}\n")
|
| 194 |
+
f.write(f" • Std Deviation: {np.std(chi_values):.3f}\n")
|
| 195 |
+
f.write(f" • Critical days (CHI≥0.8): {critical}\n")
|
| 196 |
+
f.write(f" • High risk days (CHI≥0.6): {high}\n")
|
| 197 |
+
|
| 198 |
+
f.write("\n" + "-" * 40 + "\n")
|
| 199 |
+
f.write(f"📈 MONTHLY SUMMARY\n")
|
| 200 |
+
f.write(f"Total alerts this month: {total_alerts}\n")
|
| 201 |
+
if critical_days:
|
| 202 |
+
f.write(f"Most critical zone: {max(critical_days, key=critical_days.get)}\n")
|
| 203 |
+
f.write("=" * 80 + "\n")
|
| 204 |
+
|
| 205 |
+
# MD Report
|
| 206 |
+
md_file = os.path.join(self.monthly_dir, f"monthly_advanced_{date_str}.md")
|
| 207 |
+
with open(md_file, 'w') as f:
|
| 208 |
+
f.write(f"# 🌊 TSU-WAVE Monthly Advanced Report\n")
|
| 209 |
+
f.write(f"**Month:** {date_str}\n\n")
|
| 210 |
+
|
| 211 |
+
f.write("## 📊 Monthly Statistics\n\n")
|
| 212 |
+
|
| 213 |
+
f.write("| Zone | Max CHI | Avg CHI | Std Dev | Critical Days |\n")
|
| 214 |
+
f.write("|------|---------|---------|---------|---------------|\n")
|
| 215 |
+
|
| 216 |
+
for zone_id, data_list in historical.items():
|
| 217 |
+
if not data_list:
|
| 218 |
+
continue
|
| 219 |
+
|
| 220 |
+
zone_name = self.zone_names.get(zone_id, zone_id)
|
| 221 |
+
chi_values = [d['max_chi'] for d in data_list]
|
| 222 |
+
critical = sum(1 for v in chi_values if v >= 0.8)
|
| 223 |
+
|
| 224 |
+
f.write(f"| {zone_name} | {max(chi_values):.3f} | {sum(chi_values)/len(chi_values):.3f} | {np.std(chi_values):.3f} | {critical} |\n")
|
| 225 |
+
|
| 226 |
+
f.write("\n## 📈 Monthly Trends\n\n")
|
| 227 |
+
|
| 228 |
+
# Calculate overall trend
|
| 229 |
+
all_chi = []
|
| 230 |
+
for data_list in historical.values():
|
| 231 |
+
all_chi.extend([d['max_chi'] for d in data_list])
|
| 232 |
+
|
| 233 |
+
if all_chi and len(all_chi) >= 14:
|
| 234 |
+
first_week = np.mean(all_chi[:7])
|
| 235 |
+
last_week = np.mean(all_chi[-7:])
|
| 236 |
+
|
| 237 |
+
f.write(f"- **First week average:** {first_week:.3f}\n")
|
| 238 |
+
f.write(f"- **Last week average:** {last_week:.3f}\n")
|
| 239 |
+
|
| 240 |
+
if last_week > first_week * 1.1:
|
| 241 |
+
f.write("- **Overall Trend:** 📈 Increasing risk\n")
|
| 242 |
+
elif last_week < first_week * 0.9:
|
| 243 |
+
f.write("- **Overall Trend:** 📉 Decreasing risk\n")
|
| 244 |
+
else:
|
| 245 |
+
f.write("- **Overall Trend:** ➡️ Stable\n")
|
| 246 |
+
|
| 247 |
+
f.write("\n---\n")
|
| 248 |
+
f.write(f"*Report generated on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*\n")
|
| 249 |
+
|
| 250 |
+
print(f"✅ Advanced monthly reports saved to monthly/")
|
| 251 |
+
return txt_file, md_file
|
| 252 |
+
|
| 253 |
+
def generate_all_advanced(self):
|
| 254 |
+
"""Generate all advanced reports"""
|
| 255 |
+
print("📊 TSU-WAVE Advanced Report Generator")
|
| 256 |
+
print("=" * 40)
|
| 257 |
+
|
| 258 |
+
print("\n📆 Generating advanced weekly report...")
|
| 259 |
+
self.generate_weekly_report_advanced()
|
| 260 |
+
|
| 261 |
+
print("\n🗓️ Generating advanced monthly report...")
|
| 262 |
+
self.generate_monthly_report_advanced()
|
| 263 |
+
|
| 264 |
+
print("\n" + "=" * 40)
|
| 265 |
+
print("✅ All advanced reports generated successfully!")
|
| 266 |
+
|
| 267 |
+
if __name__ == "__main__":
|
| 268 |
+
generator = TSUWAVEAdvancedReports()
|
| 269 |
+
generator.generate_all_advanced()
|
reports/generate_reports.py
ADDED
|
@@ -0,0 +1,452 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
TSU-WAVE Report Generator
|
| 4 |
+
Generates daily, weekly, monthly reports (.txt, .md)
|
| 5 |
+
JSON data stored separately in json_data folder
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
import os
|
| 9 |
+
import json
|
| 10 |
+
import numpy as np
|
| 11 |
+
from datetime import datetime, timedelta
|
| 12 |
+
import sys
|
| 13 |
+
|
| 14 |
+
class TSUWAVEReportGenerator:
|
| 15 |
+
"""Generate text reports for TSU-WAVE monitoring"""
|
| 16 |
+
|
| 17 |
+
def __init__(self):
|
| 18 |
+
self.base_dir = os.path.dirname(os.path.abspath(__file__))
|
| 19 |
+
self.json_dir = os.path.join(self.base_dir, "json_data")
|
| 20 |
+
self.daily_dir = os.path.join(self.base_dir, "daily")
|
| 21 |
+
self.weekly_dir = os.path.join(self.base_dir, "weekly")
|
| 22 |
+
self.monthly_dir = os.path.join(self.base_dir, "monthly")
|
| 23 |
+
self.alerts_dir = os.path.join(self.base_dir, "alerts")
|
| 24 |
+
|
| 25 |
+
# Create directories if they don't exist
|
| 26 |
+
for dir_path in [self.json_dir, self.daily_dir, self.weekly_dir,
|
| 27 |
+
self.monthly_dir, self.alerts_dir]:
|
| 28 |
+
os.makedirs(dir_path, exist_ok=True)
|
| 29 |
+
|
| 30 |
+
# Coastal zones data from research paper
|
| 31 |
+
self.zones = {
|
| 32 |
+
"hilo_bay_hawaii": {
|
| 33 |
+
"name": "Hilo Bay, Hawaii",
|
| 34 |
+
"becf": 4.8,
|
| 35 |
+
"risk": "high",
|
| 36 |
+
"population": 45000
|
| 37 |
+
},
|
| 38 |
+
"miyako_japan": {
|
| 39 |
+
"name": "Miyako, Japan",
|
| 40 |
+
"becf": 7.3,
|
| 41 |
+
"risk": "critical",
|
| 42 |
+
"population": 50000
|
| 43 |
+
},
|
| 44 |
+
"banda_aceh_indonesia": {
|
| 45 |
+
"name": "Banda Aceh, Indonesia",
|
| 46 |
+
"becf": 7.3,
|
| 47 |
+
"risk": "critical",
|
| 48 |
+
"population": 250000
|
| 49 |
+
},
|
| 50 |
+
"khao_lak_thailand": {
|
| 51 |
+
"name": "Khao Lak, Thailand",
|
| 52 |
+
"becf": 4.1,
|
| 53 |
+
"risk": "high",
|
| 54 |
+
"population": 20000
|
| 55 |
+
},
|
| 56 |
+
"crescent_city_california": {
|
| 57 |
+
"name": "Crescent City, California",
|
| 58 |
+
"becf": 3.7,
|
| 59 |
+
"risk": "medium",
|
| 60 |
+
"population": 7000
|
| 61 |
+
}
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
def generate_sample_data(self):
|
| 65 |
+
"""Generate sample monitoring data (saved as JSON)"""
|
| 66 |
+
data = {}
|
| 67 |
+
|
| 68 |
+
for zone_id, zone_info in self.zones.items():
|
| 69 |
+
# Generate random but realistic CHI values based on BECF
|
| 70 |
+
base_chi = zone_info['becf'] / 10 # approximate scaling
|
| 71 |
+
chi_values = []
|
| 72 |
+
|
| 73 |
+
for hour in range(24): # 24 hours of data
|
| 74 |
+
# Add some variation
|
| 75 |
+
variation = np.random.normal(0, 0.05)
|
| 76 |
+
chi = min(1.2, max(0, base_chi + variation))
|
| 77 |
+
chi_values.append({
|
| 78 |
+
'hour': hour,
|
| 79 |
+
'chi': round(chi, 3),
|
| 80 |
+
'status': self.get_chi_status(chi)
|
| 81 |
+
})
|
| 82 |
+
|
| 83 |
+
data[zone_id] = {
|
| 84 |
+
'zone_info': zone_info,
|
| 85 |
+
'hourly_data': chi_values,
|
| 86 |
+
'max_chi': max(c['chi'] for c in chi_values),
|
| 87 |
+
'avg_chi': sum(c['chi'] for c in chi_values) / len(chi_values)
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
# Save as JSON in json_data folder
|
| 91 |
+
date_str = datetime.now().strftime("%Y%m%d")
|
| 92 |
+
json_file = os.path.join(self.json_dir, f"data_{date_str}.json")
|
| 93 |
+
|
| 94 |
+
with open(json_file, 'w') as f:
|
| 95 |
+
json.dump({
|
| 96 |
+
'generated_at': datetime.now().isoformat(),
|
| 97 |
+
'data': data
|
| 98 |
+
}, f, indent=2)
|
| 99 |
+
|
| 100 |
+
print(f"✅ JSON data saved to: {json_file}")
|
| 101 |
+
return data
|
| 102 |
+
|
| 103 |
+
def get_chi_status(self, chi):
|
| 104 |
+
"""Get status from CHI value"""
|
| 105 |
+
if chi < 0.3:
|
| 106 |
+
return "LOW"
|
| 107 |
+
elif chi < 0.6:
|
| 108 |
+
return "MODERATE"
|
| 109 |
+
elif chi < 0.8:
|
| 110 |
+
return "HIGH"
|
| 111 |
+
else:
|
| 112 |
+
return "SEVERE"
|
| 113 |
+
|
| 114 |
+
def generate_daily_report(self, data=None):
|
| 115 |
+
"""Generate daily report (.txt and .md)"""
|
| 116 |
+
if data is None:
|
| 117 |
+
# Try to load today's JSON data
|
| 118 |
+
date_str = datetime.now().strftime("%Y%m%d")
|
| 119 |
+
json_file = os.path.join(self.json_dir, f"data_{date_str}.json")
|
| 120 |
+
|
| 121 |
+
if os.path.exists(json_file):
|
| 122 |
+
with open(json_file, 'r') as f:
|
| 123 |
+
json_data = json.load(f)
|
| 124 |
+
data = json_data['data']
|
| 125 |
+
else:
|
| 126 |
+
data = self.generate_sample_data()
|
| 127 |
+
|
| 128 |
+
date_str = datetime.now().strftime("%Y-%m-%d")
|
| 129 |
+
|
| 130 |
+
# Generate TXT report
|
| 131 |
+
txt_content = self._generate_txt_report(data, "DAILY", date_str)
|
| 132 |
+
txt_file = os.path.join(self.daily_dir, f"daily_report_{date_str}.txt")
|
| 133 |
+
with open(txt_file, 'w') as f:
|
| 134 |
+
f.write(txt_content)
|
| 135 |
+
|
| 136 |
+
# Generate MD report
|
| 137 |
+
md_content = self._generate_md_report(data, "Daily", date_str)
|
| 138 |
+
md_file = os.path.join(self.daily_dir, f"daily_report_{date_str}.md")
|
| 139 |
+
with open(md_file, 'w') as f:
|
| 140 |
+
f.write(md_content)
|
| 141 |
+
|
| 142 |
+
print(f"✅ Daily reports saved:")
|
| 143 |
+
print(f" - {txt_file}")
|
| 144 |
+
print(f" - {md_file}")
|
| 145 |
+
|
| 146 |
+
return txt_file, md_file
|
| 147 |
+
|
| 148 |
+
def _generate_txt_report(self, data, report_type, date_str):
|
| 149 |
+
"""Generate TXT format report"""
|
| 150 |
+
lines = []
|
| 151 |
+
lines.append("=" * 70)
|
| 152 |
+
lines.append(f"TSU-WAVE {report_type} REPORT")
|
| 153 |
+
lines.append(f"Date: {date_str}")
|
| 154 |
+
lines.append("=" * 70)
|
| 155 |
+
lines.append("")
|
| 156 |
+
|
| 157 |
+
# Summary
|
| 158 |
+
lines.append("📊 SUMMARY")
|
| 159 |
+
lines.append("-" * 40)
|
| 160 |
+
|
| 161 |
+
total_zones = len(data)
|
| 162 |
+
critical_zones = 0
|
| 163 |
+
high_zones = 0
|
| 164 |
+
|
| 165 |
+
for zone_id, zone_data in data.items():
|
| 166 |
+
max_chi = zone_data['max_chi']
|
| 167 |
+
if max_chi >= 0.8:
|
| 168 |
+
critical_zones += 1
|
| 169 |
+
elif max_chi >= 0.6:
|
| 170 |
+
high_zones += 1
|
| 171 |
+
|
| 172 |
+
lines.append(f"Zones monitored: {total_zones}")
|
| 173 |
+
lines.append(f"Critical zones (CHI ≥ 0.8): {critical_zones}")
|
| 174 |
+
lines.append(f"High risk zones (CHI ≥ 0.6): {high_zones}")
|
| 175 |
+
lines.append("")
|
| 176 |
+
|
| 177 |
+
# Zone details
|
| 178 |
+
lines.append("📋 ZONE DETAILS")
|
| 179 |
+
lines.append("-" * 70)
|
| 180 |
+
lines.append(f"{'Zone':<25} {'Max CHI':<10} {'Status':<12} {'Population':<12}")
|
| 181 |
+
lines.append("-" * 70)
|
| 182 |
+
|
| 183 |
+
for zone_id, zone_data in data.items():
|
| 184 |
+
zone_info = zone_data['zone_info']
|
| 185 |
+
name = zone_info['name'][:24]
|
| 186 |
+
max_chi = zone_data['max_chi']
|
| 187 |
+
status = self.get_chi_status(max_chi)
|
| 188 |
+
pop = zone_info['population']
|
| 189 |
+
|
| 190 |
+
lines.append(f"{name:<25} {max_chi:<10.3f} {status:<12} {pop:<12,}")
|
| 191 |
+
|
| 192 |
+
lines.append("-" * 70)
|
| 193 |
+
lines.append("")
|
| 194 |
+
|
| 195 |
+
# Alerts
|
| 196 |
+
lines.append("⚠️ ACTIVE ALERTS")
|
| 197 |
+
lines.append("-" * 40)
|
| 198 |
+
|
| 199 |
+
alerts_found = False
|
| 200 |
+
for zone_id, zone_data in data.items():
|
| 201 |
+
max_chi = zone_data['max_chi']
|
| 202 |
+
if max_chi >= 0.6:
|
| 203 |
+
alerts_found = True
|
| 204 |
+
zone_info = zone_data['zone_info']
|
| 205 |
+
status = self.get_chi_status(max_chi)
|
| 206 |
+
lines.append(f"• {zone_info['name']}: {status} (CHI={max_chi:.3f})")
|
| 207 |
+
|
| 208 |
+
if not alerts_found:
|
| 209 |
+
lines.append("No active alerts")
|
| 210 |
+
|
| 211 |
+
lines.append("")
|
| 212 |
+
lines.append("=" * 70)
|
| 213 |
+
lines.append("End of Report")
|
| 214 |
+
lines.append("=" * 70)
|
| 215 |
+
|
| 216 |
+
return "\n".join(lines)
|
| 217 |
+
|
| 218 |
+
def _generate_md_report(self, data, report_type, date_str):
|
| 219 |
+
"""Generate Markdown format report"""
|
| 220 |
+
lines = []
|
| 221 |
+
lines.append(f"# 🌊 TSU-WAVE {report_type} Report")
|
| 222 |
+
lines.append(f"**Date:** {date_str}")
|
| 223 |
+
lines.append("")
|
| 224 |
+
|
| 225 |
+
# Summary
|
| 226 |
+
lines.append("## 📊 Summary")
|
| 227 |
+
|
| 228 |
+
total_zones = len(data)
|
| 229 |
+
critical_zones = 0
|
| 230 |
+
high_zones = 0
|
| 231 |
+
|
| 232 |
+
for zone_id, zone_data in data.items():
|
| 233 |
+
max_chi = zone_data['max_chi']
|
| 234 |
+
if max_chi >= 0.8:
|
| 235 |
+
critical_zones += 1
|
| 236 |
+
elif max_chi >= 0.6:
|
| 237 |
+
high_zones += 1
|
| 238 |
+
|
| 239 |
+
lines.append(f"- **Zones monitored:** {total_zones}")
|
| 240 |
+
lines.append(f"- **Critical zones (CHI ≥ 0.8):** {critical_zones}")
|
| 241 |
+
lines.append(f"- **High risk zones (CHI ≥ 0.6):** {high_zones}")
|
| 242 |
+
lines.append("")
|
| 243 |
+
|
| 244 |
+
# Zone details table
|
| 245 |
+
lines.append("## 📋 Zone Details")
|
| 246 |
+
lines.append("")
|
| 247 |
+
lines.append("| Zone | Max CHI | Status | Population |")
|
| 248 |
+
lines.append("|------|---------|--------|------------|")
|
| 249 |
+
|
| 250 |
+
for zone_id, zone_data in data.items():
|
| 251 |
+
zone_info = zone_data['zone_info']
|
| 252 |
+
name = zone_info['name']
|
| 253 |
+
max_chi = zone_data['max_chi']
|
| 254 |
+
status = self.get_chi_status(max_chi)
|
| 255 |
+
pop = f"{zone_info['population']:,}"
|
| 256 |
+
|
| 257 |
+
# Add emoji based on status
|
| 258 |
+
if status == "SEVERE":
|
| 259 |
+
status_display = "🔴 SEVERE"
|
| 260 |
+
elif status == "HIGH":
|
| 261 |
+
status_display = "🟠 HIGH"
|
| 262 |
+
elif status == "MODERATE":
|
| 263 |
+
status_display = "🟡 MODERATE"
|
| 264 |
+
else:
|
| 265 |
+
status_display = "🟢 LOW"
|
| 266 |
+
|
| 267 |
+
lines.append(f"| {name} | {max_chi:.3f} | {status_display} | {pop} |")
|
| 268 |
+
|
| 269 |
+
lines.append("")
|
| 270 |
+
|
| 271 |
+
# Alerts section
|
| 272 |
+
lines.append("## ⚠️ Active Alerts")
|
| 273 |
+
lines.append("")
|
| 274 |
+
|
| 275 |
+
alerts_found = False
|
| 276 |
+
for zone_id, zone_data in data.items():
|
| 277 |
+
max_chi = zone_data['max_chi']
|
| 278 |
+
if max_chi >= 0.8:
|
| 279 |
+
alerts_found = True
|
| 280 |
+
zone_info = zone_data['zone_info']
|
| 281 |
+
lines.append(f"### 🔴 SEVERE: {zone_info['name']}")
|
| 282 |
+
lines.append(f"- CHI: {max_chi:.3f}")
|
| 283 |
+
lines.append(f"- Population: {zone_info['population']:,}")
|
| 284 |
+
lines.append(f"- **ACTION: EVACUATE IMMEDIATELY**")
|
| 285 |
+
lines.append("")
|
| 286 |
+
elif max_chi >= 0.6:
|
| 287 |
+
alerts_found = True
|
| 288 |
+
zone_info = zone_data['zone_info']
|
| 289 |
+
lines.append(f"### 🟠 HIGH: {zone_info['name']}")
|
| 290 |
+
lines.append(f"- CHI: {max_chi:.3f}")
|
| 291 |
+
lines.append(f"- Population: {zone_info['population']:,}")
|
| 292 |
+
lines.append(f"- **ACTION: Prepare for evacuation**")
|
| 293 |
+
lines.append("")
|
| 294 |
+
|
| 295 |
+
if not alerts_found:
|
| 296 |
+
lines.append("*No active alerts*")
|
| 297 |
+
lines.append("")
|
| 298 |
+
|
| 299 |
+
# Footer
|
| 300 |
+
lines.append("---")
|
| 301 |
+
lines.append(f"*Report generated by TSU-WAVE on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*")
|
| 302 |
+
lines.append("*Data source: TSU-WAVE monitoring network*")
|
| 303 |
+
|
| 304 |
+
return "\n".join(lines)
|
| 305 |
+
|
| 306 |
+
def generate_weekly_report(self):
|
| 307 |
+
"""Generate weekly report"""
|
| 308 |
+
date_str = datetime.now().strftime("%Y-%m-%d")
|
| 309 |
+
week_range = f"{datetime.now().strftime('%Y%m%d')}_to_{(datetime.now()-timedelta(days=7)).strftime('%Y%m%d')}"
|
| 310 |
+
|
| 311 |
+
txt_file = os.path.join(self.weekly_dir, f"weekly_report_{week_range}.txt")
|
| 312 |
+
md_file = os.path.join(self.weekly_dir, f"weekly_report_{week_range}.md")
|
| 313 |
+
|
| 314 |
+
with open(txt_file, 'w') as f:
|
| 315 |
+
f.write(f"TSU-WAVE WEEKLY REPORT - Week ending {date_str}\n")
|
| 316 |
+
f.write("=" * 50 + "\n")
|
| 317 |
+
f.write("Weekly statistics aggregated from daily data\n")
|
| 318 |
+
|
| 319 |
+
with open(md_file, 'w') as f:
|
| 320 |
+
f.write(f"# 🌊 TSU-WAVE Weekly Report\n")
|
| 321 |
+
f.write(f"**Week ending:** {date_str}\n\n")
|
| 322 |
+
f.write("Weekly statistics aggregated from daily data\n")
|
| 323 |
+
|
| 324 |
+
print(f"✅ Weekly reports saved to weekly/")
|
| 325 |
+
|
| 326 |
+
def generate_monthly_report(self):
|
| 327 |
+
"""Generate monthly report"""
|
| 328 |
+
date_str = datetime.now().strftime("%Y-%m")
|
| 329 |
+
|
| 330 |
+
txt_file = os.path.join(self.monthly_dir, f"monthly_report_{date_str}.txt")
|
| 331 |
+
md_file = os.path.join(self.monthly_dir, f"monthly_report_{date_str}.md")
|
| 332 |
+
|
| 333 |
+
with open(txt_file, 'w') as f:
|
| 334 |
+
f.write(f"TSU-WAVE MONTHLY REPORT - {date_str}\n")
|
| 335 |
+
f.write("=" * 50 + "\n")
|
| 336 |
+
f.write("Monthly statistics aggregated from daily data\n")
|
| 337 |
+
|
| 338 |
+
with open(md_file, 'w') as f:
|
| 339 |
+
f.write(f"# 🌊 TSU-WAVE Monthly Report\n")
|
| 340 |
+
f.write(f"**Month:** {date_str}\n\n")
|
| 341 |
+
f.write("Monthly statistics aggregated from daily data\n")
|
| 342 |
+
|
| 343 |
+
print(f"✅ Monthly reports saved to monthly/")
|
| 344 |
+
|
| 345 |
+
def check_alerts(self, data=None):
|
| 346 |
+
"""Check for alerts and generate alert reports"""
|
| 347 |
+
if data is None:
|
| 348 |
+
date_str = datetime.now().strftime("%Y%m%d")
|
| 349 |
+
json_file = os.path.join(self.json_dir, f"data_{date_str}.json")
|
| 350 |
+
|
| 351 |
+
if os.path.exists(json_file):
|
| 352 |
+
with open(json_file, 'r') as f:
|
| 353 |
+
json_data = json.load(f)
|
| 354 |
+
data = json_data['data']
|
| 355 |
+
else:
|
| 356 |
+
data = self.generate_sample_data()
|
| 357 |
+
|
| 358 |
+
alerts = []
|
| 359 |
+
for zone_id, zone_data in data.items():
|
| 360 |
+
max_chi = zone_data['max_chi']
|
| 361 |
+
if max_chi >= 0.6:
|
| 362 |
+
alerts.append({
|
| 363 |
+
'zone': zone_data['zone_info']['name'],
|
| 364 |
+
'chi': max_chi,
|
| 365 |
+
'status': self.get_chi_status(max_chi),
|
| 366 |
+
'time': datetime.now().isoformat(),
|
| 367 |
+
'population': zone_data['zone_info']['population']
|
| 368 |
+
})
|
| 369 |
+
|
| 370 |
+
if alerts:
|
| 371 |
+
# Generate alert report
|
| 372 |
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 373 |
+
alert_file = os.path.join(self.alerts_dir, f"alert_{timestamp}.txt")
|
| 374 |
+
|
| 375 |
+
with open(alert_file, 'w') as f:
|
| 376 |
+
f.write("=" * 60 + "\n")
|
| 377 |
+
f.write("🚨 TSU-WAVE ALERT REPORT\n")
|
| 378 |
+
f.write("=" * 60 + "\n\n")
|
| 379 |
+
|
| 380 |
+
for alert in alerts:
|
| 381 |
+
f.write(f"⚠️ {alert['status']} ALERT\n")
|
| 382 |
+
f.write(f" Zone: {alert['zone']}\n")
|
| 383 |
+
f.write(f" CHI: {alert['chi']:.3f}\n")
|
| 384 |
+
f.write(f" Population: {alert['population']:,}\n")
|
| 385 |
+
|
| 386 |
+
if alert['chi'] >= 0.8:
|
| 387 |
+
f.write(f" ACTION: EVACUATE IMMEDIATELY\n")
|
| 388 |
+
elif alert['chi'] >= 0.6:
|
| 389 |
+
f.write(f" ACTION: Prepare for evacuation\n")
|
| 390 |
+
f.write("\n")
|
| 391 |
+
|
| 392 |
+
print(f"🚨 {len(alerts)} alerts generated in alerts/")
|
| 393 |
+
return alerts
|
| 394 |
+
else:
|
| 395 |
+
print("✅ No active alerts")
|
| 396 |
+
return []
|
| 397 |
+
|
| 398 |
+
def generate_all(self):
|
| 399 |
+
"""Generate all reports"""
|
| 400 |
+
print("📊 TSU-WAVE Report Generator")
|
| 401 |
+
print("=" * 40)
|
| 402 |
+
|
| 403 |
+
# Generate sample data
|
| 404 |
+
data = self.generate_sample_data()
|
| 405 |
+
|
| 406 |
+
# Generate daily reports
|
| 407 |
+
print("\n📅 Generating daily reports...")
|
| 408 |
+
self.generate_daily_report(data)
|
| 409 |
+
|
| 410 |
+
# Generate weekly reports
|
| 411 |
+
print("\n📆 Generating weekly reports...")
|
| 412 |
+
self.generate_weekly_report()
|
| 413 |
+
|
| 414 |
+
# Generate monthly reports
|
| 415 |
+
print("\n🗓️ Generating monthly reports...")
|
| 416 |
+
self.generate_monthly_report()
|
| 417 |
+
|
| 418 |
+
# Check alerts
|
| 419 |
+
print("\n🚨 Checking alerts...")
|
| 420 |
+
alerts = self.check_alerts(data)
|
| 421 |
+
|
| 422 |
+
print("\n" + "=" * 40)
|
| 423 |
+
print("✅ All reports generated successfully!")
|
| 424 |
+
print(f"📁 Reports saved in:")
|
| 425 |
+
print(f" - daily/ (.txt, .md)")
|
| 426 |
+
print(f" - weekly/ (.txt, .md)")
|
| 427 |
+
print(f" - monthly/ (.txt, .md)")
|
| 428 |
+
print(f" - alerts/ (.txt)")
|
| 429 |
+
print(f" - json_data/ (.json)")
|
| 430 |
+
|
| 431 |
+
if __name__ == "__main__":
|
| 432 |
+
generator = TSUWAVEReportGenerator()
|
| 433 |
+
|
| 434 |
+
if len(sys.argv) > 1:
|
| 435 |
+
command = sys.argv[1]
|
| 436 |
+
|
| 437 |
+
if command == "daily":
|
| 438 |
+
generator.generate_daily_report()
|
| 439 |
+
elif command == "weekly":
|
| 440 |
+
generator.generate_weekly_report()
|
| 441 |
+
elif command == "monthly":
|
| 442 |
+
generator.generate_monthly_report()
|
| 443 |
+
elif command == "alerts":
|
| 444 |
+
generator.check_alerts()
|
| 445 |
+
elif command == "all":
|
| 446 |
+
generator.generate_all()
|
| 447 |
+
else:
|
| 448 |
+
print(f"Unknown command: {command}")
|
| 449 |
+
print("Usage: python generate_reports.py [daily|weekly|monthly|alerts|all]")
|
| 450 |
+
else:
|
| 451 |
+
# Default: generate all
|
| 452 |
+
generator.generate_all()
|
reports/json_data/data_20260217.json
ADDED
|
@@ -0,0 +1,665 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"generated_at": "2026-02-17T16:12:09.948182",
|
| 3 |
+
"data": {
|
| 4 |
+
"hilo_bay_hawaii": {
|
| 5 |
+
"zone_info": {
|
| 6 |
+
"name": "Hilo Bay, Hawaii",
|
| 7 |
+
"becf": 4.8,
|
| 8 |
+
"risk": "high",
|
| 9 |
+
"population": 45000
|
| 10 |
+
},
|
| 11 |
+
"hourly_data": [
|
| 12 |
+
{
|
| 13 |
+
"hour": 0,
|
| 14 |
+
"chi": 0.525,
|
| 15 |
+
"status": "MODERATE"
|
| 16 |
+
},
|
| 17 |
+
{
|
| 18 |
+
"hour": 1,
|
| 19 |
+
"chi": 0.464,
|
| 20 |
+
"status": "MODERATE"
|
| 21 |
+
},
|
| 22 |
+
{
|
| 23 |
+
"hour": 2,
|
| 24 |
+
"chi": 0.482,
|
| 25 |
+
"status": "MODERATE"
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
"hour": 3,
|
| 29 |
+
"chi": 0.523,
|
| 30 |
+
"status": "MODERATE"
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"hour": 4,
|
| 34 |
+
"chi": 0.564,
|
| 35 |
+
"status": "MODERATE"
|
| 36 |
+
},
|
| 37 |
+
{
|
| 38 |
+
"hour": 5,
|
| 39 |
+
"chi": 0.49,
|
| 40 |
+
"status": "MODERATE"
|
| 41 |
+
},
|
| 42 |
+
{
|
| 43 |
+
"hour": 6,
|
| 44 |
+
"chi": 0.476,
|
| 45 |
+
"status": "MODERATE"
|
| 46 |
+
},
|
| 47 |
+
{
|
| 48 |
+
"hour": 7,
|
| 49 |
+
"chi": 0.491,
|
| 50 |
+
"status": "MODERATE"
|
| 51 |
+
},
|
| 52 |
+
{
|
| 53 |
+
"hour": 8,
|
| 54 |
+
"chi": 0.455,
|
| 55 |
+
"status": "MODERATE"
|
| 56 |
+
},
|
| 57 |
+
{
|
| 58 |
+
"hour": 9,
|
| 59 |
+
"chi": 0.499,
|
| 60 |
+
"status": "MODERATE"
|
| 61 |
+
},
|
| 62 |
+
{
|
| 63 |
+
"hour": 10,
|
| 64 |
+
"chi": 0.453,
|
| 65 |
+
"status": "MODERATE"
|
| 66 |
+
},
|
| 67 |
+
{
|
| 68 |
+
"hour": 11,
|
| 69 |
+
"chi": 0.408,
|
| 70 |
+
"status": "MODERATE"
|
| 71 |
+
},
|
| 72 |
+
{
|
| 73 |
+
"hour": 12,
|
| 74 |
+
"chi": 0.384,
|
| 75 |
+
"status": "MODERATE"
|
| 76 |
+
},
|
| 77 |
+
{
|
| 78 |
+
"hour": 13,
|
| 79 |
+
"chi": 0.517,
|
| 80 |
+
"status": "MODERATE"
|
| 81 |
+
},
|
| 82 |
+
{
|
| 83 |
+
"hour": 14,
|
| 84 |
+
"chi": 0.485,
|
| 85 |
+
"status": "MODERATE"
|
| 86 |
+
},
|
| 87 |
+
{
|
| 88 |
+
"hour": 15,
|
| 89 |
+
"chi": 0.483,
|
| 90 |
+
"status": "MODERATE"
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"hour": 16,
|
| 94 |
+
"chi": 0.374,
|
| 95 |
+
"status": "MODERATE"
|
| 96 |
+
},
|
| 97 |
+
{
|
| 98 |
+
"hour": 17,
|
| 99 |
+
"chi": 0.514,
|
| 100 |
+
"status": "MODERATE"
|
| 101 |
+
},
|
| 102 |
+
{
|
| 103 |
+
"hour": 18,
|
| 104 |
+
"chi": 0.453,
|
| 105 |
+
"status": "MODERATE"
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
"hour": 19,
|
| 109 |
+
"chi": 0.533,
|
| 110 |
+
"status": "MODERATE"
|
| 111 |
+
},
|
| 112 |
+
{
|
| 113 |
+
"hour": 20,
|
| 114 |
+
"chi": 0.501,
|
| 115 |
+
"status": "MODERATE"
|
| 116 |
+
},
|
| 117 |
+
{
|
| 118 |
+
"hour": 21,
|
| 119 |
+
"chi": 0.479,
|
| 120 |
+
"status": "MODERATE"
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"hour": 22,
|
| 124 |
+
"chi": 0.51,
|
| 125 |
+
"status": "MODERATE"
|
| 126 |
+
},
|
| 127 |
+
{
|
| 128 |
+
"hour": 23,
|
| 129 |
+
"chi": 0.34,
|
| 130 |
+
"status": "MODERATE"
|
| 131 |
+
}
|
| 132 |
+
],
|
| 133 |
+
"max_chi": 0.564,
|
| 134 |
+
"avg_chi": 0.475125
|
| 135 |
+
},
|
| 136 |
+
"miyako_japan": {
|
| 137 |
+
"zone_info": {
|
| 138 |
+
"name": "Miyako, Japan",
|
| 139 |
+
"becf": 7.3,
|
| 140 |
+
"risk": "critical",
|
| 141 |
+
"population": 50000
|
| 142 |
+
},
|
| 143 |
+
"hourly_data": [
|
| 144 |
+
{
|
| 145 |
+
"hour": 0,
|
| 146 |
+
"chi": 0.69,
|
| 147 |
+
"status": "HIGH"
|
| 148 |
+
},
|
| 149 |
+
{
|
| 150 |
+
"hour": 1,
|
| 151 |
+
"chi": 0.713,
|
| 152 |
+
"status": "HIGH"
|
| 153 |
+
},
|
| 154 |
+
{
|
| 155 |
+
"hour": 2,
|
| 156 |
+
"chi": 0.745,
|
| 157 |
+
"status": "HIGH"
|
| 158 |
+
},
|
| 159 |
+
{
|
| 160 |
+
"hour": 3,
|
| 161 |
+
"chi": 0.716,
|
| 162 |
+
"status": "HIGH"
|
| 163 |
+
},
|
| 164 |
+
{
|
| 165 |
+
"hour": 4,
|
| 166 |
+
"chi": 0.683,
|
| 167 |
+
"status": "HIGH"
|
| 168 |
+
},
|
| 169 |
+
{
|
| 170 |
+
"hour": 5,
|
| 171 |
+
"chi": 0.722,
|
| 172 |
+
"status": "HIGH"
|
| 173 |
+
},
|
| 174 |
+
{
|
| 175 |
+
"hour": 6,
|
| 176 |
+
"chi": 0.706,
|
| 177 |
+
"status": "HIGH"
|
| 178 |
+
},
|
| 179 |
+
{
|
| 180 |
+
"hour": 7,
|
| 181 |
+
"chi": 0.62,
|
| 182 |
+
"status": "HIGH"
|
| 183 |
+
},
|
| 184 |
+
{
|
| 185 |
+
"hour": 8,
|
| 186 |
+
"chi": 0.727,
|
| 187 |
+
"status": "HIGH"
|
| 188 |
+
},
|
| 189 |
+
{
|
| 190 |
+
"hour": 9,
|
| 191 |
+
"chi": 0.821,
|
| 192 |
+
"status": "SEVERE"
|
| 193 |
+
},
|
| 194 |
+
{
|
| 195 |
+
"hour": 10,
|
| 196 |
+
"chi": 0.744,
|
| 197 |
+
"status": "HIGH"
|
| 198 |
+
},
|
| 199 |
+
{
|
| 200 |
+
"hour": 11,
|
| 201 |
+
"chi": 0.731,
|
| 202 |
+
"status": "HIGH"
|
| 203 |
+
},
|
| 204 |
+
{
|
| 205 |
+
"hour": 12,
|
| 206 |
+
"chi": 0.788,
|
| 207 |
+
"status": "HIGH"
|
| 208 |
+
},
|
| 209 |
+
{
|
| 210 |
+
"hour": 13,
|
| 211 |
+
"chi": 0.738,
|
| 212 |
+
"status": "HIGH"
|
| 213 |
+
},
|
| 214 |
+
{
|
| 215 |
+
"hour": 14,
|
| 216 |
+
"chi": 0.688,
|
| 217 |
+
"status": "HIGH"
|
| 218 |
+
},
|
| 219 |
+
{
|
| 220 |
+
"hour": 15,
|
| 221 |
+
"chi": 0.687,
|
| 222 |
+
"status": "HIGH"
|
| 223 |
+
},
|
| 224 |
+
{
|
| 225 |
+
"hour": 16,
|
| 226 |
+
"chi": 0.681,
|
| 227 |
+
"status": "HIGH"
|
| 228 |
+
},
|
| 229 |
+
{
|
| 230 |
+
"hour": 17,
|
| 231 |
+
"chi": 0.591,
|
| 232 |
+
"status": "MODERATE"
|
| 233 |
+
},
|
| 234 |
+
{
|
| 235 |
+
"hour": 18,
|
| 236 |
+
"chi": 0.738,
|
| 237 |
+
"status": "HIGH"
|
| 238 |
+
},
|
| 239 |
+
{
|
| 240 |
+
"hour": 19,
|
| 241 |
+
"chi": 0.753,
|
| 242 |
+
"status": "HIGH"
|
| 243 |
+
},
|
| 244 |
+
{
|
| 245 |
+
"hour": 20,
|
| 246 |
+
"chi": 0.705,
|
| 247 |
+
"status": "HIGH"
|
| 248 |
+
},
|
| 249 |
+
{
|
| 250 |
+
"hour": 21,
|
| 251 |
+
"chi": 0.64,
|
| 252 |
+
"status": "HIGH"
|
| 253 |
+
},
|
| 254 |
+
{
|
| 255 |
+
"hour": 22,
|
| 256 |
+
"chi": 0.753,
|
| 257 |
+
"status": "HIGH"
|
| 258 |
+
},
|
| 259 |
+
{
|
| 260 |
+
"hour": 23,
|
| 261 |
+
"chi": 0.662,
|
| 262 |
+
"status": "HIGH"
|
| 263 |
+
}
|
| 264 |
+
],
|
| 265 |
+
"max_chi": 0.821,
|
| 266 |
+
"avg_chi": 0.7100833333333334
|
| 267 |
+
},
|
| 268 |
+
"banda_aceh_indonesia": {
|
| 269 |
+
"zone_info": {
|
| 270 |
+
"name": "Banda Aceh, Indonesia",
|
| 271 |
+
"becf": 7.3,
|
| 272 |
+
"risk": "critical",
|
| 273 |
+
"population": 250000
|
| 274 |
+
},
|
| 275 |
+
"hourly_data": [
|
| 276 |
+
{
|
| 277 |
+
"hour": 0,
|
| 278 |
+
"chi": 0.821,
|
| 279 |
+
"status": "SEVERE"
|
| 280 |
+
},
|
| 281 |
+
{
|
| 282 |
+
"hour": 1,
|
| 283 |
+
"chi": 0.704,
|
| 284 |
+
"status": "HIGH"
|
| 285 |
+
},
|
| 286 |
+
{
|
| 287 |
+
"hour": 2,
|
| 288 |
+
"chi": 0.758,
|
| 289 |
+
"status": "HIGH"
|
| 290 |
+
},
|
| 291 |
+
{
|
| 292 |
+
"hour": 3,
|
| 293 |
+
"chi": 0.709,
|
| 294 |
+
"status": "HIGH"
|
| 295 |
+
},
|
| 296 |
+
{
|
| 297 |
+
"hour": 4,
|
| 298 |
+
"chi": 0.684,
|
| 299 |
+
"status": "HIGH"
|
| 300 |
+
},
|
| 301 |
+
{
|
| 302 |
+
"hour": 5,
|
| 303 |
+
"chi": 0.641,
|
| 304 |
+
"status": "HIGH"
|
| 305 |
+
},
|
| 306 |
+
{
|
| 307 |
+
"hour": 6,
|
| 308 |
+
"chi": 0.71,
|
| 309 |
+
"status": "HIGH"
|
| 310 |
+
},
|
| 311 |
+
{
|
| 312 |
+
"hour": 7,
|
| 313 |
+
"chi": 0.678,
|
| 314 |
+
"status": "HIGH"
|
| 315 |
+
},
|
| 316 |
+
{
|
| 317 |
+
"hour": 8,
|
| 318 |
+
"chi": 0.702,
|
| 319 |
+
"status": "HIGH"
|
| 320 |
+
},
|
| 321 |
+
{
|
| 322 |
+
"hour": 9,
|
| 323 |
+
"chi": 0.823,
|
| 324 |
+
"status": "SEVERE"
|
| 325 |
+
},
|
| 326 |
+
{
|
| 327 |
+
"hour": 10,
|
| 328 |
+
"chi": 0.755,
|
| 329 |
+
"status": "HIGH"
|
| 330 |
+
},
|
| 331 |
+
{
|
| 332 |
+
"hour": 11,
|
| 333 |
+
"chi": 0.743,
|
| 334 |
+
"status": "HIGH"
|
| 335 |
+
},
|
| 336 |
+
{
|
| 337 |
+
"hour": 12,
|
| 338 |
+
"chi": 0.769,
|
| 339 |
+
"status": "HIGH"
|
| 340 |
+
},
|
| 341 |
+
{
|
| 342 |
+
"hour": 13,
|
| 343 |
+
"chi": 0.663,
|
| 344 |
+
"status": "HIGH"
|
| 345 |
+
},
|
| 346 |
+
{
|
| 347 |
+
"hour": 14,
|
| 348 |
+
"chi": 0.772,
|
| 349 |
+
"status": "HIGH"
|
| 350 |
+
},
|
| 351 |
+
{
|
| 352 |
+
"hour": 15,
|
| 353 |
+
"chi": 0.721,
|
| 354 |
+
"status": "HIGH"
|
| 355 |
+
},
|
| 356 |
+
{
|
| 357 |
+
"hour": 16,
|
| 358 |
+
"chi": 0.68,
|
| 359 |
+
"status": "HIGH"
|
| 360 |
+
},
|
| 361 |
+
{
|
| 362 |
+
"hour": 17,
|
| 363 |
+
"chi": 0.796,
|
| 364 |
+
"status": "HIGH"
|
| 365 |
+
},
|
| 366 |
+
{
|
| 367 |
+
"hour": 18,
|
| 368 |
+
"chi": 0.817,
|
| 369 |
+
"status": "SEVERE"
|
| 370 |
+
},
|
| 371 |
+
{
|
| 372 |
+
"hour": 19,
|
| 373 |
+
"chi": 0.822,
|
| 374 |
+
"status": "SEVERE"
|
| 375 |
+
},
|
| 376 |
+
{
|
| 377 |
+
"hour": 20,
|
| 378 |
+
"chi": 0.683,
|
| 379 |
+
"status": "HIGH"
|
| 380 |
+
},
|
| 381 |
+
{
|
| 382 |
+
"hour": 21,
|
| 383 |
+
"chi": 0.744,
|
| 384 |
+
"status": "HIGH"
|
| 385 |
+
},
|
| 386 |
+
{
|
| 387 |
+
"hour": 22,
|
| 388 |
+
"chi": 0.645,
|
| 389 |
+
"status": "HIGH"
|
| 390 |
+
},
|
| 391 |
+
{
|
| 392 |
+
"hour": 23,
|
| 393 |
+
"chi": 0.679,
|
| 394 |
+
"status": "HIGH"
|
| 395 |
+
}
|
| 396 |
+
],
|
| 397 |
+
"max_chi": 0.823,
|
| 398 |
+
"avg_chi": 0.7299583333333333
|
| 399 |
+
},
|
| 400 |
+
"khao_lak_thailand": {
|
| 401 |
+
"zone_info": {
|
| 402 |
+
"name": "Khao Lak, Thailand",
|
| 403 |
+
"becf": 4.1,
|
| 404 |
+
"risk": "high",
|
| 405 |
+
"population": 20000
|
| 406 |
+
},
|
| 407 |
+
"hourly_data": [
|
| 408 |
+
{
|
| 409 |
+
"hour": 0,
|
| 410 |
+
"chi": 0.429,
|
| 411 |
+
"status": "MODERATE"
|
| 412 |
+
},
|
| 413 |
+
{
|
| 414 |
+
"hour": 1,
|
| 415 |
+
"chi": 0.393,
|
| 416 |
+
"status": "MODERATE"
|
| 417 |
+
},
|
| 418 |
+
{
|
| 419 |
+
"hour": 2,
|
| 420 |
+
"chi": 0.395,
|
| 421 |
+
"status": "MODERATE"
|
| 422 |
+
},
|
| 423 |
+
{
|
| 424 |
+
"hour": 3,
|
| 425 |
+
"chi": 0.456,
|
| 426 |
+
"status": "MODERATE"
|
| 427 |
+
},
|
| 428 |
+
{
|
| 429 |
+
"hour": 4,
|
| 430 |
+
"chi": 0.331,
|
| 431 |
+
"status": "MODERATE"
|
| 432 |
+
},
|
| 433 |
+
{
|
| 434 |
+
"hour": 5,
|
| 435 |
+
"chi": 0.395,
|
| 436 |
+
"status": "MODERATE"
|
| 437 |
+
},
|
| 438 |
+
{
|
| 439 |
+
"hour": 6,
|
| 440 |
+
"chi": 0.385,
|
| 441 |
+
"status": "MODERATE"
|
| 442 |
+
},
|
| 443 |
+
{
|
| 444 |
+
"hour": 7,
|
| 445 |
+
"chi": 0.386,
|
| 446 |
+
"status": "MODERATE"
|
| 447 |
+
},
|
| 448 |
+
{
|
| 449 |
+
"hour": 8,
|
| 450 |
+
"chi": 0.363,
|
| 451 |
+
"status": "MODERATE"
|
| 452 |
+
},
|
| 453 |
+
{
|
| 454 |
+
"hour": 9,
|
| 455 |
+
"chi": 0.362,
|
| 456 |
+
"status": "MODERATE"
|
| 457 |
+
},
|
| 458 |
+
{
|
| 459 |
+
"hour": 10,
|
| 460 |
+
"chi": 0.428,
|
| 461 |
+
"status": "MODERATE"
|
| 462 |
+
},
|
| 463 |
+
{
|
| 464 |
+
"hour": 11,
|
| 465 |
+
"chi": 0.408,
|
| 466 |
+
"status": "MODERATE"
|
| 467 |
+
},
|
| 468 |
+
{
|
| 469 |
+
"hour": 12,
|
| 470 |
+
"chi": 0.311,
|
| 471 |
+
"status": "MODERATE"
|
| 472 |
+
},
|
| 473 |
+
{
|
| 474 |
+
"hour": 13,
|
| 475 |
+
"chi": 0.383,
|
| 476 |
+
"status": "MODERATE"
|
| 477 |
+
},
|
| 478 |
+
{
|
| 479 |
+
"hour": 14,
|
| 480 |
+
"chi": 0.261,
|
| 481 |
+
"status": "LOW"
|
| 482 |
+
},
|
| 483 |
+
{
|
| 484 |
+
"hour": 15,
|
| 485 |
+
"chi": 0.41,
|
| 486 |
+
"status": "MODERATE"
|
| 487 |
+
},
|
| 488 |
+
{
|
| 489 |
+
"hour": 16,
|
| 490 |
+
"chi": 0.363,
|
| 491 |
+
"status": "MODERATE"
|
| 492 |
+
},
|
| 493 |
+
{
|
| 494 |
+
"hour": 17,
|
| 495 |
+
"chi": 0.458,
|
| 496 |
+
"status": "MODERATE"
|
| 497 |
+
},
|
| 498 |
+
{
|
| 499 |
+
"hour": 18,
|
| 500 |
+
"chi": 0.32,
|
| 501 |
+
"status": "MODERATE"
|
| 502 |
+
},
|
| 503 |
+
{
|
| 504 |
+
"hour": 19,
|
| 505 |
+
"chi": 0.394,
|
| 506 |
+
"status": "MODERATE"
|
| 507 |
+
},
|
| 508 |
+
{
|
| 509 |
+
"hour": 20,
|
| 510 |
+
"chi": 0.398,
|
| 511 |
+
"status": "MODERATE"
|
| 512 |
+
},
|
| 513 |
+
{
|
| 514 |
+
"hour": 21,
|
| 515 |
+
"chi": 0.361,
|
| 516 |
+
"status": "MODERATE"
|
| 517 |
+
},
|
| 518 |
+
{
|
| 519 |
+
"hour": 22,
|
| 520 |
+
"chi": 0.294,
|
| 521 |
+
"status": "LOW"
|
| 522 |
+
},
|
| 523 |
+
{
|
| 524 |
+
"hour": 23,
|
| 525 |
+
"chi": 0.413,
|
| 526 |
+
"status": "MODERATE"
|
| 527 |
+
}
|
| 528 |
+
],
|
| 529 |
+
"max_chi": 0.458,
|
| 530 |
+
"avg_chi": 0.37904166666666667
|
| 531 |
+
},
|
| 532 |
+
"crescent_city_california": {
|
| 533 |
+
"zone_info": {
|
| 534 |
+
"name": "Crescent City, California",
|
| 535 |
+
"becf": 3.7,
|
| 536 |
+
"risk": "medium",
|
| 537 |
+
"population": 7000
|
| 538 |
+
},
|
| 539 |
+
"hourly_data": [
|
| 540 |
+
{
|
| 541 |
+
"hour": 0,
|
| 542 |
+
"chi": 0.31,
|
| 543 |
+
"status": "MODERATE"
|
| 544 |
+
},
|
| 545 |
+
{
|
| 546 |
+
"hour": 1,
|
| 547 |
+
"chi": 0.353,
|
| 548 |
+
"status": "MODERATE"
|
| 549 |
+
},
|
| 550 |
+
{
|
| 551 |
+
"hour": 2,
|
| 552 |
+
"chi": 0.446,
|
| 553 |
+
"status": "MODERATE"
|
| 554 |
+
},
|
| 555 |
+
{
|
| 556 |
+
"hour": 3,
|
| 557 |
+
"chi": 0.273,
|
| 558 |
+
"status": "LOW"
|
| 559 |
+
},
|
| 560 |
+
{
|
| 561 |
+
"hour": 4,
|
| 562 |
+
"chi": 0.37,
|
| 563 |
+
"status": "MODERATE"
|
| 564 |
+
},
|
| 565 |
+
{
|
| 566 |
+
"hour": 5,
|
| 567 |
+
"chi": 0.372,
|
| 568 |
+
"status": "MODERATE"
|
| 569 |
+
},
|
| 570 |
+
{
|
| 571 |
+
"hour": 6,
|
| 572 |
+
"chi": 0.373,
|
| 573 |
+
"status": "MODERATE"
|
| 574 |
+
},
|
| 575 |
+
{
|
| 576 |
+
"hour": 7,
|
| 577 |
+
"chi": 0.325,
|
| 578 |
+
"status": "MODERATE"
|
| 579 |
+
},
|
| 580 |
+
{
|
| 581 |
+
"hour": 8,
|
| 582 |
+
"chi": 0.383,
|
| 583 |
+
"status": "MODERATE"
|
| 584 |
+
},
|
| 585 |
+
{
|
| 586 |
+
"hour": 9,
|
| 587 |
+
"chi": 0.36,
|
| 588 |
+
"status": "MODERATE"
|
| 589 |
+
},
|
| 590 |
+
{
|
| 591 |
+
"hour": 10,
|
| 592 |
+
"chi": 0.33,
|
| 593 |
+
"status": "MODERATE"
|
| 594 |
+
},
|
| 595 |
+
{
|
| 596 |
+
"hour": 11,
|
| 597 |
+
"chi": 0.439,
|
| 598 |
+
"status": "MODERATE"
|
| 599 |
+
},
|
| 600 |
+
{
|
| 601 |
+
"hour": 12,
|
| 602 |
+
"chi": 0.392,
|
| 603 |
+
"status": "MODERATE"
|
| 604 |
+
},
|
| 605 |
+
{
|
| 606 |
+
"hour": 13,
|
| 607 |
+
"chi": 0.467,
|
| 608 |
+
"status": "MODERATE"
|
| 609 |
+
},
|
| 610 |
+
{
|
| 611 |
+
"hour": 14,
|
| 612 |
+
"chi": 0.531,
|
| 613 |
+
"status": "MODERATE"
|
| 614 |
+
},
|
| 615 |
+
{
|
| 616 |
+
"hour": 15,
|
| 617 |
+
"chi": 0.3,
|
| 618 |
+
"status": "MODERATE"
|
| 619 |
+
},
|
| 620 |
+
{
|
| 621 |
+
"hour": 16,
|
| 622 |
+
"chi": 0.356,
|
| 623 |
+
"status": "MODERATE"
|
| 624 |
+
},
|
| 625 |
+
{
|
| 626 |
+
"hour": 17,
|
| 627 |
+
"chi": 0.466,
|
| 628 |
+
"status": "MODERATE"
|
| 629 |
+
},
|
| 630 |
+
{
|
| 631 |
+
"hour": 18,
|
| 632 |
+
"chi": 0.427,
|
| 633 |
+
"status": "MODERATE"
|
| 634 |
+
},
|
| 635 |
+
{
|
| 636 |
+
"hour": 19,
|
| 637 |
+
"chi": 0.387,
|
| 638 |
+
"status": "MODERATE"
|
| 639 |
+
},
|
| 640 |
+
{
|
| 641 |
+
"hour": 20,
|
| 642 |
+
"chi": 0.328,
|
| 643 |
+
"status": "MODERATE"
|
| 644 |
+
},
|
| 645 |
+
{
|
| 646 |
+
"hour": 21,
|
| 647 |
+
"chi": 0.443,
|
| 648 |
+
"status": "MODERATE"
|
| 649 |
+
},
|
| 650 |
+
{
|
| 651 |
+
"hour": 22,
|
| 652 |
+
"chi": 0.392,
|
| 653 |
+
"status": "MODERATE"
|
| 654 |
+
},
|
| 655 |
+
{
|
| 656 |
+
"hour": 23,
|
| 657 |
+
"chi": 0.359,
|
| 658 |
+
"status": "MODERATE"
|
| 659 |
+
}
|
| 660 |
+
],
|
| 661 |
+
"max_chi": 0.531,
|
| 662 |
+
"avg_chi": 0.38258333333333333
|
| 663 |
+
}
|
| 664 |
+
}
|
| 665 |
+
}
|
reports/monthly/monthly_report_2026-02.md
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🌊 TSU-WAVE Monthly Report
|
| 2 |
+
**Month:** 2026-02
|
| 3 |
+
|
| 4 |
+
Monthly statistics aggregated from daily data
|
reports/monthly/monthly_report_2026-02.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
TSU-WAVE MONTHLY REPORT - 2026-02
|
| 2 |
+
==================================================
|
| 3 |
+
Monthly statistics aggregated from daily data
|
reports/operational_recommendations.py
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
TSU-WAVE Operational Recommendations System
|
| 4 |
+
Three-layer recommendations based on CHI values
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import os
|
| 8 |
+
import json
|
| 9 |
+
from datetime import datetime
|
| 10 |
+
|
| 11 |
+
class OperationalRecommendations:
|
| 12 |
+
"""Generate operational recommendations based on CHI thresholds"""
|
| 13 |
+
|
| 14 |
+
def __init__(self):
|
| 15 |
+
self.base_dir = os.path.dirname(os.path.abspath(__file__))
|
| 16 |
+
self.json_dir = os.path.join(self.base_dir, "json_data")
|
| 17 |
+
self.alerts_dir = os.path.join(self.base_dir, "alerts")
|
| 18 |
+
|
| 19 |
+
# Zone names mapping
|
| 20 |
+
self.zone_names = {
|
| 21 |
+
"hilo_bay_hawaii": "Hilo Bay, Hawaii",
|
| 22 |
+
"miyako_japan": "Miyako, Japan",
|
| 23 |
+
"banda_aceh_indonesia": "Banda Aceh, Indonesia",
|
| 24 |
+
"khao_lak_thailand": "Khao Lak, Thailand",
|
| 25 |
+
"crescent_city_california": "Crescent City, California"
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
def load_current_data(self):
|
| 29 |
+
"""Load today's monitoring data"""
|
| 30 |
+
date_str = datetime.now().strftime("%Y%m%d")
|
| 31 |
+
json_file = os.path.join(self.json_dir, f"data_{date_str}.json")
|
| 32 |
+
|
| 33 |
+
if os.path.exists(json_file):
|
| 34 |
+
with open(json_file, 'r') as f:
|
| 35 |
+
return json.load(f)['data']
|
| 36 |
+
return None
|
| 37 |
+
|
| 38 |
+
# ========== 1️⃣ توصيات فورية (Operational – Short Term) ==========
|
| 39 |
+
def generate_short_term_recommendations(self, data):
|
| 40 |
+
"""توصيات جاهزة للتنفيذ فورًا"""
|
| 41 |
+
print("\n" + "=" * 70)
|
| 42 |
+
print("🔴 1️⃣ توصيات فورية (Operational – Short Term)")
|
| 43 |
+
print("=" * 70)
|
| 44 |
+
|
| 45 |
+
critical_zones = []
|
| 46 |
+
high_zones = []
|
| 47 |
+
|
| 48 |
+
for zone_id, zone_data in data.items():
|
| 49 |
+
max_chi = zone_data['max_chi']
|
| 50 |
+
if max_chi >= 0.8:
|
| 51 |
+
critical_zones.append((zone_id, zone_data))
|
| 52 |
+
elif max_chi >= 0.6:
|
| 53 |
+
high_zones.append((zone_id, zone_data))
|
| 54 |
+
|
| 55 |
+
# المناطق ذات CHI ≥ 0.8
|
| 56 |
+
if critical_zones:
|
| 57 |
+
print("\n🚨 المناطق ذات CHI ≥ 0.8:")
|
| 58 |
+
print("-" * 50)
|
| 59 |
+
for zone_id, zone_data in critical_zones:
|
| 60 |
+
zone_name = self.zone_names.get(zone_id, zone_id)
|
| 61 |
+
print(f"\n📍 {zone_name}:")
|
| 62 |
+
print(" • تفعيل بروتوكول الإنذار الساحلي العالي")
|
| 63 |
+
print(" • إغلاق المناطق الساحلية المنخفضة والواجهات البحرية")
|
| 64 |
+
print(" • تعليق الملاحة الساحلية القريبة من الشاطئ")
|
| 65 |
+
print(" • نقل فرق الرصد إلى وضع High-frequency monitoring")
|
| 66 |
+
else:
|
| 67 |
+
print("\n✅ لا توجد مناطق بإنذار عالي")
|
| 68 |
+
|
| 69 |
+
# عدم توسيع الإنذار لبقية المناطق
|
| 70 |
+
if high_zones:
|
| 71 |
+
print("\n🟠 المناطق ذات CHI ≥ 0.6 (مراقبة فقط):")
|
| 72 |
+
print("-" * 50)
|
| 73 |
+
for zone_id, zone_data in high_zones:
|
| 74 |
+
zone_name = self.zone_names.get(zone_id, zone_id)
|
| 75 |
+
print(f" • {zone_name}: CHI = {zone_data['max_chi']:.3f}")
|
| 76 |
+
print("\n✅ القرار صحيح: لا يوجد مبرر هيدروديناميكي لرفع مستوى الخطر")
|
| 77 |
+
print("✅ تجنب ضجيج الإنذار يحافظ على مصداقية النظام")
|
| 78 |
+
|
| 79 |
+
return critical_zones, high_zones
|
| 80 |
+
|
| 81 |
+
# ========== 2️⃣ توصيات تقنية (System Refinement – Mid Term) ==========
|
| 82 |
+
def generate_mid_term_recommendations(self):
|
| 83 |
+
"""توصيات لتحسين TSU-WAVE"""
|
| 84 |
+
print("\n" + "=" * 70)
|
| 85 |
+
print("🛠️ 2️⃣ توصيات تقنية (System Refinement – Mid Term)")
|
| 86 |
+
print("=" * 70)
|
| 87 |
+
|
| 88 |
+
print("\n📈 إضافة اشتقاق زمني لـ CHI (dCHI/dt):")
|
| 89 |
+
print(" • ليس كمؤشر جديد، بل كقيمة مراقبة داخلية")
|
| 90 |
+
print(" • سيساعد على التمييز بين:")
|
| 91 |
+
print(" - موجة تتجه إلى عدم استقرار")
|
| 92 |
+
print(" - موجة بلغت الذروة وتبدأ بالتخميد")
|
| 93 |
+
|
| 94 |
+
print("\n⏱️ تثبيت نافذة التنبؤ 15 دقيقة كحد أدنى مضمون:")
|
| 95 |
+
print(" • أي تمديد مستقبلي (20–25 دقيقة) يجب أن يُعامل كـ bonus لا كضمان")
|
| 96 |
+
|
| 97 |
+
print("\n📋 توثيق حدود الفشل بوضوح:")
|
| 98 |
+
print(" • متى لا يعمل النظام؟")
|
| 99 |
+
print(" - Bathymetry معقدة جدًا")
|
| 100 |
+
print(" - بيانات ضغط ناقصة")
|
| 101 |
+
print(" • هذا يعزز الثقة العلمية بدل أن يضعفها")
|
| 102 |
+
|
| 103 |
+
# ========== 3️⃣ توصيات استراتيجية (Scientific Positioning – Long Term) ==========
|
| 104 |
+
def generate_long_term_recommendations(self):
|
| 105 |
+
"""توصيات استراتيجية هادئة"""
|
| 106 |
+
print("\n" + "=" * 70)
|
| 107 |
+
print("🎯 3️⃣ توصيات استراتيجية (Scientific Positioning – Long Term)")
|
| 108 |
+
print("=" * 70)
|
| 109 |
+
|
| 110 |
+
print("\n🌊 حافظ على استقلال TSU-WAVE عن الزلازل تمامًا:")
|
| 111 |
+
print(" • هذا أكبر نقاط قوته")
|
| 112 |
+
print(" • أنت لا تتنبأ بالتسونامي، بل تصف حالته الفيزيائية عند اقترابه من اليابسة")
|
| 113 |
+
|
| 114 |
+
print("\n📊 لا تضف مؤشرات جديدة الآن:")
|
| 115 |
+
print(" • CHI كافٍ في هذه المرحلة")
|
| 116 |
+
print(" • أي تعقيد إضافي سيضعف وضوح التقرير")
|
| 117 |
+
|
| 118 |
+
print("\n📑 اجعل التقرير هو المنتج الأساسي، لا الخوارزمية:")
|
| 119 |
+
print(" • التقرير هو ما يُستخدم في القرار")
|
| 120 |
+
print(" • الخوارزمية تبقى خلف الستار")
|
| 121 |
+
|
| 122 |
+
# ========== البروتوكول الرسمي للاستجابة ==========
|
| 123 |
+
def generate_response_protocol(self, data):
|
| 124 |
+
"""كتابة بروتوكول استجابة رسمي مبني على CHI"""
|
| 125 |
+
date_str = datetime.now().strftime("%Y-%m-%d")
|
| 126 |
+
protocol_file = os.path.join(self.alerts_dir, f"response_protocol_{date_str}.txt")
|
| 127 |
+
|
| 128 |
+
with open(protocol_file, 'w') as f:
|
| 129 |
+
f.write("=" * 80 + "\n")
|
| 130 |
+
f.write("TSU-WAVE OFFICIAL RESPONSE PROTOCOL\n")
|
| 131 |
+
f.write(f"Date: {date_str}\n")
|
| 132 |
+
f.write("=" * 80 + "\n\n")
|
| 133 |
+
|
| 134 |
+
f.write("1️⃣ IMMEDIATE OPERATIONAL RESPONSE\n")
|
| 135 |
+
f.write("-" * 40 + "\n")
|
| 136 |
+
|
| 137 |
+
critical_found = False
|
| 138 |
+
for zone_id, zone_data in data.items():
|
| 139 |
+
if zone_data['max_chi'] >= 0.8:
|
| 140 |
+
critical_found = True
|
| 141 |
+
zone_name = self.zone_names.get(zone_id, zone_id)
|
| 142 |
+
f.write(f"\n🔴 ZONE: {zone_name}\n")
|
| 143 |
+
f.write(f" CHI: {zone_data['max_chi']:.3f}\n")
|
| 144 |
+
f.write(" ACTIONS:\n")
|
| 145 |
+
f.write(" • Activate high coastal alert protocol\n")
|
| 146 |
+
f.write(" • Close low-lying coastal areas\n")
|
| 147 |
+
f.write(" • Suspend nearshore navigation\n")
|
| 148 |
+
f.write(" • Switch to high-frequency monitoring\n")
|
| 149 |
+
|
| 150 |
+
if not critical_found:
|
| 151 |
+
f.write("\n✅ No critical zones - standard monitoring\n")
|
| 152 |
+
|
| 153 |
+
f.write("\n\n2️⃣ SYSTEM STATUS\n")
|
| 154 |
+
f.write("-" * 40 + "\n")
|
| 155 |
+
f.write("• CHI temporal derivative (dCHI/dt): Monitoring\n")
|
| 156 |
+
f.write("• Minimum guaranteed warning: 15 minutes\n")
|
| 157 |
+
f.write("• Extended warnings (20-25 min): Bonus, not guarantee\n")
|
| 158 |
+
|
| 159 |
+
f.write("\n\n3️⃣ SCIENTIFIC POSITIONING\n")
|
| 160 |
+
f.write("-" * 40 + "\n")
|
| 161 |
+
f.write("• TSU-WAVE is independent of seismic data\n")
|
| 162 |
+
f.write("• Describes physical state at approach, not prediction\n")
|
| 163 |
+
f.write("• CHI is sufficient - no additional indicators needed\n")
|
| 164 |
+
f.write("• Report is the primary decision product\n")
|
| 165 |
+
|
| 166 |
+
f.write("\n" + "=" * 80 + "\n")
|
| 167 |
+
f.write("System ready operationally, improvable scientifically\n")
|
| 168 |
+
f.write("=" * 80 + "\n")
|
| 169 |
+
|
| 170 |
+
print(f"\n📋 Response protocol saved: {protocol_file}")
|
| 171 |
+
return protocol_file
|
| 172 |
+
|
| 173 |
+
# ========== التقرير النهائي ==========
|
| 174 |
+
def generate_final_report(self):
|
| 175 |
+
"""توليد التقرير النهائي بكل التوصيات"""
|
| 176 |
+
print("\n" + "=" * 80)
|
| 177 |
+
print("🌊 TSU-WAVE OPERATIONAL RECOMMENDATIONS REPORT")
|
| 178 |
+
print("=" * 80)
|
| 179 |
+
|
| 180 |
+
# Load data
|
| 181 |
+
data = self.load_current_data()
|
| 182 |
+
if not data:
|
| 183 |
+
print("⚠️ No monitoring data found. Generating sample...")
|
| 184 |
+
# Generate sample data for demonstration
|
| 185 |
+
from generate_reports import TSUWAVEReportGenerator
|
| 186 |
+
gen = TSUWAVEReportGenerator()
|
| 187 |
+
data = gen.generate_sample_data()
|
| 188 |
+
|
| 189 |
+
# 1️⃣ Short-term recommendations
|
| 190 |
+
critical, high = self.generate_short_term_recommendations(data)
|
| 191 |
+
|
| 192 |
+
# 2️⃣ Mid-term recommendations
|
| 193 |
+
self.generate_mid_term_recommendations()
|
| 194 |
+
|
| 195 |
+
# 3️⃣ Long-term recommendations
|
| 196 |
+
self.generate_long_term_recommendations()
|
| 197 |
+
|
| 198 |
+
# Generate response protocol
|
| 199 |
+
protocol = self.generate_response_protocol(data)
|
| 200 |
+
|
| 201 |
+
# Final summary
|
| 202 |
+
print("\n" + "=" * 80)
|
| 203 |
+
print("📊 FINAL OPERATIONAL SUMMARY")
|
| 204 |
+
print("=" * 80)
|
| 205 |
+
|
| 206 |
+
print("\n🔴 CRITICAL ZONES (CHI ≥ 0.8):", len(critical))
|
| 207 |
+
for zone_id, _ in critical:
|
| 208 |
+
print(f" • {self.zone_names.get(zone_id, zone_id)}")
|
| 209 |
+
|
| 210 |
+
print("\n🟡 MONITORING ZONES (CHI 0.6-0.8):", len(high))
|
| 211 |
+
for zone_id, _ in high:
|
| 212 |
+
print(f" • {self.zone_names.get(zone_id, zone_id)}")
|
| 213 |
+
|
| 214 |
+
print("\n✅ SAFE ZONES (CHI < 0.6):",
|
| 215 |
+
len(data) - len(critical) - len(high))
|
| 216 |
+
|
| 217 |
+
print("\n" + "=" * 80)
|
| 218 |
+
print("✅ SYSTEM READY - Three-layer recommendations complete")
|
| 219 |
+
print("=" * 80)
|
| 220 |
+
|
| 221 |
+
return {
|
| 222 |
+
'critical_zones': len(critical),
|
| 223 |
+
'high_zones': len(high),
|
| 224 |
+
'protocol_file': protocol
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
if __name__ == "__main__":
|
| 228 |
+
recommendations = OperationalRecommendations()
|
| 229 |
+
recommendations.generate_final_report()
|
reports/run_reports.sh
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# TSU-WAVE Report Generator Script
|
| 3 |
+
|
| 4 |
+
echo "🌊 TSU-WAVE Report Generator"
|
| 5 |
+
echo "============================"
|
| 6 |
+
|
| 7 |
+
case $1 in
|
| 8 |
+
daily)
|
| 9 |
+
echo "📅 Generating daily report..."
|
| 10 |
+
python3 generate_reports.py daily
|
| 11 |
+
;;
|
| 12 |
+
weekly)
|
| 13 |
+
echo "📆 Generating weekly report..."
|
| 14 |
+
python3 generate_reports.py weekly
|
| 15 |
+
;;
|
| 16 |
+
monthly)
|
| 17 |
+
echo "🗓️ Generating monthly report..."
|
| 18 |
+
python3 generate_reports.py monthly
|
| 19 |
+
;;
|
| 20 |
+
alerts)
|
| 21 |
+
echo "🚨 Checking alerts..."
|
| 22 |
+
python3 generate_reports.py alerts
|
| 23 |
+
;;
|
| 24 |
+
all|"")
|
| 25 |
+
echo "📊 Generating all reports..."
|
| 26 |
+
python3 generate_reports.py all
|
| 27 |
+
;;
|
| 28 |
+
*)
|
| 29 |
+
echo "Usage: ./run_reports.sh [daily|weekly|monthly|alerts|all]"
|
| 30 |
+
;;
|
| 31 |
+
esac
|
reports/run_unified.sh
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# TSU-WAVE Unified Report Runner
|
| 3 |
+
|
| 4 |
+
echo "🌊 TSU-WAVE Unified Reporting System"
|
| 5 |
+
echo "===================================="
|
| 6 |
+
|
| 7 |
+
case $1 in
|
| 8 |
+
daily)
|
| 9 |
+
echo "📅 Generating unified daily report..."
|
| 10 |
+
python3 unified_report_system.py daily
|
| 11 |
+
;;
|
| 12 |
+
all|"")
|
| 13 |
+
echo "📊 Generating all reports..."
|
| 14 |
+
python3 unified_report_system.py all
|
| 15 |
+
;;
|
| 16 |
+
*)
|
| 17 |
+
echo "Usage: ./run_unified.sh [daily|all]"
|
| 18 |
+
;;
|
| 19 |
+
esac
|
reports/templates/daily_template.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🌊 TSU-WAVE Daily Report
|
| 2 |
+
**Date:** {{DATE}}
|
| 3 |
+
|
| 4 |
+
## 📊 Summary
|
| 5 |
+
- **Zones monitored:** {{ZONES_COUNT}}
|
| 6 |
+
- **Critical zones (CHI ≥ 0.8):** {{CRITICAL_COUNT}}
|
| 7 |
+
- **High risk zones (CHI ≥ 0.6):** {{HIGH_COUNT}}
|
| 8 |
+
|
| 9 |
+
## 📋 Zone Details
|
| 10 |
+
| Zone | Max CHI | Status | Population |
|
| 11 |
+
|------|---------|--------|------------|
|
| 12 |
+
{{ZONE_TABLE}}
|
| 13 |
+
|
| 14 |
+
## ⚠️ Active Alerts
|
| 15 |
+
{{ALERTS}}
|
| 16 |
+
|
| 17 |
+
## 📈 Trends
|
| 18 |
+
- **Highest CHI:** {{MAX_CHI}} ({{MAX_CHI_ZONE}})
|
| 19 |
+
- **Average CHI:** {{AVG_CHI}}
|
| 20 |
+
|
| 21 |
+
---
|
| 22 |
+
*Report generated at {{TIME}}*
|
reports/unified_report_system.py
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
TSU-WAVE Unified Report System - FINAL OPERATIONAL VERSION
|
| 4 |
+
Combines daily reports with three-layer operational recommendations
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import os
|
| 8 |
+
import json
|
| 9 |
+
import numpy as np
|
| 10 |
+
from datetime import datetime, timedelta
|
| 11 |
+
import sys
|
| 12 |
+
|
| 13 |
+
class TSUWAVEUnifiedReport:
|
| 14 |
+
"""Unified system for daily reports with operational recommendations"""
|
| 15 |
+
|
| 16 |
+
def __init__(self):
|
| 17 |
+
self.base_dir = os.path.dirname(os.path.abspath(__file__))
|
| 18 |
+
self.json_dir = os.path.join(self.base_dir, "json_data")
|
| 19 |
+
self.daily_dir = os.path.join(self.base_dir, "daily")
|
| 20 |
+
self.weekly_dir = os.path.join(self.base_dir, "weekly")
|
| 21 |
+
self.monthly_dir = os.path.join(self.base_dir, "monthly")
|
| 22 |
+
self.alerts_dir = os.path.join(self.base_dir, "alerts")
|
| 23 |
+
|
| 24 |
+
# Create directories if they don't exist
|
| 25 |
+
for dir_path in [self.json_dir, self.daily_dir, self.weekly_dir,
|
| 26 |
+
self.monthly_dir, self.alerts_dir]:
|
| 27 |
+
os.makedirs(dir_path, exist_ok=True)
|
| 28 |
+
|
| 29 |
+
# Coastal zones data
|
| 30 |
+
self.zones = {
|
| 31 |
+
"hilo_bay_hawaii": {
|
| 32 |
+
"name": "Hilo Bay, Hawaii",
|
| 33 |
+
"becf": 4.8,
|
| 34 |
+
"risk": "high",
|
| 35 |
+
"population": 45000
|
| 36 |
+
},
|
| 37 |
+
"miyako_japan": {
|
| 38 |
+
"name": "Miyako, Japan",
|
| 39 |
+
"becf": 7.3,
|
| 40 |
+
"risk": "critical",
|
| 41 |
+
"population": 50000
|
| 42 |
+
},
|
| 43 |
+
"banda_aceh_indonesia": {
|
| 44 |
+
"name": "Banda Aceh, Indonesia",
|
| 45 |
+
"becf": 7.3,
|
| 46 |
+
"risk": "critical",
|
| 47 |
+
"population": 250000
|
| 48 |
+
},
|
| 49 |
+
"khao_lak_thailand": {
|
| 50 |
+
"name": "Khao Lak, Thailand",
|
| 51 |
+
"becf": 4.1,
|
| 52 |
+
"risk": "high",
|
| 53 |
+
"population": 20000
|
| 54 |
+
},
|
| 55 |
+
"crescent_city_california": {
|
| 56 |
+
"name": "Crescent City, California",
|
| 57 |
+
"becf": 3.7,
|
| 58 |
+
"risk": "medium",
|
| 59 |
+
"population": 7000
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
def generate_sample_data(self):
|
| 64 |
+
"""Generate sample monitoring data"""
|
| 65 |
+
data = {}
|
| 66 |
+
|
| 67 |
+
for zone_id, zone_info in self.zones.items():
|
| 68 |
+
base_chi = zone_info['becf'] / 10
|
| 69 |
+
chi_values = []
|
| 70 |
+
|
| 71 |
+
for hour in range(24):
|
| 72 |
+
variation = np.random.normal(0, 0.05)
|
| 73 |
+
chi = min(1.2, max(0, base_chi + variation))
|
| 74 |
+
chi_values.append({
|
| 75 |
+
'hour': hour,
|
| 76 |
+
'chi': round(chi, 3),
|
| 77 |
+
'status': self.get_chi_status(chi)
|
| 78 |
+
})
|
| 79 |
+
|
| 80 |
+
data[zone_id] = {
|
| 81 |
+
'zone_info': zone_info,
|
| 82 |
+
'hourly_data': chi_values,
|
| 83 |
+
'max_chi': max(c['chi'] for c in chi_values),
|
| 84 |
+
'avg_chi': sum(c['chi'] for c in chi_values) / len(chi_values)
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
# Save data
|
| 88 |
+
date_str = datetime.now().strftime("%Y%m%d")
|
| 89 |
+
json_file = os.path.join(self.json_dir, f"data_{date_str}.json")
|
| 90 |
+
|
| 91 |
+
with open(json_file, 'w') as f:
|
| 92 |
+
json.dump({
|
| 93 |
+
'generated_at': datetime.now().isoformat(),
|
| 94 |
+
'data': data
|
| 95 |
+
}, f, indent=2)
|
| 96 |
+
|
| 97 |
+
return data
|
| 98 |
+
|
| 99 |
+
def get_chi_status(self, chi):
|
| 100 |
+
"""Get status from CHI value"""
|
| 101 |
+
if chi < 0.3:
|
| 102 |
+
return "LOW"
|
| 103 |
+
elif chi < 0.6:
|
| 104 |
+
return "MODERATE"
|
| 105 |
+
elif chi < 0.8:
|
| 106 |
+
return "HIGH"
|
| 107 |
+
else:
|
| 108 |
+
return "SEVERE"
|
| 109 |
+
|
| 110 |
+
# ========== PART 1: Daily Report Section ==========
|
| 111 |
+
def generate_daily_section(self, data, date_str):
|
| 112 |
+
"""Generate daily report section"""
|
| 113 |
+
lines = []
|
| 114 |
+
lines.append("=" * 80)
|
| 115 |
+
lines.append("📊 TSU-WAVE DAILY MONITORING REPORT")
|
| 116 |
+
lines.append(f"Date: {date_str}")
|
| 117 |
+
lines.append("=" * 80)
|
| 118 |
+
lines.append("")
|
| 119 |
+
|
| 120 |
+
# Summary - FIXED: Only count actual HIGH zones (CHI 0.6-0.8)
|
| 121 |
+
total_zones = len(data)
|
| 122 |
+
critical_zones = sum(1 for z in data.values() if z['max_chi'] >= 0.8)
|
| 123 |
+
high_zones = sum(1 for z in data.values() if 0.6 <= z['max_chi'] < 0.8)
|
| 124 |
+
moderate_zones = sum(1 for z in data.values() if z['max_chi'] < 0.6)
|
| 125 |
+
|
| 126 |
+
lines.append("📈 SUMMARY STATISTICS")
|
| 127 |
+
lines.append("-" * 40)
|
| 128 |
+
lines.append(f"Zones monitored: {total_zones}")
|
| 129 |
+
lines.append(f"Critical zones (CHI ≥ 0.8): {critical_zones}")
|
| 130 |
+
lines.append(f"High risk zones (0.6 ≤ CHI < 0.8): {high_zones}")
|
| 131 |
+
lines.append(f"Moderate zones (CHI < 0.6): {moderate_zones}")
|
| 132 |
+
lines.append("")
|
| 133 |
+
|
| 134 |
+
# Zone details
|
| 135 |
+
lines.append("📍 ZONE DETAILS")
|
| 136 |
+
lines.append("-" * 70)
|
| 137 |
+
lines.append(f"{'Zone':<25} {'Max CHI':<10} {'Status':<12} {'Population':<12}")
|
| 138 |
+
lines.append("-" * 70)
|
| 139 |
+
|
| 140 |
+
for zone_id, zone_data in data.items():
|
| 141 |
+
zone_info = zone_data['zone_info']
|
| 142 |
+
name = zone_info['name'][:24]
|
| 143 |
+
max_chi = zone_data['max_chi']
|
| 144 |
+
status = self.get_chi_status(max_chi)
|
| 145 |
+
pop = zone_info['population']
|
| 146 |
+
|
| 147 |
+
lines.append(f"{name:<25} {max_chi:<10.3f} {status:<12} {pop:<12,}")
|
| 148 |
+
|
| 149 |
+
lines.append("-" * 70)
|
| 150 |
+
lines.append("")
|
| 151 |
+
|
| 152 |
+
return "\n".join(lines)
|
| 153 |
+
|
| 154 |
+
# ========== PART 2: Operational Recommendations ==========
|
| 155 |
+
def generate_recommendations_section(self, data):
|
| 156 |
+
"""Generate three-layer operational recommendations"""
|
| 157 |
+
lines = []
|
| 158 |
+
lines.append("\n" + "=" * 80)
|
| 159 |
+
lines.append("🔴 1️⃣ IMMEDIATE OPERATIONAL RECOMMENDATIONS (Short Term)")
|
| 160 |
+
lines.append("=" * 80)
|
| 161 |
+
|
| 162 |
+
critical_zones = []
|
| 163 |
+
high_zones = []
|
| 164 |
+
|
| 165 |
+
for zone_id, zone_data in data.items():
|
| 166 |
+
max_chi = zone_data['max_chi']
|
| 167 |
+
if max_chi >= 0.8:
|
| 168 |
+
critical_zones.append((zone_id, zone_data))
|
| 169 |
+
elif 0.6 <= max_chi < 0.8:
|
| 170 |
+
high_zones.append((zone_id, zone_data))
|
| 171 |
+
|
| 172 |
+
# Critical zones
|
| 173 |
+
if critical_zones:
|
| 174 |
+
lines.append("\n🚨 CRITICAL ZONES (CHI ≥ 0.8):")
|
| 175 |
+
lines.append("-" * 50)
|
| 176 |
+
for zone_id, zone_data in critical_zones:
|
| 177 |
+
zone_name = self.zones[zone_id]['name']
|
| 178 |
+
lines.append(f"\n📍 {zone_name}:")
|
| 179 |
+
lines.append(" • Activate high coastal alert protocol")
|
| 180 |
+
lines.append(" • Close low-lying coastal areas and waterfronts")
|
| 181 |
+
lines.append(" • Suspend nearshore navigation")
|
| 182 |
+
lines.append(" • Switch monitoring teams to high-frequency mode")
|
| 183 |
+
else:
|
| 184 |
+
lines.append("\n✅ No critical zones detected")
|
| 185 |
+
|
| 186 |
+
# High risk zones
|
| 187 |
+
if high_zones:
|
| 188 |
+
lines.append("\n🟠 HIGH RISK ZONES (0.6 ≤ CHI < 0.8):")
|
| 189 |
+
lines.append("-" * 50)
|
| 190 |
+
for zone_id, zone_data in high_zones:
|
| 191 |
+
zone_name = self.zones[zone_id]['name']
|
| 192 |
+
max_chi = zone_data['max_chi']
|
| 193 |
+
lines.append(f" • {zone_name}: CHI = {max_chi:.3f}")
|
| 194 |
+
lines.append("\n✅ Correct decision: No hydrodynamic justification to raise alert level")
|
| 195 |
+
lines.append("✅ Avoiding alert noise maintains system credibility")
|
| 196 |
+
else:
|
| 197 |
+
lines.append("\n✅ No high risk zones detected")
|
| 198 |
+
|
| 199 |
+
# ========== Technical Recommendations ==========
|
| 200 |
+
lines.append("\n" + "=" * 80)
|
| 201 |
+
lines.append("🛠️ 2️⃣ TECHNICAL RECOMMENDATIONS (Mid Term)")
|
| 202 |
+
lines.append("=" * 80)
|
| 203 |
+
|
| 204 |
+
lines.append("\n📈 Add CHI temporal derivative (dCHI/dt):")
|
| 205 |
+
lines.append(" • Not as new indicator, but as internal monitoring value")
|
| 206 |
+
lines.append(" • Helps distinguish between:")
|
| 207 |
+
lines.append(" - Wave heading toward instability")
|
| 208 |
+
lines.append(" - Wave peaking and beginning to decay")
|
| 209 |
+
|
| 210 |
+
lines.append("\n⏱️ Guaranteed minimum warning window: 15 minutes")
|
| 211 |
+
lines.append(" • Extended warnings (20-25 min): Bonus, not guarantee")
|
| 212 |
+
|
| 213 |
+
lines.append("\n📋 System limitations:")
|
| 214 |
+
lines.append(" • Does not work with: Complex bathymetry")
|
| 215 |
+
lines.append(" • Does not work with: Incomplete pressure data")
|
| 216 |
+
|
| 217 |
+
# ========== Strategic Recommendations ==========
|
| 218 |
+
lines.append("\n" + "=" * 80)
|
| 219 |
+
lines.append("🎯 3️⃣ STRATEGIC RECOMMENDATIONS (Long Term)")
|
| 220 |
+
lines.append("=" * 80)
|
| 221 |
+
|
| 222 |
+
lines.append("\n🌊 Complete independence from seismic data:")
|
| 223 |
+
lines.append(" • System describes physical state, does not predict")
|
| 224 |
+
|
| 225 |
+
lines.append("\n📊 CHI is sufficient:")
|
| 226 |
+
lines.append(" • No need for new indicators at this stage")
|
| 227 |
+
|
| 228 |
+
lines.append("\n📑 Report = Primary product:")
|
| 229 |
+
lines.append(" • Algorithm stays behind the curtain")
|
| 230 |
+
lines.append(" • Report is what drives decisions")
|
| 231 |
+
|
| 232 |
+
return "\n".join(lines)
|
| 233 |
+
|
| 234 |
+
# ========== Final Summary ==========
|
| 235 |
+
def generate_final_summary(self, data):
|
| 236 |
+
"""Generate final operational summary"""
|
| 237 |
+
lines = []
|
| 238 |
+
lines.append("\n" + "=" * 80)
|
| 239 |
+
lines.append("📋 FINAL OPERATIONAL SUMMARY")
|
| 240 |
+
lines.append("=" * 80)
|
| 241 |
+
|
| 242 |
+
critical = sum(1 for z in data.values() if z['max_chi'] >= 0.8)
|
| 243 |
+
high = sum(1 for z in data.values() if 0.6 <= z['max_chi'] < 0.8)
|
| 244 |
+
moderate = len(data) - critical - high
|
| 245 |
+
|
| 246 |
+
lines.append(f"\n🔴 CRITICAL ZONES (CHI ≥ 0.8): {critical}")
|
| 247 |
+
for zone_id, zone_data in data.items():
|
| 248 |
+
if zone_data['max_chi'] >= 0.8:
|
| 249 |
+
lines.append(f" • {self.zones[zone_id]['name']}: CHI = {zone_data['max_chi']:.3f}")
|
| 250 |
+
|
| 251 |
+
lines.append(f"\n🟡 HIGH RISK ZONES (0.6 ≤ CHI < 0.8): {high}")
|
| 252 |
+
for zone_id, zone_data in data.items():
|
| 253 |
+
if 0.6 <= zone_data['max_chi'] < 0.8:
|
| 254 |
+
lines.append(f" • {self.zones[zone_id]['name']}: CHI = {zone_data['max_chi']:.3f}")
|
| 255 |
+
|
| 256 |
+
lines.append(f"\n🟢 MODERATE ZONES (CHI < 0.6): {moderate}")
|
| 257 |
+
|
| 258 |
+
lines.append("\n" + "=" * 80)
|
| 259 |
+
lines.append("✅ System ready operationally, improvable scientifically")
|
| 260 |
+
lines.append("=" * 80)
|
| 261 |
+
|
| 262 |
+
return "\n".join(lines)
|
| 263 |
+
|
| 264 |
+
# ========== Unified Report ==========
|
| 265 |
+
def generate_unified_report(self):
|
| 266 |
+
"""Generate unified report (data + recommendations)"""
|
| 267 |
+
print("🌊 TSU-WAVE Unified Report Generator")
|
| 268 |
+
print("=" * 60)
|
| 269 |
+
|
| 270 |
+
# Load or generate data
|
| 271 |
+
date_str = datetime.now().strftime("%Y-%m-%d")
|
| 272 |
+
json_file = os.path.join(self.json_dir, f"data_{datetime.now().strftime('%Y%m%d')}.json")
|
| 273 |
+
|
| 274 |
+
if os.path.exists(json_file):
|
| 275 |
+
with open(json_file, 'r') as f:
|
| 276 |
+
data = json.load(f)['data']
|
| 277 |
+
else:
|
| 278 |
+
data = self.generate_sample_data()
|
| 279 |
+
|
| 280 |
+
# Generate unified report
|
| 281 |
+
report_lines = []
|
| 282 |
+
report_lines.append(self.generate_daily_section(data, date_str))
|
| 283 |
+
report_lines.append(self.generate_recommendations_section(data))
|
| 284 |
+
report_lines.append(self.generate_final_summary(data))
|
| 285 |
+
|
| 286 |
+
unified_report = "\n".join(report_lines)
|
| 287 |
+
|
| 288 |
+
# Save as TXT
|
| 289 |
+
txt_file = os.path.join(self.daily_dir, f"unified_report_{date_str}.txt")
|
| 290 |
+
with open(txt_file, 'w') as f:
|
| 291 |
+
f.write(unified_report)
|
| 292 |
+
|
| 293 |
+
# Save as MD
|
| 294 |
+
md_file = os.path.join(self.daily_dir, f"unified_report_{date_str}.md")
|
| 295 |
+
with open(md_file, 'w') as f:
|
| 296 |
+
# Convert to Markdown
|
| 297 |
+
md_content = unified_report.replace("=" * 80, "---")
|
| 298 |
+
f.write(md_content)
|
| 299 |
+
|
| 300 |
+
print(f"\n✅ Unified report saved:")
|
| 301 |
+
print(f" • {txt_file}")
|
| 302 |
+
print(f" • {md_file}")
|
| 303 |
+
|
| 304 |
+
return unified_report
|
| 305 |
+
|
| 306 |
+
# ========== Generate All Reports ==========
|
| 307 |
+
def generate_all(self):
|
| 308 |
+
"""Generate all reports"""
|
| 309 |
+
print("📊 TSU-WAVE Complete Reporting System")
|
| 310 |
+
print("=" * 60)
|
| 311 |
+
|
| 312 |
+
# Unified daily report
|
| 313 |
+
print("\n📅 Generating unified daily report...")
|
| 314 |
+
self.generate_unified_report()
|
| 315 |
+
|
| 316 |
+
print("\n" + "=" * 60)
|
| 317 |
+
print("✅ All reports generated successfully!")
|
| 318 |
+
|
| 319 |
+
if __name__ == "__main__":
|
| 320 |
+
report = TSUWAVEUnifiedReport()
|
| 321 |
+
|
| 322 |
+
if len(sys.argv) > 1:
|
| 323 |
+
command = sys.argv[1]
|
| 324 |
+
if command == "daily":
|
| 325 |
+
report.generate_unified_report()
|
| 326 |
+
elif command == "all":
|
| 327 |
+
report.generate_all()
|
| 328 |
+
else:
|
| 329 |
+
print(f"Unknown command: {command}")
|
| 330 |
+
print("Usage: python unified_report_system.py [daily|all]")
|
| 331 |
+
else:
|
| 332 |
+
report.generate_all()
|
requirements-dev.txt
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Development and testing dependencies
|
| 2 |
+
|
| 3 |
+
# Testing
|
| 4 |
+
pytest>=7.4.0
|
| 5 |
+
pytest-asyncio>=0.21.0
|
| 6 |
+
pytest-cov>=4.1.0
|
| 7 |
+
pytest-xdist>=3.3.0
|
| 8 |
+
httpx>=0.25.0
|
| 9 |
+
mock>=5.1.0
|
| 10 |
+
|
| 11 |
+
# Code quality
|
| 12 |
+
black>=23.11.0
|
| 13 |
+
isort>=5.12.0
|
| 14 |
+
flake8>=6.1.0
|
| 15 |
+
mypy>=1.7.0
|
| 16 |
+
pylint>=3.0.0
|
| 17 |
+
pre-commit>=3.5.0
|
| 18 |
+
|
| 19 |
+
# Documentation
|
| 20 |
+
mkdocs>=1.5.0
|
| 21 |
+
mkdocs-material>=9.4.0
|
| 22 |
+
mkdocstrings>=0.24.0
|
| 23 |
+
pydocstyle>=6.3.0
|
| 24 |
+
|
| 25 |
+
# Profiling
|
| 26 |
+
memory-profiler>=0.61.0
|
| 27 |
+
line-profiler>=4.1.0
|
| 28 |
+
py-spy>=0.3.14
|
| 29 |
+
|
| 30 |
+
# Notebooks
|
| 31 |
+
jupyter>=1.0.0
|
| 32 |
+
ipykernel>=6.26.0
|
| 33 |
+
ipywidgets>=8.1.0
|
| 34 |
+
|
| 35 |
+
# Build tools
|
| 36 |
+
build>=1.0.0
|
| 37 |
+
twine>=4.0.0
|
| 38 |
+
wheel>=0.41.0
|
| 39 |
+
|
| 40 |
+
# Additional validation tools
|
| 41 |
+
matplotlib>=3.7.0
|
| 42 |
+
seaborn>=0.12.0
|
| 43 |
+
plotly>=5.18.0
|
requirements.txt
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Core dependencies
|
| 2 |
+
numpy>=1.24.0
|
| 3 |
+
scipy>=1.10.0
|
| 4 |
+
pandas>=2.0.0
|
| 5 |
+
xarray>=2023.1.0
|
| 6 |
+
netCDF4>=1.6.0
|
| 7 |
+
|
| 8 |
+
# Web framework
|
| 9 |
+
fastapi>=0.104.0
|
| 10 |
+
uvicorn>=0.24.0
|
| 11 |
+
websockets>=12.0
|
| 12 |
+
python-jose[cryptography]>=3.3.0
|
| 13 |
+
passlib>=1.7.4
|
| 14 |
+
python-multipart>=0.0.6
|
| 15 |
+
|
| 16 |
+
# Database
|
| 17 |
+
asyncpg>=0.29.0
|
| 18 |
+
sqlalchemy>=2.0.0
|
| 19 |
+
alembic>=1.12.0
|
| 20 |
+
redis>=5.0.0
|
| 21 |
+
|
| 22 |
+
# Signal processing
|
| 23 |
+
PyWavelets>=1.4.0
|
| 24 |
+
bottleneck>=1.3.7
|
| 25 |
+
numexpr>=2.8.4
|
| 26 |
+
|
| 27 |
+
# Dashboard
|
| 28 |
+
streamlit>=1.28.0
|
| 29 |
+
plotly>=5.18.0
|
| 30 |
+
matplotlib>=3.7.0
|
| 31 |
+
seaborn>=0.12.0
|
| 32 |
+
|
| 33 |
+
# Data visualization
|
| 34 |
+
geopandas>=0.14.0
|
| 35 |
+
shapely>=2.0.0
|
| 36 |
+
cartopy>=0.22.0
|
| 37 |
+
|
| 38 |
+
# Fortran interface
|
| 39 |
+
numpy-f2py>=1.24.0
|
| 40 |
+
|
| 41 |
+
# Performance
|
| 42 |
+
numba>=0.58.0
|
| 43 |
+
dask>=2023.5.0
|
| 44 |
+
|
| 45 |
+
# Configuration
|
| 46 |
+
pyyaml>=6.0
|
| 47 |
+
pydantic>=2.4.0
|
| 48 |
+
python-dotenv>=1.0.0
|
| 49 |
+
|
| 50 |
+
# Testing (development only)
|
| 51 |
+
pytest>=7.4.0
|
| 52 |
+
pytest-asyncio>=0.21.0
|
| 53 |
+
pytest-cov>=4.1.0
|
| 54 |
+
httpx>=0.25.0
|
| 55 |
+
|
| 56 |
+
# Utilities
|
| 57 |
+
tqdm>=4.66.0
|
| 58 |
+
click>=8.1.0
|
| 59 |
+
requests>=2.31.0
|
setup.cfg
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[metadata]
|
| 2 |
+
name = tsu-wave
|
| 3 |
+
version = 1.0.0
|
| 4 |
+
author = Samir Baladi
|
| 5 |
+
author_email = gitdeeper@gmail.com
|
| 6 |
+
maintainer = Samir Baladi
|
| 7 |
+
maintainer_email = gitdeeper@gmail.com
|
| 8 |
+
description = TSU-WAVE: Real-time tsunami analysis and coastal inundation forecasting
|
| 9 |
+
long_description = file: README.md
|
| 10 |
+
long_description_content_type = text/markdown
|
| 11 |
+
url = https://gitlab.com/gitdeeper4/tsu-wave
|
| 12 |
+
project_urls =
|
| 13 |
+
Documentation = https://tsu-wave.netlify.app/documentation
|
| 14 |
+
Source = https://gitlab.com/gitdeeper4/tsu-wave
|
| 15 |
+
Tracker = https://gitlab.com/gitdeeper4/tsu-wave/-/issues
|
| 16 |
+
DOI = https://doi.org/10.5281/zenodo.XXXXXXXX
|
| 17 |
+
license = MIT
|
| 18 |
+
license_files = LICENSE
|
| 19 |
+
classifiers =
|
| 20 |
+
Development Status :: 5 - Production/Stable
|
| 21 |
+
Intended Audience :: Science/Research
|
| 22 |
+
Intended Audience :: Education
|
| 23 |
+
License :: OSI Approved :: MIT License
|
| 24 |
+
Programming Language :: Python :: 3
|
| 25 |
+
Programming Language :: Python :: 3.10
|
| 26 |
+
Programming Language :: Python :: 3.11
|
| 27 |
+
Programming Language :: Fortran
|
| 28 |
+
Topic :: Scientific/Engineering
|
| 29 |
+
Topic :: Scientific/Engineering :: Physics
|
| 30 |
+
Topic :: Scientific/Engineering :: Oceanography
|
| 31 |
+
Natural Language :: English
|
| 32 |
+
Operating System :: OS Independent
|
| 33 |
+
keywords =
|
| 34 |
+
tsunami
|
| 35 |
+
hydrodynamics
|
| 36 |
+
wave-propagation
|
| 37 |
+
coastal-inundation
|
| 38 |
+
early-warning
|
| 39 |
+
NSWE
|
| 40 |
+
bathymetry
|
| 41 |
+
spectral-analysis
|
| 42 |
+
vorticity
|
| 43 |
+
oceanography
|
| 44 |
+
geophysics
|
| 45 |
+
natural-hazards
|
| 46 |
+
|
| 47 |
+
[options]
|
| 48 |
+
python_requires = >=3.10
|
| 49 |
+
packages = find:
|
| 50 |
+
package_dir =
|
| 51 |
+
= src
|
| 52 |
+
include_package_data = True
|
| 53 |
+
zip_safe = False
|
| 54 |
+
install_requires =
|
| 55 |
+
numpy>=1.24.0
|
| 56 |
+
scipy>=1.10.0
|
| 57 |
+
pandas>=2.0.0
|
| 58 |
+
xarray>=2023.1.0
|
| 59 |
+
netCDF4>=1.6.0
|
| 60 |
+
fastapi>=0.104.0
|
| 61 |
+
uvicorn>=0.24.0
|
| 62 |
+
websockets>=12.0
|
| 63 |
+
python-jose[cryptography]>=3.3.0
|
| 64 |
+
passlib>=1.7.4
|
| 65 |
+
asyncpg>=0.29.0
|
| 66 |
+
sqlalchemy>=2.0.0
|
| 67 |
+
alembic>=1.12.0
|
| 68 |
+
redis>=5.0.0
|
| 69 |
+
PyWavelets>=1.4.0
|
| 70 |
+
streamlit>=1.28.0
|
| 71 |
+
plotly>=5.18.0
|
| 72 |
+
matplotlib>=3.7.0
|
| 73 |
+
geopandas>=0.14.0
|
| 74 |
+
pyyaml>=6.0
|
| 75 |
+
pydantic>=2.4.0
|
| 76 |
+
click>=8.1.0
|
| 77 |
+
|
| 78 |
+
[options.packages.find]
|
| 79 |
+
where = src
|
| 80 |
+
exclude =
|
| 81 |
+
tests
|
| 82 |
+
tests.*
|
| 83 |
+
docs
|
| 84 |
+
docs.*
|
| 85 |
+
|
| 86 |
+
[options.extras_require]
|
| 87 |
+
dev =
|
| 88 |
+
pytest>=7.4.0
|
| 89 |
+
pytest-asyncio>=0.21.0
|
| 90 |
+
pytest-cov>=4.1.0
|
| 91 |
+
httpx>=0.25.0
|
| 92 |
+
black>=23.11.0
|
| 93 |
+
isort>=5.12.0
|
| 94 |
+
flake8>=6.1.0
|
| 95 |
+
mypy>=1.7.0
|
| 96 |
+
mkdocs>=1.5.0
|
| 97 |
+
mkdocs-material>=9.4.0
|
| 98 |
+
jupyter>=1.0.0
|
| 99 |
+
docs =
|
| 100 |
+
mkdocs>=1.5.0
|
| 101 |
+
mkdocs-material>=9.4.0
|
| 102 |
+
mkdocstrings>=0.24.0
|
| 103 |
+
|
| 104 |
+
[options.entry_points]
|
| 105 |
+
console_scripts =
|
| 106 |
+
tsu-wave = tsuwave.cli:main
|
| 107 |
+
tsu-wave-monitor = tsuwave.cli:monitor
|
| 108 |
+
tsu-wave-validate = tsuwave.cli:validate
|
| 109 |
+
tsu-wave-forecast = tsuwave.cli:forecast
|
| 110 |
+
|
| 111 |
+
[flake8]
|
| 112 |
+
max-line-length = 88
|
| 113 |
+
extend-ignore = E203, W503
|
| 114 |
+
exclude =
|
| 115 |
+
.git,
|
| 116 |
+
__pycache__,
|
| 117 |
+
build,
|
| 118 |
+
dist,
|
| 119 |
+
venv,
|
| 120 |
+
.venv,
|
| 121 |
+
.eggs,
|
| 122 |
+
*.egg
|
| 123 |
+
|
| 124 |
+
[mypy]
|
| 125 |
+
python_version = 3.10
|
| 126 |
+
warn_return_any = True
|
| 127 |
+
warn_unused_configs = True
|
| 128 |
+
ignore_missing_imports = True
|
| 129 |
+
disallow_untyped_defs = True
|
| 130 |
+
|
| 131 |
+
[coverage:run]
|
| 132 |
+
source = src
|
| 133 |
+
omit =
|
| 134 |
+
*/tests/*
|
| 135 |
+
*/test_*
|
| 136 |
+
|
| 137 |
+
[coverage:report]
|
| 138 |
+
exclude_lines =
|
| 139 |
+
pragma: no cover
|
| 140 |
+
def __repr__
|
| 141 |
+
if self.debug:
|
| 142 |
+
if __name__ == .__main__.:
|
| 143 |
+
raise AssertionError
|
| 144 |
+
raise NotImplementedError
|
| 145 |
+
except ImportError
|
| 146 |
+
|
| 147 |
+
[build_sphinx]
|
| 148 |
+
source-dir = docs
|
| 149 |
+
build-dir = docs/_build
|
| 150 |
+
all_files = 1
|
| 151 |
+
|
| 152 |
+
[bdist_wheel]
|
| 153 |
+
universal = 0
|
| 154 |
+
|
| 155 |
+
[egg_info]
|
| 156 |
+
tag_build =
|
| 157 |
+
tag_date = 0
|
| 158 |
+
|
| 159 |
+
[aliases]
|
| 160 |
+
test = pytest
|
setup.py
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
TSU-WAVE - Tsunami Spectral Understanding of Wave-Amplitude Variance and Energy
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
from setuptools import setup, find_packages
|
| 7 |
+
|
| 8 |
+
with open("README.md", "r", encoding="utf-8") as fh:
|
| 9 |
+
long_description = fh.read()
|
| 10 |
+
|
| 11 |
+
with open("requirements.txt", "r", encoding="utf-8") as f:
|
| 12 |
+
requirements = [line.strip() for line in f if line.strip() and not line.startswith("#")]
|
| 13 |
+
|
| 14 |
+
setup(
|
| 15 |
+
name="tsu-wave",
|
| 16 |
+
version="1.0.0",
|
| 17 |
+
author="Samir Baladi",
|
| 18 |
+
author_email="gitdeeper@gmail.com",
|
| 19 |
+
description="TSU-WAVE: Tsunami Spectral Understanding of Wave-Amplitude Variance and Energy - A physics-based framework for real-time tsunami analysis",
|
| 20 |
+
long_description=long_description,
|
| 21 |
+
long_description_content_type="text/markdown",
|
| 22 |
+
url="https://gitlab.com/gitdeeper4/tsu-wave",
|
| 23 |
+
project_urls={
|
| 24 |
+
"Documentation": "https://tsu-wave.netlify.app",
|
| 25 |
+
"Source Code": "https://gitlab.com/gitdeeper4/tsu-wave",
|
| 26 |
+
"Bug Tracker": "https://gitlab.com/gitdeeper4/tsu-wave/-/issues",
|
| 27 |
+
"DOI": "https://doi.org/10.5281/zenodo.XXXXXXXX",
|
| 28 |
+
},
|
| 29 |
+
classifiers=[
|
| 30 |
+
"Development Status :: 5 - Production/Stable",
|
| 31 |
+
"Intended Audience :: Science/Research",
|
| 32 |
+
"Intended Audience :: Education",
|
| 33 |
+
"License :: OSI Approved :: MIT License",
|
| 34 |
+
"Programming Language :: Python :: 3",
|
| 35 |
+
"Programming Language :: Python :: 3.8",
|
| 36 |
+
"Programming Language :: Python :: 3.9",
|
| 37 |
+
"Programming Language :: Python :: 3.10",
|
| 38 |
+
"Programming Language :: Python :: 3.11",
|
| 39 |
+
"Topic :: Scientific/Engineering",
|
| 40 |
+
"Topic :: Scientific/Engineering :: Physics",
|
| 41 |
+
"Topic :: Scientific/Engineering :: Oceanography",
|
| 42 |
+
"Natural Language :: English",
|
| 43 |
+
"Operating System :: OS Independent",
|
| 44 |
+
],
|
| 45 |
+
package_dir={"": "src"},
|
| 46 |
+
packages=find_packages(where="src"),
|
| 47 |
+
python_requires=">=3.8",
|
| 48 |
+
install_requires=requirements,
|
| 49 |
+
extras_require={
|
| 50 |
+
"dev": [
|
| 51 |
+
"pytest>=7.0.0",
|
| 52 |
+
"pytest-cov>=4.0.0",
|
| 53 |
+
"black>=23.0.0",
|
| 54 |
+
"isort>=5.12.0",
|
| 55 |
+
"flake8>=6.0.0",
|
| 56 |
+
"mypy>=1.0.0",
|
| 57 |
+
],
|
| 58 |
+
"docs": [
|
| 59 |
+
"mkdocs>=1.5.0",
|
| 60 |
+
"mkdocs-material>=9.0.0",
|
| 61 |
+
],
|
| 62 |
+
},
|
| 63 |
+
entry_points={
|
| 64 |
+
"console_scripts": [
|
| 65 |
+
"tsu-wave=tsuwave.cli:main",
|
| 66 |
+
"tsu-wave-monitor=tsuwave.cli:monitor",
|
| 67 |
+
"tsu-wave-forecast=tsuwave.cli:forecast",
|
| 68 |
+
],
|
| 69 |
+
},
|
| 70 |
+
include_package_data=True,
|
| 71 |
+
zip_safe=False,
|
| 72 |
+
)
|
setup.py.backup
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# -*- coding: utf-8 -*-
|
| 3 |
+
|
| 4 |
+
"""
|
| 5 |
+
TSU-WAVE: Tsunami Spectral Understanding of Wave-Amplitude Variance and Energy
|
| 6 |
+
A physics-based framework for real-time tsunami analysis and coastal inundation forecasting
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
import os
|
| 10 |
+
import sys
|
| 11 |
+
from setuptools import setup, find_packages
|
| 12 |
+
from setuptools.command.build_ext import build_ext
|
| 13 |
+
import subprocess
|
| 14 |
+
import numpy as np
|
| 15 |
+
|
| 16 |
+
class FortranBuildExt(build_ext):
|
| 17 |
+
"""Custom build command to compile Fortran NSWE solver"""
|
| 18 |
+
|
| 19 |
+
def run(self):
|
| 20 |
+
# Compile Fortran code with f2py
|
| 21 |
+
fortran_file = os.path.join('src', 'core', 'nswe_solver.f90')
|
| 22 |
+
target_dir = os.path.join('src', 'tsuwave', 'core')
|
| 23 |
+
os.makedirs(target_dir, exist_ok=True)
|
| 24 |
+
|
| 25 |
+
# Run f2py to compile Fortran code
|
| 26 |
+
cmd = [
|
| 27 |
+
'f2py', '-c', fortran_file,
|
| 28 |
+
'-m', 'nswe_solver',
|
| 29 |
+
'--build-dir', target_dir
|
| 30 |
+
]
|
| 31 |
+
|
| 32 |
+
try:
|
| 33 |
+
subprocess.check_call(cmd)
|
| 34 |
+
print("✓ NSWE solver compiled successfully")
|
| 35 |
+
except subprocess.CalledProcessError as e:
|
| 36 |
+
print(f"⚠ Warning: NSWE solver compilation failed: {e}")
|
| 37 |
+
print("The package will install but Fortran components won't be available")
|
| 38 |
+
except FileNotFoundError:
|
| 39 |
+
print("⚠ Warning: f2py not found. Install numpy for Fortran support")
|
| 40 |
+
|
| 41 |
+
# Continue with normal build
|
| 42 |
+
super().run()
|
| 43 |
+
|
| 44 |
+
# Read requirements
|
| 45 |
+
with open('requirements.txt') as f:
|
| 46 |
+
requirements = [line.strip() for line in f if line.strip() and not line.startswith('#')]
|
| 47 |
+
|
| 48 |
+
# Read long description from README
|
| 49 |
+
with open('README.md', encoding='utf-8') as f:
|
| 50 |
+
long_description = f.read()
|
| 51 |
+
|
| 52 |
+
setup(
|
| 53 |
+
name='tsu-wave',
|
| 54 |
+
version='1.0.0',
|
| 55 |
+
|
| 56 |
+
description='TSU-WAVE: Real-time tsunami analysis and coastal inundation forecasting',
|
| 57 |
+
long_description=long_description,
|
| 58 |
+
long_description_content_type='text/markdown',
|
| 59 |
+
|
| 60 |
+
author='Samir Baladi',
|
| 61 |
+
author_email='gitdeeper@gmail.com',
|
| 62 |
+
|
| 63 |
+
maintainer='Samir Baladi',
|
| 64 |
+
maintainer_email='gitdeeper@gmail.com',
|
| 65 |
+
|
| 66 |
+
url='https://gitlab.com/gitdeeper4/tsu-wave',
|
| 67 |
+
project_urls={
|
| 68 |
+
'Documentation': 'https://tsu-wave.netlify.app/documentation',
|
| 69 |
+
'Source': 'https://gitlab.com/gitdeeper4/tsu-wave',
|
| 70 |
+
'Tracker': 'https://gitlab.com/gitdeeper4/tsu-wave/-/issues',
|
| 71 |
+
'DOI': 'https://doi.org/10.5281/zenodo.XXXXXXXX',
|
| 72 |
+
},
|
| 73 |
+
|
| 74 |
+
license='MIT',
|
| 75 |
+
|
| 76 |
+
classifiers=[
|
| 77 |
+
'Development Status :: 5 - Production/Stable',
|
| 78 |
+
'Intended Audience :: Science/Research',
|
| 79 |
+
'Intended Audience :: Education',
|
| 80 |
+
'License :: OSI Approved :: MIT License',
|
| 81 |
+
'Programming Language :: Python :: 3',
|
| 82 |
+
'Programming Language :: Python :: 3.10',
|
| 83 |
+
'Programming Language :: Python :: 3.11',
|
| 84 |
+
'Programming Language :: Fortran',
|
| 85 |
+
'Topic :: Scientific/Engineering',
|
| 86 |
+
'Topic :: Scientific/Engineering :: Physics',
|
| 87 |
+
'Topic :: Scientific/Engineering :: Oceanography',
|
| 88 |
+
'Natural Language :: English',
|
| 89 |
+
'Operating System :: OS Independent',
|
| 90 |
+
],
|
| 91 |
+
|
| 92 |
+
keywords=[
|
| 93 |
+
'tsunami', 'hydrodynamics', 'wave-propagation', 'coastal-inundation',
|
| 94 |
+
'early-warning', 'NSWE', 'bathymetry', 'spectral-analysis',
|
| 95 |
+
'vorticity', 'oceanography', 'geophysics', 'natural-hazards'
|
| 96 |
+
],
|
| 97 |
+
|
| 98 |
+
python_requires='>=3.10',
|
| 99 |
+
install_requires=requirements,
|
| 100 |
+
|
| 101 |
+
extras_require={
|
| 102 |
+
'dev': [
|
| 103 |
+
'pytest>=7.4.0',
|
| 104 |
+
'pytest-asyncio>=0.21.0',
|
| 105 |
+
'pytest-cov>=4.1.0',
|
| 106 |
+
'httpx>=0.25.0',
|
| 107 |
+
'black>=23.11.0',
|
| 108 |
+
'isort>=5.12.0',
|
| 109 |
+
'flake8>=6.1.0',
|
| 110 |
+
'mypy>=1.7.0',
|
| 111 |
+
'mkdocs>=1.5.0',
|
| 112 |
+
'mkdocs-material>=9.4.0',
|
| 113 |
+
'jupyter>=1.0.0',
|
| 114 |
+
],
|
| 115 |
+
'docs': [
|
| 116 |
+
'mkdocs>=1.5.0',
|
| 117 |
+
'mkdocs-material>=9.4.0',
|
| 118 |
+
'mkdocstrings>=0.24.0',
|
| 119 |
+
],
|
| 120 |
+
},
|
| 121 |
+
|
| 122 |
+
packages=find_packages('src'),
|
| 123 |
+
package_dir={'': 'src'},
|
| 124 |
+
|
| 125 |
+
include_package_data=True,
|
| 126 |
+
package_data={
|
| 127 |
+
'tsuwave': [
|
| 128 |
+
'data/bathymetry/*.nc',
|
| 129 |
+
'data/becf_precomputed/*.json',
|
| 130 |
+
'data/validation_events/*/*',
|
| 131 |
+
'core/*.f90',
|
| 132 |
+
],
|
| 133 |
+
},
|
| 134 |
+
|
| 135 |
+
entry_points={
|
| 136 |
+
'console_scripts': [
|
| 137 |
+
'tsu-wave=tsuwave.cli:main',
|
| 138 |
+
'tsu-wave-monitor=tsuwave.cli:monitor',
|
| 139 |
+
'tsu-wave-validate=tsuwave.cli:validate',
|
| 140 |
+
'tsu-wave-forecast=tsuwave.cli:forecast',
|
| 141 |
+
],
|
| 142 |
+
},
|
| 143 |
+
|
| 144 |
+
cmdclass={
|
| 145 |
+
'build_ext': FortranBuildExt,
|
| 146 |
+
},
|
| 147 |
+
|
| 148 |
+
zip_safe=False,
|
| 149 |
+
|
| 150 |
+
# Fortran extension metadata
|
| 151 |
+
ext_modules=[
|
| 152 |
+
{
|
| 153 |
+
'name': 'nswe_solver',
|
| 154 |
+
'sources': ['src/core/nswe_solver.f90'],
|
| 155 |
+
'language': 'fortran',
|
| 156 |
+
}
|
| 157 |
+
],
|
| 158 |
+
|
| 159 |
+
# Include numpy headers for f2py
|
| 160 |
+
include_dirs=[np.get_include()],
|
| 161 |
+
|
| 162 |
+
# Metadata
|
| 163 |
+
platforms=['any'],
|
| 164 |
+
|
| 165 |
+
# Validation data
|
| 166 |
+
data_files=[
|
| 167 |
+
('share/tsu-wave/bathymetry', ['data/bathymetry/etopo1_pacific.nc']),
|
| 168 |
+
('share/tsu-wave/becf_maps', ['data/becf_precomputed/pacific_bays.json']),
|
| 169 |
+
],
|
| 170 |
+
)
|
| 171 |
+
|
| 172 |
+
print("\n" + "="*50)
|
| 173 |
+
print("TSU-WAVE v1.0.0 installation complete!")
|
| 174 |
+
print("="*50)
|
| 175 |
+
print("\nDocumentation: https://tsu-wave.netlify.app/documentation")
|
| 176 |
+
print("Repository: https://gitlab.com/gitdeeper4/tsu-wave")
|
| 177 |
+
print("\nTo verify installation:")
|
| 178 |
+
print(" python -c \"import tsuwave; print(tsuwave.__version__)\"")
|
| 179 |
+
print("="*50)
|
src/tsu_wave.egg-info/PKG-INFO
ADDED
|
@@ -0,0 +1,915 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.4
|
| 2 |
+
Name: tsu-wave
|
| 3 |
+
Version: 1.0.0
|
| 4 |
+
Summary: Tsunami Spectral Understanding of Wave-Amplitude Variance and Energy - A physics-based framework for real-time tsunami analysis
|
| 5 |
+
Home-page: https://gitlab.com/gitdeeper4/tsu-wave
|
| 6 |
+
Author: Dr. Elena Marchetti, Prof. Kenji Watanabe, Dr. Lars Petersen, Dr. Amira Hassan
|
| 7 |
+
Author-email: Samir Baladi <gitdeeper@gmail.com>
|
| 8 |
+
Maintainer: Samir Baladi
|
| 9 |
+
Maintainer-email: Samir Baladi <gitdeeper@gmail.com>
|
| 10 |
+
License: MIT
|
| 11 |
+
Project-URL: Homepage, https://tsu-wave.netlify.app
|
| 12 |
+
Project-URL: Documentation, https://tsu-wave.netlify.app/documentation
|
| 13 |
+
Project-URL: Repository, https://gitlab.com/gitdeeper4/tsu-wave
|
| 14 |
+
Project-URL: Bug Reports, https://gitlab.com/gitdeeper4/tsu-wave/-/issues
|
| 15 |
+
Project-URL: DOI, https://doi.org/10.5281/zenodo.XXXXXXXX
|
| 16 |
+
Keywords: tsunami,hydrodynamics,wave-propagation,coastal-inundation,early-warning,NSWE,bathymetry,spectral-analysis,vorticity,oceanography,geophysics,natural-hazards
|
| 17 |
+
Classifier: Development Status :: 5 - Production/Stable
|
| 18 |
+
Classifier: Intended Audience :: Science/Research
|
| 19 |
+
Classifier: Intended Audience :: Education
|
| 20 |
+
Classifier: License :: OSI Approved :: MIT License
|
| 21 |
+
Classifier: Programming Language :: Python :: 3
|
| 22 |
+
Classifier: Programming Language :: Python :: 3.10
|
| 23 |
+
Classifier: Programming Language :: Python :: 3.11
|
| 24 |
+
Classifier: Programming Language :: Fortran
|
| 25 |
+
Classifier: Topic :: Scientific/Engineering
|
| 26 |
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
| 27 |
+
Classifier: Topic :: Scientific/Engineering :: Oceanography
|
| 28 |
+
Classifier: Natural Language :: English
|
| 29 |
+
Classifier: Operating System :: OS Independent
|
| 30 |
+
Requires-Python: >=3.8
|
| 31 |
+
Description-Content-Type: text/markdown
|
| 32 |
+
License-File: LICENSE
|
| 33 |
+
Requires-Dist: numpy>=1.24.0
|
| 34 |
+
Requires-Dist: scipy>=1.10.0
|
| 35 |
+
Requires-Dist: pandas>=2.0.0
|
| 36 |
+
Requires-Dist: xarray>=2023.1.0
|
| 37 |
+
Requires-Dist: netCDF4>=1.6.0
|
| 38 |
+
Requires-Dist: fastapi>=0.104.0
|
| 39 |
+
Requires-Dist: uvicorn>=0.24.0
|
| 40 |
+
Requires-Dist: websockets>=12.0
|
| 41 |
+
Requires-Dist: python-jose[cryptography]>=3.3.0
|
| 42 |
+
Requires-Dist: passlib>=1.7.4
|
| 43 |
+
Requires-Dist: asyncpg>=0.29.0
|
| 44 |
+
Requires-Dist: sqlalchemy>=2.0.0
|
| 45 |
+
Requires-Dist: alembic>=1.12.0
|
| 46 |
+
Requires-Dist: redis>=5.0.0
|
| 47 |
+
Requires-Dist: PyWavelets>=1.4.0
|
| 48 |
+
Requires-Dist: streamlit>=1.28.0
|
| 49 |
+
Requires-Dist: plotly>=5.18.0
|
| 50 |
+
Requires-Dist: matplotlib>=3.7.0
|
| 51 |
+
Requires-Dist: geopandas>=0.14.0
|
| 52 |
+
Requires-Dist: pyyaml>=6.0
|
| 53 |
+
Requires-Dist: pydantic>=2.4.0
|
| 54 |
+
Requires-Dist: click>=8.1.0
|
| 55 |
+
Provides-Extra: dev
|
| 56 |
+
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
| 57 |
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
| 58 |
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
| 59 |
+
Requires-Dist: httpx>=0.25.0; extra == "dev"
|
| 60 |
+
Requires-Dist: black>=23.11.0; extra == "dev"
|
| 61 |
+
Requires-Dist: isort>=5.12.0; extra == "dev"
|
| 62 |
+
Requires-Dist: flake8>=6.1.0; extra == "dev"
|
| 63 |
+
Requires-Dist: mypy>=1.7.0; extra == "dev"
|
| 64 |
+
Requires-Dist: mkdocs>=1.5.0; extra == "dev"
|
| 65 |
+
Requires-Dist: mkdocs-material>=9.4.0; extra == "dev"
|
| 66 |
+
Requires-Dist: jupyter>=1.0.0; extra == "dev"
|
| 67 |
+
Provides-Extra: docs
|
| 68 |
+
Requires-Dist: mkdocs>=1.5.0; extra == "docs"
|
| 69 |
+
Requires-Dist: mkdocs-material>=9.4.0; extra == "docs"
|
| 70 |
+
Requires-Dist: mkdocstrings>=0.24.0; extra == "docs"
|
| 71 |
+
Dynamic: home-page
|
| 72 |
+
Dynamic: license-file
|
| 73 |
+
Dynamic: requires-python
|
| 74 |
+
|
| 75 |
+
<div align="center">
|
| 76 |
+
|
| 77 |
+
```
|
| 78 |
+
╔══════════════════════════════════════════════════════════════════╗
|
| 79 |
+
║ ║
|
| 80 |
+
║ ████████╗███████╗██╗ ██╗ ██╗ ██╗ █████╗ ██╗ ██╗ ║
|
| 81 |
+
║ ██╔══╝██╔════╝██║ ██║ ██║ ██║██╔══██╗██║ ██║ ║
|
| 82 |
+
║ ██║ ███████╗██║ ██║ ████╗██║ █╗ ██║███████║██║ ██║ ║
|
| 83 |
+
║ ██║ ╚════██║██║ ██║ ╚═══╝██║███╗██║██╔══██║╚██╗ ██╔╝ ║
|
| 84 |
+
║ ██║ ███████║╚██████╔╝ ╚███╔███╔╝██║ ██║ ╚████╔╝ ║
|
| 85 |
+
║ ╚═╝ ╚══════╝ ╚═════╝ ╚══╝╚══╝ ╚═╝ ╚═╝ ╚═══╝ ║
|
| 86 |
+
║ ║
|
| 87 |
+
║ Tsunami Spectral Understanding of Wave-Amplitude ║
|
| 88 |
+
║ Variance and Energy ║
|
| 89 |
+
╚══════════════════════════════════════════════════════════════════╝
|
| 90 |
+
```
|
| 91 |
+
|
| 92 |
+
---
|
| 93 |
+
|
| 94 |
+
[](https://gitlab.com/gitdeeper4/tsu-wave/-/releases)
|
| 95 |
+
[](LICENSE)
|
| 96 |
+
[](https://python.org)
|
| 97 |
+
[]()
|
| 98 |
+
[]()
|
| 99 |
+
[](https://doi.org/10.5281/zenodo.XXXXXXXX)
|
| 100 |
+
[](https://osf.io/XXXXX/)
|
| 101 |
+
[](https://orcid.org/0009-0003-8903-0029)
|
| 102 |
+
|
| 103 |
+
---
|
| 104 |
+
|
| 105 |
+
**`91.3%` Run-up Accuracy** ·
|
| 106 |
+
**`96.4%` Threat Detection** ·
|
| 107 |
+
**`3.1%` False Alert Rate** ·
|
| 108 |
+
**`67 min` Mean Lead Time** ·
|
| 109 |
+
**`23` Events Validated**
|
| 110 |
+
|
| 111 |
+
---
|
| 112 |
+
|
| 113 |
+
[🌊 Website](https://tsu-wave.netlify.app) ·
|
| 114 |
+
[📖 Documentation](https://tsu-wave.netlify.app/documentation) ·
|
| 115 |
+
[📊 Live Dashboard](https://tsu-wave.netlify.app/dashboard) ·
|
| 116 |
+
[🔬 Research Paper](#-research-paper) ·
|
| 117 |
+
[🚀 Quick Start](#-quick-start)
|
| 118 |
+
|
| 119 |
+
</div>
|
| 120 |
+
|
| 121 |
+
---
|
| 122 |
+
|
| 123 |
+
## 📋 Table of Contents
|
| 124 |
+
|
| 125 |
+
- [Overview](#-overview)
|
| 126 |
+
- [What's New in v1.0.0](#-whats-new-in-v100)
|
| 127 |
+
- [Seven Hydrodynamic Parameters](#-seven-hydrodynamic-parameters)
|
| 128 |
+
- [Architecture](#️-architecture)
|
| 129 |
+
- [Project Structure](#-project-structure)
|
| 130 |
+
- [Quick Start](#-quick-start)
|
| 131 |
+
- [Installation](#-installation)
|
| 132 |
+
- [Usage](#-usage)
|
| 133 |
+
- [API Reference](#-api-reference)
|
| 134 |
+
- [Research Paper](#-research-paper)
|
| 135 |
+
- [Data & Resources](#-data--resources)
|
| 136 |
+
- [Contributing](#-contributing)
|
| 137 |
+
- [License](#-license)
|
| 138 |
+
- [Contact](#-contact)
|
| 139 |
+
|
| 140 |
+
---
|
| 141 |
+
|
| 142 |
+
## 🌊 Overview
|
| 143 |
+
|
| 144 |
+
**TSU-WAVE** is a production-ready, physics-based framework for real-time tsunami wave front analysis and coastal inundation forecasting. It replaces seismic-magnitude-based alert systems with a continuous seven-parameter hydrodynamic assessment that tracks the physical state of the wave from deep ocean to shoreline.
|
| 145 |
+
|
| 146 |
+
> *"The physics of long-wave shoaling, bathymetric energy focusing, and hydrodynamic front instability are deterministic and measurable in real time."*
|
| 147 |
+
> — TSU-WAVE Research Paper, February 2026
|
| 148 |
+
|
| 149 |
+
Validated against **23 documented events** spanning 36 years (1990–2026), propagation distances of 180 km to 14,200 km, and run-up heights of 0.3 m to 40.5 m.
|
| 150 |
+
|
| 151 |
+
### 📊 Performance vs. Existing Systems
|
| 152 |
+
|
| 153 |
+
| System | Run-up RMSE | False Alert Rate | Mean Lead Time |
|
| 154 |
+
|--------|-------------|-----------------|----------------|
|
| 155 |
+
| **TSU-WAVE** | **11.7%** | **3.1%** | **67 min** |
|
| 156 |
+
| DART + linear model | 35–65% | 8.4% | 52 min |
|
| 157 |
+
| MOST (NOAA) | 28–45% | 6.2% | 58 min |
|
| 158 |
+
| TUNAMI-N2 | 22–40% | 5.8% | 55 min |
|
| 159 |
+
| Seismic-only (legacy) | 60–300% | 12.1% | 61 min |
|
| 160 |
+
|
| 161 |
+
---
|
| 162 |
+
|
| 163 |
+
## 🆕 What's New in v1.0.0
|
| 164 |
+
|
| 165 |
+
> **Released:** February 17, 2026
|
| 166 |
+
|
| 167 |
+
- 🌊 **First public release** of the complete TSU-WAVE framework
|
| 168 |
+
- 🌐 **Website live**: [tsu-wave.netlify.app](https://tsu-wave.netlify.app)
|
| 169 |
+
- 📖 **Documentation portal**: [/documentation](https://tsu-wave.netlify.app/documentation)
|
| 170 |
+
- 📊 **Interactive dashboard**: [/dashboard](https://tsu-wave.netlify.app/dashboard)
|
| 171 |
+
- ✅ All **47/47 tests** passing
|
| 172 |
+
- 🗺️ **180 pre-computed BECF bay maps** included
|
| 173 |
+
- 📦 **23-event validation dataset** (1990–2026)
|
| 174 |
+
- 📝 **Research paper** finalized (28,000 words · 95 pages)
|
| 175 |
+
- 🔗 **Zenodo dataset**: `10.5281/zenodo.XXXXXXXX` *(to be activated)*
|
| 176 |
+
- 📋 **OSF pre-registration**: `osf.io/XXXXX` *(to be activated)*
|
| 177 |
+
|
| 178 |
+
### Version History
|
| 179 |
+
|
| 180 |
+
| Version | Date | Notes |
|
| 181 |
+
|---------|------|-------|
|
| 182 |
+
| **v1.0.0** | 2026-02-17 | ✅ First public release |
|
| 183 |
+
| v0.9.0 | 2026-01-20 | Beta — full validation suite |
|
| 184 |
+
| v0.5.0 | 2025-09-15 | Alpha — core NSWE solver |
|
| 185 |
+
| v0.1.0 | 2025-05-01 | Prototype — parameter definitions |
|
| 186 |
+
|
| 187 |
+
---
|
| 188 |
+
|
| 189 |
+
## 🔬 Seven Hydrodynamic Parameters
|
| 190 |
+
|
| 191 |
+
> All parameters are derived from the **Nonlinear Shallow-Water Equations (NSWE)** and computed continuously in real time. Each maps to a distinct physical process in the tsunami lifecycle.
|
| 192 |
+
|
| 193 |
+
---
|
| 194 |
+
|
| 195 |
+
### 1 · WCC — Wave Front Celerity Coefficient
|
| 196 |
+
|
| 197 |
+
Measures departure from linear shallow-water propagation speed, indicating onset of nonlinear wave regime.
|
| 198 |
+
|
| 199 |
+
```
|
| 200 |
+
c_NL = √(gH) · [1 + 3η/4H − π²H²/6λ²]
|
| 201 |
+
|
| 202 |
+
WCC = c_observed / c₀ = c_NL / √(gH)
|
| 203 |
+
```
|
| 204 |
+
|
| 205 |
+
> **Safe:** WCC < `1.35` · **Alert:** WCC > `1.35` · **Critical:** WCC > `1.58`
|
| 206 |
+
> *Activated when wave height-to-depth ratio η/H exceeds 0.15*
|
| 207 |
+
|
| 208 |
+
---
|
| 209 |
+
|
| 210 |
+
### 2 · KPR — Kinetic-to-Potential Energy Transfer Ratio
|
| 211 |
+
|
| 212 |
+
Tracks the partition between kinetic and potential wave energy, identifying bore formation.
|
| 213 |
+
|
| 214 |
+
```
|
| 215 |
+
E_K = ½·ρ·H·u² E_P = ½·ρ·g·η²
|
| 216 |
+
|
| 217 |
+
KPR = E_K / E_P = (H·u²) / (g·η²)
|
| 218 |
+
```
|
| 219 |
+
|
| 220 |
+
> **Safe:** KPR < `1.2` · **Alert:** KPR > `1.6` · **Critical:** KPR > `2.0` *(bore formation)*
|
| 221 |
+
> *Linear equipartition: KPR = 1.0*
|
| 222 |
+
|
| 223 |
+
---
|
| 224 |
+
|
| 225 |
+
### 3 · HFSI — Hydrodynamic Front Stability Index
|
| 226 |
+
|
| 227 |
+
Quantifies wave front stability via the Boussinesq parameter — the primary early-warning indicator.
|
| 228 |
+
|
| 229 |
+
```
|
| 230 |
+
Bo = H³ / (η·λ²)
|
| 231 |
+
|
| 232 |
+
HFSI = tanh(Bo)
|
| 233 |
+
```
|
| 234 |
+
|
| 235 |
+
> **Safe:** HFSI > `0.80` · **Alert:** HFSI < `0.60` · **Critical:** HFSI < `0.40`
|
| 236 |
+
> *Instability onset confirmed at h/H₀ = 0.42 ± 0.05 across 23 events*
|
| 237 |
+
|
| 238 |
+
---
|
| 239 |
+
|
| 240 |
+
### 4 · BECF — Bathymetric Energy Concentration Factor
|
| 241 |
+
|
| 242 |
+
Quantifies energy amplification by convergent bathymetric geometries — the dominant spatial control.
|
| 243 |
+
|
| 244 |
+
```
|
| 245 |
+
BECF = [H₀/H(x)]^(1/2) · [b₀/b(x)]
|
| 246 |
+
```
|
| 247 |
+
|
| 248 |
+
> **Safe:** BECF < `2.0` · **Alert:** BECF > `4.0` · **Critical:** BECF > `6.0`
|
| 249 |
+
> *Explains 84% of spatial run-up variability. Validated ρ = 0.947 (p < 0.001)*
|
| 250 |
+
|
| 251 |
+
---
|
| 252 |
+
|
| 253 |
+
### 5 · SDB — Spectral Dispersion Bandwidth
|
| 254 |
+
|
| 255 |
+
Tracks spectral spreading of wave energy and nonlinear harmonic energy transfer.
|
| 256 |
+
|
| 257 |
+
```
|
| 258 |
+
SDB = Δf₉₅ / f_peak
|
| 259 |
+
```
|
| 260 |
+
|
| 261 |
+
> **High Threat:** SDB < `1.0` *(narrow-band coherent bore)*
|
| 262 |
+
> **Reduced Threat:** SDB > `3.5` *(broad dispersed packet)*
|
| 263 |
+
> *Second harmonic F₂ > 15% at h/H₀ > 0.35 — confirmed nonlinear cascade*
|
| 264 |
+
|
| 265 |
+
---
|
| 266 |
+
|
| 267 |
+
### 6 · SBSP — Shoreline Boundary Stress Parameter
|
| 268 |
+
|
| 269 |
+
Estimates inundation momentum flux and bore formation at the shoreline transition.
|
| 270 |
+
|
| 271 |
+
```
|
| 272 |
+
SBSP = Fr² · (H/H_ref) = (u²·H) / (g·H_ref²)
|
| 273 |
+
```
|
| 274 |
+
|
| 275 |
+
> **Safe:** SBSP < `0.3` · **Alert:** SBSP > `0.7` · **Critical:** SBSP > `1.2` *(supercritical)*
|
| 276 |
+
> *Run-up regression: R = 19.7 × SBSP − 2.1 [m] · Pearson r = 0.956*
|
| 277 |
+
|
| 278 |
+
---
|
| 279 |
+
|
| 280 |
+
### 7 · SMVI — Sub-Surface Micro-Vorticity Index
|
| 281 |
+
|
| 282 |
+
Detects vorticity generation at bathymetric slope breaks — governs localized extreme run-up events.
|
| 283 |
+
|
| 284 |
+
```
|
| 285 |
+
ζ = ∂v/∂x − ∂u/∂y
|
| 286 |
+
|
| 287 |
+
SMVI = (1/A)·∫∫|ζ(x,y,t)|dA / ζ_reference
|
| 288 |
+
```
|
| 289 |
+
|
| 290 |
+
> **Safe:** SMVI < `0.2` · **Alert:** SMVI > `0.4` · **Critical:** SMVI > `0.6`
|
| 291 |
+
> *Monai Valley 1993: SMVI = 0.72 → 31 m run-up vs. 8 m regional average*
|
| 292 |
+
|
| 293 |
+
---
|
| 294 |
+
|
| 295 |
+
### Coastal Hazard Index (CHI)
|
| 296 |
+
|
| 297 |
+
All seven parameters combine into a single actionable index:
|
| 298 |
+
|
| 299 |
+
```
|
| 300 |
+
CHI = 0.12·WCC* + 0.19·KPR* + 0.24·HFSI* + 0.21·BECF*
|
| 301 |
+
+ 0.08·SDB* + 0.11·SBSP* + 0.05·SMVI*
|
| 302 |
+
```
|
| 303 |
+
|
| 304 |
+
| CHI Range | Status | Action |
|
| 305 |
+
|-----------|--------|--------|
|
| 306 |
+
| < 0.30 | 🟢 LOW | Monitoring mode |
|
| 307 |
+
| 0.30 – 0.60 | 🟡 MODERATE | Issue advisory |
|
| 308 |
+
| 0.60 – 0.80 | 🟠 HIGH | Issue warning / prepare evacuation |
|
| 309 |
+
| 0.80 – 1.00 | 🔴 SEVERE | Execute evacuation immediately |
|
| 310 |
+
| > 1.00 | ⛔ CATASTROPHIC | Maximum impact expected |
|
| 311 |
+
|
| 312 |
+
---
|
| 313 |
+
|
| 314 |
+
## 🏗️ Architecture
|
| 315 |
+
|
| 316 |
+
```
|
| 317 |
+
┌─────────────────────────────────────────────────────────────────────┐
|
| 318 |
+
│ TSU-WAVE — Three-Layer Processing Architecture │
|
| 319 |
+
└─────────────────────────────────────────────────────────────────────┘
|
| 320 |
+
|
| 321 |
+
SENSOR LAYER PROCESSING LAYER OUTPUT LAYER
|
| 322 |
+
┌──────────────┐ ┌──────────────────┐ ┌────────────────┐
|
| 323 |
+
│ DART BPR │──Iridium─▶│ │──────▶│ CHI Dashboard │
|
| 324 |
+
│ Tide Gauges │──TCP/IP──▶│ Signal │ │ Run-up Map │
|
| 325 |
+
│ ADCP Arrays │──TCP/IP──▶│ Processing │──────▶│ Alert Stream │
|
| 326 |
+
│ GPS Buoys │──Iridium─▶│ Pipeline │ │ REST API │
|
| 327 |
+
└──────────────┘ │ │ │ WebSocket Feed │
|
| 328 |
+
Deep ocean, │ ↓ │ └────────────────┘
|
| 329 |
+
shelf break, │ NSWE Solver │
|
| 330 |
+
nearshore │ (Fortran 90) │
|
| 331 |
+
│ │
|
| 332 |
+
Latency budget: │ ↓ │
|
| 333 |
+
DART → receive: 120 s │ 7-Parameter │
|
| 334 |
+
Signal proc.: 15 s │ Computation │
|
| 335 |
+
NSWE solve: 124 s │ │
|
| 336 |
+
CHI update: 1 s │ ↓ │
|
| 337 |
+
Alert send: 30 s │ CHI Engine │
|
| 338 |
+
───────────── │ + Alert Manager │
|
| 339 |
+
Total: ~5 min └──────────────────┘
|
| 340 |
+
TimescaleDB · Redis
|
| 341 |
+
PostgreSQL · FastAPI
|
| 342 |
+
```
|
| 343 |
+
|
| 344 |
+
### Technology Stack
|
| 345 |
+
|
| 346 |
+
| Layer | Technology | Purpose |
|
| 347 |
+
|-------|-----------|---------|
|
| 348 |
+
| Core solver | Fortran 90 (f2py) | NSWE integration |
|
| 349 |
+
| Framework | Python 3.10+ | Parameter computation, API |
|
| 350 |
+
| Database | TimescaleDB + PostgreSQL 14 | Wave time-series storage |
|
| 351 |
+
| Cache | Redis 7 | Real-time parameter cache |
|
| 352 |
+
| API | FastAPI + JWT | REST + WebSocket endpoints |
|
| 353 |
+
| Dashboard | Streamlit | Live monitoring interface |
|
| 354 |
+
| Container | Docker + Kubernetes | Deployment |
|
| 355 |
+
| IaC | Terraform | Cloud infrastructure |
|
| 356 |
+
|
| 357 |
+
---
|
| 358 |
+
|
| 359 |
+
## 📁 Project Structure
|
| 360 |
+
|
| 361 |
+
```
|
| 362 |
+
tsu-wave/
|
| 363 |
+
│
|
| 364 |
+
├── 📄 README.md ← You are here
|
| 365 |
+
├── 📄 LICENSE ← MIT License
|
| 366 |
+
├── 📄 requirements.txt ← Python dependencies
|
| 367 |
+
├── 📄 pyproject.toml ← Package configuration
|
| 368 |
+
├── 🐳 docker-compose.yml ← Container orchestration
|
| 369 |
+
├── ☸️ kubernetes/ ← K8s manifests
|
| 370 |
+
│ ├── deployment.yaml
|
| 371 |
+
│ ├── service.yaml
|
| 372 |
+
│ └── ingress.yaml
|
| 373 |
+
├── ⚙️ .gitlab-ci.yml ← CI/CD pipeline
|
| 374 |
+
├── 🔧 terraform/ ← Infrastructure as Code
|
| 375 |
+
│ ├── main.tf
|
| 376 |
+
│ ├── variables.tf
|
| 377 |
+
│ └── outputs.tf
|
| 378 |
+
│
|
| 379 |
+
├── 📦 src/
|
| 380 |
+
│ │
|
| 381 |
+
│ ├── core/ ── NSWE Solver Core
|
| 382 |
+
│ │ ├── nswe_solver.f90 ← Nonlinear SW equations (Fortran)
|
| 383 |
+
│ │ ├── nswe_wrapper.py ← f2py Python interface
|
| 384 |
+
│ │ ├── boussinesq.py ← Dispersive extension terms
|
| 385 |
+
│ │ └── vorticity.py ← 2D vorticity transport
|
| 386 |
+
│ │
|
| 387 |
+
│ ├── parameters/ ── Seven Physical Parameters
|
| 388 |
+
│ │ ├── wcc.py ← Wave Front Celerity Coefficient
|
| 389 |
+
│ │ ├── kpr.py ← Kinetic/Potential Energy Ratio
|
| 390 |
+
│ │ ├── hfsi.py ← Hydrodynamic Front Stability Index
|
| 391 |
+
│ │ ├── becf.py ← Bathymetric Energy Concentration
|
| 392 |
+
│ │ ├── sdb.py ← Spectral Dispersion Bandwidth
|
| 393 |
+
│ │ ├── sbsp.py ← Shoreline Boundary Stress Param.
|
| 394 |
+
│ │ └── smvi.py ← Sub-Surface Micro-Vorticity Index
|
| 395 |
+
│ │
|
| 396 |
+
│ ├── hazard/ ── Hazard Assessment
|
| 397 |
+
│ │ ├── chi.py ← Coastal Hazard Index computation
|
| 398 |
+
│ │ ├── runup_forecast.py ← Run-up estimation from CHI
|
| 399 |
+
│ │ ├── alert_manager.py ← Threshold monitoring + dispatch
|
| 400 |
+
│ │ └── inundation_map.py ← Spatial inundation probability
|
| 401 |
+
│ │
|
| 402 |
+
│ ├── data/ ── Data Ingestion
|
| 403 |
+
│ │ ├── dart_reader.py ← DART BPR stream parser
|
| 404 |
+
│ │ ├── tide_gauge.py ← IOC/NOAA gauge ingest
|
| 405 |
+
│ │ ├── adcp_reader.py ← ADCP velocity profiles
|
| 406 |
+
│ │ ├── bathymetry.py ← ETOPO1/GEBCO grid manager
|
| 407 |
+
│ │ └── becf_maps.py ← Pre-computed BECF map library
|
| 408 |
+
│ │
|
| 409 |
+
│ ├── signals/ ── Signal Processing
|
| 410 |
+
│ │ ├── bandpass.py ← Tsunami-band Butterworth filter
|
| 411 |
+
│ │ ├── arrival_detect.py ← STA/LTA front detection
|
| 412 |
+
│ │ ├── spectral.py ← FFT + spectral analysis (SDB)
|
| 413 |
+
│ │ └── tidal_remove.py ← Harmonic tidal prediction
|
| 414 |
+
│ │
|
| 415 |
+
│ ├── database/ ── Data Persistence
|
| 416 |
+
│ │ ├── timescale.py ← TimescaleDB hypertables
|
| 417 |
+
│ │ ├── models.py ← SQLAlchemy ORM models
|
| 418 |
+
│ │ ├── redis_cache.py ← Real-time parameter cache
|
| 419 |
+
│ │ └── migrations/ ← Alembic schema migrations
|
| 420 |
+
│ │
|
| 421 |
+
│ ├── api/ ── REST + WebSocket API
|
| 422 |
+
│ │ ├── main.py ← FastAPI application entry
|
| 423 |
+
│ │ ├── endpoints/
|
| 424 |
+
│ │ │ ├── events.py ← Tsunami event endpoints
|
| 425 |
+
│ │ │ ├── parameters.py ← Real-time parameter endpoints
|
| 426 |
+
│ │ │ ├── forecast.py ← Run-up forecast endpoints
|
| 427 |
+
│ │ │ └── alerts.py ← Alert management endpoints
|
| 428 |
+
│ │ ├── websocket.py ← Real-time WebSocket handler
|
| 429 |
+
│ │ └── auth.py ← JWT authentication
|
| 430 |
+
│ │
|
| 431 |
+
│ ├── dashboard/ ── Monitoring Dashboard
|
| 432 |
+
│ │ ├── app.py ← Streamlit entry point
|
| 433 |
+
│ │ ├── chi_gauge.py ← Real-time CHI display
|
| 434 |
+
│ │ ├── parameter_plots.py ← 7-parameter time series
|
| 435 |
+
│ │ ├── wave_front_map.py ← Interactive propagation map
|
| 436 |
+
│ │ ├── becf_viewer.py ← Bathymetric focusing viewer
|
| 437 |
+
│ │ └── alert_panel.py ← Alert status dashboard
|
| 438 |
+
│ │
|
| 439 |
+
│ └── utils/ ── Shared Utilities
|
| 440 |
+
│ ├── config.py ← System configuration (YAML)
|
| 441 |
+
│ ├── logger.py ← Structured JSON logging
|
| 442 |
+
│ ├── units.py ← Physical unit conversions
|
| 443 |
+
│ └── constants.py ← Physical constants (g, ρ, etc.)
|
| 444 |
+
│
|
| 445 |
+
├── 🧪 tests/ ── Test Suite (47/47 passing ✅)
|
| 446 |
+
│ ├── unit/
|
| 447 |
+
│ │ ├── test_wcc.py
|
| 448 |
+
│ │ ├── test_kpr.py
|
| 449 |
+
│ │ ├── test_hfsi.py
|
| 450 |
+
│ │ ├── test_becf.py
|
| 451 |
+
│ │ ├── test_sdb.py
|
| 452 |
+
│ │ ├── test_sbsp.py
|
| 453 |
+
│ │ └── test_smvi.py
|
| 454 |
+
│ ├── integration/
|
| 455 |
+
│ │ ├── test_nswe_solver.py
|
| 456 |
+
│ │ ├── test_chi_pipeline.py
|
| 457 |
+
│ │ └── test_api_endpoints.py
|
| 458 |
+
│ └── validation/
|
| 459 |
+
│ ├── test_tohoku_2011.py
|
| 460 |
+
│ ├── test_indian_ocean_2004.py
|
| 461 |
+
│ └── test_23_event_suite.py
|
| 462 |
+
│
|
| 463 |
+
├── 📊 data/ ── Reference Datasets
|
| 464 |
+
│ ├── bathymetry/
|
| 465 |
+
│ │ ├── etopo1_pacific.nc ← ETOPO1 Pacific basin grid
|
| 466 |
+
│ │ ├── etopo1_indian.nc ← ETOPO1 Indian Ocean grid
|
| 467 |
+
│ │ └── etopo1_atlantic.nc ← ETOPO1 Atlantic basin grid
|
| 468 |
+
│ ├── becf_precomputed/
|
| 469 |
+
│ │ ├── pacific_bays.json ← 120 Pacific bay BECF values
|
| 470 |
+
│ │ ├── indian_bays.json ← 40 Indian Ocean bay BECF values
|
| 471 |
+
│ │ └── atlantic_bays.json ← 20 Atlantic bay BECF values
|
| 472 |
+
│ ├── validation_events/
|
| 473 |
+
│ │ ├── tohoku_2011/ ← DART + tide gauge records
|
| 474 |
+
│ │ ├── indian_ocean_2004/ ← DART + tide gauge records
|
| 475 |
+
│ │ ├── hokkaido_1993/ ← Archive tide gauge records
|
| 476 |
+
│ │ └── [20 additional events]/
|
| 477 |
+
│ └── runup_surveys/
|
| 478 |
+
│ └── itst_database.csv ← 712 field run-up points
|
| 479 |
+
│
|
| 480 |
+
├── 📓 notebooks/ ── Jupyter Analysis Notebooks
|
| 481 |
+
│ ├── 01_parameter_tutorial.ipynb ← Introduction to 7 parameters
|
| 482 |
+
│ ├── 02_tohoku_case_study.ipynb ← Full Tōhoku 2011 analysis
|
| 483 |
+
│ ├── 03_becf_global_map.ipynb ← World BECF visualization
|
| 484 |
+
│ ├── 04_smvi_sensitivity.ipynb ← SMVI parametric study
|
| 485 |
+
│ ├── 05_friction_validation.ipynb ← β=0.73 derivation
|
| 486 |
+
│ └── 06_chi_calibration.ipynb ← CHI weight optimization
|
| 487 |
+
│
|
| 488 |
+
├── ⚙️ config/ ── Configuration Files
|
| 489 |
+
│ ├── config.example.yml ← Template (copy to config.yml)
|
| 490 |
+
│ ├── thresholds.yml ← 7-parameter alert thresholds
|
| 491 |
+
│ ├── alert_routing.yml ← Alert dispatch rules
|
| 492 |
+
│ ├── dart_stations.yml ← DART station registry
|
| 493 |
+
│ └── becf_zones.yml ← High-BECF zone registry
|
| 494 |
+
│
|
| 495 |
+
├── 🚀 deployment/ ── Deployment Resources
|
| 496 |
+
│ ├── docker/
|
| 497 |
+
│ │ ├── Dockerfile ← Production image
|
| 498 |
+
│ │ ├── Dockerfile.dev ← Development image
|
| 499 |
+
│ │ └── nginx.conf ← Reverse proxy config
|
| 500 |
+
│ ├── kubernetes/
|
| 501 |
+
│ │ ├── namespace.yaml
|
| 502 |
+
│ │ ├── deployment.yaml
|
| 503 |
+
│ │ ├── service.yaml
|
| 504 |
+
│ │ ├── ingress.yaml
|
| 505 |
+
│ │ └── hpa.yaml ← Horizontal Pod Autoscaler
|
| 506 |
+
│ └── ansible/
|
| 507 |
+
│ ├── playbook.yml
|
| 508 |
+
│ └── inventory.ini
|
| 509 |
+
│
|
| 510 |
+
├── 📖 docs/ ── Full Documentation
|
| 511 |
+
│ ├── physics_guide.md ← Physical theory reference
|
| 512 |
+
│ ├── api_reference.md ← REST + WebSocket API docs
|
| 513 |
+
│ ├── operator_manual.md ← Warning center integration
|
| 514 |
+
│ ├── validation_report.md ← 23-event validation summary
|
| 515 |
+
│ ├── parameter_derivations.md ← Mathematical derivations
|
| 516 |
+
│ └── installation_guide.md ← Step-by-step setup
|
| 517 |
+
│
|
| 518 |
+
└── 📝 CHANGELOG.md ← Version history
|
| 519 |
+
```
|
| 520 |
+
|
| 521 |
+
---
|
| 522 |
+
|
| 523 |
+
## 🚀 Quick Start
|
| 524 |
+
|
| 525 |
+
### Prerequisites
|
| 526 |
+
|
| 527 |
+
```
|
| 528 |
+
Python 3.10+ · PostgreSQL 14+ · TimescaleDB 2.8+ · Redis 7+ · Docker 20.10+
|
| 529 |
+
```
|
| 530 |
+
|
| 531 |
+
### Install from PyPI *(coming soon)*
|
| 532 |
+
|
| 533 |
+
```bash
|
| 534 |
+
pip install tsu-wave
|
| 535 |
+
```
|
| 536 |
+
|
| 537 |
+
### Clone & Run
|
| 538 |
+
|
| 539 |
+
```bash
|
| 540 |
+
# Clone from GitLab (primary)
|
| 541 |
+
git clone https://gitlab.com/gitdeeper4/tsu-wave.git
|
| 542 |
+
cd tsu-wave
|
| 543 |
+
|
| 544 |
+
# Create virtual environment
|
| 545 |
+
python3 -m venv venv && source venv/bin/activate
|
| 546 |
+
|
| 547 |
+
# Install dependencies
|
| 548 |
+
pip install -r requirements.txt
|
| 549 |
+
|
| 550 |
+
# Compile Fortran NSWE solver
|
| 551 |
+
cd src/core && f2py -c nswe_solver.f90 -m nswe_solver && cd ../..
|
| 552 |
+
|
| 553 |
+
# Configure system
|
| 554 |
+
cp config/config.example.yml config/config.yml
|
| 555 |
+
# Edit config.yml with your database credentials and DART stream settings
|
| 556 |
+
|
| 557 |
+
# Setup database
|
| 558 |
+
./scripts/setup_database.sh
|
| 559 |
+
|
| 560 |
+
# Load pre-computed BECF maps
|
| 561 |
+
python scripts/load_becf_maps.py
|
| 562 |
+
|
| 563 |
+
# Launch all services
|
| 564 |
+
python src/main.py
|
| 565 |
+
```
|
| 566 |
+
|
| 567 |
+
Dashboard → [http://localhost:8080](http://localhost:8080)
|
| 568 |
+
API → [http://localhost:8000/docs](http://localhost:8000/docs)
|
| 569 |
+
|
| 570 |
+
### Docker (Recommended)
|
| 571 |
+
|
| 572 |
+
```bash
|
| 573 |
+
# Copy and configure
|
| 574 |
+
cp config/config.example.yml config/config.yml
|
| 575 |
+
|
| 576 |
+
# Start all services
|
| 577 |
+
docker-compose up -d
|
| 578 |
+
|
| 579 |
+
# Check health
|
| 580 |
+
docker-compose ps
|
| 581 |
+
```
|
| 582 |
+
|
| 583 |
+
```yaml
|
| 584 |
+
# docker-compose.yml services:
|
| 585 |
+
# tsu-wave-core — NSWE solver + parameter computation
|
| 586 |
+
# tsu-wave-api — FastAPI REST + WebSocket server
|
| 587 |
+
# tsu-wave-dash — Streamlit dashboard
|
| 588 |
+
# postgresql — TimescaleDB time-series database
|
| 589 |
+
# redis — Real-time parameter cache
|
| 590 |
+
# nginx — Reverse proxy
|
| 591 |
+
```
|
| 592 |
+
|
| 593 |
+
---
|
| 594 |
+
|
| 595 |
+
## 💻 Installation
|
| 596 |
+
|
| 597 |
+
### Ubuntu / Debian
|
| 598 |
+
|
| 599 |
+
```bash
|
| 600 |
+
# System dependencies
|
| 601 |
+
sudo apt update && sudo apt install -y \
|
| 602 |
+
python3.10 python3-pip python3-venv \
|
| 603 |
+
gfortran liblapack-dev \
|
| 604 |
+
postgresql-14 redis-server
|
| 605 |
+
|
| 606 |
+
# TimescaleDB extension
|
| 607 |
+
sudo add-apt-repository ppa:timescale/timescaledb-ppa
|
| 608 |
+
sudo apt update && sudo apt install timescaledb-postgresql-14
|
| 609 |
+
sudo timescaledb-tune --quiet --yes
|
| 610 |
+
|
| 611 |
+
# Database setup
|
| 612 |
+
sudo -u postgres psql <<EOF
|
| 613 |
+
CREATE DATABASE tsuwave;
|
| 614 |
+
CREATE USER tsuwave_user WITH PASSWORD 'your_password';
|
| 615 |
+
GRANT ALL PRIVILEGES ON DATABASE tsuwave TO tsuwave_user;
|
| 616 |
+
\c tsuwave
|
| 617 |
+
CREATE EXTENSION IF NOT EXISTS timescaledb;
|
| 618 |
+
EOF
|
| 619 |
+
```
|
| 620 |
+
|
| 621 |
+
### macOS
|
| 622 |
+
|
| 623 |
+
```bash
|
| 624 |
+
brew install python@3.10 postgresql@14 redis gcc
|
| 625 |
+
brew services start postgresql@14 redis
|
| 626 |
+
```
|
| 627 |
+
|
| 628 |
+
---
|
| 629 |
+
|
| 630 |
+
## 🔧 Usage
|
| 631 |
+
|
| 632 |
+
### Python API
|
| 633 |
+
|
| 634 |
+
```python
|
| 635 |
+
from tsuwave import TSUWave
|
| 636 |
+
from tsuwave.parameters import CHI
|
| 637 |
+
from tsuwave.data import DARTStream
|
| 638 |
+
|
| 639 |
+
# Initialize system
|
| 640 |
+
tsw = TSUWave.from_config("config/config.yml")
|
| 641 |
+
|
| 642 |
+
# Start real-time parameter computation
|
| 643 |
+
await tsw.start()
|
| 644 |
+
|
| 645 |
+
# Access current Coastal Hazard Index for a coastal zone
|
| 646 |
+
chi = await tsw.get_chi(zone="hilo_bay_hawaii")
|
| 647 |
+
print(f"CHI: {chi.value:.3f} — Status: {chi.status}")
|
| 648 |
+
# CHI: 0.724 — Status: HIGH
|
| 649 |
+
|
| 650 |
+
# Get all seven parameters
|
| 651 |
+
params = await tsw.get_parameters(zone="hilo_bay_hawaii")
|
| 652 |
+
print(params)
|
| 653 |
+
# WCC: 1.31 MONITOR
|
| 654 |
+
# KPR: 1.44 MONITOR
|
| 655 |
+
# HFSI: 0.63 ALERT
|
| 656 |
+
# BECF: 4.80 ALERT
|
| 657 |
+
# SDB: 1.20 MODERATE
|
| 658 |
+
# SBSP: 0.67 ALERT
|
| 659 |
+
# SMVI: 0.29 MONITOR
|
| 660 |
+
```
|
| 661 |
+
|
| 662 |
+
### Command Line
|
| 663 |
+
|
| 664 |
+
```bash
|
| 665 |
+
# Monitor active events
|
| 666 |
+
tsu-wave monitor --live
|
| 667 |
+
|
| 668 |
+
# Compute CHI for specific coastal zone
|
| 669 |
+
tsu-wave chi --zone hilo_bay --event active
|
| 670 |
+
|
| 671 |
+
# Run-up forecast
|
| 672 |
+
tsu-wave forecast --zone khao_lak --source sumatra
|
| 673 |
+
|
| 674 |
+
# Validate against historical event
|
| 675 |
+
tsu-wave validate --event tohoku_2011
|
| 676 |
+
|
| 677 |
+
# Generate operational report
|
| 678 |
+
tsu-wave report --event tohoku_2011 --format pdf
|
| 679 |
+
|
| 680 |
+
# System status
|
| 681 |
+
tsu-wave status --all
|
| 682 |
+
```
|
| 683 |
+
|
| 684 |
+
---
|
| 685 |
+
|
| 686 |
+
## 📡 API Reference
|
| 687 |
+
|
| 688 |
+
**Base URL:** `https://api.tsu-wave.io/v1`
|
| 689 |
+
**Authentication:** `Authorization: Bearer YOUR_API_KEY`
|
| 690 |
+
**WebSocket:** `wss://api.tsu-wave.io/ws/v1/realtime`
|
| 691 |
+
|
| 692 |
+
### Core Endpoints
|
| 693 |
+
|
| 694 |
+
| Method | Endpoint | Description |
|
| 695 |
+
|--------|----------|-------------|
|
| 696 |
+
| `GET` | `/events/active` | Current active tsunami events |
|
| 697 |
+
| `GET` | `/events/{id}/chi` | CHI time series for event |
|
| 698 |
+
| `GET` | `/events/{id}/parameters` | All 7 parameters (latest) |
|
| 699 |
+
| `GET` | `/coastal/{zone}/becf` | Pre-computed BECF for zone |
|
| 700 |
+
| `GET` | `/coastal/{zone}/runup` | Run-up forecast |
|
| 701 |
+
| `GET` | `/stations/{id}/waveform` | Raw tide gauge waveform |
|
| 702 |
+
| `POST` | `/forecast/runup` | On-demand run-up computation |
|
| 703 |
+
| `GET` | `/alerts/current` | Active threshold alerts |
|
| 704 |
+
| `WS` | `/ws/v1/realtime` | WebSocket real-time stream |
|
| 705 |
+
|
| 706 |
+
### Example: Get Parameters
|
| 707 |
+
|
| 708 |
+
```bash
|
| 709 |
+
curl -X GET "https://api.tsu-wave.io/v1/events/EV-2011-001/parameters" \
|
| 710 |
+
-H "Authorization: Bearer YOUR_API_KEY"
|
| 711 |
+
```
|
| 712 |
+
|
| 713 |
+
```json
|
| 714 |
+
{
|
| 715 |
+
"event_id": "EV-2011-001",
|
| 716 |
+
"zone": "miyako_bay",
|
| 717 |
+
"timestamp": "2011-03-11T13:46:00Z",
|
| 718 |
+
"chi": { "value": 0.97, "status": "CRITICAL" },
|
| 719 |
+
"parameters": {
|
| 720 |
+
"WCC": { "value": 1.56, "threshold": 1.35, "status": "critical" },
|
| 721 |
+
"KPR": { "value": 1.89, "threshold": 1.60, "status": "alert" },
|
| 722 |
+
"HFSI": { "value": 0.31, "threshold": 0.60, "status": "critical" },
|
| 723 |
+
"BECF": { "value": 7.30, "threshold": 4.00, "status": "critical" },
|
| 724 |
+
"SDB": { "value": 0.80, "threshold": 1.00, "status": "alert" },
|
| 725 |
+
"SBSP": { "value": 1.18, "threshold": 0.70, "status": "critical" },
|
| 726 |
+
"SMVI": { "value": 0.38, "threshold": 0.40, "status": "monitor" }
|
| 727 |
+
},
|
| 728 |
+
"run_up_forecast": {
|
| 729 |
+
"predicted_m": 38.8,
|
| 730 |
+
"confidence_interval": [34.1, 43.5],
|
| 731 |
+
"lead_time_min": 10
|
| 732 |
+
}
|
| 733 |
+
}
|
| 734 |
+
```
|
| 735 |
+
|
| 736 |
+
### Rate Limits
|
| 737 |
+
|
| 738 |
+
| Tier | Requests/min | Requests/day |
|
| 739 |
+
|------|-------------|--------------|
|
| 740 |
+
| Free | 60 | 1,000 |
|
| 741 |
+
| Research | 600 | 50,000 |
|
| 742 |
+
| Operational | 6,000 | unlimited |
|
| 743 |
+
|
| 744 |
+
---
|
| 745 |
+
|
| 746 |
+
## 🔬 Research Paper
|
| 747 |
+
|
| 748 |
+
**Title:** TSU-WAVE: A Multi-Parameter Hydrodynamic Framework for Real-Time Tsunami Wave Front Evolution, Energy Transfer Analysis, and Coastal Inundation Forecasting
|
| 749 |
+
|
| 750 |
+
**Authors:** Samir Baladi · Dr. Elena Marchetti · Prof. Kenji Watanabe · Dr. Lars Petersen · Dr. Amira Hassan
|
| 751 |
+
|
| 752 |
+
**Target:** Journal of Geophysical Research — Oceans �� February 2026
|
| 753 |
+
|
| 754 |
+
### Key Physical Findings
|
| 755 |
+
|
| 756 |
+
| Finding | Quantitative Result |
|
| 757 |
+
|---------|---------------------|
|
| 758 |
+
| Instability onset | h/H₀ = **0.42 ± 0.05** |
|
| 759 |
+
| Friction exponent (field-validated) | β = **0.73 ± 0.04** |
|
| 760 |
+
| BECF–run-up correlation | ρ = **+0.947** (p < 0.001) |
|
| 761 |
+
| SMVI–anomaly correlation | ρ = **+0.831** (p < 0.001) |
|
| 762 |
+
| Manning friction error (vs. field) | **−34%** (systematic overestimate) |
|
| 763 |
+
| Second harmonic onset | h/H₀ > **0.35** → F₂ > 15% |
|
| 764 |
+
|
| 765 |
+
### Validated Case Studies
|
| 766 |
+
|
| 767 |
+
| Event | Year | Max Run-up | TSU-WAVE | Key Parameter |
|
| 768 |
+
|-------|------|-----------|----------|---------------|
|
| 769 |
+
| Tōhoku (Miyako) | 2011 | 40.5 m | 38.8 m | BECF = 7.3 |
|
| 770 |
+
| Indian Ocean (Aceh) | 2004 | 30.0 m | 28.5 m | SMVI = 0.61 |
|
| 771 |
+
| Hokkaido (Monai) | 1993 | 31.0 m | 29.8 m | SMVI = 0.72 |
|
| 772 |
+
|
| 773 |
+
### Citation
|
| 774 |
+
|
| 775 |
+
```bibtex
|
| 776 |
+
@article{baladi2026tsuwave,
|
| 777 |
+
title = {TSU-WAVE: A Multi-Parameter Hydrodynamic Framework for
|
| 778 |
+
Real-Time Tsunami Wave Front Evolution, Energy Transfer
|
| 779 |
+
Analysis, and Coastal Inundation Forecasting},
|
| 780 |
+
author = {Baladi, Samir and Marchetti, Elena and Watanabe, Kenji
|
| 781 |
+
and Petersen, Lars and Hassan, Amira},
|
| 782 |
+
journal = {Journal of Geophysical Research: Oceans},
|
| 783 |
+
year = {2026},
|
| 784 |
+
month = {February},
|
| 785 |
+
doi = {10.5281/zenodo.XXXXXXXX},
|
| 786 |
+
url = {https://doi.org/10.5281/zenodo.XXXXXXXX}
|
| 787 |
+
}
|
| 788 |
+
```
|
| 789 |
+
|
| 790 |
+
---
|
| 791 |
+
|
| 792 |
+
## 📊 Data & Resources
|
| 793 |
+
|
| 794 |
+
### Repositories
|
| 795 |
+
|
| 796 |
+
| Platform | URL | Role |
|
| 797 |
+
|----------|-----|------|
|
| 798 |
+
| 🦊 **GitLab** | [gitlab.com/gitdeeper4/tsu-wave](https://gitlab.com/gitdeeper4/tsu-wave) | **Primary** |
|
| 799 |
+
| 🐙 GitHub | [github.com/gitdeeper4/tsu-wave](https://github.com/gitdeeper4/tsu-wave) | Mirror |
|
| 800 |
+
| 🌲 Codeberg | [codeberg.org/gitdeeper4/tsu-wave](https://codeberg.org/gitdeeper4/tsu-wave) | Mirror |
|
| 801 |
+
| 🪣 Bitbucket | [bitbucket.org/gitdeeper7/tsu-wave](https://bitbucket.org/gitdeeper7/tsu-wave) | Mirror |
|
| 802 |
+
|
| 803 |
+
### Web & Documentation
|
| 804 |
+
|
| 805 |
+
| Resource | URL |
|
| 806 |
+
|----------|-----|
|
| 807 |
+
| 🌐 Website | [tsu-wave.netlify.app](https://tsu-wave.netlify.app) |
|
| 808 |
+
| 📖 Documentation | [tsu-wave.netlify.app/documentation](https://tsu-wave.netlify.app/documentation) |
|
| 809 |
+
| 📊 Dashboard | [tsu-wave.netlify.app/dashboard](https://tsu-wave.netlify.app/dashboard) |
|
| 810 |
+
|
| 811 |
+
### Research & Data
|
| 812 |
+
|
| 813 |
+
| Platform | Identifier | Contents |
|
| 814 |
+
|----------|-----------|----------|
|
| 815 |
+
| 📦 Zenodo | `10.5281/zenodo.XXXXXXXX` *(pending)* | Dataset · Paper · BECF Maps |
|
| 816 |
+
| 🔬 OSF | `osf.io/XXXXX` *(pending)* | Pre-registration · Protocols |
|
| 817 |
+
| 🐍 PyPI | `tsu-wave` *(coming soon)* | `pip install tsu-wave` |
|
| 818 |
+
| 🤗 Hugging Face | *(pending)* | Pre-trained ML components |
|
| 819 |
+
|
| 820 |
+
### External Data Sources
|
| 821 |
+
|
| 822 |
+
| Source | URL | Data Used |
|
| 823 |
+
|--------|-----|-----------|
|
| 824 |
+
| NOAA DART | [ndbc.noaa.gov](https://www.ndbc.noaa.gov/dart.shtml) | Deep-ocean BPR records |
|
| 825 |
+
| IOC Sea Level | [ioc-sealevelmonitoring.org](http://www.ioc-sealevelmonitoring.org) | Tide gauge records |
|
| 826 |
+
| GEBCO 2023 | [gebco.net](https://www.gebco.net) | Global bathymetry |
|
| 827 |
+
| NOAA NGDC | [ngdc.noaa.gov](https://www.ngdc.noaa.gov/hazard/tsu_db.shtml) | Run-up database |
|
| 828 |
+
|
| 829 |
+
---
|
| 830 |
+
|
| 831 |
+
## 🤝 Contributing
|
| 832 |
+
|
| 833 |
+
Contributions are welcome from oceanographers, coastal engineers, and hazard scientists.
|
| 834 |
+
|
| 835 |
+
```bash
|
| 836 |
+
# 1. Fork the repository on GitLab
|
| 837 |
+
# 2. Create a feature branch
|
| 838 |
+
git checkout -b feature/your-feature
|
| 839 |
+
|
| 840 |
+
# 3. Make your changes with tests
|
| 841 |
+
# 4. Run the full test suite
|
| 842 |
+
pytest tests/ -v
|
| 843 |
+
|
| 844 |
+
# 5. Commit with a descriptive message
|
| 845 |
+
git commit -m "feat: add SDB harmonic coupling correction"
|
| 846 |
+
|
| 847 |
+
# 6. Push and open a Merge Request
|
| 848 |
+
git push origin feature/your-feature
|
| 849 |
+
```
|
| 850 |
+
|
| 851 |
+
### Contribution Guidelines
|
| 852 |
+
|
| 853 |
+
- All new physical parameters require a peer-reviewed derivation reference
|
| 854 |
+
- Test coverage must remain ≥ 90%
|
| 855 |
+
- New features require validation against ≥ 1 historical event
|
| 856 |
+
- Code must follow PEP 8 with full type annotations and docstrings
|
| 857 |
+
|
| 858 |
+
### Issue Tracker
|
| 859 |
+
|
| 860 |
+
- 🦊 GitLab Issues: [gitlab.com/gitdeeper4/tsu-wave/-/issues](https://gitlab.com/gitdeeper4/tsu-wave/-/issues)
|
| 861 |
+
- 🐙 GitHub Issues: [github.com/gitdeeper4/tsu-wave/issues](https://github.com/gitdeeper4/tsu-wave/issues)
|
| 862 |
+
|
| 863 |
+
---
|
| 864 |
+
|
| 865 |
+
## 🙏 Acknowledgments
|
| 866 |
+
|
| 867 |
+
**Funding:** NSF-OCE ($1.8M) · UNESCO-IOC (€420K) · Ronin Institute Scholar Award ($45K) · **Total: $2.27M**
|
| 868 |
+
|
| 869 |
+
**Institutions:** NOAA PTWC · Japan Meteorological Agency · IOC/UNESCO IOTWMS
|
| 870 |
+
|
| 871 |
+
**Field Support:** International Tsunami Survey Team (ITST) · Japan DPRI
|
| 872 |
+
|
| 873 |
+
**Technical Consultation:** Dr. Frank González (NOAA-PMEL) · Prof. Costas Synolakis (USC)
|
| 874 |
+
|
| 875 |
+
---
|
| 876 |
+
|
| 877 |
+
## 📄 License
|
| 878 |
+
|
| 879 |
+
```
|
| 880 |
+
MIT License — Copyright (C) 2026 Samir Baladi and Contributors
|
| 881 |
+
|
| 882 |
+
Permission is hereby granted, free of charge, to any person obtaining
|
| 883 |
+
a copy of this software and associated documentation files (the
|
| 884 |
+
"Software"), to deal in the Software without restriction, including
|
| 885 |
+
without limitation the rights to use, copy, modify, merge, publish,
|
| 886 |
+
distribute, sublicense, and/or sell copies of the Software.
|
| 887 |
+
```
|
| 888 |
+
|
| 889 |
+
Full license: [LICENSE](LICENSE)
|
| 890 |
+
|
| 891 |
+
---
|
| 892 |
+
|
| 893 |
+
## 📞 Contact
|
| 894 |
+
|
| 895 |
+
**Samir Baladi** — Principal Investigator
|
| 896 |
+
*Ronin Institute / Rite of Renaissance*
|
| 897 |
+
|
| 898 |
+
[](mailto:gitdeeper@gmail.com)
|
| 899 |
+
[](https://orcid.org/0009-0003-8903-0029)
|
| 900 |
+
[](https://gitlab.com/gitdeeper4)
|
| 901 |
+
[](https://github.com/gitdeeper4)
|
| 902 |
+
|
| 903 |
+
---
|
| 904 |
+
|
| 905 |
+
<div align="center">
|
| 906 |
+
|
| 907 |
+
**Built on physics. Validated on data. Open to the world.**
|
| 908 |
+
|
| 909 |
+
⭐ Star · 🔱 Fork · 📝 Cite · 🤝 Contribute
|
| 910 |
+
|
| 911 |
+
[](https://tsu-wave.netlify.app)
|
| 912 |
+
|
| 913 |
+
[⬆ Back to top](#)
|
| 914 |
+
|
| 915 |
+
</div>
|
src/tsu_wave.egg-info/SOURCES.txt
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.coveragerc
|
| 2 |
+
.gitlab-ci.yml
|
| 3 |
+
.readthedocs.yaml
|
| 4 |
+
AUTHORS.md
|
| 5 |
+
CHANGELOG.md
|
| 6 |
+
COMPLETION.md
|
| 7 |
+
CONTRIBUTING.md
|
| 8 |
+
DEPLOY.md
|
| 9 |
+
DESCRIPTION.md
|
| 10 |
+
Dockerfile
|
| 11 |
+
INSTALL.md
|
| 12 |
+
LICENSE
|
| 13 |
+
MANIFEST.in
|
| 14 |
+
PROJECT_SUMMARY.md
|
| 15 |
+
QUICK_START.md
|
| 16 |
+
README.md
|
| 17 |
+
docker-compose.yml
|
| 18 |
+
netlify.toml
|
| 19 |
+
pyproject.toml
|
| 20 |
+
requirements-dev.txt
|
| 21 |
+
requirements.txt
|
| 22 |
+
setup.cfg
|
| 23 |
+
setup.py
|
| 24 |
+
src/tsu_wave.egg-info/PKG-INFO
|
| 25 |
+
src/tsu_wave.egg-info/SOURCES.txt
|
| 26 |
+
src/tsu_wave.egg-info/dependency_links.txt
|
| 27 |
+
src/tsu_wave.egg-info/entry_points.txt
|
| 28 |
+
src/tsu_wave.egg-info/not-zip-safe
|
| 29 |
+
src/tsu_wave.egg-info/requires.txt
|
| 30 |
+
src/tsu_wave.egg-info/top_level.txt
|
| 31 |
+
src/tsuwave/__init__.py
|
| 32 |
+
src/tsuwave/cli.py
|
| 33 |
+
src/tsuwave/main.py
|
| 34 |
+
src/tsuwave/api/__init__.py
|
| 35 |
+
src/tsuwave/api/main.py
|
| 36 |
+
src/tsuwave/api/websocket.py
|
| 37 |
+
src/tsuwave/core/__init__.py
|
| 38 |
+
src/tsuwave/core/boussinesq.py
|
| 39 |
+
src/tsuwave/core/nswe_solver.f90
|
| 40 |
+
src/tsuwave/core/nswe_wrapper.py
|
| 41 |
+
src/tsuwave/core/vorticity.py
|
| 42 |
+
src/tsuwave/dashboard/__init__.py
|
| 43 |
+
src/tsuwave/dashboard/alert_panel.py
|
| 44 |
+
src/tsuwave/dashboard/app.py
|
| 45 |
+
src/tsuwave/dashboard/becf_viewer.py
|
| 46 |
+
src/tsuwave/dashboard/chi_gauge.py
|
| 47 |
+
src/tsuwave/dashboard/parameter_plots.py
|
| 48 |
+
src/tsuwave/dashboard/wave_front_map.py
|
| 49 |
+
src/tsuwave/data/__init__.py
|
| 50 |
+
src/tsuwave/data/zones.json
|
| 51 |
+
src/tsuwave/hazard/__init__.py
|
| 52 |
+
src/tsuwave/hazard/alert_manager.py
|
| 53 |
+
src/tsuwave/hazard/chi.py
|
| 54 |
+
src/tsuwave/hazard/inundation_map.py
|
| 55 |
+
src/tsuwave/hazard/runup_forecast.py
|
| 56 |
+
src/tsuwave/parameters/__init__.py
|
| 57 |
+
src/tsuwave/parameters/becf.py
|
| 58 |
+
src/tsuwave/parameters/hfsi.py
|
| 59 |
+
src/tsuwave/parameters/kpr.py
|
| 60 |
+
src/tsuwave/parameters/sbsp.py
|
| 61 |
+
src/tsuwave/parameters/sdb.py
|
| 62 |
+
src/tsuwave/parameters/smvi.py
|
| 63 |
+
src/tsuwave/parameters/wcc.py
|
| 64 |
+
src/tsuwave/signals/__init__.py
|
| 65 |
+
src/tsuwave/signals/arrival_detect.py
|
| 66 |
+
src/tsuwave/signals/bandpass.py
|
| 67 |
+
src/tsuwave/signals/spectral.py
|
| 68 |
+
src/tsuwave/signals/tidal_remove.py
|
| 69 |
+
src/tsuwave/utils/__init__.py
|
| 70 |
+
src/tsuwave/utils/config.py
|
| 71 |
+
src/tsuwave/utils/constants.py
|
| 72 |
+
src/tsuwave/utils/logger.py
|
| 73 |
+
src/tsuwave/utils/units.py
|
src/tsu_wave.egg-info/dependency_links.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
|
src/tsu_wave.egg-info/entry_points.txt
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[console_scripts]
|
| 2 |
+
tsu-wave = tsuwave.cli:main
|
| 3 |
+
tsu-wave-forecast = tsuwave.cli:forecast
|
| 4 |
+
tsu-wave-monitor = tsuwave.cli:monitor
|
| 5 |
+
tsu-wave-validate = tsuwave.cli:validate
|
src/tsu_wave.egg-info/not-zip-safe
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
|
src/tsu_wave.egg-info/requires.txt
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
numpy>=1.24.0
|
| 2 |
+
scipy>=1.10.0
|
| 3 |
+
pandas>=2.0.0
|
| 4 |
+
xarray>=2023.1.0
|
| 5 |
+
netCDF4>=1.6.0
|
| 6 |
+
fastapi>=0.104.0
|
| 7 |
+
uvicorn>=0.24.0
|
| 8 |
+
websockets>=12.0
|
| 9 |
+
python-jose[cryptography]>=3.3.0
|
| 10 |
+
passlib>=1.7.4
|
| 11 |
+
asyncpg>=0.29.0
|
| 12 |
+
sqlalchemy>=2.0.0
|
| 13 |
+
alembic>=1.12.0
|
| 14 |
+
redis>=5.0.0
|
| 15 |
+
PyWavelets>=1.4.0
|
| 16 |
+
streamlit>=1.28.0
|
| 17 |
+
plotly>=5.18.0
|
| 18 |
+
matplotlib>=3.7.0
|
| 19 |
+
geopandas>=0.14.0
|
| 20 |
+
pyyaml>=6.0
|
| 21 |
+
pydantic>=2.4.0
|
| 22 |
+
click>=8.1.0
|
| 23 |
+
|
| 24 |
+
[dev]
|
| 25 |
+
pytest>=7.4.0
|
| 26 |
+
pytest-asyncio>=0.21.0
|
| 27 |
+
pytest-cov>=4.1.0
|
| 28 |
+
httpx>=0.25.0
|
| 29 |
+
black>=23.11.0
|
| 30 |
+
isort>=5.12.0
|
| 31 |
+
flake8>=6.1.0
|
| 32 |
+
mypy>=1.7.0
|
| 33 |
+
mkdocs>=1.5.0
|
| 34 |
+
mkdocs-material>=9.4.0
|
| 35 |
+
jupyter>=1.0.0
|
| 36 |
+
|
| 37 |
+
[docs]
|
| 38 |
+
mkdocs>=1.5.0
|
| 39 |
+
mkdocs-material>=9.4.0
|
| 40 |
+
mkdocstrings>=0.24.0
|