The UFZ services GitLab and Mattermost will be unavailable on Monday, October 25 from 06:00 AM to 08:00 AM due to maintenance work.

Commit 41dd0f6d authored by Johannes Leins's avatar Johannes Leins
Browse files

Merge branch 'feat_migration' into 'offset'

# Conflicts:
#   src/main.cpp
#   stages.csv
parents a1b72eb4 cf36ef5d
Pipeline #29079 passed with stage
in 26 seconds
......@@ -1011,6 +1011,7 @@ CSVHandlerLifeCycle::CSVHandlerLifeCycle(string filename)
"migrRadius",
"migrDecay",
"migrSight",
"migrPref",
"baseImm",
"baseImmDay",
"baseImmDur"})
......@@ -1138,6 +1139,7 @@ bool CSVHandlerLifeCycle::handleFlows() {
vector<string> migrRads = getValues(headerNames[iHeader++]);
vector<string> sMigrDecays = getValues(headerNames[iHeader++]);
vector<string> sMigrSights = getValues(headerNames[iHeader++]);
vector<string> sMigrPrefs = getValues(headerNames[iHeader++]);
vector<string> baseImms = getValues(headerNames[iHeader++]);
vector<string> baseImmDays = getValues(headerNames[iHeader++]);
vector<string> baseImmDurs = getValues(headerNames[iHeader++]);
......@@ -1151,6 +1153,7 @@ bool CSVHandlerLifeCycle::handleFlows() {
std::pair<tools::ConversionResult, int> migrRad = tools::conv_stoi(migrRads[iStage]);
std::pair<tools::ConversionResult, double> migrDecay = tools::conv_stod(sMigrDecays[iStage]);
std::pair<tools::ConversionResult, double> migrSight = tools::conv_stod(sMigrSights[iStage]);
std::pair<tools::ConversionResult, double> migrPref = tools::conv_stod(sMigrPrefs[iStage]);
std::pair<tools::ConversionResult, double> baseImm = tools::conv_stod(baseImms[iStage]);
std::pair<tools::ConversionResult, int> baseImmDay = tools::conv_stoi(baseImmDays[iStage]);
std::pair<tools::ConversionResult, int> baseImmDur = tools::conv_stoi(baseImmDurs[iStage]);
......@@ -1212,6 +1215,14 @@ bool CSVHandlerLifeCycle::handleFlows() {
message.append(". CHOOSE VALUE FROM 0 TO 1");
return false;
}
if(migrPref.first == tools::ConversionResult::INVALID ||
(migrPref.first == tools::ConversionResult::VALID && migrPref.second < 0.0)) {
message = "INVALID MIGRATION SIGHT PREF FOR STAGE ";
message.append(stageFrom->getName());
message.append(". CHOOSE VALUE >= 0");
return false;
}
if(baseImm.first == tools::ConversionResult::INVALID ||
(baseImm.first == tools::ConversionResult::VALID && !(baseImm.second > 0))) {
......@@ -1268,6 +1279,9 @@ bool CSVHandlerLifeCycle::handleFlows() {
if(migrSight.first == tools::ConversionResult::VALID) {
migrSights[iStage] = migrSight.second;
}
if(migrPref.first == tools::ConversionResult::VALID) {
migrPrefs[iStage] = migrPref.second;
}
if(baseImm.first == tools::ConversionResult::VALID) {
string stageDummyBaseImmName = stageFrom->getName();
stageDummyBaseImmName.append("BaseImm");
......@@ -1331,6 +1345,13 @@ double CSVHandlerLifeCycle::getMigrSight(unsigned int iStage) {
return 0.5; // default migration sight
}
double CSVHandlerLifeCycle::getMigrPref(unsigned int iStage) {
if(migrPrefs.count(iStage) > 0) {
return migrPrefs[iStage];
}
return 1.0; // default migration pref
}
vector<Flow*> CSVHandlerLifeCycle::getBaseImmFlows() {
return baseImmFlows;
}
......@@ -73,6 +73,7 @@ private:
unordered_map<int, int> radsMigr;
unordered_map<int, double> migrDecays;
unordered_map<int, double> migrSights;
unordered_map<int, double> migrPrefs;
vector<Flow*> mortFlows;
vector<Flow*> baseImmFlows;
......@@ -91,6 +92,7 @@ public:
int getMigrRad(unsigned int iStage);
double getMigrDecay(unsigned int iStage);
double getMigrSight(unsigned int iStage);
double getMigrPref(unsigned int iStage);
vector<Flow*> getBaseImmFlows();
};
......
......@@ -31,7 +31,8 @@ namespace Constants
extern const float THRESHOLD_RMUG(0.26);
extern const float THRESHOLD_CW(0.98);
extern const float ZERO_KELVIN(273.15);
extern const int GRID_CELL_WIDTH(250);
extern const unsigned int GRASSLAND_CELL_WIDTH(250);
extern const unsigned int CLIMATE_CELL_WIDTH(12000);
extern const int SECOND_TO_DAY(60 * 60 * 24);
extern const double EPSILON(0.00001);
extern const int DAYS_1949_12_01_TO_1970_01_01_GREGORIAN(7336);
......
......@@ -96,7 +96,8 @@ namespace Constants
extern const float THRESHOLD_RMUG;
extern const float THRESHOLD_CW;
extern const float ZERO_KELVIN;
extern const int GRID_CELL_WIDTH;
extern const unsigned int GRASSLAND_CELL_WIDTH;
extern const unsigned int CLIMATE_CELL_WIDTH;
extern const int SECOND_TO_DAY;
extern const double EPSILON;
extern const int DAYS_1949_12_01_TO_1970_01_01_GREGORIAN;
......
......@@ -19,8 +19,9 @@
#include "Environment.h"
Environment::Environment(vector<StrategyClimate*> climateStrategies, unordered_set<Cell*> grasslandCells, int timestep, int deltaTimesteps, int cycleLength, int seed) {
this->habitatSize = Constants::GRID_CELL_WIDTH * Constants::GRID_CELL_WIDTH;
Environment::Environment(vector<StrategyClimate*> climateStrategies, unordered_set<Cell*> grasslandCells, int timestep, int deltaTimesteps, int habitatWidth, int climateCellWidth, int cycleLength, int seed) {
this->habitatWidth = habitatWidth > 0 ? habitatWidth : Constants::GRASSLAND_CELL_WIDTH;
this->climateCellWidth = climateCellWidth > 0 ? climateCellWidth : Constants::CLIMATE_CELL_WIDTH;
this->timestep = timestep;
this->deltaTimesteps = deltaTimesteps;
this->initialTimestep = timestep;
......@@ -271,8 +272,20 @@ void Environment::setOrderOfYears(const map<int, int>& orderOfYears) {
this->orderOfYears = orderOfYears;
}
int Environment::getHabitatSize() const {
return habitatSize;
unsigned int Environment::getHabitatWidth() const {
return habitatWidth;
}
unsigned int Environment::getHabitatSize() const {
return habitatWidth * habitatWidth;
}
unsigned int Environment::getClimateCellWidth() const {
return climateCellWidth;
}
unsigned int Environment::getClimateCellSize() const {
return climateCellWidth * climateCellWidth;
}
void Environment::setActiveNeighborhood(string key,
......
......@@ -44,7 +44,7 @@ private:
unordered_map<Point, Cell*> cellsByCoord;
unordered_set<Point> grasslandCoords;
unordered_map<Point, unordered_map<string, Measure*>> measures;
int habitatSize; // in sqm
unsigned int habitatWidth, climateCellWidth; // in m
int timestep, indexTime;
int initialTimestep, deltaTimesteps;
int cycleLength;
......@@ -60,7 +60,7 @@ private:
CSVHandlerInfluences* influenceDefinitions;
public:
Environment(vector<StrategyClimate*> climateStrategies, unordered_set<Cell*> grasslandCells, int timestep = 0, int deltaTimesteps = 1, int cycleLength = 364, int seed = 123);
Environment(vector<StrategyClimate*> climateStrategies, unordered_set<Cell*> grasslandCells, int timestep = 0, int deltaTimesteps = 1, int habitatWidth = -1, int climateCellWidth = -1, int cycleLength = 364, int seed = 123);
void update();
......@@ -126,7 +126,13 @@ public:
void setSeed(int seed, unordered_set<Point> coords = {});
int getHabitatSize() const;
unsigned int getHabitatWidth() const;
unsigned int getHabitatSize() const;
unsigned int getClimateCellWidth() const;
unsigned int getClimateCellSize() const;
void setOrderOfYears(const map<int, int>& orderOfYears);
......
......@@ -173,7 +173,7 @@ double InfluenceVariable<T>::getValue(DensityLevel variable,
default:
break;
}
return density / (Constants::GRID_CELL_WIDTH * Constants::GRID_CELL_WIDTH);
return density / environment->getHabitatSize();
}
InfluenceDensity::InfluenceDensity(DensityLevel densityLevel, double maxFactor, double minFactor, bool multiplicative, bool devRemain, double initDevState)
......@@ -205,7 +205,7 @@ double InfluenceDensity::getDensitySqm(Environment* environment, Cohort* cohort)
default:
break;
}
return density / (Constants::GRID_CELL_WIDTH * Constants::GRID_CELL_WIDTH);
return density / environment->getHabitatSize();
}
template <class T>
......
......@@ -44,7 +44,8 @@ Measure::Measure(string name, bool relativeTiming, int durationDays, UsageType t
this->mownRatio = 0.0;
if(typeOfUse == MOWING) {
// calculate the amount or rather the rather of the mown grass within this grid cell
this->mownRatio = 1.0 - ((double) (mowingPattern->getStripWidth() * mowingPattern->getNStrips())) / ((double) Constants::GRID_CELL_WIDTH);
// TODO if this ever comes to use, replace Constants::GRID_CELL_WIDTH with getHabitatWidth() from Environment
this->mownRatio = 1.0 - ((double) (mowingPattern->getStripWidth() * mowingPattern->getNStrips())) / ((double) Constants::GRASSLAND_CELL_WIDTH);
}
}
......
......@@ -474,10 +474,11 @@ void Population::resetEmigration(Environment *environment) {
}
}
double baseMigrRate = lifeCycleDefinition->getMigrRate(iStage);
double migrRad = lifeCycleDefinition->getMigrRad(iStage) / ((double) Constants::GRID_CELL_WIDTH);
double migrRad = lifeCycleDefinition->getMigrRad(iStage) / ((double) environment->getHabitatWidth());
if((baseMigrRate > 0.0 && migrRad > 0)) {
double rMigrDecay = lifeCycleDefinition->getMigrDecay(iStage); // decay rate used for distance dependant survival probality
double rMigrSight = lifeCycleDefinition->getMigrSight(iStage); // rate/exponent used informed migration. Values << 1 increase probability to find grassland
double rMigrPref = lifeCycleDefinition->getMigrPref(iStage); // exponent used for preference of nearby cells. Values 0 means that cells are preferred equally independent of their distance
influenceDefinitions->getFlowInfluencesByType();
// map to count number of cells at a certain distance
unordered_map<int, pair<int, int>> nDist; // pair.first = #grasslandCells, pair.second = total number of cells in that distance
......@@ -517,7 +518,7 @@ void Population::resetEmigration(Environment *environment) {
int distKey = distX * distX + distY * distY; //key for same distance cells is the sum of squares of distance in each direction
double distance = sqrt(((double) distKey));
if(popCoord != coord && distance <= migrRad) {
sumMigrDistance += 1.0 / distance;
sumMigrDistance += 1.0 / pow(distance, rMigrPref);
neighMigrCoords[coord] = distance;
nDist[distKey].first++;
}
......@@ -551,7 +552,7 @@ void Population::resetEmigration(Environment *environment) {
int distY = popCoord.getY() - neighCoord.getY();
int distKey = distX * distX + distY * distY; //key for same distance cells is the sum of squares of distance in each direction
double distance = neighbor.second;
double prefNeigh = (1.0 / distance) / sumMigrDistance; // the preference of migrating to this neighbor
double prefNeigh = (1.0 / pow(distance, rMigrPref)) / sumMigrDistance; // the preference of migrating to this neighbor
// TODO maybe change to use coordinate distance without actual distance between cells --> if so, change rDecay as well
double pFind = pow(propGrass[distKey].first, (1-rMigrSight)); // probabilty to find a grassland cell at this distance
double pSurv = exp(-rMigrDecay * (1 - propGrass[distKey].second) * distance); // distance-dependant survival probability
......
......@@ -1038,8 +1038,8 @@ void outputStats(ofstream *statsFile) {
}
}
}else{
string emptyPopParams = ",,,,,";
string emptyStageParams = ",,,,,";
string emptyPopParams = ",,,,,,,";
string emptyStageParams = ",,,,,,,";
if(prognosis) {
emptyPopParams = "";
emptyStageParams = ",";
......
......@@ -21,6 +21,7 @@
# - migrRadius: the maximum daily emigration radius in meters. More distant neighbors receive less emigration density
# - migrDecay: the exponential decay rate [0,1] of migration survival probability dependent on distance and grassland proportion: 0=100% survival, 1=max loss
# - migrSight: the migration sight/intelligence [0,1] increasing the probability to find a grassland patch at a distance. 0=success rate equals proportion of grassland, 1=100% success
# - migrPref: the migration preference for closer cells. Greater value increases preference for closer cells. Value 0 prefers all cells equally
# - baseImm: the amount (density) per square meter of base immigration, if applicable
# - baseImmDay: the first yearly day of base immigration
# - baseImmDur: the yearly duration in days of base immigration
......@@ -28,9 +29,9 @@
# Use the definitions of this file in combination with files influences.csv and distScheme.csv to achieve a more dynamic life cycle with external influences
# Use file initialDens.csv to change initial density depending on location
#
name,initDens,minDens,maxAge,multiCohort,capConstr,thdQuasiExtinct,rateTrans,rateRepr,rateMort,rateMigr,migrRadius,migrDecay,migrSight,baseImm,baseImmDay,baseImmDur
PreDiapause,0,0.00000064,210,false,false,,1.0,0.0,0.0008164147,,,,,,,
Diapause,3.6,0.00000064,1700,yearly,false,,1.0,0.0,0.0008164147,,,,,,,
Embryo,0,0.00000064,120,false,false,,1.0,0.0,0.0,,,,,,,
Larva,0,0.00000064,90,daily,true,,1.0,0.0,0.0358,,,,,,,
Imago,0,0.00000064,120,false,true,0.002,0.0,1.3,0.0475,0.00595,1500,0.0008,0.5,0.00011,240,5
name,initDens,minDens,maxAge,multiCohort,capConstr,thdQuasiExtinct,rateTrans,rateRepr,rateMort,rateMigr,migrRadius,migrDecay,migrSight,migrPref,baseImm,baseImmDay,baseImmDur
PreDiapause,0,0.00000064,210,false,false,,1.0,0.0,0.0008164147,,,,,,,,
Diapause,0,0.00000064,1700,yearly,false,,1.0,0.0,0.0008164147,,,,,,,,
Embryo,0,0.00000064,120,false,false,,1.0,0.0,0.0,,,,,,,,
Larva,0,0.00000064,90,daily,true,,1.0,0.0,0.0358,,,,,,,,
Imago,0,0.00000064,120,false,true,0.002,0.0,1.3,0.0475,0.00595,1500,0.0008,0.5,2,0.00011,240,5
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment