예제 #1
0
def spindle_number(x, sampling_frequency):
    """
    Single channel spindle detection. Returns the number of spindles in the given data
    """
    spindles = yasa.spindles_detect(x, sampling_frequency)
    if spindles is None:
        return 0
    return spindles.shape[0]
예제 #2
0
def fcn_spindle(data, sf, time, hypno):
    """Replace Visbrain built-in spindles detection by YASA algorithm.
    See http://visbrain.org/sleep.html#use-your-own-detections-in-sleep
    """
    # Apply on the full recording
    # sp = spindles_detect(data, sf)
    # NREM sleep only
    sp = spindles_detect(data, sf, hypno=hypno)
    return (sp[['Start', 'End']].values * sf).astype(int)
예제 #3
0
def compute_spindle_features(signal,
                             fs,
                             low=False,
                             ch_names=['EEG', 'EEG(sec)']):
    if low:
        thresh = {
            'rel_pow': 0.1,
            'corr': 0.5,
            'rms': 0.8
        }  # low threshold config
    else:
        thresh = {
            'rel_pow': 0.3,
            'corr': 0.68,
            'rms': 1.2
        }  # default config (real default is rms=1.5, but ok)

    if len(ch_names) == 2:
        sp = spindles_detect_multi(signal,
                                   fs,
                                   ch_names=ch_names,
                                   multi_only=False,
                                   thresh=thresh)
    else:
        sp = spindles_detect(data=signal, sf=fs, thresh=thresh)
    spindle_features = np.zeros(7)
    if sp is not None:
        spindle_features = sp[[
            'Amplitude', 'RMS', 'AbsPower', 'RelPower', 'Oscillations'
        ]].mean().values
        if len(ch_names) == 2:
            num_spindles_0 = np.array(
                [sp.loc[sp.Channel == 'EEG', 'Channel'].shape[0]])
            num_spindles_1 = np.array(
                [sp.loc[sp.Channel == 'EEG(sec)', 'Channel'].shape[0]])
        else:
            num_spindles_0 = np.array([sp.shape[0]])
            num_spindles_1 = 0
        spindle_features = np.append(spindle_features,
                                     np.append(num_spindles_0, num_spindles_1))
    return spindle_features
def get_spindle_templates(signal, cam=None, fs=125, sec_before=5., sec_after=5., num_ch=2, random=False, noise_inter=0):
    cam_time_intrp = np.arange(signal.shape[1]) * 1 / fs
    cam_intrp = np.interp(cam_time_intrp, np.arange(cam.shape[0]) / (cam.shape[0] / (signal.shape[1] / fs)), cam)
    assert(cam_intrp.shape[0] == 2400)  # just checking
    cam_templates = []
    # thresh = {'rel_pow': 0.1, 'corr': 0.5, 'rms': 0.8}
    thresh = {'rel_pow': 0.3, 'corr': 0.68, 'rms': 1.5}

    if num_ch == 1:
        sp = spindles_detect(signal, fs, thresh=thresh)
    else:
        sp = spindles_detect_multi(signal, fs, multi_only=False, thresh=thresh, ch_names=['EEG', 'EEG(sec)'])

    if sp is not None:
        sp_starts = df_to_event_start(df=sp, signal=signal, fs=fs, num_ch=num_ch)

        sp_starts = replace_starts_with_random(random=random, starts=sp_starts, sec_before=sec_before,
                                               sec_after=sec_after, fs=fs, signal_len=cam_intrp.shape[0],noise_inter=noise_inter)
        cam_templates = indices_to_templates(cam_intrp, indices=sp_starts, sec_before=sec_before, sec_after=sec_after, fs=fs)

    return cam_templates
예제 #5
0
raw = mne.io.read_raw_edf('Land_Scoring_6_excerpt.edf', preload=True, exclude=['MagZ'])
# raw.resample(100)                      # Downsample the data to 100 Hz
# raw.filter(0.1, 40)                    # Apply a bandpass filter from 0.1 to 40 Hz
# raw.pick_channels(['C4-A1', 'C3-A2'])  # Select a subset of EEG channels
raw # Outputs summary data about file

#Inspect Data
print('The channels are:', raw.ch_names)
print('The sampling frequency is:', raw.info['sfreq'])

# Let's now load the human-scored hypnogram, where each value represents a 30-sec epoch.
# hypno = np.loadtxt('sub-02_hypno_30s.txt', dtype=str)
# hypno

# Apply the detection using yasa.spindles_detect
sp = yasa.spindles_detect(raw)

# Display the results using .summary()
sp.summary()


# We first need to specify the channel names and, optionally, the age and sex of the participant
# - "raw" is the name of the variable containing the polysomnography data loaded with MNE.
# - "eeg_name" is the name of the EEG channel, preferentially a central derivation (e.g. C4-M1). This is always required to run the sleep staging algorithm.
# - in my case will set "eeg_name" to "LEEG3_Ch12"
# - "eog_name" is the name of the EOG channel (e.g. LOC-M1). This is optional.
# - in my case will set "eog_name" to "LEOG_Ch2"
# - "emg_name" is the name of the EOG channel (e.g. EMG1-EMG3). This is optional.
# - in my case will set "emg_name" to "LEMG_Ch5"
# - "metadata" is a dictionary containing the age and sex of the participant. This is optional.
sls = yasa.SleepStaging(raw, eeg_name="LEEG3_Ch12", eog_name="LEOG_Ch2", emg_name="LEMG_Ch5", metadata=dict(age=1.8, male=False))
예제 #6
0
def main():
    count = 600
    sn = socket.socket()
    hostn = 'localhost'
    portn = 14564
    sn.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sn.bind((hostn, portn))
    print('Server Started')
    sn.listen(5)
    cn, addrn = sn.accept()
    print('Got connection from', addrn)

    mapping = {0: 'Wake', 1: 'N1', 2: 'N2', 3: 'N3', 4: 'REM'}
    # hyp = {0: 4, 1: 2, 2: 1, 3: 0, 4: 3}
    channels = {
        0: 'EEG-FPZ-CZ',
        1: 'EEG-PZ-OZ',
        2: 'EOG',
        3: 'Resp-Oro-Nasal',
        4: 'EMG',
        5: 'Temp'
    }

    npz_file = 'SleepEDF_NPZ/SC4001E0.npz'
    with np.load(npz_file) as f:
        data = f["x"]
        labels = f["y"]

    save_path = 'data/epoch_custom.npz'

    save_dict = {"x": data[count, :, :], "y": labels[count]}

    np.savez(save_path, **save_dict)

    rt = RepeatedTimer(30, func, qu)  # it auto-starts, no need of rt.start()
    while True:
        print("Epoch Number: ", count)
        save_dict = {'x': data[count, :, :], 'y': labels[count]}
        np.savez(save_path, **save_dict)
        dict_temp = qu.get()

        grads = dict_temp["grads"]
        sleepstage = dict_temp["Y_pred"]
        print(sleepstage)

        json_data = data[count, :, :]

        from datetime import datetime
        now = datetime.now()
        print("now =", now)

        root_time = strftime("%b-%d-%Y %H:%M")

        just_time = strftime("%H:%M:%S")

        json_data_eeg_fpzcz = np.transpose(np.transpose(json_data)[0][:][:])
        json_data_eeg_pzoz = np.transpose(np.transpose(json_data)[1][:][:])

        json_data_eeg_fpzcz = json_data_eeg_fpzcz.reshape(3000, )
        json_data_eeg_pzoz = json_data_eeg_pzoz.reshape(3000, )

        plt.specgram(json_data_eeg_fpzcz, Fs=100, cmap='viridis')
        plt.ylabel('Frequency [Hz]')
        plt.xlabel('Time [sec]')
        plt.savefig('../frontend/views/eeg_fpzcz_specgram.png',
                    bbox_inches='tight')

        sf = 100
        # Define window length (4 seconds)
        win = 4 * sf

        # Apply the detection using yasa.spindles_detect
        sp = yasa.spindles_detect(json_data_eeg_fpzcz, sf)

        sw = sw_detect(json_data_eeg_fpzcz,
                       sf,
                       include=(2, 3),
                       freq_sw=(0.3, 2),
                       dur_neg=(0.3, 1.5),
                       dur_pos=(0.1, 1),
                       amp_neg=(40, 300),
                       amp_pos=(10, 150),
                       amp_ptp=(75, 400),
                       remove_outliers=False,
                       coupling=False,
                       freq_sp=(12, 16))

        if sp is None:
            mask_spindles = np.zeros(len(json_data_eeg_fpzcz))
        else:
            mask_spindles = sp.get_mask()

        spindles_highlight = json_data_eeg_fpzcz * mask_spindles
        spindles_highlight[spindles_highlight == 0] = np.nan

        if sw is None:
            mask_sw = np.zeros(len(json_data_eeg_fpzcz))
        else:
            mask_sw = sw.get_mask()

        sw_highlight = json_data_eeg_fpzcz * mask_sw
        sw_highlight[sw_highlight == 0] = np.nan

        all_rows = []
        for i in range(len(json_data_eeg_fpzcz)):
            current_time = root_time + ':{}:{}0'.format(
                str(math.floor(i / 100)).zfill(2),
                str(math.floor(i % 100)).zfill(2))
            current_time = "{}".format(current_time).replace('\'', '')
            row = {}
            row["date"] = current_time
            row["EEG_FPZ_CZ"] = json_data_eeg_fpzcz[i]
            if (np.isnan(spindles_highlight[i])):
                row["EEG_FPZ_CZ_Spindle"] = None
            else:
                row["EEG_FPZ_CZ_Spindle"] = json_data_eeg_fpzcz[i]

            if (np.isnan(sw_highlight[i])):
                row["EEG_FPZ_CZ_Slow Waves"] = None
            else:
                row["EEG_FPZ_CZ_Slow Waves"] = json_data_eeg_fpzcz[i]
            all_rows.append(row)

        with open('../frontend/data/EEG-FPZ-CZ.json', 'w') as f:
            f.write(str(all_rows).replace('\'', '"').replace('None', 'null'))

        # Apply the detection using yasa.spindles_detect
        sp = yasa.spindles_detect(json_data_eeg_pzoz, sf)

        sw = sw_detect(json_data_eeg_pzoz,
                       sf,
                       include=(2, 3),
                       freq_sw=(0.3, 2),
                       dur_neg=(0.3, 1.5),
                       dur_pos=(0.1, 1),
                       amp_neg=(40, 300),
                       amp_pos=(10, 150),
                       amp_ptp=(75, 400),
                       remove_outliers=False,
                       coupling=False,
                       freq_sp=(12, 16))

        if sp is None:
            mask_spindles = np.zeros(len(json_data_eeg_pzoz))
        else:
            mask_spindles = sp.get_mask()

        spindles_highlight = json_data_eeg_pzoz * mask_spindles
        spindles_highlight[spindles_highlight == 0] = np.nan

        if sw is None:
            mask_sw = np.zeros(len(json_data_eeg_pzoz))
        else:
            mask_sw = sw.get_mask()

        sw_highlight = json_data_eeg_pzoz * mask_sw
        sw_highlight[sw_highlight == 0] = np.nan

        all_rows = []
        for i in range(len(json_data_eeg_pzoz)):
            current_time = root_time + ':{}:{}0'.format(
                str(math.floor(i / 100)).zfill(2),
                str(math.floor(i % 100)).zfill(2))
            current_time = "{}".format(current_time).replace('\'', '')
            row = {}
            row["date"] = current_time
            row["EEG_PZ_OZ"] = json_data_eeg_pzoz[i]
            if (np.isnan(spindles_highlight[i])):
                row["EEG_PZ_OZ_Spindle"] = None
            else:
                row["EEG_PZ_OZ_Spindle"] = json_data_eeg_pzoz[i]

            if (np.isnan(sw_highlight[i])):
                row["EEG_PZ_OZ_Slow Waves"] = None
            else:
                row["EEG_PZ_OZ_Slow Waves"] = json_data_eeg_pzoz[i]
            all_rows.append(row)

        with open('../frontend/data/EEG-PZ-OZ.json', 'w') as f:
            f.write(str(all_rows).replace('\'', '"').replace('None', 'null'))

        # EEG-FPZ-CZ-Grad
        all_rows = []
        for i in range(len(json_data_eeg_fpzcz)):
            current_time = root_time + ':{}:{}0'.format(
                str(math.floor(i / 100)).zfill(2),
                str(math.floor(i % 100)).zfill(2))
            current_time = "{}".format(current_time).replace('\'', '')
            row = {}
            row["date"] = current_time
            row["EEG-FPZ-CZ"] = json_data_eeg_fpzcz[i]
            if (grads[0, i] < 0.15):
                row["EEG-FPZ-CZ-Grad"] = None
            else:
                row["EEG-FPZ-CZ-Grad"] = json_data_eeg_fpzcz[i]

            all_rows.append(row)

        with open('../frontend/data/EEG-FPZ-CZ-Grad.json', 'w') as f:
            f.write(str(all_rows).replace('\'', '"').replace('None', 'null'))

        # EEG-PZ-OZ-Grad
        all_rows = []
        for i in range(len(json_data_eeg_pzoz)):
            current_time = root_time + ':{}:{}0'.format(
                str(math.floor(i / 100)).zfill(2),
                str(math.floor(i % 100)).zfill(2))
            current_time = "{}".format(current_time).replace('\'', '')
            row = {}
            row["date"] = current_time
            row["EEG-PZ-OZ"] = json_data_eeg_pzoz[i]
            if (grads[0, i] < 0.15):
                row["EEG-PZ-OZ-Grad"] = None
            else:
                row["EEG-PZ-OZ-Grad"] = json_data_eeg_pzoz[i]

            all_rows.append(row)

        with open('../frontend/data/EEG-PZ-OZ-Grad.json', 'w') as f:
            f.write(str(all_rows).replace('\'', '"').replace('None', 'null'))

        #Other channel grads
        for index in range(2, 6):
            json_data_tmp = np.transpose(np.transpose(json_data)[index][:][:])
            json_data_tmp = json_data_tmp.reshape(3000, )

            all_rows = []
            for i in range(len(json_data_tmp)):
                current_time = root_time + ':{}:{}0'.format(
                    str(math.floor(i / 100)).zfill(2),
                    str(math.floor(i % 100)).zfill(2))
                current_time = "{}".format(current_time).replace('\'', '')
                row = {}
                row["date"] = current_time
                row[channels[index]] = json_data_tmp[i]
                if (grads[0, i] < 0.15):
                    row[channels[index] + "-Grad"] = None
                else:
                    row[channels[index] + "-Grad"] = json_data_tmp[i]
                all_rows.append(row)

            with open('../frontend/data/' + channels[index] + '-Grad.json',
                      'w') as f:
                f.write(
                    str(all_rows).replace('\'', '"').replace('None', 'null'))

        #Normal non-EEG channels
        for index in range(2, 6):
            json_data_tmp = np.transpose(np.transpose(json_data)[index][:][:])
            json_data_tmp = json_data_tmp.reshape(3000, )

            all_rows = []
            for i in range(len(json_data_tmp)):
                current_time = root_time + ':{}:{}0'.format(
                    str(math.floor(i / 100)).zfill(2),
                    str(math.floor(i % 100)).zfill(2))
                current_time = "{}".format(current_time).replace('\'', '')
                row = {}
                row["date"] = current_time
                row[channels[index]] = json_data_tmp[i]
                all_rows.append(row)

            with open('../frontend/data/' + channels[index] + '.json',
                      'w') as f:
                f.write(
                    str(all_rows).replace('\'', '"').replace('None', 'null'))

        psd, freqs = psd_array_multitaper(json_data_eeg_fpzcz,
                                          sf,
                                          normalization='full',
                                          verbose=0)

        all_rows = []
        for i in range(len(freqs[:1801])):  #Upto 60Hz (Elaborate)
            row = {}
            row["Frequencies"] = freqs[i]
            row["PSD"] = psd[i]
            all_rows.append(row)

        with open('../frontend/data/PSD-FPZCZ.json', 'w') as f:
            f.write(str(all_rows).replace('\'', '"'))

        psd, freqs = psd_array_multitaper(json_data_eeg_pzoz,
                                          sf,
                                          normalization='full',
                                          verbose=0)

        all_rows = []
        for i in range(len(freqs[:1801])):
            row = {}
            row["Frequencies"] = freqs[i]
            row["PSD"] = psd[i]
            all_rows.append(row)

        with open('../frontend/data/PSD-PZOZ.json', 'w') as f:
            f.write(str(all_rows).replace('\'', '"'))

        from scipy.fftpack import rfft, rfftfreq
        SAMPLE_RATE = 100
        DURATION = 30

        # Number of samples in normalized_tone
        N = SAMPLE_RATE * DURATION

        yf = rfft(json_data_eeg_fpzcz)
        xf = rfftfreq(N, 1 / SAMPLE_RATE)

        all_rows = []
        for i in range(len(xf)):
            row = {}
            row["x"] = xf[i]
            row["y"] = np.abs(yf[i])
            all_rows.append(row)

        with open('../frontend/data/FFT-FPZCZ.json', 'w') as f:
            f.write(str(all_rows).replace('\'', '"'))

        count_json = {}
        count_json["data"] = count

        with open('../frontend/data/count.json', 'w') as f:
            f.write(str(count_json).replace('\'', '"'))

        print("Sleepstage: ", mapping[sleepstage])

        row = {}
        row["time"] = just_time
        row["stage"] = sleepstage + 1
        print(row)
        with open('../frontend/data/sleepstage.json', 'w') as f:
            f.write(str(row).replace('\'', '"'))

        # nodeserv(hyp[int(sleepstage)], cn)
        nodeserv(int(sleepstage), cn)
        count += 1
        qu.task_done()

    try:
        sleep(150)  # your long-running job goes here
    finally:
        rt.stop(
        )  # better in a try/finally block to make sure the program ends
예제 #7
0
def find_spindles(data, fs):
    return yasa.spindles_detect(data, fs)
def find_spindles(data, fs, thresh={'rel_pow': 0.2, 'corr': 0.65, 'rms': 1.5}):
    return yasa.spindles_detect(data, fs, thresh = thresh)
    # Define sampling frequency and time vector
    sf = 1000.
    times = np.arange(data.size) / sf

    # # Plot the signal
    # fig, ax = plt.subplots(1, 1, figsize=(14, 4))
    # plt.plot(times, data, lw=1.5, color='k')
    # plt.xlabel('Time (seconds)')
    # plt.ylabel('Amplitude (uV)')
    # plt.xlim([times.min(), times.max()])
    # plt.title('LFP NREM epoch')
    # sns.despine()

    if data.size > sf:
        sp = yasa.spindles_detect(data, sf)
    else:
        print('Short epoch')
        sp = None

    if sp is not None:
        ajalas[0, x] = 1
        #  averout[x,0]=sp.get_mask()
        summary = sp.summary()
        ch = pd.DataFrame(summary).to_numpy()

        averout[x, 0] = ch
    else:
        averout[x, 0] = []

scipy.io.savemat('YASA_PAR_spindles.mat', {'averout': averout})
def plot_cam(saved_model_name,
             signal_name,
             plot_inds,
             test_loader,
             model,
             cam_target,
             label='normal',
             use_grad_cam=False,
             use_relu=True,
             grad_weight=True,
             ds=False):

    label_lookup = ['Wake', 'N1', 'N2', 'N3', 'REM']

    if ds:
        fs = 80  # [Hz]
        signal_len = 2400
        conv0_len = 2700  # signal_len / 2
    else:
        fs = 125  # [Hz]
        signal_len = 15000
        conv0_len = 1875  # signal_len/(2**3)

    time_series, true_label, name = test_loader.dataset[0]
    time_series_tensor = torch.reshape(torch.tensor(time_series),
                                       (1, 2, signal_len)).to("cpu")
    raise NotImplementedError  # this is not updated..
    feature_tensor = torch.zeros(1)  # todo: fix for real features
    logits, cam, _ = model(time_series_tensor, feature_tensor)

    if use_grad_cam:
        logits[:, cam_target].backward()
        gradients = model.get_activations_gradient()
        pooled_gradients = torch.mean(gradients, dim=[0, 2])
        activations = model.get_activations().detach()
        if grad_weight:  # weight by gradients
            for i in range(activations.shape[1]):  # change to torch.mm later
                activations[:, i, :] *= pooled_gradients[i]
        grad_cam = torch.mean(activations, dim=1).squeeze()
        if use_relu:
            grad_cam = np.maximum(grad_cam, 0)
            grad_cam /= torch.max(grad_cam)
        else:
            grad_cam = (grad_cam - torch.min(grad_cam)) / (
                torch.max(grad_cam) - torch.min(grad_cam))

        cam = grad_cam.numpy()
    else:
        cam = np.squeeze(cam.detach().numpy())[cam_target, :]
        # Clip signal to baseline
        # cam = np.maximum(cam, Counter(cam).most_common(1)[0][0])
        # cam = (cam - min(cam)) / (max(cam) - min(cam))

    logits = np.squeeze(logits.detach().numpy())

    # The following is from Seb's plot_class_activation_map and plot_class_activation_map_template

    cam_time = np.arange(cam.shape[0]) / (cam.shape[0] / 120)
    cam_time_intrp = np.arange(time_series.shape[1]) * 1 / fs
    cam_intrp = np.interp(cam_time_intrp, cam_time, cam)

    # relevant slice
    before = 60
    after = 30
    # time_series = time_series[:, int(before*fs): int(-after*fs)]
    # cam_intrp = cam_intrp[int(before*fs):int(-after*fs)]

    time_series_filt = time_series
    time_series_filt_ts = np.arange(time_series_filt.shape[1]) * 1 / fs

    cam_filt = cam_intrp
    prob = np.exp(logits) / sum(np.exp(logits))

    sp1 = spindles_detect(time_series_filt[0, :], fs)
    if sp1 is not None:
        bool_spindles1 = get_bool_vector(time_series_filt[0, :], fs, sp1)
        spindles_highlight1 = time_series_filt[0, :] * bool_spindles1
        spindles_highlight1[spindles_highlight1 == 0] = np.nan
        spindles_highlight1 = spindles_highlight1[:-1]

    sp2 = spindles_detect(time_series_filt[1, :], fs)
    if sp2 is not None:
        bool_spindles2 = get_bool_vector(time_series_filt[1, :], fs, sp2)
        spindles_highlight2 = time_series_filt[1, :] * bool_spindles2
        spindles_highlight2[spindles_highlight2 == 0] = np.nan
        spindles_highlight2 = spindles_highlight2[:-1]

    # plt.figure(figsize=(14, 4))
    # plt.plot(times, data, 'k')
    # plt.plot(times, spindles_highlight, 'indianred')

    # Setup figure
    fig = plt.figure(figsize=(15, 10))
    fig.subplots_adjust(wspace=0, hspace=0)
    ax1 = plt.subplot2grid((3, 5), (0, 0), colspan=5)
    ax2 = plt.subplot2grid((3, 5), (1, 0), colspan=5)
    ax3 = plt.subplot2grid((3, 5), (2, 0), colspan=5)

    class_target_dict = {0: 'Wake', 1: 'N1', 2: 'N2', 3: 'N3', 4: 'REM'}
    title = f'{signal_name}'

    ax1.set_title(
        title + '\n'
        f'Truth: {label}' + '\n' +
        f'Predicted Label: {label_lookup[np.squeeze(np.argmax(logits))]}  ' +
        str(np.round(prob[np.squeeze(np.argmax(logits))], 2)),
        fontsize=20,
        y=1.03)

    idx1 = plot_inds[0]
    idx2 = plot_inds[1] if plot_inds[1] < time_series_filt_ts.shape[
        0] else time_series_filt_ts.shape[0] - 1

    # Plot image
    ax1.plot(time_series_filt_ts[idx1:idx2],
             time_series_filt[0, idx1:idx2],
             '-k',
             lw=1.5)
    if sp1 is not None:
        ax1.plot(time_series_filt_ts[idx1:idx2], spindles_highlight1,
                 'indianred')
    ax1.set_ylabel('Normalized Amplitude', fontsize=22)
    ax1.set_xlim([time_series_filt_ts[idx1], time_series_filt_ts[idx2].max()])
    ax1.tick_params(labelbottom='off')
    ax1.yaxis.set_tick_params(labelsize=16)

    ax2.plot(time_series_filt_ts[idx1:idx2],
             time_series_filt[1, idx1:idx2],
             '-k',
             lw=1.5)
    if sp2 is not None:
        ax2.plot(time_series_filt_ts[idx1:idx2], spindles_highlight2,
                 'indianred')
    ax2.set_ylabel('Normalized Amplitude', fontsize=22)
    ax2.set_xlim([time_series_filt_ts[idx1], time_series_filt_ts[idx2].max()])
    ax2.tick_params(labelbottom='off')
    ax2.yaxis.set_tick_params(labelsize=16)

    # Plot CAM
    ax3.plot(time_series_filt_ts[idx1:idx2], cam_filt[idx1:idx2], '-k', lw=1.5)
    ax3.set_xlabel('Time, seconds', fontsize=22)
    ax3.set_ylabel('Class Activation Map', fontsize=22)
    ax3.set_xlim([time_series_filt_ts[idx1], time_series_filt_ts[idx2].max()])
    # ax2.set_ylim([cam_filt.min()-0.05, cam_filt.max()+0.05])
    ax3.xaxis.set_tick_params(labelsize=16)
    ax3.yaxis.set_tick_params(labelsize=16)

    plt.show()