View Raw SPL
/*****************************************************************************
* *
* WINCUT.SPL Copyright (C) 2025 DSP Development Corporation *
* All Rights Reserved *
* *
* Author: Randy Race *
* *
* Synopsis: Extracts series based on the displayed portion of a Window *
* *
* Revisions: 30 Jul 2025 RRR Creation - from cut.spl *
* *
*****************************************************************************/
#if @HELP_WINCUT
WINCUT
Purpose: Extracts a series based on the displayed contents of a Window.
Syntax: WINCUT(srcwin, series, cutxy, zeropad)
srcwin - A window, the source window to determine the
extraction range.
series - A series, the target series to extract from.
cutxy - Optional. An integer, 1: cut using both the x and y
displayed range, 0: cut using the x range only (default).
zeropad - Optional. An integer, 1: pad beginning and/or end
points with zeros if cut range beyond the series
size, 0: limit cut range to series extent (default).
Returns: A series or array
Example:
W1: gnorm(1000, 1/1000);setx(.2, .5)
W2: cumsum(w1)
W3: wincut(W1, W2)
W3 contains the data in W2 that is in the display range of W1.
Example:
W1: gnorm(1000, 1/1000);sety(-0.5, 1.5)
W2: gnorm(1000, 1/1000)
W3: wincut(W1, W2)
W4: wincut(W1, W2, 1)
W3 contains the same data as W2, but W4 contains the Y extracted
portion of the data displayed in W1. The Y values of W4 range
from -0.5 to 1.5.
Example:
W1: gnorm(1000, 1/1000);setx(-0.5, 1.5)
W2: cumsum(w1)
W3: wincut(W1, W2, 0, 0)
W4: wincut(W1, W2, 0, 1)
W3 contains the same data as W2 because the display range of W1
is longer than the data extent of W2. However, W4 pads the starting
and ending values of W2 with zeros to produce a series that extends
from -0.5 to 1.5.
Remarks:
Wincut works properly on arrays and images.
The ZEROPAD option only applies to series.
See CUT to extract the displayed portion of a window.
See Also:
Cut
Extract
Setvport
#endif
/* extract series based on displayed portion of a window */
wincut(srcwin, targ = refseries(w0), cutxy = 0, zeropad = 0)
{
local s;
if ((argc < 1) || not(iswindow(srcwin)))
{
error(sprintf("%s - source window required", __FUNC__));
}
if (not(isarray(targ)))
{
error(sprintf("%s - target series required", __FUNC__));
}
/* extract */
s = wincut_cut(srcwin, targ, cutxy, zeropad);
return(s);
}
/* core extracter */
wincut_cut(src, targ, cutxy, zeropad)
{
local nr, nc, s;
if (not(iswindow(src)))
{
error(sprintf("%s - Window Required", __CALLER__));
}
(nr, nc) = size(targ);
if (nc > 1 && not(ischart(targ)))
{
/* stripchart */
if (isstripchart(targ))
{
s = wincut_stripchart(src, targ, cutxy, zeropad, nr, nc);
}
else if (isxy(targ))
{
/* XY */
s = wincut_xy(src, targ, cutxy, zeropad, nr, nc);
}
else if (isxyz(targ))
{
/* XYZ */
s = wincut_xy(src, targ, 1, zeropad, nr, nc);
}
else
{
/* array */
s = wincut_array(src, targ, cutxy, zeropad, nr, nc);
}
}
else
{
s = wincut_interval(src, targ, cutxy, zeropad, nr, nc);
}
return(s);
}
/* swap lo to hi */
wincut_swap(a, b)
{
if (a > b)
{
return(b, a);
}
else
{
return(a, b);
}
}
/* cut XY window */
wincut_xy(src, targ, cutxy, zeropad, nr, nc)
{
local ixl, ixr, s;
/* X edges */
ixl = getxl(src);
ixr = getxr(src);
(ixl, ixr) = wincut_swap(ixl, ixr);
/* Y edges */
iyb = getyb(src);
iyt = getyt(src);
(iyb, iyt) = wincut_swap(iyb, iyt);
/* cut series */
s = wincut_xy_series(targ, ixl, ixr, iyb, iyt, cutxy, zeropad);
return(s);
}
/* cut XY series */
ITERATE wincut_xy_series(s, ixl, ixr, iyb, iyt, cutxy, zeropad)
{
local x;
if (not(isxy(s)) || isxymonotonic(s))
{
/* handles XY, offset set to actual series value */
s = xextract(s, ixl, ixr, nan, 1, zeropad);
}
else
{
/* non-monotonic in X */
x = xvals(s);
/* delete x values out of window range */
s = delete(s, x < ixl || x > ixr);
}
if (cutxy)
{
/* delete y values out of window range */
y = yvals(s);
s = delete(s, y < iyb || y > iyt);
}
return(s);
}
/* cut array */
wincut_array(src, targ, cutxy, zeropad, nr, nc)
{
local ptype, ixl, ixr, tmp, s = {};
if (nc > 1)
{
ptype = getplottype(src);
if (ptype > 0 && ptype < 6)
{
/* waterfall, contour, density, z or image */
ixl = xtoidx(src, getxl(src), 1);
ixr = xtoidx(src, getxr(src), 1);
iyb = castint(ceil( (getyb(src) - yoffset(src)) / deltay(src)) + 1);
iyt = castint(floor((getyt(src) - yoffset(src)) / deltay(src)) + 1);
if (iyb < 1) iyb = 1;
if (iyb > nc) iyb = nc;
if (iyt < 1) iyt = 1;
if (iyt > nc) iyt = nc;
(iyb, iyt) = wincut_swap(iyb, iyt);
if (ixl == ixr && ixr < nr) ixr++;
if (iyb == iyt && iyt < nc) iyt++;
/* extract region */
s = targ[ixl..ixr, iyb..iyt];
}
else
{
s = wincut_interval(src, targ, cutxy, zeropad, nr, nc);
}
}
return(s);
}
/* cut interval series */
ITERATE wincut_interval(src, targ, cutxy, zeropad, nr, nc)
{
local iyb, iyt, retarg, s = {};
if (nr > 0)
{
retarg = not(zeropad);
/* extract, offset set to actual series value */
s = xextract(targ, getxl(src), getxr(src), nan, retarg, zeropad);
if (cutxy)
{
/* clip y values */
iyb = getyb(src);
iyt = getyt(src);
(iyb, iyt) = wincut_swap(iyb, iyt);
s = clip(s, iyb, iyt);
}
}
return(s);
}
/* cut stripchart */
wincut_stripchart(src, targ, cutxy, zeropad, nr, nc)
{
local s;
/* reset autoranging */
setxauto(src, -1, -1);
setyauto(src, -1, -1);
if (nc == numitems(targ))
{
/* all traces are interval */
s = wincut_interval(src, targ, cutxy, zeropad, nr, nc);
}
else
{
s = wincut_xy(src, targ, cutxy, zeropad, nr, nc);
}
return(s);
}