WarpScript is a handy toolkit build for time series manipulation. A common use case could be to detect a sequence of values lasting a given duration
![Thinking in WarpScript: Detecting a sequence of values](https://blog.senx.io/wp-content/uploads/2019/10/Thinking_WarpScript_11-1.png)
This post describes how to detect in a series of values between 0 and 5, subsequences of value greater or equal to 3 lasting at least 5 seconds.
How to easily manipulate raw binary payloads in WarpScript |
First step
As a first step, we need a dataset. Here, we will generate a random GTS containing 300 values between 0 and 5 spaced by one second. Of course, you can use your own.
NEWGTS // Create an empty GTS
0 300 <% // for(i = 0; i < 300; i++)
'i' STORE // store the current index
NOW $i 1 s * + // tick ('now' + 'i seconds')
NaN NaN NaN // no geo coordinate
RAND 5 * ROUND // generate the random value
ADDVALUE // add the data point to gts
%> FOR // close FOR loop macro
'gts' STORE // store the result
Read more about:
NEWGTS, STORE, FOR, NOW, RAND, ROUND, ADDVALUE, DROP
The result is a random time series:
![chart presenting a sequence of values](https://blog.senx.io/wp-content/uploads/2019/10/36ddab10-624b-4ec1-98a9-e8fe69fc58d5-1024x420.png)
Second step
Now, we will build a sliding window that navigates across this series in order to detect 5 seconds of values greater or equal to 3:
[
$gts // our random series
<%
'data' STORE // store the current sliding window data
$data 0 GET // current timestamp
$data 4 GET 0 GET // current lat
$data 5 GET 0 GET // current long
$data 6 GET 0 GET // current elev
// in our 5 current points, we keep only those >= 3
// and verify we have 5 in a row
$data 7 GET <% 3 >= %> FILTERBY SIZE 5 >= // put true or false as value
%> MACROMAPPER // custom mapper
0 // pre window size
-5 s // 5 seconds of post window size
0 // occurrences
] MAP // Sliding window
RANGECOMPACT // keep only changing values
'result' STORE
Learn more about:
GET, FILTERBY, SIZE, MACROMAPPER, MAP, RANGECOMPACT
Here, we have a sequence of booleans.
![chart](https://blog.senx.io/wp-content/uploads/2019/10/137ec198-136c-4b54-b468-70a822d92853-1024x70.png)
Now, we will remove false values:
[ $result true mapper.eq 0 0 0 ] MAP 'result' STORE // retain only 'true'
Learn more about:
mapper.eq
![chart](https://blog.senx.io/wp-content/uploads/2019/10/3938360f-5069-4334-b4bb-a4f25773f523-1024x72.png)
Last step
Now, we have our original series and a second boolean series corresponding to subsequences starts:
![chart](https://blog.senx.io/wp-content/uploads/2019/10/6b7f5da5-d4ab-44c8-9aeb-af079294565a-1024x319.png)
Last thought
If you want to detect the end of subsequences, you have to invert pre- and post-window sizes of the mapper:
[
$gts
<%
'data' STORE
$data 0 GET // Current timestamp
$data 4 GET 0 GET // Current lat
$data 5 GET 0 GET // Current long
$data 6 GET 0 GET // Current elev
// in our 5 current points, we keep only >= 3 and verify we have 5 in a row
$data 7 GET <% 3 >= %> FILTERBY SIZE 5 >=
%> MACROMAPPER // custom mapper
-5 s
0
0
] MAP
You can find the final code and a running example of this sequence of values here: WarpStudio
Read more
Thinking in WarpScript - Multi-Value Support
WarpStudio in standalone mode
Working with GEOSHAPEs
![Xavier Marin](https://blog.senx.io/wp-content/uploads/2019/04/IMG_8993.jpg)
Senior Software Engineer