import os
import mne

sample_data_folder = mne.datasets.sample.data_path()
sample_data_raw_file = os.path.join(sample_data_folder, 'MEG', 'sample',
                                    'sample_audvis_raw.fif')
# the preload flag loads the data into memory now
raw = mne.io.read_raw_fif(sample_data_raw_file, preload=True)
raw.crop(tmax=10.)  # raw.crop() always happens in-place

"""
Explanation: Modifying data in-place
Many of MNE-Python's data objects (~mne.io.Raw, ~mne.Epochs, ~mne.Evoked,
etc) have methods that modify the data in-place (either optionally or
obligatorily). This can be advantageous when working with large datasets
because it reduces the amount of computer memory needed to perform the
computations. However, it can lead to unexpected results if you're not aware
that it's happening. This tutorial provides a few examples of in-place
processing, and how and when to avoid it.
As usual we'll start by importing the modules we need and
loading some example data &lt;sample-dataset&gt;:
End of explanation
"""


original_raw = raw.copy()
raw.apply_hilbert()
print(f'original data type was {original_raw.get_data().dtype}, after '
      f'apply_hilbert the data type changed to {raw.get_data().dtype}.')

"""
Explanation: Signal processing
Most MNE-Python data objects have built-in methods for filtering, including
high-, low-, and band-pass filters (~mne.io.Raw.filter), band-stop filters
(~mne.io.Raw.notch_filter),
Hilbert transforms (~mne.io.Raw.apply_hilbert),
and even arbitrary or user-defined functions (~mne.io.Raw.apply_function).
These typically always modify data in-place, so if we want to preserve
the unprocessed data for comparison, we must first make a copy of it. For
example:
End of explanation
"""


print(f'original data had {original_raw.info["nchan"]} channels.')
original_raw.pick('eeg')  # selects only the EEG channels
print(f'after picking, it has {original_raw.info["nchan"]} channels.')

"""
Explanation: Channel picking
Another group of methods where data is modified in-place are the
channel-picking methods. For example:
End of explanation
"""


rereferenced_raw, ref_data = mne.set_eeg_reference(original_raw, ['EEG 003'],
                                                   copy=True)
original_raw.plot()
rereferenced_raw.plot()

"""
Explanation: Note also that when picking only EEG channels, projectors that affected only
the magnetometers were dropped, since there are no longer any magnetometer
channels.
The copy parameter
Above we saw an example of using the ~mne.io.Raw.copy method to facilitate
comparing data before and after processing. This is not needed when using
certain MNE-Python functions, because they have a function parameter
where you can specify copy=True (return a modified copy of the data) or
copy=False (operate in-place). For example, mne.set_eeg_reference is
one such function; notice that here we plot original_raw after the
rereferencing has been done, but original_raw is unaffected because
we specified copy=True:
End of explanation
"""


