Python implementation of HASH for earthquake focal mechanism determination from P-wave polarities.
Python uses Numba JIT compilation optimization and vectorization, achieving speed improvements while maintaining complete consistency with the core Fortran algorithm.
| Metric | Python+Numba | Fortran | Speedup |
|---|---|---|---|
| 24 events | 0.068s | 0.473s | 6.9x |
| Per event | 2.85ms | 19.7ms | 6.9x |
| 5000 events | 13.0s | 98.5s | 7.6x |
| 10000 events | 26.0s | 197.0s | 7.6x |
Key Results:
- Python dip error median: 5.6° (Fortran: 11.1°)
- Python rake error median: 24.1° (Fortran: 26.6°)
- Python synthetic trials: 300/300 successful solutions
- Fortran synthetic trials: 60/60 successful solutions (direct-runs)
Note: Strike differences (40-80°) are normal - focal mechanisms have two orthogonal nodal planes that both satisfy polarity data.
pip install cnchashfrom cnchash import run_hash
import numpy as np
# Azimuths, takeoff angles, polarities, quality
p_azi = np.array([45.0, 135.0, 225.0, 315.0])
p_the = np.array([30.0, 45.0, 60.0, 75.0])
p_pol = np.array([1, -1, 1, -1]) # 1=up, -1=down
p_qual = np.array([0, 0, 0, 0])
result = run_hash(p_azi, p_the, p_pol, p_qual)
print(f"Strike: {result['strike_avg']:.1f}")
print(f"Dip: {result['dip_avg']:.1f}")
print(f"Rake: {result['rake_avg']:.1f}")
print(f"Quality: {result['quality']}")from cnchash import run_hash_with_amp
import numpy as np
# Same inputs as above, plus S/P amplitude ratios (log10 scale)
# sp_amp = 0.0 means no amplitude data for that station
sp_amp = np.array([0.3, -0.2, 0.5, 0.0]) # log10(S/P), 0.0 = no data
result = run_hash_with_amp(p_azi, p_the, p_pol, sp_amp)
print(f"Strike: {result['strike_avg']:.1f}")
print(f"Dip: {result['dip_avg']:.1f}")
print(f"Rake: {result['rake_avg']:.1f}")
print(f"Quality: {result['quality']}")
print(f"Polarity misfit: {result['mfrac']*100:.1f}%")
print(f"Amplitude misfit: {result['mavg']:.2f}")- Grid search for focal mechanism determination
- Monte Carlo uncertainty analysis
- S/P amplitude ratio constraint
- Quality rating (A-D, E, F)
- Multiple phase file formats
- Core algorithm matches Fortran exactly
See https://cnchash.readthedocs.io/ for full documentation including:
- API reference
- Algorithm details
- File format specifications
- Performance optimization
jupyter notebook HASH_Tests.ipynbcnchash/
├── core.py # Grid search algorithm (focalmc)
├── amp_subs.py # S/P amplitude ratio (focalamp_mc)
├── uncertainty.py # Uncertainty analysis (mech_prob)
├── driver.py # Main driver (run_hash, run_hash_with_amp)
├── io.py # File I/O
└── utils.py # Utilities
HASH_complete/ # Complete Fortran code with examples
He XingChen
BSD 3-Clause
Hardebeck, Jeanne L. and Peter M. Shearer, A new method for determining first-motion focal mechanisms, Bulletin of the Seismological Society of America, 92, 2264-2276, 2002.
Hardebeck, Jeanne L. and Peter M. Shearer, Using S/P Amplitude Ratios to Constrain the Focal Mechanisms of Small Earthquakes, Bulletin of the Seismological Society of America, 93, 2434-2444, 2003.

