First Survey#
This page walks through the first practical pyCSAMT workflow: load a field survey, inspect the station inventory, check parser errors, build a quality table, save a first quality-control figure, and run a small reproducible pipeline.
The examples use EDI files because EDI is the normal exchange format for MT/AMT/CSAMT transfer functions. If your first dataset is a Zonge AVG, J-format, TEM, or intermediate inversion file, start with Data Formats and then return here once you have a collection of EDI sites or a pyCSAMT site collection.
What This First Workflow Should Answer#
A first survey pass is not an inversion and it is not a final interpretation. It is the short diagnostic pass that tells you whether the dataset is ready for deeper processing.
By the end of this page you should know:
how many stations were loaded;
which stations have coordinates and tipper data;
whether any EDI files failed to parse;
whether the station/frequency coverage is usable;
where pyCSAMT writes first-pass outputs;
which documentation page to open next.
Recommended Project Layout#
Use a small project directory before you begin. Keeping raw input, generated tables, figures, and pipeline outputs separate avoids confusion later when you begin filtering, static-shift correction, or inversion preparation.
1my_survey/
2|-- data/
3| `-- edis/
4| |-- S001.edi
5| |-- S002.edi
6| `-- ...
7|-- results/
8| `-- first_survey/
9`-- notebooks/
The examples below assume the EDI directory is data/edis and the output
directory is results/first_survey. Replace these paths with your own
survey paths.
Configure The Session#
pyCSAMT has separate configuration layers for API views, plotting style, and pipeline output. For a first run, keep the configuration explicit at the top of the script or notebook.
1from pycsamt.api import configure_api_view, configure_pipe, use_style
2
3configure_api_view(backend="pycsamt")
4configure_pipe(
5 output_root="results/first_survey",
6 show_progress=True,
7 plot_dpi=200,
8 plot_fmt="png",
9)
10use_style("publication")
The configuration call is intentionally lightweight:
configure_api_view(backend="pycsamt")Keeps returned tables as pyCSAMT
APIFrameobjects. These objects still expose the underlying pandas dataframe through.df.configure_pipe(output_root=...)Sets the default root directory for pipeline outputs when a pipeline run does not receive an explicit
outdir.use_style("publication")Applies the package plotting defaults for readable saved figures.
For a deeper explanation of these layers, see Configuration.
Read The Survey#
The simplest survey reader is pycsamt.api.read_edis(). It accepts a
single file, a directory, or a sequence of files/directories and returns an
APISurvey object.
1from pycsamt.api import read_edis
2
3survey = read_edis(
4 "data/edis",
5 recursive=True,
6 strict=False,
7 on_dup="replace",
8 progress="auto",
9)
10
11print(survey)
The important options are:
recursive=TrueSearch subdirectories below
data/edis. This is useful when field exports are grouped by line, date, or crew.strict=FalseLoad every readable file and collect parser failures for review. Use
strict=Truewhen you want the read operation to fail immediately on the first malformed file.on_dup="replace"If duplicate station names are found, keep the last station encountered. Use
on_dup="keep"only when you know that the first occurrence is the one you want.progress="auto"Shows progress when the current environment supports it.
Inspect The Loaded Survey#
Start with the survey object itself. It exposes a compact public interface for common first-pass questions.
1print("Number of stations:", survey.n_sites)
2print("First stations:", survey.stations[:10])
3print("First paths:", survey.paths[:3])
4
5if survey.n_sites == 0:
6 raise RuntimeError("No EDI stations were loaded.")
survey.stations is the station-name inventory. survey.paths is the
source-file inventory. If the station count is lower than expected, check
for duplicate names, failed parses, or an input path that does not include
all exported EDI files.
Check Parser Errors#
When strict=False, pyCSAMT keeps readable stations and stores parser
errors for the files that could not be loaded. Always check these errors
before trusting a first survey summary.
1errors = survey.errors()
2
3if errors:
4 print(f"{len(errors)} file(s) could not be read.")
5 for path, exc in errors[:5]:
6 print(f"- {path}: {type(exc).__name__}: {exc}")
7else:
8 print("All discovered EDI files were read successfully.")
If only a few files fail, you can continue with QC while you repair or remove the bad files. If many files fail, stop and inspect the export format before running processing steps.
Build A Station Summary#
survey.summary() returns an APIFrame. It prints cleanly in terminals,
but it also behaves like a dataframe wrapper.
1summary = survey.summary()
2print(summary)
3
4station_table = summary.df
5print(station_table.head())
6print(station_table.columns)
For first-pass review, the most useful columns are usually:
stationStation name resolved from the EDI metadata or file identity.
n_freqNumber of frequency samples available for the station.
period_minandperiod_maxPeriod range represented by the station.
has_tipperWhether vertical-field transfer-function information is available.
latandlonGeographic coordinates when present in the EDI metadata.
You can request a smaller station table when preparing a report or debugging specific metadata.
1compact = survey.summary(
2 fields=("station", "n_freq", "period_min", "period_max", "lat", "lon")
3)
4print(compact.df)
Inspect One Station#
Before plotting the whole survey, inspect one station object. This confirms that station naming, frequency arrays, impedance tensors, and optional tipper metadata are reachable.
1station_name = survey.stations[0]
2site = survey.get_site(station_name)
3
4print("Station:", station_name)
5print(site)
6
7# Many EDI-like objects expose these attributes. Use getattr so the
8# first workflow remains tolerant of partial metadata.
9print("Path:", getattr(site, "path", None))
10print("Frequencies:", getattr(site, "freq", None))
11print("Has tipper:", getattr(site, "tipper", None) is not None)
If survey.get_site(name) returns None, the station name you supplied
does not match a loaded station, filename stem, or source path.
Use The Public Table Helper#
The survey object is convenient when you want to keep a loaded collection in memory. For a quick script, the public table helper can read a directory and return a station summary in one call.
1from pycsamt.api import sites_summary
2
3sites = sites_summary(
4 "data/edis",
5 recursive=True,
6 strict=False,
7 on_dup="replace",
8)
9
10print(sites)
11print(sites.df.head())
Use read_edis when the next step will reuse the same loaded survey. Use
sites_summary when you only need a station inventory table.
Build A First Quality Table#
The station inventory tells you what was loaded. The quality table starts to answer whether the transfer-function data are suitable for processing.
1from pycsamt.api import quality_dataframe
2
3quality = quality_dataframe(survey.to_collection())
4print(quality)
5print(quality.df.head())
Depending on the metadata available in the loaded EDI files, the quality table may include coverage, missing-value, uncertainty, and station-level diagnostic columns. Treat it as a screening table: it helps you identify stations that deserve closer plotting, not as a replacement for geophysical judgment.
Save A First QC Figure#
A confidence profile is a compact first figure because it reduces the station quality assessment to one value per station along the profile. It is a good way to spot stations that require cleaning, masking, or removal before inversion.
1from pathlib import Path
2
3import matplotlib.pyplot as plt
4
5from pycsamt.emtools.qc import plot_confidence_profile
6
7outdir = Path("results/first_survey")
8outdir.mkdir(parents=True, exist_ok=True)
9
10ax = plot_confidence_profile(
11 survey.to_collection(),
12 method="composite",
13 ci_hi=0.95,
14 ci_lo=0.50,
15 station_label_step=None,
16)
17fig = ax.get_figure()
18fig.savefig(outdir / "station_confidence_profile.png", dpi=200,
19 bbox_inches="tight")
20plt.close(fig)
Use method="presence" for a very simple completeness check. Use
method="composite" when you want a more informative first-pass score that
combines several transfer-function diagnostics.
For a station-frequency view, save a pseudo-section as well.
1from pycsamt.emtools.qc import plot_frequency_confidence_psection
2
3ax = plot_frequency_confidence_psection(
4 survey.to_collection(),
5 method="composite",
6)
7fig = ax.get_figure()
8fig.savefig(outdir / "frequency_confidence_psection.png", dpi=200,
9 bbox_inches="tight")
10plt.close(fig)
The station profile shows where weak stations are located along the line. The frequency pseudo-section shows whether the weak data are isolated at particular periods or distributed through an entire station.
Run A First Pipeline#
Once the survey can be read and inspected, run the built-in basic_qc
preset. This is the recommended first pipeline because it is small enough
for fast feedback and structured enough to produce reproducible outputs.
1from pycsamt.pipeline import Pipeline
2
3pipe = Pipeline.from_preset("basic_qc")
4print(pipe)
5
6result = pipe.run(
7 survey.to_collection(),
8 outdir="results/first_survey/basic_qc",
9 save_plots=True,
10 save_edis=True,
11 save_report=True,
12)
13
14print(result.summary())
15print("Pipeline ok:", result.ok)
16print("Step errors:", result.n_errors)
17print("Output directory:", result.outdir)
The pipeline writes a reproducible run directory. The exact files depend on the enabled output settings and the steps in the preset, but the first things to inspect are:
pipeline.yamlThe pipeline configuration that produced the run.
reports/Text or HTML summaries of the run, including step status.
plots/QC plots produced by the pipeline steps.
processed/Processed EDI files when
save_edis=True.
If result.ok is False, inspect the reported step errors before using
the processed files. With the default warning policy, a failed step may leave
the previous station collection in place so that the rest of the run can
continue.
Command-Line Equivalent#
The same first pass can be started from the command line. These commands are useful for quick validation, automation, and sharing a workflow with another developer.
1pycsamt edi info data/edis
2pycsamt edi stations data/edis --format text
3pycsamt edi validate data/edis
4
5pycsamt pipe run data/edis \
6 --preset basic_qc \
7 --out results/first_survey/basic_qc \
8 --on-error warn \
9 --dpi 200 \
10 --plot-fmt png
Use pycsamt pipe run ... --dry-run before a long run to confirm that the
survey path, preset, step count, and output directory resolve as expected.
1pycsamt pipe run data/edis \
2 --preset basic_qc \
3 --out results/first_survey/basic_qc \
4 --dry-run
First-Survey Checklist#
Before moving to filtering, static-shift correction, dimensionality analysis, or inversion preparation, confirm the following:
survey.n_sitesmatches the expected number of field stations.survey.errors()is empty or every failed file is understood.Station names are unique and ordered as expected.
Coordinates are present when profile distance or maps matter.
Frequency/period ranges are comparable across neighbouring stations.
Missing tipper data are expected, or downstream steps do not require tipper.
The confidence profile does not show unexplained clusters of weak stations.
The pipeline report has no unexpected failed steps.
The output directory contains the run configuration and generated reports.
Troubleshooting#
- No stations are loaded
Check that the input path exists and contains files with an EDI extension. If the files are nested by survey line or date, keep
recursive=True.- The station count is too low
Look for duplicate station names and parser errors. Re-run with
on_dup="keep"if the first duplicate should win, or fix station names in the source files before processing.- Many files appear in
survey.errors() Confirm the files are EDI files rather than SEG blocks, Zonge AVG files, or another export format. See Data Formats for format-specific entry points.
- Coordinates are missing
The EDI metadata may not include latitude and longitude. You can still inspect frequencies and transfer functions, but maps and distance-based plots require station-location metadata.
- The plot is empty
Confirm that the survey contains stations and that the station objects expose frequency and impedance arrays. If the dataset is partial, try a simpler table first with
survey.summary().df.- The pipeline writes somewhere unexpected
Pass
outdir=...toPipeline.runor--out ...to the CLI. The pipeline otherwise falls back to its own configured output directory and then to the global pipeline configuration.
Where To Go Next#
After a successful first survey pass, continue with the page that matches your task:
Data Formats for converting or understanding non-EDI inputs.
Read an EDI Survey for a deeper EDI-reading tutorial.
Inspect and QC a Survey for richer station diagnostics.
../pipeline/presets for choosing a processing preset.
../pipeline/outputs for understanding generated pipeline files.
Prepare an Occam2D Inversion when the data are ready for Occam2D preparation.
../agents/overview if you want the AI-assisted agents to help review a survey, plan processing, or summarize results.
In Short#
A good first pyCSAMT survey pass is deliberately simple:
1from pycsamt.api import read_edis, quality_dataframe
2from pycsamt.pipeline import Pipeline
3
4survey = read_edis("data/edis", strict=False)
5print(survey)
6print(survey.summary().df.head())
7print(quality_dataframe(survey.to_collection()).df.head())
8
9pipe = Pipeline.from_preset("basic_qc")
10result = pipe.run(survey.to_collection(), outdir="results/first_survey")
11print(result.summary())
If this short script reads the survey, prints sensible station tables, and
produces a successful basic_qc run, the project is ready for deeper
processing.