[segyio] 198/376: Read/write sub traces and speed up depth reading.

Jørgen Kvalsvik jokva-guest at moszumanska.debian.org
Wed Sep 20 08:04:32 UTC 2017


This is an automated email from the git hooks/post-receive script.

jokva-guest pushed a commit to branch debian
in repository segyio.

commit 1ae8394008de01f2b4891ccd8c0109d44a906123
Author: Jørgen Kvalsvik <jokva at statoil.com>
Date:   Thu Feb 16 14:52:49 2017 +0100

    Read/write sub traces and speed up depth reading.
    
    Reading depth slice (or generalised to any partial trace) can be done
    with the segy_readsubtr function, which also now is the implementation
    of segy_readtrace. Analogous for writing.
    
    Rough measurements indicates that this speeds up depth_slice use by a
    factor of 5.
---
 lib/include/segyio/segy.h | 22 ++++++++++++++
 lib/src/segy.c            | 77 +++++++++++++++++++++++++++++++----------------
 lib/src/segy.def          |  2 ++
 lib/test/segy.c           | 12 ++++++++
 python/segyio/_segyio.c   | 13 ++++----
 5 files changed, 93 insertions(+), 33 deletions(-)

diff --git a/lib/include/segyio/segy.h b/lib/include/segyio/segy.h
index a62dc16..1188581 100644
--- a/lib/include/segyio/segy.h
+++ b/lib/include/segyio/segy.h
@@ -148,6 +148,28 @@ int segy_writetrace( segy_file*,
                      long trace0,
                      int trace_bsize );
 
+/*
+ * read/write sub traces, with the same assumption and requirements as
+ * segy_readtrace. fst and lst are *indices*, not byte offsets, so
+ * segy_readsubtr(fp, traceno, 0, 12, ...) reads samples 0 through 12, and not
+ * 0 throuh 3.
+ */
+int segy_readsubtr( segy_file*,
+                    int traceno,
+                    int fst,
+                    int lst,
+                    float* buf,
+                    long trace0,
+                    int trace_bsize );
+
+int segy_writesubtr( segy_file*,
+                     int traceno,
+                     int fst,
+                     int lst,
+                     const float* buf,
+                     long trace0,
+                     int trace_bsize );
+
 /* convert to/from native float from segy formats (likely IBM or IEEE) */
 int segy_to_native( int format,
                     int size,
diff --git a/lib/src/segy.c b/lib/src/segy.c
index 93f802c..b4ccf53 100644
--- a/lib/src/segy.c
+++ b/lib/src/segy.c
@@ -1088,42 +1088,59 @@ int segy_crossline_indices( segy_file* fp,
     return SEGY_INVALID_SORTING;
 }
 
+static inline int subtr_seek( segy_file* fp,
+                              int traceno,
+                              int fst,
+                              int lst,
+                              long trace0,
+                              int trace_bsize ) {
+    /*
+     * Optimistically assume that indices are correct by the time they're given
+     * to subtr_seek.
+     */
+    assert( fst > lst || fst < 0 );
+    assert( sizeof( float ) == 4 );
+    assert( (lst - fst) * sizeof( float ) <= trace_bsize );
 
-static int skip_traceheader( segy_file* fp ) {
-    if( fp->addr ) {
-        fp->cur = (char*)fp->cur + SEGY_TRACE_HEADER_SIZE;
-        return SEGY_OK;
-    }
-    const int err = fseek( fp->fp, SEGY_TRACE_HEADER_SIZE, SEEK_CUR );
-    if( err != 0 ) return SEGY_FSEEK_ERROR;
-    return SEGY_OK;
+    int err;
+    // skip the trace header and skip everything before fst.
+    trace0 += (fst * sizeof( float )) + SEGY_TRACE_HEADER_SIZE;
+    return segy_seek( fp, traceno, trace0, trace_bsize );
 }
 
+
 int segy_readtrace( segy_file* fp,
                     int traceno,
                     float* buf,
                     long trace0,
                     int trace_bsize ) {
-    int err;
-    err = segy_seek( fp, traceno, trace0, trace_bsize );
-    if( err != 0 ) return err;
+    const int lst = trace_bsize / sizeof( float );
+    return segy_readsubtr( fp, traceno, 0, lst, buf, trace0, trace_bsize );
+}
 
-    err = skip_traceheader( fp );
-    if( err != 0 ) return err;
+int segy_readsubtr( segy_file* fp,
+                    int traceno,
+                    int fst,
+                    int lst,
+                    float* buf,
+                    long trace0,
+                    int trace_bsize ) {
+
+    int err = subtr_seek( fp, traceno, fst, lst, trace0, trace_bsize );
+    if( err != SEGY_OK ) return err;
 
     assert( trace_bsize >= 0 );
     const size_t bsize = (size_t) trace_bsize;
 
     if( fp->addr ) {
-        memcpy( buf, fp->cur, bsize );
+        memcpy( buf, fp->cur, sizeof( float ) * ( lst - fst ) );
         return SEGY_OK;
     }
 
-    const size_t readc = fread( buf, 1, bsize, fp->fp );
-    if( readc != bsize ) return SEGY_FREAD_ERROR;
+    const size_t readc = fread( buf, sizeof( float ), lst - fst, fp->fp );
+    if( readc != lst - fst ) return SEGY_FREAD_ERROR;
 
     return SEGY_OK;
-
 }
 
 int segy_writetrace( segy_file* fp,
@@ -1132,24 +1149,32 @@ int segy_writetrace( segy_file* fp,
                      long trace0,
                      int trace_bsize ) {
 
-    int err;
-    err = segy_seek( fp, traceno, trace0, trace_bsize );
-    if( err != 0 ) return err;
+    const int lst = trace_bsize / sizeof( float );
+    return segy_writesubtr( fp, traceno, 0, lst, buf, trace0, trace_bsize );
+}
 
-    err = skip_traceheader( fp );
-    if( err != 0 ) return err;
+int segy_writesubtr( segy_file* fp,
+                     int traceno,
+                     int fst,
+                     int lst,
+                     const float* buf,
+                     long trace0,
+                     int trace_bsize ) {
+
+    int err = subtr_seek( fp, traceno, fst, lst, trace0, trace_bsize );
+    if( err != SEGY_OK ) return err;
 
     assert( trace_bsize >= 0 );
     const size_t bsize = (size_t) trace_bsize;
 
     if( fp->addr ) {
-        memcpy( fp->cur, buf, bsize );
+        memcpy( fp->cur, buf, sizeof( float ) * ( lst - fst ) );
         return SEGY_OK;
     }
 
-    const size_t writec = fwrite( buf, 1, bsize , fp->fp );
-    if( writec != bsize )
-        return SEGY_FWRITE_ERROR;
+    const size_t writec = fwrite( buf, sizeof( float ), lst - fst, fp->fp );
+    if( writec != lst - fst ) return SEGY_FWRITE_ERROR;
+
     return SEGY_OK;
 }
 
diff --git a/lib/src/segy.def b/lib/src/segy.def
index b224243..43907ee 100644
--- a/lib/src/segy.def
+++ b/lib/src/segy.def
@@ -27,7 +27,9 @@ segy_sorting
 segy_offsets
 segy_offset_indices
 segy_readtrace
+segy_readsubtr
 segy_writetrace
+segy_writesubtr
 segy_to_native
 segy_from_native
 segy_read_line
diff --git a/lib/test/segy.c b/lib/test/segy.c
index 581d017..d6a9164 100644
--- a/lib/test/segy.c
+++ b/lib/test/segy.c
@@ -550,6 +550,18 @@ static void test_file_error_codes() {
     assertTrue( err == SEGY_FSEEK_ERROR, "Could seek in invalid file." );
 
     int l1, l2;
+    err = segy_readsubtr( fp, 0, 2, 0, NULL, 3600, 350 );
+    assertTrue( err == SEGY_INVALID_ARGS, "Could pass fst larger than lst" );
+
+    err = segy_readsubtr( fp, 0, -1, 10, NULL, 3600, 350 );
+    assertTrue( err == SEGY_INVALID_ARGS, "Could pass negative fst" );
+
+    err = segy_writesubtr( fp, 0, 2, 0, NULL, 3600, 350 );
+    assertTrue( err == SEGY_INVALID_ARGS, "Could pass fst larger than lst" );
+
+    err = segy_writesubtr( fp, 0, -1, 10, NULL, 3600, 350 );
+    assertTrue( err == SEGY_INVALID_ARGS, "Could pass negative fst" );
+
     err = segy_count_lines( fp, 0, 1, &l1, &l2, 3600, 350 );
     assertTrue( err == SEGY_FSEEK_ERROR, "Could seek in invalid file." );
 }
diff --git a/python/segyio/_segyio.c b/python/segyio/_segyio.c
index af243d3..347dd9f 100644
--- a/python/segyio/_segyio.c
+++ b/python/segyio/_segyio.c
@@ -981,17 +981,16 @@ static PyObject *py_read_depth_slice(PyObject *self, PyObject *args) {
 
     Py_ssize_t trace_no = 0;
     int error = 0;
-    float* trace_buffer = malloc(trace_bsize * samples);
     float* buf = buffer.buf;
 
     for(trace_no = 0; error == 0 && trace_no < count; ++trace_no) {
-        error = segy_readtrace(p_FILE, trace_no * offsets, trace_buffer, trace0, trace_bsize);
-
-        if (!error) {
-            buf[trace_no] = trace_buffer[depth];
-        }
+        error = segy_readsubtr(p_FILE,
+                               trace_no * offsets,
+                               depth,
+                               depth + 1,
+                               buf++,
+                               trace0, trace_bsize);
     }
-    free(trace_buffer);
 
     if (error != 0) {
         PyBuffer_Release( &buffer );

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/segyio.git



More information about the debian-science-commits mailing list