mirror of
https://github.com/wassname/segpy.git
synced 2026-06-27 19:00:53 +08:00
Merge branch 'rewrite' into header
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
The SEG Y file format is one of several standards developed by the Society of Exploration Geophysicists for storing
|
||||
geophysical seismic data. It is an open standard, and is controlled by the SEG Technical Standards Committee, a
|
||||
non-profit organization.
|
||||
|
||||
This project aims to implement an open SEG Y module in Python for transporting seismic data between SEG Y files and
|
||||
Python data structures in pure Python.
|
||||
|
||||
|
||||
Status
|
||||
======
|
||||
|
||||
*Segpy 2* is currently in alpha, so expect rough edges. That said, it seems to broadly work and is largely feature
|
||||
complete.
|
||||
|
||||
|
||||
What It Does
|
||||
============
|
||||
|
||||
How To Get It
|
||||
=============
|
||||
|
||||
*Segpy* is available on the Python Package index and can be installed with ``pip``::
|
||||
|
||||
$ pip install segpy
|
||||
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
*Segpy 2* work with Python 3.2 and higher (and 2.7 for now). For the majority of use *Segpy 2* has no external
|
||||
dependencies. Optional modules with further dependencies such as *Numpy* are included in the ``segpy.ext`` package of
|
||||
extras.
|
||||
+11
-4
@@ -1,6 +1,6 @@
|
||||
=====
|
||||
Segpy
|
||||
=====
|
||||
=======
|
||||
Segpy 2
|
||||
=======
|
||||
|
||||
Status
|
||||
======
|
||||
@@ -18,4 +18,11 @@ geophysical seismic data. It is an open standard, and is controlled by the SEG T
|
||||
non-profit organization.
|
||||
|
||||
This project aims to implement an open SEG Y module in Python for transporting seismic data between SEG Y files and
|
||||
Numpy arrays. Segpy is a package for reading, writing and manipulating SEG Y data in pure Python.
|
||||
Python data structures in pure Python.
|
||||
|
||||
Segpy Versions
|
||||
==============
|
||||
|
||||
Segpy 2.0 is a complete re-imagining of a SEG Y reader in Python and represents a complete break from Segpy 1.0 in terms
|
||||
of the interface it presents to clients and the implementation behind those interfaces. Segpy 1.0 should be considered
|
||||
unmaintained legacy software. The present and future of Segpy is Segpy 2.
|
||||
@@ -0,0 +1,137 @@
|
||||
"""Extract a timeslice from a 3D seismic volume to a Numpy array.
|
||||
|
||||
Usage: timeslice.py [-h] [--dtype DTYPE] [--null NULL]
|
||||
segy-file npy-file slice-index
|
||||
|
||||
Positional arguments:
|
||||
segy-file Path to an existing SEG Y file of 3D seismic data
|
||||
npy-file Path to the Numpy array file to be created for the timeslice
|
||||
slice-index Zero based index of the time slice to be extracted
|
||||
|
||||
Optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
--dtype DTYPE Numpy data type. If not provided a dtype compatible with the
|
||||
SEG Y data will be used.
|
||||
--null NULL Sample value to use for missing or short traces.
|
||||
|
||||
Example:
|
||||
|
||||
timeslice.py stack_final_int8.sgy slice_800.npy 800 --null=42.0 --dtype=f
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
import numpy as np
|
||||
|
||||
from segpy.reader import create_reader
|
||||
from segpy_numpy.numpy.dtypes import make_dtype
|
||||
|
||||
|
||||
class DimensionalityError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def extract_timeslice(segy_filename, out_filename, slice_index, dtype=None, null=0):
|
||||
"""Extract a timeslice from a 3D SEG Y file to a Numpy NPY file.
|
||||
|
||||
Args:
|
||||
segy_filename: Filename of a SEG Y file.
|
||||
|
||||
out_filename: Filename of the NPY file.
|
||||
|
||||
slice_index: The zero-based index (increasing with depth) of the slice to be extracted.
|
||||
|
||||
dtype: Optional Numpy dtype for the result array. If not provided a dtype compatible with
|
||||
the SEG Y data will be used.
|
||||
|
||||
null: Optional sample value to use for missing or short traces. Defaults to zero.
|
||||
"""
|
||||
with open(segy_filename, 'rb') as segy_file:
|
||||
|
||||
segy_reader = create_reader(segy_file)
|
||||
|
||||
if dtype is None:
|
||||
dtype = make_dtype(segy_reader.data_sample_format)
|
||||
|
||||
if segy_reader.dimensionality != 3:
|
||||
raise DimensionalityError("Cannot slice {n} dimensional seismic.".format(segy_reader.dimensionality))
|
||||
|
||||
i_line_range = segy_reader.inline_range()
|
||||
x_line_range = segy_reader.xline_range()
|
||||
|
||||
i_size = len(i_line_range)
|
||||
x_size = len(x_line_range)
|
||||
t_size = segy_reader.max_num_trace_samples()
|
||||
|
||||
if not (0 <= slice_index < t_size):
|
||||
raise ValueError("Time slice index {0} out of range {} to {}".format(slice_index, 0, t_size))
|
||||
|
||||
timeslice = np.full((x_size, i_size), null, dtype)
|
||||
|
||||
for inline_num, xline_num in segy_reader.inline_xline_numbers():
|
||||
trace_index = segy_reader.trace_index((inline_num, xline_num))
|
||||
trace = segy_reader.trace_samples(trace_index)
|
||||
|
||||
try:
|
||||
sample = trace[slice_index]
|
||||
except IndexError:
|
||||
sample = null
|
||||
|
||||
i_index = inline_num - i_line_range.start
|
||||
x_index = xline_num - x_line_range.start
|
||||
timeslice[x_index, i_index] = sample
|
||||
|
||||
np.save(out_filename, timeslice)
|
||||
|
||||
|
||||
def nullable_dtype(s):
|
||||
return None if s == "" else np.dtype(s)
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("segy_file", metavar="segy-file",
|
||||
help="Path to an existing SEG Y file of 3D seismic data")
|
||||
|
||||
parser.add_argument("npy_file", metavar="npy-file",
|
||||
help="Path to the Numpy array file to be created for the timeslice")
|
||||
|
||||
parser.add_argument("slice_index", metavar="slice-index", type=int,
|
||||
help="Zero based index of the time slice to be extracted", )
|
||||
|
||||
parser.add_argument("--dtype", type=nullable_dtype, default="",
|
||||
help="Numpy data type. If not provided a dtype compatible with the SEG Y data will be used.")
|
||||
|
||||
parser.add_argument("--null", type=float, default=0.0,
|
||||
help="Sample value to use for missing or short traces.")
|
||||
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
try:
|
||||
extract_timeslice(args.segy_file,
|
||||
args.npy_file,
|
||||
args.slice_index,
|
||||
args.dtype,
|
||||
args.null)
|
||||
except (FileNotFoundError, IsADirectoryError) as e:
|
||||
print(e, file=sys.stderr)
|
||||
return os.EX_NOINPUT
|
||||
except PermissionError as e:
|
||||
print(e, file=sys.stderr)
|
||||
return os.EX_NOPERM
|
||||
except Exception as e:
|
||||
traceback.print_exception(type(e), e, e.__traceback__, file=sys.stderr)
|
||||
return os.EX_SOFTWARE
|
||||
return os.EX_OK
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
Segpy-Numpy offers tools for working with both *Segpy* and *Numpy*. See the *Segpy* documentation for further details.
|
||||
|
||||
|
||||
What It Does
|
||||
============
|
||||
|
||||
How To Get It
|
||||
=============
|
||||
|
||||
*Segpy-Numpy* is available on the Python Package index and can be installed with ``pip``::
|
||||
|
||||
$ pip install segpy-numpy
|
||||
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
*Segpy-Numpy* should work with Python 3.2 and higher (and 2.7 for now). For the majority of use *Segpy 2* has no
|
||||
externaldependencies. Optional modules with further dependencies such as *Numpy* are included in the ``segpy.ext``
|
||||
package of extras.
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
print("segpy_numpy.__init__ imported")
|
||||
|
||||
from pkgutil import extend_path
|
||||
|
||||
#__path__ = extend_path(__path__, __name__)
|
||||
__version__ = '2.0.0a1'
|
||||
|
||||
|
||||
def load():
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
import numpy
|
||||
|
||||
NUMPY_DTYPES = {'ibm': numpy.dtype('f4'),
|
||||
'l': numpy.dtype('i4'),
|
||||
'h': numpy.dtype('i2'),
|
||||
'f': numpy.dtype('f4'),
|
||||
'b': numpy.dtype('i1')}
|
||||
NUMPY_DTYPES = {'ibm': numpy.dtype('f4'),
|
||||
'int32': numpy.dtype('i4'),
|
||||
'int16': numpy.dtype('i2'),
|
||||
'float32': numpy.dtype('f4'),
|
||||
'int8': numpy.dtype('i1')}
|
||||
|
||||
|
||||
def make_dtype(data_sample_format):
|
||||
@@ -0,0 +1,5 @@
|
||||
[bdist_wheel]
|
||||
# This flag says that the code is written to work on both Python 2 and Python
|
||||
# 3. If at all possible, it is good practice to do this. If you cannot, you
|
||||
# will need to generate wheels for each Python version that you support.
|
||||
universal=1
|
||||
@@ -0,0 +1,127 @@
|
||||
import io
|
||||
import os
|
||||
import re
|
||||
from setuptools import setup, find_packages # Always prefer setuptools over distutils
|
||||
from codecs import open # To use a consistent encoding
|
||||
from os import path
|
||||
|
||||
|
||||
def read(*names, **kwargs):
|
||||
with io.open(
|
||||
os.path.join(os.path.dirname(__file__), *names),
|
||||
encoding=kwargs.get("encoding", "utf8")
|
||||
) as fp:
|
||||
return fp.read()
|
||||
|
||||
|
||||
def find_version(*file_paths):
|
||||
version_file = read(*file_paths)
|
||||
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
|
||||
version_file, re.M)
|
||||
if version_match:
|
||||
return version_match.group(1)
|
||||
raise RuntimeError("Unable to find version string.")
|
||||
|
||||
|
||||
here = path.abspath(path.dirname(__file__))
|
||||
|
||||
|
||||
def local_file(name):
|
||||
return os.path.join(here, name)
|
||||
|
||||
|
||||
|
||||
# Get the long description from the relevant file
|
||||
with open(local_file('DESCRIPTION.rst'), encoding='utf-8') as f:
|
||||
long_description = f.read()
|
||||
|
||||
setup(
|
||||
name='segpy-numpy',
|
||||
|
||||
# Versions should comply with PEP440. For a discussion on single-sourcing
|
||||
# the version across setup.py and the project code, see
|
||||
# https://packaging.python.org/en/latest/single_source_version.html
|
||||
version=find_version("segpy_numpy/__init__.py"),
|
||||
|
||||
description='Interoperability between Numpy with Segpy.',
|
||||
long_description=long_description,
|
||||
|
||||
# The project's main homepage.
|
||||
url='https://github.com/rob-smallshire/segpy',
|
||||
|
||||
# Author details
|
||||
author='Robert Smallshire',
|
||||
author_email='robert@smallshire.org.uk',
|
||||
|
||||
# Choose your license
|
||||
license='GPL',
|
||||
|
||||
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||
classifiers=[
|
||||
# How mature is this project? Common values are
|
||||
# 3 - Alpha
|
||||
# 4 - Beta
|
||||
# 5 - Production/Stable
|
||||
'Development Status :: 3 - Alpha',
|
||||
|
||||
# Indicate who your project is intended for
|
||||
'Intended Audience :: Developers',
|
||||
'Topic :: Scientific/Engineering',
|
||||
'Topic :: Software Development :: Libraries',
|
||||
|
||||
# Pick your license as you wish (should match "license" above)
|
||||
'License :: OSI Approved :: MIT License',
|
||||
|
||||
# Specify the Python versions you support here. In particular, ensure
|
||||
# that you indicate whether you support Python 2, Python 3 or both.
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
],
|
||||
|
||||
# What does your project relate to?
|
||||
keywords='seismic geocomputing geophysics numpy',
|
||||
|
||||
# You can just specify the packages manually here if your project is
|
||||
# simple. Or you can use find_packages().
|
||||
packages=find_packages(here, exclude=['segpy', 'contrib', 'docs', 'test*']),
|
||||
|
||||
# List run-time dependencies here. These will be installed by pip when your
|
||||
# project is installed. For an analysis of "install_requires" vs pip's
|
||||
# requirements files see:
|
||||
# https://packaging.python.org/en/latest/requirements.html
|
||||
install_requires=['numpy'],
|
||||
|
||||
# List additional groups of dependencies here (e.g. development dependencies).
|
||||
# You can install these using the following syntax, for example:
|
||||
# $ pip install -e .[dev,test]
|
||||
extras_require = {
|
||||
'dev': ['check-manifest', 'wheel'],
|
||||
'doc': ['sphinx', 'cartouche'],
|
||||
'test': ['coverage', 'hypothesis'],
|
||||
},
|
||||
|
||||
# If there are data files included in your packages that need to be
|
||||
# installed, specify them here. If using Python 2.6 or less, then these
|
||||
# have to be included in MANIFEST.in as well.
|
||||
package_data={
|
||||
},
|
||||
|
||||
# Although 'package_data' is the preferred approach, in some case you may
|
||||
# need to place data files outside of your packages.
|
||||
# see http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files
|
||||
# In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
|
||||
data_files=[],
|
||||
|
||||
# To provide executable scripts, use entry points in preference to the
|
||||
# "scripts" keyword. Entry points provide cross-platform support and allow
|
||||
# pip to create the appropriate form of executable for the target platform.
|
||||
|
||||
# Declare entry-points to modules.
|
||||
entry_points={
|
||||
'segpy.ext': 'segpy-numpy = segpy_numpy'
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
|
||||
__version__ = '2.0.0a1'
|
||||
|
||||
@@ -1 +1,20 @@
|
||||
import pkg_resources
|
||||
|
||||
loaded = set()
|
||||
|
||||
|
||||
def load_entry_points(name=None):
|
||||
"""Load extension packages into the segpy.ext namespace.
|
||||
|
||||
Any packages registered against the 'segpy.ext' entry-point group will be
|
||||
installed dynamically into the segpy.ext namespace.
|
||||
"""
|
||||
for entry_point in pkg_resources.iter_entry_points(group='segpy.ext', name=name):
|
||||
package = entry_point.load()
|
||||
if package not in loaded:
|
||||
loaded.add(package)
|
||||
__path__.extend(package.__path__)
|
||||
package.load()
|
||||
|
||||
|
||||
load_entry_points()
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
[bdist_wheel]
|
||||
# This flag says that the code is written to work on both Python 2 and Python
|
||||
# 3. If at all possible, it is good practice to do this. If you cannot, you
|
||||
# will need to generate wheels for each Python version that you support.
|
||||
universal=1
|
||||
@@ -0,0 +1,119 @@
|
||||
import io
|
||||
import os
|
||||
import re
|
||||
from setuptools import setup, find_packages # Always prefer setuptools over distutils
|
||||
from codecs import open # To use a consistent encoding
|
||||
from os import path
|
||||
|
||||
|
||||
def read(*names, **kwargs):
|
||||
with io.open(
|
||||
os.path.join(os.path.dirname(__file__), *names),
|
||||
encoding=kwargs.get("encoding", "utf8")
|
||||
) as fp:
|
||||
return fp.read()
|
||||
|
||||
|
||||
def find_version(*file_paths):
|
||||
version_file = read(*file_paths)
|
||||
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
|
||||
version_file, re.M)
|
||||
if version_match:
|
||||
return version_match.group(1)
|
||||
raise RuntimeError("Unable to find version string.")
|
||||
|
||||
|
||||
here = path.abspath(path.dirname(__file__))
|
||||
|
||||
# Get the long description from the relevant file
|
||||
with open(path.join(here, 'DESCRIPTION.rst'), encoding='utf-8') as f:
|
||||
long_description = f.read()
|
||||
|
||||
setup(
|
||||
name='segpy',
|
||||
|
||||
# Versions should comply with PEP440. For a discussion on single-sourcing
|
||||
# the version across setup.py and the project code, see
|
||||
# https://packaging.python.org/en/latest/single_source_version.html
|
||||
version=find_version("segpy/__init__.py"),
|
||||
|
||||
description='Transfer of seismic data to and from SEG Y files',
|
||||
long_description=long_description,
|
||||
|
||||
# The project's main homepage.
|
||||
url='https://github.com/rob-smallshire/segpy',
|
||||
|
||||
# Author details
|
||||
author='Robert Smallshire',
|
||||
author_email='robert@smallshire.org.uk',
|
||||
|
||||
# Choose your license
|
||||
license='GPL',
|
||||
|
||||
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||
classifiers=[
|
||||
# How mature is this project? Common values are
|
||||
# 3 - Alpha
|
||||
# 4 - Beta
|
||||
# 5 - Production/Stable
|
||||
'Development Status :: 3 - Alpha',
|
||||
|
||||
# Indicate who your project is intended for
|
||||
'Intended Audience :: Developers',
|
||||
'Topic :: Scientific/Engineering',
|
||||
'Topic :: Software Development :: Libraries',
|
||||
|
||||
# Pick your license as you wish (should match "license" above)
|
||||
'License :: OSI Approved :: MIT License',
|
||||
|
||||
# Specify the Python versions you support here. In particular, ensure
|
||||
# that you indicate whether you support Python 2, Python 3 or both.
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
],
|
||||
|
||||
# What does your project relate to?
|
||||
keywords='seismic geocomputing geophysics',
|
||||
|
||||
# You can just specify the packages manually here if your project is
|
||||
# simple. Or you can use find_packages().
|
||||
packages=find_packages(exclude=['contrib', 'docs', 'test*']),
|
||||
|
||||
# List run-time dependencies here. These will be installed by pip when your
|
||||
# project is installed. For an analysis of "install_requires" vs pip's
|
||||
# requirements files see:
|
||||
# https://packaging.python.org/en/latest/requirements.html
|
||||
install_requires=[],
|
||||
|
||||
# List additional groups of dependencies here (e.g. development dependencies).
|
||||
# You can install these using the following syntax, for example:
|
||||
# $ pip install -e .[dev,test]
|
||||
extras_require = {
|
||||
'dev': ['check-manifest', 'wheel'],
|
||||
'doc': ['sphinx', 'cartouche'],
|
||||
'test': ['coverage', 'hypothesis'],
|
||||
},
|
||||
|
||||
# If there are data files included in your packages that need to be
|
||||
# installed, specify them here. If using Python 2.6 or less, then these
|
||||
# have to be included in MANIFEST.in as well.
|
||||
package_data={
|
||||
},
|
||||
|
||||
# Although 'package_data' is the preferred approach, in some case you may
|
||||
# need to place data files outside of your packages.
|
||||
# see http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files
|
||||
# In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
|
||||
data_files=[],
|
||||
|
||||
# To provide executable scripts, use entry points in preference to the
|
||||
# "scripts" keyword. Entry points provide cross-platform support and allow
|
||||
# pip to create the appropriate form of executable for the target platform.
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ class TestBatched(unittest.TestCase):
|
||||
self.assertTrue(all(len(batch) == batch_size for batch in batches[:-1]))
|
||||
|
||||
@given([int],
|
||||
integers_in_range(1, 1000))
|
||||
integers_in_range(1, 1000))
|
||||
def test_final_batch_sizes(self, items, batch_size):
|
||||
assume(len(items) > 0)
|
||||
assume(batch_size > 0)
|
||||
|
||||
Reference in New Issue
Block a user