├── .gitignore
├── LICENSE
├── LICENSE.txt
├── MANIFEST.in
├── Pipfile
├── Pipfile.lock
├── PyOSGPUP.egg-info
├── PKG-INFO
├── SOURCES.txt
├── dependency_links.txt
├── requires.txt
└── top_level.txt
├── PyOSGPUP
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-36.pyc
│ ├── segypy.cpython-36.pyc
│ ├── signal.cpython-36.pyc
│ ├── signalpy.cpython-36.pyc
│ ├── tuning_wedge_acces.cpython-36.pyc
│ └── wavelet.cpython-36.pyc
├── segypy.py
├── signalpy.py
├── synthe_seismo.py
├── tuning_wedge_acces.py
└── wavelet.py
├── README.md
├── README.rst
├── build
└── lib
│ ├── PyOSGPUP
│ ├── __init__.py
│ ├── segypy.py
│ ├── signalpy.py
│ ├── synthe_seismo.py
│ ├── tuning_wedge_acces.py
│ └── wavelet.py
│ └── sample
│ ├── __init__.py
│ └── package_data.dat
├── dist
└── PyOSGPUP-1.0.3-py3-none-any.whl
├── example
├── readsegy.png
├── seis1.png
├── seis2.png
├── seis3.png
└── wavelet.png
├── requirements.txt
├── setup.cfg
├── setup.py
└── tox.ini
/.gitignore:
--------------------------------------------------------------------------------
1 | # Python:
2 | ## Byte-compiled / optimized / DLL files
3 | __pycache__/
4 | *.py[cod]
5 | *$py.class
6 |
7 | ## C extensions
8 | *.so
9 |
10 | ## PyInstaller
11 | *.manifest
12 | *.spec
13 |
14 | ## Installer logs
15 | pip-log.txt
16 | pip-delete-this-directory.txt
17 |
18 | ## Unit test / coverage reports
19 | htmlcov/
20 | .tox/
21 | .coverage
22 | .coverage.*
23 | .cache
24 | nosetests.xml
25 | coverage.xml
26 | *.cover
27 | .hypothesis/
28 |
29 | ## Sphinx documentation
30 | docs/_build/
31 |
32 | ## dotenv
33 | .env
34 |
35 | ## virtualenv
36 | .venv
37 | venv/
38 | ENV/
39 |
40 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Komputasi Geofisika
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 The Python Packaging Authority (PyPA)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7 | of the Software, and to permit persons to whom the Software is furnished to do
8 | so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | # Include the license file
2 | include LICENSE.txt
3 |
4 | # Include the data files
5 | recursive-include data *
6 |
--------------------------------------------------------------------------------
/Pipfile:
--------------------------------------------------------------------------------
1 | [[source]]
2 |
3 | url = "https://pypi.python.org/simple"
4 | verify_ssl = true
5 | name = "pypi"
6 |
7 |
8 | [packages]
9 |
10 | requests = "*"
11 |
12 |
13 | [dev-packages]
14 |
15 |
16 |
17 | [requires]
18 |
19 | python_version = "3.6"
20 |
--------------------------------------------------------------------------------
/Pipfile.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_meta": {
3 | "hash": {
4 | "sha256": "33a0ec7c8e3bae6f62dd618f847de92ece20e2bd4efb496927e2524b9c7b8df8"
5 | },
6 | "pipfile-spec": 6,
7 | "requires": {
8 | "python_version": "3.6"
9 | },
10 | "sources": [
11 | {
12 | "name": "pypi",
13 | "url": "https://pypi.python.org/simple",
14 | "verify_ssl": true
15 | }
16 | ]
17 | },
18 | "default": {
19 | "certifi": {
20 | "hashes": [
21 | "sha256:14131608ad2fd56836d33a71ee60fa1c82bc9d2c8d98b7bdbc631fe1b3cd1296",
22 | "sha256:edbc3f203427eef571f79a7692bb160a2b0f7ccaa31953e99bd17e307cf63f7d"
23 | ],
24 | "version": "==2018.1.18"
25 | },
26 | "chardet": {
27 | "hashes": [
28 | "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
29 | "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
30 | ],
31 | "version": "==3.0.4"
32 | },
33 | "idna": {
34 | "hashes": [
35 | "sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f",
36 | "sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4"
37 | ],
38 | "version": "==2.6"
39 | },
40 | "requests": {
41 | "hashes": [
42 | "sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b",
43 | "sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e"
44 | ],
45 | "version": "==2.18.4"
46 | },
47 | "urllib3": {
48 | "hashes": [
49 | "sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b",
50 | "sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f"
51 | ],
52 | "version": "==1.22"
53 | }
54 | },
55 | "develop": {}
56 | }
57 |
--------------------------------------------------------------------------------
/PyOSGPUP.egg-info/PKG-INFO:
--------------------------------------------------------------------------------
1 | Metadata-Version: 1.2
2 | Name: PyOSGPUP
3 | Version: 1.0.3
4 | Summary: An open-source library for geophysical data processing, modeling, and interpretation based on Python.
5 | Home-page: https://sites.google.com/site/metkomup/
6 | Author: Komputasi Geofisika - Universitas Pertamina
7 | Author-email: metkom.up@gmail.com
8 | License: UNKNOWN
9 | Project-URL: Bug Reports, https://github.com/Metkom/PyOSGPUP/issues
10 | Project-URL: Say Thanks!, https://sites.google.com/site/metkomup/pyosgpup
11 | Project-URL: Source, https://github.com/Metkom/PyOSGPUP
12 | Description-Content-Type: UNKNOWN
13 | Description: PyOSGPUP: Python, Open-source
14 | =============================
15 |
16 | PuOSGPUP: Python Library that is Open-source created by
17 | Geophysical Engineering, Universitas Pertamina
18 |
19 | A python packages for geophysical data processing, modeling, and interpretation.
20 |
21 | Teknik Geofisika, Universitas Pertamina
22 | Jl. Teuku Nyak Arief, Simprug, South Jakarta, DKI Jakarta, Indonesia, 12220.
23 | email: metkom.up@gmail.com
24 | Keywords: geophysical data processing,modeling,and interpretation
25 | Platform: Windows
26 | Platform: Linux
27 | Platform: Mac OS-X
28 | Classifier: Development Status :: 3 - Alpha
29 | Classifier: Intended Audience :: Developers
30 | Classifier: Topic :: Software Development :: Build Tools
31 | Classifier: License :: OSI Approved :: MIT License
32 | Classifier: Programming Language :: Python :: 3.4
33 | Classifier: Programming Language :: Python :: 3.5
34 | Classifier: Programming Language :: Python :: 3.6
35 |
--------------------------------------------------------------------------------
/PyOSGPUP.egg-info/SOURCES.txt:
--------------------------------------------------------------------------------
1 | LICENSE.txt
2 | MANIFEST.in
3 | README.rst
4 | setup.cfg
5 | setup.py
6 | PyOSGPUP/__init__.py
7 | PyOSGPUP/segypy.py
8 | PyOSGPUP/signalpy.py
9 | PyOSGPUP/synthe_seismo.py
10 | PyOSGPUP/tuning_wedge_acces.py
11 | PyOSGPUP/wavelet.py
12 | PyOSGPUP.egg-info/PKG-INFO
13 | PyOSGPUP.egg-info/SOURCES.txt
14 | PyOSGPUP.egg-info/dependency_links.txt
15 | PyOSGPUP.egg-info/requires.txt
16 | PyOSGPUP.egg-info/top_level.txt
--------------------------------------------------------------------------------
/PyOSGPUP.egg-info/dependency_links.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/PyOSGPUP.egg-info/requires.txt:
--------------------------------------------------------------------------------
1 | numpy
2 | matplotlib
3 |
--------------------------------------------------------------------------------
/PyOSGPUP.egg-info/top_level.txt:
--------------------------------------------------------------------------------
1 | PyOSGPUP
2 |
--------------------------------------------------------------------------------
/PyOSGPUP/__init__.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 |
3 | from PyOSGPUP import wavelet
4 | from PyOSGPUP import segypy
5 | from PyOSGPUP import tuning_wedge_acces
6 | from PyOSGPUP import signalpy
7 |
8 | __version__ = '1.0.3'
9 | __author__ = 'PyOSGPUP Team'
10 | __license__ = 'MIT'
11 | __copyright__ = '2018, PyOSGPUP Team, https://sites.google.com/site/metkomup/pyosgpup'
12 |
--------------------------------------------------------------------------------
/PyOSGPUP/__pycache__/__init__.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Metkom/PyOSGPUP/93b2e153b3dd4e1f644a704a0d7c62ca3bda8f26/PyOSGPUP/__pycache__/__init__.cpython-36.pyc
--------------------------------------------------------------------------------
/PyOSGPUP/__pycache__/segypy.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Metkom/PyOSGPUP/93b2e153b3dd4e1f644a704a0d7c62ca3bda8f26/PyOSGPUP/__pycache__/segypy.cpython-36.pyc
--------------------------------------------------------------------------------
/PyOSGPUP/__pycache__/signal.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Metkom/PyOSGPUP/93b2e153b3dd4e1f644a704a0d7c62ca3bda8f26/PyOSGPUP/__pycache__/signal.cpython-36.pyc
--------------------------------------------------------------------------------
/PyOSGPUP/__pycache__/signalpy.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Metkom/PyOSGPUP/93b2e153b3dd4e1f644a704a0d7c62ca3bda8f26/PyOSGPUP/__pycache__/signalpy.cpython-36.pyc
--------------------------------------------------------------------------------
/PyOSGPUP/__pycache__/tuning_wedge_acces.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Metkom/PyOSGPUP/93b2e153b3dd4e1f644a704a0d7c62ca3bda8f26/PyOSGPUP/__pycache__/tuning_wedge_acces.cpython-36.pyc
--------------------------------------------------------------------------------
/PyOSGPUP/__pycache__/wavelet.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Metkom/PyOSGPUP/93b2e153b3dd4e1f644a704a0d7c62ca3bda8f26/PyOSGPUP/__pycache__/wavelet.cpython-36.pyc
--------------------------------------------------------------------------------
/PyOSGPUP/segypy.py:
--------------------------------------------------------------------------------
1 | """
2 | A python module for reading/writing/manipuating
3 | SEG-Y formatted filed
4 |
5 | segy.readSegy : Read SEGY file
6 | segy.getSegyHeader : Get SEGY header
7 | segy.getSegyTraceHeader : Get SEGY Trace header
8 | segy.getAllSegyTraceHeaders : Get all SEGY Trace headers
9 | segy.getSegyTrace : Get SEGY Trace heder and trace data for one trace
10 |
11 | segy.writeSegy : Write a data to a SEGY file
12 | segy.writeSegyStructure : Writes a segypy data structure to a SEGY file
13 |
14 | segy.getValue : Get a value from a binary string
15 | segy.ibm2ieee : Convert IBM floats to IEEE
16 |
17 | segy.version : The version of SegyPY
18 | segy.verbose : Amount of verbose information to the screen
19 | """
20 | #
21 | # segypy : A Python module for reading and writing SEG-Y formatted data
22 | #
23 | # (C) Thomas Mejer Hansen, 2005-2016
24 | #
25 | # contributions from
26 | # - Pete Forman
27 | #
28 | # modified by Andrew Squelch 2007 : sub-version 0.3.1
29 | from __future__ import division
30 | from __future__ import print_function
31 |
32 | import struct, sys # modified by A Squelch
33 |
34 | import numpy as np
35 |
36 |
37 | # SOME GLOBAL PARAMETERS
38 | version = '0.3.1' # modified by A Squelch
39 | verbose = 1;
40 |
41 | # endian='>' # Big Endian # modified by A Squelch
42 | # endian='<' # Little Endian
43 | # endian='=' # Native
44 |
45 | l_int = struct.calcsize('i')
46 | l_uint = struct.calcsize('I')
47 | l_long = 4;
48 | # Next line gives wrong result on Linux!! (gives 8 instead of 4)
49 | # l_long = struct.calcsize('l')
50 | l_ulong = struct.calcsize('L')
51 | l_short = struct.calcsize('h')
52 | l_ushort = struct.calcsize('H')
53 | l_char = struct.calcsize('c')
54 | l_uchar = struct.calcsize('B')
55 | l_float = struct.calcsize('f')
56 |
57 | ##############
58 | # INIT
59 |
60 | ##############
61 | # %% Initialize SEGY HEADER
62 | SH_def = {"Job": {"pos": 3200, "type": "int32", "def": 0}}
63 | SH_def["Line"] = {"pos": 3204, "type": "int32", "def": 0}
64 | SH_def["Reel"] = {"pos": 3208, "type": "int32", "def": 0}
65 | SH_def["DataTracePerEnsemble"] = {"pos": 3212, "type": "int16", "def": 0}
66 | SH_def["AuxiliaryTracePerEnsemble"] = {"pos": 3214, "type": "int16", "def": 0}
67 | SH_def["dt"] = {"pos": 3216, "type": "uint16", "def": 1000}
68 | SH_def["dtOrig"] = {"pos": 3218, "type": "uint16", "def": 1000}
69 | SH_def["ns"] = {"pos": 3220, "type": "uint16", "def": 0}
70 | SH_def["nsOrig"] = {"pos": 3222, "type": "uint16", "def": 0}
71 | SH_def["DataSampleFormat"] = {"pos": 3224, "type": "int16", "def": 5}
72 | SH_def["DataSampleFormat"]["descr"] = {0: {
73 | 1: "IBM Float",
74 | 2: "32 bit Integer",
75 | 3: "16 bit Integer",
76 | 8: "8 bit Integer"}}
77 |
78 | SH_def["DataSampleFormat"]["descr"][1] = {
79 | 1: "IBM Float",
80 | 2: "32 bit Integer",
81 | 3: "16 bit Integer",
82 | 5: "IEEE",
83 | 8: "8 bit Integer"}
84 |
85 | SH_def["DataSampleFormat"]["bps"] = {0: {
86 | 1: 4,
87 | 2: 4,
88 | 3: 2,
89 | 8: 1}}
90 | SH_def["DataSampleFormat"]["bps"][1] = {
91 | 1: 4,
92 | 2: 4,
93 | 3: 2,
94 | 5: 4,
95 | 8: 1}
96 | SH_def["DataSampleFormat"]["datatype"] = {0: {
97 | 1: 'ibm',
98 | 2: 'l',
99 | 3: 'h',
100 | 8: 'B'}}
101 | SH_def["DataSampleFormat"]["datatype"][1] = {
102 | 1: 'ibm',
103 | 2: 'l',
104 | 3: 'h',
105 | # 5: 'float',
106 | 5: 'f',
107 | 8: 'B'}
108 |
109 | SH_def["EnsembleFold"] = {"pos": 3226, "type": "int16", "def": 0}
110 | SH_def["TraceSorting"] = {"pos": 3228, "type": "int16", "def": 0}
111 | SH_def["VerticalSumCode"] = {"pos": 3230, "type": "int16", "def": 0}
112 | SH_def["SweepFrequencyEnd"] = {"pos": 3234, "type": "int16", "def": 0}
113 | SH_def["SweepLength"] = {"pos": 3236, "type": "int16", "def": 0}
114 | SH_def["SweepType"] = {"pos": 3238, "type": "int16", "def": 0}
115 | SH_def["SweepChannel"] = {"pos": 3240, "type": "int16", "def": 0}
116 | SH_def["SweepTaperlengthStart"] = {"pos": 3242, "type": "int16", "def": 0}
117 | SH_def["SweepTaperLengthEnd"] = {"pos": 3244, "type": "int16", "def": 0}
118 | SH_def["TaperType"] = {"pos": 3246, "type": "int16", "def": 0}
119 | SH_def["CorrelatedDataTraces"] = {"pos": 3248, "type": "int16", "def": 0}
120 | SH_def["BinaryGain"] = {"pos": 3250, "type": "int16", "def": 0}
121 | SH_def["AmplitudeRecoveryMethod"] = {"pos": 3252, "type": "int16", "def": 0}
122 | SH_def["MeasurementSystem"] = {"pos": 3254, "type": "int16", "def": 0}
123 | SH_def["ImpulseSignalPolarity"] = {"pos": 3256, "type": "int16", "def": 0}
124 | SH_def["VibratoryPolarityCode"] = {"pos": 3258, "type": "int16", "def": 0}
125 | SH_def["Unassigned1"] = {"pos": 3260, "type": "int16", "n": 120, "def": 0}
126 | SH_def["SegyFormatRevisionNumber"] = {"pos": 3500, "type": "uint16", "def": 100}
127 | SH_def["FixedLengthTraceFlag"] = {"pos": 3502, "type": "uint16", "def": 0}
128 | SH_def["NumberOfExtTextualHeaders"] = {"pos": 3504, "type": "uint16", "def": 0}
129 | SH_def["Unassigned2"] = {"pos": 3506, "type": "int16", "n": 47, "def": 0}
130 |
131 | ##############
132 | # %% Initialize SEGY TRACE HEADER SPECIFICATION
133 | STH_def = {"TraceSequenceLine": {"pos": 0, "type": "int32"}}
134 | STH_def["TraceSequenceFile"] = {"pos": 4, "type": "int32"}
135 | STH_def["FieldRecord"] = {"pos": 8, "type": "int32"}
136 | STH_def["TraceNumber"] = {"pos": 12, "type": "int32"}
137 | STH_def["EnergySourcePoint"] = {"pos": 16, "type": "int32"}
138 | STH_def["cdp"] = {"pos": 20, "type": "int32"}
139 | STH_def["cdpTrace"] = {"pos": 24, "type": "int32"}
140 | STH_def["TraceIdenitifactionCode"] = {"pos": 28, "type": "uint16"} # 'int16'); % 28
141 | STH_def["TraceIdenitifactionCode"]["descr"] = {0: {
142 | 1: "Seismic data",
143 | 2: "Dead",
144 | 3: "Dummy",
145 | 4: "Time Break",
146 | 5: "Uphole",
147 | 6: "Sweep",
148 | 7: "Timing",
149 | 8: "Water Break"}}
150 | STH_def["TraceIdenitifactionCode"]["descr"][1] = {
151 | -1: "Other",
152 | 0: "Unknown",
153 | 1: "Seismic data",
154 | 2: "Dead",
155 | 3: "Dummy",
156 | 4: "Time break",
157 | 5: "Uphole",
158 | 6: "Sweep",
159 | 7: "Timing",
160 | 8: "Waterbreak",
161 | 9: "Near-field gun signature",
162 | 10: "Far-field gun signature",
163 | 11: "Seismic pressure sensor",
164 | 12: "Multicomponent seismic sensor - Vertical component",
165 | 13: "Multicomponent seismic sensor - Cross-line component",
166 | 14: "Multicomponent seismic sensor - In-line component",
167 | 15: "Rotated multicomponent seismic sensor - Vertical component",
168 | 16: "Rotated multicomponent seismic sensor - Transverse component",
169 | 17: "Rotated multicomponent seismic sensor - Radial component",
170 | 18: "Vibrator reaction mass",
171 | 19: "Vibrator baseplate",
172 | 20: "Vibrator estimated ground force",
173 | 21: "Vibrator reference",
174 | 22: "Time-velocity pairs"}
175 | STH_def["NSummedTraces"] = {"pos": 30, "type": "int16"} # 'int16'); % 30
176 | STH_def["NStackedTraces"] = {"pos": 32, "type": "int16"} # 'int16'); % 32
177 | STH_def["DataUse"] = {"pos": 34, "type": "int16"} # 'int16'); % 34
178 | STH_def["DataUse"]["descr"] = {0: {
179 | 1: "Production",
180 | 2: "Test"}}
181 | STH_def["DataUse"]["descr"][1] = STH_def["DataUse"]["descr"][0]
182 | STH_def["offset"] = {"pos": 36, "type": "int32"} # 'int32'); %36
183 | STH_def["ReceiverGroupElevation"] = {"pos": 40, "type": "int32"} # 'int32'); %40
184 | STH_def["SourceSurfaceElevation"] = {"pos": 44, "type": "int32"} # 'int32'); %44
185 | STH_def["SourceDepth"] = {"pos": 48, "type": "int32"} # 'int32'); %48
186 | STH_def["ReceiverDatumElevation"] = {"pos": 52, "type": "int32"} # 'int32'); %52
187 | STH_def["SourceDatumElevation"] = {"pos": 56, "type": "int32"} # 'int32'); %56
188 | STH_def["SourceWaterDepth"] = {"pos": 60, "type": "int32"} # 'int32'); %60
189 | STH_def["GroupWaterDepth"] = {"pos": 64, "type": "int32"} # 'int32'); %64
190 | STH_def["ElevationScalar"] = {"pos": 68, "type": "int16"} # 'int16'); %68
191 | STH_def["SourceGroupScalar"] = {"pos": 70, "type": "int16"} # 'int16'); %70
192 | STH_def["SourceX"] = {"pos": 72, "type": "int32"} # 'int32'); %72
193 | STH_def["SourceY"] = {"pos": 76, "type": "int32"} # 'int32'); %76
194 | STH_def["GroupX"] = {"pos": 80, "type": "int32"} # 'int32'); %80
195 | STH_def["GroupY"] = {"pos": 84, "type": "int32"} # 'int32'); %84
196 | STH_def["CoordinateUnits"] = {"pos": 88, "type": "int16"} # 'int16'); %88
197 | STH_def["CoordinateUnits"]["descr"] = {1: {
198 | 1: "Length (meters or feet)",
199 | 2: "Seconds of arc"}}
200 | STH_def["CoordinateUnits"]["descr"][1] = {
201 | 1: "Length (meters or feet)",
202 | 2: "Seconds of arc",
203 | 3: "Decimal degrees",
204 | 4: "Degrees, minutes, seconds (DMS)"}
205 | STH_def["WeatheringVelocity"] = {"pos": 90, "type": "int16"} # 'int16'); %90
206 | STH_def["SubWeatheringVelocity"] = {"pos": 92, "type": "int16"} # 'int16'); %92
207 | STH_def["SourceUpholeTime"] = {"pos": 94, "type": "int16"} # 'int16'); %94
208 | STH_def["GroupUpholeTime"] = {"pos": 96, "type": "int16"} # 'int16'); %96
209 | STH_def["SourceStaticCorrection"] = {"pos": 98, "type": "int16"} # 'int16'); %98
210 | STH_def["GroupStaticCorrection"] = {"pos": 100, "type": "int16"} # 'int16'); %100
211 | STH_def["TotalStaticApplied"] = {"pos": 102, "type": "int16"} # 'int16'); %102
212 | STH_def["LagTimeA"] = {"pos": 104, "type": "int16"} # 'int16'); %104
213 | STH_def["LagTimeB"] = {"pos": 106, "type": "int16"} # 'int16'); %106
214 | STH_def["DelayRecordingTime"] = {"pos": 108, "type": "int16"} # 'int16'); %108
215 | STH_def["MuteTimeStart"] = {"pos": 110, "type": "int16"} # 'int16'); %110
216 | STH_def["MuteTimeEND"] = {"pos": 112, "type": "int16"} # 'int16'); %112
217 | STH_def["ns"] = {"pos": 114, "type": "uint16"} # 'uint16'); %114
218 | STH_def["dt"] = {"pos": 116, "type": "uint16"} # 'uint16'); %116
219 | STH_def["GainType"] = {"pos": 119, "type": "int16"} # 'int16'); %118
220 | STH_def["GainType"]["descr"] = {0: {
221 | 1: "Fixes",
222 | 2: "Binary",
223 | 3: "Floating point"}}
224 | STH_def["GainType"]["descr"][1] = STH_def["GainType"]["descr"][0]
225 | STH_def["InstrumentGainConstant"] = {"pos": 120, "type": "int16"} # 'int16'); %120
226 | STH_def["InstrumentInitialGain"] = {"pos": 122, "type": "int16"} # 'int16'); %%122
227 | STH_def["Correlated"] = {"pos": 124, "type": "int16"} # 'int16'); %124
228 | STH_def["Correlated"]["descr"] = {0: {
229 | 1: "No",
230 | 2: "Yes"}}
231 | STH_def["Correlated"]["descr"][1] = STH_def["Correlated"]["descr"][0]
232 |
233 | STH_def["SweepFrequenceStart"] = {"pos": 126, "type": "int16"} # 'int16'); %126
234 | STH_def["SweepFrequenceEnd"] = {"pos": 128, "type": "int16"} # 'int16'); %128
235 | STH_def["SweepLength"] = {"pos": 130, "type": "int16"} # 'int16'); %130
236 | STH_def["SweepType"] = {"pos": 132, "type": "int16"} # 'int16'); %132
237 | STH_def["SweepType"]["descr"] = {0: {
238 | 1: "linear",
239 | 2: "parabolic",
240 | 3: "exponential",
241 | 4: "other"}}
242 | STH_def["SweepType"]["descr"][1] = STH_def["SweepType"]["descr"][0]
243 |
244 | STH_def["SweepTraceTaperLengthStart"] = {"pos": 134, "type": "int16"} # 'int16'); %134
245 | STH_def["SweepTraceTaperLengthEnd"] = {"pos": 136, "type": "int16"} # 'int16'); %136
246 | STH_def["TaperType"] = {"pos": 138, "type": "int16"} # 'int16'); %138
247 | STH_def["TaperType"]["descr"] = {0: {
248 | 1: "linear",
249 | 2: "cos2c",
250 | 3: "other"}}
251 | STH_def["TaperType"]["descr"][1] = STH_def["TaperType"]["descr"][0]
252 |
253 | STH_def["AliasFilterFrequency"] = {"pos": 140, "type": "int16"} # 'int16'); %140
254 | STH_def["AliasFilterSlope"] = {"pos": 142, "type": "int16"} # 'int16'); %142
255 | STH_def["NotchFilterFrequency"] = {"pos": 144, "type": "int16"} # 'int16'); %144
256 | STH_def["NotchFilterSlope"] = {"pos": 146, "type": "int16"} # 'int16'); %146
257 | STH_def["LowCutFrequency"] = {"pos": 148, "type": "int16"} # 'int16'); %148
258 | STH_def["HighCutFrequency"] = {"pos": 150, "type": "int16"} # 'int16'); %150
259 | STH_def["LowCutSlope"] = {"pos": 152, "type": "int16"} # 'int16'); %152
260 | STH_def["HighCutSlope"] = {"pos": 154, "type": "int16"} # 'int16'); %154
261 | STH_def["YearDataRecorded"] = {"pos": 156, "type": "int16"} # 'int16'); %156
262 | STH_def["DayOfYear"] = {"pos": 158, "type": "int16"} # 'int16'); %158
263 | STH_def["HourOfDay"] = {"pos": 160, "type": "int16"} # 'int16'); %160
264 | STH_def["MinuteOfHour"] = {"pos": 162, "type": "int16"} # 'int16'); %162
265 | STH_def["SecondOfMinute"] = {"pos": 164, "type": "int16"} # 'int16'); %164
266 | STH_def["TimeBaseCode"] = {"pos": 166, "type": "int16"} # 'int16'); %166
267 | STH_def["TimeBaseCode"]["descr"] = {0: {
268 | 1: "Local",
269 | 2: "GMT",
270 | 3: "Other"}}
271 | STH_def["TimeBaseCode"]["descr"][1] = {
272 | 1: "Local",
273 | 2: "GMT",
274 | 3: "Other",
275 | 4: "UTC"}
276 | STH_def["TraceWeightningFactor"] = {"pos": 168, "type": "int16"} # 'int16'); %170
277 | STH_def["GeophoneGroupNumberRoll1"] = {"pos": 170, "type": "int16"} # 'int16'); %172
278 | STH_def["GeophoneGroupNumberFirstTraceOrigField"] = {"pos": 172, "type": "int16"} # 'int16'); %174
279 | STH_def["GeophoneGroupNumberLastTraceOrigField"] = {"pos": 174, "type": "int16"} # 'int16'); %176
280 | STH_def["GapSize"] = {"pos": 176, "type": "int16"} # 'int16'); %178
281 | STH_def["OverTravel"] = {"pos": 178, "type": "int16"} # 'int16'); %178
282 | STH_def["OverTravel"]["descr"] = {0: {
283 | 1: "down (or behind)",
284 | 2: "up (or ahead)",
285 | 3: "other"}}
286 | STH_def["OverTravel"]["descr"][1] = STH_def["OverTravel"]["descr"][0]
287 |
288 | STH_def["cdpX"] = {"pos": 180, "type": "int32"} # 'int32'); %180
289 | STH_def["cdpY"] = {"pos": 184, "type": "int32"} # 'int32'); %184
290 | STH_def["Inline3D"] = {"pos": 188, "type": "int32"} # 'int32'); %188
291 | STH_def["Crossline3D"] = {"pos": 192, "type": "int32"} # 'int32'); %192
292 | STH_def["ShotPoint"] = {"pos": 192, "type": "int32"} # 'int32'); %196
293 | STH_def["ShotPointScalar"] = {"pos": 200, "type": "int16"} # 'int16'); %200
294 | STH_def["TraceValueMeasurementUnit"] = {"pos": 202, "type": "int16"} # 'int16'); %202
295 | STH_def["TraceValueMeasurementUnit"]["descr"] = {1: {
296 | -1: "Other",
297 | 0: "Unknown (should be described in Data Sample Measurement Units Stanza) ",
298 | 1: "Pascal (Pa)",
299 | 2: "Volts (V)",
300 | 3: "Millivolts (v)",
301 | 4: "Amperes (A)",
302 | 5: "Meters (m)",
303 | 6: "Meters Per Second (m/s)",
304 | 7: "Meters Per Second squared (m/&s2)Other",
305 | 8: "Newton (N)",
306 | 9: "Watt (W)"}}
307 | STH_def["TransductionConstantMantissa"] = {"pos": 204, "type": "int32"} # 'int32'); %204
308 | STH_def["TransductionConstantPower"] = {"pos": 208, "type": "int16"} # 'int16'); %208
309 | STH_def["TransductionUnit"] = {"pos": 210, "type": "int16"} # 'int16'); %210
310 | STH_def["TransductionUnit"]["descr"] = STH_def["TraceValueMeasurementUnit"]["descr"]
311 | STH_def["TraceIdentifier"] = {"pos": 212, "type": "int16"} # 'int16'); %212
312 | STH_def["ScalarTraceHeader"] = {"pos": 214, "type": "int16"} # 'int16'); %214
313 | STH_def["SourceType"] = {"pos": 216, "type": "int16"} # 'int16'); %216
314 | STH_def["SourceType"]["descr"] = {1: {
315 | -1: "Other (should be described in Source Type/Orientation stanza)",
316 | 0: "Unknown",
317 | 1: "Vibratory - Vertical orientation",
318 | 2: "Vibratory - Cross-line orientation",
319 | 3: "Vibratory - In-line orientation",
320 | 4: "Impulsive - Vertical orientation",
321 | 5: "Impulsive - Cross-line orientation",
322 | 6: "Impulsive - In-line orientation",
323 | 7: "Distributed Impulsive - Vertical orientation",
324 | 8: "Distributed Impulsive - Cross-line orientation",
325 | 9: "Distributed Impulsive - In-line orientation"}}
326 |
327 | STH_def["SourceEnergyDirectionMantissa"] = {"pos": 218, "type": "int32"} # 'int32'); %218
328 | STH_def["SourceEnergyDirectionExponent"] = {"pos": 222, "type": "int16"} # 'int16'); %222
329 | STH_def["SourceMeasurementMantissa"] = {"pos": 224, "type": "int32"} # 'int32'); %224
330 | STH_def["SourceMeasurementExponent"] = {"pos": 228, "type": "int16"} # 'int16'); %228
331 | STH_def["SourceMeasurementUnit"] = {"pos": 230, "type": "int16"} # 'int16'); %230
332 | STH_def["SourceMeasurementUnit"]["descr"] = {1: {
333 | -1: "Other (should be described in Source Measurement Unit stanza)",
334 | 0: "Unknown",
335 | 1: "Joule (J)",
336 | 2: "Kilowatt (kW)",
337 | 3: "Pascal (Pa)",
338 | 4: "Bar (Bar)",
339 | 4: "Bar-meter (Bar-m)",
340 | 5: "Newton (N)",
341 | 6: "Kilograms (kg)"}}
342 | STH_def["UnassignedInt1"] = {"pos": 232, "type": "int32"} # 'int32'); %232
343 | STH_def["UnassignedInt2"] = {"pos": 236, "type": "int32"} # 'int32'); %236
344 |
345 |
346 | ##############
347 | # %% FUNCTIONS
348 |
349 | def image(Data, SH={}, maxval=-1):
350 | """
351 | image(Data,SH,maxval)
352 | Image segy Data
353 | """
354 | import matplotlib.pylab as plt
355 |
356 | if (maxval<=0):
357 | Dmax = np.max(Data)
358 | maxval = -1*maxval*Dmax
359 |
360 | if 'time' in SH:
361 | t = SH['time']
362 | ntraces = SH['ntraces']
363 | ns = SH['ns']
364 | else:
365 | ns = Data.shape[0]
366 | t = np.arange(ns)
367 | ntraces = Data.shape[1]
368 | x = np.arange(ntraces)+1
369 |
370 | print(maxval)
371 | plt.pcolor(x, t, Data, vmin=-1*maxval, vmax=maxval)
372 | plt.colorbar()
373 | plt.axis('normal')
374 | plt.xlabel('Trace number')
375 | if 'time' in SH:
376 | plt.ylabel('Time (ms)')
377 | else:
378 | plt.ylabel('Sample number')
379 | if 'filename' in SH:
380 | plt.title(SH['filename'])
381 | plt.gca().invert_yaxis()
382 |
383 | #plt.grid(True)
384 | plt.show()
385 |
386 |
387 | # %%
388 | def wiggle(Data, SH={}, maxval=-1, skipt=1, lwidth=.1):
389 | """
390 | wiggle(Data,SH)
391 | """
392 | import matplotlib.pylab as plt
393 | import numpy as np
394 |
395 | if 'time' in SH:
396 | t = SH['time']
397 | ntraces = SH['ntraces']
398 | ns = SH['ns']
399 | else:
400 | ns=Data.shape[0]
401 | t=np.arange(ns)
402 | ntraces = Data.shape[1]
403 |
404 |
405 | if (maxval<=0):
406 | Dmax = np.max(Data)
407 | maxval = -1*maxval*Dmax
408 |
409 | for i in range(0, ntraces, skipt):
410 | trace = Data[:, i]
411 | trace[0] = 0
412 | trace[ns - 1] = 0
413 | plt.plot(i + trace / maxval, t, color='black', linewidth=lwidth)
414 | for a in range(len(trace)):
415 | if (trace[a] < 0):
416 | trace[a] = 0;
417 | # pylab.fill(i+Data[:,i]/maxval,t,color='k',facecolor='g')
418 | plt.fill(i + Data[:, i] / maxval, t, 'k', linewidth=0)
419 |
420 | plt.grid(True)
421 | plt.gca().invert_yaxis()
422 |
423 | plt.xlabel('Trace number')
424 | if 'time' in SH:
425 | plt.ylabel('Time (ms)')
426 | else:
427 | plt.ylabel('Sample number')
428 | if 'filename' in SH:
429 | plt.title(SH['filename'])
430 | plt.axes().set_xlim(-1, ntraces)
431 | plt.show()
432 |
433 |
434 | # %%
435 | def getDefaultSegyHeader(ntraces=100, ns=100):
436 | """
437 | SH=getDefaultSegyHeader()
438 | """
439 | # INITIALIZE DICTIONARY
440 | SH = {"Job": {"pos": 3200, "type": "int32", "def": 0}}
441 |
442 | for key in SH_def.keys():
443 |
444 | tmpkey = SH_def[key]
445 | if (tmpkey.has_key('def')):
446 | val = tmpkey['def']
447 | else:
448 | val = 0
449 | SH[key] = val
450 |
451 | SH["ntraces"] = ntraces;
452 | SH["ns"] = ns;
453 |
454 | return SH
455 |
456 |
457 | # %%
458 | def getDefaultSegyTraceHeaders(ntraces=100, ns=100, dt=1000):
459 | """
460 | SH=getDefaultSegyTraceHeader()
461 | """
462 | # INITIALIZE DICTIONARY
463 | STH = {"TraceSequenceLine": {"pos": 0, "type": "int32"}}
464 |
465 | for key in STH_def.keys():
466 |
467 | tmpkey = STH_def[key]
468 | if (tmpkey.has_key('def')):
469 | val = tmpkey['def']
470 | else:
471 | val = 0
472 | STH[key] = np.zeros(ntraces)
473 |
474 | for a in range(ntraces):
475 | STH["TraceSequenceLine"][a] = a + 1
476 | STH["TraceSequenceFile"][a] = a + 1
477 | STH["FieldRecord"][a] = 1000
478 | STH["TraceNumber"][a] = a + 1
479 | STH["ns"][a] = ns
480 | STH["dt"][a] = dt
481 | return STH
482 |
483 |
484 | # %%
485 | def getSegyTraceHeader(SH, THN='cdp', data='none', endian='>'): # modified by A Squelch
486 | """
487 | getSegyTraceHeader(SH,TraceHeaderName)
488 | """
489 |
490 | bps = getBytePerSample(SH)
491 |
492 | if (data == 'none'):
493 | data = open(SH["filename"], 'rb').read()
494 |
495 | # MAKE SOME LOOKUP TABLE THAT HOLDS THE LOCATION OF HEADERS
496 | # THpos=TraceHeaderPos[THN]
497 | THpos = STH_def[THN]["pos"]
498 | THformat = STH_def[THN]["type"]
499 | ntraces = SH["ntraces"]
500 | thv = np.zeros(ntraces)
501 | for itrace in range(1, ntraces + 1, 1):
502 | i = itrace
503 |
504 | pos = THpos + 3600 + (SH["ns"] * bps + 240) * (itrace - 1);
505 |
506 | txt = "getSegyTraceHeader : Reading trace header " + THN + " " + str(itrace) + " of " + str(
507 | ntraces) + " " + str(pos)
508 |
509 | printverbose(txt, 20);
510 | thv[itrace - 1], index = getValue(data, pos, THformat, endian, 1)
511 | txt = "getSegyTraceHeader : " + THN + "=" + str(thv[itrace - 1])
512 | printverbose(txt, 30);
513 |
514 | return thv
515 |
516 |
517 | # %%
518 | def getLastSegyTraceHeader(SH, THN='cdp', data='none', endian='>'): # added by A Squelch
519 | """
520 | getLastSegyTraceHeader(SH,TraceHeaderName)
521 | """
522 |
523 | bps = getBytePerSample(SH)
524 |
525 | if (data == 'none'):
526 | data = open(SH["filename"]).read()
527 |
528 | # SET PARAMETERS THAT DEFINE THE LOCATION OF THE LAST HEADER
529 | # AND THE TRACE NUMBER KEY FIELD
530 | THpos = STH_def[THN]["pos"]
531 | THformat = STH_def[THN]["type"]
532 | ntraces = SH["ntraces"]
533 |
534 | pos = THpos + 3600 + (SH["ns"] * bps + 240) * (ntraces - 1);
535 |
536 | txt = "getLastSegyTraceHeader : Reading last trace header " + THN + " " + str(pos)
537 |
538 | printverbose(txt, 20);
539 | thv, index = getValue(data, pos, THformat, endian, 1)
540 | txt = "getLastSegyTraceHeader : " + THN + "=" + str(thv)
541 | printverbose(txt, 30);
542 |
543 | return thv
544 |
545 |
546 | # %%
547 | def getAllSegyTraceHeaders(SH, data='none'):
548 | SegyTraceHeaders = {'filename': SH["filename"]}
549 |
550 | printverbose('getAllSegyTraceHeaders : trying to get all segy trace headers', 2)
551 |
552 | if (data == 'none'):
553 | data = open(SH["filename"], 'rb').read()
554 |
555 | for key in STH_def.keys():
556 | sth = getSegyTraceHeader(SH, key, data)
557 | SegyTraceHeaders[key] = sth
558 | txt = "getAllSegyTraceHeaders : " + key
559 | printverbose(txt, 10)
560 |
561 | return SegyTraceHeaders
562 |
563 |
564 | # %%
565 | def readSegy(filename, endian='>'): # modified by A Squelch
566 | """
567 | Data,SegyHeader,SegyTraceHeaders=getSegyHeader(filename)
568 | """
569 |
570 | printverbose("readSegy : Trying to read " + filename, 0)
571 |
572 | data = open(filename, 'rb').read()
573 |
574 | filesize = len(data)
575 |
576 | SH = getSegyHeader(filename, endian) # modified by A Squelch
577 |
578 | bps = getBytePerSample(SH)
579 |
580 | ntraces = (filesize - 3600) / (SH['ns'] * bps + 240)
581 | # ntraces = 100
582 |
583 | printverbose("readSegy : Length of data : " + str(filesize), 2)
584 |
585 | SH["ntraces"] = np.int(ntraces);
586 |
587 | # ndummy_samples=240/bps # modified by A Squelch
588 | # printverbose("readSegy : ndummy_samples="+str(ndummy_samples),6) # modified by A Squelch
589 | printverbose("readSegy : ntraces=" + str(ntraces) + " nsamples=" + str(SH['ns']), 2)
590 |
591 | # GET TRACE
592 | index = 3600;
593 | nd = int((filesize - 3600) / bps)
594 |
595 | printverbose("filesize=%d" % filesize)
596 | printverbose("bps=%5d" % bps)
597 | printverbose("nd=%5d" % nd)
598 |
599 | # modified by A Squelch
600 | # this portion replaced by call to new function: readSegyData
601 | Data, SH, SegyTraceHeaders = readSegyData(data, SH, nd, bps, index, endian)
602 |
603 | printverbose("readSegy : Read segy data", 2) # modified by A Squelch
604 |
605 | return Data, SH, SegyTraceHeaders
606 |
607 |
608 | # %%
609 | def readSegyData(data, SH, nd, bps, index, endian='>'): # added by A Squelch
610 | """
611 | Data,SegyHeader,SegyTraceHeaders=readSegyData(data,SH,nd,bps,index)
612 |
613 | This function separated out from readSegy so that it can also be
614 | called from other external functions - by A Squelch.
615 | """
616 |
617 | # Calulate number of dummy samples needed to account for Trace Headers
618 | ndummy_samples = int(240 / bps)
619 | printverbose("readSegyData : ndummy_samples=" + str(ndummy_samples), 6)
620 |
621 | # READ ALL SEGY TRACE HEADRES
622 | STH = getAllSegyTraceHeaders(SH, data)
623 |
624 | printverbose("readSegyData : Reading segy data", 1)
625 |
626 | # READ ALL DATA EXCEPT FOR SEGY HEADER
627 | # Data = np.zeros((SH['ns'],ntraces))
628 |
629 | revision = SH["SegyFormatRevisionNumber"]
630 | if (revision == 100):
631 | revision = 1
632 | if (revision == 256): # added by A Squelch
633 | revision = 1
634 |
635 | dsf = SH["DataSampleFormat"]
636 |
637 | try: # block added by A Squelch
638 | DataDescr = SH_def["DataSampleFormat"]["descr"][revision][dsf]
639 | except KeyError:
640 | print("")
641 | print(" An error has ocurred interpreting a SEGY binary header key")
642 | print(" Please check the Endian setting for this file: ", SH["filename"])
643 | sys.exit()
644 |
645 | printverbose("readSegyData : SEG-Y revision = " + str(revision), 1)
646 | printverbose("readSegyData : DataSampleFormat=" + str(dsf) + "(" + DataDescr + ")", 1)
647 |
648 | if (SH["DataSampleFormat"] == 1):
649 | printverbose("readSegyData : Assuming DSF=1, IBM FLOATS", 2)
650 | Data1 = getValue(data, index, 'ibm', endian, nd)
651 | elif (SH["DataSampleFormat"] == 2):
652 | printverbose("readSegyData : Assuming DSF=" + str(SH["DataSampleFormat"]) + ", 32bit INT", 2)
653 | Data1 = getValue(data, index, 'l', endian, nd)
654 | elif (SH["DataSampleFormat"] == 3):
655 | printverbose("readSegyData : Assuming DSF=" + str(SH["DataSampleFormat"]) + ", 16bit INT", 2)
656 | Data1 = getValue(data, index, 'h', endian, nd)
657 | elif (SH["DataSampleFormat"] == 5):
658 | printverbose("readSegyData : Assuming DSF=" + str(SH["DataSampleFormat"]) + ", IEEE", 2)
659 | Data1 = getValue(data, index, 'float', endian, nd)
660 | elif (SH["DataSampleFormat"] == 8):
661 | printverbose("readSegyData : Assuming DSF=" + str(SH["DataSampleFormat"]) + ", 8bit CHAR", 2)
662 | Data1 = getValue(data, index, 'B', endian, nd)
663 | else:
664 | printverbose("readSegyData : DSF=" + str(SH["DataSampleFormat"]) + ", NOT SUPORTED", 2)
665 |
666 | Data = Data1[0]
667 |
668 | printverbose("readSegyData : - reshaping", 2)
669 | printverbose(" ns=" + str(SH['ns']),-2)
670 | Data = np.reshape(np.array(Data), (SH['ntraces'], SH['ns'] + ndummy_samples))
671 | printverbose("readSegyData : - stripping header dummy data", 2)
672 | Data = Data[:, ndummy_samples:(SH['ns'] + ndummy_samples)]
673 | printverbose("readSegyData : - transposing", 2)
674 | Data = np.transpose(Data)
675 |
676 | # SOMEONE NEEDS TO IMPLEMENT A NICER WAY DO DEAL WITH DSF=8
677 | if (SH["DataSampleFormat"] == 8):
678 | for i in np.arange(SH['ntraces']):
679 | for j in np.arange(SH['ns']):
680 | if Data[i][j] > 128:
681 | Data[i][j] = Data[i][j] - 256
682 |
683 | printverbose("readSegyData : Finished reading segy data", 1)
684 |
685 | return Data, SH, STH
686 |
687 |
688 | # %%
689 | def getSegyTrace(SH, itrace, endian='>'): # modified by A Squelch
690 | """
691 | SegyTraceHeader,SegyTraceData=getSegyTrace(SegyHeader,itrace)
692 | itrace : trace number to read
693 | THIS DEF IS NOT UPDATED. NOT READY TO USE
694 | """
695 | data = open(SH["filename"], 'rb').read()
696 |
697 | bps = getBytePerSample(SH)
698 |
699 | # GET TRACE HEADER
700 | index = 3200 + (itrace - 1) * (240 + SH['ns'] * bps)
701 | SegyTraceHeader = [];
702 | # print index
703 |
704 | # GET TRACE
705 | index = 3200 + (itrace - 1) * (240 + SH['ns'] * bps) + 240
706 | SegyTraceData = getValue(data, index, 'float', endian, SH['ns'])
707 | return SegyTraceHeader, SegyTraceData
708 |
709 |
710 | # %%
711 | def getSegyHeader(filename, endian='>'): # modified by A Squelch
712 | """
713 | SegyHeader=getSegyHeader(filename)
714 | """
715 |
716 | data = open(filename, 'rb').read()
717 |
718 | SegyHeader = {'filename': filename}
719 |
720 | j = 0;
721 | for key in SH_def.keys():
722 | j = j + 1;
723 | pos = SH_def[key]["pos"]
724 | format = SH_def[key]["type"]
725 |
726 | txt = "i=%3d, pos=%5d, format=%2s, key=%s" % (j, pos, format, key);
727 | printverbose(txt, 10)
728 |
729 | SegyHeader[key], index = getValue(data, pos, format, endian);
730 |
731 | txt = "SegyHeader[%s] = %f" % (key, SegyHeader[key])
732 | printverbose(txt, 2)
733 |
734 | # SET NUMBER OF BYTES PER DATA SAMPLE
735 | bps = getBytePerSample(SegyHeader)
736 |
737 | filesize = len(data)
738 | ntraces = (filesize - 3600) / (SegyHeader['ns'] * bps + 240)
739 | SegyHeader["ntraces"] = ntraces
740 | SegyHeader["time"]=np.arange(SegyHeader['ns']) * SegyHeader['dt'] / 1e+6
741 |
742 |
743 | printverbose('getSegyHeader : succesfully read ' + filename, 1)
744 |
745 | return SegyHeader
746 |
747 |
748 | # %%
749 | def writeSegy(filename, Data, dt=1000, STHin={}, SHin={}):
750 | """
751 | writeSegy(filename,Data,dt)
752 |
753 | Write SEGY
754 |
755 | See also readSegy
756 |
757 | (c) 2005, Thomas Mejer Hansen
758 |
759 | MAKE OPTIONAL INPUT FOR ALL SEGYHTRACEHEADER VALUES
760 |
761 | """
762 |
763 | printverbose("writeSegy : Trying to write " + filename, 0)
764 |
765 | N = Data.shape
766 | ns = N[0]
767 | ntraces = N[1]
768 | print(ntraces)
769 | print(ns)
770 |
771 | SH = getDefaultSegyHeader(ntraces, ns);
772 | STH = getDefaultSegyTraceHeaders(ntraces, ns, dt)
773 |
774 | # ADD STHin, if exists...
775 | for key in STHin.keys():
776 | print(key)
777 | for a in range(ntraces):
778 | STH[key] = STHin[key][a]
779 |
780 | # ADD SHin, if exists...
781 | for key in SHin.keys():
782 | print(key)
783 | SH[key] = SHin[key]
784 |
785 | writeSegyStructure(filename, Data, SH, STH)
786 |
787 |
788 | # %%
789 | def writeSegyStructure(filename, Data, SH, STH, endian='>'): # modified by A Squelch
790 | """
791 | writeSegyStructure(filename,Data,SegyHeader,SegyTraceHeaders)
792 |
793 | Write SEGY file using SegyPy data structures
794 |
795 | See also readSegy
796 |
797 | (c) 2005, Thomas Mejer Hansen
798 |
799 | """
800 |
801 | printverbose("writeSegyStructure : Trying to write " + filename, 0)
802 |
803 | f = open(filename, 'wb')
804 |
805 | # VERBOSE INF
806 | revision = SH["SegyFormatRevisionNumber"]
807 | dsf = SH["DataSampleFormat"]
808 | if (revision == 100):
809 | revision = 1
810 | if (revision == 256): # added by A Squelch
811 | revision = 1
812 |
813 | try: # block added by A Squelch
814 | DataDescr = SH_def["DataSampleFormat"]["descr"][revision][dsf]
815 | except KeyError:
816 | print("")
817 | print(" An error has ocurred interpreting a SEGY binary header key")
818 | print(" Please check the Endian setting for this file: ", SH["filename"])
819 | sys.exit()
820 |
821 | printverbose("writeSegyStructure : SEG-Y revision = " + str(revision), 1)
822 | printverbose("writeSegyStructure : DataSampleFormat=" + str(dsf) + "(" + DataDescr + ")", 1)
823 |
824 | # WRITE SEGY HEADER
825 |
826 | for key in SH_def.keys():
827 | pos = SH_def[key]["pos"]
828 | format = SH_def[key]["type"]
829 | value = SH[key]
830 |
831 | # SegyHeader[key],index = putValue(value,f,pos,format,endian);
832 | putValue(value, f, pos, format, endian);
833 |
834 | txt = str(pos) + " " + str(format) + " Reading " + key + "=" + str(value)
835 | # +"="+str(SegyHeader[key])
836 | # printverbose(txt,-1)
837 |
838 | # SEGY TRACES
839 |
840 | ctype = SH_def['DataSampleFormat']['datatype'][revision][dsf]
841 | bps = SH_def['DataSampleFormat']['bps'][revision][dsf]
842 |
843 | sizeT = 240 + SH['ns'] * bps;
844 |
845 | for itrace in range(SH['ntraces']):
846 | index = 3600 + itrace * sizeT
847 | printverbose('Writing Trace #' + str(itrace + 1) + '/' + str(SH['ntraces']), 10)
848 | # WRITE SEGY TRACE HEADER
849 | for key in STH_def.keys():
850 | pos = index + STH_def[key]["pos"]
851 | format = STH_def[key]["type"]
852 | value = STH[key][itrace]
853 | txt = str(pos) + " " + str(format) + " Writing " + key + "=" + str(value)
854 | printverbose(txt, 40)
855 | putValue(value, f, pos, format, endian);
856 |
857 | # Write Data
858 | cformat = endian + ctype
859 | for s in range(SH['ns']):
860 | strVal = struct.pack(cformat, Data[s, itrace])
861 | f.seek(index + 240 + s * struct.calcsize(cformat))
862 | f.write(strVal);
863 |
864 | f.close
865 |
866 | # return segybuffer
867 |
868 |
869 | # %%
870 | def putValue(value, fileid, index, ctype='l', endian='>', number=1):
871 | """
872 | putValue(data,index,ctype,endian,number)
873 | """
874 | if (ctype == 'l') | (ctype == 'long') | (ctype == 'int32'):
875 | size = l_long
876 | ctype = 'l'
877 | elif (ctype == 'L') | (ctype == 'ulong') | (ctype == 'uint32'):
878 | size = l_ulong
879 | ctype = 'L'
880 | elif (ctype == 'h') | (ctype == 'short') | (ctype == 'int16'):
881 | size = l_short
882 | ctype = 'h'
883 | elif (ctype == 'H') | (ctype == 'ushort') | (ctype == 'uint16'):
884 | size = l_ushort
885 | ctype = 'H'
886 | elif (ctype == 'c') | (ctype == 'char'):
887 | size = l_char
888 | ctype = 'c'
889 | elif (ctype == 'B') | (ctype == 'uchar'):
890 | size = l_uchar
891 | ctype = 'B'
892 | elif (ctype == 'f') | (ctype == 'float'):
893 | size = l_float
894 | ctype = 'f'
895 | elif (ctype == 'ibm'):
896 | size = l_float
897 | else:
898 | printverbose('Bad Ctype : ' + ctype, -1)
899 |
900 | cformat = endian + ctype * number
901 |
902 | printverbose('putValue : cformat : ' + cformat + ' ctype=' + ctype, 40)
903 |
904 | strVal = struct.pack(cformat, value)
905 | fileid.seek(index)
906 | fileid.write(strVal);
907 |
908 | return 1
909 |
910 |
911 | # %%
912 | def getValue(data, index, ctype='l', endian='>', number=1):
913 | """
914 | getValue(data,index,ctype,endian,number)
915 | """
916 | if (ctype == 'l') | (ctype == 'long') | (ctype == 'int32'):
917 | size = l_long
918 | ctype = 'l'
919 | elif (ctype == 'L') | (ctype == 'ulong') | (ctype == 'uint32'):
920 | size = l_ulong
921 | ctype = 'L'
922 | elif (ctype == 'h') | (ctype == 'short') | (ctype == 'int16'):
923 | size = l_short
924 | ctype = 'h'
925 | elif (ctype == 'H') | (ctype == 'ushort') | (ctype == 'uint16'):
926 | size = l_ushort
927 | ctype = 'H'
928 | elif (ctype == 'c') | (ctype == 'char'):
929 | size = l_char
930 | ctype = 'c'
931 | elif (ctype == 'B') | (ctype == 'uchar'):
932 | size = l_uchar
933 | ctype = 'B'
934 | elif (ctype == 'f') | (ctype == 'float'):
935 | size = l_float
936 | ctype = 'f'
937 | elif (ctype == 'ibm'):
938 | size = l_float
939 | ctype = 'ibm'
940 | else:
941 | printverbose('Bad Ctype : ' + ctype, -1)
942 |
943 | index_end = index + size * number
944 |
945 | printverbose("index=%d, number=%d, size=%d, ctype=%s" % (index, number, size, ctype), 8);
946 | printverbose("index, index_end = " + str(index) + "," + str(index_end), 9)
947 |
948 | if (ctype == 'ibm'):
949 | # ASSUME IBM FLOAT DATA
950 | Value = list(range(int(number)))
951 | for i in np.arange(number):
952 | index_ibm_start = i * 4 + index
953 | index_ibm_end = index_ibm_start + 4;
954 | ibm_val = ibm2ieee2(data[index_ibm_start:index_ibm_end])
955 | Value[i] = ibm_val;
956 | # this resturn an array as opposed to a tuple
957 | else:
958 | # ALL OTHER TYPES OF DATA
959 | cformat = 'f' * number
960 | cformat = endian + ctype * number
961 |
962 | printverbose("getValue : cformat : '" + cformat + "'", 11)
963 |
964 | Value = struct.unpack(cformat, data[index:index_end])
965 |
966 | if (ctype == 'B'):
967 | printverbose('getValue : Ineficient use of 1byte Integer...', -1)
968 |
969 | vtxt = 'getValue : ' + 'start=' + str(index) + ' size=' + str(size) + ' number=' + str(
970 | number) + ' Value=' + str(Value) + ' cformat=' + str(cformat)
971 | printverbose(vtxt, 20)
972 |
973 | if number == 1:
974 | return Value[0], index_end
975 | else:
976 | return Value, index_end
977 |
978 |
979 | # %%
980 | def print_version():
981 | print('SegyPY version is ', version)
982 |
983 |
984 | # %%
985 | def printverbose(txt, level=1):
986 | if level <= verbose:
987 | print('SegyPY' + version + ': ', txt)
988 |
989 |
990 | # %%
991 | ##############
992 | # MISC FUNCTIONS
993 | def ibm2Ieee(ibm_float):
994 | """
995 | ibm2Ieee(ibm_float)
996 | Used by permission
997 | (C) Secchi Angelo
998 | with thanks to Howard Lightstone and Anton Vredegoor.
999 | """
1000 | """
1001 | I = struct.unpack('>I',ibm_float)[0]
1002 | sign = [1,-1][bool(i & 0x100000000L)]
1003 | characteristic = ((i >> 24) & 0x7f) - 64
1004 | fraction = (i & 0xffffff)/float(0x1000000L)
1005 | return sign*16**characteristic*fraction
1006 | """
1007 |
1008 |
1009 | def ibm2ieee2(ibm_float):
1010 | """
1011 | ibm2ieee2(ibm_float)
1012 | Used by permission
1013 | (C) Secchi Angelo
1014 | with thanks to Howard Lightstone and Anton Vredegoor.
1015 | """
1016 | dividend = float(16 ** 6)
1017 |
1018 | if ibm_float == 0:
1019 | return 0.0
1020 | istic, a, b, c = struct.unpack('>BBBB', ibm_float)
1021 | if istic >= 128:
1022 | sign = -1.0
1023 | istic = istic - 128
1024 | else:
1025 | sign = 1.0
1026 | mant = float(a << 16) + float(b << 8) + float(c)
1027 | return sign * 16 ** (istic - 64) * (mant / dividend)
1028 |
1029 |
1030 | def getBytePerSample(SH):
1031 | revision = SH["SegyFormatRevisionNumber"]
1032 | if (revision == 100):
1033 | revision = 1
1034 | if (revision == 256): # added by A Squelch
1035 | revision = 1
1036 |
1037 | dsf = SH["DataSampleFormat"]
1038 |
1039 | try: # block added by A Squelch
1040 | bps = SH_def["DataSampleFormat"]["bps"][revision][dsf]
1041 | except KeyError:
1042 | print("")
1043 | print(" An error has ocurred interpreting a SEGY binary header key")
1044 | print(" Please check the Endian setting for this file: ", SH["filename"])
1045 | sys.exit()
1046 |
1047 | printverbose("getBytePerSample : bps=" + str(bps), 21);
1048 |
1049 | return bps
1050 |
1051 |
1052 | ##############
1053 | # segy class
1054 | class SegyTraceheaderClass:
1055 | def __init__(self):
1056 | self.cdp = 0
1057 |
1058 |
1059 | class SegyHeaderClass:
1060 | def __str__(self):
1061 | return "SegyHeaderClass "
1062 |
1063 | def __init__(self):
1064 | self.filename = 0
1065 | self.Trace = version
1066 |
1067 | def cdp(self):
1068 | return "Getting CDP trace header"
1069 |
1070 | def InlineX(self):
1071 | return "Getting CDP trace header"
1072 |
1073 |
1074 | class SegyClass:
1075 | STH_def = STH_def
1076 | SH_def = SH_def
1077 | STH = SegyTraceheaderClass()
1078 | SH = SegyHeaderClass()
1079 |
1080 | def __init__(self):
1081 | self.THOMAS = 'Thomas'
1082 |
--------------------------------------------------------------------------------
/PyOSGPUP/signalpy.py:
--------------------------------------------------------------------------------
1 |
2 | import numpy as np
3 | import numpy.fft import fft, ifft
4 |
5 | def hilbert(mag):
6 | """Compute the modified 1D discrete Hilbert transform
7 |
8 | Parameters
9 | ----------
10 | mag : ndarray
11 | The magnitude spectrum. Should be 1D with an even length, and
12 | preferably a fast length for FFT/IFFT.
13 | """
14 | # Adapted based on code by Niranjan Damera-Venkata,
15 | # Brian L. Evans and Shawn R. McCaslin (see refs for `minimum_phase`)
16 | sig = np.zeros(len(mag))
17 | # Leave Nyquist and DC at 0, knowing np.abs(fftfreq(N)[midpt]) == 0.5
18 | midpt = len(mag) // 2
19 | sig[1:midpt] = 1
20 | sig[midpt+1:] = -1
21 | # eventually if we want to support complex filters, we will need a
22 | # np.abs() on the mag inside the log, and should remove the .real
23 | recon = ifft(mag * np.exp(fft(sig * ifft(np.log(mag))))).real
24 | return recon
25 |
26 |
--------------------------------------------------------------------------------
/PyOSGPUP/synthe_seismo.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 | import PyOSGPUP.wavelet as wavelet
4 |
5 |
6 | def getPlotLog(d, log, dmax=200):
7 | d = np.array(d, dtype=float)
8 | log = np.array(log, dtype=float)
9 |
10 | dplot = np.kron(d, np.ones(2))
11 | logplot = np.kron(log, np.ones(2))
12 |
13 | # dplot = dplot[1:]
14 | dplot = np.append(dplot[1:], dmax)
15 |
16 | return dplot, logplot
17 |
18 |
19 | def getImpedance(rholog, vlog):
20 | """
21 | Acoustic Impedance is the product of density and velocity
22 | $$
23 | Z = \\rho v
24 | $$
25 | """
26 | rholog, vlog = np.array(rholog, dtype=float), np.array(vlog, dtype=float),
27 | return rholog * vlog
28 |
29 |
30 | def getReflectivity(d, rho, v, usingT=True):
31 | """
32 | The reflection coefficient of an interface is $$ R_i = \\frac{Z_{i+1} - Z_{i}}{Z_{i+1}+Z_{i}} $$ The reflectivity
33 | can also include the effect of transmission through above layers, in which case the reflectivity is given by $$
34 | \\text{reflectivity} = R_i \\pi_{j = 1}^{i-1}(1-R_j^2) $$
35 | """
36 | Z = getImpedance(rho, v) # acoustic impedance
37 | dZ = (Z[1:] - Z[:-1])
38 | sZ = (Z[:-1] + Z[1:])
39 | R = dZ / sZ # reflection coefficients
40 |
41 | nlayer = len(v) # number of layers
42 |
43 | rseries = R
44 |
45 | if usingT:
46 | for i in range(nlayer - 1):
47 | rseries[i + 1:] = rseries[i + 1:] * (1. - R[i] ** 2)
48 |
49 | return rseries, R
50 |
51 |
52 | def getTimeDepth(d,v,dmax=200):
53 | """
54 | The time depth conversion is computed by determining the two-way travel time for a reflection from a given depth.
55 | """
56 |
57 | d = np.sort(d)
58 | d = np.append(d,dmax)
59 |
60 | twttop = 2.*np.diff(d)/v # 2-way travel time within each layer
61 | twttop = np.append(0.,twttop)
62 | twttop = np.cumsum(twttop) # 2-way travel time from surface to top of each layer
63 |
64 | return d, twttop
65 |
66 |
67 | def getLogs(d, rho, v, usingT=True):
68 | """
69 | Function to make plotting convenient
70 | """
71 | dpth, rholog = getPlotLog(d, rho)
72 | _, vlog = getPlotLog(d, v)
73 | zlog = getImpedance(rholog, vlog)
74 | rseries, _ = getReflectivity(d, rho, v, usingT)
75 | return dpth, rholog, vlog, zlog, rseries
76 |
77 |
78 | def plotLogFormat(log, dpth, xlim, col='blue'):
79 | """
80 | Nice formatting for plotting logs as a function of depth
81 | """
82 | ax = plt.plot(log, dpth, linewidth=2, color=col)
83 | plt.xlim(xlim)
84 | plt.ylim((dpth.min(), dpth.max()))
85 | plt.grid()
86 | plt.gca().invert_yaxis()
87 | plt.setp(plt.xticks()[1], rotation='90', fontsize=9)
88 | plt.setp(plt.yticks()[1], fontsize=9)
89 |
90 | return ax
91 |
92 |
93 | def plotLogs(d, rho, v, usingT=True):
94 | """
95 | Plotting wrapper to plot density, velocity, acoustic impedance and reflectivity as a function of depth.
96 | """
97 | d = np.sort(d)
98 |
99 | dpth, rholog, vlog, zlog, rseries = getLogs(d, rho, v, usingT)
100 | nd = len(dpth)
101 |
102 | xlimrho = (1.95, 5.05)
103 | xlimv = (0.25, 4.05)
104 | xlimz = (xlimrho[0] * xlimv[0], xlimrho[1] * xlimv[1])
105 |
106 | # Plot Density
107 | plt.figure(1)
108 |
109 | plt.subplot(141)
110 | plotLogFormat(rholog * 10 ** -3, dpth, xlimrho, 'blue')
111 | plt.title('$\\rho$')
112 | plt.xlabel('Density \n $\\times 10^3$ (kg /m$^3$)', fontsize=9)
113 | plt.ylabel('Depth (m)', fontsize=9)
114 |
115 | plt.subplot(142)
116 | plotLogFormat(vlog * 10 ** -3, dpth, xlimv, 'red')
117 | plt.title('$v$')
118 | plt.xlabel('Velocity \n $\\times 10^3$ (m/s)', fontsize=9)
119 | plt.setp(plt.yticks()[1], visible=False)
120 |
121 | plt.subplot(143)
122 | plotLogFormat(zlog * 10. ** -6., dpth, xlimz, 'green')
123 | plt.gca().set_title('$Z = \\rho v$')
124 | plt.gca().set_xlabel('Impedance \n $\\times 10^{6}$ (kg m$^{-2}$ s$^{-1}$)', fontsize=9)
125 | plt.setp(plt.yticks()[1], visible=False)
126 |
127 | plt.subplot(144)
128 | plt.hlines(d[1:], np.zeros(nd - 1), rseries, linewidth=2)
129 | plt.plot(np.zeros(nd), dpth, linewidth=2, color='black')
130 | plt.title('Reflectivity')
131 | plt.xlim((-1., 1.))
132 | plt.gca().set_xlabel('Reflectivity')
133 | plt.grid()
134 | plt.gca().invert_yaxis()
135 | plt.setp(plt.xticks()[1], rotation='90', fontsize=9)
136 | plt.setp(plt.yticks()[1], visible=False)
137 |
138 | plt.tight_layout()
139 | plt.show()
140 |
141 |
142 | def plotLogsInteract(d2, d3, rho1, rho2, rho3, v1, v2, v3, usingT=False):
143 | """
144 | interactive wrapper of plotLogs
145 | """
146 | d = np.array((0., d2, d3), dtype=float)
147 | rho = np.array((rho1, rho2, rho3), dtype=float)
148 | v = np.array((v1, v2, v3), dtype=float)
149 | plotLogs(d, rho, v, usingT)
150 |
151 |
152 | def plotTimeDepth(d,v):
153 | """
154 | Wrapper to plot time-depth conversion based on the provided velocity model
155 | """
156 |
157 | dpth,t = getTimeDepth(d,v)
158 | plt.figure()
159 | plt.plot(dpth,t,linewidth=2)
160 | plt.title('Depth-Time')
161 | plt.grid()
162 | plt.gca().set_xlabel('Depth (m)',fontsize=9)
163 | plt.gca().set_ylabel('Two Way Time (s)',fontsize=9)
164 |
165 | plt.tight_layout()
166 | plt.show()
167 |
168 |
169 | def syntheticSeismogram(d, rho, v, wavf, wavA=1., usingT=True, wavtyp = 'RICKER', dt=0.0001, dmax=200):
170 | """
171 | function syntheticSeismogram(d, rho, v, wavtyp, wavf, usingT)
172 | syntheicSeismogram generates a synthetic seismogram for
173 | a simple 1-D layered model.
174 | Inputs:
175 | d : depth to the top of each layer (m)
176 | rho : density of each layer (kg/m^3)
177 | v : velocity of each layer (m/s)
178 | The last layer is assumed to be a half-space
179 | wavf : wavelet frequency
180 | wavA : wavelet amplitude
181 | usintT : using Transmission coefficients?
182 | wavtyp : type of Wavelet
183 | The wavelet options are:
184 | Ricker: takes one frequency
185 | Gaussian: still in progress
186 | Ormsby: takes 4 frequencies
187 | Klauder: takes 2 frequencies
188 | usingT : use transmission coefficients?
189 | Lindsey Heagy
190 | lheagy@eos.ubc.ca
191 | Created: November 30, 2013
192 | Modified: October 3, 2014
193 | """
194 |
195 | v, rho, d = np.array(v, dtype=float), np.array(rho, dtype=float), np.array(d, dtype=float)
196 | usingT = np.array(usingT, dtype=bool)
197 |
198 | _, t = getTimeDepth(d,v,dmax)
199 | rseries,R = getReflectivity(d,rho,v)
200 |
201 | # time for reflectivity series
202 | tref = t[1:-1]
203 |
204 | # create time vector
205 | t = np.arange(t.min(),t.max(),dt)
206 |
207 | # make wavelet
208 | twav = np.arange(-2.0/np.min(wavf), 2.0/np.min(wavf), dt)
209 |
210 | # Get source wavelet
211 | wav = {'RICKER':wavelet.getRicker, 'ORMSBY':wavelet.getOrmsby, 'KLAUDER':wavelet.getKlauder}[wavtyp](wavf,twav)
212 | wav = wavA*wav
213 |
214 | rseriesconv = np.zeros(len(t))
215 | for i in range(len(tref)):
216 | index = np.abs(t - tref[i]).argmin()
217 | rseriesconv[index] = rseries[i]
218 |
219 | # Do the convolution
220 | seis = np.convolve(wav,rseriesconv)
221 | tseis = np.min(twav)+dt*np.arange(len(seis))
222 | index = np.logical_and(tseis >= 0, tseis <= np.max(t))
223 | tseis = tseis[index]
224 | seis = seis[index]
225 |
226 | return tseis, seis, twav, wav, tref, rseries
227 |
228 |
229 | def plotSeismogram(d, rho, v, wavf, wavA=1., noise = 0., usingT=True, wavtyp='RICKER'):
230 | """
231 | Plotting function to show physical property logs (in depth) and seismogram (in time).
232 | """
233 |
234 | dpth, rholog, vlog, zlog, rseries = getLogs(d, rho, v, usingT)
235 | tseis, seis, twav, wav, tref, rseriesconv = syntheticSeismogram(d, rho, v, wavf, wavA, usingT,wavtyp)
236 |
237 | noise = noise*np.max(np.abs(seis))*np.random.randn(seis.size)
238 | filt = np.arange(1.,21.)
239 | filtr = filt[::-1]
240 | filt = np.append(filt,filtr[1:])*1./21.
241 | noise = np.convolve(noise,filt)
242 | noise = noise[0:seis.size]
243 |
244 | xlimrho = (1.95,5.05)
245 | xlimv = (0.25,4.05)
246 | xlimz = (xlimrho[0]*xlimv[0], xlimrho[1]*xlimv[1])
247 |
248 | seis = seis + noise
249 |
250 | plt.figure()
251 |
252 | plt.subplot(131)
253 | plotLogFormat(rholog*10**-3,dpth,xlimrho,'blue')
254 | plt.title('$\\rho$')
255 | plt.xlabel('Density \n $\\times 10^3$ (kg /m$^3$)',fontsize=9)
256 | plt.ylabel('Depth (m)',fontsize=9)
257 |
258 | plt.subplot(132)
259 | plotLogFormat(vlog*10**-3,dpth,xlimv,'red')
260 | plt.title('$v$')
261 | plt.xlabel('Velocity \n $\\times 10^3$ (m/s)',fontsize=9)
262 | plt.ylabel('Depth (m)',fontsize=9)
263 |
264 | plt.subplot(133)
265 | plt.plot(seis,tseis,color='black',linewidth=1)
266 | plt.title('Seismogram')
267 | plt.grid()
268 | plt.ylim((tseis.min(),tseis.max()))
269 | plt.gca().invert_yaxis()
270 | plt.xlim((-0.5,0.5))
271 | plt.setp(plt.xticks()[1],rotation='90',fontsize=9)
272 | plt.setp(plt.yticks()[1],fontsize=9)
273 | plt.gca().set_xlabel('Amplitude',fontsize=9)
274 | plt.gca().set_ylabel('Time (s)',fontsize=9)
275 |
276 | plt.tight_layout()
277 | plt.show()
--------------------------------------------------------------------------------
/PyOSGPUP/tuning_wedge_acces.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from matplotlib import gridspec
3 | import matplotlib.pyplot as plt
4 | from PyOSGPUP.signalpy import hilbert
5 |
6 |
7 | def plot_vawig(axhdl, data, t, excursion, highlight=None):
8 | [ntrc, nsamp] = data.shape
9 |
10 | t = np.hstack([0, t, t.max()])
11 |
12 | for i in range(0, ntrc):
13 | tbuf = excursion * data[i] / np.max(np.abs(data)) + i
14 |
15 | tbuf = np.hstack([i, tbuf, i])
16 |
17 | if i == highlight:
18 | lw = 2
19 | else:
20 | lw = 0.5
21 |
22 | axhdl.plot(tbuf, t, color='black', linewidth=lw)
23 |
24 | plt.fill_betweenx(t, tbuf, i, where=tbuf > i, facecolor=[0.6, 0.6, 1.0], linewidth=0)
25 | plt.fill_betweenx(t, tbuf, i, where=tbuf < i, facecolor=[1.0, 0.7, 0.7], linewidth=0)
26 |
27 | axhdl.set_xlim((-excursion, ntrc + excursion))
28 | axhdl.xaxis.tick_top()
29 | axhdl.xaxis.set_label_position('top')
30 | axhdl.invert_yaxis()
31 |
32 |
33 | def ricker(cfreq, phase, dt, wvlt_length):
34 | '''
35 | Calculate a ricker wavelet
36 |
37 | Usage:
38 | ------
39 | t, wvlt = wvlt_ricker(cfreq, phase, dt, wvlt_length)
40 |
41 | cfreq: central frequency of wavelet in Hz
42 | phase: wavelet phase in degrees
43 | dt: sample rate in seconds
44 | wvlt_length: length of wavelet in seconds
45 | '''
46 |
47 | nsamp = int(wvlt_length / dt + 1)
48 | t_max = wvlt_length * 0.5
49 | t_min = -t_max
50 |
51 | t = np.arange(t_min, t_max, dt)
52 |
53 | t = np.linspace(-wvlt_length / 2, (wvlt_length - dt) / 2, wvlt_length / dt)
54 | wvlt = (1.0 - 2.0 * (np.pi ** 2) * (cfreq ** 2) * (t ** 2)) * np.exp(-(np.pi ** 2) * (cfreq ** 2) * (t ** 2))
55 |
56 | if phase != 0:
57 | phase = phase * np.pi / 180.0
58 | wvlth = hilbert(wvlt)
59 | wvlth = np.imag(wvlth)
60 | wvlt = np.cos(phase) * wvlt - np.sin(phase) * wvlth
61 |
62 | return t, wvlt
63 |
64 |
65 | def wvlt_bpass(f1, f2, f3, f4, phase, dt, wvlt_length):
66 | '''
67 | Calculate a trapezoidal bandpass wavelet
68 |
69 | Usage:
70 | ------
71 | t, wvlt = wvlt_ricker(f1, f2, f3, f4, phase, dt, wvlt_length)
72 |
73 | f1: Low truncation frequency of wavelet in Hz
74 | f2: Low cut frequency of wavelet in Hz
75 | f3: High cut frequency of wavelet in Hz
76 | f4: High truncation frequency of wavelet in Hz
77 | phase: wavelet phase in degrees
78 | dt: sample rate in seconds
79 | wvlt_length: length of wavelet in seconds
80 | '''
81 |
82 | from numpy.fft import fft, ifft, fftfreq, fftshift, ifftshift
83 |
84 | nsamp = int(wvlt_length / dt + 1)
85 |
86 | freq = fftfreq(nsamp, dt)
87 | freq = fftshift(freq)
88 | aspec = freq * 0.0
89 | pspec = freq * 0.0
90 |
91 | # Calculate slope and y-int for low frequency ramp
92 | M1 = 1 / (f2 - f1)
93 | b1 = -M1 * f1
94 |
95 | # Calculate slop and y-int for high frequency ramp
96 | M2 = -1 / (f4 - f3)
97 | b2 = -M2 * f4
98 |
99 | # Build initial frequency and filter arrays
100 | freq = fftfreq(nsamp, dt)
101 | freq = fftshift(freq)
102 | filt = np.zeros(nsamp)
103 |
104 | # Build LF ramp
105 | idx = np.nonzero((np.abs(freq) >= f1) & (np.abs(freq) < f2))
106 | filt[idx] = M1 * np.abs(freq)[idx] + b1
107 |
108 | # Build central filter flat
109 | idx = np.nonzero((np.abs(freq) >= f2) & (np.abs(freq) <= f3))
110 | filt[idx] = 1.0
111 |
112 | # Build HF ramp
113 | idx = np.nonzero((np.abs(freq) > f3) & (np.abs(freq) <= f4))
114 | filt[idx] = M2 * np.abs(freq)[idx] + b2
115 |
116 | # Unshift the frequencies and convert filter to fourier coefficients
117 | filt2 = ifftshift(filt)
118 | Af = filt2 * np.exp(np.zeros(filt2.shape) * 1j)
119 |
120 | # Convert filter to time-domain wavelet
121 | wvlt = fftshift(ifft(Af))
122 | wvlt = np.real(wvlt)
123 | wvlt = wvlt / np.max(np.abs(wvlt)) # normalize wavelet by peak amplitude
124 |
125 | # Generate array of wavelet times
126 | t = np.linspace(-wvlt_length * 0.5, wvlt_length * 0.5, nsamp)
127 |
128 | # Apply phase rotation if desired
129 | if phase != 0:
130 | phase = phase * np.pi / 180.0
131 | wvlth = hilbert(wvlt)
132 | wvlth = np.imag(wvlth)
133 | wvlt = np.cos(phase) * wvlt - np.sin(phase) * wvlth
134 |
135 | return t, wvlt
136 |
137 |
138 | def calc_rc(vp_mod, rho_mod):
139 | '''
140 | rc_int = calc_rc(vp_mod, rho_mod)
141 | '''
142 |
143 | nlayers = len(vp_mod)
144 | nint = nlayers - 1
145 |
146 | rc_int = []
147 | for i in range(0, nint):
148 | buf1 = vp_mod[i + 1] * rho_mod[i + 1] - vp_mod[i] * rho_mod[i]
149 | buf2 = vp_mod[i + 1] * rho_mod[i + 1] + vp_mod[i] * rho_mod[i]
150 | buf3 = buf1 / buf2
151 | rc_int.append(buf3)
152 |
153 | return rc_int
154 |
155 | def calc_times(z_int, vp_mod):
156 | '''
157 | t_int = calc_times(z_int, vp_mod)
158 | '''
159 |
160 | nlayers = len(vp_mod)
161 | nint = nlayers - 1
162 |
163 | t_int = []
164 | for i in range(0, nint):
165 | if i == 0:
166 | tbuf = z_int[i] / vp_mod[i]
167 | t_int.append(tbuf)
168 | else:
169 | zdiff = z_int[i] - z_int[i - 1]
170 | tbuf = 2 * zdiff / vp_mod[i] + t_int[i - 1]
171 | t_int.append(tbuf)
172 |
173 | return t_int
174 |
175 | def digitize_model(rc_int, t_int, t):
176 | '''
177 | rc = digitize_model(rc, t_int, t)
178 |
179 | rc = reflection coefficients corresponding to interface times
180 | t_int = interface times
181 | t = regularly sampled time series defining model sampling
182 | '''
183 |
184 | import numpy as np
185 |
186 | nlayers = len(rc_int)
187 | nint = nlayers - 1
188 | nsamp = len(t)
189 |
190 | rc = list(np.zeros(nsamp, dtype='float'))
191 | lyr = 0
192 |
193 | for i in range(0, nsamp):
194 |
195 | if t[i] >= t_int[lyr]:
196 | rc[i] = rc_int[lyr]
197 | lyr = lyr + 1
198 |
199 | if lyr > nint:
200 | break
201 |
202 | return rc
203 |
204 |
205 | def wedge_tuning(mod,bound_mod,wave_parm,freq,trace_parm,plot_parm):
206 | ###########################################################
207 | #
208 | # DEFINE MODELING PARAMETERS HERE
209 | #
210 |
211 | # 3-Layer Model Parameters [Layer1, Layer2, Layer 3]
212 | vp_mod = mod[0] # P-wave velocity (m/s)
213 | vs_mod = mod[1] # S-wave velocity (m/s)
214 | rho_mod = mod[2] # Density (g/cc)
215 |
216 | dz_min = bound_mod[0] # Minimum thickness of Layer 2 (m)
217 | dz_max = bound_mod[1] # Maximum thickness of Layer 2 (m)
218 | dz_step = bound_mod[2] # Thickness step from trace-to-trace (normally 1.0 m)
219 |
220 | # Wavelet Parameters
221 | wvlt_type = wave_parm[0] # Valid values: 'ricker' or 'bandpass'
222 | wvlt_length = wave_parm[1] # Wavelet length in seconds
223 | wvlt_phase = wave_parm[2] # Wavelet phase in degrees
224 | wvlt_scalar = wave_parm[3] # Multiplier to scale wavelet amplitude (default = 1.0)
225 | wvlt_cfreq = wave_parm[4] # Ricker wavelet central frequency
226 | f1 = freq[0] # Bandpass wavelet low truncation frequency
227 | f2 = freq[1] # Bandpass wavelet low cut frequency
228 | f3 = freq[2] # Bandpass wavelet high cut frequency
229 | f4 = freq[3] # Bandpass wavelet high truncation frequency
230 |
231 | # Trace Parameters
232 | tmin = trace_parm[0]
233 | tmax = trace_parm[1]
234 | dt = trace_parm[2] # changing this from 0.0001 can affect the display quality
235 |
236 | # Plot Parameters
237 | min_plot_time = plot_parm[0]
238 | max_plot_time = plot_parm[1]
239 | excursion = plot_parm[2]
240 |
241 | ###########################################################
242 | #
243 | # DEFINE MODELING PARAMETERS HERE
244 | #
245 |
246 | # Some handy constants
247 | nlayers = len(vp_mod)
248 | nint = nlayers - 1
249 | nmodel = int((dz_max - dz_min) / dz_step + 1)
250 |
251 |
252 | # Generate wavelet
253 | if wvlt_type == 'ricker':
254 | wvlt_t, wvlt_amp = ricker(wvlt_cfreq, wvlt_phase, dt, wvlt_length)
255 |
256 | elif wvlt_type == 'bandpass':
257 | wvlt_t, wvlt_amp = wvlt_bpass(f1, f2, f3, f4, wvlt_phase, dt, wvlt_length)
258 |
259 | # Apply amplitude scale factor to wavelet (to match seismic amplitude values)
260 | wvlt_amp = wvlt_scalar * wvlt_amp
261 |
262 | # Calculate reflectivities from model parameters
263 | rc_int = calc_rc(vp_mod, rho_mod)
264 |
265 | syn_zo = []
266 | rc_zo = []
267 | lyr_times = []
268 | for model in range(0, nmodel):
269 |
270 | # Calculate interface depths
271 | z_int = [500.0]
272 | z_int.append(z_int[0] + dz_min + dz_step * model)
273 |
274 | # Calculate interface times
275 | t_int = calc_times(z_int, vp_mod)
276 | lyr_times.append(t_int)
277 |
278 | # Digitize 3-layer model
279 | nsamp = int((tmax - tmin) / dt) + 1
280 | t = []
281 | for i in range(0, nsamp):
282 | t.append(i * dt)
283 |
284 | rc = digitize_model(rc_int, t_int, t)
285 | rc_zo.append(rc)
286 |
287 | # Convolve wavelet with reflectivities
288 | syn_buf = np.convolve(rc, wvlt_amp, mode='same')
289 | syn_buf = list(syn_buf)
290 | syn_zo.append(syn_buf)
291 | print("finished step %i" % (model))
292 |
293 | syn_zo = np.array(syn_zo)
294 | t = np.array(t)
295 | lyr_times = np.array(lyr_times)
296 | lyr_indx = np.array(np.round(lyr_times / dt), dtype='int16')
297 |
298 | # Use the transpose because rows are traces;
299 | # columns are time samples.
300 | tuning_trace = np.argmax(np.abs(syn_zo.T)) % syn_zo.T.shape[1]
301 | tuning_thickness = tuning_trace * dz_step
302 |
303 | # Plotting Code
304 | [ntrc, nsamp] = syn_zo.shape
305 |
306 | fig = plt.figure(figsize=(12, 14))
307 | fig.set_facecolor('white')
308 |
309 | gs = gridspec.GridSpec(3, 1, height_ratios=[1, 1, 1])
310 |
311 | ax0 = fig.add_subplot(gs[0])
312 | ax0.plot(lyr_times[:, 0], color='blue', lw=1.5)
313 | ax0.plot(lyr_times[:, 1], color='red', lw=1.5)
314 | ax0.set_ylim((min_plot_time, max_plot_time))
315 | ax0.invert_yaxis()
316 | ax0.set_xlabel('Thickness (m)')
317 | ax0.set_ylabel('Time (s)')
318 | plt.text(2,
319 | min_plot_time + (lyr_times[0, 0] - min_plot_time) / 2.,
320 | 'Layer 1',
321 | fontsize=16)
322 | plt.text(dz_max / dz_step - 2,
323 | lyr_times[-1, 0] + (lyr_times[-1, 1] - lyr_times[-1, 0]) / 2.,
324 | 'Layer 2',
325 | fontsize=16,
326 | horizontalalignment='right')
327 | plt.text(2,
328 | lyr_times[0, 0] + (max_plot_time - lyr_times[0, 0]) / 2.,
329 | 'Layer 3',
330 | fontsize=16)
331 | plt.gca().xaxis.tick_top()
332 | plt.gca().xaxis.set_label_position('top')
333 | ax0.set_xlim((-excursion, ntrc + excursion))
334 |
335 | ax1 = fig.add_subplot(gs[1])
336 | plot_vawig(ax1, syn_zo, t, excursion, highlight=tuning_trace)
337 | ax1.plot(lyr_times[:, 0], color='blue', lw=1.5)
338 | ax1.plot(lyr_times[:, 1], color='red', lw=1.5)
339 | ax1.set_ylim((min_plot_time, max_plot_time))
340 | ax1.invert_yaxis()
341 | ax1.set_xlabel('Thickness (m)')
342 | ax1.set_ylabel('Time (s)')
343 |
344 | ax2 = fig.add_subplot(gs[2])
345 | ax2.plot(syn_zo[:, lyr_indx[:, 0]], color='blue')
346 | ax2.set_xlim((-excursion, ntrc + excursion))
347 | ax2.axvline(tuning_trace, color='k', lw=2)
348 | ax2.grid()
349 | ax2.set_title('Upper interface amplitude')
350 | ax2.set_xlabel('Thickness (m)')
351 | ax2.set_ylabel('Amplitude')
352 | plt.text(tuning_trace + 2,
353 | plt.ylim()[0] * 1.1,
354 | 'tuning thickness = {0} m'.format(str(tuning_thickness)),
355 | fontsize=16)
356 |
357 | plt.show()
358 |
359 |
360 |
361 |
362 |
363 |
--------------------------------------------------------------------------------
/PyOSGPUP/wavelet.py:
--------------------------------------------------------------------------------
1 | # Ref: https://gist.github.com/rowanc1/8338665
2 | import numpy as np
3 | pi = np.pi
4 |
5 |
6 | def getRicker(f, t):
7 | #assert len(f) == 1, 'Ricker wavelet needs 1 frequency as input'
8 | # f = f[0]
9 | pift = pi * f * t
10 | wav = (1 - 2 * pift ** 2) * np.exp(-pift ** 2)
11 | return wav
12 |
13 |
14 | def getOrmsby(f, t):
15 | assert len(f) == 4, 'Ormsby wavelet needs 4 frequencies as input'
16 | f = np.sort(f) # Ormsby wavelet frequencies must be in increasing order
17 | pif = pi * f
18 | den1 = pif[3] - pif[2]
19 | den2 = pif[1] - pif[0]
20 | term1 = (pif[3] * np.sinc(pif[3] * t)) ** 2 - (pif[2] * np.sinc(pif[2])) ** 2
21 | term2 = (pif[1] * np.sinc(pif[1] * t)) ** 2 - (pif[0] * np.sinc(pif[0])) ** 2
22 |
23 | wav = term1 / den1 - term2 / den2
24 | return wav
25 |
26 |
27 | def getKlauder(f, t, T=5.0):
28 | assert len(f) == 2, 'Klauder wavelet needs 2 frequencies as input'
29 |
30 | k = np.diff(f) / T
31 | f0 = np.sum(f) / 2.0
32 | wav = np.real(np.sin(pi * k * t * (T - t)) / (pi * k * t) * np.exp(2 * pi * 1j * f0 * t))
33 | return wav
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PyOSGPUP
2 |
3 | [](https://badge.fury.io/gh/Metkom%2FPyOSGPUP)
4 | [](https://travis-ci.org/Metkom/PyOSGPUP)
5 | 
6 | [](https://badge.fury.io/py/PyOSGPUP)
7 | [](https://pypi.python.org/pypi/PyOSGPUP/)
8 | 
9 | 
10 |
11 | 
12 | 
13 | [](http://hits.dwyl.com/Metkom/PyOSGPUP)
14 | [](https://pypi.python.org/pypi/PyOSGPUP/)
15 | 
16 | 
17 |
18 | [](http://inch-ci.org/mheriyanto/PyOSGPUP/hapi-auth-jwt2)
19 | [](https://github.com/Metkom/PyOSGPUP/issues)
20 | 
21 |
22 | A python packages for geophysical data processing modeling, inversion and interpretation. Please check here: for [official website](https://sites.google.com/site/metkomup/pyosgpup) and [package](https://pypi.org/project/PyOSGPUP/).
23 |
24 | Teknik Geofisika, Universitas Pertamina Jl. Teuku Nyak Arief, Simprug, South Jakarta, DKI Jakarta, Indonesia, 12220. email: metkom.up@gmail.com
25 |
26 | ## Requirement
27 |
28 | ```
29 | pip3 install -r requirements.txt
30 | ```
31 |
32 |
33 | ## Installation
34 |
35 | ```
36 | pip install PyOSGPUP
37 | or
38 | pip3 install PyOSGPUP
39 | ```
40 | ## User Manual
41 | User manual for this package avalaible in Bahasa ([download](https://figshare.com/articles/Petunjuk_Penggunaan_PyOSGPUP_versi_1_0_3/7325723)). Short example:
42 |
43 | **1. Create wavelet**
44 | ```python
45 | import numpy as np
46 | import PyOSGPUP.wavelet as wav
47 | import matplotlib.pyplot as plt
48 |
49 | t = np.arange(-0.4 / 2, (0.4 / 2) + 0.004, 0.004)
50 | # frequency
51 | fgR = np.array([10]) # 1 freq
52 | fgO = np.array([5, 10, 15, 20]) # 4 fred
53 | fgK = np.array([5, 10]) # 2 fred
54 | gR = wav.getRicker(fgR, t)
55 | gO = wav.getOrmsby(fgO, t)
56 | gK = wav.getKlauder(fgK, t)
57 |
58 | plt.figure()
59 | plt.plot(t, gR, linewidth=2, color="blue")
60 | plt.plot(t, gO, linewidth=2, color="red")
61 | plt.plot(t, gK, linewidth=2, color="green")
62 | plt.title('Wavelet')
63 | plt.xlabel('time [ms]')
64 | plt.ylabel('amplitude')
65 | plt.legend(['Ricker', 'Ormsby', 'Kaluder'])
66 | plt.show()
67 | ```
68 |
69 |
70 |
71 |
72 |
73 | **2. Read data segy**
74 |
75 | Please put [shotgather.sgy](https://github.com/cultpenguin/segypy/blob/master/example/shotgather.sgy) file in your directory code.
76 |
77 | ```python
78 | import PyOSGPUP.segypy as segypy
79 |
80 | filename = 'shotgather.sgy'
81 |
82 | # Set verbose level
83 | segypy.verbose = 1
84 | SH = segypy.getSegyHeader(filename)
85 |
86 | # Read Segy File
87 | [Data, SH, STH] = segypy.readSegy(filename)
88 |
89 | # Plot Segy filwe
90 | scale = 1e-9
91 |
92 | # wiggle plot
93 | segypy.wiggle(Data, SH, 1e-9)
94 |
95 | # image plot
96 | segypy.image(Data, SH, scale)
97 | ```
98 |
99 |
100 |
101 |
102 |
103 | **3. Create synthetic seismogram**
104 | ```python
105 | from PyOSGPUP.synthe_seismo import plotLogsInteract, plotTimeDepth, plotSeismogram
106 | import matplotlib.pyplot as plt
107 |
108 | # Synthetic Seismogram
109 | d = [0., 50., 100.] # Position of top of each layer (m)
110 | v = [500., 1000., 1500.] # Velocity of each layer (m/s)
111 | rho = [2000., 2300., 2500.] # Density of each layer (kg/m^3)
112 | wavtyp = 'RICKER' # Wavelet type
113 | wavf = 50. # Wavelet Frequency
114 | usingT = False # Use Transmission Coefficients?
115 |
116 | plotLogsInteract(d[1], d[2], rho[0], rho[1], rho[2], v[0], v[1], v[2])
117 | plt.show()
118 |
119 | plotTimeDepth(d, v)
120 | plt.show()
121 |
122 | plotSeismogram(d, rho, v, 50., wavA=1., noise=0., usingT=True, wavtyp='RICKER')
123 | plt.show()
124 | ```
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 | ## Citation
137 | If you find this project useful for your research, please use the following BibTeX entry.
138 |
139 |
140 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | PyOSGPUP: Python, Open-source
2 | =============================
3 |
4 | PuOSGPUP: Python Library that is Open-source created by
5 | Geophysical Engineering, Universitas Pertamina
6 |
7 | A python packages for geophysical data processing, modeling, and interpretation.
8 |
9 | Teknik Geofisika, Universitas Pertamina
10 | Jl. Teuku Nyak Arief, Simprug, South Jakarta, DKI Jakarta, Indonesia, 12220.
11 | email: metkom.up@gmail.com
--------------------------------------------------------------------------------
/build/lib/PyOSGPUP/__init__.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 |
3 | from PyOSGPUP import wavelet
4 | from PyOSGPUP import segypy
5 | from PyOSGPUP import tuning_wedge_acces
6 | from PyOSGPUP import signalpy
7 |
8 | __version__ = '1.0.3'
9 | __author__ = 'PyOSGPUP Team'
10 | __license__ = 'MIT'
11 | __copyright__ = '2018, PyOSGPUP Team, https://sites.google.com/site/metkomup/pyosgpup'
12 |
--------------------------------------------------------------------------------
/build/lib/PyOSGPUP/segypy.py:
--------------------------------------------------------------------------------
1 | """
2 | A python module for reading/writing/manipuating
3 | SEG-Y formatted filed
4 |
5 | segy.readSegy : Read SEGY file
6 | segy.getSegyHeader : Get SEGY header
7 | segy.getSegyTraceHeader : Get SEGY Trace header
8 | segy.getAllSegyTraceHeaders : Get all SEGY Trace headers
9 | segy.getSegyTrace : Get SEGY Trace heder and trace data for one trace
10 |
11 | segy.writeSegy : Write a data to a SEGY file
12 | segy.writeSegyStructure : Writes a segypy data structure to a SEGY file
13 |
14 | segy.getValue : Get a value from a binary string
15 | segy.ibm2ieee : Convert IBM floats to IEEE
16 |
17 | segy.version : The version of SegyPY
18 | segy.verbose : Amount of verbose information to the screen
19 | """
20 | #
21 | # segypy : A Python module for reading and writing SEG-Y formatted data
22 | #
23 | # (C) Thomas Mejer Hansen, 2005-2016
24 | #
25 | # contributions from
26 | # - Pete Forman
27 | #
28 | # modified by Andrew Squelch 2007 : sub-version 0.3.1
29 | from __future__ import division
30 | from __future__ import print_function
31 |
32 | import struct, sys # modified by A Squelch
33 |
34 | import numpy as np
35 |
36 |
37 | # SOME GLOBAL PARAMETERS
38 | version = '0.3.1' # modified by A Squelch
39 | verbose = 1;
40 |
41 | # endian='>' # Big Endian # modified by A Squelch
42 | # endian='<' # Little Endian
43 | # endian='=' # Native
44 |
45 | l_int = struct.calcsize('i')
46 | l_uint = struct.calcsize('I')
47 | l_long = 4;
48 | # Next line gives wrong result on Linux!! (gives 8 instead of 4)
49 | # l_long = struct.calcsize('l')
50 | l_ulong = struct.calcsize('L')
51 | l_short = struct.calcsize('h')
52 | l_ushort = struct.calcsize('H')
53 | l_char = struct.calcsize('c')
54 | l_uchar = struct.calcsize('B')
55 | l_float = struct.calcsize('f')
56 |
57 | ##############
58 | # INIT
59 |
60 | ##############
61 | # %% Initialize SEGY HEADER
62 | SH_def = {"Job": {"pos": 3200, "type": "int32", "def": 0}}
63 | SH_def["Line"] = {"pos": 3204, "type": "int32", "def": 0}
64 | SH_def["Reel"] = {"pos": 3208, "type": "int32", "def": 0}
65 | SH_def["DataTracePerEnsemble"] = {"pos": 3212, "type": "int16", "def": 0}
66 | SH_def["AuxiliaryTracePerEnsemble"] = {"pos": 3214, "type": "int16", "def": 0}
67 | SH_def["dt"] = {"pos": 3216, "type": "uint16", "def": 1000}
68 | SH_def["dtOrig"] = {"pos": 3218, "type": "uint16", "def": 1000}
69 | SH_def["ns"] = {"pos": 3220, "type": "uint16", "def": 0}
70 | SH_def["nsOrig"] = {"pos": 3222, "type": "uint16", "def": 0}
71 | SH_def["DataSampleFormat"] = {"pos": 3224, "type": "int16", "def": 5}
72 | SH_def["DataSampleFormat"]["descr"] = {0: {
73 | 1: "IBM Float",
74 | 2: "32 bit Integer",
75 | 3: "16 bit Integer",
76 | 8: "8 bit Integer"}}
77 |
78 | SH_def["DataSampleFormat"]["descr"][1] = {
79 | 1: "IBM Float",
80 | 2: "32 bit Integer",
81 | 3: "16 bit Integer",
82 | 5: "IEEE",
83 | 8: "8 bit Integer"}
84 |
85 | SH_def["DataSampleFormat"]["bps"] = {0: {
86 | 1: 4,
87 | 2: 4,
88 | 3: 2,
89 | 8: 1}}
90 | SH_def["DataSampleFormat"]["bps"][1] = {
91 | 1: 4,
92 | 2: 4,
93 | 3: 2,
94 | 5: 4,
95 | 8: 1}
96 | SH_def["DataSampleFormat"]["datatype"] = {0: {
97 | 1: 'ibm',
98 | 2: 'l',
99 | 3: 'h',
100 | 8: 'B'}}
101 | SH_def["DataSampleFormat"]["datatype"][1] = {
102 | 1: 'ibm',
103 | 2: 'l',
104 | 3: 'h',
105 | # 5: 'float',
106 | 5: 'f',
107 | 8: 'B'}
108 |
109 | SH_def["EnsembleFold"] = {"pos": 3226, "type": "int16", "def": 0}
110 | SH_def["TraceSorting"] = {"pos": 3228, "type": "int16", "def": 0}
111 | SH_def["VerticalSumCode"] = {"pos": 3230, "type": "int16", "def": 0}
112 | SH_def["SweepFrequencyEnd"] = {"pos": 3234, "type": "int16", "def": 0}
113 | SH_def["SweepLength"] = {"pos": 3236, "type": "int16", "def": 0}
114 | SH_def["SweepType"] = {"pos": 3238, "type": "int16", "def": 0}
115 | SH_def["SweepChannel"] = {"pos": 3240, "type": "int16", "def": 0}
116 | SH_def["SweepTaperlengthStart"] = {"pos": 3242, "type": "int16", "def": 0}
117 | SH_def["SweepTaperLengthEnd"] = {"pos": 3244, "type": "int16", "def": 0}
118 | SH_def["TaperType"] = {"pos": 3246, "type": "int16", "def": 0}
119 | SH_def["CorrelatedDataTraces"] = {"pos": 3248, "type": "int16", "def": 0}
120 | SH_def["BinaryGain"] = {"pos": 3250, "type": "int16", "def": 0}
121 | SH_def["AmplitudeRecoveryMethod"] = {"pos": 3252, "type": "int16", "def": 0}
122 | SH_def["MeasurementSystem"] = {"pos": 3254, "type": "int16", "def": 0}
123 | SH_def["ImpulseSignalPolarity"] = {"pos": 3256, "type": "int16", "def": 0}
124 | SH_def["VibratoryPolarityCode"] = {"pos": 3258, "type": "int16", "def": 0}
125 | SH_def["Unassigned1"] = {"pos": 3260, "type": "int16", "n": 120, "def": 0}
126 | SH_def["SegyFormatRevisionNumber"] = {"pos": 3500, "type": "uint16", "def": 100}
127 | SH_def["FixedLengthTraceFlag"] = {"pos": 3502, "type": "uint16", "def": 0}
128 | SH_def["NumberOfExtTextualHeaders"] = {"pos": 3504, "type": "uint16", "def": 0}
129 | SH_def["Unassigned2"] = {"pos": 3506, "type": "int16", "n": 47, "def": 0}
130 |
131 | ##############
132 | # %% Initialize SEGY TRACE HEADER SPECIFICATION
133 | STH_def = {"TraceSequenceLine": {"pos": 0, "type": "int32"}}
134 | STH_def["TraceSequenceFile"] = {"pos": 4, "type": "int32"}
135 | STH_def["FieldRecord"] = {"pos": 8, "type": "int32"}
136 | STH_def["TraceNumber"] = {"pos": 12, "type": "int32"}
137 | STH_def["EnergySourcePoint"] = {"pos": 16, "type": "int32"}
138 | STH_def["cdp"] = {"pos": 20, "type": "int32"}
139 | STH_def["cdpTrace"] = {"pos": 24, "type": "int32"}
140 | STH_def["TraceIdenitifactionCode"] = {"pos": 28, "type": "uint16"} # 'int16'); % 28
141 | STH_def["TraceIdenitifactionCode"]["descr"] = {0: {
142 | 1: "Seismic data",
143 | 2: "Dead",
144 | 3: "Dummy",
145 | 4: "Time Break",
146 | 5: "Uphole",
147 | 6: "Sweep",
148 | 7: "Timing",
149 | 8: "Water Break"}}
150 | STH_def["TraceIdenitifactionCode"]["descr"][1] = {
151 | -1: "Other",
152 | 0: "Unknown",
153 | 1: "Seismic data",
154 | 2: "Dead",
155 | 3: "Dummy",
156 | 4: "Time break",
157 | 5: "Uphole",
158 | 6: "Sweep",
159 | 7: "Timing",
160 | 8: "Waterbreak",
161 | 9: "Near-field gun signature",
162 | 10: "Far-field gun signature",
163 | 11: "Seismic pressure sensor",
164 | 12: "Multicomponent seismic sensor - Vertical component",
165 | 13: "Multicomponent seismic sensor - Cross-line component",
166 | 14: "Multicomponent seismic sensor - In-line component",
167 | 15: "Rotated multicomponent seismic sensor - Vertical component",
168 | 16: "Rotated multicomponent seismic sensor - Transverse component",
169 | 17: "Rotated multicomponent seismic sensor - Radial component",
170 | 18: "Vibrator reaction mass",
171 | 19: "Vibrator baseplate",
172 | 20: "Vibrator estimated ground force",
173 | 21: "Vibrator reference",
174 | 22: "Time-velocity pairs"}
175 | STH_def["NSummedTraces"] = {"pos": 30, "type": "int16"} # 'int16'); % 30
176 | STH_def["NStackedTraces"] = {"pos": 32, "type": "int16"} # 'int16'); % 32
177 | STH_def["DataUse"] = {"pos": 34, "type": "int16"} # 'int16'); % 34
178 | STH_def["DataUse"]["descr"] = {0: {
179 | 1: "Production",
180 | 2: "Test"}}
181 | STH_def["DataUse"]["descr"][1] = STH_def["DataUse"]["descr"][0]
182 | STH_def["offset"] = {"pos": 36, "type": "int32"} # 'int32'); %36
183 | STH_def["ReceiverGroupElevation"] = {"pos": 40, "type": "int32"} # 'int32'); %40
184 | STH_def["SourceSurfaceElevation"] = {"pos": 44, "type": "int32"} # 'int32'); %44
185 | STH_def["SourceDepth"] = {"pos": 48, "type": "int32"} # 'int32'); %48
186 | STH_def["ReceiverDatumElevation"] = {"pos": 52, "type": "int32"} # 'int32'); %52
187 | STH_def["SourceDatumElevation"] = {"pos": 56, "type": "int32"} # 'int32'); %56
188 | STH_def["SourceWaterDepth"] = {"pos": 60, "type": "int32"} # 'int32'); %60
189 | STH_def["GroupWaterDepth"] = {"pos": 64, "type": "int32"} # 'int32'); %64
190 | STH_def["ElevationScalar"] = {"pos": 68, "type": "int16"} # 'int16'); %68
191 | STH_def["SourceGroupScalar"] = {"pos": 70, "type": "int16"} # 'int16'); %70
192 | STH_def["SourceX"] = {"pos": 72, "type": "int32"} # 'int32'); %72
193 | STH_def["SourceY"] = {"pos": 76, "type": "int32"} # 'int32'); %76
194 | STH_def["GroupX"] = {"pos": 80, "type": "int32"} # 'int32'); %80
195 | STH_def["GroupY"] = {"pos": 84, "type": "int32"} # 'int32'); %84
196 | STH_def["CoordinateUnits"] = {"pos": 88, "type": "int16"} # 'int16'); %88
197 | STH_def["CoordinateUnits"]["descr"] = {1: {
198 | 1: "Length (meters or feet)",
199 | 2: "Seconds of arc"}}
200 | STH_def["CoordinateUnits"]["descr"][1] = {
201 | 1: "Length (meters or feet)",
202 | 2: "Seconds of arc",
203 | 3: "Decimal degrees",
204 | 4: "Degrees, minutes, seconds (DMS)"}
205 | STH_def["WeatheringVelocity"] = {"pos": 90, "type": "int16"} # 'int16'); %90
206 | STH_def["SubWeatheringVelocity"] = {"pos": 92, "type": "int16"} # 'int16'); %92
207 | STH_def["SourceUpholeTime"] = {"pos": 94, "type": "int16"} # 'int16'); %94
208 | STH_def["GroupUpholeTime"] = {"pos": 96, "type": "int16"} # 'int16'); %96
209 | STH_def["SourceStaticCorrection"] = {"pos": 98, "type": "int16"} # 'int16'); %98
210 | STH_def["GroupStaticCorrection"] = {"pos": 100, "type": "int16"} # 'int16'); %100
211 | STH_def["TotalStaticApplied"] = {"pos": 102, "type": "int16"} # 'int16'); %102
212 | STH_def["LagTimeA"] = {"pos": 104, "type": "int16"} # 'int16'); %104
213 | STH_def["LagTimeB"] = {"pos": 106, "type": "int16"} # 'int16'); %106
214 | STH_def["DelayRecordingTime"] = {"pos": 108, "type": "int16"} # 'int16'); %108
215 | STH_def["MuteTimeStart"] = {"pos": 110, "type": "int16"} # 'int16'); %110
216 | STH_def["MuteTimeEND"] = {"pos": 112, "type": "int16"} # 'int16'); %112
217 | STH_def["ns"] = {"pos": 114, "type": "uint16"} # 'uint16'); %114
218 | STH_def["dt"] = {"pos": 116, "type": "uint16"} # 'uint16'); %116
219 | STH_def["GainType"] = {"pos": 119, "type": "int16"} # 'int16'); %118
220 | STH_def["GainType"]["descr"] = {0: {
221 | 1: "Fixes",
222 | 2: "Binary",
223 | 3: "Floating point"}}
224 | STH_def["GainType"]["descr"][1] = STH_def["GainType"]["descr"][0]
225 | STH_def["InstrumentGainConstant"] = {"pos": 120, "type": "int16"} # 'int16'); %120
226 | STH_def["InstrumentInitialGain"] = {"pos": 122, "type": "int16"} # 'int16'); %%122
227 | STH_def["Correlated"] = {"pos": 124, "type": "int16"} # 'int16'); %124
228 | STH_def["Correlated"]["descr"] = {0: {
229 | 1: "No",
230 | 2: "Yes"}}
231 | STH_def["Correlated"]["descr"][1] = STH_def["Correlated"]["descr"][0]
232 |
233 | STH_def["SweepFrequenceStart"] = {"pos": 126, "type": "int16"} # 'int16'); %126
234 | STH_def["SweepFrequenceEnd"] = {"pos": 128, "type": "int16"} # 'int16'); %128
235 | STH_def["SweepLength"] = {"pos": 130, "type": "int16"} # 'int16'); %130
236 | STH_def["SweepType"] = {"pos": 132, "type": "int16"} # 'int16'); %132
237 | STH_def["SweepType"]["descr"] = {0: {
238 | 1: "linear",
239 | 2: "parabolic",
240 | 3: "exponential",
241 | 4: "other"}}
242 | STH_def["SweepType"]["descr"][1] = STH_def["SweepType"]["descr"][0]
243 |
244 | STH_def["SweepTraceTaperLengthStart"] = {"pos": 134, "type": "int16"} # 'int16'); %134
245 | STH_def["SweepTraceTaperLengthEnd"] = {"pos": 136, "type": "int16"} # 'int16'); %136
246 | STH_def["TaperType"] = {"pos": 138, "type": "int16"} # 'int16'); %138
247 | STH_def["TaperType"]["descr"] = {0: {
248 | 1: "linear",
249 | 2: "cos2c",
250 | 3: "other"}}
251 | STH_def["TaperType"]["descr"][1] = STH_def["TaperType"]["descr"][0]
252 |
253 | STH_def["AliasFilterFrequency"] = {"pos": 140, "type": "int16"} # 'int16'); %140
254 | STH_def["AliasFilterSlope"] = {"pos": 142, "type": "int16"} # 'int16'); %142
255 | STH_def["NotchFilterFrequency"] = {"pos": 144, "type": "int16"} # 'int16'); %144
256 | STH_def["NotchFilterSlope"] = {"pos": 146, "type": "int16"} # 'int16'); %146
257 | STH_def["LowCutFrequency"] = {"pos": 148, "type": "int16"} # 'int16'); %148
258 | STH_def["HighCutFrequency"] = {"pos": 150, "type": "int16"} # 'int16'); %150
259 | STH_def["LowCutSlope"] = {"pos": 152, "type": "int16"} # 'int16'); %152
260 | STH_def["HighCutSlope"] = {"pos": 154, "type": "int16"} # 'int16'); %154
261 | STH_def["YearDataRecorded"] = {"pos": 156, "type": "int16"} # 'int16'); %156
262 | STH_def["DayOfYear"] = {"pos": 158, "type": "int16"} # 'int16'); %158
263 | STH_def["HourOfDay"] = {"pos": 160, "type": "int16"} # 'int16'); %160
264 | STH_def["MinuteOfHour"] = {"pos": 162, "type": "int16"} # 'int16'); %162
265 | STH_def["SecondOfMinute"] = {"pos": 164, "type": "int16"} # 'int16'); %164
266 | STH_def["TimeBaseCode"] = {"pos": 166, "type": "int16"} # 'int16'); %166
267 | STH_def["TimeBaseCode"]["descr"] = {0: {
268 | 1: "Local",
269 | 2: "GMT",
270 | 3: "Other"}}
271 | STH_def["TimeBaseCode"]["descr"][1] = {
272 | 1: "Local",
273 | 2: "GMT",
274 | 3: "Other",
275 | 4: "UTC"}
276 | STH_def["TraceWeightningFactor"] = {"pos": 168, "type": "int16"} # 'int16'); %170
277 | STH_def["GeophoneGroupNumberRoll1"] = {"pos": 170, "type": "int16"} # 'int16'); %172
278 | STH_def["GeophoneGroupNumberFirstTraceOrigField"] = {"pos": 172, "type": "int16"} # 'int16'); %174
279 | STH_def["GeophoneGroupNumberLastTraceOrigField"] = {"pos": 174, "type": "int16"} # 'int16'); %176
280 | STH_def["GapSize"] = {"pos": 176, "type": "int16"} # 'int16'); %178
281 | STH_def["OverTravel"] = {"pos": 178, "type": "int16"} # 'int16'); %178
282 | STH_def["OverTravel"]["descr"] = {0: {
283 | 1: "down (or behind)",
284 | 2: "up (or ahead)",
285 | 3: "other"}}
286 | STH_def["OverTravel"]["descr"][1] = STH_def["OverTravel"]["descr"][0]
287 |
288 | STH_def["cdpX"] = {"pos": 180, "type": "int32"} # 'int32'); %180
289 | STH_def["cdpY"] = {"pos": 184, "type": "int32"} # 'int32'); %184
290 | STH_def["Inline3D"] = {"pos": 188, "type": "int32"} # 'int32'); %188
291 | STH_def["Crossline3D"] = {"pos": 192, "type": "int32"} # 'int32'); %192
292 | STH_def["ShotPoint"] = {"pos": 192, "type": "int32"} # 'int32'); %196
293 | STH_def["ShotPointScalar"] = {"pos": 200, "type": "int16"} # 'int16'); %200
294 | STH_def["TraceValueMeasurementUnit"] = {"pos": 202, "type": "int16"} # 'int16'); %202
295 | STH_def["TraceValueMeasurementUnit"]["descr"] = {1: {
296 | -1: "Other",
297 | 0: "Unknown (should be described in Data Sample Measurement Units Stanza) ",
298 | 1: "Pascal (Pa)",
299 | 2: "Volts (V)",
300 | 3: "Millivolts (v)",
301 | 4: "Amperes (A)",
302 | 5: "Meters (m)",
303 | 6: "Meters Per Second (m/s)",
304 | 7: "Meters Per Second squared (m/&s2)Other",
305 | 8: "Newton (N)",
306 | 9: "Watt (W)"}}
307 | STH_def["TransductionConstantMantissa"] = {"pos": 204, "type": "int32"} # 'int32'); %204
308 | STH_def["TransductionConstantPower"] = {"pos": 208, "type": "int16"} # 'int16'); %208
309 | STH_def["TransductionUnit"] = {"pos": 210, "type": "int16"} # 'int16'); %210
310 | STH_def["TransductionUnit"]["descr"] = STH_def["TraceValueMeasurementUnit"]["descr"]
311 | STH_def["TraceIdentifier"] = {"pos": 212, "type": "int16"} # 'int16'); %212
312 | STH_def["ScalarTraceHeader"] = {"pos": 214, "type": "int16"} # 'int16'); %214
313 | STH_def["SourceType"] = {"pos": 216, "type": "int16"} # 'int16'); %216
314 | STH_def["SourceType"]["descr"] = {1: {
315 | -1: "Other (should be described in Source Type/Orientation stanza)",
316 | 0: "Unknown",
317 | 1: "Vibratory - Vertical orientation",
318 | 2: "Vibratory - Cross-line orientation",
319 | 3: "Vibratory - In-line orientation",
320 | 4: "Impulsive - Vertical orientation",
321 | 5: "Impulsive - Cross-line orientation",
322 | 6: "Impulsive - In-line orientation",
323 | 7: "Distributed Impulsive - Vertical orientation",
324 | 8: "Distributed Impulsive - Cross-line orientation",
325 | 9: "Distributed Impulsive - In-line orientation"}}
326 |
327 | STH_def["SourceEnergyDirectionMantissa"] = {"pos": 218, "type": "int32"} # 'int32'); %218
328 | STH_def["SourceEnergyDirectionExponent"] = {"pos": 222, "type": "int16"} # 'int16'); %222
329 | STH_def["SourceMeasurementMantissa"] = {"pos": 224, "type": "int32"} # 'int32'); %224
330 | STH_def["SourceMeasurementExponent"] = {"pos": 228, "type": "int16"} # 'int16'); %228
331 | STH_def["SourceMeasurementUnit"] = {"pos": 230, "type": "int16"} # 'int16'); %230
332 | STH_def["SourceMeasurementUnit"]["descr"] = {1: {
333 | -1: "Other (should be described in Source Measurement Unit stanza)",
334 | 0: "Unknown",
335 | 1: "Joule (J)",
336 | 2: "Kilowatt (kW)",
337 | 3: "Pascal (Pa)",
338 | 4: "Bar (Bar)",
339 | 4: "Bar-meter (Bar-m)",
340 | 5: "Newton (N)",
341 | 6: "Kilograms (kg)"}}
342 | STH_def["UnassignedInt1"] = {"pos": 232, "type": "int32"} # 'int32'); %232
343 | STH_def["UnassignedInt2"] = {"pos": 236, "type": "int32"} # 'int32'); %236
344 |
345 |
346 | ##############
347 | # %% FUNCTIONS
348 |
349 | def image(Data, SH={}, maxval=-1):
350 | """
351 | image(Data,SH,maxval)
352 | Image segy Data
353 | """
354 | import matplotlib.pylab as plt
355 |
356 | if (maxval<=0):
357 | Dmax = np.max(Data)
358 | maxval = -1*maxval*Dmax
359 |
360 | if 'time' in SH:
361 | t = SH['time']
362 | ntraces = SH['ntraces']
363 | ns = SH['ns']
364 | else:
365 | ns = Data.shape[0]
366 | t = np.arange(ns)
367 | ntraces = Data.shape[1]
368 | x = np.arange(ntraces)+1
369 |
370 | print(maxval)
371 | plt.pcolor(x, t, Data, vmin=-1*maxval, vmax=maxval)
372 | plt.colorbar()
373 | plt.axis('normal')
374 | plt.xlabel('Trace number')
375 | if 'time' in SH:
376 | plt.ylabel('Time (ms)')
377 | else:
378 | plt.ylabel('Sample number')
379 | if 'filename' in SH:
380 | plt.title(SH['filename'])
381 | plt.gca().invert_yaxis()
382 |
383 | #plt.grid(True)
384 | plt.show()
385 |
386 |
387 | # %%
388 | def wiggle(Data, SH={}, maxval=-1, skipt=1, lwidth=.1):
389 | """
390 | wiggle(Data,SH)
391 | """
392 | import matplotlib.pylab as plt
393 | import numpy as np
394 |
395 | if 'time' in SH:
396 | t = SH['time']
397 | ntraces = SH['ntraces']
398 | ns = SH['ns']
399 | else:
400 | ns=Data.shape[0]
401 | t=np.arange(ns)
402 | ntraces = Data.shape[1]
403 |
404 |
405 | if (maxval<=0):
406 | Dmax = np.max(Data)
407 | maxval = -1*maxval*Dmax
408 |
409 | for i in range(0, ntraces, skipt):
410 | trace = Data[:, i]
411 | trace[0] = 0
412 | trace[ns - 1] = 0
413 | plt.plot(i + trace / maxval, t, color='black', linewidth=lwidth)
414 | for a in range(len(trace)):
415 | if (trace[a] < 0):
416 | trace[a] = 0;
417 | # pylab.fill(i+Data[:,i]/maxval,t,color='k',facecolor='g')
418 | plt.fill(i + Data[:, i] / maxval, t, 'k', linewidth=0)
419 |
420 | plt.grid(True)
421 | plt.gca().invert_yaxis()
422 |
423 | plt.xlabel('Trace number')
424 | if 'time' in SH:
425 | plt.ylabel('Time (ms)')
426 | else:
427 | plt.ylabel('Sample number')
428 | if 'filename' in SH:
429 | plt.title(SH['filename'])
430 | plt.axes().set_xlim(-1, ntraces)
431 | plt.show()
432 |
433 |
434 | # %%
435 | def getDefaultSegyHeader(ntraces=100, ns=100):
436 | """
437 | SH=getDefaultSegyHeader()
438 | """
439 | # INITIALIZE DICTIONARY
440 | SH = {"Job": {"pos": 3200, "type": "int32", "def": 0}}
441 |
442 | for key in SH_def.keys():
443 |
444 | tmpkey = SH_def[key]
445 | if (tmpkey.has_key('def')):
446 | val = tmpkey['def']
447 | else:
448 | val = 0
449 | SH[key] = val
450 |
451 | SH["ntraces"] = ntraces;
452 | SH["ns"] = ns;
453 |
454 | return SH
455 |
456 |
457 | # %%
458 | def getDefaultSegyTraceHeaders(ntraces=100, ns=100, dt=1000):
459 | """
460 | SH=getDefaultSegyTraceHeader()
461 | """
462 | # INITIALIZE DICTIONARY
463 | STH = {"TraceSequenceLine": {"pos": 0, "type": "int32"}}
464 |
465 | for key in STH_def.keys():
466 |
467 | tmpkey = STH_def[key]
468 | if (tmpkey.has_key('def')):
469 | val = tmpkey['def']
470 | else:
471 | val = 0
472 | STH[key] = np.zeros(ntraces)
473 |
474 | for a in range(ntraces):
475 | STH["TraceSequenceLine"][a] = a + 1
476 | STH["TraceSequenceFile"][a] = a + 1
477 | STH["FieldRecord"][a] = 1000
478 | STH["TraceNumber"][a] = a + 1
479 | STH["ns"][a] = ns
480 | STH["dt"][a] = dt
481 | return STH
482 |
483 |
484 | # %%
485 | def getSegyTraceHeader(SH, THN='cdp', data='none', endian='>'): # modified by A Squelch
486 | """
487 | getSegyTraceHeader(SH,TraceHeaderName)
488 | """
489 |
490 | bps = getBytePerSample(SH)
491 |
492 | if (data == 'none'):
493 | data = open(SH["filename"], 'rb').read()
494 |
495 | # MAKE SOME LOOKUP TABLE THAT HOLDS THE LOCATION OF HEADERS
496 | # THpos=TraceHeaderPos[THN]
497 | THpos = STH_def[THN]["pos"]
498 | THformat = STH_def[THN]["type"]
499 | ntraces = SH["ntraces"]
500 | thv = np.zeros(ntraces)
501 | for itrace in range(1, ntraces + 1, 1):
502 | i = itrace
503 |
504 | pos = THpos + 3600 + (SH["ns"] * bps + 240) * (itrace - 1);
505 |
506 | txt = "getSegyTraceHeader : Reading trace header " + THN + " " + str(itrace) + " of " + str(
507 | ntraces) + " " + str(pos)
508 |
509 | printverbose(txt, 20);
510 | thv[itrace - 1], index = getValue(data, pos, THformat, endian, 1)
511 | txt = "getSegyTraceHeader : " + THN + "=" + str(thv[itrace - 1])
512 | printverbose(txt, 30);
513 |
514 | return thv
515 |
516 |
517 | # %%
518 | def getLastSegyTraceHeader(SH, THN='cdp', data='none', endian='>'): # added by A Squelch
519 | """
520 | getLastSegyTraceHeader(SH,TraceHeaderName)
521 | """
522 |
523 | bps = getBytePerSample(SH)
524 |
525 | if (data == 'none'):
526 | data = open(SH["filename"]).read()
527 |
528 | # SET PARAMETERS THAT DEFINE THE LOCATION OF THE LAST HEADER
529 | # AND THE TRACE NUMBER KEY FIELD
530 | THpos = STH_def[THN]["pos"]
531 | THformat = STH_def[THN]["type"]
532 | ntraces = SH["ntraces"]
533 |
534 | pos = THpos + 3600 + (SH["ns"] * bps + 240) * (ntraces - 1);
535 |
536 | txt = "getLastSegyTraceHeader : Reading last trace header " + THN + " " + str(pos)
537 |
538 | printverbose(txt, 20);
539 | thv, index = getValue(data, pos, THformat, endian, 1)
540 | txt = "getLastSegyTraceHeader : " + THN + "=" + str(thv)
541 | printverbose(txt, 30);
542 |
543 | return thv
544 |
545 |
546 | # %%
547 | def getAllSegyTraceHeaders(SH, data='none'):
548 | SegyTraceHeaders = {'filename': SH["filename"]}
549 |
550 | printverbose('getAllSegyTraceHeaders : trying to get all segy trace headers', 2)
551 |
552 | if (data == 'none'):
553 | data = open(SH["filename"], 'rb').read()
554 |
555 | for key in STH_def.keys():
556 | sth = getSegyTraceHeader(SH, key, data)
557 | SegyTraceHeaders[key] = sth
558 | txt = "getAllSegyTraceHeaders : " + key
559 | printverbose(txt, 10)
560 |
561 | return SegyTraceHeaders
562 |
563 |
564 | # %%
565 | def readSegy(filename, endian='>'): # modified by A Squelch
566 | """
567 | Data,SegyHeader,SegyTraceHeaders=getSegyHeader(filename)
568 | """
569 |
570 | printverbose("readSegy : Trying to read " + filename, 0)
571 |
572 | data = open(filename, 'rb').read()
573 |
574 | filesize = len(data)
575 |
576 | SH = getSegyHeader(filename, endian) # modified by A Squelch
577 |
578 | bps = getBytePerSample(SH)
579 |
580 | ntraces = (filesize - 3600) / (SH['ns'] * bps + 240)
581 | # ntraces = 100
582 |
583 | printverbose("readSegy : Length of data : " + str(filesize), 2)
584 |
585 | SH["ntraces"] = np.int(ntraces);
586 |
587 | # ndummy_samples=240/bps # modified by A Squelch
588 | # printverbose("readSegy : ndummy_samples="+str(ndummy_samples),6) # modified by A Squelch
589 | printverbose("readSegy : ntraces=" + str(ntraces) + " nsamples=" + str(SH['ns']), 2)
590 |
591 | # GET TRACE
592 | index = 3600;
593 | nd = int((filesize - 3600) / bps)
594 |
595 | printverbose("filesize=%d" % filesize)
596 | printverbose("bps=%5d" % bps)
597 | printverbose("nd=%5d" % nd)
598 |
599 | # modified by A Squelch
600 | # this portion replaced by call to new function: readSegyData
601 | Data, SH, SegyTraceHeaders = readSegyData(data, SH, nd, bps, index, endian)
602 |
603 | printverbose("readSegy : Read segy data", 2) # modified by A Squelch
604 |
605 | return Data, SH, SegyTraceHeaders
606 |
607 |
608 | # %%
609 | def readSegyData(data, SH, nd, bps, index, endian='>'): # added by A Squelch
610 | """
611 | Data,SegyHeader,SegyTraceHeaders=readSegyData(data,SH,nd,bps,index)
612 |
613 | This function separated out from readSegy so that it can also be
614 | called from other external functions - by A Squelch.
615 | """
616 |
617 | # Calulate number of dummy samples needed to account for Trace Headers
618 | ndummy_samples = int(240 / bps)
619 | printverbose("readSegyData : ndummy_samples=" + str(ndummy_samples), 6)
620 |
621 | # READ ALL SEGY TRACE HEADRES
622 | STH = getAllSegyTraceHeaders(SH, data)
623 |
624 | printverbose("readSegyData : Reading segy data", 1)
625 |
626 | # READ ALL DATA EXCEPT FOR SEGY HEADER
627 | # Data = np.zeros((SH['ns'],ntraces))
628 |
629 | revision = SH["SegyFormatRevisionNumber"]
630 | if (revision == 100):
631 | revision = 1
632 | if (revision == 256): # added by A Squelch
633 | revision = 1
634 |
635 | dsf = SH["DataSampleFormat"]
636 |
637 | try: # block added by A Squelch
638 | DataDescr = SH_def["DataSampleFormat"]["descr"][revision][dsf]
639 | except KeyError:
640 | print("")
641 | print(" An error has ocurred interpreting a SEGY binary header key")
642 | print(" Please check the Endian setting for this file: ", SH["filename"])
643 | sys.exit()
644 |
645 | printverbose("readSegyData : SEG-Y revision = " + str(revision), 1)
646 | printverbose("readSegyData : DataSampleFormat=" + str(dsf) + "(" + DataDescr + ")", 1)
647 |
648 | if (SH["DataSampleFormat"] == 1):
649 | printverbose("readSegyData : Assuming DSF=1, IBM FLOATS", 2)
650 | Data1 = getValue(data, index, 'ibm', endian, nd)
651 | elif (SH["DataSampleFormat"] == 2):
652 | printverbose("readSegyData : Assuming DSF=" + str(SH["DataSampleFormat"]) + ", 32bit INT", 2)
653 | Data1 = getValue(data, index, 'l', endian, nd)
654 | elif (SH["DataSampleFormat"] == 3):
655 | printverbose("readSegyData : Assuming DSF=" + str(SH["DataSampleFormat"]) + ", 16bit INT", 2)
656 | Data1 = getValue(data, index, 'h', endian, nd)
657 | elif (SH["DataSampleFormat"] == 5):
658 | printverbose("readSegyData : Assuming DSF=" + str(SH["DataSampleFormat"]) + ", IEEE", 2)
659 | Data1 = getValue(data, index, 'float', endian, nd)
660 | elif (SH["DataSampleFormat"] == 8):
661 | printverbose("readSegyData : Assuming DSF=" + str(SH["DataSampleFormat"]) + ", 8bit CHAR", 2)
662 | Data1 = getValue(data, index, 'B', endian, nd)
663 | else:
664 | printverbose("readSegyData : DSF=" + str(SH["DataSampleFormat"]) + ", NOT SUPORTED", 2)
665 |
666 | Data = Data1[0]
667 |
668 | printverbose("readSegyData : - reshaping", 2)
669 | printverbose(" ns=" + str(SH['ns']),-2)
670 | Data = np.reshape(np.array(Data), (SH['ntraces'], SH['ns'] + ndummy_samples))
671 | printverbose("readSegyData : - stripping header dummy data", 2)
672 | Data = Data[:, ndummy_samples:(SH['ns'] + ndummy_samples)]
673 | printverbose("readSegyData : - transposing", 2)
674 | Data = np.transpose(Data)
675 |
676 | # SOMEONE NEEDS TO IMPLEMENT A NICER WAY DO DEAL WITH DSF=8
677 | if (SH["DataSampleFormat"] == 8):
678 | for i in np.arange(SH['ntraces']):
679 | for j in np.arange(SH['ns']):
680 | if Data[i][j] > 128:
681 | Data[i][j] = Data[i][j] - 256
682 |
683 | printverbose("readSegyData : Finished reading segy data", 1)
684 |
685 | return Data, SH, STH
686 |
687 |
688 | # %%
689 | def getSegyTrace(SH, itrace, endian='>'): # modified by A Squelch
690 | """
691 | SegyTraceHeader,SegyTraceData=getSegyTrace(SegyHeader,itrace)
692 | itrace : trace number to read
693 | THIS DEF IS NOT UPDATED. NOT READY TO USE
694 | """
695 | data = open(SH["filename"], 'rb').read()
696 |
697 | bps = getBytePerSample(SH)
698 |
699 | # GET TRACE HEADER
700 | index = 3200 + (itrace - 1) * (240 + SH['ns'] * bps)
701 | SegyTraceHeader = [];
702 | # print index
703 |
704 | # GET TRACE
705 | index = 3200 + (itrace - 1) * (240 + SH['ns'] * bps) + 240
706 | SegyTraceData = getValue(data, index, 'float', endian, SH['ns'])
707 | return SegyTraceHeader, SegyTraceData
708 |
709 |
710 | # %%
711 | def getSegyHeader(filename, endian='>'): # modified by A Squelch
712 | """
713 | SegyHeader=getSegyHeader(filename)
714 | """
715 |
716 | data = open(filename, 'rb').read()
717 |
718 | SegyHeader = {'filename': filename}
719 |
720 | j = 0;
721 | for key in SH_def.keys():
722 | j = j + 1;
723 | pos = SH_def[key]["pos"]
724 | format = SH_def[key]["type"]
725 |
726 | txt = "i=%3d, pos=%5d, format=%2s, key=%s" % (j, pos, format, key);
727 | printverbose(txt, 10)
728 |
729 | SegyHeader[key], index = getValue(data, pos, format, endian);
730 |
731 | txt = "SegyHeader[%s] = %f" % (key, SegyHeader[key])
732 | printverbose(txt, 2)
733 |
734 | # SET NUMBER OF BYTES PER DATA SAMPLE
735 | bps = getBytePerSample(SegyHeader)
736 |
737 | filesize = len(data)
738 | ntraces = (filesize - 3600) / (SegyHeader['ns'] * bps + 240)
739 | SegyHeader["ntraces"] = ntraces
740 | SegyHeader["time"]=np.arange(SegyHeader['ns']) * SegyHeader['dt'] / 1e+6
741 |
742 |
743 | printverbose('getSegyHeader : succesfully read ' + filename, 1)
744 |
745 | return SegyHeader
746 |
747 |
748 | # %%
749 | def writeSegy(filename, Data, dt=1000, STHin={}, SHin={}):
750 | """
751 | writeSegy(filename,Data,dt)
752 |
753 | Write SEGY
754 |
755 | See also readSegy
756 |
757 | (c) 2005, Thomas Mejer Hansen
758 |
759 | MAKE OPTIONAL INPUT FOR ALL SEGYHTRACEHEADER VALUES
760 |
761 | """
762 |
763 | printverbose("writeSegy : Trying to write " + filename, 0)
764 |
765 | N = Data.shape
766 | ns = N[0]
767 | ntraces = N[1]
768 | print(ntraces)
769 | print(ns)
770 |
771 | SH = getDefaultSegyHeader(ntraces, ns);
772 | STH = getDefaultSegyTraceHeaders(ntraces, ns, dt)
773 |
774 | # ADD STHin, if exists...
775 | for key in STHin.keys():
776 | print(key)
777 | for a in range(ntraces):
778 | STH[key] = STHin[key][a]
779 |
780 | # ADD SHin, if exists...
781 | for key in SHin.keys():
782 | print(key)
783 | SH[key] = SHin[key]
784 |
785 | writeSegyStructure(filename, Data, SH, STH)
786 |
787 |
788 | # %%
789 | def writeSegyStructure(filename, Data, SH, STH, endian='>'): # modified by A Squelch
790 | """
791 | writeSegyStructure(filename,Data,SegyHeader,SegyTraceHeaders)
792 |
793 | Write SEGY file using SegyPy data structures
794 |
795 | See also readSegy
796 |
797 | (c) 2005, Thomas Mejer Hansen
798 |
799 | """
800 |
801 | printverbose("writeSegyStructure : Trying to write " + filename, 0)
802 |
803 | f = open(filename, 'wb')
804 |
805 | # VERBOSE INF
806 | revision = SH["SegyFormatRevisionNumber"]
807 | dsf = SH["DataSampleFormat"]
808 | if (revision == 100):
809 | revision = 1
810 | if (revision == 256): # added by A Squelch
811 | revision = 1
812 |
813 | try: # block added by A Squelch
814 | DataDescr = SH_def["DataSampleFormat"]["descr"][revision][dsf]
815 | except KeyError:
816 | print("")
817 | print(" An error has ocurred interpreting a SEGY binary header key")
818 | print(" Please check the Endian setting for this file: ", SH["filename"])
819 | sys.exit()
820 |
821 | printverbose("writeSegyStructure : SEG-Y revision = " + str(revision), 1)
822 | printverbose("writeSegyStructure : DataSampleFormat=" + str(dsf) + "(" + DataDescr + ")", 1)
823 |
824 | # WRITE SEGY HEADER
825 |
826 | for key in SH_def.keys():
827 | pos = SH_def[key]["pos"]
828 | format = SH_def[key]["type"]
829 | value = SH[key]
830 |
831 | # SegyHeader[key],index = putValue(value,f,pos,format,endian);
832 | putValue(value, f, pos, format, endian);
833 |
834 | txt = str(pos) + " " + str(format) + " Reading " + key + "=" + str(value)
835 | # +"="+str(SegyHeader[key])
836 | # printverbose(txt,-1)
837 |
838 | # SEGY TRACES
839 |
840 | ctype = SH_def['DataSampleFormat']['datatype'][revision][dsf]
841 | bps = SH_def['DataSampleFormat']['bps'][revision][dsf]
842 |
843 | sizeT = 240 + SH['ns'] * bps;
844 |
845 | for itrace in range(SH['ntraces']):
846 | index = 3600 + itrace * sizeT
847 | printverbose('Writing Trace #' + str(itrace + 1) + '/' + str(SH['ntraces']), 10)
848 | # WRITE SEGY TRACE HEADER
849 | for key in STH_def.keys():
850 | pos = index + STH_def[key]["pos"]
851 | format = STH_def[key]["type"]
852 | value = STH[key][itrace]
853 | txt = str(pos) + " " + str(format) + " Writing " + key + "=" + str(value)
854 | printverbose(txt, 40)
855 | putValue(value, f, pos, format, endian);
856 |
857 | # Write Data
858 | cformat = endian + ctype
859 | for s in range(SH['ns']):
860 | strVal = struct.pack(cformat, Data[s, itrace])
861 | f.seek(index + 240 + s * struct.calcsize(cformat))
862 | f.write(strVal);
863 |
864 | f.close
865 |
866 | # return segybuffer
867 |
868 |
869 | # %%
870 | def putValue(value, fileid, index, ctype='l', endian='>', number=1):
871 | """
872 | putValue(data,index,ctype,endian,number)
873 | """
874 | if (ctype == 'l') | (ctype == 'long') | (ctype == 'int32'):
875 | size = l_long
876 | ctype = 'l'
877 | elif (ctype == 'L') | (ctype == 'ulong') | (ctype == 'uint32'):
878 | size = l_ulong
879 | ctype = 'L'
880 | elif (ctype == 'h') | (ctype == 'short') | (ctype == 'int16'):
881 | size = l_short
882 | ctype = 'h'
883 | elif (ctype == 'H') | (ctype == 'ushort') | (ctype == 'uint16'):
884 | size = l_ushort
885 | ctype = 'H'
886 | elif (ctype == 'c') | (ctype == 'char'):
887 | size = l_char
888 | ctype = 'c'
889 | elif (ctype == 'B') | (ctype == 'uchar'):
890 | size = l_uchar
891 | ctype = 'B'
892 | elif (ctype == 'f') | (ctype == 'float'):
893 | size = l_float
894 | ctype = 'f'
895 | elif (ctype == 'ibm'):
896 | size = l_float
897 | else:
898 | printverbose('Bad Ctype : ' + ctype, -1)
899 |
900 | cformat = endian + ctype * number
901 |
902 | printverbose('putValue : cformat : ' + cformat + ' ctype=' + ctype, 40)
903 |
904 | strVal = struct.pack(cformat, value)
905 | fileid.seek(index)
906 | fileid.write(strVal);
907 |
908 | return 1
909 |
910 |
911 | # %%
912 | def getValue(data, index, ctype='l', endian='>', number=1):
913 | """
914 | getValue(data,index,ctype,endian,number)
915 | """
916 | if (ctype == 'l') | (ctype == 'long') | (ctype == 'int32'):
917 | size = l_long
918 | ctype = 'l'
919 | elif (ctype == 'L') | (ctype == 'ulong') | (ctype == 'uint32'):
920 | size = l_ulong
921 | ctype = 'L'
922 | elif (ctype == 'h') | (ctype == 'short') | (ctype == 'int16'):
923 | size = l_short
924 | ctype = 'h'
925 | elif (ctype == 'H') | (ctype == 'ushort') | (ctype == 'uint16'):
926 | size = l_ushort
927 | ctype = 'H'
928 | elif (ctype == 'c') | (ctype == 'char'):
929 | size = l_char
930 | ctype = 'c'
931 | elif (ctype == 'B') | (ctype == 'uchar'):
932 | size = l_uchar
933 | ctype = 'B'
934 | elif (ctype == 'f') | (ctype == 'float'):
935 | size = l_float
936 | ctype = 'f'
937 | elif (ctype == 'ibm'):
938 | size = l_float
939 | ctype = 'ibm'
940 | else:
941 | printverbose('Bad Ctype : ' + ctype, -1)
942 |
943 | index_end = index + size * number
944 |
945 | printverbose("index=%d, number=%d, size=%d, ctype=%s" % (index, number, size, ctype), 8);
946 | printverbose("index, index_end = " + str(index) + "," + str(index_end), 9)
947 |
948 | if (ctype == 'ibm'):
949 | # ASSUME IBM FLOAT DATA
950 | Value = list(range(int(number)))
951 | for i in np.arange(number):
952 | index_ibm_start = i * 4 + index
953 | index_ibm_end = index_ibm_start + 4;
954 | ibm_val = ibm2ieee2(data[index_ibm_start:index_ibm_end])
955 | Value[i] = ibm_val;
956 | # this resturn an array as opposed to a tuple
957 | else:
958 | # ALL OTHER TYPES OF DATA
959 | cformat = 'f' * number
960 | cformat = endian + ctype * number
961 |
962 | printverbose("getValue : cformat : '" + cformat + "'", 11)
963 |
964 | Value = struct.unpack(cformat, data[index:index_end])
965 |
966 | if (ctype == 'B'):
967 | printverbose('getValue : Ineficient use of 1byte Integer...', -1)
968 |
969 | vtxt = 'getValue : ' + 'start=' + str(index) + ' size=' + str(size) + ' number=' + str(
970 | number) + ' Value=' + str(Value) + ' cformat=' + str(cformat)
971 | printverbose(vtxt, 20)
972 |
973 | if number == 1:
974 | return Value[0], index_end
975 | else:
976 | return Value, index_end
977 |
978 |
979 | # %%
980 | def print_version():
981 | print('SegyPY version is ', version)
982 |
983 |
984 | # %%
985 | def printverbose(txt, level=1):
986 | if level <= verbose:
987 | print('SegyPY' + version + ': ', txt)
988 |
989 |
990 | # %%
991 | ##############
992 | # MISC FUNCTIONS
993 | def ibm2Ieee(ibm_float):
994 | """
995 | ibm2Ieee(ibm_float)
996 | Used by permission
997 | (C) Secchi Angelo
998 | with thanks to Howard Lightstone and Anton Vredegoor.
999 | """
1000 | """
1001 | I = struct.unpack('>I',ibm_float)[0]
1002 | sign = [1,-1][bool(i & 0x100000000L)]
1003 | characteristic = ((i >> 24) & 0x7f) - 64
1004 | fraction = (i & 0xffffff)/float(0x1000000L)
1005 | return sign*16**characteristic*fraction
1006 | """
1007 |
1008 |
1009 | def ibm2ieee2(ibm_float):
1010 | """
1011 | ibm2ieee2(ibm_float)
1012 | Used by permission
1013 | (C) Secchi Angelo
1014 | with thanks to Howard Lightstone and Anton Vredegoor.
1015 | """
1016 | dividend = float(16 ** 6)
1017 |
1018 | if ibm_float == 0:
1019 | return 0.0
1020 | istic, a, b, c = struct.unpack('>BBBB', ibm_float)
1021 | if istic >= 128:
1022 | sign = -1.0
1023 | istic = istic - 128
1024 | else:
1025 | sign = 1.0
1026 | mant = float(a << 16) + float(b << 8) + float(c)
1027 | return sign * 16 ** (istic - 64) * (mant / dividend)
1028 |
1029 |
1030 | def getBytePerSample(SH):
1031 | revision = SH["SegyFormatRevisionNumber"]
1032 | if (revision == 100):
1033 | revision = 1
1034 | if (revision == 256): # added by A Squelch
1035 | revision = 1
1036 |
1037 | dsf = SH["DataSampleFormat"]
1038 |
1039 | try: # block added by A Squelch
1040 | bps = SH_def["DataSampleFormat"]["bps"][revision][dsf]
1041 | except KeyError:
1042 | print("")
1043 | print(" An error has ocurred interpreting a SEGY binary header key")
1044 | print(" Please check the Endian setting for this file: ", SH["filename"])
1045 | sys.exit()
1046 |
1047 | printverbose("getBytePerSample : bps=" + str(bps), 21);
1048 |
1049 | return bps
1050 |
1051 |
1052 | ##############
1053 | # segy class
1054 | class SegyTraceheaderClass:
1055 | def __init__(self):
1056 | self.cdp = 0
1057 |
1058 |
1059 | class SegyHeaderClass:
1060 | def __str__(self):
1061 | return "SegyHeaderClass "
1062 |
1063 | def __init__(self):
1064 | self.filename = 0
1065 | self.Trace = version
1066 |
1067 | def cdp(self):
1068 | return "Getting CDP trace header"
1069 |
1070 | def InlineX(self):
1071 | return "Getting CDP trace header"
1072 |
1073 |
1074 | class SegyClass:
1075 | STH_def = STH_def
1076 | SH_def = SH_def
1077 | STH = SegyTraceheaderClass()
1078 | SH = SegyHeaderClass()
1079 |
1080 | def __init__(self):
1081 | self.THOMAS = 'Thomas'
1082 |
--------------------------------------------------------------------------------
/build/lib/PyOSGPUP/signalpy.py:
--------------------------------------------------------------------------------
1 |
2 | import numpy as np
3 | from numpy.fft.fftpack import fft,ifft
4 |
5 | def hilbert(mag):
6 | """Compute the modified 1D discrete Hilbert transform
7 |
8 | Parameters
9 | ----------
10 | mag : ndarray
11 | The magnitude spectrum. Should be 1D with an even length, and
12 | preferably a fast length for FFT/IFFT.
13 | """
14 | # Adapted based on code by Niranjan Damera-Venkata,
15 | # Brian L. Evans and Shawn R. McCaslin (see refs for `minimum_phase`)
16 | sig = np.zeros(len(mag))
17 | # Leave Nyquist and DC at 0, knowing np.abs(fftfreq(N)[midpt]) == 0.5
18 | midpt = len(mag) // 2
19 | sig[1:midpt] = 1
20 | sig[midpt+1:] = -1
21 | # eventually if we want to support complex filters, we will need a
22 | # np.abs() on the mag inside the log, and should remove the .real
23 | recon = ifft(mag * np.exp(fft(sig * ifft(np.log(mag))))).real
24 | return recon
25 |
26 |
--------------------------------------------------------------------------------
/build/lib/PyOSGPUP/synthe_seismo.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 | import PyOSGPUP.wavelet as wavelet
4 |
5 |
6 | def getPlotLog(d, log, dmax=200):
7 | d = np.array(d, dtype=float)
8 | log = np.array(log, dtype=float)
9 |
10 | dplot = np.kron(d, np.ones(2))
11 | logplot = np.kron(log, np.ones(2))
12 |
13 | # dplot = dplot[1:]
14 | dplot = np.append(dplot[1:], dmax)
15 |
16 | return dplot, logplot
17 |
18 |
19 | def getImpedance(rholog, vlog):
20 | """
21 | Acoustic Impedance is the product of density and velocity
22 | $$
23 | Z = \\rho v
24 | $$
25 | """
26 | rholog, vlog = np.array(rholog, dtype=float), np.array(vlog, dtype=float),
27 | return rholog * vlog
28 |
29 |
30 | def getReflectivity(d, rho, v, usingT=True):
31 | """
32 | The reflection coefficient of an interface is $$ R_i = \\frac{Z_{i+1} - Z_{i}}{Z_{i+1}+Z_{i}} $$ The reflectivity
33 | can also include the effect of transmission through above layers, in which case the reflectivity is given by $$
34 | \\text{reflectivity} = R_i \\pi_{j = 1}^{i-1}(1-R_j^2) $$
35 | """
36 | Z = getImpedance(rho, v) # acoustic impedance
37 | dZ = (Z[1:] - Z[:-1])
38 | sZ = (Z[:-1] + Z[1:])
39 | R = dZ / sZ # reflection coefficients
40 |
41 | nlayer = len(v) # number of layers
42 |
43 | rseries = R
44 |
45 | if usingT:
46 | for i in range(nlayer - 1):
47 | rseries[i + 1:] = rseries[i + 1:] * (1. - R[i] ** 2)
48 |
49 | return rseries, R
50 |
51 |
52 | def getTimeDepth(d,v,dmax=200):
53 | """
54 | The time depth conversion is computed by determining the two-way travel time for a reflection from a given depth.
55 | """
56 |
57 | d = np.sort(d)
58 | d = np.append(d,dmax)
59 |
60 | twttop = 2.*np.diff(d)/v # 2-way travel time within each layer
61 | twttop = np.append(0.,twttop)
62 | twttop = np.cumsum(twttop) # 2-way travel time from surface to top of each layer
63 |
64 | return d, twttop
65 |
66 |
67 | def getLogs(d, rho, v, usingT=True):
68 | """
69 | Function to make plotting convenient
70 | """
71 | dpth, rholog = getPlotLog(d, rho)
72 | _, vlog = getPlotLog(d, v)
73 | zlog = getImpedance(rholog, vlog)
74 | rseries, _ = getReflectivity(d, rho, v, usingT)
75 | return dpth, rholog, vlog, zlog, rseries
76 |
77 |
78 | def plotLogFormat(log, dpth, xlim, col='blue'):
79 | """
80 | Nice formatting for plotting logs as a function of depth
81 | """
82 | ax = plt.plot(log, dpth, linewidth=2, color=col)
83 | plt.xlim(xlim)
84 | plt.ylim((dpth.min(), dpth.max()))
85 | plt.grid()
86 | plt.gca().invert_yaxis()
87 | plt.setp(plt.xticks()[1], rotation='90', fontsize=9)
88 | plt.setp(plt.yticks()[1], fontsize=9)
89 |
90 | return ax
91 |
92 |
93 | def plotLogs(d, rho, v, usingT=True):
94 | """
95 | Plotting wrapper to plot density, velocity, acoustic impedance and reflectivity as a function of depth.
96 | """
97 | d = np.sort(d)
98 |
99 | dpth, rholog, vlog, zlog, rseries = getLogs(d, rho, v, usingT)
100 | nd = len(dpth)
101 |
102 | xlimrho = (1.95, 5.05)
103 | xlimv = (0.25, 4.05)
104 | xlimz = (xlimrho[0] * xlimv[0], xlimrho[1] * xlimv[1])
105 |
106 | # Plot Density
107 | plt.figure(1)
108 |
109 | plt.subplot(141)
110 | plotLogFormat(rholog * 10 ** -3, dpth, xlimrho, 'blue')
111 | plt.title('$\\rho$')
112 | plt.xlabel('Density \n $\\times 10^3$ (kg /m$^3$)', fontsize=9)
113 | plt.ylabel('Depth (m)', fontsize=9)
114 |
115 | plt.subplot(142)
116 | plotLogFormat(vlog * 10 ** -3, dpth, xlimv, 'red')
117 | plt.title('$v$')
118 | plt.xlabel('Velocity \n $\\times 10^3$ (m/s)', fontsize=9)
119 | plt.setp(plt.yticks()[1], visible=False)
120 |
121 | plt.subplot(143)
122 | plotLogFormat(zlog * 10. ** -6., dpth, xlimz, 'green')
123 | plt.gca().set_title('$Z = \\rho v$')
124 | plt.gca().set_xlabel('Impedance \n $\\times 10^{6}$ (kg m$^{-2}$ s$^{-1}$)', fontsize=9)
125 | plt.setp(plt.yticks()[1], visible=False)
126 |
127 | plt.subplot(144)
128 | plt.hlines(d[1:], np.zeros(nd - 1), rseries, linewidth=2)
129 | plt.plot(np.zeros(nd), dpth, linewidth=2, color='black')
130 | plt.title('Reflectivity')
131 | plt.xlim((-1., 1.))
132 | plt.gca().set_xlabel('Reflectivity')
133 | plt.grid()
134 | plt.gca().invert_yaxis()
135 | plt.setp(plt.xticks()[1], rotation='90', fontsize=9)
136 | plt.setp(plt.yticks()[1], visible=False)
137 |
138 | plt.tight_layout()
139 | plt.show()
140 |
141 |
142 | def plotLogsInteract(d2, d3, rho1, rho2, rho3, v1, v2, v3, usingT=False):
143 | """
144 | interactive wrapper of plotLogs
145 | """
146 | d = np.array((0., d2, d3), dtype=float)
147 | rho = np.array((rho1, rho2, rho3), dtype=float)
148 | v = np.array((v1, v2, v3), dtype=float)
149 | plotLogs(d, rho, v, usingT)
150 |
151 |
152 | def plotTimeDepth(d,v):
153 | """
154 | Wrapper to plot time-depth conversion based on the provided velocity model
155 | """
156 |
157 | dpth,t = getTimeDepth(d,v)
158 | plt.figure()
159 | plt.plot(dpth,t,linewidth=2)
160 | plt.title('Depth-Time')
161 | plt.grid()
162 | plt.gca().set_xlabel('Depth (m)',fontsize=9)
163 | plt.gca().set_ylabel('Two Way Time (s)',fontsize=9)
164 |
165 | plt.tight_layout()
166 | plt.show()
167 |
168 |
169 | def syntheticSeismogram(d, rho, v, wavf, wavA=1., usingT=True, wavtyp = 'RICKER', dt=0.0001, dmax=200):
170 | """
171 | function syntheticSeismogram(d, rho, v, wavtyp, wavf, usingT)
172 | syntheicSeismogram generates a synthetic seismogram for
173 | a simple 1-D layered model.
174 | Inputs:
175 | d : depth to the top of each layer (m)
176 | rho : density of each layer (kg/m^3)
177 | v : velocity of each layer (m/s)
178 | The last layer is assumed to be a half-space
179 | wavf : wavelet frequency
180 | wavA : wavelet amplitude
181 | usintT : using Transmission coefficients?
182 | wavtyp : type of Wavelet
183 | The wavelet options are:
184 | Ricker: takes one frequency
185 | Gaussian: still in progress
186 | Ormsby: takes 4 frequencies
187 | Klauder: takes 2 frequencies
188 | usingT : use transmission coefficients?
189 | Lindsey Heagy
190 | lheagy@eos.ubc.ca
191 | Created: November 30, 2013
192 | Modified: October 3, 2014
193 | """
194 |
195 | v, rho, d = np.array(v, dtype=float), np.array(rho, dtype=float), np.array(d, dtype=float)
196 | usingT = np.array(usingT, dtype=bool)
197 |
198 | _, t = getTimeDepth(d,v,dmax)
199 | rseries,R = getReflectivity(d,rho,v)
200 |
201 | # time for reflectivity series
202 | tref = t[1:-1]
203 |
204 | # create time vector
205 | t = np.arange(t.min(),t.max(),dt)
206 |
207 | # make wavelet
208 | twav = np.arange(-2.0/np.min(wavf), 2.0/np.min(wavf), dt)
209 |
210 | # Get source wavelet
211 | wav = {'RICKER':wavelet.getRicker, 'ORMSBY':wavelet.getOrmsby, 'KLAUDER':wavelet.getKlauder}[wavtyp](wavf,twav)
212 | wav = wavA*wav
213 |
214 | rseriesconv = np.zeros(len(t))
215 | for i in range(len(tref)):
216 | index = np.abs(t - tref[i]).argmin()
217 | rseriesconv[index] = rseries[i]
218 |
219 | # Do the convolution
220 | seis = np.convolve(wav,rseriesconv)
221 | tseis = np.min(twav)+dt*np.arange(len(seis))
222 | index = np.logical_and(tseis >= 0, tseis <= np.max(t))
223 | tseis = tseis[index]
224 | seis = seis[index]
225 |
226 | return tseis, seis, twav, wav, tref, rseries
227 |
228 |
229 | def plotSeismogram(d, rho, v, wavf, wavA=1., noise = 0., usingT=True, wavtyp='RICKER'):
230 | """
231 | Plotting function to show physical property logs (in depth) and seismogram (in time).
232 | """
233 |
234 | dpth, rholog, vlog, zlog, rseries = getLogs(d, rho, v, usingT)
235 | tseis, seis, twav, wav, tref, rseriesconv = syntheticSeismogram(d, rho, v, wavf, wavA, usingT,wavtyp)
236 |
237 | noise = noise*np.max(np.abs(seis))*np.random.randn(seis.size)
238 | filt = np.arange(1.,21.)
239 | filtr = filt[::-1]
240 | filt = np.append(filt,filtr[1:])*1./21.
241 | noise = np.convolve(noise,filt)
242 | noise = noise[0:seis.size]
243 |
244 | xlimrho = (1.95,5.05)
245 | xlimv = (0.25,4.05)
246 | xlimz = (xlimrho[0]*xlimv[0], xlimrho[1]*xlimv[1])
247 |
248 | seis = seis + noise
249 |
250 | plt.figure()
251 |
252 | plt.subplot(131)
253 | plotLogFormat(rholog*10**-3,dpth,xlimrho,'blue')
254 | plt.title('$\\rho$')
255 | plt.xlabel('Density \n $\\times 10^3$ (kg /m$^3$)',fontsize=9)
256 | plt.ylabel('Depth (m)',fontsize=9)
257 |
258 | plt.subplot(132)
259 | plotLogFormat(vlog*10**-3,dpth,xlimv,'red')
260 | plt.title('$v$')
261 | plt.xlabel('Velocity \n $\\times 10^3$ (m/s)',fontsize=9)
262 | plt.ylabel('Depth (m)',fontsize=9)
263 |
264 | plt.subplot(133)
265 | plt.plot(seis,tseis,color='black',linewidth=1)
266 | plt.title('Seismogram')
267 | plt.grid()
268 | plt.ylim((tseis.min(),tseis.max()))
269 | plt.gca().invert_yaxis()
270 | plt.xlim((-0.5,0.5))
271 | plt.setp(plt.xticks()[1],rotation='90',fontsize=9)
272 | plt.setp(plt.yticks()[1],fontsize=9)
273 | plt.gca().set_xlabel('Amplitude',fontsize=9)
274 | plt.gca().set_ylabel('Time (s)',fontsize=9)
275 |
276 | plt.tight_layout()
277 | plt.show()
--------------------------------------------------------------------------------
/build/lib/PyOSGPUP/tuning_wedge_acces.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from matplotlib import gridspec
3 | import matplotlib.pyplot as plt
4 | from PyOSGPUP.signalpy import hilbert
5 |
6 |
7 | def plot_vawig(axhdl, data, t, excursion, highlight=None):
8 | [ntrc, nsamp] = data.shape
9 |
10 | t = np.hstack([0, t, t.max()])
11 |
12 | for i in range(0, ntrc):
13 | tbuf = excursion * data[i] / np.max(np.abs(data)) + i
14 |
15 | tbuf = np.hstack([i, tbuf, i])
16 |
17 | if i == highlight:
18 | lw = 2
19 | else:
20 | lw = 0.5
21 |
22 | axhdl.plot(tbuf, t, color='black', linewidth=lw)
23 |
24 | plt.fill_betweenx(t, tbuf, i, where=tbuf > i, facecolor=[0.6, 0.6, 1.0], linewidth=0)
25 | plt.fill_betweenx(t, tbuf, i, where=tbuf < i, facecolor=[1.0, 0.7, 0.7], linewidth=0)
26 |
27 | axhdl.set_xlim((-excursion, ntrc + excursion))
28 | axhdl.xaxis.tick_top()
29 | axhdl.xaxis.set_label_position('top')
30 | axhdl.invert_yaxis()
31 |
32 |
33 | def ricker(cfreq, phase, dt, wvlt_length):
34 | '''
35 | Calculate a ricker wavelet
36 |
37 | Usage:
38 | ------
39 | t, wvlt = wvlt_ricker(cfreq, phase, dt, wvlt_length)
40 |
41 | cfreq: central frequency of wavelet in Hz
42 | phase: wavelet phase in degrees
43 | dt: sample rate in seconds
44 | wvlt_length: length of wavelet in seconds
45 | '''
46 |
47 | nsamp = int(wvlt_length / dt + 1)
48 | t_max = wvlt_length * 0.5
49 | t_min = -t_max
50 |
51 | t = np.arange(t_min, t_max, dt)
52 |
53 | t = np.linspace(-wvlt_length / 2, (wvlt_length - dt) / 2, wvlt_length / dt)
54 | wvlt = (1.0 - 2.0 * (np.pi ** 2) * (cfreq ** 2) * (t ** 2)) * np.exp(-(np.pi ** 2) * (cfreq ** 2) * (t ** 2))
55 |
56 | if phase != 0:
57 | phase = phase * np.pi / 180.0
58 | wvlth = hilbert(wvlt)
59 | wvlth = np.imag(wvlth)
60 | wvlt = np.cos(phase) * wvlt - np.sin(phase) * wvlth
61 |
62 | return t, wvlt
63 |
64 |
65 | def wvlt_bpass(f1, f2, f3, f4, phase, dt, wvlt_length):
66 | '''
67 | Calculate a trapezoidal bandpass wavelet
68 |
69 | Usage:
70 | ------
71 | t, wvlt = wvlt_ricker(f1, f2, f3, f4, phase, dt, wvlt_length)
72 |
73 | f1: Low truncation frequency of wavelet in Hz
74 | f2: Low cut frequency of wavelet in Hz
75 | f3: High cut frequency of wavelet in Hz
76 | f4: High truncation frequency of wavelet in Hz
77 | phase: wavelet phase in degrees
78 | dt: sample rate in seconds
79 | wvlt_length: length of wavelet in seconds
80 | '''
81 |
82 | from numpy.fft import fft, ifft, fftfreq, fftshift, ifftshift
83 |
84 | nsamp = int(wvlt_length / dt + 1)
85 |
86 | freq = fftfreq(nsamp, dt)
87 | freq = fftshift(freq)
88 | aspec = freq * 0.0
89 | pspec = freq * 0.0
90 |
91 | # Calculate slope and y-int for low frequency ramp
92 | M1 = 1 / (f2 - f1)
93 | b1 = -M1 * f1
94 |
95 | # Calculate slop and y-int for high frequency ramp
96 | M2 = -1 / (f4 - f3)
97 | b2 = -M2 * f4
98 |
99 | # Build initial frequency and filter arrays
100 | freq = fftfreq(nsamp, dt)
101 | freq = fftshift(freq)
102 | filt = np.zeros(nsamp)
103 |
104 | # Build LF ramp
105 | idx = np.nonzero((np.abs(freq) >= f1) & (np.abs(freq) < f2))
106 | filt[idx] = M1 * np.abs(freq)[idx] + b1
107 |
108 | # Build central filter flat
109 | idx = np.nonzero((np.abs(freq) >= f2) & (np.abs(freq) <= f3))
110 | filt[idx] = 1.0
111 |
112 | # Build HF ramp
113 | idx = np.nonzero((np.abs(freq) > f3) & (np.abs(freq) <= f4))
114 | filt[idx] = M2 * np.abs(freq)[idx] + b2
115 |
116 | # Unshift the frequencies and convert filter to fourier coefficients
117 | filt2 = ifftshift(filt)
118 | Af = filt2 * np.exp(np.zeros(filt2.shape) * 1j)
119 |
120 | # Convert filter to time-domain wavelet
121 | wvlt = fftshift(ifft(Af))
122 | wvlt = np.real(wvlt)
123 | wvlt = wvlt / np.max(np.abs(wvlt)) # normalize wavelet by peak amplitude
124 |
125 | # Generate array of wavelet times
126 | t = np.linspace(-wvlt_length * 0.5, wvlt_length * 0.5, nsamp)
127 |
128 | # Apply phase rotation if desired
129 | if phase != 0:
130 | phase = phase * np.pi / 180.0
131 | wvlth = hilbert(wvlt)
132 | wvlth = np.imag(wvlth)
133 | wvlt = np.cos(phase) * wvlt - np.sin(phase) * wvlth
134 |
135 | return t, wvlt
136 |
137 |
138 | def calc_rc(vp_mod, rho_mod):
139 | '''
140 | rc_int = calc_rc(vp_mod, rho_mod)
141 | '''
142 |
143 | nlayers = len(vp_mod)
144 | nint = nlayers - 1
145 |
146 | rc_int = []
147 | for i in range(0, nint):
148 | buf1 = vp_mod[i + 1] * rho_mod[i + 1] - vp_mod[i] * rho_mod[i]
149 | buf2 = vp_mod[i + 1] * rho_mod[i + 1] + vp_mod[i] * rho_mod[i]
150 | buf3 = buf1 / buf2
151 | rc_int.append(buf3)
152 |
153 | return rc_int
154 |
155 | def calc_times(z_int, vp_mod):
156 | '''
157 | t_int = calc_times(z_int, vp_mod)
158 | '''
159 |
160 | nlayers = len(vp_mod)
161 | nint = nlayers - 1
162 |
163 | t_int = []
164 | for i in range(0, nint):
165 | if i == 0:
166 | tbuf = z_int[i] / vp_mod[i]
167 | t_int.append(tbuf)
168 | else:
169 | zdiff = z_int[i] - z_int[i - 1]
170 | tbuf = 2 * zdiff / vp_mod[i] + t_int[i - 1]
171 | t_int.append(tbuf)
172 |
173 | return t_int
174 |
175 | def digitize_model(rc_int, t_int, t):
176 | '''
177 | rc = digitize_model(rc, t_int, t)
178 |
179 | rc = reflection coefficients corresponding to interface times
180 | t_int = interface times
181 | t = regularly sampled time series defining model sampling
182 | '''
183 |
184 | import numpy as np
185 |
186 | nlayers = len(rc_int)
187 | nint = nlayers - 1
188 | nsamp = len(t)
189 |
190 | rc = list(np.zeros(nsamp, dtype='float'))
191 | lyr = 0
192 |
193 | for i in range(0, nsamp):
194 |
195 | if t[i] >= t_int[lyr]:
196 | rc[i] = rc_int[lyr]
197 | lyr = lyr + 1
198 |
199 | if lyr > nint:
200 | break
201 |
202 | return rc
203 |
204 |
205 | def wedge_tuning(mod,bound_mod,wave_parm,freq,trace_parm,plot_parm):
206 | ###########################################################
207 | #
208 | # DEFINE MODELING PARAMETERS HERE
209 | #
210 |
211 | # 3-Layer Model Parameters [Layer1, Layer2, Layer 3]
212 | vp_mod = mod[0] # P-wave velocity (m/s)
213 | vs_mod = mod[1] # S-wave velocity (m/s)
214 | rho_mod = mod[2] # Density (g/cc)
215 |
216 | dz_min = bound_mod[0] # Minimum thickness of Layer 2 (m)
217 | dz_max = bound_mod[1] # Maximum thickness of Layer 2 (m)
218 | dz_step = bound_mod[2] # Thickness step from trace-to-trace (normally 1.0 m)
219 |
220 | # Wavelet Parameters
221 | wvlt_type = wave_parm[0] # Valid values: 'ricker' or 'bandpass'
222 | wvlt_length = wave_parm[1] # Wavelet length in seconds
223 | wvlt_phase = wave_parm[2] # Wavelet phase in degrees
224 | wvlt_scalar = wave_parm[3] # Multiplier to scale wavelet amplitude (default = 1.0)
225 | wvlt_cfreq = wave_parm[4] # Ricker wavelet central frequency
226 | f1 = freq[0] # Bandpass wavelet low truncation frequency
227 | f2 = freq[1] # Bandpass wavelet low cut frequency
228 | f3 = freq[2] # Bandpass wavelet high cut frequency
229 | f4 = freq[3] # Bandpass wavelet high truncation frequency
230 |
231 | # Trace Parameters
232 | tmin = trace_parm[0]
233 | tmax = trace_parm[1]
234 | dt = trace_parm[2] # changing this from 0.0001 can affect the display quality
235 |
236 | # Plot Parameters
237 | min_plot_time = plot_parm[0]
238 | max_plot_time = plot_parm[1]
239 | excursion = plot_parm[2]
240 |
241 | ###########################################################
242 | #
243 | # DEFINE MODELING PARAMETERS HERE
244 | #
245 |
246 | # Some handy constants
247 | nlayers = len(vp_mod)
248 | nint = nlayers - 1
249 | nmodel = int((dz_max - dz_min) / dz_step + 1)
250 |
251 |
252 | # Generate wavelet
253 | if wvlt_type == 'ricker':
254 | wvlt_t, wvlt_amp = ricker(wvlt_cfreq, wvlt_phase, dt, wvlt_length)
255 |
256 | elif wvlt_type == 'bandpass':
257 | wvlt_t, wvlt_amp = wvlt_bpass(f1, f2, f3, f4, wvlt_phase, dt, wvlt_length)
258 |
259 | # Apply amplitude scale factor to wavelet (to match seismic amplitude values)
260 | wvlt_amp = wvlt_scalar * wvlt_amp
261 |
262 | # Calculate reflectivities from model parameters
263 | rc_int = calc_rc(vp_mod, rho_mod)
264 |
265 | syn_zo = []
266 | rc_zo = []
267 | lyr_times = []
268 | for model in range(0, nmodel):
269 |
270 | # Calculate interface depths
271 | z_int = [500.0]
272 | z_int.append(z_int[0] + dz_min + dz_step * model)
273 |
274 | # Calculate interface times
275 | t_int = calc_times(z_int, vp_mod)
276 | lyr_times.append(t_int)
277 |
278 | # Digitize 3-layer model
279 | nsamp = int((tmax - tmin) / dt) + 1
280 | t = []
281 | for i in range(0, nsamp):
282 | t.append(i * dt)
283 |
284 | rc = digitize_model(rc_int, t_int, t)
285 | rc_zo.append(rc)
286 |
287 | # Convolve wavelet with reflectivities
288 | syn_buf = np.convolve(rc, wvlt_amp, mode='same')
289 | syn_buf = list(syn_buf)
290 | syn_zo.append(syn_buf)
291 | print("finished step %i" % (model))
292 |
293 | syn_zo = np.array(syn_zo)
294 | t = np.array(t)
295 | lyr_times = np.array(lyr_times)
296 | lyr_indx = np.array(np.round(lyr_times / dt), dtype='int16')
297 |
298 | # Use the transpose because rows are traces;
299 | # columns are time samples.
300 | tuning_trace = np.argmax(np.abs(syn_zo.T)) % syn_zo.T.shape[1]
301 | tuning_thickness = tuning_trace * dz_step
302 |
303 | # Plotting Code
304 | [ntrc, nsamp] = syn_zo.shape
305 |
306 | fig = plt.figure(figsize=(12, 14))
307 | fig.set_facecolor('white')
308 |
309 | gs = gridspec.GridSpec(3, 1, height_ratios=[1, 1, 1])
310 |
311 | ax0 = fig.add_subplot(gs[0])
312 | ax0.plot(lyr_times[:, 0], color='blue', lw=1.5)
313 | ax0.plot(lyr_times[:, 1], color='red', lw=1.5)
314 | ax0.set_ylim((min_plot_time, max_plot_time))
315 | ax0.invert_yaxis()
316 | ax0.set_xlabel('Thickness (m)')
317 | ax0.set_ylabel('Time (s)')
318 | plt.text(2,
319 | min_plot_time + (lyr_times[0, 0] - min_plot_time) / 2.,
320 | 'Layer 1',
321 | fontsize=16)
322 | plt.text(dz_max / dz_step - 2,
323 | lyr_times[-1, 0] + (lyr_times[-1, 1] - lyr_times[-1, 0]) / 2.,
324 | 'Layer 2',
325 | fontsize=16,
326 | horizontalalignment='right')
327 | plt.text(2,
328 | lyr_times[0, 0] + (max_plot_time - lyr_times[0, 0]) / 2.,
329 | 'Layer 3',
330 | fontsize=16)
331 | plt.gca().xaxis.tick_top()
332 | plt.gca().xaxis.set_label_position('top')
333 | ax0.set_xlim((-excursion, ntrc + excursion))
334 |
335 | ax1 = fig.add_subplot(gs[1])
336 | plot_vawig(ax1, syn_zo, t, excursion, highlight=tuning_trace)
337 | ax1.plot(lyr_times[:, 0], color='blue', lw=1.5)
338 | ax1.plot(lyr_times[:, 1], color='red', lw=1.5)
339 | ax1.set_ylim((min_plot_time, max_plot_time))
340 | ax1.invert_yaxis()
341 | ax1.set_xlabel('Thickness (m)')
342 | ax1.set_ylabel('Time (s)')
343 |
344 | ax2 = fig.add_subplot(gs[2])
345 | ax2.plot(syn_zo[:, lyr_indx[:, 0]], color='blue')
346 | ax2.set_xlim((-excursion, ntrc + excursion))
347 | ax2.axvline(tuning_trace, color='k', lw=2)
348 | ax2.grid()
349 | ax2.set_title('Upper interface amplitude')
350 | ax2.set_xlabel('Thickness (m)')
351 | ax2.set_ylabel('Amplitude')
352 | plt.text(tuning_trace + 2,
353 | plt.ylim()[0] * 1.1,
354 | 'tuning thickness = {0} m'.format(str(tuning_thickness)),
355 | fontsize=16)
356 |
357 | plt.show()
358 |
359 |
360 |
361 |
362 |
363 |
--------------------------------------------------------------------------------
/build/lib/PyOSGPUP/wavelet.py:
--------------------------------------------------------------------------------
1 | # Ref: https://gist.github.com/rowanc1/8338665
2 | import numpy as np
3 | pi = np.pi
4 |
5 |
6 | def getRicker(f, t):
7 | #assert len(f) == 1, 'Ricker wavelet needs 1 frequency as input'
8 | # f = f[0]
9 | pift = pi * f * t
10 | wav = (1 - 2 * pift ** 2) * np.exp(-pift ** 2)
11 | return wav
12 |
13 |
14 | def getOrmsby(f, t):
15 | assert len(f) == 4, 'Ormsby wavelet needs 4 frequencies as input'
16 | f = np.sort(f) # Ormsby wavelet frequencies must be in increasing order
17 | pif = pi * f
18 | den1 = pif[3] - pif[2]
19 | den2 = pif[1] - pif[0]
20 | term1 = (pif[3] * np.sinc(pif[3] * t)) ** 2 - (pif[2] * np.sinc(pif[2])) ** 2
21 | term2 = (pif[1] * np.sinc(pif[1] * t)) ** 2 - (pif[0] * np.sinc(pif[0])) ** 2
22 |
23 | wav = term1 / den1 - term2 / den2
24 | return wav
25 |
26 |
27 | def getKlauder(f, t, T=5.0):
28 | assert len(f) == 2, 'Klauder wavelet needs 2 frequencies as input'
29 |
30 | k = np.diff(f) / T
31 | f0 = np.sum(f) / 2.0
32 | wav = np.real(np.sin(pi * k * t * (T - t)) / (pi * k * t) * np.exp(2 * pi * 1j * f0 * t))
33 | return wav
34 |
--------------------------------------------------------------------------------
/build/lib/sample/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | def main():
3 | """Entry point for the application script"""
4 | print("Call your main application code here")
5 |
--------------------------------------------------------------------------------
/build/lib/sample/package_data.dat:
--------------------------------------------------------------------------------
1 | some data
--------------------------------------------------------------------------------
/dist/PyOSGPUP-1.0.3-py3-none-any.whl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Metkom/PyOSGPUP/93b2e153b3dd4e1f644a704a0d7c62ca3bda8f26/dist/PyOSGPUP-1.0.3-py3-none-any.whl
--------------------------------------------------------------------------------
/example/readsegy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Metkom/PyOSGPUP/93b2e153b3dd4e1f644a704a0d7c62ca3bda8f26/example/readsegy.png
--------------------------------------------------------------------------------
/example/seis1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Metkom/PyOSGPUP/93b2e153b3dd4e1f644a704a0d7c62ca3bda8f26/example/seis1.png
--------------------------------------------------------------------------------
/example/seis2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Metkom/PyOSGPUP/93b2e153b3dd4e1f644a704a0d7c62ca3bda8f26/example/seis2.png
--------------------------------------------------------------------------------
/example/seis3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Metkom/PyOSGPUP/93b2e153b3dd4e1f644a704a0d7c62ca3bda8f26/example/seis3.png
--------------------------------------------------------------------------------
/example/wavelet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Metkom/PyOSGPUP/93b2e153b3dd4e1f644a704a0d7c62ca3bda8f26/example/wavelet.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | numpy==1.19.2
2 | matplotlib
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [egg_info]
2 | tag_build =
3 | tag_date = 0
4 |
5 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | """PyOSGPUP: Python, Open-source, Geophysical Eng. Univ. Pertamina
3 |
4 | A python packages for geophysical data processing modeling, and interpretation.
5 | """
6 |
7 | from os import path
8 | from distutils.core import setup
9 | from setuptools import find_packages
10 |
11 | here = path.abspath(path.dirname(__file__))
12 | # Get the long description from the README file
13 | # Get the long description from the README file
14 | with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
15 | long_description = f.read()
16 |
17 |
18 | setup(
19 | name='PyOSGPUP', # Required
20 | version='1.0.3', # Required
21 |
22 | description='An open-source library for geophysical data processing, modeling, and interpretation based on Python.', # Required
23 | long_description=long_description, # Optional
24 |
25 | url='https://sites.google.com/site/metkomup/', # Optional
26 | author='Komputasi Geofisika - Universitas Pertamina', # Optional
27 | author_email='metkom.up@gmail.com', # Optional
28 |
29 | classifiers=[ # Optional
30 | 'Development Status :: 3 - Alpha',
31 |
32 | # Indicate who your project is intended for
33 | 'Intended Audience :: Developers',
34 | 'Topic :: Software Development :: Build Tools',
35 |
36 | # Pick your license as you wish
37 | 'License :: OSI Approved :: MIT License',
38 |
39 | 'Programming Language :: Python :: 3.4',
40 | 'Programming Language :: Python :: 3.5',
41 | 'Programming Language :: Python :: 3.6',
42 | ],
43 |
44 | keywords='geophysical data processing, modeling, and interpretation', # Optional
45 | packages=find_packages(exclude=['contrib', 'docs', 'tests']), # Required
46 |
47 | install_requires=['numpy','matplotlib'], # Optional
48 |
49 | # download_url="https://github.com/Metkom/PyOSGPUP",
50 | project_urls={ # Optional
51 | 'Bug Reports': 'https://github.com/Metkom/PyOSGPUP/issues',
52 | 'Say Thanks!': 'https://sites.google.com/site/metkomup/pyosgpup',
53 | 'Source': 'https://github.com/Metkom/PyOSGPUP',
54 | },
55 | platforms=["Windows","Linux","Mac OS-X"]
56 |
57 | )
58 |
--------------------------------------------------------------------------------
/tox.ini:
--------------------------------------------------------------------------------
1 | # this file is *not* meant to cover or endorse the use of tox or pytest or
2 | # testing in general,
3 | #
4 | # It's meant to show the use of:
5 | #
6 | # - check-manifest
7 | # confirm items checked into vcs are in your sdist
8 | # - python setup.py check (using the readme_renderer extension)
9 | # confirms your long_description will render correctly on pypi
10 | #
11 | # and also to help confirm pull requests to this project.
12 |
13 | [tox]
14 | envlist = py{27,34,35,36}
15 |
16 | [testenv]
17 | basepython =
18 | py27: python2.7
19 | py34: python3.4
20 | py35: python3.5
21 | py36: python3.6
22 | deps =
23 | check-manifest
24 | readme_renderer
25 | flake8
26 | pytest
27 | commands =
28 | check-manifest --ignore tox.ini,tests*
29 | python setup.py check -m -r -s
30 | flake8 .
31 | py.test tests
32 | [flake8]
33 | exclude = .tox,*.egg,build,data
34 | select = E,W,F
35 |
--------------------------------------------------------------------------------