Statistics
| Branch: | Revision:

root / src / envir / resultrecorders.cc @ fbe00e73

History | View | Annotate | Download (5.76 KB)

1
//==========================================================================
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
}
187