bmtool 0.6.8.1__py3-none-any.whl → 0.6.8.2__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.
- bmtool/SLURM.py +40 -0
- bmtool/analysis/lfp.py +61 -0
- {bmtool-0.6.8.1.dist-info → bmtool-0.6.8.2.dist-info}/METADATA +1 -1
- {bmtool-0.6.8.1.dist-info → bmtool-0.6.8.2.dist-info}/RECORD +8 -8
- {bmtool-0.6.8.1.dist-info → bmtool-0.6.8.2.dist-info}/WHEEL +1 -1
- {bmtool-0.6.8.1.dist-info → bmtool-0.6.8.2.dist-info}/entry_points.txt +0 -0
- {bmtool-0.6.8.1.dist-info → bmtool-0.6.8.2.dist-info}/licenses/LICENSE +0 -0
- {bmtool-0.6.8.1.dist-info → bmtool-0.6.8.2.dist-info}/top_level.txt +0 -0
bmtool/SLURM.py
CHANGED
@@ -305,6 +305,45 @@ export OUTPUT_DIR={case_output_dir}
|
|
305
305
|
return True
|
306
306
|
|
307
307
|
|
308
|
+
def get_relative_path(endpoint, absolute_path):
|
309
|
+
"""Convert absolute path to relative path for Globus transfer."""
|
310
|
+
try:
|
311
|
+
# Get the directories at the mount point
|
312
|
+
result = subprocess.run(["globus", "ls", f"{endpoint}:/"], capture_output=True, text=True, check=True)
|
313
|
+
dirs = set(result.stdout.splitlines()) # Convert to a set for quicker lookup
|
314
|
+
|
315
|
+
# Split the absolute path into parts
|
316
|
+
path_parts = absolute_path.strip("/").split("/")
|
317
|
+
|
318
|
+
# Find the first matching directory in the list
|
319
|
+
for i, part in enumerate(path_parts):
|
320
|
+
if part+"/" in dirs:
|
321
|
+
# The mount point is everything up to and including this directory
|
322
|
+
mount_point = "/" + "/".join(path_parts[:i])
|
323
|
+
relative_path = absolute_path.replace(mount_point, "", 1).lstrip("/")
|
324
|
+
return relative_path
|
325
|
+
|
326
|
+
print("Error: Could not determine relative path.")
|
327
|
+
return None
|
328
|
+
except subprocess.CalledProcessError as e:
|
329
|
+
print(f"Error retrieving directories from Globus: {e}")
|
330
|
+
return None
|
331
|
+
|
332
|
+
def globus_transfer(source_endpoint, dest_endpoint, source_path, dest_path):
|
333
|
+
"""
|
334
|
+
Transfers file using custom globus transfer function.
|
335
|
+
For more info see https://github.com/GregGlickert/transfer-files/blob/main/globus_transfer.sh
|
336
|
+
"""
|
337
|
+
relative_source_path = get_relative_path(source_endpoint, source_path)
|
338
|
+
if relative_source_path is None:
|
339
|
+
print("Transfer aborted: Could not determine relative source path.")
|
340
|
+
return
|
341
|
+
|
342
|
+
command = f"globus transfer {source_endpoint}:{relative_source_path} {dest_endpoint}:{dest_path} --label 'bmtool slurm transfer'"
|
343
|
+
os.system(command)
|
344
|
+
|
345
|
+
|
346
|
+
|
308
347
|
class BlockRunner:
|
309
348
|
"""
|
310
349
|
Class to handle submitting multiple blocks sequentially.
|
@@ -334,6 +373,7 @@ class BlockRunner:
|
|
334
373
|
Updates the JSON file with new parameters before each block run.
|
335
374
|
"""
|
336
375
|
for i, block in enumerate(self.blocks):
|
376
|
+
print(block.output_base_dir)
|
337
377
|
# Update JSON file with new parameter value
|
338
378
|
if self.json_file_path == None and self.param_values == None:
|
339
379
|
source_dir = block.component_path
|
bmtool/analysis/lfp.py
CHANGED
@@ -406,3 +406,64 @@ def calculate_plv_over_time(x1: np.ndarray, x2: np.ndarray, fs: float,
|
|
406
406
|
return np.array(plv_over_time), np.array(times)
|
407
407
|
|
408
408
|
|
409
|
+
def calculate_ppc1(spike_times, lfp_signal, fs, freq_range, window_size=0.5):
|
410
|
+
"""
|
411
|
+
Calculate PPC1 metric between spike times and LFP signal using the vector dot product method.
|
412
|
+
|
413
|
+
Parameters:
|
414
|
+
-----------
|
415
|
+
spike_times : array_like
|
416
|
+
Array of spike times in seconds
|
417
|
+
lfp_signal : array_like
|
418
|
+
Local field potential time series
|
419
|
+
fs : float
|
420
|
+
Sampling frequency of the LFP signal in Hz
|
421
|
+
freq_range : tuple
|
422
|
+
Frequency range (low, high) to filter the LFP signal in Hz
|
423
|
+
window_size : float, optional
|
424
|
+
Size of the window around each spike in seconds, default is 0.5s
|
425
|
+
|
426
|
+
Returns:
|
427
|
+
--------
|
428
|
+
ppc1 : float
|
429
|
+
PPC1 value
|
430
|
+
phases : array
|
431
|
+
Phases at spike times
|
432
|
+
"""
|
433
|
+
# Convert spike times to sample indices
|
434
|
+
spike_indices = np.round(spike_times * fs).astype(int)
|
435
|
+
|
436
|
+
# Filter LFP in the frequency band of interest
|
437
|
+
nyquist = fs / 2
|
438
|
+
b, a = signal.butter(3, [freq_range[0] / nyquist, freq_range[1] / nyquist], btype='band')
|
439
|
+
filtered_lfp = signal.filtfilt(b, a, lfp_signal)
|
440
|
+
|
441
|
+
# Get analytic signal through Hilbert transform
|
442
|
+
analytic_signal = signal.hilbert(filtered_lfp)
|
443
|
+
|
444
|
+
# Extract instantaneous phase
|
445
|
+
instantaneous_phase = np.angle(analytic_signal)
|
446
|
+
|
447
|
+
# Get phases at spike times
|
448
|
+
spike_phases = []
|
449
|
+
for spike_idx in spike_indices:
|
450
|
+
if 0 <= spike_idx < len(instantaneous_phase):
|
451
|
+
spike_phases.append(instantaneous_phase[spike_idx])
|
452
|
+
|
453
|
+
spike_phases = np.array(spike_phases)
|
454
|
+
|
455
|
+
# Calculate PPC1
|
456
|
+
n = len(spike_phases)
|
457
|
+
if n <= 1:
|
458
|
+
return 0, spike_phases
|
459
|
+
|
460
|
+
# Convert phases to unit vectors in the complex plane
|
461
|
+
unit_vectors = np.exp(1j * spike_phases)
|
462
|
+
|
463
|
+
# Calculate the resultant vector
|
464
|
+
resultant_vector = np.sum(unit_vectors)
|
465
|
+
|
466
|
+
# PPC1 is the squared length of the resultant vector divided by n²
|
467
|
+
ppc1 = (np.abs(resultant_vector) ** 2) / (n ** 2)
|
468
|
+
|
469
|
+
return ppc1, spike_phases
|
@@ -1,4 +1,4 @@
|
|
1
|
-
bmtool/SLURM.py,sha256=
|
1
|
+
bmtool/SLURM.py,sha256=umHYGUX2HDlZr6Zo89wQekGrK9mZdAi0rBdCA7a--hE,19904
|
2
2
|
bmtool/__init__.py,sha256=ZStTNkAJHJxG7Pwiy5UgCzC4KlhMS5pUNPtUJZVwL_Y,136
|
3
3
|
bmtool/__main__.py,sha256=TmFkmDxjZ6250nYD4cgGhn-tbJeEm0u-EMz2ajAN9vE,650
|
4
4
|
bmtool/bmplot.py,sha256=YoI7StM9qeZqyRfFX4M7oUGFz50tXTDOMIUqjYozj9s,54066
|
@@ -9,7 +9,7 @@ bmtool/plot_commands.py,sha256=Tqujyf0c0u8olhiHOMwgUSJXIIE1hgjv6otb25G9cA0,12298
|
|
9
9
|
bmtool/singlecell.py,sha256=XZAT_2n44EhwqVLnk3qur9aO7oJ-10axJZfwPBslM88,27219
|
10
10
|
bmtool/synapses.py,sha256=gIkfLhKDG2dHHCVJJoKuQrFn_Qut843bfk_-s97wu6c,54553
|
11
11
|
bmtool/analysis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
|
-
bmtool/analysis/lfp.py,sha256=
|
12
|
+
bmtool/analysis/lfp.py,sha256=DXZvxYMVjFiCJS_IySQIUrpBQjdNuHVL8A7rxrHB7xo,16900
|
13
13
|
bmtool/analysis/spikes.py,sha256=qqJ4zD8xfvSwltlWm_Bhicdngzl6uBqH6Kn5wOMKRc8,11507
|
14
14
|
bmtool/debug/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
15
|
bmtool/debug/commands.py,sha256=AwtcR7BUUheM0NxvU1Nu234zCdpobhJv5noX8x5K2vY,583
|
@@ -19,9 +19,9 @@ bmtool/util/commands.py,sha256=zJF-fiLk0b8LyzHDfvewUyS7iumOxVnj33IkJDzux4M,64396
|
|
19
19
|
bmtool/util/util.py,sha256=00vOAwTVIifCqouBoFoT0lBashl4fCalrk8fhg_Uq4c,56654
|
20
20
|
bmtool/util/neuron/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
21
|
bmtool/util/neuron/celltuner.py,sha256=xSRpRN6DhPFz4q5buq_W8UmsD7BbUrkzYBEbKVloYss,87194
|
22
|
-
bmtool-0.6.8.
|
23
|
-
bmtool-0.6.8.
|
24
|
-
bmtool-0.6.8.
|
25
|
-
bmtool-0.6.8.
|
26
|
-
bmtool-0.6.8.
|
27
|
-
bmtool-0.6.8.
|
22
|
+
bmtool-0.6.8.2.dist-info/licenses/LICENSE,sha256=qrXg2jj6kz5d0EnN11hllcQt2fcWVNumx0xNbV05nyM,1068
|
23
|
+
bmtool-0.6.8.2.dist-info/METADATA,sha256=pE_Li9uoVYndKge-Gcm7gawxW71VbGfFhEL1lT0-kB8,20431
|
24
|
+
bmtool-0.6.8.2.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
|
25
|
+
bmtool-0.6.8.2.dist-info/entry_points.txt,sha256=0-BHZ6nUnh0twWw9SXNTiRmKjDnb1VO2DfG_-oprhAc,45
|
26
|
+
bmtool-0.6.8.2.dist-info/top_level.txt,sha256=gpd2Sj-L9tWbuJEd5E8C8S8XkNm5yUE76klUYcM-eWM,7
|
27
|
+
bmtool-0.6.8.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|