-
Notifications
You must be signed in to change notification settings - Fork 18
Tips for the omnetpp r package
Author: Tamas Borbely
The omnetpp dataset contains the run attributes in 'long' format:
> d$runattrs
runid attrname attrvalue
1 PureAlohaExperiment-0-20090220-15:51:12-31531 configname PureAlohaExperiment
2 PureAlohaExperiment-0-20090220-15:51:12-31531 datetime 20090220-15:51:12
3 PureAlohaExperiment-0-20090220-15:51:12-31531 experiment PureAlohaExperiment
4 PureAlohaExperiment-0-20090220-15:51:12-31531 inifile omnetpp.ini
5 PureAlohaExperiment-0-20090220-15:51:12-31531 iterationvars $numHosts=10, $mean=1
6 PureAlohaExperiment-0-20090220-15:51:12-31531 iterationvars2 $numHosts=10, $mean=1, $repetition=0
...
If you want to transform this into a 'wide' format (one column per attribute),
you can use the cast
function from the reshape package:
> cast(d$runattrs, runid~attrname, value='attrvalue')
runid configname datetime experiment inifile iterationvars iterationvars2 mean
1 PureAlohaExperiment-0-20090220-15:51:12-31531 PureAlohaExperiment 20090220-15:51:12 PureAlohaExperiment omnetpp.ini $numHosts=10, $mean=1 $numHosts=10, $mean=1, $repetition=0 1
2 PureAlohaExperiment-10-20090220-15:51:14-31542 PureAlohaExperiment 20090220-15:51:14 PureAlohaExperiment omnetpp.ini $numHosts=10, $mean=7 $numHosts=10, $mean=7, $repetition=0 7
3 PureAlohaExperiment-11-20090220-15:51:14-31543 PureAlohaExperiment 20090220-15:51:14 PureAlohaExperiment omnetpp.ini $numHosts=10, $mean=7 $numHosts=10, $mean=7, $repetition=1 7
4 PureAlohaExperiment-1-20090220-15:51:12-31532 PureAlohaExperiment 20090220-15:51:12 PureAlohaExperiment omnetpp.ini $numHosts=10, $mean=1 $numHosts=10, $mean=1, $repetition=1 1
5 PureAlohaExperiment-12-20090220-15:51:14-31544 PureAlohaExperiment 20090220-15:51:14 PureAlohaExperiment omnetpp.ini $numHosts=10, $mean=9 $numHosts=10, $mean=9, $repetition=0 9
6 PureAlohaExperiment-13-20090220-15:51:14-31545 PureAlohaExperiment 20090220-15:51:14 PureAlohaExperiment omnetpp.ini $numHosts=10, $mean=9 $numHosts=10, $mean=9, $repetition=1 9
measurement network numHosts processid repetition replication resultdir runnumber seedset
1 $numHosts=10, $mean=1 Aloha 10 31531 0 #0 results 0 0
2 $numHosts=10, $mean=7 Aloha 10 31542 0 #0 results 10 10
3 $numHosts=10, $mean=7 Aloha 10 31543 1 #1 results 11 11
4 $numHosts=10, $mean=1 Aloha 10 31532 1 #1 results 1 1
5 $numHosts=10, $mean=9 Aloha 10 31544 0 #0 results 12 12
6 $numHosts=10, $mean=9 Aloha 10 31545 1 #1 results 13 13
...
If you want to restrict the attribute columns:
> cast(d$runattrs, runid~attrname, value='attrvalue', subset=attrname %in% c('experiment','measurement','replication'))
runid experiment measurement replication
1 PureAlohaExperiment-0-20090220-15:51:12-31531 PureAlohaExperiment $numHosts=10, $mean=1 #0
2 PureAlohaExperiment-10-20090220-15:51:14-31542 PureAlohaExperiment $numHosts=10, $mean=7 #0
3 PureAlohaExperiment-11-20090220-15:51:14-31543 PureAlohaExperiment $numHosts=10, $mean=7 #1
4 PureAlohaExperiment-1-20090220-15:51:12-31532 PureAlohaExperiment $numHosts=10, $mean=1 #1
5 PureAlohaExperiment-12-20090220-15:51:14-31544 PureAlohaExperiment $numHosts=10, $mean=9 #0
6 PureAlohaExperiment-13-20090220-15:51:14-31545 PureAlohaExperiment $numHosts=10, $mean=9 #1
...
First add the 'experiment' and 'measurement' columns to the scalars:
> scalars <- merge(d$scalars,
cast(d$runattrs, runid~attrname, value='attrvalue', subset=attrname %in% c('experiment','measurement')),
by='runid',
all.x=TRUE)
Now you can compute the averages by calling cast()
again:
> cast(scalars, experiment+measurement+module+name ~ ., mean)
To compute confidence intervals as well:
> ci95 <- conf.int(0.95)
> cast(scalars, experiment+measurement+module+name ~ ., c(mean,ci95))
For example, if you want the average of 'avgQueueLength'
across all queue modules per run:
> cast(d$scalars, runid~name, mean, subset=grepl('.*\\.queue', module) & name=='avgQueueLength')
If you want to average for the runs too:
> cast(d$scalars, .~name, mean, subset=grepl('.*\\.queue', module) & name=='avgQueueLength')
Assume you want to compute the sum of drop counts for each node in the 'omnetpp/samples/routing/Net60' network.
First load the scalars generated by the simulation:
> d <- loadDataset('/home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca')
Each node may have several input gates and a message queue for each input port. You can select the drop counts of the queues by:
> dc <- subset(d$scalars, name=='drop:count' & grepl('.*queue.*',module))
> dc
resultkey runid file module name value
10 9 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[0].queue[0] drop:count 0
21 20 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[1].queue[0] drop:count 0
30 29 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[1].queue[1] drop:count 0
39 38 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[1].queue[2] drop:count 0
50 49 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[2].queue[0] drop:count 0
61 60 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[3].queue[0] drop:count 0
72 71 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[4].queue[0] drop:count 12
81 80 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[4].queue[1] drop:count 0
90 89 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[4].queue[2] drop:count 0
99 98 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[4].queue[3] drop:count 0
...
To sum the drop counts for each node:
> r <- aggregate(list(value=dc$value),
list(runid=dc$runid,file=dc$file,module=sub('\\.queue\\[[0-9]+\\]', '', dc$module),name=dc$name),
sum)
> head(r)
runid file module name value
1 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[0] drop:count 0
2 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[1] drop:count 0
3 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[10] drop:count 6
4 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[11] drop:count 0
5 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[12] drop:count 0
6 Net60-0-20100816-10:48:41-7648 /home/tomi/work/omnetpp/samples/routing/results/Net60-0.sca Net60.rte[13] drop:count 0
If you want to add these scalars to the original dataset, first generate resultkey
for the new scalars,
and use rbind
:
> r <- cbind(list(resultkey=seq(from=nextResultKey(d), length.out=nrow(r))), r)
> d$scalars <- rbind(d$scalars, r)
The current version of the omnetpp package does not support computing the summary statistics without loading the vectors, but it is planned in a future version to do so.
So first load the vectors into the memory:
> d <- loadDataset('Aloha.vec', add('vector'))
> d <- loadVectors(d, NULL)
If the vector is loaded into a dataset, then the mean
, sd
, min
, max
functions can be used:
> vs <- split(d$vectordata$y, d$vectordata$resultkey)
> lapply(vs, mean)
> lapply(vs, sd)
> lapply(vs, min)
> lapply(vs, max)
> lapply(vs, summary)
Its much simpler:
> cast(d$vectordata, resultkey~., c(mean,sd,min,max), value='y')
If you have the doBy package installed:
> require(doBy)
> summaryBy(y ~ resultkey, d$vectordata, FUN = list(mean, sd, min, max))
Altough the plot()
function in the graphics package can create line plots,
it is not good for drawing several lines on the same plot. We suggest to use
the lattice package instead.
The 'xyplot()' function accepts a formula identifying the 'x' and 'y' data,
and a data frame containing the data. You can also filter the rows of the dataset
by specifying the 'subset' argument. Therefore if d
is an omnetpp dataset containing
the vectors data, you can plot a specific vector by:
> require(lattice)
> xyplot(y~x, d$vectordata, subset=resultkey==2, type='l')
If you want to plot all vectors contained by the dataset:
> require(lattice)
> xyplot(y~x, d$vectordata, groups=resultkey, auto.key=TRUE)
The omnetpp package contains a plotLineChart()
function. This function is intended
to produce the same line charts as the OMNeT++ IDE.
This functions accept a list of lines as first argument, where each line is a data frame or matrix with 'x' and 'y' numeric columns sorted by 'x'.
> x <- seq(0,10,0.1)
> plotLineChart(list(a=data.frame(x=x, y=sin(x)),
b=data.frame(x=x, y=cos(x))))
In this example the lines are named 'a' and 'b'.
The plotLineChart()
function supports the graphical properties that can be set in the IDE.
> plotLineChart(list(a=data.frame(x=x, y=sin(x)),
b=data.frame(x=x, y=cos(x)),
c=data.frame(x=x, y=runif(length(x)))),
Legend.Display = 'true',
'Line.Color/a'='red', 'Symbols.Type/b'='Square', 'Line.Type/c'='SampleHold')
If you want to generate a plot from vectors in a dataset, use the makeLineChartDataset()
function.
The function builds the structure for plotLineChart
from all vectors in the dataset and names the
lines according to the specified format string.
> vs <- makeLineChartDataset(dataset, '${configname}/${runnumber} - ${module} ${name}')
> plotLineChart(vs, Legend.Display='true')
If v
is a numeric vector, then the hist()
function from the graphics package
can be used to generate a histogram object and draw a histograme plot.
> h <- hist(v)
If you want to put several histogram on a single plot:
> h1 <- hist(v1, plot=FALSE)
> h2 <- hist(v2, plot=FALSE)
> plot(h1)
> plot(h2, add=TRUE)
> histogram(~y, d$vectordata, groups=resultkey)
> qplot(y, data=d$vectordata, group=resultkey, geom='histogram', binwidth=1)
or
> ggplot(d$vectordata, aes(x=y, group=resultkey)) + geom_histogram(binwidth=1)
If d
is a loaded dataset containing histogram data, then makeHistograms()
can generate
histogram objects:
> hs <- makeHistograms(d, '{module} {name}')
The result is a list of histgram objects, the elements are identified by module and statistic name.
This list can be plotted by the plotHistogramChart
function.
> plotHistograms(hs)
> histogram( ~ y, data = d$vectordata, subset=resultkey==2,
type = "density",
panel = function(x, ...) {
panel.histogram(x, ...)
panel.densityplot(x, ...)
} )
> ggplot(d$vectordata, aes(x=y, group=resultkey)) + geom_histogram(binwidth=1) + geom_density()
Based on http://stackoverflow.com/questions/2381618
> prepanel.ci <- function(x, y, ly, uy, subscripts, ...) {
y <- as.numeric(y)
ly <- as.numeric(ly[subscripts])
uy <- as.numeric(uy[subscripts])
list(ylim = range(0, y, uy, ly, finite = TRUE))
}
> panel.ci <- function(x, y, ly, uy, subscripts, box.ratio=1, box.width=box.ratio/(1+box.ratio), groups, ...) {
panel.barchart(x, y, subscripts=subscripts, groups=groups, box.ratio=box.ratio, box.width=box.width, ...)
groups <- as.factor(groups)
nvals <- nlevels(groups)
width <- box.width / nvals
x <- as.numeric(x)
y <- as.numeric(y)
ly <- as.numeric(ly[subscripts])
uy <- as.numeric(uy[subscripts])
groups <- as.numeric(groups)
x0 <- x + width * (groups - (nvals + 1) / 2)
panel.arrows(x0, ly, x0, uy, length=0.25*width, unit='npc',
angle=90, code=3, col='black')
}
> barchart(mean ~ name, data=scalars, groups=measurement,
horizontal=FALSE, ly=scalars$mean-scalars$ci95, uy=scalars$mean+scalars$ci95,
panel=panel.ci, prepanel=prepanel.ci)
> require(ggplot2)
> ggplot(scalars, aes(x=name, y=mean, fill=measurement)) +
geom_bar(position='dodge') +
geom_errorbar(aes(ymin=mean-ci95, ymax=mean+ci95), position='dodge')
> means <- makeBarChartDataset(dataset, rows='name', columns='measurement')
> ci95 <- makeBarChartDataset(dataset, rows='name', columns='measurement', conf.int(0.95) )
> plotBarChart(means, conf.int=ci95, Legend.Display='true', Legend.Anchoring='NorthWest')
Iteration variables are saved as scalars as well, so you can write:
> d <- makeScatterChartDataset(dataset, xModule='.', xName='numHosts')
> plotLineChart(d)
In this example we create a 3D plot of the total receive time
as a function
of the mean iaTime
and numOfHosts
from the Aloha simulation.
First create a data frame containing the values of the scalars for each run:
> d <- loadDataset('/home/tomi/work/omnetpp-resultfiles/R-package/inst/extdata/PureAlohaExperiment-*.sca')
> data3d <- cast(d$scalars, runid ~ name, subset=name%in%c('mean','numHosts','total receive time'))
Now you can use the lattice package to draw a 3D scatter plot (cloud()
) or a
3D surface plot (wireframe()
):
> require(lattice)
> cloud(`total receive time` ~ numHosts * mean, data=data3d)