Forward Configuration#
Forward modelling should be reproducible. A synthetic response, training dataset, or grid experiment is only useful when another user can reconstruct the solver, model prior, sampled axis, station layout, noise model, and random seed.
The forward package provides three configuration dataclasses:
pycsamt.forward.ForwardConfigfor 1-D MT, CSAMT, and TEM dataset generation;pycsamt.forward.ForwardConfig2Dfor 2-D MT finite-difference runs;pycsamt.forward.ForwardConfig3Dfor quasi-3-D MT forward runs.
All three classes follow the same workflow:
write an annotated template;
edit the template as the project source of truth;
load the template back into Python;
validate before computation;
build arrays, grids, solvers, or dataset keyword arguments from the config;
archive the config next to datasets, figures, and interpretation notes.
Configuration Classes#
Class |
Main purpose |
Main helpers |
|---|---|---|
|
1-D MT/CSAMT/TEM synthetic dataset generation. |
|
|
2-D MT finite-difference grid and solver setup. |
|
|
Quasi-3-D MT grid and solver setup. |
|
Template Files#
Forward configuration files can be written as Python, JSON, YML, or YAML. The file extension selects the format automatically. Templates include parameter comments, which makes them good review artifacts for scientific projects.
1from pycsamt.forward import ForwardConfig, ForwardConfig2D, ForwardConfig3D
2
3ForwardConfig.write_template("configs/forward_1d.yml")
4ForwardConfig2D.write_template("configs/forward_2d.yml")
5ForwardConfig3D.write_template("configs/forward_3d.yml")
Load the edited files with strict validation of keys:
1from pycsamt.forward import ForwardConfig
2
3cfg = ForwardConfig.from_file("configs/forward_1d.yml", strict=True)
4cfg.validate()
5print(cfg.summary())
strict=True is recommended for production runs because misspelled keys
raise an error instead of being ignored. Use strict=False only when
loading a file that intentionally contains extra metadata.
1-D Configuration#
ForwardConfig controls the 1-D solver, frequency or time grid, random
layered model prior, noise model, output path, and parallel worker count.
Setting group |
Fields |
|---|---|
Solver |
|
Earth model prior |
|
Dataset |
|
Output |
|
The solver controls which sampled axis is active:
|
Active axis |
Main settings |
|---|---|---|
|
Frequency |
|
|
Frequency |
|
|
Time gates |
|
Generate a 1-D MT training dataset:
1from pycsamt.forward import ForwardConfig, generate_dataset
2
3cfg = ForwardConfig(
4 solver="mt1d",
5 freq_min=1e-3,
6 freq_max=1e4,
7 n_freqs=40,
8 n_layers_min=3,
9 n_layers_max=7,
10 rho_min=1.0,
11 rho_max=10_000.0,
12 depth_max=3000.0,
13 n_samples=5000,
14 noise_level=0.05,
15 noise_type="field",
16 include_phase=True,
17 seed=42,
18 n_jobs=1,
19 output_dir="runs/forward",
20 output_name="mt1d_training",
21)
22
23cfg.validate()
24dataset = generate_dataset(**cfg.to_dataset_kwargs())
to_dataset_kwargs() builds the correct frequency or time array and
constructs the output path. This reduces the risk of the config and the
actual dataset generation call drifting apart.
Geological Priors#
ForwardConfig.geology can replace broad rho_min/rho_max and
depth_max sampling with a named geological prior. This is useful when an
AI dataset should represent a known target class instead of arbitrary
layered-earth variation.
Common prior names include:
1sedimentary
2crystalline
3geothermal
4marine
5permafrost
1from pycsamt.forward import ForwardConfig, generate_dataset
2
3cfg = ForwardConfig(
4 solver="mt1d",
5 geology="geothermal",
6 n_layers_min=4,
7 n_layers_max=7,
8 n_samples=20_000,
9 noise_type="field",
10 seed=12,
11 output_dir="runs/forward",
12 output_name="geothermal_mt1d",
13)
14
15cfg.validate()
16dataset = generate_dataset(**cfg.to_dataset_kwargs())
When geology is set, the geological prior should be documented in the
project notes. A neural network trained on a narrow prior may not generalize
outside that geological setting.
TEM Configuration#
TEM uses time gates rather than frequency samples.
1from pycsamt.forward import ForwardConfig, generate_dataset
2
3cfg = ForwardConfig(
4 solver="tem1d",
5 time_min=1e-6,
6 time_max=1e-2,
7 n_times=25,
8 loop_radius=50.0,
9 n_layers_min=3,
10 n_layers_max=6,
11 n_samples=1000,
12 noise_type="gaussian",
13 noise_level=0.03,
14 seed=5,
15 output_dir="runs/forward",
16 output_name="tem1d_training",
17)
18
19cfg.validate()
20dataset = generate_dataset(**cfg.to_dataset_kwargs())
TEM generation can be slower than MT1D because the current implementation
uses numerical integration for the step-off response. Start with a small
n_samples value, inspect the response, then scale up.
2-D Configuration#
ForwardConfig2D creates a pycsamt.forward.Grid2D and solver
keyword arguments for pycsamt.forward.MT2DForward.
Setting group |
Fields |
|---|---|
Solver |
|
Grid |
|
Earth model |
|
Stations |
|
Output |
|
The supported model_type values are:
|
Meaning |
|---|---|
|
Uniform background resistivity. |
|
Rectangular anomaly inside a background. |
|
Random 2-D grid model generated by |
Example 2-D anomaly run:
1from pycsamt.forward import ForwardConfig2D, MT2DForward
2
3cfg = ForwardConfig2D(
4 freq_min=1e-2,
5 freq_max=1e3,
6 n_freqs=25,
7 nx=50,
8 nz=35,
9 x_max=10_000.0,
10 z_max=6000.0,
11 n_pad=8,
12 pad_factor=1.3,
13 bg_rho=300.0,
14 model_type="anomaly",
15 anomaly_rho=10.0,
16 anomaly_x_lo=2500.0,
17 anomaly_x_hi=6500.0,
18 anomaly_z_lo=400.0,
19 anomaly_z_hi=1800.0,
20 n_stations=16,
21 verbose=True,
22)
23
24cfg.validate()
25print(cfg.summary())
26
27grid = cfg.to_grid()
28solver = MT2DForward(grid=grid, **cfg.to_solver_kwargs())
29response = solver.run()
to_grid() accepts a seed argument for random models:
1cfg = ForwardConfig2D(model_type="random")
2cfg.validate()
3grid = cfg.to_grid(seed=42)
2-D Grid Tuning#
2-D forward runs are sensitive to grid design.
Parameter |
Practical guidance |
|---|---|
|
Should include all stations and enough side room that boundaries do not dominate the response. |
|
Should extend below the expected maximum investigation depth. |
|
Increase when anomalies are small or response gradients are sharp. |
|
Add side and bottom padding to reduce boundary artifacts. |
|
Values around |
|
Should resolve the lateral scale of the target. |
3-D Configuration#
ForwardConfig3D builds a pycsamt.forward.Grid3D and keyword
arguments for pycsamt.forward.MT3DForward.
Setting group |
Fields |
|---|---|
Solver |
|
Grid |
|
Earth model |
|
Stations |
|
Output |
|
The supported model_type values are:
|
Meaning |
|---|---|
|
Uniform 3-D background. |
|
Rectangular 3-D anomaly inside a background. |
|
Random horizontal layers with optional Gaussian-random-field lateral variation. |
Example quasi-3-D block anomaly:
1from pycsamt.forward import ForwardConfig3D, MT3DForward
2
3cfg = ForwardConfig3D(
4 freq_min=1e-2,
5 freq_max=1e3,
6 n_freqs=15,
7 method="quasi3d",
8 nx=24,
9 ny=24,
10 nz=18,
11 x_max=9000.0,
12 y_max=9000.0,
13 z_max=5000.0,
14 n_pad=8,
15 bg_rho=500.0,
16 model_type="block_anomaly",
17 anomaly_rho=20.0,
18 anomaly_x_lo=2500.0,
19 anomaly_x_hi=6500.0,
20 anomaly_y_lo=2500.0,
21 anomaly_y_hi=6500.0,
22 anomaly_z_lo=500.0,
23 anomaly_z_hi=2000.0,
24 nx_stations=6,
25 ny_stations=6,
26 verbose=True,
27)
28
29cfg.validate()
30print(cfg.summary())
31
32grid = cfg.to_grid()
33response = MT3DForward(grid=grid, **cfg.to_solver_kwargs()).run()
Random layered 3-D model:
1cfg = ForwardConfig3D(
2 model_type="random_layered",
3 n_layers=5,
4 lateral_variation=True,
5 corr_length=2500.0,
6 nx_stations=7,
7 ny_stations=7,
8)
9
10cfg.validate()
11grid = cfg.to_grid(seed=42)
3-D Configuration Notes#
ForwardConfig3D.method currently validates to "quasi3d". The
underlying solver code contains experimental hooks for fuller 3-D methods,
but the documented configuration path is quasi-3-D. Treat quasi-3-D outputs
as survey-scale synthetic responses, not as final production 3-D inversion
results.
For production 3-D modelling or inversion, continue to:
Validation#
Call validate() before any expensive run. Validation catches basic range
errors such as negative frequencies, invalid model types, impossible anomaly
bounds, and invalid station counts.
1from pycsamt.forward import ForwardConfig2D
2
3cfg = ForwardConfig2D(freq_min=100.0, freq_max=10.0)
4
5try:
6 cfg.validate()
7except ValueError as exc:
8 print(f"Configuration problem: {exc}")
Validation does not prove that the model is geologically meaningful. It only checks that the parameters are internally acceptable for the builder and solver.
Summaries And Provenance#
Each config object provides summary() and repr output that can be
saved in logs or reports.
1from pathlib import Path
2
3cfg = ForwardConfig2D(model_type="anomaly")
4cfg.validate()
5
6run_dir = Path("runs/forward/2d_anomaly")
7run_dir.mkdir(parents=True, exist_ok=True)
8(run_dir / "summary.txt").write_text(cfg.summary())
9cfg.to_template(run_dir / "forward_config_2d.yml")
What To Record#
For reproducibility, record:
config file path and format;
solver type and dimensionality;
frequency grid or time-gate grid;
model prior or grid constructor;
resistivity bounds, anomaly bounds, or geology prior;
station layout;
noise type and noise level;
random seed;
output dataset or figure paths;
pyCSAMT version or commit;
any manual edits made after grid creation.
Recommended Run Layout#
1runs/
2 forward/
3 mt1d_training/
4 forward_config.yml
5 summary.txt
6 mt1d_training.npz
7 sample_responses.png
8 profile_2d_anomaly/
9 forward_config_2d.yml
10 summary.txt
11 model.png
12 pseudosection_te.png
13 survey_quasi3d/
14 forward_config_3d.yml
15 summary.txt
16 response_maps/
Common Mistakes#
The generated dataset cannot be reproduced.Record
seed, configuration file, pyCSAMT version, and output path. Avoid manually changing keyword arguments outside the config.The run validates but the response is not useful.Validation only checks parameter ranges. Review frequency range, grid extents, anomaly size, station spacing, and plots.
TEM generation is unexpectedly slow.Start with fewer samples or fewer time gates. TEM1D currently uses numerical integration for the step-off response.
The 2-D model has boundary artifacts.Increase
x_max,z_max,n_pad, or adjustpad_factor.The 3-D response is treated as a production inversion result.ForwardConfig3Ddocuments quasi-3-D synthetic modelling. Use ModEM or MARE2DEM for production external-engine workflows.
Next Steps#
Solvers And Grids explains how configs create models and solvers.
Synthetic Datasets And Noise explains dataset generation and train/validation splits.
Forward Plotting shows how to inspect configured runs.
From Forward Modelling To Inversion explains synthetic recovery workflows.