def PlotSelections(self, df_main, var_name, figure_path=None, figname=""):

        fig, ax = plt.subplots(figsize=[FIGURE_WIDTH, FIGURE_HEIGHT],
                               nrows=1,
                               ncols=1,
                               constrained_layout=True)
        util.PlotROIs(ax, df_main, var_name)

        if figure_path:
            util.SaveFigure(
                "{}/meter_log_disagg_{}".format(figure_path, figname), fig)
    def PlotAnalysis(self, df_cost, df_cost_agg, result_path, isfigshow=False):

        print('plot analysis....')

        util.SetFigureStyle()

        # %%
        y_vars = [
            'time_peronline_total_sec',
            'meter_time_peronline_total_sec',
            'meter_energy_nilm_wh',
            'meter_energy_bg_wh',
            'meter_energy_wh',
            # 'meter_energy_bg_dw_wh',
            'meter_power_nilm_median_w',
            'meter_power_bg_median_w',
            'meter_power_median_w',
            # 'meter_power_utilization_median_perc',
            # 'energy_house_wh'
        ]

        x_var = 'num_processes'
        hue = 'num_houses'
        for y_var in y_vars:
            fig, ax = plt.subplots()
            fig = sns.catplot(x=x_var,
                              y=y_var,
                              data=df_cost,
                              hue=hue,
                              kind="point",
                              **kws_online_2)
            filename_plot = "{}/{}_vs_{}".format(self.figure_path, x_var,
                                                 y_var)
            util.SaveFigure(filename_plot, fig, isshow=isfigshow)

        df_cost["time_peronline_total_meter_vs_sys_diff_sec"] = df_cost[
            "meter_time_peronline_total_sec"] - df_cost[
                "time_peronline_total_sec"]
        df_cost["time_peronline_total_meter_vs_sys_diff_perc"] = 100 * df_cost[
            "time_peronline_total_meter_vs_sys_diff_sec"].divide(
                df_cost["time_peronline_total_sec"], axis="index").copy()
        for y_var in [
                "time_peronline_total_meter_vs_sys_diff_sec",
                "time_peronline_total_meter_vs_sys_diff_perc"
        ]:
            fig, ax = plt.subplots()
            fig = sns.catplot(x=x_var,
                              y=y_var,
                              data=df_cost,
                              hue=hue,
                              kind="point",
                              **kws_online_2)
            filename_plot = "{}/{}_vs_{}".format(self.figure_path, x_var,
                                                 y_var)
            util.SaveFigure(filename_plot, fig, isshow=isfigshow)

        # %%
        # Normalization: perunit house

        y_vars = [
            y_var for y_var in y_vars
            if (y_var.find('power') == -1) and (y_var.find('diff') == -1)
        ]
        print('Plotting normalized per unit house values ...')

        df_cost_norm = df_cost.copy()
        norm_var = 'num_houses'
        df_cost_norm[norm_var] = df_cost_norm[norm_var].astype('float')
        for col in self.sel_cols_online[7:]:
            df_cost_norm[col] = df_cost_norm[[col]].divide(
                df_cost_norm["num_houses"], axis="index")
        df_cost_norm[norm_var] = df_cost_norm[norm_var].astype('category')

        x_var = 'num_processes'
        hue = 'num_houses'
        for y_var in y_vars:
            fig, ax = plt.subplots()
            fig = sns.catplot(x=x_var,
                              y=y_var,
                              data=df_cost_norm,
                              hue=hue,
                              kind="point",
                              **kws_online_2)
            filename_plot = "{}/{}_vs_{}_norm".format(self.figure_path, x_var,
                                                      y_var)
            util.SaveFigure(filename_plot, fig, isshow=isfigshow)

        # Variations on Experiments
        x_var = 'num_processes'
        hue = 'expId'
        col = 'num_houses'
        n_col = df_cost_norm[col].nunique()
        for y_var in y_vars:
            fig, ax = plt.subplots()
            fig = sns.catplot(x=x_var,
                              y=y_var,
                              data=df_cost_norm,
                              col=col,
                              hue=hue,
                              kind="point",
                              col_wrap=np.min([int(np.sqrt(n_col)), 4]),
                              **kws_online_2)
            filename_plot = "{}/{}_vs_{}_all_exps_norm".format(
                self.figure_path, x_var, y_var)
            util.SaveFigure(filename_plot, fig, isshow=isfigshow)
def main(result_path):
    """
    Provides visualization tools to plot the cleaned ROIs extracted by the MeterReadingROIExtractor. 
    It also maps the generic labels of the ROIs into their actual values using the monitoring setting from CostMonitor.
    """
    
    print('MeterROIExtractionPlotter...')
    
    # %% create figure directory 
    figure_path = "{}/{}".format(result_path, setting_dict["meter_log"]["figure_dir"])
    util.CreateDir(figure_path)
    
    # %% 
    ObjSeqPattern = AlgCostSignalExtractor(result_path)
        
    print('Loading experiment settings...')
    ObjSeqPattern.LoadExprimentSetting()
    exprmnt_setting_dict = ObjSeqPattern.exprmnt_setting_dict
    # util.PrintDict(exprmnt_setting_dict)

    isdays = exprmnt_setting_dict['isdays']
    disaggtimewindow = exprmnt_setting_dict['disaggtimewindow']
    num_repeated_expt = exprmnt_setting_dict['num_repeated_expt']
    num_Nh_chunks = exprmnt_setting_dict['num_Nh_chunks']
    num_Nps = exprmnt_setting_dict['num_Nps']
    Nh_chunks = exprmnt_setting_dict['Nh_chunks']
    Nps = exprmnt_setting_dict['Nps']
    init_d = exprmnt_setting_dict['init_d']
    exprmnt_d = exprmnt_setting_dict['exprmnt_d']
    Nhchunk_d = exprmnt_setting_dict['Nhchunk_d']
    Np_d = exprmnt_setting_dict['Np_d']
    onlinedw_d = exprmnt_setting_dict['onlinedw_d']
    synch_len = onlinedw_d
    num_online_chunks = 1
    
    # %% 
    print('Loading wattsup smart meter reading...')
    df_power_log, fig = ObjSeqPattern.LoadMeterPowerReading()
    df_power_log.head()
    df_power_log.shape
   
    plt.tight_layout(pad=0.3, w_pad=0.3, h_pad=0.3)
    plt.legend(ncol = 2, loc='center right',  bbox_to_anchor = (1., 1+0.1), borderaxespad=0, frameon=True )
    util.SaveFigure("{}/meter_log_bg_removed_rec".format(figure_path), fig)

    # %%
    print('Reconstructing experiments...')
    
    df_wupower_extracted = ReconstructSections(df_power_log, exprmnt_setting_dict, ObjSeqPattern.filename_meter_log_roi_uncleaned)
 
    plt.plot(df_power_log.t, df_power_log.Watts + df_power_log['Watts_bg'], label= 'Total Power')
    plt.plot(df_power_log.t, df_power_log.Watts, label= 'Dynamic Power')
    plt.xlabel('t (sec)', fontsize=FIGURE_LBL_FONTSIZE_MAIN)
    plt.ylabel('P (W)', fontsize=FIGURE_LBL_FONTSIZE_MAIN)
    util.PlotGridSpacing(df_power_log.t.values, [0, df_power_log.Watts.max() + df_power_log['Watts_bg'].max()], x_gridno=6, y_gridno=6, issnscat = True)
    plt.tight_layout(pad=0.3, w_pad=0.3, h_pad=0.3)
    plt.legend(ncol = 2, loc='center right',  bbox_to_anchor = (1., 1+0.1), borderaxespad=0, frameon=True )
    util.SaveFigure("{}/meter_log_bg_removed_rec".format(figure_path), fig)
    
    # %%
    print('Extracting NILMROI...')
    d_synch_all = init_d + exprmnt_d + Nhchunk_d + Np_d + onlinedw_d
    
    try:
        df_power_nilm, fig = ObjSeqPattern.NILMAlgROIExtraction(df_power_log.copy(), 5*d_synch_all, init_d)
    except:
        raise 'NILM section extraction error!'
    finally:
        plt.tight_layout(pad=0.3, w_pad=0.3, h_pad=0.3)
        # plt.legend(bbox_to_anchor = (1, 1.21))
        plt.legend(loc='center right',  bbox_to_anchor = (1., 1+0.1), borderaxespad=0, frameon=True)
        util.SaveFigure("{}/meter_log_alg_rec".format(figure_path), fig)

    # %%
    print('Extracting RepetitionROIs...')
    ObjSeqPattern.PlotSelections(df_wupower_extracted, 'expId', figure_path = figure_path, figname = 'all_experiments'+'_rec')
    
    # %%
    print('Extracting LoadscaleROIs...')
    df_wupower_extracted_cleaned = pd.read_csv(ObjSeqPattern.filename_meter_log_roi)
    df_wupower_extracted_cleaned.rename(columns={'P_w':'Watts', 'P_bg_w':'Watts_bg', 'NhId':'Nh', 'NpId':'Np'}, inplace=True)
    df_wupower_extracted_cleaned['Nh'] = df_wupower_extracted_cleaned['Nh'].apply(lambda x: exprmnt_setting_dict['Nh_chunks'][x])
    df_wupower_extracted_cleaned['expId'] = df_wupower_extracted_cleaned['expId'] + 1
    df_wupower_extracted = df_wupower_extracted[df_wupower_extracted.expId.isin(df_wupower_extracted_cleaned.expId.unique())]

    expIds = list(df_wupower_extracted.expId.unique())
    
    for expId in util.tqdm(expIds, ncols=100):
        # print('plotting expId: ', expId)
        df = df_wupower_extracted[(df_wupower_extracted.expId==expId)]
        ObjSeqPattern.PlotSelections(df, 'Nh', figure_path = figure_path, figname = "expId_{}_rec".format(expId))
    
    # %%
    print('Extracting MultiprocessROIs...')
    expIds = list(df_wupower_extracted.expId.unique())
    
    for expId in util.tqdm(expIds, ncols=100):
        # print('plotting expId: ', expId)
        df_exprmnt = df_wupower_extracted[(df_wupower_extracted.expId==expId)]
        Nhs = list(df_exprmnt.Nh.unique())
        
        for Nh in Nhs:
            # print('plotting Nhs: ', Nh)
            df = df_exprmnt[(df_exprmnt.Nh==Nh)]
            ObjSeqPattern.PlotSelections(df, 'Np', figure_path = figure_path, figname = "expId_{}_NhId_{}_rec".format(expId, Nh))
       
    print('Done!')
Example #4
0
    def FeatureAnalysis(self, issave=True, isfigshow=False):
        """Feature analysis such as illustrations of the monitored costs, correlations and comparison of system and meter measurements."""

        print('monitored cost dataset analysis...')
        label_fontsize = FIGURE_LBL_FONTSIZE_MAIN

        dataset = self.dataset.copy()
        dataset.sort_values(by=['Number of Houses', 'Number of Processes'],
                            ascending=True,
                            inplace=True)

        dataset["ProcTime (" + r'$\Delta$' + ")" +
                units['ProcTime_FromMeter']] = dataset[
                    'ProcTime_FromMeter'] - dataset['ProcTime_FromSystem']
        dataset["ProcTime (" + r'$\Delta$' +
                ") (%)"] = 100 * dataset["ProcTime (" + r'$\Delta$' + ")" +
                                         units['ProcTime_FromMeter']].divide(
                                             dataset["ProcTime_FromMeter"],
                                             axis="index").copy()

        if "ProcTime_FromSystem" in self.targets:
            self.targets.remove("ProcTime_FromSystem")

        # Correlation analysis
        label_vars = self.features[:]
        label_vars.extend(self.targets)
        train_data = dataset[label_vars]
        cm = train_data.corr()
        mask = np.zeros_like(cm, dtype=np.bool)
        mask[np.triu_indices_from(mask)] = True

        fig, ax = plt.subplots(figsize=(6, 6))
        fmt = '.2f'
        label_vars = [
            var + ' (target)' if var in self.targets else var + ' (feature)'
            for var in label_vars
        ]
        annot_kws = {"size": label_fontsize + 2, "ha": 'center', "va": 'top'}
        sns.heatmap(cm,
                    annot=True,
                    annot_kws=annot_kws,
                    fmt=fmt,
                    square=True,
                    cmap='coolwarm',
                    mask=mask,
                    ax=ax,
                    linewidths=0.1)
        plt.xticks(rotation=60, fontsize=label_fontsize)
        plt.yticks(rotation=0, fontsize=label_fontsize)
        ax.set_xticklabels(label_vars, fontsize=label_fontsize)
        ax.set_yticklabels(label_vars, fontsize=label_fontsize)
        ax.set_xticks(np.arange(0, len(label_vars), 1))
        ax.set_yticks(np.arange(0.5, len(label_vars), 1))
        ax.tick_params(axis='both', which='major', labelsize=label_fontsize)
        filename_plot = "{}/correlation_analysis".format(self.figure_path)
        util.SaveFigure(filename_plot, fig, isshow=isfigshow, issave=issave)

        # %% Feature analysis
        dataset['Number of Houses'] = dataset['Number of Houses'].astype('int')
        dataset['Number of Processes'] = dataset['Number of Processes'].astype(
            'int')

        y_vars = [
            "ProcTime (" + r'$\Delta$' + ")" + units['ProcTime_FromMeter'],
            "ProcTime (" + r'$\Delta$' + ") (%)"
        ]
        x_var = 'Number of Processes'
        # print(dataset[y_vars + [x_var]].groupby([x_var]).describe())
        for i, y_var in enumerate(y_vars):
            fig, ax = plt.subplots()
            fig = sns.catplot(x=x_var,
                              y=y_var,
                              kind="box",
                              data=dataset,
                              **kws_box_2)
            plt.xlabel(x_var, fontsize=label_fontsize)
            plt.ylabel(y_var, fontsize=label_fontsize)
            y_var2 = y_var
            if '%' in y_var:
                y_var2 = y_var.replace("(%)", "_perc")
            y_var2 = y_var2.replace("$", "").replace("\\", "").replace(
                "(", "").replace(")", "")

            plt.tick_params(axis='both',
                            which='major',
                            labelsize=label_fontsize)
            X, Y = dataset[x_var].values, dataset[y_var].values
            util.PlotGridSpacing(X, Y, x_gridno=8, y_gridno=6)
            filename_plot = "{}/{}_vs_{}".format(self.figure_path, x_var,
                                                 y_var2)
            util.SaveFigure(filename_plot,
                            fig,
                            isshow=isfigshow,
                            issave=issave)

        y_vars = self.targets[:]
        x_var = 'Number of Processes'
        hue = 'Number of Houses'
        for i, y_var in enumerate(y_vars):
            fig, ax = plt.subplots()
            fig = sns.catplot(kind="point",
                              x=x_var,
                              y=y_var,
                              data=dataset,
                              hue=hue,
                              linestyles=linestyles,
                              markers=filled_markers,
                              markersize=10,
                              legend=False,
                              **kws_online_2)
            # plt.legend(fontsize=label_fontsize - 1, frameon=True, framealpha=0.5, title=hue, ncol=2, loc='upper right', bbox_to_anchor=(1, 0.99))
            plt.xlabel(x_var, fontsize=label_fontsize)
            plt.ylabel(y_var + units[y_var], fontsize=label_fontsize)
            plt.tick_params(axis='both',
                            which='major',
                            labelsize=label_fontsize)
            X, Y = dataset[x_var].values, dataset[y_var].values
            util.PlotGridSpacing(X, Y, x_gridno=8, y_gridno=6)
            filename_plot = "{}/{}_vs_{}".format(self.figure_path, x_var,
                                                 y_var)
            util.SaveFigure(filename_plot,
                            fig,
                            isshow=isfigshow,
                            issave=issave)

            dataset[y_var + "_puh"] = dataset[y_var].divide(
                dataset["Number of Houses"], axis="index").copy()
            fig = sns.catplot(kind="point",
                              x=x_var,
                              y=y_var + "_puh",
                              data=dataset,
                              hue=hue,
                              linestyles=linestyles,
                              markers=filled_markers,
                              markersize=10,
                              legend=False,
                              **kws_online_2)
            plt.xlabel(x_var, fontsize=label_fontsize)
            plt.ylabel(y_var + units[y_var], fontsize=label_fontsize)
            plt.tick_params(axis='both',
                            which='major',
                            labelsize=label_fontsize)
            plt.legend(fontsize=label_fontsize - 3,
                       frameon=True,
                       framealpha=0.5,
                       title=hue,
                       ncol=2,
                       loc='upper right')
            X, Y = dataset[x_var].values, dataset[y_var + "_puh"].values
            util.PlotGridSpacing(X, Y, x_gridno=8, y_gridno=6)
            filename_plot = "{}/{}_vs_{}_puh".format(self.figure_path, x_var,
                                                     y_var)
            util.SaveFigure(filename_plot,
                            fig,
                            isshow=isfigshow,
                            issave=issave)

        # print(dataset[[y_var +"_puh" for y_var in y_vars] + [x_var]].groupby([x_var]).describe())
        y_vars = [
            'house_energy_mean_kwh', "house_energy_median_kwh",
            'house_energy_max_kwh'
        ]
        x_var = 'Number of Processes'
        hue = 'Number of Houses'
        for i, y_var in enumerate(y_vars):
            fig = sns.catplot(kind="point",
                              x=x_var,
                              y=y_var,
                              data=dataset,
                              hue=hue,
                              linestyles=linestyles,
                              markers=filled_markers,
                              markersize=10,
                              legend=False,
                              **kws_online_2)
            plt.xlabel(x_var, fontsize=label_fontsize)
            plt.ylabel(y_var, fontsize=label_fontsize)
            plt.tick_params(axis='both',
                            which='major',
                            labelsize=label_fontsize)
            plt.legend(fontsize=label_fontsize - 3,
                       frameon=True,
                       framealpha=0.5,
                       title=hue,
                       ncol=4,
                       bbox_to_anchor=(1., 1 + 0.21 * 2))
            X, Y = dataset[x_var].values, dataset[y_var].values
            util.PlotGridSpacing(X, Y, x_gridno=8, y_gridno=6)
            filename_plot = "{}/{}_vs_{}".format(self.figure_path, x_var,
                                                 y_var)
            util.SaveFigure(filename_plot,
                            fig,
                            isshow=isfigshow,
                            issave=issave)
        # print(dataset[y_vars + [x_var]].groupby([x_var]).describe())

        y_vars = ['house_energy_total_kwh']
        x_var = 'Number of Processes'
        hue = 'Number of Houses'
        for i, y_var in enumerate(y_vars):
            dataset[y_var + "_puh"] = dataset[y_var].divide(
                dataset["Number of Houses"], axis="index").copy()
            fig = sns.catplot(kind="point",
                              x=x_var,
                              y=y_var + "_puh",
                              data=dataset,
                              hue=hue,
                              linestyles=linestyles,
                              markers=filled_markers,
                              markersize=10,
                              legend=False,
                              **kws_online_2)
            plt.xlabel(x_var, fontsize=label_fontsize)
            plt.ylabel(y_var, fontsize=label_fontsize)
            plt.tick_params(axis='both',
                            which='major',
                            labelsize=label_fontsize)
            plt.legend(fontsize=label_fontsize - 3,
                       frameon=True,
                       framealpha=0.5,
                       title=hue,
                       ncol=4,
                       bbox_to_anchor=(1., 1 + 0.21 * 2))
            X, Y = dataset[x_var].values, dataset[y_var + "_puh"].values
            util.PlotGridSpacing(X, Y, x_gridno=8, y_gridno=6)
            filename_plot = "{}/{}_vs_{}_puh".format(self.figure_path, x_var,
                                                     y_var)
            util.SaveFigure(filename_plot,
                            fig,
                            isshow=isfigshow,
                            issave=issave)
def main(result_path):
    """
    Extracts the region of interest (ROI) sections of the target active algorithm hierarchicaly and recursively from system-level power readings 
    """

    print('MeterROIExtraction...')

    # %% create debug figure directory
    figure_path = "{}/{}/{}".format(
        result_path, setting_dict["meter_log"]["log_dir"],
        setting_dict["meter_log"]["debug_figure_dir"])
    util.CreateDir(figure_path)

    # %%
    ObjSeqPattern = AlgCostSignalExtractor(result_path)
    ObjSeqPattern.ResetErrorLog()

    # %%
    print('Loading experiment settings...')
    ObjSeqPattern.LoadExprimentSetting()
    exprmnt_setting_dict = ObjSeqPattern.exprmnt_setting_dict
    util.PrintDict(exprmnt_setting_dict)

    isdays = exprmnt_setting_dict['isdays']
    disaggtimewindow = exprmnt_setting_dict['disaggtimewindow']
    num_repeated_expt = exprmnt_setting_dict['num_repeated_expt']
    num_Nh_chunks = exprmnt_setting_dict['num_Nh_chunks']
    num_Nps = exprmnt_setting_dict['num_Nps']
    Nh_chunks = exprmnt_setting_dict['Nh_chunks']
    Nps = exprmnt_setting_dict['Nps']
    init_d = exprmnt_setting_dict['init_d']
    exprmnt_d = exprmnt_setting_dict['exprmnt_d']
    Nhchunk_d = exprmnt_setting_dict['Nhchunk_d']
    Np_d = exprmnt_setting_dict['Np_d']
    onlinedw_d = exprmnt_setting_dict['onlinedw_d']
    synch_len = onlinedw_d
    num_online_chunks = 1

    # %%
    print('Loading wattsup smart meter reading...')
    df_power_log, fig = ObjSeqPattern.LoadMeterPowerReading()
    util.SaveFigure("{}/meter_log_bg_removed".format(figure_path), fig)

    # %%
    print('Extracting NILMROI...')
    d_synch_all = init_d + exprmnt_d + Nhchunk_d + Np_d + onlinedw_d

    try:
        df_power_nilm, fig = ObjSeqPattern.NILMAlgROIExtraction(
            df_power_log.copy(), 5 * d_synch_all, init_d)
    except:
        raise 'NILM section extraction error!'
    finally:
        util.SaveFigure("{}/meter_log_alg".format(figure_path), fig)

    # %%
    print('Extracting RepetitionROIs...')
    d_synch_all = d_synch_all - init_d
    df_power_nilm_exprmnts = ObjSeqPattern.RepetitionROIExtraction(
        df_power_nilm.copy(), 2 * 5 * d_synch_all, exprmnt_d,
        num_repeated_expt)
    ObjSeqPattern.PlotSelections(df_power_nilm_exprmnts,
                                 'expId',
                                 figure_path=figure_path,
                                 figname='all_experiments')

    # %%
    print('Extracting LoadscaleROIs...')
    d_synch_all = d_synch_all - exprmnt_d
    df_power_nilm_Nh_chunks = ObjSeqPattern.ScaledLoadsROIExtraction(
        df_power_nilm_exprmnts.copy(), 2 * 5 * d_synch_all, Nhchunk_d,
        num_Nh_chunks)
    expIds = list(df_power_nilm_Nh_chunks["expId"].unique())

    for expId in util.tqdm(expIds, ncols=40):
        # print('plotting expId: ', expId)
        df = df_power_nilm_Nh_chunks[(
            df_power_nilm_Nh_chunks["expId"] == expId)]
        ObjSeqPattern.PlotSelections(df,
                                     'NhId',
                                     figure_path=figure_path,
                                     figname="expId_{}".format(expId))

    # %%
    print('Extracting MultiprocessROIs...')
    d_synch_all = d_synch_all - Nhchunk_d
    df_power_nilm_Nps = ObjSeqPattern.MultiProcessesROIExtraction(
        df_power_nilm_Nh_chunks, 2 * 5 * d_synch_all, Np_d, num_Nps)
    expIds = list(df_power_nilm_Nps["expId"].unique())

    for expId in util.tqdm(expIds, ncols=100):
        # print('plotting expId: ', expId)
        df_exprmnt = df_power_nilm_Nps[(df_power_nilm_Nps["expId"] == expId)]
        NhIds = list(df_exprmnt["NhId"].unique())

        for NhId in NhIds:
            # print('plotting NhId: ', NhId)
            df = df_exprmnt[(df_exprmnt["NhId"] == NhId)]
            ObjSeqPattern.PlotSelections(df,
                                         'NpId',
                                         figure_path=figure_path,
                                         figname="expId_{}_NhId_{}".format(
                                             expId, Nh_chunks[NhId]))

    # %%
    print('Extracting consumptions of the algorithm...')
    d_synch_all = d_synch_all - onlinedw_d
    df_power_nilm_Nps_online = ObjSeqPattern.OnlineLoadROIExtraction(
        df_power_nilm_Nps.copy(), d_synch_all, onlinedw_d, num_online_chunks)
    ObjSeqPattern.SaveExtractedData(df_power_nilm_Nps_online.copy(),
                                    iscleaned=0)
    expIds = list(df_power_nilm_Nps_online["expId"].unique())

    for expId in util.tqdm(expIds, ncols=100):
        # print('plotting expId: ', expId)
        df_exprmnt = df_power_nilm_Nps_online[(
            df_power_nilm_Nps_online["expId"] == expId)]
        NhIds = list(df_exprmnt["NhId"].unique())

        for NhId in NhIds:
            # print('plotting NhId: ', NhId)
            df = df_exprmnt[(df_exprmnt["NhId"] == NhId)]
            ObjSeqPattern.PlotSelections(df,
                                         'NpId',
                                         figure_path=figure_path,
                                         figname="expId_{}_NhId_{}_alg".format(
                                             expId, Nh_chunks[NhId]))

    # %%
    print('Discarding corrupted experiment sections...')
    # corrupted_expIds = ObjSeqPattern.corrupted_expIds
    df_power_nilm_Nps_online = ObjSeqPattern.DiscardCorruptedExpriments(
        df_power_nilm_Nps_online)

    # %%
    print('Saving extracted and disaggregated data...')
    ObjSeqPattern.SaveExtractedData(df_power_nilm_Nps_online)
    # %%
    print('Done!')
    def ClusterDataPoints(self, df_wupower_log):

        x = df_wupower_log['Watts_trend'].values
        y, x = np.histogram(x, bins=30, density=True)
        norm_pmf = signal.medfilt(y, kernel_size=3)
        x = x[1:]

        width = int((np.max(x) - np.min(x)) / 10)

        while True:
            try:
                valley_indexes, _ = signal.find_peaks(
                    -1 * norm_pmf)  #distance= width, width = 0.5*width
                self.synch_P_th = x[valley_indexes[0]]
                break
            except:
                width = int(width / 2)
        target_x = x[valley_indexes[0]:]
        target_norm_pmf = norm_pmf[valley_indexes[0]:]
        isvalley_indexes_adj = target_norm_pmf <= 1.10 * target_norm_pmf[0]
        self.synch_P_th = target_x[np.where(
            isvalley_indexes_adj == False)[0][0] - 1]

        isvalley_indexes_adj[np.where(
            isvalley_indexes_adj == False)[0][0]:] = False
        valley_indexes = isvalley_indexes_adj

        fig, ax = plt.subplots()
        plt.plot(x, norm_pmf)
        plt.scatter(target_x[valley_indexes],
                    target_norm_pmf[valley_indexes],
                    marker='o',
                    color='r',
                    s=100)
        plt.plot([self.synch_P_th] * 2, [0, np.max(norm_pmf)],
                 linestyle='--',
                 linewidth=2)
        plt.annotate("Decision Threshold {}".format(np.round(self.synch_P_th)),
                     xy=(self.synch_P_th, 0.5 * np.max(norm_pmf)),
                     xytext=(self.synch_P_th + 10, 0.75 * np.max(norm_pmf)),
                     bbox=dict(boxstyle="round", alpha=0.1),
                     arrowprops=dict(arrowstyle="wedge,tail_width=0.5",
                                     alpha=0.1))
        plt.xlabel('P (W)', fontsize=FIGURE_LBL_FONTSIZE_MAIN)
        plt.ylabel('PDF', fontsize=FIGURE_LBL_FONTSIZE_MAIN)
        plt.tick_params(axis='both',
                        which='major',
                        labelsize=FIGURE_LBL_FONTSIZE_MAIN)
        util.PlotGridSpacing(x, [0, np.max(norm_pmf)],
                             x_gridno=6,
                             y_gridno=6,
                             issnscat=True)
        plt.tight_layout(pad=0.3, w_pad=0.3, h_pad=0.3)

        if isdebug:
            plt.show()
        util.SaveFigure("{}/meter_log_trend_PDF".format(self.figure_path), fig)

        self.df_wupower_log[
            'isWUsynch'] = self.df_wupower_log['Watts_trend'] < self.synch_P_th
        self.df_wupower_log['isWUsynch'] = self.df_wupower_log[
            'isWUsynch'].astype('int8')

        fig, ax = plt.subplots(figsize=[FIGURE_WIDTH, FIGURE_HEIGHT * 3.1],
                               nrows=3,
                               ncols=1,
                               constrained_layout=True)

        plt.subplot(311)

        plt.plot(self.df_wupower_log.t,
                 self.df_wupower_log.Watts,
                 linestyle='-',
                 color='g',
                 label='Dynamic Power')
        plt.plot(self.df_wupower_log.t,
                 self.df_wupower_log.Watts_trend,
                 linestyle='-',
                 color='red',
                 label='Dynamic Power (Trend)')
        plt.xlabel('t (sec)', fontsize=FIGURE_LBL_FONTSIZE_MAIN)
        plt.ylabel('P (W)', fontsize=FIGURE_LBL_FONTSIZE_MAIN)
        plt.tick_params(axis='both',
                        which='major',
                        labelsize=FIGURE_LBL_FONTSIZE_MAIN)
        util.PlotGridSpacing(self.df_wupower_log.t.values,
                             [0, self.df_wupower_log.Watts.max()],
                             x_gridno=6,
                             y_gridno=6,
                             issnscat=True)
        plt.tight_layout(pad=0.3, w_pad=0.3, h_pad=0.3)
        plt.legend(ncol=2,
                   loc='center right',
                   bbox_to_anchor=(1, 1 + 0.1),
                   borderaxespad=0,
                   frameon=True)

        plt.subplot(312)

        Ids = list(self.df_wupower_log["isWUsynch"].unique())
        for Id in Ids:
            df = self.df_wupower_log[self.df_wupower_log["isWUsynch"] == Id]
            if Id == 1:
                label = 'Cluster_Lower'
                marker = 'o'
            else:
                label = 'Cluster_Upper'
                marker = '*'
            plt.scatter(df.t, df.Watts_trend, label=label, marker=marker)

        plt.axhline(y=self.synch_P_th,
                    linestyle='-',
                    color='black',
                    label="Threshold = watts".format(
                        np.round(self.synch_P_th, 0)))
        plt.plot(self.df_wupower_log.t,
                 self.df_wupower_log.Watts_trend,
                 linestyle='--',
                 color='red',
                 label='Dynamic Power (Trend)')
        plt.xlabel('t (sec)', fontsize=FIGURE_LBL_FONTSIZE_MAIN)
        plt.ylabel('P (W)', fontsize=FIGURE_LBL_FONTSIZE_MAIN)
        plt.tick_params(axis='both',
                        which='major',
                        labelsize=FIGURE_LBL_FONTSIZE_MAIN)
        util.PlotGridSpacing(self.df_wupower_log.t.values,
                             [0, self.df_wupower_log.Watts_trend.max()],
                             x_gridno=6,
                             y_gridno=6,
                             issnscat=True)
        plt.tight_layout(pad=0.3, w_pad=0.3, h_pad=0.3)
        plt.legend(ncol=2,
                   loc='center right',
                   bbox_to_anchor=(1, 1 + 0.1 * 2),
                   borderaxespad=0,
                   frameon=True)

        plt.subplot(313)

        for Id in Ids:
            df = self.df_wupower_log[self.df_wupower_log["isWUsynch"] == Id]
            if Id == 1:
                label = 'SynchPatterns'
                marker = 'o'
            else:
                label = 'Algorithm'
                marker = '*'
            plt.scatter(df.t, df.Watts, label=label, marker=marker)

        plt.plot(self.df_wupower_log.t,
                 self.df_wupower_log.Watts,
                 linestyle='-',
                 color='g',
                 label='Dynamic Power')
        plt.xlabel('t (sec)', fontsize=FIGURE_LBL_FONTSIZE_MAIN)
        plt.ylabel('P (W)', fontsize=FIGURE_LBL_FONTSIZE_MAIN)
        plt.tick_params(axis='both',
                        which='major',
                        labelsize=FIGURE_LBL_FONTSIZE_MAIN)
        util.PlotGridSpacing(self.df_wupower_log.t.values,
                             [0, self.df_wupower_log.Watts.max()],
                             x_gridno=6,
                             y_gridno=6,
                             issnscat=True)
        plt.tight_layout(pad=0.3, w_pad=0.3, h_pad=0.3)
        plt.legend(ncol=3,
                   loc='center right',
                   bbox_to_anchor=(1, 1 + 0.1),
                   borderaxespad=0,
                   frameon=True)

        if isdebug:
            plt.show()
        util.SaveFigure("{}/meter_log_clustered".format(self.figure_path), fig)

        return self.df_wupower_log