def test_cstat_rmfpha(): """What does CSTAT calculate when there is an RMF+PHA instrument model. This includes the AREASCAL when evaluating the model. See Also -------- test_cstat_nophamodel, test_cstat_arfpha, test_cstat_rsppha """ dset, mdl, expected = setup_likelihood(scale=True) # use the full channel grid; the energy grid has to be # "the same" as the channel values since the model # has a dependency on the independent axis # egrid = 1.0 * np.concatenate((dset.channel, [dset.channel.max() + 1])) rmf = make_ideal_rmf(egrid[:-1], egrid[1:]) mdl_ascal = RMFModelPHA(rmf, dset, mdl) stat = CStat() sval_ascal = stat.calc_stat(dset, mdl_ascal) assert_allclose(sval_ascal[0], expected)
def test_rmfmodelpha_delta_call(ignore): """What happens calling an rmf (delta) with a pha? The ignore value gives the channel to ignore (counting from 0). """ exposure = 200.1 estep = 0.025 egrid = np.arange(0.1, 0.8, estep) elo = egrid[:-1] ehi = egrid[1:] rdata = create_delta_rmf(elo, ehi, e_min=elo, e_max=ehi) nchans = elo.size constant = 2.3 mdl = Const1D('flat') mdl.c0 = constant channels = np.arange(1, nchans + 1, dtype=np.int16) counts = np.ones(nchans, dtype=np.int16) pha = DataPHA('test-pha', channel=channels, counts=counts, exposure=exposure) pha.set_rmf(rdata) # force energy units (only needed if ignore is set) pha.set_analysis('energy') if ignore is not None: de = estep * 0.9 e0 = egrid[ignore] pha.notice(lo=e0, hi=e0 + de, ignore=True) # The assert are intended to help people reading this # code rather than being a useful check that the code # is working. mask = [True] * nchans mask[ignore] = False assert (pha.mask == mask).all() wrapped = RMFModelPHA(rdata, pha, mdl) # The model is evaluated on the RMF grid, not whatever # is sent in. It is also integrated across the bins, # which is why there is a multiplication by the # grid width (for this constant model). # # Note that the filter doesn't change the grid. # de = egrid[1:] - egrid[:-1] expected = constant * de out = wrapped([4, 5]) assert_allclose(out, expected)
def test_rmfmodelpha_matrix_call(ignore): """What happens calling an rmf (matrix) with a pha? The ignore value gives the channel to ignore (counting from 0). """ exposure = 200.1 rdata = create_non_delta_rmf() elo = rdata.e_min ehi = rdata.e_max nchans = elo.size constant = 12.2 slope = 0.01 mdl = Polynom1D('not-flat') mdl.c0 = constant mdl.c1 = slope channels = np.arange(1, nchans + 1, dtype=np.int16) counts = np.ones(nchans, dtype=np.int16) pha = DataPHA('test-pha', channel=channels, counts=counts, exposure=exposure) pha.set_rmf(rdata) # force energy units (only needed if ignore is set) pha.set_analysis('energy') if ignore is not None: e0 = elo[ignore] e1 = ehi[ignore] de = 0.9 * (e1 - e0) pha.notice(lo=e0, hi=e0 + de, ignore=True) # The assert are intended to help people reading this # code rather than being a useful check that the code # is working. mask = [True] * nchans mask[ignore] = False assert (pha.mask == mask).all() wrapped = RMFModelPHA(rdata, pha, mdl) # Note that the evaluation ignores any filter we've applied. # and the exposure time is not used. # modvals = mdl(rdata.energ_lo, rdata.energ_hi) matrix = get_non_delta_matrix() expected = np.matmul(modvals, matrix) out = wrapped([4, 5]) assert_allclose(out, expected)
def test_rmf1d_delta_pha_zero_energy_bin(): "What happens when the first bin starts at 0, with replacement" ethresh = 2e-7 egrid = np.asarray([0.0, 0.1, 0.2, 0.4, 0.5, 0.7, 0.8]) elo = egrid[:-1] ehi = egrid[1:] with warnings.catch_warnings(record=True) as ws: warnings.simplefilter("always") rdata = create_delta_rmf(elo, ehi, ethresh=ethresh) validate_zero_replacement(ws, 'RMF', 'delta-rmf', ethresh) exposure = 2.4 channels = np.arange(1, 7, dtype=np.int16) counts = np.ones(6, dtype=np.int16) pha = DataPHA('test-pha', channel=channels, counts=counts, exposure=exposure) pha.set_rmf(rdata) pha.set_analysis('energy') mdl = MyPowLaw1D() tmdl = PowLaw1D() wrapped = RMFModelPHA(rdata, pha, mdl) out = wrapped([0.1, 0.2]) elo[0] = ethresh expected = tmdl(elo, ehi) assert_allclose(out, expected) assert not np.isnan(out[0])