# QSSP2020: spectra followed by synthetic waveforms QSSP2020 calculates spherical-Earth responses with optional self-gravitation and vector, tensor, rotation and gravity observables. A fresh library requires a spectral calculation before time-domain synthesis. The [fresh comparison dated 2026-09-15](../guides/backend-comparison.md) includes five-backend displacement and a QSSP2020/QSEIS2025 six-component stress comparison, with 0.25 s sampling, a 2 Hz Nyquist limit, a 1.25 s effective source pulse and receivers 1 km deep. Its spectra, harmonic settings and rate integration were prepared separately. The displacement-only tutorial below retains 4 s sampling, a 64 s source and surface receivers; it does not produce those new waveforms or stress figures. ## Complete displacement calculation ```console python examples/qssp2020.py ``` The script first preprocesses spectral and six moment-source tasks, then calls the sequential builder with **`cal_spec=True`**. Time-domain synthesis consumes the resulting spectra. ```{literalinclude} ../../examples/qssp2020.py :language: python :caption: Complete QSSP2020 tutorial with the spectral stage enabled ``` ```{figure} ../_static/examples/qssp2020.png :alt: QSSP2020 east, north and up displacement at three distances. Displacement in metres. This example uses zero time reduction, so the horizontal axis is seconds since source origin. ``` The model spans the full Earth. A 10 km source and surface receiver are sampled at 300, 600 and 900 km. The spectral window is 4092 s, output window 1020 s and interval 4 s. Expect `disp.npz` of shape `(3, 3, 256)`, `disp.png`, `summary.json` and `library/` beneath `examples/output/qssp2020/`. ## Spectral and physical settings `max_frequency=0.125` Hz and `source_duration=64` s define a long-period example. Both spheroidal and toroidal modes are enabled. The configured self-gravitation range is zero, the turning-point filter is disabled and free-surface reflection is retained. `max_slowness=0.3` is in s/km and source radius is in km. The example uses `min_harmonic=2000` and `max_harmonic=8000` after a controlled harmonic-convergence check at these distances. The previous 0/800 settings produced substantial differences from SPGRN2020 and poor harmonic stability. The parameter names do not define a band that excludes degrees below `min_harmonic`. Harmonic summation starts at degree zero; `min_harmonic` controls the low-frequency baseline of the frequency-dependent upper cutoff, subject to the solver's decay criterion. `max_harmonic` caps the upper degree and also affects the spatial differential-transformation order during waveform synthesis. Increasing only the maximum can change waveforms even when the saved spectra are identical, and improvement need not be monotonic. The [archived 64 s comparison](../guides/backend-comparison-64s.md) documents these effects and the tested 2000/8000 choice. It is specific to this model, source depth, distance range and frequency band. Converge these settings together with the spectral time window and slowness range for your own calculation. `time_reduction` is the output-window start time relative to source origin, in seconds. A value of -20 means 20 s before origin, not 20 s before P. The separate `time_window` must fit the spectral calculation. Only set `cal_spec=False` when compatible `GreenSpec` files already exist. Changing model, spectral sampling, cutoffs or physics requires new spectra; a prior `.finished` marker does not establish compatibility. ## Select observables The eleven flags passed to the Fortran backend are: | Zero-based index | Physical output | Reader `output_type` | | --- | --- | --- | | 0 | Displacement | `disp` | | 1 | Velocity | `velo` | | 2 | Acceleration | `acce` | | 3 | Strain | `strain` | | 4 | Strain rate | `strain_rate` | | 5 | Stress | `stress` | | 6 | Stress rate | `stress_rate` | | 7 | Rotation | `rota` | | 8 | Rotation rate | `rota_rate` | | 9 | Gravitational acceleration vector | `gravitation` | | 10 | Gravimeter gravity change | `gravimeter` | The tutorial uses `[1] + [0] * 10`. QSSP stores selected observables directly; requesting a different one from the reader requires its files. The bulk conversion follows the same flag order as the Fortran input: displacement, velocity, acceleration, strain, strain rate, stress, stress rate, rotation, rotation rate, gravitation, gravimeter. Earlier versions swapped strain and rotation there, so conversion of those families failed. ## Files, units and limits Spectra live in `GreenSpec///`. Time-domain files live in `GreenFunc///` under six spherical tensor bases: `mrr`, `mtt`, `mpp`, `mrt`, `mrp` and `mtp`. The example retains native ASCII by setting `remove_pd=False` while creating reader binary files. The usual builder default removes those ASCII files after conversion. Displacement is in m after multiplying the unit-moment waveform by `10^15 N m`. Rotated vectors use E/N/up, tensors use EE/EN/EU/NN/NU/UU, and gravimeter output is a single downward-positive gravity change. See [normalization and axes](../conventions.md). The paper describes a broad atmosphere/ocean/solid-Earth formulation; a particular tutorial model and enabled options determine which of those capabilities are actually present. This run is not a validation of atmosphere, gravity observables, fluid-interface tensors, static limits or multi-node MPI.