daplis 0.9.1__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.
daplis-0.9.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Sergei Kulkov
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.
daplis-0.9.1/PKG-INFO ADDED
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.1
2
+ Name: daplis
3
+ Version: 0.9.1
4
+ Summary: Data Analysis Package for LInoSpad2
5
+ Author-email: Sergei Kulkov <sergei.kulkov23@gmail.com>
6
+ License: MIT
7
+ Keywords: timestamp,analysis,LinoSPAD2
8
+ Classifier: Programming Language :: Python :: 3.8
9
+ Classifier: Programming Language :: Python :: 3.9
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Requires-Python: >=3.8
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: lmfit>=0.9.1
18
+ Requires-Dist: matplotlib>=3.5.0
19
+ Requires-Dist: numpy>=1.22.4
20
+ Requires-Dist: pandas>=1.4.0
21
+ Requires-Dist: pyarrow>=17.0.0
22
+ Requires-Dist: scipy>=1.7.0
23
+ Requires-Dist: seaborn>=0.9.0
24
+ Requires-Dist: tqdm>=4.5.0
25
+
26
+ # LinoSPAD2
27
+
28
+ Package for unpacking and analyzing the binary data from LinoSPAD2.
29
+
30
+ ![Tests](https://github.com/rngKomorebi/LinoSPAD2/actions/workflows/tests.yml/badge.svg)
31
+ ![Documentation](https://github.com/rngKomorebi/LinoSPAD2/actions/workflows/documentation.yml/badge.svg)
32
+
33
+ ## Introduction
34
+
35
+ This package was written for data analysis for LinoSPAD2, mainly for
36
+ analysis of the timestamp output. The key functions are ones for
37
+ unpacking the binary output of the detector that utilizes the numpy
38
+ Python library for quick unpacking of .dat files to matrices,
39
+ dictionaries, or data frames.
40
+
41
+ The "functions" folder holds all functions from unpacking to plotting
42
+ numerous types of graphs (pixel population, histograms of timestamp
43
+ differences, etc.)
44
+
45
+ The "params" folder holds masks (used to mask some of the noisiest
46
+ pixels) and calibration data (compensating for TDC nonlinearities and
47
+ offset) for LinoSPAD2 daughterboards "A5" and "NL11".
48
+
49
+ The "archive" folder is a collection of scripts for debugging, tests,
50
+ older versions of functions, etc.
51
+
52
+ Full documentation, including examples and full documentation of
53
+ modules and functions, can be found [here](https://rngkomorebi.github.io/LinoSPAD2/).
54
+
55
+ Some functions (mainly the plotting ones) save plots as pictures in the
56
+ .png format, creating a folder for the output in the same folder that
57
+ holds the data. Others (such as delta_t.py for collecting timestamp differences
58
+ in the given time window) save .csv files with the processed data for
59
+ easier and faster plotting.
60
+
61
+ Additionally, a standalone repo with an application for online plotting
62
+ of the sensor population can be found [here](https://github.com/rngKomorebi/LinoSPAD2-app).
63
+
64
+ ## Installation and usage
65
+
66
+ To start using the package, one can download the whole repo. The 'main.py'
67
+ serves as the main hub for calling the functions. "requirements.txt"
68
+ collects all packages required for this project to run. One can create
69
+ an environment for this project either using conda or install the
70
+ necessary packages using pip (for creating virtual environments using pip
71
+ see [this](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/)):
72
+ ```
73
+ pip install virtualenv
74
+ py -m venv PATH/TO/ENVIRONMENT/ENVIRONMENT_NAME
75
+ PATH/TO/ENVIRONMENT/ENVIRONMENT_NAME/Scripts/activate
76
+ cd PATH/TO/GITHUB/CODES/LinoSPAD2
77
+ pip install -r requirements.txt
78
+ ```
79
+ or (recommended)
80
+ ```
81
+ conda create --name NEW_ENVIRONMENT_NAME --file /PATH/TO/requirements.txt -c conda-forge
82
+ ```
83
+ To install the package, first, switch to the created environment:
84
+ ```
85
+ conda activate NEW_ENVIRONMENT_NAME
86
+ ```
87
+ or
88
+ ```
89
+ PATH/TO/ENVIRONMENT/ENVIRONMENT_NAME/Scripts/activate
90
+ ```
91
+ and run
92
+ ```
93
+ pip install -e .
94
+ ```
95
+ that will install the local package LinoSPAD2. After that, you can
96
+ import all functions in your project:
97
+ ```
98
+ from LinoSPAD2.functions import plot_tmsp, delta_t, fits
99
+ ```
100
+
101
+ ## How to contribute
102
+
103
+ This repo consists of two branches: 'main' serves as the release version
104
+ of the package, tested, proven to be functional, and ready to use, while
105
+ the 'develop' branch serves as the main hub for testing new stuff. To
106
+ contribute, the best way would be to fork the 'develop' branch and
107
+ submit via pull requests. Everyone willing to contribute is kindly asked
108
+ to follow the [PEP 8](https://peps.python.org/pep-0008/) and
109
+ [PEP 257](https://peps.python.org/pep-0257/) conventions.
110
+
111
+ ## License and contact info
112
+
113
+ This package is available under the MIT license. See LICENSE for more
114
+ information. If you'd like to contact me, the author, feel free to
115
+ write at sergei.kulkov23@gmail.com.
daplis-0.9.1/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # LinoSPAD2
2
+
3
+ Package for unpacking and analyzing the binary data from LinoSPAD2.
4
+
5
+ ![Tests](https://github.com/rngKomorebi/LinoSPAD2/actions/workflows/tests.yml/badge.svg)
6
+ ![Documentation](https://github.com/rngKomorebi/LinoSPAD2/actions/workflows/documentation.yml/badge.svg)
7
+
8
+ ## Introduction
9
+
10
+ This package was written for data analysis for LinoSPAD2, mainly for
11
+ analysis of the timestamp output. The key functions are ones for
12
+ unpacking the binary output of the detector that utilizes the numpy
13
+ Python library for quick unpacking of .dat files to matrices,
14
+ dictionaries, or data frames.
15
+
16
+ The "functions" folder holds all functions from unpacking to plotting
17
+ numerous types of graphs (pixel population, histograms of timestamp
18
+ differences, etc.)
19
+
20
+ The "params" folder holds masks (used to mask some of the noisiest
21
+ pixels) and calibration data (compensating for TDC nonlinearities and
22
+ offset) for LinoSPAD2 daughterboards "A5" and "NL11".
23
+
24
+ The "archive" folder is a collection of scripts for debugging, tests,
25
+ older versions of functions, etc.
26
+
27
+ Full documentation, including examples and full documentation of
28
+ modules and functions, can be found [here](https://rngkomorebi.github.io/LinoSPAD2/).
29
+
30
+ Some functions (mainly the plotting ones) save plots as pictures in the
31
+ .png format, creating a folder for the output in the same folder that
32
+ holds the data. Others (such as delta_t.py for collecting timestamp differences
33
+ in the given time window) save .csv files with the processed data for
34
+ easier and faster plotting.
35
+
36
+ Additionally, a standalone repo with an application for online plotting
37
+ of the sensor population can be found [here](https://github.com/rngKomorebi/LinoSPAD2-app).
38
+
39
+ ## Installation and usage
40
+
41
+ To start using the package, one can download the whole repo. The 'main.py'
42
+ serves as the main hub for calling the functions. "requirements.txt"
43
+ collects all packages required for this project to run. One can create
44
+ an environment for this project either using conda or install the
45
+ necessary packages using pip (for creating virtual environments using pip
46
+ see [this](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/)):
47
+ ```
48
+ pip install virtualenv
49
+ py -m venv PATH/TO/ENVIRONMENT/ENVIRONMENT_NAME
50
+ PATH/TO/ENVIRONMENT/ENVIRONMENT_NAME/Scripts/activate
51
+ cd PATH/TO/GITHUB/CODES/LinoSPAD2
52
+ pip install -r requirements.txt
53
+ ```
54
+ or (recommended)
55
+ ```
56
+ conda create --name NEW_ENVIRONMENT_NAME --file /PATH/TO/requirements.txt -c conda-forge
57
+ ```
58
+ To install the package, first, switch to the created environment:
59
+ ```
60
+ conda activate NEW_ENVIRONMENT_NAME
61
+ ```
62
+ or
63
+ ```
64
+ PATH/TO/ENVIRONMENT/ENVIRONMENT_NAME/Scripts/activate
65
+ ```
66
+ and run
67
+ ```
68
+ pip install -e .
69
+ ```
70
+ that will install the local package LinoSPAD2. After that, you can
71
+ import all functions in your project:
72
+ ```
73
+ from LinoSPAD2.functions import plot_tmsp, delta_t, fits
74
+ ```
75
+
76
+ ## How to contribute
77
+
78
+ This repo consists of two branches: 'main' serves as the release version
79
+ of the package, tested, proven to be functional, and ready to use, while
80
+ the 'develop' branch serves as the main hub for testing new stuff. To
81
+ contribute, the best way would be to fork the 'develop' branch and
82
+ submit via pull requests. Everyone willing to contribute is kindly asked
83
+ to follow the [PEP 8](https://peps.python.org/pep-0008/) and
84
+ [PEP 257](https://peps.python.org/pep-0257/) conventions.
85
+
86
+ ## License and contact info
87
+
88
+ This package is available under the MIT license. See LICENSE for more
89
+ information. If you'd like to contact me, the author, feel free to
90
+ write at sergei.kulkov23@gmail.com.
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "daplis"
7
+ version = "0.9.1"
8
+ description = "Data Analysis Package for LInoSpad2"
9
+ authors = [{ name = "Sergei Kulkov", email = "sergei.kulkov23@gmail.com" }]
10
+ license = { text = "MIT" }
11
+ readme = "README.md"
12
+ requires-python = ">=3.8"
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3.8",
15
+ "Programming Language :: Python :: 3.9",
16
+ "Programming Language :: Python :: 3.10",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Programming Language :: Python :: 3.13",
20
+ ]
21
+ keywords = ["timestamp", "analysis", "LinoSPAD2"]
22
+
23
+ dependencies = [
24
+ "lmfit>=0.9.1",
25
+ "matplotlib>=3.5.0",
26
+ "numpy>=1.22.4",
27
+ "pandas>=1.4.0",
28
+ "pyarrow>=17.0.0",
29
+ "scipy>=1.7.0",
30
+ "seaborn>=0.9.0",
31
+ "tqdm>=4.5.0",
32
+ ]
33
+
34
+ [tool.setuptools.packages.find]
35
+ where = ["src"]
daplis-0.9.1/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
File without changes
@@ -0,0 +1,256 @@
1
+ """Module for computing timestamp differences.
2
+
3
+ Compares all timestamps from the same cycle for the given pair of pixels
4
+ against a given value (delta_window). Differences in that window are saved
5
+ and returned as a list.
6
+
7
+ This file can also be imported as a module and contains the following
8
+ functions:
9
+
10
+ TODO remove
11
+ * calculate_differences_2212 - calculate timestamp differences for
12
+ the given pair of pixels. Works only with firmware version '2212'.
13
+
14
+ * calculate_differences_2212_fast - calculate timestamp differences for
15
+ the given pair of pixels. Works only with firmware version '2212'.
16
+ Uses a faster algorithm than the function above.
17
+
18
+ """
19
+
20
+ from typing import List
21
+ from warnings import warn
22
+
23
+ import numpy as np
24
+ import pandas as pd
25
+ from numpy import ndarray
26
+
27
+ from LinoSPAD2.functions import utils
28
+
29
+
30
+ def calculate_differences_2212(
31
+ data: List[float],
32
+ pixels: List[int] | List[List[int]],
33
+ pix_coor,
34
+ delta_window: float = 50e3,
35
+ ):
36
+ """Calculate timestamp differences for firmware version 2212.
37
+
38
+ Calculate timestamp differences for the given pixels and LinoSPAD2
39
+ firmware version 2212.
40
+
41
+ Parameters
42
+ ----------
43
+ data : list of array-like
44
+ List of data arrays, each corresponding to a different TDC.
45
+ pixels : List[int] | List[List[int]]
46
+ List of pixel numbers for which the timestamp differences should
47
+ be calculated or list of two lists with pixel numbers for peak
48
+ vs. peak calculations.
49
+ pix_coor : array-like
50
+ Array for transforming the pixel address in terms of TDC (0 to 3)
51
+ to pixel number in terms of half of the sensor (0 to 255).
52
+ delta_window : float, optional
53
+ Width of the time window for counting timestamp differences.
54
+ The default is 50e3 (50 ns).
55
+
56
+ Returns
57
+ -------
58
+ deltas_all : dict
59
+ Dictionary containing timestamp differences for each pair of pixels.
60
+
61
+ """
62
+
63
+ # TODO: remove
64
+ warn(
65
+ "This function is deprecated. Use" "'calculate_differences_2212_fast'",
66
+ DeprecationWarning,
67
+ stacklevel=2,
68
+ )
69
+ # Dictionary for the timestamp differences, where keys are the
70
+ # pixel numbers of the requested pairs
71
+ deltas_all = {}
72
+
73
+ pixels_left, pixels_right = utils.pixel_list_transform(pixels)
74
+
75
+ # Find ends of cycles
76
+ cycle_ends = np.argwhere(data[0].T[0] == -2)
77
+ cycle_ends = np.insert(cycle_ends, 0, 0)
78
+
79
+ for q in pixels_left:
80
+ # First pixel in the pair
81
+ tdc1, pix_c1 = np.argwhere(pix_coor == q)[0]
82
+ pix1 = np.where(data[tdc1].T[0] == pix_c1)[0]
83
+ for w in pixels_right:
84
+ if w <= q:
85
+ continue
86
+ deltas_all[f"{q},{w}"] = []
87
+
88
+ # Second pixel in the pair
89
+ tdc2, pix_c2 = np.argwhere(pix_coor == w)[0]
90
+ pix2 = np.where(data[tdc2].T[0] == pix_c2)[0]
91
+
92
+ # Go over cycles, getting data for the appropriate cycle
93
+ # only
94
+ for cyc in range(len(cycle_ends) - 1):
95
+ slice_from = cycle_ends[cyc]
96
+ slice_to = cycle_ends[cyc + 1]
97
+ pix1_slice = pix1[(pix1 >= slice_from) & (pix1 < slice_to)]
98
+ if not np.any(pix1_slice):
99
+ continue
100
+ pix2_slice = pix2[(pix2 >= slice_from) & (pix2 < slice_to)]
101
+ if not np.any(pix2_slice):
102
+ continue
103
+
104
+ # Calculate delta t
105
+ tmsp1 = data[tdc1].T[1][pix1_slice]
106
+ tmsp1 = tmsp1[tmsp1 > 0]
107
+ tmsp2 = data[tdc2].T[1][pix2_slice]
108
+ tmsp2 = tmsp2[tmsp2 > 0]
109
+ for t1 in tmsp1:
110
+ deltas = tmsp2 - t1
111
+ ind = np.where(np.abs(deltas) < delta_window)[0]
112
+ deltas_all[f"{q},{w}"].extend(deltas[ind])
113
+
114
+ return deltas_all
115
+
116
+
117
+ def calculate_differences_2212_fast(
118
+ data: ndarray,
119
+ pixels: List[int] | List[List[int]],
120
+ pix_coor: ndarray,
121
+ delta_window: float = 50e3,
122
+ cycle_length: float = 4e9,
123
+ ):
124
+ """Calculate timestamp differences for firmware version 2212.
125
+
126
+ Calculate timestamp differences for the given pixels and LinoSPAD2
127
+ firmware version 2212.
128
+
129
+ Parameters
130
+ ----------
131
+ data : ndarray
132
+ Matrix of timestamps, where rows correspond to the TDCs.
133
+ pixels : List[int] | List[List[int]]
134
+ List of pixel numbers for which the timestamp differences should
135
+ be calculated or list of two lists with pixel numbers for peak
136
+ vs. peak calculations.
137
+ pix_coor : ndarray
138
+ Array for transforming the pixel address in terms of TDC (0 to 3)
139
+ to pixel number in terms of half of the sensor (0 to 255).
140
+ delta_window : float, optional
141
+ Width of the time window for counting timestamp differences.
142
+ The default is 50e3 (50 ns).
143
+ cycle_length : float, optional
144
+ Length of each acquisition cycle. The default is 4e9 (4 ms).
145
+
146
+ Returns
147
+ -------
148
+ deltas_all : dict
149
+ Dictionary containing timestamp differences for each pair of pixels.
150
+
151
+ """
152
+
153
+ # Dictionary for the timestamp differences, where keys are the
154
+ # pixel numbers of the requested pairs
155
+ deltas_all = {}
156
+
157
+ pixels_left, pixels_right = utils.pixel_list_transform(pixels)
158
+
159
+ # Find ends of cycles
160
+ cycle_ends = np.argwhere(data[0].T[0] == -2)
161
+ cycle_ends = np.insert(cycle_ends, 0, 0)
162
+
163
+ for q in pixels_left:
164
+ # First pixel in the pair
165
+ tdc1, pix_c1 = np.argwhere(pix_coor == q)[0]
166
+ pix1 = np.where(data[tdc1].T[0] == pix_c1)[0]
167
+ for w in pixels_right:
168
+ if w <= q:
169
+ continue
170
+ deltas_all[f"{q},{w}"] = []
171
+
172
+ timestamps_1 = []
173
+ timestamps_2 = []
174
+
175
+ # Second pixel in the pair
176
+ tdc2, pix_c2 = np.argwhere(pix_coor == w)[0]
177
+ pix2 = np.where(data[tdc2].T[0] == pix_c2)[0]
178
+
179
+ # Go over cycles, shifting the timestamps from each next
180
+ # cycle by lengths of cycles before (e.g., for the 4th cycle
181
+ # add 12 ms)
182
+ for i, _ in enumerate(cycle_ends[:-1]):
183
+ slice_from = cycle_ends[i]
184
+ slice_to = cycle_ends[i + 1]
185
+ pix1_slice = pix1[(pix1 >= slice_from) & (pix1 < slice_to)]
186
+ if not np.any(pix1_slice):
187
+ continue
188
+ pix2_slice = pix2[(pix2 >= slice_from) & (pix2 < slice_to)]
189
+ if not np.any(pix2_slice):
190
+ continue
191
+
192
+ # Shift timestamps by cycle length
193
+ tmsp1 = data[tdc1].T[1][pix1_slice]
194
+ tmsp1 = tmsp1[tmsp1 > 0]
195
+ tmsp1 = tmsp1 + cycle_length * i
196
+
197
+ tmsp2 = data[tdc2].T[1][pix2_slice]
198
+ tmsp2 = tmsp2[tmsp2 > 0]
199
+ tmsp2 = tmsp2 + cycle_length * i
200
+
201
+ timestamps_1.extend(tmsp1)
202
+ timestamps_2.extend(tmsp2)
203
+
204
+ timestamps_1 = np.array(timestamps_1)
205
+ timestamps_2 = np.array(timestamps_2)
206
+
207
+ # Indicators for each pixel: 0 for timestamps from one pixel
208
+ # 1 - from the other
209
+ pix1_ind = np.zeros(len(timestamps_1), dtype=np.int32)
210
+ pix2_ind = np.ones(len(timestamps_2), dtype=np.int32)
211
+
212
+ pix1_data = np.vstack((pix1_ind, timestamps_1))
213
+ pix2_data = np.vstack((pix2_ind, timestamps_2))
214
+
215
+ # Dataframe for each pixel with pixel indicator and
216
+ # timestamps
217
+ df1 = pd.DataFrame(
218
+ pix1_data.T, columns=["Pixel_index", "Timestamp"]
219
+ )
220
+ df2 = pd.DataFrame(
221
+ pix2_data.T, columns=["Pixel_index", "Timestamp"]
222
+ )
223
+
224
+ # Combine the two dataframes
225
+ df_combined = pd.concat((df1, df2), ignore_index=True)
226
+
227
+ # Sort the timestamps
228
+ df_combined.sort_values("Timestamp", inplace=True)
229
+
230
+ # Subtract pixel indicators of neighbors; values of 0
231
+ # correspond to timestamp differences for the same pixel
232
+ # '-1' and '1' - to differences from different pixels
233
+ df_combined["Pixel_index_diff"] = df_combined["Pixel_index"].diff()
234
+
235
+ # Calculate timestamp difference between neighbors
236
+ df_combined["Timestamp_diff"] = df_combined["Timestamp"].diff()
237
+
238
+ # Get the correct timestamp difference sign
239
+ df_combined["Timestamp_diff"] = (
240
+ df_combined["Timestamp_diff"] * df_combined["Pixel_index_diff"]
241
+ )
242
+
243
+ # Collect timestamp differences where timestamps are from
244
+ # different pixels
245
+ filtered_df = df_combined[
246
+ abs(df_combined["Pixel_index_diff"]) == 1
247
+ ]
248
+
249
+ # Save only timestamps differences in the requested window
250
+ delta_ts = filtered_df[
251
+ abs(filtered_df["Timestamp_diff"]) < delta_window
252
+ ]["Timestamp_diff"].values
253
+
254
+ deltas_all[f"{q},{w}"].extend(delta_ts)
255
+
256
+ return deltas_all