Example #1
0
def test_stats_calc_stat_wstat_pha_nobg():
    """wstat statistic fails with no background: PHA dataset"""

    statobj = WStat()
    data, model = setup_single_pha(False, False, background=False)
    with pytest.raises(StatErr):
        statobj.calc_stat(data, model)
def test_stats_calc_stat_wstat_diffbins():
    """wstat statistic fails when src/bg bin sizes do not match"""

    statobj = WStat()

    data, model = setup_single_pha(True, False, background=True)

    # Tweak data to have one-less bin than the background. This
    # used to be easy but with data validation we need to
    # create a new object.
    #
    data2 = DataPHA("faked",
                    channel=data.channel[:-1],
                    counts=data.counts[:-1],
                    staterror=data.staterror[:-1],
                    grouping=data.grouping[:-1],
                    exposure=data.exposure,
                    backscal=data.backscal,
                    areascal=data.areascal)

    # We might expect the ARF/RMF calls to fail if we add validation
    # (to check the ARF/RMF is valid for the PHA dataset).
    #
    data2.set_arf(data.get_arf())
    data2.set_rmf(data.get_rmf())
    data2.set_background(data.get_background())

    # There is no Sherpa error for this, which seems surprising
    with pytest.raises(TypeError) as err:
        statobj.calc_stat(data2, model)

    assert str(
        err.value) == "input array sizes do not match, data: 5 vs group: 4"
Example #3
0
def test_stats_calc_stat_wstat_nobg(usestat, usesys):
    """wstat statistic fails with no background"""

    statobj = WStat()
    data, model = setup_single(usestat, usesys)
    with pytest.raises(StatErr):
        statobj.calc_stat(data, model)
Example #4
0
 def test_wstat(self):
     fit = Fit(self.data, self.model, WStat(), LevMar())
     results = fit.fit()
     # On a local linux machine I have to bump the tolerance to
     # 3e-4, but this isn't seen on Travis. The fit isn't
     # "great", so it may be that the results are sensitive to
     # numerical differences (e.g. as introduced with updated
     # compilers).
     # tol = 3e-4
     tol = 1e-6  # TODO: investigate difference
     self.compare_results(self._fit_wstat_results_bench, results, tol=tol)
Example #5
0
def test_stats_calc_stat_wstat_diffbins():
    """wstat statistic fails when src/bg bin sizes do not match"""

    statobj = WStat()

    data, model = setup_single_pha(True, False, background=True)

    # Tweak data to have one-less bin than the background
    data.channel = data.channel[:-1]
    data.counts = data.channel[:-1]
    for attr in ['staterror', 'syserror', 'grouping', 'quality', 'backscal']:
        val = getattr(data, attr)
        if val is not None:
            try:
                setattr(data, attr, val[:-1])
            except TypeError:
                # assume a scalar, so leave be
                pass

    # There is no Sherpa error for this, which seems surprising
    with pytest.raises(TypeError):
        statobj.calc_stat(data, model)
Example #6
0
def test_wstat(hide_logging, reset_xspec, setup):

    fit = Fit(setup['data'], setup['model'], WStat(), LevMar())
    results = fit.fit()

    _fit_wstat_results_bench = {
        'succeeded':
        1,
        'numpoints':
        460,
        'dof':
        457,
        'istatval':
        21647.48285025895,
        'statval':
        472.6585709918982,
        'parvals':
        numpy.array([1.750204250228727, 5.47466040324842, -1.9983562007031974])
    }

    compare_results(_fit_wstat_results_bench, results, tol=2e-4)
Example #7
0
 def test_wstat_error(self):
     data = self.bkg
     data.notice(0.5, 7.0)
     fit = Fit(data, self.model, WStat(), NelderMead())
     self.assertRaises(StatErr, fit.fit)
Example #8
0
 def test_wstat(self):
     fit = Fit(self.data, self.model, WStat(), NelderMead())
     results = fit.fit()
     self.compare_results(self._fit_wstat_results_bench, results)
Example #9
0
def prepare_spectra(group, nH, add_gal, redshift):
    pha = read_pha("core_spectrum.pi")
    pha.set_analysis("energy")
    pha.notice(0.5, 7.0)
    tabs = ~pha.mask
    pha.group_counts(group, tabStops=tabs)
    x = pha.get_x()
    x = pha.apply_filter(x, pha._middle)
    y = pha.get_y(filter=True)
    pha.set_analysis("energy")

    model = xsphabs.abs1 * powlaw1d.srcp1
    print("Fitting the spectrum")

    zFlag = False
    if (nH is not None) and (nH > 0.0):
        if add_gal == 1:
            model = xsphabs.gal * xszphabs.abs1 * powlaw1d.srcp
            gal.nH = nH
            freeze(gal.nH)
            zFlag = True

        else:
            model = xsphabs.abs1 * powlaw1d.srcp1
            abs1.nH = nH
            freeze(abs1.nH)
    else:
        model = xszphabs.abs1 * powlaw1d.srcp1
        zFlag = True

    if zFlag is True and add_gal == 1:
        # print('REDSHIFT',redshift)
        abs1.redshift = redshift
        freeze(abs1.redshift)

    full_model = RSPModelPHA(pha.get_arf(), pha.get_rmf(), pha, pha.exposure * model)

    print(full_model)

    fit = Fit(pha, full_model, method=MonCar(), stat=WStat())
    res = fit.fit()

    print(res.format())
    print(fit.est_errors())

    # calculate the p-value for wstat
    mplot2 = ModelPlot()
    mplot2.prepare(pha, full_model)

    miu = mplot2.y * pha.exposure * 0.0146
    obs = y * pha.exposure * 0.0146

    c, ce, cv = gof_cstat(miu, obs)

    print(f"C0={c},C_e={ce},C_v={cv}")

    zval = (fit.calc_stat() - ce) / np.sqrt(cv)

    if zval > 0:
        pval = special.erfc(zval / np.sqrt(2))
    else:
        pval = special.erf(abs(zval) / np.sqrt(2))

    print(f"p-value for wstat = {pval}")

    set_data(pha)
    set_model(model)
    save_chart_spectrum("core_flux_chart.dat", elow=0.5, ehigh=7.0)
    # save_chart_spectrum("core_flux_chart.rdb",format='text/tsv', elow=0.5, ehigh=7.0)
    save_spectrum_rdb("core_flux_chart.dat")
Example #10
0
def test_wstat_error(hide_logging, reset_xspec, setup_bkg):
    fit = Fit(setup_bkg['bkg'], setup_bkg['model'], WStat(), NelderMead())

    with pytest.raises(StatErr):
        fit.fit()
Example #11
0
    def prepare_spectra(nH: float,
                        group: int = 1,
                        add_gal: bool = False,
                        redshift: Optional[float] = None,
                        **kwargs) -> float:
        """
        Fit the spectra using an absorbed powerlaw model using the Wstat statistic. The function also returns a p-value for the gof.
        :param nH: The galactic absorption column density in units of 10^22 /cm3
        :param group: The number of counts per energy bin
        :param add_gal: Setting this to True would add an intrinsic abrosption column density along side the galactic one
        :param redshift: The redshift to use in the fit. Only takes effect if add_gal is set to True
        ...
        :return: Returns the p-value of the gof. The null hypothesis states that the model and the observation differ while alternate says that the model explains the data
        """

        pha = read_pha("core_spectrum.pi")
        pha.set_analysis("energy")
        pha.notice(0.5, 7.0)
        tabs = ~pha.mask
        pha.group_counts(group, tabStops=tabs)
        x = pha.get_x()
        x = pha.apply_filter(x, pha._middle)
        y = pha.get_y(filter=True)
        pha.set_analysis("energy")

        model = xsphabs.abs1 * powlaw1d.srcp1
        print("Fitting the spectrum")

        zFlag = False
        if (nH is not None) and (nH > 0.0):
            if add_gal == 1:
                model = xsphabs.gal * xszphabs.abs1 * powlaw1d.srcp
                gal.nH = nH
                freeze(gal.nH)
                zFlag = True

            else:
                model = xsphabs.abs1 * powlaw1d.srcp1
                abs1.nH = nH
                freeze(abs1.nH)
        else:
            model = xszphabs.abs1 * powlaw1d.srcp1
            zFlag = True

        if zFlag is True and add_gal == 1:
            # print('REDSHIFT',redshift)
            abs1.redshift = redshift
            freeze(abs1.redshift)

        full_model = RSPModelPHA(pha.get_arf(), pha.get_rmf(), pha,
                                 pha.exposure * model)

        print(full_model)

        fit = Fit(pha, full_model, method=MonCar(), stat=WStat())
        res = fit.fit()

        print(res.format())
        print(fit.est_errors())

        # calculate the p-value for wstat
        mplot2 = ModelPlot()
        mplot2.prepare(pha, full_model)

        miu = mplot2.y * pha.exposure * 0.0146
        obs = y * pha.exposure * 0.0146

        c, ce, cv = SpecUtils.estimate_gof_cstat(miu, obs)

        #print(f"C0={c},C_e={ce},C_v={cv}")

        zval = (fit.calc_stat() - ce) / np.sqrt(cv)

        if zval > 0:
            pval = special.erfc(zval / np.sqrt(2))
        else:
            pval = special.erf(abs(zval) / np.sqrt(2))

        print(f"p-value for wstat = {pval}")

        set_data(pha)
        set_model(model)
        save_chart_spectrum("core_flux_chart.dat", elow=0.5, ehigh=7.0)
        # save_chart_spectrum("core_flux_chart.rdb",format='text/tsv', elow=0.5, ehigh=7.0)
        SAOTraceUtils.save_spectrum_rdb("core_flux_chart.dat")

        return pval