ZaksPhysicsLibrary 1.5.0__tar.gz → 1.7.0__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.
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PKG-INFO +2 -2
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/__init__.py +8 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/analysis.py +193 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/loaders/oxysoft_loader.py +7 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/processing_TDT.py +10 -0
- zaksphysicslibrary-1.7.0/PhysicsLibrary/splice.py +113 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/ZaksPhysicsLibrary.egg-info/PKG-INFO +2 -2
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/ZaksPhysicsLibrary.egg-info/SOURCES.txt +1 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/pyproject.toml +2 -2
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/LICENSE +0 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/dataset.py +0 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/field_study_validation.py +0 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/file_parser.py +0 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/file_parser_generic.py +0 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/loaders/__init__.py +0 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/loaders/pt2_loader.py +0 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/loaders/tdt_loader.py +0 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/models.py +0 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/text_field_study.py +0 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/README.md +0 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/ZaksPhysicsLibrary.egg-info/dependency_links.txt +0 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/ZaksPhysicsLibrary.egg-info/requires.txt +0 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/ZaksPhysicsLibrary.egg-info/top_level.txt +0 -0
- {zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/setup.cfg +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ZaksPhysicsLibrary
|
|
3
|
-
Version: 1.
|
|
4
|
-
Summary: Data processing and analysis library for TDT, Oxysoft NIRS, Terranova EFNMR lab data, and
|
|
3
|
+
Version: 1.7.0
|
|
4
|
+
Summary: Data processing and analysis library for TDT, Oxysoft NIRS, Terranova EFNMR lab data, and text-field studies
|
|
5
5
|
Author: zakgm2
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/zakgm2/PhysicsLibrary
|
|
@@ -45,6 +45,14 @@ from .analysis import (
|
|
|
45
45
|
annotate_fft_peaks,
|
|
46
46
|
compute_slope_segment,
|
|
47
47
|
fit_model_to_segment,
|
|
48
|
+
compute_event_zscore_peth,
|
|
49
|
+
find_significant_peaks,
|
|
50
|
+
find_peak_near_events,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
from .splice import (
|
|
54
|
+
splice_keep_inside,
|
|
55
|
+
splice_cut_out,
|
|
48
56
|
)
|
|
49
57
|
|
|
50
58
|
from .models import (
|
|
@@ -69,6 +69,199 @@ def get_zscore_slice(time_array, signal, center_t, window=None, pre=None, post=N
|
|
|
69
69
|
return seg_x, (seg_y - mu) / std
|
|
70
70
|
|
|
71
71
|
|
|
72
|
+
def compute_event_zscore_peth(time_array, signal, event_times, pre, post, num_bins=300):
|
|
73
|
+
"""
|
|
74
|
+
Z-score and align every occurrence of one event type into a
|
|
75
|
+
trial x time matrix, for a stacked-heatmap + trial-average PETH view
|
|
76
|
+
(GuPPy-style) rather than a single click-triggered PETH.
|
|
77
|
+
|
|
78
|
+
Each trial is z-scored independently against its own pre-event
|
|
79
|
+
baseline (see get_zscore_slice) — that's what makes a trial's
|
|
80
|
+
response comparable regardless of the signal's absolute level at
|
|
81
|
+
that point in the recording. Trials are then resampled onto one
|
|
82
|
+
shared relative-time axis (num_bins points spanning -pre..+post) so
|
|
83
|
+
they can be stacked into a single matrix despite each trial's raw
|
|
84
|
+
segment having a slightly different sample count from indexing
|
|
85
|
+
rounding.
|
|
86
|
+
|
|
87
|
+
Parameters
|
|
88
|
+
----------
|
|
89
|
+
time_array : array
|
|
90
|
+
signal : array
|
|
91
|
+
event_times : list of float
|
|
92
|
+
Timestamps (same units as time_array) for every occurrence of
|
|
93
|
+
the event being analyzed.
|
|
94
|
+
pre, post : float
|
|
95
|
+
Seconds before/after each event to include.
|
|
96
|
+
num_bins : int
|
|
97
|
+
Number of points each trial is resampled to.
|
|
98
|
+
|
|
99
|
+
Returns
|
|
100
|
+
-------
|
|
101
|
+
dict with:
|
|
102
|
+
time_axis : array, shape (num_bins,) — relative time, -pre..+post
|
|
103
|
+
trial_matrix : array, shape (n_valid_trials, num_bins)
|
|
104
|
+
trial_event_times : list of the event_times that produced a
|
|
105
|
+
usable trial (too-short/edge-of-recording events are skipped)
|
|
106
|
+
mean_trace : array, shape (num_bins,)
|
|
107
|
+
sem_trace : array, shape (num_bins,) — standard error of the mean
|
|
108
|
+
across trials, zero if fewer than 2 trials
|
|
109
|
+
"""
|
|
110
|
+
time_axis = np.linspace(-pre, post, num_bins)
|
|
111
|
+
rows = []
|
|
112
|
+
valid_times = []
|
|
113
|
+
for t in event_times:
|
|
114
|
+
seg_x, seg_z = get_zscore_slice(time_array, signal, t, pre=pre, post=post)
|
|
115
|
+
if seg_x is None or len(seg_x) < 2:
|
|
116
|
+
continue
|
|
117
|
+
rel_x = seg_x - t
|
|
118
|
+
rows.append(np.interp(time_axis, rel_x, seg_z))
|
|
119
|
+
valid_times.append(t)
|
|
120
|
+
|
|
121
|
+
if not rows:
|
|
122
|
+
empty = np.zeros(num_bins)
|
|
123
|
+
return {
|
|
124
|
+
"time_axis": time_axis, "trial_matrix": np.zeros((0, num_bins)),
|
|
125
|
+
"trial_event_times": [], "mean_trace": empty, "sem_trace": empty,
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
trial_matrix = np.array(rows)
|
|
129
|
+
mean_trace = trial_matrix.mean(axis=0)
|
|
130
|
+
if trial_matrix.shape[0] > 1:
|
|
131
|
+
sem_trace = trial_matrix.std(axis=0, ddof=1) / np.sqrt(trial_matrix.shape[0])
|
|
132
|
+
else:
|
|
133
|
+
sem_trace = np.zeros(num_bins)
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
"time_axis": time_axis, "trial_matrix": trial_matrix,
|
|
137
|
+
"trial_event_times": valid_times, "mean_trace": mean_trace, "sem_trace": sem_trace,
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def find_significant_peaks(time_array, signal, z_threshold=2.5, min_distance_sec=1.0,
|
|
142
|
+
include_troughs=False):
|
|
143
|
+
"""
|
|
144
|
+
Auto-detect statistically significant transients directly from the
|
|
145
|
+
signal, rather than relying on externally-supplied event markers
|
|
146
|
+
(TDT epocs, manual markers, ...) that may not actually line up with
|
|
147
|
+
where the neural signal itself is doing something.
|
|
148
|
+
|
|
149
|
+
The whole recording is z-scored against its own global mean/std
|
|
150
|
+
(not a local baseline — this is a single-pass "how unusual is this
|
|
151
|
+
point relative to the entire recording" measure, not per-event), and
|
|
152
|
+
scipy.signal.find_peaks picks local maxima at or above z_threshold,
|
|
153
|
+
at least min_distance_sec apart so a single transient's rising edge
|
|
154
|
+
doesn't get counted as several peaks.
|
|
155
|
+
|
|
156
|
+
Parameters
|
|
157
|
+
----------
|
|
158
|
+
time_array : array
|
|
159
|
+
signal : array
|
|
160
|
+
Already-processed signal (e.g. bleach-corrected + smoothed) —
|
|
161
|
+
this function does no filtering of its own.
|
|
162
|
+
z_threshold : float
|
|
163
|
+
Minimum z-score (standard deviations above the recording's own
|
|
164
|
+
mean) for a peak to count as "statistically significant".
|
|
165
|
+
min_distance_sec : float
|
|
166
|
+
Minimum spacing between detected peaks, in seconds.
|
|
167
|
+
include_troughs : bool
|
|
168
|
+
Also detect significant negative-going deflections (z <=
|
|
169
|
+
-z_threshold) — off by default since most fibre-photometry
|
|
170
|
+
analyses care about excitatory transients specifically.
|
|
171
|
+
|
|
172
|
+
Returns
|
|
173
|
+
-------
|
|
174
|
+
list of dict, each {"time": float, "z_score": float, "kind": "peak"|"trough"},
|
|
175
|
+
sorted by time.
|
|
176
|
+
"""
|
|
177
|
+
fs = 1.0 / np.median(np.diff(time_array))
|
|
178
|
+
distance = max(1, int(min_distance_sec * fs))
|
|
179
|
+
|
|
180
|
+
mu, std = np.mean(signal), np.std(signal)
|
|
181
|
+
if std < 1e-9:
|
|
182
|
+
return []
|
|
183
|
+
z = (signal - mu) / std
|
|
184
|
+
|
|
185
|
+
results = []
|
|
186
|
+
peak_idx, _ = find_peaks(z, height=z_threshold, distance=distance)
|
|
187
|
+
for i in peak_idx:
|
|
188
|
+
results.append({"time": float(time_array[i]), "z_score": float(z[i]), "kind": "peak"})
|
|
189
|
+
|
|
190
|
+
if include_troughs:
|
|
191
|
+
trough_idx, _ = find_peaks(-z, height=z_threshold, distance=distance)
|
|
192
|
+
for i in trough_idx:
|
|
193
|
+
results.append({"time": float(time_array[i]), "z_score": float(z[i]), "kind": "trough"})
|
|
194
|
+
|
|
195
|
+
results.sort(key=lambda r: r["time"])
|
|
196
|
+
return results
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def find_peak_near_events(time_array, signal, event_times, pre, post,
|
|
200
|
+
z_threshold=2.5, include_troughs=False):
|
|
201
|
+
"""
|
|
202
|
+
Check whether a statistically significant peak actually shows up near
|
|
203
|
+
each given event time, rather than assuming the event marker itself
|
|
204
|
+
marks where the neural signal responds. Works for a single event
|
|
205
|
+
(event_times of length 1) or many occurrences of the same event type
|
|
206
|
+
(checking consistency across all of them).
|
|
207
|
+
|
|
208
|
+
Each event's window is baselined the same way as get_zscore_slice
|
|
209
|
+
(pre-event portion), so "significant" means relative to that event's
|
|
210
|
+
own local baseline, not the whole recording's.
|
|
211
|
+
|
|
212
|
+
Parameters
|
|
213
|
+
----------
|
|
214
|
+
time_array : array
|
|
215
|
+
signal : array
|
|
216
|
+
event_times : list of float
|
|
217
|
+
pre, post : float
|
|
218
|
+
Seconds before/after each event to search within.
|
|
219
|
+
z_threshold : float
|
|
220
|
+
Minimum |z-score| within the window for a peak to count as found.
|
|
221
|
+
include_troughs : bool
|
|
222
|
+
Also consider negative-going deflections as candidate "peaks",
|
|
223
|
+
keeping whichever (peak or trough) is more extreme.
|
|
224
|
+
|
|
225
|
+
Returns
|
|
226
|
+
-------
|
|
227
|
+
list of dict, one per event_time (same order), each:
|
|
228
|
+
{"event_time": float, "found": bool, "peak_time": float or None,
|
|
229
|
+
"latency": float or None (peak_time - event_time),
|
|
230
|
+
"z_score": float or None, "kind": "peak"|"trough"|None}
|
|
231
|
+
"found" is False when the window was unusable (too close to the
|
|
232
|
+
recording's edges) or nothing in it reached z_threshold.
|
|
233
|
+
"""
|
|
234
|
+
results = []
|
|
235
|
+
for t in event_times:
|
|
236
|
+
seg_x, seg_z = get_zscore_slice(time_array, signal, t, pre=pre, post=post)
|
|
237
|
+
if seg_x is None or len(seg_x) == 0:
|
|
238
|
+
results.append({"event_time": t, "found": False, "peak_time": None,
|
|
239
|
+
"latency": None, "z_score": None, "kind": None})
|
|
240
|
+
continue
|
|
241
|
+
|
|
242
|
+
idx_max = int(np.argmax(seg_z))
|
|
243
|
+
if include_troughs:
|
|
244
|
+
idx_min = int(np.argmin(seg_z))
|
|
245
|
+
if abs(seg_z[idx_min]) > seg_z[idx_max]:
|
|
246
|
+
best_idx, kind = idx_min, "trough"
|
|
247
|
+
else:
|
|
248
|
+
best_idx, kind = idx_max, "peak"
|
|
249
|
+
else:
|
|
250
|
+
best_idx, kind = idx_max, "peak"
|
|
251
|
+
|
|
252
|
+
best_z = float(seg_z[best_idx])
|
|
253
|
+
found = abs(best_z) >= z_threshold
|
|
254
|
+
peak_time = float(seg_x[best_idx]) if found else None
|
|
255
|
+
results.append({
|
|
256
|
+
"event_time": t, "found": found,
|
|
257
|
+
"peak_time": peak_time,
|
|
258
|
+
"latency": (peak_time - t) if found else None,
|
|
259
|
+
"z_score": best_z if found else None,
|
|
260
|
+
"kind": kind if found else None,
|
|
261
|
+
})
|
|
262
|
+
return results
|
|
263
|
+
|
|
264
|
+
|
|
72
265
|
def smooth_signal(data, fs, window_sec=0.5):
|
|
73
266
|
"""
|
|
74
267
|
Moving average smoothing filter.
|
{zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/loaders/oxysoft_loader.py
RENAMED
|
@@ -88,6 +88,13 @@ def load_oxysoft_file(file_path: str) -> Dataset:
|
|
|
88
88
|
"""Parse a single Oxysoft .txt export into a Dataset."""
|
|
89
89
|
folder_name = os.path.splitext(os.path.basename(file_path))[0]
|
|
90
90
|
o2hb, hhb, events, metadata, ch_labels, sample_rate = _parse_oxysoft_txt(file_path)
|
|
91
|
+
if o2hb.ndim < 2 or o2hb.shape[0] == 0:
|
|
92
|
+
raise ValueError(
|
|
93
|
+
f"No O2Hb channels recognized in the Legend block of {os.path.basename(file_path)} — "
|
|
94
|
+
"this file's column labels don't match what this parser expects "
|
|
95
|
+
"(looks for 'O2Hb' in each Legend row's description). The file may use a "
|
|
96
|
+
"different Oxysoft export format/version than this parser was built against."
|
|
97
|
+
)
|
|
91
98
|
n_ch, n_samp = o2hb.shape
|
|
92
99
|
signals = np.concatenate([o2hb, hhb], axis=0)
|
|
93
100
|
return Dataset(
|
|
@@ -341,6 +341,16 @@ def get_event_markers(data):
|
|
|
341
341
|
else:
|
|
342
342
|
color = palette[i % len(palette)]
|
|
343
343
|
for t in onsets:
|
|
344
|
+
# A level-type epoc store (buffered, tracks a logic
|
|
345
|
+
# signal's on/off state — common for some Synapse Gizmo
|
|
346
|
+
# outputs) has no history before recording starts; if its
|
|
347
|
+
# logic already happened to be high the instant recording
|
|
348
|
+
# began, TDT inserts a synthetic onset at exactly t=0 to
|
|
349
|
+
# represent that pre-existing state, not a real event.
|
|
350
|
+
# Mirrors the offset=inf guard below for the same store
|
|
351
|
+
# type's opposite edge case (still active at the end).
|
|
352
|
+
if t == 0.0:
|
|
353
|
+
continue
|
|
344
354
|
markers.append({
|
|
345
355
|
'time': float(t),
|
|
346
356
|
'label': display_name,
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""
|
|
2
|
+
splice.py
|
|
3
|
+
---------
|
|
4
|
+
Non-destructive time-range edits of a signal: trim to a range, or cut
|
|
5
|
+
one out and stitch the remainder back together. Pure array/dict
|
|
6
|
+
operations — no knowledge of any GUI's cache/context shape, just plain
|
|
7
|
+
x/raw/corr arrays and marker dicts (each with at least a 'time' key).
|
|
8
|
+
|
|
9
|
+
Two operations:
|
|
10
|
+
- keep_inside: the usual "trim to a window" splice.
|
|
11
|
+
- cut_out: removes a range from the middle and stitches the two
|
|
12
|
+
remaining pieces together. Everything after the cut is shifted
|
|
13
|
+
backward by the cut's duration so the timeline stays contiguous —
|
|
14
|
+
a gap in x would break every downstream analysis that assumes
|
|
15
|
+
uniform sampling (PETH windows, FFT, ...) right at the cut boundary.
|
|
16
|
+
Markers inside the removed range are dropped (that moment no longer
|
|
17
|
+
exists); markers after it are shifted by the same amount so they
|
|
18
|
+
stay aligned with the signal.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import numpy as np
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def slice_markers_keep_inside(markers, start, end):
|
|
25
|
+
"""Keeps original absolute timestamps (not re-zeroed to the splice
|
|
26
|
+
start) so every downstream analysis that reads times straight from
|
|
27
|
+
the marker dicts keeps working with no special-casing."""
|
|
28
|
+
return [dict(m) for m in markers if start <= m['time'] <= end]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def slice_markers_cut_out(markers, start, end, shift):
|
|
32
|
+
"""Drops markers inside the removed range; shifts the rest that fall
|
|
33
|
+
after it by `shift` (the cut's duration) to stay aligned with the
|
|
34
|
+
signal's new, contiguous timeline."""
|
|
35
|
+
out = []
|
|
36
|
+
for m in markers:
|
|
37
|
+
t = m['time']
|
|
38
|
+
if start < t < end:
|
|
39
|
+
continue
|
|
40
|
+
m = dict(m)
|
|
41
|
+
if t >= end:
|
|
42
|
+
m['time'] = t - shift
|
|
43
|
+
out.append(m)
|
|
44
|
+
return out
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def splice_keep_inside(x, raw, corr, markers, detected_markers, start, end):
|
|
48
|
+
"""
|
|
49
|
+
Trims x/raw/corr to [start, end] and filters both marker lists to
|
|
50
|
+
the same range.
|
|
51
|
+
|
|
52
|
+
Parameters
|
|
53
|
+
----------
|
|
54
|
+
x, raw, corr : array
|
|
55
|
+
markers, detected_markers : list of dict, each with a 'time' key
|
|
56
|
+
start, end : float
|
|
57
|
+
|
|
58
|
+
Returns
|
|
59
|
+
-------
|
|
60
|
+
dict with x, raw, corr (copies, not views), markers,
|
|
61
|
+
detected_markers, n_samples — or None if the range doesn't contain
|
|
62
|
+
at least 2 samples.
|
|
63
|
+
"""
|
|
64
|
+
i0 = int(np.searchsorted(x, start, side='left'))
|
|
65
|
+
i1 = int(np.searchsorted(x, end, side='right'))
|
|
66
|
+
if i1 - i0 < 2:
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
"x": x[i0:i1].copy(),
|
|
71
|
+
"raw": raw[i0:i1].copy(),
|
|
72
|
+
"corr": corr[i0:i1].copy(),
|
|
73
|
+
"markers": slice_markers_keep_inside(markers, start, end),
|
|
74
|
+
"detected_markers": slice_markers_keep_inside(detected_markers, start, end),
|
|
75
|
+
"n_samples": i1 - i0,
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def splice_cut_out(x, raw, corr, markers, detected_markers, start, end):
|
|
80
|
+
"""
|
|
81
|
+
Removes [start, end] from x/raw/corr and stitches the remainder
|
|
82
|
+
together, shifting everything after the cut backward by the cut's
|
|
83
|
+
duration so the timeline stays contiguous. Markers inside the cut
|
|
84
|
+
are dropped; markers after it are shifted by the same amount.
|
|
85
|
+
|
|
86
|
+
Parameters
|
|
87
|
+
----------
|
|
88
|
+
x, raw, corr : array
|
|
89
|
+
markers, detected_markers : list of dict, each with a 'time' key
|
|
90
|
+
start, end : float
|
|
91
|
+
|
|
92
|
+
Returns
|
|
93
|
+
-------
|
|
94
|
+
dict with x, raw, corr, markers, detected_markers, n_samples — or
|
|
95
|
+
None if there isn't usable signal on both sides of the cut to
|
|
96
|
+
stitch together.
|
|
97
|
+
"""
|
|
98
|
+
i0 = int(np.searchsorted(x, start, side='left'))
|
|
99
|
+
i1 = int(np.searchsorted(x, end, side='right'))
|
|
100
|
+
if i0 < 1 or i1 >= len(x) - 1 or i1 <= i0:
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
shift = float(x[i1] - x[i0]) # cut duration, used to reconnect the timeline
|
|
104
|
+
new_x = np.concatenate([x[:i0], x[i1:] - shift])
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
"x": new_x,
|
|
108
|
+
"raw": np.concatenate([raw[:i0], raw[i1:]]),
|
|
109
|
+
"corr": np.concatenate([corr[:i0], corr[i1:]]),
|
|
110
|
+
"markers": slice_markers_cut_out(markers, start, end, shift),
|
|
111
|
+
"detected_markers": slice_markers_cut_out(detected_markers, start, end, shift),
|
|
112
|
+
"n_samples": len(new_x),
|
|
113
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ZaksPhysicsLibrary
|
|
3
|
-
Version: 1.
|
|
4
|
-
Summary: Data processing and analysis library for TDT, Oxysoft NIRS, Terranova EFNMR lab data, and
|
|
3
|
+
Version: 1.7.0
|
|
4
|
+
Summary: Data processing and analysis library for TDT, Oxysoft NIRS, Terranova EFNMR lab data, and text-field studies
|
|
5
5
|
Author: zakgm2
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/zakgm2/PhysicsLibrary
|
{zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/ZaksPhysicsLibrary.egg-info/SOURCES.txt
RENAMED
|
@@ -9,6 +9,7 @@ PhysicsLibrary/file_parser.py
|
|
|
9
9
|
PhysicsLibrary/file_parser_generic.py
|
|
10
10
|
PhysicsLibrary/models.py
|
|
11
11
|
PhysicsLibrary/processing_TDT.py
|
|
12
|
+
PhysicsLibrary/splice.py
|
|
12
13
|
PhysicsLibrary/text_field_study.py
|
|
13
14
|
PhysicsLibrary/loaders/__init__.py
|
|
14
15
|
PhysicsLibrary/loaders/oxysoft_loader.py
|
|
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ZaksPhysicsLibrary"
|
|
7
|
-
version = "1.
|
|
8
|
-
description = "Data processing and analysis library for TDT, Oxysoft NIRS, Terranova EFNMR lab data, and
|
|
7
|
+
version = "1.7.0"
|
|
8
|
+
description = "Data processing and analysis library for TDT, Oxysoft NIRS, Terranova EFNMR lab data, and text-field studies"
|
|
9
9
|
requires-python = ">=3.10"
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
license = "MIT"
|
|
File without changes
|
|
File without changes
|
{zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/PhysicsLibrary/field_study_validation.py
RENAMED
|
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
|
{zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/ZaksPhysicsLibrary.egg-info/requires.txt
RENAMED
|
File without changes
|
{zaksphysicslibrary-1.5.0 → zaksphysicslibrary-1.7.0}/ZaksPhysicsLibrary.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|