-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathManagement.cpp
More file actions
327 lines (310 loc) · 13 KB
/
Management.cpp
File metadata and controls
327 lines (310 loc) · 13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
/*----------------------------------------------------------------------------
*
* Copyright (C) 2026 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, Roslyn Henry, Théo Pannetier, Jette Wolff, Damaris Zurell
*
* This file is part of RangeShifter.
*
* RangeShifter is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RangeShifter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RangeShifter. If not, see <https://www.gnu.org/licenses/>.
*
* File Created by Jette Wolff
--------------------------------------------------------------------------*/
//---------------------------------------------------------------------------
#include "Management.h"
//---------------------------------------------------------------------------
/*
* Initialize management class
*/
Management::Management(void) {
translocation = false;
catching_rate = 1.0; // Catching rate
non_dispersed = false; // do not consider non-dispersed individuals
std::vector<int> translocation_years; // Number of years of translocation
std::map< int, std::vector <locn> > source; // Source patch or cell: should be a vector of arrays
std::map< int, std::vector <locn> > target; // Target patch or cell
std::map< int, std::vector <int> > nb; // number of ttanslocated individuals
std::map< int, std::vector <int> > min_age; // Minimum age of translocated individuals
std::map< int, std::vector <int> > max_age; // Maximum age of translocated individuals
std::map< int, std::vector <int> > stage; // Stage of translocated individuals
std::map< int, std::vector <int> > sex; // Sex of translocated individuals
}
Management::~Management(void) {
translocation_years.clear();
source.clear();
target.clear();
nb.clear();
min_age.clear();
max_age.clear();
stage.clear();
}
managementParams Management::getManagementParams(void) {
managementParams m;
m.translocation = translocation;
return m;
}
void Management::setManagementParams(const managementParams m){
translocation = m.translocation;
};
translocationParams Management::getTranslocationParams(void) {
translocationParams t;
t.catching_rate = catching_rate;
t.translocation_years = translocation_years;
t.source = source;
t.target = target;
t.nb = nb;
t.min_age = min_age;
t.max_age = max_age;
t.stage = stage;
t.sex = sex;
return t;
}
// not sure if this is a good way, so won't use it for now
void Management::setTranslocationParams(const translocationParams t){
catching_rate = t.catching_rate;
translocation_years = t.translocation_years;
source = t.source;
target = t.target;
nb = t.nb;
min_age = t.min_age;
max_age = t.max_age;
stage = t.stage;
sex = t.sex;
};
void Management::translocate(int yr
, Landscape* pLandscape
, Species* pSpecies
){
#if RS_RCPP
Rcpp::Rcout << "Start translocation events in year " << yr << endl;
#endif
#ifndef NDEBUG
cout << "Start translocation events in year " << yr << endl;
#endif
landParams ppLand = pLandscape->getLandParams();
auto it = nb.find(yr); // the number of translocation events is determined by the number of elements of the maps at year yr
auto nb_it = nb.find(yr);
auto source_it = source.find(yr);
auto target_it = target.find(yr);
auto min_age_it = min_age.find(yr);
auto max_age_it = max_age.find(yr);
auto stage_it = stage.find(yr);
auto sex_it = sex.find(yr);
// iterate over the number of events
for (int e = 0; e < it->second.size(); e++) {
#if RS_RCPP
Rcpp::Rcout << "Translocation event " << e << " in year " << yr << endl;
#endif
#ifndef NDEBUG
cout << "Translocation event " << e << " in year " << yr << endl;
#endif
// find the source patch
Patch* s_patch;
Population* s_pPop;
if(ppLand.patchModel){
if(pLandscape->existsPatch(source_it->second[e].x)){
#if RS_RCPP
Rcpp::Rcout << "Source patch exist." << endl;
#endif
#ifndef NDEBUG
cout << "Source patch exist." << endl;
#endif
s_patch = pLandscape->findPatch(source_it->second[e].x);
if (s_patch) { // if it is not a nullpointer
// test if population in patch is not zero
s_pPop = s_patch->getPopn(pSpecies); // returns the population of the species in that cell
if (s_pPop && s_pPop->getNbInds() > 0){
} else {
#if RS_RCPP
Rcpp::Rcout << "Population does not exist in source patch or is 0! skipping translocation event." << endl;
#endif
#ifndef NDEBUG
cout << "Population does not exist in source patch or is 0! skipping translocation event." << endl;
#endif
return;
}
} else {
#if RS_RCPP
Rcpp::Rcout << "Source patch was found but NULL! skipping translocation event." << endl; // not sure if this ever happens
#endif
#ifndef NDEBUG
cout << "Source patch was found but NULL! skipping translocation event." << endl; // not sure if this ever happens
#endif
return;
}
//
} else{
#if RS_RCPP
Rcpp::Rcout << "Source patch was not found in landscape! skipping translocation event." << endl;
#endif
#ifndef NDEBUG
cout << "Source patch was not found in landscape! skipping translocation event." << endl;
#endif
return;
}
} else{
Cell* pCell;
pCell = pLandscape->findCell(source_it->second[e].x, source_it->second[e].y);
if (pCell != 0) {
#if RS_RCPP
Rcpp::Rcout << "Source cell was found" << endl;
#endif
#ifndef NDEBUG
cout << "Source cell was found" << endl;
#endif
Patch *s_ppatch = pCell->getPatch();
if (s_ppatch) {
s_patch = s_ppatch;
// test if population in patch is not zero
s_pPop = s_patch->getPopn(pSpecies); // returns the population of the species in that cell
if (s_pPop && s_pPop->getNbInds() > 0){
} else {
#if RS_RCPP
Rcpp::Rcout << "Population does not exist in source cell or is 0! skipping translocation event." << endl;
#endif
#ifndef NDEBUG
cout << "Population does not exist in source cell or is 0! skipping translocation event." << endl;
#endif
return;
}
} else {
#if RS_RCPP
Rcpp::Rcout << "Source cell does not exist! skipping translocation event." << endl;
#endif
#ifndef NDEBUG
cout << "Source cell does not exist! skipping translocation event." << endl;
#endif
return;
}
} else {
#if RS_RCPP
Rcpp::Rcout << "Cell does not belong to landscape! skipping translocation event." << endl;
#endif
#ifndef NDEBUG
cout << "Cell does not belong to landscape! skipping translocation event." << endl;
#endif
return;
}
}
// find the target patch and check for existence
Patch* t_patch;
Population* t_pPop;
if(ppLand.patchModel){
if(pLandscape->existsPatch(target_it->second[e].x)){
#if RS_RCPP
Rcpp::Rcout << "Target patch exist." << endl;
#endif
#ifndef NDEBUG
cout << "Target patch exist." << endl;
#endif
t_patch = pLandscape->findPatch(target_it->second[e].x);
} else{
#if RS_RCPP
Rcpp::Rcout << "Target patch was not found in landscape! skipping translocation event." << endl;
#endif
#ifndef NDEBUG
cout << "Target patch was not found in landscape! skipping translocation event." << endl;
#endif
return;
}
} else{
Cell* pCell;
pCell = pLandscape->findCell(target_it->second[e].x, target_it->second[e].y);
if (pCell != 0) {
#if RS_RCPP
Rcpp::Rcout << "Target cell was found" << endl;
#endif
#ifndef NDEBUG
cout << "Target cell was found" << endl;
#endif
Patch *t_ppatch = pCell->getPatch();
if (t_ppatch) {
t_patch = t_ppatch;
} else {
#if RS_RCPP
Rcpp::Rcout << "Target cell does not exist! skipping translocation event." << endl;
#endif
#ifndef NDEBUG
cout << "Target cell does not exist! skipping translocation event." << endl;
#endif
return;
}
} else {
#if RS_RCPP
Rcpp::Rcout << "Target cell does not belong to landscape! skipping translocation event." << endl;
#endif
#ifndef NDEBUG
cout << "Target cell does not belong to landscape! skipping translocation event." << endl;
#endif
return;
}
}
// only if source and target cell/patch exist, we can translocate individuals:
// get individuals with the given characteristics in that population
int min_age = min_age_it->second[e];
int max_age = max_age_it->second[e];
int stage = stage_it->second[e];
int sex = sex_it->second[e];
int nb = nb_it->second[e];
int nbSampledInds = 0;
// We made already sure by now that in s_pPop at least some individuals exist
nbSampledInds = s_pPop->sampleIndividuals(nb, min_age, max_age, stage, sex); // checking values was done when reading in the parameters
popStats s_stats = s_pPop->getStats(s_patch->getDemoScaling());
Individual* catched_individual;
int translocated = 0;
// loop over all indsividuals, extract sampled individuals, try to catch individual + translocate them to new patch
for (int j = 0; j < s_stats.nInds; j++) {
// if there are individuals to catch
if(s_pPop->getSizeSampledInds()){
// if this individual is matching one of the sampled individuals
catched_individual = s_pPop->catchIndividual(catching_rate, j); // catch individual in the source patch
if (catched_individual !=NULL) { // translocated individual - has already been removed from natal population
// Check if a population of this species already exists in target patch t_patch
t_pPop = t_patch->getPopn(pSpecies);
if (!t_pPop) { // translocated individual is the first in a previously uninhabited patch
#if RS_RCPP
Rcpp::Rcout << "Population does not exist in target patch. Creating new population." << endl;
#endif
#ifndef NDEBUG
cout << "Population does not exist in target patch. Creating new population." << endl;
#endif
// create a new population in the corresponding sub-community
SubCommunity* pSubComm = (SubCommunity*)t_patch->getSubComm();
t_pPop = pSubComm->newPopn(pLandscape, pSpecies, t_patch, 0);
}
catched_individual->setStatus(10); // make sure individual is not dispersing after the translocation
t_pPop->recruit(catched_individual); // recruit individual to target population TODO: maybe use a specified function which also updates pCurrCell + pPrevCell to a random cell in target patch?
translocated ++;
// NOTE:
// the variables pCurrCell and pPrevCell are not updated! These are important for the dispersal process!
// currently, translocated individuals are not considered as potential emigrants, thus there is no problem in changing that
// however, if we want to consider dispersal events after translocation, we need to adapt that; but that would also mean, that we might loose the information
// about the natal patch of an individual?
simParams sim = paramsSim->getSim();
if (sim.outConnect) { // increment connectivity totals
int newpatch = t_patch->getSeqNum();
int prevpatch = s_patch->getSeqNum();
pLandscape->incrConnectMatrix(prevpatch, newpatch);
}
}
}
}
#if RS_RCPP
Rcpp::Rcout << "Successfully translocated " << translocated << " out of " << nb_it->second[e] << " individuals in translocation event " << e <<"." << endl;
#endif
#ifndef NDEBUG
cout << "Successfully translocated " << translocated << " out of " << nb_it->second[e] << " individuals in translocation event " << e <<"." << endl;
#endif
// remove pointers to sampled individuals
s_pPop->clean();
}
};