das2numpy 0.0.3__tar.gz → 0.0.4__tar.gz
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.
- {das2numpy-0.0.3/src/das2numpy.egg-info → das2numpy-0.0.4}/PKG-INFO +6 -5
- {das2numpy-0.0.3 → das2numpy-0.0.4}/README.md +3 -3
- {das2numpy-0.0.3 → das2numpy-0.0.4}/pyproject.toml +1 -1
- {das2numpy-0.0.3 → das2numpy-0.0.4}/src/das2numpy/filefinder.py +2 -2
- {das2numpy-0.0.3 → das2numpy-0.0.4}/src/das2numpy/setups/silixa.py +6 -8
- {das2numpy-0.0.3 → das2numpy-0.0.4}/src/das2numpy/utils.py +51 -23
- {das2numpy-0.0.3 → das2numpy-0.0.4/src/das2numpy.egg-info}/PKG-INFO +6 -5
- {das2numpy-0.0.3 → das2numpy-0.0.4}/src/example.py +10 -8
- {das2numpy-0.0.3 → das2numpy-0.0.4}/LICENSE +0 -0
- {das2numpy-0.0.3 → das2numpy-0.0.4}/setup.cfg +0 -0
- {das2numpy-0.0.3 → das2numpy-0.0.4}/src/das2numpy/__init__.py +0 -0
- {das2numpy-0.0.3 → das2numpy-0.0.4}/src/das2numpy/__main__.py +0 -0
- {das2numpy-0.0.3 → das2numpy-0.0.4}/src/das2numpy/chunk.py +0 -0
- {das2numpy-0.0.3 → das2numpy-0.0.4}/src/das2numpy/setups/light_tdms_reader.py +0 -0
- {das2numpy-0.0.3 → das2numpy-0.0.4}/src/das2numpy/setups/optasense_b35idefix.py +0 -0
- {das2numpy-0.0.3 → das2numpy-0.0.4}/src/das2numpy/setups/optasense_b35idefix_fast.py +0 -0
- {das2numpy-0.0.3 → das2numpy-0.0.4}/src/das2numpy/test.py +0 -0
- {das2numpy-0.0.3 → das2numpy-0.0.4}/src/das2numpy.egg-info/SOURCES.txt +0 -0
- {das2numpy-0.0.3 → das2numpy-0.0.4}/src/das2numpy.egg-info/dependency_links.txt +0 -0
- {das2numpy-0.0.3 → das2numpy-0.0.4}/src/das2numpy.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: das2numpy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: A simple and universal package for loading large amounts of distributed acoustic sensing (DAS) data.
|
|
5
5
|
Author-email: Erik Genthe <erik.genthe@desy.de>
|
|
6
6
|
Project-URL: Homepage, https://git.physnet.uni-hamburg.de/wave/das2numpy
|
|
@@ -10,6 +10,7 @@ Classifier: Operating System :: OS Independent
|
|
|
10
10
|
Requires-Python: >=3.8
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
|
13
|
+
Dynamic: license-file
|
|
13
14
|
|
|
14
15
|
# Module for loading Distributed Acoustic Sensing (DAS) data. SILIXA / OPTASENSE
|
|
15
16
|
|
|
@@ -80,12 +81,12 @@ For example, the above interfaces also exist with POSIX timestamps in millisecon
|
|
|
80
81
|
|
|
81
82
|
## Use as command line interface
|
|
82
83
|
|
|
83
|
-
Example call
|
|
84
|
+
Example call:
|
|
84
85
|
```
|
|
85
|
-
python -m
|
|
86
|
+
python -m das2numpy "SILIXA" /pnfs/desy.de/m/project/iDAS/raw/2025-DESY/2025-03-25-desy 2025-03-25T10:01:00 2025-03-25T10:02:00 10 0 1000 10 default
|
|
86
87
|
```
|
|
87
88
|
|
|
88
89
|
For more information:
|
|
89
90
|
```
|
|
90
|
-
python -m
|
|
91
|
+
python -m das2numpy -h
|
|
91
92
|
```
|
|
@@ -67,12 +67,12 @@ For example, the above interfaces also exist with POSIX timestamps in millisecon
|
|
|
67
67
|
|
|
68
68
|
## Use as command line interface
|
|
69
69
|
|
|
70
|
-
Example call
|
|
70
|
+
Example call:
|
|
71
71
|
```
|
|
72
|
-
python -m
|
|
72
|
+
python -m das2numpy "SILIXA" /pnfs/desy.de/m/project/iDAS/raw/2025-DESY/2025-03-25-desy 2025-03-25T10:01:00 2025-03-25T10:02:00 10 0 1000 10 default
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
For more information:
|
|
76
76
|
```
|
|
77
|
-
python -m
|
|
77
|
+
python -m das2numpy -h
|
|
78
78
|
```
|
|
@@ -109,7 +109,7 @@ class FileFinder():
|
|
|
109
109
|
return self.__file_pathes[ first[0] : last[0] + 1 ]
|
|
110
110
|
|
|
111
111
|
|
|
112
|
-
def
|
|
112
|
+
def get_elem(self, index) -> tuple:
|
|
113
113
|
if len(self.__file_pathes) == 0:
|
|
114
114
|
raise Exception(f"No data files found in root directory: {self.__root_path}")
|
|
115
|
-
return self.__file_pathes[
|
|
115
|
+
return self.__file_pathes[index]
|
|
@@ -19,16 +19,12 @@ CALIBRATE = True
|
|
|
19
19
|
|
|
20
20
|
def init(root_path, num_worker_threads):
|
|
21
21
|
assert P.isdir(root_path)
|
|
22
|
-
file_time_sample_amount = 20000
|
|
23
22
|
file_finder = FileFinder(root_path, ".tdms", filename_to_posix_timestamp)
|
|
24
|
-
example_file_path = file_finder.
|
|
23
|
+
example_file_path = file_finder.get_elem(10)[1] # TODO get first instead of 10th
|
|
25
24
|
tdms = TdmsReader(example_file_path)
|
|
26
25
|
shape = tdms.get_mmap().shape
|
|
27
26
|
file_time_sample_amount = shape[0]
|
|
28
27
|
channel_amount = shape[1]
|
|
29
|
-
#channel_amount = tdms.fileinfo['n_channels']
|
|
30
|
-
#props = tdms.get_properties()
|
|
31
|
-
#fs = props.get('SamplingFrequency[Hz]') #TODO read sampling freq from file
|
|
32
28
|
assert num_worker_threads >= 1
|
|
33
29
|
multithreaded = num_worker_threads > 1
|
|
34
30
|
return Chunk(
|
|
@@ -42,8 +38,10 @@ def init(root_path, num_worker_threads):
|
|
|
42
38
|
)
|
|
43
39
|
|
|
44
40
|
def filename_to_posix_timestamp(file_name:str) -> int:
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
timestamp_str = file_name.split("_UTC_")[1][:19]
|
|
42
|
+
timestamp_dt = DT.datetime.strptime(timestamp_str, "%Y%m%d_%H%M%S.%f")
|
|
43
|
+
timestamp_ms = to_posix_timestamp_ms(timestamp_dt)
|
|
44
|
+
return timestamp_ms
|
|
47
45
|
|
|
48
46
|
|
|
49
47
|
def load_file(file_path, rel_t_start, rel_t_end, t_step, channel_start, channel_end, channel_step) -> NP.ndarray:
|
|
@@ -76,7 +74,7 @@ def calibrate(data:NP.ndarray) -> NP.ndarray:
|
|
|
76
74
|
""" Convert raw data to strain rate data.
|
|
77
75
|
As the resulting values are decimals, the datatype should be float. Otherwise an assertion fails. """
|
|
78
76
|
#assert data.dtype in (NP.float, NP.float32, NP.float64), f"The data should be floating point. It is {data.dtype}"
|
|
79
|
-
if data.dtype not in (
|
|
77
|
+
if data.dtype not in (float, NP.float32, NP.float64):
|
|
80
78
|
NEW_TYPE = NP.float32
|
|
81
79
|
#print("Warning: For calibration the data has to be of type float. Converting from {data.dtype} to {NEW_TYPE}")
|
|
82
80
|
data = data.astype(NEW_TYPE)
|
|
@@ -41,25 +41,7 @@ def differentiate(data: NP.ndarray, axis: int) -> NP.ndarray:
|
|
|
41
41
|
data[:,i] = data[:,i+1] - data[:,i]
|
|
42
42
|
return data
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
#def integrate(data: NP.ndarray, axis: int) -> NP.ndarray:
|
|
46
|
-
# """Integrate the 2-dimensional signal over one axis
|
|
47
|
-
# A 2-d array is expected as input
|
|
48
|
-
# The return-value is None. The array is copied, modified and returned.
|
|
49
|
-
# :return: integrated array
|
|
50
|
-
# """
|
|
51
|
-
# assert axis == 0 or axis == 1
|
|
52
|
-
# data = data.copy()
|
|
53
|
-
#
|
|
54
|
-
# if data.shape[axis] < 2:
|
|
55
|
-
# raise Exception("Integration with less then two samples makes no sense.")
|
|
56
|
-
# if axis == 0:
|
|
57
|
-
# for i in range(1, data.shape[0]):
|
|
58
|
-
# data[i] = data[i] + data[i-1]
|
|
59
|
-
# elif axis == 1:
|
|
60
|
-
# for i in range(1, data.shape[1]):
|
|
61
|
-
# data[:, i] = data[:, i] + data[:, i-1]
|
|
62
|
-
# return data
|
|
44
|
+
|
|
63
45
|
def integrate(data: NP.ndarray, axis: int, sample_rate_hz:float) -> NP.ndarray:
|
|
64
46
|
"""Integrate the 2-dimensional signal over one axis
|
|
65
47
|
A 2-d array is expected as input
|
|
@@ -85,12 +67,58 @@ def butterworth_filter(
|
|
|
85
67
|
array = SS.sosfiltfilt(sos, array, axis=TIME_AXIS, padtype='odd', padlen=None)
|
|
86
68
|
return array
|
|
87
69
|
|
|
88
|
-
#https://numpy.org/doc/stable/reference/generated/numpy.fft.fft.html#numpy.fft.fft
|
|
89
|
-
def fft(array):
|
|
90
|
-
raise NotImplementedError("Not implemented yet")
|
|
91
|
-
return None
|
|
92
70
|
|
|
93
71
|
|
|
72
|
+
def spectrum_smoothing(frequencies:NP.ndarray, psd:NP.ndarray, n:int):
|
|
73
|
+
"""
|
|
74
|
+
Perform 1/n decade smoothing on the power spectral density (PSD) data.
|
|
75
|
+
See also: https://dsp.stackexchange.com/questions/9967/1-n-octave-smoothing
|
|
76
|
+
|
|
77
|
+
Parameters:
|
|
78
|
+
frequencies : numpy.ndarray
|
|
79
|
+
Array containing the frequency values.
|
|
80
|
+
psd : numpy.ndarray
|
|
81
|
+
Array containing the power spectral density values corresponding to the frequencies.
|
|
82
|
+
n : int
|
|
83
|
+
The number of divisions per decade (e.g., n=10 for 1/10 decade smoothing).
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
numpy.ndarray, numpy.ndarray
|
|
87
|
+
Smoothed frequencies and PSD.
|
|
88
|
+
"""
|
|
89
|
+
frequencies = NP.array(frequencies)
|
|
90
|
+
psd = NP.array(psd)
|
|
91
|
+
if frequencies[0] == 0.0:
|
|
92
|
+
frequencies = frequencies[1:]
|
|
93
|
+
psd = psd[1:]
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# Generate new frequency points:
|
|
97
|
+
min_freq = frequencies[0]
|
|
98
|
+
max_freq = frequencies[-1]
|
|
99
|
+
min_freq_new_log = NP.floor(NP.log10(min_freq))
|
|
100
|
+
max_freq_new_log = NP.ceil(NP.log10(max_freq))
|
|
101
|
+
n_decades = int(max_freq_new_log - min_freq_new_log)
|
|
102
|
+
freq_new = NP.logspace(min_freq_new_log, max_freq_new_log, num=n_decades*n+1, base=10)
|
|
103
|
+
freq_new_log = NP.log10(freq_new)
|
|
104
|
+
step_log = freq_new_log[1] - freq_new_log[0]
|
|
105
|
+
|
|
106
|
+
freq_new_actual = []
|
|
107
|
+
psd_new = []
|
|
108
|
+
for i in range(len(freq_new)):
|
|
109
|
+
f_log = freq_new_log[i]
|
|
110
|
+
f_lower = 10**(f_log - step_log / 2)
|
|
111
|
+
f_higher = 10**(f_log + step_log / 2)
|
|
112
|
+
|
|
113
|
+
# Find the indices within this log decade interval
|
|
114
|
+
mask = (frequencies >= f_lower) & (frequencies < f_higher)
|
|
115
|
+
#print(freq_new[i], f_lower, f_higher, mask)
|
|
116
|
+
if NP.any(mask):
|
|
117
|
+
freq_new_actual.append(NP.mean(frequencies[mask]))
|
|
118
|
+
psd_new.append(NP.mean(psd[mask]))
|
|
119
|
+
|
|
120
|
+
return NP.array(freq_new_actual), NP.array(psd_new)
|
|
121
|
+
|
|
94
122
|
|
|
95
123
|
def bin(arr: NP.ndarray, bin_factors:tuple):
|
|
96
124
|
""" Returns a binned version of arr. If factors were 1, the original array is returned."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: das2numpy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: A simple and universal package for loading large amounts of distributed acoustic sensing (DAS) data.
|
|
5
5
|
Author-email: Erik Genthe <erik.genthe@desy.de>
|
|
6
6
|
Project-URL: Homepage, https://git.physnet.uni-hamburg.de/wave/das2numpy
|
|
@@ -10,6 +10,7 @@ Classifier: Operating System :: OS Independent
|
|
|
10
10
|
Requires-Python: >=3.8
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
|
13
|
+
Dynamic: license-file
|
|
13
14
|
|
|
14
15
|
# Module for loading Distributed Acoustic Sensing (DAS) data. SILIXA / OPTASENSE
|
|
15
16
|
|
|
@@ -80,12 +81,12 @@ For example, the above interfaces also exist with POSIX timestamps in millisecon
|
|
|
80
81
|
|
|
81
82
|
## Use as command line interface
|
|
82
83
|
|
|
83
|
-
Example call
|
|
84
|
+
Example call:
|
|
84
85
|
```
|
|
85
|
-
python -m
|
|
86
|
+
python -m das2numpy "SILIXA" /pnfs/desy.de/m/project/iDAS/raw/2025-DESY/2025-03-25-desy 2025-03-25T10:01:00 2025-03-25T10:02:00 10 0 1000 10 default
|
|
86
87
|
```
|
|
87
88
|
|
|
88
89
|
For more information:
|
|
89
90
|
```
|
|
90
|
-
python -m
|
|
91
|
+
python -m das2numpy -h
|
|
91
92
|
```
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import numpy as NP
|
|
1
2
|
import sys
|
|
2
3
|
from datetime import datetime
|
|
3
4
|
import matplotlib.pyplot as PP
|
|
@@ -5,19 +6,21 @@ from das2numpy import loader, utils
|
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
print("Load data to numpy-array")
|
|
8
|
-
t_start = datetime(
|
|
9
|
-
t_end = datetime(
|
|
9
|
+
t_start = datetime(2025, 3, 25, 1, 0, 0)
|
|
10
|
+
t_end = datetime(2025, 3, 25, 1, 1, 0)
|
|
10
11
|
channel_start = 0
|
|
11
12
|
channel_end = -1
|
|
12
|
-
loader = loader("/pnfs/desy.de/m/project/iDAS/
|
|
13
|
+
loader = loader("/pnfs/desy.de/m/project/iDAS/raw/2025-DESY/2025-03-25-desy", "SILIXA", 1)
|
|
13
14
|
data = loader.load_array(t_start, t_end, channel_start, channel_end)
|
|
14
15
|
|
|
15
16
|
print("Reduce data by binning (mean averaging)")
|
|
16
|
-
bin_factors = (
|
|
17
|
-
data = utils.bin(data, bin_factors) # Reduce time sampling and spatial sampling by
|
|
17
|
+
bin_factors = (100, 10)
|
|
18
|
+
data = utils.bin(data, bin_factors) # Reduce time sampling and spatial sampling by averaging.
|
|
18
19
|
sampling_hz = 1000.0 / bin_factors[0]
|
|
19
20
|
channel_spacing = 1.0 * bin_factors[1]
|
|
20
21
|
|
|
22
|
+
NP.save("data.npy", data)
|
|
23
|
+
|
|
21
24
|
print("Create plot with pyplot")
|
|
22
25
|
PP.title(f"{t_start.isoformat()}")
|
|
23
26
|
PP.imshow(
|
|
@@ -25,9 +28,8 @@ PP.imshow(
|
|
|
25
28
|
cmap = "seismic",
|
|
26
29
|
aspect = "auto",
|
|
27
30
|
interpolation = "nearest",
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
vmax = +2e-6,
|
|
31
|
+
vmin = -1e-7,
|
|
32
|
+
vmax = +1e-7,
|
|
31
33
|
extent = (
|
|
32
34
|
channel_start, channel_start + (data.shape[1] * channel_spacing),
|
|
33
35
|
data.shape[0] / sampling_hz, 0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|