def _preprocess(
    ds, ds_index, preprocessors, save_dir=None, overwrite=False, copy_data=False
):
    """Apply preprocessor(s) to Raw or Epochs object.

    Parameters
    ----------
    ds: BaseDataset | WindowsDataset
        Dataset object to preprocess.
    ds_index : int
        Index of the BaseDataset in its BaseConcatDataset. Ignored if save_dir
        is None.
    preprocessors: list(Preprocessor)
        List of preprocessors to apply to the dataset.
    save_dir : str | None
        If provided, save the preprocessed BaseDataset in the
        specified directory.
    overwrite : bool
        If True, overwrite existing file with the same name.
    copy_data : bool
        First copy the data in case it is preloaded. Necessary for parallel processing to work.
    """

    def _preprocess_raw_or_epochs(raw_or_epochs, preprocessors):
        # Copying the data necessary in some scenarios for parallel processing
        # to work when data is in memory (else error about _data not being writeable)
        if raw_or_epochs.preload and copy_data:
            raw_or_epochs._data = raw_or_epochs._data.copy()
        for preproc in preprocessors:
            preproc.apply(raw_or_epochs)

    if hasattr(ds, "raw"):
        if isinstance(ds, EEGWindowsDataset):
            warn(
                f"Applying preprocessors {preprocessors} to the mne.io.Raw of an EEGWindowsDataset."
            )
        _preprocess_raw_or_epochs(ds.raw, preprocessors)
    elif hasattr(ds, "windows"):
        _preprocess_raw_or_epochs(ds.windows, preprocessors)
    else:
        raise ValueError(
            "Can only preprocess concatenation of BaseDataset or "
            "WindowsDataset, with either a `raw` or `windows` attribute."
        )

    # Store preprocessing keyword arguments in the dataset
    _set_preproc_kwargs(ds, preprocessors)

    if save_dir is not None:
        concat_ds = BaseConcatDataset([ds])
        concat_ds.save(save_dir, overwrite=overwrite, offset=ds_index)
    else:
        return ds
Apply preprocessor(s) to Raw or Epochs object.

    Parameters
    ----------
    ds: BaseDataset | WindowsDataset
        Dataset object to preprocess.
    ds_index : int
        Index of the BaseDataset in its BaseConcatDataset. Ignored if save_dir
        is None.
    preprocessors: list(Preprocessor)
        List of preprocessors to apply to the dataset.
    save_dir : str | None
        If provided, save the preprocessed BaseDataset in the
        specified directory.
    overwrite : bool
        If True, overwrite existing file with the same name.
    copy_data : bool
        First copy the data in case it is preloaded. Necessary for parallel processing to work.
    
braindecode/preprocessing/preprocess.py