medusa package

Subpackages

Submodules

medusa.artifact_removal module

class medusa.artifact_removal.ArtifactRegression[source]

Bases: ProcessingMethod

__init__()[source]

Initialize the artifact regression method.

This class implements a method to remove artifacts (e.g., EOG signals) from time series data (e.g., EEG signals). The artifacts must be recorded simultaneously with the signal, and this method attempts to regress out the artifacts from the main signal.

Attributes: - self.coefs: Stores the regression coefficients after fitting the

model.

Notes: The input signals (sig and art_sig) must be preprocessed (e.g., band-pass filtering) before using them in this class for better performance and accuracy.

Alternative implementation: self.coefs = np.linalg.lstsq(

art_sig.T @ art_sig, art_sig.T, rcond=None)[0] @ sig

sig = (sig.T - self.coefs.T @ art_sig.T).T

fit(sig, art_sig)[source]

Fits the artifact regression model by computing regression coefficients for removing the artifacts from the signal.

This method performs a linear regression for each signal channel to estimate how much of the artifact is present in each channel. The regression coefficients (self.coefs) are computed using the least squares solution for each channel.

Steps 1. Remove the mean from the artifact signal for normalization. 2. Compute the covariance matrix of the artifact signal. 3. For each signal channel:

  • Remove the mean from the signal.

  • Perform a least squares fit to estimate the regression

    coefficients.

Parameters
  • sig (The main signal (e.g., EEG) that contains the artifacts.) –

  • art_sig (The artifact signal (e.g., EOG) recorded alongside the main) – signal.

fit_transform(sig, art_sig)[source]

Combines the fit and transform steps into a single method.

Parameters: - sig: The main signal to clean. - art_sig: The artifact signal to regress out.

This method first fits the regression model to estimate the coefficients, then applies those coefficients to remove the artifacts from the signal.

Returns: - The cleaned signal with the artifacts removed.

transform(sig, art_sig)[source]

Removes the artifacts from the signal using the previously computed coefficients.

This method applies the regression coefficients (self.coefs) to remove the artifacts from each channel of the signal. It subtracts the artifact contribution from each signal channel.

Steps: 1. Mean-center the artifact signal. 2. For each signal channel:

  • Subtract the estimated artifact component using the regression

    coefficients.

  • sig: The main signal (e.g., EEG) to clean.

  • art_sig: The artifact signal (e.g., EOG) to regress out.

class medusa.artifact_removal.ICA[source]

Bases: object

__init__(random_state=None)[source]
fit(signal, l_cha, fs, n_components)[source]
get_components()[source]
get_sources(signal)[source]
load(path)[source]
plot_components(cmap='bwr')[source]
plot_sources(signal, sources_to_show=None, time_to_show=None, ch_offset=None)[source]
plot_summary(signal, component, psd_freq_range=[1, 70], psd_window='hamming', time_to_show=2, cmap='bwr')[source]
rebuild(signal, exclude=None)[source]
save(path)[source]
show_exclusion(signal, exclude=None, ch_to_show=None, time_to_show=None, ch_offset=None)[source]
class medusa.artifact_removal.ICAData[source]

Bases: SerializableComponent

__init__(pre_whitener=None, unmixing_matrix=None, mixing_matrix=None, n_components=None, pca_components=None, pca_mean=None, components_excluded=None, random_state=None)[source]
classmethod from_serializable_obj(dict_data)[source]

This function must return an instance of the class from a serializable (list or dict of primitive types)

to_serializable_obj()[source]

This function must return a serializable object (list or dict of primitive types) containing the relevant attributes of the class

medusa.artifact_removal.reject_noisy_epochs(epochs, signal_mean, signal_std, k=4, n_samp=2, n_cha=1)[source]

Simple thresholding method to reject noisy epochs. It discards epochs with n_samp samples greater than k*std in n_cha channels

Parameters

epochs (list or numpy.ndarray) – Epochs of signal with dimensions [n_epochs x samples x channels]

signal_meanfloat

Mean of the signal

signal_stdfloat

Standard deviation of the signal

kfloat

Standard deviation multiplier to calculate threshold

n_sampint

Minimum number of samples that have to be over the threshold in each epoch to be discarded

n_chaint

Minimum number of channels that have to have n_samples over the threshold in each epoch to be discarded

Returns

Percentage of reject epochs in

Return type

float

numpy.ndarray

Clean epochs

numpy.ndarray

Indexes for rejected epochs. True for discarded epoch

medusa.classification_utils module

class medusa.classification_utils.EarlyStopping[source]

Bases: object

Implements early stopping to terminate training when a monitored metric stops improving.

Parameters
  • mode ({'min', 'max'}, optional) – Determines whether the monitored metric should be minimized or maximized. - ‘min’ (default): Training stops when the metric does not decrease. - ‘max’: Training stops when the metric does not increase.

  • min_delta (float, optional) – The minimum change in the monitored metric to qualify as an improvement. Defaults to 0.001.

  • patience (int, optional) – Number of epochs to wait after the last improvement before stopping training. Defaults to 20.

  • verbose (bool, optional) – If True, prints messages when the best metric is updated or when patience runs out. Defaults to True.

__init__(mode='min', min_delta=0.001, patience=20, verbose=True)[source]
check_epoch(n_epoch, epoch_loss, epoch_params=None)[source]

Checks whether training should stop based on the given epoch’s loss.

Parameters
  • n_epoch (int) – The current epoch number.

  • epoch_loss (float) – The loss value for the current epoch.

  • epoch_params (dict, optional) – The parameters at the current epoch (e.g., model state dictionary).

Returns

  • bool – True if training should stop, False otherwise.

  • dict or None – The best parameters recorded during training, or None if no improvement was found.

medusa.classification_utils.categorical_labels(one_hot_labels)[source]
medusa.classification_utils.k_fold_split(x, y, k, keys=None, shuffle=False)[source]

Special implementation of k fold splitting that allows to split the dataset into k folds for cross validation in function of keys array.

It returns a list with the dataset for each iteration (k iterations).

Parameters
  • x (numpy array or list) – Training set data. Axis 0 represents each observation. Features could have one or more dimensions. For instance, [observations x eeg samples], [observations x eeg samples x channels]

  • y (numpy array or list) – Training set labels.

  • k (int) – Number of folds to split the dataset

  • keys (numpy array or list) – Keys to split the dataset. If None, the dataset is splitted considering each observation independently. If not None, each position of keys array identifies the set that owns the observation. For instance, This is useful to split the dataset by subjects or trials.

  • shuffle (boolean) – True if you want to shuffle the dataset randomly.

Returns

sets – List that contains a dict with the train and test set for each iteration of the k-fold algorithm.

Return type

list

Examples

>>> k_fold_iter = k_fold_split(x, y, k)
>>> k_fold_acc = 0
>>> for iter in k_fold_iter:
>>>     model.fit(iter["x_train"], iter["y_train"])
>>>     y_test_pred = model.predict(iter["x_test"], iter["y_test"])
>>>     k_fold_acc += np.sum(y_test_pred == iter["y_test"])/len(iter["y_test"])
>>> k_fold_acc = k_fold_acc/len(k_fold_iter)
medusa.classification_utils.one_hot_labels(categorical_labels)[source]

medusa.components module

class medusa.components.Algorithm[source]

Bases: ProcessingMethod

Algorithm class is the main tool within medusa to implement standalone processing algorithms that can be shared as a simple file, supporting third-party libraries, such as sklearn. It allows persistence to save the algorithm and its state or use it later using dill package. Take into account that the algorithm needs access to the original classes and methods in order to be reconstructed.

Check this tutorial to better understand the usage of this class.

__init__(**kwargs)[source]

ProcessingMethod constructor

Parameters

kwargs – Key-value arguments that define the exposed methods and output signature. This is used by class Algorithm for a correct implementation of signal processing pipelines.

add_method(method_key, method_instance)[source]
add_pipeline(pipeline_key, pipeline_instance)[source]
exec_pipeline(pipeline_key, **kwargs)[source]

Execute pipeline

classmethod from_pickleable_obj(alg)[source]

Returns the instance of the unpickled version of the pickleable representation given by function to_pickleable_representation. Therefore, this parameter is, by default, an instance of the class and no additional treatment is required. In some cases (i.e., keras models), the pickleable_representation may not be the instance, but some other pickleable format with the required information of the method to reinstantiate the instance itself (i.e., weights for keras models). In such cases, this function must be overriden

Parameters

pickleable_obj (object) – Pickleable representation of the processing method instance.

Returns

instance – Instance of the processing method

Return type

ProcessingMethod

get_inst(method_key)[source]

Returns the instance of a method given the key

to_pickleable_obj()[source]

Returns a pickleable representation of the class. In most cases, the instance of the class is directly pickleable (e.g., all medusa methods, sklearn classifiers), but this may not be the case for some methods (i.e., keras models). Therefore, this function must be overridden in such cases.

Returns

representation – Pickleable representation of the instance.name

Return type

object

class medusa.components.BiosignalData[source]

Bases: SerializableComponent

Skeleton class for biosignals

abstract classmethod from_serializable_obj(dict_data)[source]

This function must return an instance of the class from a serializable dict (primitive types)

abstract to_serializable_obj()[source]

This function must return a serializable dict (primitive types) containing the relevant attributes of the class

class medusa.components.CheckTreeStructure[source]

Bases: object

CheckTreeStructure is a helper class that provides validation methods for ensuring the structure and data of items in a TreeDict are correct.

validate_default_value(default_value)[source]
validate_info(info)[source]
validate_input_format(input_format, default_value=None, value_options=None)[source]
validate_value_options(value_options)[source]
validate_value_range(value_range)[source]
class medusa.components.ConsistencyChecker[source]

Bases: SerializableComponent

Class that provides functionality to check consistency across recordings to build a dataset

__init__()[source]
add_consistency_rule(rule, rule_params, parent=None)[source]

Adds a consistency check for the specified attribute It provides 2 levels of consistency using parameter key, enough to check attributes inside biosignal or experiments classes

Parameters
  • rule (str {'check-attribute-type'|'check-attribute-value'|) –

    ‘check-values-in-attribute’|’check-if-attribute-exists’| ‘check-if-type-exists’}

    Check mode of this attribute. Modes:
    • check-attribute-type: checks if the attribute has the type

      specified in parameter check_value.

    • check-attribute-value: checks if the attribute has the

      value specified in parameter check_value

    • check-values-in-attribute: checks if the attribute

      contains the values (the attribute must support in operation). It can check keys in dicts or values in lists or sets.

    • check-attribute: checks if the attribute exists

    • check-type: checks if the class contains attributes with

      the specified type. Use operator to define establish rules about the number of attributes allowed with the specified type

  • rule_params (dict) –

    Specifies the rule params. Depending on the rule, it must contain the following key-value pairs:

    • check-attribute-type: {attribute: str, type: class or list}.

      If type is list, it will be checked that the attribute is of one of the types defined in the list

    • check-attribute-value: {attribute: str, value: obj}

    • check-values-in-attribute: {attribute: str, values: list}

    • check-attribute: {attribute: str}

    • check-type: {type: class, limit: int, operator: str {‘<’|’>’|’

      <=’|’>=’|’==’|’!=’}

  • parent (str or None) – Checks the rule inside specified parent. If None, the parent is the recording itself. Therefore, the parent must be a class. This parameter designed to allow check rules inside biosignals or experiments class. If the parent is in deeper levels, use points to define the parent. For example, you can check the labels of the channels in an EEG recording setting this parameter as eeg.channel_set

check_consistency(recording)[source]

Checks the consistency of a recording according to the current rules

Parameters

recording (Recording) – Recording to be checked

classmethod from_serializable_obj(dict_data)[source]

This function must return an instance of the class from a serializable (list or dict of primitive types)

to_serializable_obj()[source]

This function must return a serializable object (list or dict of primitive types) containing the relevant attributes of the class

class medusa.components.CustomBiosignalData[source]

Bases: BiosignalData

Custom biosignal data class. This class does not check the arguments and provides less functionality that more specific classes. It should only be used for custom signals that do not fit in other data classes

__init__(**kwargs)[source]

CustomBiosginal constructor

Parameters

kwargs (kwargs) – Key-value arguments to be saved in the class. This general class does not check anything

classmethod from_serializable_obj(dict_data)[source]

This function must return an instance of the class from a serializable dict (primitive types)

to_serializable_obj()[source]

This function must return a serializable dict (primitive types) containing the relevant attributes of the class

class medusa.components.CustomExperimentData[source]

Bases: ExperimentData

Custom experiment data class. This class does not check the arguments and provides less functionality that a proper experiment class. It should only be used for custom experiments that do not fit in other experiment data classes

__init__(**kwargs)[source]

CustomExperimentData constructor

Parameters

kwargs (kwargs) – Key-value arguments to be saved in the class. This general class does not check anything

classmethod from_serializable_obj(dict_data)[source]

This function must return an instance of the class from a serializable dict (primitive types)

to_serializable_obj()[source]

This function must return a serializable dict (primitive types) containing the relevant attributes of the class

class medusa.components.Dataset[source]

Bases: ABC

Class to handle multiple recordings maintaining consistency

__init__(consistency_checker=None)[source]

Class constructor

Parameters

consistency_checker (ConsistencyChecker) – Consistency checker for this dataset.

add_recordings(recordings)[source]

Adds one or more recordings to the dataset, checking the consistency

Parameters

recordings (list or medusa.data_structures.Recording) – List containing the paths to recording files or instances of Recording class

custom_operations_on_recordings(recording)[source]

Function add_recordings calls this function before adding each recording to the dataset. Implement this method in custom classes to have personalized behaviour (e.g., change the channel set)

Parameters

recording (subclass of Recording) – Recording that will be changed. It can also be a subclass of Recording

Returns

recording – Modified recording

Return type

Recording

class medusa.components.ExperimentData[source]

Bases: SerializableComponent

Skeleton class for experiment data

abstract classmethod from_serializable_obj(dict_data)[source]

This function must return an instance of the class from a serializable dict (primitive types)

abstract to_serializable_obj()[source]

This function must return a serializable dict (primitive types) containing the relevant attributes of the class

class medusa.components.PickleableComponent[source]

Bases: ABC

Skeleton class for pickleable components. These components must implement functions to transform the class to a pickleable object using dill package. It must be used in classes that need persistence but only make sense in Python and thus, they do not require multiplatform compatibility (i.e., signal processing methods)

abstract classmethod from_pickleable_obj(pickleable_obj)[source]

Returns the instance of the unpickled version of the pickleable representation given by function to_pickleable_representation. Therefore, this parameter is, by default, an instance of the class and no additional treatment is required. In some cases (i.e., keras models), the pickleable_representation may not be the instance, but some other pickleable format with the required information of the method to reinstantiate the instance itself (i.e., weights for keras models). In such cases, this function must be overriden

Parameters

pickleable_obj (object) – Pickleable representation of the processing method instance.

Returns

instance – Instance of the component

Return type

PickleableComponent

classmethod load(path)[source]
save(path, protocol=0)[source]

Saves the class using dill into pickle format

abstract to_pickleable_obj()[source]

Returns a pickleable representation of the class. In most cases, the instance of the class is directly pickleable (e.g., all medusa methods, sklearn classifiers), but this may not be the case for some methods (i.e., keras models). Therefore, this function must be overridden in such cases.

Returns

representation – Pickleable representation of the instance.name

Return type

object

class medusa.components.Pipeline[source]

Bases: object

Pipeline that defines the tasks and connections between methods of a signal processing task. This class does not check if the connections are valid. This is done by Algorithm class, which compiles the connections with the available methods

Check this tutorial to better understand the usage of this class.

__init__()[source]

Pipeline constructor

add(method_func_key, **kwargs)[source]

Adds a method to the pipeline

Parameters
  • method_func_key (str) – Method identifier and function to be executed, separated by semicolon. Example: fir_filter:fit

  • kwargs – Key-value arguments defining the input arguments of the methods. The key specifies the input argument. The value can be a static value (i.e., int, float, object instance) or a connection to the output of another stage of the pipeline. In this case, use method conn_to

conn_to(uid, out_key, conn_exp=None)[source]

Returns a PipelineConnector object that defines a connection between the input of a method and the ouput of a previous stage of the pipeline.

Parameters
  • uid (int) – Stage unique id returned by input or add methods.

  • out_key (str) – Key of the output of the method given by uid that will be connected to the input argument.

  • conn_exp (callable) – Expresion that transforms the connected variable in some way. Fore instance, select a certain key from a dictionary, reshape an array, etc.

input(args)[source]

Defines the input arguments of the pipeline

Parameters

args (list of str) – List of input arguments to the pipeline

class medusa.components.PipelineConnector[source]

Bases: object

Auxiliary class to define connections between stages of a pipeline

Check this tutorial to better understand the usage of this class.

__init__(method_uid, output_key, conn_exp=None)[source]

PipelineConnector constructor

Parameters
  • method_uid (int) – Unique method identifier of method whose output will be connected.

  • output_key (str) – Key of the output of method_id that will be passed. Useful when a method returns several variables, but only 1 is useful as input to other stage. If None, the output will be passed straightaway.

  • conn_exp (callable) – Expresion that transforms the connected variable in some way. Fore instance, select a certain key from a dictionary, reshape an array, etc.

static from_dict(dict_data)[source]
to_dict()[source]
class medusa.components.ProcessingClassWrapper[source]

Bases: ProcessingMethod

ProcessingMethod wrapper for external classes (e.g., sklearn classifier). Use it to add an instance of the desired class to an algorithm. When designing your pipeline, take into account that the input signature (arguments) of the methods will be inherited from the original class.

DISCLAIMER: This wrapper may not work with all classes, since it uses some hacking to bind the methods and attributes of the original instance to this wrapper, changing the original type. Additionally, it is assumed that the instance is pickleable. If this is not the case, or something doesn’t work, you’ll have to design your own wrapper subclassing ProcessingMethod, which is also very easy and quick.

Check this tutorial to better understand the usage of this class.

__init__(instance, **kwargs)[source]

ProcessingClassWrapper constructor

Parameters
  • instance (object) – Instance of the class that will be implemented

  • kwargs – Key-value arguments that define the exposed methods and output signature. This is used by class Algorithm for a correct implementation of signal processing pipelines.

to_pickleable_obj()[source]

Returns a pickleable representation of the class. In most cases, the instance of the class is directly pickleable (e.g., all medusa methods, sklearn classifiers), but this may not be the case for some methods (i.e., keras models). Therefore, this function must be overridden in such cases.

Returns

representation – Pickleable representation of the instance.name

Return type

object

class medusa.components.ProcessingFuncWrapper[source]

Bases: ProcessingMethod

ProcessingMethod wrapper for processing functions. Use to add a processing function to an algorithm

Check this tutorial to better understand the usage of this class.

__init__(func, outputs, **kwargs)[source]

ProcessingFuncWrapper constructor

Parameters
  • func (callable) – Function that will be implemented

  • outputs (list) – Output signature of the method (output variables). This is used by class Algorithm for a correct implementation of signal processing pipelines.

class medusa.components.ProcessingMethod[source]

Bases: PickleableComponent

Skeleton class for processing methods. This class implements some useful features that allow the implementations of Algorithms, a key component of medusa.

Check this tutorial to better understand the usage of this class.

__init__(**kwargs)[source]

ProcessingMethod constructor

Parameters

kwargs – Key-value arguments that define the exposed methods and output signature. This is used by class Algorithm for a correct implementation of signal processing pipelines.

classmethod from_pickleable_obj(pickleable_obj)[source]

Returns the instance of the unpickled version of the pickleable representation given by function to_pickleable_representation. Therefore, this parameter is, by default, an instance of the class and no additional treatment is required. In some cases (i.e., keras models), the pickleable_representation may not be the instance, but some other pickleable format with the required information of the method to reinstantiate the instance itself (i.e., weights for keras models). In such cases, this function must be overriden

Parameters

pickleable_obj (object) – Pickleable representation of the processing method instance.

Returns

instance – Instance of the processing method

Return type

ProcessingMethod

get_exposed_methods()[source]
to_pickleable_obj()[source]

Returns a pickleable representation of the class. In most cases, the instance of the class is directly pickleable (e.g., all medusa methods, sklearn classifiers), but this may not be the case for some methods (i.e., keras models). Therefore, this function must be overridden in such cases.

Returns

representation – Pickleable representation of the instance.name

Return type

object

class medusa.components.Recording[source]

Bases: SerializableComponent

Class intended to save the data from one recording. It implements all necessary methods to save and load from several formats. It accepts different kinds of data: experiment data, which saves all the information about the experiment (e.g., events); biosignal data (e.g., EEG, MEG, NIRS), bioimaging data (e.g., fMRI, MRI); and custom data (e.g., photos, videos, audio). Temporal data must be must be synchronized with the reference. To assure multiplatform interoperability, this class must be serializable using python primitive types.

__init__(subject_id, recording_id=None, description=None, source=None, date=None, **kwargs)[source]

Recording dataset constructor. Custom useful parameters can be provided to save in the class.

Parameters
  • subject_id (int or str) – Subject identifier

  • recording_id (str or None) – Identifier of the recording for automated processing or easy identification

  • description (str or None) – Description of this recording. Useful to write comments (e.g., the subject moved a lot, the experiment was interrupted, etc)

  • source (str or None) – Source of the data, such as software, equipment, experiment, etc

  • kwargs (custom key-value parameters) – Other useful parameters (e.g., software version, research team, laboratory, etc)

add_bioimaging(bioimaging, key=None)[source]
add_biosignal(biosignal, key=None)[source]

Adds a biosignal recording. Each biosignal has predefined classes that must be instantiated before (e.g., EEG, MEG)

Parameters
  • biosignal (biosignal class) – Instance of the biosignal class. This class must be serializable. Current available: EEG, MEG.

  • key (str) – Custom name for this biosignal. If not provided, the biosignal will be saved in an attribute according to its type in lowercase (e.g., eeg, meg, etc). This parameter is useful if several biosignals of the same type are added to this recording

add_custom_data(data, key=None)[source]
add_experiment_data(experiment_data, key=None)[source]

Adds the experiment data of this recording. Each experiment should have a predefined class that must be instantiated before. Several classes are defined within medusa core, but it also can be a custom experiment.

Parameters
  • experiment_data (experiment class) – Instance of an experiment class. This class can be custom if it is serializable, but it is recommended to use the classes provided by medusa core in different modules (e.g., bci.erp_paradigms.rcp)

  • key (str) – Custom name for this experiment. If not provided, the experiment will be saved in an attribute according to its type (e.g., rcp, cake paradigm, etc). This parameter is useful if several experiments of the same type are added to this recording

cast_biosignal(key, biosignal_class)[source]

This function casts a biosignal to the class passed in biosignal_class

cast_experiment(key, experiment_class)[source]

This function casts an experiment of recording run to the class passed in experiment_class

classmethod from_serializable_obj(rec_dict)[source]

Function that loads the class from a python dictionary

get_biosignals_with_class_name(biosignal_class_name)[source]

This function returns the biosignals with a specific class name

Parameters

biosignal_class_name (str) – Class name of the biosignal (e.g., “EEG”)

get_experiments_with_class_name(exp_class_name)[source]

This function returns the experiments with a specific class name

Parameters

exp_class_name (str) – Class name of the experiment (e.g., “ERPSpellerData”)

rename_attribute(old_key, new_key)[source]

Rename an attribute. Useful to unify attribute names on fly while creating a dataset.

Parameters
  • old_key (str) – Old attribute key

  • new_key (str) – New attribute key

to_serializable_obj()[source]

This function returns a serializable dict (primitive types) containing the attributes of the class

class medusa.components.SerializableComponent[source]

Bases: ABC

Skeleton class for serializable components. These components must implement functions to transform the class to multiplatform formats, such as json, bson and mat. It must be used in classes that need persistence across multple platforms (i.e., recordings)

abstract classmethod from_serializable_obj(data)[source]

This function must return an instance of the class from a serializable (list or dict of primitive types)

classmethod load(path, data_format=None)[source]

Loads the file with the correct data structures

Parameters
  • path (str) – File path

  • data_format (None or str) – File format. If None, the format will be given by the file extension

Returns

Recording class with the correct data structures

Return type

Recording

classmethod load_from_bson(path)[source]
classmethod load_from_json(path, encoding='utf-8')[source]
classmethod load_from_mat(path, squeeze_me=True, simplify_cells=True, restore_none_objects=True)[source]

Load a mat file using scipy and restore its original class

Parameters
  • path (str) – Path to file

  • restore_none_objects (bool) – If True, it ensures that all ‘null’ strings are restored as None objects in case that these objects were removed upon saving. Nonetheless, it is computationally expensive, so it is better to leave to False and ensure manually.

classmethod load_from_pickle(path)[source]
save(path, data_format=None)[source]

Saves the component to the specified format.

Compatible formats:

  • bson: This format is safe, efficient, easy to use and multiplatform.

    Thus, it comes with advantages in comparison to other formats. BSON format requires serializable classes to python primary types.

  • json: This format is safe, human readable and multiplatform, widely

    used for web applications. Nevertheless, files are encoded in utf-8 and thus occupy more space. JSON format requires serializable classes to python primary types.

  • mat: This is a binary format widely used in research for its

    compatibility with Matlab. Very powerful and safe, but lacks of wide multiplatform compatibility. MAT format requires serializable classes, but allows numpy types.

  • pickle: This format is easy to use but lacks of multiplatform

    interoperability and it’s not very efficient.

Parameters
  • path (str) – File path. If data_format is None, The data format will be automatically decoded from the path extension.

  • data_format (str) – Format to save the recording. Current supported formats:

save_to_bson(path)[source]

Saves the class attributes in BSON format

save_to_json(path, encoding='utf-8', indent=4)[source]

Saves the class attributes in JSON format

save_to_mat(path, avoid_none_objects=True)[source]

Save the class in a MATLAB .mat file using scipy

Parameters
  • path (str) – Path to file

  • avoid_none_objects (bool) – If True, it ensures that all None objects are removed from the object to save to avoid scipy.io.savemat error with this type. Nonetheless, it is computationally expensive, so it is better to leave to False and ensure manually.

save_to_pickle(path, protocol=0)[source]

Saves the class using dill into pickle format

abstract to_serializable_obj()[source]

This function must return a serializable object (list or dict of primitive types) containing the relevant attributes of the class

class medusa.components.SettingsTreeItem[source]

Bases: SerializableComponent

General class to represent settings.

__init__(key, info, value_type=None, value=None)[source]

Class constructor.

Parameters
  • key (str) – Tree item key

  • info (str) – Information about this item

  • value_type (str ['string'|'number'|'integer'|'boolean'|'dict'|'list'], optional) – Type of the data stored in attribute value. Leave to None if the item is going to be a tree.

  • value (str, int, float, bool, dict or list, optional) – Tree item value. It must be one of the JSON types to be compatible with serialization. Leave to None if the item is going to be a tree.

add_item(item)[source]

Adds tree item to the tree. Use this function to build a custom tree. Take into account that if this function is used, attributes value and type will be set to None.

Parameters

item (SettingsTreeItem) – Tree item to add

count_items()[source]
classmethod from_serializable_obj(data)[source]

This function must return an instance of the class from a serializable (list or dict of primitive types)

is_tree()[source]
set_data(value_type, value)[source]

Adds tree item to the tree. Use this function to build a custom tree.

Parameters
  • value_type (str or list ['string'|'number'|'boolean'|'dict'|'list']) – Type of the data stored in attribute value. If a list is provided, several data types are accepted for attribute value.

  • value (str, int, float, bool, dict or list) – Tree item value. It must be one of the JSON types to be compatible with serialization. If list or dict, the items must be of type SettingsTreeItem.

to_serializable_obj()[source]

This function must return a serializable object (list or dict of primitive types) containing the relevant attributes of the class

class medusa.components.ThreadWithReturnValue[source]

Bases: Thread

This class inherits from thread class and allows getting the target function return

__init__(group=None, target=None, name=None, args=(), kwargs={})[source]

This constructor should always be called with keyword arguments. Arguments are:

group should be None; reserved for future extension when a ThreadGroup class is implemented.

target is the callable object to be invoked by the run() method. Defaults to None, meaning nothing is called.

name is the thread name. By default, a unique name is constructed of the form “Thread-N” where N is a small decimal number.

args is the argument tuple for the target invocation. Defaults to ().

kwargs is a dictionary of keyword arguments for the target invocation. Defaults to {}.

If a subclass overrides the constructor, it must make sure to invoke the base class constructor (Thread.__init__()) before doing anything else to the thread.

join(*args)[source]

Wait until the thread terminates.

This blocks the calling thread until the thread whose join() method is called terminates – either normally or through an unhandled exception or until the optional timeout occurs.

When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call is_alive() after join() to decide whether a timeout happened – if the thread is still alive, the join() call timed out.

When the timeout argument is not present or None, the operation will block until the thread terminates.

A thread can be join()ed many times.

join() raises a RuntimeError if an attempt is made to join the current thread as that would cause a deadlock. It is also an error to join() a thread before it has been started and attempts to do so raises the same exception.

run()[source]

Method representing the thread’s activity.

You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.

class medusa.components.TreeDict[source]

Bases: CheckTreeStructure

TreeDict is a utility class for building and managing hierarchical tree structures in a JSON-compatible format.

__init__(tree=None)[source]
add_item(key, default_value=None, info=None, input_format=None, value_range=None, value_options=None)[source]

Adds a new item (or sub-item) to the current tree structure.

Parameters
  • key (str) – The key name of the item.

  • default_value (str, int, float, bool or list, optional) – Default value for this item.

  • info (str, optional) – Help text or description to be displayed.

  • input_format (str, optional) – UI control type (‘checkbox’, ‘spinbox’, ‘doublespinbox’, ‘lineedit’, ‘combobox’).

  • value_range (list, optional) – List indicating the [min, max] for numeric inputs.

  • value_options (list, optional) – A list of allowed options (used for combobox).

Returns

A new TreeDict instance wrapping the added item.

Return type

TreeDict

to_dict()[source]

Returns the tree dict created.

medusa.deep_learning_models module

medusa.ecg module

exception medusa.ecg.ChannelNotFound[source]

Bases: Exception

__init__(l_cha)[source]
class medusa.ecg.ECG[source]

Bases: BiosignalData

Electrocardiography (ECG) biosignal data class.

__init__(times, signal, fs, channel_set, **kwargs)[source]

ECG constructor

Parameters
  • times (list or numpy.ndarray) – 1D numpy array [n_samples]. Timestamps of each sample. If they are not available, generate them artificially. Nevertheless, all signals and events must have the same temporal origin

  • signal (list or numpy.ndarray) – 2D numpy array [n_samples x n_channels]. EMG samples (the units should be defined using kwargs)

  • fs (int or float) – Sample rate of the recording.

  • channel_set (ECGChannelSet) – Channel information

  • kwargs (kwargs) – Key-value arguments to be saved in the class. This general class does not check anything

change_channel_set(channel_set)[source]

Smart change of channel set, updating the signal and all related attributes

Parameters

channel_set (ECGChannelSet) – ECG channel set

classmethod from_serializable_obj(dict_data)[source]

This function must return an instance of the class from a serializable dict (primitive types)

to_serializable_obj()[source]

This function must return a serializable dict (primitive types) containing the relevant attributes of the class

class medusa.ecg.ECGChannelSet[source]

Bases: SerializableComponent

Class to represent an ECG montage with ordered channels in specific coordinates. It also provides functionality to load channels from ECG standards directly from the labels.

__init__(channel_mode='leads')[source]

Constructor of class ECGChannelSet

Parameters

channel_mode (str {'leads', 'electrodes'}) – If ‘leads’, it is assumed that the channels are leads. If ‘electrodes’, it is assumed that channels are voltage difference between each electrode and the ground.

add_channel(label, descr=None)[source]

Function to add a channel to the end of the current montage. Take into account that the order of the channels is important!

Parameters
  • label (str) – Label of the channel. If mode is ‘leads’ this label must represent a lead. If mode is ‘leads’ this label must represent an electrode.

  • descr (str (optional)) – Description of the channel. If mode is ‘leads’ this description should say how it has been computed. If mode is ‘electrodes’, this description should include the location of the electrode.

See also

get_standard_channel_data_from_label

returns channel data given the channel label and the standard. It can be used to get the reference

check_channels_labels(labels, strict=False)[source]

Checks the order and labels of the channels

Parameters
  • labels (list) – Labels to check. The order matters

  • strict (bool) – If True, comparison is strict. The function will check that the channel set contains the channels given by parameter labels and in the same order. If false, the function checks that the channels are contained in the channel set, but they could be in different order and the set could contain more channels

Returns

check – True if the labels and order are the same. False otherwise

Return type

bool

classmethod from_serializable_obj(dict_data)[source]

This function must return an instance of the class from a serializable (list or dict of primitive types)

get_cha_idx_from_labels(labels)[source]

Returns the position of the channels given the labels

Parameters

labels (list) – Labels to check. The order matters

Returns

indexes – Indexes of the channels in the set

Return type

np.ndarray

set_ground(ground)[source]

Sets the ground of the montage

Parameters

ground (str) – Label of the ground. Standard ECG uses channel RL

set_montage(channels, ground=None)[source]

Sets a custom montage, overwriting the previous one. Add single channels more easily using function add_channel and add_standard_channel.

Parameters
  • channels (list) – List of dicts, each of them representing a channel. The dict must contain the label, and the description of the channel. If mode is ‘leads’ this label must represent a lead. If mode is ‘leads’ this label must represent an electrode.

  • ground (dict) – Dict containing the label and description of the ground electrode

See also

set_standard_montage

preferred choice in most cases

set_standard_montage(l_cha=None, l_ground=None, montage='12leads')[source]

Set standard ECG channels with common reference. In 3 dimensions, the equator is taken a Nz-T10-Iz-T9.

Parameters
  • l_cha (list, optional) – List of channels labels. The data will be returned keeping the same order. If None, the channels will be returned in the same order as they appear in the corresponding standard in medusa.meeg

  • l_ground (str, optional) – Label of the ground. Usual choices are AFz or FPz.

  • montage (str {'12leads'} or dict) – ECG standard. If it’s a string, the corresponding labels and locations of the standard channels will be loaded using the standards defined in this module. To load a different montage, pass a dict the same structure here.

subset(cha_idx)[source]

Selects the channels given the indexes, creating a subset. The order of the channels will be updated

Parameters

cha_idx (np.ndarray) – Indexes of the channels to select. The order matters

to_serializable_obj()[source]

This function must return a serializable object (list or dict of primitive types) containing the relevant attributes of the class

exception medusa.ecg.UnlocatedChannel[source]

Bases: Exception

__init__(l_cha)[source]
medusa.ecg.get_standard_montage(standard, channel_mode)[source]

Retrieves the electrode placements or lead configurations for a given ECG standard.

Parameters
  • standard (str {'12leads'}) – The ECG standard to retrieve.

  • channel_mode (str {'electrodes', 'leads'}) – Specifies whether to return electrode placements or lead computations.

Returns

A dictionary containing either the electrode placements or lead computations.

Return type

dict

Raises

ValueError – If an unsupported standard is requested.:

medusa.emg module

class medusa.emg.EMG[source]

Bases: BiosignalData

Electromiography (EMG) biosignal data class.

__init__(times, signal, fs, channel_set, location=None, **kwargs)[source]

EMG constructor

Parameters
  • times (list or numpy.ndarray) – 1D numpy array [n_samples]. Timestamps of each sample. If they are not available, generate them artificially. Nevertheless, all signals and events must have the same temporal origin

  • signal (list or numpy.ndarray) – 2D numpy array [n_samples x n_channels]. EMG samples (the units should be defined using kwargs)

  • fs (int or float) – Sample rate of the recording.

  • channel_set (list or Object) – Channel information

  • location (string) – Location of the recording (e.g., quadriceps)

  • kwargs (kwargs) – Key-value arguments to be saved in the class. This general class does not check anything

classmethod from_serializable_obj(dict_data)[source]

This function must return an instance of the class from a serializable dict (primitive types)

to_serializable_obj()[source]

This function must return a serializable dict (primitive types) containing the relevant attributes of the class

medusa.eog module

class medusa.eog.EOG[source]

Bases: BiosignalData

Electroculography (EOG) biosignal data class.

__init__(times, signal, fs, channel_set, location=None, **kwargs)[source]

EOG constructor

Parameters
  • times (list or numpy.ndarray) – 1D numpy array [n_samples]. Timestamps of each sample. If they are not available, generate them artificially. Nevertheless, all signals and events must have the same temporal origin

  • signal (list or numpy.ndarray) – 2D numpy array [n_samples x n_channels]. EMG samples (the units should be defined using kwargs)

  • fs (int or float) – Sample rate of the recording.

  • channel_set (list or Object) – Channel information

  • location (string) – Location of the recording (e.g., quadriceps)

  • kwargs (kwargs) – Key-value arguments to be saved in the class. This general class does not check anything

classmethod from_serializable_obj(dict_data)[source]

This function must return an instance of the class from a serializable dict (primitive types)

to_serializable_obj()[source]

This function must return a serializable dict (primitive types) containing the relevant attributes of the class

medusa.epoching module

medusa.epoching.check_epochs_feasibility(timestamps, onsets, fs, t_window)[source]

Checks if the extraction of the desired window is feasible with the available samples. Sometimes, the first/last stimulus sample is so close to the beginning/end of the signal data chunk that there are not enough samples to compute this window. In this case, the function will return “first” or “last” to identify which onset can not be extracted with the current t_window. It will return ‘ok’ if there is no conflict.

Parameters

timestamps (list or numpy.ndarray) – Timestamps of each biosginal sample

onsetslist or numpy.ndarray

Events timestamps

fsfloat

Sample rate

t_windowlist or numpy.ndarray

Temporal window in ms of the epoch. For example, t_window = [0, 1000] takes the epoch form 0 ms to 1000 ms after each onset (0 ms represents the onset).

Returns

feasibility – “ok” If window extraction is feasible. “first” If window extraction is not feasible for the first onset. “last” If window extraction is not feasible for the last onset.

Return type

string

medusa.epoching.get_epochs(signal, epochs_length, stride=None, norm=None)[source]
This function returns the signal divided in epochs following a sliding

window approach

Parameters
  • signal (list or numpy.ndarray) – Array to extract epochs with shape [samples, channels]

  • epochs_length (int) – Epochs length in samples

  • stride (int, optional) – Separation between consecutive epochs in samples. If None, stride is set to epochs_length.

  • norm (str, optional) – Set to ‘z’ for Z-score normalization or ‘dc’ for DC normalization. Statistical parameters are computed using the whole epoch.

Returns

Structured data with dimensions [n_epochs x length x n_channels]

Return type

numpy.ndarray

medusa.epoching.get_epochs_of_events(timestamps, signal, onsets, fs, w_epoch_t, w_baseline_t=None, norm=None)[source]

This function calculates the epochs of signal given the onsets of events.

Parameters
  • timestamps (list or numpy.ndarray) – Timestamps of each biosignal sample

  • signal (list or numpy.ndarray) – Biosignal samples

  • onsets (list or numpy.ndarray) – Events timestamps

  • fs (float) – Sample rate

  • w_epoch_t (list or numpy.ndarray) – Temporal window in ms of the epoch. For example, w_epoch_t = [0, 1000] takes the epoch form 0 ms to 1000 ms after each onset (0 ms represents the onset).

  • w_baseline_t (list or numpy.ndarray, optional) – Temporal window in ms of the baseline. For example, w_baseline_t = [-500, 100] takes the baseline from -500 ms before each onset to 100 ms after each onset (0 ms represents the onset). This chunk of signal is used to normalize the epoch, if applicable.

  • norm (str, optional) – Set to ‘z’ for Z-score normalization or ‘dc’ for DC normalization. Statistical parameters are computed using the whole epoch.

Returns

Structured data with dimensions [events x samples x channels]

Return type

numpy.ndarray

medusa.epoching.get_nearest_idx(timestamps, onsets)[source]

This function returns the indexes of the timestamps that are closest to the onsets.

medusa.epoching.normalize_epochs(epochs, norm_epochs=None, norm='z')[source]

Normalizes epochs

Parameters
  • epochs (list or numpy.ndarray) – Epochs of signal with dimensions [n_epochs x n_samples x n_channels]

  • norm_epochs (list or numpy.ndarray, optional) – Epochs of signal with dimensions [n_epochs x n_samples x n_channels] that are used to compute the statistical parameters for normalization. If None, norm_epochs=epochs.

  • norm (str) – Set to ‘z’ for Z-score normalization or ‘dc’ for DC normalization. Statistical parameters are computed using the whole epoch.

medusa.epoching.resample_epochs(epochs, t_window, target_fs)[source]

Resample epochs to the target_fs.

IMPORTANT: No antialising filter is applied

Parameters
  • epochs (list or numpy.ndarray) – Epochs of signal with dimensions [n_epochs x samples x channels]

  • t_window (list or numpy.ndarray) – Temporal window in ms of the epoch. For example, t_window = [0, 1000] takes the epoch form 0 ms to 1000 ms after each onset (0 ms represents the onset).

  • target_fs (float) – Target sample rate

Returns

Final epochs with dimensions [events x target_samples x channels]

Return type

numpy.ndarray

medusa.epoching.time_to_sample_index_events(times, onsets)[source]

Converts an array of time onsets to an array that indicates the sample index of the event

timeslist or numpy.ndarray

Array of shape [n_samples]. Timestamps of the biosignal

onsetslist or numpy.ndarray

Array of shape [n_events]. Onsets in time of the events

numpy.ndarray

Array of shape [n_samples]. The array is 1 only in the nearest timestamp to each onset, otherwise 0

medusa.frequency_filtering module

class medusa.frequency_filtering.FIRFilter[source]

Bases: ProcessingMethod

__init__(order, cutoff, btype, width=None, window='hamming', scale=True, filt_method='filtfilt', axis=0)[source]

FIR filter designed using the implementation of scipy.signal.firwin. See the documentation of this function to find useful information about this class

Parameters
  • order (int) – Length of the filter (number of coefficients, i.e. the filter order + 1). numtaps must be odd if a passband includes the Nyquist frequency.

  • cutoff (float or 1-D array_like) – Cutoff frequency of filter (expressed in the same units as fs) OR an array of cutoff frequencies (that is, band edges). In the latter case, the frequencies in cutoff should be positive and monotonically increasing between 0 and fs/2. The values 0 and fs/2 must not be included in cutoff.

  • btype (str {‘bandpass’|‘lowpass’|‘highpass’|‘bandstop’}) – Band type of the filter. It also controls the parameter pass_zero of them scipy.signal.firwin function

  • width (float or None, optional) – If width is not None, then assume it is the approximate width of the transition region (expressed in the same units as fs) for use in Kaiser FIR filter design. In this case, the window argument is ignored.

  • window (string or tuple of string and parameter values, optional) – Desired window to use. See scipy.signal.get_window for a list of windows and required parameters.

  • scale (bool, optional) –

    Set to True to scale the coefficients so that the frequency response is exactly unity at a certain frequency. That frequency is either:

    • 0 (DC) if the first passband starts at 0 (i.e. pass_zero is

      True)

    • fs/2 (the Nyquist frequency) if the first passband ends at

      fs/2 (i.e the filter is a single band highpass filter); center of first passband otherwise

  • filt_method (str {'lfilter', 'filtfilt'}) – Filtering method. See scipy.signal.lfilter or scipy.signal.filtfilt for more information.

  • axis (int) – The axis to which the filter is applied. By convention, signals in medusa are defined by [samples x channels], so axis is set to 0 by default.

display()[source]
fit(fs)[source]
fit_transform(signal, fs)[source]

Fits and applies the filter

Parameters
  • signal (np.ndarray) – Signal to filter. By default, the expected shape is [samples x channels], but this order can be changed using axis parameter in constructor.

  • fs (float) – The sampling frequency of the signal in Hz. Each frequency in cutoff must be between 0 and fs/2. Default is 2.

transform(signal)[source]
class medusa.frequency_filtering.IIRFilter[source]

Bases: ProcessingMethod

__init__(order, cutoff, btype, filt_method='sosfiltfilt', axis=0)[source]

IIR Butterworth filter wrapper designed using implementation of scipy.signal.butter. See the documentation of this function to find useful information about this class.

Parameters
  • order (int) – Length of the filter (number of coefficients, i.e. the filter order + 1). This parameter must be odd if a passband includes the Nyquist frequency.

  • cutoff (float or 1-D array_like) – Cutoff frequency of filter (expressed in the same units as fs) OR an array of cutoff frequencies (that is, band edges). In the latter case, the frequencies in cutoff should be positive and monotonically increasing between 0 and fs/2. The values 0 and fs/2 must not be included in cutoff.

  • btype (str {‘bandpass’|‘lowpass’|‘highpass’|‘bandstop’}) – Band type of the filter. It also controls the parameter pass_zero of them scipy.signal.firwin function

  • filt_method (str {'sosfilt', 'sosfiltfilt'}) – Filtering method. See scipy.signal.sosfilt or scipy.signal.sosfiltfilt for more information. For real time fitlering, use sosfilt. For offline filtering, sosfiltfilt is the recommended filtering method.

  • axis (int) – The axis to which the filter is applied. By convention, signals in medusa are defined by [samples x channels], so axis is set to 0 by default.

display()[source]

Displays the filter. Function fit must be called first. This uses the function medusa.frequency_filtering.display_filter()

fit(fs, n_cha=None)[source]

Fits the filter

Parameters
  • fs (float) – The sampling frequency of the signal in Hz. Each frequency in cutoff must be between 0 and fs/2. Default is 2.

  • n_cha (int) – Number of channels. Used to compute the initial conditions of the filter. Only required with sosfilt filtering method (online filtering)

fit_transform(signal, fs)[source]

Fits and applies the filter

Parameters
  • signal (np.ndarray) – Signal to filter. By default, the expected shape is [samples x channels], but this order can be changed using axis parameter in constructor.

  • fs (float) – The sampling frequency of the signal in Hz. Each frequency in cutoff must be between 0 and fs/2. Default is 2.

transform(signal)[source]

Applies the filter to the signal

Parameters

signal (np.ndarray) – Signal to filter. By default, the expected shape is [samples x channels], but this order can be changed using axis parameter in constructor.

medusa.frequency_filtering.display_filter(b, a, fs)[source]

Displays the frequency response of a given filter.

Parameters
  • b (np.ndarray) – Numerator of the filter

  • a (np.ndarray) – Denominator of the filter

  • fs (float) – Sampling frequency of the signal (in Hz)

medusa.nirs module

class medusa.nirs.NIRS[source]

Bases: BiosignalData

Near Infrarred Spectroscopy (NIRS) biosignal data class.

__init__(times, signal, fs, channel_set, **kwargs)[source]

NIRS constructor

Parameters
  • times (list or numpy.ndarray) – 1D numpy array [n_samples]. Timestamps of each sample. If they are not available, generate them artificially. Nevertheless, all signals and events must have the same temporal origin

  • signal (list or numpy.ndarray) – 2D numpy array [n_samples x n_channels]. EMG samples (the units should be defined using kwargs)

  • fs (int or float) – Sample rate of the recording.

  • channel_set (list or Object) – Channel information

  • kwargs (kwargs) – Key-value arguments to be saved in the class. This general class does not check anything

classmethod from_serializable_obj(dict_data)[source]

This function must return an instance of the class from a serializable dict (primitive types)

to_serializable_obj()[source]

This function must return a serializable dict (primitive types) containing the relevant attributes of the class

medusa.notify_me module

medusa.notify_me.notify_me(mailto, subject, body, mailfrom, password, host='smtp.live.com')[source]

This method implements sending an email (ONLY TESTED FROM A HOTMAIL ADDRESS) to any email address. To allow the email sending from you Hotmail account, you have to validate it, if you get an error please check your inbox (probably, a confirmation mail has been sent).

Parameters
  • mailto (string) – Mail recipient address.

  • subject (string) – Mail subject.

  • body (string) – Mail body.

  • mailfrom (string) – Mail sender address.

  • password (string) – Password from mailfrom address.

  • host (string) – SMTP host of the “mailfrom” address. In case of Hotmail use “smtp.live.com”

medusa.optimization module

class medusa.optimization.Grinder[source]

Bases: object

__init__(**hyparams)[source]
get_hyparams(idx)[source]
class medusa.optimization.Optimizer[source]

Bases: object

__init__(obj, func, grinder, args=None, previous_hist=None)[source]
get_best_hyparams()[source]
optimize(max_iter, approach, save_history=True)[source]
set_bayes_opt_params(n_samp, rbf_length_scale=1)[source]

medusa.performance_analysis module

medusa.performance_analysis.perf_analysis(func)[source]

Returns the run time of the decorated function

medusa.pytorch_integration module

exception medusa.pytorch_integration.DeviceNotAvailableError[source]

Bases: Exception

Exception raised when the requested computing device is not available.

This error occurs when attempting to use a specific device (e.g., ‘cuda’, ‘cuda:0’, ‘mps’) that is either not detected or unsupported on the system.

Parameters
  • device (str, optional) – The name of the device that is unavailable (e.g., ‘cuda’, ‘cuda:0’, ‘mps’).

  • msg (str, optional) – Custom error message. If not provided, a default message is generated.

Notes

  • If device is provided, the error message includes the unavailable

    device name.

  • Users should verify device availability using PyTorch methods like

    torch.cuda.is_available().

Examples

>>> raise DeviceNotAvailableError(device="cuda:0")
Traceback (most recent call last):
    ...
DeviceNotAvailableError: Device 'cuda:0' is not available. Check
    system configuration.
>>> raise DeviceNotAvailableError()
Traceback (most recent call last):
    ...
DeviceNotAvailableError: Device not available. Ensure the required device
    is connected and supported.
__init__(device=None, msg=None)[source]
exception medusa.pytorch_integration.NoGPUError[source]

Bases: Exception

Exception raised when no GPU compatible with Pytorch is available for computation.

This error occurs when a GPU is required but not detected in the system.

Parameters

msg (str, optional) – Custom error message. If not provided, a default message is used.

Notes

  • This exception is typically raised when attempting to use CUDA, but no

    GPU is available.

  • Users should verify their hardware and ensure that CUDA is properly

    installed.

  • To check GPU availability in PyTorch, use torch.cuda.is_available().

Examples

>>> raise NoGPUError()
Traceback (most recent call last):
    ...
NoGPUError: No GPU available. Ensure your system has a compatible GPU
    and that CUDA is installed.
__init__(msg=None)[source]
exception medusa.pytorch_integration.TorchExtrasNotInstalled[source]

Bases: Exception

Exception raised when a required PyTorch package or dependency is not installed.

Parameters

msg (str, optional) – Custom error message. If not provided, a default message is used.

Notes

  • This exception is typically raised when an external package that

    integrates with PyTorch is missing.

  • Users should check https://pytorch.org/ for installation instructions.

Examples

>>> raise TorchExtrasNotInstalled()
Traceback (most recent call last):
    ...
TorchExtrasNotInstalled: This functionality requires PyTorch package. Check
https://pytorch.org/ for installation instructions.
__init__(msg=None)[source]
exception medusa.pytorch_integration.TorchNotConfiguredError[source]

Bases: Exception

Exception raised when PyTorch has not been properly configured.

This error occurs when an operation requiring PyTorch is attempted without first configuring the PyTorch environment.

Parameters

msg (str, optional) – Custom error message. If not provided, a default message is used.

Notes

  • This exception is typically raised when config_pytorch() has not been

    called.

  • Users should ensure that PyTorch integration is properly initialized

    before executing GPU-dependent or Medusa-related operations.

Examples

>>> raise TorchNotConfiguredError()
Traceback (most recent call last):
    ...
TorchNotConfiguredError: PyTorch has not been configured. Call
`config_pytorch()` before using PyTorch-related features.
__init__(msg=None)[source]
medusa.pytorch_integration.check_gpu_acceleration()[source]

Checks if GPU acceleration is available and properly configured.

Returns

True if GPU acceleration is enabled, False otherwise.

Return type

bool

Raises

PyTorchNotConfiguredError – If PyTorch has not been properly configured.

Notes

  • Calls check_pytorch_config() to verify PyTorch integration.

  • If PyTorch is not configured, an exception is raised.

  • Uses the MEDUSA_TORCH_GPU_ACCELERATION environment variable to determine GPU availability.

medusa.pytorch_integration.check_pytorch_config()[source]

Checks if PyTorch has been configured within the Medusa environment.

Returns

  • 1 if PyTorch is configured and GPU acceleration status is set.

  • 0 if PyTorch is configured but GPU acceleration status is missing.

  • -1 if PyTorch is not configured.

Return type

int

Notes

  • The function checks the MEDUSA_TORCH_INTEGRATION environment variable.

  • GPU acceleration is checked using MEDUSA_TORCH_GPU_ACCELERATION.

medusa.pytorch_integration.config_pytorch(device_name=None)[source]

Configures PyTorch, checking for GPU acceleration and setting the appropriate device.

This function automatically selects a device based on availability or uses the user-specified device. It also sets environment variables to indicate the selected device and whether GPU acceleration is enabled.

Parameters

device_name (str, optional) – The specific device to use (e.g., ‘cuda’, ‘cuda:0’, or ‘cpu’). If None, the function will automatically choose ‘cuda:0’ if a GPU is available; otherwise, it defaults to ‘cpu’.

Returns

The configured PyTorch device.

Return type

torch.device

Raises
  • ImportError – If PyTorch is not properly integrated (MEDUSA_TORCH_INTEGRATION environment variable is missing).

  • TorchExtrasNotInstalled – If additional PyTorch-related dependencies are not installed.

Notes

  • If device_name is not specified, the function defaults to ‘cuda:0’

    if CUDA is available, otherwise ‘cpu’.

  • The function sets two environment variables:
    • “MEDUSA_TORCH_DEVICE”: Stores the selected device.

    • “MEDUSA_TORCH_GPU_ACCELERATION”: “1” if CUDA is used, “0”

      otherwise.

  • If GPU is unavailable and no device is specified,

    warn_gpu_not_available() is called.

Examples

>>> device = config_pytorch()
Selected device: NVIDIA GeForce RTX 3090
  - CUDA Device Index: 0
  - Compute Capability: 8.6
  - Total Memory: 24.00 GB
>>> device = config_pytorch("cpu")
Selected device: CPU
  - Cores: 8 (Threads used by PyTorch)
medusa.pytorch_integration.get_torch_device()[source]

Retrieves the PyTorch device currently used by Medusa.

Returns

The name of the configured PyTorch device (e.g., ‘cuda:0’ or ‘cpu’).

Return type

str

Raises

PyTorchNotConfiguredError – If PyTorch has not been properly configured.

Notes

  • Calls check_pytorch_config() to verify PyTorch integration.

  • If PyTorch is not configured, an exception is raised.

  • Returns the value stored in the MEDUSA_TORCH_DEVICE environment

    variable.

medusa.pytorch_integration.print_device_info(device)[source]

Prints detailed information about the selected computing device.

Parameters

device (torch.device) – The PyTorch device object (CPU or CUDA).

Notes

  • If the device is CUDA, it prints the device name, CUDA device index, compute capability, and total memory.

  • If the device is CPU, it prints the number of threads used by PyTorch.

Examples

>>> device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
>>> print_device_info(device)
Selected device: NVIDIA GeForce RTX 3090
  - CUDA Device Index: 0
  - Compute Capability: 8.6
  - Total Memory: 24.00 GB
>>> print_device_info(torch.device("cpu"))
Selected device: CPU
  - Cores: 8 (Threads used by PyTorch)
medusa.pytorch_integration.warn_gpu_not_available()[source]

Issues a warning when GPU acceleration is not available.

Notes

  • This function is called when config_pytorch() detects that no GPU is

available. - Uses warnings.warn() to provide a non-blocking alert.

medusa.signal_generators module

class medusa.signal_generators.SignalGenerator[source]

Bases: ABC

__init__(fs)[source]
abstract get_chunk(duration, n_channels)[source]
class medusa.signal_generators.SinusoidalSignalGenerator[source]

Bases: SignalGenerator

Experimental class for sinusoidal signals generation

__init__(fs, freqs, noise_type='white', noise_params={'mean': 0, 'sigma': 1})[source]
get_chunk(duration, n_channels)[source]

medusa.signal_orthogonalization module

medusa.signal_orthogonalization.signal_orthogonalization_cpu(signal_1, signal_2)[source]

This method implements the ortogonalization of each channel of signal_1 regarding all the channels in signal_2 using CPU

REFERENCES: O’Neill, G. C., Barratt, E. L., Hunt, B. A., Tewarie, P. K., & Brookes, M.J. (2015). Measuring electrophysiological connectivity by power envelope correlation: a technical review on MEG methods. Physics in Medicine & Biology, 60(21), R271.

Parameters
  • signal_1 (numpy 2D matrix) – First MEEG Signal. Allowed dimensions: [n_epochs, n_samples, n_channels], [n_samples, n_channels] and [n_samples].

  • signal_2 (numpy 2D matrix) – Second MEEG Signal. If empty signal_2 will be set to be equal to signal_1. Allowed dimensions: [n_epochs, n_samples, n_channels], [n_samples, n_channels] and [n_samples].

Returns

signal_ort – MEEG ortogonalised signals. The first dimension is epochs. The second dimension is samples. The fourth dimension is the channel of first signal, and the second dimension is regarding which channel of second signal it has been orthogonalized the channel in third dimension. [n_epochs, n_samples, n_channels, n_channels].

Return type

numpy 3D matrix

medusa.signal_orthogonalization.signal_orthogonalization_gpu(signal_1, signal_2)[source]

This function ortogonalizes each channel of signal_1 regarding all the channels in signal_2. Based in O’Neill et al. 2015

Parameters
  • signal_1 (numpy 3D matrix) – First MEEG Signal. Allowed dimensions: [n_epochs, n_samples, n_channels], [n_samples, n_channels] and [n_samples].

  • signal_2 (numpy 3D matrix) – Second MEEG Signal. If empty signal_2 will be set to be equal to signal_1. Allowed dimensions: [n_epochs, n_samples, n_channels], [n_samples, n_channels] and [n_samples].

Returns

signal_ort – MEEG ortogonalized signals. The first dimension is epochs. The second dimension is samples. The fourth dimension is the channel of first signal, and the second dimension is regarding which channel of second signal it has been orthogonalized the channel in third dimension. [n_epochs, n_samples, n_channels, n_channels].

Return type

numpy 3D matrix

medusa.signal_orthogonalization.signal_orthogonalization_gpu_old(signal_1, signal_2)[source]

DEPRECATED: This functions performs the orthogonalization of the signal but it is not vectorized nor allow epochs as inputs. Its use is not recommended.

This function ortogonalizes each channel of signal_1 regarding all the channels in signal_2. Based in O’Neill et al. 2015

Parameters
  • signal_1 (numpy 2D matrix) – MEEG Signal. SamplesXChannel.

  • signal_2 (numpy 2D matrix) – MEEG Signal. SamplesXChannel.

Returns

signal_ort – MEEG ortogonalised signals. Samples x Channel x Channel.

The first dimension are the samples, the third is the base channel used to ortogonalize the other channels and the second dimension are the ortogonalized channels regarding the third dimension

Return type

numpy 3D matrix

medusa.spatial_filtering module

class medusa.spatial_filtering.CCA[source]

Bases: ProcessingMethod

The class CCA performs a Canonical Correlation Analysis filtering. First, function fit() sould be called to train the spatial filters. Then, spatial filters could be used to project testing data. After fit(), the following attributes are computed:

wx

Mixing matrix for projecting the data, where spatial filters are stored in columns.

Type

{(channels, no_filters) ndarray}

wy

Mixing matrix for projecting the reference, where spatial filters are stored in columns.

Type

{(channels, no_filters) ndarray}

r

Sample canonical correlations.

Type

{(channels, ) ndarray}

__init__()[source]

ProcessingMethod constructor

Parameters

kwargs – Key-value arguments that define the exposed methods and output signature. This is used by class Algorithm for a correct implementation of signal processing pipelines.

static canoncorr(X, Y)[source]

Computes the canonical correlation analysis (CCA) for the data matrices X (dimensions N-by-P1) and Y (dimensions N-by-P2). X and Y must have the same number of observations (rows) but can have different numbers of variables (cols). The j-th columns of A and B contain the canonial coefficients, i.e. the linear combination of variables making up the j-th canoncial variable for X and Y, respectively. If X or Y are less than full rank, canoncorr gives a warning and returns zeros in the rows of A or B corresponding to dependent columns of X or Y. Final dimension D is computed as D = min(rank_X, rank_Y). .. rubric:: Notes

This method is adapted from the MATLAB function ‘canoncorr’. Check that file in case of conflicts, doubts or additional information.

Parameters
  • X ({(N, P1) ndarray}) – Input matrix with dimensions N-by-P1. Rows are observations and cols are variables.

  • Y ({(N, P2) ndarray}) – Input matrix with dimensions N-by-P1. Rows are observations and cols are variables.

Returns

  • A ({(P1, D) ndarray}) – Sample canonical coefficients for the variables in X. The j-th column of A contains the linear combination of variables that makes up the j-th canonical variable for X. If X is less than full rank, A will have zeros in the rows corresponding to dependent cols of X.

  • B ({(P2, D) ndarray}) – Sample canonical coefficients for the variables in Y. The j-th column of B contains the linear combination of variables that makes up the j-th canonical variable for Y. If Y is less than full rank, B will have zeros in the rows corresponding to dependent cols of Y.

  • r ({(D,) ndarray}) – Sample canonical correlations. The j-th element of r is the correlation between the h-th columns of the canonical scores for the variables in X and Y.

References

[1] Krzanowski, W.J., Principles of Multivariate Analysis, Oxford University Press, Oxford, 1988. [2] Seber, G.A.F., Multivariate Observations, Wiley, New York, 1984.

Example

>>> import numpy as np
>>> X = np.random.rand(10, 4)
>>> Y = np.random.rand(10, 4)
>>> A, B, r = canoncorr(X, Y)
fit(x, y)[source]

Fits the CCA spatial filters given the two input matrices data and reference, storing relevant parameters. :param x: First input matrix, usually data with concatenated epochs. :type x: {(samples, channels) ndarray} :param y: Second input matrix, usually the data reference. The number of

samples must match the samples of the data matrix. Repeat the reference if necessary before calling this function.

static from_dict(dict_data)[source]
project(data, filter_idx=0, projection='wy')[source]

Projects the input data matrix using the given spatial filter. Note that the spatial filter will have dimensions [no. channels x no. channels].

Parameters
  • data ({(samples, channels) ndarray}) – Testing data matrix. The number of channels must be the same as the no. channels used to train.

  • filter_idx ({int}, optional) – Indexes of the spatial filters to be used. Since filters are sorted by their importance in terms of correlation, the default filter (0) is the one that yields highest correlation.

  • projection ({str}, optional) – Canonical coefficients to be used in projection. By default, the function uses Wy. Typically, if data is averaged, Wy must be used; otherwise, if data is not averaged and just concatenated, Wx must be used.

Returns

projected_data – Projected data along the selected spatial filter.

Return type

{(samples, ) ndarray}

to_dict()[source]
class medusa.spatial_filtering.CSP[source]

Bases: ProcessingMethod

Common Spatial Pattern filtering.

filters

Mixing matrix (spatial filters are stored in columns).

Type

{(…, M, M) numpy.ndarray, (…, M, M) matrix}

eigenvalues

Eigenvalues of w.

Type

(…, M) numpy.ndarray

patterns

De-mixing matrix (activation patterns are stored in columns).

Type

numpy.ndarray

__init__(n_filters=4, selection='extremes')[source]
Parameters
  • n_filters (int or None) – Number of filters to select. Use None to return all filters (default: 4).

  • selection (basestring) – Selection method: - “extremes” (default): classic method that takes the filters from the extremes, which belong to both classes separately. This method cannot be applied in problems with more than 2 classes. - “eigenvalues”: the eigenvalues are sorted and the highest ones are eligible to be selected.

filters

Mixing matrix, or forward model (spatial filters are stored in rows).

Type

np.ndarray (n_channels, n_channels)

patterns

De-mixing matrix, or backward model (patterns are stored in rows).

Type

np.ndarray (n_channels, n_channels)

eigenvalues

Eigenvalues associated to each filter and pattern.

Type

np.ndarray (n_channels, )

sel_idxs

Selected indexes to get the desired filters and patterns.

Type

np.ndarray (n_filters, )

sel_filters

Selected spatial filters (stored in rows).

Type

np.ndarray (n_filters, n_channels)

sel_patterns

Selected patterns (stored in rows).

Type

np.ndarray (n_filters, n_channels)

sel_eigenvalues

Selected eigenvalues.

Type

np.ndarray (n_filters, )

fit(X, y)[source]

Method to train the CSP.

This code is based on [1] for the 2-class problem, and based on [2] for the > 2-class problem.

Parameters
  • X (numpy.ndarray (n_epochs, n_samples, n_channels)) – Epoched data of shape (n_epochs, n_samples, n_channels)

  • y (numpy.ndarray (n_epochs, )) – Labels for epoched data of shape (n_epochs, )

References

[1] Blankertz, B., Tomioka, R., Lemm, S., Kawanabe, M., & Muller, K. R. (2007). Optimizing spatial filters for robust EEG single-trial analysis. IEEE Signal processing magazine, 25(1), 41-56. [2] Grosse-Wentrup, Moritz, and Martin Buss. “Multiclass common spatial patterns and information theoretic feature extraction.” Biomedical Engineering, IEEE Transactions on 55, no. 8 (2008): 1991-2000.

static from_dict(dict_data)[source]
plot(channel_set, figure=None, plot_filters=False, plot_patterns=True, topo_settings=None, show=False, plot_eig=True, only_selected=True)[source]
project(X)[source]

Projects the input data X with the selected spatial filters.

Parameters

X (numpy.ndarray (n_epochs, n_samples, n_channels)) – Epoched data of shape (n_epochs, n_samples, n_channels).

Returns

Array with the epochs of signal projected in the CSP space.

Return type

numpy.ndarray (n_epochs, n_filters, n_channels)

to_dict()[source]
class medusa.spatial_filtering.LaplacianFilter[source]

Bases: ProcessingMethod

Class for fitting and applying Laplacian Filter to EEG Signals. A channel set from EEGChannelSet class must have been defined before calling LaplacianFilter class.

This class implements the second order Hjorth’s approximation of the Laplacian surface for a spatial-discrete system [1].

It counts with two different modes: - Auto: First, the location of the channel to be filtered is identified.

This allows us to determine the number of surrounding electrodes to be taken into account when calculating the laplacian surface (i.e., an electrode located in the center of the assembly is not the same as an electrode located in a corner). Then, apply the Laplacian surface correction taking into account the distance at which each electrode is located. It should take into account that this mode only applies the laplacian surface to the closest electrodes, so for next-nearest neighbours [2] the custom mode should be used.

  • Custom: In this mode, a list containing the labels of the channels to be

    used to calculate the Laplacian surface of each channel to be filtered must be defined. This allows the design of long distance filters [2].

References [1] Claudio Carvalhaes, J. Acacio de Barros, The surface Laplacian technique

in EEG: Theory and methods, International Journal of Psychophysiology, Volume 97, Issue 3, 2015, Pages 174-188.

[2] Dennis J McFarland, Lynn M. McCabe, Stephen V. David, Jonathan R. Wolpaw,

Spatial filter selection for EEG-based communication, Electroencephalography and clinical Neurophysiology, Volume 193, 1997, Pages 386-394.

__init__(channel_set, mode='auto')[source]

ProcessingMethod constructor

Parameters

kwargs – Key-value arguments that define the exposed methods and output signature. This is used by class Algorithm for a correct implementation of signal processing pipelines.

apply_lp(signal)[source]

Applies Laplacian filter to an EEG signal

Parameters

signal (np.ndarray) – Array of EEG signal with shape [N_samples x N_channels]

Returns

  • s_filtered (np.ndarray)

  • Filtered EEG signal with shape [N_samples x len(l_cha_to_filter)].

fit_lp(l_cha_to_filter, l_cha_laplace=None)[source]

Fits the Laplacian Filter depending on the mode chosen

Parameters
  • l_cha_to_filter (list of strings) – List [N x 1] containing the labels of the channels to filter. Used in both filtering modes.

  • l_cha_laplace (list) – List of lists [N x M] containing the labels of the channels to compute the laplace filter for channel in position Ni of l_cha_to_filter. Only used in mode custom.

class medusa.spatial_filtering.TRCA[source]

Bases: ProcessingMethod

The class TRCA performs a Task-related Component Analysis filtering. First, function fit() should be called to train the spatial filters. Then, spatial filters could be used to project testing data. After fit(), the following attributes are computed:

w

Spatial filter obtained.

Type

{(channels, 1) ndarray}

fit(x)[source]

Fits the TRCA spatial filter given the input matrices data and :param x: Input matrix, usually data with concatenated epochs. :type x: {(epochs ,samples, channels) ndarray}

project(data)[source]

Projects the input data matrix using the given spatial filter. Note that the spatial filter will have dimensions [no. channels x 1].

Parameters

data ({(samples, channels) ndarray}) – Testing data matrix. The number of channels must be the same as the no. channels used to train.

Returns

projected_data – Projected data along the selected spatial filter.

Return type

{(samples, ) ndarray}

static trca(X)[source]

Computes the task related component analysis (TRCA) for the data matrix X (dimensions epochs-by-samples/epoch-by-channels) and Y (dimensions N-by-P2).

Parameters

X ({(epochs ,samples/epoch, channels) ndarray}) – Input matrix with dimensions N-by-P1. Rows are observations and cols are variables.

Returns

w – Spatial filter.

Return type

{(channels, 1) ndarray}

References

[1] Tanaka, H., Group task-related component analysis (GTRCA): A multivariate method for inter-trial reproducibility and inter-subject similarity maximization for EEG data analysis, Scientific Reports, 10, 2020. [2] Nakanishi, M., Wang, Y., Chen, X., Wang, Y.T., Gao, X., Jung, T.P., Enhancing detection of SSVEPs for a high-speed brain speller using task-related component analysis, IEEE Transactions on Biomedical Engineering, 65, 2018

medusa.spatial_filtering.car(signal)[source]

Implementation of the common average reference (CAR) spatial filter.

This class applies a CAR filter over a signal with shape [samples x channels]. The CAR filtering substracts the averaged signal of all electrodes to every single one, following the expression below:

X_car = X - (1/N)*sum(X,2),

where X is the EEG signal with dimensions [samples x channels], N is the total number of channels, and sum(~,2) denotes the sum over the second dimension (i.e., over the channels, returning a [samples x 1] signal). In practice, this operation can be implemented as a matrix multiplication:

X_car = (M * X’)’,

where X is the original signal [samples x ch], and M is the spatial filter matrix, composed by:

1-(1/N) -1/N -1/N |
M = | -1/N 1-(1/N) -1/N |
-1/N -1/N 1-(1/N) |
Parameters

signal (np.ndarray) –

EEG raw signal with dimensions [samples x ch]. Note that the TRIGGER channel must be DELETED before calling this function. In other words, eeg_signal must not contain the TRIGGER channel, only the EEG

channels.

Returns

signal – Filtered signal

Return type

np.array

medusa.stats module

medusa.stats.get_confusion_matrix_stats(tp, tn, fp, fn)[source]

This function returns a collection of statistics given a confusion matrix. For more information about these statistics, refer to https://en.wikipedia.org/wiki/Positive_and_negative_predictive_values.

Parameters
  • tp (int) – Number of true positives

  • tn (int) – Number of true negatives

  • fp (int) – Number of false positives

  • fn (int) – Number of false negatives

Returns

Dictionary that contains the following statistics:
  • ”prevalence”

  • ”accuracy”

  • ”ba”, i.e. balanced accuracy

  • ”ppv”, i.e. positive predictive value

  • ”precision”, same as PPV

  • ”fdr”, i.e. false discovery rate

  • ”f1”, i.e. F1 score

  • ”for”, i.e. false omission rate

  • ”npv”, i.e. negative predictive value

  • ”fm”, i.e. Fowlkes-Mallows index

  • ”informedness”

  • ”bm”, i.e. bookmaker informedness (informedness)

  • ”tpr”, i.e. true positive rate

  • ”sensitivity”, i.e. same as TPR

  • ”recall”, i.e. same as TPR

  • ”fpr”, i.e. false positive rate (fall-out or type I error)

  • ”lr+”, positive likelihood ratio

  • ”mk”, i.e. markedness (deltaP)

  • ”mcc”, i.e. Matthews correlation coefficient

  • ”pt”, i.e. prevalence threshold

  • ”fnr”, i.e. false negative rate (miss rate or type II error)

  • ”tnr”, i.e. true negative rate (selectivity)

  • ”specificity”, i.e. same as TNR

  • ”lr-”, i.e. negative likelihood ratio

  • ”dor”, i.e. diagnostic odds ratio

  • ”ts”, i.e. threat score (Jaccard index)

  • ”csi”, i.e. critical success index (same as TS)

Return type

dict()

medusa.transforms module

medusa.utils module

medusa.utils.check_dimensions(data)[source]

This function checks if data dimensions are [n_epochs x n_samples x n_channels] and transforms to it if not