Skip to content

Commit

Permalink
Don't read tracecount from binheader, pass as arg
Browse files Browse the repository at this point in the history
The cheeky trick of passing the number of traceheaders in the binary
header when creating new files, in a field that is not dedicated to
number-of-traces-per-file, doesn't work because it's only 16 bits and
overflows very fast, and SEG-Y allows for 32-bits of traces (governed by
traceno).

Instead, pass the override-number-of-traces argument to the internal
filehandle constructor explicitly, and only consider that number if the
binary header is also passed.

This fixes the issue reported in
equinor#235
  • Loading branch information
jokva committed Mar 15, 2018
1 parent 2e2beae commit b558fb4
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 19 deletions.
8 changes: 4 additions & 4 deletions python/segyio/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,19 +135,19 @@ def create(filename, spec):
if not structured(spec):
tracecount = spec.tracecount
else:
tracecount = len(spec.ilines) * len(spec.xlines) * len(spec.offsets)
tracecount = len(spec.ilines) * len(spec.xlines) * len(spec.offsets)

ext_headers = spec.ext_headers if hasattr(spec, 'ext_headers') else 0
samples = numpy.asarray(spec.samples, dtype = numpy.single)

binary = bytearray(_segyio.binsize())
_segyio.putfield(binary, 3213, tracecount)
_segyio.putfield(binary, 3217, 4000)
_segyio.putfield(binary, 3221, len(samples))
_segyio.putfield(binary, 3225, int(spec.format))
_segyio.putfield(binary, 3505, int(ext_headers))

f = segyio.SegyFile(str(filename), "w+", binary = binary)
f = segyio.SegyFile(str(filename), "w+", tracecount = tracecount,
binary = binary)

f._il = int(spec.iline)
f._xl = int(spec.xline)
Expand All @@ -161,7 +161,7 @@ def create(filename, spec):
f._xlines = numpy.copy(numpy.asarray(spec.xlines, dtype=numpy.intc))

line_metrics = _segyio.line_metrics(f.sorting,
f.tracecount,
tracecount,
len(f.ilines),
len(f.xlines),
len(f.offsets))
Expand Down
4 changes: 2 additions & 2 deletions python/segyio/segy.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class SegyFile(object):

_unstructured_errmsg = "File opened in unstructured mode."

def __init__(self, filename, mode, iline=189, xline=193, binary=None):
def __init__(self, filename, mode, iline=189, xline=193, tracecount=0, binary=None):
"""
Constructor, internal.
"""
Expand Down Expand Up @@ -64,7 +64,7 @@ def __init__(self, filename, mode, iline=189, xline=193, binary=None):
self._xline = None
self._gather = None

self.xfd = _segyio.segyiofd(filename, mode, binary)
self.xfd = _segyio.segyiofd(filename, mode, tracecount, binary)
metrics = self.xfd.metrics()
self._fmt = metrics['format']
self._tracecount = metrics['tracecount']
Expand Down
14 changes: 5 additions & 9 deletions python/segyio/segyio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,13 @@ namespace fd {
int init( segyiofd* self, PyObject* args, PyObject* ) {
char* filename = NULL;
char* mode = NULL;
int tracecount = 0;
buffer_guard buffer;

if( !PyArg_ParseTuple( args, "ss|z*", &filename, &mode, &buffer ) )
if( !PyArg_ParseTuple( args, "ss|iz*", &filename,
&mode,
&tracecount,
&buffer ) )
return -1;

const char* binary = buffer.buf< const char >();
Expand Down Expand Up @@ -261,7 +265,6 @@ int init( segyiofd* self, PyObject* args, PyObject* ) {
return -1;
}

int tracecount = 0;
char bin[ SEGY_BINARY_HEADER_SIZE ] = {};

if( !binary ) {
Expand All @@ -273,13 +276,6 @@ int init( segyiofd* self, PyObject* args, PyObject* ) {
}

binary = bin;
} else {
/*
* usually we wouldn't trust the bin-traces in the binary header, but
* this code path is only taken with create() (or similarly
* pre-verified header), in which case we can just read the tracecount.
*/
segy_get_bfield( binary, SEGY_BIN_TRACES, &tracecount );
}

const long trace0 = segy_trace0( binary );
Expand Down
10 changes: 6 additions & 4 deletions python/test/segyio_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,18 +424,20 @@ def mkempty():
@tmpfiles("test-data/small.sgy")
def test_read_and_write_trace_mmap(tmpdir):
binary = bytearray(_segyio.binsize())
_segyio.putfield(binary, 3213, 100)
_segyio.putfield(binary, 3221, 25)
f = get_instance_segyiofd(tmpdir, "trace-wrt.sgy", "w+", binary)
f = get_instance_segyiofd(tmpdir, "trace-wrt.sgy", "w+",
tracecount=100,
binary=binary)
read_and_write_trace(f, True)


@tmpfiles("test-data/small.sgy")
def test_read_and_write_trace(tmpdir):
binary = bytearray(_segyio.binsize())
_segyio.putfield(binary, 3213, 100)
_segyio.putfield(binary, 3221, 25)
f = get_instance_segyiofd(tmpdir, "trace-wrt.sgy", "w+", binary)
f = get_instance_segyiofd(tmpdir, "trace-wrt.sgy", "w+",
tracecount=100,
binary=binary)
read_and_write_trace(f, False)


Expand Down

0 comments on commit b558fb4

Please sign in to comment.