Time Series Output
Using time iteration for time series output.
Concept
Many agro-environmental model simulations iterate through both time and space, for example involving
daily time steps and routing through hydrologic units in a watershed. The time iteration component in
a previous training example is slightly modified, renamed ('TimeSeriesIteratorReader'), and included
with mock components ('MapReader', 'Kriging') to demonstrate how time series output can generated. The
example could be further developed to on a daily time step read climate station and hydrologic unit data
(with 'MapReader'), geospatially interpolate the climate data (with 'Kriging'), and print the interpolated
data (with 'TimeSeriesIteratorWriter').
Implementation
'TimeSeriesIteratorReader' consumes time period 'start' and 'end' parameters, the calendar to use
('unit'), and the time amount ('amount') to increment through the period with each step. Until done,
the component outputs a key value pair ('data'), containing a unique key with each step and in this
example the same value {1,2,3,4,5} for each step. The component also outputs the time ('current')
of the time step.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 |
package ex19;
import java.util.Calendar;
import java.util.HashMap;
import oms3.annotations.*;
/**
* Time control
*
* @author od
*/
public class TimeSeriesIteratorReader {
@In public Calendar start;
@In public Calendar end;
@In public int unit;
@In public int amount;
@Out public Calendar current;
// flag for controlling the iteration
@Out public boolean done;
@Out public HashMap<Integer, double[]> data;
@Execute
public void execute() {
if (current == null) {
current = (Calendar) start.clone();
} else {
current.add(unit, amount);
}
done = current.before(end);
data = new HashMap<Integer, double[]>();
data.put(1, new double[] {1,2,3,4,5});
}
}
|
In this mock example, 'MapReader' executes once, printing a string ("Reading Map.") and assigning the
string "Map" to the output variable 'map', which will be consumed by the 'Kringing' component. In a
real implementation, 'MapReader' could be modified to read climate station points and data to feed
into 'Kriging'.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 |
package ex19;
import oms3.annotations.Execute;
import oms3.annotations.Out;
/**
* Map reader
*
* @author od
*/
public class MapReader {
@Out public String map;
@Execute
public void execute() {
if (map == null) {
// read map only once.
System.out.println("Reading map.");
map = "Map";
}
}
}
|
The 'Kriging' component consumes 'data' (as 'indata') from 'TimeSeriesIteratorReader' and 'map' from
'MapReader', prints the string "Inp. map", and outputs 'indata' as 'outdata' to be consumed by
'TimeSeriesIteratorWriter'.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 |
package ex19;
import java.util.Calendar;
import java.util.HashMap;
import oms3.annotations.Execute;
import oms3.annotations.In;
import oms3.annotations.Out;
/**
* Time control
*
* @author od
*/
public class Kriging {
@In public HashMap<Integer, double[]> inData;
@Out public HashMap<Integer, double[]> outData;
@In public String map;
@Execute
public void execute() {
outData=inData;
System.out.println("Inp map.");
}
}
|
'TimeSeriesIteratorWriter' consumes 'outdata' containing the key/value pair from the 'Kriging' component
and 'current' containing the current time from 'TimeSeriesIteratorReader' and prints out the current time
and the key/value pair.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 |
package ex19;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import oms3.annotations.Execute;
import oms3.annotations.In;
public class TimeSeriesIteratorWriter {
@In public Calendar current;
@In public HashMap<Integer, double[]> inData;
@Execute
public void execute() {
System.out.println(current.getTime() + " " + inData + " " + Arrays.toString(inData.get(1)));
}
}
|
In the model simulation file, iteration is declared (line 5), the four input parameters are initialized
for the 'TimeSeriesIteratorReader' component (lines 6-19), the four components instantiated (lines 21-26),
and input and output variables connected among components (lines 28-34). Running the simulation produces
the output shown in the diagram. A time series of key/value pairs from October 1-10, 2001 (10 iterations)
is produced.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 |
import static oms3.SimBuilder.instance as OMS3
OMS3.sim {
model(while:"reader.done") {
parameter {
// specified as Calendar object, not really nice looking, but possibe
'reader.start' '2001-10-01'
// ISO Data get's converted into the same GregorianCalendar object,
// same thing as above, but looks nicer.
'reader.end' '2001-10-10'
// static Calendar field constants
'reader.unit' java.util.Calendar.DAY_OF_YEAR
// the number of units to increase
'reader.amount' 1
}
components {
'mapreader' 'ex19.MapReader'
'reader' 'ex19.TimeSeriesIteratorReader'
'writer' 'ex19.TimeSeriesIteratorWriter'
'kriging' 'ex19.Kriging'
}
connect {
// pass current time to 'c1'
'reader.data' 'kriging.inData'
'reader.current' 'writer.current'
'kriging.outData' 'writer.inData'
'mapreader.map' 'kriging.map'
}
}
}
|