Subversion Repositories public iLand

Rev

Rev 1221 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
671 werner 1
/********************************************************************************************
2
**    iLand - an individual based forest landscape and disturbance model
3
**    http://iland.boku.ac.at
4
**    Copyright (C) 2009-  Werner Rammer, Rupert Seidl
5
**
6
**    This program is free software: you can redistribute it and/or modify
7
**    it under the terms of the GNU General Public License as published by
8
**    the Free Software Foundation, either version 3 of the License, or
9
**    (at your option) any later version.
10
**
11
**    This program is distributed in the hope that it will be useful,
12
**    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
**    GNU General Public License for more details.
15
**
16
**    You should have received a copy of the GNU General Public License
17
**    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
********************************************************************************************/
19
 
504 werner 20
#include "saplingout.h"
21
#include "model.h"
22
#include "resourceunit.h"
1162 werner 23
#include "saplings.h"
504 werner 24
#include "species.h"
25
 
26
SaplingOut::SaplingOut()
27
{
28
 
29
    setName("Sapling Output", "sapling");
30
    setDescription("Output of the establishment/sapling layer per resource unit and species.\n" \
31
                   "The output covers trees between a dbh of 1cm and the recruitment threshold (i.e. a height of 4m)." \
950 werner 32
                   "Cohorts with a dbh < 1cm are counted in 'cohort_count_ha' but not used for average calculations.\n\n" \
33
                   "You can specify a 'condition' to limit execution for specific time/ area with the variables 'ru' (resource unit id) and 'year' (the current year)");
570 werner 34
    columns() << OutputColumn::year() << OutputColumn::ru() << OutputColumn::id() << OutputColumn::species()
1177 werner 35
            << OutputColumn("count_ha", "number of represented individuals per ha (tree height >1.3m).", OutInteger)
36
               << OutputColumn("count_small_ha", "number of represented individuals per ha (with height <=1.3m).", OutInteger)
504 werner 37
            << OutputColumn("cohort_count_ha", "number of cohorts per ha.", OutInteger)
1177 werner 38
            << OutputColumn("height_avg_m", "arithmetic average height of the cohorts (m) ", OutDouble)
39
            << OutputColumn("age_avg", "arithmetic average age of the sapling cohorts (years)", OutDouble);
504 werner 40
 }
41
 
42
void SaplingOut::setup()
43
{
950 werner 44
    // use a condition for to control execuation for the current year
45
    QString condition = settings().value(".condition", "");
46
    mCondition.setExpression(condition);
47
    if (!mCondition.isEmpty()) {
48
        mVarRu = mCondition.addVar("ru");
49
        mVarYear = mCondition.addVar("year");
50
    }
504 werner 51
}
52
 
53
void SaplingOut::exec()
54
{
55
    Model *m = GlobalSettings::instance()->model();
950 werner 56
 
504 werner 57
    double n, avg_dbh, avg_height, avg_age;
58
    foreach(ResourceUnit *ru, m->ruList()) {
574 werner 59
        if (ru->id()==-1)
60
            continue; // do not include if out of project area
61
 
950 werner 62
        if (!mCondition.isEmpty()) {
63
            *mVarRu = ru->id();
64
            *mVarYear = GlobalSettings::instance()->currentYear();
65
            if (!mCondition.execute() )
66
                continue;
67
        }
68
 
504 werner 69
        foreach(const ResourceUnitSpecies *rus, ru->ruSpecies()) {
70
            const StandStatistics &stat = rus->constStatistics();
1162 werner 71
            const SaplingStat &sap = const_cast<ResourceUnitSpecies*>(rus)->saplingStat();
504 werner 72
 
73
            if (stat.saplingCount()==0)
74
                continue;
570 werner 75
            *this << currentYear() << ru->index() << ru->id() << rus->species()->id(); // keys
504 werner 76
 
77
            // calculate statistics based on the number of represented trees per cohort
1162 werner 78
            n = sap.livingStemNumber(rus->species(), avg_dbh, avg_height, avg_age);
1177 werner 79
            *this << sap.livingSaplings()
80
                  << sap.livingSaplingsSmall()
81
                  << sap.livingCohorts()
82
                  << sap.averageHeight()
83
                  << sap.averageAge();
504 werner 84
            writeRow();
85
        }
86
    }
87
}
1182 werner 88
 
89
SaplingDetailsOut::SaplingDetailsOut()
90
{
91
    setName("Sapling Details Output", "saplingdetail");
92
    setDescription("Detailed output on indidvidual sapling cohorts.\n" \
1183 werner 93
                   "For each occupied and living 2x2m pixel, a row is generated, unless" \
94
                   "the tree diameter is below the 'minDbh' threshold (cm). " \
95
                   "You can further specify a 'condition' to limit execution for specific time/ area with the variables 'ru' (resource unit id) and 'year' (the current year).");
1182 werner 96
    columns() << OutputColumn::year() << OutputColumn::ru() << OutputColumn::id() << OutputColumn::species()
97
              << OutputColumn("n_represented", "number of trees that are represented by the cohort (Reineke function).", OutDouble)
98
              << OutputColumn("dbh", "diameter of the cohort (cm).", OutDouble)
99
              << OutputColumn("height", "height of the cohort (m).", OutDouble)
100
              << OutputColumn("age", "age of the cohort (years) ", OutInteger);
101
 
102
}
103
 
104
void SaplingDetailsOut::exec()
105
{
106
    Model *m = GlobalSettings::instance()->model();
107
 
108
    foreach(ResourceUnit *ru, m->ruList()) {
109
        if (ru->id()==-1)
110
            continue; // do not include if out of project area
111
 
112
        // exclude if a condition is specified and condition is not met
113
        if (!mCondition.isEmpty()) {
114
            *mVarRu = ru->id();
115
            *mVarYear = GlobalSettings::instance()->currentYear();
116
            if (!mCondition.execute() )
117
                continue;
118
        }
119
        SaplingCell *s = ru->saplingCellArray();
120
        for (int px=0;px<cPxPerHectare;++px, ++s) {
121
            int n_on_px = s->n_occupied();
122
            if (n_on_px>0) {
123
                for (int i=0;i<NSAPCELLS;++i) {
124
                    if (s->saplings[i].is_occupied()) {
125
                        ResourceUnitSpecies *rus = s->saplings[i].resourceUnitSpecies(ru);
126
                        const Species *species = rus->species();
1183 werner 127
                        double dbh = s->saplings[i].height / species->saplingGrowthParameters().hdSapling  * 100.;
128
                        // check minimum dbh
129
                        if (dbh<mMinDbh)
130
                            continue;
131
 
1182 werner 132
                        double n_repr = species->saplingGrowthParameters().representedStemNumberH(s->saplings[i].height) / static_cast<double>(n_on_px);
133
 
134
                        *this <<  currentYear() << ru->index() << ru->id() << rus->species()->id();
1183 werner 135
                        *this << n_repr << dbh << s->saplings[i].height << s->saplings[i].age;
1182 werner 136
                        writeRow();
137
                    }
138
                }
139
            }
140
        }
141
    }
142
}
143
 
144
void SaplingDetailsOut::setup()
145
{
146
    // use a condition for to control execuation for the current year
147
    QString condition = settings().value(".condition", "");
148
    mCondition.setExpression(condition);
149
    if (!mCondition.isEmpty()) {
150
        mVarRu = mCondition.addVar("ru");
151
        mVarYear = mCondition.addVar("year");
152
    }
1183 werner 153
    mMinDbh = settings().valueDouble(".minDbh");
1182 werner 154
}