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.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: das2numpy
3
- Version: 0.0.3
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 (make sure that the current working directory is not inside idas2numpy):
84
+ Example call:
84
85
  ```
85
- python -m idas2numpy "SILIXA" ~/iDAS/work/2024-05-10-desy/ 2024-05-10T10:01:00 2024-05-10T10:02:00 10 0 1000 10 default
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 idas2numpy -h
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 (make sure that the current working directory is not inside idas2numpy):
70
+ Example call:
71
71
  ```
72
- python -m idas2numpy "SILIXA" ~/iDAS/work/2024-05-10-desy/ 2024-05-10T10:01:00 2024-05-10T10:02:00 10 0 1000 10 default
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 idas2numpy -h
77
+ python -m das2numpy -h
78
78
  ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "das2numpy"
7
- version = "0.0.3"
7
+ version = "0.0.4"
8
8
  authors = [
9
9
  { name="Erik Genthe", email="erik.genthe@desy.de" },
10
10
  ]
@@ -109,7 +109,7 @@ class FileFinder():
109
109
  return self.__file_pathes[ first[0] : last[0] + 1 ]
110
110
 
111
111
 
112
- def get_first(self) -> tuple:
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[0]
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.get_first()[1]
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
- return to_posix_timestamp_ms(DT.datetime.strptime(file_name[-24:], "%Y%m%d_%H%M%S.%f.tdms"))
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 (NP.float, NP.float32, NP.float64):
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
- #@njit
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
1
+ Metadata-Version: 2.4
2
2
  Name: das2numpy
3
- Version: 0.0.3
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 (make sure that the current working directory is not inside idas2numpy):
84
+ Example call:
84
85
  ```
85
- python -m idas2numpy "SILIXA" ~/iDAS/work/2024-05-10-desy/ 2024-05-10T10:01:00 2024-05-10T10:02:00 10 0 1000 10 default
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 idas2numpy -h
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(2024, 5, 11, 1, 0, 0)
9
- t_end = datetime(2024, 5, 11, 1, 0, 5)
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/work/2024-05-11-desy", "SILIXA", 1)
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 = (10, 10)
17
- data = utils.bin(data, bin_factors) # Reduce time sampling and spatial sampling by a factor of 10 by averaging each.
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
- origin = "lower",
29
- vmin = -2e-6,
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