Project

General

Profile

Statistics
| Branch: | Revision:

root / src / scave / datasorter.h @ a3be1d55

History | View | Annotate | Download (8.36 KB)

1 01873262 Georg Kunz
//==========================================================================
2
//  DATASORTER.H - part of
3
//                     OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
//  Author: Andras Varga, Tamas Borbely
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
#ifndef _DATASORTER_H_
19
#define _DATASORTER_H_
20
21
#include <algorithm>
22
#include <functional>
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <assert.h>
27
#include "resultfilemanager.h"
28
#include "commonutil.h"
29
#include "patternmatcher.h"
30
#include "scaveutils.h"
31
#include "statistics.h"
32
#include "fields.h"
33
34
NAMESPACE_BEGIN
35
36
typedef std::vector<ID> IDVector;
37
typedef std::vector<IDVector> IDVectorVector;
38
typedef std::vector<std::string> StringVector;
39
40
/**
41
 * Values arranged in a two dimensional array.
42
 */
43
class SCAVE_API XYDataset
44
{
45
    private:
46
        typedef ScalarResult Key;
47
        typedef std::map<Key, int, ResultItemFieldsLess> KeyToIndexMap;
48
        typedef std::vector<Statistics> Row;
49
50
        ResultItemFields rowFields;            // data in each row has the same value of these fields
51
        ResultItemFields columnFields;         // data in each column has the same value of these fields
52
        KeyToIndexMap rowKeyToIndexMap;    // row field values -> row index
53
        KeyToIndexMap columnKeyToIndexMap; // column field values -> column index
54
        std::vector<Key> rowKeys;
55
        std::vector<Key> columnKeys;
56
        std::vector<Row> values; // index by row/column
57
        std::vector<int> rowOrder;         // permutation of a subset of rows
58
        std::vector<int> columnOrder;      // permutation of a subset of columns
59
    public:
60
        XYDataset() {};
61
        XYDataset(ResultItemFields rowFields, ResultItemFields columnFields)
62
            : rowFields(rowFields), columnFields(columnFields),
63
            rowKeyToIndexMap(ResultItemFieldsLess(rowFields)),
64
            columnKeyToIndexMap(ResultItemFieldsLess(columnFields)) {};
65
        void add(const ScalarResult &d);
66
        void swapRows(int row1, int row2);
67
        void sortColumnsAccordingToFirstRowMean();
68
        void sortRows();
69
        void sortColumns();
70
71
        int getRowCount() const { return rowOrder.size(); }
72
        int getColumnCount() const { return columnOrder.size(); }
73
        ResultItemFields getRowFields() const { return rowFields; }
74
        ResultItemFields getColumnFields() const { return columnFields; }
75
        std::string getRowField(int row, ResultItemField field) const;
76
        std::string getRowFieldNoCheck(int row, ResultItemField field) const;
77
        std::string getColumnField(int column, ResultItemField field) const;
78
        Statistics getValue(int row, int column) const;
79
};
80
81
typedef std::vector<XYDataset> XYDatasetVector;
82
83
inline std::string XYDataset::getRowField(int row, ResultItemField field) const
84
{
85
    if (row < 0 || row >= getRowCount() || !rowFields.hasField(field))
86
        return "";
87
    return field.getFieldValue(rowKeys[rowOrder[row]]);
88
}
89
90
inline std::string XYDataset::getRowFieldNoCheck(int row, ResultItemField field) const
91
{
92
    if (row < 0 || row >= getRowCount())
93
        return "";
94
    return field.getFieldValue(rowKeys[rowOrder[row]]);
95
}
96
97
inline std::string XYDataset::getColumnField(int column, ResultItemField field) const
98
{
99
    if (column < 0 || column >= getColumnCount() || !columnFields.hasField(field))
100
        return "";
101
    return field.getFieldValue(columnKeys[columnOrder[column]]);
102
}
103
104
inline Statistics XYDataset::getValue(int row, int column) const
105
{
106
    if (row < 0 || column < 0 || row >= getRowCount() || column >= getColumnCount())
107
        return Statistics();
108
    return values.at(rowOrder[row]).at(columnOrder[column]);
109
}
110
111
/**
112
 * Helps to organize scalars in a ResultFileManager into bar charts,
113
 * scatter plots, etc.
114
 */
115
class SCAVE_API DataSorter
116
{
117
  private:
118
    ResultFileManager *resultFileMgr;
119
    static ResultFileManager *tmpResultFileMgr;
120
121
    typedef bool (*GroupingFunc)(const ScalarResult&, const ScalarResult&);
122
    typedef bool (*CompareFunc)(ID id1, ID id2);
123
124
  private:
125
    // comparison functions for doGrouping() and sortAndAlign()
126
    static bool sameGroupFileRunScalar(const ResultItem& d1, const ResultItem& d2);
127
    static bool sameGroupModuleScalar(const ResultItem& d1, const ResultItem& d2);
128
    static bool sameGroupFileRunModule(const ResultItem& d1, const ResultItem& d2);
129
    static bool lessByModuleRef(ID id1, ID id2);
130
    static bool equalByModuleRef(ID id1, ID id2);
131
    static bool lessByFileAndRun(ID id1, ID id2);
132
    static bool equalByFileAndRun(ID id1, ID id2);
133
    static bool lessByName(ID id1, ID id2);
134
    static bool equalByName(ID id1, ID id2);
135
    static bool lessByValue(ID id1, ID id2);
136
137
    /**
138
     * Form groups (IDVectors) by the grouping function passed.
139
     * The grouping function called with two ScalarResult and returns true iff
140
     * the two scalar is in the same group.
141
     */
142
    template<class GroupingFn>
143
    IDVectorVector doGrouping(const IDList& idlist, GroupingFn sameGroup);
144
145
    /**
146
     * Sort every group (IDVectors) in place by the sorting function given
147
     * and aligns.
148
     *
149
     * Then inserts "null" elements (id=-1) so that every group is of same length,
150
     * and same indices are "equal", by the equal function passed.
151
     */
152
    template<class LessFn, class EqualFn>
153
    void sortAndAlign(IDVectorVector& vv, LessFn less, EqualFn equal);
154
155
  public:
156
    /**
157
     * Constructor.
158
     */
159
    DataSorter(ResultFileManager *sm) {resultFileMgr = sm;}
160
161
    /**
162
     * Form groups (IDVectors) by the specified fields.
163
     */
164
    IDVectorVector groupByFields(const IDList& idlist, ResultItemFields fields);
165
166
    /**
167
     * Form groups (IDVectors) by the specified fields.
168
     * Then order each group, and insert "null" elements (id=-1)
169
     * so that every group is of same length, and the same indices contain
170
     * the same values of the non-grouping fields.
171
     */
172
    IDVectorVector groupAndAlign(const IDList& idlist, ResultItemFields fields);
173
174
    /**
175
     * Form rows from data of given idlist by grouping according to rowFields.
176
     * Then for each row form columns by grouping the values according to columnFields.
177
     * Compute the mean of the values in each cell and align the cells into a table.
178
     * If no data for a row/column combination, NaN will be inserted into the cell.
179
     */
180
    XYDataset groupAndAggregate(const IDList& idlist, ResultItemFields rowFields, ResultItemFields columnFields);
181
182
    /**
183
     * Group and align data for a scatter plot. The first vector will contain the
184
     * x coordinates, further vectors the y1, y2, etc series. Points are sorted
185
     * by x coordinate. For missing points in y1, y2, etc, the vector contains -1.
186
     */
187
    IDVectorVector prepareScatterPlot(const IDList& idlist, const char *moduleName, const char *scalarName);
188
189
    /**
190
     * Group and align data for a scatter plot. The first row will contain the
191
     * x coordinates, further rows the y1, y2, etc series. Points are sorted
192
     * by x coordinate. For missing points in y1, y2, etc, the row contains NaN.
193
     */
194
    XYDataset prepareScatterPlot2(const IDList& idlist, const char *xModuleName, const char *xScalarName,
195
            ResultItemFields rowFields, ResultItemFields columnFields);
196
197
    /**
198
     *
199
     */
200
    XYDatasetVector prepareScatterPlot3(const IDList& idlist, const char *moduleName, const char *scalarName,
201
            ResultItemFields rowFields, ResultItemFields columnFields,
202
            const StringVector &isoModuleNames, const StringVector &isoScalarNames, ResultItemFields isoFields);
203
204
205
    /**
206
     * Looks at the data given by their Id, and returns a subset of them
207
     * where each (moduleName, scalarName) pair occurs only once.
208
     *
209
     * Purpose: these pairs should be offered as selection of X axis for a
210
     * scatter plot.
211
     */
212
    IDList getModuleAndNamePairs(const IDList& idlist, int maxcount);
213
214
    /**
215
     * Arranges the data into a tabular form suitable for pasting into a spreadsheet:
216
     * one dimension is module and scalar name, the other is file+run number.
217
     */
218
    IDVectorVector prepareCopyToClipboard(const IDList& idlist);
219
};
220
221
NAMESPACE_END
222
223
224
#endif
225