ibl-neuropixel 1.9.0__tar.gz → 1.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.
Files changed (70) hide show
  1. {ibl_neuropixel-1.9.0/src/ibl_neuropixel.egg-info → ibl_neuropixel-1.9.1}/PKG-INFO +48 -1
  2. ibl_neuropixel-1.9.1/README.md +89 -0
  3. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/setup.py +1 -1
  4. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1/src/ibl_neuropixel.egg-info}/PKG-INFO +48 -1
  5. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/utils.py +10 -4
  6. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/voltage.py +3 -2
  7. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/spikeglx.py +14 -13
  8. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/integration/test_destripe.py +5 -4
  9. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/unit/test_spikeglx.py +23 -2
  10. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/unit/test_utils.py +2 -2
  11. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/unit/test_voltage.py +18 -0
  12. ibl_neuropixel-1.9.0/README.md +0 -42
  13. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/LICENSE +0 -0
  14. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/MANIFEST.in +0 -0
  15. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/setup.cfg +0 -0
  16. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibl_neuropixel.egg-info/SOURCES.txt +0 -0
  17. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibl_neuropixel.egg-info/dependency_links.txt +0 -0
  18. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibl_neuropixel.egg-info/requires.txt +0 -0
  19. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibl_neuropixel.egg-info/top_level.txt +0 -0
  20. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/__init__.py +0 -0
  21. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/cadzow.py +0 -0
  22. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/cuda_tools.py +0 -0
  23. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/destripe_gpu.py +0 -0
  24. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/filter_gpu.py +0 -0
  25. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/fourier.py +0 -0
  26. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/icsd.py +0 -0
  27. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/plots.py +0 -0
  28. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/raw_metrics.py +0 -0
  29. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/smooth.py +0 -0
  30. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/spiketrains.py +0 -0
  31. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/waveform_extraction.py +0 -0
  32. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/ibldsp/waveforms.py +0 -0
  33. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/neuropixel.py +0 -0
  34. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/neurowaveforms/__init__.py +0 -0
  35. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/neurowaveforms/model.py +0 -0
  36. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/np2split/NP1_meta/_spikeglx_ephysData_g0_t0.imec0.ap.meta +0 -0
  37. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/np2split/NP21_meta/_spikeglx_ephysData_g0_t0.imec0.ap.meta +0 -0
  38. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/np2split/NP24_meta/_spikeglx_ephysData_g0_t0.imec0.ap.meta +0 -0
  39. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/np2split/_spikeglx_ephysData_g0_t0.imec0.ap.ch +0 -0
  40. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/np2split/_spikeglx_ephysData_g0_t0.imec0.ap.meta +0 -0
  41. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sample3A_376_channels.ap.meta +0 -0
  42. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sample3A_g0_t0.imec.ap.meta +0 -0
  43. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sample3A_g0_t0.imec.lf.meta +0 -0
  44. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sample3A_g0_t0.imec.wiring.json +0 -0
  45. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sample3A_short_g0_t0.imec.ap.meta +0 -0
  46. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sample3B2_exported.imec0.ap.meta +0 -0
  47. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sample3B_catgt.ap.meta +0 -0
  48. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sample3B_g0_t0.imec1.ap.meta +0 -0
  49. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sample3B_g0_t0.imec1.lf.meta +0 -0
  50. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sample3B_g0_t0.nidq.meta +0 -0
  51. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sample3B_g0_t0.nidq.wiring.json +0 -0
  52. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sample3B_version202304.ap.meta +0 -0
  53. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sampleNP2.1_g0_t0.imec.ap.meta +0 -0
  54. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sampleNP2.1_prototype.ap.meta +0 -0
  55. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sampleNP2.4_1shank_g0_t0.imec.ap.meta +0 -0
  56. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sampleNP2.4_4shanks_appVersion20230905.ap.meta +0 -0
  57. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sampleNP2.4_4shanks_g0_t0.imec.ap.meta +0 -0
  58. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sampleNP2.4_4shanks_while_acquiring_incomplete.ap.meta +0 -0
  59. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/sampleNPultra_g0_t0.imec0.ap.meta +0 -0
  60. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/waveform_sample/test_arr_in.npy +0 -0
  61. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/waveform_sample/test_arr_peak.npy +0 -0
  62. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/waveform_sample/test_df.csv +0 -0
  63. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/fixtures/waveform_sample/test_df_wavinfo.csv +0 -0
  64. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/integration/__init__.py +0 -0
  65. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/integration/csd_experiments.py +0 -0
  66. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/unit/__init__.py +0 -0
  67. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/unit/test_ephys_np2.py +0 -0
  68. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/unit/test_neuropixel.py +0 -0
  69. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/unit/test_plots.py +0 -0
  70. {ibl_neuropixel-1.9.0 → ibl_neuropixel-1.9.1}/src/tests/unit/test_waveforms.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ibl-neuropixel
3
- Version: 1.9.0
3
+ Version: 1.9.1
4
4
  Summary: Collection of tools for Neuropixel 1.0 and 2.0 probes data
5
5
  Home-page: https://github.com/int-brain-lab/ibl-neuropixel
6
6
  Author: The International Brain Laboratory
@@ -41,6 +41,53 @@ Minimum Python version supported is 3.10
41
41
 
42
42
  ## Destriping
43
43
  ### Getting started
44
+
45
+ #### Compress a binary file losslessly using `mtscomp`
46
+
47
+ The mtscomp util implements fast chunked compression for neurophysiology data in a single shard.
48
+ Package repository is [here](https://github.com/int-brain-lab/mtscomp).
49
+
50
+
51
+ ```python
52
+ from pathlib import Path
53
+ import spikeglx
54
+ file_spikeglx = Path('/datadisk/neuropixel/file.imec0.ap.bin')
55
+ sr = spikeglx.Reader(file_spikeglx)
56
+ sr.compress_file()
57
+ # note: you can use sr.compress_file(keep_original=False) to also remove the orginal bin file
58
+ ```
59
+
60
+ #### Reading raw spikeglx file and manipulating arrays
61
+
62
+ The mtscomp util implements fast chunked compression for neurophysiology data in a single shard.
63
+ Package repository is [here](https://github.com/int-brain-lab/mtscomp).
64
+
65
+ ```python
66
+ from pathlib import Path
67
+ import spikeglx
68
+
69
+ import ibldsp.voltage
70
+
71
+ file_spikeglx = Path('/datadisk/Data/neuropixel/human/Pt01.imec0.ap.bin')
72
+ sr = spikeglx.Reader(file_spikeglx)
73
+
74
+ # reads in 300ms of data
75
+ raw = sr[10_300_000:10_310_000, :sr.nc - sr.nsync].T
76
+ destripe = ibldsp.voltage.destripe(raw, fs=sr.fs, neuropixel_version=1)
77
+
78
+ # display with matplotlib backend
79
+ import ibldsp.plots
80
+ ibldsp.plots.voltageshow(raw, fs=sr.fs, title='raw')
81
+ ibldsp.plots.voltageshow(destripe, fs=sr.fs, title='destripe')
82
+
83
+ # display with QT backend
84
+ from viewephys.gui import viewephys
85
+ eqc = {}
86
+ eqc['raw'] = viewephys(raw, fs=sr.fs, title='raw')
87
+ eqc['destripe'] = viewephys(destripe, fs=sr.fs, title='destripe')
88
+ ```
89
+
90
+ #### Destripe a binary file
44
91
  This relies on a fast fourier transform external library: `pip install pyfftw`.
45
92
 
46
93
  Minimal working example to destripe a neuropixel binary file.
@@ -0,0 +1,89 @@
1
+ # ibl-neuropixel
2
+ Collection of tools to handle Neuropixel 1.0 and 2.0 data
3
+ (documentation coming soon...)
4
+
5
+ ## Installation
6
+ Minimum Python version supported is 3.10
7
+ `pip install ibl-neuropixel`
8
+
9
+
10
+ ## Destriping
11
+ ### Getting started
12
+
13
+ #### Compress a binary file losslessly using `mtscomp`
14
+
15
+ The mtscomp util implements fast chunked compression for neurophysiology data in a single shard.
16
+ Package repository is [here](https://github.com/int-brain-lab/mtscomp).
17
+
18
+
19
+ ```python
20
+ from pathlib import Path
21
+ import spikeglx
22
+ file_spikeglx = Path('/datadisk/neuropixel/file.imec0.ap.bin')
23
+ sr = spikeglx.Reader(file_spikeglx)
24
+ sr.compress_file()
25
+ # note: you can use sr.compress_file(keep_original=False) to also remove the orginal bin file
26
+ ```
27
+
28
+ #### Reading raw spikeglx file and manipulating arrays
29
+
30
+ The mtscomp util implements fast chunked compression for neurophysiology data in a single shard.
31
+ Package repository is [here](https://github.com/int-brain-lab/mtscomp).
32
+
33
+ ```python
34
+ from pathlib import Path
35
+ import spikeglx
36
+
37
+ import ibldsp.voltage
38
+
39
+ file_spikeglx = Path('/datadisk/Data/neuropixel/human/Pt01.imec0.ap.bin')
40
+ sr = spikeglx.Reader(file_spikeglx)
41
+
42
+ # reads in 300ms of data
43
+ raw = sr[10_300_000:10_310_000, :sr.nc - sr.nsync].T
44
+ destripe = ibldsp.voltage.destripe(raw, fs=sr.fs, neuropixel_version=1)
45
+
46
+ # display with matplotlib backend
47
+ import ibldsp.plots
48
+ ibldsp.plots.voltageshow(raw, fs=sr.fs, title='raw')
49
+ ibldsp.plots.voltageshow(destripe, fs=sr.fs, title='destripe')
50
+
51
+ # display with QT backend
52
+ from viewephys.gui import viewephys
53
+ eqc = {}
54
+ eqc['raw'] = viewephys(raw, fs=sr.fs, title='raw')
55
+ eqc['destripe'] = viewephys(destripe, fs=sr.fs, title='destripe')
56
+ ```
57
+
58
+ #### Destripe a binary file
59
+ This relies on a fast fourier transform external library: `pip install pyfftw`.
60
+
61
+ Minimal working example to destripe a neuropixel binary file.
62
+ ```python
63
+ from pathlib import Path
64
+ from ibldsp.voltage import decompress_destripe_cbin
65
+ sr_file = Path('/datadisk/Data/spike_sorting/pykilosort_tests/imec_385_100s.ap.bin')
66
+ out_file = Path('/datadisk/scratch/imec_385_100s.ap.bin')
67
+
68
+ decompress_destripe_cbin(sr_file=sr_file, output_file=out_file, nprocesses=8)
69
+ ```
70
+
71
+ ### Viewer
72
+
73
+ The best way to look at the results is to use [viewephys](https://github.com/oliche/viewephys),
74
+ open an ephys viewer on the raw data.
75
+
76
+ - tick the destripe box.
77
+ - move to a desired location in the file
78
+ - ctr+P will make the gain and axis the same on both windows
79
+
80
+ ![alt text](./docs/raw_bin_viewer_destripe.png "Ephys viewer")
81
+
82
+ You can then move within the raw data file.
83
+
84
+ ### White Paper
85
+ The following describes the methods implemented in this repository.
86
+ https://doi.org/10.6084/m9.figshare.19705522
87
+
88
+ ## Contribution
89
+ Please see our [contribution guidelines](CONTRIBUTING.md) for details on how to contribute to this project.
@@ -8,7 +8,7 @@ with open("requirements.txt") as f:
8
8
 
9
9
  setuptools.setup(
10
10
  name="ibl-neuropixel",
11
- version="1.9.0",
11
+ version="1.9.1",
12
12
  author="The International Brain Laboratory",
13
13
  description="Collection of tools for Neuropixel 1.0 and 2.0 probes data",
14
14
  long_description=long_description,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ibl-neuropixel
3
- Version: 1.9.0
3
+ Version: 1.9.1
4
4
  Summary: Collection of tools for Neuropixel 1.0 and 2.0 probes data
5
5
  Home-page: https://github.com/int-brain-lab/ibl-neuropixel
6
6
  Author: The International Brain Laboratory
@@ -41,6 +41,53 @@ Minimum Python version supported is 3.10
41
41
 
42
42
  ## Destriping
43
43
  ### Getting started
44
+
45
+ #### Compress a binary file losslessly using `mtscomp`
46
+
47
+ The mtscomp util implements fast chunked compression for neurophysiology data in a single shard.
48
+ Package repository is [here](https://github.com/int-brain-lab/mtscomp).
49
+
50
+
51
+ ```python
52
+ from pathlib import Path
53
+ import spikeglx
54
+ file_spikeglx = Path('/datadisk/neuropixel/file.imec0.ap.bin')
55
+ sr = spikeglx.Reader(file_spikeglx)
56
+ sr.compress_file()
57
+ # note: you can use sr.compress_file(keep_original=False) to also remove the orginal bin file
58
+ ```
59
+
60
+ #### Reading raw spikeglx file and manipulating arrays
61
+
62
+ The mtscomp util implements fast chunked compression for neurophysiology data in a single shard.
63
+ Package repository is [here](https://github.com/int-brain-lab/mtscomp).
64
+
65
+ ```python
66
+ from pathlib import Path
67
+ import spikeglx
68
+
69
+ import ibldsp.voltage
70
+
71
+ file_spikeglx = Path('/datadisk/Data/neuropixel/human/Pt01.imec0.ap.bin')
72
+ sr = spikeglx.Reader(file_spikeglx)
73
+
74
+ # reads in 300ms of data
75
+ raw = sr[10_300_000:10_310_000, :sr.nc - sr.nsync].T
76
+ destripe = ibldsp.voltage.destripe(raw, fs=sr.fs, neuropixel_version=1)
77
+
78
+ # display with matplotlib backend
79
+ import ibldsp.plots
80
+ ibldsp.plots.voltageshow(raw, fs=sr.fs, title='raw')
81
+ ibldsp.plots.voltageshow(destripe, fs=sr.fs, title='destripe')
82
+
83
+ # display with QT backend
84
+ from viewephys.gui import viewephys
85
+ eqc = {}
86
+ eqc['raw'] = viewephys(raw, fs=sr.fs, title='raw')
87
+ eqc['destripe'] = viewephys(destripe, fs=sr.fs, title='destripe')
88
+ ```
89
+
90
+ #### Destripe a binary file
44
91
  This relies on a fast fourier transform external library: `pip install pyfftw`.
45
92
 
46
93
  Minimal working example to destripe a neuropixel binary file.
@@ -89,7 +89,7 @@ def parabolic_max(x):
89
89
  # for 2D arrays, operate along the last dimension
90
90
  ns = x.shape[-1]
91
91
  axis = -1
92
- imax = np.argmax(x, axis=axis)
92
+ imax = np.nanargmax(x, axis=axis)
93
93
 
94
94
  if x.ndim == 1:
95
95
  v010 = x[np.maximum(np.minimum(imax + np.array([-1, 0, 1]), ns - 1), 0)]
@@ -383,7 +383,7 @@ class WindowGenerator(object):
383
383
  yield (first, last, amp)
384
384
 
385
385
  @property
386
- def firstlast_valid(self):
386
+ def firstlast_valid(self, discard_edges=False):
387
387
  """
388
388
  Generator that yields a tuple of first, last, first_valid, last_valid index of windows
389
389
  The valid indices span up to half of the overlap
@@ -391,8 +391,14 @@ class WindowGenerator(object):
391
391
  """
392
392
  assert self.overlap % 2 == 0, "Overlap must be even"
393
393
  for first, last in self.firstlast:
394
- first_valid = 0 if first == 0 else first + self.overlap // 2
395
- last_valid = last if last == self.ns else last - self.overlap // 2
394
+ first_valid = (
395
+ 0 if first == 0 and not discard_edges else first + self.overlap // 2
396
+ )
397
+ last_valid = (
398
+ last
399
+ if last == self.ns and not discard_edges
400
+ else last - self.overlap // 2
401
+ )
396
402
  yield (first, last, first_valid, last_valid)
397
403
 
398
404
  @property
@@ -782,10 +782,11 @@ def decompress_destripe_cbin(
782
782
  np.save(
783
783
  output_qc_path.joinpath("_iblqc_ephysTimeRmsAP.timestamps.npy"), time_data
784
784
  )
785
- np.save(
786
- output_qc_path.joinpath("_iblqc_ephysSaturation.samples.npy"),
785
+ saturation_samples_to_intervals(
787
786
  saturation_data,
787
+ output_file=output_qc_path.joinpath("_iblqc_ephysSaturation.samples.pqt"),
788
788
  )
789
+ file_saturation.unlink()
789
790
 
790
791
 
791
792
  def detect_bad_channels(
@@ -144,11 +144,7 @@ class Reader:
144
144
  sglx_file = str(self.file_bin)
145
145
  if self.is_mtscomp:
146
146
  self._raw = mtscomp.Reader()
147
- self.ch_file = (
148
- _get_companion_file(sglx_file, ".ch")
149
- if self.ch_file is None
150
- else self.ch_file
151
- )
147
+ self.ch_file = self._parse_ch_file()
152
148
  self._raw.open(self.file_bin, self.ch_file)
153
149
  if self._raw.shape != (self.ns, self.nc):
154
150
  ftsec = self._raw.shape[0] / self.fs
@@ -396,10 +392,8 @@ class Reader:
396
392
  if "out" not in kwargs:
397
393
  kwargs["out"] = self.file_bin.with_suffix(".bin")
398
394
  assert self.is_mtscomp
399
- if file_ch is None:
400
- file_ch = self.file_bin.with_suffix(".ch")
401
-
402
- r = mtscomp.decompress(self.file_bin, file_ch, **kwargs)
395
+ ch_file = self._parse_ch_file(file_ch)
396
+ r = mtscomp.decompress(self.file_bin, ch_file, **kwargs)
403
397
  r.close()
404
398
  if not keep_original:
405
399
  self.close()
@@ -420,9 +414,10 @@ class Reader:
420
414
  bin_file = Path(self.file_bin).with_suffix(".bin")
421
415
  else:
422
416
  scratch_dir.mkdir(exist_ok=True, parents=True)
423
- bin_file = scratch_dir / Path(self.file_bin).with_suffix(".bin").name
424
- file_meta_scratch = scratch_dir / file_meta.name
425
- shutil.copy(self.file_meta_data, file_meta_scratch)
417
+ bin_file = (
418
+ Path(scratch_dir).joinpath(self.file_bin.name).with_suffix(".bin")
419
+ )
420
+ shutil.copy(self.file_meta_data, bin_file.parent / self.file_meta_data.name)
426
421
  if not bin_file.exists():
427
422
  t0 = time.time()
428
423
  _logger.info("File is compressed, decompressing to a temporary file...")
@@ -464,6 +459,12 @@ class Reader:
464
459
  log_func(f"SHA1 computed: {sc}")
465
460
  return sm == sc
466
461
 
462
+ def _parse_ch_file(self, ch_file=None):
463
+ ch_file = (
464
+ _get_companion_file(self.file_bin, ".ch") if ch_file is None else ch_file
465
+ )
466
+ return ch_file
467
+
467
468
 
468
469
  class OnlineReader(Reader):
469
470
  @property
@@ -999,7 +1000,7 @@ def _mock_spikeglx_file(
999
1000
  meta_file,
1000
1001
  ns,
1001
1002
  nc,
1002
- sync_depth,
1003
+ sync_depth=16,
1003
1004
  random=False,
1004
1005
  int2volts=0.6 / 32768,
1005
1006
  corrupt=False,
@@ -4,6 +4,7 @@ import logging
4
4
  import shutil
5
5
  import unittest
6
6
  from pathlib import Path
7
+ import pandas as pd
7
8
 
8
9
  import neuropixel
9
10
  import spikeglx
@@ -84,11 +85,11 @@ class TestEphysSpikeSortingMultiProcess(unittest.TestCase):
84
85
  shutil.rmtree(self.file_path.parent)
85
86
 
86
87
  def _assert_qc(self):
87
- sr = spikeglx.Reader(self.file_path)
88
- saturated = np.load(
89
- self.file_path.parent.joinpath("_iblqc_ephysSaturation.samples.npy")
88
+ df_saturated = pd.read_parquet(
89
+ self.file_path.parent.joinpath("_iblqc_ephysSaturation.samples.pqt")
90
90
  )
91
- self.assertEqual(sr.ns, saturated.size)
91
+ self.assertTrue(df_saturated.shape[1] == 2)
92
+
92
93
  self.assertTrue(
93
94
  self.file_path.parent.joinpath("_iblqc_ephysTimeRmsAP.rms.npy").exists()
94
95
  )
@@ -2,6 +2,7 @@ from pathlib import Path
2
2
  import shutil
3
3
  import tempfile
4
4
  import unittest
5
+ import uuid
5
6
 
6
7
  import numpy as np
7
8
  from iblutil.io import hashfile
@@ -671,9 +672,29 @@ class TestsBasicReader(unittest.TestCase):
671
672
  Tests the basic usage where there is a flat binary and no metadata associated
672
673
  """
673
674
 
674
- def test_get_companion_file(self):
675
- import uuid
675
+ def test_integration_companion_files_cbin(self):
676
+ with tempfile.TemporaryDirectory() as td:
677
+ bin_file_orig = Path(td) / "toto.ap.bin"
678
+ meta_file = Path(td) / f"toto.ap.{str(uuid.uuid4())}.meta"
679
+ ch_file = Path(td) / f"toto.ap.{str(uuid.uuid4())}.ch"
680
+ spikeglx._mock_spikeglx_file(
681
+ bin_file_orig,
682
+ meta_file=Path(TEST_PATH).joinpath("sample3B_g0_t0.imec1.ap.meta"),
683
+ ns=90_000,
684
+ nc=385,
685
+ )
686
+ sr = spikeglx.Reader(bin_file_orig)
687
+ sr.compress_file(keep_original=False)
688
+ cbin_file = Path(td) / f"toto.ap.{str(uuid.uuid4())}.cbin"
689
+ shutil.move(bin_file_orig.with_suffix(".cbin"), cbin_file)
690
+ shutil.move(bin_file_orig.with_suffix(".ch"), ch_file)
691
+ shutil.move(bin_file_orig.with_suffix(".meta"), meta_file)
692
+ sr = spikeglx.Reader(cbin_file)
693
+ self.assertEqual(sr.file_bin, cbin_file)
694
+ self.assertEqual(sr.file_meta_data, meta_file)
695
+ self.assertEqual(sr.ch_file, ch_file)
676
696
 
697
+ def test_get_companion_file(self):
677
698
  with tempfile.TemporaryDirectory() as td:
678
699
  sglx_file = Path(td) / f"sample3A_g0_t0.imec.ap.{str(uuid.uuid4())}.bin"
679
700
  meta_file = Path(td) / f"sample3A_g0_t0.imec.ap.{str(uuid.uuid4())}.meta"
@@ -69,8 +69,8 @@ class TestSyncTimestamps(unittest.TestCase):
69
69
 
70
70
  class TestParabolicMax(unittest.TestCase):
71
71
  # expected values
72
- maxi = np.array([np.nan, 0, 3.04166667, 3.04166667, 5, 5])
73
- ipeak = np.array([np.nan, 0, 5.166667, 2.166667, 0, 7])
72
+ maxi = np.array([0.0, 0.0, 3.04166667, 3.04166667, 5, 5])
73
+ ipeak = np.array([0.0, 0.0, 5.166667, 2.166667, 0, 7])
74
74
  # input
75
75
  x = np.array(
76
76
  [
@@ -131,6 +131,24 @@ class TestSaturation(unittest.TestCase):
131
131
  self.assertGreater(np.sum(saturated), 5)
132
132
  self.assertGreater(np.sum(mute == 0), np.sum(saturated))
133
133
 
134
+ def test_saturation_intervals_output(self):
135
+ saturation = np.zeros(50_000, dtype=bool)
136
+ # we test empty files, make sure we can read/write from empty parquet
137
+ with tempfile.TemporaryDirectory() as temp_dir:
138
+ # Create a file path within the temporary directory
139
+ temp_file = Path(temp_dir).joinpath("saturation.pqt")
140
+ df_nothing = ibldsp.voltage.saturation_samples_to_intervals(
141
+ saturation, output_file=Path(temp_dir).joinpath("saturation.pqt")
142
+ )
143
+ df_nothing2 = pd.read_parquet(temp_file)
144
+ self.assertEqual(df_nothing.shape[0], 0)
145
+ self.assertEqual(df_nothing2.shape[0], 0)
146
+ # for the case with saturation intervals, we simply test the number of rows correspond to the events
147
+ saturation[3441:3509] = True
148
+ saturation[45852:45865] = True
149
+ df_sat = ibldsp.voltage.saturation_samples_to_intervals(saturation)
150
+ self.assertEqual(81, np.sum(df_sat["stop_sample"] - df_sat["start_sample"]))
151
+
134
152
 
135
153
  class TestCadzow(unittest.TestCase):
136
154
  def test_trajectory_matrixes(self):
@@ -1,42 +0,0 @@
1
- # ibl-neuropixel
2
- Collection of tools to handle Neuropixel 1.0 and 2.0 data
3
- (documentation coming soon...)
4
-
5
- ## Installation
6
- Minimum Python version supported is 3.10
7
- `pip install ibl-neuropixel`
8
-
9
-
10
- ## Destriping
11
- ### Getting started
12
- This relies on a fast fourier transform external library: `pip install pyfftw`.
13
-
14
- Minimal working example to destripe a neuropixel binary file.
15
- ```python
16
- from pathlib import Path
17
- from ibldsp.voltage import decompress_destripe_cbin
18
- sr_file = Path('/datadisk/Data/spike_sorting/pykilosort_tests/imec_385_100s.ap.bin')
19
- out_file = Path('/datadisk/scratch/imec_385_100s.ap.bin')
20
-
21
- decompress_destripe_cbin(sr_file=sr_file, output_file=out_file, nprocesses=8)
22
- ```
23
-
24
- ### Viewer
25
-
26
- The best way to look at the results is to use [viewephys](https://github.com/oliche/viewephys),
27
- open an ephys viewer on the raw data.
28
-
29
- - tick the destripe box.
30
- - move to a desired location in the file
31
- - ctr+P will make the gain and axis the same on both windows
32
-
33
- ![alt text](./docs/raw_bin_viewer_destripe.png "Ephys viewer")
34
-
35
- You can then move within the raw data file.
36
-
37
- ### White Paper
38
- The following describes the methods implemented in this repository.
39
- https://doi.org/10.6084/m9.figshare.19705522
40
-
41
- ## Contribution
42
- Please see our [contribution guidelines](CONTRIBUTING.md) for details on how to contribute to this project.
File without changes
File without changes