Example #1
0
def sample_flux(fit, data, src, method=calc_energy_flux, correlated=False,
                num=1, lo=None, hi=None, numcores=None, samples=None):

    #
    # The following function should be modified to take advantage of numpy
    #
    def within_limits( mysamples, mymins, mymaxs ):
        num_par = mysamples.shape[ 1 ]
        for row in mysamples:
            for index in xrange( num_par ):
                if row[ index ] < mymins[ index ]:
                    row[ index ] = mymins[ index ]
                if row[ index ] > mymaxs[ index ]:
                    row[ index ] = mymaxs[ index ]
        return mysamples

    sampler = NormalParameterSampleFromScaleVector()
    if correlated:
        sampler = NormalParameterSampleFromScaleMatrix()

    # If user entered a covariance matrix but wants to run with
    # correlated as false then extract the diagonal elements.
    if correlated == False and samples != None:
        if numpy.ndarray == type( samples ):
            samples = samples.diagonal( 0 )

    samples = sampler.get_sample(fit, samples, num=num)

    hardmins = fit.model._get_thawed_par_hardmins()
    hardmaxs = fit.model._get_thawed_par_hardmaxes()
    samples = within_limits( samples, hardmins, hardmaxs )

    return calc_flux(fit, data, src, samples, method, lo, hi, numcores)
Example #2
0
def sample_flux(fit, data, src, method=calc_energy_flux, correlated=False,
                num=1, lo=None, hi=None, numcores=None, samples=None):

    #
    # The following function should be modified to take advantage of numpy
    #
    def within_limits(mysamples, mymins, mymaxs):
        num_par = mysamples.shape[1]
        for row in mysamples:
            for index in xrange(num_par):
                if row[index] < mymins[index]:
                    row[index] = mymins[index]
                if row[index] > mymaxs[index]:
                    row[index] = mymaxs[index]
        return mysamples

    sampler = NormalParameterSampleFromScaleVector()
    if correlated:
        sampler = NormalParameterSampleFromScaleMatrix()

    # If user entered a covariance matrix but wants to run with
    # correlated as false then extract the diagonal elements.
    if correlated == False and samples is not None:
        if numpy.ndarray == type(samples):
            samples = samples.diagonal(0)

    samples = sampler.get_sample(fit, samples, num=num)

    hardmins = fit.model._get_thawed_par_hardmins()
    hardmaxs = fit.model._get_thawed_par_hardmaxes()
    samples = within_limits(samples, hardmins, hardmaxs)

    return calc_flux(fit, data, src, samples, method, lo, hi, numcores)
Example #3
0
def sample_flux(fit, data, src, method=calc_energy_flux, correlated=False,
                num=1, lo=None, hi=None, numcores=None, samples=None):

    #
    # The following function should be modified to take advantage of numpy
    #
    def within_limits( mysamples, mymins, mymaxs ):
        num_par = mysamples.shape[ 1 ]
        for row in mysamples:
            for index in xrange( num_par ):
                if row[ index ] < mymins[ index ]:
                    row[ index ] = mymins[ index ]
                if row[ index ] > mymaxs[ index ]:
                    row[ index ] = mymaxs[ index ]
        return mysamples

    sampler = NormalParameterSampleFromScaleVector()
    if correlated:
        sampler = NormalParameterSampleFromScaleMatrix()
    samples = sampler.get_sample(fit, samples, num=num)

    hardmins = fit.model._get_thawed_par_hardmins()
    hardmaxs = fit.model._get_thawed_par_hardmaxes()
    samples = within_limits( samples, hardmins, hardmaxs )

    return calc_flux(fit, data, src, samples, method, lo, hi, numcores)
Example #4
0
def _sample_flux_get_samples(fit, src, correlated, num, clip='hard'):
    """Return the parameter samples, using fit to define the scales.

    The covariance method is used to estimate the errors for the
    parameter sampling.

    Parameters
    ----------
    fit : sherpa.fit.Fit instance
        The fit instance. The fit.model expression is assumed to include
        any necessary response information. The number of free parameters
        in the model expression is mfree.
    src : sherpa.models.ArithmeticModel instance
        The model for which the flux is being calculated. This must be
        a subset of the fit.model expression, and should not include the
        response information. There must be at least one thawed parameter
        in this model. The number of free parameters in src is sfree and
        must be <= mfree.
    correlated : bool
        Are the parameters assumed to be correlated or not?
    num : int
        Tne number of samples to return. This must be 1 or greater.
    clip : {'hard', 'soft', 'none'}, optional
        What clipping strategy should be applied to the sampled
        parameters. The default ('hard') is to fix values at their
        hard limits if they exceed them. A value of 'soft' uses the
        soft limits instead, and 'none' applies no clipping. The last
        column in the returned arrays indicates if the row had any
        clipped parameters (even when clip is set to 'none').

    Returns
    -------
    samples, clipped : 2D NumPy array, 1D NumPy array
        The dimensions are num by mfree. The ordering of the parameter
        values in each row matches that of the free parameters in
        fit.model. The clipped array indicates whether a row
        had one or more clipped parameters.

    Notes
    -----
    The support for src being a subset of the fit.model argument
    has not been tested for complex models, that is when fit.model
    is rmf(arf(source_model)) and src is a combination of components
    in source_model but not all the components of source_model.
    """

    npar = len(src.thawedpars)
    mpar = len(fit.model.thawedpars)
    assert mpar >= npar

    if correlated:
        sampler = NormalParameterSampleFromScaleMatrix()
    else:
        sampler = NormalParameterSampleFromScaleVector()

    samples = sampler.get_sample(fit, num=num)
    clipped = sampler.clip(fit, samples, clip=clip)
    return samples, clipped
Example #5
0
def _sample_flux_get_samples(fit, src, correlated, num):
    """Return the parameter samples, using fit to define the scales.

    The covariance method is used to estimate the errors for the
    parameter sampling.

    Parameters
    ----------
    fit : sherpa.fit.Fit instance
        The fit instance. The fit.model expression is assumed to include
        any necessary response information. The number of free parameters
        in the model expression is mfree.
    src : sherpa.models.ArithmeticModel instance
        The model for which the flux is being calculated. This must be
        a subset of the fit.model expression, and should not include the
        response information. There must be at least one thawed parameter
        in this model. The number of free parameters in src is sfree and
        must be <= mfree.
    correlated : bool
        Are the parameters assumed to be correlated or not?
    num : int
        Tne number of samples to return. This must be 1 or greater.

    Returns
    -------
    samples : 2D NumPy array
        The dimensions are num by mfree. The ordering of the parameter
        values in each row matches that of the free parameters in
        fit.model.

    Notes
    -----
    The support for src being a subset of the fit.model argument
    has not been tested for complex models, that is when fit.model
    is rmf(arf(source_model)) and src is a combination of components
    in source_model but not all the components of source_model.
    """

    npar = len(src.thawedpars)
    mpar = len(fit.model.thawedpars)
    assert mpar >= npar

    if correlated:
        sampler = NormalParameterSampleFromScaleMatrix()
    else:
        sampler = NormalParameterSampleFromScaleVector()

    return sampler.get_sample(fit, num=num)
Example #6
0
def _sample_flux_get_samples_with_scales(fit,
                                         src,
                                         correlated,
                                         scales,
                                         num,
                                         clip='hard'):
    """Return the parameter samples given the parameter scales.

    Parameters
    ----------
    fit : sherpa.fit.Fit instance
        The fit instance. The fit.model expression is assumed to include
        any necessary response information. The number of free parameters
        in fit.model is mfree.
    src : sherpa.models.ArithmeticModel instance
        The model for which the flux is being calculated. This must be
        a subset of the fit.model expression, and should not include the
        response information. There must be at least one thawed parameter
        in this model. The number of free parameters in src is sfree.
    correlated : bool
        Are the parameters assumed to be correlated or not? If correlated
        is True then scales must be 2D.
    scales : 1D or 2D array
        The parameter scales. When 1D they are the gaussian sigma
        values for the parameter, and when a 2D array they are
        the covariance matrix. The scales parameter must match the number
        of parameters in fit (mfree) and not in src (sfree) when they
        are different. For 1D the size is mfree and for 2D it is
        mfree by mfree.
    num : int
        Tne number of samples to return. This must be 1 or greater.
    clip : {'hard', 'soft', 'none'}, optional
        What clipping strategy should be applied to the sampled
        parameters. The default ('hard') is to fix values at their
        hard limits if they exceed them. A value of 'soft' uses the
        soft limits instead, and 'none' applies no clipping. The last
        column in the returned arrays indicates if the row had any
        clipped parameters (even when clip is set to 'none').

    Returns
    -------
    samples, clipped : 2D NumPy array, 1D NumPy array
        The dimensions are num by mfree. The ordering of the parameter
        values in each row matches that of the free parameters in
        fit.model.  The clipped array indicates whether a row had one
        or more clipped parameters.

    Raises
    ------
    ArgumentErr
        If the scales argument contains invalid (e.g. None or IEEE
        non-finite values) values, or is the wrong shape.
    ModelErr
        If the scales argument has the wrong size (that is, it
        does not represent mfree parameter values).

    Notes
    -----
    The support for src being a subset of the fit.model argument
    has not been tested for complex models, that is when fit.model
    is rmf(arf(source_model)) and src is a combination of components
    in source_model but not all the components of source_model.

    """

    npar = len(src.thawedpars)
    mpar = len(fit.model.thawedpars)
    assert mpar >= npar

    scales = numpy.asarray(scales)

    # A None value will cause scales to have a dtype of object,
    # which is not supported by isfinite, so check for this
    # first.
    #
    # Numpy circa 1.11 raises a FutureWarning with 'if None in scales:'
    # about this changing to element-wise comparison (which is what
    # we want). To avoid this warning I use the suggestion from
    # https://github.com/numpy/numpy/issues/1608#issuecomment-9618150
    #
    if numpy.equal(None, scales).any():
        raise ArgumentErr('bad', 'scales', 'must not contain None values')

    # We require that scales only has finite values in it.
    # The underlying sample routines are assumed to check other
    # constraints, or deal with negative values (for the 1D case
    # uncorrelated case the absolute value is used).
    #
    if not numpy.isfinite(scales).all():
        raise ArgumentErr('bad', 'scales', 'must only contain finite values')

    if scales.ndim == 2 and (scales.shape[0] != scales.shape[1]):
        raise ArgumentErr('bad', 'scales', 'scales must be square when 2D')

    # Ensure the scales array matches the correlated parameter:
    #  - when True it must be the covariance matrix (2D)
    #  - when False it can be either be a 1D array of sigmas or
    #    the covariance matrix, which we convert to an array of
    #    sigmas
    #
    if correlated:
        if scales.ndim != 2:
            raise ArgumentErr('bad', 'scales',
                              'when correlated=True, scales must be 2D')
    elif scales.ndim == 2:
        # convert from covariance matrix
        scales = numpy.sqrt(scales.diagonal())
    elif scales.ndim != 1:
        raise ArgumentErr('bad', 'scales',
                          'when correlated=False, scales must be 1D or 2D')

    # At this point either 1D or 2D square array. Now to check the
    # number of elements.
    #
    if scales.shape[0] != mpar:
        raise ModelErr('numthawed', mpar, scales.shape[0])

    if correlated:
        sampler = NormalParameterSampleFromScaleMatrix()
    else:
        sampler = NormalParameterSampleFromScaleVector()

    samples = sampler.get_sample(fit, scales, num=num)
    clipped = sampler.clip(fit, samples, clip=clip)
    return samples, clipped