mirror of
https://github.com/wassname/segpy.git
synced 2026-06-27 19:48:48 +08:00
Reinstate Python 2 compatibility.
This commit is contained in:
@@ -5,6 +5,8 @@ Usage:
|
||||
loadsave.py <in.segy> <out.segy>
|
||||
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
|
||||
import sys
|
||||
|
||||
@@ -6,6 +6,7 @@ Usage:
|
||||
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import datetime
|
||||
|
||||
import os
|
||||
|
||||
+15
-14
@@ -6,7 +6,7 @@ from segpy.portability import reprlib
|
||||
from segpy.util import contains_duplicates, measure_stride, minmax
|
||||
|
||||
|
||||
class CatalogBuilder:
|
||||
class CatalogBuilder(object):
|
||||
"""Use a catalog builder to construct optimised, immutable mappings.
|
||||
|
||||
A CatalogBuilder is useful when, depending on the particular keys and
|
||||
@@ -230,7 +230,7 @@ class RowMajorCatalog(Catalog):
|
||||
j_max (int): The maximum j value.
|
||||
c (int): The constant offset
|
||||
"""
|
||||
super().__init__()
|
||||
super(RowMajorCatalog, self).__init__()
|
||||
self._i_min = i_min
|
||||
self._i_max = i_max
|
||||
self._j_min = j_min
|
||||
@@ -305,7 +305,7 @@ class DictionaryCatalog(Catalog):
|
||||
"""
|
||||
|
||||
def __init__(self, items):
|
||||
super().__init__()
|
||||
super(DictionaryCatalog, self).__init__()
|
||||
self._items = OrderedDict(items)
|
||||
|
||||
def __getitem__(self, key):
|
||||
@@ -349,10 +349,11 @@ class RegularConstantCatalog(Catalog):
|
||||
raise ValueError("RegularIndex key range {!r} is not "
|
||||
"a multiple of stride {!r}".format(
|
||||
key_stride, key_range))
|
||||
super().__init__(key_min=key_min,
|
||||
key_max=key_max,
|
||||
value_min=value,
|
||||
value_max=value)
|
||||
super(RegularConstantCatalog, self).__init__(
|
||||
key_min=key_min,
|
||||
key_max=key_max,
|
||||
value_min=value,
|
||||
value_max=value)
|
||||
self._key_stride = key_stride
|
||||
|
||||
def __getitem__(self, key):
|
||||
@@ -397,7 +398,7 @@ class ConstantCatalog(Catalog):
|
||||
key_stride: The difference between successive keys.
|
||||
value: A value associated with all keys.
|
||||
"""
|
||||
super().__init__(value_min=value, value_max=value)
|
||||
super(ConstantCatalog, self).__init__(value_min=value, value_max=value)
|
||||
self._items = frozenset(keys)
|
||||
|
||||
def __getitem__(self, key):
|
||||
@@ -449,7 +450,7 @@ class RegularCatalog(Catalog):
|
||||
raise ValueError("{} key range {!r} is not "
|
||||
"a multiple of stride {!r}".format(self.__class__.__name__,
|
||||
key_stride, key_range))
|
||||
super().__init__(key_min=key_min, key_max=key_max)
|
||||
super(RegularCatalog, self).__init__(key_min=key_min, key_max=key_max)
|
||||
self._key_stride = key_stride
|
||||
self._values = list(values)
|
||||
num_keys = key_range // key_stride
|
||||
@@ -537,11 +538,11 @@ class LinearRegularCatalog(Catalog):
|
||||
value_range))
|
||||
self._value_stride = value_stride
|
||||
|
||||
super().__init__(key_min=key_min,
|
||||
key_max=key_max,
|
||||
value_min=value_min,
|
||||
value_max=value_max)
|
||||
|
||||
super(LinearRegularCatalog, self).__init__(
|
||||
key_min=key_min,
|
||||
key_max=key_max,
|
||||
value_min=value_min,
|
||||
value_max=value_max)
|
||||
|
||||
num_keys = (self.key_max() - self.key_min()) // self._key_stride
|
||||
num_values = (self.value_max() - self.value_min()) // self._value_stride
|
||||
|
||||
+14
-3
@@ -38,7 +38,7 @@ if sys.version_info >= (3, 0):
|
||||
return bytes(integers)
|
||||
else:
|
||||
def byte_string(integers):
|
||||
return ''.join(chr(i) for i in integers)
|
||||
return EMPTY_BYTE_STRING.join(chr(i) for i in integers)
|
||||
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
@@ -49,9 +49,11 @@ else:
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
izip = zip
|
||||
from itertools import zip_longest as izip_longest
|
||||
else:
|
||||
from itertools import izip
|
||||
izip = izip # Keep the static analyzer happy
|
||||
from itertools import (izip, izip_longest)
|
||||
izip = izip # Keep the static analyzer happy
|
||||
izip_longest = izip_longest # Keep the static analyzer happy
|
||||
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
@@ -65,3 +67,12 @@ else:
|
||||
c = ord(byte_str[2])
|
||||
d = ord(byte_str[3])
|
||||
return a, b, c, d
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
unicode = str
|
||||
else:
|
||||
unicode = unicode
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+12
-17
@@ -1,14 +1,18 @@
|
||||
from __future__ import print_function
|
||||
|
||||
from array import array
|
||||
from collections import namedtuple, OrderedDict
|
||||
import itertools
|
||||
from itertools import zip_longest
|
||||
from portability import izip_longest
|
||||
import os
|
||||
import struct
|
||||
import re
|
||||
import sys
|
||||
import logging
|
||||
|
||||
from segpy import textual_reel_header_definition
|
||||
|
||||
|
||||
from segpy.catalog import CatalogBuilder
|
||||
from segpy.datatypes import CTYPES, size_in_bytes
|
||||
from segpy.encoding import guess_encoding, is_supported_encoding, UnsupportedEncodingError
|
||||
@@ -32,6 +36,11 @@ TRACE_HEADER_NUM_BYTES = 240
|
||||
END_TEXT_STANZA = "((SEG: EndText))"
|
||||
|
||||
|
||||
def logger():
|
||||
# Defer logger creation until the module is *used* rather than imported.
|
||||
return logging.getLogger(__name__)
|
||||
|
||||
|
||||
def extract_revision(binary_reel_header):
|
||||
"""Obtain the SEG Y revision from the reel header.
|
||||
|
||||
@@ -234,7 +243,7 @@ def read_extended_headers_counted(fh, num_expected, encoding):
|
||||
ext_header = read_textual_reel_header(fh, encoding)
|
||||
if has_end_text_stanza(ext_header):
|
||||
if i != num_expected - 1:
|
||||
print("Unexpected end-text extended header", file=sys.stderr) # TODO: Log this
|
||||
logger().warning("Unexpected end-text extended header.")
|
||||
break
|
||||
extended_headers.append(ext_header)
|
||||
|
||||
@@ -522,7 +531,7 @@ def format_standard_textual_header(revision, **kwargs):
|
||||
background_slices = complementary_slices(placeholder_slices.values(), 0, len(template))
|
||||
|
||||
chunks = []
|
||||
for bg_slice, placeholder in zip_longest(background_slices, placeholder_slices.items()):
|
||||
for bg_slice, placeholder in izip_longest(background_slices, placeholder_slices.items()):
|
||||
|
||||
if bg_slice is not None:
|
||||
chunks.append(template[bg_slice])
|
||||
@@ -890,17 +899,3 @@ def _compile_trace_header_record():
|
||||
|
||||
TraceHeader = _compile_trace_header_record()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from pprint import pprint as pp
|
||||
header = format_standard_textual_header(1,
|
||||
client="Lundin",
|
||||
company="Western Geco",
|
||||
crew_number=123,
|
||||
processing1="Sixty North AS",
|
||||
sweep_start_hz=10,
|
||||
sweep_end_hz=1000,
|
||||
sweep_length_ms=10000,
|
||||
sweep_channel_number=3,
|
||||
sweep_type='spread')
|
||||
pp(header, width=200)
|
||||
|
||||
@@ -7,6 +7,7 @@ from hypothesis.searchstrategy import MappedSearchStrategy, StringStrategy
|
||||
from hypothesis.strategytable import StrategyTable
|
||||
from segpy.encoding import EBCDIC, ASCII
|
||||
from segpy.toolkit import format_extended_textual_header, CARDS_PER_HEADER, END_TEXT_STANZA, CARD_LENGTH
|
||||
from segpy.portability import unicode
|
||||
|
||||
|
||||
# class MultiLineString(str):
|
||||
@@ -31,28 +32,28 @@ from segpy.toolkit import format_extended_textual_header, CARDS_PER_HEADER, END_
|
||||
|
||||
class TestFormatExtendedTextualHeader(unittest.TestCase):
|
||||
|
||||
@given(str,
|
||||
@given(unicode,
|
||||
sampled_from([ASCII, EBCDIC]),
|
||||
bool)
|
||||
def test_forty_lines_per_page(self, text, encoding, include_text_stop):
|
||||
pages = format_extended_textual_header(text, encoding, include_text_stop)
|
||||
self.assertTrue(all(len(page) == CARDS_PER_HEADER for page in pages))
|
||||
|
||||
@given(str,
|
||||
@given(unicode,
|
||||
sampled_from([ASCII, EBCDIC]),
|
||||
bool)
|
||||
def test_eighty_bytes_per_encoded_line(self, text, encoding, include_text_stop):
|
||||
pages = format_extended_textual_header(text, encoding, include_text_stop)
|
||||
self.assertTrue(all([len(line.encode(encoding)) == CARD_LENGTH for page in pages for line in page]))
|
||||
|
||||
@given(str,
|
||||
@given(unicode,
|
||||
sampled_from([ASCII, EBCDIC]),
|
||||
bool)
|
||||
def test_lines_end_with_cr_lf(self, text, encoding, include_text_stop):
|
||||
pages = format_extended_textual_header(text, encoding, include_text_stop)
|
||||
self.assertTrue(all([line.endswith('\r\n') for page in pages for line in page]))
|
||||
|
||||
@given(str,
|
||||
@given(unicode,
|
||||
sampled_from([ASCII, EBCDIC]),
|
||||
just(True))
|
||||
def test_lines_end_with_cr_lf(self, text, encoding, include_text_stop):
|
||||
|
||||
+22
-21
@@ -2,6 +2,7 @@ import unittest
|
||||
|
||||
from segpy.ibm_float import (ieee2ibm, ibm2ieee, MAX_IBM_FLOAT, SMALLEST_POSITIVE_NORMAL_IBM_FLOAT,
|
||||
LARGEST_NEGATIVE_NORMAL_IBM_FLOAT, MIN_IBM_FLOAT)
|
||||
from segpy.portability import byte_string
|
||||
|
||||
|
||||
class Ibm2Ieee(unittest.TestCase):
|
||||
@@ -10,44 +11,44 @@ class Ibm2Ieee(unittest.TestCase):
|
||||
self.assertEqual(ibm2ieee(b'\0\0\0\0'), 0.0)
|
||||
|
||||
def test_positive_half(self):
|
||||
self.assertEqual(ibm2ieee((0b11000000, 0x80, 0x00, 0x00)), -0.5)
|
||||
self.assertEqual(ibm2ieee(byte_string((0b11000000, 0x80, 0x00, 0x00))), -0.5)
|
||||
|
||||
def test_negative_half(self):
|
||||
self.assertEqual(ibm2ieee((0b01000000, 0x80, 0x00, 0x00)), 0.5)
|
||||
self.assertEqual(ibm2ieee(byte_string((0b01000000, 0x80, 0x00, 0x00))), 0.5)
|
||||
|
||||
def test_one(self):
|
||||
self.assertEqual(ibm2ieee(b'\x41\x10\x00\x00'), 1.0)
|
||||
|
||||
def test_negative_118_625(self):
|
||||
# Example taken from Wikipedia http://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture
|
||||
self.assertEqual(ibm2ieee((0b11000010, 0b01110110, 0b10100000, 0b00000000)), -118.625)
|
||||
self.assertEqual(ibm2ieee(byte_string((0b11000010, 0b01110110, 0b10100000, 0b00000000))), -118.625)
|
||||
|
||||
def test_largest_representable_number(self):
|
||||
self.assertEqual(ibm2ieee((0b01111111, 0b11111111, 0b11111111, 0b11111111)), MAX_IBM_FLOAT)
|
||||
self.assertEqual(ibm2ieee(byte_string((0b01111111, 0b11111111, 0b11111111, 0b11111111))), MAX_IBM_FLOAT)
|
||||
|
||||
def test_smallest_positive_normalised_number(self):
|
||||
self.assertEqual(ibm2ieee((0b00000000, 0b00010000, 0b00000000, 0b00000000)), SMALLEST_POSITIVE_NORMAL_IBM_FLOAT)
|
||||
self.assertEqual(ibm2ieee(byte_string((0b00000000, 0b00010000, 0b00000000, 0b00000000))), SMALLEST_POSITIVE_NORMAL_IBM_FLOAT)
|
||||
|
||||
def test_largest_negative_normalised_number(self):
|
||||
self.assertEqual(ibm2ieee((0b10000000, 0b00010000, 0b00000000, 0b00000000)), LARGEST_NEGATIVE_NORMAL_IBM_FLOAT)
|
||||
self.assertEqual(ibm2ieee(byte_string((0b10000000, 0b00010000, 0b00000000, 0b00000000))), LARGEST_NEGATIVE_NORMAL_IBM_FLOAT)
|
||||
|
||||
def test_smallest_representable_number(self):
|
||||
self.assertEqual(ibm2ieee((0b11111111, 0b11111111, 0b11111111, 0b11111111)), MIN_IBM_FLOAT)
|
||||
self.assertEqual(ibm2ieee(byte_string((0b11111111, 0b11111111, 0b11111111, 0b11111111))), MIN_IBM_FLOAT)
|
||||
|
||||
def test_error_1(self):
|
||||
self.assertEqual(ibm2ieee((196, 74, 194, 143)), -19138.55859375)
|
||||
self.assertEqual(ibm2ieee(byte_string((196, 74, 194, 143))), -19138.55859375)
|
||||
|
||||
def test_error_2(self):
|
||||
self.assertEqual(ibm2ieee((191, 128, 0, 0)), -0.03125)
|
||||
self.assertEqual(ibm2ieee(byte_string((191, 128, 0, 0))), -0.03125)
|
||||
|
||||
def test_subnormal(self):
|
||||
self.assertEqual(ibm2ieee((0x00, 0x00, 0x00, 0x20)), 1.6472184286297693e-83)
|
||||
self.assertEqual(ibm2ieee(byte_string((0x00, 0x00, 0x00, 0x20))), 1.6472184286297693e-83)
|
||||
|
||||
def test_subnormal_is_subnormal(self):
|
||||
self.assertTrue(0 < ibm2ieee((0x00, 0x00, 0x00, 0x20)) < SMALLEST_POSITIVE_NORMAL_IBM_FLOAT)
|
||||
self.assertTrue(0 < ibm2ieee(byte_string((0x00, 0x00, 0x00, 0x20))) < SMALLEST_POSITIVE_NORMAL_IBM_FLOAT)
|
||||
|
||||
def test_subnormal_smallest_subnormal(self):
|
||||
self.assertEqual(ibm2ieee((0x00, 0x00, 0x00, 0x01)), 5.147557589468029e-85)
|
||||
self.assertEqual(ibm2ieee(byte_string((0x00, 0x00, 0x00, 0x01))), 5.147557589468029e-85)
|
||||
|
||||
|
||||
class Ieee2Ibm(unittest.TestCase):
|
||||
@@ -56,28 +57,28 @@ class Ieee2Ibm(unittest.TestCase):
|
||||
self.assertEqual(ieee2ibm(0.0), b'\0\0\0\0')
|
||||
|
||||
def test_positive_half(self):
|
||||
self.assertEqual(ieee2ibm(-0.5), bytes((0b11000000, 0x80, 0x00, 0x00)))
|
||||
self.assertEqual(ieee2ibm(-0.5), byte_string((0b11000000, 0x80, 0x00, 0x00)))
|
||||
|
||||
def test_negative_half(self):
|
||||
self.assertEqual(ieee2ibm(0.5), bytes((0b01000000, 0x80, 0x00, 0x00)))
|
||||
self.assertEqual(ieee2ibm(0.5), byte_string((0b01000000, 0x80, 0x00, 0x00)))
|
||||
|
||||
def test_one(self):
|
||||
self.assertEqual(ieee2ibm(1.0), b'\x41\x10\x00\x00')
|
||||
|
||||
def test_negative_118_625(self):
|
||||
# Example taken from Wikipedia http://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture
|
||||
self.assertEqual(ieee2ibm(-118.625), bytes((0b11000010, 0b01110110, 0b10100000, 0b00000000)))
|
||||
self.assertEqual(ieee2ibm(-118.625), byte_string((0b11000010, 0b01110110, 0b10100000, 0b00000000)))
|
||||
|
||||
def test_0_1(self):
|
||||
# Note, this is different from the Wikipedia example, because the Wikipedia example does
|
||||
# round to nearest, and our routine does round to zero
|
||||
self.assertEqual(ieee2ibm(0.1), bytes((0b01000000, 0b00011001, 0b10011001, 0b10011001)))
|
||||
self.assertEqual(ieee2ibm(0.1), byte_string((0b01000000, 0b00011001, 0b10011001, 0b10011001)))
|
||||
|
||||
def test_subnormal(self):
|
||||
self.assertEqual(ieee2ibm(1.6472184286297693e-83), bytes((0x00, 0x00, 0x00, 0x20)))
|
||||
self.assertEqual(ieee2ibm(1.6472184286297693e-83), byte_string((0x00, 0x00, 0x00, 0x20)))
|
||||
|
||||
def test_smallest_subnormal(self):
|
||||
self.assertEqual(ieee2ibm(5.147557589468029e-85), bytes((0x00, 0x00, 0x00, 0x01)))
|
||||
self.assertEqual(ieee2ibm(5.147557589468029e-85), byte_string((0x00, 0x00, 0x00, 0x01)))
|
||||
|
||||
def test_too_small_subnormal(self):
|
||||
with self.assertRaises(FloatingPointError):
|
||||
@@ -109,13 +110,13 @@ class Ibm2IeeeRoundtrip(unittest.TestCase):
|
||||
self.assertEqual(ibm_start, ibm_result)
|
||||
|
||||
def test_positive_half(self):
|
||||
ibm_start = bytes((0b11000000, 0x80, 0x00, 0x00))
|
||||
ibm_start = byte_string((0b11000000, 0x80, 0x00, 0x00))
|
||||
f = ibm2ieee(ibm_start)
|
||||
ibm_result = ieee2ibm(f)
|
||||
self.assertEqual(ibm_start, ibm_result)
|
||||
|
||||
def test_negative_half(self):
|
||||
ibm_start = bytes((0b01000000, 0x80, 0x00, 0x00))
|
||||
ibm_start = byte_string((0b01000000, 0x80, 0x00, 0x00))
|
||||
f = ibm2ieee(ibm_start)
|
||||
ibm_result = ieee2ibm(f)
|
||||
self.assertEqual(ibm_start, ibm_result)
|
||||
@@ -127,7 +128,7 @@ class Ibm2IeeeRoundtrip(unittest.TestCase):
|
||||
self.assertEqual(ibm_start, ibm_result)
|
||||
|
||||
def test_subnormal(self):
|
||||
ibm_start = bytes((0x00, 0x00, 0x00, 0x20))
|
||||
ibm_start = byte_string((0x00, 0x00, 0x00, 0x20))
|
||||
f = ibm2ieee(ibm_start)
|
||||
ibm_result = ieee2ibm(f)
|
||||
self.assertEqual(ibm_start, ibm_result)
|
||||
|
||||
Reference in New Issue
Block a user