Beispiel #1
0
    def _get_weighted_matrix(self, switch, *intervals):

        assert len(intervals) > 0, "You have to provide at least one interval"

        intervals_set = TimeIntervalSet.from_strings(*intervals)

        # Compute a set of weights for each interval
        weights = np.zeros(len(self._matrix_list))

        for interval in intervals_set:

            weights += self._weight_response(interval, switch)

        # Normalize to 1
        weights /= np.sum(weights)

        # Weight matrices
        matrix = np.dot(np.array(map(attrgetter("matrix"), self._matrix_list)).T, weights.T).T

        # Now generate the instance of the response

        # get EBOUNDS from the first matrix
        ebounds = self._matrix_list[0].ebounds

        # Get mc channels from the first matrix
        mc_channels = self._matrix_list[0].monte_carlo_energies

        matrix_instance = InstrumentResponse(matrix, ebounds, mc_channels)

        return matrix_instance
Beispiel #2
0
    def _get_weighted_matrix(self, switch, *intervals):

        assert len(intervals) > 0, "You have to provide at least one interval"

        intervals_set = TimeIntervalSet.from_strings(*intervals)

        # Compute a set of weights for each interval
        weights = np.zeros(len(self._matrix_list))

        for interval in intervals_set:

            weights += self._weight_response(interval, switch)

        # Normalize to 1
        weights /= np.sum(weights)

        # Weight matrices
        matrix = np.dot(
            np.array(list(map(attrgetter("matrix"), self._matrix_list))).T,
            weights.T).T

        # Now generate the instance of the response

        # get EBOUNDS from the first matrix
        ebounds = self._matrix_list[0].ebounds

        # Get mc channels from the first matrix
        mc_channels = self._matrix_list[0].monte_carlo_energies

        matrix_instance = InstrumentResponse(matrix, ebounds, mc_channels)

        return matrix_instance
def test_time_interval_constructor_set():

    t1 = TimeInterval(-10.0, 20.0)
    t2 = TimeInterval(10.0, 30.0)

    ts = TimeIntervalSet([t1, t2])

    assert ts[0] == t1
    assert ts[1] == t2

    # Use strings
    ts2 = TimeIntervalSet.from_strings("-10 - -5", "10 - 20", "20-30",
                                       "-10--5")

    assert ts2[0].start_time == -10
    assert ts2[0].stop_time == -5
    assert ts2[-1].start_time == -10
    assert ts2[-1].stop_time == -5
    assert ts2[1].start_time == 10
    assert ts2[1].stop_time == 20
    assert ts2[2].start_time == 20
    assert ts2[2].stop_time == 30

    # Use edges
    ts3 = TimeIntervalSet.from_list_of_edges([-2, -1, 0, 1, 2])

    assert ts3[0].start_time == -2
    assert ts3[0].stop_time == -1
    assert ts3[-1].start_time == 1
    assert ts3[-1].stop_time == 2
    assert ts3[1].start_time == -1
    assert ts3[1].stop_time == 0
    assert ts3[2].start_time == 0
    assert ts3[2].stop_time == 1

    # Use start and stops
    ts5 = TimeIntervalSet.from_starts_and_stops([-2, -1, 0, 1], [-1, 0, 1, 2])

    assert ts5[0].start_time == -2
    assert ts5[0].stop_time == -1
    assert ts5[-1].start_time == 1
    assert ts5[-1].stop_time == 2
    assert ts5[1].start_time == -1
    assert ts5[1].stop_time == 0
    assert ts5[2].start_time == 0
    assert ts5[2].stop_time == 1

    with pytest.raises(AssertionError):

        ts6 = TimeIntervalSet.from_starts_and_stops([-2, -1, 0, 1], [-1, 0, 1])

    # test display

    ts5.display()
Beispiel #4
0
def test_time_interval_constructor_set():

    t1 = TimeInterval(-10.0, 20.0)
    t2 = TimeInterval(10.0, 30.0)

    ts = TimeIntervalSet([t1, t2])

    assert ts[0] == t1
    assert ts[1] == t2

    # Use strings
    ts2 = TimeIntervalSet.from_strings("-10 - -5", "10 - 20", "20-30","-10--5")

    assert ts2[0].start_time == -10
    assert ts2[0].stop_time == -5
    assert ts2[-1].start_time == -10
    assert ts2[-1].stop_time == -5
    assert ts2[1].start_time == 10
    assert ts2[1].stop_time == 20
    assert ts2[2].start_time == 20
    assert ts2[2].stop_time == 30

    # Use edges
    ts3 = TimeIntervalSet.from_list_of_edges([-2,-1,0,1,2])

    assert ts3[0].start_time == -2
    assert ts3[0].stop_time == -1
    assert ts3[-1].start_time == 1
    assert ts3[-1].stop_time == 2
    assert ts3[1].start_time == -1
    assert ts3[1].stop_time == 0
    assert ts3[2].start_time == 0
    assert ts3[2].stop_time == 1

    # Use start and stops
    ts5 = TimeIntervalSet.from_starts_and_stops([-2, -1, 0, 1],  [-1, 0, 1, 2])

    assert ts5[0].start_time == -2
    assert ts5[0].stop_time == -1
    assert ts5[-1].start_time == 1
    assert ts5[-1].stop_time == 2
    assert ts5[1].start_time == -1
    assert ts5[1].stop_time == 0
    assert ts5[2].start_time == 0
    assert ts5[2].stop_time == 1

    with pytest.raises(AssertionError):

        ts6 = TimeIntervalSet.from_starts_and_stops([-2, -1, 0, 1], [-1, 0, 1])


    # test display

    ts5.display()
def test_interval_set_to_string():

    # also tests the time interval to string

    t1 = TimeInterval(-10.0, 0.0)
    t2 = TimeInterval(5.0, 10.0)
    t3 = TimeInterval(15.0, 20.0)

    ts1 = TimeIntervalSet([t1, t2, t3])

    strings = ts1.to_string()

    strings_split = strings.split(",")

    assert t1.to_string() == strings_split[0]
    assert t2.to_string() == strings_split[1]
    assert t3.to_string() == strings_split[2]

    ts2 = TimeIntervalSet.from_strings(t1.to_string())

    assert ts2[0] == t1
Beispiel #6
0
def test_interval_set_to_string():

    # also tests the time interval to string

    t1 = TimeInterval(-10.0, 0.0)
    t2 = TimeInterval(5., 10.0)
    t3 = TimeInterval(15.0, 20.0)

    ts1 = TimeIntervalSet([t1, t2, t3])

    strings = ts1.to_string()

    strings_split = strings.split(',')

    assert t1.to_string() == strings_split[0]
    assert t2.to_string() == strings_split[1]
    assert t3.to_string() == strings_split[2]

    ts2 = TimeIntervalSet.from_strings(t1.to_string())

    assert ts2[0] == t1
Beispiel #7
0
    def set_polynomial_fit_interval(self, *time_intervals, **options):
        """Set the time interval to fit the background.
        Multiple intervals can be input as separate arguments
        Specified as 'tmin-tmax'. Intervals are in seconds. Example:

        set_polynomial_fit_interval("-10.0-0.0","10.-15.")

        :param time_intervals: intervals to fit on
        :param options:

        """

        # Find out if we want to binned or unbinned.
        # TODO: add the option to config file
        if 'unbinned' in options:
            unbinned = options.pop('unbinned')
            assert type(
                unbinned) == bool, 'unbinned option must be True or False'

        else:

            # assuming unbinned
            # could use config file here
            # unbinned = threeML_config['ogip']['use-unbinned-poly-fitting']

            unbinned = True

        # we create some time intervals

        poly_intervals = TimeIntervalSet.from_strings(*time_intervals)

        # adjust the selections to the data

        new_intervals = []

        self._poly_selected_counts = []

        self._poly_exposure = 0.

        for i, time_interval in enumerate(poly_intervals):

            t1 = time_interval.start_time
            t2 = time_interval.stop_time

            if (self._stop_time <= t1) or (t2 <= self._start_time):
                custom_warnings.warn(
                    "The time interval %f-%f is out side of the arrival times and will be dropped"
                    % (t1, t2))

            else:

                if t1 < self._start_time:
                    custom_warnings.warn(
                        "The time interval %f-%f started before the first arrival time (%f), so we are changing the intervals to %f-%f"
                        % (t1, t2, self._start_time, self._start_time, t2))

                    t1 = self._start_time  # + 1

                if t2 > self._stop_time:
                    custom_warnings.warn(
                        "The time interval %f-%f ended after the last arrival time (%f), so we are changing the intervals to %f-%f"
                        % (t1, t2, self._stop_time, t1, self._stop_time))

                    t2 = self._stop_time  # - 1.

                new_intervals.append('%f-%f' % (t1, t2))

                self._poly_selected_counts.append(
                    self.count_per_channel_over_interval(t1, t2))
                self._poly_exposure += self.exposure_over_interval(t1, t2)

        # make new intervals after checks

        poly_intervals = TimeIntervalSet.from_strings(*new_intervals)

        self._poly_selected_counts = np.sum(self._poly_selected_counts, axis=0)

        # set the poly intervals as an attribute

        self._poly_intervals = poly_intervals

        # Fit the events with the given intervals
        if unbinned:

            self._unbinned = True  # keep track!

            self._unbinned_fit_polynomials()

        else:

            self._unbinned = False

            self._fit_polynomials()

        # we have a fit now

        self._poly_fit_exists = True

        if self._verbose:
            print("%s %d-order polynomial fit with the %s method" %
                  (self._fit_method_info['bin type'],
                   self._optimal_polynomial_grade,
                   self._fit_method_info['fit method']))
            print('\n')

        # recalculate the selected counts

        if self._time_selection_exists:
            self.set_active_time_intervals(
                *self._time_intervals.to_string().split(','))
    def set_active_time_intervals(self, *args):
        """
        Set the time interval(s) to be used during the analysis.
        Specified as 'tmin-tmax'. Intervals are in seconds. Example:

        set_active_time_intervals("0.0-10.0")

        which will set the time range 0-10. seconds.
        """

        # mark that we now have a time selection

        self._time_selection_exists = True

        # lets build a time interval set from the selections
        # and then merge intersecting intervals

        time_intervals = TimeIntervalSet.from_strings(*args)
        time_intervals.merge_intersecting_intervals(in_place=True)

        # lets adjust the time intervals to the actual ones since they are prebinned

        time_intervals = self._adjust_to_true_intervals(time_intervals)

        # start out with no time bins selection
        all_idx = np.zeros(
            len(self._binned_spectrum_set.time_intervals), dtype=bool)

        # now we need to sum up the counts and total time

        total_time = 0

        for interval in time_intervals:

            # the select bins method is called.
            # since we are sure that the interval bounds
            # are aligned with the true ones, we do not care if
            # it is inner or outer

            all_idx = np.logical_or(
                all_idx, self._select_bins(
                    interval.start_time, interval.stop_time)
            )

            total_time += interval.duration

        # sum along the time axis
        self._counts = self._binned_spectrum_set.counts_per_bin[all_idx].sum(
            axis=0)

        # the selected time intervals

        self._time_intervals = time_intervals

        tmp_counts = []
        tmp_err = []  # Temporary list to hold the err counts per chan

        if self._poly_fit_exists:

            if not self._poly_fit_exists:
                raise RuntimeError(
                    "A polynomial fit to the channels does not exist!")

            for chan in range(self._n_channels):

                total_counts = 0
                counts_err = 0

                for tmin, tmax in zip(
                    self._time_intervals.start_times, self._time_intervals.stop_times
                ):
                    # Now integrate the appropriate background polynomial
                    total_counts += self._polynomials[chan].integral(
                        tmin, tmax)
                    counts_err += (
                        self._polynomials[chan].integral_error(tmin, tmax)
                    ) ** 2

                tmp_counts.append(total_counts)

                tmp_err.append(np.sqrt(counts_err))

            self._poly_counts = np.array(tmp_counts)

            self._poly_count_err = np.array(tmp_err)

        self._exposure = self._binned_spectrum_set.exposure_per_bin[all_idx].sum(
        )

        self._active_dead_time = total_time - self._exposure
Beispiel #9
0
    def set_active_time_intervals(self, *args):
        '''Set the time interval(s) to be used during the analysis.

        Specified as 'tmin-tmax'. Intervals are in seconds. Example:

        set_active_time_intervals("0.0-10.0")

        which will set the energy range 0-10. seconds.
        '''

        self._time_selection_exists = True

        interval_masks = []

        time_intervals = TimeIntervalSet.from_strings(*args)

        time_intervals.merge_intersecting_intervals(in_place=True)

        for interval in time_intervals:
            tmin = interval.start_time
            tmax = interval.stop_time

            mask = self._select_events(tmin, tmax)

            interval_masks.append(mask)

        self._time_intervals = time_intervals

        time_mask = interval_masks[0]
        if len(interval_masks) > 1:
            for mask in interval_masks[1:]:
                time_mask = np.logical_or(time_mask, mask)

        tmp_counts = []  # Temporary list to hold the total counts per chan

        for chan in range(self._first_channel,
                          self._n_channels + self._first_channel):
            channel_mask = self._measurement == chan
            counts_mask = np.logical_and(channel_mask, time_mask)
            total_counts = len(self._arrival_times[counts_mask])

            tmp_counts.append(total_counts)

        self._counts = np.array(tmp_counts)

        tmp_counts = []
        tmp_err = []  # Temporary list to hold the err counts per chan

        if self._poly_fit_exists:

            if not self._poly_fit_exists:
                raise RuntimeError(
                    'A polynomial fit to the channels does not exist!')

            for chan in range(self._n_channels):

                total_counts = 0
                counts_err = 0

                for tmin, tmax in zip(self._time_intervals.start_times,
                                      self._time_intervals.stop_times):
                    # Now integrate the appropriate background polynomial
                    total_counts += self._polynomials[chan].integral(
                        tmin, tmax)
                    counts_err += (self._polynomials[chan].integral_error(
                        tmin, tmax))**2

                tmp_counts.append(total_counts)

                tmp_err.append(np.sqrt(counts_err))

            self._poly_counts = np.array(tmp_counts)

            self._poly_count_err = np.array(tmp_err)

        # Dead time correction

        exposure = 0.
        total_dead_time = 0.
        for interval, imask in zip(self._time_intervals, interval_masks):
            exposure += interval.duration
            if self._dead_time_fraction is not None:
                total_dead_time += interval.duration * self._dead_time_fraction[
                    imask].mean()

        self._exposure = exposure - total_dead_time

        self._active_dead_time = total_dead_time
Beispiel #10
0
    def set_active_time_intervals(self, *args):
        """
        Set the time interval(s) to be used during the analysis.
        Specified as 'tmin-tmax'. Intervals are in seconds. Example:

        set_active_time_intervals("0.0-10.0")

        which will set the time range 0-10. seconds.
        """

        # mark that we now have a time selection

        self._time_selection_exists = True

        # lets build a time interval set from the selections
        # and then merge intersecting intervals

        time_intervals = TimeIntervalSet.from_strings(*args)
        time_intervals.merge_intersecting_intervals(in_place=True)

        # lets adjust the time intervals to the actual ones since they are prebinned

        time_intervals = self._adjust_to_true_intervals(time_intervals)


        # start out with no time bins selection
        all_idx = np.zeros(len(self._binned_spectrum_set.time_intervals),dtype=bool)

        # now we need to sum up the counts and total time

        total_time = 0

        for interval in time_intervals:

            # the select bins method is called.
            # since we are sure that the interval bounds
            # are aligned with the true ones, we do not care if
            # it is inner or outer

            all_idx = np.logical_or(all_idx,self._select_bins(interval.start_time,interval.stop_time))

            total_time += interval.duration

        # sum along the time axis
        self._counts = self._binned_spectrum_set.counts_per_bin[all_idx].sum(axis=0)


        # the selected time intervals

        self._time_intervals = time_intervals


        tmp_counts = []
        tmp_err = []  # Temporary list to hold the err counts per chan

        if self._poly_fit_exists:

            if not self._poly_fit_exists:
                raise RuntimeError('A polynomial fit to the channels does not exist!')

            for chan in range(self._n_channels):

                total_counts = 0
                counts_err = 0

                for tmin, tmax in zip(self._time_intervals.start_times, self._time_intervals.stop_times):
                    # Now integrate the appropriate background polynomial
                    total_counts += self._polynomials[chan].integral(tmin, tmax)
                    counts_err += (self._polynomials[chan].integral_error(tmin, tmax)) ** 2

                tmp_counts.append(total_counts)

                tmp_err.append(np.sqrt(counts_err))

            self._poly_counts = np.array(tmp_counts)

            self._poly_count_err = np.array(tmp_err)


        self._exposure = self._binned_spectrum_set.exposure_per_bin[all_idx].sum()

        self._active_dead_time = total_time - self._exposure
Beispiel #11
0
    def set_polynomial_fit_interval(self, *time_intervals, **options):
        """Set the time interval to fit the background.
        Multiple intervals can be input as separate arguments
        Specified as 'tmin-tmax'. Intervals are in seconds. Example:

        set_polynomial_fit_interval("-10.0-0.0","10.-15.")

        :param time_intervals: intervals to fit on
        :param options:

        """

        # Find out if we want to binned or unbinned.
        # TODO: add the option to config file
        if 'unbinned' in options:
            unbinned = options.pop('unbinned')
            assert type(unbinned) == bool, 'unbinned option must be True or False'

        else:

            # assuming unbinned
            # could use config file here
            # unbinned = threeML_config['ogip']['use-unbinned-poly-fitting']

            unbinned = True

        # we create some time intervals

        poly_intervals = TimeIntervalSet.from_strings(*time_intervals)

        # adjust the selections to the data

        new_intervals = []

        self._poly_selected_counts = []

        self._poly_exposure = 0.

        for i, time_interval in enumerate(poly_intervals):

            t1 = time_interval.start_time
            t2 = time_interval.stop_time

            if (self._stop_time <= t1) or (t2 <= self._start_time):
                custom_warnings.warn(
                    "The time interval %f-%f is out side of the arrival times and will be dropped" % (
                        t1, t2))




            else:

                if t1 < self._start_time:
                    custom_warnings.warn(
                        "The time interval %f-%f started before the first arrival time (%f), so we are changing the intervals to %f-%f" % (
                            t1, t2, self._start_time, self._start_time, t2))

                    t1 = self._start_time  # + 1

                if t2 > self._stop_time:
                    custom_warnings.warn(
                        "The time interval %f-%f ended after the last arrival time (%f), so we are changing the intervals to %f-%f" % (
                            t1, t2, self._stop_time, t1, self._stop_time))

                    t2 = self._stop_time  # - 1.

                new_intervals.append('%f-%f' % (t1, t2))


                self._poly_selected_counts.append(self.count_per_channel_over_interval(t1,t2))
                self._poly_exposure += self.exposure_over_interval(t1,t2)

        # make new intervals after checks

        poly_intervals = TimeIntervalSet.from_strings(*new_intervals)

        self._poly_selected_counts = np.sum(self._poly_selected_counts, axis=0)

        # set the poly intervals as an attribute

        self._poly_intervals = poly_intervals

        # Fit the events with the given intervals
        if unbinned:

            self._unbinned = True  # keep track!

            self._unbinned_fit_polynomials()

        else:

            self._unbinned = False

            self._fit_polynomials()

        # we have a fit now

        self._poly_fit_exists = True

        if self._verbose:
            print("%s %d-order polynomial fit with the %s method" % (
                self._fit_method_info['bin type'], self._optimal_polynomial_grade, self._fit_method_info['fit method']))
            print('\n')

        # recalculate the selected counts

        if self._time_selection_exists:
            self.set_active_time_intervals(*self._time_intervals.to_string().split(','))
Beispiel #12
0
    def set_polynomial_fit_interval(self, *time_intervals, **kwargs) -> None:
        """Set the time interval to fit the background.
        Multiple intervals can be input as separate arguments
        Specified as 'tmin-tmax'. Intervals are in seconds. Example:

        set_polynomial_fit_interval("-10.0-0.0","10.-15.")

        :param time_intervals: intervals to fit on
        :param unbinned:
        :param bayes:
        :param kwargs:

        """

        # Find out if we want to binned or unbinned.
        # TODO: add the option to config file
        if "unbinned" in kwargs:
            unbinned = kwargs.pop("unbinned")
            assert type(
                unbinned) == bool, "unbinned option must be True or False"

        else:

            # assuming unbinned
            # could use config file here
            # unbinned = threeML_config['ogip']['use-unbinned-poly-fitting']

            unbinned = True

        # check if we are doing a bayesian
        # fit and record this info

        if "bayes" in kwargs:
            bayes = kwargs.pop("bayes")

        else:

            bayes = False

        if bayes:

            self._fit_method_info["fit method"] = "bayes"

        else:

            self._fit_method_info["fit method"] = "bayes"

        # we create some time intervals

        poly_intervals = TimeIntervalSet.from_strings(*time_intervals)

        # adjust the selections to the data

        new_intervals = []

        self._poly_selected_counts = []

        self._poly_exposure = 0.0

        for i, time_interval in enumerate(poly_intervals):

            t1 = time_interval.start_time
            t2 = time_interval.stop_time

            if (self._stop_time <= t1) or (t2 <= self._start_time):
                log.warning(
                    "The time interval %f-%f is out side of the arrival times and will be dropped"
                    % (t1, t2))

            else:

                if t1 < self._start_time:
                    log.warning(
                        "The time interval %f-%f started before the first arrival time (%f), so we are changing the intervals to %f-%f"
                        % (t1, t2, self._start_time, self._start_time, t2))

                    t1 = self._start_time  # + 1

                if t2 > self._stop_time:
                    log.warning(
                        "The time interval %f-%f ended after the last arrival time (%f), so we are changing the intervals to %f-%f"
                        % (t1, t2, self._stop_time, t1, self._stop_time))

                    t2 = self._stop_time  # - 1.

                new_intervals.append("%f-%f" % (t1, t2))

                self._poly_selected_counts.append(
                    self.count_per_channel_over_interval(t1, t2))
                self._poly_exposure += self.exposure_over_interval(t1, t2)

        # make new intervals after checks

        poly_intervals = TimeIntervalSet.from_strings(*new_intervals)

        self._poly_selected_counts = np.sum(self._poly_selected_counts, axis=0)

        # set the poly intervals as an attribute

        self._poly_intervals = poly_intervals

        # Fit the events with the given intervals
        if unbinned:

            self._unbinned = True  # keep track!

            self._unbinned_fit_polynomials(bayes=bayes)

        else:

            self._unbinned = False

            self._fit_polynomials(bayes=bayes)

        # we have a fit now

        self._poly_fit_exists = True

        log.info(
            f"{self._fit_method_info['bin type']} {self._optimal_polynomial_grade}-order polynomial fit with the {self._fit_method_info['fit method']} method"
        )

        # recalculate the selected counts

        if self._time_selection_exists:
            self.set_active_time_intervals(
                *self._time_intervals.to_string().split(","))
Beispiel #13
0
    def set_active_time_intervals(self, *args):
        """Set the time interval(s) to be used during the analysis.

        Specified as 'tmin-tmax'. Intervals are in seconds. Example:

        set_active_time_intervals("0.0-10.0")

        which will set the energy range 0-10. seconds.
        """
        self._time_selection_exists = True

        interval_masks = []

        time_intervals = TimeIntervalSet.from_strings(*args)

        time_intervals.merge_intersecting_intervals(in_place=True)

        for interval in time_intervals:
            tmin = interval.start_time
            tmax = interval.stop_time

            mask = self._select_events(tmin, tmax)

            interval_masks.append(mask)

        self._time_intervals = time_intervals

        time_mask = interval_masks[0]
        if len(interval_masks) > 1:
            for mask in interval_masks[1:]:
                time_mask = np.logical_or(time_mask, mask)

        # calulate exposure and deadtime
        exposure = 0
        dead_time = 0
        for interval in time_intervals:
            tmin = interval.start_time
            tmax = interval.stop_time
            this_exposure = self.exposure_over_interval(tmin, tmax)
            # check that the exposure is not larger than the total time
            if this_exposure > (tmax - tmin):
                log.error("The exposure in the active time bin is larger "
                          "than the total active time. "
                          "Something must be wrong!")
                raise RuntimeError()
            exposure += this_exposure
            dead_time += (tmax - tmin) - this_exposure

        self._exposure = exposure
        self._active_dead_time = dead_time

        tmp_counts = []  # Temporary list to hold the total counts per chan

        for chan in range(self._first_channel,
                          self._n_channels + self._first_channel):

            channel_mask = self._measurement == chan
            counts_mask = np.logical_and(channel_mask, time_mask)
            total_counts = len(self._arrival_times[counts_mask])

            tmp_counts.append(total_counts)

        self._counts = np.array(tmp_counts)

        tmp_counts = []
        tmp_err = []  # Temporary list to hold the err counts per chan

        if self._poly_fit_exists:

            if not self._poly_fit_exists:
                raise RuntimeError(
                    "A polynomial fit to the channels does not exist!")

            for chan in range(self._n_channels):

                total_counts = 0
                counts_err = 0

                for tmin, tmax in zip(self._time_intervals.start_times,
                                      self._time_intervals.stop_times):
                    # Now integrate the appropriate background polynomial
                    total_counts += self._polynomials[chan].integral(
                        tmin, tmax)
                    counts_err += (self._polynomials[chan].integral_error(
                        tmin, tmax))**2

                tmp_counts.append(total_counts)

                tmp_err.append(np.sqrt(counts_err))

            self._poly_counts = np.array(tmp_counts)

            self._poly_count_err = np.array(tmp_err)

            # apply the dead time correction to the background counts
            # and errors
            corr = self._exposure / (self._active_dead_time + self._exposure)

            self._poly_counts *= corr

            self._poly_count_err *= corr