Historical Seismograms Vectorization, Analysis, and Correction - Web Application
A web-based version of TIITBA built with FastAPI (Python) and vanilla TypeScript. Upload high-resolution seismogram images, digitize traces interactively on an HTML5 canvas, apply signal processing corrections, and export results in ASCII, SAC, or MINISEED formats.
- Backend: FastAPI + OpenCV (headless) + ObsPy + NumPy/SciPy
- Frontend: TypeScript + Vite + Plotly.js (no framework)
- Session state: Per-user sessions with automatic TTL expiry, persisted to disk (
storage/) so the last 5 sessions — including the uploaded image and digitized points — can be restored even after the browser is closed
If you have Python 3 and Node.js installed, you can start the application with a single command. The script handles dependency installation and frontend building automatically.
- Windows: Double-click
run-local.bator run it from the terminal. - Linux/macOS: Run
chmod +x run-local.sh && ./run-local.sh.
Once started, open http://localhost:8000 in your browser.
You don't need to download the source code, just run:
docker run -p 8000:8000 ghcr.io/rdcoronaf/tiitba-web:latestUse this if you want to run your local changes inside a container:
- Windows: Run
run-docker.bat. - Linux/macOS: Run
chmod +x run-docker.sh && ./run-docker.sh.
Or use manual commands:
docker compose up --build -dOpen http://localhost:8000 in your browser. To stop, run docker compose down.
If you prefer to run the components separately for development:
cd tiitba_webapp
python -m venv .venv
source .venv/bin/activate # Linux/macOS
# or: .venv\Scripts\activate # Windows
pip install -r requirements.txt
uvicorn backend.main:app --reload --port 8000cd frontend
npm install
npm run devOpen http://localhost:5173 in your browser. The Vite dev server proxies API requests to the backend on port 8000.
cd frontend
npm run build
# Built files go to frontend/dist/, served by FastAPI automatically
uvicorn backend.main:app --host 0.0.0.0 --port 8000The easiest way to run the application is using Docker. This will build both the frontend and backend and serve them on port 8000.
Using scripts:
- Windows: Double-click
run-docker.bator run it from the terminal. - Linux/macOS: Run
chmod +x run-docker.sh && ./run-docker.sh.
Manual commands:
docker compose up --build -dOpen http://localhost:8000 in your browser. To stop the application, run docker compose down.
- Upload Image - Load a high-resolution seismogram scan. The pixel density (PPI) is auto-detected from the image metadata; if it can't be detected, a modal prompts you to enter it before scale definition and vectorization are enabled.
- Process - Rotate, enhance contrast (CLAHE), binarize (Otsu), trim (draws a highlighted rectangle over the selected ROI)
- Define Scale - Pick time-marks on the image or enter corner coordinates. A status badge confirms the computed drum speed / corner values once the scale is set.
- Vectorize - Click to mark points along the trace (Z=undo, Esc=stop). A one-time instructions popup explains the controls (dismissible via "don't show again").
- Apply Corrections - Detrend, curvature correction, resample, Wiechert response. If you didn't upload a separate ASCII file, the Corrections module automatically picks up the digitized points from the Vectorization step (once a scale is defined).
- Export - Download as ASCII, SAC, or MINISEED. SAC/MINISEED exports prompt for station, network, channel, and start time; MINISEED additionally asks for the component (Z/N/E), since it can hold multiple channels.
The app keeps a rolling history of the last 5 sessions on disk (storage/), independent
of the browser — click History in the sidebar to see recent sessions and restore one
(image, scale, and digitized points are all reloaded onto the canvas).
With the backend running, visit http://localhost:8000/docs for the interactive Swagger UI.
tiitba_webapp/
├── backend/
│ ├── main.py # FastAPI app entry point
│ ├── config.py # Settings
│ ├── session.py # Session state management
│ ├── dependencies.py # FastAPI dependency injection
│ ├── schemas.py # Pydantic models
│ ├── utils.py # Image encoding utilities
│ ├── core/ # Business logic (pure Python)
│ │ ├── corrections.py # Detrend, G&A94, resample, Wiechert
│ │ ├── image_processing.py # OpenCV operations
│ │ ├── io.py # ASCII, SAC, MINISEED I/O
│ │ ├── vectorization.py # Pixel-to-physical conversion
│ │ └── math_helpers.py # Numerical utilities
│ └── routers/
│ ├── images.py # Image upload and processing
│ ├── vectorization.py # Scale definition and points
│ ├── corrections.py # Signal processing corrections
│ └── export.py # File format exports
├── frontend/
│ ├── index.html
│ ├── package.json
│ └── src/
│ ├── main.ts # App initialization
│ ├── api.ts # Backend API client
│ ├── state.ts # Client state management
│ ├── components/ # UI components (incl. modal.ts, the shared modal system)
│ └── utils/ # Canvas math, keyboard shortcuts
├── storage/ # Persisted session data (images, points, history) — gitignored
├── requirements.txt
├── Dockerfile
└── README.md
If you use TIITBA to obtain time series or any result, please cite:
Corona-Fernandez, R.D. & Santoyo, M.A. (2022) Re-examination of the 1928 Parral, Mexico earthquake (M6.3). Geoscience Data Journal. https://doi.org/10.1002/gdj3.159
See LICENSE for terms.