Summary
mdio_spec_to_segy unconditionally injects the rev 1 segy_revision binary-header field into any spec that does not already contain it. For SEG-Y rev 2 / rev 2.1 that removes the two fields the spec legitimately declares over the same bytes, and export then fails.
The code
src/mdio/segy/creation.py (v1.2.1):
# During MDIO SEGY import, TGSAI/segy always creates revision major/minor fields
# We may not have it in the user desired spec. In that case we add it here
if "segy_revision" not in segy_spec.binary_header.names:
rev_field = binary.Rev1.SEGY_REVISION.model
segy_spec.binary_header.customize(fields=rev_field)
Why the guard is wrong for rev 2
The condition tests for the rev 1 spelling of the field, but rev 2 and rev 2.1 do not lack revision information — they spell it differently, as two fields over the same bytes 301–302:
>>> from segy.standards import get_segy_standard
>>> [f.name for f in get_segy_standard(1).binary_header.fields if "revision" in f.name]
['segy_revision']
>>> [f.name for f in get_segy_standard(2).binary_header.fields if "revision" in f.name]
['segy_revision_major', 'segy_revision_minor']
"segy_revision" not in names is therefore True for rev 2, the rev 1 field is injected, and HeaderSpec.customize evicts byte-overlapping fields — removing segy_revision_major and segy_revision_minor. The factory then asks for a field the spec no longer has:
segy.exceptions.NonSpecFieldError: The header field 'segy_revision_major' is found in
field alias table as 'segy_revision_major'. However, the current SEG-Y spec does not
define this field in header fields.
Measured on multidimio==1.2.1, segy==0.6.0, Python 3.12.13.
Note on discovery order
This is not the first blocker for rev 2 — ingestion fails earlier, on the S8 trace_header_name field (filed separately). This one only becomes visible once that is worked past, so fixing the dtype issue alone would not give rev 2 a round trip. Reporting both so the second is not a surprise after the first is fixed.
Suggested fix
Make the guard test for revision information rather than for one spelling of it, e.g. skip the injection when any of segy_revision, segy_revision_major or segy_revision_minor is present. Alternatively, inject the field matching the spec's own revision rather than always the rev 1 one.
Context
Found while probing SEG-Y revision coverage for a conversion validator. We do not patch around it — reaching into a pinned dependency is not something our project permits — so rev 2 / 2.1 export is recorded as unsupported. Happy to open a PR.
Summary
mdio_spec_to_segyunconditionally injects the rev 1segy_revisionbinary-header field into any spec that does not already contain it. For SEG-Y rev 2 / rev 2.1 that removes the two fields the spec legitimately declares over the same bytes, and export then fails.The code
src/mdio/segy/creation.py(v1.2.1):Why the guard is wrong for rev 2
The condition tests for the rev 1 spelling of the field, but rev 2 and rev 2.1 do not lack revision information — they spell it differently, as two fields over the same bytes 301–302:
"segy_revision" not in namesis therefore True for rev 2, the rev 1 field is injected, andHeaderSpec.customizeevicts byte-overlapping fields — removingsegy_revision_majorandsegy_revision_minor. The factory then asks for a field the spec no longer has:Measured on
multidimio==1.2.1,segy==0.6.0, Python 3.12.13.Note on discovery order
This is not the first blocker for rev 2 — ingestion fails earlier, on the
S8trace_header_namefield (filed separately). This one only becomes visible once that is worked past, so fixing the dtype issue alone would not give rev 2 a round trip. Reporting both so the second is not a surprise after the first is fixed.Suggested fix
Make the guard test for revision information rather than for one spelling of it, e.g. skip the injection when any of
segy_revision,segy_revision_majororsegy_revision_minoris present. Alternatively, inject the field matching the spec's own revision rather than always the rev 1 one.Context
Found while probing SEG-Y revision coverage for a conversion validator. We do not patch around it — reaching into a pinned dependency is not something our project permits — so rev 2 / 2.1 export is recorded as unsupported. Happy to open a PR.