Subversion Repositories public iLand

Rev

Rev 162 | Rev 164 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1
 
105 Werner 2
/** ModelController is a helper class used to
3
  control the flow of operations during a model run.
4
  Really useful???? or a dispatcher???
5
  */
128 Werner 6
 
105 Werner 7
#include "global.h"
8
#include "modelcontroller.h"
128 Werner 9
#include <QObject>
105 Werner 10
 
11
#include "model.h"
128 Werner 12
#include "helper.h"
161 werner 13
#include "expressionwrapper.h"
105 Werner 14
 
15
ModelController::ModelController()
16
{
128 Werner 17
    mModel = NULL;
105 Werner 18
}
128 Werner 19
 
20
ModelController::~ModelController()
21
{
22
    destroy();
23
}
24
 
25
 
145 Werner 26
bool ModelController::canCreate()
128 Werner 27
{
129 Werner 28
    if (mModel)
128 Werner 29
        return false;
30
    return true;
31
}
32
 
145 Werner 33
bool ModelController::canDestroy()
128 Werner 34
{
35
    return mModel != NULL;
36
}
37
 
145 Werner 38
bool ModelController::canRun()
128 Werner 39
{
40
    if (mModel && mModel->isSetup())
41
        return true;
42
    return false;
43
}
44
 
145 Werner 45
bool ModelController::isRunning()
128 Werner 46
{
162 werner 47
 return GlobalSettings::instance()->currentYear()>0;
128 Werner 48
}
49
 
50
 
51
void ModelController::setFileName(QString initFileName)
52
{
53
    mInitFile = initFileName;
54
    try {
55
        GlobalSettings::instance()->loadProjectFile(mInitFile);
56
    } catch(const IException &e) {
57
        QString error_msg = e.toString();
58
        Helper::msg(error_msg);
59
        qDebug() << error_msg;
60
    }
61
}
62
 
63
void ModelController::create()
64
{
65
    if (!canCreate())
66
        return;
67
    try {
68
    mModel = new Model();
69
    mModel->loadProject();
136 Werner 70
 
129 Werner 71
    if (mModel->isSetup())
72
        mModel->beforeRun();
73
 
128 Werner 74
    } catch(const IException &e) {
75
        QString error_msg = e.toString();
76
        Helper::msg(error_msg);
77
        qDebug() << error_msg;
78
    }
79
}
80
 
81
void ModelController::destroy()
82
{
83
    if (canDestroy()) {
84
        delete mModel;
85
        mModel = 0;
162 werner 86
        GlobalSettings::instance()->setCurrentYear(0);
128 Werner 87
        qDebug() << "ModelController: Model destroyed.";
88
    }
89
}
90
void ModelController::run()
91
{
92
    if (!canRun()) return;
93
    try {
94
        mModel->runYear();
95
    } catch(const IException &e) {
96
        QString error_msg = e.toString();
97
        Helper::msg(error_msg);
98
        qDebug() << error_msg;
99
    }
100
}
101
 
102
void ModelController::runYear()
103
{
104
    if (!canRun()) return;
161 werner 105
    GlobalSettings::instance()->clearDebugLists();  // clear debug data
106
 
128 Werner 107
    try {
108
        mModel->runYear();
162 werner 109
        fetchDynamicOutput();
128 Werner 110
    } catch(const IException &e) {
111
        QString error_msg = e.toString();
112
        Helper::msg(error_msg);
113
        qDebug() << error_msg;
114
    }
115
}
116
 
117
 
161 werner 118
//////////////////////////////////////
119
// dynamic outut
120
//////////////////////////////////////
121
//////////////////////////////////////
122
void ModelController::setupDynamicOutput(QString fieldList)
123
{
162 werner 124
    mDynFieldList = fieldList.split(QRegExp("\\s+"), QString::SkipEmptyParts);
125
    mDynFieldList.prepend("count");
126
    mDynFieldList.prepend("year"); // fixed fields.
161 werner 127
    mDynData.clear();
128
    mDynData.append(mDynFieldList.join(";"));
129
}
162 werner 130
 
161 werner 131
QString ModelController::dynamicOutput()
132
{
133
    return mDynData.join("\n");
134
}
135
 
136
const QStringList aggList = QStringList() << "mean" << "sum" << "min" << "max" << "p25" << "p50" << "p75";
137
void ModelController::fetchDynamicOutput()
138
{
139
    if (mDynFieldList.isEmpty())
140
        return;
141
    QStringList var;
142
    QString lastVar = "";
143
    QVector<double> data;
144
    AllTreeIterator at(mModel);
145
    TreeWrapper tw;
146
    int var_index;
147
    StatData stat;
148
    double value;
149
    QStringList line;
150
    foreach (QString field, mDynFieldList) {
163 werner 151
        if (field=="count" || field=="year")
152
            continue;
153
 
161 werner 154
        var = field.split(QRegExp("\\W+"), QString::SkipEmptyParts);
155
        if (var.count()!=2)
156
                throw IException(QString("Invalid variable name for dynamic output:") + field);
157
        if (var.first()!=lastVar) {
158
            // load new field
159
            data.clear();
160
            at.reset();
161
            var_index = tw.variableIndex(var.first());
162
            if (var_index<0) {
163
                throw IException(QString("Invalid variable name for dynamic output:") + var.first());
164
            }
165
            while (Tree *t = at.next()) {
166
                tw.setTree(t);
167
                data.push_back(tw.value(var_index));
168
            }
169
            stat.setData(data);
170
        }
171
        // fetch data
172
        var_index = aggList.indexOf(var[1]);
173
        switch (var_index) {
174
            case 0: value = stat.mean(); break;
175
            case 1: value = stat.sum(); break;
176
            case 2: value = stat.min(); break;
177
            case 3: value = stat.max(); break;
178
            case 4: value = stat.percentile25(); break;
179
            case 5: value = stat.median(); break;
180
            case 6: value = stat.percentile75(); break;
181
            default: throw IException(QString("Invalid aggregate expression for dynamic output: %1\nallowed:%2")
182
                                  .arg(var[1]).arg(aggList.join(" ")));
183
        }
184
        line+=QString::number(value);
185
    }
162 werner 186
    line.prepend( QString::number(data.size()) );
187
    line.prepend( QString::number(GlobalSettings::instance()->currentYear()) );
188
    mDynData.append(line.join(";"));
161 werner 189
}