acgc.stats.boxcar API documentation

# acgc.stats.boxcar

View Source

      1# -*- coding: utf-8 -*-
      2
      3import numpy as np
      4
      5__all__ = [
      6    "boxcar",
      7    "boxcarpoly"
      8]
      9
     10def boxcarpoly( array, width, order=2, align='center'):
     11    '''Calculate a boxcar polynomial (i.e. running polynomial fit) of an array.
     12
     13    See `boxcar` for parameter definitions
     14    '''
     15    return boxcar( array, width, order=order, align=align, method='polynomial')
     16
     17def boxcar( array, width, align='center', method='mean', order=2 ):
     18    '''Calculate a boxcar average (i.e. running mean, median, or polynomial fit) of an array.
     19
     20    Elements of input array are assumed to be equally spaced along an (unspecified)
     21    coordinate dimension.
     22
     23    A centered boxcar average with even widths is traditionally
     24    not allowed. This BOXCAR program allows even widths by
     25    giving half weights to elements on either end of the
     26    averaging window and full weights to all others. A centered
     27    average with even width therefore uses uses WIDTH+1
     28    elements in its averaging kernel.
     29
     30    Parameters
     31    ----------
     32    array : array of float (N,)
     33        1D array of values to average
     34    width : int
     35        number of elements to include in the average.
     36    align : str
     37        specifies how the averaging window for each element of the output array
     38        aligns with the input array.
     39        Values: center (default), forward (trailing elements), backward (leading elements)
     40    method : {'mean' (default), 'median', 'polynomial'}
     41        specifies the averaging kernel function
     42    order : int, default=2
     43        specifies the polynomial order to fit within each boxcar window.
     44        This has no effect unless `method`='polynomial'
     45        A parabola is order=2; order=0 is equivalent to method="mean"
     46
     47    Returns
     48    -------
     49    result : array of float (N,)
     50        1D array with averages with same size as input array.
     51        Elements on either end may be NaN
     52    '''
     53
     54    N = array.size
     55
     56    # Initialize smoothed array
     57    smootharray = np.empty_like(array)
     58    smootharray[:] = np.NaN
     59
     60    # uniform averaging kernel
     61    kernel = np.ones(width)
     62
     63    # Setup for backward boxcar
     64    if align=='backward':
     65        # Half widths before and after element I
     66
     67        HW1 = width-1
     68        HW2 = width-HW1-1
     69
     70    # Setup for forward boxcar
     71    elif align=='forward':
     72        HW1 = 0
     73        HW2 = width-HW1-1
     74
     75    # Setup for centered boxcar
     76    elif align=='center':
     77        # Separate treatments for odd and even widths
     78        if np.mod(width,2)==1:
     79            # Odd widths
     80            HW1 = np.floor(width/2)
     81            HW2 = width-HW1-1
     82
     83        else:
     84            # Even widths
     85            HW1 = width/2
     86            HW2 = width-HW1
     87
     88            # Uniform kernel in middle
     89            kernel = np.ones(width+1)
     90
     91            # Half weight kernel for ends
     92            kernel[0] = 0.5
     93            kernel[width] = 0.5
     94
     95            # Normalize the kernel
     96            kernel=kernel/kernel.sum()
     97    else:
     98        raise ValueError( f'align={align} not implemented. '
     99                         + 'Value should be "center", "forward" or "backward".' )
    100
    101    # Convert to integer type
    102    HW1 = int(HW1)
    103    HW2 = int(HW2)
    104
    105    # Do boxcar
    106    for i in range(HW1,N-HW2-1):
    107
    108        # Sub array that we operate on
    109        sub = array[i-HW1:i+HW2+1]
    110
    111        if method=='median':
    112            # Running median
    113            smootharray[i] = np.nanmedian(sub)
    114
    115        elif method=='mean':
    116            # Running mean
    117            # Kernel average, only over finite elements
    118            #(NaNs removed from numerator and denominator
    119            smootharray[i] = np.nansum( sub*kernel ) / np.sum(kernel[np.where(np.isfinite(sub))])
    120
    121        elif method=='polynomial':
    122
    123            # Local x coordinate
    124            x = np.arange(-HW1,HW2+1)
    125
    126            # Fit with polynomial of specified order
    127            # Avoid NaNs
    128            idx = np.isfinite(sub)
    129
    130            # number of valid points (non NaN)
    131            nvalid = np.sum(idx)
    132
    133            if nvalid==0:
    134                # smoothed value is NaN when there are no valid points
    135                smootharray[i] = np.nan
    136
    137            else:
    138                # A polynomial fit requires at least (order+1) points.
    139                # When there are fewer points, use the highest possible order.
    140                ordmax = np.max([np.min([order,np.sum(idx)-1]),0])
    141
    142                p = np.polyfit(x[idx],sub[idx],ordmax,w=kernel[idx])
    143
    144                # The fitted value at local x=0 is just the constant term
    145                smootharray[i] = p[order]
    146
    147        else:
    148            raise ValueError( f'method={method} not implemented. '
    149                             + 'Value should be "mean", "median" or "polynomial"')
    150
    151    return smootharray

def boxcar(array, width, align='center', method='mean', order=2): View Source

     18def boxcar( array, width, align='center', method='mean', order=2 ):
     19    '''Calculate a boxcar average (i.e. running mean, median, or polynomial fit) of an array.
     20
     21    Elements of input array are assumed to be equally spaced along an (unspecified)
     22    coordinate dimension.
     23
     24    A centered boxcar average with even widths is traditionally
     25    not allowed. This BOXCAR program allows even widths by
     26    giving half weights to elements on either end of the
     27    averaging window and full weights to all others. A centered
     28    average with even width therefore uses uses WIDTH+1
     29    elements in its averaging kernel.
     30
     31    Parameters
     32    ----------
     33    array : array of float (N,)
     34        1D array of values to average
     35    width : int
     36        number of elements to include in the average.
     37    align : str
     38        specifies how the averaging window for each element of the output array
     39        aligns with the input array.
     40        Values: center (default), forward (trailing elements), backward (leading elements)
     41    method : {'mean' (default), 'median', 'polynomial'}
     42        specifies the averaging kernel function
     43    order : int, default=2
     44        specifies the polynomial order to fit within each boxcar window.
     45        This has no effect unless `method`='polynomial'
     46        A parabola is order=2; order=0 is equivalent to method="mean"
     47
     48    Returns
     49    -------
     50    result : array of float (N,)
     51        1D array with averages with same size as input array.
     52        Elements on either end may be NaN
     53    '''
     54
     55    N = array.size
     56
     57    # Initialize smoothed array
     58    smootharray = np.empty_like(array)
     59    smootharray[:] = np.NaN
     60
     61    # uniform averaging kernel
     62    kernel = np.ones(width)
     63
     64    # Setup for backward boxcar
     65    if align=='backward':
     66        # Half widths before and after element I
     67
     68        HW1 = width-1
     69        HW2 = width-HW1-1
     70
     71    # Setup for forward boxcar
     72    elif align=='forward':
     73        HW1 = 0
     74        HW2 = width-HW1-1
     75
     76    # Setup for centered boxcar
     77    elif align=='center':
     78        # Separate treatments for odd and even widths
     79        if np.mod(width,2)==1:
     80            # Odd widths
     81            HW1 = np.floor(width/2)
     82            HW2 = width-HW1-1
     83
     84        else:
     85            # Even widths
     86            HW1 = width/2
     87            HW2 = width-HW1
     88
     89            # Uniform kernel in middle
     90            kernel = np.ones(width+1)
     91
     92            # Half weight kernel for ends
     93            kernel[0] = 0.5
     94            kernel[width] = 0.5
     95
     96            # Normalize the kernel
     97            kernel=kernel/kernel.sum()
     98    else:
     99        raise ValueError( f'align={align} not implemented. '
    100                         + 'Value should be "center", "forward" or "backward".' )
    101
    102    # Convert to integer type
    103    HW1 = int(HW1)
    104    HW2 = int(HW2)
    105
    106    # Do boxcar
    107    for i in range(HW1,N-HW2-1):
    108
    109        # Sub array that we operate on
    110        sub = array[i-HW1:i+HW2+1]
    111
    112        if method=='median':
    113            # Running median
    114            smootharray[i] = np.nanmedian(sub)
    115
    116        elif method=='mean':
    117            # Running mean
    118            # Kernel average, only over finite elements
    119            #(NaNs removed from numerator and denominator
    120            smootharray[i] = np.nansum( sub*kernel ) / np.sum(kernel[np.where(np.isfinite(sub))])
    121
    122        elif method=='polynomial':
    123
    124            # Local x coordinate
    125            x = np.arange(-HW1,HW2+1)
    126
    127            # Fit with polynomial of specified order
    128            # Avoid NaNs
    129            idx = np.isfinite(sub)
    130
    131            # number of valid points (non NaN)
    132            nvalid = np.sum(idx)
    133
    134            if nvalid==0:
    135                # smoothed value is NaN when there are no valid points
    136                smootharray[i] = np.nan
    137
    138            else:
    139                # A polynomial fit requires at least (order+1) points.
    140                # When there are fewer points, use the highest possible order.
    141                ordmax = np.max([np.min([order,np.sum(idx)-1]),0])
    142
    143                p = np.polyfit(x[idx],sub[idx],ordmax,w=kernel[idx])
    144
    145                # The fitted value at local x=0 is just the constant term
    146                smootharray[i] = p[order]
    147
    148        else:
    149            raise ValueError( f'method={method} not implemented. '
    150                             + 'Value should be "mean", "median" or "polynomial"')
    151
    152    return smootharray

Calculate a boxcar average (i.e. running mean, median, or polynomial fit) of an array.

Elements of input array are assumed to be equally spaced along an (unspecified) coordinate dimension.

A centered boxcar average with even widths is traditionally not allowed. This BOXCAR program allows even widths by giving half weights to elements on either end of the averaging window and full weights to all others. A centered average with even width therefore uses uses WIDTH+1 elements in its averaging kernel.

###### Parameters

- array (array of float (N,)): 1D array of values to average
- width (int): number of elements to include in the average.
- align (str): specifies how the averaging window for each element of the output array aligns with the input array. Values: center (default), forward (trailing elements), backward (leading elements)
- method ({'mean' (default), 'median', 'polynomial'}): specifies the averaging kernel function
- order (int, default=2): specifies the polynomial order to fit within each boxcar window. This has no effect unless `method`='polynomial' A parabola is order=2; order=0 is equivalent to method="mean"

###### Returns

- result (array of float (N,)): 1D array with averages with same size as input array. Elements on either end may be NaN

def boxcarpoly(array, width, order=2, align='center'): View Source

    11def boxcarpoly( array, width, order=2, align='center'):
    12    '''Calculate a boxcar polynomial (i.e. running polynomial fit) of an array.
    13
    14    See `boxcar` for parameter definitions
    15    '''
    16    return boxcar( array, width, order=order, align=align, method='polynomial')

Calculate a boxcar polynomial (i.e. running polynomial fit) of an array.

See `boxcar` for parameter definitions