Skip to content

Encode ibm32 header fields on write - #376

Merged
BrianMichell merged 2 commits into
TGSAI:mainfrom
andgineer:fix/ibm32-header-write-encode
Jun 16, 2026
Merged

Encode ibm32 header fields on write#376
BrianMichell merged 2 commits into
TGSAI:mainfrom
andgineer:fix/ibm32-header-write-encode

Conversation

@andgineer

Copy link
Copy Markdown
Contributor

Problem

SegyFactory.create_traces does not IBM-encode ibm32 header fields, even though TraceAccessor IBM-decodes them on read. The write path is therefore asymmetric with the read path: an ibm32 header written by the factory is stored as a raw integer, and reading it back through the IBM decode yields garbage.

We hit this in a production MDIO->SEG-Y cut: an ibm32 header (azimuth) came out of the cut as a plain integer, which QC then flagged because the value no longer matched the source.

Fix

  • create_traces: add a keyed to_ibm transform to the header pipeline, placed before the byte-swap. This is the exact inverse of the read path (byte_swap then to_ieee) and mirrors the data pipeline's existing ibm32 handling.
  • create_trace_header_template: expose ibm32 fields as float32 instead of uint32, so callers fill real float values that then get encoded. This matches what the reader returns for ibm32 headers and what create_trace_sample_template already does for ibm32 samples.

The on-disk format is unchanged (4 bytes, IBM-encoded, big-endian); only the in-memory template dtype changes.

Open question

The create_traces encode change fixes the bug on its own, because the reader already hands callers a float32 array.

The create_trace_header_template -> float32 change is the consistency/usability part, and it's the only piece that changes a public dtype. Happy to drop it and keep the PR to just the encode if you'd rather avoid the template dtype change. Let me know which you prefer.

Tests

  • New TestSegyFactoryIbmHeader (big/little x 1/42 traces): on-disk bytes equal ieee2ibm(value), plus a lossless round-trip.
  • Full suite: 289 passed. mypy and ruff clean.

SegyFactory.create_traces did not IBM-encode ibm32 header fields, even
though TraceAccessor IBM-decodes them on read. An ibm32 header written by
the factory round-tripped to a wrong value: stored as a raw integer and
read back through the IBM decode as garbage.

Add a keyed to_ibm transform to the header pipeline before the byte-swap
(the inverse of the read path's byte_swap then to_ieee), mirroring the
data pipeline's existing ibm32 handling. Also promote ibm32 fields in
create_trace_header_template to float32 so callers fill real floats that
get encoded, matching the reader output and create_trace_sample_template.

Co-authored-by: Cursor <cursoragent@cursor.com>
@codecov

codecov Bot commented Jun 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.94%. Comparing base (818c1a5) to head (be68c2e).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #376      +/-   ##
==========================================
+ Coverage   95.86%   95.94%   +0.07%     
==========================================
  Files          50       50              
  Lines        2663     2713      +50     
  Branches      149      151       +2     
==========================================
+ Hits         2553     2603      +50     
  Misses         84       84              
  Partials       26       26              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@BrianMichell

Copy link
Copy Markdown
Collaborator

The create_trace_header_template -> float32 change is the consistency/usability part

I think it's appropriate for the bugfix to ensure we don't cause inadvertant trucation. float32 dtype is the way to go.

@BrianMichell BrianMichell left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please ensure that the codecov pipeline passes. I think applying that one change should satisfy it.

Comment thread src/segy/factory.py Outdated
@andgineer

Copy link
Copy Markdown
Contributor Author

Thanks! The PR already has the float32 version, so nothing to change - good to merge whenever.

Per review: drop the hand-rolled _retype_struct_fields helper and reuse
the existing _modify_dtype_field from transforms.py to promote ibm32
header fields to float32. Removes the untested None-guard branch that
left create_trace_header_template below patch coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
@BrianMichell
BrianMichell merged commit e79d7fd into TGSAI:main Jun 16, 2026
15 checks passed
@BrianMichell BrianMichell added bug Something isn't working breaking Breaking Changes labels Jun 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Breaking Changes bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants