Esempio n. 1
0
def _xrf_plot(x=None, y=None, mca=None, win=1, new=True, as_mca2=False, _larch=None,
              wxparent=None, size=None, side='left', force_draw=True, wintitle=None,
              **kws):
    """xrf_plot(energy, data[, win=1], options])

    Show XRF trace of energy, data

    Parameters:
    --------------
        energy :  array of energies
        counts :  array of counts
        mca:      Group counting MCA data (rois, etc)
        as_mca2:  use mca as background MCA

        win: index of Plot Frame (0, 1, etc).  May create a new Plot Frame.
        new: flag (True/False, default False) for whether to start a new plot.
        color: color for trace (name such as 'red', or '#RRGGBB' hex string)
        style: trace linestyle (one of 'solid', 'dashed', 'dotted', 'dot-dash')
        linewidth:  integer width of line
        marker:  symbol to draw at each point ('+', 'o', 'x', 'square', etc)
        markersize: integer size of marker

    See Also: xrf_oplot, plot
    """
    plotter = _getDisplay(wxparent=wxparent, win=win, size=size,
                          _larch=_larch, wintitle=wintitle, xrf=True)
    if plotter is None:
        return
    plotter.Raise()
    if x is None:
        return
    if isLarchMCAGroup(x):
        mca = x
        y = x.counts
        x = x.energy

    if as_mca2:
        new = False
        if isLarchMCAGroup(mca):
            plotter.plotmca(mca, as_mca2=True, new=False, **kws)
        elif y is not None:
            plotter.oplot(x, y, mca=mca, as_mca2=True, **kws)
    elif new:
        if isLarchMCAGroup(mca):
            plotter.plotmca(mca, **kws)
        elif y is not None:
            plotter.plot(x, y, mca=mca, **kws)
    else:
        plotter.oplot(x, y, mca=mca, **kws)
Esempio n. 2
0
def _xrf_plot(x=None, y=None, mca=None, win=1, new=True, as_mca2=False, _larch=None,
              wxparent=None, size=None, side='left', force_draw=True, wintitle=None,
              **kws):
    """xrf_plot(energy, data[, win=1], options])

    Show XRF trace of energy, data

    Parameters:
    --------------
        energy :  array of energies
        counts :  array of counts
        mca:      Group counting MCA data (rois, etc)
        as_mca2:  use mca as background MCA

        win: index of Plot Frame (0, 1, etc).  May create a new Plot Frame.
        new: flag (True/False, default False) for whether to start a new plot.
        color: color for trace (name such as 'red', or '#RRGGBB' hex string)
        style: trace linestyle (one of 'solid', 'dashed', 'dotted', 'dot-dash')
        linewidth:  integer width of line
        marker:  symbol to draw at each point ('+', 'o', 'x', 'square', etc)
        markersize: integer size of marker

    See Also: xrf_oplot, plot
    """
    plotter = _getDisplay(wxparent=wxparent, win=win, size=size,
                          _larch=_larch, wintitle=wintitle, xrf=True)
    if plotter is None:
        _larch.raise_exception(None, msg='No Plotter defined')
    plotter.Raise()
    if x is None:
        return
    if isLarchMCAGroup(x):
        mca = x
        y = x.counts
        x = x.energy

    if as_mca2:
        new = False
        if isLarchMCAGroup(mca):
            plotter.plotmca(mca, as_mca2=True, new=False, **kws)
        elif y is not None:
            plotter.oplot(x, y, mca=mca, as_mca2=True, **kws)
    elif new:
        if isLarchMCAGroup(mca):
            plotter.plotmca(mca, **kws)
        elif y is not None:
            plotter.plot(x, y, mca=mca, **kws)
    else:
        plotter.oplot(x, y, mca=mca, **kws)
Esempio n. 3
0
def xrf_calib_compute(mca, apply=False, _larch=None):
    """compute linear energy calibration
    from init_calib dictionary found from xrf_calib_fitrois()

    To exclude lines from the calibration, first run
     >>> xrf_calib_fitrois(mca)
    then remove items (by ROI name) from the mca.init_calib dictionay

    """
    if not isLarchMCAGroup(mca):
        print('Not a valid MCA')
        return
    if not hasattr(mca, 'init_calib'):
        xrf_calib_fitrois(mca, _larch=_larch)

    # current calib
    offset, slope = mca.offset, mca.slope
    x = np.array([c[3] for c in mca.init_calib.values()])
    y = np.array([c[0] for c in mca.init_calib.values()])
    _s, _o, r, p, std = linregress(x, y)

    mca.new_calib = (_o, _s)
    mca.cal_x = x
    mca.cal_y = y

    if apply:
        xrf_calib_apply(mca, offset=_o, slope=_s)
Esempio n. 4
0
def xrf_calib_compute(mca, apply=False, _larch=None):
    """compute linear energy calibration
    from init_calib dictionary found from xrf_calib_fitrois()

    To exclude lines from the calibration, first run
     >>> xrf_calib_fitrois(mca)
    then remove items (by ROI name) from the mca.init_calib dictionay

    """
    if not isLarchMCAGroup(mca):
        print( 'Not a valid MCA')
        return
    if not hasattr(mca, 'init_calib'):
        xrf_calib_fitrois(mca, _larch=_larch)

    # current calib
    offset, slope = mca.offset, mca.slope
    x = np.array([c[3] for c in mca.init_calib.values()])
    y = np.array([c[0] for c in mca.init_calib.values()])
    _s, _o, r, p, std = linregress(x, y)

    mca.new_calib = (_o, _s)
    mca.cal_x = x
    mca.cal_y = y

    if apply:
        xrf_calib_apply(mca, offset=_o, slope=_s)
Esempio n. 5
0
def xrf_calib_init_roi(mca, roiname):
    """initial calibration step for MCA:
    find energy locations for one ROI
    """
    if not isLarchMCAGroup(mca):
        print( 'Not a valid MCA')
        return
    energy = 1.0*mca.energy
    chans = 1.0*np.arange(len(energy))
    counts = mca.counts
    bgr = getattr(mca, 'bgr', None)
    if bgr is not None:
        counts = counts - bgr
    if not hasattr(mca, 'init_calib'):
        mca.init_calib = OrderedDict()

    roi = None
    for xroi in mca.rois:
        if xroi.name == roiname:
            roi = xroi
            break
    if roi is None:
        return
    words = roiname.split()
    elem = words[0].title()
    family = 'Ka'
    if len(words) > 1:
        family = words[1].title()
    if family == 'Lb':
        family = 'Lb1'
    eknown = xray_line(elem, family)[0]/1000.0
    llim = max(0, roi.left - roi.bgr_width)
    hlim = min(len(chans)-1, roi.right + roi.bgr_width)
    segcounts = counts[llim:hlim]
    maxcounts = max(segcounts)
    ccen = llim + np.where(segcounts==maxcounts)[0]
    ecen = ccen * mca.slope + mca.offset
    bkgcounts = counts[llim] + counts[hlim]
    if maxcounts < 2*bkgcounts:
        mca.init_calib[roiname] = (eknown, ecen, 0.0, ccen, None)
    else:
        model = GaussianModel() + ConstantModel()
        params = model.make_params(amplitude=maxcounts,
                                   sigma=(chans[hlim]-chans[llim])/2.0,
                                   center=ccen-llim, c=0.00)
        params['center'].min = -10
        params['center'].max = hlim - llim + 10
        params['c'].min = -10
        out = model.fit(counts[llim:hlim], params, x=chans[llim:hlim])
        ccen = llim + out.params['center'].value
        ecen = ccen * mca.slope + mca.offset
        fwhm = out.params['fwhm'].value * mca.slope
        mca.init_calib[roiname] = (eknown, ecen, fwhm, ccen, out)
def xrf_background(energy,
                   counts=None,
                   group=None,
                   width=4,
                   compress=2,
                   exponent=2,
                   slope=None,
                   _larch=None):
    """fit background for XRF spectra.  Arguments:

    xrf_background(energy, counts=None, group=None, width=4,
                   compress=2, exponent=2, slope=None)

    Arguments
    ---------
    energy     array of energies OR an MCA group.  If an MCA group,
               it will be used to give ``counts`` and ``mca`` arguments
    counts     array of XRF counts (or MCA.counts)
    group      group for outputs

    width      full width (in keV) of the concave down polynomials
               for when its full width is 100 counts. default = 4

    compress   compression factor to apply to spectra. Default is 2.

    exponent   power of polynomial used.  Default is 2, should be even.
    slope      channel to energy conversion, from energy calibration
               (default == None --> found from input energy array)

    outputs (written to group)
    -------
    bgr       background array
    bgr_info  dictionary of parameters used to calculate background
    """
    if isLarchMCAGroup(energy):
        group = energy
        counts = group.counts
        energy = group.energy
    if slope is None:
        slope = (energy[-1] - energy[0]) / len(energy)

    xbgr = XRFBackground(counts,
                         width=width,
                         compress=compress,
                         exponent=exponent,
                         slope=slope)

    if group is not None:
        group.bgr = xbgr.bgr
        group.bgr_info = xbgr.parinfo
Esempio n. 7
0
def xrf_calib_apply(mca, offset=None, slope=None, _larch=None):
    """apply calibration to MCA

    either supply offset and slope arguments (in keV and keV/chan)
    or run xrf_calib_compute(mca) to estimate these from ROI peaks
    """
    if not isLarchMCAGroup(mca):
        print('Not a valid MCA')
        return
    if (offset is None or slope is None) and not hasattr(mca, 'new_calib'):
        print('must supply offset and slope or run xrf_calib_compute()!')
        return

    if (offset is None or slope is None):
        offset, slope = mca.new_calib
    mca.offset = offset
    mca.slope = slope
    npts = len(mca.energy)
    mca.energy = offset + slope * np.arange(npts)
Esempio n. 8
0
def xrf_calib_apply(mca, offset=None, slope=None, _larch=None):
    """apply calibration to MCA

    either supply offset and slope arguments (in keV and keV/chan)
    or run xrf_calib_compute(mca) to estimate these from ROI peaks
    """
    if not isLarchMCAGroup(mca):
        print( 'Not a valid MCA')
        return
    if (offset is None or slope is None) and not hasattr(mca, 'new_calib'):
        print( 'must supply offset and slope or run xrf_calib_compute()!')
        return

    if (offset is None or slope is None):
        offset, slope = mca.new_calib
    mca.offset = offset
    mca.slope = slope
    npts = len(mca.energy)
    mca.energy = offset + slope*np.arange(npts)
Esempio n. 9
0
def xrf_background(energy, counts=None, group=None, width=4,
                   compress=2, exponent=2, slope=None,
                   _larch=None):
    """fit background for XRF spectra.  Arguments:

    xrf_background(energy, counts=None, group=None, width=4,
                   compress=2, exponent=2, slope=None)

    Arguments
    ---------
    energy     array of energies OR an MCA group.  If an MCA group,
               it will be used to give ``counts`` and ``mca`` arguments
    counts     array of XRF counts (or MCA.counts)
    group      group for outputs

    width      full width (in keV) of the concave down polynomials
               for when its full width is 100 counts. default = 4

    compress   compression factor to apply to spectra. Default is 2.

    exponent   power of polynomial used.  Default is 2, should be even.
    slope      channel to energy conversion, from energy calibration
               (default == None --> found from input energy array)

    outputs (written to group)
    -------
    bgr       background array
    bgr_info  dictionary of parameters used to calculate background
    """
    if isLarchMCAGroup(energy):
        group  = energy
        counts = group.counts
        energy = group.energy
    if slope is None:
        slope = (energy[-1] - energy[0])/len(energy)

    xbgr = XRFBackground(counts, width=width, compress=compress,
                         exponent=exponent, slope=slope)

    if group is not None:
        group.bgr = xbgr.bgr
        group.bgr_info = xbgr.parinfo
Esempio n. 10
0
def xrf_calib_fitrois(mca, _larch=None):
    """initial calibration step for MCA:
    find energy locations for all ROIs

    """
    if not isLarchMCAGroup(mca):
        print('Not a valid MCA')
        return

    energy = 1.0 * mca.energy
    chans = 1.0 * np.arange(len(energy))
    counts = mca.counts
    bgr = getattr(mca, 'bgr', None)
    if bgr is not None:
        counts = counts - bgr
    calib = OrderedDict()
    for roi in mca.rois:
        words = roi.name.split()
        elem = words[0].title()
        family = 'ka'
        if len(words) > 1:
            family = words[1]
        try:
            eknown = xray_line(elem, family, _larch=_larch)[0] / 1000.0
        except:
            continue
        llim = max(0, roi.left - roi.bgr_width)
        hlim = min(len(chans) - 1, roi.right + roi.bgr_width)
        fit = fit_peak(chans[llim:hlim],
                       counts[llim:hlim],
                       'Gaussian',
                       background='constant',
                       _larch=_larch)

        ccen = fit.params.center.value
        ecen = ccen * mca.slope + mca.offset
        fwhm = 2.354820 * fit.params.sigma.value * mca.slope
        calib[roi.name] = (eknown, ecen, fwhm, ccen, fit)
    mca.init_calib = calib
Esempio n. 11
0
def xrf_calib_fitrois(mca, _larch=None):
    """initial calibration step for MCA:
    find energy locations for all ROIs

    """
    if not isLarchMCAGroup(mca):
        print( 'Not a valid MCA')
        return

    energy = 1.0*mca.energy
    chans = 1.0*np.arange(len(energy))
    counts = mca.counts
    bgr = getattr(mca, 'bgr', None)
    if bgr is not None:
        counts = counts - bgr
    calib = OrderedDict()
    for roi in mca.rois:
        words = roi.name.split()
        elem = words[0].title()
        family = 'ka'
        if len(words) > 1:
            family = words[1]
        try:
            eknown = xray_line(elem, family, _larch=_larch)[0]/1000.0
        except:
            continue
        llim = max(0, roi.left - roi.bgr_width)
        hlim = min(len(chans)-1, roi.right + roi.bgr_width)
        fit = fit_peak(chans[llim:hlim], counts[llim:hlim],
                       'Gaussian', background='constant',
                       _larch=_larch)

        ccen = fit.params['center'].value
        ecen = ccen * mca.slope + mca.offset
        fwhm = 2.354820 * fit.params['sigma'].value * mca.slope
        calib[roi.name] = (eknown, ecen, fwhm, ccen, fit)
    mca.init_calib = calib
Esempio n. 12
0
def xrf_background(energy, counts=None, group=None, width=None, exponent=2, **kws):
    """fit background for XRF spectra.

    xrf_background(energy, counts=None, group=None, exponent=2)

    Arguments
    ---------
    energy     array of energies OR an MCA group.  If an MCA group,
               it will be used to give ``counts`` and ``mca`` arguments
    counts     array of XRF counts (or MCA.counts)
    group      group for outputs

    width      full width (in keV) of the concave down polynomials when its
               value is ~1% of max counts.  Default width is (energy range)/4.0
    exponent   power of polynomial used.  Default is 2, should be even.

    Outputs (written to group)
    -------
    bgr       background array
    bgr_info  dictionary of parameters used to calculate background
    """
    if isLarchMCAGroup(energy):
        group  = energy
        energy = group.energy
        if counts is None:
            counts = group.counts

    nchans = len(counts)
    slope = energy[1] - energy[0]
    if width is None:
        width = max(energy)/4.0

    tcounts = 1.0 * counts
    tcounts[np.where(tcounts<0.01)] = 0.01

    bgr = -1.0*np.ones(nchans)

    # use 1% of 99% percentile of counts as height at which
    # the polynomial should have full width = width
    max_count = np.percentile(tcounts, [99])[0]

    indices = np.linspace(-nchans, nchans, 2*nchans+1) * (2.0 * slope / width)
    polynom = 0.01 * max_count * indices**exponent
    polynom = np.compress((polynom <= max_count), polynom)
    max_index = int(len(polynom)/2 - 1)
    for chan in range(nchans-1):
       chan0  = max((chan - max_index), 0)
       chan1  = min((chan + max_index), (nchans-1))
       chan1  = max(chan1, chan0) + 1
       idx0   = chan0 - chan + max_index
       idx1   = chan1 - chan + max_index
       offset = tcounts[chan] - polynom[idx0:idx1]
       test   = tcounts[chan0:chan1] - offset
       bgr[chan0:chan1] = np.maximum(bgr[chan0:chan1],
                                       min(test)+offset)

    bgr[np.where(bgr <= 0)] = 0.0

    if group is not None:
        group.bgr = bgr
        group.bgr_info = dict(width=width, exponent=exponent)