Output files and array layouts#
Directory structure#
path_output/
├── grn_s/ # Static library, models and metadata
├── grn_d/
│ ├── qseis/ # Layered dynamic library, or
│ ├── qssp/ # Spherical dynamic library
│ └── results_each/ # Dynamic per-point arrays and job/cache metadata
└── results/
├── static/ # Static tensors and projected CSV files
└── dynamic/ # Assembled dynamic CSV files
Configuration parsing creates library/result roots. Libraries contain their
own backend-specific files and green_lib_info.json; retain these together.
Filename patterns#
Let n be an observation plane ID and z a depth formatted to two decimals.
Quantity/mode |
Fault result |
Fixed-depth result |
|---|---|---|
Static tensor, all modes |
|
|
Static CFS, mode 0 |
|
|
Static CFS, mode 1 |
|
|
Static CFS, mode 2 |
|
|
Dynamic CFS, mode 0 |
|
|
Dynamic CFS, mode 1 |
|
|
Dynamic CFS, mode 2 |
|
|
Other keys are normal_vector, rupture_vector, normal_stress and
shear_stress; optimal-rake mode adds rake.
OOP outputs use numbered quantities such as normal_vector1 and
normal_vector2. Dynamic tensor CSVs use the key stress_ned and include
the mode marker, e.g. stress_ned_os_dynamic_plane1.csv.
Depth filenames have only two decimal places, so nearby depths can produce the same name. Different receiver modes retain separate projected filenames, but static tensor files are shared.
Shapes#
For N receivers and T time samples:
Data |
Shape |
|---|---|
Static tensor NPY |
|
Static scalar CSV |
|
Static vector CSV |
|
Dynamic per-point tensor NPY |
|
Dynamic per-point vector NPY |
|
Dynamic per-point scalar NPY |
|
Dynamic scalar CSV |
|
Dynamic vector CSV |
|
Dynamic tensor CSV |
|
All CSVs omit headers and index columns. Dynamic vector/tensor rows are
receiver-major: all components of receiver 0, then receiver 1, etc.
Tensor order is [NN, NE, ND, EE, ED, DD]. Vectors use NED.
Stress is in Pa, orientation angles in degrees, unit vectors dimensionless.
from pathlib import Path
import numpy as np
result = Path("my-output/results/dynamic")
raw = np.loadtxt(result / "stress_ned_dynamic_plane1.csv", delimiter=",", ndmin=2)
n_receivers = raw.shape[0] // 6
stress = raw.reshape(n_receivers, 6, raw.shape[1]).transpose(0, 2, 1)
# stress.shape == (n_receivers, time_samples, 6)
Geographic grid order#
Let n_lat = cal_grid_num(obs_lat_range, obs_delta_lat) and likewise for
longitude. The flattened index is i_lat * n_lon + i_lon.
Reshape a scalar snapshot to (n_lat, n_lon).
Preserve the INI, input CSVs and row order with your outputs; result CSVs
do not carry receiver coordinates or a time column.
Parallel depth preparation additionally saves obs_plane_<z>.npy
under grn_d/results_each/.
Per-point cache names#
Dynamic filenames begin with latitude, longitude and depth, each to four
decimals, separated by underscores. The tensor cache uses
*_stress_ned.npy and *_stress_ned.json.
See reuse rules before treating existing files as complete.