pyseiskit 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pyseiskit/__init__.py ADDED
@@ -0,0 +1,7 @@
1
+ from .modules import gain
2
+ from .modules import palettes
3
+ from .modules import sourceData
4
+ from .modules import clip
5
+
6
+ # Expose the applyGains function directly at the root
7
+ from .modules.applyGains.applyGains import applyGains, GainType
File without changes
File without changes
@@ -0,0 +1 @@
1
+ from .clipAdapter import createClipAdapter
@@ -0,0 +1,16 @@
1
+ from typing import Callable
2
+ import numpy.typing as np_types
3
+
4
+ def createClipAdapter(func: Callable) -> Callable:
5
+ """
6
+ Wraps a 2-parameter clipping function to safely accept
7
+ the 3-parameter strategy caller signature.
8
+ """
9
+ def clipAdapter(
10
+ gatherAmplitudes: np_types.NDArray,
11
+ gainValue: float,
12
+ intervalTimeSamples: float
13
+ ) -> np_types.NDArray:
14
+ return func(gatherAmplitudes, gainValue)
15
+
16
+ return clipAdapter
@@ -0,0 +1,42 @@
1
+ from typing import TypedDict
2
+ from numpy import typing as np_types
3
+
4
+ from .gainStrategies import gainStrategies
5
+
6
+ class GainType(TypedDict):
7
+ """
8
+ A dictionary defining the supported types of gain that can
9
+ be applied to seismic data.
10
+ """
11
+ AGC: float
12
+ GAUSSIAN_AGC: float
13
+ PERCENTILE_CLIPPING: float
14
+
15
+ def applyGains(
16
+ data: np_types.NDArray,
17
+ gains: GainType,
18
+ intervalTimeSamples: float,
19
+ ) -> np_types.NDArray:
20
+ """
21
+ Applies the specified gain to the input data.
22
+ \nChecks for gain values, not keys.
23
+ \nIn case of None or 0 values, the gain will be skipped.
24
+
25
+ Parameters
26
+ ----------
27
+ data: np_types.NDArray
28
+ Input data array [2D array]
29
+ gains: GainType [dict]
30
+ Dictionary containing the gain values.
31
+ intervalTimeSamples: float
32
+ Time step between samples in seconds.
33
+
34
+ Returns: np_types.NDArray
35
+ The gained data array.
36
+ """
37
+ newData = data.copy()
38
+
39
+ for gainType, gainValue in gains.items():
40
+ newData = gainStrategies[gainType](newData, gainValue, intervalTimeSamples)
41
+
42
+ return newData
@@ -0,0 +1,11 @@
1
+ from .adapters import createClipAdapter
2
+
3
+ from ..gain.contracts import GenericGainProtocol
4
+ from ..gain import applyAGC, applyGAGC
5
+ from ..clip import applyPercentileClip
6
+
7
+ gainStrategies: dict[str, GenericGainProtocol] = {
8
+ 'AGC': applyAGC,
9
+ 'GAUSSIAN_AGC': applyGAGC,
10
+ 'PERCENTILE_CLIPPING': createClipAdapter(applyPercentileClip)
11
+ }
@@ -0,0 +1 @@
1
+ from .percentileClip import applyPercentileClip
@@ -0,0 +1,19 @@
1
+ import numpy.typing as np_types
2
+ from typing import Protocol
3
+
4
+ class PercentileClipProtocol(Protocol):
5
+ def __call__(
6
+ self,
7
+ gatherAmplitudes: np_types.NDArray,
8
+ percentile: float,
9
+ ) -> np_types.NDArray:
10
+ """
11
+ Clip functions must exactly match these parameter names, order, and types.
12
+ """
13
+ ...
14
+
15
+ def PercentileClipContract(function: PercentileClipProtocol) -> PercentileClipProtocol:
16
+ """
17
+ Decorator that forces type checkers to verify the function matches ClipProtocol.
18
+ """
19
+ return function
@@ -0,0 +1 @@
1
+ from .PercentileClip import PercentileClipContract
@@ -0,0 +1,31 @@
1
+ import numpy as np
2
+ from numpy import typing as np_types
3
+
4
+ from .contracts.PercentileClip import PercentileClipContract
5
+
6
+ @PercentileClipContract
7
+ def applyPercentileClip(
8
+ gatherAmplitudes: np_types.NDArray,
9
+ percentile: float
10
+ ) -> np_types.NDArray:
11
+ """
12
+ Apply a percentile-based clipping to input data.
13
+
14
+ Parameters
15
+ ----------
16
+ gatherAmplitudes : np_types.NDArray
17
+ Input data array.
18
+ percentile : float
19
+ Percentile value for clipping.
20
+
21
+ Returns
22
+ -------
23
+ np_types.NDArray
24
+ Clipped data array.
25
+ """
26
+ maxTraceAmplitude = np.percentile(
27
+ np.absolute(gatherAmplitudes),
28
+ percentile
29
+ )
30
+ clippedTraces = np.clip(gatherAmplitudes, a_min=-maxTraceAmplitude, a_max=maxTraceAmplitude)
31
+ return clippedTraces
@@ -0,0 +1,2 @@
1
+ from .agc import applyAGC
2
+ from .gagc import applyGAGC
@@ -0,0 +1,52 @@
1
+ import numpy as np
2
+ import numpy.typing as np_types
3
+ from scipy import ndimage
4
+
5
+ from .contracts import AutomaticGainContract
6
+
7
+ @AutomaticGainContract
8
+ def applyAGC(
9
+ gatherAmplitudes: np_types.NDArray,
10
+ wagc: float,
11
+ intervalTimeSamples: float
12
+ ) -> np_types.NDArray:
13
+ """
14
+ Calculates Simple Automatic Gain Control (AGC) of a seismic gather.
15
+
16
+ Parameters
17
+ ----------
18
+ gatherAmplitudes : np_types.NDArray
19
+ Array of gather amplitudes [2D array]
20
+ wagc : float
21
+ Window length for AGC in seconds.
22
+ intervalTimeSamples : float
23
+ Time step between samples in seconds.
24
+ """
25
+ half_window_samples = round(wagc / intervalTimeSamples)
26
+
27
+ # *** Define the physical window dimensions
28
+ fullWindowSamples = 2 * half_window_samples
29
+
30
+ # *** Rectangular filter (weights sum to 1.0 to compute a true mean)
31
+ averagingWeights = np.ones(fullWindowSamples) / fullWindowSamples
32
+
33
+ # *** Moving energy average
34
+ # *** Apply the 1D filter down the time axis (axis=0)
35
+ # *** mode='constant' with cval=0.0 safely pads the top and bottom with zeros
36
+ localMeanSquaredEnergy = ndimage.convolve1d(
37
+ gatherAmplitudes**2,
38
+ averagingWeights,
39
+ mode='constant',
40
+ cval=0.0,
41
+ axis=0
42
+ )
43
+
44
+ # *** Extract RMS and apply gain
45
+ rootMeanSquareEnergy = np.sqrt(localMeanSquaredEnergy)
46
+
47
+ return np.divide(
48
+ gatherAmplitudes,
49
+ rootMeanSquareEnergy,
50
+ out=np.zeros_like(gatherAmplitudes),
51
+ where=rootMeanSquareEnergy!=0
52
+ )
@@ -0,0 +1,21 @@
1
+ import numpy.typing as np_types
2
+
3
+ from .GenericGain import GenericGainProtocol
4
+
5
+ class AutomaticGainProtocol(GenericGainProtocol):
6
+ def __call__(
7
+ self,
8
+ gatherAmplitudes: np_types.NDArray,
9
+ wagc: float,
10
+ intervalTimeSamples: float
11
+ ) -> np_types.NDArray:
12
+ """
13
+ Automatic gain functions must exactly match these parameter names, order, and types.
14
+ """
15
+ ...
16
+
17
+ def AutomaticGainContract(function: AutomaticGainProtocol) -> AutomaticGainProtocol:
18
+ """
19
+ Decorator that forces type checkers to verify the function matches AutomaticGainProtocol.
20
+ """
21
+ return function
@@ -0,0 +1,19 @@
1
+ import numpy.typing as np_types
2
+ from typing import Protocol
3
+
4
+ class GenericGainProtocol(Protocol):
5
+ def __call__(
6
+ self,
7
+ data: np_types.NDArray,
8
+ value: float,
9
+ # *** The '= ...' makes the third parameter optional.
10
+ timeSamples: float = ...,
11
+ # *** '/' means this protocol is positional-only.
12
+ /
13
+ ) -> np_types.NDArray:
14
+ """
15
+ Functions can name their variables wagc, percentile, threshold, etc.,
16
+ and it will still be valid.
17
+ The third parameter is optional.
18
+ """
19
+ ...
@@ -0,0 +1,2 @@
1
+ from .GenericGain import GenericGainProtocol
2
+ from .AutomaticGain import AutomaticGainContract
@@ -0,0 +1,57 @@
1
+ import numpy as np
2
+ import numpy.typing as np_types
3
+ from scipy import ndimage
4
+
5
+ from .contracts import AutomaticGainContract
6
+
7
+ EPS: float = 3.8090232
8
+
9
+ @AutomaticGainContract
10
+ def applyGAGC(
11
+ gatherAmplitudes: np_types.NDArray,
12
+ wagc: float,
13
+ intervalTimeSamples: float
14
+ ) -> np_types.NDArray:
15
+ """
16
+ Calculates Gaussian Automatic Gain Control (GAGC) of a seismic gather.
17
+
18
+ Parameters
19
+ ----------
20
+ gatherAmplitudes : np_types.NDArray
21
+ Array of gather amplitudes [2D array]
22
+ wagc : float
23
+ Window length for AGC in seconds.
24
+ intervalTimeSamples : float
25
+ Time step between samples in seconds.
26
+ """
27
+ halfWindowSamples = round(wagc / intervalTimeSamples)
28
+
29
+ # *** Define the variance/decay of the Gaussian curve based on the window size
30
+ decayScalar = EPS / halfWindowSamples
31
+
32
+ # *** Array of relative distances from the center of the window
33
+ sampleOffsets = np.arange(-halfWindowSamples + 1, halfWindowSamples)
34
+
35
+ # *** Bell curve weights using the decay scalar and distances
36
+ gaussianWeights = np.exp(
37
+ -((decayScalar**2) * sampleOffsets * sampleOffsets)
38
+ )
39
+
40
+ # *** Moving energy average weighted by the Gaussian curve
41
+ localWeightedEnergy = ndimage.convolve1d(
42
+ gatherAmplitudes**2,
43
+ gaussianWeights,
44
+ mode='constant',
45
+ cval=0.0,
46
+ axis=0
47
+ )
48
+
49
+ # *** Extract Root Weighted Energy and apply gain
50
+ rootWeightedEnergy = np.sqrt(localWeightedEnergy)
51
+
52
+ return np.divide(
53
+ gatherAmplitudes,
54
+ rootWeightedEnergy,
55
+ out=np.zeros_like(gatherAmplitudes),
56
+ where=rootWeightedEnergy!=0
57
+ )
@@ -0,0 +1,12 @@
1
+ from bokeh.palettes import Greys256, viridis
2
+ from colorcet import rainbow4
3
+
4
+
5
+ from .getFadingPalette import getFadingPalette
6
+
7
+ PALETTES = {
8
+ "Greys256": Greys256,
9
+ "FadingGreys": getFadingPalette(Greys256),
10
+ "viridis": viridis(256),
11
+ "rainbow": rainbow4,
12
+ }
@@ -0,0 +1 @@
1
+ from .PALETTES import PALETTES
@@ -0,0 +1,19 @@
1
+ def getFadingPalette(base_palette):
2
+ """
3
+ Takes a palette (list of hex strings) and applies an alpha gradient.
4
+ The first color becomes 100% opaque, fading to 100% transparent at the last color.
5
+ """
6
+ palette_length = len(base_palette)
7
+ fading_palette = []
8
+
9
+ for index, color in enumerate(base_palette):
10
+ # *** index=0 -> alpha=255 (opaque)
11
+ # *** index=(length-1) -> alpha=0 (transparent)
12
+ alpha = int(255 * (1 - (index / (palette_length - 1))))
13
+ # *** Grab just the #RRGGBB part
14
+ # *** in case the original palette already had alpha
15
+ base_hex = color[:7]
16
+ # *** Append the calculated alpha as a 2-character hex string
17
+ fading_palette.append(f"{base_hex}{alpha:02x}")
18
+
19
+ return fading_palette
@@ -0,0 +1,3 @@
1
+ from .rescaleDataForWiggle import rescaleDataForWiggle
2
+ from .wiggleLinesDataFactory import wiggleLinesDataFactory
3
+ from .wigglePatchesDataFactory import wigglePatchesDataFactory
@@ -0,0 +1,52 @@
1
+ import numpy as np
2
+ from numpy import typing as np_types
3
+
4
+ def rescaleDataForWiggle(
5
+ data: np_types.NDArray,
6
+ offsetPosition: np_types.NDArray,
7
+ overlap: float = 1.0,
8
+ percentile: float = 100.0
9
+ ) -> np_types.NDArray:
10
+ """
11
+ Rescales seismic data amplitudes to physical horizontal offsets for wiggle trace plotting.
12
+
13
+ Args:
14
+ data: 2D array of amplitudes (samples x traces).
15
+ offsetPosition: 1D array of horizontal trace locations.
16
+ overlap: Controls the maximum horizontal swing. A value of 1.0 (Seismic Unix 'xcur' equivalent)
17
+ means a maximum amplitude peak will swing exactly 1.0 trace spacing, touching the baseline
18
+ of the adjacent trace.
19
+ percentile: Percentile of absolute amplitudes used as the maximum for scaling.
20
+ Values < 100.0 (e.g., 99.0) ignore extreme outlier spikes when determining the
21
+ normalization reference, mirroring the behavior of Seismic Unix's 'perc' parameter.
22
+ """
23
+ # Determine maximum scale reference using the specified percentile
24
+ if percentile < 100.0:
25
+ dataMax = np.percentile(np.abs(data), percentile)
26
+ else:
27
+ dataMax = np.max(np.abs(data))
28
+
29
+ if dataMax == 0:
30
+ return data.copy()
31
+
32
+ dataNormalized = data / dataMax
33
+
34
+ # For a single trace there is no inter-trace spacing to reference,
35
+ # so the normalized data is already the final result.
36
+ if data.shape[1] == 1:
37
+ return dataNormalized
38
+
39
+ # Calculate trace spacing robustly (median of non-zero absolute differences)
40
+ abs_diffs = np.abs(np.diff(offsetPosition))
41
+ valid_diffs = abs_diffs[abs_diffs > 0]
42
+
43
+ if len(valid_diffs) == 0:
44
+ # Fallback if all traces are literally on the exact same physical offset
45
+ minTraceSpacing = 1.0
46
+ else:
47
+ minTraceSpacing = np.min(valid_diffs)
48
+
49
+ # Scale normalized data so the maximum deflection equals overlap * trace spacing
50
+ dataRescaled = dataNormalized * (minTraceSpacing * overlap)
51
+
52
+ return dataRescaled
@@ -0,0 +1,19 @@
1
+ import numpy as np
2
+ from numpy import typing as np_types
3
+
4
+
5
+ def wiggleLinesDataFactory(
6
+ data: np_types.NDArray,
7
+ offsetPosition: np_types.NDArray,
8
+ timeSampleInstants: np_types.NDArray,
9
+ ):
10
+ tracesAmount = data.shape[1]
11
+
12
+ # *** Positioning each trace at its corresponding X-axis offset
13
+ broadcastOffsetPosition = np.broadcast_to(offsetPosition, data.shape)
14
+ dataRepositioned = data + broadcastOffsetPosition
15
+
16
+ dataPositioned = dataRepositioned.T.tolist()
17
+ timesPositioned = [timeSampleInstants for _ in range(tracesAmount)]
18
+
19
+ return {"xs": dataPositioned, "ys": timesPositioned}
@@ -0,0 +1,126 @@
1
+ import numpy as np
2
+ from numpy import typing as np_types
3
+ from typing import Tuple, List
4
+
5
+ MIDPOINT_INDEX_OFFSET = 0.5
6
+
7
+ def _interpolateLobeCoordinates(
8
+ timeSampleInstants: np_types.NDArray,
9
+ traceAmplitudes: np_types.NDArray,
10
+ traceOffset: float
11
+ ) -> Tuple[List[float], List[float]]:
12
+ """
13
+ Finds all active amplitudes and calculates the exact zero-crossing interpolation
14
+ points, returning the sorted boundary coordinates for the filled lobes of a single trace.
15
+ Expects data to be pre-flipped if positive lobes are desired.
16
+ """
17
+ currentAmplitudes = traceAmplitudes[:-1]
18
+ nextAmplitudes = traceAmplitudes[1:]
19
+ currentTime = timeSampleInstants[:-1]
20
+ nextTime = timeSampleInstants[1:]
21
+
22
+ # Capture strictly negative values (since we flip the data if filling positive)
23
+ negativeMask = currentAmplitudes <= 0
24
+ negativeIndices = np.where(negativeMask)[0]
25
+
26
+ xs_neg = traceOffset + currentAmplitudes[negativeMask]
27
+ ys_neg = currentTime[negativeMask]
28
+
29
+ # Capture exact zero crossings
30
+ crossingMask = (
31
+ (currentAmplitudes < 0) & (nextAmplitudes > 0)
32
+ ) | (
33
+ (currentAmplitudes > 0) & (nextAmplitudes < 0)
34
+ )
35
+ crossingIndices = np.where(crossingMask)[0]
36
+
37
+ # Linear interpolation to find the exact time at zero
38
+ # Handle potential divide by zero just in case
39
+ diffAmp = nextAmplitudes[crossingMask] - currentAmplitudes[crossingMask]
40
+ safeDiffAmp = np.where(diffAmp == 0, 1e-10, diffAmp)
41
+
42
+ crossingTimes = (
43
+ currentTime[crossingMask] + (
44
+ nextTime[crossingMask] - currentTime[crossingMask]
45
+ ) * (0 - currentAmplitudes[crossingMask]) / safeDiffAmp
46
+ )
47
+
48
+ xs_cross = np.full(len(crossingIndices), traceOffset)
49
+ ys_cross = crossingTimes
50
+
51
+ # Combine and sort to preserve the chronological order
52
+ sortOrder = np.argsort(np.concatenate(
53
+ [negativeIndices, crossingIndices + MIDPOINT_INDEX_OFFSET]
54
+ ))
55
+
56
+ new_xs = np.concatenate([xs_neg, xs_cross])[sortOrder].tolist()
57
+ new_ys = np.concatenate([ys_neg, ys_cross])[sortOrder].tolist()
58
+
59
+ # Add the last point if it is part of the lobe
60
+ if traceAmplitudes[-1] <= 0:
61
+ new_xs.append(float(traceOffset + traceAmplitudes[-1]))
62
+ new_ys.append(float(timeSampleInstants[-1]))
63
+
64
+ return new_xs, new_ys
65
+
66
+
67
+ def wigglePatchesDataFactory(
68
+ data: np_types.NDArray,
69
+ offsetPosition: np_types.NDArray,
70
+ timeSampleInstants: np_types.NDArray,
71
+ fill_mode: str = "positive"
72
+ ) -> Tuple[List[List[float]], List[List[float]]]:
73
+ """
74
+ Generates polygon coordinates for rendering filled wiggle lobes.
75
+
76
+ This function calculates sub-sample exact zero-crossings using linear interpolation
77
+ to create mathematically smooth filled areas. It is plotting-library agnostic.
78
+
79
+ Args:
80
+ data: 2D array of rescaled amplitudes (samples x traces).
81
+ offsetPosition: 1D array of horizontal trace locations.
82
+ timeSampleInstants: 1D array of time/depth values for the vertical axis.
83
+ fill_mode: "positive" to fill right-swinging lobes, "negative" for left-swinging.
84
+
85
+ Returns:
86
+ A dictionary `{"xs": [...], "ys": [...]}` where:
87
+ xs: List of lists containing the X coordinates for each trace's filled polygon.
88
+ ys: List of lists containing the Y coordinates for each trace's filled polygon.
89
+ """
90
+ if fill_mode not in ["positive", "negative"]:
91
+ raise ValueError("fill_mode must be 'positive' or 'negative'")
92
+
93
+ # The internal algorithm extracts negative values.
94
+ # If the user wants to fill positive lobes, we simply flip the polarity of the data.
95
+ working_data = -data if fill_mode == "positive" else data
96
+
97
+ xs_patches = []
98
+ ys_patches = []
99
+
100
+ for traceOffset, traceAmplitude in zip(offsetPosition, working_data.T):
101
+ lobeAmplitudes, lobeTimes = _interpolateLobeCoordinates(
102
+ timeSampleInstants,
103
+ traceAmplitude,
104
+ traceOffset
105
+ )
106
+
107
+ # Skip if the trace has no lobes of the requested polarity
108
+ if not lobeAmplitudes:
109
+ xs_patches.append([])
110
+ ys_patches.append([])
111
+ continue
112
+
113
+ # Build the single continuous polygon: Lobe path + return path along the baseline
114
+ # Note: We must invert the amplitude back to normal if we flipped it earlier
115
+ if fill_mode == "positive":
116
+ actualAmplitudes = [traceOffset - (amp - traceOffset) for amp in lobeAmplitudes]
117
+ else:
118
+ actualAmplitudes = lobeAmplitudes
119
+
120
+ polygonOffsetCoordinates = [traceOffset] * len(actualAmplitudes) + actualAmplitudes[::-1]
121
+ polygonTimeCoordinates = lobeTimes + lobeTimes[::-1]
122
+
123
+ xs_patches.append(polygonOffsetCoordinates)
124
+ ys_patches.append(polygonTimeCoordinates)
125
+
126
+ return {"xs": xs_patches, "ys": ys_patches}
pyseiskit/py.typed ADDED
File without changes
@@ -0,0 +1,43 @@
1
+ Metadata-Version: 2.5
2
+ Name: pyseiskit
3
+ Version: 0.1.0
4
+ Summary: A Python library for seismic data processing and pre-visualization.
5
+ Project-URL: Homepage, https://github.com/PETROGEO-UFRN/pyseiskit
6
+ Project-URL: Repository, https://github.com/PETROGEO-UFRN/pyseiskit
7
+ Author-email: JorbFreire <jorbfreire@gmail.com>
8
+ License: MIT
9
+ License-File: LICENSE
10
+ Keywords: SU,data processing,geophysics,seismic,seismic unix,wiggle
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Scientific/Engineering :: Physics
21
+ Requires-Python: >=3.9
22
+ Requires-Dist: numpy
23
+ Requires-Dist: scipy
24
+ Description-Content-Type: text/markdown
25
+
26
+ # pyseiskit
27
+
28
+ A Python library for seismic data processing.
29
+
30
+ Includes *wiggle* helpers, wich can be used together with common plot libraries such as:
31
+
32
+ - Matplotlib
33
+ - Bokeh
34
+ - Plotly
35
+
36
+ ## Installation
37
+ ```bash
38
+ pip install pyseiskit
39
+ ```
40
+
41
+ ## [Available Demos](/demos)
42
+ - [Wiggle plotting with common libraries](/demos/wiggle.ipynb)
43
+ - [Gain methods](/demos/gain.ipynb)
@@ -0,0 +1,29 @@
1
+ pyseiskit/__init__.py,sha256=AwTaxxl5N9qCrb6ZyjOYBkmwv8v1NWV-3biR0m4mVVU,233
2
+ pyseiskit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ pyseiskit/modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ pyseiskit/modules/applyGains/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ pyseiskit/modules/applyGains/applyGains.py,sha256=U4ZiK86gb84xYl6oqDaodP8crj-AX6DvjrTRHgbHDZg,1092
6
+ pyseiskit/modules/applyGains/gainStrategies.py,sha256=ezZRmy7jU8D83MCPKO-nHCvn-q174uEmVVl3bAVuSw4,340
7
+ pyseiskit/modules/applyGains/adapters/__init__.py,sha256=A1-rqVJZR6deGC0DbYlhJqMp7ov2_cPMFAJPUSV0HsY,43
8
+ pyseiskit/modules/applyGains/adapters/clipAdapter.py,sha256=7CxVhsR_n7xCnil_AIYDdzJI1oLEAWn0jSDr0mVps8s,465
9
+ pyseiskit/modules/clip/__init__.py,sha256=AJT90JbIk-bdYLygqI84S2EbshJ8mUIsMVH0tbH62Vc,48
10
+ pyseiskit/modules/clip/percentileClip.py,sha256=s2G7VU8CrkODOXbEoFZrckleY0YaKirge-zeRdRQi2o,777
11
+ pyseiskit/modules/clip/contracts/PercentileClip.py,sha256=HgFvARg8KLN9QE6viNiGZyqIY3iQVlmHOzeaD7yzIQ8,560
12
+ pyseiskit/modules/clip/contracts/__init__.py,sha256=yN1CT2zDL-_cu0m9S6z8N2TE3RzZK_VrPTexUBQQBJg,51
13
+ pyseiskit/modules/gain/__init__.py,sha256=Qks9VshxyA_OH8BpUQerxeg_7IGWf01BPOnBcvlBvDo,54
14
+ pyseiskit/modules/gain/agc.py,sha256=RrWQXd0d2O1DoLe6MugoYZY6DG0_RoWZ3G3OWX9ilqY,1529
15
+ pyseiskit/modules/gain/gagc.py,sha256=EgxiwFSUuxeuDOaGq98g_h7CQpNdtjMeelGuD8MFMTk,1635
16
+ pyseiskit/modules/gain/contracts/AutomaticGain.py,sha256=ngE_djLcV0sokG7lEhFKWwPKXQLJoHDJxLRMRu4oeS0,633
17
+ pyseiskit/modules/gain/contracts/GenericGain.py,sha256=fQqOgOql16QJi_AgWL_V0-JoJGoEndXBgcs7q4qFvHQ,568
18
+ pyseiskit/modules/gain/contracts/__init__.py,sha256=5d5y6DdJ98S70_wRtp6ql_1t5bsM0hHy6UgKP0gI7D4,94
19
+ pyseiskit/modules/palettes/PALETTES.py,sha256=6TM7ZYqGNzc97l1dLUOMFyUaQUvDgO0y9gQj7KDfETw,255
20
+ pyseiskit/modules/palettes/__init__.py,sha256=Mv_bF0y13eguj98wI9rz_LcL0jEeCjBPlpfvYL5oCk8,31
21
+ pyseiskit/modules/palettes/getFadingPalette.py,sha256=Rcmiece8xxAECJKg9KN3-xKBd4Tgnj9I_blsfyFNrsk,787
22
+ pyseiskit/modules/sourceData/__init__.py,sha256=upeayOuOXNzJpEg-DY8ex4gY6C-RVdr8f9RHUlXK9_E,177
23
+ pyseiskit/modules/sourceData/rescaleDataForWiggle.py,sha256=Z8ZLz5VVjOIoOlTtnoPGkHBlM6GBYmIktNVgiu8eA74,2023
24
+ pyseiskit/modules/sourceData/wiggleLinesDataFactory.py,sha256=JAP0LQuol0dop-O0D7ueoksrwhpkCwpW1ddP2EtijSs,607
25
+ pyseiskit/modules/sourceData/wigglePatchesDataFactory.py,sha256=rKMGpumCXIZBk0o8qSgTNi8NGM4ifTYkVQxKd_b3k3s,4856
26
+ pyseiskit-0.1.0.dist-info/METADATA,sha256=dalBtDtyHOvQLsuUoiZu8GJ2xpeHRm1ynz48aIbzO4U,1388
27
+ pyseiskit-0.1.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
28
+ pyseiskit-0.1.0.dist-info/licenses/LICENSE,sha256=Nb2j7KkrzjaGNwtyEBAOIZHOqlVlyxML27s62sVL-hA,1065
29
+ pyseiskit-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.32.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PETROGEO
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.