m3resp.M3Session#

class m3resp.M3Session(eit_adapter=None, emg_adapter=None, metadata=None, allow_overwrite=False, ventilator_adapter=None)[source]#

Recordings, processing results and provenance for a multimodal study session.

Methods

add_events

Store a named event list while keeping session.events as backing data.

align_modalities

Deprecated alias for synchronize_multimodal_breaths - kept for backward compatibility with existing calling code.

compute_breath_timing_parameters

Compute and store breath timing measures from linked_breaths.

detect_eit_breaths

Detect EIT breaths and store them as BreathEvent objects.

detect_emg_breaths

Detect EMG breaths and store normalized events.

detect_ventilator_breaths

Detect ventilator breaths from the volume channel.

emg_moving_baseline

Compute the moving baseline of the EMG envelope (Grasshoff et al. 2021).

emg_slopesum_baseline

Compute the slope-sum baseline of the EMG envelope (ReSurfEMG).

export_summary

Write session tables, JSON summaries and array archives.

get_events

Return a named event list from session.events.

get_ventilator

A loaded ventilator recording by name, or the primary one.

link_breaths

Link breaths across modalities into LinkedBreath objects (Milestone 2.5).

load_eit

Load EIT data and store it under raw["eit"].

load_emg

Load EMG data and store it under raw["emg"].

load_ventilator

Load ventilator data and store it under raw["ventilator"].

postprocess_emg

Run EMG postprocessing through the adapter.

preprocess_eit

Preprocess the loaded EIT recording and store the results.

preprocess_emg

Run EMG preprocessing through the adapter.

preprocess_ventilator

Extract ventilator channels and optionally apply a low-pass filter.

primary_ventilator_name

The name of the recording session.ventilator points at.

run_preset

Run a registered preset on this session.

skip_synchronization

Use the loaded recordings as they are, without synchronizing them.

slice_eit

Keep only the part of the loaded EIT recording between two times.

slice_emg

Keep only the part of the loaded EMG recording between two times.

slice_ventilator

Keep only the part of standalone ventilator recordings between two times.

synchronize_multimodal_breaths

Apply basic Stage 1 alignment to stored breath event lists.

synchronize_raw_modalities

Set when each loaded recording started, on one shared clock.

Parameters:
  • eit_adapter (EITProcessingAdapter | None)

  • emg_adapter (ReSurfEMGAdapter | None)

  • metadata (SessionMetadata | dict[str, Any] | None)

  • allow_overwrite (bool)

  • ventilator_adapter (Any | None)

add_events(name, events)[source]#

Store a named event list while keeping session.events as backing data.

Parameters:
  • name (str) – The name to store the events under, for example "emg_breaths". An existing list with this name is replaced.

  • events (Any) – The events, for example a list of BreathEvent.

Returns:

The stored events.

Return type:

list[Any]

align_modalities(method='manual_offset', offset_seconds=0.0, reference_modality=None)[source]#

Deprecated alias for synchronize_multimodal_breaths - kept for backward compatibility with existing calling code.

Parameters:
  • method (str) – See synchronize_multimodal_breaths.

  • offset_seconds (float | Mapping[str, float]) – See synchronize_multimodal_breaths.

  • reference_modality (str | None) – See synchronize_multimodal_breaths.

Returns:

The shifted breath lists, keyed by list name.

Return type:

dict[str, Any]

compute_breath_timing_parameters(*, delay_pairs=None, duration_pairs=None, anchor='start')[source]#

Compute and store breath timing measures from linked_breaths.

Call link_breaths after aligning the recordings’ time axes. Each successful call replaces all stored multimodal breath-timing results, including those from earlier pairs or anchors, and records provenance. Other parameter results are retained. Empty linked breaths clear the previous timing results and return an empty list.

Parameters:
  • delay_pairs (Sequence[tuple[str, str]] | None) – Ordered pairs (from, to) for delays and event agreement. Positive delays mean the second modality occurs later. None selects every unordered pair of observed modalities in alphabetical order; [] selects none.

  • duration_pairs (Sequence[tuple[str, str]] | None) – Ordered pairs (a, b) for duration(a) minus duration(b). None uses every observed pair in alphabetical order; [] selects none.

  • anchor (str) – Breath point for delays: “start” (default), “extremum”, or “end”.

Returns:

Stored results: per-breath delays and duration

differences in seconds, and aggregate agreement fractions per delay pair. Agreement counts links holding either modality and measures the fraction holding both. Per-breath results require both breaths; delays also require both selected anchors.

Return type:

list[ParameterResult]

Raises:

ValueError – If the anchor name is invalid, including for empty inputs. Existing parameter results are retained when validation fails.

detect_eit_breaths(*, variant=None, **kwargs)[source]#

Detect EIT breaths and store them as BreathEvent objects.

Breaths matching an existing per-breath EIT result by modality and exact start and end time reuse that result’s breath object, including its identifier. Detection is recorded in the session’s history.

Parameters:
  • variant (str | None) – Detect breaths in the preprocess_eit(..., variant=<name>) result. Events are stored under session.events['eit_breaths:<name>']. None uses the default processed result, falling back to the raw recording, and stores events under 'eit_breaths'.

  • **kwargs (Any) – Passed on to EITProcessingAdapter.detect_breaths. detector= replaces the detection with a function of your own.

Returns:

Detected breaths in detector order, also stored

in session.events. Times use the input recording’s clock.

Return type:

list[BreathEvent]

Raises:

MissingModalityDataError – If the named preprocessing variant is unavailable, or default processed EIT data and a raw recording are both unavailable.

detect_emg_breaths(*, variant=None, **kwargs)[source]#

Detect EMG breaths and store normalized events.

Parameters:
  • variant (str | None) – Detect breaths in the preprocess_emg result with this name, stored under session.events[“emg_breaths:<name>”]. See detect_eit_breaths.

  • **kwargs (Any) – Passed on to ReSurfEMGAdapter.detect_breaths (for example baseline=). detector= replaces the detection with a function of your own.

Returns:

The detected breaths, a list of BreathEvent.

Return type:

Any

detect_ventilator_breaths(*, variant=None, **kwargs)[source]#

Detect ventilator breaths from the volume channel.

This promotes what used to be a side effect of postprocess_emg into a method of its own, so ventilator breaths can be detected without running EMG postprocessing first. postprocess_emg still populates session.events[“ventilator_breaths”] as before.

Parameters:
  • variant (str | None) – Detect breaths in the preprocess_ventilator result with this name, stored under session.events[“ventilator_breaths:<name>”]. See detect_eit_breaths. When None and the ventilator has not been preprocessed, it is preprocessed here with the default settings.

  • **kwargs (Any) – Passed on to VentilatorAdapter.detect_breaths (for example breath_width_seconds). detector= replaces the detection with a function of your own.

Returns:

The detected breaths, a list of BreathEvent.

Return type:

Any

emg_moving_baseline(*, window_seconds=7.5, step_seconds=0.2, percentile=33.0, variant=None)[source]#

Compute the moving baseline of the EMG envelope (Grasshoff et al. 2021).

The baseline is the quiet level of the envelope: a percentile of the envelope in a moving window. Breath detection measures its threshold above this level, so compute it before detect_emg_breaths and pass it on, with the same variant:

baseline = session.emg_moving_baseline()
session.detect_emg_breaths(baseline=baseline)

The baseline is added to session.signals as <channel>_moving_baseline (<channel>_moving_baseline:<variant> for a variant), replacing the one from an earlier call, and the call is recorded in session.provenance.

Parameters:
  • window_seconds (float) – Window length in seconds.

  • step_seconds (float) – Time between baseline updates, in seconds.

  • percentile (float) – Percentile of the envelope in each window, 0 to 100.

  • variant (str | None) – Use the preprocess_emg result with this name; None uses the current processed EMG.

Returns:

One baseline value per envelope sample, in the

units of the envelope.

Return type:

numpy.ndarray

Raises:
  • MissingModalityDataError – If there is no processed EMG (or no such variant).

  • ValueError – If the processed EMG has no envelope, or a setting is out of range.

emg_slopesum_baseline(*, window_seconds=7.5, step_seconds=0.2, percentile=33.0, augmented_percentile=25.0, moving_average_seconds=0.5, percentile_window_seconds=1.0, variant=None)[source]#

Compute the slope-sum baseline of the EMG envelope (ReSurfEMG).

The slope-sum baseline is the quiet level of the envelope with its slope added: in each window it is 1.2 times a percentile of the envelope plus its absolute, smoothed slope. The calculation is the same as in the emg.slopesum_baseline step. Breath detection measures its threshold above this level, so pass it on, with the same variant:

baseline = session.emg_slopesum_baseline()
session.detect_emg_breaths(baseline=baseline)

Three signals are added to session.signals: <channel>_slopesum_baseline, and the running mean and running standard deviation of the moving baseline, <channel>_slopesum_baseline_running_mean and ..._running_std (each with :<variant> at the end for a variant). They replace the ones from an earlier call. The call is recorded in session.provenance.

Parameters:
  • window_seconds (float) – Window length in seconds.

  • step_seconds (float) – Time between updates of the moving baseline, in seconds.

  • percentile (float) – Percentile of the envelope in each window for the moving baseline, 0 to 100.

  • augmented_percentile (float) – Percentile of the envelope plus its slope in each window, 0 to 100.

  • moving_average_seconds (float) – Smoothing window of the envelope slope, in seconds.

  • percentile_window_seconds (float) – Time between updates of the slope-sum baseline, in seconds.

  • variant (str | None) – Use the preprocess_emg result with this name; None uses the current processed EMG.

Returns:

One baseline value per envelope sample, in the

units of the envelope.

Return type:

numpy.ndarray

Raises:
  • MissingModalityDataError – If there is no processed EMG (or no such variant).

  • ValueError – If the processed EMG has no envelope, or a setting is out of range.

export_summary(output_dir, *, processing_run_id=None)[source]#

Write session tables, JSON summaries and array archives.

Creates the destination directory and records the export in the session’s provenance after writing. See export_session_summary for file contents.

Parameters:
  • output_dir (str | Path) – Destination folder; existing export files are replaced.

  • processing_run_id (str | None) – Optional ProcessingRun identifier, typically from WorkflowResult.processing_run_id. When a data-model recorder is attached, links written array archives to that run.

Returns:

Directory containing the exported files.

Return type:

Path

Raises:

OSError – If the directory or an export file cannot be written.

get_events(name, default=None)[source]#

Return a named event list from session.events.

Parameters:
  • name (str) – The name the events were stored under, for example "emg_breaths".

  • default (Any) – What to return when no events have this name.

Returns:

The stored events, or default.

Return type:

Any

get_ventilator(name=None)[source]#

A loaded ventilator recording by name, or the primary one.

Parameters:

name (str | None) – The name the recording was loaded under (see load_ventilator). None gives the primary recording.

Returns:

The loaded recording.

Return type:

VentilatorRecording

Link breaths across modalities into LinkedBreath objects (Milestone 2.5).

Prefers the aligned breath lists produced by synchronize_multimodal_breaths (self.processed["synchronized"]) over the per-modality event lists in self.events. A list that was not aligned there is moved onto the shared clock here, using the start times from synchronize_raw_modalities, so breaths are always matched on one time axis.

Warns (UnsynchronizedDataWarning) when the breaths come from recordings on different clocks and one of them was never synchronized; see skip_synchronization.

Parameters:

time_tolerance (float) – Largest time difference, in seconds, at which two breaths from different modalities are still linked. The closest match wins; a breath with no match gets a LinkedBreath of its own.

Returns:

The linked breaths. Also stored in

session.linked_breaths.

Return type:

list[LinkedBreath]

load_eit(path, vendor=None, *, loader='auto', **kwargs)[source]#

Load EIT data and store it under raw[“eit”].

A newly loaded recording has not been synchronized yet: any EIT start time and synchronization record from before are cleared.

Parameters:
  • path (str | Path | list) – The EIT file to read, or a list of files recorded one after the other, read as one recording. The files are joined in the given order; a pause between two files stays in the time axis and gives a warning. With eitprocessing, first_frame/max_frames cannot be used with several files.

  • vendor (str | None) – The EIT device maker, passed to eitprocessing (for example "draeger").

  • loader (str) – "eitprocessing" reads a Draeger, Sentec or Timpel file and needs vendor; "custom" uses the loader given to session.eit_adapter (EITProcessingAdapter( loader=...)); "auto" uses that custom loader when there is one, else eitprocessing.

  • **kwargs (Any) – Passed on to the EIT file reader.

Returns:

The loaded eitprocessing Sequence (session.eit.data).

Return type:

Any

load_emg(path, **kwargs)[source]#

Load EMG data and store it under raw[“emg”].

A newly loaded recording has not been synchronized yet: any EMG start time and synchronization record from before are cleared.

Parameters:
  • path (str | Path) – The EMG file to read.

  • **kwargs (Any) – Passed on to the EMG file reader.

Returns:

The loaded EMG data (session.emg.data), a dictionary with

the samples under "array" and the file details under "metadata".

Return type:

Any

load_ventilator(path, *, name=None, **kwargs)[source]#

Load ventilator data and store it under raw[“ventilator”].

Mirrors load_eit/load_emg. The recording is additionally stored under the legacy raw[“vent”] key, pointing at the same object.

A newly loaded standalone recording has not been synchronized yet: its own start time and synchronization record from before are cleared. Ventilator data from the EIT or EMG file follows that file’s clock.

Parameters:
  • path (str | Path) – The file the ventilator data arrives in: the multi-channel export shared with the sEMG, or an EIT *.bin carrying ventilator waveforms beside its impedance frames. VentilatorAdapter picks by file suffix.

  • name (str | None) – Files this recording alongside any already loaded, for a study where more than one instrument recorded ventilator data - a ventilator export and the EIT file’s own Medibus channels, say, each with its own airway pressure. Without a name the recording is the primary one, which is what session.ventilator and raw[“ventilator”] point at. Preprocess a named recording with preprocess_ventilator(name=…), which qualifies its channel keys so the two airway pressures stay distinct in session.signals.

  • **kwargs (Any) – Passed on to the ventilator file reader. Use source="eit"/"emg"/"ventilator" to choose the file type, and ventilator_channels= to select which channels to read from a *.bin (see m3resp.adapters.ventilator_adapter).

Returns:

The loaded ventilator data (VentilatorRecording.data), a

dictionary with the samples under "array" and the file details under "metadata".

Return type:

Any

postprocess_emg(**kwargs)[source]#

Run EMG postprocessing through the adapter.

Uses the default EMG preprocessing result and the breaths in session.events[“emg_breaths”]. Any ventilator breaths found during postprocessing are stored in session.events[“ventilator_breaths”].

Parameters:

**kwargs (Any) – Passed on to ReSurfEMGAdapter.postprocess, for example ventilator, ventilator_fs (Hz) and ventilator_breath_width_seconds.

Returns:

The postprocessing result, a dictionary with the values

computed ("computed"), those skipped ("skipped") and the settings used ("settings"). Also stored in session.parameters[“emg_postprocessing”].

Return type:

Any

preprocess_eit(*, variant=None, overwrite=False, **kwargs)[source]#

Preprocess the loaded EIT recording and store the results.

Results are stored in session.processed_variants['eit'] under the variant name, or 'default' when omitted. The default result is also stored in session.processed['eit']. Upstream preprocessing adds signals, rate parameters, values per breath and quality flags to the session’s collections. Per-breath results reuse breaths stored under the matching variant’s event key.

Parameters:
  • variant (str | None) – Name to store this result under. None stores it as "default".

  • overwrite (bool) – Replace a result already stored under the same name. session.allow_overwrite also permits replacement.

  • **kwargs (Any) – Passed on to EITProcessingAdapter.preprocess (for example filter_mode). preprocess= replaces the whole step with a function of your own; its output is stored directly in the processed-result dictionaries.

Returns:

The preprocessing result, also stored in

session.processed_variants[“eit”].

Return type:

Any

Raises:
  • MissingModalityDataError – If an EIT recording has yet to be loaded.

  • VariantAlreadyExistsError – If the variant already exists and replacement is disabled.

preprocess_emg(*, variant=None, overwrite=False, **kwargs)[source]#

Run EMG preprocessing through the adapter.

See preprocess_eit for what variant/overwrite/allow_overwrite do - it persists this result under session.processed_variants[“emg”][name], raising VariantAlreadyExistsError if name is already populated, and mirrors it onto session.processed[“emg”] only when name is “default”.

Parameters:
  • variant (str | None) – Name to store this result under. None stores it as "default".

  • overwrite (bool) – Replace a result already stored under the same name.

  • **kwargs (Any) – Passed on to ReSurfEMGAdapter.preprocess. preprocess= replaces the whole step with a function of your own.

Returns:

The preprocessing result. The default step gives a

dictionary that includes the "filtered" and "envelope" signals, the "channel" used and the sampling rate "fs" in Hz.

Return type:

Any

preprocess_ventilator(*, name=None, variant=None, overwrite=False, **kwargs)[source]#

Extract ventilator channels and optionally apply a low-pass filter.

Stores the result in processed_variants[“ventilator”], adds signals, parameters and quality flags from the adapter, and records provenance. Updates the recording’s airway_pressure, flow, volume and fs fields. The default and primary-recording variants also update processed[“ventilator”].

Parameters:
  • name (str | None) – Loaded recording to preprocess. None selects the primary recording. Other recordings get channel keys ending in their name, such as “airway_pressure__pod”.

  • variant (str | None) – Name for the stored result. Defaults to the recording name supplied in name, or “default” when name is None.

  • overwrite (bool) – Allow replacement of an existing variant. The session’s allow_overwrite setting also allows replacement.

  • **kwargs (Any) – Options for VentilatorAdapter.preprocess, including channels, explicit channel indices, fs in Hz, lowpass_hz in Hz, and filter_order. The default selection is airway_pressure, flow and volume. With lowpass_hz=None, values retain their recorded units and are copied into the channel arrays. preprocess may supply a custom function.

Returns:

Adapter result. The default result contains channel arrays,

raw and filtered channel mappings, per-channel units, and fs in Hz. Filtering is applied when lowpass_hz is supplied.

Return type:

Any

Raises:
  • MissingModalityDataError – If the selected recording is unavailable.

  • VariantAlreadyExistsError – If the variant exists and overwriting is disabled.

  • UnresolvedChannelError – If a requested channel cannot be found.

primary_ventilator_name()[source]#

The name of the recording session.ventilator points at.

Returns:

The name, or None when no ventilator recording is

loaded.

Return type:

str | None

run_preset(name, *, config=None)[source]#

Run a registered preset on this session.

The built-in presets are eit, emg and multimodal. Each runs a fixed sequence of session methods or registered steps using the supplied settings. Load the required recordings first; the multimodal preset uses previously detected breaths to store aligned events.

Parameters:
  • name (str) – Registered preset name.

  • config (Mapping[str, Mapping[str, Any]] | None) – Keyword arguments grouped by the preset’s configuration keys, e.g. {"preprocess": {"high_pass_hz": 20.0}} for emg. None uses the preset’s defaults. See m3resp.presets for the supported groups.

Returns:

This session with results and provenance added by the preset’s

operations. Changes made before an operation fails remain available.

Return type:

M3Session

Raises:
  • UnknownPresetError – If name is unregistered.

  • MissingModalityDataError – If an operation needs an unavailable recording.

skip_synchronization()[source]#

Use the loaded recordings as they are, without synchronizing them.

For recordings that really did start at the same moment - for example when one trigger started every device. Each loaded recording that has not been synchronized is recorded as "none" in session.sync_methods, so steps that compare recordings skip their missing-synchronization warning, while the choice stays visible in the provenance log and the exported summary. Recordings already synchronized keep their record. Breath lists added directly with add_events, without a loaded recording, are covered too. Recordings loaded later are not.

Returns:

The recordings marked "none".

Return type:

list[str]

slice_eit(start_seconds, end_seconds=None)[source]#

Keep only the part of the loaded EIT recording between two times.

Times are in seconds from the first frame of the recording as it is now (after any earlier slicing), not the time of day stored in the file. end_seconds=None keeps everything up to the end. The kept part runs from the first frame at or after start_seconds up to, but not including, the first frame at or after end_seconds.

The cutting itself is done by eitprocessing (EITProcessingAdapter.slice_sequence): pixel data, global impedance, the pressure/flow channels and the vendor’s markers are all cut to the same frames. A ventilator recording loaded from the same EIT file is cut at exactly those frames too, so it stays lined up with the EIT. EIT frame times keep their original values; the EIT start time in session.start_times moves later by the part cut off the front, so the EIT stays lined up with the other recordings.

Run this before preprocess_eit. The removed frames are gone from the loaded recording; reload the file to get them back.

Parameters:
  • start_seconds (float) – Start of the part to keep, in seconds.

  • end_seconds (float | None) – End of the part to keep, in seconds. None keeps everything up to the end.

Returns:

The times used, the number of frames removed from

the start and the end and kept, and how many ventilator recordings were cut with the EIT. Also stored in session.parameters[“eit_slice”].

Return type:

dict[str, Any]

slice_emg(start_seconds, end_seconds=None)[source]#

Keep only the part of the loaded EMG recording between two times.

Times are in seconds from the start of the recording as it is now (after any earlier slicing). end_seconds=None keeps everything up to the end. Ventilator channels recorded in the same file (for example airway pressure on a Biopac export) are cut the same way, so they stay lined up with the EMG. After slicing, EMG times count from the new start, and the EMG start time in session.start_times moves later by start_seconds, so the EMG stays lined up with the other modalities.

Run this before preprocess_emg. The removed samples are gone from the loaded recording; reload the file to get them back.

Parameters:
  • start_seconds (float) – Start of the part to keep, in seconds.

  • end_seconds (float | None) – End of the part to keep, in seconds. None keeps everything up to the end.

Returns:

The times used and the number of samples removed

from the start and the end and kept. Also stored in session.parameters[“emg_slice”].

Return type:

dict[str, Any]

slice_ventilator(start_seconds, end_seconds=None, *, name=None)[source]#

Keep only the part of standalone ventilator recordings between two times.

“Standalone” means a ventilator or monitor export with a clock of its own, loaded with load_ventilator(path, source="ventilator"). Ventilator data that came inside the EIT or EMG file is on that file’s clock and is cut with it by slice_eit or slice_emg; asking to cut it here raises an error, since cutting it alone would move it out of line with its host recording.

Times are in seconds from the start of the recording as it is now (after any earlier slicing). end_seconds=None keeps everything up to the end. After slicing, the recording’s times count from the new start, and its start time moves later by start_seconds: it is stored under its own "ventilator:<name>" entry in session.start_times, so the recording stays lined up with the other modalities and no other recording moves.

Run this before preprocess_ventilator. The removed samples are gone from the loaded recording; reload the file to get them back.

Parameters:
  • start_seconds (float) – Start of the part to keep, in seconds.

  • end_seconds (float | None) – End of the part to keep, in seconds. None keeps everything up to the end.

  • name (str | None) – Cut only the recording loaded under this name. None cuts every standalone ventilator recording.

Returns:

The times used and, under "recordings", the

number of samples removed from the start and the end and kept for each recording that was cut. Also stored in session.parameters[“ventilator_slice”].

Return type:

dict[str, Any]

synchronize_multimodal_breaths(method='manual_offset', offset_seconds=0.0, reference_modality=None)[source]#

Apply basic Stage 1 alignment to stored breath event lists.

Named to mirror synchronize_raw_modalities: that one shifts raw signals in time before processing, this one shifts already-detected breath events (ALIGNMENT_EVENT_LISTS) in time after detection. Previously named align_modalities, kept below as an alias.

Offsets are resolved relative to reference_modality (or the auto-detected one - see m3resp.synchronization.alignment.breath_reference_modality) before being applied, so the reference modality’s own events are shifted by zero and every other modality moves by its offset relative to the reference, matching synchronize_raw_modalities. self.parameters[“alignment”] keeps both: offset_seconds (relative, what was actually applied) and configured_offset_seconds (the raw per-modality values passed in).

The start times set by synchronize_raw_modalities are added on top, so the shifted breaths are on the shared clock. The two add up: offset_seconds is only for a further correction after detection. start_time_shift_seconds records what was added for each modality.

Parameters:
  • method (str) – How the breaths are shifted. Only "manual_offset" is supported.

  • offset_seconds (float | Mapping[str, float]) – Extra shift of each modality’s breaths in seconds, on top of the start times, for example {"emg": 0.2}. A single number is the EMG shift.

  • reference_modality (str | None) – The modality whose breaths are not shifted by an extra offset. When None: the ventilator if there are ventilator breaths, otherwise EIT.

Returns:

The shifted breath lists, keyed by list name (for

example "emg_breaths"). Also stored in session.processed[“synchronized”].

Return type:

dict[str, Any]

synchronize_raw_modalities(method='manual_offset', offset_seconds=0.0, reference_modality=None)[source]#

Set when each loaded recording started, on one shared clock.

No samples are removed: every recording keeps its full length. The start times are stored in session.start_times and are added to breath times only when modalities are compared (synchronize_multimodal_breaths, link_breaths), so each modality’s own results stay on its own clock. Calling this again replaces the start times rather than adding to them. See m3resp.synchronization.start_times.

Parameters:
  • method (str) – How the start times are found. Only "manual_offset" is supported.

  • offset_seconds (float | Mapping[str, float]) – Start time of each modality in seconds, for example {"emg": 5.0} for “EMG started 5 s after EIT”, or {"emg": -5.0} for “EMG started 5 s before EIT”. A single number is the EMG start time. "ventilator" is the start time of the standalone ventilator recordings (those loaded with source="ventilator"). When two of them started at different moments, give one its own start time with "ventilator:<name>", the name it was loaded under, e.g. {"ventilator": 0.0, "ventilator:monitor": 12.5}. Ventilator data that came inside the EIT or EMG file always uses that file’s start time.

  • reference_modality (str | None) – The recording that start times are counted from, so its own start time is always 0. A modality name or "ventilator:<name>". When None: the ventilator if one is loaded, otherwise EIT, otherwise EMG.

Returns:

{modality: {"start_time_seconds": ...}} for

every loaded modality, plus a "ventilator:<name>" entry for each standalone ventilator recording given its own start time.

Return type:

dict[str, Any]

Tutorials that use M3Session#

Process an EIT recording

Process an EIT recording

Process an EMG recording

Process an EMG recording