View Raw SPL
/*****************************************************************************
*                                                                            *
*   XEXTRACT.SPL Copyright (C) 2012-2016 DSP Development Corporation         *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:       Randy Race                                                 *
*                                                                            *
*   Synopsis:     Extract a series segment based on X values                 *
*                                                                            *
*   Revisions:    10 Apr 2012  RRR  Creation                                 *
*                 13 Nov 2015  RRR  re-target X offset                       *
*                 21 Oct 2016  RRR  re-target only if requested              *
*                                                                            *
*****************************************************************************/

#if @HELP_XEXTRACT

    XEXTRACT

    Purpose: Extract a portion of a series based on X values.

    Syntax:  XEXTRACT(s, x1, x2, offset, retarget)

                   s - A series, the input series.

                  x1 - A real, the starting X value.

                  x2 - Optional. A real, the ending X values. Defaults to the
                       series extent.

              offset - Optional. A real, the x-offset of the resulting
                       series. Defaults to x1, the starting value.

              retarg - Optional. An integer tag to retarget the OFFSET value
                       to land on a series index value.

                         0: use OFFSET as given (default)
                         1: retarget OFFSET to index value

    Returns: A series, the extracted result.

    Example:
             W1: 1..100;setdeltax(1/100)
             W2: xextract(w1, 1.2, 1.25)

             W2 == {21, 22, 23, 24, 25, 26} with an x-offset of 1.2 and a delta-x
             of 0.01.

    Example:
             W1: 1..100;setdeltax(1/100)
             W2: xextract(w1, 1.2, 1.25, 0)

             Same as above except the x-offset is set to 0.0.

    Example:
             W1: gnorm(1000, 1/100)
             W2: xextract(w1, 3)

             Extracts 700 points of W1 from 3 seconds to 9.99 seconds.

    Example:
             W1: gnorm(1000, 1/100)
             W2: xextract(w1, -10, 20)

             Preserves W1 but prepends zeros from -10 seconds to 0 seconds
             and appends zeros from 10 seconds to 20 seconds. The resulting
             series contains 3001 samples.

    Remarks:
             If X1 is prior to the start of the series (the x-offset),
             zeros are prepended to the result.  If X2 is beyond the
             end of the series, the result is padded with zeros.

             If RETARG is set, the OFFSET value is converted to a value
             that lands on an index of the result.

             See EXTRACT to extract a series based on indices.

    See Also:
             Colextract
             Extract
#endif


/* extract based on X values */
ITERATE xextract(s, x1, x2, offset, retarg, zeropad)
{
        local i1, i2, len;

        if (argc < 6)
        {
                if (argc < 5)
                {
                        if (argc < 4)
                        {
                                if (argc < 3)
                                {
                                        if (argc < 2)
                                        {
                                                if (argc < 1) error("xextract - series required");

                                                /* default to first x value */        
                                                x1 = idxtox(s, 1);
                                        }

                                        /* default to last x value */
                                        x2 = idxtox(s, length(s));
                                }

                                /* x offset */
                                offset = min(x1, x2);
                        }

                        /* accept offset as is */
                        retarg = 0;
                }

                /* zero pad by default */
                zeropad = 1;
        }

        /* convert to indices without range limits if zero pad */
        i1 = xtoidx(s, x1, not(zeropad));
        i2 = xtoidx(s, x2, not(zeropad));

        /* extraction length and starting index */
        len = abs(i2 - i1) + 1;
        i1  = min(i1, i2);

        if (isnavalue(offset))
        {
                offset = min(x1, x2);
        }

        /* re-target x offset to existing value */
        if (retarg && not(offset == 0))
        {
                offset = idxtox(s, xtoidx(s, offset));
        }

        /* extract segment */
        s = extract(s, i1, len, offset);

        return(s);
}