Subversion Repositories public iLand

Rev

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