Пример #1
0
    def fit(self, conf = False):


        ui.ignore(None, None)
        ui.notice(self.start, self.stop)
        self.set_source()
        ui.fit(1)
        if conf:
            ui.conf()
        res = ui.get_fit_results()

        for line in (self.H2lines + self.nonH2lines):
            sourcename = line['source'].split('.')[1]
            print sourcename
            for p in ['pos', 'fwhm', 'ampl']:
                n = '{0}.{1}'.format(sourcename, p)
                _place_val(line, p, ui.get_par(n).val)

        self.const = ui.get_par('c1.c0').val
        self.redchi2 = res.rstat


        if conf:
            res = ui.get_conf_results()
            for line in (self.H2lines + self.nonH2lines):
                sourcename = line['source'].split('.')[1]
                for p in ['pos', 'fwhm', 'ampl']:
                    n = '{0}.{1}'.format(sourcename, p)
                    parmin, parmax = _parminmax(res, n)
                    line[p+'_max'] = parmax
                    line[p+'_min'] = parmin
            # deal with error on const
            parmin, parmax = _parminmax(res, 'c1.c0')
            self.const_min = parmin
            self.const_max = parmax
Пример #2
0
    def center_psf(self):
        """Set ``xpos`` and ``ypos`` of the PSF to the dataspace center."""
        import sherpa.astro.ui as sau
        try:
            ny, nx = sau.get_data().shape
            for _ in ['psf1', 'psf2', 'psf3']:
                par = sau.get_par(_ + '.xpos')
                par.val = nx / 2.

                par = sau.get_par(_ + '.ypos')
                par.val = ny / 2.
        except:
            raise Exception('PSF is not centered.')
Пример #3
0
    def center_psf(self):
        """Set ``xpos`` and ``ypos`` of the PSF to the dataspace center."""
        import sherpa.astro.ui as sau
        try:
            ny, nx = sau.get_data().shape
            for _ in ['psf1', 'psf2', 'psf3']:
                par = sau.get_par(_ + '.xpos')
                par.val = nx / 2.

                par = sau.get_par(_ + '.ypos')
                par.val = ny / 2.
        except:
            raise Exception('PSF is not centered.')
Пример #4
0
def _set_val(model, argstring, val):
    '''Set the value of a Sherpa model parameter

    Parameters
    ----------
    model : sherpa model instance
    argstring : string
        name of the parameter, e.g. 'kT' or 'norm'
    val : string or number
        Value to be set. Can be number or string of the form
        'f 1234' which set the parameter to 1234 and freezes it.
    '''
    par = ui.get_par(model.name+'.'+argstring)
    if isinstance(val, basestring):

        if val[0] == '"':
            val = val[1:-1]
        val = val.strip('" \t').strip("' \t").split()
        par.frozen = False
        for v in val:
            print v
            if v == 'f':
                par.frozen = True
            elif _isfloat(v):
                par.val = float(v)
            else:
                raise ValueError('Not valid format to set a parameter {0}'.format(v))

    else:
        par.frozen = False
        par.val = val
Пример #5
0
    def fit(self):
        """
        Do a fit of the model parameters using the "onion-peeling" method:   

         - First fit the outside shell model using the outer annulus spectrum
         - Freeze the model parameters for the outside shell
         - Fit the next inward shell / annulus and freeze those parameters
         - Repeat until all datasets have been fit and all shell parameters determined.
         - Return model parameters to original thawed/frozen status

        :rtype: None
        """
        thawed = []                  # Parameter objects that are not already frozen
        for annulus in reversed(range(self.nshell)):
            dataids = [x['id'] for x in self.datasets if x['annulus'] == annulus]
            print 'Fitting', dataids
            SherpaUI.fit(*dataids)
            for model_comp in self.model_comps:
                name = model_comp['name']
                if model_comp['shell'] == annulus:
                    # Remember parameters that are currently thawed
                    for par in [SherpaUI.get_par('%s.%s'%(name, x))
                                for x in SherpaUI.get_model_pars(name)]:
                        if not par.frozen:
                            thawed.append(par)
                    print 'Freezing', model_comp['name']
                    SherpaUI.freeze(model_comp['name'])

        # Unfreeze parameters
        for par in thawed:
            print 'Thawing', par.fullname
            par.thaw()
Пример #6
0
def _get_parameter_value(name, val):
    """Return a numeric value given one of:
       a number
       a model parameter (something with a .val field)
       a string nameing a model parameter

    The name field is used in any error message, val is the
    value to decode.

    Raises an ValueError if unable to retrieve a number.

    If val is not a string or without a .val field then we just
    return val. We do not throw an error.
    """

    # Could try isinstance(val, sherpa.models.parameter.Parameter)
    # here instead, but stick with hasattr for now
    #
    if hasattr(val, "val"):
        return val.val
    elif isinstance(val, str):
        try:
            return ui.get_par(val).val
        except ArgumentErr:
            raise ValueError(
                "Name of {0} argument does not appear to be a model parameter: '{1}'"
                .format(name, val))
    else:
        return val
Пример #7
0
def test_user_model_stat_docs():
    """
    This test reproduces the documentation shown at:
    http://cxc.harvard.edu/sherpa4.4/statistics/#userstat

    and:
    http://cxc.harvard.edu/sherpa/threads/user_model/

    I tried to be as faithful as possible to the original, although the examples in thedocs
    are not completely self-contained, so some changes were necessary. I changed the numpy
    reference, as it is imported as `np` here, and added a clean up of the environment
    before doing anything.

    For the model, the difference is that I am not importing the function from an
    external module, plus the dataset is different.

    Also, the stats docs do not perform a fit.
    """
    def my_stat_func(data, model, staterror, syserror=None, weight=None):
        # A simple function to replicate χ2
        fvec = ((data - model) / staterror)**2
        stat = fvec.sum()
        return (stat, fvec)

    def my_staterr_func(data):
        # A simple staterror function
        return np.sqrt(data)

    def myline(pars, x):
        return pars[0]*x + pars[1]

    x = [1, 2, 3]
    y = [4, 5, 6.01]

    ui.clean()
    ui.load_arrays(1, x, y)
    ui.load_user_stat("mystat", my_stat_func, my_staterr_func)
    ui.set_stat(eval('mystat'))
    ui.load_user_model(myline, "myl")
    ui.add_user_pars("myl", ["m", "b"])
    ui.set_model(eval('myl'))

    ui.fit()

    assert ui.get_par("myl.m").val == approx(1, abs=0.01)
    assert ui.get_par("myl.b").val == approx(3, abs=0.01)
Пример #8
0
    def conf(self):
        """
        Run conf on each of the model parameters using the "onion-peeling" method:   

         - First conf the outside shell model using the outer annulus spectrum
         - Freeze the model parameters for the outside shell
         - get confidences for the next inward shell / annulus and freeze those parameters
         - Repeat until all datasets have been conf()-ed and all shell-by-shell error parameters determined.
         - Return model parameters to original thawed/frozen status
         - WARNING: This ignores the correlations between parameters

        :rtype: None
        """
        thawed = []                  # Parameter objects that are not already frozen
        conf_results = []
        this_conf_result = []
        for annulus in reversed(range(self.nshell)):
            dataids = [x['id'] for x in self.datasets if x['annulus'] == annulus]
            print 'Getting shell-by-shell confidence for dataset ', dataids
            SherpaUI.conf(*dataids)
            this_conf_result = SherpaUI.get_conf_results()
            conf_results.insert(0, this_conf_result)
            for model_comp in self.model_comps:
                name = model_comp['name']
                if model_comp['shell'] == annulus:
                    # Remember parameters that are currently thawed
                    for par in [SherpaUI.get_par('%s.%s'%(name, x))
                                for x in SherpaUI.get_model_pars(name)]:
                        if not par.frozen:
                            thawed.append(par)
                    print 'Freezing', model_comp['name']
                    SherpaUI.freeze(model_comp['name'])

        # Unfreeze parameters
        for par in thawed:
            print 'Thawing', par.fullname
            par.thaw()
            
        return conf_results
Пример #9
0
def test_341():
    """
    The original reporter of bug #341 had a special implementation that should be captured
    by this test. The implementation has a proxy model that takes care of updating the actual
    model when it is evaluated. During a recent refactoring of the Stat and Fit code
    (PR #287) a regression was introduced by short-circuiting the evaluation of the model.

    """
    class ExampleModel(object):
        """ Class to define model
        """
        def __init__(self, x, y):
            self.x = np.array(x)
            self.y = np.array(y)
            self.parvals = [1, 2]
            self.parnames = ("m", "b")

        def calc_stat(self):
            return float(np.sum(np.abs(self.y - self.model())))

        def model(self):
            return self.parvals[0] * self.x + self.parvals[1]

    class CalcModel(object):
        """ Class to update model parameters
        """
        def __init__(self, model):
            self.model = model

        def __call__(self, pars, x):
            self.model.parvals = pars
            return np.ones_like(x)

    class CalcStat(object):
        """ Class to determine fit statistic
        """
        def __init__(self, model):
            self.model = model

        def __call__(self, _data, _model, *args, **kwargs):
            fit_stat = self.model.calc_stat()

            return fit_stat, np.ones(1)

    xdata = [1, 2, 3]
    ydata = [4, 5, 6]
    newmodel = ExampleModel(xdata, ydata)

    dummy_data = np.zeros(1)
    dummy_times = np.arange(1)
    ui.load_arrays(1, dummy_times, dummy_data)

    method = 'simplex'
    ui.set_method(method)

    ui.load_user_model(CalcModel(newmodel), 'simplemodel')
    ui.add_user_pars('simplemodel', newmodel.parnames)
    ui.set_model(1, 'simplemodel')

    calc_stat = CalcStat(newmodel)
    ui.load_user_stat('customstat', calc_stat, lambda x: np.ones_like(x))
    ui.set_stat(eval('customstat'))

    ui.fit(1)

    assert ui.get_par("simplemodel.m").val == approx(1, abs=0.00001)
    assert ui.get_par("simplemodel.b").val == approx(3, abs=0.00001)