Project

General

Profile

Statistics
| Branch: | Revision:

root / src / envir / resultrecorders.cc @ 7c7d95e5

History | View | Annotate | Download (5.76 KB)

1 01873262 Georg Kunz
//==========================================================================
2
//  RESULTRECORDERS.CC - part of
3
//                     OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
//  Author: Andras Varga
7
//
8
//==========================================================================
9
10
/*--------------------------------------------------------------*
11
  Copyright (C) 1992-2008 Andras Varga
12
  Copyright (C) 2006-2008 OpenSim Ltd.
13

14
  This file is distributed WITHOUT ANY WARRANTY. See the file
15
  `license' for details on this and other legal matters.
16
*--------------------------------------------------------------*/
17
18
#include "resultrecorders.h"
19
#include "cproperty.h"
20
#include "chistogram.h"
21
22
23
Register_ResultRecorder("vector", VectorRecorder);
24
Register_ResultRecorder("count", CountRecorder);
25
Register_ResultRecorder("last", LastValueRecorder);
26
Register_ResultRecorder("sum", SumRecorder);
27
Register_ResultRecorder("mean", MeanRecorder);
28
Register_ResultRecorder("min", MinRecorder);
29
Register_ResultRecorder("max", MaxRecorder);
30
Register_ResultRecorder("timeavg", TimeAverageRecorder);
31
Register_ResultRecorder("stats", StatsRecorder);
32
Register_ResultRecorder("histogram", HistogramRecorder);
33
34
35
void VectorRecorder::subscribedTo(ResultFilter *prev)
36
{
37
    NumericResultRecorder::subscribedTo(prev);
38
39
    // we can register the vector here, because base class ensures we are subscribed only at once place
40
    opp_string_map attributes = getStatisticAttributes();
41
42
    handle = ev.registerOutputVector(getComponent()->getFullPath().c_str(), getResultName().c_str());
43
    ASSERT(handle != NULL);
44
    for (opp_string_map::iterator it = attributes.begin(); it != attributes.end(); ++it)
45
        ev.setVectorAttribute(handle, it->first.c_str(), it->second.c_str());
46
}
47
48
void VectorRecorder::collect(simtime_t_cref t, double value)
49
{
50
    if (t < lastTime)
51
    {
52
        throw cRuntimeError("%s: Cannot record data with an earlier timestamp (t=%s) "
53
                            "than the previously recorded value (t=%s)",
54
                            getClassName(), SIMTIME_STR(t), SIMTIME_STR(lastTime));
55
    }
56
57
    lastTime = t;
58
    ev.recordInOutputVector(handle, t, value);
59
}
60
61
//---
62
63
void CountRecorder::finish(ResultFilter *prev)
64
{
65
    opp_string_map attributes = getStatisticAttributes();
66
    ev.recordScalar(getComponent(), getResultName().c_str(), count, &attributes);
67
}
68
69
//---
70
71
void LastValueRecorder::finish(ResultFilter *prev)
72
{
73
    opp_string_map attributes = getStatisticAttributes();
74
    ev.recordScalar(getComponent(), getResultName().c_str(), lastValue, &attributes);
75
}
76
77
//---
78
79
void SumRecorder::finish(ResultFilter *prev)
80
{
81
    opp_string_map attributes = getStatisticAttributes();
82
    ev.recordScalar(getComponent(), getResultName().c_str(), sum, &attributes);
83
}
84
85
//---
86
87
void MeanRecorder::finish(ResultFilter *prev)
88
{
89
    opp_string_map attributes = getStatisticAttributes();
90
    ev.recordScalar(getComponent(), getResultName().c_str(), sum/count, &attributes); // note: this is NaN if count==0
91
}
92
93
//---
94
95
void MinRecorder::finish(ResultFilter *prev)
96
{
97
    opp_string_map attributes = getStatisticAttributes();
98
    ev.recordScalar(getComponent(), getResultName().c_str(), isPositiveInfinity(min) ? NaN : min, &attributes);
99
}
100
101
//---
102
103
void MaxRecorder::finish(ResultFilter *prev)
104
{
105
    opp_string_map attributes = getStatisticAttributes();
106
    ev.recordScalar(getComponent(), getResultName().c_str(), isNegativeInfinity(max) ? NaN : max, &attributes);
107
}
108
109
//---
110
111
void TimeAverageRecorder::collect(simtime_t_cref t, double value)
112
{
113
    if (startTime < SIMTIME_ZERO) // uninitialized
114
        startTime = t;
115
    else
116
        weightedSum += lastValue * SIMTIME_DBL(t - lastTime);
117
    lastTime = t;
118
    lastValue = value;
119
}
120
121
void TimeAverageRecorder::finish(ResultFilter *prev)
122
{
123
    bool empty = (startTime < SIMTIME_ZERO);
124
    simtime_t t = simulation.getSimTime();
125
    collect(t, NaN); // to get the last interval counted in; the value is just a dummy
126
    double interval = SIMTIME_DBL(t - startTime);
127
128
    opp_string_map attributes = getStatisticAttributes();
129
    ev.recordScalar(getComponent(), getResultName().c_str(), empty ? NaN : (weightedSum / interval), &attributes);
130
}
131
132
//---
133
134
void StatisticsRecorder::finish(ResultFilter *prev)
135
{
136
    opp_string_map attributes = getStatisticAttributes();
137
    ev.recordStatistic(getComponent(), getResultName().c_str(), statistic, &attributes);
138
}
139
140
StatsRecorder::StatsRecorder() : StatisticsRecorder(new cStdDev())
141
{
142
}
143
144
HistogramRecorder::HistogramRecorder() : StatisticsRecorder(new cHistogram())
145
{
146
}
147
148
//---
149
150
class RecValueVariable : public Expression::Variable
151
{
152
  private:
153
    ExpressionRecorder *owner;
154
  public:
155
    RecValueVariable(ExpressionRecorder *recorder) {owner = recorder;}
156
    virtual Functor *dup() const {return new RecValueVariable(owner);}
157
    virtual const char *getName() const {return "<lastsignalvalue>";}
158
    virtual char getReturnType() const {return Expression::Value::DBL;}
159
    virtual Expression::Value evaluate(Expression::Value args[], int numargs) {return owner->lastValue;}
160
};
161
162
//XXX currently unused
163
class RecTimeVariable : public Expression::Variable
164
{
165
  public:
166
    virtual Functor *dup() const {return new RecTimeVariable();}
167
    virtual const char *getName() const {return "<simtime>";}
168
    virtual char getReturnType() const {return Expression::Value::DBL;}
169
    virtual Expression::Value evaluate(Expression::Value args[], int numargs) {return SIMTIME_DBL(simulation.getSimTime());}
170
};
171
172
Expression::Functor *ExpressionRecorder::makeValueVariable()
173
{
174
    return new RecValueVariable(this);
175
}
176
177
Expression::Functor *ExpressionRecorder::makeTimeVariable()
178
{
179
    return new RecTimeVariable();
180
}
181
182
void ExpressionRecorder::finish(ResultFilter *prev)
183
{
184
    opp_string_map attributes = getStatisticAttributes();
185
    ev.recordScalar(getComponent(), getResultName().c_str(), expr.doubleValue(), &attributes);
186
}