2.11. pycsamt.jones#
Jones/J-file parsing, validation, collection objects, headers, blocks, and conversion helpers.
Jones-format transfer functions, blocks, headers, spectra, and utilities.
- class pycsamt.jones.Banner(top_lines=None, *, software=None, station=None, date=None, note=None, verbose=0)#
Bases:
JComponentBaseParse and serialize the top provenance comment line.
This helper targets lines such as:
# WRITTEN BY GEOTOOLS: kb0-s001 10/06/95 RAW RECSIt extracts the producer software name, an optional station hint, a free-form date token, and an optional trailing note. The writer defaults the software field to
PYSCAMTwhen none is provided.- Parameters:
top_lines (sequence of str, optional) – An initial slice of file lines. The constructor scans these lines and parses the first matching banner.
software (str, optional) – Producer software name (e.g.,
'GEOTOOLS'). When omitted and the banner is not present, the writer uses'PYSCAMT'as a default.station (str, optional) – Station identifier hint found in the banner. This does not replace the station found in the
Head.date (str, optional) – Free-form date token as found in the banner line.
note (str, optional) – Extra text following the date token on the same line.
verbose (int, default=0) – Verbosity for warnings during parsing.
- Variables:
software (str or None) – Producer software parsed from the banner or provided by the user.
station_hint (str or None) – Station token parsed from the banner; may differ from the station found in the
Head.date (str or None) – Banner date token as text; not parsed into a datetime.
note (str or None) – Trailing free-form text after the date token.
path (pathlib.Path or None) – Source path when constructed via
from_file().encoding (str) – Text encoding used by
from_file().verbose (int) – Verbosity level inherited from
JComponentBase.
- read(top_lines)#
Parse the first matching banner from the given lines and mark the instance as read.
- write()#
Render a banner line. Defaults the software field to
PYSCAMTif missing.
Notes
The banner parser is intentionally liberal: it ignores leading whitespace, is case-insensitive on the
WRITTEN BYmarker, and preserves the raw text of the trailing note. It does not validate dates or enforce a specific date format.Examples
>>> b = Banner().read( ... [ ... "#WRITTEN BY GEOTOOLS: kb0-s001 10/06/95 RAW RECS" ... ] ... ) >>> b.software, b.station_hint, b.date ('GEOTOOLS', 'kb0-s001', '10/06/95') >>> Banner().write()[0].startswith("#WRITTEN BY PYSCAMT:") True
See also
References
[Banner-1]A. G. Jones (1994). Magnetotelluric data file J-format, version 2.0.
[Banner-2]MTNet. “J format documentation”.
- classmethod from_file(j_fn, *, verbose=0)#
- classmethod from_lines(lines, *, verbose=0)#
- write(*, new=True, include_origin=False)#
- class pycsamt.jones.Head(j_header_list=None, *, verbose=0, **kwargs)#
Bases:
JComponentBaseParse and serialize a single J-format head triple.
This lightweight component represents one data-block header consisting of the station line, the data-type line, and the row count. It provides a consistent constructor and the
read/writeround-trip expected by the package.- Parameters:
j_header_list (sequence of str, optional) – Three logical header lines. The sequence may be a clean triple
[station, dtype, n]or a longer slice from a file; the parser will extract the first valid triple.verbose (int, default=0) – Verbosity for warnings during parsing.
**kwargs – Accepted for API forwards-compatibility; ignored here.
- Variables:
station (str or None) – Upper-cased station identifier. Trailing azimuth tokens on the same line are supported and ignored here (but see
az_hint).dtype (DataType or None) – Parsed data-type token (e.g.,
ZXY,RTE) with optional normalized units and a TE/TM tensor hint.n (int or None) – Number of data rows that follow this header.
az_hint (float or None) – Optional azimuth extracted from the station line when present (e.g.,
KB0001 -30). This is not the same as siteAZIMUTHfrom the info block.path (pathlib.Path or None) – Source path when constructed via
from_file().encoding (str) – Text encoding used by
from_file().verbose (int) – Verbosity level inherited from
JComponentBase.
- from_file(j_fn, \*, verbose=0)#
Read a file and return a
Head. Only the first valid triple is parsed.
- from_lines(j_header_list, \*, verbose=0)#
Build a
Headfrom an in-memory sequence. If the sequence is longer than three lines, the first valid triple is extracted.
- read(j_header_list)#
Parse the header triple into attributes and mark the instance as read (see
__has_read__).
- write(head_list_infos=None)#
Return a list of three strings representing the header triple. If
head_list_infosis given, it is parsed first and then serialized.
Notes
The station regex accepts common field variants, including hyphens and underscores, and an optional numeric azimuth token after the station id. The data-type parser is liberal with whitespace and recognizes
SI(S.I.) andFIELDunits.Examples
>>> Head().read(["KB0001 -30", "ZXY SI", "29"]) Head(station='KB0001', n=29) >>> h = Head.from_file("data/j/kb0-s001.txt") >>> h.station 'KB0001'
See also
InfoSite information (
>KEY=VALUElines).HeadsJSitePropertyRobust latitude/longitude parsing.
DataTypeStructured token for kind / comp / units.
References
[Head-1]A. G. Jones (1994). Magnetotelluric data file J-format, version 2.0.
[Head-2]MTNet. “J format documentation”.
- classmethod from_file(j_fn, *, verbose=0)#
- classmethod from_lines(j_header_list=None, *, verbose=0)#
- write(head_list_infos=None)#
- class pycsamt.jones.Heads(head=None, info=None, *, verbose=0)#
Bases:
JComponentBaseMinimal container for one
Headand oneInfo.The class provides convenient accessors for station and site-level properties, and a small banner recorder for the top provenance line (
#WRITTEN BY ...). It is intended as the lightest useful representation of a single J header section.- Parameters:
- Variables:
head (Head) – The parsed header triple.
info (Info) – The parsed site information block.
banner (Banner) – Parsed top comment provenance. The writer defaults the
softwarefield toPYSCAMTif missing.n (int) –
0or1depending on whether a head has been parsed.station (str or None) – Shortcut to
head.station.azimuth (latitude, longitude, elevation,) – Shortcuts to values provided by
info.azimuthfalls back tohead.az_hintwhen the info block does not containAZIMUTH.
- from_lines(lines, \*, verbose=0)#
Build from an in-memory line sequence.
- read(text_or_lines)#
Extract info + head lists and parse both.
Notes
This class does not parse the subsequent data rows. It is focused on fast, dependency-free header discovery to support scanning tasks and metadata extraction.
Examples
>>> h = Heads.from_file("data/j/kb0-s001.txt") >>> h.station, h.latitude, h.software ('KB0001', 41.9782, 'GEOTOOLS')
References
[Heads-1]A. G. Jones (1994). Magnetotelluric data file J-format, version 2.0.
- classmethod from_lines(lines, *, verbose=0)#
- classmethod from_file(j_fn, *, verbose=0)#
- class pycsamt.jones.HeadMixin#
Bases:
objectMixin that provides a
Headon host classes.The mixin offers class-level and instance-level helpers that delegate to
Headwhile keeping a single copy of the header on the host.- Variables:
head (Head) – Lazily created and cached on first use.
- from_file(edi_fn)#
Class method that returns
Head.from_file(edi_fn).
- read(j_header_list=None)#
Ensure a
Headexists on the host, parse into it, and return it.
- write(head_list_infos=None)#
Serialize the host’s
Headto three header lines.
Examples
>>> class Host(HeadMixin): ... pass >>> Host.from_file("file.j") Head(...)
- class pycsamt.jones.Info(j_info_list=None, *, verbose=0, **kwargs)#
Bases:
JComponentBaseParse and serialize the J-format information block.
This component collects
>KEY=VALUErecords along with leading comment lines. It exposes a small set of convenience properties derived fromJSiteProperty.- Parameters:
j_info_list (sequence of str, optional) – A sequence containing the comment and information records. The parser stops at the first non-info, non-comment, non-blank line.
verbose (int, default=0) – Verbosity for warnings during parsing.
**kwargs – Accepted for API forwards-compatibility; ignored here.
- Variables:
items (dict of (str -> str)) – Mapping of upper-cased keys to unmodified string values.
comments (list of str) – Preserved leading comment lines (starting with
#).site (JSiteProperty) – Lazily parsed view providing normalized latitude, longitude, azimuth and elevation (see properties below).
latitude (float or None) – Decimal degrees; hemisphere and DMS tolerated.
longitude (float or None) – Decimal degrees in
[-180, 180).azimuth (float or None) – Site X-axis azimuth (degrees, true north).
elevation (float or None) – Elevation in metres.
path (pathlib.Path or None) – Source path when constructed via
from_file().encoding (str) – Text encoding used by
from_file().verbose (int) – Verbosity level inherited from
JComponentBase.
- from_file(j_fn, \*, verbose=0)#
Read only the comment/info header from a file.
- from_lines(j_info_list, \*, verbose=0)#
Build from an in-memory sequence.
- read(j_info_list)#
Parse the header and mark the instance as read.
- write(j_info_list=None)#
Render comments and
>KEY = VALUElines.
Notes
Unknown keys are preserved verbatim. Coordinate and azimuth values are normalized via
JSiteProperty, which handles ranges, hemispheres and DMS.Examples
>>> info = Info.from_file("data/j/kb0-s001.txt") >>> info.latitude, info.longitude (41.9782, 140.8958) >>> lines = info.write() >>> Info.from_lines(lines).azimuth == info.azimuth True
See also
HeadOne data-block header (station / dtype / count).
HeadsCombined view with convenience properties.
JSitePropertyRobust parsing used by this class.
References
[Info-1]A. G. Jones (1994). Magnetotelluric data file J-format, version 2.0.
- classmethod from_file(j_fn, *, verbose=0)#
- classmethod from_lines(j_info_list=None, *, verbose=0)#
- property site: JSiteProperty#
- class pycsamt.jones.InfoMixin#
Bases:
objectMixin that provides an
Infoon host classes.The mixin mirrors
HeadMixinbut for the information block. It centralizes parsing and writing of>KEY=VALUElines.- Variables:
info (Info) – Lazily created and cached on first use.
- from_file(edi_fn)#
Class method that returns
Info.from_file(edi_fn).
- read(j_info_list=None)#
Ensure an
Infoexists on the host, parse into it, and return it.
- write(j_info_list=None)#
Serialize the host’s
Infoto comment and info lines.
Examples
>>> class Host(InfoMixin): ... pass >>> Host().read([">LATITUDE=10"]) Info(items=1)
- class pycsamt.jones.JSiteProperty(azimuth=None, latitude=None, longitude=None, elevation=None, extra=<factory>, verbose=0, strict=False)#
Bases:
objectContainer for site properties parsed from J-format info.
This class stores site-level metadata such as latitude, longitude, azimuth, and elevation that are declared in the J-format information block as
>KEY=VALUElines.- Parameters:
azimuth (float or None, optional) – Site X-axis azimuth in degrees, referenced to true north. Values are wrapped to
[0, 360)when parsed.latitude (float or None, optional) – Latitude in decimal degrees. Inputs may include DMS or hemisphere suffixes and are normalized to
[-90, 90].longitude (float or None, optional) – Longitude in decimal degrees. Inputs may include DMS or hemisphere suffixes and are normalized to
[-180, 180).elevation (float or None, optional) – Elevation in metres. Missing sentinels are mapped to
None.extra (dict of (str -> str), optional) – Unrecognized
>KEY=VALUEpairs preserved verbatim.verbose (int or bool, default 0) – Verbosity for non-fatal parsing warnings.
strict (bool, default False) – If
True, out-of-range coordinates raise errors instead of being coerced to valid bounds.
- Variables:
Notes
Parsing leverages robust coordinate helpers that accept DMS, hemisphere letters, and free whitespace. Longitudes are normalized into the half-open interval
[-180, 180).Examples
>>> lines = [\">LATITUDE = 41.9782\", \">LONGITUDE = 140.8958\"]\n >>> prop = JSiteProperty.from_lines(lines)\n >>> prop.location\n (41.9782, 140.8958)
See also
InfoHigh-level container of the information block which can be used to build a
JSiteProperty.
References
[JSiteProperty-1]A. G. Jones (1994). Magnetotelluric data file J-format, version 2.0.
- classmethod from_file(obj, *, encoding='utf-8', strict=False, verbose=0)#
Build a
JSitePropertyfrom a J file path or file-like object.Only the initial information block is consumed. Later station or data sections are ignored by this method.
- Parameters:
obj (str or pathlib.Path or TextIO) – Path to a J file or an open text stream positioned at the beginning of the file.
encoding (str, default 'utf-8') – Text encoding used when reading from a file path.
strict (bool, default False) – If
True, invalid coordinates raise. IfFalse, out-of-range values are coerced with a warning.verbose (int or bool, default 0) – Verbosity for non-fatal parsing warnings.
- Returns:
Parsed site properties.
- Return type:
Notes
This method stops at the first line that is not a comment, not blank, and not a
>KEY=VALUErecord.Examples
>>> prop = JSiteProperty.from_file(\"data/j/kb0-s001.txt\")\n >>> prop.azimuth is None or 0.0 <= prop.azimuth < 360.0\n True
See also
from_linesParse from an in-memory sequence of lines.
from_mappingQuick constructor from a dict of keys and values.
References
[JSiteProperty-from-file-1]A. G. Jones (1994). Magnetotelluric data file J-format, version 2.0.
- classmethod from_lines(lines, *, strict=False, verbose=0)#
Build a
JSitePropertyfrom an iterable of lines.The parser reads sequentially and collects
>KEY=VALUEpairs as long as lines are comments, blanks, or info records. It stops at the first non-conforming line.- Parameters:
- Returns:
Parsed site properties.
- Return type:
Notes
Latitude and longitude accept flexible text including DMS and hemisphere tokens. Longitudes are normalized into
[-180, 180).Examples
>>> from pycsamt. >>> lines = [\n ... \">AZIMUTH = -30.0\", \">LATITUDE = 41.9782\",\n ... \">LONGITUDE = 140.8958\", \">ELEVATION = 0.0\",\n ... ]\n >>> prop = JSiteProperty.from_lines(lines)\n >>> prop.location[0] == 41.9782\n True
See also
from_fileParse from a file path or open stream.
from_mappingQuick constructor from a dict of keys and values.
References
[JSiteProperty-from-lines-1]A. G. Jones (1994). Magnetotelluric data file J-format, version 2.0.
- classmethod from_mapping(mapping, *, strict=False, verbose=0)#
Build a
JSitePropertyfrom a dict of key-value pairs.Keys can be any case and will be normalized to the upper case tokens used by J files. Values can be strings or numbers. Unknown keys are preserved in
extra.- Parameters:
- Returns:
Parsed site properties.
- Return type:
Notes
This is a convenience front-end that converts the mapping to synthetic
>KEY=VALUElines and forwards the work tofrom_lines().Examples
>>> prop = JSiteProperty.from_mapping({\n ... 'azimuth': 370, 'latitude': '41:58N',\n ... 'longitude': '140:54E', 'elevation': 0,\n ... })\n >>> 0.0 <= (prop.azimuth or 0.0) < 360.0\n True
See also
from_linesParse from an in-memory sequence of lines.
from_fileParse from a file path or open stream.
References
[JSiteProperty-from-mapping-1]A. G. Jones (1994). Magnetotelluric data file J-format, version 2.0.
- class pycsamt.jones.RRow(period, rho, pha, rhomax, rhomin, phamax, phamin, wrho, wpha, rej=False)#
Bases:
objectOne parsed resistivity/phase row of a J R/S block.
The row stores period (s), apparent resistivity (Ω·m), phase (deg), their 1σ bounds, and per-column weights. A derived boolean flag
rejmarks a row as rejected according to the J-format rules.- Parameters:
period (float) – Period in seconds. If input stored frequency (Hz) as a negative number, it is normalized to a positive period.
rho (float) – Apparent resistivity. Values
< 0mark the estimate as rejected.pha (float) – Phase in degrees.
rhomax (float) – Upper and lower 1σ bounds of resistivity. May be missing.
rhomin (float) – Upper and lower 1σ bounds of resistivity. May be missing.
phamax (float) – Upper and lower 1σ bounds of phase. May be missing.
phamin (float) – Upper and lower 1σ bounds of phase. May be missing.
wrho (float) – Weights. A negative weight marks the estimate as rejected.
wpha (float) – Weights. A negative weight marks the estimate as rejected.
rej (bool) – Convenience rejection flag derived from the rules above.
Notes
Missing numeric values are often written as
-999.0in J files. The higher-level APIs convert them toNaNfor numeric workflows.Examples
>>> row = RRow( ... period=1.0, rho=100.0, pha=45.0, ... rhomax=110.0, rhomin=90.0, ... phamax=50.0, phamin=40.0, ... wrho=1.0, wpha=1.0, rej=False, ... ) >>> row.rho, row.rej (100.0, False)
References
[RRow-1]A. G. Jones (1994). Magnetotelluric data file J-format, version 2.0.
- class pycsamt.jones.TFRow(period, real, imag, error, weight, rej=False)#
Bases:
objectOne parsed transfer-function row of a J Z/Q/C/T block.
The row stores period (s), real/imag parts, a standard error, a row weight, and a derived
rejflag based on J-format rules.- Parameters:
period (float) – Period in seconds. If input stored frequency (Hz) as a negative number, it is normalized to a positive period.
real (float) – Real and imaginary parts of the transfer function.
imag (float) – Real and imaginary parts of the transfer function.
error (float) – Standard error (format-specific). May be missing.
weight (float) – Row weight. Negative values mark the row as rejected.
rej (bool) – Convenience rejection flag derived from the rules above.
Notes
The J specification allows several TF families (Z/Q/C/T). The row schema stays the same; only the physical meaning differs.
Examples
>>> tf = TFRow( ... period=0.1, real=1.0, imag=-2.0, ... error=0.1, weight=1.0, rej=False, ... ) >>> tf.period, tf.rej (0.1, False)
References
[TFRow-1]A. G. Jones (1994). Magnetotelluric data file J-format, version 2.0.
- class pycsamt.jones.JBlock(head=None, *, rows=None, verbose=0)#
Bases:
JComponentBaseAbstract base for J-format data blocks.
A block ties a parsed header (
Head) to a homogeneous sequence of rows (RRoworTFRow). Subclasses implement the row parser, normalization, serialization, and simple QA summaries.- Parameters:
- Variables:
head (Head) – Block header with
station,kind,comp,n.nrows (int) – Number of parsed data rows.
units (station, kind, comp,) – Convenience views onto
head.dtype.columns (tuple of str) – Column names for the structured numeric view.
shape ((int, int)) –
(nrows, ncols)derived from the current rows.
- from_file(j_fn, \*, verbose=0)#
Build a block from a file slice. The concrete subclass is chosen from the header’s
kind.
- from_lines(lines, \*, verbose=0)#
Parse from in-memory lines (header + body).
- read((head, body_lines))#
Populate the block from an existing
Headand the subsequent body lines. Marks the instance as read.
- to_numpy()#
Structured array view with numeric normalization (period sign, missing sentinels, rejection flags).
- to_dataframe()#
Optional
pandasrepresentation (if available).
Notes
The base class is intentionally minimal to keep the parser light. Subclasses define the row regex, column names, and row-level normalization logic.
Examples
>>> # Pseudocode; subclass chosen from header >>> blk = JBlock.from_lines(["S01", "RXY", "1", "..."]) >>> blk.station, blk.nrows ('S01', 1)
References
[JBlock-1]A. G. Jones (1994). Magnetotelluric data file J-format, version 2.0.
- classmethod from_file(j_fn, *, verbose=0)#
- classmethod from_lines(lines, *, verbose=0)#
- normalize()#
Apply row-level normalization:
negative period => frequency (Hz) to period (s)
missing sentinel (-999) => NaN
set rejection flags per rules
- Return type:
- to_dataframe()#
- property periods#
- class pycsamt.jones.RBlock(head=None, *, rows=None, verbose=0)#
Bases:
JBlockResistivity/phase (R/S) block implementation.
Parses rows of the form
period rho pha rhomax rhomin phamax phamin wrho wpha. Applies J-format rules to normalize period sign and to mark rejected estimates.- Parameters:
- Variables:
columns (tuple of str) –
('period', 'rho', 'pha', 'rhomax', 'rhomin', 'phamax', 'phamin', 'wrho', 'wpha', 'rej').
Notes
Normalization rules:
If input period is negative, the value stores frequency in Hz and is converted to period (s).
rho < 0orwrho < 0marks the row as rejected.-999.0sentinels are converted toNaNin numeric views.
Examples
>>> lines = [ ... "S01", ... "RXY", ... "2", ... "-1.0 100 45 110 90 50 40 1 1", ... " 2.0 -5 30 35 25 40 20 1 1", ... ] >>> blk = RBlock.from_lines(lines) >>> a = blk.to_numpy() >>> a["period"][0] # 1/Hz -> s 1.0 >>> a["rej"][1] # rho < 0 True
References
[RBlock-1]A. G. Jones (1994). Magnetotelluric data file J-format, version 2.0.
- normalize()#
Apply row-level normalization:
negative period => frequency (Hz) to period (s)
missing sentinel (-999) => NaN
set rejection flags per rules
- Return type:
- class pycsamt.jones.TFBlock(head=None, *, rows=None, verbose=0)#
Bases:
JBlockTransfer-function (Z/Q/C/T) block implementation.
Parses rows of the form
period real imag error weight. Applies J-format rules to normalize period sign and to mark rejected estimates.- Parameters:
- Variables:
columns (tuple of str) –
('period', 'real', 'imag', 'error', 'weight', 'rej').
Notes
Normalization rules:
If input period is negative, the value stores frequency in Hz and is converted to period (s).
weight < 0marks the row as rejected.-999.0sentinels are converted toNaNin numeric views.
Examples
>>> lines = [ ... "S02", ... "ZXY SI", ... "2", ... "-1.0e+1 1.0 -2.0 0.1 1.0", ... " 5.0 -999 3.0 -999 -1.0", ... ] >>> blk = TFBlock.from_lines(lines) >>> a = blk.to_numpy() >>> round(a["period"][0], 3) 0.1 >>> a["rej"][1] # weight < 0 True
References
[TFBlock-1]A. G. Jones (1994). Magnetotelluric data file J-format, version 2.0.
- normalize()#
Apply row-level normalization:
negative period => frequency (Hz) to period (s)
missing sentinel (-999) => NaN
set rejection flags per rules
- Return type:
- class pycsamt.jones.JBlocks(blocks=None, *, verbose=0)#
Bases:
JComponentBaseContainer for a sequence of parsed J data blocks.
Provides discovery from raw text, iteration, selection by family or component, serialization, and quick QA roll-ups across blocks.
- Parameters:
- Variables:
- from_file(j_fn, \*, verbose=0)#
Parse all blocks found in a file.
- from_lines(lines, \*, verbose=0)#
Parse blocks from an in-memory sequence of lines.
- read(lines)#
Replace current content with blocks parsed from lines.
- select(kind=None, comp=None)#
Return blocks filtered by family and/or component.
- period_range()#
Global period min/max across blocks (ignores
NaN).
Notes
Header discovery is tolerant to real-world quirks, including optional azimuth on the station line and the count-before-dtype pattern seen in some files.
Examples
>>> col = JBlocks.from_file("data/j/kb0-s001.txt") >>> col.n >= 1 True >>> [b.station for b in col.select(kind="R")] ['KB0001', ...]
References
[JBlocks-1]A. G. Jones (1994). Magnetotelluric data file J-format, version 2.0.
- classmethod from_file(j_fn, *, verbose=0)#
- classmethod from_lines(lines, *, verbose=0)#
- to_dataframe()#
- property station: str | None#
Return the single, unique station name for the block collection. Returns None if no blocks are present.
- select(*, kind=None, comp=None)#
- class pycsamt.jones.JMixin#
Bases:
objectLightweight helpers shared by J-format readers.
The mixin groups small, allocation-friendly utilities that many parsers need. It keeps math, alignment and token-handling logic out of higher-level classes.
Notes
The helpers are intentionally tiny and avoid importing heavy libraries beyond
numpy. They favor pure functions that accept and return arrays.- _complex(re, im)#
Combine real and imaginary parts into a complex vector. Shapes must be broadcast-compatible.
- _deg2rad(x)#
Degrees to radians conversion with float return.
- _hz_from_period(p)#
Convert period seconds to frequency in Hz. Non- positive entries are mapped to
nan.
- _align_by_periods(p0, p1)#
Return a tuple
(p_common, i0, i1)wherep_commonare periods present in both sequences, ordered likep0;i0andi1are indices to select the matching rows in the original arrays.
Examples
>>> jm = JMixin() >>> jm._complex([1, -2], [0.5, 3]).dtype.kind == "c" True >>> jm._deg2rad(180.0) 3.141592653589793 >>> jm._hz_from_period([1.0, 0.5]) array([1., 2.]) >>> pc, i0, i1 = jm._align_by_periods([1, 2, 3], [3, 1]) >>> pc.tolist(), i0.tolist(), i1.tolist() ([1, 3], [0, 2], [1, 0])
See also
References
[JMixin-1]A. G. Jones, Magnetotelluric data file J-format, version 2.0, 1994.
[JMixin-2]MTNet, J format documentation.
- class pycsamt.jones.JIOMixin#
Bases:
JMixinTolerant BLOCK parser and TF/R/Tipper builder.
This mixin concentrates the I/O-oriented parts for J files: scanning blocks, aligning periods, normalizing rows, and assembling higher-level objects (
Z,Tipper, andResPhase).It aims to be robust against non-canonical header orders and minor format quirks.
Notes
Data rows are normalized before assembly. Period sign conventions (negative means Hz) are corrected.
Missing sentinels (e.g.,
-999) are mapped tonanfor numeric arrays, but objects are pre- allocated with zeros to keep shapes consistent.When only rho/phi are present, impedance is rebuilt using \(|Z|=\sqrt{\mu_0 \,\omega\, \rho}\) and \(\phi\) for the phase. The vacuum permeability \(\mu_0\) is imported from
pycsamt.constants.
- _scan_blocks(path, \*, start=None, empty_val=...)#
Parse the file into a component dictionary indexed by tokens like
'ZXY','RXX'or'TZX'. Values include period, real/imag/error (TF) or rho/ phi (+ auxiliary columns for R blocks).
- _build_from_comp(comp, \*, z_obj=None, tip_obj=None)#
Assemble
Z,Tipper, andResPhasefrom the scanned components. Returns a triple(Z|None, Tipper|None, ResPhase|None).
Examples
>>> mix = JIOMixin() >>> # (typically used via JFile; direct use shown here) >>> # comp = mix._scan_blocks(Path("data/j/site.j")) >>> # z, tip, rp = mix._build_from_comp(comp)
See also
JMixinMathematical utilities used by this mixin.
JFileHigh-level reader/writer that calls these methods.
pycsamt.z.z.ZImpedance tensor container.
pycsamt.z.tipper.TipperTipper container.
pycsamt.z.resphase.ResPhaseR–φ container.
References
[JIOMixin-1]A. G. Jones, Magnetotelluric data file J-format, version 2.0, 1994.
[JIOMixin-2]MTNet, J format documentation.
- class pycsamt.jones.JFile(path=None, *, verbose=0)#
Bases:
JIOMixinHigh-level J dispatcher for MT/SEG archives.
The class reads a J file, extracts headers and blocks, and builds analysis-ready objects for impedance (
Z), resistivity/phase (Res), and tipper (Tip). It also writes new J files from the in-memory state.- Parameters:
- Variables:
path (Path or None) – Source path when set via
__init__orfrom_file().heads (pycsamt.jones.heads.Heads or None) – Parsed banner, info and a single head triple.
blocks (pycsamt.jones.blocks.JBlocks or None) – Parsed data blocks (R and/or TF).
Z (pycsamt.z.z.Z or None) – Impedance tensor container, possibly rebuilt from rho/phi when TF are absent.
Tip (pycsamt.z.tipper.Tipper or None) – Tipper container if ZX/ZY are present.
Res (pycsamt.z.resphase.ResPhase or None) – Resistivity/phase view (direct or derived).
freq (ndarray or None) – Shared frequency vector inferred from available objects. Periods are available via
JFile.periods.periods (ndarray or None) – Convenience view of
1.0/freqwhen known.n_freq (int) – Number of frequency samples (
0if unknown).name (str or None) – Friendly site/station name. Precedence is:
Z.name-> head.station -> file stem.site (str or None) – Alias for the station code (if known).
elev (lat, lon, azimuth, az_hint,) – Geographic metadata proxied from headers.
- from_file(path, \*, verbose=0)#
Construct and read in one call.
- read(path=None, \*, start=None)#
Parse headers and blocks, then build
Z,TipandResas available.
- write(j_fn=None, new_jfn=None, datatype=None,
savepath=None, *, verbose=None, overwrite=True)
Serialize the current state to a J file. The
datatypeselector accepts combinations like'Z','R','T','ZR', or'ALL'.
Examples
>>> jf = JFile.from_file("data/j/kb0-s001.txt", verbose=0) >>> jf.n_freq > 0 True >>> out = jf.write(new_jfn="out.j", datatype="ZR", overwrite=True) >>> isinstance(out, str) True >>> jf.lat, jf.lon # site coordinates if present ( ... )
Notes
writeprefers existing uncertainties; missing errors are filled with zeros. Periods are written from the active frequency vector.When only R-blocks exist,
Zis rebuilt so that downstream code can still compute QA metrics or plot tensor-based products.
See also
pycsamt.jones.heads.HeadsHeader and metadata view.
pycsamt.jones.blocks.JBlocksLow-level parsed blocks.
pycsamt.z.z.ZImpedance tensor class.
pycsamt.z.tipper.TipperTipper class.
pycsamt.z.resphase.ResPhaseR–φ class.
References
[JFile-1]A. G. Jones, Magnetotelluric data file J-format, version 2.0, 1994.
[JFile-2]MTNet, J format documentation.
- classmethod from_file(path, *, verbose=0)#
Construct and read a J file in one call.
This convenience constructor mirrors
__init__+read(). It resolvespathto a filesystem location, parses headers and data blocks, and builds analysis-ready objects (Z,Tip,Res) when present or derivable.- Parameters:
- Returns:
Instance with
JFile.heads,JFile.blocksand objects (JFile.Z,JFile.Tip,JFile.Res) populated where possible.- Return type:
Notes
Headers (banner +
>KEY=VALUE+ the first head triple) are parsed viaHeads.Blocks are scanned with
JBlocks, then assembled intoZ/Tip/ResviaJIOMixin.
Examples
>>> jf = JFile.from_file("data/j/kb0-s001.txt") >>> jf.n_freq > 0 True
See also
JFile.readLower-level method if you already have an instance.
JBlocksLow-level block parser.
HeadsHeader and site metadata container.
References
[JFile-from-file-1]A. G. Jones, Magnetotelluric data file J-format, version 2.0, 1994.
- read(path=None, *, start=None)#
Parse a J file and build objects in memory.
The method reads the banner, info block and the first head triple, then scans all following data blocks. Transfer functions (
Zxx,Zxy, …) and tipper (Tzx,Tzy) are assembled when present. If only resistivity/phase blocks exist, a synthetic impedance is rebuilt from \(\rho\) and \(\phi\).- Parameters:
- Returns:
The instance itself (for chaining).
- Return type:
Notes
Block scanning is tolerant to minor format quirks (blank lines, non-canonical head order where the row count precedes the data-type).
Period sign conventions are normalized (negative values mean input was frequency in Hz).
Missing sentinels (e.g.,
-999) are mapped tonanin numeric arrays, while objects are pre- allocated with zeros to keep shapes consistent.
Examples
>>> jf = JFile(verbose=0) >>> _ = jf.read("data/j/kb0-s001.txt") >>> jf.Z is not None or jf.Res is not None True
See also
JFile.from_fileShortcut that constructs then calls this method.
JBlocksUnderlying block parser.
Z,Tipper,ResPhaseReferences
[JFile-read-1]A. G. Jones, Magnetotelluric data file J-format, version 2.0, 1994.
- write(j_fn=None, new_jfn=None, datatype=None, savepath=None, *, verbose=None, overwrite=True)#
Serialize the current state to a J-format file.
The writer renders a banner, info lines and one or more data blocks selected via
datatype. When uncertainties are unavailable, zero-filled error columns are emitted to preserve column layout. Periods are derived from the active frequency vector.- Parameters:
j_fn (str, optional) – Base filename to use. If omitted, derive from
JFile.pathor default to'out.j'.new_jfn (str, optional) – Replacement filename. Takes precedence over
j_fnwhen provided.datatype ({'Z','R','T','ZR','RT','ZT','ZRT','ALL'}, optional) – Select families to emit. If
None, the writer auto-detects from available objects on the instance.savepath (str or Path, optional) – Folder where to save. Defaults to the parent of
JFile.pathor the current directory.verbose (int, optional) – Override verbosity. If
None, reuseJFile.verbose.overwrite (bool, default=True) – If
Falseand the target exists, a numeric suffix is appended to avoid clobbering.
- Returns:
out_path – The filesystem path of the written file.
- Return type:
Notes
The station code and optional azimuth hint are taken from the parsed head. Units for transfer functions are written as
SI.If only
Rblocks exist, they can be emitted directly; if onlyZis present, syntheticR/φcan be computed for writing when the selector requests it.The banner defaults to
PYCSAMTwhen no producer is known. The original banner (if parsed) can be preserved or referenced by the caller before writing.
Examples
>>> jf = JFile.from_file("data/j/kb0-s001.txt") >>> out = jf.write(new_jfn="site_out.j", datatype="ZR", overwrite=True) >>> isinstance(out, str) True
References
[JFile-write-1]A. G. Jones, Magnetotelluric data file J-format, version 2.0, 1994.
- property site#
- class pycsamt.jones.IsJ#
Bases:
ABCAbstract base for A.G. Jones J-format validation helpers.
Subclasses implement
IsJ.is_valid. The static method_assert_j()provides a robust, file-level validator that accepts either a path or an existingIsJinstance. The check is heuristic, fast and tolerant of minor formatting issues (e.g., non-canonical head order).
- pycsamt.jones.is_j_file(file, *, deep=True)#
Convenience wrapper around
IsJ._assert_j().
- class pycsamt.jones.JParseMixin#
Bases:
objectLightweight helpers for scanning Jones J-format text.
The mixin implements tolerant, file-level utilities used by higher-level parsers and collections. It focuses on small, dependency-free pieces such as path coercion, candidate file discovery, banner and header probing, and quick content reads.
The mixin does not keep state. Methods are small and side-effect free so they can be reused by different classes (e.g.,
JCoreParser,JCBBase,JCollection).Notes
Utilities are designed to be permissive. They handle odd encodings, mixed line endings, and common filename patterns. They also accept both
pathlib.Pathand strings.The intent is to keep the heavy parsing in dedicated readers, while providing robust file discovery and quick checks here.
Examples
Discover candidate files in a folder:
>>> m = JParseMixin() >>> root = "data/j" >>> list(m._iter_j_files([root]))[:1] [PosixPath('...kb0-s001.txt')]
Coerce user inputs to
Path:>>> p = m._as_path("data/j/kb0-s001.txt") >>> p.exists() True
See also
JCoreParserAdds content probing (station, dtype, counts).
JCBBaseState-holding base for collections.
pycsamt.jones.validation.IsJFile-level validator for J candidates.
pycsamt.jones.j.JFileHigh-level reader that builds Z/Tipper/R blocks.
References
[JParseMixin-1]Jones (1994). J-format v2.0. MTNet notes.
- J_SUFFIXES = {'.dat', '.j', '.jones', '.txt'}#
- is_j_like(src, *, deep=True)#
Light heuristic to decide if
srclooks like a Jones file.
- class pycsamt.jones.JCoreParser(*, recursive=True, strict=False, on_dup='replace', verbose=0)#
Bases:
JParseMixinCore scanner for J files that extracts light metadata.
Extends
JParseMixinwith small, read-only probes that inspect the top header and first data head triple. This class can reveal the station code, presence of info keys, encountered data kinds, and the declared row count of the first block. It avoids loading the whole file.The implementation aims to be fast and safe for directory crawls, where many files are filtered before full parse.
- Variables:
encoding (str, default
'utf-8') – Encoding used when reading text. Implementations may choose a tolerant variant such as'utf-8-sig'witherrors='replace'.- Parameters:
- _read_text(path)#
Return the file content as a single text string.
- _scan_one(path)#
Return a small dict of hints (e.g.,
station,kinds,nrows) obtained without full parsing.
- _looks_like_j(path)#
Heuristic check that a path is a J candidate.
- _iter_info_keys(text)#
Yield info keys (
>KEY=VALUE) from the header area.
Notes
The scanner is structural. It does not validate numeric content or cross-block consistency. It is designed to be called many times in batch workflows.
Examples
Quick peek of a single file:
>>> p = "data/j/kb0-s001.txt" >>> core = JCoreParser() >>> hints = core._scan_one(p) >>> "station" in hints and "kinds" in hints True
Filter a folder to J candidates:
>>> paths = list(core._iter_j_files(["data/j"])) >>> all(core._looks_like_j(p) for p in paths) True
See also
JParseMixinPath and discovery helpers used by this scanner.
JCBBaseCollection base that can cache these hints.
pycsamt.jones.heads.HeadsFull header reader (Info + Head + Banner).
pycsamt.jones.blocks.JBlocksFull data block reader.
References
[JCoreParser-1]Jones (1994). J-format v2.0. MTNet notes.
- errors()#
- Return type:
- class pycsamt.jones.JCBBase(items=None, *, verbose=0)#
Bases:
objectMinimal stateful base for collections of J files.
The class manages a list of parsed items (usually
JFile), keeps light metadata for indexing and filtering, and offers a stable surface for higher-level collection types. It is intentionally small so projects can extend it without tight coupling.- Parameters:
- Variables:
- parse(paths)#
Build and add items from paths. Uses the light probes from
JCoreParserbefore full parse.
- filter(**kws)#
Optional helper that returns a new instance filtered by station, component family, or other metadata.
- __len__(), __iter__()#
Python container protocol for lists of items.
Notes
Subclasses are encouraged to keep the API stable while augmenting with domain-specific helpers, like saving index CSV files or computing per-site quality metrics.
The base class uses tolerant discovery, so it can be used on mixed folders where some files are not Jones J-format.
Examples
Build a collection from a folder:
>>> col = JCBBase(verbose=0) >>> items = col.parse(["data/j"]) >>> len(items) == col.n True
Iterate over sites and write quick summaries:
>>> for it in col: ... print(getattr(it, "site", None))
See also
pycsamt.jones.collection.JCollectionHigher-level collection with convenience features.
pycsamt.jones.j.JFileHigh-level reader used as per-item object.
JCoreParserProvides the fast scanning used during
parse.
References
[JCBBase-1]Jones (1994). J-format v2.0. MTNet notes.
- classmethod load(sources, *, parser=None, recursive=True, strict=False, on_dup='replace', verbose=0)#
- write(savepath, *, pattern='{station}.j', **kwargs)#
- property items#
unified iterator over stored items.
- Type:
Internal
- class pycsamt.jones.JCollectionMixin#
Bases:
JParseMixinMixin that provides folder/glob expansion and robust parsing orchestration for Jones J-format collections.
The mixin augments a stateful base (e.g.,
JCBBase) with helpers to normalize user input paths, expand folders and wildcards, deduplicate candidates, and parse items using a tolerant strategy.Implementations typically use
JFileas the per-item reader, but the mixin is agnostic to the concrete class as long as it exposes a compatiblefrom_fileconstructor.Notes
The design keeps discovery and parsing separate. First the mixin expands and filters path candidates; then the owning class decides how to instantiate items and how to record failures. This separation avoids tight coupling and keeps error handling clear.
The mixin favors permissive heuristics while still catching obvious mistakes (non-files, unreadable paths, extensions that are unlikely to be J-format, etc.).
2.11. Typical Methods#
- from_paths(paths, *, strict=False, verbose=0)
Expand and parse
pathsinto items. Returns the created items (usually a list).- _iter_paths(paths)
Yield
pathlib.Pathobjects from strings or paths, ignoring duplicates.- _iter_j_files(paths, *, recursive=True)
Yield J-candidates by expanding folders and glob patterns (e.g.,
"*.j","**/*.txt").- _is_j_candidate(path)
Light heuristic that recognizes J-format candidates.
Examples
Expand a folder and parse all candidates:
>>> mix = JCollectionMixin() >>> # usually inherited together with JCBBase >>> list(mix._iter_j_files(["data/j"]))[:1] [PosixPath('...kb0-s001.txt')]
See also
JCBBaseMinimal stateful base for collections (stores items).
JCollectionHigh-level collection that mixes in this helper and provides user-facing APIs.
pycsamt.jones.j.JFileHigh-level J reader used as default item type.
References
[JCollectionMixin-1]Jones (1994). J-format v2.0. MTNet notes.
- add_from(sources, *, recursive=True, strict=False, on_dup='replace', verbose=None)#
- select(stations)#
- Parameters:
- Return type:
- where(fn)#
- Parameters:
- Return type:
- sort(key='station', *, reverse=False)#
- class pycsamt.jones.JCollection(items=None, *, verbose=0)#
Bases:
JCBBase,JCollectionMixinHigh-level collection of Jones J-format files.
Combines
JCBBase(state container) withJCollectionMixin(discovery/orchestration) to offer a convenient interface for batch loading, quick metadata browsing, and simple filtering over many J files.The default per-item object is
JFile, which exposes parsed headers (Heads) and data blocks (JBlocks) as well as MT objects (pycsamt.z.z.Z,pycsamt.z.tipper.Tipper,pycsamt.z.resphase.ResPhase) when available.- Parameters:
- Variables:
items (list of JFile) – Parsed items in insertion order. The class follows Python’s container protocol (
__len__,__iter__).n (int) – Number of items in the collection (
len(self)).paths (list of Path) – Convenience view of the associated file paths.
stations (list of str) – Station codes when available on items (best-effort).
- parse(paths, \*, strict=False, verbose=None)#
Expand
paths(file, folder, glob), parse J files, and append items to the collection. Returns the new items.
- where(**query)#
Optional, return a filtered view (e.g., by
stationor by component familyhas_Z/has_R/has_T).
- summary()#
Optional, return a compact text or dataframe summary.
- write_index(path, \*, overwrite=True)#
Optional, serialize a CSV/TSV inventory for the collection.
Notes
The collection is intentionally lightweight. It does not enforce a database schema, and it avoids implicitly reading large arrays until needed. This makes it suitable for quick exploration and CI tests.
Error handling is conservative: unreadable paths or parse errors are usually skipped with a warning (unless
strict=Trueis requested).Examples
Parse a folder and browse basic metadata:
>>> col = JCollection(verbose=0) >>> _ = col.parse(["data/j"]) >>> len(col) >= 1 True >>> sorted(set(getattr(x, "site", None) for x in col))[ ... :3 ... ] [...]
Filter by station (if
whereis provided):>>> sub = getattr(col, "where", lambda **k: col)(station="KB0001") >>> len(sub) >= 1 True
See also
JCBBaseUnderlying state container.
JCollectionMixinPath expansion and tolerant orchestration.
pycsamt.jones.j.JFilePer-item high-level J reader.
References
[JCollection-1]Jones (1994). J-format v2.0. MTNet notes.
- classmethod from_sources(sources, *, recursive=True, strict=False, on_dup='replace', verbose=0)#
- merge(other, *, on_dup='replace')#
- Parameters:
other (JCollection)
on_dup (str)
- Return type:
- get(site, what, default=None)#
- Quick extractor. ‘what’ supports:
‘freq’
‘z’,’zxx’,’zxy’,’zyx’,’zyy’
‘tip’,’tx’,’ty’
‘rxy’,’ryx’,’rxx’,’ryy’ (rho)
‘phixy’,’phiyx’,’phixx’,’phiyy’
‘station’/’site’,’lat’,’lon’,’elev’,’az’,’name’
‘path’,’filename’
- set(site, *, jfile=None, update=None)#
Replace or mutate a site’s
JFile.If ‘jfile’ is given, replace the stored object.
Else apply ‘update’ keys on the existing object: ‘station’/’site’,’lat’,’lon’,’elev’,’az’, ‘freq’,’z’,’tip’,’resphase’
- adjust(site, *, dlat=None, dlon=None, lat=None, lon=None, elev=None, rename=None)#
Shift or set position and/or rename station.
- summary(fields=('station', 'n_freq', 'has_z', 'has_r', 'has_t', 'lat', 'lon', 'az'))#
- export(output_dir, *, file_pattern='{station}.j', export_summary=False, summary_filename='summary.csv', **jfile_write_kwargs)#
Exports all JFile items to a directory with advanced options.
This method orchestrates the writing of each JFile in the collection to a specified directory, with flexible naming, error handling, and an optional summary CSV file.
- Parameters:
output_dir (Pathish) – The path to the directory where files will be saved. It will be created if it does not exist.
file_pattern (str, default="{station}.j") – A format string for output filenames. Can use attributes of JFile like {station}, {name}, {site}.
export_summary (bool, default=False) – If True, a summary of the collection will also be saved as a CSV file in the output directory.
summary_filename (str, default="summary.csv") – The name of the summary file if export_summary is True.
**jfile_write_kwargs – Keyword arguments to be passed directly to each JFile.write() call (e.g., datatype=”ZRT”, overwrite=True).
- Returns:
A dictionary with two keys: - ‘successful’: A list of paths to successfully written files. - ‘failed’: A list of tuples, where each tuple contains the
station name and the error that occurred.
- Return type:
- fetch(site=None, lat=None, lon=None, tol=0.001, first=False, **kwargs)#
Fetches JFile objects from the collection based on specified criteria.
This method provides a flexible way to search for J-format files by site name, geographic coordinates, or any other attribute of the JFile object or its nested Heads sections.
- Parameters:
site (str, optional) – The site or station name to search for. The comparison is case-insensitive.
lat (float, optional) – The latitude to search for, in decimal degrees.
lon (float, optional) – The longitude to search for, in decimal degrees.
tol (float, default=0.001) – The tolerance in decimal degrees for geographic coordinate searches. A match is found if the absolute difference is within this tolerance.
first (bool, default=False) – If True, returns only the first matching JFile object found, or None if no match is found. If False, returns a list of all matching objects.
**kwargs (Any) – Additional keyword arguments to match against attributes of the JFile object or its nested Heads object (e.g., acqby=’Contractor’). The attribute name is case-insensitive.
- Returns:
If first=True, returns the first matching JFile or None.
If first=False, returns a list of all matching JFile objects. An empty list is returned if no matches are found.
- Return type:
Examples
>>> # Fetch a single site by its name >>> jfile_obj = jcollection.fetch(site="S01", first=True)
>>> # Fetch all sites where the azimuth is 0 >>> zero_az_files = jcollection.fetch(azimuth=0)
>>> # Fetch all sites within a small geographic area >>> area_files = jcollection.fetch(lat=26.05, lon=-10.33, tol=0.1)
- class pycsamt.jones.JComponentMixin#
Bases:
objectLightweight facade to manage Jones (J-format) components on a host object. The host is expected to expose a mapping-like container (
self.sectionsorself.components). Keys are normalized to lowercase for stable lookups.The mixin centralizes small CRUD helpers (
cget/cset/chas/ cdrop/snapshot) and offers typed accessors for frequent J parts such asbanner,info,head,heads,blocks, and derived data objects (z,tip,res).It also provides
compose_headerswhich serializes the header portion of a J file by callingwrite()on available components. If a combinedheadscomponent is present, it takes precedence over separatebanner/head/infoparts to avoid duplication.- compose_headers(*, prefer_heads=True, join=False)#
Serialize header lines by querying available components. If
prefer_headsis True and aheadscomponent is present, it is used exclusively. Otherwise the mixin attemptsbanner+head+infoin that order.When
joinis True, returns a single string joined with newlines. Otherwise returns a list of lines.
- pycsamt.jones.iter_lines(obj, *, encoding='utf-8', keepends=False)#
Yield lines from a path, file‑like, or a sequence of strings.
- Parameters:
- Yields:
str – One line at a time.
- Return type:
- pycsamt.jones.parse_datatype_units(line, *, lineno=None)#
Parse a data‑type line like
ZXY SIorRTE.The result contains the kind, component, optional units, and a
tensor_hintfor TE/TM modes.
2.11.1. Jones Modules#
|
Minimal bases for the Jones (J-format) subsystem. |
|
|
|
|
|
|
|
|
|
Configuration and canonical constants for the A.G. |
|
|
|
|
|
Site‑level properties parsed from the J‑format information block. |
|
Lightweight parsing utilities for A.G. |
|
|
|