def test_time_interval_equivalence():

    t1 = TimeInterval(10.523, 20.32)

    assert t1 == TimeInterval(10.523, 20.32)

    assert not t1 == None
Пример #2
0
def test_instrument_response_constructor():

    # Make a fake test matrix

    matrix, mc_energies, ebounds = get_matrix_elements()

    rsp = InstrumentResponse(matrix, ebounds, mc_energies)

    assert np.all(rsp.matrix == matrix)
    assert np.all(rsp.ebounds == ebounds)
    assert np.all(rsp.monte_carlo_energies == mc_energies)

    # Now with coverage interval

    with pytest.raises(AssertionError):

        _ = InstrumentResponse(matrix, ebounds, mc_energies, "10-20")

    rsp = InstrumentResponse(matrix, ebounds, mc_energies,
                             TimeInterval(10.0, 20.0))

    assert rsp.rsp_filename is None
    assert rsp.arf_filename is None
    assert rsp.coverage_interval == TimeInterval(10.0, 20.0)

    # Check that we do not accept nans in the matrix
    matrix[2, 2] = np.nan

    with pytest.raises(AssertionError):

        _ = InstrumentResponse(matrix, ebounds, mc_energies, "10-20")
Пример #3
0
def test_response_set_constructor():

    [rsp_aw,
     rsp_bw], exposure_getter, counts_getter = get_matrix_set_elements()

    with pytest.raises(RuntimeError):

        # This should raise because there is no time information for the matrices

        _ = InstrumentResponseSet([rsp_aw, rsp_bw], exposure_getter,
                                  counts_getter)

    # Add the time information

    (
        [rsp_a, rsp_b],
        exposure_getter,
        counts_getter,
    ) = get_matrix_set_elements_with_coverage()

    # This should work now
    rsp_set = InstrumentResponseSet([rsp_a, rsp_b], exposure_getter,
                                    counts_getter)

    assert rsp_set[0] == rsp_a
    assert rsp_set[1] == rsp_b

    # Check that the constructor order the matrices by time when needed
    # This should work now
    rsp_set = InstrumentResponseSet([rsp_b, rsp_a], exposure_getter,
                                    counts_getter)

    assert rsp_set[0] == rsp_a
    assert rsp_set[1] == rsp_b

    # Now test construction from the .from_rsp2 method
    rsp2_file = get_path_of_data_file("ogip_test_gbm_b0.rsp2")

    with warnings.catch_warnings():

        warnings.simplefilter("error", np.VisibleDeprecationWarning)

        rsp_set = InstrumentResponseSet.from_rsp2_file(rsp2_file,
                                                       exposure_getter,
                                                       counts_getter)

    assert len(rsp_set) == 3

    # Now test that we cannot initialize a response set with matrices which have non-contiguous coverage intervals
    matrix, mc_energies, ebounds = get_matrix_elements()

    rsp_c = InstrumentResponse(matrix, ebounds, mc_energies,
                               TimeInterval(0.0, 10.0))
    rsp_d = InstrumentResponse(matrix, ebounds, mc_energies,
                               TimeInterval(20.0, 30.0))

    with pytest.raises(RuntimeError):

        _ = InstrumentResponseSet([rsp_c, rsp_d], exposure_getter,
                                  counts_getter)
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()
Пример #5
0
    def from_rsp2_file(cls, rsp2_file, exposure_getter, counts_getter, reference_time=0.0, half_shifted=True):

        # This assumes the Fermi/GBM rsp2 file format

        # make the rsp file proper
        rsp_file = sanitize_filename(rsp2_file)

        assert file_existing_and_readable(rsp_file), "OGIPResponse file %s not existing or not readable" % rsp_file

        # Will fill up the list of matrices
        list_of_matrices = []

        # Read the response
        with pyfits.open(rsp_file) as f:

            n_responses = f['PRIMARY'].header['DRM_NUM']

            # we will read all the matrices and save them
            for rsp_number in range(1, n_responses + 1):

                this_response = OGIPResponse(rsp2_file + '{%i}' % rsp_number)

                list_of_matrices.append(this_response)

        if half_shifted:

            # Now the GBM format has a strange feature: the matrix, instead of covering from TSTART to TSTOP, covers
            # from (TSTART + TSTOP) / 2.0 of the previous matrix to the (TSTART + TSTOP) / 2.0 of itself.
            # So let's adjust the coverage intervals accordingly

            if len(list_of_matrices) > 1:

                for i, this_matrix in enumerate(list_of_matrices):

                    if i == 0:

                        # The first matrix covers from its TSTART to its half time

                        this_matrix._coverage_interval = TimeInterval(this_matrix.coverage_interval.start_time,
                                                                      this_matrix.coverage_interval.half_time)

                    else:

                        # Any other matrix covers from the half time of the previous matrix to its half time
                        # However, the previous matrix has been already processed, so we use its stop time which
                        # has already begun the half time of what it was before processing

                        prev_matrix = list_of_matrices[i-1]

                        this_matrix._coverage_interval = TimeInterval(prev_matrix.coverage_interval.stop_time,
                                                                      this_matrix.coverage_interval.half_time)


        return InstrumentResponseSet(list_of_matrices, exposure_getter, counts_getter, reference_time)
Пример #6
0
def get_matrix_set_elements_with_coverage(reference_time=0.0):

    [rsp_a, rsp_b], exposure_getter, counts_getter = get_matrix_set_elements()

    # By making the coverage interval twice for the second matrix we restore parity with the first one,
    # so that the weighting by exposure should simply return the first matrix

    rsp_a._coverage_interval = TimeInterval(0.0, 10.0) + reference_time
    rsp_b._coverage_interval = TimeInterval(10.0, 30.0) + reference_time

    return [rsp_a, rsp_b], exposure_getter, counts_getter
def test_time_interval_set_pop():

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

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

    popped = ts.pop(1)

    assert popped == t2
def test_time_interval_argsort_set():

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

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

    idx = ts.argsort()

    assert idx == [2, 0, 1]
Пример #9
0
def test_time_interval_overlaps_with():

    t1 = TimeInterval(-10.0, 10.0)
    t2 = TimeInterval(0.0, 30.0)
    t3 = TimeInterval(-100, 100.0)
    t4 = TimeInterval(-100, -10)
    t5 = TimeInterval(100.0, 200.0)

    assert t1.overlaps_with(t2) == True
    assert t1.overlaps_with(t3) == True
    assert t1.overlaps_with(t4) == False
    assert t1.overlaps_with(t5) == False
def test_time_interval_sort_set():

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

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

    ts2 = ts.sort()

    assert ts2[0] == t3
    assert ts2[1] == t1
    assert ts2[2] == t2
def test_time_interval_sets_starts_stops():

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

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

    for start, stop, interval in zip(ts1.start_times, ts1.stop_times,
                                     [t1, t2, t3]):

        assert interval.start_time == start
        assert interval.stop_time == stop
def test_time_interval_constructor():

    t = TimeInterval(-10.0, 10.0)

    assert t.start_time == -10.0
    assert t.stop_time == 10.0
    assert t.duration == 20.0
    assert t.half_time == 0.0

    with pytest.raises(RuntimeError):

        _ = TimeInterval(10.0, -10.0, swap_if_inverted=False)

    _ = TimeInterval(-10.0, 10.0, swap_if_inverted=True)
Пример #13
0
def test_time_interval_merge():
    t1 = TimeInterval(-10.0, 10.0)
    t2 = TimeInterval(0.0, 30.0)

    t = t1.merge(t2)

    assert t.start_time == -10.0
    assert t.stop_time == 30.0

    with pytest.raises(IntervalsDoNotOverlap):

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

        _ = t1.merge(t2)
def test_time_interval_add_sub_set():

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

    ts = TimeIntervalSet([t1, t2])

    ts2 = ts + 10.0  # type: TimeIntervalSet

    assert ts2[0].start_time == 0.0
    assert ts2[1].stop_time == 40.0

    ts3 = ts - 10.0  # type: TimeIntervalSet

    assert ts3[0].start_time == -20.0
    assert ts3[1].stop_time == 20.0
def test_time_interval_iterator_set():

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

    ts = TimeIntervalSet([t1, t2])

    for i, tt in enumerate(ts):

        if i == 0:

            assert tt == t1

        else:

            assert tt == t2
def test_time_interval_sub():

    t = TimeInterval(-10.0, 10.0)

    new_t = t - 10.0  # type: TimeInterval

    assert new_t.start_time == -20.0
    assert new_t.stop_time == 0.0
def test_time_interval_extend_set():

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

    ts = TimeIntervalSet([t1, t2])

    t3 = TimeInterval(30.0, 40.0)
    t4 = TimeInterval(40.0, 50.0)

    ts.extend([t3, t4])

    assert len(ts) == 4

    ts.extend(TimeIntervalSet([t3, t4]))

    assert len(ts) == 6
def test_time_interval_add():

    t = TimeInterval(-10.0, 10.0)

    new_t = t + 10.0  # type: TimeInterval

    assert new_t.start_time == 0
    assert new_t.stop_time == 20.0
def test_time_interval_overlaps_with():

    t1 = TimeInterval(-10.0, 10.0)
    t2 = TimeInterval(0.0, 30.0)
    t3 = TimeInterval(-100, 100.0)
    t4 = TimeInterval(-100, -10)
    t5 = TimeInterval(100.0, 200.0)

    assert t1.overlaps_with(t2) == True
    assert t1.overlaps_with(t3) == True
    assert t1.overlaps_with(t4) == False
    assert t1.overlaps_with(t5) == False
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
def test_time_interval_merge():
    t1 = TimeInterval(-10.0, 10.0)
    t2 = TimeInterval(0.0, 30.0)

    t = t1.merge(t2)

    assert t.start_time == -10.0
    assert t.stop_time == 30.0

    with pytest.raises(IntervalsDoNotOverlap):

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

        _ = t1.merge(t2)
Пример #22
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
def test_time_edges():

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

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

    assert ts1.time_edges[0] == -10.0
    assert ts1.time_edges[1] == 0.0
    assert ts1.time_edges[2] == 10.0
    assert ts1.time_edges[3] == 20.0

    with pytest.raises(IntervalsNotContiguous):
        t1 = TimeInterval(-10.0, -5.0)
        t2 = TimeInterval(0.0, 10.0)
        t3 = TimeInterval(10.0, 20.0)

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

        _ = ts1.time_edges
def test_merging_set_intervals():

    # test that non overlapping intervals
    # do not result in a merge

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

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

    ts2 = ts1.merge_intersecting_intervals(in_place=False)

    assert len(ts2) == 3
    assert t1 == ts2[0]
    assert t2 == ts2[1]
    assert t3 == ts2[2]

    # end merge works

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

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

    ts2 = ts1.merge_intersecting_intervals(in_place=False)

    assert len(ts2) == 2
    assert t1 == ts2[0]
    assert TimeInterval(5.0, 20.0) == ts2[1]

    # begin merge works

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

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

    ts2 = ts1.merge_intersecting_intervals(in_place=False)

    assert len(ts2) == 2
    assert TimeInterval(-10.0, 10.0) == ts2[0]
    assert TimeInterval(15.0, 20.0) == ts2[1]

    # middle merge works

    t1 = TimeInterval(-10.0, 0.0)
    t2 = TimeInterval(5.0, 10.0)
    t3 = TimeInterval(7.0, 20.0)
    t4 = TimeInterval(35.0, 40.0)

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

    ts2 = ts1.merge_intersecting_intervals(in_place=False)

    assert len(ts2) == 3
    assert t1 == ts2[0]
    assert TimeInterval(5.0, 20.0) == ts2[1]
    assert t4 == ts2[2]

    # both end merge works

    t1 = TimeInterval(-10.0, 0.0)
    t2 = TimeInterval(-5.0, 10.0)
    t3 = TimeInterval(15.0, 20.0)
    t4 = TimeInterval(35.0, 45.0)
    t5 = TimeInterval(40.0, 50.0)

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

    ts2 = ts1.merge_intersecting_intervals(in_place=False)

    assert len(ts2) == 3
    assert TimeInterval(-10.0, 10.0) == ts2[0]
    assert t3 == ts2[1]
    assert TimeInterval(35.0, 50.0) == ts2[2]

    # multi merge works

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

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

    ts2 = ts1.merge_intersecting_intervals(in_place=False)

    assert len(ts2) == 1
    assert TimeInterval(-10.0, 20.0) == ts2[0]

    # complete overlap merge works

    t1 = TimeInterval(-10.0, 25.0)
    t2 = TimeInterval(-5.0, 10.0)
    t3 = TimeInterval(7, 20.0)

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

    ts2 = ts1.merge_intersecting_intervals(in_place=False)

    assert len(ts2) == 1
    assert TimeInterval(-10.0, 25.0) == ts2[0]

    # tests the inplace operation

    t1 = TimeInterval(-10.0, 25.0)
    t2 = TimeInterval(-5.0, 10.0)
    t3 = TimeInterval(7, 20.0)

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

    ts1.merge_intersecting_intervals(in_place=True)

    assert len(ts1) == 1
    assert TimeInterval(-10.0, 25.0) == ts1[0]
Пример #25
0
    def __init__(self, rsp_file: str, arf_file: Optional[str] = None) -> None:
        """

        :param rsp_file:
        :param arf_file:
        """

        # Now make sure that the response file exist

        rsp_file: Path = sanitize_filename(rsp_file)

        if not fits_file_existing_and_readable(rsp_file):

            log.error(
                f"OGIPResponse file {rsp_file} not existing or not readable")

            raise RuntimeError()

        # Check if we are dealing with a .rsp2 file (containing more than
        # one response). This is checked by looking for the syntax
        # [responseFile]{[responseNumber]}

        if "{" in str(rsp_file):

            tokens = str(rsp_file).split("{")
            rsp_file: Path = sanitize_filename(tokens[0])
            rsp_number = int(tokens[-1].split("}")[0].replace(" ", ""))

        else:

            rsp_number = 1

        self._rsp_file: Path = rsp_file

        # Read the response
        with pyfits.open(rsp_file) as f:

            try:

                # This is usually when the response file contains only the energy dispersion

                data = f["MATRIX", rsp_number].data
                header = f["MATRIX", rsp_number].header

                if arf_file is None:
                    log.warning(
                        "The response is in an extension called MATRIX, which usually means you also "
                        "need an ancillary file (ARF) which you didn't provide. You should refer to the "
                        "documentation  of the instrument and make sure you don't need an ARF."
                    )

            except Exception as e:
                log.warning(
                    "The default choice for MATRIX extension failed:" +
                    repr(e) + "available: " +
                    " ".join([repr(e.header.get("EXTNAME")) for e in f]))

                # Other detectors might use the SPECRESP MATRIX name instead, usually when the response has been
                # already convoluted with the effective area

                # Note that here we are not catching any exception, because
                # we have to fail if we cannot read the matrix

                data = f["SPECRESP MATRIX", rsp_number].data
                header = f["SPECRESP MATRIX", rsp_number].header

            # These 3 operations must be executed when the file is still open

            matrix = self._read_matrix(data, header)

            ebounds = self._read_ebounds(f["EBOUNDS"])

            mc_channels = self._read_mc_channels(data)

        # Now, if there is information on the coverage interval, let's use it

        header_start = header.get("TSTART", None)
        header_stop = header.get("TSTOP", None)

        if header_start is not None and header_stop is not None:

            super(OGIPResponse, self).__init__(
                matrix=matrix,
                ebounds=ebounds,
                monte_carlo_energies=mc_channels,
                coverage_interval=TimeInterval(header_start, header_stop),
            )

        else:

            super(OGIPResponse,
                  self).__init__(matrix=matrix,
                                 ebounds=ebounds,
                                 monte_carlo_energies=mc_channels)

        # Read the ARF if there is any
        # NOTE: this has to happen *after* calling the parent constructor

        self._arf_file: Optional[str] = None

        if arf_file is not None and str(arf_file).lower() != "none":

            self._read_arf_file(arf_file)
def test_time_interval_repr():

    t = TimeInterval(-10.0, 10.0)

    print(t)
def test_time_interval_set_is_contiguous():

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

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

    assert ts.is_contiguous() == False

    t1 = TimeInterval(0.0, 1.0)
    t2 = TimeInterval(1.0, 2.0)
    t3 = TimeInterval(2.0, 3.0)

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

    assert ts.is_contiguous() == True

    t1 = TimeInterval(0.0, 1.0)
    t2 = TimeInterval(1.1, 2.0)
    t3 = TimeInterval(2.0, 3.0)

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

    assert ts.is_contiguous() == False

    t1 = TimeInterval(0.0, 1.0)
    t2 = TimeInterval(2.0, 3.0)
    t3 = TimeInterval(1.0, 2.0)

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

    assert ts.is_contiguous() == False

    new_ts = ts.sort()

    assert new_ts.is_contiguous() == True