Yann Bouteiller commited on
Commit
da5fc70
·
1 Parent(s): 45a88e4

updated version

Browse files
portiloop/capture.py CHANGED
@@ -4,7 +4,6 @@ import sys
4
  from time import sleep
5
  import time
6
  import numpy as np
7
- import matplotlib.pyplot as plt
8
  import os
9
  from pathlib import Path
10
  from datetime import datetime, timedelta
@@ -14,7 +13,6 @@ import shutil
14
  from threading import Thread, Lock
15
  import alsaaudio
16
 
17
- import matplotlib.pyplot as plt
18
  from EDFlib.edfwriter import EDFwriter
19
  from scipy.signal import firwin
20
 
@@ -63,8 +61,8 @@ DEFAULT_FRONTEND_CONFIG = [
63
  FRONTEND_CONFIG = [
64
  0x3E, # ID (RO)
65
  0x95, # CONFIG1 [95] [1, DAISY_EN(bar), CLK_EN, 1, 0, DR[2:0]] : Datarate = 500 SPS
66
- 0xD0, # CONFIG2 [C0] [1, 1, 0, INT_CAL, 0, CAL_AMP0, CAL_FREQ[1:0]]
67
- 0xE8, # CONFIG3 [E0] [PD_REFBUF(bar), 1, 1, BIAS_MEAS, BIASREF_INT, PD_BIAS(bar), BIAS_LOFF_SENS, BIAS_STAT] : Power-down reference buffer, no bias
68
  0x00, # No lead-off
69
  0x60, # CH1SET [60] [PD1, GAIN1[2:0], SRB2, MUX1[2:0]]
70
  0x60, # CH2SET 66
@@ -76,8 +74,8 @@ FRONTEND_CONFIG = [
76
  0x60, # CH8SET
77
  0x04, # BIAS_SENSP 04
78
  0x04, # BIAS_SENSN 04
79
- 0xFF, # LOFF_SENSP Lead-off on all positive pins?
80
- 0xFF, # LOFF_SENSN Lead-off on all negative pins?
81
  0x00, # Normal lead-off
82
  0x00, # Lead-off positive status (RO)
83
  0x00, # Lead-off negative status (RO)
@@ -133,24 +131,20 @@ def mod_config(config, datarate, channel_modes):
133
  elif chan_mode == 'disabled':
134
  mod = mod | 0x81 # PDn = 1 and input shorted (001)
135
  elif chan_mode == 'with bias':
 
136
  bit_i = 1 << chan_i
137
  config[13] = config[13] | bit_i
138
- config[14] = config[14] | bit_i
139
- bias_active = True
140
  elif chan_mode == 'bias out':
141
- mod = mod | 0x06 # MUX[2:0] = BIAS_DRP (110)
142
  bias_active = True
 
143
  else:
144
  assert False, f"Wrong key: {chan_mode}."
145
  config[n] = mod
146
- print(f"DEBUG: new config[{n}]:{hex(config[n])}")
147
- print(f"DEBUG: new config[13]:{hex(config[13])}")
148
- print(f"DEBUG: new config[14]:{hex(config[14])}")
149
  if bias_active:
150
- config[3] = config[3] | 0x04 # PD_BIAS bar = 1
151
- else:
152
- config[3] = config[3] & 0xFB # PD_BIAS bar = 0
153
- print(f"DEBUG: new config[3]:{hex(config[3])}")
154
  return config
155
 
156
 
@@ -399,6 +393,17 @@ def _capture_process(p_data_o, p_msg_io, duration, frequency, python_clock, time
399
  p_data_o.close()
400
 
401
 
 
 
 
 
 
 
 
 
 
 
 
402
  class Capture:
403
  def __init__(self, detector_cls=None, stimulator_cls=None):
404
  # {now.strftime('%m_%d_%Y_%H_%M_%S')}
@@ -441,10 +446,12 @@ class Capture:
441
  self._test_stimulus = False
442
 
443
  mixers = alsaaudio.mixers()
444
- if 'PCM' in mixers:
 
 
 
445
  self.mixer = alsaaudio.Mixer(control='PCM')
446
  else:
447
- assert len(mixers) > 0, 'No ALSA mixer found'
448
  warnings.warn(f"Could not find mixer PCM, using {mixers[0]} instead.")
449
  self.mixer = alsaaudio.Mixer(control=mixers[0])
450
  self.volume = self.mixer.getvolume()[0] # we will set the same volume on all channels
 
4
  from time import sleep
5
  import time
6
  import numpy as np
 
7
  import os
8
  from pathlib import Path
9
  from datetime import datetime, timedelta
 
13
  from threading import Thread, Lock
14
  import alsaaudio
15
 
 
16
  from EDFlib.edfwriter import EDFwriter
17
  from scipy.signal import firwin
18
 
 
61
  FRONTEND_CONFIG = [
62
  0x3E, # ID (RO)
63
  0x95, # CONFIG1 [95] [1, DAISY_EN(bar), CLK_EN, 1, 0, DR[2:0]] : Datarate = 500 SPS
64
+ 0xC0, # CONFIG2 [C0] [1, 1, 0, INT_CAL, 0, CAL_AMP0, CAL_FREQ[1:0]]
65
+ 0xE0, # CONFIG3 [E0] [PD_REFBUF(bar), 1, 1, BIAS_MEAS, BIASREF_INT, PD_BIAS(bar), BIAS_LOFF_SENS, BIAS_STAT] : Power-down reference buffer, no bias
66
  0x00, # No lead-off
67
  0x60, # CH1SET [60] [PD1, GAIN1[2:0], SRB2, MUX1[2:0]]
68
  0x60, # CH2SET 66
 
74
  0x60, # CH8SET
75
  0x04, # BIAS_SENSP 04
76
  0x04, # BIAS_SENSN 04
77
+ 0x00, # LOFF_SENSP Lead-off on all positive pins?
78
+ 0x00, # LOFF_SENSN Lead-off on all negative pins?
79
  0x00, # Normal lead-off
80
  0x00, # Lead-off positive status (RO)
81
  0x00, # Lead-off negative status (RO)
 
131
  elif chan_mode == 'disabled':
132
  mod = mod | 0x81 # PDn = 1 and input shorted (001)
133
  elif chan_mode == 'with bias':
134
+ bias_active = True
135
  bit_i = 1 << chan_i
136
  config[13] = config[13] | bit_i
137
+ # config[14] = config[14] | bit_i
 
138
  elif chan_mode == 'bias out':
 
139
  bias_active = True
140
+ mod = mod | 0x06 # MUX[2:0] = BIAS_DRP (110)
141
  else:
142
  assert False, f"Wrong key: {chan_mode}."
143
  config[n] = mod
 
 
 
144
  if bias_active:
145
+ config[3] = config[3] | 0x1c
146
+ for n, c in enumerate(config):
147
+ print(f"DEBUG: new config[{n}]:\t{c:08b}\t({hex(c)})")
 
148
  return config
149
 
150
 
 
393
  p_data_o.close()
394
 
395
 
396
+ class DummyAlsaMixer:
397
+ def __init__(self):
398
+ self.volume = 50
399
+
400
+ def getvolume(self):
401
+ return [self.volume]
402
+
403
+ def setvolume(self, volume):
404
+ self.volume = volume
405
+
406
+
407
  class Capture:
408
  def __init__(self, detector_cls=None, stimulator_cls=None):
409
  # {now.strftime('%m_%d_%Y_%H_%M_%S')}
 
446
  self._test_stimulus = False
447
 
448
  mixers = alsaaudio.mixers()
449
+ if len(mixers) <= 0:
450
+ warnings.warn(f"No ALSA mixer found.")
451
+ self.mixer = DummyAlsaMixer()
452
+ elif 'PCM' in mixers:
453
  self.mixer = alsaaudio.Mixer(control='PCM')
454
  else:
 
455
  warnings.warn(f"Could not find mixer PCM, using {mixers[0]} instead.")
456
  self.mixer = alsaaudio.Mixer(control=mixers[0])
457
  self.volume = self.mixer.getvolume()[0] # we will set the same volume on all channels
portiloop/detection.py CHANGED
@@ -137,7 +137,7 @@ class SleepSpindleRealTimeDetector(Detector):
137
  output_data_y = self.interpreters[idx].get_tensor(output_details[1]['index'])
138
 
139
  output_scale, output_zero_point = output_details[1]["quantization"]
140
- output_data_y = float(output_data_y - output_zero_point) * output_scale
141
 
142
  if self.verbose:
143
  print(f"Computed output {output_data_y} in {end_time - start_time} seconds")
 
137
  output_data_y = self.interpreters[idx].get_tensor(output_details[1]['index'])
138
 
139
  output_scale, output_zero_point = output_details[1]["quantization"]
140
+ output_data_y = (int(output_data_y) - output_zero_point) * output_scale
141
 
142
  if self.verbose:
143
  print(f"Computed output {output_data_y} in {end_time - start_time} seconds")
portiloop/notebooks/tests.ipynb CHANGED
@@ -2,46 +2,12 @@
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
- "execution_count": 1,
6
- "id": "7b2fc5da",
7
  "metadata": {
8
  "scrolled": false
9
  },
10
- "outputs": [
11
- {
12
- "data": {
13
- "application/vnd.jupyter.widget-view+json": {
14
- "model_id": "5bd498c14c0b47ef8fc0c7b25d6197c0",
15
- "version_major": 2,
16
- "version_minor": 0
17
- },
18
- "text/plain": [
19
- "VBox(children=(Accordion(children=(GridBox(children=(Label(value='CH1'), Label(value='CH2'), Label(value='CH3'…"
20
- ]
21
- },
22
- "metadata": {},
23
- "output_type": "display_data"
24
- },
25
- {
26
- "name": "stdout",
27
- "output_type": "stream",
28
- "text": [
29
- "DEBUG:/home/mendel/software/portiloop-software/portiloop/sounds/stimulus.wav\n",
30
- "PID capture: 4311\n",
31
- "DEBUG: new config[5]:0xe1\n",
32
- "DEBUG: new config[6]:0xe1\n",
33
- "DEBUG: new config[7]:0xe1\n",
34
- "DEBUG: new config[8]:0xe1\n",
35
- "DEBUG: new config[9]:0xe1\n",
36
- "DEBUG: new config[10]:0xe1\n",
37
- "DEBUG: new config[11]:0xe1\n",
38
- "DEBUG: new config[12]:0xe1\n",
39
- "DEBUG: new config[13]:0x0\n",
40
- "DEBUG: new config[14]:0x0\n",
41
- "DEBUG: new config[3]:0xe8\n"
42
- ]
43
- }
44
- ],
45
  "source": [
46
  "from portiloop.capture import Capture\n",
47
  "from portiloop.detection import SleepSpindleRealTimeDetector\n",
@@ -56,7 +22,7 @@
56
  {
57
  "cell_type": "code",
58
  "execution_count": null,
59
- "id": "fd7c79a7",
60
  "metadata": {},
61
  "outputs": [],
62
  "source": []
@@ -64,7 +30,7 @@
64
  ],
65
  "metadata": {
66
  "kernelspec": {
67
- "display_name": "Python 3 (ipykernel)",
68
  "language": "python",
69
  "name": "python3"
70
  },
 
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
+ "execution_count": null,
6
+ "id": "16651843",
7
  "metadata": {
8
  "scrolled": false
9
  },
10
+ "outputs": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  "source": [
12
  "from portiloop.capture import Capture\n",
13
  "from portiloop.detection import SleepSpindleRealTimeDetector\n",
 
22
  {
23
  "cell_type": "code",
24
  "execution_count": null,
25
+ "id": "cded6bbc",
26
  "metadata": {},
27
  "outputs": [],
28
  "source": []
 
30
  ],
31
  "metadata": {
32
  "kernelspec": {
33
+ "display_name": "Python 3",
34
  "language": "python",
35
  "name": "python3"
36
  },
setup.py CHANGED
@@ -8,13 +8,13 @@ setup(
8
  install_requires=['wheel',
9
  'EDFlib-Python',
10
  'numpy',
11
- 'matplotlib',
12
  'portilooplot',
13
  'ipywidgets',
14
  'python-periphery',
15
  'spidev',
16
  'pylsl-coral',
17
  'scipy',
18
- 'pycoral'
 
19
  ]
20
  )
 
8
  install_requires=['wheel',
9
  'EDFlib-Python',
10
  'numpy',
 
11
  'portilooplot',
12
  'ipywidgets',
13
  'python-periphery',
14
  'spidev',
15
  'pylsl-coral',
16
  'scipy',
17
+ 'pycoral',
18
+ 'pyalsaaudio'
19
  ]
20
  )