def convert_obs_groups_binning_def_michi_to_default():
    """Convert observation groups binning definition "michi" to "default".
    """
    # observation groups binning definition "michi"

    # alt az bin edges definitions
    altitude_edges = Angle([0, 20, 23, 27, 30, 33, 37, 40, 44, 49, 53, 58, 64, 72, 90], 'degree')
    azimuth_edges = Angle([-90, 90, 270], 'degree')

    # convert observation groups binning definition "michi" to "default"

    list_obs_group_axis = [ObservationGroupAxis('ALT', altitude_edges, 'bin_edges'),
                           ObservationGroupAxis('AZ', azimuth_edges, 'bin_edges')]
    obs_groups_michi = ObservationGroups(list_obs_group_axis)
    print("Observation groups 'michi':")
    print(obs_groups_michi.obs_groups_table)
    # save
    outfile = 'bg_observation_groups_michi.ecsv'
    print('Writing {}'.format(outfile))
    obs_groups_michi.write(outfile)

    # lookup table: equivalences in group/file naming "defualt" <-> "michi"
    # 3 columns: GROUP_ID, ALT_ID, AZ_ID
    # 28 rows: 1 per GROUP_ID

    lookup_obs_groups_michi = Table()
    n_cols = 1 + len(list_obs_group_axis)
    n_rows = obs_groups_michi.n_groups
    lookup_obs_groups_michi['GROUP_ID'] = np.zeros(n_rows, dtype=np.int)
    lookup_obs_groups_michi['ALT_ID'] = np.zeros(n_rows, dtype=np.int)
    lookup_obs_groups_michi['AZ_ID'] = np.zeros(n_rows, dtype=np.int)

    # loop over each observation group axis
    count_groups = 0
    for alt_id in np.arange(len(altitude_edges) - 1):
        for az_id in np.arange(len(azimuth_edges) - 1):
            lookup_obs_groups_michi['GROUP_ID'][count_groups] = count_groups
            lookup_obs_groups_michi['ALT_ID'][count_groups] = alt_id
            lookup_obs_groups_michi['AZ_ID'][count_groups] = az_id
            count_groups += 1

    print("lookup table:")
    print(lookup_obs_groups_michi)

    # save
    outfile = 'lookup_obs_groups_michi.ecsv'
    print('Writing {}'.format(outfile))
    # `~astropy.io.ascii` always overwrites the file
    ascii.write(lookup_obs_groups_michi, outfile,
                format='ecsv', fast_writer=False)
def create_dummy_observation_grouping():
    """Define dummy observation grouping.

    Define an observation grouping with only one group.

    Returns
    -------
    obs_groups : `~gammapy.obsObservationGroups`
        Observation grouping.
    """
    alt_axis = ObservationGroupAxis("ALT", ALT_RANGE, "bin_edges")
    az_axis = ObservationGroupAxis("AZ", AZ_RANGE, "bin_edges")
    obs_groups = ObservationGroups([alt_axis, az_axis])
    obs_groups.obs_groups_table["GROUP_ID"][0] = GROUP_ID

    return obs_groups
def plot_bg_cube_model_comparison():
    """
    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:

    * **input_dir1**, **input_dir2**: directory where the
      corresponding set of bg cube models is stored.

    * **binning_format1**, **binning_format2**: binning format;
      accepted values are:
          * *default* for the Gammapy format from
            `~gammapy.obs.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)

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

    * **SAVE**: set to 1 (True) to save the output:
          * comparison plots as png
          * *michi* binning groups and lookup as ECVS files

    * **GRAPH_DEBUG**: if set to 1 (True) the program waits between
      each observation group iteration until the image is closed
    """
    # 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))

    # 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 = CubeBackgroundModel.read(filename1,
                                                      format='table').background_cube
            bg_cube_model2 = CubeBackgroundModel.read(filename2,
                                                      format='table').background_cube

            # 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("model 1: {}".format(axes[0, 0].get_title()))
            bg_cube_model1.plot_image(energy=Quantity(50., 'TeV'), ax=axes[1, 0])
            axes[1, 0].set_title("model 1: {}".format(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("model 2: {}".format(axes[0, 1].get_title()))
            bg_cube_model2.plot_image(energy=Quantity(50., 'TeV'), ax=axes[1, 1])
            axes[1, 1].set_title("model 2: {}".format(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='model 1'))
            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='model 2'))
            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='model 1'))
            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='model 2'))
            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()

            if GRAPH_DEBUG:
                plt.show() # wait until image is closed

            if SAVE:
                outfile = "bg_cube_model_comparison_alt{0}_az{1}.png".format(i_alt,
                                                                             i_az)
                print('Writing {}'.format(outfile))
                fig.savefig(outfile)

    plt.show() # don't leave at the end
# "michi" alt az bin IDs:
#  - alt_bin_ids_selection = [7, 10, 13]
#  - az_bin_ids_selection = [0, 1]
group_ids_selection = [14, 15, 20, 21, 26, 27]

# observation groups binning definition "michi"

# alt az bin edges definitions
altitude_edges = Angle([0, 20, 23, 27, 30, 33, 37, 40, 44, 49, 53, 58, 64, 72, 90], 'degree')
azimuth_edges = Angle([-90, 90, 270], 'degree')

# convert observation groups binning definition "michi" to "default"

list_obs_group_axis = [ObservationGroupAxis('ALT', altitude_edges, 'bin_edges'),
                       ObservationGroupAxis('AZ', azimuth_edges, 'bin_edges')]
obs_groups_michi = ObservationGroups(list_obs_group_axis)
print("Observation groups 'michi':")
print(obs_groups_michi.obs_groups_table)
if SAVE:
    outfile = 'bg_observation_groups_michi.ecsv'
    print('Writing {}'.format(outfile))
    obs_groups_michi.write(outfile)

# lookup table: equivalences in group/file naming "defualt" <-> "michi"
# 3 columns: GROUP_ID, ALT_ID, AZ_ID
# 28 rows: 1 per GROUP_ID

lookup_obs_groups_michi = Table()
n_cols = 1 + len(list_obs_group_axis)
n_rows = obs_groups_michi.n_groups
lookup_obs_groups_michi['GROUP_ID'] = np.zeros(n_rows, dtype=np.int)
Exemplo n.º 5
0
def plot_bg_cube_model_comparison():
    """
    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:

    * **input_dir1**, **input_dir2**: directory where the
      corresponding set of bg cube models is stored.

    * **binning_format1**, **binning_format2**: binning format;
      accepted values are:
          * *default* for the Gammapy format from
            `~gammapy.obs.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)

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

    * **SAVE**: set to 1 (True) to save the output:
          * comparison plots as png
          * *michi* binning groups and lookup as ECVS files

    * **GRAPH_DEBUG**: if set to 1 (True) the program waits between
      each observation group iteration until the image is closed
    """
    # 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))

    # 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 = CubeBackgroundModel.read(
                filename1, format='table').background_cube
            bg_cube_model2 = CubeBackgroundModel.read(
                filename2, format='table').background_cube

            # 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("model 1: {}".format(axes[0, 0].get_title()))
            bg_cube_model1.plot_image(energy=Quantity(50., 'TeV'),
                                      ax=axes[1, 0])
            axes[1, 0].set_title("model 1: {}".format(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("model 2: {}".format(axes[0, 1].get_title()))
            bg_cube_model2.plot_image(energy=Quantity(50., 'TeV'),
                                      ax=axes[1, 1])
            axes[1, 1].set_title("model 2: {}".format(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='model 1'))
            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='model 2'))
            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='model 1'))
            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='model 2'))
            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()

            if GRAPH_DEBUG:
                plt.show()  # wait until image is closed

            if SAVE:
                outfile = "bg_cube_model_comparison_alt{0}_az{1}.png".format(
                    i_alt, i_az)
                print('Writing {}'.format(outfile))
                fig.savefig(outfile)

    plt.show()  # don't leave at the end
Exemplo n.º 6
0
group_ids_selection = [14, 15, 20, 21, 26, 27]

# observation groups binning definition "michi"

# alt az bin edges definitions
altitude_edges = Angle(
    [0, 20, 23, 27, 30, 33, 37, 40, 44, 49, 53, 58, 64, 72, 90], 'degree')
azimuth_edges = Angle([-90, 90, 270], 'degree')

# convert observation groups binning definition "michi" to "default"

list_obs_group_axis = [
    ObservationGroupAxis('ALT', altitude_edges, 'bin_edges'),
    ObservationGroupAxis('AZ', azimuth_edges, 'bin_edges')
]
obs_groups_michi = ObservationGroups(list_obs_group_axis)
print("Observation groups 'michi':")
print(obs_groups_michi.obs_groups_table)
if SAVE:
    outfile = 'bg_observation_groups_michi.ecsv'
    print('Writing {}'.format(outfile))
    obs_groups_michi.write(outfile)

# lookup table: equivalences in group/file naming "defualt" <-> "michi"
# 3 columns: GROUP_ID, ALT_ID, AZ_ID
# 28 rows: 1 per GROUP_ID

lookup_obs_groups_michi = Table()
n_cols = 1 + len(list_obs_group_axis)
n_rows = obs_groups_michi.n_groups
lookup_obs_groups_michi['GROUP_ID'] = np.zeros(n_rows, dtype=np.int)
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.obs.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 = CubeBackgroundModel.read(filename1,
                                                      format='table').background_cube
            bg_cube_model2 = CubeBackgroundModel.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)