Пример #1
0
def plot_bg_cube_model_comparison(input_dir1, binning_format1, name1,
                                  input_dir2, binning_format2, name2):
    """
    Plot background cube model comparison.

    Produce a few figures for comparing 2 sets of bg cube models (1
    and 2), supposing same binning in both sets of observation
    groups (a.k.a. observation bin).

    Each figure corresponds to 1 observation group.
    Plot strategy in each figure:

    * Images:
        * rows: similar energy bin
        * cols: same bg cube model set
    * Spectra:
        * rows: similar det bin
        * cols: compare both bg cube model sets

    The script can be customized by setting a few global variables:

    * **group_ids_selection**: groups to compare; if empty: use all
      groups

    * **NORMALIZE**: normalization to use for the models. If
      activate, model 1 is normalized to match model 2. This can be
      useful, when comparing reco models w.r.t. true ones. Options:
          * *0*: do not normalize
          * *1*: normalize w.r.t. cube integral
          * *2*: normalize w.r.t images integral; each image (i.e.
            energy bin/slice) is normalized independently; this
            option can alter the spectral shape of the bg rate, but
            is is the way how smoothing method *michi* normalizes the
            background cube model, hence it is necessary to compare
            to those models that use that particular smoothing

    Parameters
    ----------
    input_dir1, input_dir2 : str
        Directory where the corresponding set of bg cube models is stored.
    binning_format1, binning_format2 : {'default', 'michi'}
        String specifying the binning format; accepted values are:

        * *default* for the Gammapy format from
          `~gammapy.data.ObservationGroups`; an observation groups
          ECVS file is expected in the bg cube models dir.
        * *michi* for the binning used by Michale Mayer;
          this script has methods to convert it to the
          *default* format.
          ref: [Mayer2015]_ (section 5.2.4)

    name1, name2 : str
        Name to use for plot labels/legends.
    """
    # check binning
    accepted_binnings = ['default', 'michi']

    if ((binning_format1 not in accepted_binnings)
            or (binning_format2 not in accepted_binnings)):
        raise ValueError("Invalid binning format: {0} or {1}".format(
            binning_format1, binning_format2))

    # convert binning, if necessary
    if binning_format1 == 'michi' or binning_format2 == 'michi':
        convert_obs_groups_binning_def_michi_to_default()

    # loop over observation groups: use binning of the 1st set to compare
    if binning_format1 == 'michi':
        observation_groups = obs_groups_michi
    else:
        observation_groups = ObservationGroups.read(
            input_dir1 + '/bg_observation_groups.ecsv')
    groups = observation_groups.list_of_groups
    print()
    print("list of groups", groups)

    for group in groups:
        print()
        print("group ", group)
        # compare only observation groups in group IDs selection
        # if empty, use all groups:
        if len(group_ids_selection) is not 0:
            groups_to_compare = group_ids_selection
        else:
            groups_to_compare = groups
        if group in groups_to_compare:
            group_info = observation_groups.info_group(group)
            print(group_info)

            # get cubes
            if binning_format1 == 'michi':
                # find corresponding ALT_ID, AZ_ID in lookup table
                i_alt, i_az = look_obs_groups_michi(group)
                filename1 = input_dir1 + '/hist_alt' + str(i_alt) + \
                            '_az' + str(i_az) + '.fits.gz'
            else:
                filename1 = input_dir1 + '/bg_cube_model_group' + str(group) + \
                            '_table.fits.gz'
            if binning_format2 == 'michi':
                # find corresponding ALT_ID, AZ_ID in lookup table
                i_alt, i_az = look_obs_groups_michi(group)
                filename2 = input_dir2 + '/hist_alt' + str(i_alt) + \
                            '_az' + str(i_az) + '.fits.gz'
            else:
                filename2 = input_dir2 + '/bg_cube_model_group' + str(group) + \
                            '_table.fits.gz'
            print('filename1', filename1)
            print('filename2', filename2)
            bg_cube_model1 = FOVCubeBackgroundModel.read(
                filename1, format='table').background_cube
            bg_cube_model2 = FOVCubeBackgroundModel.read(
                filename2, format='table').background_cube

            # normalize 1 w.r.t. 2 (i.e. true w.r.t. reco)
            if NORMALIZE == 1:
                # normalize w.r.t. cube integral
                integral1 = bg_cube_model1.integral
                integral2 = bg_cube_model2.integral
                bg_cube_model1.data *= integral2 / integral1
            elif NORMALIZE == 2:
                # normalize w.r.t images integral (normalize each image on its own)
                integral_images1 = bg_cube_model1.integral_images
                integral_images2 = bg_cube_model2.integral_images
                for i_energy in np.arange(
                        len(bg_cube_model1.energy_edges) - 1):
                    bg_cube_model1.data[i_energy] *= (
                        integral_images2 / integral_images1)[i_energy]

            # compare binning
            print("energy edges 1", bg_cube_model1.energy_edges)
            print("energy edges 2", bg_cube_model2.energy_edges)
            print("detector edges 1 Y", bg_cube_model1.coordy_edges)
            print("detector edges 2 Y", bg_cube_model2.coordy_edges)
            print("detector edges 1 X", bg_cube_model1.coordx_edges)
            print("detector edges 2 X", bg_cube_model2.coordx_edges)

            # make sure that both cubes use the same units for the plots
            bg_cube_model2.data = bg_cube_model2.data.to(
                bg_cube_model1.data.unit)

            # plot
            fig, axes = plt.subplots(nrows=2, ncols=3)
            fig.set_size_inches(30., 15., forward=True)
            plt.suptitle(group_info)

            # plot images
            #  rows: similar energy bin
            #  cols: same file
            # bg_cube_model1.plot_image(energy=Quantity(0.5, 'TeV'), ax=axes[0, 0])
            bg_cube_model1.plot_image(energy=Quantity(5., 'TeV'),
                                      ax=axes[0, 0])
            axes[0, 0].set_title("{0}: {1}".format(name1, axes[0,
                                                               0].get_title()))
            bg_cube_model1.plot_image(energy=Quantity(50., 'TeV'),
                                      ax=axes[1, 0])
            axes[1, 0].set_title("{0}: {1}".format(name1, axes[1,
                                                               0].get_title()))
            # bg_cube_model2.plot_image(energy=Quantity(0.5, 'TeV'), ax=axes[0, 1])
            bg_cube_model2.plot_image(energy=Quantity(5., 'TeV'),
                                      ax=axes[0, 1])
            axes[0, 1].set_title("{0}: {1}".format(name2, axes[0,
                                                               1].get_title()))
            bg_cube_model2.plot_image(energy=Quantity(50., 'TeV'),
                                      ax=axes[1, 1])
            axes[1, 1].set_title("{0}: {1}".format(name2, axes[1,
                                                               1].get_title()))

            # plot spectra
            #  rows: similar det bin
            #  cols: compare both files
            bg_cube_model1.plot_spectrum(coord=Angle([0., 0.], 'degree'),
                                         ax=axes[0, 2],
                                         style_kwargs=dict(color='blue',
                                                           label=name1))
            spec_title1 = axes[0, 2].get_title()
            bg_cube_model2.plot_spectrum(coord=Angle([0., 0.], 'degree'),
                                         ax=axes[0, 2],
                                         style_kwargs=dict(color='red',
                                                           label=name2))
            spec_title2 = axes[0, 2].get_title()
            if spec_title1 != spec_title2:
                s_error = "Expected same det binning, but got "
                s_error += "\"{0}\" and \"{1}\"".format(
                    spec_title1, spec_title2)
                raise ValueError(s_error)
            else:
                axes[0, 2].set_title(spec_title1)
            axes[0, 2].legend()

            bg_cube_model1.plot_spectrum(coord=Angle([2., 2.], 'degree'),
                                         ax=axes[1, 2],
                                         style_kwargs=dict(color='blue',
                                                           label=name1))
            spec_title1 = axes[1, 2].get_title()
            bg_cube_model2.plot_spectrum(coord=Angle([2., 2.], 'degree'),
                                         ax=axes[1, 2],
                                         style_kwargs=dict(color='red',
                                                           label=name2))
            spec_title2 = axes[1, 2].get_title()
            if spec_title1 != spec_title2:
                s_error = "Expected same det binning, but got "
                s_error += "\"{0}\" and \"{1}\"".format(
                    spec_title1, spec_title2)
                raise ValueError(s_error)
            else:
                axes[1, 2].set_title(spec_title1)
            axes[1, 2].legend()

            plt.draw()

            # save
            outfile = "bg_cube_model_comparison_group{}.png".format(group)
            print('Writing {}'.format(outfile))
            fig.savefig(outfile)

    plt.show()  # don't leave at the end
Пример #2
0
def plot_bg_cube_model_comparison(input_file1, name1, input_file2, name2):
    """
    Plot background cube model comparison.

    Produce a figure for comparing 2 bg cube models (1 and 2).

    Plot strategy in each figure:

    * Images:
        * rows: similar energy bin
        * cols: same bg cube model set
    * Spectra:
        * rows: similar det bin
        * cols: compare both bg cube model sets

    Parameters
    ----------
    input_file1, input_file2 : str
        File where the corresponding bg cube model is stored.
    name1, name2 : str
        Name to use for plot labels/legends.
    """
    # get cubes
    filename1 = input_file1
    filename2 = input_file2
    bg_cube_model1 = FOVCubeBackgroundModel.read(
        filename1, format='table').background_cube
    bg_cube_model2 = FOVCubeBackgroundModel.read(
        filename2, format='table').background_cube

    # normalize 1 w.r.t. 2 (i.e. true w.r.t. reco)
    # normalize w.r.t. cube integral
    integral1 = bg_cube_model1.integral
    integral2 = bg_cube_model2.integral
    bg_cube_model1.data *= integral2 / integral1

    # make sure that both cubes use the same units for the plots
    bg_cube_model2.data = bg_cube_model2.data.to(bg_cube_model1.data.unit)

    # plot
    fig, axes = plt.subplots(nrows=2, ncols=3)
    fig.set_size_inches(30., 15., forward=True)
    group_info = 'group 27: ALT = [72.0, 90.0) deg, AZ = [90.0, 270.0) deg'
    plt.suptitle(group_info)

    # plot images
    #  rows: similar energy bin
    #  cols: same file
    bg_cube_model1.plot_image(energy=Quantity(1., 'TeV'), ax=axes[0, 0])
    axes[0, 0].set_title("{0}: {1}".format(name1, axes[0, 0].get_title()))
    bg_cube_model1.plot_image(energy=Quantity(10., 'TeV'), ax=axes[1, 0])
    axes[1, 0].set_title("{0}: {1}".format(name1, axes[1, 0].get_title()))
    bg_cube_model2.plot_image(energy=Quantity(1., 'TeV'), ax=axes[0, 1])
    axes[0, 1].set_title("{0}: {1}".format(name2, axes[0, 1].get_title()))
    bg_cube_model2.plot_image(energy=Quantity(10., 'TeV'), ax=axes[1, 1])
    axes[1, 1].set_title("{0}: {1}".format(name2, axes[1, 1].get_title()))

    # plot spectra
    #  rows: similar det bin
    #  cols: compare both files
    bg_cube_model1.plot_spectrum(coord=Angle([0., 0.], 'degree'),
                                 ax=axes[0, 2],
                                 style_kwargs=dict(color='blue', label=name1))
    spec_title1 = axes[0, 2].get_title()
    bg_cube_model2.plot_spectrum(coord=Angle([0., 0.], 'degree'),
                                 ax=axes[0, 2],
                                 style_kwargs=dict(color='red', label=name2))
    spec_title2 = axes[0, 2].get_title()
    if spec_title1 != spec_title2:
        s_error = "Expected same det binning, but got "
        s_error += "\"{0}\" and \"{1}\"".format(spec_title1, spec_title2)
        raise ValueError(s_error)
    else:
        axes[0, 2].set_title(spec_title1)

    # plot normalized models on top
    plot_data_x, normed_pl = get_normed_pl(plot_data=axes[0, 2].get_lines()[0],
                                           E_0=E_REF,
                                           norm=NORM,
                                           index=INDEX)
    axes[0, 2].plot(plot_data_x,
                    normed_pl,
                    color='blue',
                    linestyle='dotted',
                    linewidth=2,
                    label='model index = {}'.format(INDEX))
    plot_data_x, normed_pl = get_normed_pl(plot_data=axes[0, 2].get_lines()[0],
                                           E_0=E_REF,
                                           norm=NORM,
                                           index=INDEX + 1)
    axes[0, 2].plot(plot_data_x,
                    normed_pl,
                    color='blue',
                    linestyle='dashed',
                    linewidth=2,
                    label='model index = {}'.format(INDEX + 1))

    axes[0, 2].legend()

    bg_cube_model1.plot_spectrum(coord=Angle([2., 2.], 'degree'),
                                 ax=axes[1, 2],
                                 style_kwargs=dict(color='blue', label=name1))
    spec_title1 = axes[1, 2].get_title()
    bg_cube_model2.plot_spectrum(coord=Angle([2., 2.], 'degree'),
                                 ax=axes[1, 2],
                                 style_kwargs=dict(color='red', label=name2))
    spec_title2 = axes[1, 2].get_title()
    if spec_title1 != spec_title2:
        s_error = "Expected same det binning, but got "
        s_error += "\"{0}\" and \"{1}\"".format(spec_title1, spec_title2)
        raise ValueError(s_error)
    else:
        axes[1, 2].set_title(spec_title1)

    # plot normalized models on top
    plot_data_x, normed_pl = get_normed_pl(plot_data=axes[1, 2].get_lines()[0],
                                           E_0=E_REF,
                                           norm=NORM,
                                           index=INDEX)
    axes[1, 2].plot(plot_data_x,
                    normed_pl,
                    color='blue',
                    linestyle='dotted',
                    linewidth=2,
                    label='model index = {}'.format(INDEX))
    plot_data_x, normed_pl = get_normed_pl(plot_data=axes[1, 2].get_lines()[0],
                                           E_0=E_REF,
                                           norm=NORM,
                                           index=INDEX + 1)
    axes[1, 2].plot(plot_data_x,
                    normed_pl,
                    color='blue',
                    linestyle='dashed',
                    linewidth=2,
                    label='model index = {}'.format(INDEX + 1))

    axes[1, 2].legend()

    plt.show()
Пример #3
0
def plot_bg_cube_model_comparison(input_dir1, binning_format1, name1,
                                  input_dir2, binning_format2, name2):
    """
    Plot background cube model comparison.

    Produce a few figures for comparing 2 sets of bg cube models (1
    and 2), supposing same binning in both sets of observation
    groups (a.k.a. observation bin).

    Each figure corresponds to 1 observation group.
    Plot strategy in each figure:

    * Images:
        * rows: similar energy bin
        * cols: same bg cube model set
    * Spectra:
        * rows: similar det bin
        * cols: compare both bg cube model sets

    The script can be customized by setting a few global variables:

    * **group_ids_selection**: groups to compare; if empty: use all
      groups

    * **NORMALIZE**: normalization to use for the models. If
      activate, model 1 is normalized to match model 2. This can be
      useful, when comparing reco models w.r.t. true ones. Options:
          * *0*: do not normalize
          * *1*: normalize w.r.t. cube integral
          * *2*: normalize w.r.t images integral; each image (i.e.
            energy bin/slice) is normalized independently; this
            option can alter the spectral shape of the bg rate, but
            is is the way how smoothing method *michi* normalizes the
            background cube model, hence it is necessary to compare
            to those models that use that particular smoothing

    Parameters
    ----------
    input_dir1, input_dir2 : str
        Directory where the corresponding set of bg cube models is stored.
    binning_format1, binning_format2 : {'default', 'michi'}
        String specifying the binning format; accepted values are:

        * *default* for the Gammapy format from
          `~gammapy.data.ObservationGroups`; an observation groups
          ECVS file is expected in the bg cube models dir.
        * *michi* for the binning used by Michale Mayer;
          this script has methods to convert it to the
          *default* format.
          ref: [Mayer2015]_ (section 5.2.4)

    name1, name2 : str
        Name to use for plot labels/legends.
    """
    # check binning
    accepted_binnings = ['default', 'michi']

    if ((binning_format1 not in accepted_binnings) or
            (binning_format2 not in accepted_binnings)):
        raise ValueError("Invalid binning format: {0} or {1}".format(binning_format1,
                                                                     binning_format2))

    # convert binning, if necessary
    if binning_format1 == 'michi' or binning_format2 == 'michi':
        convert_obs_groups_binning_def_michi_to_default()

    # loop over observation groups: use binning of the 1st set to compare
    if binning_format1 == 'michi':
        observation_groups = obs_groups_michi
    else:
        observation_groups = ObservationGroups.read(input_dir1 + '/bg_observation_groups.ecsv')
    groups = observation_groups.list_of_groups
    print()
    print("list of groups", groups)

    for group in groups:
        print()
        print("group ", group)
        # compare only observation groups in group IDs selection
        # if empty, use all groups:
        if len(group_ids_selection) is not 0:
            groups_to_compare = group_ids_selection
        else:
            groups_to_compare = groups
        if group in groups_to_compare:
            group_info = observation_groups.info_group(group)
            print(group_info)

            # get cubes
            if binning_format1 == 'michi':
                # find corresponding ALT_ID, AZ_ID in lookup table
                i_alt, i_az = look_obs_groups_michi(group)
                filename1 = input_dir1 + '/hist_alt' + str(i_alt) + \
                            '_az' + str(i_az) + '.fits.gz'
            else:
                filename1 = input_dir1 + '/bg_cube_model_group' + str(group) + \
                            '_table.fits.gz'
            if binning_format2 == 'michi':
                # find corresponding ALT_ID, AZ_ID in lookup table
                i_alt, i_az = look_obs_groups_michi(group)
                filename2 = input_dir2 + '/hist_alt' + str(i_alt) + \
                            '_az' + str(i_az) + '.fits.gz'
            else:
                filename2 = input_dir2 + '/bg_cube_model_group' + str(group) + \
                            '_table.fits.gz'
            print('filename1', filename1)
            print('filename2', filename2)
            bg_cube_model1 = FOVCubeBackgroundModel.read(filename1,
                                                         format='table').background_cube
            bg_cube_model2 = FOVCubeBackgroundModel.read(filename2,
                                                         format='table').background_cube

            # normalize 1 w.r.t. 2 (i.e. true w.r.t. reco)
            if NORMALIZE == 1:
                # normalize w.r.t. cube integral
                integral1 = bg_cube_model1.integral
                integral2 = bg_cube_model2.integral
                bg_cube_model1.data *= integral2 / integral1
            elif NORMALIZE == 2:
                # normalize w.r.t images integral (normalize each image on its own)
                integral_images1 = bg_cube_model1.integral_images
                integral_images2 = bg_cube_model2.integral_images
                for i_energy in np.arange(len(bg_cube_model1.energy_edges) - 1):
                    bg_cube_model1.data[i_energy] *= (integral_images2 / integral_images1)[i_energy]

            # compare binning
            print("energy edges 1", bg_cube_model1.energy_edges)
            print("energy edges 2", bg_cube_model2.energy_edges)
            print("detector edges 1 Y", bg_cube_model1.coordy_edges)
            print("detector edges 2 Y", bg_cube_model2.coordy_edges)
            print("detector edges 1 X", bg_cube_model1.coordx_edges)
            print("detector edges 2 X", bg_cube_model2.coordx_edges)

            # make sure that both cubes use the same units for the plots
            bg_cube_model2.data = bg_cube_model2.data.to(bg_cube_model1.data.unit)

            # plot
            fig, axes = plt.subplots(nrows=2, ncols=3)
            fig.set_size_inches(30., 15., forward=True)
            plt.suptitle(group_info)

            # plot images
            #  rows: similar energy bin
            #  cols: same file
            # bg_cube_model1.plot_image(energy=Quantity(0.5, 'TeV'), ax=axes[0, 0])
            bg_cube_model1.plot_image(energy=Quantity(5., 'TeV'), ax=axes[0, 0])
            axes[0, 0].set_title("{0}: {1}".format(name1, axes[0, 0].get_title()))
            bg_cube_model1.plot_image(energy=Quantity(50., 'TeV'), ax=axes[1, 0])
            axes[1, 0].set_title("{0}: {1}".format(name1, axes[1, 0].get_title()))
            # bg_cube_model2.plot_image(energy=Quantity(0.5, 'TeV'), ax=axes[0, 1])
            bg_cube_model2.plot_image(energy=Quantity(5., 'TeV'), ax=axes[0, 1])
            axes[0, 1].set_title("{0}: {1}".format(name2, axes[0, 1].get_title()))
            bg_cube_model2.plot_image(energy=Quantity(50., 'TeV'), ax=axes[1, 1])
            axes[1, 1].set_title("{0}: {1}".format(name2, axes[1, 1].get_title()))

            # plot spectra
            #  rows: similar det bin
            #  cols: compare both files
            bg_cube_model1.plot_spectrum(coord=Angle([0., 0.], 'degree'),
                                         ax=axes[0, 2],
                                         style_kwargs=dict(color='blue',
                                                           label=name1))
            spec_title1 = axes[0, 2].get_title()
            bg_cube_model2.plot_spectrum(coord=Angle([0., 0.], 'degree'),
                                         ax=axes[0, 2],
                                         style_kwargs=dict(color='red',
                                                           label=name2))
            spec_title2 = axes[0, 2].get_title()
            if spec_title1 != spec_title2:
                s_error = "Expected same det binning, but got "
                s_error += "\"{0}\" and \"{1}\"".format(spec_title1, spec_title2)
                raise ValueError(s_error)
            else:
                axes[0, 2].set_title(spec_title1)
            axes[0, 2].legend()

            bg_cube_model1.plot_spectrum(coord=Angle([2., 2.], 'degree'),
                                         ax=axes[1, 2],
                                         style_kwargs=dict(color='blue',
                                                           label=name1))
            spec_title1 = axes[1, 2].get_title()
            bg_cube_model2.plot_spectrum(coord=Angle([2., 2.], 'degree'),
                                         ax=axes[1, 2],
                                         style_kwargs=dict(color='red',
                                                           label=name2))
            spec_title2 = axes[1, 2].get_title()
            if spec_title1 != spec_title2:
                s_error = "Expected same det binning, but got "
                s_error += "\"{0}\" and \"{1}\"".format(spec_title1, spec_title2)
                raise ValueError(s_error)
            else:
                axes[1, 2].set_title(spec_title1)
            axes[1, 2].legend()

            plt.draw()

            # save
            outfile = "bg_cube_model_comparison_group{}.png".format(group)
            print('Writing {}'.format(outfile))
            fig.savefig(outfile)

    plt.show()  # don't leave at the end
Пример #4
0
def plot_bg_cube_model_comparison(input_file1, name1,
                                  input_file2, name2):
    """
    Plot background cube model comparison.

    Produce a figure for comparing 2 bg cube models (1 and 2).

    Plot strategy in each figure:

    * Images:
        * rows: similar energy bin
        * cols: same bg cube model set
    * Spectra:
        * rows: similar det bin
        * cols: compare both bg cube model sets

    Parameters
    ----------
    input_file1, input_file2 : str
        File where the corresponding bg cube model is stored.
    name1, name2 : str
        Name to use for plot labels/legends.
    """
    # get cubes
    filename1 = input_file1
    filename2 = input_file2
    bg_cube_model1 = FOVCubeBackgroundModel.read(filename1,
                                                 format='table').background_cube
    bg_cube_model2 = FOVCubeBackgroundModel.read(filename2,
                                                 format='table').background_cube

    # normalize 1 w.r.t. 2 (i.e. true w.r.t. reco)
    # normalize w.r.t. cube integral
    integral1 = bg_cube_model1.integral
    integral2 = bg_cube_model2.integral
    bg_cube_model1.data *= integral2 / integral1

    # make sure that both cubes use the same units for the plots
    bg_cube_model2.data = bg_cube_model2.data.to(bg_cube_model1.data.unit)

    # plot
    fig, axes = plt.subplots(nrows=2, ncols=3)
    fig.set_size_inches(30., 15., forward=True)
    group_info = 'group 27: ALT = [72.0, 90.0) deg, AZ = [90.0, 270.0) deg'
    plt.suptitle(group_info)

    # plot images
    #  rows: similar energy bin
    #  cols: same file
    bg_cube_model1.plot_image(energy=Quantity(1., 'TeV'), ax=axes[0, 0])
    axes[0, 0].set_title("{0}: {1}".format(name1, axes[0, 0].get_title()))
    bg_cube_model1.plot_image(energy=Quantity(10., 'TeV'), ax=axes[1, 0])
    axes[1, 0].set_title("{0}: {1}".format(name1, axes[1, 0].get_title()))
    bg_cube_model2.plot_image(energy=Quantity(1., 'TeV'), ax=axes[0, 1])
    axes[0, 1].set_title("{0}: {1}".format(name2, axes[0, 1].get_title()))
    bg_cube_model2.plot_image(energy=Quantity(10., 'TeV'), ax=axes[1, 1])
    axes[1, 1].set_title("{0}: {1}".format(name2, axes[1, 1].get_title()))

    # plot spectra
    #  rows: similar det bin
    #  cols: compare both files
    bg_cube_model1.plot_spectrum(coord=Angle([0., 0.], 'degree'),
                                 ax=axes[0, 2],
                                 style_kwargs=dict(color='blue',
                                                   label=name1))
    spec_title1 = axes[0, 2].get_title()
    bg_cube_model2.plot_spectrum(coord=Angle([0., 0.], 'degree'),
                                 ax=axes[0, 2],
                                 style_kwargs=dict(color='red',
                                                   label=name2))
    spec_title2 = axes[0, 2].get_title()
    if spec_title1 != spec_title2:
        s_error = "Expected same det binning, but got "
        s_error += "\"{0}\" and \"{1}\"".format(spec_title1, spec_title2)
        raise ValueError(s_error)
    else:
        axes[0, 2].set_title(spec_title1)

    # plot normalized models on top
    plot_data_x, normed_pl = get_normed_pl(plot_data=axes[0, 2].get_lines()[0],
                                           E_0=E_REF, norm=NORM, index=INDEX)
    axes[0, 2].plot(plot_data_x, normed_pl, color='blue',
                    linestyle='dotted', linewidth=2,
                    label='model index = {}'.format(INDEX))
    plot_data_x, normed_pl = get_normed_pl(plot_data=axes[0, 2].get_lines()[0],
                                           E_0=E_REF, norm=NORM, index=INDEX + 1)
    axes[0, 2].plot(plot_data_x, normed_pl, color='blue',
                    linestyle='dashed', linewidth=2,
                    label='model index = {}'.format(INDEX + 1))

    axes[0, 2].legend()

    bg_cube_model1.plot_spectrum(coord=Angle([2., 2.], 'degree'),
                                 ax=axes[1, 2],
                                 style_kwargs=dict(color='blue',
                                                   label=name1))
    spec_title1 = axes[1, 2].get_title()
    bg_cube_model2.plot_spectrum(coord=Angle([2., 2.], 'degree'),
                                 ax=axes[1, 2],
                                 style_kwargs=dict(color='red',
                                                   label=name2))
    spec_title2 = axes[1, 2].get_title()
    if spec_title1 != spec_title2:
        s_error = "Expected same det binning, but got "
        s_error += "\"{0}\" and \"{1}\"".format(spec_title1, spec_title2)
        raise ValueError(s_error)
    else:
        axes[1, 2].set_title(spec_title1)

    # plot normalized models on top
    plot_data_x, normed_pl = get_normed_pl(plot_data=axes[1, 2].get_lines()[0],
                                           E_0=E_REF, norm=NORM, index=INDEX)
    axes[1, 2].plot(plot_data_x, normed_pl, color='blue',
                    linestyle='dotted', linewidth=2,
                    label='model index = {}'.format(INDEX))
    plot_data_x, normed_pl = get_normed_pl(plot_data=axes[1, 2].get_lines()[0],
                                           E_0=E_REF, norm=NORM, index=INDEX + 1)
    axes[1, 2].plot(plot_data_x, normed_pl, color='blue',
                    linestyle='dashed', linewidth=2,
                    label='model index = {}'.format(INDEX + 1))

    axes[1, 2].legend()

    plt.show()