Skip to content

Instrument management

Use the InstrumentManager() to start experiments and control your PalmSens instrument.

The most high-level way to start a measurement is to use the measure() function:

>>> import pypalmsens as ps

>>> method = ps.CyclicVoltammetry()
>>> ps.measure(method)

You can also manage the connection yourself, using connect(), for example:

>>> with ps.connect() as manager:
...    method = ps.ChronoAmperometry()
...    measurement = manager.measure(method)

Or using InstrumentManager() directly as a context manager:

>>> instruments = discover()

>>> with ps.InstrumentManager(instruments[0]) as manager:
...    measurement = manager.measure(method)

Or managing the instrument connection yourself:

>>> instruments = discover()

>>> manager = ps.InstrumentManager(instruments[0])
>>> manager.connect()
>>> # ...
>>> manager.disconnect()

For more information, see the measurement documentation.

Functions:

Classes:

pypalmsens.connect

connect(instrument: None | Instrument = None) -> InstrumentManager

Connect to instrument and return InstrumentManager.

Connects to any plugged-in PalmSens USB device. Error if multiple devices are plugged-in.

Parameters:

  • instrument

    (Instrument, default: None ) –

    Connect to a specific instrument. Use pypalmsens.discover() to discover instruments.

Returns:

  • manager ( InstrumentManager ) –

    Return instance of InstrumentManager connected to the given instrument.

Source code in src/pypalmsens/_instruments/instrument_manager.py
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
def connect(
    instrument: None | Instrument = None,
) -> InstrumentManager:
    """Connect to instrument and return InstrumentManager.

    Connects to any plugged-in PalmSens USB device.
    Error if multiple devices are plugged-in.

    Parameters
    ----------
    instrument : Instrument, optional
        Connect to a specific instrument.
        Use `pypalmsens.discover()` to discover instruments.

    Returns
    -------
    manager : InstrumentManager
        Return instance of `InstrumentManager` connected to the given instrument.
    """
    if not instrument:
        available_instruments = discover(ignore_errors=True)

        if not available_instruments:
            raise ConnectionError('No instruments were discovered.')

        if len(available_instruments) > 1:
            raise ConnectionError('More than one device discovered.')

        instrument = available_instruments[0]

    manager = InstrumentManager(instrument)
    manager.connect()
    return manager

pypalmsens.discover

discover(ftdi: bool = True, usbcdc: bool = True, winusb: bool = True, bluetooth: bool = False, serial: bool = True, ignore_errors: bool = False) -> list[Instrument]

Discover instruments.

For a list of device interfaces, see: https://dev.palmsens.com/python/latest/_attachments/installation/index.html#compatibility

Parameters:

  • ftdi

    (bool, default: True ) –

    If True, discover ftdi devices

  • usbcdc

    (bool, default: True ) –

    If True, discover usbcdc devices (Windows only)

  • winusb

    (bool, default: True ) –

    If True, discover winusb devices (Windows only)

  • bluetooth

    (bool, default: False ) –

    If True, discover bluetooth devices (Windows only)

  • serial

    (bool, default: True ) –

    If True, discover serial devices

  • ignore_errors

    (False, default: False ) –

    Ignores errors in device discovery

Returns:

  • discovered ( list[Instrument] ) –

    List of dataclasses with discovered instruments.

Source code in src/pypalmsens/_instruments/instrument.py
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
def discover(
    ftdi: bool = True,
    usbcdc: bool = True,
    winusb: bool = True,
    bluetooth: bool = False,
    serial: bool = True,
    ignore_errors: bool = False,
) -> list[Instrument]:
    """Discover instruments.

    For a list of device interfaces, see:
        https://dev.palmsens.com/python/latest/_attachments/installation/index.html#compatibility

    Parameters
    ----------
    ftdi : bool
        If True, discover ftdi devices
    usbcdc : bool
        If True, discover usbcdc devices (Windows only)
    winusb : bool
        If True, discover winusb devices (Windows only)
    bluetooth : bool
        If True, discover bluetooth devices (Windows only)
    serial : bool
        If True, discover serial devices
    ignore_errors : False
        Ignores errors in device discovery

    Returns
    -------
    discovered : list[Instrument]
        List of dataclasses with discovered instruments.
    """
    return asyncio.run(
        discover_async(
            ftdi=ftdi,
            usbcdc=usbcdc,
            winusb=winusb,
            bluetooth=bluetooth,
            serial=serial,
            ignore_errors=ignore_errors,
        )
    )

pypalmsens.measure

measure(method: MethodTypeCompatible, instrument: None | Instrument = None, callback: Callback | CallbackEIS | None = None, stream: str | Path | None = None) -> Measurement

Run measurement.

Executes the given method on any plugged-in PalmSens USB device. Error if multiple devices are plugged-in.

Parameters:

  • instrument

    (Instrument, default: None ) –

    Connect to and meassure on a specific instrument. Use pypalmsens.discover() to discover instruments.

  • callback

    (Callback | CallbackEIS | None, default: None ) –

    If specified, call this function on every new set of data points. New data points are batched, and contain all points since the last time it was called. Each point is an instance of ps.data.CallbackData for non-impedimetric or ps.data.CallbackDataEIS for impedimetric measurments.

  • stream

    (str | Path | None, default: None ) –

    If defined, stream data directly to this file in JSON Lines text format (https://jsonlines.org). This option is useful for long-term measurements. In case of a PC crash or power outage, the most recent measurement data will still be available.

Returns:

  • measurement ( Measurement ) –

    Finished measurement.

Source code in src/pypalmsens/_instruments/instrument_manager.py
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
def measure(
    method: MethodTypeCompatible,
    instrument: None | Instrument = None,
    callback: Callback | CallbackEIS | None = None,
    stream: str | Path | None = None,
) -> Measurement:
    """Run measurement.

    Executes the given method on any plugged-in PalmSens USB device.
    Error if multiple devices are plugged-in.

    Parameters
    ----------
    instrument : Instrument, optional
        Connect to and meassure on a specific instrument.
        Use `pypalmsens.discover()` to discover instruments.
    callback: Callback | CallbackEIS, optional
        If specified, call this function on every new set of data points.
        New data points are batched, and contain all points since the last
        time it was called. Each point is an instance of `ps.data.CallbackData`
        for non-impedimetric or `ps.data.CallbackDataEIS`
        for impedimetric measurments.
    stream: Path | str | None
        If defined, stream data directly to this file in JSON Lines text format
        (https://jsonlines.org). This option is useful for long-term measurements.
        In case of a PC crash or power outage, the most recent measurement data will
        still be available.

    Returns
    -------
    measurement : Measurement
        Finished measurement.
    """
    with connect(instrument=instrument) as manager:
        measurement = manager.measure(method, callback=callback, stream=stream)

    assert measurement

    return measurement

pypalmsens.Instrument dataclass

Instrument(id: str, interface: str, device: Device)

Dataclass holding instrument info.

Methods:

  • from_ip

    Create TCP instrument class.

  • from_port

    Create serial port instrument class.

Attributes:

  • baudrate (int) –

    Baud rate.

  • channel (int) –

    Channel index if part of a multichannel device.

  • device (Device) –

    Device connection class.

  • id (str) –

    Device ID of the instrument.

  • interface (str) –

    Type of the connection.

  • name (str) –

    Name of the instrument.

baudrate property

baudrate: int

Baud rate.

channel class-attribute instance-attribute

channel: int = field(init=False, default=-1)

Channel index if part of a multichannel device.

Returns -1 if instrument is not part of a multichannel device.

device class-attribute instance-attribute

device: Device = field(repr=False)

Device connection class.

id class-attribute instance-attribute

id: str = field(repr=False)

Device ID of the instrument.

interface instance-attribute

interface: str

Type of the connection.

name class-attribute instance-attribute

name: str = field(init=False)

Name of the instrument.

from_ip classmethod

from_ip(hostname: str, port: int = 49152) -> Instrument

Create TCP instrument class.

Use this method to connect to a device that is connected to the network, like a Nexus.

Parameters:

  • hostname

    (str) –

    Hostname or IP to connect to.

  • port

    (str, default: 49152 ) –

    Port to connect to (default: Nexus default port).

Returns:

  • instrument ( Instrument ) –

    Instrument dataclass

Source code in src/pypalmsens/_instruments/instrument.py
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
@classmethod
def from_ip(cls, hostname: str, port: int = 49152) -> Instrument:
    """Create TCP instrument class.

    Use this method to connect to a device that is connected to the network,
    like a Nexus.

    Parameters
    ----------
    hostname : str
        Hostname or IP to connect to.
    port : str
        Port to connect to (default: Nexus default port).

    Returns
    -------
    instrument : Instrument
        Instrument dataclass
    """
    device = PSDevices.TCPDevice(hostname, port)
    return cls._from_device(device)

from_port classmethod

from_port(port: str, *, baudrate: int | None = None) -> Instrument

Create serial port instrument class.

Parameters:

  • port

    (str) –

    Name of the port to connect to.

  • baudrate

    (int, default: None ) –

    Set the baudrate. If None, use the default baudrate.

Returns:

  • instrument ( Instrument ) –

    Instrument dataclass

Source code in src/pypalmsens/_instruments/instrument.py
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
@classmethod
def from_port(cls, port: str, *, baudrate: int | None = None) -> Instrument:
    """Create serial port instrument class.

    Parameters
    ----------
    port : str
        Name of the port to connect to.
    baudrate : int, optional
        Set the baudrate. If None, use the default baudrate.

    Returns
    -------
    instrument : Instrument
        Instrument dataclass
    """
    if baudrate is None:
        device = PSDevices.SerialPortDevice(port)
    else:
        device = PSDevices.SerialPortDevice(port, baudrate=baudrate)

    return cls._from_device(device)

pypalmsens.InstrumentManager

InstrumentManager(instrument: Instrument)

Instrument manager for PalmSens instruments.

Parameters:

  • instrument

    (Instrument) –

    Instrument to connect to, use discover() to find connected instruments.

Methods:

Attributes:

Source code in src/pypalmsens/_instruments/instrument_manager.py
123
124
125
126
127
128
129
def __init__(self, instrument: Instrument):
    super().__init__()

    self.instrument: Instrument = instrument
    """Instrument being managed by this class."""

    self._comm: CommManager

capabilities property

capabilities: Capabilities

Retrieve device capabilities and device info as a dataclass.

Returns:

  • capabilities ( Capabilities ) –

    Device capabilities and device info.

instrument instance-attribute

instrument: Instrument = instrument

Instrument being managed by this class.

abort

abort() -> None

Abort measurement.

Source code in src/pypalmsens/_instruments/instrument_manager.py
367
368
369
370
def abort(self) -> None:
    """Abort measurement."""
    with self._lock():
        self._comm.Abort()

connect

connect() -> None

Connect to instrument.

Source code in src/pypalmsens/_instruments/instrument_manager.py
169
170
171
172
173
174
175
176
177
178
179
180
def connect(self) -> None:
    """Connect to instrument."""
    if self.is_connected():
        return

    # The comm manager needs to open async, because the measurement is handled async.
    # Opening the comm manager in async sets some handlers in ClientConnection
    # that are sync or async specific. This affects the measurement,
    # receive status, and device state change events.
    self._comm = asyncio.run(self.instrument._connect_async())

    firmware_warning(self._comm.Capabilities)

disconnect

disconnect()

Disconnect from the instrument.

Source code in src/pypalmsens/_instruments/instrument_manager.py
505
506
507
508
509
510
511
512
def disconnect(self):
    """Disconnect from the instrument."""
    if not self.is_connected():
        return

    self._comm.Disconnect()

    del self._comm

ensure_connection

ensure_connection()

Raises connection error if the instrument is not connected.

Source code in src/pypalmsens/_instruments/instrument_manager.py
164
165
166
167
def ensure_connection(self):
    """Raises connection error if the instrument is not connected."""
    if not self.is_connected():
        raise ConnectionError('Not connected to an instrument')

get_current_range

get_current_range() -> AllowedCurrentRanges

Get the current range for the cell.

Returns:

Source code in src/pypalmsens/_instruments/instrument_manager.py
225
226
227
228
229
230
231
232
233
def get_current_range(self) -> AllowedCurrentRanges:
    """Get the current range for the cell.

    Returns
    -------
    current_range: AllowedCurrentRanges
    """
    with self._lock():
        return cr_enum_to_string(self._comm.CurrentRange)

get_estimated_duration

get_estimated_duration(method: Method | MethodTypeCompatible) -> float

Get the estimated duration for this method.

Parameters:

  • method

    (MethodType) –

    The method to get the estimated duration for.

Returns:

  • float

    Estimated duration in seconds.

Source code in src/pypalmsens/_instruments/capabilities_mixin.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
def get_estimated_duration(
    self: HasCommProtocol,
    method: PalmSens.Method | MethodTypeCompatible,
) -> float:
    """Get the estimated duration for this method.

    Parameters
    -----------
    method : MethodType
        The method to get the estimated duration for.

    Returns
    -------
    float
        Estimated duration in seconds.
    """
    self.ensure_connection()

    if not isinstance(method, PalmSens.Method):
        method = method._to_psmethod()

    capabilities = self._comm.Capabilities

    return method.GetMinimumEstimatedMeasurementDuration(capabilities)

get_instrument_serial

get_instrument_serial() -> str

Return instrument serial number.

Returns:

  • serial ( str ) –

    Instrument serial.

Source code in src/pypalmsens/_instruments/instrument_manager.py
294
295
296
297
298
299
300
301
302
303
304
305
def get_instrument_serial(self) -> str:
    """Return instrument serial number.

    Returns
    -------
    serial : str
        Instrument serial.
    """
    with self._lock():
        serial = self._comm.DeviceSerial.ToString()

    return serial

get_potential_range

get_potential_range() -> AllowedPotentialRanges

Get the potential range for the cell.

Returns:

Source code in src/pypalmsens/_instruments/instrument_manager.py
272
273
274
275
276
277
278
279
280
def get_potential_range(self) -> AllowedPotentialRanges:
    """Get the potential range for the cell.

    Returns
    -------
    potential_range: AllowedPotentialRanges
    """
    with self._lock():
        return pr_enum_to_string(self._comm.PotentialRange)

initialize_multiplexer

initialize_multiplexer(mux_model: int) -> int

Initialize the multiplexer.

Parameters:

  • mux_model

    (int) –

    The model of the multiplexer. - 0 = 8 channel - 1 = 16 channel - 2 = 32 channel

Returns:

  • channels ( int ) –

    Number of available multiplexes channels

Source code in src/pypalmsens/_instruments/instrument_manager.py
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
def initialize_multiplexer(self, mux_model: int) -> int:
    """Initialize the multiplexer.

    Parameters
    ----------
    mux_model: int
        The model of the multiplexer.
        - 0 = 8 channel
        - 1 = 16 channel
        - 2 = 32 channel

    Returns
    -------
    channels : int
        Number of available multiplexes channels
    """
    with self._lock():
        model = PalmSens.MuxModel(mux_model)

        if model == PalmSens.MuxModel.MUX8R2 and (
            self._comm.ClientConnection.GetType().Equals(
                clr.GetClrType(PalmSens.Comm.ClientConnectionPS4)
            )
            or self._comm.ClientConnection.GetType().Equals(
                clr.GetClrType(PalmSens.Comm.ClientConnectionMS)
            )
        ):
            self._comm.ClientConnection.ReadMuxInfo()

        self._comm.Capabilities.MuxModel = model

        if self._comm.Capabilities.MuxModel == PalmSens.MuxModel.MUX8:
            self._comm.Capabilities.NumMuxChannels = 8
        elif self._comm.Capabilities.MuxModel == PalmSens.MuxModel.MUX16:
            self._comm.Capabilities.NumMuxChannels = 16
        elif self._comm.Capabilities.MuxModel == PalmSens.MuxModel.MUX8R2:
            self._comm.ClientConnection.ReadMuxInfo()

    channels = self._comm.Capabilities.NumMuxChannels
    return channels

is_cell_on

is_cell_on() -> bool

Get cell status.

Returns:

  • cell_on ( bool ) –

    Return true if the cell is on

Source code in src/pypalmsens/_instruments/instrument_manager.py
201
202
203
204
205
206
207
208
209
210
def is_cell_on(self) -> bool:
    """Get cell status.

    Returns
    -------
    cell_on : bool
        Return true if the cell is on
    """
    with self._lock():
        return self._comm.CellOn

is_connected

is_connected() -> bool

Return True if an instrument connection exists.

Source code in src/pypalmsens/_instruments/instrument_manager.py
160
161
162
def is_connected(self) -> bool:
    """Return True if an instrument connection exists."""
    return hasattr(self, '_comm')

is_measuring

is_measuring() -> bool

Return True if device is measuring.

Source code in src/pypalmsens/_instruments/instrument_manager.py
143
144
145
def is_measuring(self) -> bool:
    """Return True if device is measuring."""
    return int(self._comm.State) == CommManager.DeviceState.Measurement

measure

measure(method: MethodTypeCompatible, *, callback: Callback | CallbackEIS | None = None, stream: Path | str | None = None) -> Measurement

Start measurement using given method parameters.

Parameters:

  • method

    (MethodTypeCompatible) –

    Method parameters for measurement

  • callback

    (Callback | CallbackEIS | None, default: None ) –

    If specified, call this function on every new set of data points. New data points are batched, and contain all points since the last time it was called. Each point is an instance of ps.data.CallbackData for non-impedimetric or ps.data.CallbackDataEIS for impedimetric measurments.

  • stream

    (Path | str | None, default: None ) –

    If defined, stream data directly to this file in JSON Lines text format (https://jsonlines.org). This option is useful for long-term measurements. In case of a PC crash or power outage, the most recent measurement data will still be available.

Returns:

  • measurement ( Measurement ) –

    Finished measurement.

Source code in src/pypalmsens/_instruments/instrument_manager.py
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
def measure(
    self,
    method: MethodTypeCompatible,
    *,
    callback: Callback | CallbackEIS | None = None,
    stream: Path | str | None = None,
) -> Measurement:
    """Start measurement using given method parameters.

    Parameters
    ----------
    method: MethodType
        Method parameters for measurement
    callback: Callback, optional
        If specified, call this function on every new set of data points.
        New data points are batched, and contain all points since the last
        time it was called. Each point is an instance of `ps.data.CallbackData`
        for non-impedimetric or  `ps.data.CallbackDataEIS`
        for impedimetric measurments.
    stream: Path | str | None
        If defined, stream data directly to this file in JSON Lines text format
        (https://jsonlines.org). This option is useful for long-term measurements.
        In case of a PC crash or power outage, the most recent measurement data will
        still be available.

    Returns
    -------
    measurement : Measurement
        Finished measurement.
    """
    self.ensure_connection()
    self.validate_method(method)

    # note that the comm manager must be opened async so it sets the
    # correct async event handlers
    measurement_manager = MeasurementManagerAsync(comm=self._comm)

    return asyncio.run(
        measurement_manager.measure(
            method,
            callback=callback,
            stream=stream,
            listeners=self._listeners,
        )
    )

on

on(event: AllowedEvents, callback: Callable[..., None]) -> EventHandle

Register a callback to invoke for the specified event.

Parameters:

  • event

    (AllowedEvents) –

    Name of the event to subscribe to. For most events this simply appends callback to the internal listeners dictionary.

  • callback

    (Callable[..., None]) –

    Function that will be invoked when the event is triggered.

Returns:

  • EventHandle

    Handle that can be used to cancel the subscription.

Notes
  • 'receive_message' and 'receive_status' are handled specially: they create instances of :class:EventHandleReceiveMessage or :class:EventHandleStatus, respectively, which attach the callback directly to the underlying communication layer.
Source code in src/pypalmsens/_instruments/events_mixin.py
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
def on(
    self,
    event: AllowedEvents,
    callback: Callable[..., None],
) -> EventHandle:
    """Register a callback to invoke for the specified event.

    Parameters
    ----------
    event : AllowedEvents
        Name of the event to subscribe to. For most events this simply
        appends callback to the internal listeners dictionary.
    callback : Callable[..., None]
        Function that will be invoked when the event is triggered.

    Returns
    -------
    EventHandle
        Handle that can be used to cancel the subscription.

    Notes
    -----
    * ``'receive_message'`` and ``'receive_status'`` are handled specially:
      they create instances of :class:`EventHandleReceiveMessage` or
      :class:`EventHandleStatus`, respectively, which attach the callback
      directly to the underlying communication layer.
    """
    if event == 'receive_message':
        return EventHandleReceiveMessage(emitter=self, event=event, callback=callback)

    elif event == 'receive_status':
        return EventHandleStatus(emitter=self, event=event, callback=callback)

    self._listeners[event].append(callback)
    return EventHandle(emitter=self, event=event, callback=callback)

on_curve_begin

on_curve_begin(callback: Callable[[Curve], None]) -> EventHandle

Register a callback to invoke at the start of a new curve.

For EIS use on_eis_data_start.

Parameters:

Returns:

  • EventHandle

    Handle that can be used to cancel the subscription.

Source code in src/pypalmsens/_instruments/events_mixin.py
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
def on_curve_begin(self, callback: Callable[[Curve], None]) -> EventHandle:
    """Register a callback to invoke at the start of a new curve.

    For EIS use `on_eis_data_start`.

    Parameters
    ----------
    callback : Callable[[Curve]]
        The function to call when triggered.
        Passes [pypalmsens.data.Curve][] as argument to the callback.

    Returns
    -------
    EventHandle
        Handle that can be used to cancel the subscription.
    """
    return self.on('curve_begin', callback=callback)

on_curve_end

on_curve_end(callback: Callable[[Curve], None]) -> EventHandle

Register a callback to invoke at the end of a curve.

For EIS use on_eis_data_end.

Parameters:

Returns:

  • EventHandle

    Handle that can be used to cancel the subscription.

Source code in src/pypalmsens/_instruments/events_mixin.py
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
def on_curve_end(self, callback: Callable[[Curve], None]) -> EventHandle:
    """Register a callback to invoke at the end of a curve.

    For EIS use `on_eis_data_end`.

    Parameters
    ----------
    callback : Callable[[Curve]]
        The function to call when triggered.
        Passes [pypalmsens.data.Curve][] as argument to the callback.

    Returns
    -------
    EventHandle
        Handle that can be used to cancel the subscription.
    """
    return self.on('curve_end', callback=callback)

on_curve_new_data

on_curve_new_data(callback: Callable[[CallbackData], None]) -> EventHandle

Register a callback to invoke when new data are received

Note that the data are batched depending on available resources.

For EIS use on_eis_new_data.

Parameters:

Returns:

  • EventHandle

    Handle that can be used to cancel the subscription.

Source code in src/pypalmsens/_instruments/events_mixin.py
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
def on_curve_new_data(self, callback: Callable[[CallbackData], None]) -> EventHandle:
    """Register a callback to invoke when new data are received

    Note that the data are batched depending on available resources.

    For EIS use `on_eis_new_data`.

    Parameters
    ----------
    callback : Callable[[CallbackData]]
        The function to call when triggered.
        Passes [pypalmsens.data.CallbackData][] as argument to the callback.

    Returns
    -------
    EventHandle
        Handle that can be used to cancel the subscription.
    """
    return self.on('curve_new_data', callback=callback)

on_eis_data_begin

on_eis_data_begin(callback: Callable[[EISData], None]) -> EventHandle

Register a callback to invoke at the start of a new EIS data set.

Parameters:

Returns:

  • EventHandle

    Handle that can be used to cancel the subscription.

Source code in src/pypalmsens/_instruments/events_mixin.py
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
def on_eis_data_begin(self, callback: Callable[[EISData], None]) -> EventHandle:
    """Register a callback to invoke at the start of a new EIS data set.

    Parameters
    ----------
    callback : Callable[[EISData]]
        The function to call when triggered.
        Passes [pypalmsens.data.EISData][] as argument to the callback.

    Returns
    -------
    EventHandle
        Handle that can be used to cancel the subscription.
    """
    return self.on('eis_data_begin', callback=callback)

on_eis_data_end

on_eis_data_end(callback: Callable[[], None]) -> EventHandle

Register a callback to invoke at the end of an EIS data set.

Parameters:

  • callback

    (Callable) –

    The function to call when triggered.

Returns:

  • EventHandle

    Handle that can be used to cancel the subscription.

Source code in src/pypalmsens/_instruments/events_mixin.py
282
283
284
285
286
287
288
289
290
291
292
293
294
295
def on_eis_data_end(self, callback: Callable[[], None]) -> EventHandle:
    """Register a callback to invoke at the end of an EIS data set.

    Parameters
    ----------
    callback : Callable
        The function to call when triggered.

    Returns
    -------
    EventHandle
        Handle that can be used to cancel the subscription.
    """
    return self.on('eis_data_end', callback=callback)

on_eis_new_data

on_eis_new_data(callback: Callable[[CallbackDataEIS], None]) -> EventHandle

Register a callback to invoke when new eis data are received.

Data points are batched depending on available resources.

Parameters:

Returns:

  • EventHandle

    Handle that can be used to cancel the subscription.

Source code in src/pypalmsens/_instruments/events_mixin.py
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
def on_eis_new_data(self, callback: Callable[[CallbackDataEIS], None]) -> EventHandle:
    """Register a callback to invoke when new eis data are received.

    Data points are batched depending on available resources.

    Parameters
    ----------
    callback : Callable[[CallbackDataEIS]]
        The function to call when triggered.
        Passes [pypalmsens.data.CallbackDataEIS][] as argument to the callback.

    Returns
    -------
    EventHandle
        Handle that can be used to cancel the subscription.
    """
    return self.on('eis_new_data', callback=callback)

on_error

on_error(callback: Callable[..., None]) -> EventHandle

Register a callback to invoke when an error occurs during a measurement.

These errors can be a connection or communication error.

Parameters:

  • callback

    (Callable) –

    The function to call when triggered.

Returns:

  • EventHandle

    Handle that can be used to cancel the subscription.

Source code in src/pypalmsens/_instruments/events_mixin.py
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
def on_error(self, callback: Callable[..., None]) -> EventHandle:
    """Register a callback to invoke when an error occurs during a measurement.

    These errors can be a connection or communication error.

    Parameters
    ----------
    callback : Callable
        The function to call when triggered.

    Returns
    -------
    EventHandle
        Handle that can be used to cancel the subscription.
    """
    return self.on('error', callback=callback)

on_measurement_begin

on_measurement_begin(callback: Callable[[Measurement], None]) -> EventHandle

Register a callback to invoke at the start of a measurement.

Parameters:

Returns:

  • EventHandle

    Handle that can be used to cancel the subscription.

Source code in src/pypalmsens/_instruments/events_mixin.py
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
def on_measurement_begin(self, callback: Callable[[Measurement], None]) -> EventHandle:
    """Register a callback to invoke at the start of a measurement.

    Parameters
    ----------
    callback : Callable
        The function to call when triggered.
        Passes [pypalmsens.data.Measurement][] as argument to the callback.

    Returns
    -------
    EventHandle
        Handle that can be used to cancel the subscription.
    """
    return self.on('measurement_begin', callback=callback)

on_measurement_end

on_measurement_end(callback: Callable[[Measurement], None]) -> EventHandle

Register a callback to invoke at the end of a measurement.

Parameters:

Returns:

  • EventHandle

    Handle that can be used to cancel the subscription.

Source code in src/pypalmsens/_instruments/events_mixin.py
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
def on_measurement_end(self, callback: Callable[[Measurement], None]) -> EventHandle:
    """Register a callback to invoke at the end of a measurement.

    Parameters
    ----------
    callback : Callable
        The function to call when triggered.
        Passes [pypalmsens.data.Measurement][] as argument to the callback.

    Returns
    -------
    EventHandle
        Handle that can be used to cancel the subscription.
    """
    return self.on('measurement_end', callback=callback)

on_measurement_setup

on_measurement_setup(callback: Callable[[], None]) -> EventHandle

Register a callback to invoke before the measurement starts.

Use this to set up file resources, database connections, etc.

Parameters:

  • callback

    (Callable) –

    The function to call when triggered.

Returns:

  • EventHandle

    Handle that can be used to cancel the subscription.

Source code in src/pypalmsens/_instruments/events_mixin.py
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
def on_measurement_setup(self, callback: Callable[[], None]) -> EventHandle:
    """Register a callback to invoke before the measurement starts.

    Use this to set up file resources, database connections, etc.

    Parameters
    ----------
    callback : Callable
        The function to call when triggered.

    Returns
    -------
    EventHandle
        Handle that can be used to cancel the subscription.
    """
    return self.on('measurement_setup', callback=callback)

on_measurement_teardown

on_measurement_teardown(callback: Callable[[], None]) -> EventHandle

Register a callback to invoke after the measurement ends.

The measurement ends when it finnished successfully or after an error occurs. Use this to close files or clean up resources.

Parameters:

  • callback

    (Callable) –

    The function to call when triggered.

Returns:

  • EventHandle

    Handle that can be used to cancel the subscription.

Source code in src/pypalmsens/_instruments/events_mixin.py
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
def on_measurement_teardown(self, callback: Callable[[], None]) -> EventHandle:
    """Register a callback to invoke after the measurement ends.

    The measurement ends when it finnished successfully or after an error occurs.
    Use this to close files or clean up resources.

    Parameters
    ----------
    callback : Callable
        The function to call when triggered.

    Returns
    -------
    EventHandle
        Handle that can be used to cancel the subscription.
    """
    return self.on('measurement_teardown', callback=callback)

on_receive_message

on_receive_message(callback: Callable[[str], None])

Register a callback for when a new message is received.

The callback will be invoked, for example, when a method is started, or when send_string is called in MethodSCRIPT.

Parameters:

  • callback

    (callable[[str]]) –

    The function to call when triggered. Passes str as argument to the callback.

Returns:

  • EventHandle

    Handle that can be used to cancel the subscription.

Source code in src/pypalmsens/_instruments/events_mixin.py
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
def on_receive_message(self, callback: Callable[[str], None], /):
    """Register a callback for when a new message is received.

    The callback will be invoked, for example, when a method is started,
    or when `send_string` is called in MethodSCRIPT.

    Parameters
    ----------
    callback : callable[[str]]
        The function to call when triggered.
        Passes [str][] as argument to the callback.

    Returns
    -------
    EventHandle
        Handle that can be used to cancel the subscription.
    """
    return self.on('receive_message', callback=callback)

on_receive_status

on_receive_status(callback: Callable[[Status], None])

Register a callback for idle status update events.

Requires active event loop (i.e. async only).

The callback will be invoked whenever the instrument sends updated current/potential values during idle state or pretreatment phases. The update frequency varies per device.

Parameters:

Returns:

  • EventHandle

    Handle that can be used to cancel the subscription.

Source code in src/pypalmsens/_instruments/events_mixin.py
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
def on_receive_status(self, callback: Callable[[Status], None], /):
    """Register a callback for idle status update events.

    Requires active event loop (i.e. async only).

    The callback will be invoked whenever the instrument sends
    updated current/potential values during idle state or pretreatment phases.
    The update frequency varies per device.

    Parameters
    ----------
    callback : callable[[Status]]
        The function to call when triggered.
        Passes [pypalmsens.data.Status][] as argument to the callback.

    Returns
    -------
    EventHandle
        Handle that can be used to cancel the subscription.
    """
    return self.on('receive_status', callback=callback)

query

query(command: str, delay: float | None = None) -> str

Send a command using the communication protocol and return its response.

This is a method for direct communication with the instrument. It writes the command to the device, waits for completion, reads the full response, and returns it as a string.

For commands that run for a long time (e.g. scripts), this method will block until the script completes or times out.

See also pypalmsens.CommProtocol.

Parameters:

  • command

    (str) –

    The command to send (e.g., 'i' to get the serial number). If command does not end with '\n', one is automatically added.

  • delay

    (float, default: None ) –

    Pause (in seconds) between read attempts. Defaults to self.delay.

Returns:

  • response ( str ) –

    The complete response from the device.

Source code in src/pypalmsens/_instruments/instrument_manager.py
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
def query(self, command: str, delay: float | None = None) -> str:
    """Send a command using the communication protocol and return its response.

    This is a method for direct communication with the instrument.
    It writes the command to the device, waits for completion,
    reads the full response, and returns it as a string.

    For commands that run for a long time (e.g. scripts), this
    method will block until the script completes or times out.

    See also [pypalmsens.CommProtocol][].

    Parameters
    ----------
    command : str
        The command to send (e.g., 'i' to get the serial number).
        If `command` does not end with `'\\n'`, one is automatically added.
    delay : float, optional
        Pause (in seconds) between read attempts. Defaults to `self.delay`.

    Returns
    -------
    response : str
        The complete response from the device.
    """
    if not isinstance(self._comm.ClientConnection, PalmSens.Comm.ClientConnectionMS):
        raise TypeError(
            'The Communication Protocol is only supported on MethodSCRIPT devices.'
        )

    with self._lock():
        # this temporarily turns off idle messages
        status_when_idle = self._comm.get_StatusWhenIdle()
        self._comm.set_StatusWhenIdle(False)
        comm = CommProtocol(self.instrument)

        try:
            response = comm.query(command, delay=delay)
        finally:
            self._comm.set_StatusWhenIdle(status_when_idle)

    return response

read_current

read_current() -> float

Read the current in µA.

Returns:

  • current ( float ) –

    Current in µA.

Source code in src/pypalmsens/_instruments/instrument_manager.py
212
213
214
215
216
217
218
219
220
221
222
223
def read_current(self) -> float:
    """Read the current in µA.

    Returns
    -------
    current : float
        Current in µA.
    """
    with self._lock():
        current = self._comm.Current

    return current

read_potential

read_potential() -> float

Read the potential in V.

Returns:

  • potential ( float ) –

    Potential in V.

Source code in src/pypalmsens/_instruments/instrument_manager.py
247
248
249
250
251
252
253
254
255
256
257
258
259
def read_potential(self) -> float:
    """Read the potential in V.

    Returns
    -------
    potential : float
        Potential in V.
    """

    with self._lock():
        potential = self._comm.Potential

    return potential

set_cell

set_cell(cell_on: bool)

Turn the cell on or off.

Parameters:

  • cell_on

    (bool) –

    If true, turn on the cell

Source code in src/pypalmsens/_instruments/instrument_manager.py
190
191
192
193
194
195
196
197
198
199
def set_cell(self, cell_on: bool):
    """Turn the cell on or off.

    Parameters
    ----------
    cell_on : bool
        If true, turn on the cell
    """
    with self._lock():
        self._comm.CellOn = cell_on

set_current_range

set_current_range(current_range: AllowedCurrentRanges)

Set the current range for the cell.

Parameters:

  • current_range

    (AllowedCurrentRanges) –

    Set the current range as a string. See pypalmsens.settings.AllowedCurrentRanges for options.

Source code in src/pypalmsens/_instruments/instrument_manager.py
235
236
237
238
239
240
241
242
243
244
245
def set_current_range(self, current_range: AllowedCurrentRanges):
    """Set the current range for the cell.

    Parameters
    ----------
    current_range: AllowedCurrentRanges
        Set the current range as a string.
        See `pypalmsens.settings.AllowedCurrentRanges` for options.
    """
    with self._lock():
        self._comm.CurrentRange = cr_string_to_enum(current_range)

set_multiplexer_channel

set_multiplexer_channel(channel: int)

Sets the multiplexer channel.

Parameters:

  • channel

    (int) –

    Index of the channel to set.

Source code in src/pypalmsens/_instruments/instrument_manager.py
494
495
496
497
498
499
500
501
502
503
def set_multiplexer_channel(self, channel: int):
    """Sets the multiplexer channel.

    Parameters
    ----------
    channel : int
        Index of the channel to set.
    """
    with self._lock():
        self._comm.ClientConnection.SetMuxChannel(channel)

set_mux8r2_settings

Set the settings for the Mux8R2 multiplexer.

Parameters:

  • connect_sense_to_working_electrode

    (bool, default: False ) –

    Connect the sense electrode to the working electrode. Default is False.

  • combine_reference_and_counter_electrodes

    (bool, default: False ) –

    Combine the reference and counter electrodes. Default is False.

  • use_channel_1_reference_and_counter_electrodes

    (bool, default: False ) –

    Use channel 1 reference and counter electrodes for all working electrodes. Default is False.

  • set_unselected_channel_working_electrode

    (int, default: 0 ) –

    Set the unselected channel working electrode to disconnected/floating (0), ground (1), or standby potential (2). Default is 0.

Source code in src/pypalmsens/_instruments/instrument_manager.py
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
def set_mux8r2_settings(
    self,
    connect_sense_to_working_electrode: bool = False,
    combine_reference_and_counter_electrodes: bool = False,
    use_channel_1_reference_and_counter_electrodes: bool = False,
    set_unselected_channel_working_electrode: int = 0,
):
    """Set the settings for the Mux8R2 multiplexer.

    Parameters
    ---------
    connect_sense_to_working_electrode: float
        Connect the sense electrode to the working electrode. Default is False.
    combine_reference_and_counter_electrodes: float
        Combine the reference and counter electrodes. Default is False.
    use_channel_1_reference_and_counter_electrodes: float
        Use channel 1 reference and counter electrodes for all working electrodes. Default is False.
    set_unselected_channel_working_electrode: float
        Set the unselected channel working electrode to disconnected/floating (0), ground (1), or standby potential (2). Default is 0.
    """
    self.ensure_connection()

    if self._comm.Capabilities.MuxModel != PalmSens.MuxModel.MUX8R2:
        raise ValueError(
            f"Incompatible mux model: {self._comm.Capabilities.MuxModel}, expected 'MUXR2'."
        )

    mux_settings = PalmSens.Method.MuxSettings(False)
    mux_settings.ConnSEWE = connect_sense_to_working_electrode
    mux_settings.ConnectCERE = combine_reference_and_counter_electrodes
    mux_settings.CommonCERE = use_channel_1_reference_and_counter_electrodes
    mux_settings.UnselWE = PalmSens.Method.MuxSettings.UnselWESetting(
        set_unselected_channel_working_electrode
    )

    with self._lock():
        self._comm.ClientConnection.SetMuxSettings(MuxType(1), mux_settings)

set_potential

set_potential(potential: float)

Set the potential of the cell.

Parameters:

  • potential

    (float) –

    Potential in V

Source code in src/pypalmsens/_instruments/instrument_manager.py
261
262
263
264
265
266
267
268
269
270
def set_potential(self, potential: float):
    """Set the potential of the cell.

    Parameters
    ----------
    potential : float
        Potential in V
    """
    with self._lock():
        self._comm.Potential = potential

set_potential_range

Set the potential range for the cell.

Parameters:

  • potential_range

    (AllowedPotentialRanges) –

    Set the potential range as a string. See pypalmsens.settings.AllowedPotentialRanges for options.

Source code in src/pypalmsens/_instruments/instrument_manager.py
282
283
284
285
286
287
288
289
290
291
292
def set_potential_range(self, potential_range: AllowedPotentialRanges):
    """Set the potential range for the cell.

    Parameters
    ----------
    potential_range: AllowedPotentialRanges
        Set the potential range as a string.
        See `pypalmsens.settings.AllowedPotentialRanges` for options.
    """
    with self._lock():
        self._comm.PotentialRange = pr_string_to_enum(potential_range)

status

status() -> Status

Get status.

Source code in src/pypalmsens/_instruments/instrument_manager.py
182
183
184
185
186
187
188
def status(self) -> Status:
    """Get status."""
    self.ensure_connection()
    return Status(
        self._comm.get_Status(),
        device_state=str(self._comm.get_State()),  # type:ignore
    )

supported_applied_current_ranges

supported_applied_current_ranges() -> list[AllowedCurrentRanges]

List applied current ranges supported by this device.

Returns:

Source code in src/pypalmsens/_instruments/capabilities_mixin.py
63
64
65
66
67
68
69
70
71
72
def supported_applied_current_ranges(self: HasCommProtocol) -> list[AllowedCurrentRanges]:
    """List applied current ranges supported by this device.

    Returns
    -------
    current_ranges: list[AllowedCurrentRanges]
        List of supported current ranges.
    """
    self.ensure_connection()
    return CapabilitiesInterface(comm=self._comm).supported_applied_current_ranges

supported_bipot_current_ranges

supported_bipot_current_ranges() -> list[AllowedCurrentRanges]

List bipot current ranges supported by this device.

Returns:

Source code in src/pypalmsens/_instruments/capabilities_mixin.py
74
75
76
77
78
79
80
81
82
83
def supported_bipot_current_ranges(self: HasCommProtocol) -> list[AllowedCurrentRanges]:
    """List bipot current ranges supported by this device.

    Returns
    -------
    current_ranges: list[AllowedCurrentRanges]
        List of supported current ranges.
    """
    self.ensure_connection()
    return CapabilitiesInterface(comm=self._comm).supported_bipot_current_ranges

supported_current_ranges

supported_current_ranges() -> list[AllowedCurrentRanges]

List current ranges supported by this device.

Returns:

Source code in src/pypalmsens/_instruments/capabilities_mixin.py
52
53
54
55
56
57
58
59
60
61
def supported_current_ranges(self: HasCommProtocol) -> list[AllowedCurrentRanges]:
    """List current ranges supported by this device.

    Returns
    -------
    current_ranges: list[AllowedCurrentRanges]
        List of supported current ranges.
    """
    self.ensure_connection()
    return CapabilitiesInterface(comm=self._comm).supported_current_ranges

supported_methods

supported_methods() -> list[AllowedMethods]

List methods supported by this device.

Returns:

Source code in src/pypalmsens/_instruments/capabilities_mixin.py
41
42
43
44
45
46
47
48
49
50
def supported_methods(self: HasCommProtocol) -> list[AllowedMethods]:
    """List methods supported by this device.

    Returns
    -------
    methods: list[AllowedMethods]
        List of supported methods.
    """
    self.ensure_connection()
    return CapabilitiesInterface(comm=self._comm).supported_methods

supported_potential_ranges

supported_potential_ranges() -> list[AllowedPotentialRanges]

List applied potential ranges supported by this device.

Returns:

Source code in src/pypalmsens/_instruments/capabilities_mixin.py
85
86
87
88
89
90
91
92
93
94
def supported_potential_ranges(self: HasCommProtocol) -> list[AllowedPotentialRanges]:
    """List applied potential ranges supported by this device.

    Returns
    -------
    potential_ranges: list[AllowedPotentialRanges]
        List of supported potential ranges.
    """
    self.ensure_connection()
    return CapabilitiesInterface(comm=self._comm).supported_potential_ranges

validate_method

validate_method(method: MethodTypeCompatible)

Validate method.

Raise ValueError if the method cannot be validated.

Parameters:

Source code in src/pypalmsens/_instruments/capabilities_mixin.py
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
def validate_method(
    self: HasCommProtocol,
    method: MethodTypeCompatible,
):
    """Validate method.

    Raise ValueError if the method cannot be validated.

    Parameters
    -----------
    method: MethodType
        The method to validate.
    """
    self.ensure_connection()

    capabilities = self._comm.Capabilities

    psmethod = method._to_psmethod()
    errors = psmethod.Validate(capabilities)

    if any(error.IsFatal for error in errors):
        message = '\n'.join([error.Message for error in errors])
        raise MethodIncompatibleError(f'Method not compatible:\n{message}')

wait_digital_trigger

wait_digital_trigger(wait_for_high: bool)

Wait for digital trigger.

Parameters:

  • wait_for_high

    (bool) –

    Wait for digital line high before starting

Source code in src/pypalmsens/_instruments/instrument_manager.py
353
354
355
356
357
358
359
360
361
362
363
364
365
def wait_digital_trigger(self, wait_for_high: bool):
    """Wait for digital trigger.

    Parameters
    ----------
    wait_for_high: bool
        Wait for digital line high before starting
    """
    with self._lock():
        while True:
            if self._comm.DigitalLineD0 == wait_for_high:
                break
            sleep(0.05)

pypalmsens.InstrumentPool

Manages a set of instrument.

Most calls are run asynchronously in the background, which means that measurements are running in parallel.

This is a thin wrapper around the InstrumentPoolAsync class.

Parameters:

Methods:

  • add

    Open and add manager to the pool.

  • connect

    Connect all instrument managers in the pool.

  • disconnect

    Disconnect all instrument managers in the pool.

  • is_connected

    Return true if all managers in the pool are connected.

  • is_disconnected

    Return true if all managers in the pool are disconnected.

  • measure

    Concurrently run measurement on all managers in the pool.

  • remove

    Close and remove manager from pool.

  • status

    Return status for all managers in pool.

Attributes:

Source code in src/pypalmsens/_instruments/instrument_pool.py
31
32
33
34
35
36
37
38
39
def __init__(
    self,
    instruments_or_managers: Sequence[Instrument | InstrumentManagerAsync],
):
    self._async: InstrumentPoolAsync = InstrumentPoolAsync(instruments_or_managers)
    self._loop = asyncio.new_event_loop()

    self.managers: list[InstrumentManagerAsync] = self._async.managers
    """List of instruments managers in the pool."""

managers instance-attribute

managers: list[InstrumentManagerAsync] = self._async.managers

List of instruments managers in the pool.

add

Open and add manager to the pool.

Parameters:

Source code in src/pypalmsens/_instruments/instrument_pool.py
 97
 98
 99
100
101
102
103
104
105
def add(self, manager: InstrumentManagerAsync) -> None:
    """Open and add manager to the pool.

    Parameters
    ----------
    manager : InstrumentManagerAsync
        Instance of an instrument manager.
    """
    self._loop.run_until_complete(self._async.add(manager))

connect

connect(attempts: int = 1) -> None

Connect all instrument managers in the pool.

Parameters:

  • attempts

    (int, default: 1 ) –

    Number of attempts to establish connection. Use this if you experience connection issues via USB.

Source code in src/pypalmsens/_instruments/instrument_pool.py
64
65
66
67
68
69
70
71
72
73
def connect(self, attempts: int = 1) -> None:
    """Connect all instrument managers in the pool.

    Parameters
    ----------
    attempts: int, optional
        Number of attempts to establish connection.
        Use this if you experience connection issues via USB.
    """
    self._loop.run_until_complete(self._async.connect(attempts=attempts))

disconnect

disconnect() -> None

Disconnect all instrument managers in the pool.

Source code in src/pypalmsens/_instruments/instrument_pool.py
75
76
77
def disconnect(self) -> None:
    """Disconnect all instrument managers in the pool."""
    self._loop.run_until_complete(self._async.disconnect())

is_connected

is_connected() -> bool

Return true if all managers in the pool are connected.

Source code in src/pypalmsens/_instruments/instrument_pool.py
79
80
81
def is_connected(self) -> bool:
    """Return true if all managers in the pool are connected."""
    return self._async.is_connected()

is_disconnected

is_disconnected() -> bool

Return true if all managers in the pool are disconnected.

Source code in src/pypalmsens/_instruments/instrument_pool.py
83
84
85
def is_disconnected(self) -> bool:
    """Return true if all managers in the pool are disconnected."""
    return self._async.is_disconnected()

measure

measure(method: MethodType, callback: Sequence[Callback | CallbackEIS] | Callback | CallbackEIS | None = None, **kwargs) -> list[Measurement]

Concurrently run measurement on all managers in the pool.

For hardware synchronization, set .general.use_hardware_sync on the method. For MethodSCRIPT, use 'set_channel_sync 1'.

In addition, the pool must contain: - channels from a single multichannel instrument only - the first channel of the multichannel instrument - at least two channels

All instruments are prepared and put in a waiting state. The measurements are started via a hardware sync trigger on channel 1.

Parameters:

  • method

    (MethodType) –

    Method parameters for measurement.

  • callback

    (list[Callback] | Callback | CallbackEIS | None, default: None ) –

    If specified, call these functions/this function on every new set of data points. New data points are batched, and contain all points since the last time it was called.

    Specify a sequence of callbacks to set a different function for every channel. The number of callbacks must match the number of channels.

    Specify a single callback to set the same function to all channels.

  • **kwargs

    These keyword parameters are passed to the measure function.

Source code in src/pypalmsens/_instruments/instrument_pool.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def measure(
    self,
    method: MethodType,
    callback: Sequence[Callback | CallbackEIS] | Callback | CallbackEIS | None = None,
    **kwargs,
) -> list[Measurement]:
    """Concurrently run measurement on all managers in the pool.

    For hardware synchronization, set `.general.use_hardware_sync` on the method.
    For MethodSCRIPT, use 'set_channel_sync 1'.

    In addition, the pool must contain:
    - channels from a single multichannel instrument only
    - the first channel of the multichannel instrument
    - at least two channels

    All instruments are prepared and put in a waiting state.
    The measurements are started via a hardware sync trigger on channel 1.

    Parameters
    ----------
    method : MethodType
        Method parameters for measurement.
    callback : list[Callback] | Callback | CallbackEIS | None
        If specified, call these functions/this function on every new set of data points.
        New data points are batched, and contain all points since the last
        time it was called.

        Specify a sequence of callbacks to set a different function for every channel.
        The number of callbacks must match the number of channels.

        Specify a single callback to set the same function to all channels.
    **kwargs
        These keyword parameters are passed to the measure function.
    """
    return self._loop.run_until_complete(
        self._async.measure(method=method, callback=callback, **kwargs)
    )

remove

Close and remove manager from pool.

Parameters:

Source code in src/pypalmsens/_instruments/instrument_pool.py
87
88
89
90
91
92
93
94
95
def remove(self, manager: InstrumentManagerAsync) -> None:
    """Close and remove manager from pool.

    Parameters
    ----------
    manager : InstrumentManagerAsync
        Instance of an instrument manager.
    """
    self._loop.run_until_complete(self._async.remove(manager))

status

status() -> list[Status]

Return status for all managers in pool.

Returns:

Source code in src/pypalmsens/_instruments/instrument_pool.py
107
108
109
110
111
112
113
114
115
def status(self) -> list[Status]:
    """Return status for all managers in pool.

    Returns
    -------
    list[Status]
        List of status objects.
    """
    return [manager.status() for manager in self]