Rev 1111 | Rev 1113 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | |||
1111 | werner | 2 | #include "global.h" |
3 | #include "saplings.h" |
||
4 | |||
5 | #include "globalsettings.h" |
||
6 | #include "model.h" |
||
7 | #include "resourceunit.h" |
||
8 | #include "resourceunitspecies.h" |
||
9 | #include "establishment.h" |
||
10 | #include "species.h" |
||
11 | #include "seeddispersal.h" |
||
12 | |||
13 | |||
14 | Saplings::Saplings() |
||
15 | { |
||
16 | |||
17 | } |
||
18 | |||
19 | void Saplings::setup() |
||
20 | { |
||
21 | mGrid.setup(GlobalSettings::instance()->model()->grid()->metricRect(), GlobalSettings::instance()->model()->grid()->cellsize()); |
||
22 | |||
23 | // mask out out-of-project areas |
||
24 | HeightGrid *hg = GlobalSettings::instance()->model()->heightGrid(); |
||
25 | for (int i=0;i<mGrid.count();++i) { |
||
26 | if (!hg->valueAtIndex(mGrid.index5(i)).isValid()) |
||
27 | mGrid[i].state = SaplingCell::CellInvalid; |
||
28 | else |
||
29 | mGrid[i].state = SaplingCell::CellFree; |
||
30 | } |
||
31 | |||
32 | |||
33 | } |
||
34 | |||
35 | void Saplings::establishment(const ResourceUnit *ru) |
||
36 | { |
||
37 | Grid<float> &seedmap = const_cast<Grid<float>& > (ru->ruSpecies().first()->species()->seedDispersal()->seedMap() ); |
||
38 | HeightGrid *height_grid = GlobalSettings::instance()->model()->heightGrid(); |
||
39 | FloatGrid *lif_grid = GlobalSettings::instance()->model()->grid(); |
||
40 | |||
41 | QPoint iseedmap = seedmap.indexAt(ru->boundingBox().topLeft()) ; |
||
42 | QPoint imap = mGrid.indexAt(ru->boundingBox().topLeft()); |
||
43 | |||
44 | int species_idx = irandom(0, ru->ruSpecies().size()-1); |
||
45 | for (int s_idx = 0; s_idx<ru->ruSpecies().size(); ++s_idx) { |
||
46 | |||
47 | // start from a random species (and cycle through the available species) |
||
48 | species_idx = ++species_idx % ru->ruSpecies().size(); |
||
49 | |||
50 | ResourceUnitSpecies *rus = ru->ruSpecies()[species_idx]; |
||
51 | // check if there are seeds of the given species on the resource unit |
||
52 | float seeds = 0.f; |
||
53 | for (int iy=0;iy<5;++iy) { |
||
54 | float *p = seedmap.ptr(iseedmap.x(), iseedmap.y()); |
||
55 | for (int ix=0;ix<5;++ix) |
||
56 | seeds += *p++; |
||
57 | } |
||
58 | // if there are no seeds: no need to do more |
||
59 | if (seeds==0.f) |
||
60 | continue; |
||
61 | |||
62 | // calculate the abiotic environment (TACA) |
||
63 | rus->establishment().calculateAbioticEnvironment(); |
||
64 | double abiotic_env = rus->establishment().abioticEnvironment(); |
||
65 | if (abiotic_env==0.) |
||
66 | continue; |
||
67 | |||
68 | // loop over all 2m cells on this resource unit |
||
69 | SaplingCell *s; |
||
70 | int isc = 0; // index on 2m cell |
||
71 | for (int iy=0; iy<cPxPerRU; ++iy) { |
||
72 | s = mGrid.ptr(imap.x(), imap.y()+iy); // ptr to the row |
||
73 | isc = mGrid.index(imap.x(), imap.y()+iy); |
||
74 | |||
75 | for (int ix=0;ix<cPxPerRU; ++ix, ++s, ++isc, ++mTested) { |
||
76 | if (s->state == SaplingCell::CellFree) { |
||
77 | bool viable = true; |
||
78 | // is a sapling of the current species already on the pixel? |
||
79 | // * test for sapling height already in cell state |
||
80 | // * test for grass-cover already in cell state |
||
81 | int i_occupied = -1; |
||
82 | for (int i=0;i<NSAPCELLS;++i) { |
||
83 | if (!s->saplings[i].is_occupied() && i_occupied<0) |
||
84 | i_occupied=i; |
||
85 | if (s->saplings[i].species_index == species_idx) { |
||
86 | viable = false; |
||
87 | } |
||
88 | } |
||
89 | |||
1112 | werner | 90 | if (viable && i_occupied>=0) { |
1111 | werner | 91 | // grass cover? |
92 | DBG_IF(i_occupied<0, "establishment", "invalid value i_occupied<0"); |
||
93 | float seed_map_value = seedmap[seedmap.index10(isc)]; |
||
94 | if (seed_map_value==0.f) |
||
95 | continue; |
||
96 | const HeightGridValue &hgv = (*height_grid)[height_grid->index5(isc)]; |
||
97 | float lif_value = (*lif_grid)[isc]; |
||
98 | double lif_corrected = rus->species()->speciesSet()->LRIcorrection(lif_value, 4. / hgv.height); |
||
99 | // check for the combination of seed availability and light on the forest floor |
||
100 | if (drandom() < seed_map_value*lif_corrected*abiotic_env ) { |
||
101 | // ok, lets add a sapling at the given position |
||
102 | s->saplings[i_occupied].setSapling(0.05f, 1, species_idx); |
||
103 | s->checkState(); |
||
104 | mAdded++; |
||
105 | |||
106 | } |
||
107 | |||
108 | } |
||
109 | |||
110 | } |
||
111 | } |
||
112 | } |
||
113 | |||
114 | } |
||
115 | |||
116 | } |