From 63b920f20ab35014eb4536f57d798317a84de1a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Pannetier?= Date: Mon, 23 Oct 2023 13:36:25 +0100 Subject: [PATCH 01/17] ignore CMakeLists --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 31831ca..8d034d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ .gitignore #README.md +# CMake +CMakeLists.txt + # CodeLite /.build-debug/ /Debug/ From 91ec5e6ca0ee72b5ec4aed52e68c99769294c467 Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Mon, 23 Oct 2023 13:44:14 +0100 Subject: [PATCH 02/17] include Version.h obsolete in batch with cmake --- Community.h | 4 ++-- Model.h | 4 ++-- Parameters.h | 4 ++-- Patch.h | 4 ++-- RSrandom.h | 4 ++-- RandomCheck.h | 4 ++-- Species.h | 4 ++-- SubCommunity.h | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Community.h b/Community.h index 6a07b5b..36a4a12 100644 --- a/Community.h +++ b/Community.h @@ -52,9 +52,9 @@ Last updated: 25 June 2021 by Anne-Kathleen Malchow #include #include using namespace std; -//#if RS_RCPP && !R_CMD +#if RS_RCPP #include "../Version.h" -//#endif +#endif //#if !RS_RCPP && R_CMD //#include "../../Batch/Version.h" diff --git a/Model.h b/Model.h index 4acf37a..dc943fd 100644 --- a/Model.h +++ b/Model.h @@ -49,9 +49,9 @@ Last updated: 26 October 2021 by Steve Palmer #include #include -//#if RS_RCPP && !R_CMD +#if RS_RCPP #include "../Version.h" -//#endif +#endif //#if !RS_RCPP && R_CMD //#include "../../Batch/Version.h" diff --git a/Parameters.h b/Parameters.h index d44cf14..b029491 100644 --- a/Parameters.h +++ b/Parameters.h @@ -60,9 +60,9 @@ Last updated: 25 June 2021 by Steve Palmer #include #include using namespace std; -//#if RS_RCPP && !R_CMD +#if RS_RCPP #include "../Version.h" -//#endif +#endif //#if !RS_RCPP && R_CMD //#include "../../Batch/Version.h" diff --git a/Patch.h b/Patch.h index 2bc30e7..2f086d7 100644 --- a/Patch.h +++ b/Patch.h @@ -68,9 +68,9 @@ Last updated: 25 June 2021 by Steve Palmer #include using namespace std; -//#if RS_RCPP && !R_CMD +#if RS_RCPP #include "../Version.h" -//#endif +#endif //#if !RS_RCPP && R_CMD //#include "../../Batch/Version.h" diff --git a/RSrandom.h b/RSrandom.h index 9293b29..98d91f4 100644 --- a/RSrandom.h +++ b/RSrandom.h @@ -40,9 +40,9 @@ Last updated: 12 January 2021 by Steve Palmer #include //#include -//#if RS_RCPP && !R_CMD +#if RS_RCPP #include "../Version.h" -//#endif +#endif //#if !RS_RCPP && R_CMD //#include "../../Batch/Version.h" diff --git a/RandomCheck.h b/RandomCheck.h index b4f6f01..45c6b82 100644 --- a/RandomCheck.h +++ b/RandomCheck.h @@ -28,9 +28,9 @@ #include using namespace std; -//#if RS_RCPP && !R_CMD +#if RS_RCPP #include "../Version.h" -//#endif +#endif //#if !RS_RCPP && R_CMD //#include "../../Batch/Version.h" diff --git a/Species.h b/Species.h index a6d0ee9..55dbacf 100644 --- a/Species.h +++ b/Species.h @@ -45,9 +45,9 @@ Last updated: 28 July 2021 by Greta Bocedi #ifndef SpeciesH #define SpeciesH -//#if RS_RCPP && !R_CMD +#if RS_RCPP #include "../Version.h" -//#endif +#endif //#if !RS_RCPP && R_CMD //#include "../../Batch/Version.h" diff --git a/SubCommunity.h b/SubCommunity.h index 3f1266f..ece9281 100644 --- a/SubCommunity.h +++ b/SubCommunity.h @@ -50,9 +50,9 @@ Last updated: 26 October 2021 by Steve Palmer #include using namespace std; -//#if RS_RCPP && !R_CMD +#if RS_RCPP #include "../Version.h" -//#endif +#endif //#if !RS_RCPP && R_CMD //#include "../../Batch/Version.h" From 233898d9a1bc54c120744b4fb8baae0616e1361f Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Mon, 23 Oct 2023 14:29:54 +0100 Subject: [PATCH 03/17] don't ignore CMakeList after all --- .gitignore | 5 ----- CMakeLists.txt | 7 +++++++ 2 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 CMakeLists.txt diff --git a/.gitignore b/.gitignore index 8d034d8..3986f7a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,6 @@ .gitignore #README.md -# CMake -CMakeLists.txt - # CodeLite /.build-debug/ /Debug/ @@ -14,11 +11,9 @@ compile_commands.json Makefile .build-release/ build-Release/ -*.txt *.project *.workspace *.mk -*.txt *.tags # Hidden source diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6700d5d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,7 @@ +# Config file for compilation with CMake +# Only relevant for Batch mode, but this file needs to live in the RScore folder + +add_library(RScore Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp) + +# pass config definitions to compiler +target_compile_definitions(RScore PRIVATE "RSDEBUG" "LINUX_CLUSTER" "RSWIN64" "BATCH") \ No newline at end of file From 3764f7aaaaf9a6624af0037511077a42bbb6ad4e Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Thu, 9 Nov 2023 17:22:57 +0000 Subject: [PATCH 04/17] strip unused macros --- .gitignore | 4 ++++ CMakeLists.txt | 6 +++++- Model.cpp | 31 ++----------------------------- Model.h | 14 +++++++------- Population.cpp | 10 ---------- 5 files changed, 18 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index 3986f7a..0545382 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,7 @@ vignettes/*.pdf # compilation files *.o + +# Visual Studio +.vs/ +out/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 6700d5d..31e59e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,4 +4,8 @@ add_library(RScore Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp) # pass config definitions to compiler -target_compile_definitions(RScore PRIVATE "RSDEBUG" "LINUX_CLUSTER" "RSWIN64" "BATCH") \ No newline at end of file +if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin") + target_compile_definitions(RScore PRIVATE "RSDEBUG" "RSWIN64" "LINUX_CLUSTER") +else() # Windows + target_compile_definitions(RScore PRIVATE "RSDEBUG" "RSWIN64") +endif() \ No newline at end of file diff --git a/Model.cpp b/Model.cpp index 9f26886..64b5d87 100644 --- a/Model.cpp +++ b/Model.cpp @@ -152,17 +152,10 @@ DEBUGLOG << endl << "RunModel(): generating new landscape ..." << endl; DEBUGLOG << "RunModel(): finished resetting landscape" << endl << endl; #endif pLandscape->generatePatches(); -//#if VCL if (v.viewLand || sim.saveMaps) { pLandscape->setLandMap(); pLandscape->drawLandscape(rep,0,ppLand.landNum); } -//#endif -//#if BATCH -// if (sim.saveMaps) { -// pLandscape->drawLandscape(rep,0,ppLand.landNum); -// } -//#endif #if RSDEBUG DEBUGLOG << endl << "RunModel(): finished generating patches" << endl; #endif @@ -313,12 +306,8 @@ DEBUGLOG << "RunModel(): completed updating carrying capacity" << endl; DEBUGLOG << "RunModel(): completed initialisation, rep=" << rep << " pSpecies=" << pSpecies << endl; #endif -#if BATCH -#if RS_RCPP && !R_CMD +#if BATCH && RS_RCPP && !R_CMD Rcpp::Rcout << "RunModel(): completed initialisation " << endl; -#else - cout << "RunModel(): completed initialisation " << endl; -#endif #endif // open a new individuals file for each replicate @@ -926,7 +915,7 @@ return errorfolder; //For outputs and population visualisations pre-reproduction void PreReproductionOutput(Landscape *pLand,Community *pComm,int rep,int yr,int gen) { -#if RSDEBUG || VCL +#if RSDEBUG landParams ppLand = pLand->getLandParams(); #endif simParams sim = paramsSim->getSim(); @@ -1341,22 +1330,6 @@ if (dem.stageStruct){ outPar << endl; } } -#if VCL - else { - - // NOTE: TO PREVENT COMPILING FOR BATCH MODE, THIS CODE NEEDS TO BE INCLUDED IN COMPILER - // CONDITIONAL BLOCK AS SHOWN - -// outPar << "Row count: " << frmSpecies->transMatrix->RowCount << endl; -// outPar << "Col count: " << frmSpecies->transMatrix->ColCount << endl; - for (int i = 1; i < frmSpecies->transMatrix->RowCount; i++) { - for (int j = 1; j < frmSpecies->transMatrix->ColCount; j++) { - outPar << frmSpecies->transMatrix->Cells[j][i].ToDouble() << "\t"; - } - outPar << endl; - } - } -#endif outPar << endl; #endif */ diff --git a/Model.h b/Model.h index dc943fd..5bd02bd 100644 --- a/Model.h +++ b/Model.h @@ -75,12 +75,12 @@ extern ofstream DEBUGLOG; #if RS_RCPP && !R_CMD Rcpp::List RunModel( Landscape*, // pointer to Landscape - int // sequential simulation number (always 0 for VCL version) + int // sequential simulation number ); #else int RunModel( Landscape*, // pointer to Landscape - int // sequential simulation number (always 0 for VCL version) + int // sequential simulation number ); #endif // RS_RCPP && !R_CMD bool CheckDirectory(void); @@ -125,11 +125,11 @@ extern Community *pComm; const bool batchMode = true; extern string landFile; extern vector hfnames; -extern string habmapname; // see FormLand.cpp (VCL) OR Main.cpp (batch) -extern string patchmapname; // see FormLand.cpp (VCL) OR Main.cpp (batch) -extern string distnmapname; // see FormLand.cpp (VCL) OR Main.cpp (batch) -extern string costmapname; // see FormMove.cpp (VCL) OR Main.cpp (batch) -extern string genfilename; // see FormGenetics.cpp (VCL) OR Main.cpp (batch) +extern string habmapname; // see Main.cpp (batch) +extern string patchmapname; // see Main.cpp (batch) +extern string distnmapname; // see Main.cpp (batch) +extern string costmapname; // see Main.cpp (batch) +extern string genfilename; // see Main.cpp (batch) extern RSrandom *pRandom; // these functions to have different version for GUI and batch applications ... diff --git a/Population.cpp b/Population.cpp index 05d8633..002e860 100644 --- a/Population.cpp +++ b/Population.cpp @@ -433,12 +433,6 @@ void Population::reproduction(const float localK,const float envval,const int re int ninds = (int)inds.size(); #if RSDEBUG //DEBUGLOG << "Population::reproduction(): this=" << this -//#if BUTTERFLYDISP -// << " option=" << option -//#endif // BUTTERFLYDISP -//#if RS_CONTAIN -// << " hab=" << hab -//#endif // RS_CONTAIN // << " ninds=" << ninds // << endl; #endif // RSDEBUG @@ -464,12 +458,8 @@ if (dem.repType == 0) nsexes = 1; else nsexes = 2; #if RSDEBUG //DEBUGLOG << "Population::reproduction(): this=" << this -//#if RS_CONTAIN -// << " hab=" << hab -//#else // << " pSpecies=" << pSpecies // << " localK=" << localK << " envval=" << envval << " resol=" << resol -//#endif // RS_CONTAIN // << " sstruct.nStages=" << sstruct.nStages << " nsexes=" << nsexes << " ninds=" << ninds // << endl; #endif From 6a9e15af2dad97895d8cdf73cf2d4e8d70be73a2 Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Thu, 23 Nov 2023 13:42:36 +0000 Subject: [PATCH 05/17] draft for main --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 31e59e4..4a1584e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ # Config file for compilation with CMake # Only relevant for Batch mode, but this file needs to live in the RScore folder -add_library(RScore Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp) +add_library(RScore Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp "Main.cpp") # pass config definitions to compiler if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin") From 6fefa2104864dfaebaa834a5b44ebdd166f40079 Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Thu, 23 Nov 2023 13:42:50 +0000 Subject: [PATCH 06/17] draft for main --- Main.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 Main.cpp diff --git a/Main.cpp b/Main.cpp new file mode 100644 index 0000000..74b036f --- /dev/null +++ b/Main.cpp @@ -0,0 +1,63 @@ +/*---------------------------------------------------------------------------- + * + * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . + * + --------------------------------------------------------------------------*/ + +#include +#include +#include + +using namespace std; + +#if LINUX_CLUSTER || R_CMD +#include +#else +#include +#endif + +void assert_error(const string& exptd_err_msg, void (*x)(void)) { + string err_msg{ "No error.\n" }; + try { x(); } + catch (exception& e) { err_msg = e.what(); } + assert(err_msg == exptd_err_msg); +} + +void run_unit_tests() { + cout << "******* Unit test output *******" << endl; + testRSrandom(); + testIndividual(); + cout << endl << "************************" << endl; +} + +#if LINUX_CLUSTER || RS_RCPP +int main(int argc, char* argv[]) +#else +int _tmain(int argc, _TCHAR* argv[]) +#endif +{ +#ifdef NDEBUG + cout << "This code is only for running tests and not meant to run in release." << endl; + return 1; +# else + assert(0.1 > 0.0); // assert does run correctly + run_unit_tests(); + cout << "All tests have completed." << endl; + return 0; // if tests succeed, we are happy +# endif // NDEBUG +} \ No newline at end of file From febd01c64f9f03a52b70ba84c56a0ad73587cf20 Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Thu, 23 Nov 2023 13:45:03 +0000 Subject: [PATCH 07/17] import changes from rs_batch_dev::unit_test --- CMakeLists.txt | 14 +- Individual.cpp | 3400 ++++++++++++++++++++---------------------------- Individual.h | 15 +- Landscape.cpp | 8 +- Population.cpp | 3080 ++++++++++++++++++------------------------- Population.h | 3 - RSrandom.cpp | 29 +- RSrandom.h | 6 +- Utils.cpp | 9 + Utils.h | 12 + 10 files changed, 2730 insertions(+), 3846 deletions(-) create mode 100644 Utils.cpp create mode 100644 Utils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a1584e..56c5971 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,17 @@ # Config file for compilation with CMake # Only relevant for Batch mode, but this file needs to live in the RScore folder -add_library(RScore Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp "Main.cpp") +add_library(RScore Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp Utils.cpp) # pass config definitions to compiler +target_compile_definitions(RScore PRIVATE RSWIN64) + +# enable LINUX_CLUSTER macro on Linux + macOS if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin") - target_compile_definitions(RScore PRIVATE "RSDEBUG" "RSWIN64" "LINUX_CLUSTER") -else() # Windows - target_compile_definitions(RScore PRIVATE "RSDEBUG" "RSWIN64") + add_compile_definitions("LINUX_CLUSTER") +endif() + +# Debug Mode by default, unless "release" is passed +if(NOT DEFINED release) + add_compile_definitions(RSDEBUG) endif() \ No newline at end of file diff --git a/Individual.cpp b/Individual.cpp index 357f175..cc7bf6e 100644 --- a/Individual.cpp +++ b/Individual.cpp @@ -1,26 +1,26 @@ /*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, Damaris Zurell - * + * + * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * + * --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- + + + //--------------------------------------------------------------------------- #include "Individual.h" //--------------------------------------------------------------------------- @@ -30,82 +30,70 @@ int Individual::indCounter = 0; //--------------------------------------------------------------------------- // Individual constructor -Individual::Individual(Cell *pCell,Patch *pPatch,short stg,short a,short repInt, - float probmale,bool movt,short moveType) +Individual::Individual(Cell* pCell, Patch* pPatch, short stg, short a, short repInt, + float probmale, bool movt, short moveType) { -indId = indCounter; indCounter++; // unique identifier for each individual -#if RSDEBUG -//DEBUGLOG << "Individual::Individual(): indId=" << indId -// << " stg=" << stg << " a=" << a << " probmale=" << probmale -// << endl; -#endif + indId = indCounter; + indCounter++; // unique identifier for each individual -stage = stg; -if (probmale <= 0.0) sex = 0; -else sex = pRandom->Bernoulli(probmale); -age = a; -status = 0; + stage = stg; + if (probmale <= 0.0) sex = 0; + else sex = pRandom->Bernoulli(probmale); + age = a; + status = 0; -if (sex == 0 && repInt > 0) { // set no. of fallow seasons for female - fallow = pRandom->IRandom(0,repInt); -} -else fallow = 9999; -isDeveloping = false; -pPrevCell = pCurrCell = pCell; -pNatalPatch = pPatch; -if (movt) { - locn loc = pCell->getLocn(); - path = new pathData; - path->year = 0; path->total = 0; path->out = 0; - path->pSettPatch = 0; path->settleStatus = 0; -// path->leftNatalPatch = false; + if (sex == 0 && repInt > 0) { // set no. of fallow seasons for female + fallow = pRandom->IRandom(0, repInt); + } + else fallow = 9999; + isDeveloping = false; + pPrevCell = pCurrCell = pCell; + pNatalPatch = pPatch; + if (movt) { + locn loc = pCell->getLocn(); + path = new pathData; + path->year = 0; path->total = 0; path->out = 0; + path->pSettPatch = 0; path->settleStatus = 0; #if RS_RCPP - path->pathoutput = 1; -#endif - if (moveType == 1) { // SMS - // set up location data for SMS - smsData = new smsdata; - smsData->dp = smsData->gb = smsData->alphaDB = 1.0; - smsData->betaDB = 1; - smsData->prev.x = loc.x; smsData->prev.y = loc.y; // previous location - smsData->goal.x = loc.x; smsData->goal.y = loc.y; // goal location - initialised for dispersal bias - } - else smsData = 0; - if (moveType == 2) { // CRW - // set up continuous co-ordinates etc. for CRW movement - crw = new crwParams; - crw->xc = ((float)pRandom->Random()*0.999f) + (float)loc.x; - crw->yc = (float)(pRandom->Random()*0.999f) + (float)loc.y; - crw->prevdrn = (float)(pRandom->Random()*2.0 * PI); - crw->stepL = crw->rho = 0.0; - } - else crw = 0; -} -else { - path = 0; crw = 0; smsData = 0; -} -emigtraits = 0; -kerntraits = 0; -setttraits = 0; -pGenome = 0; -#if RSDEBUG -//locn currloc = pCurrCell->getLocn(); -//DEBUGLOG << "Individual::Individual(): indId=" << indId -// << " x=" << currloc.x << " y=" << currloc.y -//// << " smsData=" << smsData << " dp=" << smsData->dp -// << endl; -#endif + path->pathoutput = 1; +#endif + if (moveType == 1) { // SMS + // set up location data for SMS + smsData = new smsdata; + smsData->dp = smsData->gb = smsData->alphaDB = 1.0; + smsData->betaDB = 1; + smsData->prev.x = loc.x; smsData->prev.y = loc.y; // previous location + smsData->goal.x = loc.x; smsData->goal.y = loc.y; // goal location - initialised for dispersal bias + } + else smsData = 0; + if (moveType == 2) { // CRW + // set up continuous co-ordinates etc. for CRW movement + crw = new crwParams; + crw->xc = ((float)pRandom->Random() * 0.999f) + (float)loc.x; + crw->yc = (float)(pRandom->Random() * 0.999f) + (float)loc.y; + crw->prevdrn = (float)(pRandom->Random() * 2.0 * PI); + crw->stepL = crw->rho = 0.0; + } + else crw = 0; + } + else { + path = 0; crw = 0; smsData = 0; + } + emigtraits = 0; + kerntraits = 0; + setttraits = 0; + pGenome = 0; } Individual::~Individual(void) { -if (path != 0) delete path; -if (crw != 0) delete crw; -if (smsData != 0) delete smsData; -if (emigtraits != 0) delete emigtraits; -if (kerntraits != 0) delete kerntraits; -if (setttraits != 0) delete setttraits; + if (path != 0) delete path; + if (crw != 0) delete crw; + if (smsData != 0) delete smsData; + if (emigtraits != 0) delete emigtraits; + if (kerntraits != 0) delete kerntraits; + if (setttraits != 0) delete setttraits; -if (pGenome != 0) delete pGenome; + if (pGenome != 0) delete pGenome; } @@ -114,376 +102,301 @@ if (pGenome != 0) delete pGenome; //--------------------------------------------------------------------------- // Set genes for individual variation from species initialisation parameters -void Individual::setGenes(Species *pSpecies,int resol) { -demogrParams dem = pSpecies->getDemogr(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -genomeData gen = pSpecies->getGenomeData(); -simParams sim = paramsSim->getSim(); -int ntraits; // first trait for all/female expression, second for male expression - -if (gen.trait1Chromosome) { - pGenome = new Genome(pSpecies->getNChromosomes(),pSpecies->getNLoci(0), - pSpecies->isDiploid()); -} -else { - pGenome = new Genome(pSpecies); -} -#if RSDEBUG -//DEBUGLOG << endl; -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " sex=" << sex -// << " trait1Chromosome=" << gen.trait1Chromosome << " pGenome=" << pGenome -// << endl; -#endif - -int gposn = 0; // current position on genome -int expr = 0; // gene expression type - NOT CURRENTLY USED - -//int emigposn = 0; -#if RSDEBUG -//DEBUGLOG << "Individual::setGenes(): emigration genes" << endl; -#endif -if (emig.indVar) { // set emigration genes - int emigposn = gposn; - double d0,alpha,beta; - emigParams eparams; -// emigScales scale = pSpecies->getEmigScales(); - if (emig.sexDep) { // must be a sexual species - ntraits = 2; +void Individual::setGenes(Species* pSpecies, int resol) { + demogrParams dem = pSpecies->getDemogr(); + emigRules emig = pSpecies->getEmig(); + trfrRules trfr = pSpecies->getTrfr(); + settleType sett = pSpecies->getSettle(); + genomeData gen = pSpecies->getGenomeData(); + simParams sim = paramsSim->getSim(); + int ntraits; // first trait for all/female expression, second for male expression + + if (gen.trait1Chromosome) { + pGenome = new Genome(pSpecies->getNChromosomes(), pSpecies->getNLoci(0), + pSpecies->isDiploid()); } else { - if (dem.repType == 0) { // asexual reproduction (haploid) - ntraits = 1; - } - else { // sexual reproduction - ntraits = 1; - } + pGenome = new Genome(pSpecies); } - for (int g = 0; g < ntraits; g++) { // first trait for females/all, second for males - eparams = pSpecies->getEmigParams(0,g); - d0 = pRandom->Normal(0.0,eparams.d0SD) / eparams.d0Scale; - if (emig.densDep) { - alpha = pRandom->Normal(0.0,eparams.alphaSD) / eparams.alphaScale; - beta = pRandom->Normal(0.0,eparams.betaSD) / eparams.betaScale; + + int gposn = 0; // current position on genome + int expr = 0; // gene expression type - NOT CURRENTLY USED + + if (emig.indVar) { // set emigration genes + int emigposn = gposn; + double d0, alpha, beta; + emigParams eparams; + if (emig.sexDep) { // must be a sexual species + ntraits = 2; } -#if RSDEBUG -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " g=" << g -// << " eparams.d0Mean=" << eparams.d0Mean << " eparams.d0SD=" << eparams.d0SD -// << " eparams.d0Scale=" << eparams.d0Scale << " d0=" << d0 -//// << " log(d0/(1.0-d0))=" << log(d0/(1.0-d0)) -// << endl; -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " g=" << g -// << " eparams.alphaMean=" << eparams.alphaMean << " eparams.alphaSD=" << eparams.alphaSD -// << " eparams.alphaScale=" << eparams.alphaScale << " alpha=" << alpha -// << endl; -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " g=" << g -// << " eparams.betaMean=" << eparams.betaMean << " eparams.betaSD=" << eparams.betaSD -// << " eparams.betaScale=" << eparams.betaScale << " beta=" << beta -// << endl; -#endif - if (gen.trait1Chromosome) { - pGenome->setGene(gposn++,expr,d0,gen.alleleSD); - if (emig.densDep) { - pGenome->setGene(gposn++,expr,alpha,gen.alleleSD); - pGenome->setGene(gposn++,expr,beta,gen.alleleSD); + else { + if (dem.repType == 0) { // asexual reproduction (haploid) + ntraits = 1; + } + else { // sexual reproduction + ntraits = 1; } } - else { - pGenome->setTrait(pSpecies,gposn++,d0,gen.alleleSD); + for (int g = 0; g < ntraits; g++) { // first trait for females/all, second for males + eparams = pSpecies->getEmigParams(0, g); + d0 = pRandom->Normal(0.0, eparams.d0SD) / eparams.d0Scale; if (emig.densDep) { - pGenome->setTrait(pSpecies,gposn++,alpha,gen.alleleSD); - pGenome->setTrait(pSpecies,gposn++,beta,gen.alleleSD); + alpha = pRandom->Normal(0.0, eparams.alphaSD) / eparams.alphaScale; + beta = pRandom->Normal(0.0, eparams.betaSD) / eparams.betaScale; + } + if (gen.trait1Chromosome) { + pGenome->setGene(gposn++, expr, d0, gen.alleleSD); + if (emig.densDep) { + pGenome->setGene(gposn++, expr, alpha, gen.alleleSD); + pGenome->setGene(gposn++, expr, beta, gen.alleleSD); + } + } + else { + pGenome->setTrait(pSpecies, gposn++, d0, gen.alleleSD); + if (emig.densDep) { + pGenome->setTrait(pSpecies, gposn++, alpha, gen.alleleSD); + pGenome->setTrait(pSpecies, gposn++, beta, gen.alleleSD); + } } } - } - // record phenotypic traits - if (emig.densDep) { - setEmigTraits(pSpecies,emigposn,3,emig.sexDep); - } - else { - setEmigTraits(pSpecies,emigposn,1,emig.sexDep); - } -} - -//int trfrposn = 0; -if (trfr.indVar) { // set transfer genes - int trfrposn = gposn; - if (trfr.sexDep) { // must be a sexual species - ntraits = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ntraits = 1; + // record phenotypic traits + if (emig.densDep) { + setEmigTraits(pSpecies, emigposn, 3, emig.sexDep); } - else { // sexual reproduction - ntraits = 1; + else { + setEmigTraits(pSpecies, emigposn, 1, emig.sexDep); } } -// trfrScales scale = pSpecies->getTrfrScales(); - if (trfr.moveModel) { - if (trfr.moveType == 1) { // set SMS genes - double dp,gb,alphaDB,betaDB; - trfrSMSParams smsparams = pSpecies->getSMSParams(0,0); // only traits for females/all - trfrSMSTraits smstraits = pSpecies->getSMSTraits(); - dp = pRandom->Normal(0.0,smsparams.dpSD) / smsparams.dpScale; - gb = pRandom->Normal(0.0,smsparams.gbSD) / smsparams.gbScale; - if (smstraits.goalType == 2) { - alphaDB = pRandom->Normal(0.0,smsparams.alphaDBSD) / smsparams.alphaDBScale; - betaDB = pRandom->Normal(0.0,smsparams.betaDBSD) / smsparams.betaDBScale; + + //int trfrposn = 0; + if (trfr.indVar) { // set transfer genes + int trfrposn = gposn; + if (trfr.sexDep) { // must be a sexual species + ntraits = 2; + } + else { + if (dem.repType == 0) { // asexual reproduction + ntraits = 1; } - if (gen.trait1Chromosome) { - pGenome->setGene(gposn++,expr,dp,gen.alleleSD); - pGenome->setGene(gposn++,expr,gb,gen.alleleSD); + else { // sexual reproduction + ntraits = 1; + } + } + if (trfr.moveModel) { + if (trfr.moveType == 1) { // set SMS genes + double dp, gb, alphaDB, betaDB; + trfrSMSParams smsparams = pSpecies->getSMSParams(0, 0); // only traits for females/all + trfrSMSTraits smstraits = pSpecies->getSMSTraits(); + dp = pRandom->Normal(0.0, smsparams.dpSD) / smsparams.dpScale; + gb = pRandom->Normal(0.0, smsparams.gbSD) / smsparams.gbScale; if (smstraits.goalType == 2) { - pGenome->setGene(gposn++,expr,alphaDB,gen.alleleSD); - pGenome->setGene(gposn++,expr,betaDB,gen.alleleSD); + alphaDB = pRandom->Normal(0.0, smsparams.alphaDBSD) / smsparams.alphaDBScale; + betaDB = pRandom->Normal(0.0, smsparams.betaDBSD) / smsparams.betaDBScale; + } + if (gen.trait1Chromosome) { + pGenome->setGene(gposn++, expr, dp, gen.alleleSD); + pGenome->setGene(gposn++, expr, gb, gen.alleleSD); + if (smstraits.goalType == 2) { + pGenome->setGene(gposn++, expr, alphaDB, gen.alleleSD); + pGenome->setGene(gposn++, expr, betaDB, gen.alleleSD); + } + } + else { + pGenome->setTrait(pSpecies, gposn++, dp, gen.alleleSD); + pGenome->setTrait(pSpecies, gposn++, gb, gen.alleleSD); + if (smstraits.goalType == 2) { + pGenome->setTrait(pSpecies, gposn++, alphaDB, gen.alleleSD); + pGenome->setTrait(pSpecies, gposn++, betaDB, gen.alleleSD); + } } + // record phenotypic traits + if (smstraits.goalType == 2) + setSMSTraits(pSpecies, trfrposn, 4, false); + else + setSMSTraits(pSpecies, trfrposn, 2, false); } - else { - pGenome->setTrait(pSpecies,gposn++,dp,gen.alleleSD); - pGenome->setTrait(pSpecies,gposn++,gb,gen.alleleSD); - if (smstraits.goalType == 2) { - pGenome->setTrait(pSpecies,gposn++,alphaDB,gen.alleleSD); - pGenome->setTrait(pSpecies,gposn++,betaDB,gen.alleleSD); + if (trfr.moveType == 2) { // set CRW genes + double stepL, rho; + trfrCRWParams m = pSpecies->getCRWParams(0, 0); // only traits for females/all + stepL = pRandom->Normal(0.0, m.stepLgthSD) / m.stepLScale; + rho = pRandom->Normal(0.0, m.rhoSD) / m.rhoScale; + if (gen.trait1Chromosome) { + pGenome->setGene(gposn++, expr, stepL, gen.alleleSD); + pGenome->setGene(gposn++, expr, rho, gen.alleleSD); + } + else { + pGenome->setTrait(pSpecies, gposn++, stepL, gen.alleleSD); + pGenome->setTrait(pSpecies, gposn++, rho, gen.alleleSD); + } + // record phenotypic traits + setCRWTraits(pSpecies, trfrposn, 2, false); + } + } + else { // set kernel genes + double dist1, dist2, prob1; + trfrKernParams k; + for (int g = 0; g < ntraits; g++) { // first traits for females/all, second for males + k = pSpecies->getKernParams(0, g); + dist1 = pRandom->Normal(0.0, k.dist1SD) / k.dist1Scale; + if (trfr.twinKern) + { + dist2 = pRandom->Normal(0.0, k.dist2SD) / k.dist2Scale; + prob1 = pRandom->Normal(0.0, k.PKern1SD) / k.PKern1Scale; + } + if (gen.trait1Chromosome) { + pGenome->setGene(gposn++, expr, dist1, gen.alleleSD); + if (trfr.twinKern) + { + pGenome->setGene(gposn++, expr, dist2, gen.alleleSD); + pGenome->setGene(gposn++, expr, prob1, gen.alleleSD); + } + } + else { + pGenome->setTrait(pSpecies, gposn++, dist1, gen.alleleSD); + if (trfr.twinKern) + { + pGenome->setTrait(pSpecies, gposn++, dist2, gen.alleleSD); + pGenome->setTrait(pSpecies, gposn++, prob1, gen.alleleSD); + } } } // record phenotypic traits - if (smstraits.goalType == 2) - setSMSTraits(pSpecies,trfrposn,4,false); - else - setSMSTraits(pSpecies,trfrposn,2,false); - } - if (trfr.moveType == 2) { // set CRW genes - double stepL,rho; - trfrCRWParams m = pSpecies->getCRWParams(0,0); // only traits for females/all - stepL = pRandom->Normal(0.0,m.stepLgthSD) / m.stepLScale; - rho = pRandom->Normal(0.0,m.rhoSD) / m.rhoScale; - if (gen.trait1Chromosome) { - pGenome->setGene(gposn++,expr,stepL,gen.alleleSD); - pGenome->setGene(gposn++,expr,rho,gen.alleleSD); + if (trfr.twinKern) + { + setKernTraits(pSpecies, trfrposn, 3, resol, trfr.sexDep); } else { - pGenome->setTrait(pSpecies,gposn++,stepL,gen.alleleSD); - pGenome->setTrait(pSpecies,gposn++,rho,gen.alleleSD); + setKernTraits(pSpecies, trfrposn, 1, resol, trfr.sexDep); } - // record phenotypic traits - setCRWTraits(pSpecies,trfrposn,2,false); } } - else { // set kernel genes - double dist1,dist2,prob1; - trfrKernParams k; - for (int g = 0; g < ntraits; g++) { // first traits for females/all, second for males - k = pSpecies->getKernParams(0,g); - dist1 = pRandom->Normal(0.0,k.dist1SD) / k.dist1Scale; - if (trfr.twinKern) - { - dist2 = pRandom->Normal(0.0,k.dist2SD) / k.dist2Scale; - prob1 = pRandom->Normal(0.0,k.PKern1SD) / k.PKern1Scale; + + if (sett.indVar) { + int settposn = gposn; + double s0, alpha, beta; + settParams sparams; + if (sett.sexDep) { // must be a sexual species + ntraits = 2; + } + else { + if (dem.repType == 0) { // asexual reproduction + ntraits = 1; } + else { // sexual reproduction + ntraits = 1; + } + } + for (int g = 0; g < ntraits; g++) { // first trait for females/all, second for males + if (sim.batchMode) { + sparams = pSpecies->getSettParams(0, g); + } + else { // individual variability not (yet) implemented as sex-dependent in GUI + sparams = pSpecies->getSettParams(0, 0); + } + s0 = pRandom->Normal(0.0, sparams.s0SD) / sparams.s0Scale; + alpha = pRandom->Normal(0.0, sparams.alphaSSD) / sparams.alphaSScale; + beta = pRandom->Normal(0.0, sparams.betaSSD) / sparams.betaSScale; + if (gen.trait1Chromosome) { - pGenome->setGene(gposn++,expr,dist1,gen.alleleSD); - if (trfr.twinKern) - { - pGenome->setGene(gposn++,expr,dist2,gen.alleleSD); - pGenome->setGene(gposn++,expr,prob1,gen.alleleSD); - } + pGenome->setGene(gposn++, expr, s0, gen.alleleSD); + pGenome->setGene(gposn++, expr, alpha, gen.alleleSD); + pGenome->setGene(gposn++, expr, beta, gen.alleleSD); } else { - pGenome->setTrait(pSpecies,gposn++,dist1,gen.alleleSD); - if (trfr.twinKern) - { - pGenome->setTrait(pSpecies,gposn++,dist2,gen.alleleSD); - pGenome->setTrait(pSpecies,gposn++,prob1,gen.alleleSD); - } - } + pGenome->setTrait(pSpecies, gposn++, s0, gen.alleleSD); + pGenome->setTrait(pSpecies, gposn++, alpha, gen.alleleSD); + pGenome->setTrait(pSpecies, gposn++, beta, gen.alleleSD); + } } // record phenotypic traits - if (trfr.twinKern) - { - setKernTraits(pSpecies,trfrposn,3,resol,trfr.sexDep); - } - else { - setKernTraits(pSpecies,trfrposn,1,resol,trfr.sexDep); - } + setSettTraits(pSpecies, settposn, 3, sett.sexDep); } -} -//int settposn = 0; -#if RSDEBUG -//DEBUGLOG << "Individual::setGenes(): settlement genes" << endl; -#endif -if (sett.indVar) { - int settposn = gposn; - double s0,alpha,beta; - settParams sparams; -// settScales scale = pSpecies->getSettScales(); - if (sett.sexDep) { // must be a sexual species - ntraits = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ntraits = 1; - } - else { // sexual reproduction - ntraits = 1; - } - } - for (int g = 0; g < ntraits; g++) { // first trait for females/all, second for males - if (sim.batchMode) { - sparams = pSpecies->getSettParams(0,g); - } - else { // individual variability not (yet) implemented as sex-dependent in GUI - sparams = pSpecies->getSettParams(0,0); - } - s0 = pRandom->Normal(0.0,sparams.s0SD) / sparams.s0Scale; - alpha = pRandom->Normal(0.0,sparams.alphaSSD) / sparams.alphaSScale; - beta = pRandom->Normal(0.0,sparams.betaSSD) / sparams.betaSScale; -#if RSDEBUG -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " g=" << g -// << " sparams.s0Mean=" << sparams.s0Mean -// << " sparams.s0SD=" << sparams.s0SD -// << " sparams.s0Scale=" << sparams.s0Scale -// << " s0=" << s0 -// << endl; -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " g=" << g -// << " sparams.alphaSMean=" << sparams.alphaSMean -// << " sparams.alphaSSD=" << sparams.alphaSSD -// << " sparams.alphaSScale=" << sparams.alphaSScale -// << " alpha=" << alpha -// << endl; -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " g=" << g -// << " sparams.betaSMean=" << sparams.betaSMean -// << " sparams.betaSSD=" << sparams.betaSSD -// << " sparams.betaSScale=" << sparams.betaSScale -// << " beta=" << beta -// << endl; -#endif - if (gen.trait1Chromosome) { - pGenome->setGene(gposn++,expr,s0,gen.alleleSD); - pGenome->setGene(gposn++,expr,alpha,gen.alleleSD); - pGenome->setGene(gposn++,expr,beta,gen.alleleSD); - } - else { - pGenome->setTrait(pSpecies,gposn++,s0,gen.alleleSD); - pGenome->setTrait(pSpecies,gposn++,alpha,gen.alleleSD); - pGenome->setTrait(pSpecies,gposn++,beta,gen.alleleSD); + if (!gen.trait1Chromosome) { + if (gen.neutralMarkers || pSpecies->getNNeutralLoci() > 0) { + pGenome->setNeutralLoci(pSpecies, gen.alleleSD); } } - // record phenotypic traits - setSettTraits(pSpecies,settposn,3,sett.sexDep); -} - -if (!gen.trait1Chromosome) { - if (gen.neutralMarkers || pSpecies->getNNeutralLoci() > 0) { - pGenome->setNeutralLoci(pSpecies,gen.alleleSD); - } -} -#if RSDEBUG -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " finished" -// << endl; -#endif } // Inherit genome from parent(s) -void Individual::setGenes(Species *pSpecies,Individual *mother,Individual *father, +void Individual::setGenes(Species* pSpecies, Individual* mother, Individual* father, int resol) { -#if RSDEBUG -//locn currloc = pCurrCell->getLocn(); -//DEBUGLOG << "Individual::setGenes(): indId=" << indId -// << " x=" << currloc.x << " y=" << currloc.y -//// << " pSpecies=" << pSpecies -// << " mother=" << mother -// << " motherID=" << mother->getId() -// << " father=" << father; -//if (father != 0) DEBUGLOG << " fatherID=" << father->getId(); -//DEBUGLOG << endl; -#endif -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); - -Genome *pFatherGenome; -if (father == 0) pFatherGenome = 0; else pFatherGenome = father->pGenome; + emigRules emig = pSpecies->getEmig(); + trfrRules trfr = pSpecies->getTrfr(); + settleType sett = pSpecies->getSettle(); -pGenome = new Genome(pSpecies,mother->pGenome,pFatherGenome); + Genome* pFatherGenome; + if (father == 0) pFatherGenome = 0; else pFatherGenome = father->pGenome; -if (emig.indVar) { - // record emigration traits - if (father == 0) { // haploid - if (emig.densDep) { - setEmigTraits(pSpecies,0,3,0); - } - else { - setEmigTraits(pSpecies,0,1,0); - } - } - else { // diploid - if (emig.densDep) { - setEmigTraits(pSpecies,0,3,emig.sexDep); - } - else { - setEmigTraits(pSpecies,0,1,emig.sexDep); - } - } -} + pGenome = new Genome(pSpecies, mother->pGenome, pFatherGenome); -if (trfr.indVar) { - // record movement model traits - if (trfr.moveModel) { - if (trfr.moveType == 1) { // SMS - trfrSMSTraits s = pSpecies->getSMSTraits(); - if (s.goalType == 2) - setSMSTraits(pSpecies,trfr.movtTrait[0],4,0); - else - setSMSTraits(pSpecies,trfr.movtTrait[0],2,0); - } - if (trfr.moveType == 2) { // CRW - setCRWTraits(pSpecies,trfr.movtTrait[0],2,0); - } - } - else { // kernel + if (emig.indVar) { + // record emigration traits if (father == 0) { // haploid - if (trfr.twinKern) - { - setKernTraits(pSpecies,trfr.movtTrait[0],3,resol,0); + if (emig.densDep) { + setEmigTraits(pSpecies, 0, 3, 0); } else { - setKernTraits(pSpecies,trfr.movtTrait[0],1,resol,0); + setEmigTraits(pSpecies, 0, 1, 0); } } else { // diploid - if (trfr.twinKern) - { - setKernTraits(pSpecies,trfr.movtTrait[0],3,resol,trfr.sexDep); + if (emig.densDep) { + setEmigTraits(pSpecies, 0, 3, emig.sexDep); } else { - setKernTraits(pSpecies,trfr.movtTrait[0],1,resol,trfr.sexDep); + setEmigTraits(pSpecies, 0, 1, emig.sexDep); } } } -} -if (sett.indVar) { - // record settlement traits - if (father == 0) { // haploid - setSettTraits(pSpecies,sett.settTrait[0],3,0); - } - else { // diploid - setSettTraits(pSpecies,sett.settTrait[0],3,sett.sexDep); -// setSettTraits(pSpecies,sett.settTrait[0],3,0); + if (trfr.indVar) { + // record movement model traits + if (trfr.moveModel) { + if (trfr.moveType == 1) { // SMS + trfrSMSTraits s = pSpecies->getSMSTraits(); + if (s.goalType == 2) + setSMSTraits(pSpecies, trfr.movtTrait[0], 4, 0); + else + setSMSTraits(pSpecies, trfr.movtTrait[0], 2, 0); + } + if (trfr.moveType == 2) { // CRW + setCRWTraits(pSpecies, trfr.movtTrait[0], 2, 0); + } + } + else { // kernel + if (father == 0) { // haploid + if (trfr.twinKern) + { + setKernTraits(pSpecies, trfr.movtTrait[0], 3, resol, 0); + } + else { + setKernTraits(pSpecies, trfr.movtTrait[0], 1, resol, 0); + } + } + else { // diploid + if (trfr.twinKern) + { + setKernTraits(pSpecies, trfr.movtTrait[0], 3, resol, trfr.sexDep); + } + else { + setKernTraits(pSpecies, trfr.movtTrait[0], 1, resol, trfr.sexDep); + } + } + } } -} -#if RSDEBUG -//emigParams e = getEmigTraits(0,1,0); -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " finished " -// << " d0=" << e.d0 -//// << " alpha=" << e.alpha << " beta=" << e.beta -// << endl; -#endif + if (sett.indVar) { + // record settlement traits + if (father == 0) { // haploid + setSettTraits(pSpecies, sett.settTrait[0], 3, 0); + } + else { // diploid + setSettTraits(pSpecies, sett.settTrait[0], 3, sett.sexDep); + } + } } //--------------------------------------------------------------------------- @@ -491,12 +404,12 @@ if (sett.indVar) { // Identify whether an individual is a potentially breeding female - // if so, return her stage, otherwise return 0 int Individual::breedingFem(void) { -if (sex == 0) { - if (status == 0 || status == 4 || status == 5) return stage; + if (sex == 0) { + if (status == 0 || status == 4 || status == 5) return stage; + else return 0; + } else return 0; } -else return 0; -} int Individual::getId(void) { return indId; } @@ -505,617 +418,428 @@ int Individual::getSex(void) { return sex; } int Individual::getStatus(void) { return status; } indStats Individual::getStats(void) { -indStats s; -s.stage = stage; s.sex = sex; s.age = age; s.status = status; s.fallow = fallow; -s.isDeveloping = isDeveloping; -return s; + indStats s; + s.stage = stage; s.sex = sex; s.age = age; s.status = status; s.fallow = fallow; + s.isDeveloping = isDeveloping; + return s; } Cell* Individual::getLocn(const short option) { -if (option == 0) { // return previous location - return pPrevCell; -} -else { // return current location - return pCurrCell; -} + if (option == 0) { // return previous location + return pPrevCell; + } + else { // return current location + return pCurrCell; + } } Patch* Individual::getNatalPatch(void) { return pNatalPatch; } void Individual::setYearSteps(int t) { -if (path != 0 && t >= 0) { - if (t >= 0) path->year = t; - else path->year = 666; -} -#if RSDEBUG -//DEBUGLOG << "Individual::setYearSteps(): indId=" << indId -// << " t=" << t << " path->year=" << path->year -// << endl; -#endif + if (path != 0 && t >= 0) { + if (t >= 0) path->year = t; + else path->year = 666; + } } pathSteps Individual::getSteps(void) { -pathSteps s; -if (path == 0) { - s.year = 0; s.total = 0; s.out = 0; -} -else { - s.year = path->year; s.total = path->total; s.out = path->out; -} -return s; + pathSteps s; + if (path == 0) { + s.year = 0; s.total = 0; s.out = 0; + } + else { + s.year = path->year; s.total = path->total; s.out = path->out; + } + return s; } settlePatch Individual::getSettPatch(void) { -settlePatch s; -if (path == 0) { - s.pSettPatch = 0; s.settleStatus = 0; -} -else { - s.pSettPatch = path->pSettPatch; s.settleStatus = path->settleStatus; -} -return s; + settlePatch s; + if (path == 0) { + s.pSettPatch = 0; s.settleStatus = 0; + } + else { + s.pSettPatch = path->pSettPatch; s.settleStatus = path->settleStatus; + } + return s; } void Individual::setSettPatch(const settlePatch s) { -if (path == 0) { - path = new pathData; - path->year = 0; path->total = 0; path->out = 0; path->settleStatus = 0; + if (path == 0) { + path = new pathData; + path->year = 0; path->total = 0; path->out = 0; path->settleStatus = 0; #if RS_RCPP - path->pathoutput = 1; + path->pathoutput = 1; #endif -} -if (s.settleStatus >= 0 && s.settleStatus <= 2) path->settleStatus = s.settleStatus; -path->pSettPatch = s.pSettPatch; + } + if (s.settleStatus >= 0 && s.settleStatus <= 2) path->settleStatus = s.settleStatus; + path->pSettPatch = s.pSettPatch; } // Set phenotypic emigration traits -void Individual::setEmigTraits(Species *pSpecies,short emiggenelocn,short nemigtraits, +void Individual::setEmigTraits(Species* pSpecies, short emiggenelocn, short nemigtraits, bool sexdep) { -#if RSDEBUG -//DEBUGLOG << "Individual::setEmigTraits(): indId=" << indId -// << " emiggenelocn=" << emiggenelocn << " nemigtraits=" << nemigtraits << " sexdep=" << sexdep -// << endl; -#endif -emigTraits e; e.d0 = e.alpha = e.beta = 0.0; -if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - if (nemigtraits == 3) { // emigration is density-dependent - e.d0 = (float)pGenome->express(emiggenelocn+3*sex,0,0); - e.alpha = (float)pGenome->express(emiggenelocn+3*sex+1,0,0); - e.beta = (float)pGenome->express(emiggenelocn+3*sex+2,0,0); + emigTraits e; e.d0 = e.alpha = e.beta = 0.0; + if (pGenome != 0) { + if (pSpecies->has1ChromPerTrait()) { + if (sexdep) { + if (nemigtraits == 3) { // emigration is density-dependent + e.d0 = (float)pGenome->express(emiggenelocn + 3 * sex, 0, 0); + e.alpha = (float)pGenome->express(emiggenelocn + 3 * sex + 1, 0, 0); + e.beta = (float)pGenome->express(emiggenelocn + 3 * sex + 2, 0, 0); + } + else { + e.d0 = (float)pGenome->express(emiggenelocn + sex, 0, 0); + } } else { - e.d0 = (float)pGenome->express(emiggenelocn+sex,0,0); + e.d0 = (float)pGenome->express(emiggenelocn, 0, 0); + if (nemigtraits == 3) { // emigration is density-dependent + e.alpha = (float)pGenome->express(emiggenelocn + 1, 0, 0); + e.beta = (float)pGenome->express(emiggenelocn + 2, 0, 0); + } } } else { - e.d0 = (float)pGenome->express(emiggenelocn,0,0); - if (nemigtraits == 3) { // emigration is density-dependent - e.alpha = (float)pGenome->express(emiggenelocn+1,0,0); - e.beta = (float)pGenome->express(emiggenelocn+2,0,0); - } - } - } - else { - if (sexdep) { - if (nemigtraits == 3) { // emigration is density-dependent - e.d0 = (float)pGenome->express(pSpecies,emiggenelocn+3*sex); - e.alpha = (float)pGenome->express(pSpecies,emiggenelocn+3*sex+1); - e.beta = (float)pGenome->express(pSpecies,emiggenelocn+3*sex+2); + if (sexdep) { + if (nemigtraits == 3) { // emigration is density-dependent + e.d0 = (float)pGenome->express(pSpecies, emiggenelocn + 3 * sex); + e.alpha = (float)pGenome->express(pSpecies, emiggenelocn + 3 * sex + 1); + e.beta = (float)pGenome->express(pSpecies, emiggenelocn + 3 * sex + 2); + } + else { + e.d0 = (float)pGenome->express(pSpecies, emiggenelocn + sex); + } } else { - e.d0 = (float)pGenome->express(pSpecies,emiggenelocn+sex); - } - } - else { - e.d0 = (float)pGenome->express(pSpecies,emiggenelocn); - if (nemigtraits == 3) { // emigration is density-dependent - e.alpha = (float)pGenome->express(pSpecies,emiggenelocn+1); - e.beta = (float)pGenome->express(pSpecies,emiggenelocn+2); + e.d0 = (float)pGenome->express(pSpecies, emiggenelocn); + if (nemigtraits == 3) { // emigration is density-dependent + e.alpha = (float)pGenome->express(pSpecies, emiggenelocn + 1); + e.beta = (float)pGenome->express(pSpecies, emiggenelocn + 2); + } } } } -} -#if RSDEBUG -//DEBUGLOG << "Individual::setEmigTraits(): indId=" << indId -// << " e.d0=" << e.d0 << " e.alpha=" << e.alpha << " e.beta=" << e.beta -// << endl; -#endif -emigParams eparams; -if (sexdep) { - eparams = pSpecies->getEmigParams(0,sex); -} -else { - eparams = pSpecies->getEmigParams(0,0); -} -#if RSDEBUG -//DEBUGLOG << "Individual::setEmigTraits(): indId=" << indId -// << " eparams.betaMean=" << eparams.betaMean << " eparams.betaSD=" << eparams.betaSD -// << " eparams.betaScale=" << eparams.betaScale -// << endl; -#endif -emigtraits = new emigTraits; -emigtraits->d0 = (float)(e.d0*eparams.d0Scale + eparams.d0Mean); -emigtraits->alpha = (float)(e.alpha*eparams.alphaScale + eparams.alphaMean); -emigtraits->beta = (float)(e.beta*eparams.betaScale + eparams.betaMean); -#if RSDEBUG -//DEBUGLOG << "Individual::setEmigTraits(): indId=" << indId -// << " emigtraits->d0=" << emigtraits->d0 -// << " emigtraits->alpha=" << emigtraits->alpha << " emigtraits->beta=" << emigtraits->beta -// << endl; -#endif -if (emigtraits->d0 < 0.0) emigtraits->d0 = 0.0; -if (emigtraits->d0 > 1.0) emigtraits->d0 = 1.0; -#if RSDEBUG -//DEBUGLOG << "Individual::setEmigTraits(): indId=" << indId -// << " emigtraits->d0=" << emigtraits->d0 -// << " emigtraits->alpha=" << emigtraits->alpha << " emigtraits->beta=" << emigtraits->beta -// << endl; -#endif -return; + emigParams eparams; + if (sexdep) { + eparams = pSpecies->getEmigParams(0, sex); + } + else { + eparams = pSpecies->getEmigParams(0, 0); + } + emigtraits = new emigTraits; + emigtraits->d0 = (float)(e.d0 * eparams.d0Scale + eparams.d0Mean); + emigtraits->alpha = (float)(e.alpha * eparams.alphaScale + eparams.alphaMean); + emigtraits->beta = (float)(e.beta * eparams.betaScale + eparams.betaMean); + if (emigtraits->d0 < 0.0) emigtraits->d0 = 0.0; + if (emigtraits->d0 > 1.0) emigtraits->d0 = 1.0; + return; } // Get phenotypic emigration traits emigTraits Individual::getEmigTraits(void) { -#if RSDEBUG -//DEBUGLOG << "Individual::getEmigTraits(): indId=" << indId -// << endl; -#endif -emigTraits e; e.d0 = e.alpha = e.beta = 0.0; -if (emigtraits != 0) { - e.d0 = emigtraits->d0; - e.alpha = emigtraits->alpha; - e.beta = emigtraits->beta; -} -#if RSDEBUG -//DEBUGLOG << "Individual::getEmigTraits(): indId=" << indId -// << " e.d0=" << e.d0 << " e.alpha=" << e.alpha << " e.beta=" << e.beta -// << endl; -#endif - -return e; + emigTraits e; e.d0 = e.alpha = e.beta = 0.0; + if (emigtraits != 0) { + e.d0 = emigtraits->d0; + e.alpha = emigtraits->alpha; + e.beta = emigtraits->beta; + } + return e; } // Set phenotypic transfer by kernel traits -void Individual::setKernTraits(Species *pSpecies,short kerngenelocn,short nkerntraits, - int resol,bool sexdep) { -#if RSDEBUG -//DEBUGLOG << "Individual::setKernTraits(): indId=" << indId -// << " kerngenelocn=" << kerngenelocn << " nkerntraits=" << nkerntraits << " sexdep=" << sexdep -// << endl; -#endif -trfrKernTraits k; k.meanDist1 = k.meanDist2 = k.probKern1 = 0.0; -if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - if (nkerntraits == 3) { // twin kernel - k.meanDist1 = (float)pGenome->express(kerngenelocn+3*sex,0,sex); - k.meanDist2 = (float)pGenome->express(kerngenelocn+3*sex+1,0,sex); - k.probKern1 = (float)pGenome->express(kerngenelocn+3*sex+2,0,sex); +void Individual::setKernTraits(Species* pSpecies, short kerngenelocn, short nkerntraits, + int resol, bool sexdep) { + trfrKernTraits k; k.meanDist1 = k.meanDist2 = k.probKern1 = 0.0; + if (pGenome != 0) { + if (pSpecies->has1ChromPerTrait()) { + if (sexdep) { + if (nkerntraits == 3) { // twin kernel + k.meanDist1 = (float)pGenome->express(kerngenelocn + 3 * sex, 0, sex); + k.meanDist2 = (float)pGenome->express(kerngenelocn + 3 * sex + 1, 0, sex); + k.probKern1 = (float)pGenome->express(kerngenelocn + 3 * sex + 2, 0, sex); + } + else { + k.meanDist1 = (float)pGenome->express(kerngenelocn + sex, 0, sex); + } } else { - k.meanDist1 = (float)pGenome->express(kerngenelocn+sex,0,sex); + k.meanDist1 = (float)pGenome->express(kerngenelocn, 0, 0); + if (nkerntraits == 3) { // twin kernel + k.meanDist2 = (float)pGenome->express(kerngenelocn + 1, 0, 0); + k.probKern1 = (float)pGenome->express(kerngenelocn + 2, 0, 0); + } } } else { - k.meanDist1 = (float)pGenome->express(kerngenelocn,0,0); - if (nkerntraits == 3) { // twin kernel - k.meanDist2 = (float)pGenome->express(kerngenelocn+1,0,0); - k.probKern1 = (float)pGenome->express(kerngenelocn+2,0,0); - } - } - } - else { - if (sexdep) { - if (nkerntraits == 3) { // twin kernel - k.meanDist1 = (float)pGenome->express(pSpecies,kerngenelocn+3*sex); - k.meanDist2 = (float)pGenome->express(pSpecies,kerngenelocn+3*sex+1); - k.probKern1 = (float)pGenome->express(pSpecies,kerngenelocn+3*sex+2); + if (sexdep) { + if (nkerntraits == 3) { // twin kernel + k.meanDist1 = (float)pGenome->express(pSpecies, kerngenelocn + 3 * sex); + k.meanDist2 = (float)pGenome->express(pSpecies, kerngenelocn + 3 * sex + 1); + k.probKern1 = (float)pGenome->express(pSpecies, kerngenelocn + 3 * sex + 2); + } + else { + k.meanDist1 = (float)pGenome->express(pSpecies, kerngenelocn + sex); + } } else { - k.meanDist1 = (float)pGenome->express(pSpecies,kerngenelocn+sex); - } - } - else { - k.meanDist1 = (float)pGenome->express(pSpecies,kerngenelocn); - if (nkerntraits == 3) { // twin kernel - k.meanDist2 = (float)pGenome->express(pSpecies,kerngenelocn+1); - k.probKern1 = (float)pGenome->express(pSpecies,kerngenelocn+2); + k.meanDist1 = (float)pGenome->express(pSpecies, kerngenelocn); + if (nkerntraits == 3) { // twin kernel + k.meanDist2 = (float)pGenome->express(pSpecies, kerngenelocn + 1); + k.probKern1 = (float)pGenome->express(pSpecies, kerngenelocn + 2); + } } } - } -} -#if RSDEBUG -//DEBUGLOG << "Individual::setKernTraits(): indId=" << indId -// << " k.meanDist1=" << k.meanDist1 << " k.meanDist2=" << k.meanDist2 -// << " k.probKern1=" << k.probKern1 -// << endl; -#endif + } -trfrKernParams kparams; -if (sexdep) { - kparams = pSpecies->getKernParams(0,sex); -} -else { - kparams = pSpecies->getKernParams(0,0); -} -kerntraits = new trfrKernTraits; -kerntraits->meanDist1 = (float)(k.meanDist1*kparams.dist1Scale + kparams.dist1Mean); -kerntraits->meanDist2 = (float)(k.meanDist2*kparams.dist2Scale + kparams.dist2Mean); -kerntraits->probKern1 = (float)(k.probKern1*kparams.PKern1Scale + kparams.PKern1Mean); -#if RSDEBUG -//DEBUGLOG << "Individual::setKernTraits(): indId=" << indId -// << " kerntraits->meanDist1=" << kerntraits->meanDist1 -// << " kerntraits->meanDist2=" << kerntraits->meanDist2 -// << " kerntraits->probKern1=" << kerntraits->probKern1 -// << endl; -#endif -if (!pSpecies->useFullKernel()) { - // kernel mean(s) may not be less than landscape resolution - if (kerntraits->meanDist1 < resol) kerntraits->meanDist1 = (float)resol; - if (kerntraits->meanDist2 < resol) kerntraits->meanDist2 = (float)resol; -} -if (kerntraits->probKern1 < 0.0) kerntraits->probKern1 = 0.0; -if (kerntraits->probKern1 > 1.0) kerntraits->probKern1 = 1.0; -#if RSDEBUG -//DEBUGLOG << "Individual::setKernTraits(): indId=" << indId -// << " kerntraits->meanDist1=" << kerntraits->meanDist1 -// << " kerntraits->meanDist2=" << kerntraits->meanDist2 -// << " kerntraits->probKern1=" << kerntraits->probKern1 -// << endl; -#endif -return; + trfrKernParams kparams; + if (sexdep) { + kparams = pSpecies->getKernParams(0, sex); + } + else { + kparams = pSpecies->getKernParams(0, 0); + } + kerntraits = new trfrKernTraits; + kerntraits->meanDist1 = (float)(k.meanDist1 * kparams.dist1Scale + kparams.dist1Mean); + kerntraits->meanDist2 = (float)(k.meanDist2 * kparams.dist2Scale + kparams.dist2Mean); + kerntraits->probKern1 = (float)(k.probKern1 * kparams.PKern1Scale + kparams.PKern1Mean); + if (!pSpecies->useFullKernel()) { + // kernel mean(s) may not be less than landscape resolution + if (kerntraits->meanDist1 < resol) kerntraits->meanDist1 = (float)resol; + if (kerntraits->meanDist2 < resol) kerntraits->meanDist2 = (float)resol; + } + if (kerntraits->probKern1 < 0.0) kerntraits->probKern1 = 0.0; + if (kerntraits->probKern1 > 1.0) kerntraits->probKern1 = 1.0; + return; } // Get phenotypic emigration traits trfrKernTraits Individual::getKernTraits(void) { -#if RSDEBUG -//DEBUGLOG << "Individual::getKernTraits(): indId=" << indId -// << endl; -#endif -trfrKernTraits k; k.meanDist1 = k.meanDist2 = k.probKern1 = 0.0; -if (kerntraits != 0) { - k.meanDist1 = kerntraits->meanDist1; - k.meanDist2 = kerntraits->meanDist2; - k.probKern1 = kerntraits->probKern1; -} -#if RSDEBUG -//DEBUGLOG << "Individual::getKernTraits(): indId=" << indId -// << " k.meanDist1=" << k.meanDist1 << " k.meanDist2=" << k.meanDist1 -// << " k.probKern1=" << k.probKern1 -// << endl; -#endif - -return k; + trfrKernTraits k; k.meanDist1 = k.meanDist2 = k.probKern1 = 0.0; + if (kerntraits != 0) { + k.meanDist1 = kerntraits->meanDist1; + k.meanDist2 = kerntraits->meanDist2; + k.probKern1 = kerntraits->probKern1; + } + return k; } // Set phenotypic transfer by SMS traits -void Individual::setSMSTraits(Species *pSpecies,short SMSgenelocn,short nSMStraits, - bool sexdep) { -#if RSDEBUG -//DEBUGLOG << "Individual::setSMSTraits(): indId=" << indId -// << " SMSgenelocn=" << SMSgenelocn << " nSMStraits=" << nSMStraits << " sexdep=" << sexdep -// << endl; -#endif -trfrSMSTraits s = pSpecies->getSMSTraits(); -double dp,gb,alphaDB,betaDB; -dp = gb = alphaDB = betaDB = 0.0; -if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - dp = pGenome->express(SMSgenelocn,0,0); - gb = pGenome->express(SMSgenelocn+1,0,0); - if (nSMStraits == 4) { - alphaDB = pGenome->express(SMSgenelocn+2,0,0); - betaDB = pGenome->express(SMSgenelocn+3,0,0); +void Individual::setSMSTraits(Species* pSpecies, short SMSgenelocn, short nSMStraits, + bool sexdep) { + trfrSMSTraits s = pSpecies->getSMSTraits(); + double dp, gb, alphaDB, betaDB; + dp = gb = alphaDB = betaDB = 0.0; + if (pGenome != 0) { + if (pSpecies->has1ChromPerTrait()) { + if (sexdep) { + dp = pGenome->express(SMSgenelocn, 0, 0); + gb = pGenome->express(SMSgenelocn + 1, 0, 0); + if (nSMStraits == 4) { + alphaDB = pGenome->express(SMSgenelocn + 2, 0, 0); + betaDB = pGenome->express(SMSgenelocn + 3, 0, 0); + } + } + else { + dp = pGenome->express(SMSgenelocn, 0, 0); + gb = pGenome->express(SMSgenelocn + 1, 0, 0); + if (nSMStraits == 4) { + alphaDB = pGenome->express(SMSgenelocn + 2, 0, 0); + betaDB = pGenome->express(SMSgenelocn + 3, 0, 0); + } } } else { - dp = pGenome->express(SMSgenelocn,0,0); - gb = pGenome->express(SMSgenelocn+1,0,0); - if (nSMStraits == 4) { - alphaDB = pGenome->express(SMSgenelocn+2,0,0); - betaDB = pGenome->express(SMSgenelocn+3,0,0); + if (sexdep) { + dp = pGenome->express(pSpecies, SMSgenelocn); + gb = pGenome->express(pSpecies, SMSgenelocn + 1); + if (nSMStraits == 4) { + alphaDB = pGenome->express(pSpecies, SMSgenelocn + 2); + betaDB = pGenome->express(pSpecies, SMSgenelocn + 3); + } + } + else { + dp = pGenome->express(pSpecies, SMSgenelocn); + gb = pGenome->express(pSpecies, SMSgenelocn + 1); + if (nSMStraits == 4) { + alphaDB = pGenome->express(pSpecies, SMSgenelocn + 2); + betaDB = pGenome->express(pSpecies, SMSgenelocn + 3); + } } } } + trfrSMSParams smsparams; + if (sexdep) { + smsparams = pSpecies->getSMSParams(0, 0); + } else { - if (sexdep) { - dp = pGenome->express(pSpecies,SMSgenelocn); - gb = pGenome->express(pSpecies,SMSgenelocn+1); - if (nSMStraits == 4) { - alphaDB = pGenome->express(pSpecies,SMSgenelocn+2); - betaDB = pGenome->express(pSpecies,SMSgenelocn+3); - } - } - else { - dp = pGenome->express(pSpecies,SMSgenelocn); - gb = pGenome->express(pSpecies,SMSgenelocn+1); - if (nSMStraits == 4) { - alphaDB = pGenome->express(pSpecies,SMSgenelocn+2); - betaDB = pGenome->express(pSpecies,SMSgenelocn+3); - } - } + smsparams = pSpecies->getSMSParams(0, 0); } -} -#if RSDEBUG -//DEBUGLOG << "Individual::setSMSTraits(): indId=" << indId -// << " dp=" << dp << " gb=" << gb -// << " alphaDB=" << alphaDB << " betaDB=" << betaDB -// << endl; -#endif - -trfrSMSParams smsparams; -if (sexdep) { - smsparams = pSpecies->getSMSParams(0,0); -} -else { - smsparams = pSpecies->getSMSParams(0,0); -} -smsData->dp = (float)(dp*smsparams.dpScale + smsparams.dpMean); -smsData->gb = (float)(gb*smsparams.gbScale + smsparams.gbMean); -if (s.goalType == 2) { - smsData->alphaDB = (float)(alphaDB*smsparams.alphaDBScale + smsparams.alphaDBMean); - smsData->betaDB = (int)(betaDB*smsparams.betaDBScale + smsparams.betaDBMean + 0.5); -} -else { - smsData->alphaDB = s.alphaDB; - smsData->betaDB = s.betaDB; -} -#if RSDEBUG -//DEBUGLOG << "Individual::setSMSTraits() 1111: indId=" << indId -// << " smsData->dp=" << smsData->dp << " smsData->gb=" << smsData->gb -// << " smsData->alphaDB=" << smsData->alphaDB << " smsData->betaDB=" << smsData->betaDB -// << endl; -#endif -if (smsData->dp < 1.0) smsData->dp = 1.0; -if (smsData->gb < 1.0) smsData->gb = 1.0; -if (smsData->alphaDB <= 0.0) smsData->alphaDB = 0.000001f; -if (smsData->betaDB < 1) smsData->betaDB = 1; -#if RSDEBUG -//DEBUGLOG << "Individual::setSMSTraits() 2222: indId=" << indId -// << " smsData->dp=" << smsData->dp << " smsData->gb=" << smsData->gb -// << " smsData->alphaDB=" << smsData->alphaDB << " smsData->betaDB=" << smsData->betaDB -// << endl; -#endif -return; + smsData->dp = (float)(dp * smsparams.dpScale + smsparams.dpMean); + smsData->gb = (float)(gb * smsparams.gbScale + smsparams.gbMean); + if (s.goalType == 2) { + smsData->alphaDB = (float)(alphaDB * smsparams.alphaDBScale + smsparams.alphaDBMean); + smsData->betaDB = (int)(betaDB * smsparams.betaDBScale + smsparams.betaDBMean + 0.5); + } + else { + smsData->alphaDB = s.alphaDB; + smsData->betaDB = s.betaDB; + } + if (smsData->dp < 1.0) smsData->dp = 1.0; + if (smsData->gb < 1.0) smsData->gb = 1.0; + if (smsData->alphaDB <= 0.0) smsData->alphaDB = 0.000001f; + if (smsData->betaDB < 1) smsData->betaDB = 1; + return; } // Get phenotypic transfer by SMS traits trfrSMSTraits Individual::getSMSTraits(void) { -#if RSDEBUG -//DEBUGLOG << "Individual::getSMSTraits(): indId=" << indId << " smsData=" << smsData -// << endl; -#endif -trfrSMSTraits s; s.dp = s.gb = s.alphaDB = 1.0; s.betaDB = 1; -if (smsData != 0) { - s.dp = smsData->dp; s.gb = smsData->gb; - s.alphaDB = smsData->alphaDB; s.betaDB = smsData->betaDB; -} -#if RSDEBUG -//DEBUGLOG << "Individual::getSMSTraits(): indId=" << indId -// << " s.dp=" << s.dp << " s.gb=" << s.gb -// << " s.alphaDB=" << s.alphaDB << " s.betaDB=" << s.betaDB -// << endl; -#endif -return s; + trfrSMSTraits s; s.dp = s.gb = s.alphaDB = 1.0; s.betaDB = 1; + if (smsData != 0) { + s.dp = smsData->dp; s.gb = smsData->gb; + s.alphaDB = smsData->alphaDB; s.betaDB = smsData->betaDB; + } + return s; } // Set phenotypic transfer by CRW traits -void Individual::setCRWTraits(Species *pSpecies,short CRWgenelocn,short nCRWtraits, +void Individual::setCRWTraits(Species* pSpecies, short CRWgenelocn, short nCRWtraits, bool sexdep) { -#if RSDEBUG -//DEBUGLOG << "Individual::setCRWTraits(): indId=" << indId -// << " CRWgenelocn=" << CRWgenelocn << " nCRWtraits=" << nCRWtraits << " sexdep=" << sexdep -// << endl; -#endif -trfrCRWTraits c; c.stepLength = c.rho = 0.0; -if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - c.stepLength = (float)pGenome->express(CRWgenelocn+sex,0,sex); - c.rho = (float)pGenome->express(CRWgenelocn+2+sex,0,sex); + trfrCRWTraits c; c.stepLength = c.rho = 0.0; + if (pGenome != 0) { + if (pSpecies->has1ChromPerTrait()) { + if (sexdep) { + c.stepLength = (float)pGenome->express(CRWgenelocn + sex, 0, sex); + c.rho = (float)pGenome->express(CRWgenelocn + 2 + sex, 0, sex); + } + else { + c.stepLength = (float)pGenome->express(CRWgenelocn, 0, 0); + c.rho = (float)pGenome->express(CRWgenelocn + 1, 0, 0); + } } else { - c.stepLength = (float)pGenome->express(CRWgenelocn,0,0); - c.rho = (float)pGenome->express(CRWgenelocn+1,0,0); + if (sexdep) { + c.stepLength = (float)pGenome->express(pSpecies, CRWgenelocn + sex); + c.rho = (float)pGenome->express(pSpecies, CRWgenelocn + 2 + sex); + } + else { + c.stepLength = (float)pGenome->express(pSpecies, CRWgenelocn); + c.rho = (float)pGenome->express(pSpecies, CRWgenelocn + 1); + } } } + + trfrCRWParams cparams; + if (sexdep) { + cparams = pSpecies->getCRWParams(0, sex); + } else { - if (sexdep) { - c.stepLength = (float)pGenome->express(pSpecies,CRWgenelocn+sex); - c.rho = (float)pGenome->express(pSpecies,CRWgenelocn+2+sex); - } - else { - c.stepLength = (float)pGenome->express(pSpecies,CRWgenelocn); - c.rho = (float)pGenome->express(pSpecies,CRWgenelocn+1); - } + cparams = pSpecies->getCRWParams(0, 0); } -} -#if RSDEBUG -//DEBUGLOG << "Individual::setCRWTraits(): indId=" << indId -// << " c.stepLength=" << c.stepLength << " c.rho=" << c.rho -// << endl; -#endif - -trfrCRWParams cparams; -if (sexdep) { - cparams = pSpecies->getCRWParams(0,sex); -} -else { - cparams = pSpecies->getCRWParams(0,0); -} -crw->stepL = (float)(c.stepLength*cparams.stepLScale + cparams.stepLgthMean); -crw->rho = (float)(c.rho*cparams.rhoScale + cparams.rhoMean); -#if RSDEBUG -//DEBUGLOG << "Individual::setCRWTraits(): indId=" << indId -// << " crw->stepL=" << crw->stepL << " crw->rho=" << crw->rho -// << endl; -#endif -if (crw->stepL < 1.0) crw->stepL = 1.0; -if (crw->rho < 0.0) crw->rho = 0.0; -if (crw->rho > 0.999) crw->rho = 0.999f; -#if RSDEBUG -//DEBUGLOG << "Individual::setCRWTraits(): indId=" << indId -// << " crw->stepL=" << crw->stepL << " crw->rho=" << crw->rho -// << endl; -#endif -return; + crw->stepL = (float)(c.stepLength * cparams.stepLScale + cparams.stepLgthMean); + crw->rho = (float)(c.rho * cparams.rhoScale + cparams.rhoMean); + if (crw->stepL < 1.0) crw->stepL = 1.0; + if (crw->rho < 0.0) crw->rho = 0.0; + if (crw->rho > 0.999) crw->rho = 0.999f; + return; } // Get phenotypic transfer by CRW traits trfrCRWTraits Individual::getCRWTraits(void) { -#if RSDEBUG -//DEBUGLOG << "Individual::getCRWTraits(): indId=" << indId -// << endl; -#endif -trfrCRWTraits c; c.stepLength = c.rho = 0.0; -if (crw != 0) { - c.stepLength = crw->stepL; - c.rho = crw->rho; -} -#if RSDEBUG -//DEBUGLOG << "Individual::getCRWTraits(): indId=" << indId -// << " c.stepLength=" << c.stepLength << " c.rho=" << c.rho -// << endl; -#endif - -return c; - + trfrCRWTraits c; c.stepLength = c.rho = 0.0; + if (crw != 0) { + c.stepLength = crw->stepL; + c.rho = crw->rho; + } + return c; } // Set phenotypic settlement traits -void Individual::setSettTraits(Species *pSpecies,short settgenelocn,short nsetttraits, +void Individual::setSettTraits(Species* pSpecies, short settgenelocn, short nsetttraits, bool sexdep) { -#if RSDEBUG -//DEBUGLOG << "Individual::setSettTraits(): indId=" << indId << " sex=" << sex -// << " settgenelocn=" << settgenelocn << " nsetttraits=" << nsetttraits << " sexdep=" << sexdep -// << endl; -#endif -//simParams sim = paramsSim->getSim(); -settleTraits s; s.s0 = s.alpha = s.beta = 0.0; -if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - s.s0 = (float)pGenome->express(settgenelocn+3*sex,0,0); - s.alpha = (float)pGenome->express(settgenelocn+3*sex+1,0,0); - s.beta = (float)pGenome->express(settgenelocn+3*sex+2,0,0); + settleTraits s; s.s0 = s.alpha = s.beta = 0.0; + if (pGenome != 0) { + if (pSpecies->has1ChromPerTrait()) { + if (sexdep) { + s.s0 = (float)pGenome->express(settgenelocn + 3 * sex, 0, 0); + s.alpha = (float)pGenome->express(settgenelocn + 3 * sex + 1, 0, 0); + s.beta = (float)pGenome->express(settgenelocn + 3 * sex + 2, 0, 0); + } + else { + s.s0 = (float)pGenome->express(settgenelocn, 0, 0); + s.alpha = (float)pGenome->express(settgenelocn + 1, 0, 0); + s.beta = (float)pGenome->express(settgenelocn + 2, 0, 0); + } } else { - s.s0 = (float)pGenome->express(settgenelocn,0,0); - s.alpha = (float)pGenome->express(settgenelocn+1,0,0); - s.beta = (float)pGenome->express(settgenelocn+2,0,0); + if (sexdep) { + s.s0 = (float)pGenome->express(pSpecies, settgenelocn + 3 * sex); + s.alpha = (float)pGenome->express(pSpecies, settgenelocn + 3 * sex + 1); + s.beta = (float)pGenome->express(pSpecies, settgenelocn + 3 * sex + 2); + } + else { + s.s0 = (float)pGenome->express(pSpecies, settgenelocn); + s.alpha = (float)pGenome->express(pSpecies, settgenelocn + 1); + s.beta = (float)pGenome->express(pSpecies, settgenelocn + 2); + } + } } - else { - if (sexdep) { - s.s0 = (float)pGenome->express(pSpecies,settgenelocn+3*sex); - s.alpha = (float)pGenome->express(pSpecies,settgenelocn+3*sex+1); - s.beta = (float)pGenome->express(pSpecies,settgenelocn+3*sex+2); - } - else { - s.s0 = (float)pGenome->express(pSpecies,settgenelocn); - s.alpha = (float)pGenome->express(pSpecies,settgenelocn+1); - s.beta = (float)pGenome->express(pSpecies,settgenelocn+2); - } - } -} -#if RSDEBUG -//DEBUGLOG << "Individual::setSettTraits(): indId=" << indId -// << " s.s0=" << s.s0 << " s.alpha=" << s.alpha << " s.beta=" << s.beta -// << endl; -#endif - -settParams sparams; -if (sexdep) { - sparams = pSpecies->getSettParams(0,sex); -} -else { - sparams = pSpecies->getSettParams(0,0); -} -#if RSDEBUG -//DEBUGLOG << "Individual::setSettTraits(): indId=" << indId -// << " sparams.s0Mean=" << sparams.s0Mean << " sparams.s0SD=" << sparams.s0SD -// << " sparams.s0Scale=" << sparams.s0Scale -// << endl; -#endif -setttraits = new settleTraits; -setttraits->s0 = (float)(s.s0*sparams.s0Scale + sparams.s0Mean); -setttraits->alpha = (float)(s.alpha*sparams.alphaSScale + sparams.alphaSMean); -setttraits->beta = (float)(s.beta*sparams.betaSScale + sparams.betaSMean); -#if RSDEBUG -//DEBUGLOG << "Individual::setSettTraits(): indId=" << indId -// << " setttraits->s0=" << setttraits->s0 -// << " setttraits->alpha=" << setttraits->alpha << " setttraits->beta=" << setttraits->beta -// << endl; -#endif -if (setttraits->s0 < 0.0) setttraits->s0 = 0.0; -if (setttraits->s0 > 1.0) setttraits->s0 = 1.0; -#if RSDEBUG -//DEBUGLOG << "Individual::setSettTraits(): indId=" << indId -// << " setttraits->s0=" << setttraits->s0 -// << " setttraits->alpha=" << setttraits->alpha << " setttraits->beta=" << setttraits->beta -// << endl; -#endif -return; + settParams sparams; + if (sexdep) { + sparams = pSpecies->getSettParams(0, sex); + } + else { + sparams = pSpecies->getSettParams(0, 0); + } + setttraits = new settleTraits; + setttraits->s0 = (float)(s.s0 * sparams.s0Scale + sparams.s0Mean); + setttraits->alpha = (float)(s.alpha * sparams.alphaSScale + sparams.alphaSMean); + setttraits->beta = (float)(s.beta * sparams.betaSScale + sparams.betaSMean); + if (setttraits->s0 < 0.0) setttraits->s0 = 0.0; + if (setttraits->s0 > 1.0) setttraits->s0 = 1.0; + return; } // Get phenotypic settlement traits settleTraits Individual::getSettTraits(void) { -#if RSDEBUG -//DEBUGLOG << "Individual::getSettTraits(): indId=" << indId -// << endl; -#endif -settleTraits s; s.s0 = s.alpha = s.beta = 0.0; -if (setttraits != 0) { - s.s0 = setttraits->s0; - s.alpha = setttraits->alpha; - s.beta = setttraits->beta; -} -#if RSDEBUG -//DEBUGLOG << "Individual::getSettTraits(): indId=" << indId -// << " s.s0=" << s.s0 << " s.alpha=" << s.alpha << " s.beta=" << s.beta -// << endl; -#endif + settleTraits s; s.s0 = s.alpha = s.beta = 0.0; + if (setttraits != 0) { + s.s0 = setttraits->s0; + s.alpha = setttraits->alpha; + s.beta = setttraits->beta; + } -return s; + return s; } -/* -locus Individual::getAlleles(int g) { -locus l; l.allele[0] = l.allele[1] = 0.0; -if (pGenome != 0) l = pGenome->getAlleles(g); -return l; -} -*/ void Individual::setStatus(short s) { -if (s >= 0 && s <= 9) status = s; -status = s; + if (s >= 0 && s <= 9) status = s; + status = s; } void Individual::developing(void) { -isDeveloping = true; + isDeveloping = true; } void Individual::develop(void) { -stage++; isDeveloping = false; + stage++; isDeveloping = false; } void Individual::ageIncrement(short maxage) { -if (status < 6) { // alive - age++; - if (age > maxage) status = 9; // exceeds max. age - dies - else { - if (path != 0) path->year = 0; // reset annual step count for movement models - if (status == 3) // waiting to continue dispersal - status = 1; + if (status < 6) { // alive + age++; + if (age > maxage) status = 9; // exceeds max. age - dies + else { + if (path != 0) path->year = 0; // reset annual step count for movement models + if (status == 3) // waiting to continue dispersal + status = 1; + } } } -} void Individual::incFallow(void) { fallow++; } @@ -1123,551 +847,406 @@ void Individual::resetFallow(void) { fallow = 0; } //--------------------------------------------------------------------------- // Move to a specified neighbouring cell -void Individual::moveto(Cell *newCell) { -// check that location is indeed a neighbour of the current cell -locn currloc = pCurrCell->getLocn(); -locn newloc = newCell->getLocn(); -double d = sqrt(((double)currloc.x-(double)newloc.x)*((double)currloc.x-(double)newloc.x) - + ((double)currloc.y-(double)newloc.y)*((double)currloc.y-(double)newloc.y)); -if (d >= 1.0 && d < 1.5) { // ok - pCurrCell = newCell; status = 5; -} +void Individual::moveto(Cell* newCell) { + // check that location is indeed a neighbour of the current cell + locn currloc = pCurrCell->getLocn(); + locn newloc = newCell->getLocn(); + double d = sqrt(((double)currloc.x - (double)newloc.x) * ((double)currloc.x - (double)newloc.x) + + ((double)currloc.y - (double)newloc.y) * ((double)currloc.y - (double)newloc.y)); + if (d >= 1.0 && d < 1.5) { // ok + pCurrCell = newCell; status = 5; + } } //--------------------------------------------------------------------------- // Move to a new cell by sampling a dispersal distance from a single or double // negative exponential kernel // Returns 1 if still dispersing (including having found a potential patch), otherwise 0 -int Individual::moveKernel(Landscape *pLandscape,Species *pSpecies, - const short repType,const bool absorbing) +int Individual::moveKernel(Landscape* pLandscape, Species* pSpecies, + const short repType, const bool absorbing) { -intptr patch; -int patchNum = 0; -int newX = 0,newY = 0; -int dispersing = 1; -double xrand,yrand,meandist,dist,r1,rndangle,nx,ny; -float localK; -trfrKernTraits kern; -Cell* pCell; -Patch* pPatch; -locn loc = pCurrCell->getLocn(); - -landData land = pLandscape->getLandData(); - -bool usefullkernel = pSpecies->useFullKernel(); -trfrRules trfr = pSpecies->getTrfr(); -settleRules sett = pSpecies->getSettRules(stage,sex); - -pCell = NULL; -pPatch = NULL; - -if (trfr.indVar) { // get individual's kernel parameters - kern.meanDist1 = kern.meanDist2 = kern.probKern1 = 0.0; -// kparams = pSpecies->getKernParams(stage,sex); - if (pGenome != 0) { - kern.meanDist1 = kerntraits->meanDist1; - if (trfr.twinKern) - { - kern.meanDist2 = kerntraits->meanDist2; - kern.probKern1 = kerntraits->probKern1; - } - } -} -else { // get kernel parameters for the species - if (trfr.sexDep) { - if (trfr.stgDep) { - kern = pSpecies->getKernTraits(stage,sex); - } - else { - kern = pSpecies->getKernTraits(0,sex); + intptr patch; + int patchNum = 0; + int newX = 0, newY = 0; + int dispersing = 1; + double xrand, yrand, meandist, dist, r1, rndangle, nx, ny; + float localK; + trfrKernTraits kern; + Cell* pCell; + Patch* pPatch; + locn loc = pCurrCell->getLocn(); + + landData land = pLandscape->getLandData(); + + bool usefullkernel = pSpecies->useFullKernel(); + trfrRules trfr = pSpecies->getTrfr(); + settleRules sett = pSpecies->getSettRules(stage, sex); + + pCell = NULL; + pPatch = NULL; + + if (trfr.indVar) { // get individual's kernel parameters + kern.meanDist1 = kern.meanDist2 = kern.probKern1 = 0.0; + if (pGenome != 0) { + kern.meanDist1 = kerntraits->meanDist1; + if (trfr.twinKern) + { + kern.meanDist2 = kerntraits->meanDist2; + kern.probKern1 = kerntraits->probKern1; + } } } - else { - if (trfr.stgDep) { - kern = pSpecies->getKernTraits(stage,0); + else { // get kernel parameters for the species + if (trfr.sexDep) { + if (trfr.stgDep) { + kern = pSpecies->getKernTraits(stage, sex); + } + else { + kern = pSpecies->getKernTraits(0, sex); + } } else { - kern = pSpecies->getKernTraits(0,0); + if (trfr.stgDep) { + kern = pSpecies->getKernTraits(stage, 0); + } + else { + kern = pSpecies->getKernTraits(0, 0); + } } } -} -#if RSDEBUG -//Patch *startPatch = (Patch*)startpatch; -//DEBUGLOG << "Individual::moveKernel(): indId=" << indId << " x=" << loc.x << " y=" << loc.y -//// << " natalPatch = " << natalPatch -//// << " startpatch = " << startpatch << " patchNum = " << startPatch->getPatchNum() -// << " kern.meanDist1=" << kern.meanDist1; -//if (trfr.twinKern) { -// DEBUGLOG << " meanDist2=" << kern.meanDist2 << " probKern1=" << kern.probKern1; -//} -//DEBUGLOG << endl; -#endif -// scale the appropriate kernel mean to the cell size -if (trfr.twinKern) -{ - if (pRandom->Bernoulli(kern.probKern1)) - meandist = kern.meanDist1 / (float)land.resol; + // scale the appropriate kernel mean to the cell size + if (trfr.twinKern) + { + if (pRandom->Bernoulli(kern.probKern1)) + meandist = kern.meanDist1 / (float)land.resol; + else + meandist = kern.meanDist2 / (float)land.resol; + } else - meandist = kern.meanDist2 / (float)land.resol; -} -else - meandist = kern.meanDist1 / (float)land.resol; -#if RSDEBUG -//DEBUGLOG << "Individual::moveKernel(): indId=" << indId << " meandist=" << meandist << endl; -#endif -// scaled mean may not be less than 1 unless emigration derives from the kernel -// (i.e. the 'use full kernel' option is applied) -if (!usefullkernel && meandist < 1.0) meandist = 1.0; -#if RSDEBUG -//DEBUGLOG << "Individual::moveKernel(): indId=" << indId << " meandist=" << meandist << endl; -#endif + meandist = kern.meanDist1 / (float)land.resol; -#if RSDEBUG -//Patch *startPatch = (Patch*)startpatch; -//DEBUGLOG << "Individual::moveKernel(): indId = " << indId << " x = " << x << " y = " << y -// << " natalPatch = " << natalPatch -//// << " startpatch = " << startpatch << " patchNum = " << startPatch->getPatchNum() -// << " meanDist1 = " << kern.meanDist1; -//if (trfr.twinKern) { -// DEBUGLOG << " probKern1 = " << kern.probKern1 << " meanDist2 = " << kern.meanDist2; -//} -//DEBUGLOG << " meandist = " << meandist << endl; -#endif + // scaled mean may not be less than 1 unless emigration derives from the kernel + // (i.e. the 'use full kernel' option is applied) + if (!usefullkernel && meandist < 1.0) meandist = 1.0; -int loopsteps = 0; // new counter to prevent infinite loop added 14/8/15 -do { + int loopsteps = 0; // new counter to prevent infinite loop added 14/8/15 do { do { - // randomise the cell within the patch, provided that the individual is still in - // its natal cell (i.e. not waiting in the matrix) - // this is because, if the patch is very large, the individual is near the centre - // and the (single) kernel mean is (not much more than) the cell size, an infinite - // loop could otherwise result, as the individual never reaches the patch edge - // (in a cell-based model, this has no effect, other than as a processing overhead) - if (status == 1) { - pCell = pNatalPatch->getRandomCell(); - if (pCell != 0) { - loc = pCell->getLocn(); + do { + // randomise the cell within the patch, provided that the individual is still in + // its natal cell (i.e. not waiting in the matrix) + // this is because, if the patch is very large, the individual is near the centre + // and the (single) kernel mean is (not much more than) the cell size, an infinite + // loop could otherwise result, as the individual never reaches the patch edge + // (in a cell-based model, this has no effect, other than as a processing overhead) + if (status == 1) { + pCell = pNatalPatch->getRandomCell(); + if (pCell != 0) { + loc = pCell->getLocn(); + } } - } - // randomise the position of the individual inside the cell - xrand = (double)loc.x + pRandom->Random()*0.999; - yrand = (double)loc.y + pRandom->Random()*0.999; - - r1 = 0.0000001 + pRandom->Random()*(1.0-0.0000001); -// dist = (-1.0*meandist)*std::log(r1); - dist = (-1.0*meandist)*log(r1); // for LINUX_CLUSTER - - rndangle = pRandom->Random() * 2.0 * PI; - nx = xrand + dist * sin(rndangle); - ny = yrand + dist * cos(rndangle); - if (nx < 0.0) newX = -1; else newX = (int)nx; - if (ny < 0.0) newY = -1; else newY = (int)ny; -#if RSDEBUG - if (path != 0) (path->year)++; -#endif - loopsteps++; + // randomise the position of the individual inside the cell + xrand = (double)loc.x + pRandom->Random() * 0.999; + yrand = (double)loc.y + pRandom->Random() * 0.999; + + r1 = 0.0000001 + pRandom->Random() * (1.0 - 0.0000001); + // dist = (-1.0*meandist)*std::log(r1); + dist = (-1.0 * meandist) * log(r1); // for LINUX_CLUSTER + + rndangle = pRandom->Random() * 2.0 * PI; + nx = xrand + dist * sin(rndangle); + ny = yrand + dist * cos(rndangle); + if (nx < 0.0) newX = -1; else newX = (int)nx; + if (ny < 0.0) newY = -1; else newY = (int)ny; #if RSDEBUG -//DEBUGLOG << "Individual::moveKernel(): indId=" << indId << " status=" << status -// << " loopsteps=" << loopsteps << " newX=" << newX << " newY=" << newY -// << " loc.x=" << loc.x << " loc.y=" << loc.y -// << endl; + if (path != 0) (path->year)++; #endif - } while (loopsteps < 1000 && + loopsteps++; + } while (loopsteps < 1000 && ((!absorbing && (newX < land.minX || newX > land.maxX - || newY < land.minY || newY > land.maxY)) - || (!usefullkernel && newX == loc.x && newY == loc.y)) + || newY < land.minY || newY > land.maxY)) + || (!usefullkernel && newX == loc.x && newY == loc.y)) ); - if (loopsteps < 1000) { - if (newX < land.minX || newX > land.maxX + if (loopsteps < 1000) { + if (newX < land.minX || newX > land.maxX || newY < land.minY || newY > land.maxY) { // beyond absorbing boundary - pCell = 0; - patch = 0; - patchNum = -1; - } - else { - pCell = pLandscape->findCell(newX,newY); - if (pCell == 0) { // no-data cell + pCell = 0; patch = 0; patchNum = -1; } else { - patch = pCell->getPatch(); - if (patch == 0) { // matrix - pPatch = 0; - patchNum = 0; + pCell = pLandscape->findCell(newX, newY); + if (pCell == 0) { // no-data cell + patch = 0; + patchNum = -1; } else { - pPatch = (Patch*)patch; - patchNum = pPatch->getPatchNum(); + patch = pCell->getPatch(); + if (patch == 0) { // matrix + pPatch = 0; + patchNum = 0; + } + else { + pPatch = (Patch*)patch; + patchNum = pPatch->getPatchNum(); + } } } } - } - else { - patch = 0; - patchNum = -1; - } -#if RSDEBUG -//DEBUGLOG << "Individual::moveKernel(): indId=" << indId << " status=" << status -// << " loopsteps=" << loopsteps << " newX=" << newX << " newY=" << newY -// << " pCell=" << pCell << " patch=" << patch << " patchNum=" << patchNum -// << endl; -#endif - } while (!absorbing && patchNum < 0 && loopsteps < 1000); // in a no-data region -} -while (!usefullkernel && pPatch == pNatalPatch && loopsteps < 1000); // still in the original (natal) patch + else { + patch = 0; + patchNum = -1; + } + } while (!absorbing && patchNum < 0 && loopsteps < 1000); // in a no-data region + } while (!usefullkernel && pPatch == pNatalPatch && loopsteps < 1000); // still in the original (natal) patch -if (loopsteps < 1000) { - if (pCell == 0) { // beyond absorbing boundary or in no-data cell - pCurrCell = 0; - status = 6; - dispersing = 0; - } - else { - pCurrCell = pCell; - if (pPatch == 0) localK = 0.0; // matrix - else localK = pPatch->getK(); - if (patchNum > 0 && localK > 0.0) { // found a new patch - status = 2; // record as potential settler + if (loopsteps < 1000) { + if (pCell == 0) { // beyond absorbing boundary or in no-data cell + pCurrCell = 0; + status = 6; + dispersing = 0; } else { - dispersing = 0; - // can wait in matrix if population is stage structured ... - if (pSpecies->stageStructured()) { - // ... and wait option is applied ... - if (sett.wait) { // ... it is - status = 3; // waiting + pCurrCell = pCell; + if (pPatch == 0) localK = 0.0; // matrix + else localK = pPatch->getK(); + if (patchNum > 0 && localK > 0.0) { // found a new patch + status = 2; // record as potential settler + } + else { + dispersing = 0; + // can wait in matrix if population is stage structured ... + if (pSpecies->stageStructured()) { + // ... and wait option is applied ... + if (sett.wait) { // ... it is + status = 3; // waiting + } + else // ... it is not + status = 6; // dies (unless there is a suitable neighbouring cell) } - else // ... it is not + else status = 6; // dies (unless there is a suitable neighbouring cell) } - else - status = 6; // dies (unless there is a suitable neighbouring cell) } } -} -else { - status = 6; - dispersing = 0; -} -#if RSDEBUG -//DEBUGLOG << "Individual::moveKernel(): indId=" << indId -// << " newX=" << newX << " newY=" << newY -// << " patch=" << patch -// << " patchNum=" << patchNum << " status=" << status; -//DEBUGLOG << endl; -#endif - -// apply dispersal-related mortality, which may be distance-dependent -dist *= (float)land.resol; // re-scale distance moved to landscape scale -if (status < 7) { - double dispmort; - trfrMortParams mort = pSpecies->getMortParams(); - if (trfr.distMort) { - dispmort = 1.0 / (1.0 + exp(-(dist - mort.mortBeta)*mort.mortAlpha)); - } else { - dispmort = mort.fixedMort; - } - if (pRandom->Bernoulli(dispmort)) { - status = 7; // dies + status = 6; dispersing = 0; } -} -return dispersing; + // apply dispersal-related mortality, which may be distance-dependent + dist *= (float)land.resol; // re-scale distance moved to landscape scale + if (status < 7) { + double dispmort; + trfrMortParams mort = pSpecies->getMortParams(); + if (trfr.distMort) { + dispmort = 1.0 / (1.0 + exp(-(dist - mort.mortBeta) * mort.mortAlpha)); + } + else { + dispmort = mort.fixedMort; + } + if (pRandom->Bernoulli(dispmort)) { + status = 7; // dies + dispersing = 0; + } + } + + return dispersing; } //--------------------------------------------------------------------------- // Make a single movement step according to a mechanistic movement model // Returns 1 if still dispersing (including having found a potential patch), otherwise 0 -int Individual::moveStep(Landscape *pLandscape,Species *pSpecies, - const short landIx,const bool absorbing) +int Individual::moveStep(Landscape* pLandscape, Species* pSpecies, + const short landIx, const bool absorbing) { -if (status != 1) return 0; // not currently dispersing - -intptr patch; -int patchNum; -int newX,newY; -locn loc; -int dispersing = 1; -double xcnew,ycnew; -double angle; -double mortprob,rho,steplen; -movedata move; -Patch* pPatch = 0; -bool absorbed = false; -//int popsize; - -landData land = pLandscape->getLandData(); -simParams sim = paramsSim->getSim(); - -trfrRules trfr = pSpecies->getTrfr(); -trfrCRWTraits movt = pSpecies->getCRWTraits(); -settleSteps settsteps = pSpecies->getSteps(stage,sex); - -patch = pCurrCell->getPatch(); -#if RSDEBUG -//DEBUGLOG << "Individual::moveStep() AAAA: indId=" << indId -// << " pCurrCell=" << pCurrCell << " patch=" << patch -// << endl; -#endif + if (status != 1) return 0; // not currently dispersing + + intptr patch; + int patchNum; + int newX, newY; + locn loc; + int dispersing = 1; + double xcnew, ycnew; + double angle; + double mortprob, rho, steplen; + movedata move; + Patch* pPatch = 0; + bool absorbed = false; + + landData land = pLandscape->getLandData(); + simParams sim = paramsSim->getSim(); + + trfrRules trfr = pSpecies->getTrfr(); + trfrCRWTraits movt = pSpecies->getCRWTraits(); + settleSteps settsteps = pSpecies->getSteps(stage, sex); + + patch = pCurrCell->getPatch(); -if (patch == 0) { // matrix - pPatch = 0; - patchNum = 0; -} -else { - pPatch = (Patch*)patch; - patchNum = pPatch->getPatchNum(); -} -// apply step-dependent mortality risk ... -if (trfr.habMort) -{ // habitat-dependent - int h = pCurrCell->getHabIndex(landIx); - if (h < 0) { // no-data cell - should not occur, but if it does, individual dies - mortprob = 1.0; - } - else mortprob = pSpecies->getHabMort(h); -#if RSDEBUG -//locn temploc = pCurrCell->getLocn(); -//DEBUGLOG << "Individual::moveStep(): x=" << temploc.x << " y=" << temploc.x -// << " landIx=" << landIx << " h=" << h << " mortprob=" << mortprob -// << endl; -#endif -} -else mortprob = movt.stepMort; -// ... unless individual has not yet left natal patch in emigration year -if (pPatch == pNatalPatch && path->out == 0 && path->year == path->total) { - mortprob = 0.0; -} -#if RSDEBUG -locn loc0,loc1,loc2; -//loc0 = pCurrCell->getLocn(); -//DEBUGLOG << "Individual::moveStep() BBBB: indId=" << indId << " status=" << status -// << " path->year=" << path->year << " path->out=" << path->out -// << " settleStatus=" << path->settleStatus -// << " x=" << loc0.x << " y=" << loc0.y -//// << " patch=" << patch -// << " pPatch=" << pPatch -// << " patchNum=" << patchNum; -//// << " natalPatch=" << natalPatch; -////if (crw != 0) { -//// DEBUGLOG << " xc=" << crw->xc << " yc=" << crw->yc; -//// DEBUGLOG << " rho=" << movt.rho << " stepLength=" << movt.stepLength; -////} -//DEBUGLOG << endl; -#endif -if (pRandom->Bernoulli(mortprob)) { // individual dies - status = 7; - dispersing = 0; -} -else { // take a step - (path->year)++; - (path->total)++; -// if (pPatch != pNatalPatch || path->out > 0) (path->out)++; - if (patch == 0 || pPatch == 0 || patchNum == 0) { // not in a patch - if (path != 0) path->settleStatus = 0; // reset path settlement status - (path->out)++; + if (patch == 0) { // matrix + pPatch = 0; + patchNum = 0; } - loc = pCurrCell->getLocn(); - newX = loc.x; newY = loc.y; - - - switch (trfr.moveType) { - - case 1: // SMS -#if RSDEBUG -//loc1 = pCurrCell->getLocn(); -//DEBUGLOG << "Individual::moveStep() FFFF: indId=" << indId << " status=" << status -//// << " path->year=" << path->year -// << " path->season=" << path->season -// << " x=" << loc1.x << " y=" << loc1.y -// << " smsData->goalType=" << smsData->goalType -// << " goal.x=" << smsData->goal.x -// << " goal.y=" << smsData->goal.y -// << endl; -#endif - move = smsMove(pLandscape,pSpecies,landIx,pPatch==pNatalPatch,trfr.indVar,absorbing); -#if RSDEBUG -//DEBUGLOG << "Individual::moveStep() GGGG: indId=" << indId << " status=" << status -// << " move.dist=" << move.dist -// << endl; -#endif - if (move.dist < 0.0) { - // either INTERNAL ERROR CONDITION - INDIVIDUAL IS IN NO-DATA SQUARE - // or individual has crossed absorbing boundary ... - // ... individual dies - status = 6; - dispersing = 0; + else { + pPatch = (Patch*)patch; + patchNum = pPatch->getPatchNum(); + } + // apply step-dependent mortality risk ... + if (trfr.habMort) + { // habitat-dependent + int h = pCurrCell->getHabIndex(landIx); + if (h < 0) { // no-data cell - should not occur, but if it does, individual dies + mortprob = 1.0; + } + else mortprob = pSpecies->getHabMort(h); + } + else mortprob = movt.stepMort; + // ... unless individual has not yet left natal patch in emigration year + if (pPatch == pNatalPatch && path->out == 0 && path->year == path->total) { + mortprob = 0.0; + } + if (pRandom->Bernoulli(mortprob)) { // individual dies + status = 7; + dispersing = 0; + } + else { // take a step + (path->year)++; + (path->total)++; + if (patch == 0 || pPatch == 0 || patchNum == 0) { // not in a patch + if (path != 0) path->settleStatus = 0; // reset path settlement status + (path->out)++; } - else { -#if RSDEBUG -//loc1 = pCurrCell->getLocn(); -//DEBUGLOG << "Individual::moveStep() HHHH: indId=" << indId << " status=" << status -// << " path->year=" << path->year -// << " x=" << loc1.x << " y=" << loc1.y -//// << " smsData = " << smsData -// << endl; -#endif + loc = pCurrCell->getLocn(); + newX = loc.x; newY = loc.y; + - // WOULD IT BE MORE EFFICIENT FOR smsMove TO RETURN A POINTER TO THE NEW CELL? ... + switch (trfr.moveType) { - patch = pCurrCell->getPatch(); - //int patchnum; - if (patch == 0) { - pPatch = 0; - //patchnum = 0; + case 1: // SMS + move = smsMove(pLandscape, pSpecies, landIx, pPatch == pNatalPatch, trfr.indVar, absorbing); + if (move.dist < 0.0) { + // either INTERNAL ERROR CONDITION - INDIVIDUAL IS IN NO-DATA SQUARE + // or individual has crossed absorbing boundary ... + // ... individual dies + status = 6; + dispersing = 0; } else { - pPatch = (Patch*)patch; - //patchnum = pPatch->getPatchNum(); - } - if (sim.saveVisits && pPatch != pNatalPatch) { - pCurrCell->incrVisits(); + + // WOULD IT BE MORE EFFICIENT FOR smsMove TO RETURN A POINTER TO THE NEW CELL? ... + + patch = pCurrCell->getPatch(); + if (patch == 0) { + pPatch = 0; + } + else { + pPatch = (Patch*)patch; + } + if (sim.saveVisits && pPatch != pNatalPatch) { + pCurrCell->incrVisits(); + } } - } - break; + break; - case 2: // CRW - if (trfr.indVar) { - if (crw != 0) { - movt.stepLength = crw->stepL; - movt.rho = crw->rho; + case 2: // CRW + if (trfr.indVar) { + if (crw != 0) { + movt.stepLength = crw->stepL; + movt.rho = crw->rho; + } } - } - steplen = movt.stepLength; if (steplen < 0.2*land.resol) steplen = 0.2*land.resol; - rho = movt.rho; if (rho > 0.99) rho = 0.99; - if (pPatch == pNatalPatch) { - rho = 0.99; // to promote leaving natal patch - path->out = 0; - } - if (movt.straigtenPath && path->settleStatus > 0) { - // individual is in a patch and has already determined whether to settle - rho = 0.99; // to promote leaving the patch - path->out = 0; - } - int loopsteps = 0; // new counter to prevent infinite loop added 14/8/15 - do { + steplen = movt.stepLength; if (steplen < 0.2 * land.resol) steplen = 0.2 * land.resol; + rho = movt.rho; if (rho > 0.99) rho = 0.99; + if (pPatch == pNatalPatch) { + rho = 0.99; // to promote leaving natal patch + path->out = 0; + } + if (movt.straigtenPath && path->settleStatus > 0) { + // individual is in a patch and has already determined whether to settle + rho = 0.99; // to promote leaving the patch + path->out = 0; + } + int loopsteps = 0; // new counter to prevent infinite loop added 14/8/15 do { - // new direction - if (newX < land.minX || newX > land.maxX || newY < land.minY || newY > land.maxY - || pCurrCell == 0) { - // individual has tried to go out-of-bounds or into no-data area - // allow random move to prevent repeated similar move - angle = wrpcauchy(crw->prevdrn,0.0); + do { + // new direction + if (newX < land.minX || newX > land.maxX || newY < land.minY || newY > land.maxY + || pCurrCell == 0) { + // individual has tried to go out-of-bounds or into no-data area + // allow random move to prevent repeated similar move + angle = wrpcauchy(crw->prevdrn, 0.0); + } + else + angle = wrpcauchy(crw->prevdrn, rho); + // new continuous cell coordinates + xcnew = crw->xc + sin(angle) * steplen / (float)land.resol; + ycnew = crw->yc + cos(angle) * steplen / (float)land.resol; + if (xcnew < 0.0) newX = -1; else newX = (int)xcnew; + if (ycnew < 0.0) newY = -1; else newY = (int)ycnew; + loopsteps++; + } while (!absorbing && loopsteps < 1000 && + (newX < land.minX || newX > land.maxX || newY < land.minY || newY > land.maxY)); + if (newX < land.minX || newX > land.maxX || newY < land.minY || newY > land.maxY) + pCurrCell = 0; + else + pCurrCell = pLandscape->findCell(newX, newY); + if (pCurrCell == 0) { // no-data cell or beyond absorbing boundary + patch = 0; + if (absorbing) absorbed = true; } else - angle = wrpcauchy(crw->prevdrn,rho); - // new continuous cell coordinates - xcnew = crw->xc + sin(angle) * steplen/(float)land.resol; - ycnew = crw->yc + cos(angle) * steplen/(float)land.resol; - if (xcnew < 0.0) newX = -1; else newX = (int)xcnew; - if (ycnew < 0.0) newY = -1; else newY = (int)ycnew; - loopsteps++; -#if RSDEBUG -//DEBUGLOG << "Individual::moveStep(): indId=" << indId -// << " xc=" << crw->xc << " yc=" << crw->yc << " pCurrCell=" << pCurrCell -// << " steps=" << path->year << " loopsteps=" << loopsteps -// << " steplen=" << steplen << " rho=" << rho << " angle=" << angle -// << " xcnew=" << xcnew << " ycnew=" << ycnew << " newX=" << newX << " newY=" << newY << endl; -#endif - } - while (!absorbing && loopsteps < 1000 && - (newX < land.minX || newX > land.maxX || newY < land.minY || newY > land.maxY)); - if (newX < land.minX || newX > land.maxX || newY < land.minY || newY > land.maxY) - pCurrCell = 0; - else - pCurrCell = pLandscape->findCell(newX,newY); - if (pCurrCell == 0) { // no-data cell or beyond absorbing boundary - patch = 0; - if (absorbing) absorbed = true; - } - else - patch = pCurrCell->getPatch(); -#if RSDEBUG -//DEBUGLOG << "Individual::moveStep(): indId=" << indId -// << " loopsteps=" << loopsteps << " absorbed=" << absorbed -// << " pCurrCell=" << pCurrCell << " patch=" << patch << endl; -#endif - } while (!absorbing && pCurrCell == 0 && loopsteps < 1000); - crw->prevdrn = (float)angle; - crw->xc = (float)xcnew; crw->yc = (float)ycnew; - if (absorbed) { // beyond absorbing boundary or in no-data square - status = 6; - dispersing = 0; - pCurrCell = 0; - } - else { - if (loopsteps >= 1000) { // unable to make a move - // INTERNAL ERROR CONDITION - INDIVIDUAL IS IN NO-DATA SQUARE - // NEED TO TAKE SOME FORM OF INFORMATIVE ACTION ... - // ... individual dies as it cannot move + patch = pCurrCell->getPatch(); + } while (!absorbing && pCurrCell == 0 && loopsteps < 1000); + crw->prevdrn = (float)angle; + crw->xc = (float)xcnew; crw->yc = (float)ycnew; + if (absorbed) { // beyond absorbing boundary or in no-data square status = 6; dispersing = 0; - // current cell will be invalid (zero), so set back to previous cell - pCurrCell = pPrevCell; + pCurrCell = 0; } - } -#if RSDEBUG -//DEBUGLOG << "Individual::moveStep(): indId=" << indId -// << " status=" << status -// << " pCurrCell=" << pCurrCell << " patch=" << patch << endl; -#endif - break; + else { + if (loopsteps >= 1000) { // unable to make a move + // INTERNAL ERROR CONDITION - INDIVIDUAL IS IN NO-DATA SQUARE + // NEED TO TAKE SOME FORM OF INFORMATIVE ACTION ... + // ... individual dies as it cannot move + status = 6; + dispersing = 0; + // current cell will be invalid (zero), so set back to previous cell + pCurrCell = pPrevCell; + } + } + break; - } // end of switch (trfr.moveType) + } // end of switch (trfr.moveType) -#if RSDEBUG -//locn loc2; -//if (pCurrCell > 0) { -// loc2 = pCurrCell->getLocn(); -//} -//else { -// loc2.x = -9999; loc2.y = -9999; -//} -//DEBUGLOG << "Individual::moveStep() ZZZZ: indId=" << indId -// << " status=" << status -// << " path->total=" << path->total -// << " x=" << loc2.x << " y=" << loc2.y -// << " patch=" << patch; -//if (patch > 0) { -// pPatch = (Patch*)patch; -// DEBUGLOG << " patchNum=" << pPatch->getPatchNum() -// << " getK()=" << pPatch->getK() -// << " popn=" << pPatch->getPopn((int)pSpecies); -//} -// DEBUGLOG << endl; -#endif - if (patch > 0 // not no-data area or matrix - && path->total >= settsteps.minSteps) { - pPatch = (Patch*)patch; - if (pPatch != pNatalPatch) - { - // determine whether the new patch is potentially suitable - if (pPatch->getK() > 0.0) - { // patch is suitable + if (patch > 0 // not no-data area or matrix + && path->total >= settsteps.minSteps) { + pPatch = (Patch*)patch; + if (pPatch != pNatalPatch) + { + // determine whether the new patch is potentially suitable + if (pPatch->getK() > 0.0) + { // patch is suitable status = 2; + } } } - } - if (status != 2 && status != 6) { // suitable patch not found, not already dead - if (path->year >= settsteps.maxStepsYr) { - status = 3; // waits until next year - } - if (path->total >= settsteps.maxSteps) { - status = 6; // dies - dispersing = 0; + if (status != 2 && status != 6) { // suitable patch not found, not already dead + if (path->year >= settsteps.maxStepsYr) { + status = 3; // waits until next year + } + if (path->total >= settsteps.maxSteps) { + status = 6; // dies + dispersing = 0; + } } - } -} // end of single movement step + } // end of single movement step -return dispersing; + return dispersing; } @@ -1676,696 +1255,478 @@ return dispersing; // Functions to implement the SMS algorithm // Move to a neighbouring cell according to the SMS algorithm -movedata Individual::smsMove(Landscape *pLand,Species *pSpecies, - const short landIx,const bool natalPatch,const bool indvar,const bool absorbing) +movedata Individual::smsMove(Landscape* pLand, Species* pSpecies, + const short landIx, const bool natalPatch, const bool indvar, const bool absorbing) { -array3x3d nbr; // to hold weights/costs/probs of moving to neighbouring cells -array3x3d goal; // to hold weights for moving towards a goal location -array3x3f hab; // to hold weights for habitat (includes percep range) -int x2,y2; // x index from 0=W to 2=E, y index from 0=N to 2=S -int newX = 0,newY = 0; -Cell *pCell; -Cell *pNewCell = NULL; -double sum_nbrs = 0.0; -movedata move; -int cellcost,newcellcost; -locn current; - -//if (write_out) { -// out<findCell(x,y); -if (pCurrCell == 0) -{ -// x,y is a NODATA square - this should not occur here -// return a negative distance to indicate an error - move.dist = -69.0; move.cost = 0.0; - return move; -} - -#if RSDEBUG -//DEBUGLOG << "Individual::smsMove(): this=" << this << endl; -#endif + array3x3d nbr; // to hold weights/costs/probs of moving to neighbouring cells + array3x3d goal; // to hold weights for moving towards a goal location + array3x3f hab; // to hold weights for habitat (includes percep range) + int x2, y2; // x index from 0=W to 2=E, y index from 0=N to 2=S + int newX = 0, newY = 0; + Cell* pCell; + Cell* pNewCell = NULL; + double sum_nbrs = 0.0; + movedata move; + int cellcost, newcellcost; + locn current; + + if (pCurrCell == 0) + { + // x,y is a NODATA square - this should not occur here + // return a negative distance to indicate an error + move.dist = -69.0; move.cost = 0.0; + return move; + } -landData land = pLand->getLandData(); -trfrSMSTraits movt = pSpecies->getSMSTraits(); -current = pCurrCell->getLocn(); - -//get weights for directional persistence.... -//if ((path->out > 0 && path->out < 10 && path->out < 2*movt.pr) -if ((path->out > 0 && path->out <= (movt.pr+1)) -|| natalPatch -|| (movt.straigtenPath && path->settleStatus > 0)) { - // inflate directional persistence to promote leaving the patch - if (indvar) nbr = getSimDir(current.x,current.y,10.0f*smsData->dp); - else nbr = getSimDir(current.x,current.y,10.0f*movt.dp); -} -else { - if (indvar) nbr = getSimDir(current.x,current.y,smsData->dp); - else nbr = getSimDir(current.x,current.y,movt.dp); -} -if (natalPatch || path->settleStatus > 0) path->out = 0; -//if (natalPatch) path->out = 0; -#if RSDEBUG -//DEBUGLOG << "Individual::smsMove() 0000: nbr matrix" << endl; -//for (y2 = 2; y2 > -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) DEBUGLOG << nbr.cell[x2][y2] << " "; -// DEBUGLOG << endl; -//} -#endif -//if (write_out) { -// out< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) out< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) out< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) out< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) DEBUGLOG << hab.cell[x2][y2] << " "; -// DEBUGLOG << endl; -//} -#endif - pCurrCell->setEffCosts(hab); -} -else { // they have already been calculated - no action required -// if (write_out) { -// out<<"*** using previous effective costs ***"< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) { -// out< -1; y2--) { - for (x2 = 0; x2 < 3; x2++) { - if(x2 == 1 && y2 == 1) nbr.cell[x2][y2] = 0.0; - else { - if(x2 == 1 || y2 == 1) //not diagonal - nbr.cell[x2][y2] = nbr.cell[x2][y2]*goal.cell[x2][y2]*hab.cell[x2][y2]; - else // diagonal - nbr.cell[x2][y2] = (float)SQRT2*nbr.cell[x2][y2]*goal.cell[x2][y2]*hab.cell[x2][y2]; - } -// if (write_out) { -// out< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) DEBUGLOG << nbr.cell[x2][y2] << " "; -// DEBUGLOG << endl; -//} -#endif + if (natalPatch || path->settleStatus > 0) path->out = 0; -// determine reciprocal of effective cost for the 8 neighbours -//if (write_out) out<<"reciprocal weighted effective costs:"< -1; y2--) { - for (x2 = 0; x2 < 3; x2++) { - if (nbr.cell[x2][y2] > 0.0) nbr.cell[x2][y2] = 1.0f/nbr.cell[x2][y2]; -// if (write_out) { -// out<year == path->total) { // first year of dispersal - use no. of steps outside natal patch + nsteps = path->out; + } + else { // use total no. of steps + nsteps = path->total; + } + if (indvar) { + double exp_arg = -((double)nsteps - (double)smsData->betaDB) * (-smsData->alphaDB); + if (exp_arg > 100.0) exp_arg = 100.0; // to prevent exp() overflow error + gb = 1.0 + (smsData->gb - 1.0) / (1.0 + exp(exp_arg)); + } + else { + double exp_arg = -((double)nsteps - (double)movt.betaDB) * (-movt.alphaDB); + if (exp_arg > 100.0) exp_arg = 100.0; // to prevent exp() overflow error + gb = 1.0 + (movt.gb - 1.0) / (1.0 + exp(exp_arg)); + } } -// if (write_out) out< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) { -// temp.cell[x2][y2] = nbr.cell[x2][y2]; -// if (current.x == 488 && current.y == 422) { -// pCell = pLand->findCell((current.x+x2-1),(current.y+y2-1)); -// DEBUGLOG << "Individual::smsMove(): this=" << this -// << " IN THE PROBLEM CELL" -// << " y=" << current.y << " x=" << current.x -// << " y2=" << y2 << " x2=" << x2 -// << " pCell=" << pCell; -// if (pCell != 0) DEBUGLOG << " pCell->getCost=" << pCell->getCost(); -// DEBUGLOG << endl; -// } -// } -//} -#endif + hab = pCurrCell->getEffCosts(); + + if (hab.cell[0][0] < 0.0) { // costs have not already been calculated + hab = getHabMatrix(pLand, pSpecies, current.x, current.y, movt.pr, movt.prMethod, + landIx, absorbing); + pCurrCell->setEffCosts(hab); + } + else { + // they have already been calculated - no action required + } -for (y2 = 2; y2 > -1; y2--) { - for (x2 = 0; x2 < 3; x2++) { - if (!absorbing) { - if ((current.y+y2-1) < land.minY || (current.y+y2-1) > land.maxY - || (current.x+x2-1) < land.minX || (current.x+x2-1) > land.maxX) - // cell is beyond current landscape limits - nbr.cell[x2][y2] = 0.0; - else { // check if no-data cell - pCell = pLand->findCell((current.x+x2-1),(current.y+y2-1)); - if (pCell == 0) nbr.cell[x2][y2] = 0.0; // no-data cell + // determine weighted effective cost for the 8 neighbours + // multiply directional persistence, goal bias and habitat habitat-dependent weights + for (y2 = 2; y2 > -1; y2--) { + for (x2 = 0; x2 < 3; x2++) { + if (x2 == 1 && y2 == 1) nbr.cell[x2][y2] = 0.0; + else { + if (x2 == 1 || y2 == 1) //not diagonal + nbr.cell[x2][y2] = nbr.cell[x2][y2] * goal.cell[x2][y2] * hab.cell[x2][y2]; + else // diagonal + nbr.cell[x2][y2] = (float)SQRT2 * nbr.cell[x2][y2] * goal.cell[x2][y2] * hab.cell[x2][y2]; } } -#if RSDEBUG -//DEBUGLOG << "Individual::smsMove(): this=" << this -// << " y=" << current.y << " x=" << current.x -// << " y2=" << y2 << " x2=" << x2 -// << " pCell=" << pCell -// << endl; -#endif -// if (write_out) { -// out< 0.0) { // should always be the case, but safest to check... + // determine reciprocal of effective cost for the 8 neighbours for (y2 = 2; y2 > -1; y2--) { for (x2 = 0; x2 < 3; x2++) { - nbr.cell[x2][y2] = nbr.cell[x2][y2]/(float)sum_nbrs; -// if (write_out) { -// out< 0.0) nbr.cell[x2][y2] = 1.0f / nbr.cell[x2][y2]; } -// if (write_out) out< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) DEBUGLOG << nbr.cell[x2][y2] << " "; -// DEBUGLOG << endl; -//} -#endif -// set up cell selection probabilities -//if (write_out) out<<"rnd = "< land.maxX - || newY < land.minY || newY > land.maxY))); - if (loopsteps >= 1000) pNewCell = 0; - else { - if (newX < land.minX || newX > land.maxX - || newY < land.minY || newY > land.maxY) { - pNewCell = 0; + } + + // set up cell selection probabilities + double cumulative[9]; + int j = 0; + cumulative[0] = nbr.cell[0][0]; + for (y2 = 0; y2 < 3; y2++) { + for (x2 = 0; x2 < 3; x2++) { + if (j != 0) cumulative[j] = cumulative[j - 1] + nbr.cell[x2][y2]; + j++; } - pNewCell = pLand->findCell(newX,newY); } -} -while (!absorbing && pNewCell == 0 && loopsteps < 1000); // no-data cell -#if RSDEBUG -//DEBUGLOG << "Individual::smsMove() 8888: pNewCell=" << pNewCell -// << " loopsteps=" << loopsteps -// << " current.x=" << current.x << " current.y=" << current.y -// << " newX=" << newX << " newY=" << newY -// << " land.minX=" << land.minX << " land.minY=" << land.minY -// << " land.maxX=" << land.maxX << " land.maxY=" << land.maxY -// << endl; -#endif -if (loopsteps >= 1000 || pNewCell == 0) { - // unable to make a move or crossed absorbing boundary - // flag individual to die - move.dist = -123.0; - if (pNewCell == 0) pCurrCell = pNewCell; -} -else { - newcellcost = pNewCell->getCost(); - move.cost = move.dist*0.5f*((float)cellcost + (float)newcellcost); - // make the selected move - if ((short)memory.size() == movt.memSize) { - memory.pop(); // remove oldest memory element - } - memory.push(current); // record previous location in memory - //if (write_out) out << "queue length is " << memory.size() << endl; - pCurrCell = pNewCell; -} -return move; + + // select direction at random based on cell selection probabilities + // landscape boundaries and no-data cells may be reflective or absorbing + cellcost = pCurrCell->getCost(); + int loopsteps = 0; // new counter to prevent infinite loop added 14/8/15 + do { + do { + double rnd = pRandom->Random(); + j = 0; + for (y2 = 0; y2 < 3; y2++) { + for (x2 = 0; x2 < 3; x2++) { + if (rnd < cumulative[j]) { + newX = current.x + x2 - 1; + newY = current.y + y2 - 1; + if (x2 == 1 || y2 == 1) move.dist = (float)(land.resol); + else move.dist = (float)(land.resol) * (float)SQRT2; + y2 = 999; x2 = 999; //to break out of x2 and y2 loops. + } + j++; + } + } + loopsteps++; + } while (loopsteps < 1000 + && (!absorbing && (newX < land.minX || newX > land.maxX + || newY < land.minY || newY > land.maxY))); + if (loopsteps >= 1000) pNewCell = 0; + else { + if (newX < land.minX || newX > land.maxX + || newY < land.minY || newY > land.maxY) { + pNewCell = 0; + } + pNewCell = pLand->findCell(newX, newY); + } + } while (!absorbing && pNewCell == 0 && loopsteps < 1000); // no-data cell + if (loopsteps >= 1000 || pNewCell == 0) { + // unable to make a move or crossed absorbing boundary + // flag individual to die + move.dist = -123.0; + if (pNewCell == 0) pCurrCell = pNewCell; + } + else { + newcellcost = pNewCell->getCost(); + move.cost = move.dist * 0.5f * ((float)cellcost + (float)newcellcost); + // make the selected move + if ((short)memory.size() == movt.memSize) { + memory.pop(); // remove oldest memory element + } + memory.push(current); // record previous location in memory + pCurrCell = pNewCell; + } + return move; } // Weight neighbouring cells on basis of current movement direction -array3x3d Individual::getSimDir(const int x, const int y, const float dp) +array3x3d Individual::getSimDir(const int x, const int y, const float dp) { -array3x3d d; -locn prev; -double theta; -int xx,yy; - -//if (write_out) out<<"step 0"<goal.x) == 0 && (y - smsData->goal.y) == 0) { - // at goal, set matrix to unity -// if (write_out) out<<"*** at goal: x,y = "<goal.x) == 0 && (y - smsData->goal.y) == 0) { + // at goal, set matrix to unity + for (xx = 0; xx < 3; xx++) { + for (yy = 0; yy < 3; yy++) { + d.cell[xx][yy] = 1.0; + } } + return d; + } + if (goaltype == 1) { + // TEMPORARY CODE - GOAL TYPE 1 NOT YET IMPLEMENTED, AS WE HAVE NO MEANS OF + // CAPTURING THE GOAL LOCATION OF EACH INDIVIDUAL + for (xx = 0; xx < 3; xx++) { + for (yy = 0; yy < 3; yy++) { + d.cell[xx][yy] = 1.0; + } + } + return d; } - return d; + else // goaltype == 2 + theta = atan2(((double)x - (double)smsData->goal.x), ((double)y - (double)smsData->goal.y)); + d = calcWeightings(gb, (float)theta); } - else // goaltype == 2 - theta = atan2(((double)x -(double)smsData->goal.x),((double)y-(double)smsData->goal.y)); -// if (write_out) out<<"goalx,goaly: "< 7.0 * PI / 8.0) { dx = 0; dy = -1; } -else { - if (fabs(theta) > 5.0 * PI / 8.0) { dy = -1; if (theta > 0) dx = 1; else dx = -1; } + if (fabs(theta) > 7.0 * PI / 8.0) { dx = 0; dy = -1; } else { - if (fabs(theta) > 3.0 * PI / 8.0) { dy = 0; if (theta > 0) dx = 1; else dx = -1; } + if (fabs(theta) > 5.0 * PI / 8.0) { dy = -1; if (theta > 0) dx = 1; else dx = -1; } else { - if (fabs(theta) > PI / 8.0) { dy = 1; if (theta > 0) dx = 1; else dx = -1; } - else { dy = 1; dx = 0; } + if (fabs(theta) > 3.0 * PI / 8.0) { dy = 0; if (theta > 0) dx = 1; else dx = -1; } + else { + if (fabs(theta) > PI / 8.0) { dy = 1; if (theta > 0) dx = 1; else dx = -1; } + else { dy = 1; dx = 0; } + } } - } -} -// if (write_out) out<<"goalx,goaly: "< 1) dx -= 2; yy = dy; - d.cell[xx+1][yy+1] = (float)i1; d.cell[-xx+1][yy+1] = (float)i1; - d.cell[xx+1][-yy+1] = (float)i3; d.cell[-xx+1][-yy+1] = (float)i3; - } - else { // theta points W or E - yy = dy+1; if (yy > 1) dy -= 2; xx = dx; - d.cell[xx+1][yy+1] = (float)i1; d.cell[xx+1][-yy+1] = (float)i1; - d.cell[-xx+1][yy+1] = (float)i3; d.cell[-xx+1][-yy+1] = (float)i3; - } -} -else { // theta points to an ordinal direction - d.cell[dx+1][-dy+1] = (float)i2; d.cell[-dx+1][dy+1] = (float)i2; - xx = dx+1; if (xx > 1) xx -= 2; d.cell[xx+1][dy+1] = (float)i1; - yy = dy+1; if (yy > 1) yy -= 2; d.cell[dx+1][yy+1] = (float)i1; - d.cell[-xx+1][-dy+1] = (float)i3; d.cell[-dx+1][-yy+1] = (float)i3; - } - -return d; + } + d.cell[1][1] = 0; // central cell has zero weighting + d.cell[dx + 1][dy + 1] = (float)i0; + d.cell[-dx + 1][-dy + 1] = (float)i4; + if (dx == 0 || dy == 0) { // theta points to a cardinal direction + d.cell[dy + 1][dx + 1] = (float)i2; d.cell[-dy + 1][-dx + 1] = (float)i2; + if (dx == 0) { // theta points N or S + xx = dx + 1; if (xx > 1) dx -= 2; yy = dy; + d.cell[xx + 1][yy + 1] = (float)i1; d.cell[-xx + 1][yy + 1] = (float)i1; + d.cell[xx + 1][-yy + 1] = (float)i3; d.cell[-xx + 1][-yy + 1] = (float)i3; + } + else { // theta points W or E + yy = dy + 1; if (yy > 1) dy -= 2; xx = dx; + d.cell[xx + 1][yy + 1] = (float)i1; d.cell[xx + 1][-yy + 1] = (float)i1; + d.cell[-xx + 1][yy + 1] = (float)i3; d.cell[-xx + 1][-yy + 1] = (float)i3; + } + } + else { // theta points to an ordinal direction + d.cell[dx + 1][-dy + 1] = (float)i2; d.cell[-dx + 1][dy + 1] = (float)i2; + xx = dx + 1; if (xx > 1) xx -= 2; d.cell[xx + 1][dy + 1] = (float)i1; + yy = dy + 1; if (yy > 1) yy -= 2; d.cell[dx + 1][yy + 1] = (float)i1; + d.cell[-xx + 1][-dy + 1] = (float)i3; d.cell[-dx + 1][-yy + 1] = (float)i3; + } + + return d; } // Weight neighbouring cells on basis of (habitat) costs -array3x3f Individual::getHabMatrix(Landscape *pLand,Species *pSpecies, - const int x,const int y,const short pr,const short prmethod,const short landIx, +array3x3f Individual::getHabMatrix(Landscape* pLand, Species* pSpecies, + const int x, const int y, const short pr, const short prmethod, const short landIx, const bool absorbing) { -array3x3f w; // array of effective costs to be returned -int ncells,x4,y4; -double weight,sumweights; -// NW and SE corners of effective cost array relative to the current cell (x,y): -int xmin = 0,ymin = 0,xmax = 0,ymax = 0; -int cost,nodatacost,h; -Cell *pCell; + array3x3f w; // array of effective costs to be returned + int ncells, x4, y4; + double weight, sumweights; + // NW and SE corners of effective cost array relative to the current cell (x,y): + int xmin = 0, ymin = 0, xmax = 0, ymax = 0; + int cost, nodatacost, h; + Cell* pCell; -landData land = pLand->getLandData(); -if (absorbing) nodatacost = ABSNODATACOST; -else nodatacost = NODATACOST; + landData land = pLand->getLandData(); + if (absorbing) nodatacost = ABSNODATACOST; + else nodatacost = NODATACOST; -for (int x2=-1; x2<2; x2++) { // index of relative move in x direction - for (int y2=-1; y2<2; y2++) { // index of relative move in x direction + for (int x2 = -1; x2 < 2; x2++) { // index of relative move in x direction + for (int y2 = -1; y2 < 2; y2++) { // index of relative move in x direction - w.cell[x2+1][y2+1] = 0.0; // initialise costs array to zeroes + w.cell[x2 + 1][y2 + 1] = 0.0; // initialise costs array to zeroes - // set up corners of perceptual range relative to current cell - if (x2==0 && y2==0) { // current cell - do nothing - xmin=0; ymin=0; xmax=0; ymax=0; - } - else { - if (x2==0 || y2==0) { // not diagonal (rook move) - if (x2==0){ // vertical (N-S) move - //out<<"ROOK N-S: x2 = "< land.maxX) x4 = x+x3-land.maxX-1; else x4 = x+x3; } - if ((y+y3) < 0) y4 = y+y3+land.maxY+1; - else { if ((y+y3) > land.maxY) y4 = y+y3-land.maxY-1; else y4 = y+y3; } -// if (write_out && (x4 < 0 || y4 < 0)) { -// out<<"ERROR: x "< land.maxX || y4 < 0 || y4 > land.maxY) { - // unexpected problem - e.g. due to ridiculously large PR - // treat as a no-data cell - cost = nodatacost; - } - else { - // add cost of cell to total PR cost - pCell = pLand->findCell(x4,y4); - if (pCell == 0) { // no-data cell + if (xmin > xmax) { int z = xmax; xmax = xmin; xmin = z; } // swap xmin and xmax + if (ymin > ymax) { int z = ymax; ymax = ymin; ymin = z; } // swap ymin and ymax + + // calculate effective mean cost of cells in perceptual range + ncells = 0; weight = 0.0; sumweights = 0.0; + if (x2 != 0 || y2 != 0) { // not central cell (i.e. current cell) + for (int x3 = xmin; x3 <= xmax; x3++) { + for (int y3 = ymin; y3 <= ymax; y3++) { + // if cell is out of bounds, treat landscape as a torus + // for purpose of obtaining a cost, + if ((x + x3) < 0) x4 = x + x3 + land.maxX + 1; + else { if ((x + x3) > land.maxX) x4 = x + x3 - land.maxX - 1; else x4 = x + x3; } + if ((y + y3) < 0) y4 = y + y3 + land.maxY + 1; + else { if ((y + y3) > land.maxY) y4 = y + y3 - land.maxY - 1; else y4 = y + y3; } + if (x4 < 0 || x4 > land.maxX || y4 < 0 || y4 > land.maxY) { + // unexpected problem - e.g. due to ridiculously large PR + // treat as a no-data cell cost = nodatacost; } else { - cost = pCell->getCost(); - if (cost < 0) cost = nodatacost; + // add cost of cell to total PR cost + pCell = pLand->findCell(x4, y4); + if (pCell == 0) { // no-data cell + cost = nodatacost; + } else { - if (cost == 0) { // cost not yet set for the cell - h = pCell->getHabIndex(landIx); - cost = pSpecies->getHabCost(h); -#if RSDEBUG -//DEBUGLOG << "Individual::getHabMatrix(): x4=" << x4 << " y4=" << y4 -// << " landIx=" << landIx << " h=" << h << " cost=" << cost -// << endl; -#endif - pCell->setCost(cost); - } + cost = pCell->getCost(); + if (cost < 0) cost = nodatacost; else { -#if RSDEBUG -//DEBUGLOG << "Individual::getHabMatrix(): x4=" << x4 << " y4=" << y4 -// << " cost=" << cost -// << endl; -#endif - - } + if (cost == 0) { // cost not yet set for the cell + h = pCell->getHabIndex(landIx); + cost = pSpecies->getHabCost(h); + pCell->setCost(cost); + } + else { + + } + } } } + if (prmethod == 1) { // arithmetic mean + w.cell[x2 + 1][y2 + 1] += cost; + ncells++; + } + if (prmethod == 2) { // harmonic mean + if (cost > 0) { + w.cell[x2 + 1][y2 + 1] += (1.0f / (float)cost); + ncells++; + } + } + if (prmethod == 3) { // arithmetic mean weighted by inverse distance + if (cost > 0) { + // NB distance is still given by (x3,y3) + weight = 1.0f / (double)sqrt((pow((double)x3, 2) + pow((double)y3, 2))); + w.cell[x2 + 1][y2 + 1] += (float)(weight * (double)cost); + ncells++; sumweights += weight; + } + } + } //end of y3 loop + } //end of x3 loop + if (ncells > 0) { + if (prmethod == 1) w.cell[x2 + 1][y2 + 1] /= ncells; // arithmetic mean + if (prmethod == 2) w.cell[x2 + 1][y2 + 1] = ncells / w.cell[x2 + 1][y2 + 1]; // hyperbolic mean + if (prmethod == 3 && sumweights > 0) + w.cell[x2 + 1][y2 + 1] /= (float)sumweights; // weighted arithmetic mean + } + } + else { // central cell + // record cost if not already recorded + // has effect of preparing for storing effective costs for the cell + pCell = pLand->findCell(x, y); + cost = pCell->getCost(); + if (cost < 0) cost = nodatacost; + else { + if (cost == 0) { // cost not yet set for the cell + h = pCell->getHabIndex(landIx); + cost = pSpecies->getHabCost(h); + pCell->setCost(cost); } - if (prmethod==1) { // arithmetic mean - w.cell[x2+1][y2+1] += cost; - ncells++; - } - if (prmethod==2) { // harmonic mean - if (cost > 0) { - w.cell[x2+1][y2+1] += (1.0f/(float)cost); - ncells++; - } - } - if (prmethod==3) { // arithmetic mean weighted by inverse distance - if (cost>0) { - // NB distance is still given by (x3,y3) - weight = 1.0f /(double)sqrt((pow((double)x3,2)+pow((double)y3,2))); - w.cell[x2+1][y2+1] += (float)(weight*(double)cost); - ncells++; sumweights += weight; - } - } -// if (write_out2) out2<get_target() > 50) targetseen++; -// } -//#endif - } //end of y3 loop - } //end of x3 loop -// if (write_out) out<<"ncells in PR = "<total << "\t" << loc.x << "\t" << loc.y << "\t" - << status << "\t" - << endl; + << path->total << "\t" << loc.x << "\t" << loc.y << "\t" + << status << "\t" + << endl; } // if not anymore dispersing... - if(status > 1 && status < 10){ + if (status > 1 && status < 10) { prev_loc = pPrevCell->getLocn(); // record only if this is the first step as non-disperser if (path->pathoutput) { // if this is also the first step taken at all, record the start cell first - if(path->total == 1){ + if (path->total == 1) { outMovePaths << year << "\t" << indId << "\t" - << "0\t" << prev_loc.x << "\t" << prev_loc.y << "\t" - << "0\t" // status at start cell is 0 - << endl; + << "0\t" << prev_loc.x << "\t" << prev_loc.y << "\t" + << "0\t" // status at start cell is 0 + << endl; } outMovePaths << year << "\t" << indId << "\t" - << path->total << "\t" << loc.x << "\t" << loc.y << "\t" - << status << "\t" - << endl; + << path->total << "\t" << loc.x << "\t" << loc.y << "\t" + << status << "\t" + << endl; // current cell will be invalid (zero), so set back to previous cell //pPrevCell = pCurrCell; path->pathoutput = 0; @@ -2422,33 +1783,76 @@ void Individual::outMovePath(const int year) //--------------------------------------------------------------------------- -double wrpcauchy (double location, double rho) { -double result; - -if(rho < 0.0 || rho > 1.0) { -// ML_ERR_return_NAN; - result = location; -} +double wrpcauchy(double location, double rho) { + double result; -if(rho == 0) - result = pRandom->Random() * M_2PI; -else - if(rho == 1) result = location; - else { - result = fmod(cauchy(location, -log(rho)), M_2PI); + if (rho < 0.0 || rho > 1.0) { + result = location; } -return result; + + if (rho == 0) + result = pRandom->Random() * M_2PI; + else + if (rho == 1) result = location; + else { + result = fmod(cauchy(location, -log(rho)), M_2PI); + } + return result; } double cauchy(double location, double scale) { -if (scale < 0) return location; -//return location + scale * tan(M_PI * unif_rand()); -return location + scale * tan(PI * pRandom->Random()); -//return location + scale * tan(M_PI * pRandom->Random()); + if (scale < 0) return location; + return location + scale * tan(PI * pRandom->Random()); } -//#endif -//#endif //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- + +#if RSDEBUG + + +void testIndividual() { + + Patch* pPatch = new Patch(0, 0); + int cell_x = 2; + int cell_y = 5; + int cell_hab = 2; + Cell* pCell = new Cell(cell_x, cell_y, (intptr)pPatch, cell_hab); + + // Create an individual + short stg = 0; + short age = 0; + short repInt = 0; + float probmale = 0; + bool uses_movt_process = true; + short moveType = 1; + Individual ind(pCell, pPatch, stg, age, repInt, probmale, uses_movt_process, moveType); + + // An individual... + { + std::vector inds; + for (int i = 0; i < 2; i++) + { + inds.push_back(new Individual(pCell, pPatch, stg, age, repInt, probmale, uses_movt_process, moveType)); + } + } + + // Reproduces + // depending on whether it is sexual or not + // depending on the stage + // depending on the trait inheritance + + + // Disperses + // Emigrates + // Transfers + // Settles + + // Survives + + // Develops + +} +#endif // RSDEBUG + diff --git a/Individual.h b/Individual.h index d843d7e..bdc4ecb 100644 --- a/Individual.h +++ b/Individual.h @@ -49,7 +49,6 @@ Last updated: 26 October 2021 by Steve Palmer #include using namespace std; -//#include "mathlib.h" #include "Parameters.h" #include "Species.h" #include "Landscape.h" @@ -73,7 +72,6 @@ struct pathData { // to hold path data common to SMS and CRW models short settleStatus; // whether ind may settle in current patch // 0 = not set, 1 = debarred through density dependence rule // 2 = OK to settle subject to finding a mate -// bool leftNatalPatch; // individual has moved out of its natal patch #if RS_RCPP short pathoutput; #endif @@ -209,13 +207,6 @@ class Individual { const short, // landscape change index const bool // absorbing boundaries? ); - void drawMove( // Visualise paths resulting from movement simulation model - // NULL for the batch version - const float, // initial x co-ordinate - const float, // initial y co-ordinate - const float, // final x co-ordinate - const float // final y co-ordinate - ); movedata smsMove( // Move to a neighbouring cell according to the SMS algorithm Landscape*, // pointer to Landscape Species*, // pointer to Species @@ -313,5 +304,9 @@ extern ofstream DEBUGLOG; extern ofstream outMovePaths; #endif -//--------------------------------------------------------------------------- +#if RSDEBUG +void testIndividual(); #endif + +//--------------------------------------------------------------------------- +#endif // IndividualH diff --git a/Landscape.cpp b/Landscape.cpp index b74e7f2..be63ae9 100644 --- a/Landscape.cpp +++ b/Landscape.cpp @@ -184,10 +184,8 @@ if (!dfile.is_open()) return 21; // read landscape data from header records of distribution file // NB headers of all files have already been compared -double tmpresol; dfile >> header >> ncols >> header >> nrows >> header >> minEast >> header >> minNorth - >> header >> tmpresol >> header >> nodata; -resol = (int) tmpresol; + >> header >> resol >> header >> nodata; #if RS_RCPP if (!dfile.good()) { // corrupt file stream @@ -2096,10 +2094,8 @@ if (fileNum == 0) { // read landscape data from header records of habitat file // NB headers of all files have already been compared -double tmpresol; hfile >> header >> ncols >> header >> nrows >> header >> minEast >> header >> minNorth - >> header >> tmpresol >> header >> habnodata; -resol = (int) tmpresol; + >> header >> resol >> header >> habnodata; #if RS_RCPP if (!hfile.good()) { diff --git a/Population.cpp b/Population.cpp index 002e860..4af1e84 100644 --- a/Population.cpp +++ b/Population.cpp @@ -1,26 +1,26 @@ /*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, Damaris Zurell - * + * + * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * + * --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- + + + //--------------------------------------------------------------------------- #include "Population.h" //--------------------------------------------------------------------------- @@ -30,655 +30,442 @@ ofstream outInds; //--------------------------------------------------------------------------- -Population::Population(void) { -nSexes = nStages = 0; -pPatch = NULL; -pSpecies = NULL; -return; +Population::Population(void) { + nSexes = nStages = 0; + pPatch = NULL; + pSpecies = NULL; + return; } -Population::Population(Species *pSp,Patch *pPch,int ninds,int resol) +Population::Population(Species* pSp, Patch* pPch, int ninds, int resol) { -// constructor for a Population of a specified size -#if RSDEBUG -//DEBUGLOG << "Population::Population(): this=" << this -// << " pPch=" << pPch << " ninds="<< ninds << endl; -#endif - -int n,nindivs,age = 0,minage,maxage,nAges = 0; -int cumtotal = 0; -float probmale; -double ageprob,ageprobsum; -std::vector ageProb; // for quasi-equilibrium initial age distribution -Cell *pCell; + // constructor for a Population of a specified size + + int n, nindivs, age = 0, minage, maxage, nAges = 0; + int cumtotal = 0; + float probmale; + double ageprob, ageprobsum; + std::vector ageProb; // for quasi-equilibrium initial age distribution + Cell* pCell; + + if (ninds > 0) { + inds.reserve(ninds); + juvs.reserve(ninds); + } -if (ninds > 0) { - inds.reserve(ninds); - juvs.reserve(ninds); -} + pSpecies = pSp; + pPatch = pPch; + // record the new population in the patch + patchPopn pp; + pp.pSp = (intptr)pSpecies; pp.pPop = (intptr)this; + pPatch->addPopn(pp); -pSpecies = pSp; -pPatch = pPch; -// record the new population in the patch -patchPopn pp; -pp.pSp = (intptr)pSpecies; pp.pPop = (intptr)this; -pPatch->addPopn(pp); -#if RSDEBUG -//DEBUGLOG << "Population::Population(): this=" << this -// << " added population to patch " << endl; -#endif + demogrParams dem = pSpecies->getDemogr(); + stageParams sstruct = pSpecies->getStage(); + emigRules emig = pSpecies->getEmig(); + trfrRules trfr = pSpecies->getTrfr(); + settleType sett = pSpecies->getSettle(); + genomeData gen = pSpecies->getGenomeData(); + initParams init = paramsInit->getInit(); -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -//trfrSMSTraits sms = pSpecies->getSMSTraits(); -settleType sett = pSpecies->getSettle(); -genomeData gen = pSpecies->getGenomeData(); -initParams init = paramsInit->getInit(); - -// determine no. of stages and sexes of species to initialise -if (dem.stageStruct) { - nStages = sstruct.nStages; -} -else // non-structured population has 2 stages, but user only ever sees stage 1 - nStages = 2; -if (dem.repType == 0) { nSexes = 1; probmale = 0.0; } -else { nSexes = 2; probmale = dem.propMales; } - -// set up population sub-totals -for (int stg = 0; stg < NSTAGES; stg++) { - for (int sex = 0; sex < NSEXES; sex++) { - nInds[stg][sex] = 0; + // determine no. of stages and sexes of species to initialise + if (dem.stageStruct) { + nStages = sstruct.nStages; + } + else // non-structured population has 2 stages, but user only ever sees stage 1 + nStages = 2; + if (dem.repType == 0) { nSexes = 1; probmale = 0.0; } + else { nSexes = 2; probmale = dem.propMales; } + + // set up population sub-totals + for (int stg = 0; stg < NSTAGES; stg++) { + for (int sex = 0; sex < NSEXES; sex++) { + nInds[stg][sex] = 0; + } } -} -// set up local copy of minimum age table -short minAge[NSTAGES][NSEXES]; -for (int stg = 0; stg < nStages; stg++) { - for (int sex = 0; sex < nSexes; sex++) { - if (dem.stageStruct) { - if (dem.repType == 1) { // simple sexual model - // both sexes use minimum ages recorded for females - minAge[stg][sex] = pSpecies->getMinAge(stg,0); + // set up local copy of minimum age table + short minAge[NSTAGES][NSEXES]; + for (int stg = 0; stg < nStages; stg++) { + for (int sex = 0; sex < nSexes; sex++) { + if (dem.stageStruct) { + if (dem.repType == 1) { // simple sexual model + // both sexes use minimum ages recorded for females + minAge[stg][sex] = pSpecies->getMinAge(stg, 0); + } + else { + minAge[stg][sex] = pSpecies->getMinAge(stg, sex); + } } - else { - minAge[stg][sex] = pSpecies->getMinAge(stg,sex); + else { // non-structured population + minAge[stg][sex] = 0; } } - else { // non-structured population - minAge[stg][sex] = 0; - } -#if RSDEBUG -//DEBUGLOG << "Population::Population(): 1111 " -// << " minAge[" << stg << "][" << sex << "]=" << minAge[stg][sex] -// << endl; -#endif } -} -// individuals of new population must be >= stage 1 -for (int stg = 1; stg < nStages; stg++) { - if (dem.stageStruct) { // allocate to stages according to initialisation conditions - // final stage is treated separately to ensure that correct total - // no. of individuals is created - if (stg == nStages-1) { - n = ninds - cumtotal; + // individuals of new population must be >= stage 1 + for (int stg = 1; stg < nStages; stg++) { + if (dem.stageStruct) { // allocate to stages according to initialisation conditions + // final stage is treated separately to ensure that correct total + // no. of individuals is created + if (stg == nStages - 1) { + n = ninds - cumtotal; + } + else { + n = (int)(ninds * paramsInit->getProp(stg) + 0.5); + cumtotal += n; + } } - else { - n = (int)(ninds * paramsInit->getProp(stg) + 0.5); - cumtotal += n; + else { // non-structured - all individuals go into stage 1 + n = ninds; } - } - else { // non-structured - all individuals go into stage 1 - n = ninds; - } -// for (int sex = 0; sex < nSexes; sex++) { -// if (n < nSexes) n = nSexes; // to ensure at least one individual of each age is created -// subPops.push_back(new SubPop(loc,stg,sex,n/nSexes)); -// } - // establish initial age distribution - minage = maxage = stg; - if (dem.stageStruct) { - // allow for stage-dependent minimum ages (use whichever sex is greater) - if (minAge[stg][0] > 0 && minage < minAge[stg][0]) minage = minAge[stg][0]; - if (nSexes == 2 && minAge[stg][1] > 0 && minage < minAge[stg][1]) minage = minAge[stg][1]; - // allow for specified age distribution - if (init.initAge != 0) { // not lowest age - if (stg == nStages-1) maxage = sstruct.maxAge; // final stage - else { // all other stages - use female max age, as sex of individuals is not predetermined - maxage = minAge[stg+1][0] - 1; - } - if (maxage < minage) maxage = minage; - nAges = maxage - minage + 1; - if (init.initAge == 2) { // quasi-equilibrium distribution - double psurv = (double)pSpecies->getSurv(stg,0); // use female survival for the stage - ageProb.clear(); - ageprobsum = 0.0; - ageprob = 1.0; - for (int i = 0; i < nAges; i++) { - ageProb.push_back(ageprob); ageprobsum += ageprob; ageprob *= psurv; + // establish initial age distribution + minage = maxage = stg; + if (dem.stageStruct) { + // allow for stage-dependent minimum ages (use whichever sex is greater) + if (minAge[stg][0] > 0 && minage < minAge[stg][0]) minage = minAge[stg][0]; + if (nSexes == 2 && minAge[stg][1] > 0 && minage < minAge[stg][1]) minage = minAge[stg][1]; + // allow for specified age distribution + if (init.initAge != 0) { // not lowest age + if (stg == nStages - 1) maxage = sstruct.maxAge; // final stage + else { // all other stages - use female max age, as sex of individuals is not predetermined + maxage = minAge[stg + 1][0] - 1; } - for (int i = 0; i < nAges; i++) { - ageProb[i] /= ageprobsum; - if (i > 0) ageProb[i] += ageProb[i-1]; // to give cumulative probability + if (maxage < minage) maxage = minage; + nAges = maxage - minage + 1; + if (init.initAge == 2) { // quasi-equilibrium distribution + double psurv = (double)pSpecies->getSurv(stg, 0); // use female survival for the stage + ageProb.clear(); + ageprobsum = 0.0; + ageprob = 1.0; + for (int i = 0; i < nAges; i++) { + ageProb.push_back(ageprob); ageprobsum += ageprob; ageprob *= psurv; + } + for (int i = 0; i < nAges; i++) { + ageProb[i] /= ageprobsum; + if (i > 0) ageProb[i] += ageProb[i - 1]; // to give cumulative probability + } } } } - } -#if RSDEBUG -//DEBUGLOG << "Population::Population(): this=" << this -// << " n=" << n << " stg=" << stg << " minage=" << minage << " maxage=" << maxage -// << endl; -#endif - // create individuals - int sex; - nindivs = (int)inds.size(); - for (int i = 0; i < n; i++) { - pCell = pPatch->getRandomCell(); - if (dem.stageStruct) { - switch (init.initAge) { - case 0: // lowest possible age - age = minage; - break; - case 1: // randomised - if (maxage > minage) age = pRandom->IRandom(minage,maxage); - else age = minage; - break; - case 2: // quasi-equilibrium - if (nAges > 1) { - double rrr = pRandom->Random(); - int ageclass = 0; - while (rrr > ageProb[ageclass]) ageclass++; - age = minage + ageclass; + // create individuals + int sex; + nindivs = (int)inds.size(); + for (int i = 0; i < n; i++) { + pCell = pPatch->getRandomCell(); + if (dem.stageStruct) { + switch (init.initAge) { + case 0: // lowest possible age + age = minage; + break; + case 1: // randomised + if (maxage > minage) age = pRandom->IRandom(minage, maxage); + else age = minage; + break; + case 2: // quasi-equilibrium + if (nAges > 1) { + double rrr = pRandom->Random(); + int ageclass = 0; + while (rrr > ageProb[ageclass]) ageclass++; + age = minage + ageclass; + } + else age = minage; + break; } - else age = minage; - break; } - } - else age = stg; + else age = stg; #if RSDEBUG - // NOTE: CURRENTLY SETTING ALL INDIVIDUALS TO RECORD NO. OF STEPS ... - inds.push_back(new Individual(pCell,pPatch,stg,age,sstruct.repInterval, - probmale,true,trfr.moveType)); + // NOTE: CURRENTLY SETTING ALL INDIVIDUALS TO RECORD NO. OF STEPS ... + inds.push_back(new Individual(pCell, pPatch, stg, age, sstruct.repInterval, + probmale, true, trfr.moveType)); #else - inds.push_back(new Individual(pCell,pPatch,stg,age,sstruct.repInterval, - probmale,trfr.moveModel,trfr.moveType)); -#endif - sex = inds[nindivs+i]->getSex(); - if (emig.indVar || trfr.indVar || sett.indVar || gen.neutralMarkers) - { - // individual variation - set up genetics - inds[nindivs+i]->setGenes(pSpecies,resol); + inds.push_back(new Individual(pCell, pPatch, stg, age, sstruct.repInterval, + probmale, trfr.moveModel, trfr.moveType)); +#endif + sex = inds[nindivs + i]->getSex(); + if (emig.indVar || trfr.indVar || sett.indVar || gen.neutralMarkers) + { + // individual variation - set up genetics + inds[nindivs + i]->setGenes(pSpecies, resol); + } + nInds[stg][sex]++; } - nInds[stg][sex]++; } } -#if RSDEBUG -//DEBUGLOG << "Population::Population(): this=" << this -// << " finished " << endl; -#endif -} Population::~Population(void) { -int ninds = (int)inds.size(); -for (int i = 0; i < ninds; i++) { - if (inds[i] != NULL) delete inds[i]; -} -inds.clear(); -int njuvs = (int)juvs.size(); -for (int i = 0; i < njuvs; i++) { - if (juvs[i] != NULL) delete juvs[i]; -} -juvs.clear(); -} - -traitsums Population::getTraits(Species *pSpecies) { -int g; -traitsums ts; -for (int i = 0; i < NSEXES; i++) { - ts.ninds[i] = 0; - ts.sumD0[i] = ts.ssqD0[i] = 0.0; - ts.sumAlpha[i] = ts.ssqAlpha[i] = 0.0; ts.sumBeta[i] = ts.ssqBeta[i] = 0.0; - ts.sumDist1[i] = ts.ssqDist1[i] = 0.0; ts.sumDist2[i] = ts.ssqDist2[i] = 0.0; - ts.sumProp1[i] = ts.ssqProp1[i] = 0.0; - ts.sumDP[i] = ts.ssqDP[i] = 0.0; - ts.sumGB[i] = ts.ssqGB[i] = 0.0; - ts.sumAlphaDB[i] = ts.ssqAlphaDB[i] = 0.0; - ts.sumBetaDB[i] = ts.ssqBetaDB[i] = 0.0; - ts.sumStepL[i] = ts.ssqStepL[i] = 0.0; ts.sumRho[i] = ts.ssqRho[i] = 0.0; - ts.sumS0[i] = ts.ssqS0[i] = 0.0; - ts.sumAlphaS[i] = ts.ssqAlphaS[i] = 0.0; ts.sumBetaS[i] = ts.ssqBetaS[i] = 0.0; -} -//locus loc; + int ninds = (int)inds.size(); + for (int i = 0; i < ninds; i++) { + if (inds[i] != NULL) delete inds[i]; + } + inds.clear(); + int njuvs = (int)juvs.size(); + for (int i = 0; i < njuvs; i++) { + if (juvs[i] != NULL) delete juvs[i]; + } + juvs.clear(); +} + +traitsums Population::getTraits(Species* pSpecies) { + int g; + traitsums ts; + for (int i = 0; i < NSEXES; i++) { + ts.ninds[i] = 0; + ts.sumD0[i] = ts.ssqD0[i] = 0.0; + ts.sumAlpha[i] = ts.ssqAlpha[i] = 0.0; ts.sumBeta[i] = ts.ssqBeta[i] = 0.0; + ts.sumDist1[i] = ts.ssqDist1[i] = 0.0; ts.sumDist2[i] = ts.ssqDist2[i] = 0.0; + ts.sumProp1[i] = ts.ssqProp1[i] = 0.0; + ts.sumDP[i] = ts.ssqDP[i] = 0.0; + ts.sumGB[i] = ts.ssqGB[i] = 0.0; + ts.sumAlphaDB[i] = ts.ssqAlphaDB[i] = 0.0; + ts.sumBetaDB[i] = ts.ssqBetaDB[i] = 0.0; + ts.sumStepL[i] = ts.ssqStepL[i] = 0.0; ts.sumRho[i] = ts.ssqRho[i] = 0.0; + ts.sumS0[i] = ts.ssqS0[i] = 0.0; + ts.sumAlphaS[i] = ts.ssqAlphaS[i] = 0.0; ts.sumBetaS[i] = ts.ssqBetaS[i] = 0.0; + } -demogrParams dem = pSpecies->getDemogr(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); + demogrParams dem = pSpecies->getDemogr(); + emigRules emig = pSpecies->getEmig(); + trfrRules trfr = pSpecies->getTrfr(); + settleType sett = pSpecies->getSettle(); -int ninds = (int)inds.size(); -#if RSDEBUG -//DEBUGLOG << "Population::getTraits(): ninds = " << ts.ninds[0] -//// << " nalleles = "<< nalleles -//// << " nemiggenes = " << nemiggenes << " ntrfrgenes = " << ntrfrgenes -// << endl; -#endif -for (int i = 0; i < ninds; i++) { - int sex = inds[i]->getSex(); - if (emig.sexDep || trfr.sexDep || sett.sexDep) g = sex; else g = 0; - ts.ninds[g] += 1; - // emigration traits - emigTraits e = inds[i]->getEmigTraits(); - if (emig.sexDep) g = sex; else g = 0; - ts.sumD0[g] += e.d0; ts.ssqD0[g] += e.d0 * e.d0; - ts.sumAlpha[g] += e.alpha; ts.ssqAlpha[g] += e.alpha * e.alpha; - ts.sumBeta[g] += e.beta; ts.ssqBeta[g] += e.beta * e.beta; - // transfer traits - trfrKernTraits k = inds[i]->getKernTraits(); - if (trfr.sexDep) g = sex; else g = 0; - ts.sumDist1[g] += k.meanDist1; ts.ssqDist1[g] += k.meanDist1 * k.meanDist1; - ts.sumDist2[g] += k.meanDist2; ts.ssqDist2[g] += k.meanDist2 * k.meanDist2; - ts.sumProp1[g] += k.probKern1; ts.ssqProp1[g] += k.probKern1 * k.probKern1; - trfrSMSTraits sms = inds[i]->getSMSTraits(); - g = 0; // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT - ts.sumDP[g] += sms.dp; ts.ssqDP[g] += sms.dp * sms.dp; - ts.sumGB[g] += sms.gb; ts.ssqGB[g] += sms.gb * sms.gb; - ts.sumAlphaDB[g] += sms.alphaDB; ts.ssqAlphaDB[g] += sms.alphaDB * sms.alphaDB; - ts.sumBetaDB[g] += sms.betaDB; ts.ssqBetaDB[g] += sms.betaDB * sms.betaDB; -#if RSDEBUG -//DEBUGLOG << "Population::getTraits():" -// << " i=" << i << " g=" << g -// << " sms.dp= " << sms.dp << " sms.gb= " << sms.gb -// << " ts.sumDP[g]= " << ts.sumDP[g] << " ts.ssqDP[g]= " << ts.ssqDP[g] -// << " ts.sumGB[g]= " << ts.sumGB[g] << " ts.ssqGB[g]= " << ts.ssqGB[g] -// << endl; -#endif - trfrCRWTraits c = inds[i]->getCRWTraits(); - g = 0; // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT - ts.sumStepL[g] += c.stepLength; ts.ssqStepL[g] += c.stepLength * c.stepLength; - ts.sumRho[g] += c.rho; ts.ssqRho[g] += c.rho * c.rho; - // settlement traits - settleTraits s = inds[i]->getSettTraits(); - if (sett.sexDep) g = sex; else g = 0; -// g = 0; // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT - ts.sumS0[g] += s.s0; ts.ssqS0[g] += s.s0 * s.s0; - ts.sumAlphaS[g] += s.alpha; ts.ssqAlphaS[g] += s.alpha * s.alpha; - ts.sumBetaS[g] += s.beta; ts.ssqBetaS[g] += s.beta * s.beta; -#if RSDEBUG -//DEBUGLOG << "Population::getTraits():" -// << " i=" << i << " g=" << g << " a=" << a -// << " e.d0= " << e.d0 << " e.alpha= " << e.alpha << " e.beta= " << e.beta -// << " mnd0= " << emigTraits[g]->mnD0 << " mnAlpha= " << emigTraits[g]->mnAlpha << " mnBeta= " << emigTraits[g]->mnBeta -// << " sqd0= " << emigTraits[g]->sqD0 << " sqAlpha= " << emigTraits[g]->sqAlpha << " sqBeta= " << emigTraits[g]->sqBeta -// << endl; -#endif -} + int ninds = (int)inds.size(); + for (int i = 0; i < ninds; i++) { + int sex = inds[i]->getSex(); + if (emig.sexDep || trfr.sexDep || sett.sexDep) g = sex; else g = 0; + ts.ninds[g] += 1; + // emigration traits + emigTraits e = inds[i]->getEmigTraits(); + if (emig.sexDep) g = sex; else g = 0; + ts.sumD0[g] += e.d0; ts.ssqD0[g] += e.d0 * e.d0; + ts.sumAlpha[g] += e.alpha; ts.ssqAlpha[g] += e.alpha * e.alpha; + ts.sumBeta[g] += e.beta; ts.ssqBeta[g] += e.beta * e.beta; + // transfer traits + trfrKernTraits k = inds[i]->getKernTraits(); + if (trfr.sexDep) g = sex; else g = 0; + ts.sumDist1[g] += k.meanDist1; ts.ssqDist1[g] += k.meanDist1 * k.meanDist1; + ts.sumDist2[g] += k.meanDist2; ts.ssqDist2[g] += k.meanDist2 * k.meanDist2; + ts.sumProp1[g] += k.probKern1; ts.ssqProp1[g] += k.probKern1 * k.probKern1; + trfrSMSTraits sms = inds[i]->getSMSTraits(); + g = 0; // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT + ts.sumDP[g] += sms.dp; ts.ssqDP[g] += sms.dp * sms.dp; + ts.sumGB[g] += sms.gb; ts.ssqGB[g] += sms.gb * sms.gb; + ts.sumAlphaDB[g] += sms.alphaDB; ts.ssqAlphaDB[g] += sms.alphaDB * sms.alphaDB; + ts.sumBetaDB[g] += sms.betaDB; ts.ssqBetaDB[g] += sms.betaDB * sms.betaDB; + trfrCRWTraits c = inds[i]->getCRWTraits(); + g = 0; // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT + ts.sumStepL[g] += c.stepLength; ts.ssqStepL[g] += c.stepLength * c.stepLength; + ts.sumRho[g] += c.rho; ts.ssqRho[g] += c.rho * c.rho; + // settlement traits + settleTraits s = inds[i]->getSettTraits(); + if (sett.sexDep) g = sex; else g = 0; + ts.sumS0[g] += s.s0; ts.ssqS0[g] += s.s0 * s.s0; + ts.sumAlphaS[g] += s.alpha; ts.ssqAlphaS[g] += s.alpha * s.alpha; + ts.sumBetaS[g] += s.beta; ts.ssqBetaS[g] += s.beta * s.beta; + } -return ts; + return ts; } int Population::getNInds(void) { return (int)inds.size(); } -popStats Population::getStats(void) +popStats Population::getStats(void) { -popStats p; -int ninds; -float fec; -bool breeders[2]; breeders[0] = breeders[1] = false; -demogrParams dem = pSpecies->getDemogr(); -p.pSpecies = pSpecies; -p.pPatch = pPatch; -p.spNum = pSpecies->getSpNum(); -p.nInds = (int)inds.size(); -p.nNonJuvs = p.nAdults = 0; -p.breeding = false; -#if RSDEBUG -//DEBUGLOG << "Population::getStats(): this=" << this -//// << " p.pSpecies=" << p.pSpecies << " p.spNum=" << p.spNum -// << " p.pPatch=" << p.pPatch << " patchNum=" << p.pPatch->getPatchNum() -// << " nStages=" << nStages << " nSexes=" << nSexes << " p.nInds=" << p.nInds -// << endl; -#endif -for (int stg = 1; stg < nStages; stg++) { - for (int sex = 0; sex < nSexes; sex++) { - ninds = nInds[stg][sex]; - p.nNonJuvs += ninds; -#if RSDEBUG -//DEBUGLOG << "Population::getStats(): this=" << this -// << " stg=" << stg << " sex=" << sex -// << " nInds[stg][sex]=" << nInds[stg][sex] << " p.nNonJuvs=" << p.nNonJuvs -// << endl; -#endif - if (ninds > 0) { - if (pSpecies->stageStructured()) { - if (dem.repType == 2) fec = pSpecies->getFec(stg,sex); - else fec = pSpecies->getFec(stg,0); - if (fec > 0.0) { breeders[sex] = true; p.nAdults += ninds; } + popStats p; + int ninds; + float fec; + bool breeders[2]; breeders[0] = breeders[1] = false; + demogrParams dem = pSpecies->getDemogr(); + p.pSpecies = pSpecies; + p.pPatch = pPatch; + p.spNum = pSpecies->getSpNum(); + p.nInds = (int)inds.size(); + p.nNonJuvs = p.nAdults = 0; + p.breeding = false; + for (int stg = 1; stg < nStages; stg++) { + for (int sex = 0; sex < nSexes; sex++) { + ninds = nInds[stg][sex]; + p.nNonJuvs += ninds; + + if (ninds > 0) { + if (pSpecies->stageStructured()) { + if (dem.repType == 2) fec = pSpecies->getFec(stg, sex); + else fec = pSpecies->getFec(stg, 0); + if (fec > 0.0) { breeders[sex] = true; p.nAdults += ninds; } + } + else breeders[sex] = true; } - else breeders[sex] = true; } } -} -// is there a breeding population present? -if (nSexes == 1) { - p.breeding = breeders[0]; -} -else { - if (breeders[0] && breeders[1]) p.breeding = true; -} -#if RSDEBUG -//DEBUGLOG << "Population::getStats(): this=" << this -// << " p.nInds=" << p.nInds << " p.nAdults=" << p.nAdults << " p.nNonJuvs=" << p.nNonJuvs -// << " breeders[0]=" << breeders[0] << " breeders[1]=" << breeders[1] -// << " p.breeding=" << p.breeding -// << endl; -#endif -return p; + // is there a breeding population present? + if (nSexes == 1) { + p.breeding = breeders[0]; + } + else { + if (breeders[0] && breeders[1]) p.breeding = true; + } + return p; } Species* Population::getSpecies(void) { return pSpecies; } int Population::totalPop(void) { -int t = 0; -for (int stg = 0; stg < nStages; stg++) { - for (int sex = 0; sex < nSexes; sex++) { - t += nInds[stg][sex]; -#if RSDEBUG -//DEBUGLOG << "Population::totalPop(): this=" << this -// << " stg=" << stg << " sex=" << sex -// << " nInds[stg][sex]=" << nInds[stg][sex] << " t=" << t -// << endl; -#endif + int t = 0; + for (int stg = 0; stg < nStages; stg++) { + for (int sex = 0; sex < nSexes; sex++) { + t += nInds[stg][sex]; + } } -} -return t; + return t; } int Population::stagePop(int stg) { -int t = 0; -if (stg < 0 || stg >= nStages) return t; -for (int sex = 0; sex < nSexes; sex++) { - t += nInds[stg][sex]; -} -return t; + int t = 0; + if (stg < 0 || stg >= nStages) return t; + for (int sex = 0; sex < nSexes; sex++) { + t += nInds[stg][sex]; + } + return t; } //--------------------------------------------------------------------------- // Remove all Individuals void Population::extirpate(void) { -int ninds = (int)inds.size(); -for (int i = 0; i < ninds; i++) { - if (inds[i] != NULL) delete inds[i]; -} -inds.clear(); -int njuvs = (int)juvs.size(); -for (int i = 0; i < njuvs; i++) { - if (juvs[i] != NULL) delete juvs[i]; -} -juvs.clear(); -for (int sex = 0; sex < nSexes; sex++) { - for (int stg = 0; stg < nStages; stg++) { - nInds[stg][sex] = 0; + int ninds = (int)inds.size(); + for (int i = 0; i < ninds; i++) { + if (inds[i] != NULL) delete inds[i]; + } + inds.clear(); + int njuvs = (int)juvs.size(); + for (int i = 0; i < njuvs; i++) { + if (juvs[i] != NULL) delete juvs[i]; + } + juvs.clear(); + for (int sex = 0; sex < nSexes; sex++) { + for (int stg = 0; stg < nStages; stg++) { + nInds[stg][sex] = 0; + } } -} } //--------------------------------------------------------------------------- // Produce juveniles and hold them in the juvs vector -void Population::reproduction(const float localK,const float envval,const int resol) +void Population::reproduction(const float localK, const float envval, const int resol) { -// get population size at start of reproduction -int ninds = (int)inds.size(); -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): this=" << this -// << " ninds=" << ninds -// << endl; -#endif // RSDEBUG -if (ninds == 0) return; - -int nsexes,stage,sex,njuvs,nj,nmales,nfemales; -Cell *pCell; -indStats ind; -double expected; -bool skipbreeding; - -//envGradParams grad = paramsGrad->getGradient(); -envStochParams env = paramsStoch->getStoch(); -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -genomeData gen = pSpecies->getGenomeData(); -simView v = paramsSim->getViews(); - -if (dem.repType == 0) nsexes = 1; else nsexes = 2; + // get population size at start of reproduction + int ninds = (int)inds.size(); + if (ninds == 0) return; -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): this=" << this -// << " pSpecies=" << pSpecies -// << " localK=" << localK << " envval=" << envval << " resol=" << resol -// << " sstruct.nStages=" << sstruct.nStages << " nsexes=" << nsexes << " ninds=" << ninds -// << endl; -#endif + int nsexes, stage, sex, njuvs, nj, nmales, nfemales; + Cell* pCell; + indStats ind; + double expected; + bool skipbreeding; -// set up local copy of species fecundity table -float fec[NSTAGES][NSEXES]; -for (int stg = 0; stg < sstruct.nStages; stg++) { - for (int sex = 0; sex < nsexes; sex++) { - if (dem.stageStruct) { - if (dem.repType == 1) { // simple sexual model - // both sexes use fecundity recorded for females - fec[stg][sex] = pSpecies->getFec(stg,0); + envStochParams env = paramsStoch->getStoch(); + demogrParams dem = pSpecies->getDemogr(); + stageParams sstruct = pSpecies->getStage(); + emigRules emig = pSpecies->getEmig(); + trfrRules trfr = pSpecies->getTrfr(); + settleType sett = pSpecies->getSettle(); + genomeData gen = pSpecies->getGenomeData(); + simView v = paramsSim->getViews(); + + if (dem.repType == 0) nsexes = 1; else nsexes = 2; + + // set up local copy of species fecundity table + float fec[NSTAGES][NSEXES]; + for (int stg = 0; stg < sstruct.nStages; stg++) { + for (int sex = 0; sex < nsexes; sex++) { + if (dem.stageStruct) { + if (dem.repType == 1) { // simple sexual model + // both sexes use fecundity recorded for females + fec[stg][sex] = pSpecies->getFec(stg, 0); + } + else fec[stg][sex] = pSpecies->getFec(stg, sex); + } + else { // non-structured population + if (stg == 1) fec[stg][sex] = dem.lambda; // adults + else fec[stg][sex] = 0.0; // juveniles } - else - fec[stg][sex] = pSpecies->getFec(stg,sex); -// if (sex == 0 && fec[stg][sex] > dem.lambda) dem.lambda = fec[stg][sex]; - } - else { // non-structured population - if (stg == 1) fec[stg][sex] = dem.lambda; // adults - else fec[stg][sex] = 0.0; // juveniles } -#if RSDEBUG -//if (ninds > 0) { -//DEBUGLOG << "Population::reproduction(): fec[" << stg << "][" << sex << "] = " << fec[stg][sex] -// << endl; -//} -#endif } -} -if (dem.stageStruct) { -#if RSDEBUG -//if (ninds > 0) { -// DEBUGLOG << "Population::reproduction(): ninds=" << ninds << " localK=" << localK -// << " effect of density dependence:" << endl; -//} -#endif - // apply environmental effects and density dependence - // to all non-zero female non-juvenile stages - for (int stg = 1; stg < nStages; stg++) { - if (fec[stg][0] > 0.0) { - // apply any effect of environmental gradient and/or stochasticty - fec[stg][0] *= envval; - if (env.stoch && !env.inK) { - // fecundity (at low density) is constrained to lie between limits specified - // for the species - float limit; - limit = pSpecies->getMinMax(0); - if (fec[stg][0] < limit) fec[stg][0] = limit; - limit = pSpecies->getMinMax(1); - if (fec[stg][0] > limit) fec[stg][0] = limit; - } - if (sstruct.fecDens) { // apply density dependence - float effect = 0.0; - if (sstruct.fecStageDens) { // stage-specific density dependence - // NOTE: matrix entries represent effect of ROW on COLUMN - // AND males precede females - float weight = 0.0; - for (int effstg = 0; effstg < nStages; effstg++) { - for (int effsex = 0; effsex < nSexes; effsex++) { - if (dem.repType == 2) { - if (effsex == 0) weight = pSpecies->getDDwtFec(2*stg+1,2*effstg+1); - else weight = pSpecies->getDDwtFec(2*stg+1,2*effstg); - } - else { - weight = pSpecies->getDDwtFec(stg,effstg); + if (dem.stageStruct) { + // apply environmental effects and density dependence + // to all non-zero female non-juvenile stages + for (int stg = 1; stg < nStages; stg++) { + if (fec[stg][0] > 0.0) { + // apply any effect of environmental gradient and/or stochasticty + fec[stg][0] *= envval; + if (env.stoch && !env.inK) { + // fecundity (at low density) is constrained to lie between limits specified + // for the species + float limit; + limit = pSpecies->getMinMax(0); + if (fec[stg][0] < limit) fec[stg][0] = limit; + limit = pSpecies->getMinMax(1); + if (fec[stg][0] > limit) fec[stg][0] = limit; + } + if (sstruct.fecDens) { // apply density dependence + float effect = 0.0; + if (sstruct.fecStageDens) { // stage-specific density dependence + // NOTE: matrix entries represent effect of ROW on COLUMN + // AND males precede females + float weight = 0.0; + for (int effstg = 0; effstg < nStages; effstg++) { + for (int effsex = 0; effsex < nSexes; effsex++) { + if (dem.repType == 2) { + if (effsex == 0) weight = pSpecies->getDDwtFec(2 * stg + 1, 2 * effstg + 1); + else weight = pSpecies->getDDwtFec(2 * stg + 1, 2 * effstg); + } + else { + weight = pSpecies->getDDwtFec(stg, effstg); + } + effect += (float)nInds[effstg][effsex] * weight; } - effect += (float)nInds[effstg][effsex] * weight; -#if RSDEBUG -//if (ninds > 0) { -// DEBUGLOG << " effstg=" << effstg << " effsex=" << effsex << " nInds=" << nInds[effstg][effsex]; -// DEBUGLOG << " weight=" << weight << " effect=" << effect -// << endl; -//} -#endif } } + else // not stage-specific + effect = (float)totalPop(); + if (localK > 0.0) fec[stg][0] *= exp(-effect / localK); } - else // not stage-specific - effect = (float)totalPop(); - if (localK > 0.0) fec[stg][0] *= exp(-effect/localK); -#if RSDEBUG -//if (ninds > 0) { -// DEBUGLOG << " eff popn=" << effect << " exponential=" << exp(-effect/localK); -// DEBUGLOG << " fec[" << stg << "][0]=" << fec[stg][0] -// << endl; -//} -#endif } } } -} -else { // non-structured - set fecundity for adult females only - // apply any effect of environmental gradient and/or stochasticty - fec[1][0] *= envval; - if (env.stoch && !env.inK) { - // fecundity (at low density) is constrained to lie between limits specified - // for the species - float limit; - limit = pSpecies->getMinMax(0); - if (fec[1][0] < limit) fec[1][0] = limit; - limit = pSpecies->getMinMax(1); - if (fec[1][0] > limit) fec[1][0] = limit; - } - // apply density dependence - if (localK > 0.0) { -//#if GOBYMODEL -// ddeffect[1] = (float)ninds/localK; -//#else - if (dem.repType == 1 || dem.repType == 2) { // sexual model - // apply factor of 2 (as in manual, eqn. 6) - fec[1][0] *= 2.0; + else { // non-structured - set fecundity for adult females only + // apply any effect of environmental gradient and/or stochasticty + fec[1][0] *= envval; + if (env.stoch && !env.inK) { + // fecundity (at low density) is constrained to lie between limits specified + // for the species + float limit; + limit = pSpecies->getMinMax(0); + if (fec[1][0] < limit) fec[1][0] = limit; + limit = pSpecies->getMinMax(1); + if (fec[1][0] > limit) fec[1][0] = limit; } - fec[1][0] /= (1.0f + fabs(dem.lambda-1.0f)*pow(((float)ninds/localK),dem.bc)); -//#endif - } -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): dem.lambda=" << dem.lambda << " ninds=" << ninds -// << " localK=" << localK << " dem.bc=" << dem.bc << " fec[1][0]=" << fec[1][0] -// << endl; -#endif -} - -double propBreed; -Individual *father; -std::vector fathers; - -switch (dem.repType) { - -case 0: // asexual model - for (int i = 0; i < ninds; i++) { - stage = inds[i]->breedingFem(); -#if RSDEBUG -//DEBUGLOG << "Population::reproduction():" -// << " i=" << i << " ID=" << inds[i]->getId() << " stage=" << stage -// << endl; -#endif - if (stage > 0) { // female of breeding age - if (dem.stageStruct) { - // determine whether she must miss current breeding attempt - ind = inds[i]->getStats(); - if (ind.fallow >= sstruct.repInterval) { - if (pRandom->Bernoulli(sstruct.probRep)) skipbreeding = false; - else skipbreeding = true; - } - else skipbreeding = true; // cannot breed this time - } - else skipbreeding = false; // not structured - always breed - if (skipbreeding) { - inds[i]->incFallow(); - } - else { // attempt to breed - inds[i]->resetFallow(); - expected = fec[stage][0]; - if (expected <= 0.0) njuvs = 0; - else njuvs = pRandom->Poisson(expected); - nj = (int)juvs.size(); - pCell = pPatch->getRandomCell(); - for (int j = 0; j < njuvs; j++) { -#if RSDEBUG - // NOTE: CURRENTLY SETTING ALL INDIVIDUALS TO RECORD NO. OF STEPS ... - juvs.push_back(new Individual(pCell,pPatch,0,0,0,0.0,true,trfr.moveType)); -#else - juvs.push_back(new Individual(pCell,pPatch,0,0,0,0.0,trfr.moveModel,trfr.moveType)); -#endif - nInds[0][0]++; - if (emig.indVar || trfr.indVar || sett.indVar || gen.neutralMarkers) - { - // juv inherits genome from parent (mother) - juvs[nj+j]->setGenes(pSpecies,inds[i],0,resol); - } - } + // apply density dependence + if (localK > 0.0) { + if (dem.repType == 1 || dem.repType == 2) { // sexual model + // apply factor of 2 (as in manual, eqn. 6) + fec[1][0] *= 2.0; } + fec[1][0] /= (1.0f + fabs(dem.lambda - 1.0f) * pow(((float)ninds / localK), dem.bc)); } } - break; -case 1: // simple sexual model -case 2: // complex sexual model - // count breeding females and males - // add breeding males to list of potential fathers -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): case 1:" -// << " fec[1][0]=" << fec[1][0] << " fec[1][1]=" << fec[1][1] -// << endl; -#endif - nfemales = nmales = 0; - for (int i = 0; i < ninds; i++) { - ind = inds[i]->getStats(); - if (ind.sex == 0 && fec[ind.stage][0] > 0.0) nfemales++; - if (ind.sex == 1 && fec[ind.stage][1] > 0.0) { - fathers.push_back(inds[i]); - nmales++; -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): i=" << i << " nmales=" << nmales -// << " inds[i]=" << inds[i] << endl; -#endif - } - } -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): breeding nfemales=" << nfemales -// << " breeding nmales=" << nmales << endl; -#endif - if (nfemales > 0 && nmales > 0) - { // population can breed - if (dem.repType == 2) { // complex sexual model - // calculate proportion of eligible females which breed - propBreed = (2.0*dem.harem*nmales)/(nfemales+dem.harem*nmales); - if (propBreed > 1.0) propBreed = 1.0; -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): harem=" << dem.harem -// << " nfemales=" << nfemales << " nmales=" << nmales << " propBreed=" << propBreed -// << endl; -#endif - } - else propBreed = 1.0; + double propBreed; + Individual* father; + std::vector fathers; + + switch (dem.repType) { + + case 0: // asexual model for (int i = 0; i < ninds; i++) { stage = inds[i]->breedingFem(); - if (stage > 0 && fec[stage][0] > 0.0) { // (potential) breeding female + if (stage > 0) { // female of breeding age if (dem.stageStruct) { // determine whether she must miss current breeding attempt ind = inds[i]->getStats(); @@ -694,685 +481,568 @@ case 2: // complex sexual model } else { // attempt to breed inds[i]->resetFallow(); - // NOTE: FOR COMPLEX SEXUAL MODEL, NO. OF FEMALES *ACTUALLY* BREEDING DOES NOT - // NECESSARILY EQUAL THE EXPECTED NO. FROM EQN. 7 IN THE MANUAL... - if (pRandom->Bernoulli(propBreed)) { - expected = fec[stage][0]; // breeds -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): THIS LINE SHOULD NOT APPEAR FOR GOBY MODEL" -// << " expected=" << expected -// << endl; -#endif - } - else expected = 0.0; // fails to breed + expected = fec[stage][0]; if (expected <= 0.0) njuvs = 0; else njuvs = pRandom->Poisson(expected); + nj = (int)juvs.size(); + pCell = pPatch->getRandomCell(); + for (int j = 0; j < njuvs; j++) { #if RSDEBUG -//DEBUGLOG << "Population::reproduction():" -// << " i " << i << " ID=" << inds[i]->getId() << " stage=" << stage -// << " expected=" << expected << " njuvs=" << njuvs << endl; + // NOTE: CURRENTLY SETTING ALL INDIVIDUALS TO RECORD NO. OF STEPS ... + juvs.push_back(new Individual(pCell, pPatch, 0, 0, 0, 0.0, true, trfr.moveType)); +#else + juvs.push_back(new Individual(pCell, pPatch, 0, 0, 0, 0.0, trfr.moveModel, trfr.moveType)); #endif - if (njuvs > 0) - { - nj = (int)juvs.size(); + nInds[0][0]++; + if (emig.indVar || trfr.indVar || sett.indVar || gen.neutralMarkers) + { + // juv inherits genome from parent (mother) + juvs[nj + j]->setGenes(pSpecies, inds[i], 0, resol); + } + } + } + } + } + break; + + case 1: // simple sexual model + case 2: // complex sexual model + // count breeding females and males + // add breeding males to list of potential fathers + + nfemales = nmales = 0; + for (int i = 0; i < ninds; i++) { + ind = inds[i]->getStats(); + if (ind.sex == 0 && fec[ind.stage][0] > 0.0) nfemales++; + if (ind.sex == 1 && fec[ind.stage][1] > 0.0) { + fathers.push_back(inds[i]); + nmales++; + } + } + if (nfemales > 0 && nmales > 0) + { // population can breed + if (dem.repType == 2) { // complex sexual model + // calculate proportion of eligible females which breed + propBreed = (2.0 * dem.harem * nmales) / (nfemales + dem.harem * nmales); + if (propBreed > 1.0) propBreed = 1.0; + } + else propBreed = 1.0; + for (int i = 0; i < ninds; i++) { + stage = inds[i]->breedingFem(); + if (stage > 0 && fec[stage][0] > 0.0) { // (potential) breeding female + if (dem.stageStruct) { + // determine whether she must miss current breeding attempt + ind = inds[i]->getStats(); + if (ind.fallow >= sstruct.repInterval) { + if (pRandom->Bernoulli(sstruct.probRep)) skipbreeding = false; + else skipbreeding = true; + } + else skipbreeding = true; // cannot breed this time + } + else skipbreeding = false; // not structured - always breed + if (skipbreeding) { + inds[i]->incFallow(); + } + else { // attempt to breed + inds[i]->resetFallow(); + // NOTE: FOR COMPLEX SEXUAL MODEL, NO. OF FEMALES *ACTUALLY* BREEDING DOES NOT + // NECESSARILY EQUAL THE EXPECTED NO. FROM EQN. 7 IN THE MANUAL... + if (pRandom->Bernoulli(propBreed)) { + expected = fec[stage][0]; // breeds + } + else expected = 0.0; // fails to breed + if (expected <= 0.0) njuvs = 0; + else njuvs = pRandom->Poisson(expected); + if (njuvs > 0) + { + nj = (int)juvs.size(); // select father at random from breeding males ... int rrr = 0; - if (nmales > 1) rrr = pRandom->IRandom(0,nmales-1); + if (nmales > 1) rrr = pRandom->IRandom(0, nmales - 1); father = fathers[rrr]; -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): i = " << i << " rrr = " << rrr -// << " father = " << father << endl; -#endif pCell = pPatch->getRandomCell(); for (int j = 0; j < njuvs; j++) { #if RSDEBUG // NOTE: CURRENTLY SETTING ALL INDIVIDUALS TO RECORD NO. OF STEPS ... - juvs.push_back(new Individual(pCell,pPatch,0,0,0,dem.propMales,true,trfr.moveType)); + juvs.push_back(new Individual(pCell, pPatch, 0, 0, 0, dem.propMales, true, trfr.moveType)); #else - juvs.push_back(new Individual(pCell,pPatch,0,0,0,dem.propMales,trfr.moveModel,trfr.moveType)); + juvs.push_back(new Individual(pCell, pPatch, 0, 0, 0, dem.propMales, trfr.moveModel, trfr.moveType)); #endif - sex = juvs[nj+j]->getSex(); + sex = juvs[nj + j]->getSex(); nInds[0][sex]++; if (emig.indVar || trfr.indVar || sett.indVar || gen.neutralMarkers) { // juv inherits genome from parents - juvs[nj+j]->setGenes(pSpecies,inds[i],father,resol); + juvs[nj + j]->setGenes(pSpecies, inds[i], father, resol); } } + } } } } } - } - fathers.clear(); - break; - -} // end of switch (dem.repType) + fathers.clear(); + break; -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): before reprodn. " << " inds.size() = " << inds.size() -// << endl; -#endif + } // end of switch (dem.repType) // THIS MAY NOT BE CORRECT FOR MULTIPLE SPECIES IF THERE IS SOME FORM OF // CROSS-SPECIES DENSITY-DEPENDENT FECUNDITY - -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): after reprodn. this = " << this -// << " juvs.size() = " << juvs.size() << " inds.size() = " << inds.size() -// << endl; -#endif - } // Following reproduction of ALL species, add juveniles to the population prior to dispersal void Population::fledge(void) { -#if RSDEBUG -//DEBUGLOG << "Population::fledge(): this=" << this -// << " ninds=" << (int)inds.size() -// << " njuvs=" << (int)juvs.size() -// << endl; -#endif -demogrParams dem = pSpecies->getDemogr(); + demogrParams dem = pSpecies->getDemogr(); -if (dem.stageStruct) { // juveniles are added to the individuals vector - inds.insert(inds.end(),juvs.begin(),juvs.end()); -// nInds += nJuvs; nJuvs = 0; -} -else { // all adults die and juveniles replace adults - int ninds = (int)inds.size(); - for (int i = 0; i < ninds; i++) { - delete inds[i]; + if (dem.stageStruct) { // juveniles are added to the individuals vector + inds.insert(inds.end(), juvs.begin(), juvs.end()); } - inds.clear(); - for (int sex = 0; sex < nSexes; sex++) { - nInds[1][sex] = 0; // set count of adults to zero + else { // all adults die and juveniles replace adults + int ninds = (int)inds.size(); + for (int i = 0; i < ninds; i++) { + delete inds[i]; + } + inds.clear(); + for (int sex = 0; sex < nSexes; sex++) { + nInds[1][sex] = 0; // set count of adults to zero + } + inds = juvs; } - inds = juvs; -} -juvs.clear(); + juvs.clear(); } // Determine which individuals will disperse void Population::emigration(float localK) { -int nsexes; -double disp,Pdisp,NK; -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -emigRules emig = pSpecies->getEmig(); -emigTraits eparams; -trfrRules trfr = pSpecies->getTrfr(); -indStats ind; -#if RSDEBUG -//DEBUGLOG << "Population::emigration(): this=" << this -// << " nStages=" << sstruct.nStages -//// << " emig.emigGenes[0]=" << emig.emigGenes[0] -//// << " emig.emigGenes[1]=" << emig.emigGenes[1] -// << endl; -#endif + int nsexes; + double disp, Pdisp, NK; + demogrParams dem = pSpecies->getDemogr(); + stageParams sstruct = pSpecies->getStage(); + emigRules emig = pSpecies->getEmig(); + emigTraits eparams; + trfrRules trfr = pSpecies->getTrfr(); + indStats ind; // to avoid division by zero, assume carrying capacity is at least one individual // localK can be zero if there is a moving gradient or stochasticity in K -if (localK < 1.0) localK = 1.0; -NK = (float)totalPop() / localK; + if (localK < 1.0) localK = 1.0; + NK = (float)totalPop() / localK; -int ninds = (int)inds.size(); + int ninds = (int)inds.size(); -// set up local copy of emigration probability table -// used when there is no individual variability -// NB - IT IS DOUBTFUL THIS CONTRIBUTES ANY SUBSTANTIAL TIME SAVING -if (dem.repType == 0) nsexes = 1; else nsexes = 2; -double Pemig[NSTAGES][NSEXES]; + // set up local copy of emigration probability table + // used when there is no individual variability + // NB - IT IS DOUBTFUL THIS CONTRIBUTES ANY SUBSTANTIAL TIME SAVING + if (dem.repType == 0) nsexes = 1; else nsexes = 2; + double Pemig[NSTAGES][NSEXES]; -for (int stg = 0; stg < sstruct.nStages; stg++) { - for (int sex = 0; sex < nsexes; sex++) { - if (emig.indVar) Pemig[stg][sex] = 0.0; - else { - if (emig.densDep) { - if (emig.sexDep) { - if (emig.stgDep) { - eparams = pSpecies->getEmigTraits(stg,sex); + for (int stg = 0; stg < sstruct.nStages; stg++) { + for (int sex = 0; sex < nsexes; sex++) { + if (emig.indVar) Pemig[stg][sex] = 0.0; + else { + if (emig.densDep) { + if (emig.sexDep) { + if (emig.stgDep) { + eparams = pSpecies->getEmigTraits(stg, sex); + } + else { + eparams = pSpecies->getEmigTraits(0, sex); + } } - else { - eparams = pSpecies->getEmigTraits(0,sex); + else { // !emig.sexDep + if (emig.stgDep) { + eparams = pSpecies->getEmigTraits(stg, 0); + } + else { + eparams = pSpecies->getEmigTraits(0, 0); + } } - } - else { // !emig.sexDep - if (emig.stgDep) { - eparams = pSpecies->getEmigTraits(stg,0); - } - else { - eparams = pSpecies->getEmigTraits(0,0); - } - } - Pemig[stg][sex] = eparams.d0/(1.0+exp(-(NK - eparams.beta)*eparams.alpha)); -#if RSDEBUG -//if (ppLand.patch_model) { -// DEBUGLOG << "Population::emigration(): stg=" << stg << " sex=" << sex -// << " totalPop=" << totalPop() << " localK=" << localK << " NK=" << NK -// << " d0=" << eparams.d0 << " beta=" << eparams.beta << " alpha=" << eparams.alpha -// << " Pemig[stg][sex]=" << Pemig[stg][sex] -// << endl; -//} -#endif - } - else { // density-independent - if (emig.sexDep) { - if (emig.stgDep) { - Pemig[stg][sex] = pSpecies->getEmigD0(stg,sex); - } - else { // !emig.stgDep - Pemig[stg][sex] = pSpecies->getEmigD0(0,sex); - } - } - else { // !emig.sexDep - if (emig.stgDep) { - Pemig[stg][sex] = pSpecies->getEmigD0(stg,0); - } - else { // !emig.stgDep - Pemig[stg][sex] = pSpecies->getEmigD0(0,0); - } - } - } - } // end of !emig.indVar -#if RSDEBUG -//DEBUGLOG << "Population::emigration(): this=" << (int)this -// << " totalPop()=" << totalPop() -// << " Pemig[" << stg << "][" << sex << "]="<< Pemig[stg][sex] << endl; -#endif - } -} - -//#if GROUPDISP -//bool newgroup = true; -//int currentsize = 0; -//#endif // GROUPDISP - -//#if PARTMIGRN -//double cumprop[7]; -//cumprop[0] = 0.0; -//for (int i = 1; i < 7; i++) { -// cumprop[i] = cumprop[i-1] + pSpecies->getPropDispMigrn(i); -//#if RSDEBUG -//DEBUGLOG << "Population::emigration(): i=" << i -// << " cumprop[i]=" << cumprop[i] -// << endl; -//#endif -//} -//#endif // PARTMIGRN -// - -for (int i = 0; i < ninds; i++) { - ind = inds[i]->getStats(); - if (ind.status < 1) - { - if (emig.indVar) { // individual variability in emigration - if (dem.stageStruct && ind.stage != emig.emigStage) { - // emigration may not occur - Pdisp = 0.0; - } - else { // non-structured or individual is in emigration stage - eparams = inds[i]->getEmigTraits(); - if (emig.densDep) { // density-dependent - NK = (float)totalPop() / localK; - Pdisp = eparams.d0/(1.0+exp(-(NK - eparams.beta)*eparams.alpha)); + Pemig[stg][sex] = eparams.d0 / (1.0 + exp(-(NK - eparams.beta) * eparams.alpha)); } else { // density-independent if (emig.sexDep) { - Pdisp = Pemig[0][ind.sex] + eparams.d0; + if (emig.stgDep) { + Pemig[stg][sex] = pSpecies->getEmigD0(stg, sex); + } + else { // !emig.stgDep + Pemig[stg][sex] = pSpecies->getEmigD0(0, sex); + } } - else { - Pdisp = Pemig[0][0] + eparams.d0; + else { // !emig.sexDep + if (emig.stgDep) { + Pemig[stg][sex] = pSpecies->getEmigD0(stg, 0); + } + else { // !emig.stgDep + Pemig[stg][sex] = pSpecies->getEmigD0(0, 0); + } } } - } - } // end of individual variability - else { // no individual variability + } // end of !emig.indVar + } + } - if (emig.densDep) { - if (emig.sexDep) { - if (emig.stgDep) { - Pdisp = Pemig[ind.stage][ind.sex]; - } - else { - Pdisp = Pemig[0][ind.sex]; - } + for (int i = 0; i < ninds; i++) { + ind = inds[i]->getStats(); + if (ind.status < 1) + { + if (emig.indVar) { // individual variability in emigration + if (dem.stageStruct && ind.stage != emig.emigStage) { + // emigration may not occur + Pdisp = 0.0; } - else { // !emig.sexDep - if (emig.stgDep) { - Pdisp = Pemig[ind.stage][0]; + else { // non-structured or individual is in emigration stage + eparams = inds[i]->getEmigTraits(); + if (emig.densDep) { // density-dependent + NK = (float)totalPop() / localK; + Pdisp = eparams.d0 / (1.0 + exp(-(NK - eparams.beta) * eparams.alpha)); } - else { - Pdisp = Pemig[0][0]; + else { // density-independent + if (emig.sexDep) { + Pdisp = Pemig[0][ind.sex] + eparams.d0; + } + else { + Pdisp = Pemig[0][0] + eparams.d0; + } } } -#if RSDEBUG -//if (ppLand.patch_model) { -// DEBUGLOG << "Population::emigration(): i=" << i << " sex=" << ind.sex << " stage=" << ind.stage -// << " totalPop=" << totalPop() << " localK=" << localK << " NK=" << NK -// << " Pdisp=" << Pdisp -// << endl; -//} -#endif - } - else { // density-independent - if (emig.sexDep) { - if (emig.stgDep) { - Pdisp = Pemig[ind.stage][ind.sex]; + } // end of individual variability + else { // no individual variability + + if (emig.densDep) { + if (emig.sexDep) { + if (emig.stgDep) { + Pdisp = Pemig[ind.stage][ind.sex]; + } + else { + Pdisp = Pemig[0][ind.sex]; + } } - else { // !emig.stgDep - Pdisp = Pemig[0][ind.sex]; + else { // !emig.sexDep + if (emig.stgDep) { + Pdisp = Pemig[ind.stage][0]; + } + else { + Pdisp = Pemig[0][0]; + } } } - else { // !emig.sexDep - if (emig.stgDep) { - Pdisp = Pemig[ind.stage][0]; + else { // density-independent + if (emig.sexDep) { + if (emig.stgDep) { + Pdisp = Pemig[ind.stage][ind.sex]; + } + else { // !emig.stgDep + Pdisp = Pemig[0][ind.sex]; + } } - else { // !emig.stgDep - Pdisp = Pemig[0][0]; + else { // !emig.sexDep + if (emig.stgDep) { + Pdisp = Pemig[ind.stage][0]; + } + else { // !emig.stgDep + Pdisp = Pemig[0][0]; + } } } -//#if GROUPDISP -// if (emig.groupdisp) { -// if (Pdisp > 0) { -// -// } -// -// } -//#endif // GROUPDISP - } - - } // end of no individual variability - disp = pRandom->Bernoulli(Pdisp); -#if RSDEBUG -//DEBUGLOG << "Population::emigration(): i=" << i << " sex=" << ind.sex << " stage=" << ind.stage -// << " Pdisp=" << Pdisp << " disp=" << disp << endl; -#endif + } // end of no individual variability - if (disp == 1) { // emigrant - inds[i]->setStatus(1); - } - } // end of if (ind.status < 1) condition -} // end of for loop + disp = pRandom->Bernoulli(Pdisp); + + if (disp == 1) { // emigrant + inds[i]->setStatus(1); + } + } // end of if (ind.status < 1) condition + } // end of for loop } // All individuals emigrate after patch destruction void Population::allEmigrate(void) { -int ninds = (int)inds.size(); -for (int i = 0; i < ninds; i++) { - inds[i]->setStatus(1); -} + int ninds = (int)inds.size(); + for (int i = 0; i < ninds; i++) { + inds[i]->setStatus(1); + } } // If an Individual has been identified as an emigrant, remove it from the Population disperser Population::extractDisperser(int ix) { -disperser d; -indStats ind = inds[ix]->getStats(); -#if RSDEBUG -//if (ind.status > 0) { -// DEBUGLOG << "Population::extractDisperser(): ix = " << ix << " inds[ix] = " << inds[ix] -// << " indId = " << inds[ix]->getId() << " ind.status = " << ind.status -// << endl; -//} -#endif -if (ind.status == 1) { // emigrant - d.pInd = inds[ix]; d.yes = true; - inds[ix] = 0; - nInds[ind.stage][ind.sex]--; -} -else { - d.pInd = NULL; d.yes = false; -} -return d; + disperser d; + indStats ind = inds[ix]->getStats(); + if (ind.status == 1) { // emigrant + d.pInd = inds[ix]; d.yes = true; + inds[ix] = 0; + nInds[ind.stage][ind.sex]--; + } + else { + d.pInd = NULL; d.yes = false; + } + return d; } // For an individual identified as being in the matrix population: // if it is a settler, return its new location and remove it from the current population // otherwise, leave it in the matrix population for possible reporting before deletion disperser Population::extractSettler(int ix) { -disperser d; -Cell* pCell; -//Patch* pPatch; + disperser d; + Cell* pCell; -indStats ind = inds[ix]->getStats(); + indStats ind = inds[ix]->getStats(); -pCell = inds[ix]->getLocn(1); -#if RSDEBUG -//DEBUGLOG << "Population::extractSettler(): ix = " << ix << " inds[ix] = " << inds[ix] -// << " indId = " << inds[ix]->getId() << " ind.status = " << ind.status << endl; -#endif -d.pInd = inds[ix]; d.pCell = pCell; d.yes = false; -if (ind.status == 4 || ind.status == 5) { // settled - d.yes = true; - inds[ix] = 0; - nInds[ind.stage][ind.sex]--; -} -return d; + pCell = inds[ix]->getLocn(1); + d.pInd = inds[ix]; d.pCell = pCell; d.yes = false; + if (ind.status == 4 || ind.status == 5) { // settled + d.yes = true; + inds[ix] = 0; + nInds[ind.stage][ind.sex]--; + } + return d; } // Add a specified individual to the new/current dispersal group // Add a specified individual to the population -void Population::recruit(Individual *pInd) { -inds.push_back(pInd); -indStats ind = pInd->getStats(); -nInds[ind.stage][ind.sex]++; -#if RSDEBUG -//DEBUGLOG << "Population::recruit(): patchNum=" << pPatch->getPatchNum() -// << " indId=" << pInd->getId() -// << " nInds[" << ind.stage << "][" << ind.sex << "]=" << nInds[ind.stage][ind.sex] -// << endl; -#endif +void Population::recruit(Individual* pInd) { + inds.push_back(pInd); + indStats ind = pInd->getStats(); + nInds[ind.stage][ind.sex]++; } //--------------------------------------------------------------------------- // Transfer is run for populations in the matrix only #if RS_RCPP // included also SEASONAL -int Population::transfer(Landscape *pLandscape,short landIx,short nextseason) +int Population::transfer(Landscape* pLandscape, short landIx, short nextseason) #else -int Population::transfer(Landscape *pLandscape,short landIx) +int Population::transfer(Landscape* pLandscape, short landIx) #endif { -int ndispersers = 0; -int disperser; -short othersex; -bool mateOK,densdepOK; -intptr patch,popn; -int patchnum; -double localK,popsize,settprob; -Patch *pPatch = 0; -Cell *pCell = 0; -indStats ind; -Population *pNewPopn = 0; -locn newloc,nbrloc; - -landData ppLand = pLandscape->getLandData(); -short reptype = pSpecies->getRepType(); -trfrRules trfr = pSpecies->getTrfr(); -settleType settletype = pSpecies->getSettle(); -settleRules sett; -settleTraits settDD; -settlePatch settle; -simParams sim = paramsSim->getSim(); - -// each individual takes one step -// for dispersal by kernel, this should be the only step taken -int ninds = (int)inds.size(); -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 0000: ninds = " << ninds -// << " ndispersers = " << ndispersers << endl; -#endif -for (int i = 0; i < ninds; i++) { -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 1111: i = " << i << " ID = " << inds[i]->getId() -// << endl; -#endif - if (trfr.moveModel) { -#if RSDEBUG -//pCell = inds[i]->getLocn(1); -//locn loc = pCell->getLocn(); -//DEBUGLOG << "Population::transfer(): 1112: i = " << i << " ID = " << inds[i]->getId() -// << " before:" << " x = " << loc.x << " y = " << loc.y -// << endl; -#endif - disperser = inds[i]->moveStep(pLandscape,pSpecies,landIx,sim.absorbing); -#if RSDEBUG -//pCell = inds[i]->getLocn(1); -//newloc = pCell->getLocn(); -//DEBUGLOG << "Population::transfer(): 1113: i = " << i << " ID = " << inds[i]->getId() -// << " after: " << " x = " << newloc.x << " y = " << newloc.y -// << endl; -#endif - } - else { - disperser = inds[i]->moveKernel(pLandscape,pSpecies,reptype,sim.absorbing); - } - ndispersers += disperser; - if (disperser) { - if (reptype > 0) - { // sexual species - record as potential settler in new patch - if (inds[i]->getStatus() == 2) - { // disperser has found a patch - pCell = inds[i]->getLocn(1); - patch = pCell->getPatch(); - if (patch != 0) { // not no-data area - pPatch = (Patch*)patch; - pPatch->incrPossSettler(pSpecies,inds[i]->getSex()); + int ndispersers = 0; + int disperser; + short othersex; + bool mateOK, densdepOK; + intptr patch, popn; + int patchnum; + double localK, popsize, settprob; + Patch* pPatch = 0; + Cell* pCell = 0; + indStats ind; + Population* pNewPopn = 0; + locn newloc, nbrloc; + + landData ppLand = pLandscape->getLandData(); + short reptype = pSpecies->getRepType(); + trfrRules trfr = pSpecies->getTrfr(); + settleType settletype = pSpecies->getSettle(); + settleRules sett; + settleTraits settDD; + settlePatch settle; + simParams sim = paramsSim->getSim(); + + // each individual takes one step + // for dispersal by kernel, this should be the only step taken + int ninds = (int)inds.size(); + for (int i = 0; i < ninds; i++) { + if (trfr.moveModel) { + disperser = inds[i]->moveStep(pLandscape, pSpecies, landIx, sim.absorbing); + } + else { + disperser = inds[i]->moveKernel(pLandscape, pSpecies, reptype, sim.absorbing); + } + ndispersers += disperser; + if (disperser) { + if (reptype > 0) + { // sexual species - record as potential settler in new patch + if (inds[i]->getStatus() == 2) + { // disperser has found a patch + pCell = inds[i]->getLocn(1); + patch = pCell->getPatch(); + if (patch != 0) { // not no-data area + pPatch = (Patch*)patch; + pPatch->incrPossSettler(pSpecies, inds[i]->getSex()); + } } } } } -} -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 5555: ninds=" << ninds -// << " ndispersers=" << ndispersers << endl; -#endif // each individual which has reached a potential patch decides whether to settle -for (int i = 0; i < ninds; i++) { - ind = inds[i]->getStats(); - if (ind.sex == 0) othersex = 1; else othersex = 0; - if (settletype.stgDep) { - if (settletype.sexDep) sett = pSpecies->getSettRules(ind.stage,ind.sex); - else sett = pSpecies->getSettRules(ind.stage,0); - } - else { - if (settletype.sexDep) sett = pSpecies->getSettRules(0,ind.sex); - else sett = pSpecies->getSettRules(0,0); - } - if (ind.status == 2) - { // awaiting settlement - pCell = inds[i]->getLocn(1); - if (pCell == 0) { - // this condition can occur in a patch-based model at the time of a dynamic landscape - // change when there is a range restriction in place, since a patch can straddle the - // range restriction and an individual forced to disperse upon patch removal could - // start its trajectory beyond the boundary of the restrictyed range - such a model is - // not good practice, but the condition must be handled by killing the individual conceerned - ind.status = 6; + for (int i = 0; i < ninds; i++) { + ind = inds[i]->getStats(); + if (ind.sex == 0) othersex = 1; else othersex = 0; + if (settletype.stgDep) { + if (settletype.sexDep) sett = pSpecies->getSettRules(ind.stage, ind.sex); + else sett = pSpecies->getSettRules(ind.stage, 0); } else { - -#if RSDEBUG -//newloc = pCell->getLocn(); -//DEBUGLOG << "Population::transfer(): 6666: i=" << i << " ID=" << inds[i]->getId() -// << " sex=" << ind.sex << " status=" << ind.status -// << " pCell=" << pCell << " x=" << newloc.x << " y=" << newloc.y -// << " findMate=" << sett.findMate -//// << " wait=" << sett.wait -//// << " go2nbrLocn=" << sett.go2nbrLocn -// << endl; -#endif - - mateOK = false; - if (sett.findMate) { - // determine whether at least one individual of the opposite sex is present in the - // new population - if (matePresent(pCell,othersex)) mateOK = true; -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 7777: othersex=" << othersex -// << " this=" << this << " pNewPopn=" << pNewPopn << " popsize=" << popsize << " mateOK=" << mateOK -// << endl; -#endif - } - else { // no requirement to find a mate - mateOK = true; + if (settletype.sexDep) sett = pSpecies->getSettRules(0, ind.sex); + else sett = pSpecies->getSettRules(0, 0); + } + if (ind.status == 2) + { // awaiting settlement + pCell = inds[i]->getLocn(1); + if (pCell == 0) { + // this condition can occur in a patch-based model at the time of a dynamic landscape + // change when there is a range restriction in place, since a patch can straddle the + // range restriction and an individual forced to disperse upon patch removal could + // start its trajectory beyond the boundary of the restrictyed range - such a model is + // not good practice, but the condition must be handled by killing the individual conceerned + ind.status = 6; } + else { + mateOK = false; + if (sett.findMate) { + // determine whether at least one individual of the opposite sex is present in the + // new population + if (matePresent(pCell, othersex)) mateOK = true; + } + else { // no requirement to find a mate + mateOK = true; + } - densdepOK = false; - settle = inds[i]->getSettPatch(); - if (sett.densDep) - { - patch = pCell->getPatch(); -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 8880: i=" << i << " patch=" << patch -// << endl; -#endif - if (patch != 0) { // not no-data area - pPatch = (Patch*)patch; - if (settle.settleStatus == 0 - || settle.pSettPatch != pPatch) - // note: second condition allows for having moved from one patch to another - // adjacent one - { -// inds[i]->resetPathOut(); // reset steps out of patch to zero - // determine whether settlement occurs in the (new) patch - localK = (double)pPatch->getK(); - popn = pPatch->getPopn((intptr)pSpecies); -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 8881: i=" << i << " patchNum=" << pPatch->getPatchNum() -// << " localK=" << localK << " popn=" << popn << endl; -#endif - if (popn == 0) { // population has not been set up in the new patch - popsize = 0.0; - } - else { - pNewPopn = (Population*)popn; - popsize = (double)pNewPopn->totalPop(); - } - if (localK > 0.0) { - // make settlement decision - if (settletype.indVar) settDD = inds[i]->getSettTraits(); + densdepOK = false; + settle = inds[i]->getSettPatch(); + if (sett.densDep) + { + patch = pCell->getPatch(); + if (patch != 0) { // not no-data area + pPatch = (Patch*)patch; + if (settle.settleStatus == 0 + || settle.pSettPatch != pPatch) + // note: second condition allows for having moved from one patch to another + // adjacent one + { + // determine whether settlement occurs in the (new) patch + localK = (double)pPatch->getK(); + popn = pPatch->getPopn((intptr)pSpecies); + if (popn == 0) { // population has not been set up in the new patch + popsize = 0.0; + } + else { + pNewPopn = (Population*)popn; + popsize = (double)pNewPopn->totalPop(); + } + if (localK > 0.0) { + // make settlement decision + if (settletype.indVar) settDD = inds[i]->getSettTraits(); #if RS_RCPP - else settDD = pSpecies->getSettTraits(ind.stage,ind.sex); + else settDD = pSpecies->getSettTraits(ind.stage, ind.sex); #else - else { - if (settletype.sexDep) { - if (settletype.stgDep) - settDD = pSpecies->getSettTraits(ind.stage,ind.sex); - else - settDD = pSpecies->getSettTraits(0,ind.sex); - } else { - if (settletype.stgDep) - settDD = pSpecies->getSettTraits(ind.stage,0); - else - settDD = pSpecies->getSettTraits(0,0); + if (settletype.sexDep) { + if (settletype.stgDep) + settDD = pSpecies->getSettTraits(ind.stage, ind.sex); + else + settDD = pSpecies->getSettTraits(0, ind.sex); + } + else { + if (settletype.stgDep) + settDD = pSpecies->getSettTraits(ind.stage, 0); + else + settDD = pSpecies->getSettTraits(0, 0); + } } - } #endif //RS_RCPP - settprob = settDD.s0 / - (1.0 + exp(-(popsize/localK - (double)settDD.beta) * (double)settDD.alpha)); -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 8888: i=" << i << " ind.stage=" << ind.stage -// << " this=" << this << " pNewPopn=" << pNewPopn << " popsize=" << popsize -// << " localK=" << localK << " alpha=" << settDD.alpha << " beta=" << settDD.beta -// << " settprob=" << settprob -// << endl; -#endif - if (pRandom->Bernoulli(settprob)) { // settlement allowed - densdepOK = true; - settle.settleStatus = 2; - } - else { // settlement procluded - settle.settleStatus = 1; + settprob = settDD.s0 / + (1.0 + exp(-(popsize / localK - (double)settDD.beta) * (double)settDD.alpha)); + + if (pRandom->Bernoulli(settprob)) { // settlement allowed + densdepOK = true; + settle.settleStatus = 2; + } + else { // settlement procluded + settle.settleStatus = 1; + } + settle.pSettPatch = pPatch; } -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 8889: i=" << i -// << " settleStatus=" << settle.settleStatus << " mateOK=" << (int)mateOK; -//if (settle.settleStatus == 2 && mateOK) { -// DEBUGLOG << " SETTLES -"; -// if (ind.sex == 1) DEBUGLOG << " MALE "; else DEBUGLOG << " FEMALE "; -//} -//DEBUGLOG << endl; -#endif - settle.pSettPatch = pPatch; + inds[i]->setSettPatch(settle); } - inds[i]->setSettPatch(settle); - } - else { - if (settle.settleStatus == 2) { // previously allowed to settle - densdepOK = true; + else { + if (settle.settleStatus == 2) { // previously allowed to settle + densdepOK = true; + } } } } - } - else { // no density-dependent settlement - densdepOK = true; - settle.settleStatus = 2; - settle.pSettPatch = pPatch; - inds[i]->setSettPatch(settle); - } + else { // no density-dependent settlement + densdepOK = true; + settle.settleStatus = 2; + settle.pSettPatch = pPatch; + inds[i]->setSettPatch(settle); + } - if (mateOK && densdepOK) { // can recruit to patch - ind.status = 4; - ndispersers--; - } - else { // does not recruit - if (trfr.moveModel) { - ind.status = 1; // continue dispersing, unless ... - // ... maximum steps has been exceeded - pathSteps steps = inds[i]->getSteps(); - settleSteps settsteps = pSpecies->getSteps(ind.stage,ind.sex); - if (steps.year >= settsteps.maxStepsYr) { - ind.status = 3; // waits until next year - } - if (steps.total >= settsteps.maxSteps) { - ind.status = 6; // dies - } + if (mateOK && densdepOK) { // can recruit to patch + ind.status = 4; + ndispersers--; } - else { // dispersal kernel - if (sett.wait) { - ind.status = 3; // wait until next dispersal event + else { // does not recruit + if (trfr.moveModel) { + ind.status = 1; // continue dispersing, unless ... + // ... maximum steps has been exceeded + pathSteps steps = inds[i]->getSteps(); + settleSteps settsteps = pSpecies->getSteps(ind.stage, ind.sex); + if (steps.year >= settsteps.maxStepsYr) { + ind.status = 3; // waits until next year + } + if (steps.total >= settsteps.maxSteps) { + ind.status = 6; // dies + } } - else { - ind.status = 6; // (dies unless a neighbouring cell is suitable) + else { // dispersal kernel + if (sett.wait) { + ind.status = 3; // wait until next dispersal event + } + else { + ind.status = 6; // (dies unless a neighbouring cell is suitable) + } + ndispersers--; } - ndispersers--; } } - } - inds[i]->setStatus(ind.status); - } + inds[i]->setStatus(ind.status); + } #if RS_RCPP - // write each individuals current movement step and status to paths file - if (trfr.moveModel && sim.outPaths) { - if(nextseason >= sim.outStartPaths && nextseason%sim.outIntPaths==0) { + // write each individuals current movement step and status to paths file + if (trfr.moveModel && sim.outPaths) { + if (nextseason >= sim.outStartPaths && nextseason % sim.outIntPaths == 0) { inds[i]->outMovePath(nextseason); + } } - } #endif - if (!trfr.moveModel && sett.go2nbrLocn && (ind.status == 3 || ind.status == 6)) - { - // for kernel-based transfer only ... - // determine whether recruitment to a neighbouring cell is possible -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): neighbour cell search: sett.go2nbrLocn = " << sett.go2nbrLocn -// << " ind.status = " << ind.status -// << endl; -#endif - pCell = inds[i]->getLocn(1); - newloc = pCell->getLocn(); - vector nbrlist; - for (int dx = -1; dx < 2; dx++) { - for (int dy = -1; dy < 2; dy++) { - if (dx !=0 || dy != 0) { //cell is not the current cell - nbrloc.x = newloc.x + dx; nbrloc.y = newloc.y + dy; - if (nbrloc.x >= 0 && nbrloc.x <= ppLand.maxX - && nbrloc.y >= 0 && nbrloc.y <= ppLand.maxY) { // within landscape - // add to list of potential neighbouring cells if suitable, etc. - pCell = pLandscape->findCell(nbrloc.x,nbrloc.y); - if (pCell != 0) { // not no-data area - patch = pCell->getPatch(); - if (patch != 0) { // not no-data area - pPatch = (Patch*)patch; - patchnum = pPatch->getPatchNum(); - if (patchnum > 0 && pPatch != inds[i]->getNatalPatch()) - { // not the matrix or natal patch - if (pPatch->getK() > 0.0) - { // suitable - if (sett.findMate) { - if (matePresent(pCell,othersex)) nbrlist.push_back(pCell); + if (!trfr.moveModel && sett.go2nbrLocn && (ind.status == 3 || ind.status == 6)) + { + // for kernel-based transfer only ... + // determine whether recruitment to a neighbouring cell is possible + + pCell = inds[i]->getLocn(1); + newloc = pCell->getLocn(); + vector nbrlist; + for (int dx = -1; dx < 2; dx++) { + for (int dy = -1; dy < 2; dy++) { + if (dx != 0 || dy != 0) { //cell is not the current cell + nbrloc.x = newloc.x + dx; nbrloc.y = newloc.y + dy; + if (nbrloc.x >= 0 && nbrloc.x <= ppLand.maxX + && nbrloc.y >= 0 && nbrloc.y <= ppLand.maxY) { // within landscape + // add to list of potential neighbouring cells if suitable, etc. + pCell = pLandscape->findCell(nbrloc.x, nbrloc.y); + if (pCell != 0) { // not no-data area + patch = pCell->getPatch(); + if (patch != 0) { // not no-data area + pPatch = (Patch*)patch; + patchnum = pPatch->getPatchNum(); + if (patchnum > 0 && pPatch != inds[i]->getNatalPatch()) + { // not the matrix or natal patch + if (pPatch->getK() > 0.0) + { // suitable + if (sett.findMate) { + if (matePresent(pCell, othersex)) nbrlist.push_back(pCell); + } + else + nbrlist.push_back(pCell); } - else - nbrlist.push_back(pCell); } } } @@ -1380,61 +1050,54 @@ for (int i = 0; i < ninds; i++) { } } } - } - int listsize = (int)nbrlist.size(); - if (listsize > 0) { // there is at least one suitable neighbouring cell - if (listsize == 1) { - inds[i]->moveto(nbrlist[0]); - } - else { // select at random from the list - int rrr = pRandom->IRandom(0,listsize-1); - inds[i]->moveto(nbrlist[rrr]); + int listsize = (int)nbrlist.size(); + if (listsize > 0) { // there is at least one suitable neighbouring cell + if (listsize == 1) { + inds[i]->moveto(nbrlist[0]); + } + else { // select at random from the list + int rrr = pRandom->IRandom(0, listsize - 1); + inds[i]->moveto(nbrlist[rrr]); + } } + // else list empty - do nothing - individual retains its current location and status } - // else list empty - do nothing - individual retains its current location and status } -} -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 9999: ninds = " << ninds -// << " ndispersers = " << ndispersers << endl; -#endif - - -return ndispersers; + return ndispersers; } // Determine whether there is a potential mate present in a patch which a potential // settler has reached -bool Population::matePresent(Cell *pCell,short othersex) +bool Population::matePresent(Cell* pCell, short othersex) { -int patch; -Patch *pPatch; -Population *pNewPopn; -int popsize = 0; -bool matefound = false; - -patch = (int)pCell->getPatch(); -if (patch != 0) { - pPatch = (Patch*)pCell->getPatch(); - if (pPatch->getPatchNum() > 0) { // not the matrix patch - if (pPatch->getK() > 0.0) - { // suitable - pNewPopn = (Population*)pPatch->getPopn((intptr)pSpecies); - if (pNewPopn != 0) { - // count members of other sex already resident in the patch - for (int stg = 0; stg < nStages; stg++) { - popsize += pNewPopn->nInds[stg][othersex]; + int patch; + Patch* pPatch; + Population* pNewPopn; + int popsize = 0; + bool matefound = false; + + patch = (int)pCell->getPatch(); + if (patch != 0) { + pPatch = (Patch*)pCell->getPatch(); + if (pPatch->getPatchNum() > 0) { // not the matrix patch + if (pPatch->getK() > 0.0) + { // suitable + pNewPopn = (Population*)pPatch->getPopn((intptr)pSpecies); + if (pNewPopn != 0) { + // count members of other sex already resident in the patch + for (int stg = 0; stg < nStages; stg++) { + popsize += pNewPopn->nInds[stg][othersex]; + } + } + if (popsize < 1) { + // add any potential settlers of the other sex + popsize += pPatch->getPossSettlers(pSpecies, othersex); } - } - if (popsize < 1) { - // add any potential settlers of the other sex - popsize += pPatch->getPossSettlers(pSpecies,othersex); } } } -} -if (popsize > 0) matefound = true; -return matefound; + if (popsize > 0) matefound = true; + return matefound; } //--------------------------------------------------------------------------- @@ -1444,794 +1107,565 @@ return matefound; // FOR MULTIPLE SPECIES, MAY NEED TO SEPARATE OUT THIS IDENTIFICATION STAGE, // SO THAT IT CAN BE PERFORMED FOR ALL SPECIES BEFORE ANY UPDATING OF POPULATIONS -void Population::survival0(float localK,short option0,short option1) +void Population::survival0(float localK, short option0, short option1) { -// option0: 0 - stage 0 (juveniles) only -// 1 - all stages -// 2 - stage 1 and above (all non-juveniles) -// option1: 0 - development only (when survival is annual) -// 1 - development and survival -// 2 - survival only (when survival is annual) - -#if RSDEBUG -//DEBUGLOG << "Population::survival0():" -// << " pSpecies=" << pSpecies << " this=" << this << " PatchNum=" << pPatch->getPatchNum() -//#if SEASONAL -// << " season=" << season -//#endif // SEASONAL -// << " localK=" << localK << " option=" << option -// << endl; -#endif + // option0: 0 - stage 0 (juveniles) only + // 1 - all stages + // 2 - stage 1 and above (all non-juveniles) + // option1: 0 - development only (when survival is annual) + // 1 - development and survival + // 2 - survival only (when survival is annual) + + densDepParams ddparams = pSpecies->getDensDep(); + demogrParams dem = pSpecies->getDemogr(); + stageParams sstruct = pSpecies->getStage(); -densDepParams ddparams = pSpecies->getDensDep(); -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); - -// get surrent population size -int ninds = (int)inds.size(); -if (ninds == 0) return; - -// set up local copies of species development and survival tables -int nsexes; -if (dem.repType == 0) nsexes = 1; else nsexes = 2; -float dev[NSTAGES][NSEXES]; -float surv[NSTAGES][NSEXES]; -short minAge[NSTAGES][NSEXES]; -for (int stg = 0; stg < sstruct.nStages; stg++) { - for (int sex = 0; sex < nsexes; sex++) { - if (dem.stageStruct) { - if (dem.repType == 1) { // simple sexual model - // both sexes use development and survival recorded for females - dev[stg][sex] = pSpecies->getDev(stg,0); - surv[stg][sex] = pSpecies->getSurv(stg,0); - minAge[stg][sex] = pSpecies->getMinAge(stg,0); - } - else { - dev[stg][sex] = pSpecies->getDev(stg,sex); - surv[stg][sex] = pSpecies->getSurv(stg,sex); - minAge[stg][sex] = pSpecies->getMinAge(stg,sex); - } - if (option1 == 0) surv[stg][sex] = 1.0; // development only - all survive - if (option1 == 2) dev[stg][sex] = 0.0; // survival only - none develops - } - else { // non-structured population - if (stg == 1) { // adults - dev[stg][sex] = 0.0; surv[stg][sex] = 0.0; minAge[stg][sex] = 0; + // get surrent population size + int ninds = (int)inds.size(); + if (ninds == 0) return; + + // set up local copies of species development and survival tables + int nsexes; + if (dem.repType == 0) nsexes = 1; else nsexes = 2; + float dev[NSTAGES][NSEXES]; + float surv[NSTAGES][NSEXES]; + short minAge[NSTAGES][NSEXES]; + for (int stg = 0; stg < sstruct.nStages; stg++) { + for (int sex = 0; sex < nsexes; sex++) { + if (dem.stageStruct) { + if (dem.repType == 1) { // simple sexual model + // both sexes use development and survival recorded for females + dev[stg][sex] = pSpecies->getDev(stg, 0); + surv[stg][sex] = pSpecies->getSurv(stg, 0); + minAge[stg][sex] = pSpecies->getMinAge(stg, 0); + } + else { + dev[stg][sex] = pSpecies->getDev(stg, sex); + surv[stg][sex] = pSpecies->getSurv(stg, sex); + minAge[stg][sex] = pSpecies->getMinAge(stg, sex); + } + if (option1 == 0) surv[stg][sex] = 1.0; // development only - all survive + if (option1 == 2) dev[stg][sex] = 0.0; // survival only - none develops } - else { // juveniles - dev[stg][sex] = 1.0; surv[stg][sex] = 1.0; minAge[stg][sex] = 0; + else { // non-structured population + if (stg == 1) { // adults + dev[stg][sex] = 0.0; surv[stg][sex] = 0.0; minAge[stg][sex] = 0; + } + else { // juveniles + dev[stg][sex] = 1.0; surv[stg][sex] = 1.0; minAge[stg][sex] = 0; + } } } -#if RSDEBUG -//DEBUGLOG << "Population::survival0(): 1111 " -// << " dev[" << stg << "][" << sex << "] = " << dev[stg][sex] -// << " surv[" << stg << "][" << sex << "] = " << surv[stg][sex] -// << endl; -#endif } -} -if (dem.stageStruct) { -#if RSDEBUG -// DEBUGLOG << "Population::survival0(): 2222 " -// << " ninds=" << ninds << " localK=" << localK -// << " effect of density dependence:" << endl; -// for (int st = 0; st < nStages; st++) { -// for (int sx = 0; sx < nsexes; sx++) { -// DEBUGLOG << "st=" << st << " sx=" << sx << " nInds=" << nInds[st][sx] << endl; -// } -// } -#endif + if (dem.stageStruct) { // apply density dependence in development and/or survival probabilities - for (int stg = 0; stg < nStages; stg++) { - for (int sex = 0; sex < nsexes; sex++) { - if (option1 != 2 && sstruct.devDens && stg > 0) { + for (int stg = 0; stg < nStages; stg++) { + for (int sex = 0; sex < nsexes; sex++) { + if (option1 != 2 && sstruct.devDens && stg > 0) { #if RSDEBUG -// DEBUGLOG << "DD in DEVELOPMENT for stg=" << stg << " sex=" << sex << endl; + // DEBUGLOG << "DD in DEVELOPMENT for stg=" << stg << " sex=" << sex << endl; #endif // NB DD in development does NOT apply to juveniles, // which must develop to stage 1 if they survive - float effect = 0.0; - if (sstruct.devStageDens) { // stage-specific density dependence - // NOTE: matrix entries represent effect of ROW on COLUMN - // AND males precede females - float weight = 0.0; - for (int effstg = 0; effstg < nStages; effstg++) { - for (int effsex = 0; effsex < nSexes; effsex++) { - if (dem.repType == 2) { - int rowincr,colincr; - if (effsex == 0) rowincr = 1; else rowincr = 0; - if (sex == 0) colincr = 1; else colincr = 0; - weight = pSpecies->getDDwtDev(2*stg+colincr,2*effstg+rowincr); - } - else { - weight = pSpecies->getDDwtDev(stg,effstg); + float effect = 0.0; + if (sstruct.devStageDens) { // stage-specific density dependence + // NOTE: matrix entries represent effect of ROW on COLUMN + // AND males precede females + float weight = 0.0; + for (int effstg = 0; effstg < nStages; effstg++) { + for (int effsex = 0; effsex < nSexes; effsex++) { + if (dem.repType == 2) { + int rowincr, colincr; + if (effsex == 0) rowincr = 1; else rowincr = 0; + if (sex == 0) colincr = 1; else colincr = 0; + weight = pSpecies->getDDwtDev(2 * stg + colincr, 2 * effstg + rowincr); + } + else { + weight = pSpecies->getDDwtDev(stg, effstg); + } + effect += (float)nInds[effstg][effsex] * weight; } - effect += (float)nInds[effstg][effsex] * weight; -#if RSDEBUG -// DEBUGLOG << " effstg=" << effstg << " effsex=" << effsex; -// DEBUGLOG << " weight=" << weight << " effect=" << effect -// << endl; -#endif } } - } - else // not stage-specific - effect = (float)totalPop(); - if (localK > 0.0) - dev[stg][sex] *= exp(-(ddparams.devCoeff*effect)/localK); -#if RSDEBUG -//DEBUGLOG << "Population::survival0(): 2288 " << " effect=" << effect; -//if (localK > 0.0) -// DEBUGLOG << " exp=" << exp(-(ddparams.devCoeff*effect)/localK); -//DEBUGLOG << " dev[" << stg << "][" << sex << "] = " << dev[stg][sex] -// << endl; -#endif - } // end of if (sstruct.devDens && stg > 0) - if (option1 != 0 && sstruct.survDens) { -#if RSDEBUG -// DEBUGLOG << "DD in SURVIVAL for stg=" << stg << " sex=" << sex << endl; -#endif - float effect = 0.0; - if (sstruct.survStageDens) { // stage-specific density dependence - // NOTE: matrix entries represent effect of ROW on COLUMN - // AND males precede females - float weight = 0.0; - for (int effstg = 0; effstg < nStages; effstg++) { - for (int effsex = 0; effsex < nSexes; effsex++) { - if (dem.repType == 2) { - int rowincr,colincr; - if (effsex == 0) rowincr = 1; else rowincr = 0; - if (sex == 0) colincr = 1; else colincr = 0; - weight = pSpecies->getDDwtSurv(2*stg+colincr,2*effstg+rowincr); - } - else { - weight = pSpecies->getDDwtSurv(stg,effstg); + else // not stage-specific + effect = (float)totalPop(); + if (localK > 0.0) + dev[stg][sex] *= exp(-(ddparams.devCoeff * effect) / localK); + } // end of if (sstruct.devDens && stg > 0) + if (option1 != 0 && sstruct.survDens) { + float effect = 0.0; + if (sstruct.survStageDens) { // stage-specific density dependence + // NOTE: matrix entries represent effect of ROW on COLUMN + // AND males precede females + float weight = 0.0; + for (int effstg = 0; effstg < nStages; effstg++) { + for (int effsex = 0; effsex < nSexes; effsex++) { + if (dem.repType == 2) { + int rowincr, colincr; + if (effsex == 0) rowincr = 1; else rowincr = 0; + if (sex == 0) colincr = 1; else colincr = 0; + weight = pSpecies->getDDwtSurv(2 * stg + colincr, 2 * effstg + rowincr); + } + else { + weight = pSpecies->getDDwtSurv(stg, effstg); + } + effect += (float)nInds[effstg][effsex] * weight; } - effect += (float)nInds[effstg][effsex] * weight; -#if RSDEBUG -// DEBUGLOG << " effstg=" << effstg << " effsex=" << effsex; -// DEBUGLOG << " weight=" << weight << " effect=" << effect -// << endl; -#endif } } - } - else // not stage-specific - effect = (float)totalPop(); - if (localK > 0.0) - surv[stg][sex] *= exp(-(ddparams.survCoeff*effect)/localK); -#if RSDEBUG -//DEBUGLOG << "Population::survival0(): 3333 " << " effect=" << effect; -//if (localK > 0.0) -// DEBUGLOG << " exp = " << exp(-(ddparams.survCoeff*effect)/localK); -//DEBUGLOG << " surv[" << stg << "][" << sex << "] = " << surv[stg][sex] -// << endl; -#endif - } // end of if (sstruct.survDens) + else // not stage-specific + effect = (float)totalPop(); + if (localK > 0.0) + surv[stg][sex] *= exp(-(ddparams.survCoeff * effect) / localK); + } // end of if (sstruct.survDens) + } } } -} -// identify which individuals die or develop -#if RSDEBUG -//DEBUGLOG << "Population::survival0():" << " ninds " << ninds -// << endl; -#endif -for (int i = 0; i < ninds; i++) { - indStats ind = inds[i]->getStats(); -#if RSDEBUG -//DEBUGLOG << "Population::survival0():" -// << " i=" << i << " indId=" << inds[i]->getId() -// << " stage=" << ind.stage << " status=" << ind.status << " sex=" << ind.sex -//#if PARTMIGRN -// << " migrnstatus=" << inds[i]->getMigrnStatus() -//#endif // PARTMIGRN -// << endl; -#endif - if ((ind.stage == 0 && option0 < 2) || (ind.stage > 0 && option0 > 0)) { - // condition for processing the stage is met... - if (ind.status < 6) { // not already doomed - double probsurv = surv[ind.stage][ind.sex]; - // does the individual survive? - if (pRandom->Bernoulli(probsurv)) { // survives - // does the individual develop? - double probdev = dev[ind.stage][ind.sex]; - if (ind.stage < nStages-1) { // not final stage -#if RSDEBUG -//DEBUGLOG << "Population::survival0():" -// << " i=" << i << " indId=" << inds[i]->getId() -// << " age=" << ind.age << " minAge[stage+1]=" << minAge[ind.stage+1][ind.sex] -// << " probdev=" << probdev -// << endl; -#endif - if (ind.age >= minAge[ind.stage+1][ind.sex]) { // old enough to enter next stage -#if RSDEBUG -//DEBUGLOG << "Population::survival0():" -// << " i=" << i << " indId=" << inds[i]->getId() << " OLD ENOUGH" -// << endl; -#endif - if (pRandom->Bernoulli(probdev)) { - inds[i]->developing(); + // identify which individuals die or develop + for (int i = 0; i < ninds; i++) { + indStats ind = inds[i]->getStats(); + if ((ind.stage == 0 && option0 < 2) || (ind.stage > 0 && option0 > 0)) { + // condition for processing the stage is met... + if (ind.status < 6) { // not already doomed + double probsurv = surv[ind.stage][ind.sex]; + // does the individual survive? + if (pRandom->Bernoulli(probsurv)) { // survives + // does the individual develop? + double probdev = dev[ind.stage][ind.sex]; + if (ind.stage < nStages - 1) { // not final stage + if (ind.age >= minAge[ind.stage + 1][ind.sex]) { // old enough to enter next stage + if (pRandom->Bernoulli(probdev)) { + inds[i]->developing(); + } } } } - } - else { // doomed to die -#if RSDEBUG -//DEBUGLOG << "Population::survival0():" -// << " i=" << i << " indId=" << inds[i]->getId() << " DIES" -// << endl; -#endif - inds[i]->setStatus(8); + else { // doomed to die + inds[i]->setStatus(8); + } } } } -#if RSDEBUG -//ind = inds[i]->getStats(); -//DEBUGLOG << "Population::survival0():" -// << " i = " << i << " ID = " << inds[i]->getId() -// << " stage = " << ind.stage << " status = " << ind.status -// << endl; -#endif -} } // Apply survival changes to the population void Population::survival1(void) { -int ninds = (int)inds.size(); -#if RSDEBUG -//DEBUGLOG << "Population::survival1(): this=" << this -// << " patchNum=" << pPatch->getPatchNum() << " ninds=" << ninds -// << endl; -#endif -for (int i = 0; i < ninds; i++) { - indStats ind = inds[i]->getStats(); -#if RSDEBUG -//DEBUGLOG << "Population::survival1(): i=" << i -// << " indId=" << inds[i]->getId() << " stage=" << ind.stage << " sex=" << ind.sex -// << " isDeveloping=" << ind.isDeveloping << " status=" << ind.status -// << endl; -#endif - if (ind.status > 5) { // doomed to die - delete inds[i]; - inds[i] = NULL; - nInds[ind.stage][ind.sex]--; - } - else { - if (ind.isDeveloping) { // develops to next stage + int ninds = (int)inds.size(); + for (int i = 0; i < ninds; i++) { + indStats ind = inds[i]->getStats(); + if (ind.status > 5) { // doomed to die + delete inds[i]; + inds[i] = NULL; nInds[ind.stage][ind.sex]--; - inds[i]->develop(); - nInds[ind.stage+1][ind.sex]++; + } + else { + if (ind.isDeveloping) { // develops to next stage + nInds[ind.stage][ind.sex]--; + inds[i]->develop(); + nInds[ind.stage + 1][ind.sex]++; + } } } -} -#if RSDEBUG -//DEBUGLOG << "Population::survival1(): this=" << this -// << " patchNum=" << pPatch->getPatchNum() << " completed individuals loop" -// << endl; -#endif - -#if RSDEBUG -//for (int i = 0; i < inds.size(); i++) { -//DEBUGLOG << "Population::survival1():" << " inds[" << i << "] = " << inds[i] << endl; -//} -#endif // remove pointers to dead individuals -clean(); -#if RSDEBUG -//DEBUGLOG << "Population::survival1(): this=" << this -// << " patchNum=" << pPatch->getPatchNum() << " finished" -// << endl; -#endif - + clean(); } void Population::ageIncrement(void) { -int ninds = (int)inds.size(); -stageParams sstruct = pSpecies->getStage(); -#if RSDEBUG -//DEBUGLOG << "Population::ageIncrement():" << " inds.size() = " << inds.size() -// << endl; -#endif -for (int i = 0; i < ninds; i++) { - inds[i]->ageIncrement(sstruct.maxAge); -} + int ninds = (int)inds.size(); + stageParams sstruct = pSpecies->getStage(); + for (int i = 0; i < ninds; i++) { + inds[i]->ageIncrement(sstruct.maxAge); + } } //--------------------------------------------------------------------------- // Remove zero pointers to dead or dispersed individuals void Population::clean(void) { -int ninds = (int)inds.size(); -if (ninds > 0) { -// sort (inds.begin(), inds.end()); -// reverse (inds.begin(), inds.end()); -// -// while (inds.size() > 0 && inds[inds.size()-1] == NULL ) { -// inds.pop_back(); -// } - // ALTERNATIVE METHOD: AVOIDS SLOW SORTING OF POPULATION - std::vector survivors; // all surviving individuals - for (int i = 0; i < ninds; i++) { - if (inds[i] != NULL) { - survivors.push_back(inds[i]); + int ninds = (int)inds.size(); + if (ninds > 0) { + // ALTERNATIVE METHOD: AVOIDS SLOW SORTING OF POPULATION + std::vector survivors; // all surviving individuals + for (int i = 0; i < ninds; i++) { + if (inds[i] != NULL) { + survivors.push_back(inds[i]); + } } - } - inds.clear(); - inds = survivors; + inds.clear(); + inds = survivors; #if RS_RCPP - shuffle(inds.begin(), inds.end(), pRandom->getRNG() ); + shuffle(inds.begin(), inds.end(), pRandom->getRNG()); #else #if !RSDEBUG - // do not randomise individuals in RSDEBUG mode, as the function uses rand() - // and therefore the randomisation will differ between identical runs of RS - shuffle(inds.begin(), inds.end(), pRandom->getRNG() ); + // do not randomise individuals in RSDEBUG mode, as the function uses rand() + // and therefore the randomisation will differ between identical runs of RS + shuffle(inds.begin(), inds.end(), pRandom->getRNG()); #endif // !RSDEBUG #endif // RS_RCPP -} + } } //--------------------------------------------------------------------------- // Open population file and write header record -bool Population::outPopHeaders(int landNr,bool patchModel) { +bool Population::outPopHeaders(int landNr, bool patchModel) { -if (landNr == -999) { // close file - if (outPop.is_open()) outPop.close(); - outPop.clear(); - return true; -} + if (landNr == -999) { // close file + if (outPop.is_open()) outPop.close(); + outPop.clear(); + return true; + } -string name; -//landParams ppLand = pLandscape->getLandParams(); -//envStochParams env = paramsStoch->getStoch(); -simParams sim = paramsSim->getSim(); -envGradParams grad = paramsGrad->getGradient(); + string name; + simParams sim = paramsSim->getSim(); + envGradParams grad = paramsGrad->getGradient(); -// NEED TO REPLACE CONDITIONAL COLUMNS BASED ON ATTRIBUTES OF ONE SPECIES TO COVER -// ATTRIBUTES OF *ALL* SPECIES AS DETECTED AT MODEL LEVEL -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); + // NEED TO REPLACE CONDITIONAL COLUMNS BASED ON ATTRIBUTES OF ONE SPECIES TO COVER + // ATTRIBUTES OF *ALL* SPECIES AS DETECTED AT MODEL LEVEL + demogrParams dem = pSpecies->getDemogr(); + stageParams sstruct = pSpecies->getStage(); -if (sim.batchMode) { - name = paramsSim->getDir(2) - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(landNr) + "_Pop.txt"; -} -else{ - name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) +"_Pop.txt"; -} -outPop.open(name.c_str()); -outPop << "Rep\tYear\tRepSeason"; -if (patchModel) outPop << "\tPatchID\tNcells"; -else outPop << "\tx\ty"; -// determine whether environmental data need be written for populations -bool writeEnv = false; -if (grad.gradient) writeEnv = true; -if (paramsStoch->envStoch()) writeEnv = true; -if (writeEnv) outPop << "\tEpsilon\tGradient\tLocal_K"; -outPop << "\tSpecies\tNInd"; -#if RSDEBUG -//DEBUGLOG << "Population::outPopHeaders(): this=" << this -// << " patchNum=" << pPatch->getPatchNum() -// << " totalPop()=" << totalPop() -// << " nStages=" << nStages << " nSexes=" << nSexes -// << endl; -#endif -if (dem.stageStruct) { - if (dem.repType == 0) - { - for (int i = 1; i < sstruct.nStages; i++) outPop << "\tNInd_stage" << i ; - outPop << "\tNJuvs"; + if (sim.batchMode) { + name = paramsSim->getDir(2) + + "Batch" + Int2Str(sim.batchNum) + "_" + + "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(landNr) + "_Pop.txt"; } else { - for (int i = 1; i < sstruct.nStages; i++) - outPop << "\tNfemales_stage" << i << "\tNmales_stage" << i ; - outPop << "\tNJuvFemales\tNJuvMales"; + name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) + "_Pop.txt"; } -} -else { - if (dem.repType != 0) outPop << "\tNfemales\tNmales"; -} -outPop << endl; + outPop.open(name.c_str()); + outPop << "Rep\tYear\tRepSeason"; + if (patchModel) outPop << "\tPatchID\tNcells"; + else outPop << "\tx\ty"; + // determine whether environmental data need be written for populations + bool writeEnv = false; + if (grad.gradient) writeEnv = true; + if (paramsStoch->envStoch()) writeEnv = true; + if (writeEnv) outPop << "\tEpsilon\tGradient\tLocal_K"; + outPop << "\tSpecies\tNInd"; + if (dem.stageStruct) { + if (dem.repType == 0) + { + for (int i = 1; i < sstruct.nStages; i++) outPop << "\tNInd_stage" << i; + outPop << "\tNJuvs"; + } + else { + for (int i = 1; i < sstruct.nStages; i++) + outPop << "\tNfemales_stage" << i << "\tNmales_stage" << i; + outPop << "\tNJuvFemales\tNJuvMales"; + } + } + else { + if (dem.repType != 0) outPop << "\tNfemales\tNmales"; + } + outPop << endl; -return outPop.is_open(); + return outPop.is_open(); } //--------------------------------------------------------------------------- // Write record to population file -void Population::outPopulation(int rep,int yr,int gen,float eps, - bool patchModel,bool writeEnv,bool gradK) +void Population::outPopulation(int rep, int yr, int gen, float eps, + bool patchModel, bool writeEnv, bool gradK) { -Cell *pCell; - -#if RSDEBUG -//DEBUGLOG << "Population::outPopulations(): this=" << this -// << " writeEnv " << (int)writeEnv -// << endl; -#endif - + Cell* pCell; // NEED TO REPLACE CONDITIONAL COLUMNS BASED ON ATTRIBUTES OF ONE SPECIES TO COVER // ATTRIBUTES OF *ALL* SPECIES AS DETECTED AT MODEL LEVEL -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -popStats p; - -outPop << rep << "\t" << yr << "\t" << gen; -if (patchModel) { - outPop << "\t" << pPatch->getPatchNum(); - outPop << "\t" << pPatch->getNCells(); -} -else { - locn loc = pPatch->getCellLocn(0); - outPop << "\t" << loc.x << "\t" << loc.y; -} -if (writeEnv) { - if (pPatch->getPatchNum() == 0) { // matrix - outPop << "\t0\t0\t0"; + demogrParams dem = pSpecies->getDemogr(); + stageParams sstruct = pSpecies->getStage(); + popStats p; + + outPop << rep << "\t" << yr << "\t" << gen; + if (patchModel) { + outPop << "\t" << pPatch->getPatchNum(); + outPop << "\t" << pPatch->getNCells(); } else { - float k = pPatch->getK(); - float envval = 0.0; - pCell = pPatch->getRandomCell(); - if (pCell != 0) envval = pCell->getEnvVal(); - outPop << "\t" << eps << "\t" << envval << "\t" << k; + locn loc = pPatch->getCellLocn(0); + outPop << "\t" << loc.x << "\t" << loc.y; } -} -#if RSDEBUG -//DEBUGLOG << "Population::outPopulation(): this=" << this -// << " patchNum=" << pPatch->getPatchNum() -// << " totalPop()=" << totalPop() -// << " nStages=" << nStages << " nSexes=" << nSexes -// << endl; -#endif -outPop << "\t" << pSpecies->getSpNum(); -if (dem.stageStruct) { - p = getStats(); - outPop << "\t" << p.nNonJuvs; - // non-juvenile stage totals from permanent array - for (int stg = 1; stg < nStages; stg++) { - for (int sex = 0; sex < nSexes; sex++) { - outPop << "\t" << nInds[stg][sex]; + if (writeEnv) { + if (pPatch->getPatchNum() == 0) { // matrix + outPop << "\t0\t0\t0"; + } + else { + float k = pPatch->getK(); + float envval = 0.0; + pCell = pPatch->getRandomCell(); + if (pCell != 0) envval = pCell->getEnvVal(); + outPop << "\t" << eps << "\t" << envval << "\t" << k; } } - // juveniles from permanent array - for (int sex = 0; sex < nSexes; sex++) { - outPop << "\t" << nInds[0][sex]; - } -} -else { // non-structured population - outPop << "\t" << totalPop(); - if (dem.repType != 0) - { // sexual model - outPop << "\t" << nInds[1][0] << "\t" << nInds[1][1]; - } -} -outPop << endl; - -/* -#if RS_ABC -obsdata obs; -if (abcYear) { - int nobs = (int)pABCmaster->NObs(); - for (int i = 0; i < nobs; i++) { - obs = pABCmaster->getObsData(i); -#if RSDEBUG -//DEBUGLOG << "Population::outPopulation(): this=" << this << " i=" << i << " yr=" << yr -// << " obs.year=" << obs.year << " obs.type=" << obs.type << " obs.name=" << obs.name -// << " obs.x=" << obs.x << " obs.y=" << obs.y -// << endl; -#endif - if (obs.year == yr && obs.type == 2) { - if (obs.name == "NInds" || obs.name == "Occupied") { - bool match = false; - if (patchModel) { - if (obs.x == pPatch->getPatchNum()) { - match = true; -#if RSDEBUG -//DEBUGLOG << "Population::outPopulation(): i=" << i << " PROCESS Population NInds" -// << " obs.id=" << obs.id << " obs.value=" << obs.value << " obs.x=" << obs.x -// << " pPatch->PatchNum()=" << pPatch->getPatchNum() -// << " totalPop()=" << totalPop() << " p.nNonJuvs=" << p.nNonJuvs -// << endl; -#endif - } - } - else { - locn loc = pPatch->getCentroid(); - if (obs.x == loc.x && obs.y == loc.y) { - match = true; -#if RSDEBUG -DEBUGLOG << "Population::outPopulation(): i=" << i << " PROCESS Population NInds" - << " obs.id=" << obs.id << " obs.value=" << obs.value << " obs.x=" - << obs.x << " obs.y=" << obs.y << " loc.x=" << loc.x << " loc.y=" << loc.y - << " totalPop()=" << totalPop() << " p.nNonJuvs=" << p.nNonJuvs - << endl; -#endif - } - } - if (match) { - if (obs.name == "NInds") { - if (dem.stageStruct) - pABCmaster->AddNewPred(sim.simulation,obs.id,rep,obs.value,p.nNonJuvs,obs.weight); - else - pABCmaster->AddNewPred(sim.simulation,obs.id,rep,obs.value,totalPop(),obs.weight); - } - else { // obs.name == "Occupied" - pABCmaster->AddNewPred(sim.simulation,obs.id,rep,obs.value,p.breeding,obs.weight); - } - } + outPop << "\t" << pSpecies->getSpNum(); + if (dem.stageStruct) { + p = getStats(); + outPop << "\t" << p.nNonJuvs; + // non-juvenile stage totals from permanent array + for (int stg = 1; stg < nStages; stg++) { + for (int sex = 0; sex < nSexes; sex++) { + outPop << "\t" << nInds[stg][sex]; } } + // juveniles from permanent array + for (int sex = 0; sex < nSexes; sex++) { + outPop << "\t" << nInds[0][sex]; + } } -} -#endif // ABC -*/ + else { // non-structured population + outPop << "\t" << totalPop(); + if (dem.repType != 0) + { // sexual model + outPop << "\t" << nInds[1][0] << "\t" << nInds[1][1]; + } + } + outPop << endl; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Open individuals file and write header record -void Population::outIndsHeaders(int rep,int landNr,bool patchModel) +void Population::outIndsHeaders(int rep, int landNr, bool patchModel) { -if (landNr == -999) { // close file - if (outInds.is_open()) { - outInds.close(); outInds.clear(); + if (landNr == -999) { // close file + if (outInds.is_open()) { + outInds.close(); outInds.clear(); + } + return; } - return; -} -string name; -demogrParams dem = pSpecies->getDemogr(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -simParams sim = paramsSim->getSim(); - -if (sim.batchMode) { - name = paramsSim->getDir(2) - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) - + "_Land" + Int2Str(landNr) + "_Rep" + Int2Str(rep) + "_Inds.txt"; -} -else { - name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) - + "_Rep" + Int2Str(rep) +"_Inds.txt"; -} -outInds.open(name.c_str()); - -outInds << "Rep\tYear\tRepSeason\tSpecies\tIndID\tStatus"; -if (patchModel) outInds << "\tNatal_patch\tPatchID"; -else outInds << "\tNatal_X\tNatal_Y\tX\tY"; -if (dem.repType != 0) outInds << "\tSex"; -if (dem.stageStruct) outInds << "\tAge\tStage"; -if (emig.indVar) { - if (emig.densDep) outInds << "\tD0\tAlpha\tBeta"; - else outInds << "\tEP"; -} -if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 1) { // SMS - outInds << "\tDP\tGB\tAlphaDB\tBetaDB"; + string name; + demogrParams dem = pSpecies->getDemogr(); + emigRules emig = pSpecies->getEmig(); + trfrRules trfr = pSpecies->getTrfr(); + settleType sett = pSpecies->getSettle(); + simParams sim = paramsSim->getSim(); + + if (sim.batchMode) { + name = paramsSim->getDir(2) + + "Batch" + Int2Str(sim.batchNum) + "_" + + "Sim" + Int2Str(sim.simulation) + + "_Land" + Int2Str(landNr) + "_Rep" + Int2Str(rep) + "_Inds.txt"; + } + else { + name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) + + "_Rep" + Int2Str(rep) + "_Inds.txt"; + } + outInds.open(name.c_str()); + + outInds << "Rep\tYear\tRepSeason\tSpecies\tIndID\tStatus"; + if (patchModel) outInds << "\tNatal_patch\tPatchID"; + else outInds << "\tNatal_X\tNatal_Y\tX\tY"; + if (dem.repType != 0) outInds << "\tSex"; + if (dem.stageStruct) outInds << "\tAge\tStage"; + if (emig.indVar) { + if (emig.densDep) outInds << "\tD0\tAlpha\tBeta"; + else outInds << "\tEP"; + } + if (trfr.indVar) { + if (trfr.moveModel) { + if (trfr.moveType == 1) { // SMS + outInds << "\tDP\tGB\tAlphaDB\tBetaDB"; + } + if (trfr.moveType == 2) { // CRW + outInds << "\tStepLength\tRho"; + } } - if (trfr.moveType == 2) { // CRW - outInds << "\tStepLength\tRho"; + else { // kernel + outInds << "\tMeanDistI"; + if (trfr.twinKern) outInds << "\tMeanDistII\tPKernelI"; } } - else { // kernel - outInds << "\tMeanDistI"; - if (trfr.twinKern) outInds << "\tMeanDistII\tPKernelI"; + if (sett.indVar) { + outInds << "\tS0\tAlphaS\tBetaS"; } -} -if (sett.indVar) { - outInds << "\tS0\tAlphaS\tBetaS"; -} -outInds << "\tDistMoved"; + outInds << "\tDistMoved"; #if RSDEBUG -// ALWAYS WRITE NO. OF STEPS -outInds << "\tNsteps"; + // ALWAYS WRITE NO. OF STEPS + outInds << "\tNsteps"; #else -if (trfr.moveModel) outInds << "\tNsteps"; + if (trfr.moveModel) outInds << "\tNsteps"; #endif -outInds << endl; + outInds << endl; } //--------------------------------------------------------------------------- // Write records to individuals file -void Population::outIndividual(Landscape *pLandscape,int rep,int yr,int gen, +void Population::outIndividual(Landscape* pLandscape, int rep, int yr, int gen, int patchNum) { -//int x, y, p_id; -bool writeInd; -pathSteps steps; -Cell *pCell; - -landParams ppLand = pLandscape->getLandParams(); -//landOrigin lim = pLandscape->getOrigin(); -demogrParams dem = pSpecies->getDemogr(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -short spNum = pSpecies->getSpNum(); - -int ninds = (int)inds.size(); - -for (int i = 0; i < ninds; i++) { - indStats ind = inds[i]->getStats(); - if (yr == -1) { // write all initialised individuals - writeInd = true; - outInds << rep << "\t" << yr << "\t" << dem.repSeasons-1; - } - else { - if (dem.stageStruct && gen < 0) { // write status 9 individuals only - if (ind.status == 9) { - writeInd = true; - outInds << rep << "\t" << yr << "\t" << dem.repSeasons-1; - } - else writeInd = false; - } - else { + //int x, y, p_id; + bool writeInd; + pathSteps steps; + Cell* pCell; + + landParams ppLand = pLandscape->getLandParams(); + demogrParams dem = pSpecies->getDemogr(); + emigRules emig = pSpecies->getEmig(); + trfrRules trfr = pSpecies->getTrfr(); + settleType sett = pSpecies->getSettle(); + short spNum = pSpecies->getSpNum(); + + int ninds = (int)inds.size(); + + for (int i = 0; i < ninds; i++) { + indStats ind = inds[i]->getStats(); + if (yr == -1) { // write all initialised individuals writeInd = true; - outInds << rep << "\t" << yr << "\t" << gen; - } - } - if (writeInd) { - outInds << "\t" << spNum << "\t" << inds[i]->getId(); - if (dem.stageStruct) outInds << "\t" << ind.status; - else { // non-structured population - outInds << "\t" << ind.status; + outInds << rep << "\t" << yr << "\t" << dem.repSeasons - 1; } - pCell = inds[i]->getLocn(1); - locn loc; - if (pCell == 0) loc.x = loc.y = -1; // beyond boundary or in no-data cell - else loc = pCell->getLocn(); - pCell = inds[i]->getLocn(0); - locn natalloc = pCell->getLocn(); -//#if SEASONAL -// pCell = inds[i]->getLocn(2); -// locn prevloc = pCell->getLocn(); -//#endif - if (ppLand.patchModel) { - outInds << "\t" << inds[i]->getNatalPatch()->getPatchNum(); - if (loc.x == -1) outInds << "\t-1"; - else outInds << "\t" << patchNum; - } - else { // cell-based model - // EITHER write co-ordinates in cell units ... - outInds << "\t" << (float)natalloc.x << "\t" << natalloc.y; - outInds << "\t" << (float)loc.x << "\t" << (float)loc.y ; - // ... OR write co-ordinates in real-world units -// outInds << "\t" << (float)natalloc.x * (float)ppLand.resol + (float)lim.minEast -// << "\t" << natalloc.y * (float)ppLand.resol + (float)lim.minNorth; -// outInds << "\t" << (float)loc.x * (float)ppLand.resol + (float)lim.minEast -// << "\t" << (float)loc.y * (float)ppLand.resol + (float)lim.minNorth; - } - if (dem.repType != 0) outInds <<"\t" << ind.sex; - if (dem.stageStruct) outInds <<"\t" << ind.age <<"\t"<< ind.stage; - - if (emig.indVar) { - emigTraits e = inds[i]->getEmigTraits(); - if (emig.densDep) { - outInds << "\t" << e.d0 << "\t" << e.alpha << "\t" << e.beta; + else { + if (dem.stageStruct && gen < 0) { // write status 9 individuals only + if (ind.status == 9) { + writeInd = true; + outInds << rep << "\t" << yr << "\t" << dem.repSeasons - 1; + } + else writeInd = false; } else { - outInds << "\t" << e.d0; + writeInd = true; + outInds << rep << "\t" << yr << "\t" << gen; } - } // end of if (emig.indVar) - - if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 1) { // SMS - trfrSMSTraits s = inds[i]->getSMSTraits(); - outInds << "\t" << s.dp << "\t" << s.gb; - outInds << "\t" << s.alphaDB << "\t" << s.betaDB; - } // end of SMS - if (trfr.moveType == 2) { // CRW - trfrCRWTraits c = inds[i]->getCRWTraits(); - outInds << "\t" << c.stepLength << "\t" << c.rho; -#if RSDEBUG -//DEBUGLOG << "Population::outIndividual():" -// << " patchNum=" << patchNum << " i=" << i << " ID=" << inds[i]->getId() -// << " nTrfrGenes=" << nTrfrGenes << " loc[0][0].allele[0]=" << loc[0][0].allele[0] -// << endl; -#endif - } // end of CRW + } + if (writeInd) { + outInds << "\t" << spNum << "\t" << inds[i]->getId(); + if (dem.stageStruct) outInds << "\t" << ind.status; + else { // non-structured population + outInds << "\t" << ind.status; } - else { // kernel - trfrKernTraits k = inds[i]->getKernTraits(); - if (trfr.twinKern) - { - outInds << "\t" << k.meanDist1 << "\t" << k.meanDist2 << "\t" << k.probKern1; + pCell = inds[i]->getLocn(1); + locn loc; + if (pCell == 0) loc.x = loc.y = -1; // beyond boundary or in no-data cell + else loc = pCell->getLocn(); + pCell = inds[i]->getLocn(0); + locn natalloc = pCell->getLocn(); + if (ppLand.patchModel) { + outInds << "\t" << inds[i]->getNatalPatch()->getPatchNum(); + if (loc.x == -1) outInds << "\t-1"; + else outInds << "\t" << patchNum; + } + else { // cell-based model + outInds << "\t" << (float)natalloc.x << "\t" << natalloc.y; + outInds << "\t" << (float)loc.x << "\t" << (float)loc.y; + } + if (dem.repType != 0) outInds << "\t" << ind.sex; + if (dem.stageStruct) outInds << "\t" << ind.age << "\t" << ind.stage; + + if (emig.indVar) { + emigTraits e = inds[i]->getEmigTraits(); + if (emig.densDep) { + outInds << "\t" << e.d0 << "\t" << e.alpha << "\t" << e.beta; } else { - outInds << "\t" << k.meanDist1; + outInds << "\t" << e.d0; + } + } // end of if (emig.indVar) + + if (trfr.indVar) { + if (trfr.moveModel) { + if (trfr.moveType == 1) { // SMS + trfrSMSTraits s = inds[i]->getSMSTraits(); + outInds << "\t" << s.dp << "\t" << s.gb; + outInds << "\t" << s.alphaDB << "\t" << s.betaDB; + } // end of SMS + if (trfr.moveType == 2) { // CRW + trfrCRWTraits c = inds[i]->getCRWTraits(); + outInds << "\t" << c.stepLength << "\t" << c.rho; + } // end of CRW + } + else { // kernel + trfrKernTraits k = inds[i]->getKernTraits(); + if (trfr.twinKern) + { + outInds << "\t" << k.meanDist1 << "\t" << k.meanDist2 << "\t" << k.probKern1; + } + else { + outInds << "\t" << k.meanDist1; + } } } - } - if (sett.indVar) { - settleTraits s = inds[i]->getSettTraits(); - outInds << "\t" << s.s0 << "\t" << s.alpha << "\t" << s.beta; - } + if (sett.indVar) { + settleTraits s = inds[i]->getSettTraits(); + outInds << "\t" << s.s0 << "\t" << s.alpha << "\t" << s.beta; + } - // distance moved (metres) - if (loc.x == -1) outInds << "\t-1"; - else { - float d = ppLand.resol * sqrt((float)((natalloc.x-loc.x)*(natalloc.x-loc.x) - + (natalloc.y-loc.y)*(natalloc.y-loc.y))); - outInds << "\t" << d; - } + // distance moved (metres) + if (loc.x == -1) outInds << "\t-1"; + else { + float d = ppLand.resol * sqrt((float)((natalloc.x - loc.x) * (natalloc.x - loc.x) + + (natalloc.y - loc.y) * (natalloc.y - loc.y))); + outInds << "\t" << d; + } #if RSDEBUG - // ALWAYS WRITE NO. OF STEPS - steps = inds[i]->getSteps(); - outInds << "\t" << steps.year; -#else - if (trfr.moveModel) { + // ALWAYS WRITE NO. OF STEPS steps = inds[i]->getSteps(); outInds << "\t" << steps.year; - } +#else + if (trfr.moveModel) { + steps = inds[i]->getSteps(); + outInds << "\t" << steps.year; + } #endif - outInds << endl; - } // end of writeInd condition - -} + outInds << endl; + } // end of writeInd condition + } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Write records to genetics file -void Population::outGenetics(const int rep,const int year,const int landNr) +void Population::outGenetics(const int rep, const int year, const int landNr) { -simParams sim = paramsSim->getSim(); + simParams sim = paramsSim->getSim(); -if (landNr >= 0) { // open file - Genome *pGenome; - genomeData gen = pSpecies->getGenomeData(); - if (gen.trait1Chromosome) { - pGenome = new Genome(pSpecies->getNChromosomes(),pSpecies->getNLoci(0), - pSpecies->isDiploid()); - } - else { - pGenome = new Genome(pSpecies); + if (landNr >= 0) { // open file + Genome* pGenome; + genomeData gen = pSpecies->getGenomeData(); + if (gen.trait1Chromosome) { + pGenome = new Genome(pSpecies->getNChromosomes(), pSpecies->getNLoci(0), + pSpecies->isDiploid()); + } + else { + pGenome = new Genome(pSpecies); + } + pGenome->outGenHeaders(rep, landNr, sim.outGenXtab); + delete pGenome; + return; } - pGenome->outGenHeaders(rep,landNr,sim.outGenXtab); - delete pGenome; - return; -} -if (landNr == -999) { // close file - Genome *pGenome = new Genome(); - pGenome->outGenHeaders(rep,landNr,sim.outGenXtab); - delete pGenome; - return; -} - -short spNum = pSpecies->getSpNum(); -short nstages = 1; -if (pSpecies->stageStructured()) { - stageParams sstruct = pSpecies->getStage(); - nstages = sstruct.nStages; -} + if (landNr == -999) { // close file + Genome* pGenome = new Genome(); + pGenome->outGenHeaders(rep, landNr, sim.outGenXtab); + delete pGenome; + return; + } + short spNum = pSpecies->getSpNum(); + short nstages = 1; + if (pSpecies->stageStructured()) { + stageParams sstruct = pSpecies->getStage(); + nstages = sstruct.nStages; + } -int ninds = (int)inds.size(); -for (int i = 0; i < ninds; i++) { - indStats ind = inds[i]->getStats(); - if (year == 0 || sim.outGenType == 1 - || (sim.outGenType == 0 && ind.stage == 0) - || (sim.outGenType == 2 && ind.stage == nstages-1)) { - inds[i]->outGenetics(rep,year,spNum,landNr,sim.outGenXtab); + int ninds = (int)inds.size(); + for (int i = 0; i < ninds; i++) { + indStats ind = inds[i]->getStats(); + if (year == 0 || sim.outGenType == 1 + || (sim.outGenType == 0 && ind.stage == 0) + || (sim.outGenType == 2 && ind.stage == nstages - 1)) { + inds[i]->outGenetics(rep, year, spNum, landNr, sim.outGenXtab); + } } -} } diff --git a/Population.h b/Population.h index 9c8efd8..fd1fa66 100644 --- a/Population.h +++ b/Population.h @@ -50,9 +50,6 @@ Last updated: 22 January 2022 by Steve Palmer #include #include -//#include -//#include -//#include using namespace std; #include "Parameters.h" diff --git a/RSrandom.cpp b/RSrandom.cpp index 79744c9..1b9f523 100644 --- a/RSrandom.cpp +++ b/RSrandom.cpp @@ -26,7 +26,6 @@ #if !RS_RCPP - #if RSDEBUG #include "Parameters.h" extern paramSim* paramsSim; @@ -94,6 +93,8 @@ int RSrandom::IRandom(int min, int max) int RSrandom::Bernoulli(double p) { + if (p < 0) throw runtime_error("Bernoulli's p cannot be negative.\n"); + if (p > 1) throw runtime_error("Bernoulli's p cannot be above 1.\n"); return Random() < p; } @@ -190,6 +191,8 @@ int RSrandom::Poisson(double mean) } int RSrandom::Bernoulli(double p) { + if (p < 0) throw runtime_error("Bernoulli's p cannot be negative.\n"); + if (p > 1) throw runtime_error("Bernoulli's p cannot be above 1.\n"); return Random() < p; } @@ -253,4 +256,28 @@ int RSrandom::Poisson(double mean) #endif // RS_RCPP + +#if RSDEBUG + void testRSrandom() { + + { + // Bernoulli distribution + // Abuse cases + assert_error("Bernoulli's p cannot be negative.\n", []{ + RSrandom rsr; + rsr.Bernoulli(-0.3); + }); + assert_error("Bernoulli's p cannot be above 1.\n", [] { + RSrandom rsr; + rsr.Bernoulli(1.1); + }); + // Use cases + RSrandom rsr; + assert(rsr.Bernoulli(0) == 0); + assert(rsr.Bernoulli(1) == 1); + int bern_trial = rsr.Bernoulli(0.5); + assert(bern_trial == 0 || bern_trial == 1); + } + } +#endif // RSDEBUG //--------------------------------------------------------------------------- diff --git a/RSrandom.h b/RSrandom.h index 98d91f4..0e61c19 100644 --- a/RSrandom.h +++ b/RSrandom.h @@ -38,7 +38,8 @@ Last updated: 12 January 2021 by Steve Palmer #include #include -//#include +#include +#include "Utils.h" #if RS_RCPP #include "../Version.h" @@ -131,6 +132,9 @@ extern ofstream DEBUGLOG; #endif // !RS_RCPP +#if RSDEBUG + void testRSrandom(); +#endif // RSDEBUG //--------------------------------------------------------------------------- diff --git a/Utils.cpp b/Utils.cpp new file mode 100644 index 0000000..049bc9e --- /dev/null +++ b/Utils.cpp @@ -0,0 +1,9 @@ +#include "Utils.h" + +// Evaluate a lambda and assert we get the correct error +void assert_error(const string& exptd_err_msg, void (*lambda)(void)) { + string err_msg{ "No error.\n" }; + try { lambda(); } // evaluate + catch (exception& e) { err_msg = e.what(); } + assert(err_msg == exptd_err_msg); +} \ No newline at end of file diff --git a/Utils.h b/Utils.h new file mode 100644 index 0000000..948a8c2 --- /dev/null +++ b/Utils.h @@ -0,0 +1,12 @@ +#ifndef UtilsH +#define UtilsH + +#include +#include +#include +using namespace std; + +// Evaluate a lambda and assert we get the correct error +void assert_error(const string& exptd_err_msg, void (*x)(void)); + +#endif // UtilsH From 3e654d899b3157fdb934d3b9dc77f034dcdcffac Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Thu, 23 Nov 2023 16:14:53 +0000 Subject: [PATCH 08/17] functional main --- CMakeLists.txt | 16 ++++++++++++-- Main.cpp | 57 +++++++++++++++++++++++++++++++++++++++----------- Utils.cpp | 17 +++++++++++++++ Utils.h | 6 ++++++ 4 files changed, 82 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 56c5971..dda2692 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,17 @@ +cmake_minimum_required(VERSION 3.10) + +# set the project name and version +project(RScore VERSION 2.1.0) + +# specify the C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) + # Config file for compilation with CMake # Only relevant for Batch mode, but this file needs to live in the RScore folder -add_library(RScore Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp Utils.cpp) +add_executable(RScore Main.cpp Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp Utils.cpp) +#add_library(RScore Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp Utils.cpp) # pass config definitions to compiler target_compile_definitions(RScore PRIVATE RSWIN64) @@ -14,4 +24,6 @@ endif() # Debug Mode by default, unless "release" is passed if(NOT DEFINED release) add_compile_definitions(RSDEBUG) -endif() \ No newline at end of file +endif() + +target_include_directories(RScore PUBLIC "${PROJECT_BINARY_DIR}") diff --git a/Main.cpp b/Main.cpp index 74b036f..0f6ae48 100644 --- a/Main.cpp +++ b/Main.cpp @@ -19,11 +19,6 @@ * --------------------------------------------------------------------------*/ -#include -#include -#include - -using namespace std; #if LINUX_CLUSTER || R_CMD #include @@ -31,12 +26,20 @@ using namespace std; #include #endif -void assert_error(const string& exptd_err_msg, void (*x)(void)) { - string err_msg{ "No error.\n" }; - try { x(); } - catch (exception& e) { err_msg = e.what(); } - assert(err_msg == exptd_err_msg); -} +#include +#include +#include +#include +#include "Individual.h" +#include "Community.h" +#include "RSrandom.h" +#include "Utils.h" +#include "Parameters.h" +#include "Landscape.h" +#include "Species.h" +#include "SubCommunity.h" + +using namespace std; void run_unit_tests() { cout << "******* Unit test output *******" << endl; @@ -45,6 +48,36 @@ void run_unit_tests() { cout << endl << "************************" << endl; } +// Global vars +string habmapname, patchmapname, distnmapname; +string costmapname, genfilename; +string landFile; +paramGrad* paramsGrad; +paramStoch* paramsStoch; +paramInit* paramsInit; +paramSim* paramsSim; +RSrandom* pRandom; +ofstream DEBUGLOG; +ofstream MUTNLOG; +vector hfnames; +Species* pSpecies; +Community* pComm; +void DebugGUI(string msg) { + // nothing +} +void MemoLine(string msg) { + /// nothing +} +traitCanvas SetupTraitCanvas(void) { + traitCanvas tcanv; + for (int i = 0; i < NTRAITS; i++) { tcanv.pcanvas[i] = 0; } + return tcanv; +} +void Landscape::setLandMap(void) { } +void Landscape::drawLandscape(int rep, int yr, int landnum) { } +void Community::viewOccSuit(int year, double mn, double se) { } +void Community::draw(int rep, int yr, int gen, int landNum) { } + #if LINUX_CLUSTER || RS_RCPP int main(int argc, char* argv[]) #else @@ -60,4 +93,4 @@ int _tmain(int argc, _TCHAR* argv[]) cout << "All tests have completed." << endl; return 0; // if tests succeed, we are happy # endif // NDEBUG -} \ No newline at end of file +} diff --git a/Utils.cpp b/Utils.cpp index 049bc9e..9d36b92 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -1,5 +1,22 @@ #include "Utils.h" +const string Int2Str(const int x) +{ + ostringstream o; + if (!(o << x)) return "ERROR"; + return o.str(); +} +const string Float2Str(const float x) { + ostringstream o; + if (!(o << x)) return "ERROR"; + return o.str(); +} +const string Double2Str(const double x) { + ostringstream o; + if (!(o << x)) return "ERROR"; + return o.str(); +} + // Evaluate a lambda and assert we get the correct error void assert_error(const string& exptd_err_msg, void (*lambda)(void)) { string err_msg{ "No error.\n" }; diff --git a/Utils.h b/Utils.h index 948a8c2..34854a7 100644 --- a/Utils.h +++ b/Utils.h @@ -3,9 +3,15 @@ #include #include +#include + #include using namespace std; +const string Int2Str(const int x); +const string Float2Str(const float x); +const string Double2Str(const double x); + // Evaluate a lambda and assert we get the correct error void assert_error(const string& exptd_err_msg, void (*x)(void)); From 313402294f41d1f68a23f3f3c5b27698fa55631d Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Thu, 23 Nov 2023 17:09:45 +0000 Subject: [PATCH 09/17] compile RScore as standalone with CMake, fix #16 --- CMakeLists.txt | 27 ++++++++++++++------------- Main.cpp | 1 - 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dda2692..c14a3e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,17 +1,16 @@ -cmake_minimum_required(VERSION 3.10) - -# set the project name and version -project(RScore VERSION 2.1.0) - -# specify the C++ standard -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED True) - # Config file for compilation with CMake -# Only relevant for Batch mode, but this file needs to live in the RScore folder -add_executable(RScore Main.cpp Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp Utils.cpp) -#add_library(RScore Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp Utils.cpp) +if (NOT batchmode) # that is, RScore as a standalone + cmake_minimum_required(VERSION 3.10) + # set the project name and version + project(RScore VERSION 2.1.0) + # specify the C++ standard + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED True) + add_executable(RScore Main.cpp Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp Utils.cpp) +else() # that is, RScore compiled as library within RangeShifter_batch + add_library(RScore Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp Utils.cpp) +endif() # pass config definitions to compiler target_compile_definitions(RScore PRIVATE RSWIN64) @@ -26,4 +25,6 @@ if(NOT DEFINED release) add_compile_definitions(RSDEBUG) endif() -target_include_directories(RScore PUBLIC "${PROJECT_BINARY_DIR}") +if(NOT batchmode) + target_include_directories(RScore PUBLIC "${PROJECT_BINARY_DIR}") +endif() \ No newline at end of file diff --git a/Main.cpp b/Main.cpp index 0f6ae48..42f783b 100644 --- a/Main.cpp +++ b/Main.cpp @@ -19,7 +19,6 @@ * --------------------------------------------------------------------------*/ - #if LINUX_CLUSTER || R_CMD #include #else From 14177eebe01c6aa9e921752d95e57f76c623db12 Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Thu, 23 Nov 2023 17:10:16 +0000 Subject: [PATCH 10/17] go github action --- .github/workflows/check.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/check.yml diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..2e86587 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,26 @@ +name: check +on: push + +jobs: + check: + strategy: + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + include: + - os: windows-latest + path_to_exe: ./build/Debug/RScore.exe + - os: ubuntu-latest + path_to_exe: ./build/RScore + - os: macos-latest + path_to_exe: ./build/RScore + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + + - name: build + run: | + mkdir build && cd build + cmake ../ && cmake --build . + + - name: run + run: ${{ matrix.path_to_exe }} From 3f7525d87c95eddee2c674f2ba32a3789816be66 Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Thu, 23 Nov 2023 18:01:18 +0000 Subject: [PATCH 11/17] replaced unicode greek characters with LaTeX commands --- RangeShiftR/R/class_DemogParams.R | 52 ++++++------- RangeShiftR/R/class_DispersalParams.R | 100 ++++++++++++------------- RangeShiftR/R/class_RSparams.R | 12 +-- RangeShiftR/R/class_SimulationParams.R | 12 +-- RangeShiftR/R/plotProbs.R | 12 +-- RangeShiftR/man/CorrRW.Rd | 2 +- RangeShiftR/man/DispersalKernel.Rd | 38 +++++----- RangeShiftR/man/Emigration.Rd | 20 ++--- RangeShiftR/man/Settlement.Rd | 22 +++--- RangeShiftR/man/Simulation.Rd | 12 +-- RangeShiftR/man/StageStructure.Rd | 52 ++++++------- RangeShiftR/man/plotProbs.Rd | 12 +-- 12 files changed, 173 insertions(+), 173 deletions(-) diff --git a/RangeShiftR/R/class_DemogParams.R b/RangeShiftR/R/class_DemogParams.R index 82f1e5c..99d4682 100644 --- a/RangeShiftR/R/class_DemogParams.R +++ b/RangeShiftR/R/class_DemogParams.R @@ -57,39 +57,39 @@ #' demographic parameters. Individuals are characterized by their age and stage. Each stage has a certain fecundity, survival probability and probability of developing to the next stage. #' #' These parameters are provided through classical transition matrices \insertCite{caswell2001}{RangeShiftR}. -#' \ifelse{html}{\out{φi}}{\eqn{φ_i}} is the fecundity of stage \eqn{i} ; -#' \ifelse{html}{\out{σi}}{\eqn{Ď_i}} is the survival probability of an individual in stage \eqn{i} ; -#' and \ifelse{html}{\out{γi-j}}{\eqn{Îł_(i-j)}} is the probability of developing from stage \eqn{i} to stage \eqn{j}. +#' \ifelse{html}{\out{φi}}{\eqn{\phi_i}} is the fecundity of stage \eqn{i} ; +#' \ifelse{html}{\out{σi}}{\eqn{\sigma_i}} is the survival probability of an individual in stage \eqn{i} ; +#' and \ifelse{html}{\out{γi-j}}{\eqn{\gamma_(i-j)}} is the probability of developing from stage \eqn{i} to stage \eqn{j}. #' In this way, the transition matrix describes the effect of each individuals current stage (column) on all stages at the next timestep (rows). #' Since all offspring is born into the juvenile stage (stage 0), all fecundities are always located in the first row of the matrix. #' #' However, in \emph{RangeShiftR}, these parameters are not used deterministically as \emph{rates} (like it is typical for matrix models) but, instead, as \emph{probabilities} which are -#' applied stochastically at the individual level. Hence, each female at stage \eqn{i}, if it reproduces, produces a number of offspring given by \eqn{Poisson}(\ifelse{html}{\out{φi}}{\eqn{φ_i}}), -#' while Bernoulli trials \eqn{Bern}(\ifelse{html}{\out{σi}}{\eqn{Ď_i}}) and \eqn{Bern}(\ifelse{html}{\out{γi,i+1}}{\eqn{Îł_(i,i+1)}}) determine if an individual/female survives or not +#' applied stochastically at the individual level. Hence, each female at stage \eqn{i}, if it reproduces, produces a number of offspring given by \eqn{Poisson}(\ifelse{html}{\out{φi}}{\eqn{\phi_i}}), +#' while Bernoulli trials \eqn{Bern}(\ifelse{html}{\out{σi}}{\eqn{\sigma_i}}) and \eqn{Bern}(\ifelse{html}{\out{γi,i+1}}{\eqn{\gamma_(i,i+1)}}) determine if an individual/female survives or not #' and - if it survives - if it develops to the next stage or not. #' #' An example transition matrix for a 3-staged only-female or simple sexual (\code{ReproductionType={0,1}}) population model: -#' \tabular{ccccc}{0 \tab | \tab 0 \tab | \tab \ifelse{html}{\out{φ2}}{\eqn{φ_2}} \cr -#' \eqn{1.0} \tab | \tab \ifelse{html}{\out{σ1 (1-γ1-2)}}{\eqn{Ď_1 (1 â’ Îł_(1-2))}} \tab | \tab \eqn{0} \cr -#' \eqn{0} \tab | \tab \ifelse{html}{\out{σ1 γ1-2}}{\eqn{Ď_1 Îł_(1-2)}} \tab | \tab \ifelse{html}{\out{σ2}}{\eqn{Ď_2}} \cr} +#' \tabular{ccccc}{0 \tab | \tab 0 \tab | \tab \ifelse{html}{\out{φ2}}{\eqn{\phi_2}} \cr +#' \eqn{1.0} \tab | \tab \ifelse{html}{\out{σ1 (1-γ1-2)}}{\eqn{\sigma_1 (1 - \gamma_(1-2))}} \tab | \tab \eqn{0} \cr +#' \eqn{0} \tab | \tab \ifelse{html}{\out{σ1 γ1-2}}{\eqn{\sigma_1 \gamma_(1-2)}} \tab | \tab \ifelse{html}{\out{σ2}}{\eqn{\sigma_2}} \cr} #' -#' In a female-only model (\code{ReproductionType=0}), \ifelse{html}{\out{φ}}{\eqn{φ}} represents the number of female offspring per female and reproductive event. \cr +#' In a female-only model (\code{ReproductionType=0}), \ifelse{html}{\out{φ}}{\eqn{\phi}} represents the number of female offspring per female and reproductive event. \cr #' Note that for an implicit (simple) sexual model (\code{ReproductionType=1}), the demographic parameters are not sex-specific. However, individuals are defined by their sex, which is acknowledged for example in the dispersal -#' process and transmission of alleles. The fecundities \ifelse{html}{\out{φ}}{\eqn{φ}} refer to the number of all offspring (males and females) per female and reproductive event. +#' process and transmission of alleles. The fecundities \ifelse{html}{\out{φ}}{\eqn{\phi}} refer to the number of all offspring (males and females) per female and reproductive event. #' #' In case of an explicit (complex) sexual model (\code{ReproductionType=2}), in contrast, each stage must be represented by two columns and rows to distinguish male and female demographic parameters. -#' Note, however, that in any case the juvenile stage has only one row; it contains the fecundities. Male fecundities should have one of two possible values: set \ifelse{html}{\out{φm}}{\eqn{φ_m}} \eqn{=1.0} for reproductive males or \ifelse{html}{\out{φm}}{\eqn{φ_m}} \eqn{=0.0} for non-reproductive males.\cr +#' Note, however, that in any case the juvenile stage has only one row; it contains the fecundities. Male fecundities should have one of two possible values: set \ifelse{html}{\out{φm}}{\eqn{\phi_m}} \eqn{=1.0} for reproductive males or \ifelse{html}{\out{φm}}{\eqn{\phi_m}} \eqn{=0.0} for non-reproductive males.\cr #' An example transition matrix for a 3-staged explicit sexual population model \insertCite{weeks1986,lindstrom1998}{RangeShiftR}: -#' \tabular{ccccccccccc}{\eqn{0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{φ1m}}{\eqn{φ_1m}} \tab | \tab \ifelse{html}{\out{φ1f}}{\eqn{φ_1f}} \tab | \tab \ifelse{html}{\out{φ2m}}{\eqn{φ_2m}} \tab | \tab \ifelse{html}{\out{φ2f}}{\eqn{φ_2f}} \cr -#' \eqn{1.0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1m (1-γ1-2,m)}}{\eqn{Ď_1m (1 â’ Îł_(1-2,m))}} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \cr -#' \eqn{0} \tab | \tab \eqn{1.0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1f γ1-2,f}}{\eqn{Ď_1f Îł_(1-2,f)}} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \cr -#' \eqn{0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1m γ1-2,m}}{\eqn{Ď_1m Îł_(1-2,m)}} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ2m}}{\eqn{Ď_2m}} \tab | \tab \eqn{0} \cr -#' \eqn{0} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1f γ1-2,f}}{\eqn{Ď_1f Îł_(1-2,f)}} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ2f}}{\eqn{Ď_2f}} \cr}#' The mating system is explicitly modelled and a female’s probability of reproducing is determined as described in \code{\link[RangeShiftR]{Demography}} \insertCite{weeks1986,caswell2001}{RangeShiftR}. +#' \tabular{ccccccccccc}{\eqn{0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{φ1m}}{\eqn{\phi_1m}} \tab | \tab \ifelse{html}{\out{φ1f}}{\eqn{\phi_1f}} \tab | \tab \ifelse{html}{\out{φ2m}}{\eqn{\phi_2m}} \tab | \tab \ifelse{html}{\out{φ2f}}{\eqn{\phi_2f}} \cr +#' \eqn{1.0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1m (1-γ1-2,m)}}{\eqn{\sigma_1m (1 - \gamma_(1-2,m))}} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \cr +#' \eqn{0} \tab | \tab \eqn{1.0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1f γ1-2,f}}{\eqn{\sigma_1f \gamma_(1-2,f)}} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \cr +#' \eqn{0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1m γ1-2,m}}{\eqn{\sigma_1m \gamma_(1-2,m)}} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ2m}}{\eqn{\sigma_2m}} \tab | \tab \eqn{0} \cr +#' \eqn{0} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1f γ1-2,f}}{\eqn{\sigma_1f \gamma_(1-2,f)}} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ2f}}{\eqn{\sigma_2f}} \cr}#' The mating system is explicitly modelled and a female’s probability of reproducing is determined as described in \code{\link[RangeShiftR]{Demography}} \insertCite{weeks1986,caswell2001}{RangeShiftR}. #' #' A common mistake in building a transition matrix is made when offspring produced at year \eqn{t} develop to the next stage in the same year \insertCite{@ @caswell2001 pg. 60-62}{RangeShiftR}. To avoid this problem without losing the offspring stage, and hence the chance for simulating post-natal dispersal, #' we require an additional explicit juvenile stage (stage 0). Juveniles have to develop to stage 1 in the same year they are born. Hence the minimum number of stages of a stage-structured model is always \eqn{2}. It is important to note that juvenile mortality can be accounted for in -#' two ways. Either, as in the examples above, it is included in adult fecundity \ifelse{html}{\out{φ}}{\eqn{φ}} (by appropriately reducing its value), and \ifelse{html}{\out{σ0 γ(0-1)}}{\eqn{Ď_0 Îł_(0-1)}} is equal to \eqn{1.0}. This is how it is typically accounted for in matrix models. Or, alternatively, -#' φ is equal to the true maximum fecundity and \ifelse{html}{\out{σ0 γ(0-1)}}{\eqn{Ď_0 Îł_(0-1)}} is less than \eqn{1.0}. +#' two ways. Either, as in the examples above, it is included in adult fecundity \ifelse{html}{\out{φ}}{\eqn{\phi}} (by appropriately reducing its value), and \ifelse{html}{\out{σ0 γ(0-1)}}{\eqn{\sigma_0 \gamma_(0-1)}} is equal to \eqn{1.0}. This is how it is typically accounted for in matrix models. Or, alternatively, +#' \phi is equal to the true maximum fecundity and \ifelse{html}{\out{σ0 γ(0-1)}}{\eqn{\sigma_0 \gamma_(0-1)}} is less than \eqn{1.0}. #' Only the first approach allows straightforward direct comparison with standard analytical matrix models. #' #' \emph{Minimum ages:} For every row in the transition matrix, a minimum age must be provided through a vector in argument \code{MinAge}. It specifies the age which an individual in stage \eqn{i-1} (with sex \eqn{m/f}, if applicable) must already have reached before it can develop into the next stage \eqn{(i)}. The vector must be in @@ -122,26 +122,26 @@ #' \emph{Density dependence} can act on each of the three demographic phases (i.e. reproduction, survival and development) and is controlled by \code{FecDensDep,DevDensDep,SurvDensDep}. #' It is implemented as an exponential decay \insertCite{neubert2000}{RangeShiftR}: #' -#' \ifelse{html}{\out{   φi(r,t) = φ0,i * e - b(r) N(t) }}{\deqn{φ_i(r,t)=φ_(0,i) * exp(- b(r) N(t) ) }} +#' \ifelse{html}{\out{   φi(r,t) = φ0,i * e - b(r) N(t) }}{\deqn{\phi_i(r,t)=\phi_(0,i) * exp(- b(r) N(t) ) }} #' -#' \ifelse{html}{\out{   σi(r,t) = σ0,i * e - Cσ b(r) N(t) }}{\deqn{Ď_i(r,t)=Ď_(0,i) * exp(- C_\sigma b(r) N(t) ) }} +#' \ifelse{html}{\out{   σi(r,t) = σ0,i * e - Cσ b(r) N(t) }}{\deqn{\sigma_i(r,t)=\sigma_(0,i) * exp(- C_\sigma b(r) N(t) ) }} #' -#' \ifelse{html}{\out{   γi(r,t) = γ0,i * e - Cγ b(r) N(t) }}{\deqn{Îł_i(r,t)=Îł_(0,i) * exp(- C_Îł b(r) N(t) ) }} +#' \ifelse{html}{\out{   γi(r,t) = γ0,i * e - Cγ b(r) N(t) }}{\deqn{\gamma_i(r,t)=\gamma_(0,i) * exp(- C_\gamma b(r) N(t) ) }} #' #' where \eqn{b(r)} is the strength of density dependence in fecundity at site \eqn{r}, which is given by the argument \code{K_or_DensDep} in the landscape module. -#' Furthermore, \ifelse{html}{\out{Cσ}}{\eqn{C_\sigma}} and \ifelse{html}{\out{Cγ}}{\eqn{C_Îł}} (\code{DevDensCoeff,SurvDensCoeff}) +#' Furthermore, \ifelse{html}{\out{Cσ}}{\eqn{C_\sigma}} and \ifelse{html}{\out{Cγ}}{\eqn{C_\gamma}} (\code{DevDensCoeff,SurvDensCoeff}) #' scale the strength of density dependence in survival and development relative to that in fecundity. #' #' Moreover, the strength of density-dependence can be uniform for all stages or stage-dependent. Even greater complexity can be incorporated with #' different stages contributing differently to density-dependence \insertCite{caswell2004}{RangeShiftR}: #' -#' \ifelse{html}{\out{  φi(r,t) = φ0,i * e - b(r) ΣjS ωφ,ij N(j,t)}}{\deqn{φ_i(r,t)=φ_(0,i) * exp(- b(r) \Sigma_j^S ω_{φ,ij} N_j(t) ) }} +#' \ifelse{html}{\out{  φi(r,t) = φ0,i * e - b(r) ΣjS ωφ,ij N(j,t)}}{\deqn{\phi_i(r,t)=\phi_(0,i) * exp(- b(r) \Sigma_j^S \omega_{\phi,ij} N_j(t) ) }} #' -#' \ifelse{html}{\out{  σi(r,t) = σ0,i * e - Cσ b(r) ΣjS ωσ,ij N(j,t) }}{\deqn{Ď_i(r,t)=Ď_(0,i) * exp(- C_\sigma b(r) \Sigma_j^S ω_{Ď,ij} N_j(t) )}} +#' \ifelse{html}{\out{  σi(r,t) = σ0,i * e - Cσ b(r) ΣjS ωσ,ij N(j,t) }}{\deqn{\sigma_i(r,t)=\sigma_(0,i) * exp(- C_\sigma b(r) \Sigma_j^S \omega_{\sigma,ij} N_j(t) )}} #' -#' \ifelse{html}{\out{  γi(r,t) = γ0,i * e - Cγ b(r) ΣjS ωγ,ij N(j,t)}}{\deqn{Îł_i(r,t)=Îł_(0,i) * exp(- C_Îł b(r) \Sigma_j^S ω_{Îł,ij} N_j(t) )}} +#' \ifelse{html}{\out{  γi(r,t) = γ0,i * e - Cγ b(r) ΣjS ωγ,ij N(j,t)}}{\deqn{\gamma_i(r,t)=\gamma_(0,i) * exp(- C_\gamma b(r) \Sigma_j^S \omega_{\gamma,ij} N_j(t) )}} #' -#' where \ifelse{html}{\out{ωφ}}{\eqn{ω_φ}}, \ifelse{html}{\out{ωσ}}{\eqn{ω_Ď}}, \ifelse{html}{\out{ωγ}}{\eqn{ω_Îł}} are weight matrices given by \code{FecStageWtsMatrix, DevStageWtsMatrix, SurvStageWtsMatrix}. Their elements \ifelse{html}{\out{ωij}}{\eqn{ω_ij}} +#' where \ifelse{html}{\out{ωφ}}{\eqn{\omega_\phi}}, \ifelse{html}{\out{ωσ}}{\eqn{\omega_\sigma}}, \ifelse{html}{\out{ωγ}}{\eqn{\omega_\gamma}} are weight matrices given by \code{FecStageWtsMatrix, DevStageWtsMatrix, SurvStageWtsMatrix}. Their elements \ifelse{html}{\out{ωij}}{\eqn{\omega_ij}} #' represent the contributions of the abundance of stage \eqn{j} to the density dependence in the fecundity / survival / development of stage \eqn{i}, thus they are quadratic matrices of size \code{Stages}\eqn{^2}. Note that the row sums are not required to be normalized, therefore they can be used #' to scale the density-dependence for the different stages. In fact, any real value will be accepted for the single weights, so care should be taken when setting them. #' @examples # Stage-structure for simple sexual model diff --git a/RangeShiftR/R/class_DispersalParams.R b/RangeShiftR/R/class_DispersalParams.R index 29e88a0..acd8b60 100644 --- a/RangeShiftR/R/class_DispersalParams.R +++ b/RangeShiftR/R/class_DispersalParams.R @@ -58,18 +58,18 @@ #' #' The emigration probability \eqn{d} can be density-dependent (set \code{DensDep=TRUE}), in which case it is given by the following function, introduced by \insertCite{kun2006evolution;textual}{RangeShiftR}: #' -#' \ifelse{html}{\out{   d(i,t) = D0 / ( 1 + e-αsub>E (N(i,t) / K(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-α_E (N(i,t)/K(i,t) - β_E) ] ) } } +#' \ifelse{html}{\out{   d(i,t) = D0 / ( 1 + e-αsub>E (N(i,t) / K(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-\alpha_E (N(i,t)/K(i,t) - \beta_E) ] ) } } #' #' In the case of stage-structured models this equation is modified to: #' -#' \ifelse{html}{\out{   d(i,t) = D0 / ( 1 + e-αsub>E (b(i,t) * N(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-α_E (b(i,t) N(i,t) - β_E) ] ) } } +#' \ifelse{html}{\out{   d(i,t) = D0 / ( 1 + e-αsub>E (b(i,t) * N(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-\alpha_E (b(i,t) N(i,t) - \beta_E) ] ) } } #' #' In the first case, \eqn{K(i,t)} is the carrying capacity of the cell/patch \eqn{i} at time \eqn{t} given by \code{K_or_DensDep}. #' In the latter case, \eqn{b(i,t)} represents the strength of density dependence and is given by the inverse of \code{K_or_DensDep}.\cr #' Further, \ifelse{html}{\out{D0}}{\eqn{D_0}} is the maximum emigration probability, #' \eqn{N(i,t)} is the number of individuals in the cell/patch \eqn{i} at time \eqn{t}, -#' \ifelse{html}{\out{βE}}{\eqn{β_S}} is the inflection point of the function and -#' \ifelse{html}{\out{αE}}{\eqn{α_S}} is the slope at the inflection point.\cr +#' \ifelse{html}{\out{βE}}{\eqn{\beta_S}} is the inflection point of the function and +#' \ifelse{html}{\out{αE}}{\eqn{\alpha_S}} is the slope at the inflection point.\cr #' #' Various functions have been proposed for density dependent emigration \insertCite{hovestadt2010information,poethke2011ability}{RangeShiftR}. #' This one was chosen here because it is a flexible function that @@ -78,8 +78,8 @@ #' Information acquisition is not explicitly modelled. #' #' The emigration probability can be allowed to vary between individuals (set \code{IndVar=TRUE}) and to evolve. In the this case, individuals exhibit either one trait -#' determining the density-independent \eqn{d} (when \code{DensDep=FALSE}), or the three traits \ifelse{html}{\out{D0}}{\eqn{D_0}}, \eqn{α} and -#' \eqn{β} determining the density-dependent emigration probability (when \code{DensDep=TRUE}).\cr +#' determining the density-independent \eqn{d} (when \code{DensDep=FALSE}), or the three traits \ifelse{html}{\out{D0}}{\eqn{D_0}}, \eqn{\alpha} and +#' \eqn{\beta} determining the density-dependent emigration probability (when \code{DensDep=TRUE}).\cr #' For each trait the initial distribution in the population (as mean and standard variation) must be set in \code{EmigProb} (instead of only one constant value), #' as well as their scaling factors in \code{TraitScaleFactor} (see \code{\link[RangeShiftR]{Genetics}}). #' Also, if \code{IndVar=TRUE} is set for a stage-structured population, it is required to specify the stage which emigrates via \code{EmigStage}. @@ -91,7 +91,7 @@ #' #' The parameters that determine the emigration probabilities have to be provided via \code{EmigProb}, which generally takes a matrix, or - if only a single constant probability is #' used (i.e. \code{DensDep, IndVar, StageDep, SexDep = FALSE}) - a single numeric. The format of the matrix is defined as follows: The number of columns depend on the options \code{DensDep} and \code{IndVar}. If \code{DensDep=FALSE}, the -#' density-independent probability \eqn{d} must be specified. If \code{DensDep=TRUE}, the functional parameters \ifelse{html}{\out{D0}}{\eqn{D_0}}, \eqn{α} and \eqn{β} (cp. equation above) must be specified. +#' density-independent probability \eqn{d} must be specified. If \code{DensDep=TRUE}, the functional parameters \ifelse{html}{\out{D0}}{\eqn{D_0}}, \eqn{\alpha} and \eqn{\beta} (cp. equation above) must be specified. #' Additionally, if \code{IndVar=FALSE}, these parameters are fixed, but if \code{IndVar=TRUE} each of them is replaced by two parameters: their respective mean and #' standard deviation. They are used to normally distribute the traits values among the individuals of the initial population. #' @@ -103,11 +103,11 @@ #' F \tab F \tab T \tab F \tab stage, \eqn{d} \cr #' F \tab F \tab F \tab T \tab sex, \eqn{d} \cr #' F \tab F \tab T \tab T \tab stage, sex, \eqn{d} \cr -#' T \tab F \tab F \tab F \tab \ifelse{html}{\out{D0}}{\eqn{D_0}}, \eqn{α}, \eqn{β} \cr +#' T \tab F \tab F \tab F \tab \ifelse{html}{\out{D0}}{\eqn{D_0}}, \eqn{\alpha}, \eqn{\beta} \cr #' F \tab T \tab F \tab F \tab mean\eqn{(d)}, sd\eqn{(d)} \cr -#' T \tab T \tab F \tab F \tab \ifelse{html}{\out{mean(D0)}}{mean\eqn{(D_0)}}, \ifelse{html}{\out{sd(D0)}}{sd\eqn{(D_0)}}, mean\eqn{(α)}, sd\eqn{(α)}, mean\eqn{(β)}, sd\eqn{(β)} \cr +#' T \tab T \tab F \tab F \tab \ifelse{html}{\out{mean(D0)}}{mean\eqn{(D_0)}}, \ifelse{html}{\out{sd(D0)}}{sd\eqn{(D_0)}}, mean\eqn{(\alpha)}, sd\eqn{(\alpha)}, mean\eqn{(\beta)}, sd\eqn{(\beta)} \cr #' \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \cr -#' T \tab T \tab F \tab T \tab sex, \ifelse{html}{\out{mean(D0)}}{mean\eqn{(D_0)}}, \ifelse{html}{\out{sd(D0)}}{sd\eqn{(D_0)}}, mean\eqn{(α)}, sd\eqn{(α)}, mean\eqn{(β)}, sd\eqn{(β)} +#' T \tab T \tab F \tab T \tab sex, \ifelse{html}{\out{mean(D0)}}{mean\eqn{(D_0)}}, \ifelse{html}{\out{sd(D0)}}{sd\eqn{(D_0)}}, mean\eqn{(\alpha)}, sd\eqn{(\alpha)}, mean\eqn{(\beta)}, sd\eqn{(\beta)} #' } #' #' The column headings need not be included, only the numeric matrix is required. The rows require no particular order, but there must be exactly one row for each stage/sex combination. For example, in the case of density-, stage- and sex-dependent emigration with no individual variability: @@ -250,10 +250,10 @@ setValidity("EmigrationParams", function(object) { } else { if (object@TraitScaleFactor[1] <= 0.0 || object@TraitScaleFactor[1] > 1.0 ) { - msg <- c(msg, "TraitScaleFactor ÎĽ(D0) must be in the half-open interval (0,1] !") + msg <- c(msg, "TraitScaleFactor mu(D0) must be in the half-open interval (0,1] !") } if (any(object@TraitScaleFactor[2:3] <= 0.0 )) { - msg <- c(msg, "TraitScaleFactor ÎĽ(α) and ÎĽ(β) must be strictly positive !") + msg <- c(msg, "TraitScaleFactor mu(\alpha) and mu(\beta) must be strictly positive !") } } } @@ -263,7 +263,7 @@ setValidity("EmigrationParams", function(object) { } else { if (object@TraitScaleFactor <= 0 || object@TraitScaleFactor > 1 ) { - msg <- c(msg, "TraitScaleFactor ÎĽ(D0) must be in the half-open interval (0,1] !") + msg <- c(msg, "TraitScaleFactor mu(D0) must be in the half-open interval (0,1] !") } } } @@ -491,10 +491,10 @@ setMethod("show", "TransferParams", function(object){ #' #' \emph{Negative exponential} \cr #' If the individual disperses, the distance and the movement direction are determined in continuous space. -#' The distance is drawn from a negative exponential distribution with a given mean \eqn{δ}, and the direction is selected randomly from a uniform -#' distribution between \eqn{0} and \eqn{2Ď€} radians. +#' The distance is drawn from a negative exponential distribution with a given mean \eqn{\delta}, and the direction is selected randomly from a uniform +#' distribution between \eqn{0} and \eqn{2\pi} radians. #' -#' \ifelse{html}{\out{   p(d;δ) = δ-1 e- d / δ}}{\deqn{ p(d;δ) = 1/δ exp(-d/δ) } } +#' \ifelse{html}{\out{   p(d;δ) = δ-1 e- d / δ}}{\deqn{ p(d;\delta) = 1/\delta exp(-d/\delta) } } #' #' If the arrival point lies beyond the boundary of the landscape, distance and direction are re-drawn.\cr #' The individual is displaced from a random point (using continuous coordinates) inside the natal cell to the arrival cell where the model @@ -511,17 +511,17 @@ setMethod("show", "TransferParams", function(object){ #' #' \emph{Mixed kernel} \cr #' The distance an individual moves is sampled from a mixed kernel given by the combination of two negative exponentials -#' with different means \ifelse{html}{\out{δ1}}{\eqn{δ_1}} and \ifelse{html}{\out{δ2}}{\eqn{δ_2}}, +#' with different means \ifelse{html}{\out{δ1}}{\eqn{\delta_1}} and \ifelse{html}{\out{δ2}}{\eqn{\delta_2}}, #' occurring with probability \ifelse{html}{\out{pI}}{\eqn{p_I}} and \eqn{1-}\ifelse{html}{\out{pI}}{\eqn{p_I}} respectively \insertCite{hovestadt2011all}{RangeShiftR}. #' Otherwise, the conditions for the single kernel apply. #' -#' \ifelse{html}{\out{   p(d; δ12) = pI p(d;δ1) + (1-pI) p(d;δ1)}}{\deqn{ p(d; δ_1,δ_2) = p_I p(d;δ_1) + (1-p_I) p(d;δ_2)}} +#' \ifelse{html}{\out{   p(d; δ12) = pI p(d;δ1) + (1-pI) p(d;δ1)}}{\deqn{ p(d; \delta_1,\delta_2) = p_I p(d;\delta_1) + (1-p_I) p(d;\delta_2)}} #' #' For both types of kernel, inter-individual variability of the kernel traits is possible (set \code{IndVar=TRUE}). Individuals will -#' carry either one trait for \eqn{δ} or three traits for \ifelse{html}{\out{δ1}}{\eqn{δ_1}}, \ifelse{html}{\out{δ2}}{\eqn{δ_2}} and +#' carry either one trait for \eqn{\delta} or three traits for \ifelse{html}{\out{δ1}}{\eqn{\delta_1}}, \ifelse{html}{\out{δ2}}{\eqn{\delta_2}} and #' \ifelse{html}{\out{pI}}{\eqn{p_I}}, which they inherit from their parents.\cr -#' Dispersal kernels can also be sex-dependent (set \code{SexDep=TRUE}). In the case of inter-individual variability, the number of traits is doubled to two trait (female \eqn{δ} -#' and male δ) or six traits (female and male \ifelse{html}{\out{δ1}}{\eqn{δ_1}}, \ifelse{html}{\out{δ2}}{\eqn{δ_2}} and \ifelse{html}{\out{pI}}{\eqn{p_I}}).\cr +#' Dispersal kernels can also be sex-dependent (set \code{SexDep=TRUE}). In the case of inter-individual variability, the number of traits is doubled to two trait (female \eqn{\delta} +#' and male \delta) or six traits (female and male \ifelse{html}{\out{δ1}}{\eqn{\delta_1}}, \ifelse{html}{\out{δ2}}{\eqn{\delta_2}} and \ifelse{html}{\out{pI}}{\eqn{p_I}}).\cr #' For each trait the initial distribution in the population (as mean and standard variation) must be set in \code{Distances} (instead of only one constant value), #' as well as their scaling factors in \code{TraitScaleFactor} (see \code{\link[RangeShiftR]{Genetics}}).\cr #' @@ -529,8 +529,8 @@ setMethod("show", "TransferParams", function(object){ #' #' All dispersal kernel parameters have to be provided via \code{Distances}, which generally takes a matrix, or - if only a single constant mean distance is #' used (i.e. \code{DensDep, IndVar, StageDep, SexDep = FALSE}) - a single numeric. The format of the matrix is defined as follows: The number of columns depend on the options \code{IndVar} and \code{DoubleKernel}. -#' If \code{DoubleKernel=FALSE}, the mean dispersal distance \eqn{δ} must be specified (in meters). If \code{DoubleKernel=TRUE}, the mean dispersal distances -#' \ifelse{html}{\out{δ1}}{\eqn{δ_1}} and \ifelse{html}{\out{δ2}}{\eqn{δ_2}} (in meters), as well as the probability \ifelse{html}{\out{pI}}{\eqn{p_I}} of using Kernel-1 must be specified. +#' If \code{DoubleKernel=FALSE}, the mean dispersal distance \eqn{\delta} must be specified (in meters). If \code{DoubleKernel=TRUE}, the mean dispersal distances +#' \ifelse{html}{\out{δ1}}{\eqn{\delta_1}} and \ifelse{html}{\out{δ2}}{\eqn{\delta_2}} (in meters), as well as the probability \ifelse{html}{\out{pI}}{\eqn{p_I}} of using Kernel-1 must be specified. #' Additionally, if \code{IndVar=FALSE}, these parameters are fixed, but if \code{IndVar=TRUE} each of them is replaced by two parameters: their respective mean and #' standard deviation. They are used to normally distribute the traits values among the individuals of the initial population. #' @@ -539,15 +539,15 @@ setMethod("show", "TransferParams", function(object){ #' table lists the required columns and their correct order for different settings: #' #' \tabular{ccccc}{IndVar \tab DoubleKernel \tab StageDep \tab SexDep \tab columns \cr -#' F \tab F \tab F \tab F \tab \eqn{δ} \cr -#' F \tab F \tab T \tab F \tab stage, \eqn{δ} \cr -#' F \tab F \tab F \tab T \tab sex, \eqn{δ} \cr -#' F \tab F \tab T \tab T \tab stage, sex, \eqn{δ} \cr -#' F \tab T \tab F \tab F \tab \ifelse{html}{\out{δ1, δ2, pI}}{\eqn{δ_1, δ_2, p_I}} \cr -#' T \tab F \tab F \tab F \tab mean\eqn{(δ)}, sd\eqn{(δ)} \cr -#' T \tab T \tab F \tab F \tab \ifelse{html}{\out{mean(δ1)}}{mean\eqn{(δ_1)}}, \ifelse{html}{\out{sd(δ1)}}{sd\eqn{(δ_1)}}, \ifelse{html}{\out{mean(δ2)}}{mean\eqn{(δ_2)}}, \ifelse{html}{\out{sd(δ2)}}{sd\eqn{(δ_2)}}, mean\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}}, sd\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}} \cr +#' F \tab F \tab F \tab F \tab \eqn{\delta} \cr +#' F \tab F \tab T \tab F \tab stage, \eqn{\delta} \cr +#' F \tab F \tab F \tab T \tab sex, \eqn{\delta} \cr +#' F \tab F \tab T \tab T \tab stage, sex, \eqn{\delta} \cr +#' F \tab T \tab F \tab F \tab \ifelse{html}{\out{δ1, δ2, pI}}{\eqn{\delta_1, \delta_2, p_I}} \cr +#' T \tab F \tab F \tab F \tab mean\eqn{(\delta)}, sd\eqn{(\delta)} \cr +#' T \tab T \tab F \tab F \tab \ifelse{html}{\out{mean(δ1)}}{mean\eqn{(\delta_1)}}, \ifelse{html}{\out{sd(δ1)}}{sd\eqn{(\delta_1)}}, \ifelse{html}{\out{mean(δ2)}}{mean\eqn{(\delta_2)}}, \ifelse{html}{\out{sd(δ2)}}{sd\eqn{(\delta_2)}}, mean\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}}, sd\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}} \cr #' \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \cr -#' T \tab T \tab F \tab T \tab sex, \ifelse{html}{\out{mean(δ1)}}{mean\eqn{(δ_1)}}, \ifelse{html}{\out{sd(δ1)}}{sd\eqn{(δ_1)}}, \ifelse{html}{\out{mean(δ2)}}{mean\eqn{(δ_2)}}, \ifelse{html}{\out{sd(δ2)}}{sd\eqn{(δ_2)}}, mean\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}}, sd\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}} +#' T \tab T \tab F \tab T \tab sex, \ifelse{html}{\out{mean(δ1)}}{mean\eqn{(\delta_1)}}, \ifelse{html}{\out{sd(δ1)}}{sd\eqn{(\delta_1)}}, \ifelse{html}{\out{mean(δ2)}}{mean\eqn{(\delta_2)}}, \ifelse{html}{\out{sd(δ2)}}{sd\eqn{(\delta_2)}}, mean\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}}, sd\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}} #' } #' #' The column headings need not be included, only the numeric matrix is required. The rows require no particular order, but there must be exactly @@ -573,7 +573,7 @@ setMethod("show", "TransferParams", function(object){ #' A second source of dispersal mortality can be specified via the option \code{DistMort}: The probability of mortality is either a constant #' (\eqn{m=}\code{MortProb}) or a function of distance \eqn{d} (i.e. individuals that travel further are more likely to die): #' -#' \ifelse{html}{\out{   m(d) = 1 / ( 1 + e-a (d- b) ) } }{\deqn{ m(d) = 1 / ( 1 + exp[-α (d-b) ] ) } } +#' \ifelse{html}{\out{   m(d) = 1 / ( 1 + e-a (d- b) ) } }{\deqn{ m(d) = 1 / ( 1 + exp[-\alpha (d-b) ] ) } } #' #' with the inflection point \eqn{b=}\code{InflPoint} at which \eqn{m(d=b)=0.5} and the slope \eqn{a=}\code{Slope}.This option may be thought #' to represent the increased energetic, time or attritional costs that longer-distance dispersers will experience \insertCite{bonte2012costs}{RangeShiftR}. @@ -702,10 +702,10 @@ setValidity("DispersalKernel", function(object) { } else { if (object@TraitScaleFactor[3] <= 0.0 || object@TraitScaleFactor[3] > 1.0 ) { - msg <- c(msg, "TraitScaleFactor ÎĽ(p) must be in the half-open interval (0,1] !") + msg <- c(msg, "TraitScaleFactor mu(p) must be in the half-open interval (0,1] !") } if (any(object@TraitScaleFactor[1:2] <= 0.0 )) { - msg <- c(msg, "TraitScaleFactor ÎĽ(δ1) and ÎĽ(δ2) must be strictly positive !") + msg <- c(msg, "TraitScaleFactor mu(delta1) and mu(delta2) must be strictly positive !") } } } @@ -715,7 +715,7 @@ setValidity("DispersalKernel", function(object) { } else { if (object@TraitScaleFactor <= 0.0) { - msg <- c(msg, "TraitScaleFactor ÎĽ(δ) must be strictly positive !") + msg <- c(msg, "TraitScaleFactor mu(delta) must be strictly positive !") } } } @@ -1430,7 +1430,7 @@ setMethod("plotProbs", "StochMove", function(x, xmax = NULL, ymax = NULL){ #' StepMort = 0.0) #' @param StepLength Step length given in meters, defaults to \eqn{1}.\cr If \code{IndVar=TRUE}, expects a vector of length three #' specifying (Mean, SD, TraitScaleFactor) of \code{StepLength}. -#' @param Rho Correlation parameter \eqn{Ď}, defaults to \eqn{0.5}. Must be in the open interval \eqn{(0,1)}.\cr If \code{IndVar=TRUE}, +#' @param Rho Correlation parameter \eqn{\rho}, defaults to \eqn{0.5}. Must be in the open interval \eqn{(0,1)}.\cr If \code{IndVar=TRUE}, #' expects a vector of length three specifying (Mean, SD, TraitScaleFactor) of \code{Rho}. #' @param IndVar Individual variability in CorrRW traits (i.e. \code{StepLength} and \code{Rho})? Defaults to \code{FALSE}. #' @param StraightenPath Straighten path after decision not to settle in a patch? Defaults to \code{TRUE}, see Details below. @@ -1648,8 +1648,8 @@ setMethod("show", "CorrRW", function(object){ #' In any case, dispersing individuals are not allowed to settle in their natal cell or patch.\cr #' \emph{RangeShiftR} incorporates some basic settlement rules that can be stage- or sex-specific or both (set \code{StageDep}, \code{SexDep}). #' Inter-individual variability (\code{IndVar}) is implemented only for movement processes and then for the three traits -#' determining density-dependent settlement (\ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{α_S}}, -#' \ifelse{html}{\out{βS}}{\eqn{β_S}}; see below). In this case, settlement may not be stage-dependent.\cr +#' determining density-dependent settlement (\ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{\alpha_S}}, +#' \ifelse{html}{\out{βS}}{\eqn{\beta_S}}; see below). In this case, settlement may not be stage-dependent.\cr #' #' \emph{Settlement with dispersal kernels}\cr #' When using a \code{\link[RangeShiftR]{DispersalKernel}}, individuals are displaced directly from the starting location to the arrival location. The suitability @@ -1692,18 +1692,18 @@ setMethod("show", "CorrRW", function(object){ #' Furthermore, the settlement decision can be density-dependent (set \code{DensDep=TRUE}). In this case, the individual has a probability \ifelse{html}{\out{pS}}{\eqn{p_S}} #' of settling in the cell or patch \eqn{i}, given by: #' -#' \ifelse{html}{\out{   pS(i,t) = S0 / ( 1 + eS (N(i,t) / K(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-α_S (N(i,t)/K(i,t) - β_S) ] ) } } +#' \ifelse{html}{\out{   pS(i,t) = S0 / ( 1 + eS (N(i,t) / K(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-\alpha_S (N(i,t)/K(i,t) - \beta_S) ] ) } } #' #' In the case of stage-structured models the above equation is modified to: #' -#' \ifelse{html}{\out{   pS(i,t) = S0 / ( 1 + eS (b(i,t) * N(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-α_S (b(i,t) N(i,t) - β_S) ] ) } } +#' \ifelse{html}{\out{   pS(i,t) = S0 / ( 1 + eS (b(i,t) * N(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-\alpha_S (b(i,t) N(i,t) - \beta_S) ] ) } } #' #' In the first case, \eqn{K(i,t)} is the carrying capacity of the cell/patch \eqn{i} at time \eqn{t} given by \code{K_or_DensDep}. #' In the latter case, \eqn{b(i,t)} represents the strength of density dependence that is given by the inverse of \code{K_or_DensDep}.\cr #' Further, \ifelse{html}{\out{S0}}{\eqn{S_0}} is the maximum settlement probability, #' \eqn{N(i,t)} is the number of individuals in the cell/patch \eqn{i} at time \eqn{t}, -#' \ifelse{html}{\out{βS}}{\eqn{β_S}} is the inflection point of the function and -#' \ifelse{html}{\out{αS}}{\eqn{α_S}} is the slope at the inflection point.\cr +#' \ifelse{html}{\out{βS}}{\eqn{\beta_S}} is the inflection point of the function and +#' \ifelse{html}{\out{αS}}{\eqn{\alpha_S}} is the slope at the inflection point.\cr #' #' Inter-individual variability \code{IndVar=TRUE} and thus evolution is implemented only for the three traits determining density-dependent settlement #' (\code{DensDep=TRUE}), and if so, it may not be stage-dependent (\code{StageDep=FALSE}). @@ -1714,7 +1714,7 @@ setMethod("show", "CorrRW", function(object){ #' used (i.e. \code{DensDep, IndVar, StageDep, SexDep = FALSE}) - a single numeric. #' The format of the matrix is defined as follows: The number of columns depend on the options \code{DensDep} and \code{IndVar}. If \code{DensDep=FALSE}, the #' density-independent probability \ifelse{html}{\out{pS}}{\eqn{p_S}} must be specified. If \code{DensDep=TRUE}, the functional parameters \ifelse{html}{\out{S0}}{\eqn{S_0}}, -#' \ifelse{html}{\out{αS}}{\eqn{α_S}} and \ifelse{html}{\out{βS}}{\eqn{β_S}} (cf. equation above) must be specified. +#' \ifelse{html}{\out{αS}}{\eqn{\alpha_S}} and \ifelse{html}{\out{βS}}{\eqn{\beta_S}} (cf. equation above) must be specified. #' Additionally, if \code{IndVar=FALSE}, these traits are fixed, but if \code{IndVar=TRUE} each of them is replaced by two parameters: their respective initial mean and #' standard deviation. They are used to normally distribute the traits values among the individuals of the initial population. Additionally, the \code{TraitScaleFactor} of #' these traits have to be set. @@ -1729,11 +1729,11 @@ setMethod("show", "CorrRW", function(object){ #' F \tab F \tab T \tab F \tab stage \cr #' F \tab F \tab F \tab T \tab sex \cr #' F \tab F \tab T \tab T \tab stage, sex \cr -#' T \tab F \tab F \tab F \tab \ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{α_S}}, \ifelse{html}{\out{βS}}{\eqn{β_S}} \cr +#' T \tab F \tab F \tab F \tab \ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{\alpha_S}}, \ifelse{html}{\out{βS}}{\eqn{\beta_S}} \cr #' \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \cr -#' T \tab F \tab T \tab T \tab stage, sex, \ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{α_S}}, \ifelse{html}{\out{βS}}{\eqn{β_S}} \cr -#' T \tab T \tab F \tab F \tab mean\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, sd\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, mean\ifelse{html}{\out{(αS)}}{(\eqn{α_S})}, sd\ifelse{html}{\out{(αS)}}{(\eqn{α_S})}, mean\ifelse{html}{\out{(βS)}}{(\eqn{β_S})}, sd\ifelse{html}{\out{(βS)}}{(\eqn{β_S})} \cr -#' T \tab T \tab F \tab T \tab sex, mean\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, sd\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, mean\ifelse{html}{\out{(αS)}}{(\eqn{α_S})}, sd\ifelse{html}{\out{(αS)}}{(\eqn{α_S})}, mean\ifelse{html}{\out{(βS)}}{(\eqn{β_S})}, sd\ifelse{html}{\out{(βS)}}{(\eqn{β_S})} +#' T \tab F \tab T \tab T \tab stage, sex, \ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{\alpha_S}}, \ifelse{html}{\out{βS}}{\eqn{\beta_S}} \cr +#' T \tab T \tab F \tab F \tab mean\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, sd\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, mean\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, sd\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, mean\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})}, sd\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})} \cr +#' T \tab T \tab F \tab T \tab sex, mean\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, sd\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, mean\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, sd\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, mean\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})}, sd\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})} #' } #' #' The column headings need not be included, only the numeric matrix is required. The rows require no particular order, but there must be exactly one row for each stage/sex combination. @@ -1846,10 +1846,10 @@ setValidity("SettlementParams", function(object) { } else { if (object@TraitScaleFactor[1] <= 0.0 || object@TraitScaleFactor[1] > 1.0 ) { - msg <- c(msg, "TraitScaleFactor ÎĽ(S_0) must be in the half-open interval (0,1] !") + msg <- c(msg, "TraitScaleFactor mu(S_0) must be in the half-open interval (0,1] !") } if (any(object@TraitScaleFactor[2:3] <= 0.0 )) { - msg <- c(msg, "TraitScaleFactor ÎĽ(α_s) and ÎĽ(β_s) must be strictly positive !") + msg <- c(msg, "TraitScaleFactor mu(\alpha_s) and mu(\beta_s) must be strictly positive !") } } } @@ -1859,7 +1859,7 @@ setValidity("SettlementParams", function(object) { } else { if (object@TraitScaleFactor <= 0 || object@TraitScaleFactor > 1 ) { - msg <- c(msg, "TraitScaleFactor ÎĽ(S_0) must be in the half-open interval (0,1] !") + msg <- c(msg, "TraitScaleFactor mu(S_0) must be in the half-open interval (0,1] !") } } } diff --git a/RangeShiftR/R/class_RSparams.R b/RangeShiftR/R/class_RSparams.R index b417103..a967284 100644 --- a/RangeShiftR/R/class_RSparams.R +++ b/RangeShiftR/R/class_RSparams.R @@ -216,14 +216,14 @@ setValidity("RSparams", function(object) { } if (object@dispersal@Emigration@DensDep) { if(any(object@dispersal@Emigration@EmigProb[,c((offset+4),(offset+6))]<=0 )){ - msg <- c(msg, paste0("Columns ", (offset+4), " and ", (offset+6), " of emigration traits matrix (EmigProb) must contain sd(α) and sd(β), with strictly positive values!")) + msg <- c(msg, paste0("Columns ", (offset+4), " and ", (offset+6), " of emigration traits matrix (EmigProb) must contain sd(alpha) and sd(beta), with strictly positive values!")) } else { if(any(object@dispersal@Emigration@EmigProb[,(offset+4)] > object@dispersal@Emigration@TraitScaleFactor[2])) { - msg <- c(msg, paste0("Column ", (offset+4), " of emigration traits matrix (EmigProb) must contain sd(α), with values less than or equal to TraitScaleFactor ÎĽ(α)!")) + msg <- c(msg, paste0("Column ", (offset+4), " of emigration traits matrix (EmigProb) must contain sd(alpha), with values less than or equal to TraitScaleFactor ÎĽ(alpha)!")) } if(any(object@dispersal@Emigration@EmigProb[,(offset+6)] > object@dispersal@Emigration@TraitScaleFactor[3])) { - msg <- c(msg, paste0("Column ", (offset+6), " of emigration traits matrix (EmigProb) must contain sd(β), with values less than or equal to TraitScaleFactor ÎĽ(β)!")) + msg <- c(msg, paste0("Column ", (offset+6), " of emigration traits matrix (EmigProb) must contain sd(beta), with values less than or equal to TraitScaleFactor ÎĽ(beta)!")) } } } @@ -621,14 +621,14 @@ setValidity("RSparams", function(object) { } } if(any(object@dispersal@Settlement@Settle[,c((offset+4),(offset+6))]<=0 )){ - msg <- c(msg, paste0("Columns ", (offset+4), " and ", (offset+6), " of settlement traits matrix (Settle) must contain sd(α_s) and sd(β_s), with strictly positive values!")) + msg <- c(msg, paste0("Columns ", (offset+4), " and ", (offset+6), " of settlement traits matrix (Settle) must contain sd(alpha_s) and sd(beta_s), with strictly positive values!")) } else { if(any(object@dispersal@Settlement@Settle[,(offset+4)] > object@dispersal@Settlement@TraitScaleFactor[2])) { - msg <- c(msg, paste0("Column ", (offset+4), " of settlement traits matrix (Settle) must contain sd(α_s), with values less than or equal to TraitScaleFactor ÎĽ(α_s)!")) + msg <- c(msg, paste0("Column ", (offset+4), " of settlement traits matrix (Settle) must contain sd(alpha_s), with values less than or equal to TraitScaleFactor ÎĽ(alpha_s)!")) } if(any(object@dispersal@Settlement@Settle[,(offset+6)] > object@dispersal@Settlement@TraitScaleFactor[3])) { - msg <- c(msg, paste0("Column ", (offset+6), " of settlement traits matrix (Settle) must contain sd(β_s), with values less than or equal to TraitScaleFactor ÎĽ(β_s)!")) + msg <- c(msg, paste0("Column ", (offset+6), " of settlement traits matrix (Settle) must contain sd(beta_s), with values less than or equal to TraitScaleFactor ÎĽ(beta_s)!")) } } } diff --git a/RangeShiftR/R/class_SimulationParams.R b/RangeShiftR/R/class_SimulationParams.R index 06c73a6..5614eb2 100644 --- a/RangeShiftR/R/class_SimulationParams.R +++ b/RangeShiftR/R/class_SimulationParams.R @@ -149,7 +149,7 @@ #' The local heterogeneity is determined by a random number drawn from a uniform distribution between \eqn{-1} and \eqn{1} for each cell #' and \code{f}, the local scaling factor that determines the magnitude of this stochastic local variation relative to the extremal value. #' -#' The gradient in fecundity φ applies to the fecundity of each stage. Negative local values in \eqn{z(x,y)} are set to \eqn{0}. +#' The gradient in fecundity \eqn{\phi} applies to the fecundity of each stage. Negative local values in \eqn{z(x,y)} are set to \eqn{0}. #' #' It is also possible to simulate the shifting of the gradient by setting the option \code{Shifting}. Here the position \eqn{y} of the species’ #' optimum is shifted northwards (increasing \eqn{y}) at a given rate \code{ShiftRate} (in units of rows per year), @@ -166,18 +166,18 @@ #' \emph{Environmental Stochasticity}\cr #' It is possible to model environmental stochasticity via the option \code{EnvStoch} acting at a global or local scale #' and can be applied to \code{K_or_DensDep}, the demographic density dependence (\code{EnvStoch=1}), or to growth rate / fecundity (\code{EnvStoch=0}). -#' It is implemented using a first order autoregressive process to generate time series of the noise value \eqn{ε} +#' It is implemented using a first order autoregressive process to generate time series of the noise value \eqn{\epsilon} #' \insertCite{ruokolainen2009}{RangeShiftR}: #' -#' \deqn{ε(t+1) = Îş ε(t) + \omega(t) \sqrt(1-\kappa^2)} +#' \deqn{\epsilon(t+1) = \kappa \epsilon(t) + \omega(t) \sqrt(1-\kappa^2)} #' -#' where Îş is the autocorrelation coefficient (\code{ac}) and ω is a random normal variable drawn from \eqn{N(0,Ď)}. -#' Changing Ď (\code{std}) changes the magnitude of the fluctuations. The spatial scale of the variation can either be global (a single time series +#' where \eqn{\kappa} is the autocorrelation coefficient (\code{ac}) and \eqn{\omega} is a random normal variable drawn from \eqn{N(0,\sigma)}. +#' Changing \eqn{\sigma} (\code{std}) changes the magnitude of the fluctuations. The spatial scale of the variation can either be global (a single time series #' for the entire landscape) or local (each cell fluctuates independently), and is always applied on a yearly basis. #' Different degrees of spatial autocorrelation are not implemented in the current version. #' #' The noise affects the species' selected parameter \eqn{Z} as follows: -#' \deqn{Z(x,y,t) = Z(x,y,0) + Z ε(t)} +#' \deqn{Z(x,y,t) = Z(x,y,0) + Z \epsilon(t)} #' where \eqn{x} and \eqn{y} are the cell coordinates and \eqn{Z} is the original parameter value in absence of stochasticity and gradients. #' In the presence of an environmental gradient, \eqn{Z(x,y,0)} is the gradient value at the cell location, otherwise its equal to \eqn{Z}. #' The resulting values \eqn{Z(x,y,t)} are limited to the maximum and minimum values \code{minR,maxR} or \code{minK,maxK}, respectively. diff --git a/RangeShiftR/R/plotProbs.R b/RangeShiftR/R/plotProbs.R index bcd6b00..0c6bebe 100644 --- a/RangeShiftR/R/plotProbs.R +++ b/RangeShiftR/R/plotProbs.R @@ -49,21 +49,21 @@ #' If a mixed kernel was defined (i.e. \code{DoubleKernel=TRUE}), plot the resulting dispersal probability by... #' \itemize{ #' \item \code{combinekernels=FALSE} - ...plotting both kernels separately (default) -#' \item \code{combinekernels= TRUE} - ...combining both kernels, i.e. \ifelse{html}{ \out{p(d; δ12) = pI p(d;δ1) + (1-pI) p(d;δ1) } }{\deqn{ p(d; δ_1,δ_2) = p_I p(d;δ_1) + (1-p_I) p(d;δ_2)} } +#' \item \code{combinekernels= TRUE} - ...combining both kernels, i.e. \ifelse{html}{ \out{p(d; δ12) = pI p(d;δ1) + (1-pI) p(d;δ1) } }{\deqn{ p(d; \delta_1,\delta_2) = p_I p(d;\delta_1) + (1-p_I) p(d;\delta_2)} } #' } #' \item \code{\link[RangeShiftR]{StageStructure}}: plot fecundity as well as survival and development probabilities. #' #' Survival and development are calculated based on the transition matrix. Consider e.g. a 3 stage matrix with a transition matrix of #' -#' \tabular{ccccc}{0 \tab | \tab 0 \tab | \tab \ifelse{html}{\out{φ2}}{\eqn{φ_2}} \cr -#' \eqn{1.0} \tab | \tab \ifelse{html}{\out{σ1 (1-γ1-2)}}{\eqn{Ď_1 (1 â’ Îł_(1-2))}} \tab | \tab \eqn{0} \cr -#' \eqn{0} \tab | \tab \ifelse{html}{\out{σ1 γ1-2}}{\eqn{Ď_1 Îł_(1-2)}} \tab | \tab \ifelse{html}{\out{σ2}}{\eqn{Ď_2}} \cr} +#' \tabular{ccccc}{0 \tab | \tab 0 \tab | \tab \ifelse{html}{\out{φ2}}{\eqn{\phi_2}} \cr +#' \eqn{1.0} \tab | \tab \ifelse{html}{\out{σ1 (1-γ1-2)}}{\eqn{\sigma_1 (1 - \gamma_(1-2))}} \tab | \tab \eqn{0} \cr +#' \eqn{0} \tab | \tab \ifelse{html}{\out{σ1 γ1-2}}{\eqn{\sigma_1 \gamma_(1-2)}} \tab | \tab \ifelse{html}{\out{σ2}}{\eqn{\sigma_2}} \cr} #' #' The survival probability is calculated as the sum of the probability to stay in the same stage and the probability to reach the next stage. -#' E.g. for stage 1: \ifelse{html}{\out{σ1 = sum( σ1 (1-γ1-2), σ1 γ1-2}}{\eqn{Ď_1 = sum(Ď_1 (1 â’ Îł_(1-2)), Ď_1 Îł_(1-2))}} +#' E.g. for stage 1: \ifelse{html}{\out{σ1 = sum( σ1 (1-γ1-2), σ1 γ1-2}}{\eqn{\sigma_1 = sum(\sigma_1 (1 - \gamma_(1-2)), \sigma_1 \gamma_(1-2))}} #' #' The development probability of stage 1 to stage 2 is the ratio of the probability to reach stage 2 and the previously calculated survival probability. -#' E.g. for stage 1: \ifelse{html}{\out{γ1-2 = σ1 γ1-2 / σ1}}{\eqn{Îł_(1-2) = Ď_1 / (Ď_1 Îł_(1-2) )}} +#' E.g. for stage 1: \ifelse{html}{\out{γ1-2 = σ1 γ1-2 / σ1}}{\eqn{\gamma_(1-2) = \sigma_1 / (\sigma_1 \gamma_(1-2) )}} #' } #' @export setGeneric("plotProbs", function(x, ...) standardGeneric("plotProbs") ) diff --git a/RangeShiftR/man/CorrRW.Rd b/RangeShiftR/man/CorrRW.Rd index 4c057c8..869e739 100644 --- a/RangeShiftR/man/CorrRW.Rd +++ b/RangeShiftR/man/CorrRW.Rd @@ -14,7 +14,7 @@ CorrRW(StepLength = 1, Rho = 0.5, \item{StepLength}{Step length given in meters, defaults to \eqn{1}.\cr If \code{IndVar=TRUE}, expects a vector of length three specifying (Mean, SD, TraitScaleFactor) of \code{StepLength}.} -\item{Rho}{Correlation parameter \eqn{Ď}, defaults to \eqn{0.5}. Must be in the open interval \eqn{(0,1)}.\cr If \code{IndVar=TRUE}, +\item{Rho}{Correlation parameter \eqn{\rho}, defaults to \eqn{0.5}. Must be in the open interval \eqn{(0,1)}.\cr If \code{IndVar=TRUE}, expects a vector of length three specifying (Mean, SD, TraitScaleFactor) of \code{Rho}.} \item{IndVar}{Individual variability in CorrRW traits (i.e. \code{StepLength} and \code{Rho})? Defaults to \code{FALSE}.} diff --git a/RangeShiftR/man/DispersalKernel.Rd b/RangeShiftR/man/DispersalKernel.Rd index f7b7cd4..76a2e87 100644 --- a/RangeShiftR/man/DispersalKernel.Rd +++ b/RangeShiftR/man/DispersalKernel.Rd @@ -59,10 +59,10 @@ valuable method for discerning between common short-distance and rare long-dista \emph{Negative exponential} \cr If the individual disperses, the distance and the movement direction are determined in continuous space. -The distance is drawn from a negative exponential distribution with a given mean \eqn{δ}, and the direction is selected randomly from a uniform -distribution between \eqn{0} and \eqn{2Ď€} radians. +The distance is drawn from a negative exponential distribution with a given mean \eqn{\delta}, and the direction is selected randomly from a uniform +distribution between \eqn{0} and \eqn{2\pi} radians. -\ifelse{html}{\out{   p(d;δ) = δ-1 e- d / δ}}{\deqn{ p(d;δ) = 1/δ exp(-d/δ) } } +\ifelse{html}{\out{   p(d;δ) = δ-1 e- d / δ}}{\deqn{ p(d;\delta) = 1/\delta exp(-d/\delta) } } If the arrival point lies beyond the boundary of the landscape, distance and direction are re-drawn.\cr The individual is displaced from a random point (using continuous coordinates) inside the natal cell to the arrival cell where the model @@ -79,17 +79,17 @@ not they emigrate. \emph{Mixed kernel} \cr The distance an individual moves is sampled from a mixed kernel given by the combination of two negative exponentials -with different means \ifelse{html}{\out{δ1}}{\eqn{δ_1}} and \ifelse{html}{\out{δ2}}{\eqn{δ_2}}, +with different means \ifelse{html}{\out{δ1}}{\eqn{\delta_1}} and \ifelse{html}{\out{δ2}}{\eqn{\delta_2}}, occurring with probability \ifelse{html}{\out{pI}}{\eqn{p_I}} and \eqn{1-}\ifelse{html}{\out{pI}}{\eqn{p_I}} respectively \insertCite{hovestadt2011all}{RangeShiftR}. Otherwise, the conditions for the single kernel apply. -\ifelse{html}{\out{   p(d; δ12) = pI p(d;δ1) + (1-pI) p(d;δ1)}}{\deqn{ p(d; δ_1,δ_2) = p_I p(d;δ_1) + (1-p_I) p(d;δ_2)}} +\ifelse{html}{\out{   p(d; δ12) = pI p(d;δ1) + (1-pI) p(d;δ1)}}{\deqn{ p(d; \delta_1,\delta_2) = p_I p(d;\delta_1) + (1-p_I) p(d;\delta_2)}} For both types of kernel, inter-individual variability of the kernel traits is possible (set \code{IndVar=TRUE}). Individuals will -carry either one trait for \eqn{δ} or three traits for \ifelse{html}{\out{δ1}}{\eqn{δ_1}}, \ifelse{html}{\out{δ2}}{\eqn{δ_2}} and +carry either one trait for \eqn{\delta} or three traits for \ifelse{html}{\out{δ1}}{\eqn{\delta_1}}, \ifelse{html}{\out{δ2}}{\eqn{\delta_2}} and \ifelse{html}{\out{pI}}{\eqn{p_I}}, which they inherit from their parents.\cr -Dispersal kernels can also be sex-dependent (set \code{SexDep=TRUE}). In the case of inter-individual variability, the number of traits is doubled to two trait (female \eqn{δ} -and male δ) or six traits (female and male \ifelse{html}{\out{δ1}}{\eqn{δ_1}}, \ifelse{html}{\out{δ2}}{\eqn{δ_2}} and \ifelse{html}{\out{pI}}{\eqn{p_I}}).\cr +Dispersal kernels can also be sex-dependent (set \code{SexDep=TRUE}). In the case of inter-individual variability, the number of traits is doubled to two trait (female \eqn{\delta} +and male \delta) or six traits (female and male \ifelse{html}{\out{δ1}}{\eqn{\delta_1}}, \ifelse{html}{\out{δ2}}{\eqn{\delta_2}} and \ifelse{html}{\out{pI}}{\eqn{p_I}}).\cr For each trait the initial distribution in the population (as mean and standard variation) must be set in \code{Distances} (instead of only one constant value), as well as their scaling factors in \code{TraitScaleFactor} (see \code{\link[RangeShiftR]{Genetics}}).\cr @@ -97,8 +97,8 @@ Further, dispersal kernels can be stage-specific (set \code{StageDep=TRUE}). For All dispersal kernel parameters have to be provided via \code{Distances}, which generally takes a matrix, or - if only a single constant mean distance is used (i.e. \code{DensDep, IndVar, StageDep, SexDep = FALSE}) - a single numeric. The format of the matrix is defined as follows: The number of columns depend on the options \code{IndVar} and \code{DoubleKernel}. -If \code{DoubleKernel=FALSE}, the mean dispersal distance \eqn{δ} must be specified (in meters). If \code{DoubleKernel=TRUE}, the mean dispersal distances -\ifelse{html}{\out{δ1}}{\eqn{δ_1}} and \ifelse{html}{\out{δ2}}{\eqn{δ_2}} (in meters), as well as the probability \ifelse{html}{\out{pI}}{\eqn{p_I}} of using Kernel-1 must be specified. +If \code{DoubleKernel=FALSE}, the mean dispersal distance \eqn{\delta} must be specified (in meters). If \code{DoubleKernel=TRUE}, the mean dispersal distances +\ifelse{html}{\out{δ1}}{\eqn{\delta_1}} and \ifelse{html}{\out{δ2}}{\eqn{\delta_2}} (in meters), as well as the probability \ifelse{html}{\out{pI}}{\eqn{p_I}} of using Kernel-1 must be specified. Additionally, if \code{IndVar=FALSE}, these parameters are fixed, but if \code{IndVar=TRUE} each of them is replaced by two parameters: their respective mean and standard deviation. They are used to normally distribute the traits values among the individuals of the initial population. @@ -107,15 +107,15 @@ If \code{SexDep=TRUE}, state the corresponding stage in the next (i.e. first/sec table lists the required columns and their correct order for different settings: \tabular{ccccc}{IndVar \tab DoubleKernel \tab StageDep \tab SexDep \tab columns \cr - F \tab F \tab F \tab F \tab \eqn{δ} \cr - F \tab F \tab T \tab F \tab stage, \eqn{δ} \cr - F \tab F \tab F \tab T \tab sex, \eqn{δ} \cr - F \tab F \tab T \tab T \tab stage, sex, \eqn{δ} \cr - F \tab T \tab F \tab F \tab \ifelse{html}{\out{δ1, δ2, pI}}{\eqn{δ_1, δ_2, p_I}} \cr - T \tab F \tab F \tab F \tab mean\eqn{(δ)}, sd\eqn{(δ)} \cr - T \tab T \tab F \tab F \tab \ifelse{html}{\out{mean(δ1)}}{mean\eqn{(δ_1)}}, \ifelse{html}{\out{sd(δ1)}}{sd\eqn{(δ_1)}}, \ifelse{html}{\out{mean(δ2)}}{mean\eqn{(δ_2)}}, \ifelse{html}{\out{sd(δ2)}}{sd\eqn{(δ_2)}}, mean\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}}, sd\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}} \cr + F \tab F \tab F \tab F \tab \eqn{\delta} \cr + F \tab F \tab T \tab F \tab stage, \eqn{\delta} \cr + F \tab F \tab F \tab T \tab sex, \eqn{\delta} \cr + F \tab F \tab T \tab T \tab stage, sex, \eqn{\delta} \cr + F \tab T \tab F \tab F \tab \ifelse{html}{\out{δ1, δ2, pI}}{\eqn{\delta_1, \delta_2, p_I}} \cr + T \tab F \tab F \tab F \tab mean\eqn{(\delta)}, sd\eqn{(\delta)} \cr + T \tab T \tab F \tab F \tab \ifelse{html}{\out{mean(δ1)}}{mean\eqn{(\delta_1)}}, \ifelse{html}{\out{sd(δ1)}}{sd\eqn{(\delta_1)}}, \ifelse{html}{\out{mean(δ2)}}{mean\eqn{(\delta_2)}}, \ifelse{html}{\out{sd(δ2)}}{sd\eqn{(\delta_2)}}, mean\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}}, sd\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}} \cr \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \cr - T \tab T \tab F \tab T \tab sex, \ifelse{html}{\out{mean(δ1)}}{mean\eqn{(δ_1)}}, \ifelse{html}{\out{sd(δ1)}}{sd\eqn{(δ_1)}}, \ifelse{html}{\out{mean(δ2)}}{mean\eqn{(δ_2)}}, \ifelse{html}{\out{sd(δ2)}}{sd\eqn{(δ_2)}}, mean\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}}, sd\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}} + T \tab T \tab F \tab T \tab sex, \ifelse{html}{\out{mean(δ1)}}{mean\eqn{(\delta_1)}}, \ifelse{html}{\out{sd(δ1)}}{sd\eqn{(\delta_1)}}, \ifelse{html}{\out{mean(δ2)}}{mean\eqn{(\delta_2)}}, \ifelse{html}{\out{sd(δ2)}}{sd\eqn{(\delta_2)}}, mean\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}}, sd\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}} } The column headings need not be included, only the numeric matrix is required. The rows require no particular order, but there must be exactly @@ -141,7 +141,7 @@ proportion of suitable habitat in the landscape and will increase as the availab A second source of dispersal mortality can be specified via the option \code{DistMort}: The probability of mortality is either a constant (\eqn{m=}\code{MortProb}) or a function of distance \eqn{d} (i.e. individuals that travel further are more likely to die): -\ifelse{html}{\out{   m(d) = 1 / ( 1 + e-a (d- b) ) } }{\deqn{ m(d) = 1 / ( 1 + exp[-α (d-b) ] ) } } +\ifelse{html}{\out{   m(d) = 1 / ( 1 + e-a (d- b) ) } }{\deqn{ m(d) = 1 / ( 1 + exp[-\alpha (d-b) ] ) } } with the inflection point \eqn{b=}\code{InflPoint} at which \eqn{m(d=b)=0.5} and the slope \eqn{a=}\code{Slope}.This option may be thought to represent the increased energetic, time or attritional costs that longer-distance dispersers will experience \insertCite{bonte2012costs}{RangeShiftR}. diff --git a/RangeShiftR/man/Emigration.Rd b/RangeShiftR/man/Emigration.Rd index b66dae9..7d97783 100644 --- a/RangeShiftR/man/Emigration.Rd +++ b/RangeShiftR/man/Emigration.Rd @@ -48,18 +48,18 @@ rate can be larger than \eqn{d}, if a stage with \eqn{d>0} lasts for more than o The emigration probability \eqn{d} can be density-dependent (set \code{DensDep=TRUE}), in which case it is given by the following function, introduced by \insertCite{kun2006evolution;textual}{RangeShiftR}: -\ifelse{html}{\out{   d(i,t) = D0 / ( 1 + e-αsub>E (N(i,t) / K(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-α_E (N(i,t)/K(i,t) - β_E) ] ) } } +\ifelse{html}{\out{   d(i,t) = D0 / ( 1 + e-αsub>E (N(i,t) / K(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-\alpha_E (N(i,t)/K(i,t) - \beta_E) ] ) } } In the case of stage-structured models this equation is modified to: -\ifelse{html}{\out{   d(i,t) = D0 / ( 1 + e-αsub>E (b(i,t) * N(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-α_E (b(i,t) N(i,t) - β_E) ] ) } } +\ifelse{html}{\out{   d(i,t) = D0 / ( 1 + e-αsub>E (b(i,t) * N(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-\alpha_E (b(i,t) N(i,t) - \beta_E) ] ) } } In the first case, \eqn{K(i,t)} is the carrying capacity of the cell/patch \eqn{i} at time \eqn{t} given by \code{K_or_DensDep}. In the latter case, \eqn{b(i,t)} represents the strength of density dependence and is given by the inverse of \code{K_or_DensDep}.\cr Further, \ifelse{html}{\out{D0}}{\eqn{D_0}} is the maximum emigration probability, \eqn{N(i,t)} is the number of individuals in the cell/patch \eqn{i} at time \eqn{t}, -\ifelse{html}{\out{βE}}{\eqn{β_S}} is the inflection point of the function and -\ifelse{html}{\out{αE}}{\eqn{α_S}} is the slope at the inflection point.\cr +\ifelse{html}{\out{βE}}{\eqn{\beta_S}} is the inflection point of the function and +\ifelse{html}{\out{αE}}{\eqn{\alpha_S}} is the slope at the inflection point.\cr Various functions have been proposed for density dependent emigration \insertCite{hovestadt2010information,poethke2011ability}{RangeShiftR}. This one was chosen here because it is a flexible function that @@ -68,8 +68,8 @@ emigration, we assume individuals to have full knowledge of the population densi Information acquisition is not explicitly modelled. The emigration probability can be allowed to vary between individuals (set \code{IndVar=TRUE}) and to evolve. In the this case, individuals exhibit either one trait -determining the density-independent \eqn{d} (when \code{DensDep=FALSE}), or the three traits \ifelse{html}{\out{D0}}{\eqn{D_0}}, \eqn{α} and -\eqn{β} determining the density-dependent emigration probability (when \code{DensDep=TRUE}).\cr +determining the density-independent \eqn{d} (when \code{DensDep=FALSE}), or the three traits \ifelse{html}{\out{D0}}{\eqn{D_0}}, \eqn{\alpha} and +\eqn{\beta} determining the density-dependent emigration probability (when \code{DensDep=TRUE}).\cr For each trait the initial distribution in the population (as mean and standard variation) must be set in \code{EmigProb} (instead of only one constant value), as well as their scaling factors in \code{TraitScaleFactor} (see \code{\link[RangeShiftR]{Genetics}}). Also, if \code{IndVar=TRUE} is set for a stage-structured population, it is required to specify the stage which emigrates via \code{EmigStage}. @@ -81,7 +81,7 @@ However, the current version does not accommodate inter-individual variation in The parameters that determine the emigration probabilities have to be provided via \code{EmigProb}, which generally takes a matrix, or - if only a single constant probability is used (i.e. \code{DensDep, IndVar, StageDep, SexDep = FALSE}) - a single numeric. The format of the matrix is defined as follows: The number of columns depend on the options \code{DensDep} and \code{IndVar}. If \code{DensDep=FALSE}, the -density-independent probability \eqn{d} must be specified. If \code{DensDep=TRUE}, the functional parameters \ifelse{html}{\out{D0}}{\eqn{D_0}}, \eqn{α} and \eqn{β} (cp. equation above) must be specified. +density-independent probability \eqn{d} must be specified. If \code{DensDep=TRUE}, the functional parameters \ifelse{html}{\out{D0}}{\eqn{D_0}}, \eqn{\alpha} and \eqn{\beta} (cp. equation above) must be specified. Additionally, if \code{IndVar=FALSE}, these parameters are fixed, but if \code{IndVar=TRUE} each of them is replaced by two parameters: their respective mean and standard deviation. They are used to normally distribute the traits values among the individuals of the initial population. @@ -93,11 +93,11 @@ If \code{SexDep=TRUE}, state the corresponding stage in the next (i.e. first/sec F \tab F \tab T \tab F \tab stage, \eqn{d} \cr F \tab F \tab F \tab T \tab sex, \eqn{d} \cr F \tab F \tab T \tab T \tab stage, sex, \eqn{d} \cr - T \tab F \tab F \tab F \tab \ifelse{html}{\out{D0}}{\eqn{D_0}}, \eqn{α}, \eqn{β} \cr + T \tab F \tab F \tab F \tab \ifelse{html}{\out{D0}}{\eqn{D_0}}, \eqn{\alpha}, \eqn{\beta} \cr F \tab T \tab F \tab F \tab mean\eqn{(d)}, sd\eqn{(d)} \cr - T \tab T \tab F \tab F \tab \ifelse{html}{\out{mean(D0)}}{mean\eqn{(D_0)}}, \ifelse{html}{\out{sd(D0)}}{sd\eqn{(D_0)}}, mean\eqn{(α)}, sd\eqn{(α)}, mean\eqn{(β)}, sd\eqn{(β)} \cr + T \tab T \tab F \tab F \tab \ifelse{html}{\out{mean(D0)}}{mean\eqn{(D_0)}}, \ifelse{html}{\out{sd(D0)}}{sd\eqn{(D_0)}}, mean\eqn{(\alpha)}, sd\eqn{(\alpha)}, mean\eqn{(\beta)}, sd\eqn{(\beta)} \cr \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \cr - T \tab T \tab F \tab T \tab sex, \ifelse{html}{\out{mean(D0)}}{mean\eqn{(D_0)}}, \ifelse{html}{\out{sd(D0)}}{sd\eqn{(D_0)}}, mean\eqn{(α)}, sd\eqn{(α)}, mean\eqn{(β)}, sd\eqn{(β)} + T \tab T \tab F \tab T \tab sex, \ifelse{html}{\out{mean(D0)}}{mean\eqn{(D_0)}}, \ifelse{html}{\out{sd(D0)}}{sd\eqn{(D_0)}}, mean\eqn{(\alpha)}, sd\eqn{(\alpha)}, mean\eqn{(\beta)}, sd\eqn{(\beta)} } The column headings need not be included, only the numeric matrix is required. The rows require no particular order, but there must be exactly one row for each stage/sex combination. For example, in the case of density-, stage- and sex-dependent emigration with no individual variability: diff --git a/RangeShiftR/man/Settlement.Rd b/RangeShiftR/man/Settlement.Rd index 474811b..072f597 100644 --- a/RangeShiftR/man/Settlement.Rd +++ b/RangeShiftR/man/Settlement.Rd @@ -57,8 +57,8 @@ The type of implemented settlement rules depends on the movement model utilized In any case, dispersing individuals are not allowed to settle in their natal cell or patch.\cr \emph{RangeShiftR} incorporates some basic settlement rules that can be stage- or sex-specific or both (set \code{StageDep}, \code{SexDep}). Inter-individual variability (\code{IndVar}) is implemented only for movement processes and then for the three traits -determining density-dependent settlement (\ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{α_S}}, -\ifelse{html}{\out{βS}}{\eqn{β_S}}; see below). In this case, settlement may not be stage-dependent.\cr +determining density-dependent settlement (\ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{\alpha_S}}, +\ifelse{html}{\out{βS}}{\eqn{\beta_S}}; see below). In this case, settlement may not be stage-dependent.\cr \emph{Settlement with dispersal kernels}\cr When using a \code{\link[RangeShiftR]{DispersalKernel}}, individuals are displaced directly from the starting location to the arrival location. The suitability @@ -101,18 +101,18 @@ it gets converted to \eqn{S_0=1.0}, i.e. 'always settle when habitat is suitable Furthermore, the settlement decision can be density-dependent (set \code{DensDep=TRUE}). In this case, the individual has a probability \ifelse{html}{\out{pS}}{\eqn{p_S}} of settling in the cell or patch \eqn{i}, given by: -\ifelse{html}{\out{   pS(i,t) = S0 / ( 1 + eS (N(i,t) / K(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-α_S (N(i,t)/K(i,t) - β_S) ] ) } } +\ifelse{html}{\out{   pS(i,t) = S0 / ( 1 + eS (N(i,t) / K(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-\alpha_S (N(i,t)/K(i,t) - \beta_S) ] ) } } In the case of stage-structured models the above equation is modified to: -\ifelse{html}{\out{   pS(i,t) = S0 / ( 1 + eS (b(i,t) * N(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-α_S (b(i,t) N(i,t) - β_S) ] ) } } +\ifelse{html}{\out{   pS(i,t) = S0 / ( 1 + eS (b(i,t) * N(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-\alpha_S (b(i,t) N(i,t) - \beta_S) ] ) } } In the first case, \eqn{K(i,t)} is the carrying capacity of the cell/patch \eqn{i} at time \eqn{t} given by \code{K_or_DensDep}. In the latter case, \eqn{b(i,t)} represents the strength of density dependence that is given by the inverse of \code{K_or_DensDep}.\cr Further, \ifelse{html}{\out{S0}}{\eqn{S_0}} is the maximum settlement probability, \eqn{N(i,t)} is the number of individuals in the cell/patch \eqn{i} at time \eqn{t}, -\ifelse{html}{\out{βS}}{\eqn{β_S}} is the inflection point of the function and -\ifelse{html}{\out{αS}}{\eqn{α_S}} is the slope at the inflection point.\cr +\ifelse{html}{\out{βS}}{\eqn{\beta_S}} is the inflection point of the function and +\ifelse{html}{\out{αS}}{\eqn{\alpha_S}} is the slope at the inflection point.\cr Inter-individual variability \code{IndVar=TRUE} and thus evolution is implemented only for the three traits determining density-dependent settlement (\code{DensDep=TRUE}), and if so, it may not be stage-dependent (\code{StageDep=FALSE}). @@ -123,7 +123,7 @@ The parameters that determine the settlement probabilities have to be provided v used (i.e. \code{DensDep, IndVar, StageDep, SexDep = FALSE}) - a single numeric. The format of the matrix is defined as follows: The number of columns depend on the options \code{DensDep} and \code{IndVar}. If \code{DensDep=FALSE}, the density-independent probability \ifelse{html}{\out{pS}}{\eqn{p_S}} must be specified. If \code{DensDep=TRUE}, the functional parameters \ifelse{html}{\out{S0}}{\eqn{S_0}}, -\ifelse{html}{\out{αS}}{\eqn{α_S}} and \ifelse{html}{\out{βS}}{\eqn{β_S}} (cf. equation above) must be specified. +\ifelse{html}{\out{αS}}{\eqn{\alpha_S}} and \ifelse{html}{\out{βS}}{\eqn{\beta_S}} (cf. equation above) must be specified. Additionally, if \code{IndVar=FALSE}, these traits are fixed, but if \code{IndVar=TRUE} each of them is replaced by two parameters: their respective initial mean and standard deviation. They are used to normally distribute the traits values among the individuals of the initial population. Additionally, the \code{TraitScaleFactor} of these traits have to be set. @@ -137,11 +137,11 @@ The following table lists the required columns and their correct order for diffe F \tab F \tab T \tab F \tab stage \cr F \tab F \tab F \tab T \tab sex \cr F \tab F \tab T \tab T \tab stage, sex \cr - T \tab F \tab F \tab F \tab \ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{α_S}}, \ifelse{html}{\out{βS}}{\eqn{β_S}} \cr + T \tab F \tab F \tab F \tab \ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{\alpha_S}}, \ifelse{html}{\out{βS}}{\eqn{\beta_S}} \cr \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \cr - T \tab F \tab T \tab T \tab stage, sex, \ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{α_S}}, \ifelse{html}{\out{βS}}{\eqn{β_S}} \cr - T \tab T \tab F \tab F \tab mean\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, sd\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, mean\ifelse{html}{\out{(αS)}}{(\eqn{α_S})}, sd\ifelse{html}{\out{(αS)}}{(\eqn{α_S})}, mean\ifelse{html}{\out{(βS)}}{(\eqn{β_S})}, sd\ifelse{html}{\out{(βS)}}{(\eqn{β_S})} \cr - T \tab T \tab F \tab T \tab sex, mean\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, sd\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, mean\ifelse{html}{\out{(αS)}}{(\eqn{α_S})}, sd\ifelse{html}{\out{(αS)}}{(\eqn{α_S})}, mean\ifelse{html}{\out{(βS)}}{(\eqn{β_S})}, sd\ifelse{html}{\out{(βS)}}{(\eqn{β_S})} + T \tab F \tab T \tab T \tab stage, sex, \ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{\alpha_S}}, \ifelse{html}{\out{βS}}{\eqn{\beta_S}} \cr + T \tab T \tab F \tab F \tab mean\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, sd\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, mean\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, sd\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, mean\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})}, sd\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})} \cr + T \tab T \tab F \tab T \tab sex, mean\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, sd\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, mean\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, sd\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, mean\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})}, sd\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})} } The column headings need not be included, only the numeric matrix is required. The rows require no particular order, but there must be exactly one row for each stage/sex combination. diff --git a/RangeShiftR/man/Simulation.Rd b/RangeShiftR/man/Simulation.Rd index fe2fd82..5dcbb36 100644 --- a/RangeShiftR/man/Simulation.Rd +++ b/RangeShiftR/man/Simulation.Rd @@ -146,7 +146,7 @@ and \eqn{G} (\code{GradSteep}), the gradient steepness in units of fraction of t The local heterogeneity is determined by a random number drawn from a uniform distribution between \eqn{-1} and \eqn{1} for each cell and \code{f}, the local scaling factor that determines the magnitude of this stochastic local variation relative to the extremal value. -The gradient in fecundity φ applies to the fecundity of each stage. Negative local values in \eqn{z(x,y)} are set to \eqn{0}. +The gradient in fecundity \eqn{\phi} applies to the fecundity of each stage. Negative local values in \eqn{z(x,y)} are set to \eqn{0}. It is also possible to simulate the shifting of the gradient by setting the option \code{Shifting}. Here the position \eqn{y} of the species’ optimum is shifted northwards (increasing \eqn{y}) at a given rate \code{ShiftRate} (in units of rows per year), @@ -163,18 +163,18 @@ This does not affect any demographic parameters but simply kills off the local p \emph{Environmental Stochasticity}\cr It is possible to model environmental stochasticity via the option \code{EnvStoch} acting at a global or local scale and can be applied to \code{K_or_DensDep}, the demographic density dependence (\code{EnvStoch=1}), or to growth rate / fecundity (\code{EnvStoch=0}). -It is implemented using a first order autoregressive process to generate time series of the noise value \eqn{ε} +It is implemented using a first order autoregressive process to generate time series of the noise value \eqn{\epsilon} \insertCite{ruokolainen2009}{RangeShiftR}: -\deqn{ε(t+1) = Îş ε(t) + \omega(t) \sqrt(1-\kappa^2)} +\deqn{\epsilon(t+1) = \kappa \epsilon(t) + \omega(t) \sqrt(1-\kappa^2)} -where Îş is the autocorrelation coefficient (\code{ac}) and ω is a random normal variable drawn from \eqn{N(0,Ď)}. -Changing Ď (\code{std}) changes the magnitude of the fluctuations. The spatial scale of the variation can either be global (a single time series +where \eqn{\kappa} is the autocorrelation coefficient (\code{ac}) and \eqn{\omega} is a random normal variable drawn from \eqn{N(0,\sigma)}. +Changing \eqn{\sigma} (\code{std}) changes the magnitude of the fluctuations. The spatial scale of the variation can either be global (a single time series for the entire landscape) or local (each cell fluctuates independently), and is always applied on a yearly basis. Different degrees of spatial autocorrelation are not implemented in the current version. The noise affects the species' selected parameter \eqn{Z} as follows: -\deqn{Z(x,y,t) = Z(x,y,0) + Z ε(t)} +\deqn{Z(x,y,t) = Z(x,y,0) + Z \epsilon(t)} where \eqn{x} and \eqn{y} are the cell coordinates and \eqn{Z} is the original parameter value in absence of stochasticity and gradients. In the presence of an environmental gradient, \eqn{Z(x,y,0)} is the gradient value at the cell location, otherwise its equal to \eqn{Z}. The resulting values \eqn{Z(x,y,t)} are limited to the maximum and minimum values \code{minR,maxR} or \code{minK,maxK}, respectively. diff --git a/RangeShiftR/man/StageStructure.Rd b/RangeShiftR/man/StageStructure.Rd index 60a492a..2ea332a 100644 --- a/RangeShiftR/man/StageStructure.Rd +++ b/RangeShiftR/man/StageStructure.Rd @@ -49,39 +49,39 @@ In stage-structured populations, generations can overlap and individuals can be demographic parameters. Individuals are characterized by their age and stage. Each stage has a certain fecundity, survival probability and probability of developing to the next stage. These parameters are provided through classical transition matrices \insertCite{caswell2001}{RangeShiftR}. -\ifelse{html}{\out{φi}}{\eqn{φ_i}} is the fecundity of stage \eqn{i} ; -\ifelse{html}{\out{σi}}{\eqn{Ď_i}} is the survival probability of an individual in stage \eqn{i} ; -and \ifelse{html}{\out{γi-j}}{\eqn{Îł_(i-j)}} is the probability of developing from stage \eqn{i} to stage \eqn{j}. +\ifelse{html}{\out{φi}}{\eqn{\phi_i}} is the fecundity of stage \eqn{i} ; +\ifelse{html}{\out{σi}}{\eqn{\sigma_i}} is the survival probability of an individual in stage \eqn{i} ; +and \ifelse{html}{\out{γi-j}}{\eqn{\gamma_(i-j)}} is the probability of developing from stage \eqn{i} to stage \eqn{j}. In this way, the transition matrix describes the effect of each individuals current stage (column) on all stages at the next timestep (rows). Since all offspring is born into the juvenile stage (stage 0), all fecundities are always located in the first row of the matrix. However, in \emph{RangeShiftR}, these parameters are not used deterministically as \emph{rates} (like it is typical for matrix models) but, instead, as \emph{probabilities} which are -applied stochastically at the individual level. Hence, each female at stage \eqn{i}, if it reproduces, produces a number of offspring given by \eqn{Poisson}(\ifelse{html}{\out{φi}}{\eqn{φ_i}}), -while Bernoulli trials \eqn{Bern}(\ifelse{html}{\out{σi}}{\eqn{Ď_i}}) and \eqn{Bern}(\ifelse{html}{\out{γi,i+1}}{\eqn{Îł_(i,i+1)}}) determine if an individual/female survives or not +applied stochastically at the individual level. Hence, each female at stage \eqn{i}, if it reproduces, produces a number of offspring given by \eqn{Poisson}(\ifelse{html}{\out{φi}}{\eqn{\phi_i}}), +while Bernoulli trials \eqn{Bern}(\ifelse{html}{\out{σi}}{\eqn{\sigma_i}}) and \eqn{Bern}(\ifelse{html}{\out{γi,i+1}}{\eqn{\gamma_(i,i+1)}}) determine if an individual/female survives or not and - if it survives - if it develops to the next stage or not. An example transition matrix for a 3-staged only-female or simple sexual (\code{ReproductionType={0,1}}) population model: -\tabular{ccccc}{0 \tab | \tab 0 \tab | \tab \ifelse{html}{\out{φ2}}{\eqn{φ_2}} \cr -\eqn{1.0} \tab | \tab \ifelse{html}{\out{σ1 (1-γ1-2)}}{\eqn{Ď_1 (1 â’ Îł_(1-2))}} \tab | \tab \eqn{0} \cr -\eqn{0} \tab | \tab \ifelse{html}{\out{σ1 γ1-2}}{\eqn{Ď_1 Îł_(1-2)}} \tab | \tab \ifelse{html}{\out{σ2}}{\eqn{Ď_2}} \cr} +\tabular{ccccc}{0 \tab | \tab 0 \tab | \tab \ifelse{html}{\out{φ2}}{\eqn{\phi_2}} \cr +\eqn{1.0} \tab | \tab \ifelse{html}{\out{σ1 (1-γ1-2)}}{\eqn{\sigma_1 (1 - \gamma_(1-2))}} \tab | \tab \eqn{0} \cr +\eqn{0} \tab | \tab \ifelse{html}{\out{σ1 γ1-2}}{\eqn{\sigma_1 \gamma_(1-2)}} \tab | \tab \ifelse{html}{\out{σ2}}{\eqn{\sigma_2}} \cr} -In a female-only model (\code{ReproductionType=0}), \ifelse{html}{\out{φ}}{\eqn{φ}} represents the number of female offspring per female and reproductive event. \cr +In a female-only model (\code{ReproductionType=0}), \ifelse{html}{\out{φ}}{\eqn{\phi}} represents the number of female offspring per female and reproductive event. \cr Note that for an implicit (simple) sexual model (\code{ReproductionType=1}), the demographic parameters are not sex-specific. However, individuals are defined by their sex, which is acknowledged for example in the dispersal -process and transmission of alleles. The fecundities \ifelse{html}{\out{φ}}{\eqn{φ}} refer to the number of all offspring (males and females) per female and reproductive event. +process and transmission of alleles. The fecundities \ifelse{html}{\out{φ}}{\eqn{\phi}} refer to the number of all offspring (males and females) per female and reproductive event. In case of an explicit (complex) sexual model (\code{ReproductionType=2}), in contrast, each stage must be represented by two columns and rows to distinguish male and female demographic parameters. -Note, however, that in any case the juvenile stage has only one row; it contains the fecundities. Male fecundities should have one of two possible values: set \ifelse{html}{\out{φm}}{\eqn{φ_m}} \eqn{=1.0} for reproductive males or \ifelse{html}{\out{φm}}{\eqn{φ_m}} \eqn{=0.0} for non-reproductive males.\cr +Note, however, that in any case the juvenile stage has only one row; it contains the fecundities. Male fecundities should have one of two possible values: set \ifelse{html}{\out{φm}}{\eqn{\phi_m}} \eqn{=1.0} for reproductive males or \ifelse{html}{\out{φm}}{\eqn{\phi_m}} \eqn{=0.0} for non-reproductive males.\cr An example transition matrix for a 3-staged explicit sexual population model \insertCite{weeks1986,lindstrom1998}{RangeShiftR}: -\tabular{ccccccccccc}{\eqn{0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{φ1m}}{\eqn{φ_1m}} \tab | \tab \ifelse{html}{\out{φ1f}}{\eqn{φ_1f}} \tab | \tab \ifelse{html}{\out{φ2m}}{\eqn{φ_2m}} \tab | \tab \ifelse{html}{\out{φ2f}}{\eqn{φ_2f}} \cr -\eqn{1.0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1m (1-γ1-2,m)}}{\eqn{Ď_1m (1 â’ Îł_(1-2,m))}} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \cr -\eqn{0} \tab | \tab \eqn{1.0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1f γ1-2,f}}{\eqn{Ď_1f Îł_(1-2,f)}} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \cr -\eqn{0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1m γ1-2,m}}{\eqn{Ď_1m Îł_(1-2,m)}} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ2m}}{\eqn{Ď_2m}} \tab | \tab \eqn{0} \cr -\eqn{0} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1f γ1-2,f}}{\eqn{Ď_1f Îł_(1-2,f)}} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ2f}}{\eqn{Ď_2f}} \cr}#' The mating system is explicitly modelled and a female’s probability of reproducing is determined as described in \code{\link[RangeShiftR]{Demography}} \insertCite{weeks1986,caswell2001}{RangeShiftR}. +\tabular{ccccccccccc}{\eqn{0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{φ1m}}{\eqn{\phi_1m}} \tab | \tab \ifelse{html}{\out{φ1f}}{\eqn{\phi_1f}} \tab | \tab \ifelse{html}{\out{φ2m}}{\eqn{\phi_2m}} \tab | \tab \ifelse{html}{\out{φ2f}}{\eqn{\phi_2f}} \cr +\eqn{1.0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1m (1-γ1-2,m)}}{\eqn{\sigma_1m (1 - \gamma_(1-2,m))}} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \cr +\eqn{0} \tab | \tab \eqn{1.0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1f γ1-2,f}}{\eqn{\sigma_1f \gamma_(1-2,f)}} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \cr +\eqn{0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1m γ1-2,m}}{\eqn{\sigma_1m \gamma_(1-2,m)}} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ2m}}{\eqn{\sigma_2m}} \tab | \tab \eqn{0} \cr +\eqn{0} \tab | \tab \eqn{0} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ1f γ1-2,f}}{\eqn{\sigma_1f \gamma_(1-2,f)}} \tab | \tab \eqn{0} \tab | \tab \ifelse{html}{\out{σ2f}}{\eqn{\sigma_2f}} \cr}#' The mating system is explicitly modelled and a female’s probability of reproducing is determined as described in \code{\link[RangeShiftR]{Demography}} \insertCite{weeks1986,caswell2001}{RangeShiftR}. A common mistake in building a transition matrix is made when offspring produced at year \eqn{t} develop to the next stage in the same year \insertCite{@ @caswell2001 pg. 60-62}{RangeShiftR}. To avoid this problem without losing the offspring stage, and hence the chance for simulating post-natal dispersal, we require an additional explicit juvenile stage (stage 0). Juveniles have to develop to stage 1 in the same year they are born. Hence the minimum number of stages of a stage-structured model is always \eqn{2}. It is important to note that juvenile mortality can be accounted for in -two ways. Either, as in the examples above, it is included in adult fecundity \ifelse{html}{\out{φ}}{\eqn{φ}} (by appropriately reducing its value), and \ifelse{html}{\out{σ0 γ(0-1)}}{\eqn{Ď_0 Îł_(0-1)}} is equal to \eqn{1.0}. This is how it is typically accounted for in matrix models. Or, alternatively, -φ is equal to the true maximum fecundity and \ifelse{html}{\out{σ0 γ(0-1)}}{\eqn{Ď_0 Îł_(0-1)}} is less than \eqn{1.0}. +two ways. Either, as in the examples above, it is included in adult fecundity \ifelse{html}{\out{φ}}{\eqn{\phi}} (by appropriately reducing its value), and \ifelse{html}{\out{σ0 γ(0-1)}}{\eqn{\sigma_0 \gamma_(0-1)}} is equal to \eqn{1.0}. This is how it is typically accounted for in matrix models. Or, alternatively, +\phi is equal to the true maximum fecundity and \ifelse{html}{\out{σ0 γ(0-1)}}{\eqn{\sigma_0 \gamma_(0-1)}} is less than \eqn{1.0}. Only the first approach allows straightforward direct comparison with standard analytical matrix models. \emph{Minimum ages:} For every row in the transition matrix, a minimum age must be provided through a vector in argument \code{MinAge}. It specifies the age which an individual in stage \eqn{i-1} (with sex \eqn{m/f}, if applicable) must already have reached before it can develop into the next stage \eqn{(i)}. The vector must be in @@ -114,26 +114,26 @@ If the transition matrix contains the annual survival and development rates, \co \emph{Density dependence} can act on each of the three demographic phases (i.e. reproduction, survival and development) and is controlled by \code{FecDensDep,DevDensDep,SurvDensDep}. It is implemented as an exponential decay \insertCite{neubert2000}{RangeShiftR}: -\ifelse{html}{\out{   φi(r,t) = φ0,i * e - b(r) N(t) }}{\deqn{φ_i(r,t)=φ_(0,i) * exp(- b(r) N(t) ) }} +\ifelse{html}{\out{   φi(r,t) = φ0,i * e - b(r) N(t) }}{\deqn{\phi_i(r,t)=\phi_(0,i) * exp(- b(r) N(t) ) }} -\ifelse{html}{\out{   σi(r,t) = σ0,i * e - Cσ b(r) N(t) }}{\deqn{Ď_i(r,t)=Ď_(0,i) * exp(- C_\sigma b(r) N(t) ) }} +\ifelse{html}{\out{   σi(r,t) = σ0,i * e - Cσ b(r) N(t) }}{\deqn{\sigma_i(r,t)=\sigma_(0,i) * exp(- C_\sigma b(r) N(t) ) }} -\ifelse{html}{\out{   γi(r,t) = γ0,i * e - Cγ b(r) N(t) }}{\deqn{Îł_i(r,t)=Îł_(0,i) * exp(- C_Îł b(r) N(t) ) }} +\ifelse{html}{\out{   γi(r,t) = γ0,i * e - Cγ b(r) N(t) }}{\deqn{\gamma_i(r,t)=\gamma_(0,i) * exp(- C_\gamma b(r) N(t) ) }} where \eqn{b(r)} is the strength of density dependence in fecundity at site \eqn{r}, which is given by the argument \code{K_or_DensDep} in the landscape module. -Furthermore, \ifelse{html}{\out{Cσ}}{\eqn{C_\sigma}} and \ifelse{html}{\out{Cγ}}{\eqn{C_Îł}} (\code{DevDensCoeff,SurvDensCoeff}) +Furthermore, \ifelse{html}{\out{Cσ}}{\eqn{C_\sigma}} and \ifelse{html}{\out{Cγ}}{\eqn{C_\gamma}} (\code{DevDensCoeff,SurvDensCoeff}) scale the strength of density dependence in survival and development relative to that in fecundity. Moreover, the strength of density-dependence can be uniform for all stages or stage-dependent. Even greater complexity can be incorporated with different stages contributing differently to density-dependence \insertCite{caswell2004}{RangeShiftR}: -\ifelse{html}{\out{  φi(r,t) = φ0,i * e - b(r) ΣjS ωφ,ij N(j,t)}}{\deqn{φ_i(r,t)=φ_(0,i) * exp(- b(r) \Sigma_j^S ω_{φ,ij} N_j(t) ) }} +\ifelse{html}{\out{  φi(r,t) = φ0,i * e - b(r) ΣjS ωφ,ij N(j,t)}}{\deqn{\phi_i(r,t)=\phi_(0,i) * exp(- b(r) \Sigma_j^S \omega_{\phi,ij} N_j(t) ) }} -\ifelse{html}{\out{  σi(r,t) = σ0,i * e - Cσ b(r) ΣjS ωσ,ij N(j,t) }}{\deqn{Ď_i(r,t)=Ď_(0,i) * exp(- C_\sigma b(r) \Sigma_j^S ω_{Ď,ij} N_j(t) )}} +\ifelse{html}{\out{  σi(r,t) = σ0,i * e - Cσ b(r) ΣjS ωσ,ij N(j,t) }}{\deqn{\sigma_i(r,t)=\sigma_(0,i) * exp(- C_\sigma b(r) \Sigma_j^S \omega_{\sigma,ij} N_j(t) )}} -\ifelse{html}{\out{  γi(r,t) = γ0,i * e - Cγ b(r) ΣjS ωγ,ij N(j,t)}}{\deqn{Îł_i(r,t)=Îł_(0,i) * exp(- C_Îł b(r) \Sigma_j^S ω_{Îł,ij} N_j(t) )}} +\ifelse{html}{\out{  γi(r,t) = γ0,i * e - Cγ b(r) ΣjS ωγ,ij N(j,t)}}{\deqn{\gamma_i(r,t)=\gamma_(0,i) * exp(- C_\gamma b(r) \Sigma_j^S \omega_{\gamma,ij} N_j(t) )}} -where \ifelse{html}{\out{ωφ}}{\eqn{ω_φ}}, \ifelse{html}{\out{ωσ}}{\eqn{ω_Ď}}, \ifelse{html}{\out{ωγ}}{\eqn{ω_Îł}} are weight matrices given by \code{FecStageWtsMatrix, DevStageWtsMatrix, SurvStageWtsMatrix}. Their elements \ifelse{html}{\out{ωij}}{\eqn{ω_ij}} +where \ifelse{html}{\out{ωφ}}{\eqn{\omega_\phi}}, \ifelse{html}{\out{ωσ}}{\eqn{\omega_\sigma}}, \ifelse{html}{\out{ωγ}}{\eqn{\omega_\gamma}} are weight matrices given by \code{FecStageWtsMatrix, DevStageWtsMatrix, SurvStageWtsMatrix}. Their elements \ifelse{html}{\out{ωij}}{\eqn{\omega_ij}} represent the contributions of the abundance of stage \eqn{j} to the density dependence in the fecundity / survival / development of stage \eqn{i}, thus they are quadratic matrices of size \code{Stages}\eqn{^2}. Note that the row sums are not required to be normalized, therefore they can be used to scale the density-dependence for the different stages. In fact, any real value will be accepted for the single weights, so care should be taken when setting them. } diff --git a/RangeShiftR/man/plotProbs.Rd b/RangeShiftR/man/plotProbs.Rd index 29d6497..98b37b3 100644 --- a/RangeShiftR/man/plotProbs.Rd +++ b/RangeShiftR/man/plotProbs.Rd @@ -31,20 +31,20 @@ Available methods and their options: If a mixed kernel was defined (i.e. \code{DoubleKernel=TRUE}), plot the resulting dispersal probability by... \itemize{ \item \code{combinekernels=FALSE} - ...plotting both kernels separately (default) - \item \code{combinekernels= TRUE} - ...combining both kernels, i.e. \ifelse{html}{ \out{p(d; δ12) = pI p(d;δ1) + (1-pI) p(d;δ1) } }{\deqn{ p(d; δ_1,δ_2) = p_I p(d;δ_1) + (1-p_I) p(d;δ_2)} } + \item \code{combinekernels= TRUE} - ...combining both kernels, i.e. \ifelse{html}{ \out{p(d; δ12) = pI p(d;δ1) + (1-pI) p(d;δ1) } }{\deqn{ p(d; \delta_1,\delta_2) = p_I p(d;\delta_1) + (1-p_I) p(d;\delta_2)} } } \item \code{\link[RangeShiftR]{StageStructure}}: plot fecundity as well as survival and development probabilities. Survival and development are calculated based on the transition matrix. Consider e.g. a 3 stage matrix with a transition matrix of - \tabular{ccccc}{0 \tab | \tab 0 \tab | \tab \ifelse{html}{\out{φ2}}{\eqn{φ_2}} \cr - \eqn{1.0} \tab | \tab \ifelse{html}{\out{σ1 (1-γ1-2)}}{\eqn{Ď_1 (1 â’ Îł_(1-2))}} \tab | \tab \eqn{0} \cr - \eqn{0} \tab | \tab \ifelse{html}{\out{σ1 γ1-2}}{\eqn{Ď_1 Îł_(1-2)}} \tab | \tab \ifelse{html}{\out{σ2}}{\eqn{Ď_2}} \cr} + \tabular{ccccc}{0 \tab | \tab 0 \tab | \tab \ifelse{html}{\out{φ2}}{\eqn{\phi_2}} \cr + \eqn{1.0} \tab | \tab \ifelse{html}{\out{σ1 (1-γ1-2)}}{\eqn{\sigma_1 (1 - \gamma_(1-2))}} \tab | \tab \eqn{0} \cr + \eqn{0} \tab | \tab \ifelse{html}{\out{σ1 γ1-2}}{\eqn{\sigma_1 \gamma_(1-2)}} \tab | \tab \ifelse{html}{\out{σ2}}{\eqn{\sigma_2}} \cr} The survival probability is calculated as the sum of the probability to stay in the same stage and the probability to reach the next stage. - E.g. for stage 1: \ifelse{html}{\out{σ1 = sum( σ1 (1-γ1-2), σ1 γ1-2}}{\eqn{Ď_1 = sum(Ď_1 (1 â’ Îł_(1-2)), Ď_1 Îł_(1-2))}} + E.g. for stage 1: \ifelse{html}{\out{σ1 = sum( σ1 (1-γ1-2), σ1 γ1-2}}{\eqn{\sigma_1 = sum(\sigma_1 (1 - \gamma_(1-2)), \sigma_1 \gamma_(1-2))}} The development probability of stage 1 to stage 2 is the ratio of the probability to reach stage 2 and the previously calculated survival probability. - E.g. for stage 1: \ifelse{html}{\out{γ1-2 = σ1 γ1-2 / σ1}}{\eqn{Îł_(1-2) = Ď_1 / (Ď_1 Îł_(1-2) )}} + E.g. for stage 1: \ifelse{html}{\out{γ1-2 = σ1 γ1-2 / σ1}}{\eqn{\gamma_(1-2) = \sigma_1 / (\sigma_1 \gamma_(1-2) )}} } } From 6bbfc57e3ecf53cd8ddde8840a6339edddff627e Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Fri, 24 Nov 2023 10:44:52 +0000 Subject: [PATCH 12/17] fix out of equation greek symbols --- RangeShiftR/R/class_DemogParams.R | 2 +- RangeShiftR/R/class_DispersalParams.R | 2 +- RangeShiftR/man/DispersalKernel.Rd | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/RangeShiftR/R/class_DemogParams.R b/RangeShiftR/R/class_DemogParams.R index 99d4682..0d3e5c6 100644 --- a/RangeShiftR/R/class_DemogParams.R +++ b/RangeShiftR/R/class_DemogParams.R @@ -89,7 +89,7 @@ #' A common mistake in building a transition matrix is made when offspring produced at year \eqn{t} develop to the next stage in the same year \insertCite{@ @caswell2001 pg. 60-62}{RangeShiftR}. To avoid this problem without losing the offspring stage, and hence the chance for simulating post-natal dispersal, #' we require an additional explicit juvenile stage (stage 0). Juveniles have to develop to stage 1 in the same year they are born. Hence the minimum number of stages of a stage-structured model is always \eqn{2}. It is important to note that juvenile mortality can be accounted for in #' two ways. Either, as in the examples above, it is included in adult fecundity \ifelse{html}{\out{φ}}{\eqn{\phi}} (by appropriately reducing its value), and \ifelse{html}{\out{σ0 γ(0-1)}}{\eqn{\sigma_0 \gamma_(0-1)}} is equal to \eqn{1.0}. This is how it is typically accounted for in matrix models. Or, alternatively, -#' \phi is equal to the true maximum fecundity and \ifelse{html}{\out{σ0 γ(0-1)}}{\eqn{\sigma_0 \gamma_(0-1)}} is less than \eqn{1.0}. +#' \eqn{\phi} is equal to the true maximum fecundity and \ifelse{html}{\out{σ0 γ(0-1)}}{\eqn{\sigma_0 \gamma_(0-1)}} is less than \eqn{1.0}. #' Only the first approach allows straightforward direct comparison with standard analytical matrix models. #' #' \emph{Minimum ages:} For every row in the transition matrix, a minimum age must be provided through a vector in argument \code{MinAge}. It specifies the age which an individual in stage \eqn{i-1} (with sex \eqn{m/f}, if applicable) must already have reached before it can develop into the next stage \eqn{(i)}. The vector must be in diff --git a/RangeShiftR/R/class_DispersalParams.R b/RangeShiftR/R/class_DispersalParams.R index acd8b60..f57fea0 100644 --- a/RangeShiftR/R/class_DispersalParams.R +++ b/RangeShiftR/R/class_DispersalParams.R @@ -521,7 +521,7 @@ setMethod("show", "TransferParams", function(object){ #' carry either one trait for \eqn{\delta} or three traits for \ifelse{html}{\out{δ1}}{\eqn{\delta_1}}, \ifelse{html}{\out{δ2}}{\eqn{\delta_2}} and #' \ifelse{html}{\out{pI}}{\eqn{p_I}}, which they inherit from their parents.\cr #' Dispersal kernels can also be sex-dependent (set \code{SexDep=TRUE}). In the case of inter-individual variability, the number of traits is doubled to two trait (female \eqn{\delta} -#' and male \delta) or six traits (female and male \ifelse{html}{\out{δ1}}{\eqn{\delta_1}}, \ifelse{html}{\out{δ2}}{\eqn{\delta_2}} and \ifelse{html}{\out{pI}}{\eqn{p_I}}).\cr +#' and male delta) or six traits (female and male \ifelse{html}{\out{δ1}}{\eqn{\delta_1}}, \ifelse{html}{\out{δ2}}{\eqn{\delta_2}} and \ifelse{html}{\out{pI}}{\eqn{p_I}}).\cr #' For each trait the initial distribution in the population (as mean and standard variation) must be set in \code{Distances} (instead of only one constant value), #' as well as their scaling factors in \code{TraitScaleFactor} (see \code{\link[RangeShiftR]{Genetics}}).\cr #' diff --git a/RangeShiftR/man/DispersalKernel.Rd b/RangeShiftR/man/DispersalKernel.Rd index 76a2e87..6dfca89 100644 --- a/RangeShiftR/man/DispersalKernel.Rd +++ b/RangeShiftR/man/DispersalKernel.Rd @@ -89,7 +89,7 @@ For both types of kernel, inter-individual variability of the kernel traits is p carry either one trait for \eqn{\delta} or three traits for \ifelse{html}{\out{δ1}}{\eqn{\delta_1}}, \ifelse{html}{\out{δ2}}{\eqn{\delta_2}} and \ifelse{html}{\out{pI}}{\eqn{p_I}}, which they inherit from their parents.\cr Dispersal kernels can also be sex-dependent (set \code{SexDep=TRUE}). In the case of inter-individual variability, the number of traits is doubled to two trait (female \eqn{\delta} -and male \delta) or six traits (female and male \ifelse{html}{\out{δ1}}{\eqn{\delta_1}}, \ifelse{html}{\out{δ2}}{\eqn{\delta_2}} and \ifelse{html}{\out{pI}}{\eqn{p_I}}).\cr +and male delta) or six traits (female and male \ifelse{html}{\out{δ1}}{\eqn{\delta_1}}, \ifelse{html}{\out{δ2}}{\eqn{\delta_2}} and \ifelse{html}{\out{pI}}{\eqn{p_I}}).\cr For each trait the initial distribution in the population (as mean and standard variation) must be set in \code{Distances} (instead of only one constant value), as well as their scaling factors in \code{TraitScaleFactor} (see \code{\link[RangeShiftR]{Genetics}}).\cr From 7fb5a858d7476c3d61a98215578e44cd21bd37ff Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Fri, 24 Nov 2023 11:22:01 +0000 Subject: [PATCH 13/17] fix LaTeX errors - tabular errors bc of html tab and some unicode characters --- RangeShiftR/R/class_DemogParams.R | 16 +++---- RangeShiftR/R/class_DispersalParams.R | 58 +++++++++++++------------- RangeShiftR/R/class_SimulationParams.R | 2 +- RangeShiftR/man/Demography.Rd | 4 +- RangeShiftR/man/DispersalKernel.Rd | 20 ++++----- RangeShiftR/man/Emigration.Rd | 18 ++++---- RangeShiftR/man/Settlement.Rd | 20 ++++----- RangeShiftR/man/Simulation.Rd | 2 +- RangeShiftR/man/StageStructure.Rd | 14 +++---- 9 files changed, 77 insertions(+), 77 deletions(-) diff --git a/RangeShiftR/R/class_DemogParams.R b/RangeShiftR/R/class_DemogParams.R index 0d3e5c6..18c1b2e 100644 --- a/RangeShiftR/R/class_DemogParams.R +++ b/RangeShiftR/R/class_DemogParams.R @@ -122,11 +122,11 @@ #' \emph{Density dependence} can act on each of the three demographic phases (i.e. reproduction, survival and development) and is controlled by \code{FecDensDep,DevDensDep,SurvDensDep}. #' It is implemented as an exponential decay \insertCite{neubert2000}{RangeShiftR}: #' -#' \ifelse{html}{\out{   φi(r,t) = φ0,i * e - b(r) N(t) }}{\deqn{\phi_i(r,t)=\phi_(0,i) * exp(- b(r) N(t) ) }} +#' \ifelse{html}{\out{ φi(r,t) = φ0,i * e - b(r) N(t) }}{\deqn{\phi_i(r,t)=\phi_(0,i) * exp(- b(r) N(t) ) }} #' -#' \ifelse{html}{\out{   σi(r,t) = σ0,i * e - Cσ b(r) N(t) }}{\deqn{\sigma_i(r,t)=\sigma_(0,i) * exp(- C_\sigma b(r) N(t) ) }} +#' \ifelse{html}{\out{ σi(r,t) = σ0,i * e - Cσ b(r) N(t) }}{\deqn{\sigma_i(r,t)=\sigma_(0,i) * exp(- C_\sigma b(r) N(t) ) }} #' -#' \ifelse{html}{\out{   γi(r,t) = γ0,i * e - Cγ b(r) N(t) }}{\deqn{\gamma_i(r,t)=\gamma_(0,i) * exp(- C_\gamma b(r) N(t) ) }} +#' \ifelse{html}{\out{ γi(r,t) = γ0,i * e - Cγ b(r) N(t) }}{\deqn{\gamma_i(r,t)=\gamma_(0,i) * exp(- C_\gamma b(r) N(t) ) }} #' #' where \eqn{b(r)} is the strength of density dependence in fecundity at site \eqn{r}, which is given by the argument \code{K_or_DensDep} in the landscape module. #' Furthermore, \ifelse{html}{\out{Cσ}}{\eqn{C_\sigma}} and \ifelse{html}{\out{Cγ}}{\eqn{C_\gamma}} (\code{DevDensCoeff,SurvDensCoeff}) @@ -135,11 +135,11 @@ #' Moreover, the strength of density-dependence can be uniform for all stages or stage-dependent. Even greater complexity can be incorporated with #' different stages contributing differently to density-dependence \insertCite{caswell2004}{RangeShiftR}: #' -#' \ifelse{html}{\out{  φi(r,t) = φ0,i * e - b(r) ΣjS ωφ,ij N(j,t)}}{\deqn{\phi_i(r,t)=\phi_(0,i) * exp(- b(r) \Sigma_j^S \omega_{\phi,ij} N_j(t) ) }} +#' \ifelse{html}{\out{ φi(r,t) = φ0,i * e - b(r) ΣjS ωφ,ij N(j,t)}}{\deqn{\phi_i(r,t)=\phi_(0,i) * exp(- b(r) \Sigma_j^S \omega_{\phi,ij} N_j(t) ) }} #' -#' \ifelse{html}{\out{  σi(r,t) = σ0,i * e - Cσ b(r) ΣjS ωσ,ij N(j,t) }}{\deqn{\sigma_i(r,t)=\sigma_(0,i) * exp(- C_\sigma b(r) \Sigma_j^S \omega_{\sigma,ij} N_j(t) )}} +#' \ifelse{html}{\out{ σi(r,t) = σ0,i * e - Cσ b(r) ΣjS ωσ,ij N(j,t) }}{\deqn{\sigma_i(r,t)=\sigma_(0,i) * exp(- C_\sigma b(r) \Sigma_j^S \omega_{\sigma,ij} N_j(t) )}} #' -#' \ifelse{html}{\out{  γi(r,t) = γ0,i * e - Cγ b(r) ΣjS ωγ,ij N(j,t)}}{\deqn{\gamma_i(r,t)=\gamma_(0,i) * exp(- C_\gamma b(r) \Sigma_j^S \omega_{\gamma,ij} N_j(t) )}} +#' \ifelse{html}{\out{ γi(r,t) = γ0,i * e - Cγ b(r) ΣjS ωγ,ij N(j,t)}}{\deqn{\gamma_i(r,t)=\gamma_(0,i) * exp(- C_\gamma b(r) \Sigma_j^S \omega_{\gamma,ij} N_j(t) )}} #' #' where \ifelse{html}{\out{ωφ}}{\eqn{\omega_\phi}}, \ifelse{html}{\out{ωσ}}{\eqn{\omega_\sigma}}, \ifelse{html}{\out{ωγ}}{\eqn{\omega_\gamma}} are weight matrices given by \code{FecStageWtsMatrix, DevStageWtsMatrix, SurvStageWtsMatrix}. Their elements \ifelse{html}{\out{ωij}}{\eqn{\omega_ij}} #' represent the contributions of the abundance of stage \eqn{j} to the density dependence in the fecundity / survival / development of stage \eqn{i}, thus they are quadratic matrices of size \code{Stages}\eqn{^2}. Note that the row sums are not required to be normalized, therefore they can be used @@ -543,7 +543,7 @@ setClassUnion("StagesSlot", c("logical", "StagesParams")) #' \emph{Asexual / only-female models:} (\code{ReproductionType=0})\cr #' Recruitment is determined by a stochastic, individual-based formulation of the \insertCite{smith1973;textual}{RangeShiftR} population model, where the number of offspring produced by a single individual in the cell/patch \eqn{i} at time \eqn{t}, is drawn from the following distribution:\cr #' -#' \ifelse{html}{\out{  Njuv(i,t) = Poisson( R(i,t) / (1+|R(i,t) - 1| * (N(i,t) / K(i,t))bc ) ) } }{\deqn{N_juv(i,t) = Poisson( R(i,t) / (1 + |R(i,t) - 1|*( N(i,t) / K(i,t) )^bc ) ) } } +#' \ifelse{html}{\out{Njuv(i,t) = Poisson( R(i,t) / (1+|R(i,t) - 1| * (N(i,t) / K(i,t))bc ) ) } }{\deqn{N_juv(i,t) = Poisson( R(i,t) / (1 + |R(i,t) - 1|*( N(i,t) / K(i,t) )^bc ) ) } } #' #' Here, \eqn{R(i,t)} is the maximum growth rate \code{Rmax} (obtained at very low density only) and \eqn{K(i,t)} is the carrying capacity #' at patch \eqn{i} and time \eqn{t}. @@ -559,7 +559,7 @@ setClassUnion("StagesSlot", c("logical", "StagesParams")) #' This is the simplest form of mate limitation. Each female individual is assumed to mate, as long as there is at least one male in the population. As for the asexual case, the Maynard Smith and Slatkin model is used to determine the expected number of #' offspring produced by each female. To maintain equivalence between the asexual and sexual versions, the expected value of the Poisson distribution is multiplied by \eqn{2} (Lindström & Kokko 1998):\cr #' -#' \ifelse{html}{\out{  Njuv(i,t) = Poisson( 2 R(i,t) / (1+|R(i,t) - 1| * (N(i,t) / K(i,t) )bc ) ) } }{\deqn{N_juv(i,t) = Poisson( 2 R(i,t) / (1 + |R(i,t) - 1|*( N(i,t) / K(i,t) )^bc ) ) } } +#' \ifelse{html}{\out{Njuv(i,t) = Poisson( 2 R(i,t) / (1+|R(i,t) - 1| * (N(i,t) / K(i,t) )bc ) ) } }{\deqn{N_juv(i,t) = Poisson( 2 R(i,t) / (1 + |R(i,t) - 1|*( N(i,t) / K(i,t) )^bc ) ) } } #' #' \emph{Complex mating system:} (\code{ReproductionType=2})\cr #' More complex and flexible mating system. Mating is explicitly modelled through a mating function diff --git a/RangeShiftR/R/class_DispersalParams.R b/RangeShiftR/R/class_DispersalParams.R index f57fea0..3226b88 100644 --- a/RangeShiftR/R/class_DispersalParams.R +++ b/RangeShiftR/R/class_DispersalParams.R @@ -58,11 +58,11 @@ #' #' The emigration probability \eqn{d} can be density-dependent (set \code{DensDep=TRUE}), in which case it is given by the following function, introduced by \insertCite{kun2006evolution;textual}{RangeShiftR}: #' -#' \ifelse{html}{\out{   d(i,t) = D0 / ( 1 + e-αsub>E (N(i,t) / K(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-\alpha_E (N(i,t)/K(i,t) - \beta_E) ] ) } } +#' \ifelse{html}{\out{ d(i,t) = D0 / ( 1 + e-αsub>E (N(i,t) / K(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-\alpha_E (N(i,t)/K(i,t) - \beta_E) ] ) } } #' #' In the case of stage-structured models this equation is modified to: #' -#' \ifelse{html}{\out{   d(i,t) = D0 / ( 1 + e-αsub>E (b(i,t) * N(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-\alpha_E (b(i,t) N(i,t) - \beta_E) ] ) } } +#' \ifelse{html}{\out{ d(i,t) = D0 / ( 1 + e-αsub>E (b(i,t) * N(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-\alpha_E (b(i,t) N(i,t) - \beta_E) ] ) } } #' #' In the first case, \eqn{K(i,t)} is the carrying capacity of the cell/patch \eqn{i} at time \eqn{t} given by \code{K_or_DensDep}. #' In the latter case, \eqn{b(i,t)} represents the strength of density dependence and is given by the inverse of \code{K_or_DensDep}.\cr @@ -106,17 +106,17 @@ #' T \tab F \tab F \tab F \tab \ifelse{html}{\out{D0}}{\eqn{D_0}}, \eqn{\alpha}, \eqn{\beta} \cr #' F \tab T \tab F \tab F \tab mean\eqn{(d)}, sd\eqn{(d)} \cr #' T \tab T \tab F \tab F \tab \ifelse{html}{\out{mean(D0)}}{mean\eqn{(D_0)}}, \ifelse{html}{\out{sd(D0)}}{sd\eqn{(D_0)}}, mean\eqn{(\alpha)}, sd\eqn{(\alpha)}, mean\eqn{(\beta)}, sd\eqn{(\beta)} \cr -#' \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \cr +#' \out{:} \tab \out{:} \tab \out{:} \tab \out{:} \tab \out{:} \cr #' T \tab T \tab F \tab T \tab sex, \ifelse{html}{\out{mean(D0)}}{mean\eqn{(D_0)}}, \ifelse{html}{\out{sd(D0)}}{sd\eqn{(D_0)}}, mean\eqn{(\alpha)}, sd\eqn{(\alpha)}, mean\eqn{(\beta)}, sd\eqn{(\beta)} #' } #' #' The column headings need not be included, only the numeric matrix is required. The rows require no particular order, but there must be exactly one row for each stage/sex combination. For example, in the case of density-, stage- and sex-dependent emigration with no individual variability: -#' \tabular{ccccc}{ \out{ } 0 \tab \out{ } 0 \tab \out{ } 1.0 \tab \out{ } 20 \tab \out{ } 0.2 \cr -#' \out{ } 0 \tab \out{ } 1 \tab \out{ } 1.0 \tab \out{ } 20 \tab \out{ } 0.1 \cr -#' \out{ } 1 \tab \out{ } 0 \tab \out{ } 0.7 \tab \out{ } 25 \tab \out{ } 0.5 \cr -#' \out{ } 1 \tab \out{ } 1 \tab \out{ } 0.8 \tab \out{ } 50 \tab \out{ } 0.5 \cr -#' \out{ } 2 \tab \out{ } 0 \tab \out{ } 0.4 \tab \out{ } 10 \tab \out{ } 1.0 \cr -#' \out{ } 2 \tab \out{ } 1 \tab \out{ } 0.5 \tab \out{ } 20 \tab \out{ } 1.0 +#' \tabular{ccccc}{ \out{} 0 \tab \out{} 0 \tab \out{} 1.0 \tab \out{} 20 \tab \out{} 0.2 \cr +#' \out{} 0 \tab \out{} 1 \tab \out{} 1.0 \tab \out{} 20 \tab \out{} 0.1 \cr +#' \out{} 1 \tab \out{} 0 \tab \out{} 0.7 \tab \out{} 25 \tab \out{} 0.5 \cr +#' \out{} 1 \tab \out{} 1 \tab \out{} 0.8 \tab \out{} 50 \tab \out{} 0.5 \cr +#' \out{} 2 \tab \out{} 0 \tab \out{} 0.4 \tab \out{} 10 \tab \out{} 1.0 \cr +#' \out{} 2 \tab \out{} 1 \tab \out{} 0.5 \tab \out{} 20 \tab \out{} 1.0 #' } #' #' In the special case that \code{DensDep=FALSE} and transfer is realised by \code{\link[RangeShiftR]{DispersalKernel}}, then the option \code{UseFullKern} may be switched on. It @@ -494,7 +494,7 @@ setMethod("show", "TransferParams", function(object){ #' The distance is drawn from a negative exponential distribution with a given mean \eqn{\delta}, and the direction is selected randomly from a uniform #' distribution between \eqn{0} and \eqn{2\pi} radians. #' -#' \ifelse{html}{\out{   p(d;δ) = δ-1 e- d / δ}}{\deqn{ p(d;\delta) = 1/\delta exp(-d/\delta) } } +#' \ifelse{html}{\out{ p(d;δ) = δ-1 e- d / δ}}{\deqn{ p(d;\delta) = 1/\delta exp(-d/\delta) } } #' #' If the arrival point lies beyond the boundary of the landscape, distance and direction are re-drawn.\cr #' The individual is displaced from a random point (using continuous coordinates) inside the natal cell to the arrival cell where the model @@ -515,7 +515,7 @@ setMethod("show", "TransferParams", function(object){ #' occurring with probability \ifelse{html}{\out{pI}}{\eqn{p_I}} and \eqn{1-}\ifelse{html}{\out{pI}}{\eqn{p_I}} respectively \insertCite{hovestadt2011all}{RangeShiftR}. #' Otherwise, the conditions for the single kernel apply. #' -#' \ifelse{html}{\out{   p(d; δ12) = pI p(d;δ1) + (1-pI) p(d;δ1)}}{\deqn{ p(d; \delta_1,\delta_2) = p_I p(d;\delta_1) + (1-p_I) p(d;\delta_2)}} +#' \ifelse{html}{\out{ p(d; δ12) = pI p(d;δ1) + (1-pI) p(d;δ1)}}{\deqn{ p(d; \delta_1,\delta_2) = p_I p(d;\delta_1) + (1-p_I) p(d;\delta_2)}} #' #' For both types of kernel, inter-individual variability of the kernel traits is possible (set \code{IndVar=TRUE}). Individuals will #' carry either one trait for \eqn{\delta} or three traits for \ifelse{html}{\out{δ1}}{\eqn{\delta_1}}, \ifelse{html}{\out{δ2}}{\eqn{\delta_2}} and @@ -546,18 +546,18 @@ setMethod("show", "TransferParams", function(object){ #' F \tab T \tab F \tab F \tab \ifelse{html}{\out{δ1, δ2, pI}}{\eqn{\delta_1, \delta_2, p_I}} \cr #' T \tab F \tab F \tab F \tab mean\eqn{(\delta)}, sd\eqn{(\delta)} \cr #' T \tab T \tab F \tab F \tab \ifelse{html}{\out{mean(δ1)}}{mean\eqn{(\delta_1)}}, \ifelse{html}{\out{sd(δ1)}}{sd\eqn{(\delta_1)}}, \ifelse{html}{\out{mean(δ2)}}{mean\eqn{(\delta_2)}}, \ifelse{html}{\out{sd(δ2)}}{sd\eqn{(\delta_2)}}, mean\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}}, sd\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}} \cr -#' \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \cr +#' \out{:} \tab \out{:} \tab \out{:} \tab \out{:} \tab \out{:} \cr #' T \tab T \tab F \tab T \tab sex, \ifelse{html}{\out{mean(δ1)}}{mean\eqn{(\delta_1)}}, \ifelse{html}{\out{sd(δ1)}}{sd\eqn{(\delta_1)}}, \ifelse{html}{\out{mean(δ2)}}{mean\eqn{(\delta_2)}}, \ifelse{html}{\out{sd(δ2)}}{sd\eqn{(\delta_2)}}, mean\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}}, sd\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}} #' } #' #' The column headings need not be included, only the numeric matrix is required. The rows require no particular order, but there must be exactly #' one row for each stage/sex combination. For example, in the case of a mixed kernel with stage- and sex-dependent distances and no individual variability: -#' \tabular{ccccc}{ \out{ } 0 \tab \out{ } 0 \tab \out{ } 1000 \tab \out{ } 4500 \tab \out{ } 0.92 \cr -#' \out{ } 0 \tab \out{ } 1 \tab \out{ } 1400 \tab \out{ } 6000 \tab \out{ } 0.95 \cr -#' \out{ } 1 \tab \out{ } 0 \tab \out{ } 700 \tab \out{ } 500 \tab \out{ } 0.50 \cr -#' \out{ } 1 \tab \out{ } 1 \tab \out{ } 500 \tab \out{ } 600 \tab \out{ } 0.55 \cr -#' \out{ } 2 \tab \out{ } 0 \tab \out{ } 100 \tab \out{ } 0 \tab \out{ } 1.0 \cr -#' \out{ } 2 \tab \out{ } 1 \tab \out{ } 100 \tab \out{ } 0 \tab \out{ } 1.0 +#' \tabular{ccccc}{ \out{} 0 \tab \out{} 0 \tab \out{} 1000 \tab \out{} 4500 \tab \out{} 0.92 \cr +#' \out{} 0 \tab \out{} 1 \tab \out{} 1400 \tab \out{} 6000 \tab \out{} 0.95 \cr +#' \out{} 1 \tab \out{} 0 \tab \out{} 700 \tab \out{} 500 \tab \out{} 0.50 \cr +#' \out{} 1 \tab \out{} 1 \tab \out{} 500 \tab \out{} 600 \tab \out{} 0.55 \cr +#' \out{} 2 \tab \out{} 0 \tab \out{} 100 \tab \out{} 0 \tab \out{} 1.0 \cr +#' \out{} 2 \tab \out{} 1 \tab \out{} 100 \tab \out{} 0 \tab \out{} 1.0 #' } #' #' In the case that the dispersal kernel is applied to the entire @@ -573,7 +573,7 @@ setMethod("show", "TransferParams", function(object){ #' A second source of dispersal mortality can be specified via the option \code{DistMort}: The probability of mortality is either a constant #' (\eqn{m=}\code{MortProb}) or a function of distance \eqn{d} (i.e. individuals that travel further are more likely to die): #' -#' \ifelse{html}{\out{   m(d) = 1 / ( 1 + e-a (d- b) ) } }{\deqn{ m(d) = 1 / ( 1 + exp[-\alpha (d-b) ] ) } } +#' \ifelse{html}{\out{ m(d) = 1 / ( 1 + e-a (d- b) ) } }{\deqn{ m(d) = 1 / ( 1 + exp[-\alpha (d-b) ] ) } } #' #' with the inflection point \eqn{b=}\code{InflPoint} at which \eqn{m(d=b)=0.5} and the slope \eqn{a=}\code{Slope}.This option may be thought #' to represent the increased energetic, time or attritional costs that longer-distance dispersers will experience \insertCite{bonte2012costs}{RangeShiftR}. @@ -1679,7 +1679,7 @@ setMethod("show", "CorrRW", function(object){ #' \eqn{2} = randomly choose a suitable neighbouring cell or die,\cr #' \eqn{3} = randomly choose a suitable neighbouring cell or wait (stage-structured models only).\cr #' -#' Simple example for sex-dependence only: Females choose a neighbouring cell or wait, males wait: \tabular{cc}{\out{ } 0 \tab \out{ } 3 \cr \out{ } 1 \tab \out{ } 0 } +#' Simple example for sex-dependence only: Females choose a neighbouring cell or wait, males wait: \tabular{cc}{\out{} 0 \tab \out{} 3 \cr \out{} 1 \tab \out{} 0 } #' #' \emph{Settlement with movement processes}\cr #' If individuals are dispersing by one of the two movement processes implemented (\code{\link[RangeShiftR]{SMS}} or @@ -1692,11 +1692,11 @@ setMethod("show", "CorrRW", function(object){ #' Furthermore, the settlement decision can be density-dependent (set \code{DensDep=TRUE}). In this case, the individual has a probability \ifelse{html}{\out{pS}}{\eqn{p_S}} #' of settling in the cell or patch \eqn{i}, given by: #' -#' \ifelse{html}{\out{   pS(i,t) = S0 / ( 1 + eS (N(i,t) / K(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-\alpha_S (N(i,t)/K(i,t) - \beta_S) ] ) } } +#' \ifelse{html}{\out{ pS(i,t) = S0 / ( 1 + eS (N(i,t) / K(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-\alpha_S (N(i,t)/K(i,t) - \beta_S) ] ) } } #' #' In the case of stage-structured models the above equation is modified to: #' -#' \ifelse{html}{\out{   pS(i,t) = S0 / ( 1 + eS (b(i,t) * N(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-\alpha_S (b(i,t) N(i,t) - \beta_S) ] ) } } +#' \ifelse{html}{\out{ pS(i,t) = S0 / ( 1 + eS (b(i,t) * N(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-\alpha_S (b(i,t) N(i,t) - \beta_S) ] ) } } #' #' In the first case, \eqn{K(i,t)} is the carrying capacity of the cell/patch \eqn{i} at time \eqn{t} given by \code{K_or_DensDep}. #' In the latter case, \eqn{b(i,t)} represents the strength of density dependence that is given by the inverse of \code{K_or_DensDep}.\cr @@ -1730,7 +1730,7 @@ setMethod("show", "CorrRW", function(object){ #' F \tab F \tab F \tab T \tab sex \cr #' F \tab F \tab T \tab T \tab stage, sex \cr #' T \tab F \tab F \tab F \tab \ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{\alpha_S}}, \ifelse{html}{\out{βS}}{\eqn{\beta_S}} \cr -#' \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \cr +#' \out{:} \tab \out{:} \tab \out{:} \tab \out{:} \tab \out{:} \cr #' T \tab F \tab T \tab T \tab stage, sex, \ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{\alpha_S}}, \ifelse{html}{\out{βS}}{\eqn{\beta_S}} \cr #' T \tab T \tab F \tab F \tab mean\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, sd\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, mean\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, sd\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, mean\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})}, sd\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})} \cr #' T \tab T \tab F \tab T \tab sex, mean\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, sd\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, mean\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, sd\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, mean\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})}, sd\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})} @@ -1738,12 +1738,12 @@ setMethod("show", "CorrRW", function(object){ #' #' The column headings need not be included, only the numeric matrix is required. The rows require no particular order, but there must be exactly one row for each stage/sex combination. #' For example, in the case of density-, stage- and sex-dependent settlement with no individual variability: -#' \tabular{ccccc}{ \out{ } 0 \tab \out{ } 0 \tab \out{ } 1.0 \tab \out{ } 0.2 \tab \out{ } 4.0 \cr -#' \out{ } 0 \tab \out{ } 1 \tab \out{ } 1.0 \tab \out{ } 0.1 \tab \out{ } 6.0 \cr -#' \out{ } 1 \tab \out{ } 0 \tab \out{ } 0.7 \tab \out{ } 0.5 \tab \out{ } 2.0 \cr -#' \out{ } 1 \tab \out{ } 1 \tab \out{ } 0.5 \tab \out{ } 0.5 \tab \out{ } 2.0 \cr -#' \out{ } 2 \tab \out{ } 0 \tab \out{ } 0.05 \tab \out{ } 1.0 \tab \out{ } 1.0 \cr -#' \out{ } 2 \tab \out{ } 1 \tab \out{ } 0.05 \tab \out{ } 1.0 \tab \out{ } 1.0 +#' \tabular{ccccc}{ \out{} 0 \tab \out{} 0 \tab \out{} 1.0 \tab \out{} 0.2 \tab \out{} 4.0 \cr +#' \out{} 0 \tab \out{} 1 \tab \out{} 1.0 \tab \out{} 0.1 \tab \out{} 6.0 \cr +#' \out{} 1 \tab \out{} 0 \tab \out{} 0.7 \tab \out{} 0.5 \tab \out{} 2.0 \cr +#' \out{} 1 \tab \out{} 1 \tab \out{} 0.5 \tab \out{} 0.5 \tab \out{} 2.0 \cr +#' \out{} 2 \tab \out{} 0 \tab \out{} 0.05 \tab \out{} 1.0 \tab \out{} 1.0 \cr +#' \out{} 2 \tab \out{} 1 \tab \out{} 0.05 \tab \out{} 1.0 \tab \out{} 1.0 #' } #' #' To avoid having individuals moving perpetually because they cannot find suitable conditions to settle, the model requires a maximum number diff --git a/RangeShiftR/R/class_SimulationParams.R b/RangeShiftR/R/class_SimulationParams.R index 5614eb2..8cf9a60 100644 --- a/RangeShiftR/R/class_SimulationParams.R +++ b/RangeShiftR/R/class_SimulationParams.R @@ -187,7 +187,7 @@ #' All the output files will be named with a standard name reporting the simulation ID number and #' the type of output. The file name will start with the batch number, and also indicate the number #' of the landscape to which the output refers. Additionally, for each simulation all the set parameters -#' will be automatically written to a text file named \"Sim0_Parameters.txt\" in the case of simulation\eqn{#=0}. +#' will be automatically written to a text file named \"Sim0_Parameters.txt\" in the case of simulation\eqn{=0}. #' #' - \emph{Species range} (\code{Sim0_Range.txt}) \cr #' contains the following general information regarding the species’ range:\cr diff --git a/RangeShiftR/man/Demography.Rd b/RangeShiftR/man/Demography.Rd index dcd69d7..c460c55 100644 --- a/RangeShiftR/man/Demography.Rd +++ b/RangeShiftR/man/Demography.Rd @@ -45,7 +45,7 @@ and for species for which it is considered crucial to model both sexes explicitl \emph{Asexual / only-female models:} (\code{ReproductionType=0})\cr Recruitment is determined by a stochastic, individual-based formulation of the \insertCite{smith1973;textual}{RangeShiftR} population model, where the number of offspring produced by a single individual in the cell/patch \eqn{i} at time \eqn{t}, is drawn from the following distribution:\cr -\ifelse{html}{\out{  Njuv(i,t) = Poisson( R(i,t) / (1+|R(i,t) - 1| * (N(i,t) / K(i,t))bc ) ) } }{\deqn{N_juv(i,t) = Poisson( R(i,t) / (1 + |R(i,t) - 1|*( N(i,t) / K(i,t) )^bc ) ) } } +\ifelse{html}{\out{Njuv(i,t) = Poisson( R(i,t) / (1+|R(i,t) - 1| * (N(i,t) / K(i,t))bc ) ) } }{\deqn{N_juv(i,t) = Poisson( R(i,t) / (1 + |R(i,t) - 1|*( N(i,t) / K(i,t) )^bc ) ) } } Here, \eqn{R(i,t)} is the maximum growth rate \code{Rmax} (obtained at very low density only) and \eqn{K(i,t)} is the carrying capacity at patch \eqn{i} and time \eqn{t}. @@ -61,7 +61,7 @@ In this type of models, individuals are explicitly characterized by their sex. T This is the simplest form of mate limitation. Each female individual is assumed to mate, as long as there is at least one male in the population. As for the asexual case, the Maynard Smith and Slatkin model is used to determine the expected number of offspring produced by each female. To maintain equivalence between the asexual and sexual versions, the expected value of the Poisson distribution is multiplied by \eqn{2} (Lindström & Kokko 1998):\cr -\ifelse{html}{\out{  Njuv(i,t) = Poisson( 2 R(i,t) / (1+|R(i,t) - 1| * (N(i,t) / K(i,t) )bc ) ) } }{\deqn{N_juv(i,t) = Poisson( 2 R(i,t) / (1 + |R(i,t) - 1|*( N(i,t) / K(i,t) )^bc ) ) } } +\ifelse{html}{\out{Njuv(i,t) = Poisson( 2 R(i,t) / (1+|R(i,t) - 1| * (N(i,t) / K(i,t) )bc ) ) } }{\deqn{N_juv(i,t) = Poisson( 2 R(i,t) / (1 + |R(i,t) - 1|*( N(i,t) / K(i,t) )^bc ) ) } } \emph{Complex mating system:} (\code{ReproductionType=2})\cr More complex and flexible mating system. Mating is explicitly modelled through a mating function diff --git a/RangeShiftR/man/DispersalKernel.Rd b/RangeShiftR/man/DispersalKernel.Rd index 6dfca89..5f8ee72 100644 --- a/RangeShiftR/man/DispersalKernel.Rd +++ b/RangeShiftR/man/DispersalKernel.Rd @@ -62,7 +62,7 @@ If the individual disperses, the distance and the movement direction are determi The distance is drawn from a negative exponential distribution with a given mean \eqn{\delta}, and the direction is selected randomly from a uniform distribution between \eqn{0} and \eqn{2\pi} radians. -\ifelse{html}{\out{   p(d;δ) = δ-1 e- d / δ}}{\deqn{ p(d;\delta) = 1/\delta exp(-d/\delta) } } +\ifelse{html}{\out{ p(d;δ) = δ-1 e- d / δ}}{\deqn{ p(d;\delta) = 1/\delta exp(-d/\delta) } } If the arrival point lies beyond the boundary of the landscape, distance and direction are re-drawn.\cr The individual is displaced from a random point (using continuous coordinates) inside the natal cell to the arrival cell where the model @@ -83,7 +83,7 @@ with different means \ifelse{html}{\out{δ1}}{\eqn{\delta_1}} an occurring with probability \ifelse{html}{\out{pI}}{\eqn{p_I}} and \eqn{1-}\ifelse{html}{\out{pI}}{\eqn{p_I}} respectively \insertCite{hovestadt2011all}{RangeShiftR}. Otherwise, the conditions for the single kernel apply. -\ifelse{html}{\out{   p(d; δ12) = pI p(d;δ1) + (1-pI) p(d;δ1)}}{\deqn{ p(d; \delta_1,\delta_2) = p_I p(d;\delta_1) + (1-p_I) p(d;\delta_2)}} +\ifelse{html}{\out{ p(d; δ12) = pI p(d;δ1) + (1-pI) p(d;δ1)}}{\deqn{ p(d; \delta_1,\delta_2) = p_I p(d;\delta_1) + (1-p_I) p(d;\delta_2)}} For both types of kernel, inter-individual variability of the kernel traits is possible (set \code{IndVar=TRUE}). Individuals will carry either one trait for \eqn{\delta} or three traits for \ifelse{html}{\out{δ1}}{\eqn{\delta_1}}, \ifelse{html}{\out{δ2}}{\eqn{\delta_2}} and @@ -114,18 +114,18 @@ table lists the required columns and their correct order for different settings: F \tab T \tab F \tab F \tab \ifelse{html}{\out{δ1, δ2, pI}}{\eqn{\delta_1, \delta_2, p_I}} \cr T \tab F \tab F \tab F \tab mean\eqn{(\delta)}, sd\eqn{(\delta)} \cr T \tab T \tab F \tab F \tab \ifelse{html}{\out{mean(δ1)}}{mean\eqn{(\delta_1)}}, \ifelse{html}{\out{sd(δ1)}}{sd\eqn{(\delta_1)}}, \ifelse{html}{\out{mean(δ2)}}{mean\eqn{(\delta_2)}}, \ifelse{html}{\out{sd(δ2)}}{sd\eqn{(\delta_2)}}, mean\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}}, sd\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}} \cr - \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \cr + \out{:} \tab \out{:} \tab \out{:} \tab \out{:} \tab \out{:} \cr T \tab T \tab F \tab T \tab sex, \ifelse{html}{\out{mean(δ1)}}{mean\eqn{(\delta_1)}}, \ifelse{html}{\out{sd(δ1)}}{sd\eqn{(\delta_1)}}, \ifelse{html}{\out{mean(δ2)}}{mean\eqn{(\delta_2)}}, \ifelse{html}{\out{sd(δ2)}}{sd\eqn{(\delta_2)}}, mean\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}}, sd\ifelse{html}{\out{(pI)}}{\eqn{(p_I)}} } The column headings need not be included, only the numeric matrix is required. The rows require no particular order, but there must be exactly one row for each stage/sex combination. For example, in the case of a mixed kernel with stage- and sex-dependent distances and no individual variability: -\tabular{ccccc}{ \out{ } 0 \tab \out{ } 0 \tab \out{ } 1000 \tab \out{ } 4500 \tab \out{ } 0.92 \cr - \out{ } 0 \tab \out{ } 1 \tab \out{ } 1400 \tab \out{ } 6000 \tab \out{ } 0.95 \cr - \out{ } 1 \tab \out{ } 0 \tab \out{ } 700 \tab \out{ } 500 \tab \out{ } 0.50 \cr - \out{ } 1 \tab \out{ } 1 \tab \out{ } 500 \tab \out{ } 600 \tab \out{ } 0.55 \cr - \out{ } 2 \tab \out{ } 0 \tab \out{ } 100 \tab \out{ } 0 \tab \out{ } 1.0 \cr - \out{ } 2 \tab \out{ } 1 \tab \out{ } 100 \tab \out{ } 0 \tab \out{ } 1.0 +\tabular{ccccc}{ \out{} 0 \tab \out{} 0 \tab \out{} 1000 \tab \out{} 4500 \tab \out{} 0.92 \cr + \out{} 0 \tab \out{} 1 \tab \out{} 1400 \tab \out{} 6000 \tab \out{} 0.95 \cr + \out{} 1 \tab \out{} 0 \tab \out{} 700 \tab \out{} 500 \tab \out{} 0.50 \cr + \out{} 1 \tab \out{} 1 \tab \out{} 500 \tab \out{} 600 \tab \out{} 0.55 \cr + \out{} 2 \tab \out{} 0 \tab \out{} 100 \tab \out{} 0 \tab \out{} 1.0 \cr + \out{} 2 \tab \out{} 1 \tab \out{} 100 \tab \out{} 0 \tab \out{} 1.0 } In the case that the dispersal kernel is applied to the entire @@ -141,7 +141,7 @@ proportion of suitable habitat in the landscape and will increase as the availab A second source of dispersal mortality can be specified via the option \code{DistMort}: The probability of mortality is either a constant (\eqn{m=}\code{MortProb}) or a function of distance \eqn{d} (i.e. individuals that travel further are more likely to die): -\ifelse{html}{\out{   m(d) = 1 / ( 1 + e-a (d- b) ) } }{\deqn{ m(d) = 1 / ( 1 + exp[-\alpha (d-b) ] ) } } +\ifelse{html}{\out{ m(d) = 1 / ( 1 + e-a (d- b) ) } }{\deqn{ m(d) = 1 / ( 1 + exp[-\alpha (d-b) ] ) } } with the inflection point \eqn{b=}\code{InflPoint} at which \eqn{m(d=b)=0.5} and the slope \eqn{a=}\code{Slope}.This option may be thought to represent the increased energetic, time or attritional costs that longer-distance dispersers will experience \insertCite{bonte2012costs}{RangeShiftR}. diff --git a/RangeShiftR/man/Emigration.Rd b/RangeShiftR/man/Emigration.Rd index 7d97783..7eed664 100644 --- a/RangeShiftR/man/Emigration.Rd +++ b/RangeShiftR/man/Emigration.Rd @@ -48,11 +48,11 @@ rate can be larger than \eqn{d}, if a stage with \eqn{d>0} lasts for more than o The emigration probability \eqn{d} can be density-dependent (set \code{DensDep=TRUE}), in which case it is given by the following function, introduced by \insertCite{kun2006evolution;textual}{RangeShiftR}: -\ifelse{html}{\out{   d(i,t) = D0 / ( 1 + e-αsub>E (N(i,t) / K(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-\alpha_E (N(i,t)/K(i,t) - \beta_E) ] ) } } +\ifelse{html}{\out{ d(i,t) = D0 / ( 1 + e-αsub>E (N(i,t) / K(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-\alpha_E (N(i,t)/K(i,t) - \beta_E) ] ) } } In the case of stage-structured models this equation is modified to: -\ifelse{html}{\out{   d(i,t) = D0 / ( 1 + e-αsub>E (b(i,t) * N(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-\alpha_E (b(i,t) N(i,t) - \beta_E) ] ) } } +\ifelse{html}{\out{ d(i,t) = D0 / ( 1 + e-αsub>E (b(i,t) * N(i,t) - βsub>E) ) } }{\deqn{ d(i,t) = D_0 / ( 1 + exp[-\alpha_E (b(i,t) N(i,t) - \beta_E) ] ) } } In the first case, \eqn{K(i,t)} is the carrying capacity of the cell/patch \eqn{i} at time \eqn{t} given by \code{K_or_DensDep}. In the latter case, \eqn{b(i,t)} represents the strength of density dependence and is given by the inverse of \code{K_or_DensDep}.\cr @@ -96,17 +96,17 @@ If \code{SexDep=TRUE}, state the corresponding stage in the next (i.e. first/sec T \tab F \tab F \tab F \tab \ifelse{html}{\out{D0}}{\eqn{D_0}}, \eqn{\alpha}, \eqn{\beta} \cr F \tab T \tab F \tab F \tab mean\eqn{(d)}, sd\eqn{(d)} \cr T \tab T \tab F \tab F \tab \ifelse{html}{\out{mean(D0)}}{mean\eqn{(D_0)}}, \ifelse{html}{\out{sd(D0)}}{sd\eqn{(D_0)}}, mean\eqn{(\alpha)}, sd\eqn{(\alpha)}, mean\eqn{(\beta)}, sd\eqn{(\beta)} \cr - \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \cr + \out{:} \tab \out{:} \tab \out{:} \tab \out{:} \tab \out{:} \cr T \tab T \tab F \tab T \tab sex, \ifelse{html}{\out{mean(D0)}}{mean\eqn{(D_0)}}, \ifelse{html}{\out{sd(D0)}}{sd\eqn{(D_0)}}, mean\eqn{(\alpha)}, sd\eqn{(\alpha)}, mean\eqn{(\beta)}, sd\eqn{(\beta)} } The column headings need not be included, only the numeric matrix is required. The rows require no particular order, but there must be exactly one row for each stage/sex combination. For example, in the case of density-, stage- and sex-dependent emigration with no individual variability: -\tabular{ccccc}{ \out{ } 0 \tab \out{ } 0 \tab \out{ } 1.0 \tab \out{ } 20 \tab \out{ } 0.2 \cr - \out{ } 0 \tab \out{ } 1 \tab \out{ } 1.0 \tab \out{ } 20 \tab \out{ } 0.1 \cr - \out{ } 1 \tab \out{ } 0 \tab \out{ } 0.7 \tab \out{ } 25 \tab \out{ } 0.5 \cr - \out{ } 1 \tab \out{ } 1 \tab \out{ } 0.8 \tab \out{ } 50 \tab \out{ } 0.5 \cr - \out{ } 2 \tab \out{ } 0 \tab \out{ } 0.4 \tab \out{ } 10 \tab \out{ } 1.0 \cr - \out{ } 2 \tab \out{ } 1 \tab \out{ } 0.5 \tab \out{ } 20 \tab \out{ } 1.0 +\tabular{ccccc}{ \out{} 0 \tab \out{} 0 \tab \out{} 1.0 \tab \out{} 20 \tab \out{} 0.2 \cr + \out{} 0 \tab \out{} 1 \tab \out{} 1.0 \tab \out{} 20 \tab \out{} 0.1 \cr + \out{} 1 \tab \out{} 0 \tab \out{} 0.7 \tab \out{} 25 \tab \out{} 0.5 \cr + \out{} 1 \tab \out{} 1 \tab \out{} 0.8 \tab \out{} 50 \tab \out{} 0.5 \cr + \out{} 2 \tab \out{} 0 \tab \out{} 0.4 \tab \out{} 10 \tab \out{} 1.0 \cr + \out{} 2 \tab \out{} 1 \tab \out{} 0.5 \tab \out{} 20 \tab \out{} 1.0 } In the special case that \code{DensDep=FALSE} and transfer is realised by \code{\link[RangeShiftR]{DispersalKernel}}, then the option \code{UseFullKern} may be switched on. It diff --git a/RangeShiftR/man/Settlement.Rd b/RangeShiftR/man/Settlement.Rd index 072f597..ff64309 100644 --- a/RangeShiftR/man/Settlement.Rd +++ b/RangeShiftR/man/Settlement.Rd @@ -88,7 +88,7 @@ Settlement condition codes: If the individuals current step ends in unsuitable h \eqn{2} = randomly choose a suitable neighbouring cell or die,\cr \eqn{3} = randomly choose a suitable neighbouring cell or wait (stage-structured models only).\cr -Simple example for sex-dependence only: Females choose a neighbouring cell or wait, males wait: \tabular{cc}{\out{ } 0 \tab \out{ } 3 \cr \out{ } 1 \tab \out{ } 0 } +Simple example for sex-dependence only: Females choose a neighbouring cell or wait, males wait: \tabular{cc}{\out{} 0 \tab \out{} 3 \cr \out{} 1 \tab \out{} 0 } \emph{Settlement with movement processes}\cr If individuals are dispersing by one of the two movement processes implemented (\code{\link[RangeShiftR]{SMS}} or @@ -101,11 +101,11 @@ it gets converted to \eqn{S_0=1.0}, i.e. 'always settle when habitat is suitable Furthermore, the settlement decision can be density-dependent (set \code{DensDep=TRUE}). In this case, the individual has a probability \ifelse{html}{\out{pS}}{\eqn{p_S}} of settling in the cell or patch \eqn{i}, given by: -\ifelse{html}{\out{   pS(i,t) = S0 / ( 1 + eS (N(i,t) / K(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-\alpha_S (N(i,t)/K(i,t) - \beta_S) ] ) } } +\ifelse{html}{\out{ pS(i,t) = S0 / ( 1 + eS (N(i,t) / K(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-\alpha_S (N(i,t)/K(i,t) - \beta_S) ] ) } } In the case of stage-structured models the above equation is modified to: -\ifelse{html}{\out{   pS(i,t) = S0 / ( 1 + eS (b(i,t) * N(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-\alpha_S (b(i,t) N(i,t) - \beta_S) ] ) } } +\ifelse{html}{\out{ pS(i,t) = S0 / ( 1 + eS (b(i,t) * N(i,t) - βS) ) } }{\deqn{ p_S(i,t) = S_0 / ( 1 + exp[-\alpha_S (b(i,t) N(i,t) - \beta_S) ] ) } } In the first case, \eqn{K(i,t)} is the carrying capacity of the cell/patch \eqn{i} at time \eqn{t} given by \code{K_or_DensDep}. In the latter case, \eqn{b(i,t)} represents the strength of density dependence that is given by the inverse of \code{K_or_DensDep}.\cr @@ -138,7 +138,7 @@ The following table lists the required columns and their correct order for diffe F \tab F \tab F \tab T \tab sex \cr F \tab F \tab T \tab T \tab stage, sex \cr T \tab F \tab F \tab F \tab \ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{\alpha_S}}, \ifelse{html}{\out{βS}}{\eqn{\beta_S}} \cr - \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \tab \out{⋮} \cr + \out{:} \tab \out{:} \tab \out{:} \tab \out{:} \tab \out{:} \cr T \tab F \tab T \tab T \tab stage, sex, \ifelse{html}{\out{S0}}{\eqn{S_0}}, \ifelse{html}{\out{αS}}{\eqn{\alpha_S}}, \ifelse{html}{\out{βS}}{\eqn{\beta_S}} \cr T \tab T \tab F \tab F \tab mean\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, sd\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, mean\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, sd\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, mean\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})}, sd\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})} \cr T \tab T \tab F \tab T \tab sex, mean\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, sd\ifelse{html}{\out{(S0)}}{\eqn{(S_0)}}, mean\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, sd\ifelse{html}{\out{(αS)}}{(\eqn{\alpha_S})}, mean\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})}, sd\ifelse{html}{\out{(βS)}}{(\eqn{\beta_S})} @@ -146,12 +146,12 @@ The following table lists the required columns and their correct order for diffe The column headings need not be included, only the numeric matrix is required. The rows require no particular order, but there must be exactly one row for each stage/sex combination. For example, in the case of density-, stage- and sex-dependent settlement with no individual variability: -\tabular{ccccc}{ \out{ } 0 \tab \out{ } 0 \tab \out{ } 1.0 \tab \out{ } 0.2 \tab \out{ } 4.0 \cr - \out{ } 0 \tab \out{ } 1 \tab \out{ } 1.0 \tab \out{ } 0.1 \tab \out{ } 6.0 \cr - \out{ } 1 \tab \out{ } 0 \tab \out{ } 0.7 \tab \out{ } 0.5 \tab \out{ } 2.0 \cr - \out{ } 1 \tab \out{ } 1 \tab \out{ } 0.5 \tab \out{ } 0.5 \tab \out{ } 2.0 \cr - \out{ } 2 \tab \out{ } 0 \tab \out{ } 0.05 \tab \out{ } 1.0 \tab \out{ } 1.0 \cr - \out{ } 2 \tab \out{ } 1 \tab \out{ } 0.05 \tab \out{ } 1.0 \tab \out{ } 1.0 +\tabular{ccccc}{ \out{} 0 \tab \out{} 0 \tab \out{} 1.0 \tab \out{} 0.2 \tab \out{} 4.0 \cr + \out{} 0 \tab \out{} 1 \tab \out{} 1.0 \tab \out{} 0.1 \tab \out{} 6.0 \cr + \out{} 1 \tab \out{} 0 \tab \out{} 0.7 \tab \out{} 0.5 \tab \out{} 2.0 \cr + \out{} 1 \tab \out{} 1 \tab \out{} 0.5 \tab \out{} 0.5 \tab \out{} 2.0 \cr + \out{} 2 \tab \out{} 0 \tab \out{} 0.05 \tab \out{} 1.0 \tab \out{} 1.0 \cr + \out{} 2 \tab \out{} 1 \tab \out{} 0.05 \tab \out{} 1.0 \tab \out{} 1.0 } To avoid having individuals moving perpetually because they cannot find suitable conditions to settle, the model requires a maximum number diff --git a/RangeShiftR/man/Simulation.Rd b/RangeShiftR/man/Simulation.Rd index 5dcbb36..5c127e2 100644 --- a/RangeShiftR/man/Simulation.Rd +++ b/RangeShiftR/man/Simulation.Rd @@ -184,7 +184,7 @@ Seven different types of outputs can be produced, plus one more for patch-based All the output files will be named with a standard name reporting the simulation ID number and the type of output. The file name will start with the batch number, and also indicate the number of the landscape to which the output refers. Additionally, for each simulation all the set parameters -will be automatically written to a text file named \"Sim0_Parameters.txt\" in the case of simulation\eqn{#=0}. +will be automatically written to a text file named \"Sim0_Parameters.txt\" in the case of simulation\eqn{=0}. - \emph{Species range} (\code{Sim0_Range.txt}) \cr contains the following general information regarding the species’ range:\cr diff --git a/RangeShiftR/man/StageStructure.Rd b/RangeShiftR/man/StageStructure.Rd index 2ea332a..598e553 100644 --- a/RangeShiftR/man/StageStructure.Rd +++ b/RangeShiftR/man/StageStructure.Rd @@ -81,7 +81,7 @@ An example transition matrix for a 3-staged explicit sexual population model \in A common mistake in building a transition matrix is made when offspring produced at year \eqn{t} develop to the next stage in the same year \insertCite{@ @caswell2001 pg. 60-62}{RangeShiftR}. To avoid this problem without losing the offspring stage, and hence the chance for simulating post-natal dispersal, we require an additional explicit juvenile stage (stage 0). Juveniles have to develop to stage 1 in the same year they are born. Hence the minimum number of stages of a stage-structured model is always \eqn{2}. It is important to note that juvenile mortality can be accounted for in two ways. Either, as in the examples above, it is included in adult fecundity \ifelse{html}{\out{φ}}{\eqn{\phi}} (by appropriately reducing its value), and \ifelse{html}{\out{σ0 γ(0-1)}}{\eqn{\sigma_0 \gamma_(0-1)}} is equal to \eqn{1.0}. This is how it is typically accounted for in matrix models. Or, alternatively, -\phi is equal to the true maximum fecundity and \ifelse{html}{\out{σ0 γ(0-1)}}{\eqn{\sigma_0 \gamma_(0-1)}} is less than \eqn{1.0}. +\eqn{\phi} is equal to the true maximum fecundity and \ifelse{html}{\out{σ0 γ(0-1)}}{\eqn{\sigma_0 \gamma_(0-1)}} is less than \eqn{1.0}. Only the first approach allows straightforward direct comparison with standard analytical matrix models. \emph{Minimum ages:} For every row in the transition matrix, a minimum age must be provided through a vector in argument \code{MinAge}. It specifies the age which an individual in stage \eqn{i-1} (with sex \eqn{m/f}, if applicable) must already have reached before it can develop into the next stage \eqn{(i)}. The vector must be in @@ -114,11 +114,11 @@ If the transition matrix contains the annual survival and development rates, \co \emph{Density dependence} can act on each of the three demographic phases (i.e. reproduction, survival and development) and is controlled by \code{FecDensDep,DevDensDep,SurvDensDep}. It is implemented as an exponential decay \insertCite{neubert2000}{RangeShiftR}: -\ifelse{html}{\out{   φi(r,t) = φ0,i * e - b(r) N(t) }}{\deqn{\phi_i(r,t)=\phi_(0,i) * exp(- b(r) N(t) ) }} +\ifelse{html}{\out{ φi(r,t) = φ0,i * e - b(r) N(t) }}{\deqn{\phi_i(r,t)=\phi_(0,i) * exp(- b(r) N(t) ) }} -\ifelse{html}{\out{   σi(r,t) = σ0,i * e - Cσ b(r) N(t) }}{\deqn{\sigma_i(r,t)=\sigma_(0,i) * exp(- C_\sigma b(r) N(t) ) }} +\ifelse{html}{\out{ σi(r,t) = σ0,i * e - Cσ b(r) N(t) }}{\deqn{\sigma_i(r,t)=\sigma_(0,i) * exp(- C_\sigma b(r) N(t) ) }} -\ifelse{html}{\out{   γi(r,t) = γ0,i * e - Cγ b(r) N(t) }}{\deqn{\gamma_i(r,t)=\gamma_(0,i) * exp(- C_\gamma b(r) N(t) ) }} +\ifelse{html}{\out{ γi(r,t) = γ0,i * e - Cγ b(r) N(t) }}{\deqn{\gamma_i(r,t)=\gamma_(0,i) * exp(- C_\gamma b(r) N(t) ) }} where \eqn{b(r)} is the strength of density dependence in fecundity at site \eqn{r}, which is given by the argument \code{K_or_DensDep} in the landscape module. Furthermore, \ifelse{html}{\out{Cσ}}{\eqn{C_\sigma}} and \ifelse{html}{\out{Cγ}}{\eqn{C_\gamma}} (\code{DevDensCoeff,SurvDensCoeff}) @@ -127,11 +127,11 @@ scale the strength of density dependence in survival and development relative to Moreover, the strength of density-dependence can be uniform for all stages or stage-dependent. Even greater complexity can be incorporated with different stages contributing differently to density-dependence \insertCite{caswell2004}{RangeShiftR}: -\ifelse{html}{\out{  φi(r,t) = φ0,i * e - b(r) ΣjS ωφ,ij N(j,t)}}{\deqn{\phi_i(r,t)=\phi_(0,i) * exp(- b(r) \Sigma_j^S \omega_{\phi,ij} N_j(t) ) }} +\ifelse{html}{\out{ φi(r,t) = φ0,i * e - b(r) ΣjS ωφ,ij N(j,t)}}{\deqn{\phi_i(r,t)=\phi_(0,i) * exp(- b(r) \Sigma_j^S \omega_{\phi,ij} N_j(t) ) }} -\ifelse{html}{\out{  σi(r,t) = σ0,i * e - Cσ b(r) ΣjS ωσ,ij N(j,t) }}{\deqn{\sigma_i(r,t)=\sigma_(0,i) * exp(- C_\sigma b(r) \Sigma_j^S \omega_{\sigma,ij} N_j(t) )}} +\ifelse{html}{\out{ σi(r,t) = σ0,i * e - Cσ b(r) ΣjS ωσ,ij N(j,t) }}{\deqn{\sigma_i(r,t)=\sigma_(0,i) * exp(- C_\sigma b(r) \Sigma_j^S \omega_{\sigma,ij} N_j(t) )}} -\ifelse{html}{\out{  γi(r,t) = γ0,i * e - Cγ b(r) ΣjS ωγ,ij N(j,t)}}{\deqn{\gamma_i(r,t)=\gamma_(0,i) * exp(- C_\gamma b(r) \Sigma_j^S \omega_{\gamma,ij} N_j(t) )}} +\ifelse{html}{\out{ γi(r,t) = γ0,i * e - Cγ b(r) ΣjS ωγ,ij N(j,t)}}{\deqn{\gamma_i(r,t)=\gamma_(0,i) * exp(- C_\gamma b(r) \Sigma_j^S \omega_{\gamma,ij} N_j(t) )}} where \ifelse{html}{\out{ωφ}}{\eqn{\omega_\phi}}, \ifelse{html}{\out{ωσ}}{\eqn{\omega_\sigma}}, \ifelse{html}{\out{ωγ}}{\eqn{\omega_\gamma}} are weight matrices given by \code{FecStageWtsMatrix, DevStageWtsMatrix, SurvStageWtsMatrix}. Their elements \ifelse{html}{\out{ωij}}{\eqn{\omega_ij}} represent the contributions of the abundance of stage \eqn{j} to the density dependence in the fecundity / survival / development of stage \eqn{i}, thus they are quadratic matrices of size \code{Stages}\eqn{^2}. Note that the row sums are not required to be normalized, therefore they can be used From ce9ba1cc918608853a2a3fb5cb96f763b35a218f Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Fri, 24 Nov 2023 15:14:15 +0000 Subject: [PATCH 14/17] fix dependencies in doc --- RangeShiftR/DESCRIPTION | 2 + RangeShiftR/NAMESPACE | 1 + RangeShiftR/R/RSsim.R | 2 +- RangeShiftR/R/RangeShiftR.R | 2 +- RangeShiftR/R/Rfunctions.R | 8 +- RangeShiftR/R/RunRS.R | 2 +- RangeShiftR/R/addition.R | 26 ++--- RangeShiftR/R/class_ControlParams.R | 2 +- RangeShiftR/R/class_DemogParams.R | 30 ++--- RangeShiftR/R/class_DispersalParams.R | 122 ++++++++++----------- RangeShiftR/R/class_GeneticsParams.R | 4 +- RangeShiftR/R/class_InitialisationParams.R | 4 +- RangeShiftR/R/class_LandParams.R | 21 ++-- RangeShiftR/R/class_RSparams.R | 52 ++++----- RangeShiftR/R/class_SimulationParams.R | 6 +- RangeShiftR/R/output_handling.R | 50 ++++----- 16 files changed, 169 insertions(+), 165 deletions(-) diff --git a/RangeShiftR/DESCRIPTION b/RangeShiftR/DESCRIPTION index 8f93e06..ba007f0 100644 --- a/RangeShiftR/DESCRIPTION +++ b/RangeShiftR/DESCRIPTION @@ -19,6 +19,8 @@ Imports: Rcpp (>= 1.0.0), Rdpack (>= 0.7), methods, + raster +Suggests: rmarkdown, terra RdMacros: Rdpack diff --git a/RangeShiftR/NAMESPACE b/RangeShiftR/NAMESPACE index e294623..87853d6 100644 --- a/RangeShiftR/NAMESPACE +++ b/RangeShiftR/NAMESPACE @@ -28,4 +28,5 @@ export(readRange) export(validateRSparams) importFrom(Rcpp,sourceCpp) importFrom(Rdpack,reprompt) +importFrom(methods,new) useDynLib(RangeShiftR) diff --git a/RangeShiftR/R/RSsim.R b/RangeShiftR/R/RSsim.R index aa459fb..f38df8d 100644 --- a/RangeShiftR/R/RSsim.R +++ b/RangeShiftR/R/RSsim.R @@ -130,6 +130,6 @@ RSsim <- function(batchnum = 1L, if (!is.null(args$gene)) s <- s + gene if (!is.null(args$init)) s <- s + init # check validity - if(validObject(s)) return(s) + if(methods::validObject(s)) return(s) else return(NULL) } diff --git a/RangeShiftR/R/RangeShiftR.R b/RangeShiftR/R/RangeShiftR.R index 9423a1c..a919319 100644 --- a/RangeShiftR/R/RangeShiftR.R +++ b/RangeShiftR/R/RangeShiftR.R @@ -92,5 +92,5 @@ RangeShiftR_license <- function () #' @export RangeShiftR_citation <- function () { - citation(package = "RangeShiftR", lib.loc = NULL, auto = NULL) + utils::citation(package = "RangeShiftR", lib.loc = NULL, auto = NULL) } diff --git a/RangeShiftR/R/Rfunctions.R b/RangeShiftR/R/Rfunctions.R index e8d3e73..c28618c 100644 --- a/RangeShiftR/R/Rfunctions.R +++ b/RangeShiftR/R/Rfunctions.R @@ -32,13 +32,13 @@ #---------------------- #for Integer and Numerical so that 'Integer'-slots can also accept 'Numerical' input -setClassUnion("integer_OR_numeric", c("integer", "numeric")) +methods::setClassUnion("integer_OR_numeric", c("integer", "numeric")) #for Matrix and Numerical so that 'Matrix'-slots can also accept 'Numerical' input when 1x1-Matrix is expected -setClassUnion("matrix_OR_numeric", c("matrix", "numeric")) +methods::setClassUnion("matrix_OR_numeric", c("matrix", "numeric")) #for cost layer to accept habitat codes or raster map file -setClassUnion("numeric_OR_character", c("numeric", "character")) +methods::setClassUnion("numeric_OR_character", c("numeric", "character")) #-- define error and warning messages @@ -59,4 +59,4 @@ densdep <- function(x, A0 = 1.0, alpha = 1.0, beta = 0.0) { #' Validate a given RS parameter object #' #' @export -validateRSparams <- function(x){validObject(x)} +validateRSparams <- function(x){methods::validObject(x)} diff --git a/RangeShiftR/R/RunRS.R b/RangeShiftR/R/RunRS.R index e8f031d..6a469d6 100644 --- a/RangeShiftR/R/RunRS.R +++ b/RangeShiftR/R/RunRS.R @@ -43,7 +43,7 @@ RunRS <- function(RSparams, dirpath = getwd()){ stop("Parameter object must be of class RSparams") } else { - validObject(RSparams) + methods::validObject(RSparams) } } if (is.null(dirpath)) { diff --git a/RangeShiftR/R/addition.R b/RangeShiftR/R/addition.R index 84678de..bbf3729 100644 --- a/RangeShiftR/R/addition.R +++ b/RangeShiftR/R/addition.R @@ -31,13 +31,13 @@ setGeneric("+") setMethod("+", signature(e1 = "RSparams", e2 = "SimulationParams"), function(e1, e2) { - validObject(e2) + methods::validObject(e2) e1@simul <- e2 return(e1)} ) setMethod("+", signature(e1 = "RSparams", e2 = "LandParams"), function(e1, e2) { - validObject(e2) + methods::validObject(e2) if (class(e2)[1] == "ImportedLandscape") { if (any(e2@PatchFile=="NULL")) { e1@control@patchmodel = FALSE @@ -76,7 +76,7 @@ setMethod("+", signature(e1 = "RSparams", e2 = "LandParams"), function(e1, e2) { ) setMethod("+", signature(e1 = "RSparams", e2 = "DemogParams"), function(e1, e2) { - validObject(e2) + methods::validObject(e2) e1@control@reproductn = e2@ReproductionType if (class(e2@StageStruct)[1] == "StagesParams") { e1@control@repseasons = e2@StageStruct@RepSeasons @@ -101,7 +101,7 @@ setMethod("+", signature(e1 = "RSparams", e2 = "DemogParams"), function(e1, e2) ) setMethod("+", signature(e1 = "DemogParams", e2 = "StagesParams"), function(e1, e2) { - validObject(e2) + methods::validObject(e2) e1@StageStruct <- e2 e1@Rmax <- -9L e1@bc <- -9L @@ -109,7 +109,7 @@ setMethod("+", signature(e1 = "DemogParams", e2 = "StagesParams"), function(e1, ) setMethod("+", signature(e1 = "RSparams", e2 = "DispersalParams"), function(e1, e2) { - validObject(e2) + methods::validObject(e2) if (class(e2@Transfer)[1] == "DispersalKernel") { e1@control@transfer = 0 } @@ -131,34 +131,34 @@ setMethod("+", signature(e1 = "RSparams", e2 = "DispersalParams"), function(e1, ) setMethod("+", signature(e1 = "DispersalParams", e2 = "EmigrationParams"), function(e1, e2) { - validObject(e2) + methods::validObject(e2) e1@Emigration <- e2 - validObject(e1) + methods::validObject(e1) return(e1)} ) setMethod("+", signature(e1 = "DispersalParams", e2 = "TransferParams"), function(e1, e2) { - validObject(e2) + methods::validObject(e2) e1@Transfer <- e2 - validObject(e1) + methods::validObject(e1) return(e1)} ) setMethod("+", signature(e1 = "DispersalParams", e2 = "SettlementParams"), function(e1, e2) { - validObject(e2) + methods::validObject(e2) e1@Settlement <- e2 - validObject(e1) + methods::validObject(e1) return(e1)} ) setMethod("+", signature(e1 = "RSparams", e2 = "GeneticsParams"), function(e1, e2) { - validObject(e2) + methods::validObject(e2) e1@gene <- e2 return(e1)} ) setMethod("+", signature(e1 = "RSparams", e2 = "InitialisationParams"), function(e1, e2) { - validObject(e2) + methods::validObject(e2) e1@init <- e2 return(e1)} ) diff --git a/RangeShiftR/R/class_ControlParams.R b/RangeShiftR/R/class_ControlParams.R index 423dcc9..9b36145 100644 --- a/RangeShiftR/R/class_ControlParams.R +++ b/RangeShiftR/R/class_ControlParams.R @@ -25,7 +25,7 @@ # from RS 'CONTROL.txt' file -ControlParams <- setClass("ControlParams", slots = c( +ControlParams <- methods::setClass("ControlParams", slots = c( #nSimuls = "integer_OR_numeric", # Not yet used by R version, in C++ version its read from parameterfile #nLandscapes = "integer_OR_numeric", # Not yet used by R version, in C++ version its read from landfile batchnum = "integer_OR_numeric", # only variable to set from RSsim(), optional diff --git a/RangeShiftR/R/class_DemogParams.R b/RangeShiftR/R/class_DemogParams.R index 18c1b2e..2c71aed 100644 --- a/RangeShiftR/R/class_DemogParams.R +++ b/RangeShiftR/R/class_DemogParams.R @@ -159,7 +159,7 @@ #' @author Anne-Kathleen Malchow #' @name StageStructure #' @export StageStructure -StageStructure <- setClass("StagesParams", slots = c(Stages = "integer_OR_numeric", +StageStructure <- methods::setClass("StagesParams", slots = c(Stages = "integer_OR_numeric", TransMatrix = "matrix", MaxAge = "integer_OR_numeric", MinAge = "integer_OR_numeric", @@ -373,9 +373,9 @@ setMethod("initialize", "StagesParams", function(.Object,...) { if (!is.null(args$SurvStageWtsMatrix)) { .Object@SurvStageWts <- TRUE } - .Object <- callNextMethod() + .Object <- methods::callNextMethod() if ( length(args) == 0 ) { - validObject(.Object) + methods::validObject(.Object) } if (!.Object@FecDensDep) { if (.Object@FecStageWts) { @@ -489,12 +489,12 @@ setMethod("plotProbs", "StagesParams", function(x, stage = NULL, sex = NULL, xma this.sex = 0 } if (this.stage %in% stage && this.sex %in% sex) { - if(x@FecDensDep){ lines(xvals, fecs[line]*exp(-xvals), type = "l", lty = 1, col = line) } - else{ lines(xvals, rep(fecs[line], length(xvals)), type = "l", lty = 1, col = line) } - if(x@SurvDensDep){ lines(xvals, surv[line]*exp(-x@SurvDensCoeff*xvals), type = "l", lty = 2, col = line) } - else{ lines(xvals, rep(surv[line], length(xvals)), type = "l", lty = 2, col = line) } - if(x@DevDensDep){ lines(xvals, devs[line]*exp(-x@DevDensCoeff*xvals), type = "l", lty = 3, col = line) } - else{ lines(xvals, rep(devs[line], length(xvals)), type = "l", lty = 3, col = line) } + if(x@FecDensDep){ graphics::lines(xvals, fecs[line]*exp(-xvals), type = "l", lty = 1, col = line) } + else{ graphics::lines(xvals, rep(fecs[line], length(xvals)), type = "l", lty = 1, col = line) } + if(x@SurvDensDep){ graphics::lines(xvals, surv[line]*exp(-x@SurvDensCoeff*xvals), type = "l", lty = 2, col = line) } + else{ graphics::lines(xvals, rep(surv[line], length(xvals)), type = "l", lty = 2, col = line) } + if(x@DevDensDep){ graphics::lines(xvals, devs[line]*exp(-x@DevDensCoeff*xvals), type = "l", lty = 3, col = line) } + else{ graphics::lines(xvals, rep(devs[line], length(xvals)), type = "l", lty = 3, col = line) } if(SexDep) {leg.txt <- c(leg.txt, paste0("Stage ",this.stage, ifelse(this.sex," female"," male")))} else {leg.txt <- c(leg.txt, paste0("Stage ",this.stage))} leg.col <- c(leg.col, line) @@ -502,7 +502,7 @@ setMethod("plotProbs", "StagesParams", function(x, stage = NULL, sex = NULL, xma } if (length(leg.txt)>0) { leg.txt <- c("Fecundity","Survival prob.","Developmt. prob.",leg.txt) - legend("topright", leg.txt, col = c(rep(1,3),leg.col), lwd = 1.5, lty = c(1:3,rep(1,length(leg.col))) ) + graphics::legend("topright", leg.txt, col = c(rep(1,3),leg.col), lwd = 1.5, lty = c(1:3,rep(1,length(leg.col))) ) } }) @@ -512,7 +512,7 @@ setMethod("plotProbs", "StagesParams", function(x, stage = NULL, sex = NULL, xma # contains basic demographic parameters (originally in RS 'Rarameters'-file) and optionally the 'StageStruct' object # define this ClassUnion so that the 'stages' slot in the parameter master class 'RSparams' can be FALSE for option 'population with non-overlapping generations' -setClassUnion("StagesSlot", c("logical", "StagesParams")) +methods::setClassUnion("StagesSlot", c("logical", "StagesParams")) #' Set Demographic Parameters #' @@ -581,7 +581,7 @@ setClassUnion("StagesSlot", c("logical", "StagesParams")) #' @author Anne-Kathleen Malchow #' @name Demography #' @export Demography -Demography <- setClass("DemogParams", slots = c(Rmax = "integer_OR_numeric", +Demography <- methods::setClass("DemogParams", slots = c(Rmax = "integer_OR_numeric", bc = "numeric", StageStruct = "StagesSlot", ReproductionType = "integer_OR_numeric", @@ -626,7 +626,7 @@ setValidity("DemogParams", function(object) { } } } - validObject(object@StageStruct) + methods::validObject(object@StageStruct) if (class(object@StageStruct)[1]=="logical") { if (object@StageStruct) { # StageStruct=TRUE msg <- c(msg, "StageStruct must either be FALSE or an object of class \"StagesParams\" !") @@ -804,9 +804,9 @@ setValidity("DemogParams", function(object) { setMethod("initialize", "DemogParams", function(.Object,...) { this_func = "Demography(): " args <- list(...) - .Object <- callNextMethod() + .Object <- methods::callNextMethod() if ( length(args) == 0 ) { - validObject(.Object) + methods::validObject(.Object) } if (class(.Object@StageStruct)[1]=="StagesParams") { .Object@Rmax = -9L diff --git a/RangeShiftR/R/class_DispersalParams.R b/RangeShiftR/R/class_DispersalParams.R index 3226b88..90951da 100644 --- a/RangeShiftR/R/class_DispersalParams.R +++ b/RangeShiftR/R/class_DispersalParams.R @@ -143,7 +143,7 @@ #' @author Anne-Kathleen Malchow #' @name Emigration #' @export Emigration -Emigration <- setClass("EmigrationParams", slots = c(DensDep = "logical", +Emigration <- methods::setClass("EmigrationParams", slots = c(DensDep = "logical", IndVar = "logical", StageDep = "logical", SexDep = "logical", @@ -282,9 +282,9 @@ setValidity("EmigrationParams", function(object) { setMethod("initialize", "EmigrationParams", function(.Object, ...) { this_func = "Emigration(): " args <- list(...) - .Object <- callNextMethod() + .Object <- methods::callNextMethod() if ( length(args) == 0 ) { - validObject(.Object) + methods::validObject(.Object) } if (!is.null(args$EmigProb)) { if (class(args$EmigProb)[1] =="numeric" && length(args$EmigProb)==1) { @@ -385,17 +385,17 @@ setMethod("plotProbs", "EmigrationParams", function(x, stage = NULL, sex = NULL, res[,6] <- densdep(xvals, A0 = emig[line,ind_D0]+emig[line,ind_D0+1], alpha = emig[line,ind_D0+2]-emig[line,ind_D0+3], beta = emig[line,ind_D0+4]+emig[line,ind_D0+5]) res[,7] <- densdep(xvals, A0 = emig[line,ind_D0]+emig[line,ind_D0+1], alpha = emig[line,ind_D0+2]+emig[line,ind_D0+3], beta = emig[line,ind_D0+4]-emig[line,ind_D0+5]) res[,8] <- densdep(xvals, A0 = emig[line,ind_D0]+emig[line,ind_D0+1], alpha = emig[line,ind_D0+2]+emig[line,ind_D0+3], beta = emig[line,ind_D0+4]+emig[line,ind_D0+5]) - polygon(c(xvals,rev(xvals)), c(apply(res, 1, min), rev(apply(res, 1, max))), border=NA, col='grey80') + graphics::polygon(c(xvals,rev(xvals)), c(apply(res, 1, min), rev(apply(res, 1, max))), border=NA, col='grey80') } else {#constant - polygon(c(0,xmax,xmax,0), c(rep(emig[line,ind_D0]-emig[line,ind_D0+1],2),rep(emig[line,ind_D0]+emig[line,ind_D0+1],2)), border=NA, col='grey80') + graphics::polygon(c(0,xmax,xmax,0), c(rep(emig[line,ind_D0]-emig[line,ind_D0+1],2),rep(emig[line,ind_D0]+emig[line,ind_D0+1],2)), border=NA, col='grey80') } } if (x@DensDep) { - lines(xvals, densdep(xvals, A0 = emig[line,ind_D0], alpha = emig[line,ind_D0+IV], beta = emig[line,ind_D0+2*IV]), type = "l", lty = 1, col = line) + graphics::lines(xvals, densdep(xvals, A0 = emig[line,ind_D0], alpha = emig[line,ind_D0+IV], beta = emig[line,ind_D0+2*IV]), type = "l", lty = 1, col = line) } else {#constant - lines(x=c(0,xmax), y=rep(emig[line,ind_D0],2), type = "l", lty = 1, col = line) + graphics::lines(x=c(0,xmax), y=rep(emig[line,ind_D0],2), type = "l", lty = 1, col = line) } if (x@StageDep) { if (x@SexDep) {leg.txt <- c(leg.txt, paste0("Stage ",emig[line,1], ifelse(emig[line,2]," male"," female")))} else {leg.txt <- c(leg.txt, paste0("Stage ",emig[line,1]))} @@ -405,7 +405,7 @@ setMethod("plotProbs", "EmigrationParams", function(x, stage = NULL, sex = NULL, } } if (length(leg.txt)>0) { - legend("topleft", leg.txt, col = 1:nrow(emig), lwd = 1.5) + graphics::legend("topleft", leg.txt, col = 1:nrow(emig), lwd = 1.5) } }) @@ -439,7 +439,7 @@ setMethod("plotProbs", "EmigrationParams", function(x, stage = NULL, sex = NULL, #' \insertAllCited{} #' @author Anne-Kathleen Malchow #' @name Transfer -TransferParams <- setClass("TransferParams") +TransferParams <- methods::setClass("TransferParams") setMethod("show", "TransferParams", function(object){ if (class(object)[1] == "DispersalKernel") cat(" Dispersal Kernel\n") if (class(object)[1] == "StochMove") cat(" Stochastic Movement Simulator\n") @@ -596,7 +596,7 @@ setMethod("show", "TransferParams", function(object){ #' @author Anne-Kathleen Malchow #' @name DispersalKernel #' @export DispersalKernel -DispersalKernel <- setClass("DispersalKernel", slots = c(IndVar = "logical", +DispersalKernel <- methods::setClass("DispersalKernel", slots = c(IndVar = "logical", DoubleKernel = "logical", StageDep = "logical", SexDep = "logical", @@ -750,9 +750,9 @@ setValidity("DispersalKernel", function(object) { setMethod("initialize", "DispersalKernel", function(.Object, ...) { this_func = "DispersalKernel(): " args <- list(...) - .Object <- callNextMethod() + .Object <- methods::callNextMethod() if ( length(args) == 0 ) { - validObject(.Object) + methods::validObject(.Object) } if (class(args$Distances)[1]=="numeric" && length(args$Distances)==1) { .Object@Distances <- as.matrix(args$Distances) @@ -782,7 +782,7 @@ setMethod("initialize", "DispersalKernel", function(.Object, ...) { .Object} ) setMethod("show", "DispersalKernel", function(object){ - callNextMethod() + methods::callNextMethod() if (object@IndVar) { cat(" IndVar =", object@IndVar, "\n") } @@ -876,15 +876,15 @@ setMethod("plotProbs", "DispersalKernel", function(x, mortality = FALSE, combine if (!combinekernels){ if (x@IndVar) { res <- matrix(ncol = 3, nrow = length(xvals)) - res[,1] <- dexp(xvals, rate = 1/(dists[line,ind_kernel1])) - res[,2] <- dexp(xvals, rate = 1/(dists[line,ind_kernel1]+dists[line,ind_kernel1+1])) - res[,3] <- dexp(xvals, rate = 1/(dists[line,ind_kernel1]-dists[line,ind_kernel1+1])) - polygon(c(xvals,rev(xvals)), c(apply(res, 1, min), rev(apply(res, 1, max))), border=NA, col='grey80') + res[,1] <- stats::dexp(xvals, rate = 1/(dists[line,ind_kernel1])) + res[,2] <- stats::dexp(xvals, rate = 1/(dists[line,ind_kernel1]+dists[line,ind_kernel1+1])) + res[,3] <- stats::dexp(xvals, rate = 1/(dists[line,ind_kernel1]-dists[line,ind_kernel1+1])) + graphics::polygon(c(xvals,rev(xvals)), c(apply(res, 1, min), rev(apply(res, 1, max))), border=NA, col='grey80') } - lines(xvals,dexp(xvals,rate = 1/dists[line,ind_kernel1]), type = "l", lty = 1, col = line) + graphics::lines(xvals,stats::dexp(xvals,rate = 1/dists[line,ind_kernel1]), type = "l", lty = 1, col = line) } } - else {lines(xvals, rep(0, length(xvals)), type = "l", lty = 1, col = line)} + else {graphics::lines(xvals, rep(0, length(xvals)), type = "l", lty = 1, col = line)} if (x@DoubleKernel){ if(dists[line,ind_kernel2]>0){ if (combinekernels){ @@ -892,31 +892,31 @@ setMethod("plotProbs", "DispersalKernel", function(x, mortality = FALSE, combine if (x@IndVar) { pI_sd <- c(pI+dists[line,ind_pI+1],pI-dists[line,ind_pI+1]) res <- matrix(ncol = 8, nrow = length(xvals)) - res[,1] <- pI_sd[1] * dexp(xvals, rate = 1/(dists[line,ind_kernel1]+dists[line,ind_kernel1+1])) + (1-pI_sd[1]) * dexp(xvals, rate = 1/(dists[line,ind_kernel2]+dists[line,ind_kernel2+1])) - res[,2] <- pI_sd[2] * dexp(xvals, rate = 1/(dists[line,ind_kernel1]+dists[line,ind_kernel1+1])) + (1-pI_sd[2]) * dexp(xvals, rate = 1/(dists[line,ind_kernel2]+dists[line,ind_kernel2+1])) - res[,3] <- pI_sd[1] * dexp(xvals, rate = 1/(dists[line,ind_kernel1]-dists[line,ind_kernel1+1])) + (1-pI_sd[1]) * dexp(xvals, rate = 1/(dists[line,ind_kernel2]+dists[line,ind_kernel2+1])) - res[,4] <- pI_sd[2] * dexp(xvals, rate = 1/(dists[line,ind_kernel1]-dists[line,ind_kernel1+1])) + (1-pI_sd[2]) * dexp(xvals, rate = 1/(dists[line,ind_kernel2]+dists[line,ind_kernel2+1])) - res[,5] <- pI_sd[1] * dexp(xvals, rate = 1/(dists[line,ind_kernel1]+dists[line,ind_kernel1+1])) + (1-pI_sd[1]) * dexp(xvals, rate = 1/(dists[line,ind_kernel2]-dists[line,ind_kernel2+1])) - res[,6] <- pI_sd[2] * dexp(xvals, rate = 1/(dists[line,ind_kernel1]+dists[line,ind_kernel1+1])) + (1-pI_sd[2]) * dexp(xvals, rate = 1/(dists[line,ind_kernel2]-dists[line,ind_kernel2+1])) - res[,7] <- pI_sd[1] * dexp(xvals, rate = 1/(dists[line,ind_kernel1]-dists[line,ind_kernel1+1])) + (1-pI_sd[1]) * dexp(xvals, rate = 1/(dists[line,ind_kernel2]-dists[line,ind_kernel2+1])) - res[,8] <- pI_sd[2] * dexp(xvals, rate = 1/(dists[line,ind_kernel1]-dists[line,ind_kernel1+1])) + (1-pI_sd[2]) * dexp(xvals, rate = 1/(dists[line,ind_kernel2]-dists[line,ind_kernel2+1])) - polygon(c(xvals,rev(xvals)), c(apply(res, 1, min), rev(apply(res, 1, max))), border=NA, col='grey80') + res[,1] <- pI_sd[1] * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel1]+dists[line,ind_kernel1+1])) + (1-pI_sd[1]) * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel2]+dists[line,ind_kernel2+1])) + res[,2] <- pI_sd[2] * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel1]+dists[line,ind_kernel1+1])) + (1-pI_sd[2]) * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel2]+dists[line,ind_kernel2+1])) + res[,3] <- pI_sd[1] * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel1]-dists[line,ind_kernel1+1])) + (1-pI_sd[1]) * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel2]+dists[line,ind_kernel2+1])) + res[,4] <- pI_sd[2] * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel1]-dists[line,ind_kernel1+1])) + (1-pI_sd[2]) * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel2]+dists[line,ind_kernel2+1])) + res[,5] <- pI_sd[1] * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel1]+dists[line,ind_kernel1+1])) + (1-pI_sd[1]) * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel2]-dists[line,ind_kernel2+1])) + res[,6] <- pI_sd[2] * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel1]+dists[line,ind_kernel1+1])) + (1-pI_sd[2]) * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel2]-dists[line,ind_kernel2+1])) + res[,7] <- pI_sd[1] * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel1]-dists[line,ind_kernel1+1])) + (1-pI_sd[1]) * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel2]-dists[line,ind_kernel2+1])) + res[,8] <- pI_sd[2] * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel1]-dists[line,ind_kernel1+1])) + (1-pI_sd[2]) * stats::dexp(xvals, rate = 1/(dists[line,ind_kernel2]-dists[line,ind_kernel2+1])) + graphics::polygon(c(xvals,rev(xvals)), c(apply(res, 1, min), rev(apply(res, 1, max))), border=NA, col='grey80') } - yvals <- pI * dexp(xvals, rate = 1/dists[line,ind_kernel1]) + (1-pI) * dexp(xvals, rate = 1/dists[line,ind_kernel2]) - lines(xvals, yvals , type = "l", lty = 1, col = line) + yvals <- pI * stats::dexp(xvals, rate = 1/dists[line,ind_kernel1]) + (1-pI) * stats::dexp(xvals, rate = 1/dists[line,ind_kernel2]) + graphics::lines(xvals, yvals , type = "l", lty = 1, col = line) } else { if (x@IndVar) { - res[,1] <- dexp(xvals, rate = 1/(dists[line,ind_kernel2])) - res[,2] <- dexp(xvals, rate = 1/(dists[line,ind_kernel2]+dists[line,ind_kernel2+1])) - res[,3] <- dexp(xvals, rate = 1/(dists[line,ind_kernel2]-dists[line,ind_kernel2+1])) - polygon(c(xvals,rev(xvals)), c(apply(res, 1, min), rev(apply(res, 1, max))), border=NA, col='grey80') + res[,1] <- stats::dexp(xvals, rate = 1/(dists[line,ind_kernel2])) + res[,2] <- stats::dexp(xvals, rate = 1/(dists[line,ind_kernel2]+dists[line,ind_kernel2+1])) + res[,3] <- stats::dexp(xvals, rate = 1/(dists[line,ind_kernel2]-dists[line,ind_kernel2+1])) + graphics::polygon(c(xvals,rev(xvals)), c(apply(res, 1, min), rev(apply(res, 1, max))), border=NA, col='grey80') } - lines(xvals,dexp(xvals,rate = 1/dists[line,ind_kernel2]), type = "l", lty = 2, col = line) + graphics::lines(xvals,stats::dexp(xvals,rate = 1/dists[line,ind_kernel2]), type = "l", lty = 2, col = line) } } else{ - lines(xvals, rep(0, length(xvals)), type = "l", lty = 2, col = line) + graphics::lines(xvals, rep(0, length(xvals)), type = "l", lty = 2, col = line) } } if (x@StageDep) { @@ -927,7 +927,7 @@ setMethod("plotProbs", "DispersalKernel", function(x, mortality = FALSE, combine } } if (length(leg.txt)>0) { - legend("topright", leg.txt, col = 1:nrow(dists), lwd = 1.5) + graphics::legend("topright", leg.txt, col = 1:nrow(dists), lwd = 1.5) } } }) @@ -1063,7 +1063,7 @@ setMethod("plotProbs", "DispersalKernel", function(x, mortality = FALSE, combine #' @author Anne-Kathleen Malchow #' @name SMS #' @export SMS -SMS <- setClass("StochMove", slots = c(PR = "integer_OR_numeric", +SMS <- methods::setClass("StochMove", slots = c(PR = "integer_OR_numeric", PRMethod = "integer_OR_numeric", # Perceptual range method: 1 = arithmetic mean; 2 = harmonic mean; 3 = weighted arithmtic mean MemSize = "integer_OR_numeric", GoalType = "integer_OR_numeric", # 0 (none) or 2 (dispersal bias) @@ -1311,9 +1311,9 @@ setValidity("StochMove", function(object) { setMethod("initialize", "StochMove", function(.Object,...) { this_func = "SMS(): " args <- list(...) - .Object <- callNextMethod() + .Object <- methods::callNextMethod() if ( length(args) == 0 ) { - validObject(.Object) + methods::validObject(.Object) } if (!.Object@GoalType) { # GoalType = 0 .Object@GoalBias = 1.0 @@ -1340,7 +1340,7 @@ setMethod("initialize", "StochMove", function(.Object,...) { .Object} ) setMethod("show", "StochMove", function(object){ - callNextMethod() + methods::callNextMethod() cat(" PR =", object@PR, ", MemSize =", object@MemSize, "\n") if (object@PRMethod == 1) cat(" Method: Arithmetic mean \n") if (object@PRMethod == 2) cat(" Method: Harmonic mean \n") @@ -1402,17 +1402,17 @@ setMethod("plotProbs", "StochMove", function(x, xmax = NULL, ymax = NULL){ res[,6] <- 1+densdep(xvals, A0 = (gb[1]+gb[2]-1), alpha = -(alp[1]-alp[2]), beta = (bet[1]+bet[2])) res[,7] <- 1+densdep(xvals, A0 = (gb[1]+gb[2]-1), alpha = -(alp[1]+alp[2]), beta = (bet[1]-bet[2])) res[,8] <- 1+densdep(xvals, A0 = (gb[1]+gb[2]-1), alpha = -(alp[1]+alp[2]), beta = (bet[1]+bet[2])) - polygon(c(xvals,rev(xvals)), c(apply(res, 1, min), rev(apply(res, 1, max))), border=NA, col='grey80') + graphics::polygon(c(xvals,rev(xvals)), c(apply(res, 1, min), rev(apply(res, 1, max))), border=NA, col='grey80') } else {#constant - polygon(c(0,xmax,xmax,0), c(rep(gb[1]-gb[2],2),rep(gb[1]+gb[2],2)), border=NA, col='grey80') + graphics::polygon(c(0,xmax,xmax,0), c(rep(gb[1]-gb[2],2),rep(gb[1]+gb[2],2)), border=NA, col='grey80') } } # plot lines if (x@GoalType == 2) { - lines(xvals, 1+densdep(xvals, A0 = (gb[1]-1), alpha = -alp[1], beta = bet[1]), type = "b", lty = 1, col = "blue") + graphics::lines(xvals, 1+densdep(xvals, A0 = (gb[1]-1), alpha = -alp[1], beta = bet[1]), type = "b", lty = 1, col = "blue") }else { # constant - lines(x=c(0,xmax), y=rep(gb[1],2), type = "b", lty = 1, col = "blue") + graphics::lines(x=c(0,xmax), y=rep(gb[1],2), type = "b", lty = 1, col = "blue") } }) @@ -1480,7 +1480,7 @@ setMethod("plotProbs", "StochMove", function(x, xmax = NULL, ymax = NULL){ #' @author Anne-Kathleen Malchow #' @name CorrRW #' @export CorrRW -CorrRW <- setClass("CorrRW", slots = c(IndVar = "logical", +CorrRW <- methods::setClass("CorrRW", slots = c(IndVar = "logical", StepLength = "numeric", Rho = "numeric", StraightenPath = "logical", @@ -1585,14 +1585,14 @@ setValidity("CorrRW", function(object) { # setMethod("initialize", "CorrRW", function(.Object,...) { # this_func = "CorrRW(): " # args <- list(...) -# .Object <- callNextMethod() +# .Object <- methods::callNextMethod() # if ( length(args) == 0 ) { -# validObject(.Object) +# methods::validObject(.Object) # } # .Object} # ) setMethod("show", "CorrRW", function(object){ - callNextMethod() + methods::callNextMethod() if (object@IndVar) { cat(" StepLength =", object@StepLength[1], "\u00B1" , object@StepLength[2], ", scale \u03bc =", object@StepLength[3], "\n") cat(" Rho =", object@Rho[1], "\u00B1" , object@Rho[2], ", scale \u03bc =", object@Rho[3], "\n") @@ -1772,7 +1772,7 @@ setMethod("show", "CorrRW", function(object){ #' @author Anne-Kathleen Malchow #' @name Settlement #' @export Settlement -Settlement <- setClass("SettlementParams", slots = c(StageDep = "logical", +Settlement <- methods::setClass("SettlementParams", slots = c(StageDep = "logical", SexDep = "logical", Settle = "matrix_OR_numeric", # Settlement conditions for all sexes/stages. Settlement rule if the arrival cell/patch is unsuitable: 0 = die, 1 = wait, 2 = randomly choose a suitable cell/patch or die, 3 = randomly choose a suitable cell/patch or wait FindMate = "logical", @@ -1915,9 +1915,9 @@ setValidity("SettlementParams", function(object) { setMethod("initialize", "SettlementParams", function(.Object,...) { this_func = "Settlement(): " args <- list(...) - .Object <- callNextMethod() + .Object <- methods::callNextMethod() if ( length(args) == 0 ) { - validObject(.Object) + methods::validObject(.Object) } if (!is.null(args$Settle)) { if (class(args$Settle)[1]=="numeric" && length(args$Settle)==1) { @@ -2000,9 +2000,9 @@ setMethod("plotProbs", "SettlementParams", function(x, stage = NULL, sex = NULL, res[,6] <- densdep(xvals, A0 = sett[line,ind_D0]+sett[line,ind_D0+1], alpha = sett[line,ind_D0+2]-sett[line,ind_D0+3], beta = sett[line,ind_D0+4]+sett[line,ind_D0+5]) res[,7] <- densdep(xvals, A0 = sett[line,ind_D0]+sett[line,ind_D0+1], alpha = sett[line,ind_D0+2]+sett[line,ind_D0+3], beta = sett[line,ind_D0+4]-sett[line,ind_D0+5]) res[,8] <- densdep(xvals, A0 = sett[line,ind_D0]+sett[line,ind_D0+1], alpha = sett[line,ind_D0+2]+sett[line,ind_D0+3], beta = sett[line,ind_D0+4]+sett[line,ind_D0+5]) - polygon(c(xvals,rev(xvals)), c(apply(res, 1, min), rev(apply(res, 1, max))), border=NA, col='grey80') + graphics::polygon(c(xvals,rev(xvals)), c(apply(res, 1, min), rev(apply(res, 1, max))), border=NA, col='grey80') } - lines(xvals, densdep(xvals, A0 = sett[line,ind_D0], alpha = sett[line,ind_D0+IV], beta = sett[line,ind_D0+2*IV]), type = "l", lty = 1, col = line) + graphics::lines(xvals, densdep(xvals, A0 = sett[line,ind_D0], alpha = sett[line,ind_D0+IV], beta = sett[line,ind_D0+2*IV]), type = "l", lty = 1, col = line) if (x@StageDep) { if (x@SexDep) {leg.txt <- c(leg.txt, paste0("Stage ",sett[line,1], ifelse(sett[line,2]," male"," female")))} else {leg.txt <- c(leg.txt, paste0("Stage ",sett[line,1]))} @@ -2012,7 +2012,7 @@ setMethod("plotProbs", "SettlementParams", function(x, stage = NULL, sex = NULL, } } if (length(leg.txt)>0) { - legend("topright", leg.txt, col = 1:nrow(sett), lwd = 1.5) + graphics::legend("topright", leg.txt, col = 1:nrow(sett), lwd = 1.5) } } else{ print("Plotting is only implemented for density-dependent settlement (in a movement process).\n") } @@ -2074,7 +2074,7 @@ setMethod("plotProbs", "SettlementParams", function(x, stage = NULL, sex = NULL, #' @author Anne-Kathleen Malchow #' @name Dispersal #' @export Dispersal -Dispersal <- setClass("DispersalParams", slots = c(Emigration = "EmigrationParams", +Dispersal <- methods::setClass("DispersalParams", slots = c(Emigration = "EmigrationParams", Transfer = "TransferParams", Settlement = "SettlementParams") , prototype = list(Emigration = Emigration(), @@ -2085,14 +2085,14 @@ Dispersal <- setClass("DispersalParams", slots = c(Emigration = "EmigrationParam setValidity("DispersalParams", function(object) { msg <- NULL - validObject(object@Emigration) + methods::validObject(object@Emigration) if (object@Emigration@UseFullKern) { if (!class(object@Transfer)[1] == "DispersalKernel") { msg <- c(msg, "Dispersal(): The emigration option \"UseFullKern\" can only be used if a dispersal kernel is used as transfer method!") } } - validObject(object@Transfer) - validObject(object@Settlement) + methods::validObject(object@Transfer) + methods::validObject(object@Settlement) if (class(object@Transfer)[1] == "DispersalKernel") { if (object@Settlement@DensDep) { msg <- c(msg, "Dispersal(): Settlement can only be density-dependent (DensDep = TRUE) if a movement process is used as transfer method!") @@ -2107,9 +2107,9 @@ setValidity("DispersalParams", function(object) { setMethod("initialize", "DispersalParams", function(.Object,...) { this_func = "Dispersal(): " args <- list(...) - .Object <- callNextMethod() + .Object <- methods::callNextMethod() if ( length(args) == 0 ) { - validObject(.Object) + methods::validObject(.Object) } .Object} ) diff --git a/RangeShiftR/R/class_GeneticsParams.R b/RangeShiftR/R/class_GeneticsParams.R index de519f4..9fa855a 100644 --- a/RangeShiftR/R/class_GeneticsParams.R +++ b/RangeShiftR/R/class_GeneticsParams.R @@ -190,7 +190,7 @@ #' @author Anne-Kathleen Malchow #' @name Genetics #' @export Genetics -Genetics <- setClass("GeneticsParams", slots = c(Architecture = "integer_OR_numeric", +Genetics <- methods::setClass("GeneticsParams", slots = c(Architecture = "integer_OR_numeric", NLoci = "integer_OR_numeric", ArchFile = "character", ProbMutn = "numeric", @@ -268,7 +268,7 @@ setValidity('GeneticsParams', function(object){ setMethod('initialize', 'GeneticsParams', function(.Object, ...) { this_func = "Genetics(): " args <- list(...) - .Object <- callNextMethod() + .Object <- methods::callNextMethod() if(.Object@Architecture == 0) { if (!is.null(args$ArchFile)) { warning(this_func, "ArchFile", warn_msg_ignored, "since Architecture = 0 (one chromosome per trait).", call. = FALSE) diff --git a/RangeShiftR/R/class_InitialisationParams.R b/RangeShiftR/R/class_InitialisationParams.R index 6fccbf7..bf60612 100644 --- a/RangeShiftR/R/class_InitialisationParams.R +++ b/RangeShiftR/R/class_InitialisationParams.R @@ -157,7 +157,7 @@ #' @author Anne-Kathleen Malchow #' @name Initialise #' @export Initialise -Initialise <- setClass("InitialisationParams", slots = c(InitType = "integer_OR_numeric", +Initialise <- methods::setClass("InitialisationParams", slots = c(InitType = "integer_OR_numeric", FreeType = "integer_OR_numeric", SpType = "integer_OR_numeric", NrCells = "integer_OR_numeric", @@ -415,7 +415,7 @@ setValidity('InitialisationParams', function(object){ setMethod('initialize', 'InitialisationParams', function(.Object, ...) { this_func = "Initialise(): " args <- list(...) - .Object <- callNextMethod() + .Object <- methods::callNextMethod() if (.Object@InitType != 0) { .Object@FreeType = -9L if (!is.null(args$FreeType)) { diff --git a/RangeShiftR/R/class_LandParams.R b/RangeShiftR/R/class_LandParams.R index 1c73d10..030cb0c 100644 --- a/RangeShiftR/R/class_LandParams.R +++ b/RangeShiftR/R/class_LandParams.R @@ -26,7 +26,7 @@ # from RS 'Land' file # can take one of two forms: 'ArtificialLandscape' or 'ImportedLandscape' -LandParams <- setClass("LandParams", slots = c(LandNum = "integer_OR_numeric") +LandParams <- methods::setClass("LandParams", slots = c(LandNum = "integer_OR_numeric") , prototype = list(LandNum = 1L) ) # landscape number must be unique @@ -44,7 +44,7 @@ setValidity("LandParams", function(object) { if (is.null(msg)) TRUE else msg} ) setMethod("initialize", "LandParams", function(.Object, ...) { - .Object <- callNextMethod() + .Object <- methods::callNextMethod() .Object} ) @@ -100,7 +100,8 @@ setMethod("initialize", "LandParams", function(.Object, ...) { #' @author Anne-Kathleen Malchow #' @name ArtificialLandscape #' @export ArtificialLandscape -ArtificialLandscape <- setClass("ArtificialLandscape", slots = c(propSuit = "numeric", +#' @importFrom methods new +ArtificialLandscape <- methods::setClass("ArtificialLandscape", slots = c(propSuit = "numeric", K_or_DensDep = "integer_OR_numeric", Resolution = "integer_OR_numeric", dimX = "integer_OR_numeric", @@ -122,7 +123,7 @@ ArtificialLandscape <- setClass("ArtificialLandscape", slots = c(propSuit = "num #maxPct, , contains = "LandParams") -setValidity("ArtificialLandscape", function(object) { +methods::setValidity("ArtificialLandscape", function(object) { msg <- NULL if (anyNA(object@propSuit) || length(object@propSuit)!=1) { msg <- c(msg, "Proportion of suitable habitat must be set and of length 1!") @@ -233,12 +234,12 @@ setValidity("ArtificialLandscape", function(object) { } if (is.null(msg)) TRUE else msg} ) -setMethod("initialize", "ArtificialLandscape", function(.Object,...) { +methods::setMethod("initialize", "ArtificialLandscape", function(.Object,...) { this_func = "ArtificialLandscape(): " args <- list(...) - .Object <- callNextMethod() + .Object <- methods::callNextMethod() if ( length(args) == 0 ) { - validObject(.Object) + methods::validObject(.Object) } if (!.Object@fractal) { .Object@hurst = -9L @@ -258,7 +259,7 @@ setMethod("initialize", "ArtificialLandscape", function(.Object,...) { } .Object} ) -setMethod("show", "ArtificialLandscape", function(object){ +methods::setMethod("show", "ArtificialLandscape", function(object){ cat(" Artificial landscape: ") #cat(" Artificial landscape #", object@LandNum, ": ") if(object@fractal) { @@ -531,9 +532,9 @@ setValidity("ImportedLandscape", function(object) { setMethod("initialize", "ImportedLandscape", function(.Object, ...) { this_func = "ImportedLandscape(): " args <- list(...) - .Object <- callNextMethod() + .Object <- methods::callNextMethod() if ( length(args) == 0 ) { - validObject(.Object) + methods::validObject(.Object) } if (.Object@HabPercent) { .Object@Nhabitats = 1L diff --git a/RangeShiftR/R/class_RSparams.R b/RangeShiftR/R/class_RSparams.R index a967284..1df83e6 100644 --- a/RangeShiftR/R/class_RSparams.R +++ b/RangeShiftR/R/class_RSparams.R @@ -30,7 +30,7 @@ #' @include class_DispersalParams.R #' @include class_GeneticsParams.R #' @include class_InitialisationParams.R -RSparams <- setClass("RSparams", slots = c(control = "ControlParams", +RSparams <- methods::setClass("RSparams", slots = c(control = "ControlParams", simul = "SimulationParams", land = "LandParams", demog = "DemogParams", @@ -41,9 +41,9 @@ RSparams <- setClass("RSparams", slots = c(control = "ControlParams", setValidity("RSparams", function(object) { msg <- NULL #CONTROL - validObject(object@control) + methods::validObject(object@control) #SIMULATION - validObject(object@simul) + methods::validObject(object@simul) if (object@control@patchmodel) { if (object@simul@Gradient) { msg <- c(msg, "Environmental gradients are not implemented for patch-based models!") @@ -82,7 +82,7 @@ setValidity("RSparams", function(object) { } } #LAND - validObject(object@land) + methods::validObject(object@land) if (any(object@control@landtype==c(0,2))){ if (any(object@land@DynamicLandYears>object@simul@Years)) { warning("ImportedLandscape(): Dynamic landscape contains years that exceed the simulated years, so that some land changes will not apply.", call. = FALSE) @@ -99,9 +99,9 @@ setValidity("RSparams", function(object) { } } #DEMOGRAPHY - validObject(object@demog) + methods::validObject(object@demog) #DISPERSAL - validObject(object@dispersal) + methods::validObject(object@dispersal) ## Emigration: check dimensions and values of EmigProb and EmigStage: # check StageDep and SexDep dim_ok = TRUE @@ -211,7 +211,7 @@ setValidity("RSparams", function(object) { } else { if(any(object@dispersal@Emigration@EmigProb[,(offset+2)] > object@dispersal@Emigration@TraitScaleFactor[1])) { - msg <- c(msg, paste0("Column ", (offset+2), " of emigration traits matrix (EmigProb) must contain sd(D0), with values less than or equal to TraitScaleFactor ÎĽ(D0)!")) + msg <- c(msg, paste0("Column ", (offset+2), " of emigration traits matrix (EmigProb) must contain sd(D0), with values less than or equal to TraitScaleFactor mu(D0)!")) } } if (object@dispersal@Emigration@DensDep) { @@ -220,10 +220,10 @@ setValidity("RSparams", function(object) { } else { if(any(object@dispersal@Emigration@EmigProb[,(offset+4)] > object@dispersal@Emigration@TraitScaleFactor[2])) { - msg <- c(msg, paste0("Column ", (offset+4), " of emigration traits matrix (EmigProb) must contain sd(alpha), with values less than or equal to TraitScaleFactor ÎĽ(alpha)!")) + msg <- c(msg, paste0("Column ", (offset+4), " of emigration traits matrix (EmigProb) must contain sd(alpha), with values less than or equal to TraitScaleFactor mu(alpha)!")) } if(any(object@dispersal@Emigration@EmigProb[,(offset+6)] > object@dispersal@Emigration@TraitScaleFactor[3])) { - msg <- c(msg, paste0("Column ", (offset+6), " of emigration traits matrix (EmigProb) must contain sd(beta), with values less than or equal to TraitScaleFactor ÎĽ(beta)!")) + msg <- c(msg, paste0("Column ", (offset+6), " of emigration traits matrix (EmigProb) must contain sd(beta), with values less than or equal to TraitScaleFactor mu(beta)!")) } } } @@ -348,25 +348,25 @@ setValidity("RSparams", function(object) { if (object@dispersal@Transfer@IndVar) { if (object@dispersal@Transfer@DoubleKernel) { if(any(object@dispersal@Transfer@Distances[,(offset+1)]= ", (resol), " (=landscape resolution (unless UseFullKernel=TRUE)) !")) + msg <- c(msg, paste0("Column ", (offset+1), " of dispersal kernel traits (Distances) matrix must contain the mean of the mean distance of Kernel 1, mean(delta1), with values >= ", (resol), " (=landscape resolution (unless UseFullKernel=TRUE)) !")) } if(any(object@dispersal@Transfer@Distances[,(offset+2)]<=0.0)){ - msg <- c(msg, paste0("Column ", (offset+2), " of dispersal kernel traits (Distances) matrix must contain the std. dev. of the mean distance of Kernel 1, sd(δ1), with strictly positive values!")) + msg <- c(msg, paste0("Column ", (offset+2), " of dispersal kernel traits (Distances) matrix must contain the std. dev. of the mean distance of Kernel 1, sd(delta1), with strictly positive values!")) } else { if(any(object@dispersal@Transfer@Distances[,(offset+2)] > object@dispersal@Transfer@TraitScaleFactor[1])) { - msg <- c(msg, paste0("Column ", (offset+2), " of dispersal kernel traits (Distances) matrix must contain sd(δ1), with values less than or equal to TraitScaleFactor ÎĽ(δ1)!")) + msg <- c(msg, paste0("Column ", (offset+2), " of dispersal kernel traits (Distances) matrix must contain sd(delta1), with values less than or equal to TraitScaleFactor mu(delta1)!")) } } if(any(object@dispersal@Transfer@Distances[,(offset+3)]= ", (resol), " (=landscape resolution (unless UseFullKernel=TRUE)) !")) + msg <- c(msg, paste0("Column ", (offset+3), " of dispersal kernel traits (Distances) matrix must contain the mean of the mean distance of Kernel 2, mean(delta2), with values >= ", (resol), " (=landscape resolution (unless UseFullKernel=TRUE)) !")) } if(any(object@dispersal@Transfer@Distances[,(offset+4)]<=0.0)){ - msg <- c(msg, paste0("Column ", (offset+4), " of dispersal kernel traits (Distances) matrix must contain the std. dev. of the mean distance of Kernel 2, sd(δ2), with strictly positive values!")) + msg <- c(msg, paste0("Column ", (offset+4), " of dispersal kernel traits (Distances) matrix must contain the std. dev. of the mean distance of Kernel 2, sd(delta2), with strictly positive values!")) } else { if(any(object@dispersal@Transfer@Distances[,(offset+4)] > object@dispersal@Transfer@TraitScaleFactor[2])) { - msg <- c(msg, paste0("Column ", (offset+4), " of dispersal kernel traits (Distances) matrix must contain sd(δ2), with values less than or equal to TraitScaleFactor ÎĽ(δ2)!")) + msg <- c(msg, paste0("Column ", (offset+4), " of dispersal kernel traits (Distances) matrix must contain sd(delta2), with values less than or equal to TraitScaleFactor mu(delta2)!")) } } if(any(object@dispersal@Transfer@Distances[,(offset+5)]<=0.0 | object@dispersal@Transfer@Distances[,(offset+5)]>=1.0)){ @@ -377,20 +377,20 @@ setValidity("RSparams", function(object) { } else { if(any(object@dispersal@Transfer@Distances[,(offset+6)] > object@dispersal@Transfer@TraitScaleFactor[3])) { - msg <- c(msg, paste0("Column ", (offset+6), " of dispersal kernel traits (Distances) matrix must contain sd(p), with values less than or equal to TraitScaleFactor ÎĽ(p)!")) + msg <- c(msg, paste0("Column ", (offset+6), " of dispersal kernel traits (Distances) matrix must contain sd(p), with values less than or equal to TraitScaleFactor mu(p)!")) } } } else { # !DoubleKernel if(any(object@dispersal@Transfer@Distances[,(offset+1)]= ", (resol), " (=landscape resolution (unless UseFullKernel=TRUE)) !")) + msg <- c(msg, paste0("Column ", (offset+1), " of dispersal kernel traits (Distances) matrix must contain the mean of the mean distance, mean(delta), with values >= ", (resol), " (=landscape resolution (unless UseFullKernel=TRUE)) !")) } if(any(object@dispersal@Transfer@Distances[,(offset+2)]<=0.0)){ - msg <- c(msg, paste0("Column ", (offset+2), " of dispersal kernel traits (Distances) matrix must contain the std. dev. of the mean distance, sd(δ), with strictly positive values!")) + msg <- c(msg, paste0("Column ", (offset+2), " of dispersal kernel traits (Distances) matrix must contain the std. dev. of the mean distance, sd(delta), with strictly positive values!")) } else { if(any(object@dispersal@Transfer@Distances[,(offset+2)] > object@dispersal@Transfer@TraitScaleFactor[1])) { - msg <- c(msg, paste0("Column ", (offset+2), " of dispersal kernel traits (Distances) matrix must contain sd(δ), with values less than or equal to TraitScaleFactor ÎĽ(δ)!")) + msg <- c(msg, paste0("Column ", (offset+2), " of dispersal kernel traits (Distances) matrix must contain sd(delta), with values less than or equal to TraitScaleFactor mu(delta)!")) } } } @@ -398,7 +398,7 @@ setValidity("RSparams", function(object) { else { # !IndVar if (object@dispersal@Transfer@DoubleKernel) { if(any(object@dispersal@Transfer@Distances[,(offset+1):(offset+2)]= ", (resol), " (=landscape resolution (unless UseFullKernel=TRUE)) !")) + msg <- c(msg, paste0("Columns ", (offset+1), " and ", (offset+2), " of dispersal kernel traits (Distances) matrix must contain the two mean distance delta1 and delta2, with values >= ", (resol), " (=landscape resolution (unless UseFullKernel=TRUE)) !")) } if(any(object@dispersal@Transfer@Distances[,(offset+3)]<=0 | object@dispersal@Transfer@Distances[,(offset+3)]>=1)) { msg <- c(msg, paste0("Column ", (offset+3), " of dispersal kernel traits (Distances) matrix must contain the probability p of using kernel 1, with values in the open interval (0,1) !")) @@ -406,7 +406,7 @@ setValidity("RSparams", function(object) { } else{ if(any(object@dispersal@Transfer@Distances[,(offset+1)]= ", (resol), " (=landscape resolution (unless UseFullKernel=TRUE)) !")) + msg <- c(msg, paste0("Column ", (offset+1), " of dispersal kernel traits (Distances) matrix must contain the mean distance delta, with values >= ", (resol), " (=landscape resolution (unless UseFullKernel=TRUE)) !")) } } } @@ -617,7 +617,7 @@ setValidity("RSparams", function(object) { } else { if(any(object@dispersal@Settlement@Settle[,(offset+2)] > object@dispersal@Settlement@TraitScaleFactor[1])) { - msg <- c(msg, paste0("Column ", (offset+2), " of settlement traits matrix (Settle) must contain sd(S0), with values less than or equal to TraitScaleFactor ÎĽ(S0)!")) + msg <- c(msg, paste0("Column ", (offset+2), " of settlement traits matrix (Settle) must contain sd(S0), with values less than or equal to TraitScaleFactor mu(S0)!")) } } if(any(object@dispersal@Settlement@Settle[,c((offset+4),(offset+6))]<=0 )){ @@ -625,10 +625,10 @@ setValidity("RSparams", function(object) { } else { if(any(object@dispersal@Settlement@Settle[,(offset+4)] > object@dispersal@Settlement@TraitScaleFactor[2])) { - msg <- c(msg, paste0("Column ", (offset+4), " of settlement traits matrix (Settle) must contain sd(alpha_s), with values less than or equal to TraitScaleFactor ÎĽ(alpha_s)!")) + msg <- c(msg, paste0("Column ", (offset+4), " of settlement traits matrix (Settle) must contain sd(alpha_s), with values less than or equal to TraitScaleFactor mu(alpha_s)!")) } if(any(object@dispersal@Settlement@Settle[,(offset+6)] > object@dispersal@Settlement@TraitScaleFactor[3])) { - msg <- c(msg, paste0("Column ", (offset+6), " of settlement traits matrix (Settle) must contain sd(beta_s), with values less than or equal to TraitScaleFactor ÎĽ(beta_s)!")) + msg <- c(msg, paste0("Column ", (offset+6), " of settlement traits matrix (Settle) must contain sd(beta_s), with values less than or equal to TraitScaleFactor mu(beta_s)!")) } } } @@ -675,13 +675,13 @@ setValidity("RSparams", function(object) { } #GENETICS - validObject(object@gene) + methods::validObject(object@gene) if(any(object@dispersal@Emigration@IndVar,object@dispersal@Transfer@IndVar,object@dispersal@Settlement@IndVar)) anyIndVar <- TRUE else anyIndVar <- FALSE # if( ...(object@gene) & !anyIndVar) # TODO: check if genetics module is set but no variable traits -> give warning in this case #INITIALISATION - validObject(object@init) + methods::validObject(object@init) if (object@control@landtype == 9) { # artificial land if (object@init@InitType) { msg <- c(msg, 'Initialise(): InitType must be set to 0 (Free initialisation) for an artificial landscape!') diff --git a/RangeShiftR/R/class_SimulationParams.R b/RangeShiftR/R/class_SimulationParams.R index 8cf9a60..03023bb 100644 --- a/RangeShiftR/R/class_SimulationParams.R +++ b/RangeShiftR/R/class_SimulationParams.R @@ -308,7 +308,7 @@ #' \insertAllCited{} #' @name Simulation #' @export Simulation -Simulation <- setClass("SimulationParams", slots = c(Simulation = "integer_OR_numeric", +Simulation <- methods::setClass("SimulationParams", slots = c(Simulation = "integer_OR_numeric", Replicates = "integer_OR_numeric", Years = "integer_OR_numeric", Absorbing = "logical", @@ -852,9 +852,9 @@ setValidity('SimulationParams', function(object){ setMethod("initialize", "SimulationParams", function(.Object, ...) { this_func = "Simulation(): " args <- list(...) - .Object <- callNextMethod() + .Object <- methods::callNextMethod() if ( length(args) == 0 ) { - validObject(.Object) + methods::validObject(.Object) } if(.Object@Gradient == 0){ .Object@GradSteep = -9L diff --git a/RangeShiftR/R/output_handling.R b/RangeShiftR/R/output_handling.R index fc42dfb..019c4a4 100644 --- a/RangeShiftR/R/output_handling.R +++ b/RangeShiftR/R/output_handling.R @@ -43,7 +43,7 @@ setGeneric("readRange", function(s,dirpath) standardGeneric("readRange") ) setMethod("readRange", c(s="RSparams", dirpath="character"), function(s,dirpath) { path <- paste0(dirpath, "Outputs/Batch", s@control@batchnum, "_Sim", s@simul@Simulation, "_Land", s@land@LandNum, "_Range.txt") if(file.exists(path)){ - return(read.table(path, h = T, sep = "\t")) + return(utils::read.table(path, h = T, sep = "\t")) }else { warning("The 'range' output file for this simulation does not exist.", call. = FALSE) } @@ -64,7 +64,7 @@ setGeneric("readPop", function(s,dirpath,...) standardGeneric("readPop") ) setMethod("readPop", c(s="RSparams", dirpath="character"), function(s,dirpath,center=TRUE) { path <- paste0(dirpath, "Outputs/Batch", s@control@batchnum, "_Sim", s@simul@Simulation, "_Land", s@land@LandNum, "_Pop.txt") if(file.exists(path)){ - pop_table <- read.table(path, h = T, sep = "\t") + pop_table <- utils::read.table(path, h = T, sep = "\t") if (sum(grepl('x',names(pop_table))) & center){ pop_table$x <- (pop_table$x+0.5)*s@land@Resolution pop_table$y <- (pop_table$y+0.5)*s@land@Resolution @@ -136,7 +136,7 @@ setMethod("ColonisationStats", "data.frame", function(x, y = NULL, years = numer digitsY <- ifelse(maxY < 1, 0, floor(log10(maxY)) + 1) x$PatchID <- (x$x*(10^digitsY)) + (x$y) #+ (maxY+1-x$y) } - + NInd <- NULL # not used, necessary to pass CRAN check x <- subset(x, NInd>0, select = c("Rep","PatchID","Year","NInd") ) reps <- sort(unique(x$Rep)) n=length(reps) @@ -285,13 +285,13 @@ setMethod("ColonisationStats", "data.frame", function(x, y = NULL, years = numer patch_outstack <- c(patch_outstack, patch_occ_prob) terra::values(patch_outstack[[j]])[value_ix] <- occ_prob[,j+2] } - crs(patch_outstack) <- NA + terra::crs(patch_outstack) <- NA #} else{ # raster::values(patch_occ_prob)[value_ix] <- occ_prob[,1] # patch_outstack <- patch_occ_prob #} terra::values(patch_col_time)[value_ix] <- ifelse(is.na(col_time_mean[]),-9,col_time_mean[]) - crs(patch_col_time) <- NA + terra::crs(patch_col_time) <- NA return(list(occ_prob=occ_prob, col_time=col_time, map_occ_prob=patch_outstack, map_col_time=patch_col_time)) @@ -351,7 +351,7 @@ setMethod("ColonisationStats", "RSparams", function(x, y = getwd(), years = nume if ( class(patch_curr) == "try-error" ) warning("ColonisationStats(): Couldn't read patch raster file nr ", current , " for this simulation.", call. = FALSE) else patch_r <- c(patch_r , patch_curr) - if(class(pop_df) == "data.frame" & nlyr(patch_r)==(length(years)+1) ) res <- ColonisationStats(pop_df,patch_r,years) + if(class(pop_df) == "data.frame" & terra::nlyr(patch_r)==(length(years)+1) ) res <- ColonisationStats(pop_df,patch_r,years) } }else{ # for cell-based model, read only main habitat maps to use as raster template @@ -398,10 +398,10 @@ setGeneric("plotAbundance", function(s,...) standardGeneric("plotAbundance") ) setMethod("plotAbundance", "data.frame", function(s, sd = FALSE, replicates = TRUE, ylim=NULL, ...) { # Calculate means - rep_means <- aggregate(NInds~Year, data = s, FUN = "mean") + rep_means <- stats::aggregate(NInds~Year, data = s, FUN = "mean") # Calculate standard deviation if (sd) { - rep_sd <- aggregate(NInds~Year, data = s, FUN = "sd") + rep_sd <- stats::aggregate(NInds~Year, data = s, FUN = "sd") rep_sd[is.na(rep_sd)] <- 0 } # Set y-limits @@ -420,16 +420,16 @@ setMethod("plotAbundance", "data.frame", function(s, sd = FALSE, replicates = TR plot(NULL, type = "n", ylab = "Abundance", xlab = "Year", xlim=c(0, max(s$Year)), ylim=ylim, ...) # Plot standard deviation if (sd) { - polygon(c(rep_sd$Year,rev(rep_sd$Year)), c(rep_means$NInds+rep_sd$NInds, rev(pmax(0,rep_means$NInds-rep_sd$NInds))), border=NA, col='grey80') + graphics::polygon(c(rep_sd$Year,rev(rep_sd$Year)), c(rep_means$NInds+rep_sd$NInds, rev(pmax(0,rep_means$NInds-rep_sd$NInds))), border=NA, col='grey80') } # Plot replicates if (replicates) { for (i in 0:max(s$Rep)) { - lines(s$Year[s$Rep==i], s$NInds[s$Rep==i], type = "l", lwd = 0.5) + graphics::lines(s$Year[s$Rep==i], s$NInds[s$Rep==i], type = "l", lwd = 0.5) } } # Plot abundance - lines(rep_means$Year, rep_means$NInds, type = "l", lwd = 3, col = "red") + graphics::lines(rep_means$Year, rep_means$NInds, type = "l", lwd = 3, col = "red") }) setMethod("plotAbundance", "RSparams", function(s, dirpath, ...) { if (class(dirpath)=="character"){ @@ -458,10 +458,10 @@ setGeneric("plotOccupancy", function(s,...) standardGeneric("plotOccupancy") ) setMethod("plotOccupancy", "data.frame", function(s, sd = FALSE, replicates = TRUE, ylim=NULL, ...) { names(s)[grep('NOccup',names(s))] <- 'NOccup' # Calculate means - rep_means <- aggregate(NOccup~Year, data = s, FUN = "mean") + rep_means <- stats::aggregate(NOccup~Year, data = s, FUN = "mean") # Calculate standard deviation if (sd) { - rep_sd <- aggregate(NOccup~Year, data = s, FUN = "sd") + rep_sd <- stats::aggregate(NOccup~Year, data = s, FUN = "sd") rep_sd[is.na(rep_sd)] <- 0 } # Set y-limits @@ -480,16 +480,16 @@ setMethod("plotOccupancy", "data.frame", function(s, sd = FALSE, replicates = TR plot(NULL, type = "n", ylab = "Occupancy", xlab = "Year", xlim=c(0, max(s$Year)), ylim=ylim, ...) # Plot standard deviation if (sd) { - polygon(c(rep_sd$Year,rev(rep_sd$Year)), c(rep_means$NOccup+rep_sd$NOccup, rev(pmax(0,rep_means$NOccup-rep_sd$NOccup))), border=NA, col='grey80') + graphics::polygon(c(rep_sd$Year,rev(rep_sd$Year)), c(rep_means$NOccup+rep_sd$NOccup, rev(pmax(0,rep_means$NOccup-rep_sd$NOccup))), border=NA, col='grey80') } # plot replicates if (replicates) { for (i in 0:max(s$Rep)) { - lines(s$Year[s$Rep==i], s$NOccup[s$Rep==i], type = "l", lwd = 0.5) + graphics::lines(s$Year[s$Rep==i], s$NOccup[s$Rep==i], type = "l", lwd = 0.5) } } # Plot occupancy - lines(rep_means$Year, rep_means$NOccup, type = "l", lwd = 3, col = "blue") + graphics::lines(rep_means$Year, rep_means$NOccup, type = "l", lwd = 3, col = "blue") }) setMethod("plotOccupancy", "RSparams", function(s, dirpath, ...) { if (class(dirpath)=="character"){ @@ -537,7 +537,7 @@ setMethod("SMSpathLengths", c(s="RSparams", dirpath="character"), function(s,dir null_tb <- rep(0,maxLength) names(null_tb) <- sapply(1:maxLength, FUN=paste0) for(i in 0:(s@simul@Replicates-1)){ - steps <- try(read.table(paste0(dirpath, + steps <- try(utils::read.table(paste0(dirpath, "Outputs/Batch",s@control@batchnum, "_Sim",s@simul@Simulation, "_Land",s@land@LandNum, @@ -551,10 +551,10 @@ setMethod("SMSpathLengths", c(s="RSparams", dirpath="character"), function(s,dir steps_y <- sapply(seq(nr_maps), FUN = function(y){ tb <- null_tb lo <- year_blocks[y] - if (y==nr_maps) tb_n <- table(aggregate(Step~IndID, data=subset(steps, Year >= lo), FUN = max)$Step) + if (y==nr_maps) tb_n <- table(stats::aggregate(Step~IndID, data=subset(steps, Year >= lo), FUN = max)$Step) else { up <- year_blocks[y+1] - tb_n <- table(aggregate(Step~IndID, data=subset(steps, Year >= lo & Year < up), FUN = max)$Step) + tb_n <- table(stats::aggregate(Step~IndID, data=subset(steps, Year >= lo & Year < up), FUN = max)$Step) } ix <- names(tb) %in% names(tb_n) tb[ix] <- tb_n[1:sum(ix)] @@ -855,9 +855,9 @@ setMethod("getLocalisedEquilPop", "DemogParams", function(demog, DensDep_values, xlabs <- print(DensDep_values, digits = 2) # which stages to plot? if(is.null(stages_out)) stages_out = seq((!juv.stage),demog@StageStruct@Stages-1) - colors <- hcl.colors(length(stages_out), palette = "Harmonic") + colors <- grDevices::hcl.colors(length(stages_out), palette = "Harmonic") if(demog@ReproductionType <2){ - barplot(res[as.character(stages_out),], names.arg = xlabs, beside = F, col = colors, + graphics::barplot(res[as.character(stages_out),], names.arg = xlabs, beside = F, col = colors, main = "Localised equilibrium densities", xlab = "1/b", ylab = "Population density") } if(demog@ReproductionType==2){ @@ -868,13 +868,13 @@ setMethod("getLocalisedEquilPop", "DemogParams", function(demog, DensDep_values, fem <- seq.int(2,length(stages_out)*2,2) res_2 <- cbind(res_2[mal,1:length(DensDep_values)],res_2[fem,1:length(DensDep_values)]) res_2 <- cbind(res_2[,c(sapply(1:length(DensDep_values), function(i){c(0,1)*length(DensDep_values)+i}))]) - barplot(res_2, space=c(0.3,0.1), names.arg = c(rbind(xlabs,NA)), beside = F, col = rep(colors, 2), + graphics::barplot(res_2, space=c(0.3,0.1), names.arg = c(rbind(xlabs,NA)), beside = F, col = rep(colors, 2), main = "Localised equilibrium densities", xlab = "1/b", ylab = "Population density") - text(seq(0.5,length(DensDep_values)*2,2)*1.2, colSums(res_2[,seq(1,length(DensDep_values)*2,2)])*1.1, "m", cex=1, col="black") - text(seq(1.5,length(DensDep_values)*2,2)*1.2, colSums(res_2[,seq(2,length(DensDep_values)*2,2)])*1.1, "f", cex=1, col="black") + graphics::text(seq(0.5,length(DensDep_values)*2,2)*1.2, colSums(res_2[,seq(1,length(DensDep_values)*2,2)])*1.1, "m", cex=1, col="black") + graphics::text(seq(1.5,length(DensDep_values)*2,2)*1.2, colSums(res_2[,seq(2,length(DensDep_values)*2,2)])*1.1, "f", cex=1, col="black") } } - legend("topleft", legend = rev(sapply(stages_out, function(s){paste("Stage",s)})), col = rev(colors), pch = 16) + graphics::legend("topleft", legend = rev(sapply(stages_out, function(s){paste("Stage",s)})), col = rev(colors), pch = 16) } # return equilibrium population densities return(res) From 260b011f343aaf3ea20136462d257b640006a292 Mon Sep 17 00:00:00 2001 From: Pannetier Date: Fri, 24 Nov 2023 15:26:32 +0000 Subject: [PATCH 15/17] switch to rscore branch unit_test --- RangeShiftR/src/RScore/.gitignore | 85 - RangeShiftR/src/RScore/Cell.cpp | 237 -- RangeShiftR/src/RScore/Cell.h | 174 -- RangeShiftR/src/RScore/Community.cpp | 1717 ----------- RangeShiftR/src/RScore/Community.h | 231 -- RangeShiftR/src/RScore/FractalGenerator.cpp | 243 -- RangeShiftR/src/RScore/FractalGenerator.h | 85 - RangeShiftR/src/RScore/Genome.cpp | 861 ------ RangeShiftR/src/RScore/Genome.h | 251 -- RangeShiftR/src/RScore/Individual.cpp | 2454 --------------- RangeShiftR/src/RScore/Individual.h | 317 -- RangeShiftR/src/RScore/LICENSE | 674 ----- RangeShiftR/src/RScore/Landscape.cpp | 2983 ------------------- RangeShiftR/src/RScore/Landscape.h | 567 ---- RangeShiftR/src/RScore/Model.cpp | 2292 -------------- RangeShiftR/src/RScore/Model.h | 149 - RangeShiftR/src/RScore/Parameters.cpp | 398 --- RangeShiftR/src/RScore/Parameters.h | 393 --- RangeShiftR/src/RScore/Patch.cpp | 358 --- RangeShiftR/src/RScore/Patch.h | 182 -- RangeShiftR/src/RScore/Population.cpp | 2252 -------------- RangeShiftR/src/RScore/Population.h | 248 -- RangeShiftR/src/RScore/README.md | 3 - RangeShiftR/src/RScore/RSrandom.cpp | 256 -- RangeShiftR/src/RScore/RSrandom.h | 140 - RangeShiftR/src/RScore/RandomCheck.cpp | 93 - RangeShiftR/src/RScore/RandomCheck.h | 47 - RangeShiftR/src/RScore/Species.cpp | 1455 --------- RangeShiftR/src/RScore/Species.h | 756 ----- RangeShiftR/src/RScore/SubCommunity.cpp | 1204 -------- RangeShiftR/src/RScore/SubCommunity.h | 216 -- 31 files changed, 21321 deletions(-) delete mode 100644 RangeShiftR/src/RScore/.gitignore delete mode 100644 RangeShiftR/src/RScore/Cell.cpp delete mode 100644 RangeShiftR/src/RScore/Cell.h delete mode 100644 RangeShiftR/src/RScore/Community.cpp delete mode 100644 RangeShiftR/src/RScore/Community.h delete mode 100644 RangeShiftR/src/RScore/FractalGenerator.cpp delete mode 100644 RangeShiftR/src/RScore/FractalGenerator.h delete mode 100644 RangeShiftR/src/RScore/Genome.cpp delete mode 100644 RangeShiftR/src/RScore/Genome.h delete mode 100644 RangeShiftR/src/RScore/Individual.cpp delete mode 100644 RangeShiftR/src/RScore/Individual.h delete mode 100644 RangeShiftR/src/RScore/LICENSE delete mode 100644 RangeShiftR/src/RScore/Landscape.cpp delete mode 100644 RangeShiftR/src/RScore/Landscape.h delete mode 100644 RangeShiftR/src/RScore/Model.cpp delete mode 100644 RangeShiftR/src/RScore/Model.h delete mode 100644 RangeShiftR/src/RScore/Parameters.cpp delete mode 100644 RangeShiftR/src/RScore/Parameters.h delete mode 100644 RangeShiftR/src/RScore/Patch.cpp delete mode 100644 RangeShiftR/src/RScore/Patch.h delete mode 100644 RangeShiftR/src/RScore/Population.cpp delete mode 100644 RangeShiftR/src/RScore/Population.h delete mode 100644 RangeShiftR/src/RScore/README.md delete mode 100644 RangeShiftR/src/RScore/RSrandom.cpp delete mode 100644 RangeShiftR/src/RScore/RSrandom.h delete mode 100644 RangeShiftR/src/RScore/RandomCheck.cpp delete mode 100644 RangeShiftR/src/RScore/RandomCheck.h delete mode 100644 RangeShiftR/src/RScore/Species.cpp delete mode 100644 RangeShiftR/src/RScore/Species.h delete mode 100644 RangeShiftR/src/RScore/SubCommunity.cpp delete mode 100644 RangeShiftR/src/RScore/SubCommunity.h diff --git a/RangeShiftR/src/RScore/.gitignore b/RangeShiftR/src/RScore/.gitignore deleted file mode 100644 index 31831ca..0000000 --- a/RangeShiftR/src/RScore/.gitignore +++ /dev/null @@ -1,85 +0,0 @@ -.gitignore -#README.md - -# CodeLite -/.build-debug/ -/Debug/ -/Release/ -/RNG_test/ -.codelite/ -compile_commands.json -Makefile -.build-release/ -build-Release/ -*.txt -*.project -*.workspace -*.mk -*.txt -*.tags - -# Hidden source -/RangeShiftR/src/.* - -# Windows files -/RangeShiftR/src/*.dll - -# History files -.Rhistory -.Rapp.history - -# RStudio files -.Rproj.user/ -/RangeShiftR/.Rproj.user/ -#/RangeShiftR/RangeShiftR.Rproj -/RangeShiftR/Read-and-delete-me -/RangeShiftR/.Rhistory -#/RangeShiftR/.Rbuildignore - -# Session Data files -.RData -tags - -# User-specific files -.Ruserdata - -# Example code in package build process -*-Ex.R - -# Output files from R CMD build -*.tar.gz -/RangeShiftR/src/*.o -/RangeShiftR/src/RangeShiftR.so - - -# Windows files -/RangeShiftR/src/*.dll - -# Output files from R CMD check -/*.Rcheck/ - -# Output from Rcpp compile.attributes() -#/RangeShiftR/R/RcppExports.R -#/RangeShiftR/src/RcppExports.cpp - -# RStudio files -.Rproj.user/ - -# produced vignettes -vignettes/*.html -vignettes/*.pdf -#/RangeShiftR/man/ - -# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 -.httr-oauth - -# knitr and R markdown default cache directories -/*_cache/ -/cache/ - -# Temporary files created by R markdown -*.utf8.md -*.knit.md - -# compilation files -*.o diff --git a/RangeShiftR/src/RScore/Cell.cpp b/RangeShiftR/src/RScore/Cell.cpp deleted file mode 100644 index 1c0f937..0000000 --- a/RangeShiftR/src/RScore/Cell.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Cell.h" - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -// Cell functions - -Cell::Cell(int xx,int yy,intptr patch,int hab) -{ -x = xx; y = yy; -pPatch = patch; -envVal = 1.0; // default - no effect of any gradient -envDev = eps = 0.0; -habIxx.push_back(hab); -#if RSDEBUG -//DebugGUI(("Cell::Cell(): this=" + Int2Str((int)this) -// + " x=" + Int2Str(x) + " y=" + Int2Str(y) -// + " habIndex=" + Int2Str(habIndex) -//).c_str()); -#endif -visits = 0; -smsData = 0; -} - -Cell::Cell(int xx,int yy,intptr patch,float hab) -{ -x = xx; y = yy; -pPatch = patch; -envVal = 1.0; // default - no effect of any gradient -envDev = eps = 0.0; -habitats.push_back(hab); -visits = 0; -smsData = 0; -} - -Cell::~Cell() { -#if RSDEBUG -//DEBUGLOG << "Cell::~Cell(): this = " << this << " smsData = " << smsData << endl; -#endif -habIxx.clear(); -habitats.clear(); -if (smsData != 0) { - if (smsData->effcosts != 0) delete smsData->effcosts; - delete smsData; -} -#if RSDEBUG -//DEBUGLOG << "Cell::~Cell(): deleted" << endl; -#endif -} - -void Cell::setHabIndex(short hx) { -#if RSDEBUG -//DebugGUI(("Cell::setHabIndex(): this=" + Int2Str((int)this) -// + " x=" + Int2Str(x) + " y=" + Int2Str(y) -// + " habIx=" + Int2Str(habIx) -//).c_str()); -#endif -if (hx < 0) habIxx.push_back(0); -else habIxx.push_back(hx); -} - -void Cell::changeHabIndex(short ix,short hx) { -if (ix >= 0 && ix < (short)habIxx.size() && hx >= 0) habIxx[ix] = hx; -else habIxx[ix] = 0; -} - -int Cell::getHabIndex(int ix) { -if (ix < 0 || ix >= (int)habIxx.size()) - // nodata cell OR should not occur, but treat as such - return -1; -else return habIxx[ix]; -} -int Cell::nHabitats(void) { -int nh = (int)habIxx.size(); -if ((int)habitats.size() > nh) nh = (int)habitats.size(); -return nh; -} - -void Cell::setHabitat(float q) { -if (q >= 0.0 && q <= 100.0) habitats.push_back(q); -else habitats.push_back(0.0); -} - -float Cell::getHabitat(int ix) { -if (ix < 0 || ix >= (int)habitats.size()) - // nodata cell OR should not occur, but treat as such - return -1.0; -else return habitats[ix]; -} - -void Cell::setPatch(intptr p) { -pPatch = p; -} -intptr Cell::getPatch(void) -{ -#if RSDEBUG -//DebugGUI(("Cell::getPatch(): this=" + Int2Str((int)this) -// + " x=" + Int2Str(x) + " y=" + Int2Str(y) -// + " habIxx[0]=" + Int2Str(habIxx[0]) + " pPatch=" + Int2Str(pPatch) -//).c_str()); -#endif -return pPatch; -} - -locn Cell::getLocn(void) { locn q; q.x = x; q.y = y; return q; } - -void Cell::setEnvDev(float d) { envDev = d; } - -float Cell::getEnvDev(void) { return envDev; } - -void Cell::setEnvVal(float e) { -if (e >= 0.0) envVal = e; -} - -float Cell::getEnvVal(void) { return envVal; } - -void Cell::updateEps(float ac,float randpart) { -eps = eps*ac + randpart; -} - -float Cell::getEps(void) { return eps; } - -// Functions to handle costs for SMS - -int Cell::getCost(void) { -int c; -if (smsData == 0) c = 0; // costs not yet set up -else c = smsData->cost; -return c; -} - -void Cell::setCost(int c) { -if (smsData == 0) { - smsData = new smscosts; - smsData->effcosts = 0; -} -smsData->cost = c; -} - -// Reset the cost and the effective cost of the cell -void Cell::resetCost(void) { -if (smsData != 0) { resetEffCosts(); delete smsData; } -smsData = 0; -} - -array3x3f Cell::getEffCosts(void) { -array3x3f a; -if (smsData == 0 || smsData->effcosts == 0) { // effective costs have not been calculated - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - a.cell[i][j] = -1.0; - } - } -} -else - a = *smsData->effcosts; -return a; -} - -void Cell::setEffCosts(array3x3f a) { -if (smsData->effcosts == 0) smsData->effcosts = new array3x3f; -*smsData->effcosts = a; -} - -// Reset the effective cost, but not the cost, of the cell -void Cell::resetEffCosts(void) { -if (smsData != 0) { - if (smsData->effcosts != 0) { - delete smsData->effcosts; - smsData->effcosts = 0; - } -} -} - -void Cell::resetVisits(void) { visits = 0; } -void Cell::incrVisits(void) { visits++; } -unsigned long int Cell::getVisits(void) { return visits; } - -//--------------------------------------------------------------------------- - -// Initial species distribution cell functions - -DistCell::DistCell(int xx,int yy) { -x = xx; y = yy; initialise = false; -} - -DistCell::~DistCell() { - -} - -void DistCell::setCell(bool init) { -initialise = init; -} - -bool DistCell::toInitialise(locn loc) { -if (loc.x == x && loc.y == y) return initialise; -else return false; -} - -bool DistCell::selected(void) { return initialise; } - -locn DistCell::getLocn(void) { -locn loc; loc.x = x; loc.y = y; return loc; -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - - - - diff --git a/RangeShiftR/src/RScore/Cell.h b/RangeShiftR/src/RScore/Cell.h deleted file mode 100644 index 5382a1e..0000000 --- a/RangeShiftR/src/RScore/Cell.h +++ /dev/null @@ -1,174 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Cell - -Implements the following classes: - -Cell - Landscape cell - -DistCell - Initial species distribution cell - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 14 January 2021 by Steve Palmer - -------------------------------------------------------------------------------*/ - -#ifndef CellH -#define CellH - -#include -using namespace std; - -#include "Parameters.h" - -//--------------------------------------------------------------------------- - -struct array3x3f { float cell[3][3]; }; // neighbourhood cell array (SMS) -struct smscosts { int cost; array3x3f *effcosts; }; // cell costs for SMS - -// Landscape cell - -class Cell{ -public: - Cell( // Constructor for habitat codes - int, // x co-ordinate - int, // y co-ordinate - intptr, // pointer (cast as integer) to the Patch to which Cell belongs - int // habitat index number - ); - Cell( // Constructor for habitat % cover or habitat quality - int, // x co-ordinate - int, // y co-ordinate - intptr, // pointer (cast as integer) to the Patch to which Cell belongs - float // habitat proportion or cell quality score - ); - ~Cell(); - void setHabIndex( - short // habitat index number - ); - void changeHabIndex( - short, // landscape change number - short // habitat index number - ); - int getHabIndex( - int // landscape change number - ); - int nHabitats(void); - void setHabitat( - float // habitat proportions or cell quality score - ); - float getHabitat( // Get habitat proportion / quality score - int // habitat index number / landscape change number - ); - void setPatch( - intptr // pointer (cast as integer) to the Patch to which Cell belongs - ); - intptr getPatch(void); - locn getLocn(void); - void setEnvDev( - float // local environmental deviation - ); - float getEnvDev(void); - void setEnvVal( - float // environmental value - ); - float getEnvVal(void); - void updateEps( // Update local environmental stochasticity (epsilon) - float, // autocorrelation coefficient - float // random adjustment - ); - float getEps(void); - void setCost( - int // cost value for SMS - ); - int getCost(void); - void resetCost(void); - array3x3f getEffCosts(void); - void setEffCosts( - array3x3f // 3 x 3 array of effective costs for neighbouring cells - ); - void resetEffCosts(void); // Reset the effective cost, but not the cost, of the cell - void resetVisits(void); - void incrVisits(void); - unsigned long int getVisits(void); - -private: - int x,y; // cell co-ordinates - intptr pPatch; // pointer (cast as integer) to the Patch to which cell belongs - // NOTE: THE FOLLOWING ENVIRONMENTAL VARIABLES COULD BE COMBINED IN A STRUCTURE - // AND ACCESSED BY A POINTER ... - float envVal; // environmental value, representing one of: - // gradient in K, r or extinction probability - float envDev; // local environmental deviation (static, in range -1.0 to +1.0) - float eps; // local environmental stochasticity (epsilon) (dynamic, from N(0,std)) - unsigned long int visits; // no. of times square is visited by dispersers - smscosts *smsData; - - vector habIxx; // habitat indices (rasterType=0) - // NB initially, habitat codes are loaded, then converted to index nos. - // once landscape is fully loaded - vector habitats; // habitat proportions (rasterType=1) or quality (rasterType=2) -}; - -//--------------------------------------------------------------------------- - -// Initial species distribution cell - -class DistCell{ -public: - DistCell( - int, // x co-ordinate - int // y co-ordinate - ); - ~DistCell(); - void setCell( - bool // TRUE if cell is to be initialised, FALSE if not - ); - bool toInitialise( - locn // structure holding co-ordinates of cell - ); - bool selected(void); - locn getLocn(void); - -private: - int x,y; // cell co-ordinates - bool initialise; // cell is to be initialised - -}; - -#if RSDEBUG -extern void DebugGUI(string); -#endif - -//--------------------------------------------------------------------------- - -#endif diff --git a/RangeShiftR/src/RScore/Community.cpp b/RangeShiftR/src/RScore/Community.cpp deleted file mode 100644 index 12b190c..0000000 --- a/RangeShiftR/src/RScore/Community.cpp +++ /dev/null @@ -1,1717 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Community.h" - -//--------------------------------------------------------------------------- - - -ofstream outrange; -ofstream outoccup,outsuit; -ofstream outtraitsrows; - -//--------------------------------------------------------------------------- - -Community::Community(Landscape *pLand) { -pLandscape = pLand; -indIx = 0; -} - -Community::~Community(void) { -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - delete subComms[i]; -} -subComms.clear(); -} - -SubCommunity* Community::addSubComm(Patch *pPch,int num) { -int nsubcomms = (int)subComms.size(); -subComms.push_back(new SubCommunity(pPch,num)); -return subComms[nsubcomms]; -} - -void Community::initialise(Species *pSpecies,int year) -{ - -int nsubcomms,npatches,ndistcells,spratio,patchnum,rr = 0; -locn distloc; -patchData pch; -patchLimits limits; -intptr ppatch,subcomm; -std::vector subcomms; -std::vector selected; -SubCommunity *pSubComm; -Patch *pPatch; -Cell *pCell; -landParams ppLand = pLandscape->getLandParams(); -initParams init = paramsInit->getInit(); - -nsubcomms = (int)subComms.size(); - -spratio = ppLand.spResol / ppLand.resol; - -#if RSDEBUG -DEBUGLOG << endl << "Community::initialise(): this=" << this - << " seedType=" << init.seedType << " freeType=" << init.freeType - << " minSeedX=" << init.minSeedX << " minSeedY=" << init.minSeedY - << " maxSeedX=" << init.maxSeedX << " maxSeedY=" << init.maxSeedY - << " indsFile=" << init.indsFile - << " nsubcomms=" << nsubcomms << " spratio=" << spratio - << endl; -#endif - -switch (init.seedType) { - -case 0: // free initialisation - - switch (init.freeType) { - - case 0: // random - // determine no. of patches / cells within the specified initialisation limits - // and record their corresponding sub-communities in a list - // parallel list records which have been selected - npatches = pLandscape->patchCount(); - limits.xMin = init.minSeedX; limits.xMax = init.maxSeedX; - limits.yMin = init.minSeedY; limits.yMax = init.maxSeedY; - for (int i = 0; i < npatches; i++) { - pch = pLandscape->getPatchData(i); - if (pch.pPatch->withinLimits(limits)) { - if (ppLand.patchModel) { - if (pch.pPatch->getPatchNum() != 0) { - subcomms.push_back(pch.pPatch->getSubComm()); - selected.push_back(false); - } - } - else { // cell-based model - is cell(patch) suitable - if (pch.pPatch->getK() > 0.0) - { - subcomms.push_back(pch.pPatch->getSubComm()); - selected.push_back(false); - } - } - } - } - // select specified no. of patches/cells at random - npatches = (int)subcomms.size(); - if (init.nSeedPatches > npatches/2) { // use backwards selection method - for (int i = 0; i < npatches; i++) selected[i] = true; - for (int i = 0; i < (npatches-init.nSeedPatches); i++) { - do { - rr = pRandom->IRandom(0,npatches-1); - } while (!selected[rr]); - selected[rr] = false; - } - } - else { // use forwards selection method - for (int i = 0; i < init.nSeedPatches; i++) { - do { - rr = pRandom->IRandom(0,npatches-1); - } while (selected[rr]); - selected[rr] = true; - } - } - // selected sub-communities for initialisation - for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->setInitial(false); - } - for (int i = 0; i < npatches; i++) { - if (selected[i]) { - pSubComm = (SubCommunity*)subcomms[i]; - pSubComm->setInitial(true); - } - } - break; - - case 1: // all suitable patches/cells - npatches = pLandscape->patchCount(); - limits.xMin = init.minSeedX; limits.xMax = init.maxSeedX; - limits.yMin = init.minSeedY; limits.yMax = init.maxSeedY; - for (int i = 0; i < npatches; i++) { - pch = pLandscape->getPatchData(i); - if (pch.pPatch->withinLimits(limits)) { - patchnum = pch.pPatch->getPatchNum(); - if (patchnum != 0) { - if (pch.pPatch->getK() > 0.0) - { // patch is suitable - subcomm = pch.pPatch->getSubComm(); - if (subcomm == 0) { - // create a sub-community in the patch - pSubComm = addSubComm(pch.pPatch,patchnum); - } - else { - pSubComm = (SubCommunity*)subcomm; - } - pSubComm->setInitial(true); - } - } - } - } - - break; - - case 2: // manually selected patches/cells - break; - - } // end of switch (init.freeType) - nsubcomms = (int)subComms.size(); - for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->initialise(pLandscape,pSpecies); - } - break; - -case 1: // from species distribution - if (ppLand.spDist) - { - // deselect all existing sub-communities - for (int i = 0; i < nsubcomms; i++) { - subComms[i]->setInitial(false); - } - // initialise from loaded species distribution - switch (init.spDistType) { - case 0: // all presence cells - pLandscape->setDistribution(pSpecies,0); // activate all patches - break; - case 1: // some randomly selected presence cells - pLandscape->setDistribution(pSpecies,init.nSpDistPatches); // activate random patches - break; - case 2: // manually selected presence cells - // cells have already been identified - no further action here - break; - } - - // THE FOLLOWING WILL HAVE TO BE CHANGED FOR MULTIPLE SPECIES... - ndistcells = pLandscape->distCellCount(0); - for (int i = 0; i < ndistcells; i++) { - distloc = pLandscape->getSelectedDistnCell(0,i); - if (distloc.x >= 0) { // distribution cell is selected - // process each landscape cell within the distribution cell - for (int x = 0; x < spratio; x++) { - for (int y = 0; y < spratio; y++) { - pCell = pLandscape->findCell(distloc.x*spratio+x,distloc.y*spratio+y); - if (pCell != 0) { // not a no-data cell - ppatch = pCell->getPatch(); - if (ppatch != 0) { - pPatch = (Patch*)ppatch; - if (pPatch->getSeqNum() != 0) { // not the matrix patch - subcomm = pPatch->getSubComm(); - if (subcomm != 0) { - pSubComm = (SubCommunity*)subcomm; - pSubComm->setInitial(true); - } - } - } - } - } - } - } - } - - nsubcomms = (int)subComms.size(); - for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->initialise(pLandscape,pSpecies); - } - } - else { - // WHAT HAPPENS IF INITIAL DISTRIBUTION IS NOT LOADED ??? .... - // should not occur - take no action - no initialisation will occur - } - break; - -case 2: // initial individuals in specified patches/cells - if (year < 0) { - // initialise matrix sub-community only - subComms[0]->initialise(pLandscape,pSpecies); - indIx = 0; // reset index for initial individuals - } - else { // add any initial individuals for the current year - initInd iind; iind.year = 0; - int ninds = paramsInit->numInitInds(); - while (indIx < ninds && iind.year <= year) { - iind = paramsInit->getInitInd(indIx); - while (iind.year == year) { -#if RSDEBUG -//DEBUGLOG << "Community::initialise(): year=" << year -// << " indIx=" << indIx << " iind.year=" << iind.year -// << " iind.patchID=" << iind.patchID << " iind.x=" << iind.x << " iind.y=" << iind.y -// << " iind.sex=" << iind.sex << " iind.age=" << iind.age << " iind.stage=" << iind.stage -// << endl; -#endif - if (ppLand.patchModel) { - if (pLandscape->existsPatch(iind.patchID)) { - pPatch = pLandscape->findPatch(iind.patchID); - if (pPatch->getK() > 0.0) - { // patch is suitable - subcomm = pPatch->getSubComm(); - if (subcomm == 0) { - // create a sub-community in the patch - pSubComm = addSubComm(pPatch,iind.patchID); - } - else { - pSubComm = (SubCommunity*)subcomm; - } - pSubComm->initialInd(pLandscape,pSpecies,pPatch,pPatch->getRandomCell(),indIx); - } - } - } - else { // cell-based model - pCell = pLandscape->findCell(iind.x,iind.y); - if (pCell != 0) { - intptr ppatch = pCell->getPatch(); - if (ppatch != 0) { - pPatch = (Patch*)ppatch; - if (pPatch->getK() > 0.0) - { // patch is suitable - subcomm = pPatch->getSubComm(); - if (subcomm == 0) { - // create a sub-community in the patch - pSubComm = addSubComm(pPatch,iind.patchID); - } - else { - pSubComm = (SubCommunity*)subcomm; - } - pSubComm->initialInd(pLandscape,pSpecies,pPatch,pCell,indIx); - } - } - } - } - indIx++; - if (indIx < ninds) { - iind = paramsInit->getInitInd(indIx); - } - else { - iind.year = 99999999; - } - } - } - } - break; - -case 3: // from file - // this condition cannot occur here, as init.seedType will have been changed to 0 or 1 - // when the initialisation file was read - break; - -} // end of switch (init.seedType) - -#if RSDEBUG -DEBUGLOG << "Community::initialise(): this=" << this - << " nsubcomms=" << nsubcomms - << endl; -#endif - -} - -// Add manually selected patches/cells to the selected set for initialisation -void Community::addManuallySelected(void) { -int npatches; -intptr subcomm,patch; -locn initloc; -Cell *pCell; -Patch *pPatch; -SubCommunity *pSubComm; - -landParams ppLand = pLandscape->getLandParams(); - -npatches = pLandscape->initCellCount(); // no. of patches/cells specified -#if RSDEBUG -DEBUGLOG << "Community::addManuallySelected(): this = " << this - << " npatches = " << npatches << endl; -#endif -// identify sub-communities to be initialised -if (ppLand.patchModel) { - for (int i = 0; i < npatches; i++) { - initloc = pLandscape->getInitCell(i); // patch number held in x-coord of list - pPatch = pLandscape->findPatch(initloc.x); - if (pPatch != 0) { - subcomm = pPatch->getSubComm(); - if (subcomm != 0) { - pSubComm = (SubCommunity*)subcomm; - pSubComm->setInitial(true); - } - } - } -} -else { // cell-based model - for (int i = 0; i < npatches; i++) { - initloc = pLandscape->getInitCell(i); - if (initloc.x >= 0 && initloc.x < ppLand.dimX - && initloc.y >= 0 && initloc.y < ppLand.dimY) { - pCell = pLandscape->findCell(initloc.x,initloc.y); - if (pCell != 0) { // not no-data cell - patch = pCell->getPatch(); -#if RSDEBUG -DEBUGLOG << "Community::initialise(): i = " << i - << " x = " << initloc.x << " y = " << initloc.y - << " pCell = " << pCell << " patch = " << patch - << endl; -#endif - if (patch != 0) { - pPatch = (Patch*)patch; - subcomm = pPatch->getSubComm(); -#if RSDEBUG -DEBUGLOG << "Community::initialise(): i = " << i - << " pPatch = " << pPatch << " subcomm = " << subcomm - << endl; -#endif - if (subcomm != 0) { - pSubComm = (SubCommunity*)subcomm; - pSubComm->setInitial(true); -#if RSDEBUG -DEBUGLOG << "Community::initialise(): i = " << i - << " pSubComm = " << pSubComm - << endl; -#endif - } - } - } - } - } -} -} - -void Community::resetPopns(void) { -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->resetPopns(); -} -// reset the individual ids to start from zero -Individual::indCounter = 0; -} - -void Community::localExtinction(int option) { -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - if (subComms[i]->getNum() > 0) { // except in matrix - subComms[i]->localExtinction(option); - } -} -} - -void Community::patchChanges(void) { -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - if (subComms[i]->getNum() > 0) { // except in matrix - subComms[i]->patchChange(); - } -} -} - -void Community::reproduction(int yr) -{ -float eps = 0.0; // epsilon for environmental stochasticity -landParams land = pLandscape->getLandParams(); -envStochParams env = paramsStoch->getStoch(); -int nsubcomms = (int)subComms.size(); -#if RSDEBUG -DEBUGLOG << "Community::reproduction(): this=" << this - << " nsubcomms=" << nsubcomms << endl; -#endif - -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - if (env.stoch) { - if (!env.local) { // global stochasticty - eps = pLandscape->getGlobalStoch(yr); - } - } - subComms[i]->reproduction(land.resol,eps,land.rasterType,land.patchModel); -} -#if RSDEBUG -DEBUGLOG << "Community::reproduction(): finished" << endl; -#endif -} - -void Community::emigration(void) -{ -int nsubcomms = (int)subComms.size(); -#if RSDEBUG -DEBUGLOG << "Community::emigration(): this=" << this - << " nsubcomms=" << nsubcomms << endl; -#endif -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->emigration(); -} -#if RSDEBUG -DEBUGLOG << "Community::emigration(): finished" << endl; -#endif -} - -#if RS_RCPP // included also SEASONAL -void Community::dispersal(short landIx,short nextseason) -#else -void Community::dispersal(short landIx) -#endif // SEASONAL || RS_RCPP -{ -#if RSDEBUG -int t0,t1,t2; -t0 = time(0); -#endif - -simParams sim = paramsSim->getSim(); - -int nsubcomms = (int)subComms.size(); -// initiate dispersal - all emigrants leave their natal community and join matrix community -SubCommunity *matrix = subComms[0]; // matrix community is always the first -for (int i = 0; i < nsubcomms; i++) { // all populations - subComms[i]->initiateDispersal(matrix); -} -#if RSDEBUG -t1 = time(0); -DEBUGLOG << "Community::dispersal(): this=" << this - << " nsubcomms=" << nsubcomms << " initiation time=" << t1-t0 << endl; -#endif - -// dispersal is undertaken by all individuals now in the matrix patch -// (even if not physically in the matrix) -int ndispersers = 0; -do { - for (int i = 0; i < nsubcomms; i++) { // all populations - subComms[i]->resetPossSettlers(); - } -#if RSDEBUG -//DEBUGLOG << "Community::dispersal() 1111: ndispersers=" << ndispersers << endl; -#endif -#if RS_RCPP // included also SEASONAL - ndispersers = matrix->transfer(pLandscape,landIx,nextseason); -#else - ndispersers = matrix->transfer(pLandscape,landIx); -#endif // SEASONAL || RS_RCPP -#if RSDEBUG -//DEBUGLOG << "Community::dispersal() 2222: ndispersers=" << ndispersers << endl; -#endif - matrix->completeDispersal(pLandscape,sim.outConnect); -#if RSDEBUG -//DEBUGLOG << "Community::dispersal() 3333: ndispersers=" << ndispersers << endl; -#endif -} while (ndispersers > 0); - -#if RSDEBUG -DEBUGLOG << "Community::dispersal(): matrix=" << matrix << endl; -t2 = time(0); -DEBUGLOG << "Community::dispersal(): transfer time=" << t2-t1 << endl; -#endif - -#if RSDEBUG -//int t3 = time(0); -//DEBUGLOG << "Community::dispersal(): completion time = " << t3-t2 << endl; -#endif - -} - -void Community::survival(short part,short option0,short option1) -{ -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all communities (including in matrix) - subComms[i]->survival(part,option0,option1); -} -} - -void Community::ageIncrement(void) { -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all communities (including in matrix) - subComms[i]->ageIncrement(); -} -} - -// Calculate total no. of individuals of all species -int Community::totalInds(void) { -popStats p; -int total = 0; -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all communities (including in matrix) - p = subComms[i]->getPopStats(); - total += p.nInds; -} -return total; -} - -// Find the population of a given species in a given patch -Population* Community::findPop(Species *pSp,Patch *pPch) { -Population *pPop = 0; -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all communities (including in matrix) - pPop = subComms[i]->findPop(pSp,pPch); - if (pPop != 0) break; -} -return pPop; -} - -//--------------------------------------------------------------------------- -void Community::createOccupancy(int nrows,int reps) { -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { - subComms[i]->createOccupancy(nrows); -} -// Initialise array for occupancy of suitable cells/patches -occSuit = new float *[nrows]; -for (int i = 0; i < nrows; i++) -{ - occSuit[i] = new float[reps]; - for (int ii = 0; ii < reps; ii++) occSuit[i][ii] = 0.0; -} -} - -void Community::updateOccupancy(int row,int rep) -{ -#if RSDEBUG -DEBUGLOG << "Community::updateOccupancy(): row=" << row << endl; -#endif -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { - subComms[i]->updateOccupancy(row); -} - -commStats s = getStats(); -occSuit[row][rep] = (float)s.occupied / (float)s.suitable; - -} - -void Community::deleteOccupancy(int nrows) { -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { - subComms[i]->deleteOccupancy(); -} - -for(int i = 0; i < nrows; i++) - delete[] occSuit[i]; -delete[] occSuit; - -} - -//--------------------------------------------------------------------------- -// Count no. of sub-communities (suitable patches) and those occupied (non-zero populations) -// Determine range margins -commStats Community::getStats(void) -{ -commStats s; -landParams ppLand = pLandscape->getLandParams(); -s.ninds = s.nnonjuvs = s.suitable = s.occupied = 0; -s.minX = ppLand.maxX; s.minY = ppLand.maxY; s.maxX = s.maxY = 0; -float localK; -popStats patchPop; -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - patchPop = subComms[i]->getPopStats(); - s.ninds += patchPop.nInds; - s.nnonjuvs += patchPop.nNonJuvs; -#if RSDEBUG -//DEBUGLOG << "Community::getStats(): i = " << i -// << " pSpecies = " << patchPop.pSpecies << " pPatch = " << patchPop.pPatch -// << " nInds = " << patchPop.nInds << endl; -#endif - if (patchPop.pPatch != 0) { // not the matrix patch -#if RSDEBUG -//DEBUGLOG << "Community::getStats(): i = " << i -// << " patchNum = " << patchPop.pPatch->getPatchNum() << endl; -#endif - if (patchPop.pPatch->getPatchNum() != 0) { // not matrix patch - localK = patchPop.pPatch->getK(); -#if RSDEBUG -//DEBUGLOG << "Community::getStats(): i= " << i -// << " pSpecies= " << patchPop.pSpecies << " pPatch= " << patchPop.pPatch -// << " patchNum= " << patchPop.pPatch->getPatchNum() << " localK= " << localK -// << " nInds= " << patchPop.nInds << " breeding= " << (int)patchPop.breeding -// << endl; -#endif - if (localK > 0.0) s.suitable++; - if (patchPop.nInds > 0 && patchPop.breeding) { - s.occupied++; - patchLimits pchlim = patchPop.pPatch->getLimits(); - if (pchlim.xMin < s.minX) s.minX = pchlim.xMin; - if (pchlim.xMax > s.maxX) s.maxX = pchlim.xMax; - if (pchlim.yMin < s.minY) s.minY = pchlim.yMin; - if (pchlim.yMax > s.maxY) s.maxY = pchlim.yMax; - } - } - } -} -return s; -} - -//--------------------------------------------------------------------------- - -// Functions to control production of output files - -// Open population file and write header record -bool Community::outPopHeaders(Species *pSpecies,int option) { -return subComms[0]->outPopHeaders(pLandscape,pSpecies,option); -} - -// Write records to population file -void Community::outPop(int rep,int yr,int gen) -{ -// generate output for each sub-community (patch) in the community -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->outPop(pLandscape,rep,yr,gen); -} - -} - - -// Write records to individuals file -void Community::outInds(int rep, int yr, int gen,int landNr) { - -if (landNr >= 0) { // open the file - subComms[0]->outInds(pLandscape,rep,yr,gen,landNr); - return; -} -if (landNr == -999) { // close the file - subComms[0]->outInds(pLandscape,rep,yr,gen,-999); - return; -} -// generate output for each sub-community (patch) in the community -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->outInds(pLandscape,rep,yr,gen,landNr); -} -} - -// Write records to genetics file -void Community::outGenetics(int rep, int yr, int gen,int landNr) { -//landParams ppLand = pLandscape->getLandParams(); -if (landNr >= 0) { // open the file - subComms[0]->outGenetics(rep,yr,gen,landNr); - return; -} -if (landNr == -999) { // close the file - subComms[0]->outGenetics(rep,yr,gen,landNr); - return; -} -// generate output for each sub-community (patch) in the community -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->outGenetics(rep,yr,gen,landNr); -} -} - -// Open range file and write header record -bool Community::outRangeHeaders(Species *pSpecies,int landNr) -{ - -if (landNr == -999) { // close the file - if (outrange.is_open()) outrange.close(); - outrange.clear(); - return true; -} - -string name; -landParams ppLand = pLandscape->getLandParams(); -envStochParams env = paramsStoch->getStoch(); -simParams sim = paramsSim->getSim(); - -// NEED TO REPLACE CONDITIONAL COLUMNS BASED ON ATTRIBUTES OF ONE SPECIES TO COVER -// ATTRIBUTES OF *ALL* SPECIES AS DETECTED AT MODEL LEVEL -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); - -#if RSDEBUG -DEBUGLOG << "Community::outRangeHeaders(): simulation=" << sim.simulation - << " sim.batchMode=" << sim.batchMode - << " landNr=" << landNr << endl; -#endif - -if (sim.batchMode) { - name = paramsSim->getDir(2) -#if RS_RCPP - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" - + Int2Str(landNr) -#else - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" - + Int2Str(landNr) -#endif - + "_Range.txt"; -} -else { - name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) + "_Range.txt"; -} -outrange.open(name.c_str()); -outrange << "Rep\tYear\tRepSeason"; -if (env.stoch && !env.local) outrange << "\tEpsilon"; - -outrange << "\tNInds"; -if (dem.stageStruct) { - for (int i = 1; i < sstruct.nStages; i++) outrange << "\tNInd_stage" << i; - outrange << "\tNJuvs"; -} -if (ppLand.patchModel) outrange << "\tNOccupPatches"; -else outrange << "\tNOccupCells"; -outrange << "\tOccup/Suit\tmin_X\tmax_X\tmin_Y\tmax_Y"; - -if (emig.indVar) { - if (emig.sexDep) { - if (emig.densDep) { - outrange << "\tF_meanD0\tF_stdD0\tM_meanD0\tM_stdD0"; - outrange << "\tF_meanAlpha\tF_stdAlpha\tM_meanAlpha\tM_stdAlpha"; - outrange << "\tF_meanBeta\tF_stdBeta\tM_meanBeta\tM_stdBeta"; - } - else { - outrange << "\tF_meanEP\tF_stdEP\tM_meanEP\tM_stdEP"; - } - } - else { - if (emig.densDep) { - outrange << "\tmeanD0\tstdD0\tmeanAlpha\tstdAlpha"; - outrange << "\tmeanBeta\tstdBeta"; - } - else { - outrange << "\tmeanEP\tstdEP"; - } - } -} -if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 1) { - outrange << "\tmeanDP\tstdDP\tmeanGB\tstdGB"; - outrange << "\tmeanAlphaDB\tstdAlphaDB\tmeanBetaDB\tstdBetaDB"; - } - if (trfr.moveType == 2) { - outrange << "\tmeanStepLength\tstdStepLength\tmeanRho\tstdRho"; - } - } - else { - if (trfr.sexDep) { - outrange << "\tF_mean_distI\tF_std_distI\tM_mean_distI\tM_std_distI"; - if (trfr.twinKern) - outrange << "\tF_mean_distII\tF_std_distII\tM_mean_distII\tM_std_distII" - << "\tF_meanPfirstKernel\tF_stdPfirstKernel" - << "\tM_meanPfirstKernel\tM_stdPfirstKernel"; - } - else { - outrange << "\tmean_distI\tstd_distI"; - if (trfr.twinKern) - outrange << "\tmean_distII\tstd_distII\tmeanPfirstKernel\tstdPfirstKernel"; - } - } -} -if (sett.indVar) { - if (sett.sexDep) { - outrange << "\tF_meanS0\tF_stdS0\tM_meanS0\tM_stdS0"; - outrange << "\tF_meanAlphaS\tF_stdAlphaS\tM_meanAlphaS\tM_stdAlphaS"; - outrange << "\tF_meanBetaS\tF_stdBetaS\tM_meanBetaS\tM_stdBetaS"; - - } - else { - outrange << "\tmeanS0\tstdS0"; - outrange << "\tmeanAlphaS\tstdAlphaS"; - outrange << "\tmeanBetaS\tstdBetaS"; - } -} -outrange << endl; - -#if RSDEBUG -DEBUGLOG << "Community::outRangeHeaders(): finished" << endl; -#endif - -return outrange.is_open(); -} - -// Write record to range file -void Community::outRange(Species *pSpecies,int rep,int yr,int gen) -{ -#if RSDEBUG -DEBUGLOG << "Community::outRange(): rep=" << rep - << " yr=" << yr << " gen=" << gen << endl; -#endif - -landParams ppLand = pLandscape->getLandParams(); -envStochParams env = paramsStoch->getStoch(); - -// NEED TO REPLACE CONDITIONAL COLUMNS BASED ON ATTRIBUTES OF ONE SPECIES TO COVER -// ATTRIBUTES OF *ALL* SPECIES AS DETECTED AT MODEL LEVEL -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); - -outrange << rep << "\t" << yr << "\t" << gen; -if (env.stoch && !env.local) // write global environmental stochasticity - outrange << "\t" << pLandscape->getGlobalStoch(yr); - -commStats s = getStats(); - -if (dem.stageStruct) { - outrange << "\t" << s.nnonjuvs; - int stagepop; - int nsubcomms = (int)subComms.size(); - // all non-juvenile stages - for (int stg = 1; stg < sstruct.nStages; stg++) { - stagepop = 0; - for (int i = 0; i < nsubcomms; i++) { // all sub-communities - stagepop += subComms[i]->stagePop(stg); - } - outrange <<"\t" << stagepop; - } - // juveniles born in current reproductive season - stagepop = 0; - for (int i = 0; i < nsubcomms; i++) { // all sub-communities - stagepop += subComms[i]->stagePop(0); - } - outrange <<"\t" << stagepop; -} -else { // non-structured species - outrange << "\t" << s.ninds; -} - -float occsuit = 0.0; -if (s.suitable > 0) occsuit = (float)s.occupied / (float)s.suitable; -outrange << "\t" << s.occupied << "\t" << occsuit; -// RANGE MINIMA AND MAXIMA NEED TO BECOME A PROPERTY OF THE SPECIES -if (s.ninds > 0) { - landOrigin origin = pLandscape->getOrigin(); - outrange << "\t" << (float)s.minX * (float)ppLand.resol + origin.minEast - << "\t" << (float)(s.maxX+1) * (float)ppLand.resol + origin.minEast - << "\t" << (float)s.minY * (float)ppLand.resol + origin.minNorth - << "\t" << (float)(s.maxY+1) * (float)ppLand.resol + origin.minNorth; -} -else - outrange <<"\t0\t0\t0\t0"; - -if (emig.indVar || trfr.indVar || sett.indVar) { // output trait means - traitsums ts; - traitsums scts; // sub-community traits - traitCanvas tcanv; - int ngenes,popsize; - - tcanv.pcanvas[0] = NULL; - - for (int i = 0; i < NSEXES; i++) { - ts.ninds[i] = 0; - ts.sumD0[i] = ts.ssqD0[i] = 0.0; - ts.sumAlpha[i] = ts.ssqAlpha[i] = 0.0; ts.sumBeta[i] = ts.ssqBeta[i] = 0.0; - ts.sumDist1[i] = ts.ssqDist1[i] = 0.0; ts.sumDist2[i] = ts.ssqDist2[i] = 0.0; - ts.sumProp1[i] = ts.ssqProp1[i] = 0.0; - ts.sumDP[i] = ts.ssqDP[i] = 0.0; - ts.sumGB[i] = ts.ssqGB[i] = 0.0; - ts.sumAlphaDB[i] = ts.ssqAlphaDB[i] = 0.0; - ts.sumBetaDB[i] = ts.ssqBetaDB[i] = 0.0; - ts.sumStepL[i] = ts.ssqStepL[i] = 0.0; ts.sumRho[i] = ts.ssqRho[i] = 0.0; - ts.sumS0[i] = ts.ssqS0[i] = 0.0; - ts.sumAlphaS[i] = ts.ssqAlphaS[i] = 0.0; ts.sumBetaS[i] = ts.ssqBetaS[i] = 0.0; - } - - int nsubcomms = (int)subComms.size(); - for (int i = 0; i < nsubcomms; i++) { // all sub-communities (incl. matrix) - scts = subComms[i]->outTraits(tcanv,pLandscape,rep,yr,gen,true); - for (int j = 0; j < NSEXES; j++) { - ts.ninds[j] += scts.ninds[j]; - ts.sumD0[j] += scts.sumD0[j]; ts.ssqD0[j] += scts.ssqD0[j]; - ts.sumAlpha[j] += scts.sumAlpha[j]; ts.ssqAlpha[j] += scts.ssqAlpha[j]; - ts.sumBeta[j] += scts.sumBeta[j]; ts.ssqBeta[j] += scts.ssqBeta[j]; - ts.sumDist1[j] += scts.sumDist1[j]; ts.ssqDist1[j] += scts.ssqDist1[j]; - ts.sumDist2[j] += scts.sumDist2[j]; ts.ssqDist2[j] += scts.ssqDist2[j]; - ts.sumProp1[j] += scts.sumProp1[j]; ts.ssqProp1[j] += scts.ssqProp1[j]; - ts.sumDP[j] += scts.sumDP[j]; ts.ssqDP[j] += scts.ssqDP[j]; - ts.sumGB[j] += scts.sumGB[j]; ts.ssqGB[j] += scts.ssqGB[j]; - ts.sumAlphaDB[j] += scts.sumAlphaDB[j]; ts.ssqAlphaDB[j] += scts.ssqAlphaDB[j]; - ts.sumBetaDB[j] += scts.sumBetaDB[j]; ts.ssqBetaDB[j] += scts.ssqBetaDB[j]; - ts.sumStepL[j] += scts.sumStepL[j]; ts.ssqStepL[j] += scts.ssqStepL[j]; - ts.sumRho[j] += scts.sumRho[j]; ts.ssqRho[j] += scts.ssqRho[j]; - ts.sumS0[j] += scts.sumS0[j]; ts.ssqS0[j] += scts.ssqS0[j]; - ts.sumAlphaS[j] += scts.sumAlphaS[j]; ts.ssqAlphaS[j] += scts.ssqAlphaS[j]; - ts.sumBetaS[j] += scts.sumBetaS[j]; ts.ssqBetaS[j] += scts.ssqBetaS[j]; -#if RSDEBUG -//DEBUGLOG << "Community::outRange(): i=" << i << " j=" << j -// << " scts.ninds[j]=" << scts.ninds[j] -// << " scts.sumD0[j]=" << scts.sumD0[j] -// << " scts.ssqD0[j]=" << scts.ssqD0[j] -// << endl; -//DEBUGLOG << "Community::outRange(): i=" << i << " j=" << j -// << " ts.ninds[j]=" << ts.ninds[j] -// << " ts.sumD0[j]=" << ts.sumD0[j] << " ts.ssqD0[j]=" << ts.ssqD0[j] -// << endl; -#endif - } - } - - if (emig.indVar) { - if (emig.sexDep) { // must be a sexual species - ngenes = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ngenes = 1; - } - else { // sexual reproduction - ngenes = 1; - } - } - double mnD0[2],mnAlpha[2],mnBeta[2],sdD0[2],sdAlpha[2],sdBeta[2]; - for (int g = 0; g < ngenes; g++) { - mnD0[g] = mnAlpha[g] = mnBeta[g] = sdD0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - // individuals may have been counted by sex if there was - // sex dependency in another dispersal phase - if (ngenes == 2) popsize = ts.ninds[g]; - else popsize = ts.ninds[0] + ts.ninds[1]; - if (popsize > 0) { - mnD0[g] = ts.sumD0[g] / (double)popsize; - mnAlpha[g] = ts.sumAlpha[g] / (double)popsize; - mnBeta[g] = ts.sumBeta[g] / (double)popsize; - if (popsize > 1) { - sdD0[g] = ts.ssqD0[g]/(double)popsize - mnD0[g]*mnD0[g]; - if (sdD0[g] > 0.0) sdD0[g] = sqrt(sdD0[g]); else sdD0[g] = 0.0; - sdAlpha[g] = ts.ssqAlpha[g]/(double)popsize - mnAlpha[g]*mnAlpha[g]; - if (sdAlpha[g] > 0.0) sdAlpha[g] = sqrt(sdAlpha[g]); else sdAlpha[g] = 0.0; - sdBeta[g] = ts.ssqBeta[g]/(double)popsize - mnBeta[g]*mnBeta[g]; - if (sdBeta[g] > 0.0) sdBeta[g] = sqrt(sdBeta[g]); else sdBeta[g] = 0.0; - } - else { - sdD0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - } - } -#if RSDEBUG -//DEBUGLOG << "Community::outRange(): ngenes=" << ngenes << " g=" << g -// << " ts.ninds[g]=" << ts.ninds[g] -// << " ts.sumD0[g]=" << ts.sumD0[g] -// << " ts.ssqD0[g]=" << ts.ssqD0[g] -// << endl; -//DEBUGLOG << "Community::outRange(): popsize=" << popsize -// << " mnD0[g]" << mnD0[g] << " sdD0[g]" << sdD0[g] -// << endl; -#endif - } - if (emig.sexDep) { - outrange << "\t" << mnD0[0] << "\t" << sdD0[0]; - outrange << "\t" << mnD0[1] << "\t" << sdD0[1]; - if (emig.densDep) { - outrange << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outrange << "\t" << mnAlpha[1] << "\t" << sdAlpha[1]; - outrange << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - outrange << "\t" << mnBeta[1] << "\t" << sdBeta[1]; - } - } - else { // sex-independent - outrange << "\t" << mnD0[0] << "\t" << sdD0[0]; - if (emig.densDep) { - outrange << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outrange << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - } - } - } - - if (trfr.indVar) { - if (trfr.moveModel) { - // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT - ngenes = 1; - } - else { - if (trfr.sexDep) { // must be a sexual species - ngenes = 2; - } - else { - ngenes = 1; - } - } - double mnDist1[2],mnDist2[2],mnProp1[2],mnStepL[2],mnRho[2]; - double sdDist1[2],sdDist2[2],sdProp1[2],sdStepL[2],sdRho[2]; - double mnDP[2],mnGB[2],mnAlphaDB[2],mnBetaDB[2]; - double sdDP[2],sdGB[2],sdAlphaDB[2],sdBetaDB[2]; - for (int g = 0; g < ngenes; g++) { - mnDist1[g] = mnDist2[g] = mnProp1[g] = mnStepL[g] = mnRho[g] = 0.0; - sdDist1[g] = sdDist2[g] = sdProp1[g] = sdStepL[g] = sdRho[g] = 0.0; - mnDP[g] = mnGB[g] = mnAlphaDB[g] = mnBetaDB[g] = 0.0; - sdDP[g] = sdGB[g] = sdAlphaDB[g] = sdBetaDB[g] = 0.0; - // individuals may have been counted by sex if there was - // sex dependency in another dispersal phase - if (ngenes == 2) popsize = ts.ninds[g]; - else popsize = ts.ninds[0] + ts.ninds[1]; - if (popsize > 0) { - mnDist1[g] = ts.sumDist1[g] / (double)popsize; - mnDist2[g] = ts.sumDist2[g] / (double)popsize; - mnProp1[g] = ts.sumProp1[g] / (double)popsize; - mnStepL[g] = ts.sumStepL[g] / (double)popsize; - mnRho[g] = ts.sumRho[g] / (double)popsize; - mnDP[g] = ts.sumDP[g] / (double)popsize; - mnGB[g] = ts.sumGB[g] / (double)popsize; - mnAlphaDB[g] = ts.sumAlphaDB[g] / (double)popsize; - mnBetaDB[g] = ts.sumBetaDB[g] / (double)popsize; - if (popsize > 1) { - sdDist1[g] = ts.ssqDist1[g]/(double)popsize - mnDist1[g]*mnDist1[g]; - if (sdDist1[g] > 0.0) sdDist1[g] = sqrt(sdDist1[g]); else sdDist1[g] = 0.0; - sdDist2[g] = ts.ssqDist2[g]/(double)popsize - mnDist2[g]*mnDist2[g]; - if (sdDist2[g] > 0.0) sdDist2[g] = sqrt(sdDist2[g]); else sdDist2[g] = 0.0; - sdProp1[g] = ts.ssqProp1[g]/(double)popsize - mnProp1[g]*mnProp1[g]; - if (sdProp1[g] > 0.0) sdProp1[g] = sqrt(sdProp1[g]); else sdProp1[g] = 0.0; - sdStepL[g] = ts.ssqStepL[g]/(double)popsize - mnStepL[g]*mnStepL[g]; - if (sdStepL[g] > 0.0) sdStepL[g] = sqrt(sdStepL[g]); else sdStepL[g] = 0.0; - sdRho[g] = ts.ssqRho[g]/(double)popsize - mnRho[g]*mnRho[g]; - if (sdRho[g] > 0.0) sdRho[g] = sqrt(sdRho[g]); else sdRho[g] = 0.0; - sdDP[g] = ts.ssqDP[g]/(double)popsize - mnDP[g]*mnDP[g]; - if (sdDP[g] > 0.0) sdDP[g] = sqrt(sdDP[g]); else sdDP[g] = 0.0; - sdGB[g] = ts.ssqGB[g]/(double)popsize - mnGB[g]*mnGB[g]; - if (sdGB[g] > 0.0) sdGB[g] = sqrt(sdGB[g]); else sdGB[g] = 0.0; - sdAlphaDB[g] = ts.ssqAlphaDB[g]/(double)popsize - mnAlphaDB[g]*mnAlphaDB[g]; - if (sdAlphaDB[g] > 0.0) sdAlphaDB[g] = sqrt(sdAlphaDB[g]); else sdAlphaDB[g] = 0.0; - sdBetaDB[g] = ts.ssqBetaDB[g]/(double)popsize - mnBetaDB[g]*mnBetaDB[g]; - if (sdBetaDB[g] > 0.0) sdBetaDB[g] = sqrt(sdBetaDB[g]); else sdBetaDB[g] = 0.0; - } - } -#if RSDEBUG -//DEBUGLOG << "Community::outRange(): ngenes=" << ngenes << " g=" << g -// << " ts.ninds[g]=" << ts.ninds[g] -// << " ts.sumDP[g]=" << ts.sumDP[g] << " ts.ssqDP[g]=" << ts.ssqDP[g] -// << " ts.sumGB[g]=" << ts.sumGB[g] << " ts.ssqGB[g]=" << ts.ssqGB[g] -// << endl; -//DEBUGLOG << "Community::outRange(): popsize=" << popsize -// << " mnDP[g]" << mnDP[g] << " sdDP[g]" << sdDP[g] -// << " mnGB[g]" << mnGB[g] << " sdGB[g]" << sdGB[g] -// << endl; -#endif - } - if (trfr.moveModel) { - if (trfr.moveType == 1) { - outrange << "\t" << mnDP[0] << "\t" << sdDP[0]; - outrange << "\t" << mnGB[0] << "\t" << sdGB[0]; - outrange << "\t" << mnAlphaDB[0] << "\t" << sdAlphaDB[0]; - outrange << "\t" << mnBetaDB[0] << "\t" << sdBetaDB[0]; - } - if (trfr.moveType == 2) { - outrange << "\t" << mnStepL[0] << "\t" << sdStepL[0]; - outrange << "\t" << mnRho[0] << "\t" << sdRho[0]; - } - } - else { - if (trfr.sexDep) { - outrange << "\t" << mnDist1[0] << "\t" << sdDist1[0]; - outrange << "\t" << mnDist1[1] << "\t" << sdDist1[1]; - if (trfr.twinKern) - { - outrange << "\t" << mnDist2[0] << "\t" << sdDist2[0]; - outrange << "\t" << mnDist2[1] << "\t" << sdDist2[1]; - outrange << "\t" << mnProp1[0] << "\t" << sdProp1[0]; - outrange << "\t" << mnProp1[1] << "\t" << sdProp1[1]; - } - } - else { // sex-independent - outrange << "\t" << mnDist1[0] << "\t" << sdDist1[0]; - if (trfr.twinKern) - { - outrange << "\t" << mnDist2[0] << "\t" << sdDist2[0]; - outrange << "\t" << mnProp1[0] << "\t" << sdProp1[0]; - } - } - } - } - - if (sett.indVar) { - if (sett.sexDep) { // must be a sexual species - ngenes = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ngenes = 1; - } - else { // sexual reproduction - ngenes = 1; - } - } - // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT - double mnS0[2],mnAlpha[2],mnBeta[2],sdS0[2],sdAlpha[2],sdBeta[2]; - for (int g = 0; g < ngenes; g++) { - mnS0[g] = mnAlpha[g] = mnBeta[g] = sdS0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - // individuals may have been counted by sex if there was - // sex dependency in another dispersal phase - if (ngenes == 2) popsize = ts.ninds[g]; - else popsize = ts.ninds[0] + ts.ninds[1]; - if (popsize > 0) { - mnS0[g] = ts.sumS0[g] / (double)popsize; - mnAlpha[g] = ts.sumAlphaS[g] / (double)popsize; - mnBeta[g] = ts.sumBetaS[g] / (double)popsize; - if (popsize > 1) { - sdS0[g] = ts.ssqS0[g]/(double)popsize - mnS0[g]*mnS0[g]; - if (sdS0[g] > 0.0) sdS0[g] = sqrt(sdS0[g]); else sdS0[g] = 0.0; - sdAlpha[g] = ts.ssqAlphaS[g]/(double)popsize - mnAlpha[g]*mnAlpha[g]; - if (sdAlpha[g] > 0.0) sdAlpha[g] = sqrt(sdAlpha[g]); else sdAlpha[g] = 0.0; - sdBeta[g] = ts.ssqBetaS[g]/(double)popsize - mnBeta[g]*mnBeta[g]; - if (sdBeta[g] > 0.0) sdBeta[g] = sqrt(sdBeta[g]); else sdBeta[g] = 0.0; - } - else { - sdS0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - } - } - } - if (sett.sexDep) { - outrange << "\t" << mnS0[0] << "\t" << sdS0[0]; - outrange << "\t" << mnS0[1] << "\t" << sdS0[1]; - outrange << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outrange << "\t" << mnAlpha[1] << "\t" << sdAlpha[1]; - outrange << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - outrange << "\t" << mnBeta[1] << "\t" << sdBeta[1]; - } - else { - outrange << "\t" << mnS0[0] << "\t" << sdS0[0]; - outrange << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outrange << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - } - } - -} - -outrange << endl; -} - -// Open occupancy file, write header record and set up occupancy array -bool Community::outOccupancyHeaders(int option) -{ -if (option == -999) { // close the files - if (outsuit.is_open()) outsuit.close(); - if (outoccup.is_open()) outoccup.close(); - outsuit.clear(); outoccup.clear(); - return true; -} - -string name, nameI; -simParams sim = paramsSim->getSim(); -//demogrParams dem = pSpecies->getDemogr(); -landParams ppLand = pLandscape->getLandParams(); -int outrows = (sim.years/sim.outIntOcc) + 1; - -name = paramsSim->getDir(2); -if (sim.batchMode) { - name += "Batch" + Int2Str(sim.batchNum) + "_"; - name += "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(ppLand.landNum); -} -else - name += "Sim" + Int2Str(sim.simulation); -name += "_Occupancy_Stats.txt"; -outsuit.open(name.c_str()); -outsuit << "Year\tMean_OccupSuit\tStd_error" << endl; - -name = paramsSim->getDir(2); -if (sim.batchMode) { - name += "Batch" + Int2Str(sim.batchNum) + "_"; - name += "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(ppLand.landNum); -} -else - name += "Sim" + Int2Str(sim.simulation); -name += "_Occupancy.txt"; -outoccup.open(name.c_str()); -if (ppLand.patchModel) { - outoccup << "PatchID"; -} -else { - outoccup << "X\tY"; -} -for (int i = 0; i < outrows; i++) - outoccup << "\t" << "Year_" << i*sim.outIntOcc; -outoccup << endl; - -// Initialise cells/patches occupancy array -createOccupancy(outrows,sim.reps); - -return outsuit.is_open() && outoccup.is_open(); -} - -void Community::outOccupancy(void) { -landParams ppLand = pLandscape->getLandParams(); -simParams sim = paramsSim->getSim(); -//streamsize prec = outoccup.precision(); -locn loc; - -int nsubcomms = (int)subComms.size(); -for (int i = 1; i < nsubcomms; i++) { // all except matrix sub-community - if (ppLand.patchModel) { - outoccup << subComms[i]->getPatch()->getPatchNum(); - } - else { - loc = subComms[i]->getLocn(); - outoccup << loc.x << "\t" << loc.y; - } - for (int row = 0; row <= (sim.years/sim.outIntOcc); row++) - { - outoccup << "\t" << (double)subComms[i]->getOccupancy(row)/(double)sim.reps; - } - outoccup << endl; -} -} - -void Community::outOccSuit(bool view) { -double sum,ss,mean,sd,se; -simParams sim = paramsSim->getSim(); -//streamsize prec = outsuit.precision(); - -#if RSDEBUG -//DEBUGLOG << "Community::outOccSuit(): sim.reps=" << sim.reps -// << " sim.years=" << sim.years << " sim.outInt=" << sim.outInt << endl; -#endif -for (int i = 0; i < (sim.years/sim.outIntOcc)+1; i++) { - sum = ss = 0.0; - for (int rep = 0; rep < sim.reps; rep++) { - sum += occSuit[i][rep]; - ss += occSuit[i][rep] * occSuit[i][rep]; -#if RSDEBUG -//DEBUGLOG << "Community::outOccSuit(): i=" << i << " rep=" << rep -// << " occSuit[i][rep]=" << occSuit[i][rep] -// << " sum=" << sum << " ss=" << ss -// << endl; -#endif - } - mean = sum/(double)sim.reps; - sd = (ss - (sum*sum/(double)sim.reps)) / (double)(sim.reps-1); -#if RSDEBUG -//DEBUGLOG << "Community::outOccSuit(): i=" << i -// << " mean=" << mean << " sd=" << sd << endl; -#endif - if (sd > 0.0) sd = sqrt(sd); - else sd = 0.0; - se = sd / sqrt((double)(sim.reps)); -#if RSDEBUG -//DEBUGLOG << "Community::outOccSuit(): i=" << i -// << " sd=" << sd << " se=" << se << endl; -#endif - -// outsuit << i*sim.outInt << "\t" << mean << "\t" << se << endl; -// if (view) viewOccSuit(i*sim.outInt,mean,se); - outsuit << i*sim.outIntOcc << "\t" << mean << "\t" << se << endl; - if (view) viewOccSuit(i*sim.outIntOcc,mean,se); -} - -} - -// Open traits file and write header record -bool Community::outTraitsHeaders(Species *pSpecies,int landNr) { -return subComms[0]->outTraitsHeaders(pLandscape,pSpecies,landNr); -} - -// Write records to traits file -/* NOTE: for summary traits by rows, which is permissible for a cell-based landscape -only, this function relies on the fact that subcommunities are created in the same -sequence as patches, which is in asecending order of x nested within descending -order of y -*/ -//void Community::outTraits(emigCanvas ecanv,trfrCanvas tcanv,Species *pSpecies, -// int rep,int yr,int gen) -void Community::outTraits(traitCanvas tcanv,Species *pSpecies, - int rep,int yr,int gen) -{ -simParams sim = paramsSim->getSim(); -simView v = paramsSim->getViews(); -landParams land = pLandscape->getLandParams(); -//demogrParams dem = pSpecies->getDemogr(); -//emigRules emig = pSpecies->getEmig(); -//trfrRules trfr = pSpecies->getTrfr(); -//locn loc; -traitsums *ts = 0; -traitsums sctraits; -if (sim.outTraitsRows && yr >= sim.outStartTraitRow && yr%sim.outIntTraitRow == 0) { - // create array of traits means, etc., one for each row - ts = new traitsums[land.dimY]; - for (int y = 0; y < land.dimY; y++) { - for (int i = 0; i < NSEXES; i++) { - ts[y].ninds[i] = 0; - ts[y].sumD0[i] = ts[y].ssqD0[i] = 0.0; - ts[y].sumAlpha[i] = ts[y].ssqAlpha[i] = 0.0; - ts[y].sumBeta[i] = ts[y].ssqBeta[i] = 0.0; - ts[y].sumDist1[i] = ts[y].ssqDist1[i] = 0.0; - ts[y].sumDist2[i] = ts[y].ssqDist2[i] = 0.0; - ts[y].sumProp1[i] = ts[y].ssqProp1[i] = 0.0; - ts[y].sumStepL[i] = ts[y].ssqStepL[i] = 0.0; - ts[y].sumRho[i] = ts[y].ssqRho[i] = 0.0; - ts[y].sumS0[i] = ts[y].ssqS0[i] = 0.0; - ts[y].sumAlphaS[i] = ts[y].ssqAlphaS[i] = 0.0; - ts[y].sumBetaS[i] = ts[y].ssqBetaS[i] = 0.0; - } - } -} -if (v.viewTraits -|| ((sim.outTraitsCells && yr >= sim.outStartTraitCell && yr%sim.outIntTraitCell == 0) || - (sim.outTraitsRows && yr >= sim.outStartTraitRow && yr%sim.outIntTraitRow == 0))) -{ - // generate output for each sub-community (patch) in the community - int nsubcomms = (int)subComms.size(); - for (int i = 1; i < nsubcomms; i++) { // // all except matrix sub-community -// sctraits = subComms[i]->outTraits(ecanv,tcanv,pLandscape,rep,yr,gen); -// sctraits = subComms[i]->outTraits(tcanv,pLandscape,rep,yr,gen,v.viewGrad); - sctraits = subComms[i]->outTraits(tcanv,pLandscape,rep,yr,gen,false); - locn loc = subComms[i]->getLocn(); - int y = loc.y; - if (sim.outTraitsRows && yr >= sim.outStartTraitRow && yr%sim.outIntTraitRow == 0) - { - for (int s = 0; s < NSEXES; s++) { - ts[y].ninds[s] += sctraits.ninds[s]; - ts[y].sumD0[s] += sctraits.sumD0[s]; ts[y].ssqD0[s] += sctraits.ssqD0[s]; - ts[y].sumAlpha[s] += sctraits.sumAlpha[s]; ts[y].ssqAlpha[s] += sctraits.ssqAlpha[s]; - ts[y].sumBeta[s] += sctraits.sumBeta[s]; ts[y].ssqBeta[s] += sctraits.ssqBeta[s]; - ts[y].sumDist1[s] += sctraits.sumDist1[s]; ts[y].ssqDist1[s] += sctraits.ssqDist1[s]; - ts[y].sumDist2[s] += sctraits.sumDist2[s]; ts[y].ssqDist2[s] += sctraits.ssqDist2[s]; - ts[y].sumProp1[s] += sctraits.sumProp1[s]; ts[y].ssqProp1[s] += sctraits.ssqProp1[s]; - ts[y].sumStepL[s] += sctraits.sumStepL[s]; ts[y].ssqStepL[s] += sctraits.ssqStepL[s]; - ts[y].sumRho[s] += sctraits.sumRho[s]; ts[y].ssqRho[s] += sctraits.ssqRho[s]; - ts[y].sumS0[s] += sctraits.sumS0[s]; ts[y].ssqS0[s] += sctraits.ssqS0[s]; - ts[y].sumAlphaS[s] += sctraits.sumAlphaS[s]; ts[y].ssqAlphaS[s] += sctraits.ssqAlphaS[s]; - ts[y].sumBetaS[s] += sctraits.sumBetaS[s]; ts[y].ssqBetaS[s] += sctraits.ssqBetaS[s]; - } - } - } - if (nsubcomms > 0 && sim.outTraitsRows - && yr >= sim.outStartTraitRow && yr%sim.outIntTraitRow == 0) { - for (int y = 0; y < land.dimY; y++) { - if ((ts[y].ninds[0]+ts[y].ninds[1]) > 0) { - writeTraitsRows(pSpecies,rep,yr,gen,y,ts[y]); - } - } - } -} -//if (sim.outTraitsRows && yr >= sim.outStartTraitRow && yr%sim.outIntTraitRow == 0) -//{ -// if (ts != 0) delete[] ts; -//} -if (ts != 0) { delete[] ts; ts = 0; } -} - -// Write records to trait rows file -void Community::writeTraitsRows(Species *pSpecies,int rep,int yr,int gen,int y, - traitsums ts) -{ -//simParams sim = paramsSim->getSim(); -//simView v = paramsSim->getViews(); -//landData land = pLandscape->getLandData(); -//landOrigin origin = pLandscape->getOrigin(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -double mn,sd; - -// calculate population size in case one phase is sex-dependent and the other is not -// (in which case numbers of individuals are recorded by sex) -int popsize = ts.ninds[0] + ts.ninds[1]; -outtraitsrows << rep << "\t" << yr << "\t" << gen - << "\t" << y; -// << "\t" << y*land.resol + origin.minNorth; -if ((emig.indVar && emig.sexDep) || (trfr.indVar && trfr.sexDep)) - outtraitsrows << "\t" << ts.ninds[0] << "\t" << ts.ninds[1]; -else - outtraitsrows << "\t" << popsize; - -if (emig.indVar) { - if (emig.sexDep) { - if (ts.ninds[0] > 0) mn = ts.sumD0[0]/(double)ts.ninds[0]; else mn = 0.0; - if (ts.ninds[0] > 1) sd = ts.ssqD0[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[1] > 0) mn = ts.sumD0[1]/(double)ts.ninds[1]; else mn = 0.0; - if (ts.ninds[1] > 1) sd = ts.ssqD0[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (emig.densDep) { - if (ts.ninds[0] > 0) mn = ts.sumAlpha[0]/(double)ts.ninds[0]; else mn = 0.0; - if (ts.ninds[0] > 1) sd = ts.ssqAlpha[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[1] > 0) mn = ts.sumAlpha[1]/(double)ts.ninds[1]; else mn = 0.0; - if (ts.ninds[1] > 1) sd = ts.ssqAlpha[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[0] > 0) mn = ts.sumBeta[0]/(double)ts.ninds[0]; else mn = 0.0; - if (ts.ninds[0] > 1) sd = ts.ssqBeta[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[1] > 0) mn = ts.sumBeta[1]/(double)ts.ninds[1]; else mn = 0.0; - if (ts.ninds[1] > 1) sd = ts.ssqBeta[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - } - } - else { // no sex dependence in emigration - if (popsize > 0) mn = ts.sumD0[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqD0[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (emig.densDep) { - if (popsize > 0) mn = ts.sumAlpha[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqAlpha[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (popsize > 0) mn = ts.sumBeta[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqBeta[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - } - } -} - -if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 2) { // CRW - // NB - CURRENTLY CANNOT BE SEX-DEPENDENT... - if (popsize > 0) mn = ts.sumStepL[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqStepL[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (popsize > 0) mn = ts.sumRho[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqRho[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; -// if (ts.ninds[0] > 0) mn = ts.sumStepL[0]/(double)ts.ninds[0]; else mn = 0.0; -// if (ts.ninds[0] > 1) sd = ts.ssqStepL[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; -// if (ts.ninds[0] > 0) mn = ts.sumRho[0]/(double)ts.ninds[0]; else mn = 0.0; -// if (ts.ninds[0] > 1) sd = ts.ssqRho[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; - } - } - else { // dispersal kernel - if (trfr.sexDep) { - if (ts.ninds[0] > 0) mn = ts.sumDist1[0]/(double)ts.ninds[0]; else mn = 0.0; - if (ts.ninds[0] > 1) sd = ts.ssqDist1[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[1] > 0) mn = ts.sumDist1[1]/(double)ts.ninds[1]; else mn = 0.0; - if (ts.ninds[1] > 1) sd = ts.ssqDist1[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (trfr.twinKern) - { - if (ts.ninds[0] > 0) mn = ts.sumDist2[0]/(double)ts.ninds[0]; else mn = 0.0; - if (ts.ninds[0] > 1) sd = ts.ssqDist2[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[1] > 0) mn = ts.sumDist2[1]/(double)ts.ninds[1]; else mn = 0.0; - if (ts.ninds[1] > 1) sd = ts.ssqDist2[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[0] > 0) mn = ts.sumProp1[0]/(double)ts.ninds[0]; else mn = 0.0; - if (ts.ninds[0] > 1) sd = ts.ssqProp1[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[1] > 0) mn = ts.sumProp1[1]/(double)ts.ninds[1]; else mn = 0.0; - if (ts.ninds[1] > 1) sd = ts.ssqProp1[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - } - } - else { // sex-independent - if (popsize > 0) mn = ts.sumDist1[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqDist1[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (trfr.twinKern) - { - if (popsize > 0) mn = ts.sumDist2[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqDist2[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (popsize > 0) mn = ts.sumProp1[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqProp1[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - } - } - } -} - -if (sett.indVar) { - // NB - CURRENTLY CANNOT BE SEX-DEPENDENT... -// if (sett.sexDep) { -// if (ts.ninds[0] > 0) mn = ts.sumS0[0]/(double)ts.ninds[0]; else mn = 0.0; -// if (ts.ninds[0] > 1) sd = ts.ssqS0[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; -// if (ts.ninds[1] > 0) mn = ts.sumS0[1]/(double)ts.ninds[1]; else mn = 0.0; -// if (ts.ninds[1] > 1) sd = ts.ssqS0[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; -// if (ts.ninds[0] > 0) mn = ts.sumAlphaS[0]/(double)ts.ninds[0]; else mn = 0.0; -// if (ts.ninds[0] > 1) sd = ts.ssqAlphaS[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; -// if (ts.ninds[1] > 0) mn = ts.sumAlphaS[1]/(double)ts.ninds[1]; else mn = 0.0; -// if (ts.ninds[1] > 1) sd = ts.ssqAlphaS[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; -// if (ts.ninds[0] > 0) mn = ts.sumBetaS[0]/(double)ts.ninds[0]; else mn = 0.0; -// if (ts.ninds[0] > 1) sd = ts.ssqBetaS[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; -// if (ts.ninds[1] > 0) mn = ts.sumBetaS[1]/(double)ts.ninds[1]; else mn = 0.0; -// if (ts.ninds[1] > 1) sd = ts.ssqBetaS[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; -// } -// else { // no sex dependence in settlement - if (popsize > 0) mn = ts.sumS0[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqS0[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (popsize > 0) mn = ts.sumAlphaS[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqAlphaS[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (popsize > 0) mn = ts.sumBetaS[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqBetaS[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; -// } -} - -outtraitsrows << endl; -} - -// Open trait rows file and write header record -bool Community::outTraitsRowsHeaders(Species *pSpecies,int landNr) { - -if (landNr == -999) { // close file - if (outtraitsrows.is_open()) outtraitsrows.close(); - outtraitsrows.clear(); - return true; -} - -string name; -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -simParams sim = paramsSim->getSim(); - -string DirOut = paramsSim->getDir(2); -if (sim.batchMode) { - name = DirOut - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(landNr) + "_TraitsXrow.txt"; -} -else { - name = DirOut + "Sim" + Int2Str(sim.simulation) + "_TraitsXrow.txt"; -} -outtraitsrows.open(name.c_str()); - -outtraitsrows << "Rep\tYear\tRepSeason\ty"; -if ((emig.indVar && emig.sexDep) || (trfr.indVar && trfr.sexDep)) - outtraitsrows << "\tN_females\tN_males"; -else - outtraitsrows << "\tN"; - -if (emig.indVar) { - if (emig.sexDep) { - if (emig.densDep) { - outtraitsrows << "\tF_meanD0\tF_stdD0\tM_meanD0\tM_stdD0"; - outtraitsrows << "\tF_meanAlpha\tF_stdAlpha\tM_meanAlpha\tM_stdAlpha"; - outtraitsrows << "\tF_meanBeta\tF_stdBeta\tM_meanBeta\tM_stdBeta"; - } - else { - outtraitsrows << "\tF_meanEP\tF_stdEP\tM_meanEP\tM_stdEP"; - } - } - else { - if (emig.densDep) { - outtraitsrows << "\tmeanD0\tstdD0\tmeanAlpha\tstdAlpha"; - outtraitsrows << "\tmeanBeta\tstdBeta"; - } - else { - outtraitsrows << "\tmeanEP\tstdEP"; - } - } -} -if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 2) { - outtraitsrows << "\tmeanStepLength\tstdStepLength\tmeanRho\tstdRho"; - } - } - else { // dispersal kernel - if (trfr.sexDep) { - outtraitsrows << "\tF_mean_distI\tF_std_distI\tM_mean_distI\tM_std_distI"; - if (trfr.twinKern) - outtraitsrows << "\tF_mean_distII\tF_std_distII\tM_mean_distII\tM_std_distII" - << "\tF_meanPfirstKernel\tF_stdPfirstKernel" - << "\tM_meanPfirstKernel\tM_stdPfirstKernel"; - } - else { - outtraitsrows << "\tmean_distI\tstd_distI"; - if (trfr.twinKern) - outtraitsrows << "\tmean_distII\tstd_distII\tmeanPfirstKernel\tstdPfirstKernel"; - } - } -} - -if (sett.indVar) { -// if (sett.sexDep) { -// outtraitsrows << "\tF_meanS0\tF_stdS0\tM_meanS0\tM_stdS0"; -// outtraitsrows << "\tF_meanAlphaS\tF_stdAlphaS\tM_meanAlphaS\tM_stdAlphaS"; -// outtraitsrows << "\tF_meanBetaS\tF_stdBetaS\tM_meanBetaS\tM_stdBetaS"; -// } -// else { - outtraitsrows << "\tmeanS0\tstdS0"; - outtraitsrows << "\tmeanAlphaS\tstdAlphaS"; - outtraitsrows << "\tmeanBetaS\tstdBetaS"; -// } -} -outtraitsrows << endl; - -return outtraitsrows.is_open(); - -} - -#if RS_RCPP && !R_CMD -Rcpp::IntegerMatrix Community::addYearToPopList(int rep, int yr) { // TODO: define new simparams to control start and interval of output - - landParams ppLand = pLandscape->getLandParams(); - Rcpp::IntegerMatrix pop_map_year(ppLand.dimY,ppLand.dimX); - intptr patch = 0; - Patch* pPatch = 0; - intptr subcomm = 0; - SubCommunity *pSubComm = 0; - popStats pop; - //pop.breeding = false; - pop.nInds = pop.nAdults = pop.nNonJuvs = 0; - - for (int y = 0; y < ppLand.dimY; y++) { - for (int x = 0; x < ppLand.dimX; x++) { - Cell *pCell = pLandscape->findCell(x,y); //if (pLandscape->cells[y][x] == 0) { - if (pCell == 0) { // no-data cell - pop_map_year(ppLand.dimY-1-y,x) = NA_INTEGER; - } else { - patch = pCell->getPatch(); - if (patch == 0) { // matrix cell - pop_map_year(ppLand.dimY-1-y,x) = 0; - } - else{ - pPatch = (Patch*)patch; - subcomm = pPatch->getSubComm(); - if (subcomm == 0) { // check if sub-community exists - pop_map_year(ppLand.dimY-1-y,x) = 0; - } else { - pSubComm = (SubCommunity*)subcomm; - pop = pSubComm->getPopStats(); - pop_map_year(ppLand.dimY-1-y,x) = pop.nInds; // use indices like this because matrix gets transposed upon casting it into a raster on R-level - //pop_map_year(ppLand.dimY-1-y,x) = pop.nAdults; - } - } - } - } - } - //list_outPop.push_back(pop_map_year, "rep" + std::to_string(rep) + "_year" + std::to_string(yr)); - return pop_map_year; -} -#endif - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- diff --git a/RangeShiftR/src/RScore/Community.h b/RangeShiftR/src/RScore/Community.h deleted file mode 100644 index 6a07b5b..0000000 --- a/RangeShiftR/src/RScore/Community.h +++ /dev/null @@ -1,231 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Community - -Implements the Community class - -There is ONLY ONE instance of a Community in an individual replicate simulation. -It holds a SubCommunity for each Patch in the Landscape (including the matrix), -and is thus the highest-level entity accessed for most processing concerned with -simulated populations. - -Optionally, the Community maintains a record of the occupancy of suitable cells -or patches during the course of simulation of multiple replicates. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 25 June 2021 by Anne-Kathleen Malchow - -------------------------------------------------------------------------------*/ - -#ifndef CommunityH -#define CommunityH - -#include -#include -using namespace std; -//#if RS_RCPP && !R_CMD -#include "../Version.h" -//#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif -#include "SubCommunity.h" -#include "Landscape.h" -#include "Patch.h" -#include "Cell.h" -#include "Species.h" - -//--------------------------------------------------------------------------- -struct commStats { -int ninds,nnonjuvs,suitable,occupied; -int minX,maxX,minY,maxY; -}; - -class Community { - -public: - Community(Landscape*); - ~Community(void); - SubCommunity* addSubComm(Patch*,int); - // functions to manage populations occurring in the community - void initialise( - Species*, // pointer to Species - int // year (relevent only for seedType == 2) - ); - void addManuallySelected(void); - void resetPopns(void); - void localExtinction(int); - void patchChanges(void); - void reproduction( - int // year - ); - void emigration(void); -#if RS_RCPP // included also SEASONAL - void dispersal( - short, // landscape change index - short // season / year - ); -#else - void dispersal( - short // landscape change index - ); -#endif // SEASONAL || RS_RCPP - - void survival( - short, // part: 0 = determine survival & development, - // 1 = apply survival changes to the population - short, // option0: 0 = stage 0 (juveniles) only ) - // 1 = all stages ) used by part 0 only - // 2 = stage 1 and above (all non-juvs) ) - short // option1: 0 - development only (when survival is annual) - // 1 - development and survival - ); - void ageIncrement(void); - int totalInds(void); - Population* findPop( // Find the population of a given species in a given patch - Species*, // pointer to Species - Patch* // pointer to Patch - ); - commStats getStats(void); - void createOccupancy( - int, // no. of rows = (no. of years / interval) + 1 - int // no. of replicates - ); - void updateOccupancy( - int, // row = (no. of years / interval) - int // replicate - ); - void deleteOccupancy( - int // no. of rows (as above) - ); - - bool outRangeHeaders( // Open range file and write header record - Species*, // pointer to Species - int // Landscape number (-999 to close the file) - ); - void outRange( // Write record to range file - Species*, // pointer to Species - int, // replicate - int, // year - int // generation - ); - bool outPopHeaders( // Open population file and write header record - Species*, // pointer to Species - int // option: -999 to close the file - ); - void outPop( // Write records to population file - int, // replicate - int, // year - int // generation - ); - - void outInds( // Write records to individuals file - int, // replicate - int, // year - int, // generation - int // Landscape number (>= 0 to open the file, -999 to close the file - // -1 to write data records) - ); - void outGenetics( // Write records to genetics file - int, // replicate - int, // year - int, // generation - int // Landscape number (>= 0 to open the file, -999 to close the file - // -1 to write data records) - ); - // Open occupancy file, write header record and set up occupancy array - bool outOccupancyHeaders( - int // option: -999 to close the file - ); - void outOccupancy(void); - void outOccSuit( - bool // TRUE if occupancy graph is to be viewed on screen - ); - void viewOccSuit( // Update the occupancy graph on the screen - // NULL for the batch version - int, // year - double, // mean occupancy - double // standard error of occupancy - ); - bool outTraitsHeaders( // Open traits file and write header record - Species*, // pointer to Species - int // Landscape number (-999 to close the file) - ); - bool outTraitsRowsHeaders( // Open trait rows file and write header record - Species*, // pointer to Species - int // Landscape number (-999 to close the file) - ); - void outTraits( // Write records to traits file - traitCanvas,// pointers to canvases for drawing variable traits -// emigCanvas, // pointers to canvases for drawing emigration traits -// trfrCanvas, // pointers to canvases for drawing emigration traits - // see SubCommunity.h - // in the batch version, these are replaced by integers set to zero - Species*, // pointer to Species - int, // replicate - int, // year - int // generation - ); - void writeTraitsRows( // Write records to trait rows file - Species*, // pointer to Species - int, // replicate - int, // year - int, // generation - int, // row number (Y cell co-ordinate) - traitsums // structure holding sums of trait genes for dispersal (see Population.h) - ); - void draw( // Draw the Community on the landscape map and optionally save the map - // NULL for the batch version - int, // replicate - int, // year - int, // generation - int // Landscape number - ); -#if RS_RCPP && !R_CMD - Rcpp::IntegerMatrix addYearToPopList(int,int); -#endif - -private: - Landscape *pLandscape; - int indIx; // index used to apply initial individuals - float **occSuit; // occupancy of suitable cells / patches - std::vector subComms; - -}; - -extern paramSim *paramsSim; -extern paramInit *paramsInit; - - -//--------------------------------------------------------------------------- -#endif diff --git a/RangeShiftR/src/RScore/FractalGenerator.cpp b/RangeShiftR/src/RScore/FractalGenerator.cpp deleted file mode 100644 index 7a5ccc3..0000000 --- a/RangeShiftR/src/RScore/FractalGenerator.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "FractalGenerator.h" -//--------------------------------------------------------------------------- - -vector patches; - -//----- Landscape creation -------------------------------------------------- - -land::land(): x_coord(0), y_coord(0), value(0.0), avail(0) {} - -bool compare(const land& z, const land& zz) //compares only the values of the cells -{ -return z.value < zz.value; -} - -vector& fractal_landscape(int X,int Y,double Hurst,double prop, - double maxValue,double minValue) -{ -#if RSDEBUG -DEBUGLOG << "fractal_landscape(): X=" << X << " Y=" << Y - << " Hurst=" << Hurst << " prop=" << prop - << " maxValue=" << maxValue << " minValue=" << minValue - << endl; -#endif - -int ii, jj, x, y; -int ix, iy; -//int x0, y0, size, kx, kx2, ky, ky2; -int kx,kx2,ky,ky2; - -double range; //range to draw random numbers at each iteration -double nx, ny; -double i, j; -int Nx = X; -int Ny = Y; - -double ran[5]; // to store each time the 5 random numbers for the random displacement - -int Nno; // number of cells NON suitable as habitat - -// exponents used to obtain the landscape dimensions -double pow2x = log(((double)X-1.0))/log(2.0); -double pow2y = log(((double)Y-1.0))/log(2.0); - -double **arena = new double *[X]; -for(ii = 0; ii < X; ii++) { - arena[ii] = new double[Y]; -} - -patches.clear(); -// initialise all the landscape with zeroes -for (jj = 0; jj < X; jj++) { - for (ii = 0; ii < Y; ii++) { - arena[jj][ii]=0; - } -} - -// initialisation of the four corners -arena[0][0] = 1.0 + pRandom->Random() * (maxValue-1.0); -arena[0][Y-1] = 1.0 + pRandom->Random() * (maxValue-1.0); -arena[X-1][0] = 1.0 + pRandom->Random() * (maxValue-1.0); -arena[X-1][Y-1] = 1.0 + pRandom->Random() * (maxValue-1.0); - -/////////////MIDPOINT DISPLACEMENT ALGORITHM////////////////////////////////// -kx = (Nx-1) / 2; -kx2 = 2 * kx; -ky = (Ny-1) / 2; -ky2 = 2 * ky; - -for (ii = 0; ii < 5; ii++) //random displacement -{ - ran[ii] = 1.0 + pRandom->Random() * (maxValue-1.0); -} - -//The diamond step: -arena[kx][ky] = ((arena[0][0] + arena[0][ky2] + arena[kx2][0] + arena[kx2][ky2])/4) + ran[0]; - -//The square step: -//left -arena[0][ky] = ((arena[0][0] +arena[0][ky2] + arena[kx][ky]) / 3) + ran[1]; -//top -arena[kx][0] = ((arena[0][0] + arena[kx][ky] + arena[kx2][0]) / 3) + ran[2]; -//right -arena[kx2][ky] = ((arena[kx2][0] + arena[kx][ky] + arena[kx2][ky2]) / 3) + ran[3]; -//bottom -arena[kx][ky2] = ((arena[0][ky2] + arena[kx][ky] +arena[kx2][ky2]) / 3) + ran[4]; - -range = maxValue*pow(2,-Hurst); - -i = pow2x-1; -j = pow2y-1; - -while (i > 0) { - nx = pow(2,i)+1; - kx = (int)((nx-1) / 2); - kx2 = 2 * kx; - - ny = pow(2,j)+1; - ky = (int)((ny-1) / 2); - ky2 = 2 * ky; - - ix = 0; - while (ix <= (Nx-nx)) { - iy = 0; - while (iy <= (Ny-ny)) { - for (ii = 0; ii < 5; ii++) //random displacement - { - ran[ii] = (int)(pRandom->Random() * 2.0 * range - range); - } - //The diamond step: - - arena[ix+kx][iy+ky] = ((arena[ix][iy] + arena[ix][iy+ky2] + arena[ix+ky2][iy] - + arena[ix+kx2][iy+ky2])/ 4) + ran[0]; - if (arena[ix+kx][iy+ky] < 1) arena[ix+kx][iy+ky] = 1; - - //The square step: - //left - arena[ix][iy+ky] =((arena[ix][iy] +arena[ix][iy+ky2] + arena[ix+kx][iy+ky])/3) - + ran[1]; - if (arena[ix][iy+ky] < 1) arena[ix][iy+ky] = 1; - //top - arena[ix+kx][iy] =((arena[ix][iy] + arena[ix+kx][iy+ky] + arena[ix+kx2][iy])/3) - + ran[2]; - if (arena[ix+kx][iy] < 1) arena[ix+kx][iy] = 1; - //right - arena[ix+kx2][iy+ky] = ((arena[ix+kx2][iy] + arena[ix+kx][iy+ky] + - arena[ix+kx2][iy+ky2]) / 3) + ran[3]; - if (arena[ix+kx2][iy+ky] < 1) arena[ix+kx2][iy+ky] = 1; - //bottom - arena[ix+kx][iy+ky2] = ((arena[ix][iy+ky2] + arena[ix+kx][iy+ky] + - arena[ix+kx2][iy+ky2]) / 3) + ran[4]; - if (arena[ix+kx][iy+ky2] < 1) arena[ix+kx][iy+ky2] = 1; - - iy += ((int)ny-1); - } - ix += ((int)nx-1); - } - if (i==j) j--; - i--; - - range = range*pow(2,-Hurst); //reduce the random number range -} - -// Now all the cells will be sorted and the Nno cells with the lower carrying -// capacity will be set as matrix, i.e. with K = 0 - -land *patch; - -for (x = 0; x < X; x++) // put all the cells with their values in a vector -{ - for (y = 0; y < Y; y++) - { - patch = new land; - patch->x_coord = x; - patch->y_coord = y; - patch->value = (float)arena[x][y]; - patch->avail = 1; - - patches.push_back(*patch); - - delete patch; - } -} - - -sort(patches.begin(),patches.end(),compare); // sorts the vector - -Nno = (int)(prop*X*Y); -for (ii = 0; ii < Nno; ii++) -{ - patches[ii].value = 0.0; - patches[ii].avail = 0; -} - -double min = (double)patches[Nno].value; // variables for the rescaling -double max = (double)patches[X*Y-1].value; - -double diff = max - min; -double diffK = maxValue-minValue; -double new_value; - -vector::iterator iter = patches.begin(); -while (iter != patches.end()) -{ - if (iter->value > 0) // rescale to a range of K between Kmin and Kmax - { - new_value = maxValue - diffK * (max - (double)iter->value) / diff; - - iter->value = (float)new_value; - } - else iter->value = 0; - - iter++; -} - -if (arena != NULL) { -#if RSDEBUG -//DebugGUI(("fractal_landscape(): arena=" + Int2Str((int)arena) -// + " X=" + Int2Str(X) + " Y=" + Int2Str(Y) -// ).c_str()); -#endif - for(ii = 0; ii < X; ii++) { -#if RSDEBUG -//DebugGUI(("fractal_landscape(): ii=" + Int2Str(ii) -// + " arena[ii]=" + Int2Str((int)arena[ii]) -// ).c_str()); -#endif - delete[] arena[ii]; - } - delete[] arena; -} - -return patches; - -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - diff --git a/RangeShiftR/src/RScore/FractalGenerator.h b/RangeShiftR/src/RScore/FractalGenerator.h deleted file mode 100644 index 24acbc7..0000000 --- a/RangeShiftR/src/RScore/FractalGenerator.h +++ /dev/null @@ -1,85 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 FractalGenerator - -Implements the midpoint displacement algorithm for generating a fractal Landscape, -following: - -Saupe, D. (1988). Algorithms for random fractals. In: The Science of Fractal Images -(eds. Pietgen, H.O. & Saupe, D.). Springer, New York, pp. 71–113. - - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 15 July 2021 by Anne-Kathleen Malchow - -------------------------------------------------------------------------------*/ - -#ifndef FractalGeneratorH -#define FractalGeneratorH - -#include -#include -//using namespace std; - -#include "Parameters.h" - -class land -{ - public: - land(); - int x_coord; - int y_coord; - float value; - int avail; // if 0 the patch is not available as habitat, if 1 it is - private: -}; - -// IMPORTANT NOTE: X AND Y ARE TRANSPOSED, i.e. X IS THE VERTICAL CO-ORDINATE -// ========================================================================== - -vector& fractal_landscape( - int, // X dimension (Y of LandScape) - int, // Y dimension (X of LandScape) - double, // Hurst exponent - double, // proportion of NON-suitable habitat - double, // maximum quality value - double // minimum quality value -); -bool compare(const land&, const land&); - -extern RSrandom *pRandom; -#if RSDEBUG -extern void DebugGUI(string); -#endif - -//--------------------------------------------------------------------------- -#endif diff --git a/RangeShiftR/src/RScore/Genome.cpp b/RangeShiftR/src/RScore/Genome.cpp deleted file mode 100644 index 90d030b..0000000 --- a/RangeShiftR/src/RScore/Genome.cpp +++ /dev/null @@ -1,861 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Genome.h" -//--------------------------------------------------------------------------- - -ofstream outGenetic; - -//--------------------------------------------------------------------------- - -#ifdef RSDEBUG -//std::ofstream chromdebug("chromdebug.txt"); -//std::ofstream chromdebug1("chromdebug1.txt"); -#endif - -//--------------------------------------------------------------------------- - -Chromosome::Chromosome(int nloc) -{ -#if RSDEBUG -//DEBUGLOG << "Chromosome::Chromosome(): this=" << this -// << " nloc=" << nloc -//// << " maternalLoci.size()=" << maternalLoci.size() -//// << " paternalLoci.size()=" << paternalLoci.size() -// << endl; -//DebugGUI("Chromosome::Chromosome(): this=" + Int2Str((int)this) -// + " nloc=" + Int2Str(nloc) -//// + " maternalLoci.size()=" + Int2Str((int)maternalLoci.size()) -//// + " paternalLoci.size()=" + Int2Str((int)paternalLoci.size()) -// ); -#endif -if (nloc > 0) nloci = nloc; else nloci = 1; -pLoci = new locus[nloci]; -for (int i = 0; i < nloci; i++) { - pLoci[i].allele[0] = pLoci[i].allele[1] = 0; -} -} - -Chromosome::~Chromosome() { -#if RSDEBUG -//DEBUGLOG << "Chromosome::~Chromosome(): this=" << this << endl; -#endif -#if RSDEBUG -//DEBUGLOG << "Chromosome::Chromosome(): deleting this=" << this << endl; -//DebugGUI("Chromosome::Chromosome(): deleting this=" + Int2Str((int)this)); -#endif -if (pLoci != 0) { -// for (int i = 0; i < nloci; i++) { -// delete pLoci[i]; pLoci[i] = NULL; -// } - delete[] pLoci; pLoci = NULL; -} -} - -short Chromosome::nLoci(void) { return nloci; } - -locus Chromosome::alleles(const int loc) { // return allele values at a specified locus -locus l; l.allele[0] = l.allele[1] = 0; -if (loc >= 0 && loc < nloci) { - l.allele[0] = pLoci[loc].allele[0]; l.allele[1] = pLoci[loc].allele[1]; -} -return l; -} - -double Chromosome::additive(const bool diploid) { -int sum = 0; -for (int i = 0; i < nloci; i++) { - sum += pLoci[i].allele[0]; - if (diploid) sum += pLoci[i].allele[1]; -} -#if RSDEBUG -//DEBUGLOG << "Chromosome::additive(): this=" << this -// << " sum=" << sum -// << endl; -#endif -return (double)sum / INTBASE; -} - -double Chromosome::meanvalue(const bool diploid) { -int sum = 0; -double mean; -for (int i = 0; i < nloci; i++) { - sum += pLoci[i].allele[0]; - if (diploid) sum += pLoci[i].allele[1]; -} -mean = (double)sum / (double)nloci; -if (diploid) mean /= 2.0; -mean /= INTBASE; -#if RSDEBUG -//DEBUGLOG << "Chromosome::meanvalue(): this=" << this -// << " sum=" << sum -// << " mean=" << mean -// << endl; -#endif -return mean; -} - -double Chromosome::additive(const short loc,const bool diploid) { -int sum = 0; -sum += pLoci[loc].allele[0]; -if (diploid) sum += pLoci[loc].allele[1]; -#if RSDEBUG -//DEBUGLOG << "Chromosome::additive(): this=" << this -// << " sum=" << sum -// << endl; -#endif -return (double)sum / INTBASE; -} - -/* -double Chromosome::probval(const bool diploid) { -double genval,phenval; -int sum = 0; -for (int i = 0; i < nloci; i++) { - sum += pLoci[i].allele[0]; - if (diploid) sum += pLoci[i].allele[1]; -} -genval = (double)sum / INTBASE; -phenval = 1.0 / (1.0 + exp(-genval)); -#if RSDEBUG -//DEBUGLOG << "Chromosome::probval(): this=" << this -// << " sum=" << sum -// << " genval=" << genval -// << " phenval=" << phenval -// << endl; -#endif -return phenval; -} -*/ - -// Set up chromosome at simulation initialisation -//void Chromosome::initialise(const float mean,const float sd, -// const bool diploid) { -void Chromosome::initialise(const double mean, const double sd, - const bool diploid) { -double avalue; -double intbase = INTBASE; -//// adjust mean and s.d. allowing for number of alleles determining phenotype -//double adjmean,adjsd,factor; -//if (diploid) factor = (double)(nloci * 2); else factor = (double)(nloci); -//adjmean = mean / factor; -//adjsd = sqrt(sd * sd / factor); -for (int i = 0; i < nloci; i++) { -// avalue = pRandom->Normal(adjmean,adjsd); - avalue = pRandom->Normal(mean,sd); - if (avalue > 0.0) - pLoci[i].allele[0] = (int)(avalue * intbase + 0.5); - else - pLoci[i].allele[0] = (int)(avalue * intbase - 0.5); -#if RSDEBUG -//DEBUGLOG << "Chromosome::initialise(): this=" << this -// << " mean=" << mean << " sd=" << sd -// << " i=" << i << " avalue=" << avalue -// << " allele[0]=" << pLoci[i].allele[0]; -//DEBUGLOG << endl; -#endif - if (diploid) { -// avalue = pRandom->Normal(adjmean,adjsd); - avalue = pRandom->Normal(mean,sd); - if (avalue > 0.0) - pLoci[i].allele[1] = (int)(avalue * intbase + 0.5); - else - pLoci[i].allele[1] = (int)(avalue * intbase - 0.5); -#if RSDEBUG -//DEBUGLOG << "Chromosome::initialise(): this=" << this -// << " mean=" << mean << " sd=" << sd -// << " i=" << i << " avalue=" << avalue -// << " allele[1]=" << pLoci[i].allele[1]; -//DEBUGLOG << endl; -#endif - } -} - -} - -// Set up specified locus at simulation initialisation -void Chromosome::initialise(const short locus,const short posn,const int aval) -{ -// note that initialising value is ADDED to current value to allow for pleiotropy -pLoci[locus].allele[posn] += aval; -} - -// Inherit from specified parent -void Chromosome::inherit(const Chromosome *parentChr,const short posn,const short nloc, - const double probmutn,const double probcross,const double mutnSD,const bool diploid) -{ - -// NOTE: At present for diploid genome, presence of crossover is determined at each -// locus (except first). However, Roslyn has shown that it is more efficient to sample -// crossover locations from geometric distribution if number of loci is large. -// HOW LARGE IS 'LARGE' IN THIS CASE?... - -//// adjust mutation variance for number of loci -//double mutnsd; -//if (diploid) -// mutnsd = sqrt(mutnSD * mutnSD / (double)(2*nloc)); -//else -// mutnsd = sqrt(mutnSD * mutnSD / (double)nloc); -int ix = 0; // indexes maternal and paternal strands -if (diploid) ix = pRandom->Bernoulli(0.5); // start index at random -for (int i = 0; i < nloc; i++) { - if (diploid) { - pLoci[i].allele[posn] = parentChr->pLoci[i].allele[ix]; - if (pRandom->Bernoulli(probcross)) { // crossover occurs - if (ix == 0) ix = 1; else ix = 0; - } - } - else - pLoci[i].allele[posn] = parentChr->pLoci[i].allele[0]; -#if RSDEBUG -//DEBUGLOG << "Chromosome::inherit(): this=" << this -// << " posn=" << posn << " nloc=" << nloc << " pmutn=" << pmutn -// << " i=" << i << " allele=" << pLoci[i].allele[posn] -// << endl; -#endif - if (pRandom->Bernoulli(probmutn)) { // mutation occurs - double intbase = INTBASE; -#if RSDEBUG - int oldval = pLoci[i].allele[posn]; -#endif -// double mutnvalue = pRandom->Normal(0,mutnsd); - double mutnvalue = pRandom->Normal(0,mutnSD); - if (mutnvalue > 0.0) - pLoci[i].allele[posn] += (int)(intbase * mutnvalue + 0.5); - else - pLoci[i].allele[posn] += (int)(intbase * mutnvalue - 0.5); -#if RSDEBUG -//DEBUGLOG << "Chromosome::inherit(): this=" << this -// << " probmutn=" << probmutn << " nloc=" << nloc -//// << " mutnsd=" << mutnsd -// << " mutnSD=" << mutnSD -// << " posn=" << posn << " locus=" << i << " MUTATED " -// << " old=" << oldval << " new=" << pLoci[i].allele[posn] -// << endl; -#endif -#if RSDEBUG -//MUTNLOG << 1 << endl; -MUTNLOG << mutnvalue << " " << oldval << " " << pLoci[i].allele[posn] << " " << endl; -#endif - } -#if RSDEBUG -// else { -//MUTNLOG << 0 << endl; -// } -#endif -} -} - - -//--------------------------------------------------------------------------- - -// NB THIS FUNCTION IS CURRENTLY NOT BEING CALLED TO CONSTRUCT AN INSTANCE OF Genome -// Genome(int) IS USED INSTEAD - -Genome::Genome(){ -pChromosome = NULL; -nChromosomes = 0; -} - -// Set up new genome at initialisation for 1 chromosome per trait -Genome::Genome(int nchromosomes,int nloci,bool d) { -#if RSDEBUG -//DEBUGLOG << "Genome::Genome(): this=" << this -// << " nchromosomes=" << nchromosomes << " nLoci=" << nLoci -// << endl; -#endif - -diploid = d; -if (nchromosomes > 0) nChromosomes = nchromosomes; else nChromosomes = 1; -pChromosome = new Chromosome *[nChromosomes]; -for (int i = 0; i < nChromosomes; i++) { - pChromosome[i] = new Chromosome(nloci); -// pChromosome[i]->initialise(alleleMean,alleleSD); -} - -} - -// Set up new genome at initialisation for trait mapping -Genome::Genome(Species *pSpecies) { -int nloci; -nChromosomes = pSpecies->getNChromosomes(); -diploid = pSpecies->isDiploid(); -#if RSDEBUG -//DEBUGLOG << "Genome::Genome(): this=" << this -// << " nChromosomes=" << nChromosomes -// << endl; -#endif -pChromosome = new Chromosome *[nChromosomes]; -for (int i = 0; i < nChromosomes; i++) { - nloci = pSpecies->getNLoci(i); -#if RSDEBUG -//DEBUGLOG << "Genome::Genome(): this=" << this -// << " i=" << i << " nloci=" << nloci << endl; -#endif - pChromosome[i] = new Chromosome(nloci); -} -} - -// Inherit genome from parent(s) -Genome::Genome(Species *pSpecies,Genome *mother,Genome *father) -{ -genomeData gen = pSpecies->getGenomeData(); - -nChromosomes = mother->nChromosomes; -diploid = mother->diploid; -pChromosome = new Chromosome *[nChromosomes]; - -for (int i = 0; i < nChromosomes; i++) { - pChromosome[i] = new Chromosome(mother->pChromosome[i]->nLoci()); - inherit(mother,0,i,gen.probMutn,gen.probCrossover,gen.mutationSD); - if (diploid) { - if (father == 0) { // species is hermaphrodite - inherit again from mother - inherit(mother,1,i,gen.probMutn,gen.probCrossover,gen.mutationSD); - } - else inherit(father,1,i,gen.probMutn,gen.probCrossover,gen.mutationSD); - } -} - -} - -Genome::~Genome(){ - -if (pChromosome == NULL) return; - -for (int i = 0; i < nChromosomes; i++) { - delete pChromosome[i]; -} -delete[] pChromosome; - -} - -/* -Genome::~Genome(void) -{ -if (genome != 0) { - delete genome; genome = NULL; -} -} -*/ - -//--------------------------------------------------------------------------- - -void Genome::setDiploid(bool dip) { diploid = dip; } -bool Genome::isDiploid(void) { return diploid; } -short Genome::getNChromosomes(void) { return nChromosomes; } - -//--------------------------------------------------------------------------- - -// Inherit from specified parent -void Genome::inherit(const Genome *parent,const short posn,const short chr, - const double probmutn,const double probcross,const double mutnSD) -{ -// adjust mutation variance for number of loci -//double mutnSD = sqrt(mutationSD * mutationSD / (double)nLoci); -//for (int i = 0; i < nChromosomes; i++) { -// pChromosome[i]->inherit(parent->pChromosome[i],pChromosome[i]->nLoci()); -//} -pChromosome[chr]->inherit(parent->pChromosome[chr],posn,parent->pChromosome[chr]->nLoci(), - probmutn,probcross,mutnSD,diploid); - -} - -void Genome::outGenHeaders(const int rep,const int landNr,const bool xtab) -{ - -if (landNr == -999) { // close file - if (outGenetic.is_open()) { - outGenetic.close(); outGenetic.clear(); - } - return; -} - -string name; -simParams sim = paramsSim->getSim(); - -if (sim.batchMode) { - name = paramsSim->getDir(2) - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) - + "_Land" + Int2Str(landNr) + "_Rep" + Int2Str(rep) + "_Genetics.txt"; -} -else { - name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) - + "_Rep" + Int2Str(rep) +"_Genetics.txt"; -} -outGenetic.open(name.c_str()); - -outGenetic << "Rep\tYear\tSpecies\tIndID"; -if (xtab) { - for (int i = 0; i < nChromosomes; i++) { - int nloci = pChromosome[i]->nLoci(); - for (int j = 0; j < nloci; j++) { - outGenetic << "\tChr" << i << "Loc" << j << "Allele0"; - if (diploid) outGenetic << "\tChr" << i << "Loc" << j << "Allele1"; - } - } - outGenetic << endl; -} -else { - outGenetic << "\tChromosome\tLocus\tAllele0"; - if (diploid) outGenetic << "\tAllele1"; - outGenetic << endl; -} - -} - -void Genome::outGenetics(const int rep,const int year,const int spnum, - const int indID,const bool xtab) - { -locus l; -if (xtab) { - outGenetic << rep << "\t" << year << "\t" << spnum << "\t" << indID; - for (int i = 0; i < nChromosomes; i++) { - int nloci = pChromosome[i]->nLoci(); - for (int j = 0; j < nloci; j++) { - l = pChromosome[i]->alleles(j); - outGenetic << "\t" << l.allele[0]; - if (diploid) outGenetic << "\t" << l.allele[1]; - } - } - outGenetic << endl; -} -else { - for (int i = 0; i < nChromosomes; i++) { - int nloci = pChromosome[i]->nLoci(); - for (int j = 0; j < nloci; j++) { - outGenetic << rep << "\t" << year << "\t" << spnum << "\t" - << indID << "\t" << i << "\t" << j; - l = pChromosome[i]->alleles(j); - outGenetic << "\t" << l.allele[0]; - if (diploid) outGenetic << "\t" << l.allele[1]; - outGenetic << endl; - } - } -} -} - -//--------------------------------------------------------------------------- - -// Set up new gene at initialisation for 1 chromosome per trait -//void Genome::setGene(const short chr,const short exp, -// const float traitval,const float alleleSD) -void Genome::setGene(const short chr, const short exp, - const double traitval, const double alleleSD) -// NB PARAMETER exp FOR EXPRESSION TYPE IS NOT CURRENTLY USED... -{ -#if RSDEBUG -//DEBUGLOG << "Genome::setGene(): this=" << this -// << " chr=" << chr -// << " exp=" << exp << " traitval=" << traitval -// << " alleleSD=" << alleleSD -// << endl; -#endif -if (chr >= 0 && chr < nChromosomes) { - pChromosome[chr]->initialise(traitval,alleleSD,diploid); -} -} - -// Set up trait at initialisation for trait mapping -//void Genome::setTrait(Species *pSpecies,const int trait, -// const float traitval,const float alleleSD) -void Genome::setTrait(Species* pSpecies, const int trait, - const double traitval, const double alleleSD) -{ -traitAllele allele; -int nalleles = pSpecies->getNTraitAlleles(trait); -int ntraitmaps = pSpecies->getNTraitMaps(); -#if RSDEBUG -//DEBUGLOG << "Genome::setTrait(): this=" << this << " ntraitmaps=" << ntraitmaps -// << " trait=" << trait << " traitval=" << traitval << " alleleSD=" << alleleSD -// << " nalleles=" << nalleles -// << endl; -#endif - -int avalue; -double intbase = INTBASE; -if (trait < ntraitmaps) { -// // adjust mean and s.d. allowing for number of alleles determining phenotype -// double adjmean,adjsd,factor; -// if (diploid) factor = (double)(nalleles * 2); else factor = (double)(nalleles); -// adjmean = traitval / factor; -// adjsd = sqrt(alleleSD * alleleSD / factor); - - for (int i = 0; i < nalleles; i++) { - allele = pSpecies->getTraitAllele(trait,i); -// avalue = (int)(pRandom->Normal(adjmean,adjsd) * intbase); - avalue = (int)(pRandom->Normal(traitval,alleleSD) * intbase); -#if RSDEBUG -//DEBUGLOG << "Genome::setTrait(): this=" << this -// << " i=" << i << " chromo=" << allele.chromo << " locus=" << allele.locus -// << " posn=" << 0 << " avalue=" << avalue -// << endl; -#endif - pChromosome[allele.chromo]->initialise(allele.locus,0,avalue); - if (diploid) { -// avalue = (int)(pRandom->Normal(adjmean,adjsd) * intbase); - avalue = (int)(pRandom->Normal(traitval,alleleSD) * intbase); - pChromosome[allele.chromo]->initialise(allele.locus,1,avalue); - } - } -} -else { // insufficient traits were defined - // alleles cannot be initialised - all individuals have mean phenotype -#if RSDEBUG -//DEBUGLOG << "Genome::setTrait(): this=" << this -// << " *** unable to initialise undefined trait ***" << endl; -#endif -} - -} - -// Set up trait at initialisation for trait mapping -void Genome::setNeutralLoci(Species *pSpecies,const double alleleSD) -{ -traitAllele allele; -int nneutral = pSpecies->getNNeutralLoci(); -#if RSDEBUG -//DEBUGLOG << "Genome::setNeutralLoci(): this=" << this -// << " nneutral=" << nneutral << " alleleSD=" << alleleSD -// << endl; -#endif - -//int avalue; -double avalue; -double intbase = INTBASE; -//// adjust allele s.d. for diploid genotype -//double adjsd,factor; -//if (diploid) factor = 2.0; else factor = 1.0; -//adjsd = sqrt(alleleSD * alleleSD / factor); - -for (int i = 0; i < nneutral; i++) { - allele = pSpecies->getNeutralAllele(i); -// avalue = (int)(pRandom->Normal(0.0,adjsd) * intbase); -// pChromosome[allele.chromo]->initialise(allele.locus,0,avalue); - avalue = pRandom->Normal(0.0,alleleSD); - if (avalue > 0.0) - pChromosome[allele.chromo]->initialise(allele.locus,0,(int)(avalue * intbase + 0.5)); - else - pChromosome[allele.chromo]->initialise(allele.locus,0,(int)(avalue * intbase - 0.5)); -#if RSDEBUG -//DEBUGLOG << "Genome::setNeutralLoci(): this=" << this -// << " i=" << i << " chromo=" << allele.chromo << " locus=" << allele.locus -// << " avalue=" << avalue -// << endl; -#endif - if (diploid) { -// avalue = (int)(pRandom->Normal(0.0,adjsd) * intbase); -// pChromosome[allele.chromo]->initialise(allele.locus,1,avalue); - avalue = pRandom->Normal(0.0,alleleSD); - if (avalue > 0.0) - pChromosome[allele.chromo]->initialise(allele.locus,1,(int)(avalue * intbase + 0.5)); - else - pChromosome[allele.chromo]->initialise(allele.locus,1,(int)(avalue * intbase - 0.5)); - } -} -} - -// Return a single allele, having applied mutation -// Either allele is returned with equal probability, unless the gene is sex-linked, -// in which case a male returns the allele inherited from his father and a female -// returns the allele inherited from her mother -/* -double Genome::copy(int i,int sexx) -{ -double genevalue = 0.0; -return genevalue; -} -*/ - -// Return the expressed value of a gene when species has one chromosome per trait -double Genome::express(short chr,short expr,short indsex) -{ -double genevalue = 0.0; -//if (expr == 1) { -// genevalue = pChromosome[chr]->probval(diploid); -//} -//else -//genevalue = pChromosome[chr]->additive(diploid); -genevalue = pChromosome[chr]->meanvalue(diploid); -#if RSDEBUG -//DEBUGLOG << "Genome::express(): this=" << this -// << " chr=" << chr -// << " genevalue=" << genevalue -// << endl; -#endif -return genevalue; -} -/* -// Return the expressed value of an allele -double Genome::express(short chr,short loc) -{ -double genevalue = 0.0; -//if (expr == 1) { -// genevalue = pChromosome[chr]->probval(diploid); -//} -//else -genevalue = pChromosome[chr]->additive(loc,diploid); -#if RSDEBUG -//DEBUGLOG << "Genome::express(): this=" << this -// << " expr=" << expr -// << " genevalue=" << genevalue -// << endl; -#endif -return genevalue; -} -*/ - -// Return the expressed value of a trait when genetic architecture is defined -double Genome::express(Species *pSpecies,short traitnum) -{ -double genevalue = 0.0; - -traitAllele allele; -int nalleles = pSpecies->getNTraitAlleles(traitnum); -if (nalleles > 0) { - for (int i = 0; i < nalleles; i++) { - allele = pSpecies->getTraitAllele(traitnum,i); - genevalue += pChromosome[allele.chromo]->additive(allele.locus,diploid); - } - genevalue /= (double)nalleles; - if (diploid) genevalue /= 2.0; -} - -// genevalue = pChromosome[chr]->additive(diploid); -#if RSDEBUG -//DEBUGLOG << "Genome::express(): this=" << this -// << " traitnum=" << traitnum << " nalleles=" << nalleles -// << " genevalue=" << genevalue -// << endl; -#endif -return genevalue; -} - - -locusOK Genome::getAlleles(short chr,short loc) { -locusOK l; -l.allele[0] = l.allele[1] = 0; l.ok = false; -//double intbase = INTBASE; -if (chr >= 0 && chr < nChromosomes) { - if (pChromosome[chr] != 0) { - if (loc >= 0 && loc < pChromosome[chr]->nLoci()) { - locus a = pChromosome[chr]->alleles(loc); - l.allele[0] = a.allele[0]; l.allele[1] = a.allele[1]; l.ok = true; - } - } -} -// l.allele[0] = (int)(intbase * pChromosome[0]->additive(diploid)); - -return l; -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - -// OLD CODE WHICH MIGHT BE USEFUL FOR IMPLEMENTING ALTERNATIVE FORMS OF EXPRESSION - -/* - -// Set up new genome at initialisation -Genome::Genome(int g) { -if (g < 1) return; - -genomesize = g; -genome = new gene *[genomesize]; -for (int i = 0; i < genomesize; i++) { - genome[i] = new gene; - genome[i]->expression = 0; genome[i]->mutntype = 0; - genome[i]->Pmutn = 0.0; genome[i]->mutnSize = 0.0; - genome[i]->allele[0] = genome[i]->allele[1] = 0.0; -} - -} - -// Inherit genome from parent(s) -Genome::Genome(Genome *mother,Genome *father) -{ -#if RSDEBUG -//locn currloc = currCell->getLocn(); -//DEBUGLOG << "Genome::setGenes(): indId=" << indId -// << " x=" << currloc.x << " y=" << currloc.y -// << " pSpecies=" << pSpecies -// << " mother=" << mother -// << " father=" << father -// << endl; -#endif - -genomesize = mother->genomesize; -genome = new gene *[genomesize]; -for (int i = 0; i < genomesize; i++) { - genome[i] = new gene; - genome[i]->expression = mother->genome[i]->expression; - genome[i]->mutntype = mother->genome[i]->mutntype; - genome[i]->Pmutn = mother->genome[i]->Pmutn; - genome[i]->mutnSize = mother->genome[i]->mutnSize; - genome[i]->allele[0] = mother->copy(i,0); - if (father == 0) genome[i]->allele[1] = 0.0; - else genome[i]->allele[1] = father->copy(i,1); -} - -} - -Genome::~Genome(void) -{ -if (genome != 0) { - for (int i = 0; i < genomesize; i++) { - delete genome[i]; genome[i] = NULL; - } - delete genome; genome = NULL; -} - -} - -// Set up new gene -void Genome::setGene(int i,short exp,short mtype,float pmut,float msize,double a0,double a1) -{ -if (exp >= 0 && exp <= 4) genome[i]->expression = exp; -if (mtype >= 0 && mtype <= 5) genome[i]->mutntype = mtype; -if (pmut >= 0.0 && pmut <= 1.0) genome[i]->Pmutn = pmut; -if (msize > 0.0) genome[i]->mutnSize = msize; -genome[i]->allele[0] = a0; -genome[i]->allele[1] = a1; -} - -// Return a single allele, having applied mutation -// Either allele is returned with equal probability, unless the gene is sex-linked, -// in which case a male returns the allele inherited from his father and a female -// returns the allele inherited from her mother -double Genome::copy(int i,int sexx) -{ -double genevalue,logP,logitP; - -switch (genome[i]->expression) { -case 0: // haploid - genevalue = genome[i]->allele[0]; - break; -case 1: // sex-linked gene - if (sexx == 0 || sexx == 1) genevalue = genome[i]->allele[sexx]; - else return -999999.999; // indicates error in sex of parent animal - break; -default: // otherwise - select one of the alleles at random - genevalue = genome[i]->allele[pRandom->Bernoulli(0.5)]; - ; -} -#if RSDEBUG -//DEBUGLOG << "Gene::copy(): expression=" << expression -// << " mutntype=" << mutntype -// << " Pmutn=" << Pmutn << " mutnSize=" << mutnSize -// << " allele[0]=" << allele[0] << " allele[1]=" << allele[1] -// << " genevalue=" << genevalue -// << endl; -#endif -// apply mutation to the gene -if (pRandom->Random() < genome[i]->Pmutn) { - switch (genome[i]->mutntype) { - case 0: genevalue = pRandom->Random(); break; - case 1: genevalue += pRandom->Normal(0.0,genome[i]->mutnSize); break; - case 2: - logitP = log(genevalue/(1.0-genevalue)); - logitP += pRandom->Normal(0.0,genome[i]->mutnSize); - genevalue = 1.0 / (1 + exp(-logitP)); - if (genevalue >= 1.0) genevalue = 0.999999999; - if (genevalue <= 0.0) genevalue = 0.000000001; - break; - case 3: - logP = log(genevalue); - logP += pRandom->Normal(0.0,genome[i]->mutnSize); - genevalue = exp(logP); - break; - case 4: - genevalue += pRandom->Random()*(2.0*genome[i]->mutnSize) - genome[i]->mutnSize; - break; - case 5: - genevalue += pRandom->Random()*(2.0*genome[i]->mutnSize) - genome[i]->mutnSize; - if (genevalue > 1.0) genevalue = 1.0; - if (genevalue < 0.0) genevalue = 0.0; - break; - default: genevalue = -888888.888; // error in mutation type - } -} -#if RSDEBUG -//DEBUGLOG << "Gene::copy():" -// << " allele[0]=" << allele[0] << " allele[1]=" << allele[1] -// << " genevalue=" << genevalue -// << endl; -#endif -return genevalue; -} - -// Return the expressed value of a gene -double Genome::express(int i,int sexx) -{ -double genevalue; - -switch (genome[i]->expression) { - case 0: // sex-linked gene - genevalue = genome[i]->allele[0]; - break; - case 1: // sex-linked gene - if (sexx == 0 || sexx == 1) genevalue = genome[i]->allele[sexx]; - else genevalue = -999999.999; // indicates error in sex of parent animal - break; - case 2: // dominance of greater value - genevalue = genome[i]->allele[0]; - if (genome[i]->allele[1] > genevalue) genevalue = genome[i]->allele[1]; - break; - case 3: // co-dominance (mean value) - genevalue = (genome[i]->allele[0] + genome[i]->allele[1]) / 2.0; - break; - case 4: // sex-expressed co-dominance -// NB does not differ from co-dominance other than when genes interact to determine -// phenotypic level of expression - genevalue = (genome[i]->allele[0] + genome[i]->allele[1]) / 2.0; -// if (sexx == 0 || sexx == 1) genevalue = genome[i]->allele[sexx]; -// else genevalue = -999999.999; // indicates error in sex of parent animal - break; -default: genevalue = -777777.777; // error in expression type -} - -return genevalue; - -} - -locus Genome::getAlleles(int g) { -locus l; -if (g >= 0 && g < genomesize) { - l.allele[0] = genome[g]->allele[0]; - l.allele[1] = genome[g]->allele[1]; -} -else { - l.allele[0] = l.allele[1] = 0.0; -} -return l; -} - -*/ - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - diff --git a/RangeShiftR/src/RScore/Genome.h b/RangeShiftR/src/RScore/Genome.h deleted file mode 100644 index d42c161..0000000 --- a/RangeShiftR/src/RScore/Genome.h +++ /dev/null @@ -1,251 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Genome - -Implements the Genome class - -Author: Steve Palmer & Roslyn Henry, University of Aberdeen - -Last updated: 28 July 2021 by Greta Bocedi - -------------------------------------------------------------------------------*/ - -#ifndef GenomeH -#define GenomeH - -#include -#include -//#include "maths.h" - -#include "Parameters.h" -#include "Species.h" - -#define INTBASE 100.0; // to convert integer alleles into continuous traits - -struct locus { short allele[2]; }; -struct locusOK { short allele[2]; bool ok; }; - -//--------------------------------------------------------------------------- - -class Chromosome { - -public: - Chromosome(int); - ~Chromosome(); - short nLoci(void); - double additive( // Return trait value on normalised genetic scale - const bool // diploid - ); - double meanvalue( // Return trait value on normalised genetic scale - const bool // diploid - ); - double additive( // Return trait value on normalised genetic scale - const short, // locus - const bool // diploid - ); -// double probval(const bool); - locus alleles( // Return allele values at a specified locus - const int // position of locus on chromosome - ); - void initialise( // Set up chromosome at simulation initialisation - const double, // normalised phenotypic trait value - const double, // s.d. of allelic variance (genetic scale) - const bool // diploid - ); - void initialise( // Set up specified locus at simulation initialisation - const short, // locus - const short, // position: 0 from mother, 1 from father - const int // allele value - ); - void inherit( // Inherit chromosome from specified parent - const Chromosome*, // pointer to parent's chromosome - const short, // position: 0 from mother, 1 from father - const short, // no. of loci - const double, // mutation probability - const double, // crossover probability - const double, // s.d. of mutation magnitude (genetic scale) - const bool // diploid - ); - -protected: - -private: - short nloci; - locus *pLoci; - -}; - -//--------------------------------------------------------------------------- - -class Genome{ - -public: -// -// static float delPMutation, delEffectSize, delDominance, delBackMutation ,genomeMeanRecombination; -// static int delMaxSize, delNMutations; -// static bool genomeCanRecombine, genomeCompletelyUnlinked; -// - - Genome(); - Genome(int,int,bool); - Genome(Species*); - Genome(Species*,Genome*,Genome*); - ~Genome(); - void setGene( // Set up new gene at initialisation for 1 chromosome per trait - const short, // chromosome number - const short, // expression type (NOT CURRENTLY USED) - const double, // normalised trait value - const double // s.d. of allelic variance - ); - void setTrait( // Set up trait at initialisation for trait mapping - Species*, // pointer to Species - const int, // trait number - const double, // normalised trait value - const double // s.d. of allelic variance - ); - void setNeutralLoci( // Set up neutral loci at initialisation - Species*, // pointer to Species - const double // s.d. of allelic variance - ); -// double copy(int,int); - double express( - // Return the expressed value of a gene when species has one chromosome per trait - short, // chromosome number - short, // expression type (NOT CURRENTLY USED) - short // individual's sex (NOT CURRENTLY USED) - ); -// double express( -// short, // chromosome number -// short // locus on chromosome -// ); - double express( - // Return the expressed value of a trait when genetic architecture is defined - Species*, // pointer to Species - short // trait number -// bool // true if trait is sex-dependent - ); - locusOK getAlleles( // Get allele values at a specified locus - short, // chromosome number - short // locus position on chromosome - ); - // SCFP NEW DECLARATIONS - void setDiploid(bool); - bool isDiploid(void); - void inherit( // Inherit from specified parent - const Genome*, // pointer to parent's genome - const short, // position: 0 from mother, 1 from father - const short, // chromasome number - const double, // mutation probability - const double, // crossover probability - const double // s.d. of mutation magnitude (genetic scale) - ); -// void setStaticData(genomeData); -// genomeData getStaticData(void); - short getNChromosomes(void); - void outGenHeaders( - const int, // replicate - const int, // landscape number - const bool // output as cross table? - ); - void outGenetics( - const int, // replicate - const int, // year - const int, // species number - const int, // individual ID - const bool // output as cross table? - ); - - -private: - short nChromosomes; // no. of chromosomes - bool diploid; - Chromosome **pChromosome; - -}; - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - -/* - -struct gene { - short expression; // used to control how gene is expressed: - // 0 = haploid - // 1 = sex-linked - // 2 = dominance of greater value - // 3 = co-dominance (mean value) - // 4 = sex-expressed (but not sex-linked) - short mutntype; // mutation type: - // 0 = random in [0,1] - // 1 = normal - // 2 = logit scale - // 3 = log-normal (gene must be positive) - // 4 = RS method - random in specified range - // 5 = RS method - random in specified range and constrained to [0,1] - float Pmutn; // mutation probability - float mutnSize; // mutation size (s.d. of normal distribution) - double allele[2]; // allele pair: [0] from mother, [1] from father -}; -; - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - -class Genome -{ -public: - Genome(int); - Genome(Genome*,Genome*); - ~Genome(void); - void setGene(int); - void setGene(int,short,short,float,float,double,double); // new gene - double copy(int,int); - double express(int,int); - locus getAlleles( // Get allele values at a specified locus - int // locus position within genome - ); - -private: - int genomesize; - gene **genome; - -}; - -*/ - -//--------------------------------------------------------------------------- - -extern paramSim *paramsSim; -extern RSrandom *pRandom; - -#if RSDEBUG -extern ofstream DEBUGLOG; -extern ofstream MUTNLOG; -extern void DebugGUI(string); -#endif - -//--------------------------------------------------------------------------- - -#endif diff --git a/RangeShiftR/src/RScore/Individual.cpp b/RangeShiftR/src/RScore/Individual.cpp deleted file mode 100644 index 357f175..0000000 --- a/RangeShiftR/src/RScore/Individual.cpp +++ /dev/null @@ -1,2454 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Individual.h" -//--------------------------------------------------------------------------- - -int Individual::indCounter = 0; - -//--------------------------------------------------------------------------- - -// Individual constructor -Individual::Individual(Cell *pCell,Patch *pPatch,short stg,short a,short repInt, - float probmale,bool movt,short moveType) -{ -indId = indCounter; indCounter++; // unique identifier for each individual -#if RSDEBUG -//DEBUGLOG << "Individual::Individual(): indId=" << indId -// << " stg=" << stg << " a=" << a << " probmale=" << probmale -// << endl; -#endif - -stage = stg; -if (probmale <= 0.0) sex = 0; -else sex = pRandom->Bernoulli(probmale); -age = a; -status = 0; - -if (sex == 0 && repInt > 0) { // set no. of fallow seasons for female - fallow = pRandom->IRandom(0,repInt); -} -else fallow = 9999; -isDeveloping = false; -pPrevCell = pCurrCell = pCell; -pNatalPatch = pPatch; -if (movt) { - locn loc = pCell->getLocn(); - path = new pathData; - path->year = 0; path->total = 0; path->out = 0; - path->pSettPatch = 0; path->settleStatus = 0; -// path->leftNatalPatch = false; -#if RS_RCPP - path->pathoutput = 1; -#endif - if (moveType == 1) { // SMS - // set up location data for SMS - smsData = new smsdata; - smsData->dp = smsData->gb = smsData->alphaDB = 1.0; - smsData->betaDB = 1; - smsData->prev.x = loc.x; smsData->prev.y = loc.y; // previous location - smsData->goal.x = loc.x; smsData->goal.y = loc.y; // goal location - initialised for dispersal bias - } - else smsData = 0; - if (moveType == 2) { // CRW - // set up continuous co-ordinates etc. for CRW movement - crw = new crwParams; - crw->xc = ((float)pRandom->Random()*0.999f) + (float)loc.x; - crw->yc = (float)(pRandom->Random()*0.999f) + (float)loc.y; - crw->prevdrn = (float)(pRandom->Random()*2.0 * PI); - crw->stepL = crw->rho = 0.0; - } - else crw = 0; -} -else { - path = 0; crw = 0; smsData = 0; -} -emigtraits = 0; -kerntraits = 0; -setttraits = 0; -pGenome = 0; -#if RSDEBUG -//locn currloc = pCurrCell->getLocn(); -//DEBUGLOG << "Individual::Individual(): indId=" << indId -// << " x=" << currloc.x << " y=" << currloc.y -//// << " smsData=" << smsData << " dp=" << smsData->dp -// << endl; -#endif -} - -Individual::~Individual(void) { -if (path != 0) delete path; -if (crw != 0) delete crw; -if (smsData != 0) delete smsData; -if (emigtraits != 0) delete emigtraits; -if (kerntraits != 0) delete kerntraits; -if (setttraits != 0) delete setttraits; - -if (pGenome != 0) delete pGenome; - -} - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -// Set genes for individual variation from species initialisation parameters -void Individual::setGenes(Species *pSpecies,int resol) { -demogrParams dem = pSpecies->getDemogr(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -genomeData gen = pSpecies->getGenomeData(); -simParams sim = paramsSim->getSim(); -int ntraits; // first trait for all/female expression, second for male expression - -if (gen.trait1Chromosome) { - pGenome = new Genome(pSpecies->getNChromosomes(),pSpecies->getNLoci(0), - pSpecies->isDiploid()); -} -else { - pGenome = new Genome(pSpecies); -} -#if RSDEBUG -//DEBUGLOG << endl; -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " sex=" << sex -// << " trait1Chromosome=" << gen.trait1Chromosome << " pGenome=" << pGenome -// << endl; -#endif - -int gposn = 0; // current position on genome -int expr = 0; // gene expression type - NOT CURRENTLY USED - -//int emigposn = 0; -#if RSDEBUG -//DEBUGLOG << "Individual::setGenes(): emigration genes" << endl; -#endif -if (emig.indVar) { // set emigration genes - int emigposn = gposn; - double d0,alpha,beta; - emigParams eparams; -// emigScales scale = pSpecies->getEmigScales(); - if (emig.sexDep) { // must be a sexual species - ntraits = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction (haploid) - ntraits = 1; - } - else { // sexual reproduction - ntraits = 1; - } - } - for (int g = 0; g < ntraits; g++) { // first trait for females/all, second for males - eparams = pSpecies->getEmigParams(0,g); - d0 = pRandom->Normal(0.0,eparams.d0SD) / eparams.d0Scale; - if (emig.densDep) { - alpha = pRandom->Normal(0.0,eparams.alphaSD) / eparams.alphaScale; - beta = pRandom->Normal(0.0,eparams.betaSD) / eparams.betaScale; - } -#if RSDEBUG -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " g=" << g -// << " eparams.d0Mean=" << eparams.d0Mean << " eparams.d0SD=" << eparams.d0SD -// << " eparams.d0Scale=" << eparams.d0Scale << " d0=" << d0 -//// << " log(d0/(1.0-d0))=" << log(d0/(1.0-d0)) -// << endl; -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " g=" << g -// << " eparams.alphaMean=" << eparams.alphaMean << " eparams.alphaSD=" << eparams.alphaSD -// << " eparams.alphaScale=" << eparams.alphaScale << " alpha=" << alpha -// << endl; -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " g=" << g -// << " eparams.betaMean=" << eparams.betaMean << " eparams.betaSD=" << eparams.betaSD -// << " eparams.betaScale=" << eparams.betaScale << " beta=" << beta -// << endl; -#endif - if (gen.trait1Chromosome) { - pGenome->setGene(gposn++,expr,d0,gen.alleleSD); - if (emig.densDep) { - pGenome->setGene(gposn++,expr,alpha,gen.alleleSD); - pGenome->setGene(gposn++,expr,beta,gen.alleleSD); - } - } - else { - pGenome->setTrait(pSpecies,gposn++,d0,gen.alleleSD); - if (emig.densDep) { - pGenome->setTrait(pSpecies,gposn++,alpha,gen.alleleSD); - pGenome->setTrait(pSpecies,gposn++,beta,gen.alleleSD); - } - } - } - // record phenotypic traits - if (emig.densDep) { - setEmigTraits(pSpecies,emigposn,3,emig.sexDep); - } - else { - setEmigTraits(pSpecies,emigposn,1,emig.sexDep); - } -} - -//int trfrposn = 0; -if (trfr.indVar) { // set transfer genes - int trfrposn = gposn; - if (trfr.sexDep) { // must be a sexual species - ntraits = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ntraits = 1; - } - else { // sexual reproduction - ntraits = 1; - } - } -// trfrScales scale = pSpecies->getTrfrScales(); - if (trfr.moveModel) { - if (trfr.moveType == 1) { // set SMS genes - double dp,gb,alphaDB,betaDB; - trfrSMSParams smsparams = pSpecies->getSMSParams(0,0); // only traits for females/all - trfrSMSTraits smstraits = pSpecies->getSMSTraits(); - dp = pRandom->Normal(0.0,smsparams.dpSD) / smsparams.dpScale; - gb = pRandom->Normal(0.0,smsparams.gbSD) / smsparams.gbScale; - if (smstraits.goalType == 2) { - alphaDB = pRandom->Normal(0.0,smsparams.alphaDBSD) / smsparams.alphaDBScale; - betaDB = pRandom->Normal(0.0,smsparams.betaDBSD) / smsparams.betaDBScale; - } - if (gen.trait1Chromosome) { - pGenome->setGene(gposn++,expr,dp,gen.alleleSD); - pGenome->setGene(gposn++,expr,gb,gen.alleleSD); - if (smstraits.goalType == 2) { - pGenome->setGene(gposn++,expr,alphaDB,gen.alleleSD); - pGenome->setGene(gposn++,expr,betaDB,gen.alleleSD); - } - } - else { - pGenome->setTrait(pSpecies,gposn++,dp,gen.alleleSD); - pGenome->setTrait(pSpecies,gposn++,gb,gen.alleleSD); - if (smstraits.goalType == 2) { - pGenome->setTrait(pSpecies,gposn++,alphaDB,gen.alleleSD); - pGenome->setTrait(pSpecies,gposn++,betaDB,gen.alleleSD); - } - } - // record phenotypic traits - if (smstraits.goalType == 2) - setSMSTraits(pSpecies,trfrposn,4,false); - else - setSMSTraits(pSpecies,trfrposn,2,false); - } - if (trfr.moveType == 2) { // set CRW genes - double stepL,rho; - trfrCRWParams m = pSpecies->getCRWParams(0,0); // only traits for females/all - stepL = pRandom->Normal(0.0,m.stepLgthSD) / m.stepLScale; - rho = pRandom->Normal(0.0,m.rhoSD) / m.rhoScale; - if (gen.trait1Chromosome) { - pGenome->setGene(gposn++,expr,stepL,gen.alleleSD); - pGenome->setGene(gposn++,expr,rho,gen.alleleSD); - } - else { - pGenome->setTrait(pSpecies,gposn++,stepL,gen.alleleSD); - pGenome->setTrait(pSpecies,gposn++,rho,gen.alleleSD); - } - // record phenotypic traits - setCRWTraits(pSpecies,trfrposn,2,false); - } - } - else { // set kernel genes - double dist1,dist2,prob1; - trfrKernParams k; - for (int g = 0; g < ntraits; g++) { // first traits for females/all, second for males - k = pSpecies->getKernParams(0,g); - dist1 = pRandom->Normal(0.0,k.dist1SD) / k.dist1Scale; - if (trfr.twinKern) - { - dist2 = pRandom->Normal(0.0,k.dist2SD) / k.dist2Scale; - prob1 = pRandom->Normal(0.0,k.PKern1SD) / k.PKern1Scale; - } - if (gen.trait1Chromosome) { - pGenome->setGene(gposn++,expr,dist1,gen.alleleSD); - if (trfr.twinKern) - { - pGenome->setGene(gposn++,expr,dist2,gen.alleleSD); - pGenome->setGene(gposn++,expr,prob1,gen.alleleSD); - } - } - else { - pGenome->setTrait(pSpecies,gposn++,dist1,gen.alleleSD); - if (trfr.twinKern) - { - pGenome->setTrait(pSpecies,gposn++,dist2,gen.alleleSD); - pGenome->setTrait(pSpecies,gposn++,prob1,gen.alleleSD); - } - } - } - // record phenotypic traits - if (trfr.twinKern) - { - setKernTraits(pSpecies,trfrposn,3,resol,trfr.sexDep); - } - else { - setKernTraits(pSpecies,trfrposn,1,resol,trfr.sexDep); - } - } -} - -//int settposn = 0; -#if RSDEBUG -//DEBUGLOG << "Individual::setGenes(): settlement genes" << endl; -#endif -if (sett.indVar) { - int settposn = gposn; - double s0,alpha,beta; - settParams sparams; -// settScales scale = pSpecies->getSettScales(); - if (sett.sexDep) { // must be a sexual species - ntraits = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ntraits = 1; - } - else { // sexual reproduction - ntraits = 1; - } - } - for (int g = 0; g < ntraits; g++) { // first trait for females/all, second for males - if (sim.batchMode) { - sparams = pSpecies->getSettParams(0,g); - } - else { // individual variability not (yet) implemented as sex-dependent in GUI - sparams = pSpecies->getSettParams(0,0); - } - s0 = pRandom->Normal(0.0,sparams.s0SD) / sparams.s0Scale; - alpha = pRandom->Normal(0.0,sparams.alphaSSD) / sparams.alphaSScale; - beta = pRandom->Normal(0.0,sparams.betaSSD) / sparams.betaSScale; -#if RSDEBUG -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " g=" << g -// << " sparams.s0Mean=" << sparams.s0Mean -// << " sparams.s0SD=" << sparams.s0SD -// << " sparams.s0Scale=" << sparams.s0Scale -// << " s0=" << s0 -// << endl; -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " g=" << g -// << " sparams.alphaSMean=" << sparams.alphaSMean -// << " sparams.alphaSSD=" << sparams.alphaSSD -// << " sparams.alphaSScale=" << sparams.alphaSScale -// << " alpha=" << alpha -// << endl; -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " g=" << g -// << " sparams.betaSMean=" << sparams.betaSMean -// << " sparams.betaSSD=" << sparams.betaSSD -// << " sparams.betaSScale=" << sparams.betaSScale -// << " beta=" << beta -// << endl; -#endif - if (gen.trait1Chromosome) { - pGenome->setGene(gposn++,expr,s0,gen.alleleSD); - pGenome->setGene(gposn++,expr,alpha,gen.alleleSD); - pGenome->setGene(gposn++,expr,beta,gen.alleleSD); - } - else { - pGenome->setTrait(pSpecies,gposn++,s0,gen.alleleSD); - pGenome->setTrait(pSpecies,gposn++,alpha,gen.alleleSD); - pGenome->setTrait(pSpecies,gposn++,beta,gen.alleleSD); - } - } - // record phenotypic traits - setSettTraits(pSpecies,settposn,3,sett.sexDep); -} - -if (!gen.trait1Chromosome) { - if (gen.neutralMarkers || pSpecies->getNNeutralLoci() > 0) { - pGenome->setNeutralLoci(pSpecies,gen.alleleSD); - } -} -#if RSDEBUG -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " finished" -// << endl; -#endif -} - -// Inherit genome from parent(s) -void Individual::setGenes(Species *pSpecies,Individual *mother,Individual *father, - int resol) -{ -#if RSDEBUG -//locn currloc = pCurrCell->getLocn(); -//DEBUGLOG << "Individual::setGenes(): indId=" << indId -// << " x=" << currloc.x << " y=" << currloc.y -//// << " pSpecies=" << pSpecies -// << " mother=" << mother -// << " motherID=" << mother->getId() -// << " father=" << father; -//if (father != 0) DEBUGLOG << " fatherID=" << father->getId(); -//DEBUGLOG << endl; -#endif -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); - -Genome *pFatherGenome; -if (father == 0) pFatherGenome = 0; else pFatherGenome = father->pGenome; - -pGenome = new Genome(pSpecies,mother->pGenome,pFatherGenome); - -if (emig.indVar) { - // record emigration traits - if (father == 0) { // haploid - if (emig.densDep) { - setEmigTraits(pSpecies,0,3,0); - } - else { - setEmigTraits(pSpecies,0,1,0); - } - } - else { // diploid - if (emig.densDep) { - setEmigTraits(pSpecies,0,3,emig.sexDep); - } - else { - setEmigTraits(pSpecies,0,1,emig.sexDep); - } - } -} - -if (trfr.indVar) { - // record movement model traits - if (trfr.moveModel) { - if (trfr.moveType == 1) { // SMS - trfrSMSTraits s = pSpecies->getSMSTraits(); - if (s.goalType == 2) - setSMSTraits(pSpecies,trfr.movtTrait[0],4,0); - else - setSMSTraits(pSpecies,trfr.movtTrait[0],2,0); - } - if (trfr.moveType == 2) { // CRW - setCRWTraits(pSpecies,trfr.movtTrait[0],2,0); - } - } - else { // kernel - if (father == 0) { // haploid - if (trfr.twinKern) - { - setKernTraits(pSpecies,trfr.movtTrait[0],3,resol,0); - } - else { - setKernTraits(pSpecies,trfr.movtTrait[0],1,resol,0); - } - } - else { // diploid - if (trfr.twinKern) - { - setKernTraits(pSpecies,trfr.movtTrait[0],3,resol,trfr.sexDep); - } - else { - setKernTraits(pSpecies,trfr.movtTrait[0],1,resol,trfr.sexDep); - } - } - } -} - -if (sett.indVar) { - // record settlement traits - if (father == 0) { // haploid - setSettTraits(pSpecies,sett.settTrait[0],3,0); - } - else { // diploid - setSettTraits(pSpecies,sett.settTrait[0],3,sett.sexDep); -// setSettTraits(pSpecies,sett.settTrait[0],3,0); - } -} - -#if RSDEBUG -//emigParams e = getEmigTraits(0,1,0); -//DEBUGLOG << "Individual::setGenes(): indId=" << indId << " finished " -// << " d0=" << e.d0 -//// << " alpha=" << e.alpha << " beta=" << e.beta -// << endl; -#endif -} - -//--------------------------------------------------------------------------- - -// Identify whether an individual is a potentially breeding female - -// if so, return her stage, otherwise return 0 -int Individual::breedingFem(void) { -if (sex == 0) { - if (status == 0 || status == 4 || status == 5) return stage; - else return 0; -} -else return 0; -} - -int Individual::getId(void) { return indId; } - -int Individual::getSex(void) { return sex; } - -int Individual::getStatus(void) { return status; } - -indStats Individual::getStats(void) { -indStats s; -s.stage = stage; s.sex = sex; s.age = age; s.status = status; s.fallow = fallow; -s.isDeveloping = isDeveloping; -return s; -} - -Cell* Individual::getLocn(const short option) { -if (option == 0) { // return previous location - return pPrevCell; -} -else { // return current location - return pCurrCell; -} -} - -Patch* Individual::getNatalPatch(void) { return pNatalPatch; } - -void Individual::setYearSteps(int t) { -if (path != 0 && t >= 0) { - if (t >= 0) path->year = t; - else path->year = 666; -} -#if RSDEBUG -//DEBUGLOG << "Individual::setYearSteps(): indId=" << indId -// << " t=" << t << " path->year=" << path->year -// << endl; -#endif -} - -pathSteps Individual::getSteps(void) { -pathSteps s; -if (path == 0) { - s.year = 0; s.total = 0; s.out = 0; -} -else { - s.year = path->year; s.total = path->total; s.out = path->out; -} -return s; -} - -settlePatch Individual::getSettPatch(void) { -settlePatch s; -if (path == 0) { - s.pSettPatch = 0; s.settleStatus = 0; -} -else { - s.pSettPatch = path->pSettPatch; s.settleStatus = path->settleStatus; -} -return s; -} - -void Individual::setSettPatch(const settlePatch s) { -if (path == 0) { - path = new pathData; - path->year = 0; path->total = 0; path->out = 0; path->settleStatus = 0; -#if RS_RCPP - path->pathoutput = 1; -#endif -} -if (s.settleStatus >= 0 && s.settleStatus <= 2) path->settleStatus = s.settleStatus; -path->pSettPatch = s.pSettPatch; -} - -// Set phenotypic emigration traits -void Individual::setEmigTraits(Species *pSpecies,short emiggenelocn,short nemigtraits, - bool sexdep) { -#if RSDEBUG -//DEBUGLOG << "Individual::setEmigTraits(): indId=" << indId -// << " emiggenelocn=" << emiggenelocn << " nemigtraits=" << nemigtraits << " sexdep=" << sexdep -// << endl; -#endif -emigTraits e; e.d0 = e.alpha = e.beta = 0.0; -if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - if (nemigtraits == 3) { // emigration is density-dependent - e.d0 = (float)pGenome->express(emiggenelocn+3*sex,0,0); - e.alpha = (float)pGenome->express(emiggenelocn+3*sex+1,0,0); - e.beta = (float)pGenome->express(emiggenelocn+3*sex+2,0,0); - } - else { - e.d0 = (float)pGenome->express(emiggenelocn+sex,0,0); - } - } - else { - e.d0 = (float)pGenome->express(emiggenelocn,0,0); - if (nemigtraits == 3) { // emigration is density-dependent - e.alpha = (float)pGenome->express(emiggenelocn+1,0,0); - e.beta = (float)pGenome->express(emiggenelocn+2,0,0); - } - } - } - else { - if (sexdep) { - if (nemigtraits == 3) { // emigration is density-dependent - e.d0 = (float)pGenome->express(pSpecies,emiggenelocn+3*sex); - e.alpha = (float)pGenome->express(pSpecies,emiggenelocn+3*sex+1); - e.beta = (float)pGenome->express(pSpecies,emiggenelocn+3*sex+2); - } - else { - e.d0 = (float)pGenome->express(pSpecies,emiggenelocn+sex); - } - } - else { - e.d0 = (float)pGenome->express(pSpecies,emiggenelocn); - if (nemigtraits == 3) { // emigration is density-dependent - e.alpha = (float)pGenome->express(pSpecies,emiggenelocn+1); - e.beta = (float)pGenome->express(pSpecies,emiggenelocn+2); - } - } - } -} -#if RSDEBUG -//DEBUGLOG << "Individual::setEmigTraits(): indId=" << indId -// << " e.d0=" << e.d0 << " e.alpha=" << e.alpha << " e.beta=" << e.beta -// << endl; -#endif - -emigParams eparams; -if (sexdep) { - eparams = pSpecies->getEmigParams(0,sex); -} -else { - eparams = pSpecies->getEmigParams(0,0); -} -#if RSDEBUG -//DEBUGLOG << "Individual::setEmigTraits(): indId=" << indId -// << " eparams.betaMean=" << eparams.betaMean << " eparams.betaSD=" << eparams.betaSD -// << " eparams.betaScale=" << eparams.betaScale -// << endl; -#endif -emigtraits = new emigTraits; -emigtraits->d0 = (float)(e.d0*eparams.d0Scale + eparams.d0Mean); -emigtraits->alpha = (float)(e.alpha*eparams.alphaScale + eparams.alphaMean); -emigtraits->beta = (float)(e.beta*eparams.betaScale + eparams.betaMean); -#if RSDEBUG -//DEBUGLOG << "Individual::setEmigTraits(): indId=" << indId -// << " emigtraits->d0=" << emigtraits->d0 -// << " emigtraits->alpha=" << emigtraits->alpha << " emigtraits->beta=" << emigtraits->beta -// << endl; -#endif -if (emigtraits->d0 < 0.0) emigtraits->d0 = 0.0; -if (emigtraits->d0 > 1.0) emigtraits->d0 = 1.0; -#if RSDEBUG -//DEBUGLOG << "Individual::setEmigTraits(): indId=" << indId -// << " emigtraits->d0=" << emigtraits->d0 -// << " emigtraits->alpha=" << emigtraits->alpha << " emigtraits->beta=" << emigtraits->beta -// << endl; -#endif -return; -} - -// Get phenotypic emigration traits -emigTraits Individual::getEmigTraits(void) { -#if RSDEBUG -//DEBUGLOG << "Individual::getEmigTraits(): indId=" << indId -// << endl; -#endif -emigTraits e; e.d0 = e.alpha = e.beta = 0.0; -if (emigtraits != 0) { - e.d0 = emigtraits->d0; - e.alpha = emigtraits->alpha; - e.beta = emigtraits->beta; -} -#if RSDEBUG -//DEBUGLOG << "Individual::getEmigTraits(): indId=" << indId -// << " e.d0=" << e.d0 << " e.alpha=" << e.alpha << " e.beta=" << e.beta -// << endl; -#endif - -return e; -} - -// Set phenotypic transfer by kernel traits -void Individual::setKernTraits(Species *pSpecies,short kerngenelocn,short nkerntraits, - int resol,bool sexdep) { -#if RSDEBUG -//DEBUGLOG << "Individual::setKernTraits(): indId=" << indId -// << " kerngenelocn=" << kerngenelocn << " nkerntraits=" << nkerntraits << " sexdep=" << sexdep -// << endl; -#endif -trfrKernTraits k; k.meanDist1 = k.meanDist2 = k.probKern1 = 0.0; -if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - if (nkerntraits == 3) { // twin kernel - k.meanDist1 = (float)pGenome->express(kerngenelocn+3*sex,0,sex); - k.meanDist2 = (float)pGenome->express(kerngenelocn+3*sex+1,0,sex); - k.probKern1 = (float)pGenome->express(kerngenelocn+3*sex+2,0,sex); - } - else { - k.meanDist1 = (float)pGenome->express(kerngenelocn+sex,0,sex); - } - } - else { - k.meanDist1 = (float)pGenome->express(kerngenelocn,0,0); - if (nkerntraits == 3) { // twin kernel - k.meanDist2 = (float)pGenome->express(kerngenelocn+1,0,0); - k.probKern1 = (float)pGenome->express(kerngenelocn+2,0,0); - } - } - } - else { - if (sexdep) { - if (nkerntraits == 3) { // twin kernel - k.meanDist1 = (float)pGenome->express(pSpecies,kerngenelocn+3*sex); - k.meanDist2 = (float)pGenome->express(pSpecies,kerngenelocn+3*sex+1); - k.probKern1 = (float)pGenome->express(pSpecies,kerngenelocn+3*sex+2); - } - else { - k.meanDist1 = (float)pGenome->express(pSpecies,kerngenelocn+sex); - } - } - else { - k.meanDist1 = (float)pGenome->express(pSpecies,kerngenelocn); - if (nkerntraits == 3) { // twin kernel - k.meanDist2 = (float)pGenome->express(pSpecies,kerngenelocn+1); - k.probKern1 = (float)pGenome->express(pSpecies,kerngenelocn+2); - } - } - } -} -#if RSDEBUG -//DEBUGLOG << "Individual::setKernTraits(): indId=" << indId -// << " k.meanDist1=" << k.meanDist1 << " k.meanDist2=" << k.meanDist2 -// << " k.probKern1=" << k.probKern1 -// << endl; -#endif - -trfrKernParams kparams; -if (sexdep) { - kparams = pSpecies->getKernParams(0,sex); -} -else { - kparams = pSpecies->getKernParams(0,0); -} -kerntraits = new trfrKernTraits; -kerntraits->meanDist1 = (float)(k.meanDist1*kparams.dist1Scale + kparams.dist1Mean); -kerntraits->meanDist2 = (float)(k.meanDist2*kparams.dist2Scale + kparams.dist2Mean); -kerntraits->probKern1 = (float)(k.probKern1*kparams.PKern1Scale + kparams.PKern1Mean); -#if RSDEBUG -//DEBUGLOG << "Individual::setKernTraits(): indId=" << indId -// << " kerntraits->meanDist1=" << kerntraits->meanDist1 -// << " kerntraits->meanDist2=" << kerntraits->meanDist2 -// << " kerntraits->probKern1=" << kerntraits->probKern1 -// << endl; -#endif -if (!pSpecies->useFullKernel()) { - // kernel mean(s) may not be less than landscape resolution - if (kerntraits->meanDist1 < resol) kerntraits->meanDist1 = (float)resol; - if (kerntraits->meanDist2 < resol) kerntraits->meanDist2 = (float)resol; -} -if (kerntraits->probKern1 < 0.0) kerntraits->probKern1 = 0.0; -if (kerntraits->probKern1 > 1.0) kerntraits->probKern1 = 1.0; -#if RSDEBUG -//DEBUGLOG << "Individual::setKernTraits(): indId=" << indId -// << " kerntraits->meanDist1=" << kerntraits->meanDist1 -// << " kerntraits->meanDist2=" << kerntraits->meanDist2 -// << " kerntraits->probKern1=" << kerntraits->probKern1 -// << endl; -#endif -return; -} - -// Get phenotypic emigration traits -trfrKernTraits Individual::getKernTraits(void) { -#if RSDEBUG -//DEBUGLOG << "Individual::getKernTraits(): indId=" << indId -// << endl; -#endif -trfrKernTraits k; k.meanDist1 = k.meanDist2 = k.probKern1 = 0.0; -if (kerntraits != 0) { - k.meanDist1 = kerntraits->meanDist1; - k.meanDist2 = kerntraits->meanDist2; - k.probKern1 = kerntraits->probKern1; -} -#if RSDEBUG -//DEBUGLOG << "Individual::getKernTraits(): indId=" << indId -// << " k.meanDist1=" << k.meanDist1 << " k.meanDist2=" << k.meanDist1 -// << " k.probKern1=" << k.probKern1 -// << endl; -#endif - -return k; -} - -// Set phenotypic transfer by SMS traits -void Individual::setSMSTraits(Species *pSpecies,short SMSgenelocn,short nSMStraits, - bool sexdep) { -#if RSDEBUG -//DEBUGLOG << "Individual::setSMSTraits(): indId=" << indId -// << " SMSgenelocn=" << SMSgenelocn << " nSMStraits=" << nSMStraits << " sexdep=" << sexdep -// << endl; -#endif -trfrSMSTraits s = pSpecies->getSMSTraits(); -double dp,gb,alphaDB,betaDB; -dp = gb = alphaDB = betaDB = 0.0; -if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - dp = pGenome->express(SMSgenelocn,0,0); - gb = pGenome->express(SMSgenelocn+1,0,0); - if (nSMStraits == 4) { - alphaDB = pGenome->express(SMSgenelocn+2,0,0); - betaDB = pGenome->express(SMSgenelocn+3,0,0); - } - } - else { - dp = pGenome->express(SMSgenelocn,0,0); - gb = pGenome->express(SMSgenelocn+1,0,0); - if (nSMStraits == 4) { - alphaDB = pGenome->express(SMSgenelocn+2,0,0); - betaDB = pGenome->express(SMSgenelocn+3,0,0); - } - } - } - else { - if (sexdep) { - dp = pGenome->express(pSpecies,SMSgenelocn); - gb = pGenome->express(pSpecies,SMSgenelocn+1); - if (nSMStraits == 4) { - alphaDB = pGenome->express(pSpecies,SMSgenelocn+2); - betaDB = pGenome->express(pSpecies,SMSgenelocn+3); - } - } - else { - dp = pGenome->express(pSpecies,SMSgenelocn); - gb = pGenome->express(pSpecies,SMSgenelocn+1); - if (nSMStraits == 4) { - alphaDB = pGenome->express(pSpecies,SMSgenelocn+2); - betaDB = pGenome->express(pSpecies,SMSgenelocn+3); - } - } - } -} -#if RSDEBUG -//DEBUGLOG << "Individual::setSMSTraits(): indId=" << indId -// << " dp=" << dp << " gb=" << gb -// << " alphaDB=" << alphaDB << " betaDB=" << betaDB -// << endl; -#endif - -trfrSMSParams smsparams; -if (sexdep) { - smsparams = pSpecies->getSMSParams(0,0); -} -else { - smsparams = pSpecies->getSMSParams(0,0); -} -smsData->dp = (float)(dp*smsparams.dpScale + smsparams.dpMean); -smsData->gb = (float)(gb*smsparams.gbScale + smsparams.gbMean); -if (s.goalType == 2) { - smsData->alphaDB = (float)(alphaDB*smsparams.alphaDBScale + smsparams.alphaDBMean); - smsData->betaDB = (int)(betaDB*smsparams.betaDBScale + smsparams.betaDBMean + 0.5); -} -else { - smsData->alphaDB = s.alphaDB; - smsData->betaDB = s.betaDB; -} -#if RSDEBUG -//DEBUGLOG << "Individual::setSMSTraits() 1111: indId=" << indId -// << " smsData->dp=" << smsData->dp << " smsData->gb=" << smsData->gb -// << " smsData->alphaDB=" << smsData->alphaDB << " smsData->betaDB=" << smsData->betaDB -// << endl; -#endif -if (smsData->dp < 1.0) smsData->dp = 1.0; -if (smsData->gb < 1.0) smsData->gb = 1.0; -if (smsData->alphaDB <= 0.0) smsData->alphaDB = 0.000001f; -if (smsData->betaDB < 1) smsData->betaDB = 1; -#if RSDEBUG -//DEBUGLOG << "Individual::setSMSTraits() 2222: indId=" << indId -// << " smsData->dp=" << smsData->dp << " smsData->gb=" << smsData->gb -// << " smsData->alphaDB=" << smsData->alphaDB << " smsData->betaDB=" << smsData->betaDB -// << endl; -#endif -return; -} - -// Get phenotypic transfer by SMS traits -trfrSMSTraits Individual::getSMSTraits(void) { -#if RSDEBUG -//DEBUGLOG << "Individual::getSMSTraits(): indId=" << indId << " smsData=" << smsData -// << endl; -#endif -trfrSMSTraits s; s.dp = s.gb = s.alphaDB = 1.0; s.betaDB = 1; -if (smsData != 0) { - s.dp = smsData->dp; s.gb = smsData->gb; - s.alphaDB = smsData->alphaDB; s.betaDB = smsData->betaDB; -} -#if RSDEBUG -//DEBUGLOG << "Individual::getSMSTraits(): indId=" << indId -// << " s.dp=" << s.dp << " s.gb=" << s.gb -// << " s.alphaDB=" << s.alphaDB << " s.betaDB=" << s.betaDB -// << endl; -#endif -return s; -} - -// Set phenotypic transfer by CRW traits -void Individual::setCRWTraits(Species *pSpecies,short CRWgenelocn,short nCRWtraits, - bool sexdep) { -#if RSDEBUG -//DEBUGLOG << "Individual::setCRWTraits(): indId=" << indId -// << " CRWgenelocn=" << CRWgenelocn << " nCRWtraits=" << nCRWtraits << " sexdep=" << sexdep -// << endl; -#endif -trfrCRWTraits c; c.stepLength = c.rho = 0.0; -if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - c.stepLength = (float)pGenome->express(CRWgenelocn+sex,0,sex); - c.rho = (float)pGenome->express(CRWgenelocn+2+sex,0,sex); - } - else { - c.stepLength = (float)pGenome->express(CRWgenelocn,0,0); - c.rho = (float)pGenome->express(CRWgenelocn+1,0,0); - } - } - else { - if (sexdep) { - c.stepLength = (float)pGenome->express(pSpecies,CRWgenelocn+sex); - c.rho = (float)pGenome->express(pSpecies,CRWgenelocn+2+sex); - } - else { - c.stepLength = (float)pGenome->express(pSpecies,CRWgenelocn); - c.rho = (float)pGenome->express(pSpecies,CRWgenelocn+1); - } - } -} -#if RSDEBUG -//DEBUGLOG << "Individual::setCRWTraits(): indId=" << indId -// << " c.stepLength=" << c.stepLength << " c.rho=" << c.rho -// << endl; -#endif - -trfrCRWParams cparams; -if (sexdep) { - cparams = pSpecies->getCRWParams(0,sex); -} -else { - cparams = pSpecies->getCRWParams(0,0); -} -crw->stepL = (float)(c.stepLength*cparams.stepLScale + cparams.stepLgthMean); -crw->rho = (float)(c.rho*cparams.rhoScale + cparams.rhoMean); -#if RSDEBUG -//DEBUGLOG << "Individual::setCRWTraits(): indId=" << indId -// << " crw->stepL=" << crw->stepL << " crw->rho=" << crw->rho -// << endl; -#endif -if (crw->stepL < 1.0) crw->stepL = 1.0; -if (crw->rho < 0.0) crw->rho = 0.0; -if (crw->rho > 0.999) crw->rho = 0.999f; -#if RSDEBUG -//DEBUGLOG << "Individual::setCRWTraits(): indId=" << indId -// << " crw->stepL=" << crw->stepL << " crw->rho=" << crw->rho -// << endl; -#endif -return; -} - -// Get phenotypic transfer by CRW traits -trfrCRWTraits Individual::getCRWTraits(void) { -#if RSDEBUG -//DEBUGLOG << "Individual::getCRWTraits(): indId=" << indId -// << endl; -#endif -trfrCRWTraits c; c.stepLength = c.rho = 0.0; -if (crw != 0) { - c.stepLength = crw->stepL; - c.rho = crw->rho; -} -#if RSDEBUG -//DEBUGLOG << "Individual::getCRWTraits(): indId=" << indId -// << " c.stepLength=" << c.stepLength << " c.rho=" << c.rho -// << endl; -#endif - -return c; - -} - -// Set phenotypic settlement traits -void Individual::setSettTraits(Species *pSpecies,short settgenelocn,short nsetttraits, - bool sexdep) { -#if RSDEBUG -//DEBUGLOG << "Individual::setSettTraits(): indId=" << indId << " sex=" << sex -// << " settgenelocn=" << settgenelocn << " nsetttraits=" << nsetttraits << " sexdep=" << sexdep -// << endl; -#endif -//simParams sim = paramsSim->getSim(); -settleTraits s; s.s0 = s.alpha = s.beta = 0.0; -if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - s.s0 = (float)pGenome->express(settgenelocn+3*sex,0,0); - s.alpha = (float)pGenome->express(settgenelocn+3*sex+1,0,0); - s.beta = (float)pGenome->express(settgenelocn+3*sex+2,0,0); - } - else { - s.s0 = (float)pGenome->express(settgenelocn,0,0); - s.alpha = (float)pGenome->express(settgenelocn+1,0,0); - s.beta = (float)pGenome->express(settgenelocn+2,0,0); - } - } - else { - if (sexdep) { - s.s0 = (float)pGenome->express(pSpecies,settgenelocn+3*sex); - s.alpha = (float)pGenome->express(pSpecies,settgenelocn+3*sex+1); - s.beta = (float)pGenome->express(pSpecies,settgenelocn+3*sex+2); - } - else { - s.s0 = (float)pGenome->express(pSpecies,settgenelocn); - s.alpha = (float)pGenome->express(pSpecies,settgenelocn+1); - s.beta = (float)pGenome->express(pSpecies,settgenelocn+2); - } - - } -} -#if RSDEBUG -//DEBUGLOG << "Individual::setSettTraits(): indId=" << indId -// << " s.s0=" << s.s0 << " s.alpha=" << s.alpha << " s.beta=" << s.beta -// << endl; -#endif - -settParams sparams; -if (sexdep) { - sparams = pSpecies->getSettParams(0,sex); -} -else { - sparams = pSpecies->getSettParams(0,0); -} -#if RSDEBUG -//DEBUGLOG << "Individual::setSettTraits(): indId=" << indId -// << " sparams.s0Mean=" << sparams.s0Mean << " sparams.s0SD=" << sparams.s0SD -// << " sparams.s0Scale=" << sparams.s0Scale -// << endl; -#endif -setttraits = new settleTraits; -setttraits->s0 = (float)(s.s0*sparams.s0Scale + sparams.s0Mean); -setttraits->alpha = (float)(s.alpha*sparams.alphaSScale + sparams.alphaSMean); -setttraits->beta = (float)(s.beta*sparams.betaSScale + sparams.betaSMean); -#if RSDEBUG -//DEBUGLOG << "Individual::setSettTraits(): indId=" << indId -// << " setttraits->s0=" << setttraits->s0 -// << " setttraits->alpha=" << setttraits->alpha << " setttraits->beta=" << setttraits->beta -// << endl; -#endif -if (setttraits->s0 < 0.0) setttraits->s0 = 0.0; -if (setttraits->s0 > 1.0) setttraits->s0 = 1.0; -#if RSDEBUG -//DEBUGLOG << "Individual::setSettTraits(): indId=" << indId -// << " setttraits->s0=" << setttraits->s0 -// << " setttraits->alpha=" << setttraits->alpha << " setttraits->beta=" << setttraits->beta -// << endl; -#endif -return; -} - -// Get phenotypic settlement traits -settleTraits Individual::getSettTraits(void) { -#if RSDEBUG -//DEBUGLOG << "Individual::getSettTraits(): indId=" << indId -// << endl; -#endif -settleTraits s; s.s0 = s.alpha = s.beta = 0.0; -if (setttraits != 0) { - s.s0 = setttraits->s0; - s.alpha = setttraits->alpha; - s.beta = setttraits->beta; -} -#if RSDEBUG -//DEBUGLOG << "Individual::getSettTraits(): indId=" << indId -// << " s.s0=" << s.s0 << " s.alpha=" << s.alpha << " s.beta=" << s.beta -// << endl; -#endif - -return s; -} - -/* -locus Individual::getAlleles(int g) { -locus l; l.allele[0] = l.allele[1] = 0.0; -if (pGenome != 0) l = pGenome->getAlleles(g); -return l; -} -*/ - -void Individual::setStatus(short s) { -if (s >= 0 && s <= 9) status = s; -status = s; -} - -void Individual::developing(void) { -isDeveloping = true; -} - -void Individual::develop(void) { -stage++; isDeveloping = false; -} - -void Individual::ageIncrement(short maxage) { -if (status < 6) { // alive - age++; - if (age > maxage) status = 9; // exceeds max. age - dies - else { - if (path != 0) path->year = 0; // reset annual step count for movement models - if (status == 3) // waiting to continue dispersal - status = 1; - } -} -} - -void Individual::incFallow(void) { fallow++; } - -void Individual::resetFallow(void) { fallow = 0; } - -//--------------------------------------------------------------------------- -// Move to a specified neighbouring cell -void Individual::moveto(Cell *newCell) { -// check that location is indeed a neighbour of the current cell -locn currloc = pCurrCell->getLocn(); -locn newloc = newCell->getLocn(); -double d = sqrt(((double)currloc.x-(double)newloc.x)*((double)currloc.x-(double)newloc.x) - + ((double)currloc.y-(double)newloc.y)*((double)currloc.y-(double)newloc.y)); -if (d >= 1.0 && d < 1.5) { // ok - pCurrCell = newCell; status = 5; -} -} - -//--------------------------------------------------------------------------- -// Move to a new cell by sampling a dispersal distance from a single or double -// negative exponential kernel -// Returns 1 if still dispersing (including having found a potential patch), otherwise 0 -int Individual::moveKernel(Landscape *pLandscape,Species *pSpecies, - const short repType,const bool absorbing) -{ - -intptr patch; -int patchNum = 0; -int newX = 0,newY = 0; -int dispersing = 1; -double xrand,yrand,meandist,dist,r1,rndangle,nx,ny; -float localK; -trfrKernTraits kern; -Cell* pCell; -Patch* pPatch; -locn loc = pCurrCell->getLocn(); - -landData land = pLandscape->getLandData(); - -bool usefullkernel = pSpecies->useFullKernel(); -trfrRules trfr = pSpecies->getTrfr(); -settleRules sett = pSpecies->getSettRules(stage,sex); - -pCell = NULL; -pPatch = NULL; - -if (trfr.indVar) { // get individual's kernel parameters - kern.meanDist1 = kern.meanDist2 = kern.probKern1 = 0.0; -// kparams = pSpecies->getKernParams(stage,sex); - if (pGenome != 0) { - kern.meanDist1 = kerntraits->meanDist1; - if (trfr.twinKern) - { - kern.meanDist2 = kerntraits->meanDist2; - kern.probKern1 = kerntraits->probKern1; - } - } -} -else { // get kernel parameters for the species - if (trfr.sexDep) { - if (trfr.stgDep) { - kern = pSpecies->getKernTraits(stage,sex); - } - else { - kern = pSpecies->getKernTraits(0,sex); - } - } - else { - if (trfr.stgDep) { - kern = pSpecies->getKernTraits(stage,0); - } - else { - kern = pSpecies->getKernTraits(0,0); - } - } -} -#if RSDEBUG -//Patch *startPatch = (Patch*)startpatch; -//DEBUGLOG << "Individual::moveKernel(): indId=" << indId << " x=" << loc.x << " y=" << loc.y -//// << " natalPatch = " << natalPatch -//// << " startpatch = " << startpatch << " patchNum = " << startPatch->getPatchNum() -// << " kern.meanDist1=" << kern.meanDist1; -//if (trfr.twinKern) { -// DEBUGLOG << " meanDist2=" << kern.meanDist2 << " probKern1=" << kern.probKern1; -//} -//DEBUGLOG << endl; -#endif - -// scale the appropriate kernel mean to the cell size -if (trfr.twinKern) -{ - if (pRandom->Bernoulli(kern.probKern1)) - meandist = kern.meanDist1 / (float)land.resol; - else - meandist = kern.meanDist2 / (float)land.resol; -} -else - meandist = kern.meanDist1 / (float)land.resol; -#if RSDEBUG -//DEBUGLOG << "Individual::moveKernel(): indId=" << indId << " meandist=" << meandist << endl; -#endif -// scaled mean may not be less than 1 unless emigration derives from the kernel -// (i.e. the 'use full kernel' option is applied) -if (!usefullkernel && meandist < 1.0) meandist = 1.0; -#if RSDEBUG -//DEBUGLOG << "Individual::moveKernel(): indId=" << indId << " meandist=" << meandist << endl; -#endif - -#if RSDEBUG -//Patch *startPatch = (Patch*)startpatch; -//DEBUGLOG << "Individual::moveKernel(): indId = " << indId << " x = " << x << " y = " << y -// << " natalPatch = " << natalPatch -//// << " startpatch = " << startpatch << " patchNum = " << startPatch->getPatchNum() -// << " meanDist1 = " << kern.meanDist1; -//if (trfr.twinKern) { -// DEBUGLOG << " probKern1 = " << kern.probKern1 << " meanDist2 = " << kern.meanDist2; -//} -//DEBUGLOG << " meandist = " << meandist << endl; -#endif - -int loopsteps = 0; // new counter to prevent infinite loop added 14/8/15 -do { - do { - do { - // randomise the cell within the patch, provided that the individual is still in - // its natal cell (i.e. not waiting in the matrix) - // this is because, if the patch is very large, the individual is near the centre - // and the (single) kernel mean is (not much more than) the cell size, an infinite - // loop could otherwise result, as the individual never reaches the patch edge - // (in a cell-based model, this has no effect, other than as a processing overhead) - if (status == 1) { - pCell = pNatalPatch->getRandomCell(); - if (pCell != 0) { - loc = pCell->getLocn(); - } - } - // randomise the position of the individual inside the cell - xrand = (double)loc.x + pRandom->Random()*0.999; - yrand = (double)loc.y + pRandom->Random()*0.999; - - r1 = 0.0000001 + pRandom->Random()*(1.0-0.0000001); -// dist = (-1.0*meandist)*std::log(r1); - dist = (-1.0*meandist)*log(r1); // for LINUX_CLUSTER - - rndangle = pRandom->Random() * 2.0 * PI; - nx = xrand + dist * sin(rndangle); - ny = yrand + dist * cos(rndangle); - if (nx < 0.0) newX = -1; else newX = (int)nx; - if (ny < 0.0) newY = -1; else newY = (int)ny; -#if RSDEBUG - if (path != 0) (path->year)++; -#endif - loopsteps++; -#if RSDEBUG -//DEBUGLOG << "Individual::moveKernel(): indId=" << indId << " status=" << status -// << " loopsteps=" << loopsteps << " newX=" << newX << " newY=" << newY -// << " loc.x=" << loc.x << " loc.y=" << loc.y -// << endl; -#endif - } while (loopsteps < 1000 && - ((!absorbing && (newX < land.minX || newX > land.maxX - || newY < land.minY || newY > land.maxY)) - || (!usefullkernel && newX == loc.x && newY == loc.y)) - ); - if (loopsteps < 1000) { - if (newX < land.minX || newX > land.maxX - || newY < land.minY || newY > land.maxY) { // beyond absorbing boundary - pCell = 0; - patch = 0; - patchNum = -1; - } - else { - pCell = pLandscape->findCell(newX,newY); - if (pCell == 0) { // no-data cell - patch = 0; - patchNum = -1; - } - else { - patch = pCell->getPatch(); - if (patch == 0) { // matrix - pPatch = 0; - patchNum = 0; - } - else { - pPatch = (Patch*)patch; - patchNum = pPatch->getPatchNum(); - } - } - } - } - else { - patch = 0; - patchNum = -1; - } -#if RSDEBUG -//DEBUGLOG << "Individual::moveKernel(): indId=" << indId << " status=" << status -// << " loopsteps=" << loopsteps << " newX=" << newX << " newY=" << newY -// << " pCell=" << pCell << " patch=" << patch << " patchNum=" << patchNum -// << endl; -#endif - } while (!absorbing && patchNum < 0 && loopsteps < 1000); // in a no-data region -} -while (!usefullkernel && pPatch == pNatalPatch && loopsteps < 1000); // still in the original (natal) patch - -if (loopsteps < 1000) { - if (pCell == 0) { // beyond absorbing boundary or in no-data cell - pCurrCell = 0; - status = 6; - dispersing = 0; - } - else { - pCurrCell = pCell; - if (pPatch == 0) localK = 0.0; // matrix - else localK = pPatch->getK(); - if (patchNum > 0 && localK > 0.0) { // found a new patch - status = 2; // record as potential settler - } - else { - dispersing = 0; - // can wait in matrix if population is stage structured ... - if (pSpecies->stageStructured()) { - // ... and wait option is applied ... - if (sett.wait) { // ... it is - status = 3; // waiting - } - else // ... it is not - status = 6; // dies (unless there is a suitable neighbouring cell) - } - else - status = 6; // dies (unless there is a suitable neighbouring cell) - } - } -} -else { - status = 6; - dispersing = 0; -} -#if RSDEBUG -//DEBUGLOG << "Individual::moveKernel(): indId=" << indId -// << " newX=" << newX << " newY=" << newY -// << " patch=" << patch -// << " patchNum=" << patchNum << " status=" << status; -//DEBUGLOG << endl; -#endif - -// apply dispersal-related mortality, which may be distance-dependent -dist *= (float)land.resol; // re-scale distance moved to landscape scale -if (status < 7) { - double dispmort; - trfrMortParams mort = pSpecies->getMortParams(); - if (trfr.distMort) { - dispmort = 1.0 / (1.0 + exp(-(dist - mort.mortBeta)*mort.mortAlpha)); - } - else { - dispmort = mort.fixedMort; - } - if (pRandom->Bernoulli(dispmort)) { - status = 7; // dies - dispersing = 0; - } -} - -return dispersing; -} - -//--------------------------------------------------------------------------- -// Make a single movement step according to a mechanistic movement model -// Returns 1 if still dispersing (including having found a potential patch), otherwise 0 -int Individual::moveStep(Landscape *pLandscape,Species *pSpecies, - const short landIx,const bool absorbing) -{ - -if (status != 1) return 0; // not currently dispersing - -intptr patch; -int patchNum; -int newX,newY; -locn loc; -int dispersing = 1; -double xcnew,ycnew; -double angle; -double mortprob,rho,steplen; -movedata move; -Patch* pPatch = 0; -bool absorbed = false; -//int popsize; - -landData land = pLandscape->getLandData(); -simParams sim = paramsSim->getSim(); - -trfrRules trfr = pSpecies->getTrfr(); -trfrCRWTraits movt = pSpecies->getCRWTraits(); -settleSteps settsteps = pSpecies->getSteps(stage,sex); - -patch = pCurrCell->getPatch(); -#if RSDEBUG -//DEBUGLOG << "Individual::moveStep() AAAA: indId=" << indId -// << " pCurrCell=" << pCurrCell << " patch=" << patch -// << endl; -#endif - -if (patch == 0) { // matrix - pPatch = 0; - patchNum = 0; -} -else { - pPatch = (Patch*)patch; - patchNum = pPatch->getPatchNum(); -} -// apply step-dependent mortality risk ... -if (trfr.habMort) -{ // habitat-dependent - int h = pCurrCell->getHabIndex(landIx); - if (h < 0) { // no-data cell - should not occur, but if it does, individual dies - mortprob = 1.0; - } - else mortprob = pSpecies->getHabMort(h); -#if RSDEBUG -//locn temploc = pCurrCell->getLocn(); -//DEBUGLOG << "Individual::moveStep(): x=" << temploc.x << " y=" << temploc.x -// << " landIx=" << landIx << " h=" << h << " mortprob=" << mortprob -// << endl; -#endif -} -else mortprob = movt.stepMort; -// ... unless individual has not yet left natal patch in emigration year -if (pPatch == pNatalPatch && path->out == 0 && path->year == path->total) { - mortprob = 0.0; -} -#if RSDEBUG -locn loc0,loc1,loc2; -//loc0 = pCurrCell->getLocn(); -//DEBUGLOG << "Individual::moveStep() BBBB: indId=" << indId << " status=" << status -// << " path->year=" << path->year << " path->out=" << path->out -// << " settleStatus=" << path->settleStatus -// << " x=" << loc0.x << " y=" << loc0.y -//// << " patch=" << patch -// << " pPatch=" << pPatch -// << " patchNum=" << patchNum; -//// << " natalPatch=" << natalPatch; -////if (crw != 0) { -//// DEBUGLOG << " xc=" << crw->xc << " yc=" << crw->yc; -//// DEBUGLOG << " rho=" << movt.rho << " stepLength=" << movt.stepLength; -////} -//DEBUGLOG << endl; -#endif -if (pRandom->Bernoulli(mortprob)) { // individual dies - status = 7; - dispersing = 0; -} -else { // take a step - (path->year)++; - (path->total)++; -// if (pPatch != pNatalPatch || path->out > 0) (path->out)++; - if (patch == 0 || pPatch == 0 || patchNum == 0) { // not in a patch - if (path != 0) path->settleStatus = 0; // reset path settlement status - (path->out)++; - } - loc = pCurrCell->getLocn(); - newX = loc.x; newY = loc.y; - - - switch (trfr.moveType) { - - case 1: // SMS -#if RSDEBUG -//loc1 = pCurrCell->getLocn(); -//DEBUGLOG << "Individual::moveStep() FFFF: indId=" << indId << " status=" << status -//// << " path->year=" << path->year -// << " path->season=" << path->season -// << " x=" << loc1.x << " y=" << loc1.y -// << " smsData->goalType=" << smsData->goalType -// << " goal.x=" << smsData->goal.x -// << " goal.y=" << smsData->goal.y -// << endl; -#endif - move = smsMove(pLandscape,pSpecies,landIx,pPatch==pNatalPatch,trfr.indVar,absorbing); -#if RSDEBUG -//DEBUGLOG << "Individual::moveStep() GGGG: indId=" << indId << " status=" << status -// << " move.dist=" << move.dist -// << endl; -#endif - if (move.dist < 0.0) { - // either INTERNAL ERROR CONDITION - INDIVIDUAL IS IN NO-DATA SQUARE - // or individual has crossed absorbing boundary ... - // ... individual dies - status = 6; - dispersing = 0; - } - else { -#if RSDEBUG -//loc1 = pCurrCell->getLocn(); -//DEBUGLOG << "Individual::moveStep() HHHH: indId=" << indId << " status=" << status -// << " path->year=" << path->year -// << " x=" << loc1.x << " y=" << loc1.y -//// << " smsData = " << smsData -// << endl; -#endif - - // WOULD IT BE MORE EFFICIENT FOR smsMove TO RETURN A POINTER TO THE NEW CELL? ... - - patch = pCurrCell->getPatch(); - //int patchnum; - if (patch == 0) { - pPatch = 0; - //patchnum = 0; - } - else { - pPatch = (Patch*)patch; - //patchnum = pPatch->getPatchNum(); - } - if (sim.saveVisits && pPatch != pNatalPatch) { - pCurrCell->incrVisits(); - } - } - break; - - case 2: // CRW - if (trfr.indVar) { - if (crw != 0) { - movt.stepLength = crw->stepL; - movt.rho = crw->rho; - } - } - - steplen = movt.stepLength; if (steplen < 0.2*land.resol) steplen = 0.2*land.resol; - rho = movt.rho; if (rho > 0.99) rho = 0.99; - if (pPatch == pNatalPatch) { - rho = 0.99; // to promote leaving natal patch - path->out = 0; - } - if (movt.straigtenPath && path->settleStatus > 0) { - // individual is in a patch and has already determined whether to settle - rho = 0.99; // to promote leaving the patch - path->out = 0; - } - int loopsteps = 0; // new counter to prevent infinite loop added 14/8/15 - do { - do { - // new direction - if (newX < land.minX || newX > land.maxX || newY < land.minY || newY > land.maxY - || pCurrCell == 0) { - // individual has tried to go out-of-bounds or into no-data area - // allow random move to prevent repeated similar move - angle = wrpcauchy(crw->prevdrn,0.0); - } - else - angle = wrpcauchy(crw->prevdrn,rho); - // new continuous cell coordinates - xcnew = crw->xc + sin(angle) * steplen/(float)land.resol; - ycnew = crw->yc + cos(angle) * steplen/(float)land.resol; - if (xcnew < 0.0) newX = -1; else newX = (int)xcnew; - if (ycnew < 0.0) newY = -1; else newY = (int)ycnew; - loopsteps++; -#if RSDEBUG -//DEBUGLOG << "Individual::moveStep(): indId=" << indId -// << " xc=" << crw->xc << " yc=" << crw->yc << " pCurrCell=" << pCurrCell -// << " steps=" << path->year << " loopsteps=" << loopsteps -// << " steplen=" << steplen << " rho=" << rho << " angle=" << angle -// << " xcnew=" << xcnew << " ycnew=" << ycnew << " newX=" << newX << " newY=" << newY << endl; -#endif - } - while (!absorbing && loopsteps < 1000 && - (newX < land.minX || newX > land.maxX || newY < land.minY || newY > land.maxY)); - if (newX < land.minX || newX > land.maxX || newY < land.minY || newY > land.maxY) - pCurrCell = 0; - else - pCurrCell = pLandscape->findCell(newX,newY); - if (pCurrCell == 0) { // no-data cell or beyond absorbing boundary - patch = 0; - if (absorbing) absorbed = true; - } - else - patch = pCurrCell->getPatch(); -#if RSDEBUG -//DEBUGLOG << "Individual::moveStep(): indId=" << indId -// << " loopsteps=" << loopsteps << " absorbed=" << absorbed -// << " pCurrCell=" << pCurrCell << " patch=" << patch << endl; -#endif - } while (!absorbing && pCurrCell == 0 && loopsteps < 1000); - crw->prevdrn = (float)angle; - crw->xc = (float)xcnew; crw->yc = (float)ycnew; - if (absorbed) { // beyond absorbing boundary or in no-data square - status = 6; - dispersing = 0; - pCurrCell = 0; - } - else { - if (loopsteps >= 1000) { // unable to make a move - // INTERNAL ERROR CONDITION - INDIVIDUAL IS IN NO-DATA SQUARE - // NEED TO TAKE SOME FORM OF INFORMATIVE ACTION ... - // ... individual dies as it cannot move - status = 6; - dispersing = 0; - // current cell will be invalid (zero), so set back to previous cell - pCurrCell = pPrevCell; - } - } -#if RSDEBUG -//DEBUGLOG << "Individual::moveStep(): indId=" << indId -// << " status=" << status -// << " pCurrCell=" << pCurrCell << " patch=" << patch << endl; -#endif - break; - - } // end of switch (trfr.moveType) - -#if RSDEBUG -//locn loc2; -//if (pCurrCell > 0) { -// loc2 = pCurrCell->getLocn(); -//} -//else { -// loc2.x = -9999; loc2.y = -9999; -//} -//DEBUGLOG << "Individual::moveStep() ZZZZ: indId=" << indId -// << " status=" << status -// << " path->total=" << path->total -// << " x=" << loc2.x << " y=" << loc2.y -// << " patch=" << patch; -//if (patch > 0) { -// pPatch = (Patch*)patch; -// DEBUGLOG << " patchNum=" << pPatch->getPatchNum() -// << " getK()=" << pPatch->getK() -// << " popn=" << pPatch->getPopn((int)pSpecies); -//} -// DEBUGLOG << endl; -#endif - if (patch > 0 // not no-data area or matrix - && path->total >= settsteps.minSteps) { - pPatch = (Patch*)patch; - if (pPatch != pNatalPatch) - { - // determine whether the new patch is potentially suitable - if (pPatch->getK() > 0.0) - { // patch is suitable - status = 2; - } - } - } - if (status != 2 && status != 6) { // suitable patch not found, not already dead - if (path->year >= settsteps.maxStepsYr) { - status = 3; // waits until next year - } - if (path->total >= settsteps.maxSteps) { - status = 6; // dies - dispersing = 0; - } - } -} // end of single movement step - -return dispersing; - -} - -//--------------------------------------------------------------------------- - -// Functions to implement the SMS algorithm - -// Move to a neighbouring cell according to the SMS algorithm -movedata Individual::smsMove(Landscape *pLand,Species *pSpecies, - const short landIx,const bool natalPatch,const bool indvar,const bool absorbing) -{ - -array3x3d nbr; // to hold weights/costs/probs of moving to neighbouring cells -array3x3d goal; // to hold weights for moving towards a goal location -array3x3f hab; // to hold weights for habitat (includes percep range) -int x2,y2; // x index from 0=W to 2=E, y index from 0=N to 2=S -int newX = 0,newY = 0; -Cell *pCell; -Cell *pNewCell = NULL; -double sum_nbrs = 0.0; -movedata move; -int cellcost,newcellcost; -locn current; - -//if (write_out) { -// out<findCell(x,y); -if (pCurrCell == 0) -{ -// x,y is a NODATA square - this should not occur here -// return a negative distance to indicate an error - move.dist = -69.0; move.cost = 0.0; - return move; -} - -#if RSDEBUG -//DEBUGLOG << "Individual::smsMove(): this=" << this << endl; -#endif - -landData land = pLand->getLandData(); -trfrSMSTraits movt = pSpecies->getSMSTraits(); -current = pCurrCell->getLocn(); - -//get weights for directional persistence.... -//if ((path->out > 0 && path->out < 10 && path->out < 2*movt.pr) -if ((path->out > 0 && path->out <= (movt.pr+1)) -|| natalPatch -|| (movt.straigtenPath && path->settleStatus > 0)) { - // inflate directional persistence to promote leaving the patch - if (indvar) nbr = getSimDir(current.x,current.y,10.0f*smsData->dp); - else nbr = getSimDir(current.x,current.y,10.0f*movt.dp); -} -else { - if (indvar) nbr = getSimDir(current.x,current.y,smsData->dp); - else nbr = getSimDir(current.x,current.y,movt.dp); -} -if (natalPatch || path->settleStatus > 0) path->out = 0; -//if (natalPatch) path->out = 0; -#if RSDEBUG -//DEBUGLOG << "Individual::smsMove() 0000: nbr matrix" << endl; -//for (y2 = 2; y2 > -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) DEBUGLOG << nbr.cell[x2][y2] << " "; -// DEBUGLOG << endl; -//} -#endif -//if (write_out) { -// out< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) out< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) out< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) out< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) DEBUGLOG << hab.cell[x2][y2] << " "; -// DEBUGLOG << endl; -//} -#endif - pCurrCell->setEffCosts(hab); -} -else { // they have already been calculated - no action required -// if (write_out) { -// out<<"*** using previous effective costs ***"< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) { -// out< -1; y2--) { - for (x2 = 0; x2 < 3; x2++) { - if(x2 == 1 && y2 == 1) nbr.cell[x2][y2] = 0.0; - else { - if(x2 == 1 || y2 == 1) //not diagonal - nbr.cell[x2][y2] = nbr.cell[x2][y2]*goal.cell[x2][y2]*hab.cell[x2][y2]; - else // diagonal - nbr.cell[x2][y2] = (float)SQRT2*nbr.cell[x2][y2]*goal.cell[x2][y2]*hab.cell[x2][y2]; - } -// if (write_out) { -// out< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) DEBUGLOG << nbr.cell[x2][y2] << " "; -// DEBUGLOG << endl; -//} -#endif - -// determine reciprocal of effective cost for the 8 neighbours -//if (write_out) out<<"reciprocal weighted effective costs:"< -1; y2--) { - for (x2 = 0; x2 < 3; x2++) { - if (nbr.cell[x2][y2] > 0.0) nbr.cell[x2][y2] = 1.0f/nbr.cell[x2][y2]; -// if (write_out) { -// out< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) { -// temp.cell[x2][y2] = nbr.cell[x2][y2]; -// if (current.x == 488 && current.y == 422) { -// pCell = pLand->findCell((current.x+x2-1),(current.y+y2-1)); -// DEBUGLOG << "Individual::smsMove(): this=" << this -// << " IN THE PROBLEM CELL" -// << " y=" << current.y << " x=" << current.x -// << " y2=" << y2 << " x2=" << x2 -// << " pCell=" << pCell; -// if (pCell != 0) DEBUGLOG << " pCell->getCost=" << pCell->getCost(); -// DEBUGLOG << endl; -// } -// } -//} -#endif - -for (y2 = 2; y2 > -1; y2--) { - for (x2 = 0; x2 < 3; x2++) { - if (!absorbing) { - if ((current.y+y2-1) < land.minY || (current.y+y2-1) > land.maxY - || (current.x+x2-1) < land.minX || (current.x+x2-1) > land.maxX) - // cell is beyond current landscape limits - nbr.cell[x2][y2] = 0.0; - else { // check if no-data cell - pCell = pLand->findCell((current.x+x2-1),(current.y+y2-1)); - if (pCell == 0) nbr.cell[x2][y2] = 0.0; // no-data cell - } - } -#if RSDEBUG -//DEBUGLOG << "Individual::smsMove(): this=" << this -// << " y=" << current.y << " x=" << current.x -// << " y2=" << y2 << " x2=" << x2 -// << " pCell=" << pCell -// << endl; -#endif -// if (write_out) { -// out< 0.0) { // should always be the case, but safest to check... - for (y2 = 2; y2 > -1; y2--) { - for (x2 = 0; x2 < 3; x2++) { - nbr.cell[x2][y2] = nbr.cell[x2][y2]/(float)sum_nbrs; -// if (write_out) { -// out< -1; y2--) { -// for (x2 = 0; x2 < 3; x2++) DEBUGLOG << nbr.cell[x2][y2] << " "; -// DEBUGLOG << endl; -//} -#endif - -// set up cell selection probabilities -//if (write_out) out<<"rnd = "< land.maxX - || newY < land.minY || newY > land.maxY))); - if (loopsteps >= 1000) pNewCell = 0; - else { - if (newX < land.minX || newX > land.maxX - || newY < land.minY || newY > land.maxY) { - pNewCell = 0; - } - pNewCell = pLand->findCell(newX,newY); - } -} -while (!absorbing && pNewCell == 0 && loopsteps < 1000); // no-data cell -#if RSDEBUG -//DEBUGLOG << "Individual::smsMove() 8888: pNewCell=" << pNewCell -// << " loopsteps=" << loopsteps -// << " current.x=" << current.x << " current.y=" << current.y -// << " newX=" << newX << " newY=" << newY -// << " land.minX=" << land.minX << " land.minY=" << land.minY -// << " land.maxX=" << land.maxX << " land.maxY=" << land.maxY -// << endl; -#endif -if (loopsteps >= 1000 || pNewCell == 0) { - // unable to make a move or crossed absorbing boundary - // flag individual to die - move.dist = -123.0; - if (pNewCell == 0) pCurrCell = pNewCell; -} -else { - newcellcost = pNewCell->getCost(); - move.cost = move.dist*0.5f*((float)cellcost + (float)newcellcost); - // make the selected move - if ((short)memory.size() == movt.memSize) { - memory.pop(); // remove oldest memory element - } - memory.push(current); // record previous location in memory - //if (write_out) out << "queue length is " << memory.size() << endl; - pCurrCell = pNewCell; -} -return move; -} - -// Weight neighbouring cells on basis of current movement direction -array3x3d Individual::getSimDir(const int x, const int y, const float dp) -{ - -array3x3d d; -locn prev; -double theta; -int xx,yy; - -//if (write_out) out<<"step 0"<goal.x) == 0 && (y - smsData->goal.y) == 0) { - // at goal, set matrix to unity -// if (write_out) out<<"*** at goal: x,y = "<goal.x),((double)y-(double)smsData->goal.y)); -// if (write_out) out<<"goalx,goaly: "< 7.0 * PI / 8.0) { dx = 0; dy = -1; } -else { - if (fabs(theta) > 5.0 * PI / 8.0) { dy = -1; if (theta > 0) dx = 1; else dx = -1; } - else { - if (fabs(theta) > 3.0 * PI / 8.0) { dy = 0; if (theta > 0) dx = 1; else dx = -1; } - else { - if (fabs(theta) > PI / 8.0) { dy = 1; if (theta > 0) dx = 1; else dx = -1; } - else { dy = 1; dx = 0; } - } - } -} -// if (write_out) out<<"goalx,goaly: "< 1) dx -= 2; yy = dy; - d.cell[xx+1][yy+1] = (float)i1; d.cell[-xx+1][yy+1] = (float)i1; - d.cell[xx+1][-yy+1] = (float)i3; d.cell[-xx+1][-yy+1] = (float)i3; - } - else { // theta points W or E - yy = dy+1; if (yy > 1) dy -= 2; xx = dx; - d.cell[xx+1][yy+1] = (float)i1; d.cell[xx+1][-yy+1] = (float)i1; - d.cell[-xx+1][yy+1] = (float)i3; d.cell[-xx+1][-yy+1] = (float)i3; - } -} -else { // theta points to an ordinal direction - d.cell[dx+1][-dy+1] = (float)i2; d.cell[-dx+1][dy+1] = (float)i2; - xx = dx+1; if (xx > 1) xx -= 2; d.cell[xx+1][dy+1] = (float)i1; - yy = dy+1; if (yy > 1) yy -= 2; d.cell[dx+1][yy+1] = (float)i1; - d.cell[-xx+1][-dy+1] = (float)i3; d.cell[-dx+1][-yy+1] = (float)i3; - } - -return d; -} - -// Weight neighbouring cells on basis of (habitat) costs -array3x3f Individual::getHabMatrix(Landscape *pLand,Species *pSpecies, - const int x,const int y,const short pr,const short prmethod,const short landIx, - const bool absorbing) -{ - -array3x3f w; // array of effective costs to be returned -int ncells,x4,y4; -double weight,sumweights; -// NW and SE corners of effective cost array relative to the current cell (x,y): -int xmin = 0,ymin = 0,xmax = 0,ymax = 0; -int cost,nodatacost,h; -Cell *pCell; - -landData land = pLand->getLandData(); -if (absorbing) nodatacost = ABSNODATACOST; -else nodatacost = NODATACOST; - -for (int x2=-1; x2<2; x2++) { // index of relative move in x direction - for (int y2=-1; y2<2; y2++) { // index of relative move in x direction - - w.cell[x2+1][y2+1] = 0.0; // initialise costs array to zeroes - - // set up corners of perceptual range relative to current cell - if (x2==0 && y2==0) { // current cell - do nothing - xmin=0; ymin=0; xmax=0; ymax=0; - } - else { - if (x2==0 || y2==0) { // not diagonal (rook move) - if (x2==0){ // vertical (N-S) move - //out<<"ROOK N-S: x2 = "< land.maxX) x4 = x+x3-land.maxX-1; else x4 = x+x3; } - if ((y+y3) < 0) y4 = y+y3+land.maxY+1; - else { if ((y+y3) > land.maxY) y4 = y+y3-land.maxY-1; else y4 = y+y3; } -// if (write_out && (x4 < 0 || y4 < 0)) { -// out<<"ERROR: x "< land.maxX || y4 < 0 || y4 > land.maxY) { - // unexpected problem - e.g. due to ridiculously large PR - // treat as a no-data cell - cost = nodatacost; - } - else { - // add cost of cell to total PR cost - pCell = pLand->findCell(x4,y4); - if (pCell == 0) { // no-data cell - cost = nodatacost; - } - else { - cost = pCell->getCost(); - if (cost < 0) cost = nodatacost; - else { - if (cost == 0) { // cost not yet set for the cell - h = pCell->getHabIndex(landIx); - cost = pSpecies->getHabCost(h); -#if RSDEBUG -//DEBUGLOG << "Individual::getHabMatrix(): x4=" << x4 << " y4=" << y4 -// << " landIx=" << landIx << " h=" << h << " cost=" << cost -// << endl; -#endif - pCell->setCost(cost); - } - else { -#if RSDEBUG -//DEBUGLOG << "Individual::getHabMatrix(): x4=" << x4 << " y4=" << y4 -// << " cost=" << cost -// << endl; -#endif - - } - } - } - } - if (prmethod==1) { // arithmetic mean - w.cell[x2+1][y2+1] += cost; - ncells++; - } - if (prmethod==2) { // harmonic mean - if (cost > 0) { - w.cell[x2+1][y2+1] += (1.0f/(float)cost); - ncells++; - } - } - if (prmethod==3) { // arithmetic mean weighted by inverse distance - if (cost>0) { - // NB distance is still given by (x3,y3) - weight = 1.0f /(double)sqrt((pow((double)x3,2)+pow((double)y3,2))); - w.cell[x2+1][y2+1] += (float)(weight*(double)cost); - ncells++; sumweights += weight; - } - } -// if (write_out2) out2<get_target() > 50) targetseen++; -// } -//#endif - } //end of y3 loop - } //end of x3 loop -// if (write_out) out<<"ncells in PR = "<total << "\t" << loc.x << "\t" << loc.y << "\t" - << status << "\t" - << endl; - } - // if not anymore dispersing... - if(status > 1 && status < 10){ - prev_loc = pPrevCell->getLocn(); - // record only if this is the first step as non-disperser - if (path->pathoutput) { - // if this is also the first step taken at all, record the start cell first - if(path->total == 1){ - outMovePaths << year << "\t" << indId << "\t" - << "0\t" << prev_loc.x << "\t" << prev_loc.y << "\t" - << "0\t" // status at start cell is 0 - << endl; - } - outMovePaths << year << "\t" << indId << "\t" - << path->total << "\t" << loc.x << "\t" << loc.y << "\t" - << status << "\t" - << endl; - // current cell will be invalid (zero), so set back to previous cell - //pPrevCell = pCurrCell; - path->pathoutput = 0; - } - } -} -#endif - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -double wrpcauchy (double location, double rho) { -double result; - -if(rho < 0.0 || rho > 1.0) { -// ML_ERR_return_NAN; - result = location; -} - -if(rho == 0) - result = pRandom->Random() * M_2PI; -else - if(rho == 1) result = location; - else { - result = fmod(cauchy(location, -log(rho)), M_2PI); - } -return result; -} - -double cauchy(double location, double scale) { -if (scale < 0) return location; -//return location + scale * tan(M_PI * unif_rand()); -return location + scale * tan(PI * pRandom->Random()); -//return location + scale * tan(M_PI * pRandom->Random()); -} -//#endif -//#endif - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- diff --git a/RangeShiftR/src/RScore/Individual.h b/RangeShiftR/src/RScore/Individual.h deleted file mode 100644 index d843d7e..0000000 --- a/RangeShiftR/src/RScore/Individual.h +++ /dev/null @@ -1,317 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Individual - -Implements the Individual class - -Various optional attributes (genes for traits, movement parameters, etc.) are -allocated dynamically and accessed by pointers if required. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 26 October 2021 by Steve Palmer - -------------------------------------------------------------------------------*/ - -#ifndef IndividualH -#define IndividualH - - -#include -#include -using namespace std; - -//#include "mathlib.h" -#include "Parameters.h" -#include "Species.h" -#include "Landscape.h" -#include "Patch.h" -#include "Cell.h" -#include "Genome.h" - -#define NODATACOST 100000 // cost to use in place of nodata value for SMS -#define ABSNODATACOST 100 // cost to use in place of nodata value for SMS - // when boundaries are absorbing - -//--------------------------------------------------------------------------- - -struct indStats { - short stage; short sex; short age; short status; short fallow; - bool isDeveloping; -}; -struct pathData { // to hold path data common to SMS and CRW models - int year, total, out; // nos. of steps - Patch* pSettPatch; // pointer to most recent patch tested for settlement - short settleStatus; // whether ind may settle in current patch - // 0 = not set, 1 = debarred through density dependence rule - // 2 = OK to settle subject to finding a mate -// bool leftNatalPatch; // individual has moved out of its natal patch -#if RS_RCPP - short pathoutput; -#endif -}; -struct pathSteps { // nos. of steps for movement model - int year, total, out; -}; -struct settlePatch { - Patch* pSettPatch; short settleStatus; -}; -struct crwParams { // to hold data for CRW movement model - float prevdrn; // direction of previous step (UNITS) - float xc,yc; // continuous cell co-ordinates - float stepL; // phenotypic step length (m) - float rho; // phenotypic step correlation coefficient -}; -struct array3x3d { double cell[3][3]; }; -struct movedata { float dist; float cost; }; -struct smsdata { - locn prev; // location of previous cell - locn goal; // location of goal - float dp; // directional persistence - float gb; // goal bias - float alphaDB; // dispersal bias decay rate - int betaDB; // dispersal bias decay inflection point (no. of steps) -}; - -class Individual { - -public: - static int indCounter; // used to create ID, held by class, not members of class - Individual( // Individual constructor - Cell*, // pointer to Cell - Patch*, // pointer to patch - short, // stage - short, // age - short, // reproduction interval (no. of years/seasons between breeding attempts) - float, // probability that sex is male - bool, // TRUE for a movement model, FALSE for kernel-based transfer - short // movement type: 1 = SMS, 2 = CRW - ); - ~Individual(void); - void setGenes( // Set genes for individual variation from species initialisation parameters - Species*, // pointer to Species - int // Landscape resolution - ); - void setGenes( // Inherit genome from parents - Species*, // pointer to Species - Individual*, // pointer to mother - Individual*, // pointer to father (must be 0 for an asexual Species) - int // Landscape resolution - ); - void setEmigTraits( // Set phenotypic emigration traits - Species*, // pointer to Species - short, // location of emigration genes on genome - short, // number of emigration genes - bool // TRUE if emigration is sex-dependent - ); - emigTraits getEmigTraits(void); // Get phenotypic emigration traits - - void setKernTraits( // Set phenotypic transfer by kernel traits - Species*, // pointer to Species - short, // location of kernel genes on genome - short, // number of kernel genes - int, // Landscape resolution - bool // TRUE if transfer is sex-dependent - ); - trfrKernTraits getKernTraits(void); // Get phenotypic transfer by kernel traits - - void setSMSTraits( // Set phenotypic transfer by SMS traits - Species*, // pointer to Species - short, // location of SMS genes on genome - short, // number of SMS genes - bool // TRUE if transfer is sex-dependent - ); - trfrSMSTraits getSMSTraits(void); // Get phenotypic transfer by SMS traits - void setCRWTraits( // Set phenotypic transfer by CRW traits - Species*, // pointer to Species - short, // location of CRW genes on genome - short, // number of CRW genes - bool // TRUE if transfer is sex-dependent - ); - trfrCRWTraits getCRWTraits(void); // Get phenotypic transfer by CRW traits - - void setSettTraits( // Set phenotypic settlement traits - Species*, // pointer to Species - short, // location of settlement genes on genome - short, // number of settlement genes - bool // TRUE if settlement is sex-dependent - ); - settleTraits getSettTraits(void); // Get phenotypic settlement traits - - // Identify whether an individual is a potentially breeding female - - // if so, return her stage, otherwise return 0 - int breedingFem(void); - int getId(void); - int getSex(void); - int getStatus(void); - indStats getStats(void); - Cell* getLocn( // Return location (as pointer to Cell) - const short // option: 0 = get natal locn, 1 = get current locn - ); // - Patch* getNatalPatch(void); - void setYearSteps(int); - pathSteps getSteps(void); - settlePatch getSettPatch(void); - void setSettPatch(const settlePatch); - void setStatus(short); - void developing(void); - void develop(void); - void ageIncrement( // Age by one year - short // maximum age - if exceeded, the Individual dies - ); - void incFallow(void); // Inrement no. of reproductive seasons since last reproduction - void resetFallow(void); - void moveto( // Move to a specified neighbouring cell - Cell* // pointer to the new cell - ); - // Move to a new cell by sampling a dispersal distance from a single or double - // negative exponential kernel - // Returns 1 if still dispersing (including having found a potential patch), otherwise 0 - int moveKernel( - Landscape*, // pointer to Landscape - Species*, // pointer to Species - const short, // reproduction type (see Species) - const bool // absorbing boundaries? - ); - // Make a single movement step according to a mechanistic movement model - // Returns 1 if still dispersing (including having found a potential patch), otherwise 0 - int moveStep( - Landscape*, // pointer to Landscape - Species*, // pointer to Species - const short, // landscape change index - const bool // absorbing boundaries? - ); - void drawMove( // Visualise paths resulting from movement simulation model - // NULL for the batch version - const float, // initial x co-ordinate - const float, // initial y co-ordinate - const float, // final x co-ordinate - const float // final y co-ordinate - ); - movedata smsMove( // Move to a neighbouring cell according to the SMS algorithm - Landscape*, // pointer to Landscape - Species*, // pointer to Species - const short, // landscape change index - const bool, // TRUE if still in (or returned to) natal patch - const bool, // individual variability? - const bool // absorbing boundaries? - ); - array3x3d getSimDir( // Weight neighbouring cells on basis of current movement direction - const int, // current x co-ordinate - const int, // current y co-ordinate - const float // directional persistence value - ); - array3x3d getGoalBias( // Weight neighbouring cells on basis of goal bias - const int, // current x co-ordinate - const int, // current y co-ordinate - const int, // goal type: 0 = none, 1 = towards goal (NOT IMPLEMENTED), 2 = dispersal bias - const float // GOAL BIAS VALUE - ); - array3x3d calcWeightings( // Calculate weightings for neighbouring cells - const double, // base for power-law (directional persistence or goal bias value) - const double // direction in which lowest (unit) weighting is to be applied - ); - array3x3f getHabMatrix( // Weight neighbouring cells on basis of (habitat) costs - Landscape*, // pointer to Landscape - Species*, // pointer to Species - const int, // current x co-ordinate - const int, // current y co-ordinate - const short, // perceptual range (cells) - const short, // perceptual range evaluation method (see Species) - const short, // landscape change index - const bool // absorbing boundaries? - ); - void outGenetics( // Write records to genetics file - const int, // replicate - const int, // year - const int, // species number - const int, // landscape number - const bool // output as cross table? - ); -#if RS_RCPP - void outMovePath( // Write records to movement paths file - const int // year - ); -#endif - -private: - int indId; - short stage; - short sex; - short age; - short status; // 0 = initial status in natal patch / philopatric recruit - // 1 = disperser - // 2 = disperser awaiting settlement in possible suitable patch - // 3 = waiting between dispersal events - // 4 = completed settlement - // 5 = completed settlement in a suitable neighbouring cell - // 6 = died during transfer by failing to find a suitable patch - // (includes exceeding maximum number of steps or crossing - // absorbing boundary) - // 7 = died during transfer by constant, step-dependent, - // habitat-dependent or distance-dependent mortality - // 8 = failed to survive annual (demographic) mortality - // 9 = exceeded maximum age - short fallow; // reproductive seasons since last reproduction - bool isDeveloping; - Cell *pPrevCell; // pointer to previous Cell - Cell *pCurrCell; // pointer to current Cell - Patch *pNatalPatch; // pointer to natal Patch - emigTraits *emigtraits; // pointer to emigration traits - trfrKernTraits *kerntraits; // pointers to transfer by kernel traits - pathData *path; // pointer to path data for movement model - crwParams *crw; // pointer to CRW traits and data - smsdata *smsData; // pointer to variables required for SMS - settleTraits *setttraits; // pointer to settlement traits - std::queue memory; // memory of last N squares visited for SMS - - Genome *pGenome; - -}; - - -//--------------------------------------------------------------------------- - -double cauchy(double location, double scale) ; -double wrpcauchy (double location, double rho = exp(double(-1))); - -extern RSrandom *pRandom; - -#if RSDEBUG -extern ofstream DEBUGLOG; -#endif - -#if RS_RCPP -extern ofstream outMovePaths; -#endif - -//--------------------------------------------------------------------------- -#endif diff --git a/RangeShiftR/src/RScore/LICENSE b/RangeShiftR/src/RScore/LICENSE deleted file mode 100644 index 94a9ed0..0000000 --- a/RangeShiftR/src/RScore/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program 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. - - This program 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 this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/RangeShiftR/src/RScore/Landscape.cpp b/RangeShiftR/src/RScore/Landscape.cpp deleted file mode 100644 index ac9b733..0000000 --- a/RangeShiftR/src/RScore/Landscape.cpp +++ /dev/null @@ -1,2983 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Landscape.h" -//--------------------------------------------------------------------------- - -ifstream landscape; - -ofstream outConnMat; -ofstream outvisits; -#if RS_RCPP -ofstream outMovePaths; -#endif // RS_RCPP - -//--------------------------------------------------------------------------- - -// Initial species distribution functions - -InitDist::InitDist(Species *pSp) -{ -pSpecies = pSp; -resol = 0; -maxX = 0; -maxY = 0; -minEast = 0.0; -minNorth = 0.0; -} - -InitDist::~InitDist() { -int ncells = (int)cells.size(); -for (int i = 0; i < ncells; i++) - if (cells[i] != NULL) delete cells[i]; -cells.clear(); -} - -void InitDist::setDistribution(int nInit) { -int rr = 0; -int ncells = (int)cells.size(); -if (nInit == 0) { // set all cells to be initialised - for (int i = 0; i < ncells; i++) { - cells[i]->setCell(true); - } -} -else { // set specified number of cells at random to be initialised - if (nInit > ncells/2) { // use backwards selection method - for (int i = 0; i < ncells; i++) cells[i]->setCell(true); - for (int i = 0; i < (ncells-nInit); i++) { - do { - rr = pRandom->IRandom(0,ncells-1); - } while (!cells[rr]->selected()); - cells[rr]->setCell(false); - } - } - else { // use forwards selection method - for (int i = 0; i < ncells; i++) cells[i]->setCell(false); - for (int i = 0; i < nInit; i++) { - do { - rr = pRandom->IRandom(0,ncells-1); - } while (cells[rr]->selected()); - cells[rr]->setCell(true); - } - } -} -} - -// Set a specified cell (by position in cells vector) -void InitDist::setDistCell(int ix,bool init) { -cells[ix]->setCell(init); -} - -// Set a specified cell (by co-ordinates) -void InitDist::setDistCell(locn loc,bool init) { -locn cellloc; -int ncells = (int)cells.size(); -for (int i = 0; i < ncells; i++) { - cellloc = cells[i]->getLocn(); - if (cellloc.x == loc.x && cellloc.y == loc.y) { - cells[i]->setCell(init); - i = ncells; - } -} -} - -// Specified location is within the initial distribution? -bool InitDist::inInitialDist(locn loc) { -int ncells = (int)cells.size(); -for (int i = 0; i < ncells; i++) { - if (cells[i]->toInitialise(loc)) { // cell is to be initialised - return true; - } -} -return false; -} - -int InitDist::cellCount(void) { -return (int)cells.size(); -} - -// Return the co-ordinates of a specified initial distribution cell -locn InitDist::getCell(int ix) { -locn loc; -if (ix >= 0 && ix < (int)cells.size()) { - loc = cells[ix]->getLocn(); -} -else { - loc.x = loc.y = -666; // indicates invalid index specified -} -return loc; -} - -// Return the co-ordinates of a specified initial distribution cell if it has been -// selected - otherwise return negative co-ordinates -locn InitDist::getSelectedCell(int ix) { -locn loc; loc.x = loc.y = -666; -if (ix < (int)cells.size()) { - if (cells[ix]->selected()) { - loc = cells[ix]->getLocn(); - } -} -return loc; -} - -locn InitDist::getDimensions(void) { -locn d; d.x = maxX; d.y = maxY; return d; -} - -void InitDist::resetDistribution(void) { -int ncells = (int)cells.size(); -for (int i = 0; i < ncells; i++) { - cells[i]->setCell(false); -} -} - -//--------------------------------------------------------------------------- - -// Read species initial distribution file - -int InitDist::readDistribution(string distfile) { -#if RS_RCPP -wstring header; -#else -string header; -#endif -int p,nodata; -int ncols,nrows; -#if RS_RCPP -wifstream dfile; // species distribution file input stream -#else -ifstream dfile; // species distribution file input stream -#endif - -// open distribution file -#if !RS_RCPP || RSWIN64 - dfile.open(distfile.c_str()); -#else - dfile.open(distfile, std::ios::binary); - if(spdistraster.utf) { - // apply BOM-sensitive UTF-16 facet - dfile.imbue(std::locale(dfile.getloc(), new std::codecvt_utf16)); - } -#endif -if (!dfile.is_open()) return 21; - -// read landscape data from header records of distribution file -// NB headers of all files have already been compared -double tmpresol; -dfile >> header >> ncols >> header >> nrows >> header >> minEast >> header >> minNorth - >> header >> tmpresol >> header >> nodata; -resol = (int) tmpresol; -#if RS_RCPP -if (!dfile.good()) { - // corrupt file stream - StreamErrorR(distfile); - dfile.close(); - dfile.clear(); - return 144; -} -#endif - -maxX = ncols-1; maxY = nrows-1; - -// set up bad integer value to ensure that valid values are read -int badvalue = -9; if (nodata == -9) badvalue = -99; - -for (int y = nrows-1; y >= 0; y--) { - for (int x = 0; x < ncols; x++) { - p = badvalue; -#if RS_RCPP - if(dfile >> p) { -#else - dfile >> p; -#endif -#if RSDEBUG -//DEBUGLOG << "InitDist::readDistribution():" -// << " y = " << y << " x = " << x << " p = " << p << endl; -#endif - if (p == nodata || p == 0 || p == 1) { // only valid values - if (p == 1) { // species present - cells.push_back(new DistCell(x,y)); - } - } - else { // error in file - dfile.close(); dfile.clear(); - return 22; - } -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(distfile); - dfile.close(); - dfile.clear(); - return 144; - } -#endif - } -} -#if RS_RCPP - dfile >> p; - if (!dfile.eof()) EOFerrorR(distfile); -#endif - -dfile.close(); dfile.clear(); -return 0; -} - - -//--------------------------------------------------------------------------- - -// Landscape functions - -Landscape::Landscape(void) { -patchModel = false; spDist = false; generated = false; fractal = false; continuous = false; -dynamic = false; habIndexed = false; -resol = spResol = landNum = 0; -rasterType = 0; -nHab = nHabMax = 0; -dimX = dimY = 100; -minX = minY = 0; -maxX = maxY = 99; -minPct = maxPct = propSuit = hurst = 0.0; -maxCells = 100; -gpix = 1.0; -pix = (int)gpix; -minEast = minNorth = 0.0; -cells = 0; -#if RSDEBUG -// NOTE: do NOT write to output stream before it has been opened - it will be empty -//DebugGUI("Landscape::Landscape(): this = " + Int2Str((int)this) -// + " pCell = " + Int2Str((int)pCell)); -//DEBUGLOGGUI << "Landscape::Landscape(): this = " << this << " pCell = " << pCell << endl; -#endif -connectMatrix = 0; -epsGlobal = 0; -patchChgMatrix = 0; -costsChgMatrix = 0; - -#if RSDEBUG -//DEBUGLOG << "Landscape::Landscape():" -// << " rasterType= " << rasterType << endl; -#endif -#if RSDEBUG -//MemoLine(("Landscape::Landscape(): landscape created " + Int2Str(0) -// ).c_str()); -#endif -} - -Landscape::~Landscape() { - -#if RSDEBUG -//DebugGUI(("Landscape::~Landscape(): this=" + Int2Str((int)this) + " cells=" + Int2Str((int)cells) -// + " maxX=" + Int2Str(maxX) + " maxY=" + Int2Str(maxY)).c_str()); -#endif -if (cells != 0) { - for (int y = dimY-1; y >= 0; y--) { -#if RSDEBUG -//DebugGUI(("Landscape::~Landscape(): y=" + Int2Str(y) + " cells[y]=" + Int2Str((int)cells[y])).c_str()); -#endif - for (int x = 0; x < dimX; x++) { -#if RSDEBUG -//DebugGUI(("Landscape::~Landscape(): y=" + Int2Str(y) + " x=" + Int2Str(x) -// + " cells[y][x]=" + Int2Str((int)cells[y][x])).c_str()); -#endif - if (cells[y][x] != 0) delete cells[y][x]; - } - if (cells[y] != 0) { -#if RSDEBUG -//DebugGUI(("Landscape::~Landscape(): deleting cells[y]=" + Int2Str((int)cells[y])).c_str()); -#endif -// delete cells[y]; - delete[] cells[y]; - } - } - delete[] cells; - cells = 0; -} -#if RSDEBUG -//DebugGUI(("Landscape::~Landscape(): this=" + Int2Str((int)this) -// + " cells=" + Int2Str((int)cells)).c_str()); -#endif - -int npatches = (int)patches.size(); -for (int i = 0; i < npatches; i++) - if (patches[i] != NULL) delete patches[i]; -patches.clear(); - -int ndistns = (int)distns.size(); -for (int i = 0; i < ndistns; i++) - if (distns[i] != NULL) delete distns[i]; -distns.clear(); - -int ninitcells = (int)initcells.size(); -for (int i = 0; i < ninitcells; i++) - if (initcells[i] != NULL) delete initcells[i]; -initcells.clear(); - -patchnums.clear(); -habCodes.clear(); -colours.clear(); -landchanges.clear(); -patchchanges.clear(); - -deleteConnectMatrix(); -deletePatchChgMatrix(); -if (epsGlobal != 0) delete[] epsGlobal; - -#if RSDEBUG -//MemoLine(("Landscape::~Landscape(): landscape deleted " + Int2Str(1) -// ).c_str()); -#endif -} - -// Remove all patches and cells -// Used for replicating artificial landscape without deleting the landscape itself -void Landscape::resetLand(void) { - -#if RSDEBUG -//DebugGUI("Landscape::resetLand(): starting..."); -#endif -resetLandLimits(); -int npatches = (int)patches.size(); -#if RSDEBUG -//DebugGUI(("Landscape::resetLand(): npatches=" + Int2Str(npatches) -// ).c_str()); -#endif -for (int i = 0; i < npatches; i++) if (patches[i] != NULL) delete patches[i]; -patches.clear(); -#if RSDEBUG -//DebugGUI("Landscape::resetLand(): finished resetting patches"); -#endif - -#if RSDEBUG -//DebugGUI(("Landscape::resetLand(): this=" + Int2Str((int)this) -// + " cells=" + Int2Str((int)cells)).c_str()); -#endif -if (cells != 0) { - for(int y = dimY-1; y >= 0; y--){ -#if RSDEBUG -//DebugGUI(("Landscape::resetLand(): y=" + Int2Str(y) + " cells[y]=" + Int2Str((int)cells[y])).c_str()); -#endif - for (int x = 0; x < dimX; x++) { -#if RSDEBUG -//DebugGUI(("Landscape::resetLand(): y=" + Int2Str(y) + " x=" + Int2Str(x) -// + " cells[y][x]=" + Int2Str((int)cells[y][x])).c_str()); -#endif - if (cells[y][x] != 0) delete cells[y][x]; - } - if (cells[y] != 0) { -#if RSDEBUG -//DebugGUI(("Landscape::resetLand(): deleting cells[y]=" + Int2Str((int)cells[y])).c_str()); -#endif - delete[] cells[y]; - } - } - delete[] cells; - cells = 0; -} -#if RSDEBUG -//DebugGUI(("Landscape::resetLand(): this=" + Int2Str((int)this) -// + " cells=" + Int2Str((int)cells)).c_str()); -#endif -} - -void Landscape::setLandParams(landParams ppp,bool batchMode) -{ -generated = ppp.generated; patchModel = ppp.patchModel; spDist = ppp.spDist; -dynamic = ppp.dynamic; -landNum = ppp.landNum; -if (ppp.resol > 0) resol = ppp.resol; -if (ppp.spResol > 0 && ppp.spResol%ppp.resol == 0) spResol = ppp.spResol; -if ((ppp.rasterType >= 0 && ppp.rasterType <= 2) || ppp.rasterType == 9) - rasterType = ppp.rasterType; -if (ppp.nHab >= 1) nHab = ppp.nHab; -if (ppp.nHabMax >= 1) nHabMax = ppp.nHabMax; -if (ppp.dimX > 0) dimX = ppp.dimX; -if (ppp.dimY > 0) dimY = ppp.dimY; -if (ppp.minX >= 0 && ppp.maxX >= 0 && ppp.minX <= ppp.maxX && ppp.maxX < dimX) { - minX = ppp.minX; maxX = ppp.maxX; -} -else { - minX = 0; maxX = dimX - 1; -} -if (ppp.minY >= 0 && ppp.maxY >= 0 && ppp.minY <= ppp.maxY && ppp.maxY < dimY) { - minY = ppp.minY; maxY = ppp.maxY; -} -else { - minY = 0; maxY = dimY - 1; -} -if (batchMode && rasterType == 0) { - // in batch mode, set up sequential habitat codes if not already present - if (habCodes.size() == 0) { - for (int i = 0; i < nHabMax; i++) { - habCodes.push_back(i+1); - } - } -} -} - -landParams Landscape::getLandParams(void) -{ -landParams ppp; -ppp.generated = generated; ppp.patchModel = patchModel; ppp.spDist = spDist; -ppp.dynamic = dynamic; -ppp.landNum = landNum; -ppp.resol = resol; ppp.spResol = spResol; -ppp.rasterType = rasterType; -ppp.nHab = nHab; ppp.nHabMax = nHabMax; -ppp.dimX = dimX; ppp.dimY = dimY; -ppp.minX = minX; ppp.minY = minY; -ppp.maxX = maxX; ppp.maxY = maxY; -return ppp; -} - -landData Landscape::getLandData(void) { -landData dd; -dd.resol = resol; -dd.dimX = dimX; dd.dimY = dimY; -dd.minX = minX; dd.minY = minY; -dd.maxX = maxX; dd.maxY = maxY; -return dd; -} - -void Landscape::setGenLandParams(genLandParams ppp) -{ -fractal = ppp.fractal; -continuous = ppp.continuous; -if (ppp.minPct > 0.0 && ppp.minPct < 100.0) minPct = ppp.minPct; -if (ppp.maxPct > 0.0 && ppp.maxPct <= 100.0) maxPct = ppp.maxPct; -if (ppp.propSuit >= 0.0 && ppp.propSuit <= 1.0) propSuit = ppp.propSuit; -if (ppp.hurst > 0.0 && ppp.hurst < 1.0) hurst = ppp.hurst; -if (ppp.maxCells > 0) maxCells = ppp.maxCells; -} - -genLandParams Landscape::getGenLandParams(void) -{ -genLandParams ppp; -ppp.fractal = fractal; ppp.continuous = continuous; -ppp.minPct = minPct; ppp.maxPct = maxPct; ppp.propSuit = propSuit; ppp.hurst = hurst; -ppp.maxCells = maxCells; -return ppp; -} - -void Landscape::setLandLimits(int x0,int y0,int x1,int y1) { -if (x0 >= 0 && x1 >= 0 && x0 <= x1 && x1 < dimX -&& y0 >= 0 && y1 >= 0 && y0 <= y1 && y1 < dimY) { - minX = x0; maxX = x1; minY = y0; maxY = y1; -} -} - -void Landscape::resetLandLimits(void) { -minX = minY = 0; maxX = dimX-1; maxY = dimY-1; -} - -//--------------------------------------------------------------------------- - -void Landscape::setLandPix(landPix p) { -if (p.pix > 0) pix = p.pix; -if (p.gpix > 0.0) gpix = p.gpix; -} - -landPix Landscape::getLandPix(void) { -landPix p; -p.pix = pix; p.gpix = gpix; -return p; -} - -void Landscape::setOrigin(landOrigin origin) { -minEast = origin.minEast; minNorth = origin.minNorth; -} - -landOrigin Landscape::getOrigin(void) { -landOrigin origin; -origin.minEast = minEast; origin.minNorth = minNorth; -return origin; -} - -//--------------------------------------------------------------------------- - -// Functions to handle habitat codes - -bool Landscape::habitatsIndexed(void) { return habIndexed; } - -void Landscape::listHabCodes(void) { -int nhab = (int)habCodes.size(); -#if RS_RCPP && !R_CMD -Rcpp::Rcout << endl; -for (int i = 0; i < nhab; i++) { - Rcpp::Rcout << "Habitat code[ " << i << "] = " << habCodes[i] << endl; -} -Rcpp::Rcout << endl; -#else -cout << endl; -for (int i = 0; i < nhab; i++) { - cout << "Habitat code[ " << i << "] = " << habCodes[i] << endl; -} -cout << endl; -#endif -} - -void Landscape::addHabCode(int hab) { -int nhab = (int)habCodes.size(); -bool addCode = true; -for (int i = 0; i < nhab; i++) { - if (hab == habCodes[i]) { - addCode = false; i = nhab+1; - } -} -if (addCode) { habCodes.push_back(hab); nHab++; } -} - -// Get the index number of the specified habitat in the habitats vector -int Landscape::findHabCode(int hab) { -int nhab = (int)habCodes.size(); -for (int i = 0; i < nhab; i++) { - if (hab == habCodes[i]) return i; -} -return -999; -} - -// Get the specified habitat code -int Landscape::getHabCode(int ixhab) { -if (ixhab < (int)habCodes.size()) return habCodes[ixhab]; -else return -999; -} - -void Landscape::clearHabitats(void) { -habCodes.clear(); -colours.clear(); -} - -void Landscape::addColour(rgb c) { -colours.push_back(c); -} - -void Landscape::changeColour(int i,rgb col) { -int ncolours = (int)colours.size(); -if (i >= 0 && i < ncolours) { - if (col.r >=0 && col.r <= 255 && col.g >=0 && col.g <= 255 && col.b >=0 && col.b <= 255) - colours[i] = col; -} -} - -rgb Landscape::getColour(int ix) { -return colours[ix]; -} - -int Landscape::colourCount(void) { -return (int)colours.size(); -} - -//--------------------------------------------------------------------------- -void Landscape::setCellArray(void) { -#if RSDEBUG -//DebugGUI(("Landscape::setCellArray(): start: this=" + Int2Str((int)this) -// + " cells=" + Int2Str((int)cells)).c_str()); -#endif -if (cells != 0) resetLand(); -//cells = new Cell **[maxY+1]; -cells = new Cell **[dimY]; -#if RSDEBUG -//DebugGUI(("Landscape::setCellArray(): cells=" + Int2Str((int)cells)).c_str()); -#endif -for (int y = dimY-1; y >= 0; y--) { - cells[y] = new Cell *[dimX]; -#if RSDEBUG -//DebugGUI(("Landscape::setCellArray(): y=" + Int2Str(y) -// + " cells[y]=" + Int2Str((int)cells[y])).c_str()); -#endif - for (int x = 0; x < dimX; x++) { - cells[y][x] = 0; - } -} -#if RSDEBUG -//DebugGUI(("Landscape::setCellArray(): end: this=" + Int2Str((int)this) -// + " cells=" + Int2Str((int)cells)).c_str()); -#endif -} - -void Landscape::addPatchNum(int p) { -int npatches = (int)patchnums.size(); -bool addpatch = true; -for (int i = 0; i < npatches; i++) { - if (p == patchnums[i]) { - addpatch = false; i = npatches+1; - } -} -if (addpatch) patchnums.push_back(p); -} - - -//--------------------------------------------------------------------------- -/* Create an artificial landscape (random or fractal), which can be -either binary (habitat index 0 is the matrix, 1 is suitable habitat) -or continuous (0 is the matrix, >0 is suitable habitat) */ -void Landscape::generatePatches(void) -{ -int x,y,ncells; -double p; -Patch *pPatch; -Cell *pCell; - -vector ArtLandscape; - -#if RSDEBUG -//int iiiiii = (int)fractal; -//DEBUGLOG << "Landscape::generatePatches(): (int)fractal=" << iiiiii -// << " rasterType=" << rasterType -// << " continuous=" << continuous -// << " dimX=" << dimX << " dimY=" << dimY -// << " propSuit=" << propSuit -// << " hurst=" << hurst -// << " maxPct=" << maxPct << " minPct=" << minPct -// << endl; -#endif - -setCellArray(); - -int patchnum = 0; // initial patch number for cell-based landscape -// create patch 0 - the matrix patch (even if there is no matrix) -newPatch(patchnum++); - -// as landscape generator returns cells in a random sequence, first set up all cells -// in the landscape in the correct sequence, then update them and create patches for -// habitat cells -for (int yy = dimY-1; yy >= 0; yy--) { - for (int xx = 0; xx < dimX; xx++) { -#if RSDEBUG -//DEBUGLOG << "Landscape::generatePatches(): yy=" << yy << " xx=" << xx << endl; -#endif - addNewCellToLand(xx,yy,0); - } -} - -if (continuous) rasterType = 2; -else rasterType = 0; -if (fractal) { - p = 1.0 - propSuit; - // fractal_landscape() requires Max_prop > 1 (but does not check it!) - // as in turn it calls runif(1.0,Max_prop) - double maxpct; - if (maxPct < 1.0) maxpct = 100.0; else maxpct = maxPct; - - ArtLandscape = fractal_landscape(dimY,dimX,hurst,p,maxpct,minPct); - - vector::iterator iter = ArtLandscape.begin(); - while (iter != ArtLandscape.end()) { - x = iter->y_coord; y = iter->x_coord; -#if RSDEBUG -//DEBUGLOG << "Landscape::generatePatches(): x=" << x << " y=" << y -// << " iter->avail=" << iter->avail -// << " iter->value=" << iter->value << endl; -#endif - pCell = findCell(x,y); - if (continuous) { - if (iter->value > 0.0) { // habitat - pPatch = newPatch(patchnum++); - addCellToPatch(pCell,pPatch,iter->value); - } - else { // matrix - addCellToPatch(pCell,patches[0],iter->value); - } - } - else { // discrete - if (iter->avail == 0) { // matrix - addCellToPatch(pCell,patches[0]); - } - else { // habitat - pPatch = newPatch(patchnum++); - addCellToPatch(pCell,pPatch); - pCell->changeHabIndex(0,1); - } - } - iter++; - } -} -else { // random landscape - int hab = 0; - ncells = (int)((float)(dimX) * (float)(dimY) * propSuit + 0.00001); // no. of cells to initialise -#if RSDEBUG -//DEBUGLOG << "Landscape::generatePatches(): dimX=" << dimX << " dimY=" << dimY -// << " propSuit=" << propSuit -// << " PRODUCT=" << ((float)(dimX) * (float)(dimY) * propSuit + 0.00001) -// << " ncells=" << ncells << endl; -#endif - int i = 0; - do { - do { - x = pRandom->IRandom(0,dimX-1); y = pRandom->IRandom(0,dimY-1); - pCell = findCell(x,y); - hab = pCell->getHabIndex(0); - } while (hab > 0); -#if RSDEBUG -//DEBUGLOG << "Landscape::generatePatches() 00000: y=" << y << " x=" << x -// << " i=" << i << " hab=" << hab << " patchnum=" << patchnum -// << endl; -#endif - pPatch = newPatch(patchnum++); - pCell = findCell(x,y); - addCellToPatch(pCell,pPatch); - pCell->changeHabIndex(0,1); - if (continuous) { - pCell->setHabitat((float)(minPct + pRandom->Random() * (maxPct - minPct))); - } - i++; - } while (i < ncells); - // remaining cells need to be added to the matrix patch - p = 0.0; - x = 0; - for (int yy = dimY-1; yy >= 0; yy--) { - for (int xx = 0; xx < dimX; xx++) { - pCell = findCell(xx,yy); - if (continuous) { - if (pCell->getHabitat(0) <= 0.0) - { - addCellToPatch(pCell,patches[0],(float)p); - } - } - else { // discrete - if (pCell->getHabIndex(0) == 0) { -#if RSDEBUG -//DEBUGLOG << "Landscape::generatePatches() 11111: yy=" << yy << " xx=" << xx -// << endl; -#endif - addCellToPatch(pCell,patches[0],x); - } - } - } - } -} - -#if RSDEBUG -//DEBUGLOG << "Landscape::generatePatches(): finished, no. of patches = " -// << patchCount() << endl; -#endif - -} - -//--------------------------------------------------------------------------- - -// Landscape patch-management functions - -//--------------------------------------------------------------------------- -/* Create a patch for each suitable cell of a cell-based landscape (all other -habitat cells are added to the matrix patch) */ -void Landscape::allocatePatches(Species *pSpecies) -{ -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): pSpecies=" << pSpecies -// << " N patches=" << (int)patches.size() << endl; -#endif -//int hx; -float habK; -Patch *pPatch; -Cell *pCell; - -// delete all existing patches -int npatches = (int)patches.size(); -for (int i = 0; i < npatches; i++) { -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): i=" << i -// << " patches[i]=" << patches[i] << endl; -#endif - if (patches[i] != NULL) delete patches[i]; -} -patches.clear(); -// create the matrix patch -patches.push_back(new Patch(0,0)); -Patch *matrixPatch = patches[0]; -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): npatches=" << npatches -// << " N patches=" << (int)patches.size() << endl; -#endif -int patchnum = 1; - -switch (rasterType) { - -case 0: // habitat codes - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): x=" << x << " y=" << y -// << " cells=" << cells[y][x] << endl; -#endif - if (cells[y][x] != 0) { // not no-data cell - pCell = cells[y][x]; -// hx = pCell->getHabIndex(); -// habK = pSpecies->getHabK(hx); - habK = 0.0; - int nhab = pCell->nHabitats(); - for (int i = 0; i < nhab; i++) { - habK += pSpecies->getHabK(pCell->getHabIndex(i)); -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): x=" << x << " y=" << y -// << " i=" << i -// << " cells[y][x]=" << cells[y][x] -// << " pCell=" << pCell -// << " habK=" << habK << endl; -#endif - } - if (habK > 0.0) { // cell is suitable - create a patch for it - pPatch = newPatch(patchnum++); - addCellToPatch(pCell,pPatch); - } - else { // cell is not suitable - add to the matrix patch - addCellToPatch(pCell,matrixPatch); - pPatch = 0; - } - } - } - } - break; -case 1: // habitat cover - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): x=" << x << " y=" << y -// << " cells=" << cells[y][x] << endl; -#endif - if (cells[y][x] != 0) { // not no-data cell - pCell = cells[y][x]; - habK = 0.0; - int nhab = pCell->nHabitats(); -// for (int i = 0; i < nHab; i++) - for (int i = 0; i < nhab; i++) - { - habK += pSpecies->getHabK(i) * pCell->getHabitat(i) / 100.0f; -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): x=" << x << " y=" << y -// << " i=" << i -// << " cells[y][x]=" << cells[y][x] -// << " pCell=" << pCell -// << " habK=" << habK << endl; -#endif - } - if (habK > 0.0) { // cell is suitable - create a patch for it - pPatch = newPatch(patchnum++); - addCellToPatch(pCell,pPatch); - } - else { // cell is not suitable - add to the matrix patch - addCellToPatch(pCell,matrixPatch); - pPatch = 0; - } - } - } - } - break; -case 2: // habitat quality - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): x=" << x << " y=" << y -// << " cells=" << cells[y][x] << endl; -#endif - if (cells[y][x] != 0) { // not no-data cell - pCell = cells[y][x]; - habK = 0.0; - int nhab = pCell->nHabitats(); -// for (int i = 0; i < nHab; i++) - for (int i = 0; i < nhab; i++) - { - habK += pSpecies->getHabK(0) * pCell->getHabitat(i) / 100.0f; -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): x=" << x << " y=" << y -// << " i=" << i -// << " cells[y][x]=" << cells[y][x] -// << " pCell=" << pCell -// << " habK=" << habK << endl; -#endif - } - if (habK > 0.0) { // cell is suitable (at some time) - create a patch for it - pPatch = newPatch(patchnum++); - addCellToPatch(pCell,pPatch); - } - else { // cell is never suitable - add to the matrix patch - addCellToPatch(pCell,matrixPatch); - pPatch = 0; - } - } - } - } - break; - -} // end of switch (rasterType) - -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): finished, N patches = " << (int)patches.size() << endl; -#endif - -} - -Patch* Landscape::newPatch(int num) -{ -int npatches = (int)patches.size(); -patches.push_back(new Patch(num,num)); -return patches[npatches]; -} - -Patch* Landscape::newPatch(int seqnum,int num) -{ -int npatches = (int)patches.size(); -patches.push_back(new Patch(seqnum,num)); -return patches[npatches]; -} - -void Landscape::resetPatches(void) { -int npatches = (int)patches.size(); -for (int i = 0; i < npatches; i++) { - patches[i]->resetLimits(); -} -} - -void Landscape::addNewCellToLand(int x,int y,float q) { -if (q < 0.0) // no-data cell - no Cell created - cells[y][x] = 0; -else - cells[y][x] = new Cell(x,y,0,q); -} - -void Landscape::addNewCellToLand(int x,int y,int hab) { -if (hab < 0) // no-data cell - no Cell created - cells[y][x] = 0; -else - cells[y][x] = new Cell(x,y,0,hab); -} - -void Landscape::addNewCellToPatch(Patch *pPatch,int x,int y,float q) { -if (q < 0.0) { // no-data cell - no Cell created - cells[y][x] = 0; -} -else { // create the new cell - cells[y][x] = new Cell(x,y,(intptr)pPatch,q); - if (pPatch != 0) { // not the matrix patch - // add the cell to the patch - pPatch->addCell(cells[y][x],x,y); - } -} -} - -void Landscape::addNewCellToPatch(Patch *pPatch,int x,int y,int hab) { -if (hab < 0) // no-data cell - no Cell created - cells[y][x] = 0; -else { // create the new cell - cells[y][x] = new Cell(x,y,(intptr)pPatch,hab); - if (pPatch != 0) { // not the matrix patch - // add the cell to the patch - pPatch->addCell(cells[y][x],x,y); - } -} -} - -void Landscape::addCellToPatch(Cell *pCell,Patch *pPatch) { -pCell->setPatch((intptr)pPatch); -locn loc = pCell->getLocn(); -// add the cell to the patch -pPatch->addCell(pCell,loc.x,loc.y); -} - -void Landscape::addCellToPatch(Cell *pCell,Patch *pPatch,float q) { -pCell->setPatch((intptr)pPatch); -// update the habitat type of the cell -pCell->setHabitat(q); -locn loc = pCell->getLocn(); -// add the cell to the patch -pPatch->addCell(pCell,loc.x,loc.y); -} - -void Landscape::addCellToPatch(Cell *pCell,Patch *pPatch,int hab) { -pCell->setPatch((intptr)pPatch); -// update the habitat type of the cell -pCell->setHabIndex(hab); -locn loc = pCell->getLocn(); -// add the cell to the patch -pPatch->addCell(pCell,loc.x,loc.y); -} - -patchData Landscape::getPatchData(int ix) { -patchData ppp; -ppp.pPatch = patches[ix]; ppp.patchNum = patches[ix]->getPatchNum(); -ppp.nCells = patches[ix]->getNCells(); -locn randloc; randloc.x = -666; randloc.y = -666; -Cell *pCell = patches[ix]->getRandomCell(); -if (pCell != 0) { - randloc = pCell->getLocn(); -} -ppp.x = randloc.x; ppp.y = randloc.y; -return ppp; -} - -bool Landscape::existsPatch(int num) { -int npatches = (int)patches.size(); -for (int i = 0; i < npatches; i++) { - if (num == patches[i]->getPatchNum()) return true; -} -return false; -} - -Patch* Landscape::findPatch(int num) { -int npatches = (int)patches.size(); -for (int i = 0; i < npatches; i++) { - if (num == patches[i]->getPatchNum()) return patches[i]; -} -return 0; -} - -void Landscape::resetPatchPopns(void) { -int npatches = (int)patches.size(); -for (int i = 0; i < npatches; i++) { - patches[i]->resetPopn(); -} -} - -void Landscape::updateCarryingCapacity(Species *pSpecies,int yr,short landIx) { -envGradParams grad = paramsGrad->getGradient(); -bool gradK = false; -if (grad.gradient && grad.gradType == 1) gradK = true; // gradient in carrying capacity -patchLimits landlimits; -landlimits.xMin = minX; landlimits.xMax = maxX; -landlimits.yMin = minY; landlimits.yMax = maxY; -#if RSDEBUG -//DEBUGLOG << "Landscape::updateCarryingCapacity(): yr=" << yr -// << " xMin=" << landlimits.xMin << " yMin=" << landlimits.yMin -// << " xMax=" << landlimits.xMax << " yMax=" << landlimits.yMax -// << endl; -#endif -int npatches = (int)patches.size(); -for (int i = 0; i < npatches; i++) { - if (patches[i]->getPatchNum() != 0) { // not matrix patch - patches[i]->setCarryingCapacity(pSpecies,landlimits, - getGlobalStoch(yr),nHab,rasterType,landIx,gradK); - } -} - -} - -Cell* Landscape::findCell(int x,int y) { -if (x >= 0 && x < dimX && y >= 0 && y < dimY) return cells[y][x]; -else return 0; -} - -int Landscape::patchCount(void) { -return (int)patches.size(); -} - -void Landscape::listPatches(void) { -patchLimits p; -int npatches = (int)patches.size(); -#if RS_RCPP && !R_CMD -Rcpp::Rcout << endl; -for (int i = 0; i < npatches; i++) { - p = patches[i]->getLimits(); - Rcpp::Rcout << "Patch " << patches[i]->getPatchNum() - << " xMin = " << p.xMin << " xMax = " << p.xMax - << " \tyMin = " << p.yMin << " yMax = " << p.yMax - << endl; -} -Rcpp::Rcout << endl; -#else -cout << endl; -for (int i = 0; i < npatches; i++) { - p = patches[i]->getLimits(); - cout << "Patch " << patches[i]->getPatchNum() - << " xMin = " << p.xMin << " xMax = " << p.xMax - << " \tyMin = " << p.yMin << " yMax = " << p.yMax - << endl; -} -cout << endl; -#endif -} - -// Check that total cover of any cell does not exceed 100% -// and identify matrix cells -int Landscape::checkTotalCover(void) { -if (rasterType != 1) return 0; // not appropriate test -int nCells = 0; -for(int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - if (cells[y][x] != 0) - { // not a no-data cell - float sumCover = 0.0; - for (int i = 0; i < nHab; i++) { - sumCover += cells[y][x]->getHabitat(i); -#if RSDEBUG -//DebugGUI(("Landscape::checkTotalCover(): y=" + Int2Str(y) -// + " x=" + Int2Str(x) -// + " i=" + Int2Str(i) -// + " sumCover=" + Float2Str(sumCover) -// ).c_str()); -#endif - } - if (sumCover > 100.00001) nCells++; // decimal part to allow for floating point error - if (sumCover <= 0.0) // cell is a matrix cell - cells[y][x]->setHabIndex(0); - else - cells[y][x]->setHabIndex(1); - } - } -} -return nCells; -} - -// Convert habitat codes stored on loading habitat codes landscape to -// sequential sorted index numbers -void Landscape::updateHabitatIndices(void) { -// sort codes -sort (habCodes.begin(),habCodes.end()); -nHab = (int)habCodes.size(); -// convert codes in landscape -int h; -int changes = (int)landchanges.size(); -#if RSDEBUG -//DebugGUI(("Landscape::updateHabitatIndices(): nHab=" + Int2Str(nHab) -// + " changes=" + Int2Str(changes) -// ).c_str()); -#endif -for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - if (cells[y][x] != 0) { // not a no-data cell - for (int c = 0; c <= changes; c++) { - h = cells[y][x]->getHabIndex(c); -#if RSDEBUG -//DebugGUI(("Landscape::updateHabitatIndices() 00000: y=" + Int2Str(y) -// + " x=" + Int2Str(x) + " c=" + Int2Str(c) + " h=" + Int2Str(h) -// ).c_str()); -#endif - if (h >= 0) { - h = findHabCode(h); -#if RSDEBUG -//DebugGUI(("Landscape::updateHabitatIndices() 11111: y=" + Int2Str(y) -// + " x=" + Int2Str(x) + " c=" + Int2Str(c) + " h=" + Int2Str(h) -// ).c_str()); -#endif - cells[y][x]->changeHabIndex(c,h); - } - } - } - } -} -habIndexed = true; -} - -void Landscape::setEnvGradient(Species *pSpecies,bool initial) -{ -float dist_from_opt,dev; -float habK; -//int hab; -double envval; -// gradient parameters -envGradParams grad = paramsGrad->getGradient(); -#if RSDEBUG -//DEBUGLOG << "Landscape::setEnvGradient(): grad.opt_y = " << grad.opt_y -// << " grad.grad_inc = " << grad.grad_inc << " grad.factor " << grad.factor -// << endl; -#endif -for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - // NB: gradient lies in range 0-1 for all types, and is applied when necessary... - // ... implies gradient increment will be dimensionless in range 0-1 (but << 1) - if (cells[y][x] != 0) { // not no-data cell - habK = 0.0; - int nhab = cells[y][x]->nHabitats(); - for (int i = 0; i < nhab; i++) { - switch (rasterType) { - case 0: - habK += pSpecies->getHabK(cells[y][x]->getHabIndex(i)); - break; - case 1: - habK += pSpecies->getHabK(i) * cells[y][x]->getHabitat(i) / 100.0f; - break; - case 2: - habK += pSpecies->getHabK(0) * cells[y][x]->getHabitat(i) / 100.0f; - break; - } - } -#if RSDEBUG -//DEBUGLOG << "Landscape::setEnvGradient(): y=" << y << " x=" << x -// << " dist_from_opt=" << dist_from_opt << " rasterType=" << rasterType << " hab=" << hab -// << endl; -#endif - if (habK > 0.0) { // suitable cell - if (initial) { // set local environmental deviation - cells[y][x]->setEnvDev((float)pRandom->Random()*(2.0f) - 1.0f); - } - dist_from_opt = (float)(fabs((double)grad.opt_y - (double)y)); - dev = cells[y][x]->getEnvDev(); - envval = 1.0 - dist_from_opt*grad.grad_inc + dev*grad.factor; -#if RSDEBUG -//DEBUGLOG << "Landscape::setEnvGradient(): y=" << y << " x=" << x -// << " dist_from_opt=" << dist_from_opt << " dev=" << dev << " p=" << p -// << endl; -#endif - if (envval < 0.000001) envval = 0.0; - if (envval > 1.0) envval = 1.0; - } - else envval = 0.0; - cells[y][x]->setEnvVal((float)envval); - } - } -} - -} - -void Landscape::setGlobalStoch(int nyears) { -envStochParams env = paramsStoch->getStoch(); -if (epsGlobal != 0) delete[] epsGlobal; -epsGlobal = new float[nyears]; -epsGlobal[0] = (float)(pRandom->Normal(0.0,env.std)*sqrt(1.0-(env.ac*env.ac))); -for (int i = 1; i < nyears; i++){ - epsGlobal[i] = (float)(env.ac*epsGlobal[i-1] + pRandom->Normal(0.0,env.std)*sqrt(1.0-(env.ac*env.ac))); -} -} - -float Landscape::getGlobalStoch(int yr) { -if (epsGlobal != 0 && yr >= 0) { - return epsGlobal[yr]; -} -else return 0.0; -} - -void Landscape::updateLocalStoch(void) { -envStochParams env = paramsStoch->getStoch(); -float randpart; -for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - if (cells[y][x] != 0) { // not a no-data cell - randpart = (float)(pRandom->Normal(0.0,env.std) * sqrt(1.0-(env.ac*env.ac))); -#if RSDEBUG -//DEBUGLOG << "Landscape::updateLocalStoch(): y=" << y << " x=" << x -// << " env.std= " << env.std << " env.ac= " << env.ac << " randpart= " << randpart -// << endl; -#endif - cells[y][x]->updateEps((float)env.ac,randpart); - } - } -} - -} - -void Landscape::resetCosts(void) { -for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - if (cells[y][x] != 0) { // not a no-data cell - cells[y][x]->resetCost(); - } - } -} -} - -void Landscape::resetEffCosts(void) { -for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - if (cells[y][x] != 0) { // not a no-data cell - cells[y][x]->resetEffCosts(); - } - } -} -} - -//--------------------------------------------------------------------------- - -// Dynamic landscape functions - -void Landscape::setDynamicLand(bool dyn) { dynamic = dyn; } - -void Landscape::addLandChange(landChange c) { -#if RSDEBUG -//DebugGUI(("Landscape::addLandChange(): chgnum=" + Int2Str(c.chgnum) -// + " chgyear=" + Int2Str(c.chgyear) -// ).c_str()); -#endif -landchanges.push_back(c); -} - -int Landscape::numLandChanges(void) { return (int)landchanges.size(); } - -landChange Landscape::getLandChange(short ix) { -landChange c; c.chgnum = c.chgyear = 0; -c.habfile = c.pchfile = c.costfile = "none"; -int nchanges = (int)landchanges.size(); -if (ix < nchanges) c = landchanges[ix]; -return c; -} - -void Landscape::deleteLandChanges(void) { -while (landchanges.size() > 0) landchanges.pop_back(); -landchanges.clear(); -} - -#if RS_RCPP && !R_CMD -int Landscape::readLandChange(int filenum, bool costs, wifstream& hfile, wifstream& pfile, wifstream& cfile, int habnodata, int pchnodata, int costnodata) -#else -int Landscape::readLandChange(int filenum,bool costs) -#endif -{ - -#if RSDEBUG -DEBUGLOG << "Landscape::readLandChange(): filenum=" << filenum << " costs=" << int(costs) - << endl; -#endif - -#if RS_RCPP -wstring header; -#else -string header; -int ncols,nrows,habnodata,costnodata,pchnodata; -costnodata = 0; -pchnodata = 0; -#endif -int h = 0,p = 0,c = 0, pchseq = 0; -float hfloat,pfloat,cfloat; -simParams sim = paramsSim->getSim(); - -if (filenum < 0) return 19; - -//if (patchModel && (rasterType == 0 || rasterType == 2)) { -// if (filenum == 0) { // first change -// createPatchChgMatrix(); -// } -// pchseq = patchCount(); -//} -if (patchModel) pchseq = patchCount(); - -#if !RS_RCPP - ifstream hfile; // habitat file input stream - ifstream pfile; // patch file input stream - ifstream cfile; // costs file input stream -#endif - -#if !RS_RCPP || R_CMD -// open habitat file and optionally also patch and costs files -hfile.open(landchanges[filenum].habfile.c_str()); -if (!hfile.is_open()) return 30; -if (patchModel) { - pfile.open(landchanges[filenum].pchfile.c_str()); - if (!pfile.is_open()) { - hfile.close(); hfile.clear(); - return 31; - } -} -if (costs) { - cfile.open(landchanges[filenum].costfile.c_str()); - if (!cfile.is_open()) { - hfile.close(); hfile.clear(); - if (pfile.is_open()) { - pfile.close(); pfile.clear(); - } - return 32; - } -} - -// read header records of habitat (and patch) file(s) -// NB headers of all files have already been compared -hfile >> header >> ncols >> header >> nrows >> header >> hfloat >> header >> hfloat - >> header >> hfloat >> header >> habnodata; -if (patchModel) { - for (int i = 0; i < 5; i++) pfile >> header >> pfloat; - pfile >> header >> pchnodata; -} -if (costs) { - for (int i = 0; i < 5; i++) cfile >> header >> cfloat; - cfile >> header >> costnodata; -} -#endif - -// set up bad float values to ensure that valid values are read -float badhfloat = -9.0; if (habnodata == -9) badhfloat = -99.0; -float badpfloat = -9.0; if (pchnodata == -9) badpfloat = -99.0; -float badcfloat = -9.0; if (costnodata == -9) badcfloat = -99.0; - -switch (rasterType) { - -case 0: // raster with habitat codes - 100% habitat each cell - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - hfloat = badhfloat; -#if RS_RCPP - if(hfile >> hfloat) { -#else - hfile >> hfloat; -#endif - h = (int)hfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR("habitatchgfile"); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 171; - } -#endif - if (patchModel) { - pfloat = badpfloat; -#if RS_RCPP - if(pfile >> pfloat) { -#else - pfile >> pfloat; -#endif - p = (int)pfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR("patchchgfile"); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 172; - } -#endif - } - if (costs) { - cfloat = badcfloat; -#if RS_RCPP - if(cfile >> cfloat) { -#else - cfile >> cfloat; -#endif - c = (int)cfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR("costchgfile"); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 173; - } -#endif - } -#if RSDEBUG -//DebugGUI(("Landscape::readLandscape(): x=" + Int2Str(x) + " y=" + Int2Str(y) -// + " h=" + Int2Str(h) + " p=" + Int2Str(p) -//).c_str()); -#endif - if (cells[y][x] != 0) { // not a no data cell (in initial landscape) - if (h == habnodata) { // invalid no data cell in change map - hfile.close(); hfile.clear(); - return 36; - } - else { - if (h < 0 || (sim.batchMode && (h < 1 || h > nHabMax))) { - // invalid habitat code - hfile.close(); hfile.clear(); - if (patchModel) { pfile.close(); pfile.clear(); } - return 33; - } - else { - addHabCode(h); - cells[y][x]->setHabIndex(h); - } - } - if (patchModel) { - if (p < 0 || p == pchnodata) { // invalid patch code - #if RS_RCPP && !R_CMD - if (p == pchnodata) Rcpp::Rcout << "Found patch NA in valid habitat cell." << std::endl; - else Rcpp::Rcout << "Found negative patch ID in valid habitat cell." << std::endl; - #endif - hfile.close(); hfile.clear(); - pfile.close(); pfile.clear(); - return 34; - } - else { - patchChgMatrix[y][x][2] = p; - if (p > 0 && !existsPatch(p)) { - addPatchNum(p); - newPatch(pchseq++,p); - } - } - } - if (costs) { - if (c < 1) { // invalid cost - hfile.close(); hfile.clear(); - if (pfile.is_open()) { - pfile.close(); pfile.clear(); - } - return 38; - } - else { - costsChgMatrix[y][x][2] = c; - } - } - } - } - } -#if RS_RCPP - hfile >> hfloat; - if (!hfile.eof()) EOFerrorR("habitatchgfile"); - if (patchModel) - { - pfile >> pfloat; - if (!pfile.eof()) EOFerrorR("patchchgfile"); - } - if (costs) - { - cfile >> cfloat; - if (!cfile.eof()) EOFerrorR("costchgfile"); - } -#endif - break; - - case 2: // habitat quality - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - hfloat = badhfloat; -#if RS_RCPP - if(hfile >> hfloat) { -#else - hfile >> hfloat; -#endif - h = (int)hfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR("habitatchgfile"); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 172; - } -#endif - if (patchModel) { - pfloat = badpfloat; -#if RS_RCPP - if(pfile >> pfloat) { -#else - pfile >> pfloat; -#endif - p = (int)pfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR("patchchgfile"); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 175; - } -#endif - } - if (costs) { - cfloat = badcfloat; -#if RS_RCPP - if(cfile >> cfloat) { -#else - cfile >> cfloat; -#endif - c = (int)cfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR("costchgfile"); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 173; - } -#endif - } -#if RSDEBUG -//MemoLine(("y=" + Int2Str(y) + " x=" + Int2Str(x) + " hfloat=" + Float2Str(hfloat) -// + " p=" + Int2Str(p)).c_str()); -#endif - if (cells[y][x] != 0) { // not a no data cell (in initial landscape) - if (h == habnodata) { // invalid no data cell in change map - hfile.close(); hfile.clear(); - if (patchModel) { pfile.close(); pfile.clear(); } - return 36; - } - else { - if (hfloat < 0.0 || hfloat > 100.0) { // invalid quality score - hfile.close(); hfile.clear(); - if (patchModel) { pfile.close(); pfile.clear(); } - return 37; - } - else { - cells[y][x]->setHabitat(hfloat); - } - } - if (patchModel) { - if (p < 0 || p == pchnodata) { // invalid patch code - #if RS_RCPP && !R_CMD - if (p == pchnodata) Rcpp::Rcout << "Found patch NA in valid habitat cell." << std::endl; - else Rcpp::Rcout << "Found negative patch ID in valid habitat cell." << std::endl; - #endif - hfile.close(); hfile.clear(); - pfile.close(); pfile.clear(); - return 34; - } - else { - patchChgMatrix[y][x][2] = p; - if (p > 0 && !existsPatch(p)) { - addPatchNum(p); - newPatch(pchseq++,p); - } - } - } - if (costs) { - if (c < 1) { // invalid cost - hfile.close(); hfile.clear(); - if (pfile.is_open()) { - pfile.close(); pfile.clear(); - } - return 38; - } - else { - costsChgMatrix[y][x][2] = c; - } - } - } - } - } -#if RS_RCPP - hfile >> hfloat; - if (!hfile.eof()) EOFerrorR("habitatchgfile"); - if (patchModel) - { - pfile >> pfloat; - if (!pfile.eof()) EOFerrorR("patchchgfile"); - } - if (costs) - { - cfile >> cfloat; - if (!cfile.eof()) EOFerrorR("costchgfile"); - } -#endif - break; - -default: - break; -} - -if (hfile.is_open()) { hfile.close(); hfile.clear(); } -if (pfile.is_open()) { pfile.close(); pfile.clear(); } -if (cfile.is_open()) { cfile.close(); cfile.clear(); } -return 0; - -} - -// Create & initialise patch change matrix -void Landscape::createPatchChgMatrix(void) -{ -intptr patch; -Patch *pPatch; -Cell *pCell; -if (patchChgMatrix != 0) deletePatchChgMatrix(); -patchChgMatrix = new int **[dimY]; -for(int y = dimY-1; y >= 0; y--){ - patchChgMatrix[y] = new int *[dimX]; - for (int x = 0; x < dimX; x++) { - patchChgMatrix[y][x] = new int [3]; - pCell = findCell(x,y); - if (pCell == 0) { // no-data cell - patchChgMatrix[y][x][0] = patchChgMatrix[y][x][1] = 0; - } - else { - // record initial patch number - patch = pCell->getPatch(); - if (patch == 0) { // matrix cell - patchChgMatrix[y][x][0] = patchChgMatrix[y][x][1] = 0; - } - else { - pPatch = (Patch*)patch; - patchChgMatrix[y][x][0] = patchChgMatrix[y][x][1] = pPatch->getPatchNum(); - } - } - patchChgMatrix[y][x][2] = 0; -#if RSDEBUG -//DebugGUI(("Landscape::createPatchChgMatrix(): y=" + Int2Str(y) -// + " x=" + Int2Str(x) -// + " patchChgMatrix[y][x][0]=" + Int2Str(patchChgMatrix[y][x][0]) -// + " [1]=" + Int2Str(patchChgMatrix[y][x][1]) -// + " [2]=" + Int2Str(patchChgMatrix[y][x][2]) -// ).c_str()); -#endif - } -} -} - -void Landscape::recordPatchChanges(int landIx) { -if (patchChgMatrix == 0) return; // should not occur -patchChange chg; - -for(int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - if (landIx == 0) { // reset to original landscape - if (patchChgMatrix[y][x][0] != patchChgMatrix[y][x][2]) { - // record change of patch for current cell - chg.chgnum = 666666; chg.x = x; chg.y = y; - chg.oldpatch = patchChgMatrix[y][x][2]; - chg.newpatch = patchChgMatrix[y][x][0]; - patchchanges.push_back(chg); -#if RSDEBUG -//DebugGUI(("Landscape::recordPatchChanges(): landIx=" + Int2Str(landIx) -// + " chg.chgnum=" + Int2Str(chg.chgnum) -// + " chg.x=" + Int2Str(chg.x) -// + " chg.y=" + Int2Str(chg.y) -// + " chg.oldpatch=" + Int2Str(chg.oldpatch) -// + " chg.newpatch=" + Int2Str(chg.newpatch) -// ).c_str()); -#endif - } - } - else { // any other change - if (patchChgMatrix[y][x][2] != patchChgMatrix[y][x][1]) { - // record change of patch for current cell - chg.chgnum = landIx; chg.x = x; chg.y = y; - chg.oldpatch = patchChgMatrix[y][x][1]; - chg.newpatch = patchChgMatrix[y][x][2]; - patchchanges.push_back(chg); -#if RSDEBUG -//DebugGUI(("Landscape::recordPatchChanges(): landIx=" + Int2Str(landIx) -// + " chg.chgnum=" + Int2Str(chg.chgnum) -// + " chg.x=" + Int2Str(chg.x) -// + " chg.y=" + Int2Str(chg.y) -// + " chg.oldpatch=" + Int2Str(chg.oldpatch) -// + " chg.newpatch=" + Int2Str(chg.newpatch) -// ).c_str()); -#endif - } - } - // reset cell for next landscape change - patchChgMatrix[y][x][1] = patchChgMatrix[y][x][2]; - } -} - -} - -int Landscape::numPatchChanges(void) { return (int)patchchanges.size(); } - -patchChange Landscape::getPatchChange(int i) { -patchChange c; c.chgnum = 99999999; c.x = c.y = c.oldpatch = c.newpatch = -1; -if (i >= 0 && i < (int)patchchanges.size()) c = patchchanges[i]; -return c; -} - -void Landscape::deletePatchChgMatrix(void) { -if (patchChgMatrix != 0) { - for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - delete[] patchChgMatrix[y][x]; - } - delete[] patchChgMatrix[y]; - } -} -patchChgMatrix = 0; -} - -// Create & initialise costs change matrix -void Landscape::createCostsChgMatrix(void) -{ -//intptr patch; -//Patch *pPatch; -Cell *pCell; -if (costsChgMatrix != 0) deleteCostsChgMatrix(); -costsChgMatrix = new int **[dimY]; -for(int y = dimY-1; y >= 0; y--){ - costsChgMatrix[y] = new int *[dimX]; - for (int x = 0; x < dimX; x++) { - costsChgMatrix[y][x] = new int [3]; - pCell = findCell(x,y); - if (pCell == 0) { // no-data cell - costsChgMatrix[y][x][0] = costsChgMatrix[y][x][1] = 0; - } - else { - // record initial cost - costsChgMatrix[y][x][0] = costsChgMatrix[y][x][1] = pCell->getCost(); - } - costsChgMatrix[y][x][2] = 0; -#if RSDEBUG -//DebugGUI(("Landscape::createCostsChgMatrix(): y=" + Int2Str(y) -// + " x=" + Int2Str(x) -// + " costsChgMatrix[y][x][0]=" + Int2Str(costsChgMatrix[y][x][0]) -// + " [1]=" + Int2Str(costsChgMatrix[y][x][1]) -// + " [2]=" + Int2Str(costsChgMatrix[y][x][2]) -// ).c_str()); -#endif - } -} -} - -void Landscape::recordCostChanges(int landIx) { -#if RSDEBUG -DEBUGLOG << "Landscape::recordCostChanges(): landIx=" << landIx << endl; -#endif -if (costsChgMatrix == 0) return; // should not occur -costChange chg; - -for(int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - if (landIx == 0) { // reset to original landscape - if (costsChgMatrix[y][x][0] != costsChgMatrix[y][x][2]) { - // record change of cost for current cell - chg.chgnum = 666666; chg.x = x; chg.y = y; - chg.oldcost = costsChgMatrix[y][x][2]; - chg.newcost = costsChgMatrix[y][x][0]; - costschanges.push_back(chg); -#if RSDEBUG -//DebugGUI(("Landscape::recordCostsChanges(): landIx=" + Int2Str(landIx) -// + " chg.chgnum=" + Int2Str(chg.chgnum) -// + " chg.x=" + Int2Str(chg.x) -// + " chg.y=" + Int2Str(chg.y) -// + " chg.oldcost=" + Int2Str(chg.oldcost) -// + " chg.newcost=" + Int2Str(chg.newcost) -// ).c_str()); -#endif - } - } - else { // any other change -#if RSDEBUG -//if (x < 20 && y == 0) { -// DEBUGLOG << "Landscape::recordCostChanges(): x=" << x << " y=" << y -// << " costsChgMatrix[y][x][0]=" << costsChgMatrix[y][x][0] -// << " costsChgMatrix[y][x][1]=" << costsChgMatrix[y][x][1] -// << " costsChgMatrix[y][x][2]=" << costsChgMatrix[y][x][2] -// << endl; -//} -#endif - if (costsChgMatrix[y][x][2] != costsChgMatrix[y][x][1]) { - // record change of cost for current cell - chg.chgnum = landIx; chg.x = x; chg.y = y; - chg.oldcost = costsChgMatrix[y][x][1]; - chg.newcost = costsChgMatrix[y][x][2]; - costschanges.push_back(chg); -#if RSDEBUG -//DebugGUI(("Landscape::recordCostsChanges(): landIx=" + Int2Str(landIx) -// + " chg.chgnum=" + Int2Str(chg.chgnum) -// + " chg.x=" + Int2Str(chg.x) -// + " chg.y=" + Int2Str(chg.y) -// + " chg.oldcost=" + Int2Str(chg.oldcost) -// + " chg.newcost=" + Int2Str(chg.newcost) -// ).c_str()); -#endif - } - } - // reset cell for next landscape change - costsChgMatrix[y][x][1] = costsChgMatrix[y][x][2]; - } -} - -} - -int Landscape::numCostChanges(void) { return (int)costschanges.size(); } - -costChange Landscape::getCostChange(int i) { -costChange c; c.chgnum = 99999999; c.x = c.y = c.oldcost = c.newcost = -1; -if (i >= 0 && i < (int)costschanges.size()) c = costschanges[i]; -return c; -} - -void Landscape::deleteCostsChgMatrix(void) { -if (costsChgMatrix != 0) { - for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - delete[] costsChgMatrix[y][x]; - } - delete[] costsChgMatrix[y]; - } -} -costsChgMatrix = 0; -} - -//--------------------------------------------------------------------------- - -// Species distribution functions - -int Landscape::newDistribution(Species *pSpecies, string distname) { -int readcode; -int ndistns = (int)distns.size(); -distns.push_back(new InitDist(pSpecies)); -readcode = distns[ndistns]->readDistribution(distname); -if (readcode != 0) { // error encountered - // delete the distribution created above - delete distns[ndistns]; - distns.pop_back(); -} -return readcode; -} - -void Landscape::setDistribution(Species *pSpecies,int nInit) { -// WILL NEED TO SELECT DISTRIBUTION FOR CORRECT SPECIES ... -// ... CURRENTLY IT IS THE ONLY ONE -distns[0]->setDistribution(nInit); -} - -// Specified cell match one of the distribution cells to be initialised? -bool Landscape::inInitialDist(Species *pSpecies,locn loc) { -// convert landscape co-ordinates to distribution co-ordinates -locn initloc; -initloc.x = loc.x * resol / spResol; -initloc.y = loc.y * resol / spResol; -// WILL HAVE TO GET CORRECT SPECIES WHEN THERE ARE MULTIPLE SPECIES ... -bool initialise = distns[0]->inInitialDist(initloc); -return initialise; -} - -void Landscape::deleteDistribution(Species *pSpecies) { -// WILL NEED TO SELECT DISTRIBUTION FOR CORRECT SPECIES ... -// ... CURRENTLY IT IS THE ONLY ONE ... -// ... FOR MULTIPLE SPECIES IT MAY BE BETTER TO USE A DYNAMIC ARRAY FOR -// SPECIES DISTRIBUTIONS INDEXED BY SPECIES NUMBER, RATHER THAN A VECTOR -if (distns[0] != 0) delete distns[0]; distns.clear(); -} - -// Return no. of initial distributions -int Landscape::distnCount(void) { -return (int)distns.size(); -} - -int Landscape::distCellCount(int dist) { -return distns[dist]->cellCount(); -} - -// Set a cell in a specified initial distribution (by position in cells vector) -void Landscape::setDistnCell(int dist,int ix,bool init) { -distns[dist]->setDistCell(ix,init); -} - -// Set a cell in a specified initial distribution (by given co-ordinates) -void Landscape::setDistnCell(int dist,locn loc,bool init) { -distns[dist]->setDistCell(loc,init); -} - -// Get the co-ordinates of a specified cell in a specified initial distribution -locn Landscape::getDistnCell(int dist,int ix) { -return distns[dist]->getCell(ix); -} - -// Get the co-ordinates of a specified cell in a specified initial distribution -// Returns negative co-ordinates if the cell is not selected -locn Landscape::getSelectedDistnCell(int dist,int ix) { -return distns[dist]->getSelectedCell(ix); -} - -// Get the dimensions of a specified initial distribution -locn Landscape::getDistnDimensions(int dist) { -return distns[dist]->getDimensions(); -} - -// Reset the distribution for a given species so that all cells are deselected -void Landscape::resetDistribution(Species *pSp) { -// CURRENTLY WORKS FOR FIRST SPECIES ONLY ... -distns[0]->resetDistribution(); -} - -//--------------------------------------------------------------------------- - -// Initialisation cell functions - -int Landscape::initCellCount(void) { -return (int)initcells.size(); -} - -void Landscape::addInitCell(int x,int y) { -initcells.push_back(new DistCell(x,y)); -} - -locn Landscape::getInitCell(int ix) { -return initcells[ix]->getLocn(); -} - -void Landscape::clearInitCells(void) { -int ncells = (int)initcells.size(); -for (int i = 0; i < ncells; i++) { - delete initcells[i]; -} -initcells.clear(); -} - -//--------------------------------------------------------------------------- - -// Read landscape file(s) -// Returns error code or zero if read correctly - -int Landscape::readLandscape(int fileNum,string habfile,string pchfile,string costfile) -{ -// fileNum == 0 for (first) habitat file and optional patch file -// fileNum > 0 for subsequent habitat files under the %cover option - -#if RS_RCPP -wstring header; -#else -string header; -#endif -int h,seq,p,habnodata; -int pchnodata = 0; -int ncols,nrows; -float hfloat,pfloat; -Patch *pPatch; -simParams sim = paramsSim->getSim(); - -if (fileNum < 0) return 19; - -#if RS_RCPP - wifstream hfile; // habitat file input stream - wifstream pfile; // patch file input stream -#else - ifstream hfile; // habitat file input stream - ifstream pfile; // patch file input stream -#endif -initParams init = paramsInit->getInit(); - -// open habitat file and optionally also patch file -#if !RS_RCPP || RSWIN64 -hfile.open(habfile.c_str()); -#else -hfile.open(habfile, std::ios::binary); -if(landraster.utf) { - // apply BOM-sensitive UTF-16 facet - hfile.imbue(std::locale(hfile.getloc(), new std::codecvt_utf16)); -} -#endif -if (!hfile.is_open()) return 11; -if (fileNum == 0) { - if (patchModel) { -#if !RS_RCPP || RSWIN64 - pfile.open(pchfile.c_str()); -#else - pfile.open(pchfile, std::ios::binary); - if(patchraster.utf) { - // apply BOM-sensitive UTF-16 facet - pfile.imbue(std::locale(pfile.getloc(), new std::codecvt_utf16)); - } -#endif - if (!pfile.is_open()) { - hfile.close(); hfile.clear(); - return 12; - } - } -} - -// read landscape data from header records of habitat file -// NB headers of all files have already been compared -double tmpresol; -hfile >> header >> ncols >> header >> nrows >> header >> minEast >> header >> minNorth - >> header >> tmpresol >> header >> habnodata; -resol = (int) tmpresol; - -#if RS_RCPP - if (!hfile.good()) { - // corrupt file stream - StreamErrorR(habfile); - hfile.close(); - hfile.clear(); - if (patchModel) { - pfile.close(); - pfile.clear(); - } - return 131; - } -#endif - -dimX = ncols; dimY = nrows; minX = maxY = 0; maxX = dimX-1; maxY = dimY-1; -if (fileNum == 0) { - // set initialisation limits to landscape limits - init.minSeedX = init.minSeedY = 0; - init.maxSeedX = maxX; init.maxSeedY = maxY; - paramsInit->setInit(init); -} - -if (fileNum == 0) { - if (patchModel) { - for (int i = 0; i < 5; i++) pfile >> header >> pfloat; - pfile >> header >> pchnodata; - } -#if RS_RCPP - if (!pfile.good()) { - // corrupt file stream - StreamErrorR(pchfile); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 135; - } -#endif - setCellArray(); -} - - -// set up bad float values to ensure that valid values are read -float badhfloat = -9.0; if (habnodata == -9) badhfloat = -99.0; -float badpfloat = -9.0; if (pchnodata == -9) badpfloat = -99.0; - -seq = 0; // initial sequential patch landscape -p = 0; // initial patch number for cell-based landscape -// create patch 0 - the matrix patch (even if there is no matrix) -if (fileNum == 0) newPatch(seq++,p++); - -switch (rasterType) { - -case 0: // raster with habitat codes - 100% habitat each cell - if (fileNum > 0) return 19; // error condition - should not occur - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - hfloat = badhfloat; -#if RS_RCPP - if(hfile >> hfloat) { -#else - hfile >> hfloat; -#endif - h = (int)hfloat; - if (patchModel) { - pfloat = badpfloat; -#if RS_RCPP - if(pfile >> pfloat) { -#else - pfile >> pfloat; -#endif - p = (int)pfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(pchfile); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 132; - } -#endif - } -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(habfile); - hfile.close(); - hfile.clear(); - if (patchModel) { - pfile.close(); - pfile.clear(); - } - return 135; - } -#endif - -#if RSDEBUG -//DebugGUI(("Landscape::readLandscape(): x=" + Int2Str(x) + " y=" + Int2Str(y) -// + " h=" + Int2Str(h) + " p=" + Int2Str(p) -//).c_str()); -#endif - if (h == habnodata) - addNewCellToLand(x,y,-1); // add cell only to landscape - else { - - // THERE IS AN ANOMALY HERE - CURRENTLY HABITAT 0 IS OK FOR GUI VERSION BUT - // NOT ALLOWED FOR BATCH VERSION (HABITATS MUST BE 1...n) - // SHOULD WE MAKE THE TWO VERSIONS AGREE? ... - - if (h < 0 || (sim.batchMode && (h < 1 || h > nHabMax))) { - // invalid habitat code - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "Found invalid habitat code." << std::endl; - #endif - hfile.close(); hfile.clear(); - if (patchModel) { - pfile.close(); pfile.clear(); - } - return 13; - } - else { - addHabCode(h); - if (patchModel) { - if (p < 0 || p == pchnodata) { // invalid patch code - #if RS_RCPP && !R_CMD - if (p == pchnodata) Rcpp::Rcout << "Found patch NA in valid habitat cell." << std::endl; - else Rcpp::Rcout << "Found negative patch ID in valid habitat cell." << std::endl; - #endif - hfile.close(); hfile.clear(); - pfile.close(); pfile.clear(); - return 14; - } - if (p == 0) { // cell is in the matrix - addNewCellToPatch(0,x,y,h); - } - else { - if (existsPatch(p)) { - pPatch = findPatch(p); - addNewCellToPatch(pPatch,x,y,h); -// addNewCellToPatch(findPatch(p),x,y,h); - } - else { - pPatch = newPatch(seq++,p); - addNewCellToPatch(pPatch,x,y,h); - } - } - } - else { // cell-based model - // add cell to landscape (patches created later) - addNewCellToLand(x,y,h); - } - } - } - } - } -#if RS_RCPP - hfile >> hfloat; - if (!hfile.eof()) EOFerrorR(habfile); - if (patchModel) - { - pfile >> pfloat; - if (!pfile.eof()) EOFerrorR(pchfile); - } -#endif - break; - -case 1: // multiple % cover - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - hfloat = badhfloat; -#if RS_RCPP - if(hfile >> hfloat) { -#else - hfile >> hfloat; -#endif - h = (int)hfloat; - if (fileNum == 0) { // first habitat cover layer - if (patchModel) { - pfloat = badpfloat; -#if RS_RCPP - if(pfile >> pfloat) { -#else - pfile >> pfloat; -#endif - p = (int)pfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(pchfile); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 135; - } -#endif - } //end if patchmodel - -#if RSDEBUG -//MemoLine(("y=" + Int2Str(y) + " x=" + Int2Str(x) + " hfloat=" + Float2Str(hfloat) -// + " p=" + Int2Str(p)).c_str()); -#endif - if (h == habnodata) { - addNewCellToLand(x,y,-1); // add cell only to landscape - } - else { - if (hfloat < 0.0 || hfloat > 100.0) { // invalid cover score - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "Found invalid habitat cover score." << std::endl; - #endif - hfile.close(); hfile.clear(); - if (patchModel) { - pfile.close(); pfile.clear(); - } - return 17; - } - else { - if (patchModel) { - if (p < 0 || p == pchnodata) { // invalid patch code - #if RS_RCPP && !R_CMD - if (p == pchnodata) Rcpp::Rcout << "Found patch NA in valid habitat cell." << std::endl; - else Rcpp::Rcout << "Found negative patch ID in valid habitat cell." << std::endl; - #endif - hfile.close(); hfile.clear(); - pfile.close(); pfile.clear(); - return 14; - } - if (p == 0) { // cell is in the matrix - addNewCellToPatch(0,x,y,hfloat); - } - else { - if (existsPatch(p)) { - pPatch = findPatch(p); - addNewCellToPatch(pPatch,x,y,hfloat); -// addNewCellToPatch(findPatch(p),x,y,hfloat); - } - else { - pPatch = newPatch(seq++,p); - addNewCellToPatch(pPatch,x,y,hfloat); - } - } - } - else { // cell-based model - // add cell to landscape (patches created later) - addNewCellToLand(x,y,hfloat); - } - } - } - } - else { // additional habitat cover layers - if (h != habnodata) { - if (hfloat < 0.0 || hfloat > 100.0) { // invalid cover score - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "Found invalid habitat cover score." << std::endl; - #endif - hfile.close(); hfile.clear(); - if (patchModel) { - pfile.close(); pfile.clear(); - } - return 17; - } - else { - cells[y][x]->setHabitat(hfloat); - } - } // end of h != habnodata - } -#if RS_RCPP - } else { // couldn't read from hfile - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(habfile); - hfile.close(); - hfile.clear(); - if (patchModel) { - pfile.close(); - pfile.clear(); - } - return 133; - } -#endif - - } - } - habIndexed = true; // habitats are already numbered 1...n in correct order -#if RS_RCPP - hfile >> hfloat; - if (!hfile.eof()) EOFerrorR(habfile); - if (patchModel) - { - pfile >> pfloat; - if (!pfile.eof()) EOFerrorR(pchfile); - } -#endif - break; - -case 2: // habitat quality - if (fileNum > 0) return 19; // error condition - should not occur - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - hfloat = badhfloat; -#if RS_RCPP - if(hfile >> hfloat) { -#else - hfile >> hfloat; -#endif - h = (int)hfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(habfile); - hfile.close(); - hfile.clear(); - if (patchModel) { - pfile.close(); - pfile.clear(); - } - return 134; - } -#endif - if (patchModel) { - pfloat = badpfloat; -#if RS_RCPP - if(pfile >> pfloat) { -#else - pfile >> pfloat; -#endif - p = (int)pfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(pchfile); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 135; - } -#endif - } -#if RSDEBUG -//MemoLine(("y=" + Int2Str(y) + " x=" + Int2Str(x) + " hfloat=" + Float2Str(hfloat) -// + " p=" + Int2Str(p)).c_str()); -#endif - if (h == habnodata) { - addNewCellToLand(x,y,-1); // add cell only to landscape - } - else { - if (hfloat < 0.0 || hfloat > 100.0) { // invalid quality score - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "Found invalid habitat quality score." << std::endl; - #endif - hfile.close(); hfile.clear(); - if (patchModel) { - pfile.close(); pfile.clear(); - } - return 17; - } - else { - if (patchModel) { - if (p < 0 || p == pchnodata) { // invalid patch code - #if RS_RCPP && !R_CMD - if (p == pchnodata) Rcpp::Rcout << "Found patch NA in valid habitat cell." << std::endl; - else Rcpp::Rcout << "Found negative patch ID in valid habitat cell." << std::endl; - #endif - hfile.close(); hfile.clear(); - pfile.close(); pfile.clear(); - return 14; - } - if (p == 0) { // cell is in the matrix - addNewCellToPatch(0,x,y,hfloat); - } - else { - if (existsPatch(p)) { - pPatch = findPatch(p); - addNewCellToPatch(pPatch,x,y,hfloat); -// addNewCellToPatch(findPatch(p),x,y,hfloat); - } - else { - addPatchNum(p); - pPatch = newPatch(seq++,p); - addNewCellToPatch(pPatch,x,y,hfloat); - } - } - } - else { // cell-based model - // add cell to landscape (patches created later) - addNewCellToLand(x,y,hfloat); - } - } - } - } - } -#if RS_RCPP - hfile >> hfloat; - if (!hfile.eof()) EOFerrorR(habfile); - if (patchModel) - { - pfile >> pfloat; - if (!pfile.eof()) EOFerrorR(pchfile); - } -#endif - break; - -default: - break; -} // end switch(rasterType) - -if (hfile.is_open()) { hfile.close(); hfile.clear(); } -if (pfile.is_open()) { pfile.close(); pfile.clear(); } - -if (sim.batchMode) { - if (costfile != "NULL") { - int retcode = readCosts(costfile); - if (retcode < 0) return 54; - } -} - -return 0; - -} - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -int Landscape::readCosts(string fname) -{ - -#if RS_RCPP - wifstream costs; // cost map file input stream -#else - ifstream costs; // cost map file input stream -#endif - -//int hc,maxYcost,maxXcost,NODATACost,hab; -int hc,maxYcost,maxXcost,NODATACost; -float minLongCost, minLatCost; int resolCost; -float fcost; -#if RS_RCPP -wstring header; -#else -string header; -#endif -Cell *pCell; -#if !RS_RCPP -simView v = paramsSim->getViews(); -#endif - -int maxcost = 0; - -#if RSDEBUG -#if BATCH -//DEBUGLOG << "Landscape::readCosts(): fname=" << fname << endl; -#endif -#endif - // open cost file -#if !RS_RCPP || RSWIN64 - costs.open(fname.c_str()); -#else - costs.open(fname, std::ios::binary); - if(costsraster.utf) { - // apply BOM-sensitive UTF-16 facet - costs.imbue(std::locale(costs.getloc(), new std::codecvt_utf16)); - } -#endif -//if (!costs.is_open()) { -// MessageDlg("COSTS IS NOT OPEN!!!!!", -// mtError, TMsgDlgButtons() << mbRetry,0); -//} -//else { -// MessageDlg("Costs is open!", -// mtError, TMsgDlgButtons() << mbRetry,0); -//} -// read headers and check that they correspond to the landscape ones -costs >> header; -#if RS_RCPP - if (!costs.good()) { - // corrupt file stream - StreamErrorR(fname); - costs.close(); - costs.clear(); - return -181; - } - if (header != L"ncols" && header != L"NCOLS") { -#else - if (header != "ncols" && header != "NCOLS") { -#endif -// MessageDlg("The selected file is not a raster.", -// MessageDlg("Header problem in import_CostsLand()", -// mtError, TMsgDlgButtons() << mbRetry,0); - costs.close(); costs.clear(); - return -1; -} -costs >> maxXcost >> header >> maxYcost >> header >> minLongCost; -costs >> header >> minLatCost >> header >> resolCost >> header >> NODATACost; - -#if !RS_RCPP -MemoLine("Loading costs map. Please wait..."); -#endif - -for (int y = maxYcost - 1; y > -1; y--){ - for (int x = 0; x < maxXcost; x++){ -#if RS_RCPP - if(costs >> fcost) { -#else - costs >> fcost; -#endif - hc = (int)fcost; // read as float and convert to int -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(fname); - costs.close(); - costs.clear(); - return -181; - } -#endif - if ( hc < 1 && hc != NODATACost ) { -#if RSDEBUG -#if BATCH -// DEBUGLOG << "Landscape::readCosts(): x=" << x << " y=" << y -// << " fcost=" << fcost << " hc=" << hc -// << endl; -#endif -#endif -#if RS_RCPP && !R_CMD - Rcpp::Rcout << "Cost map my only contain values of 1 or higher, but found " << fcost << "." << endl; -#endif - // error - zero / negative cost not allowed -// MessageDlg("Error in the costs map file : zero or negative cost detected." -// , mtError, TMsgDlgButtons() << mbOK,0); - costs.close(); costs.clear(); - return -999; - } - pCell = findCell(x,y); - if (pCell != 0) { // not no-data cell - pCell->setCost(hc); - if (hc > maxcost) maxcost = hc; - } - } -} -#if RS_RCPP - costs >> fcost; - if (costs.eof()) { - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "Costs map loaded." << endl; - #endif - } - else EOFerrorR(fname); -#else - MemoLine("Costs map loaded."); -#endif - -costs.close(); costs.clear(); - -return maxcost; - -} - -//--------------------------------------------------------------------------- - -rasterdata CheckRasterFile(string fname) -{ -rasterdata r; -string header; -int inint; -ifstream infile; - -r.ok = true; -r.errors = r.ncols = r.nrows = r.cellsize = 0; -r.xllcorner = r.yllcorner = 0.0; - -infile.open(fname.c_str()); -if (infile.is_open()) { - infile >> header >> r.ncols; -#if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " r.ncols=" + Int2Str(r.ncols) - ).c_str()); -#endif - if (header != "ncols" && header != "NCOLS") r.errors++; - infile >> header >> r.nrows; -#if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " r.nrows=" + Int2Str(r.nrows) - ).c_str()); -#endif - if (header != "nrows" && header != "NROWS") r.errors++; - infile >> header >> r.xllcorner; -#if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " r.xllcorner=" + Float2Str(r.xllcorner) - ).c_str()); -#endif - if (header != "xllcorner" && header != "XLLCORNER") r.errors++; - infile >> header >> r.yllcorner; -#if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " r.yllcorner=" + Float2Str(r.yllcorner) - ).c_str()); -#endif - if (header != "yllcorner" && header != "YLLCORNER") r.errors++; - double tmpcellsize; - infile >> header >> tmpcellsize; - r.cellsize = (int) tmpcellsize; -#if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " r.cellsize=" + Int2Str(r.cellsize) - ).c_str()); -#endif - if (header != "cellsize" && header != "CELLSIZE") r.errors++; - infile >> header >> inint; -#if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " inint=" + Int2Str(inint) - ).c_str()); -#endif - if (header != "NODATA_value" && header != "NODATA_VALUE") r.errors++; - infile.close(); - infile.clear(); - if (r.errors > 0) r.ok = false; -} -else { - r.ok = false; r.errors = -111; -} -infile.clear(); - -return r; -} - -//--------------------------------------------------------------------------- - -// Patch connectivity functions - -// Create & initialise connectivity matrix -void Landscape::createConnectMatrix(void) -{ -if (connectMatrix != 0) deleteConnectMatrix(); -int npatches = (int)patches.size(); -#if RSDEBUG -//DEBUGLOG << "Landscape::createConnectMatrix(): npatches=" << npatches << endl; -#endif -connectMatrix = new int *[npatches]; -for (int i = 0; i < npatches; i++) { - connectMatrix[i] = new int[npatches]; - for (int j = 0; j < npatches; j++) connectMatrix[i][j] = 0; -} -} - -// Re-initialise connectivity matrix -void Landscape::resetConnectMatrix(void) -{ -if (connectMatrix != 0) { - int npatches = (int)patches.size(); - for (int i = 0; i < npatches; i++) { - for (int j = 0; j < npatches; j++) connectMatrix[i][j] = 0; - } -} -} - -// Increment connectivity count between two specified patches -void Landscape::incrConnectMatrix(int p0,int p1) { -int npatches = (int)patches.size(); -if (connectMatrix == 0 || p0 < 0 || p0 >= npatches || p1 < 0 || p1 >= npatches) return; -connectMatrix[p0][p1]++; -} - -// Delete connectivity matrix -void Landscape::deleteConnectMatrix(void) -{ -if (connectMatrix != 0) { - int npatches = (int)patches.size(); - for (int j = 0; j < npatches; j++) { - if (connectMatrix[j] != 0) - delete connectMatrix[j]; - } - delete[] connectMatrix; - connectMatrix = 0; -} -} - -// Write connectivity file headers -bool Landscape::outConnectHeaders(int option) -{ -if (option == -999) { // close the file - if (outConnMat.is_open()) outConnMat.close(); - outConnMat.clear(); - return true; -} - -simParams sim = paramsSim->getSim(); - -string name = paramsSim->getDir(2); -if (sim.batchMode) { - name += "Batch" + Int2Str(sim.batchNum) + "_"; - name += "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(landNum); -} -else - name += "Sim" + Int2Str(sim.simulation); -name += "_Connect.txt"; -outConnMat.open(name.c_str()); - -outConnMat << "Rep\tYear\tStartPatch\tEndPatch\tNinds" << endl; - -return outConnMat.is_open(); -} - -#if RS_RCPP -// Write movement paths file headers -void Landscape::outPathsHeaders(int rep, int option) -{ - if (option == -999) { // close the file - if (outMovePaths.is_open()) outMovePaths.close(); - outMovePaths.clear(); - } - if (option == 0) { // open the file and write header - - simParams sim = paramsSim->getSim(); - string name = paramsSim->getDir(2); - if (sim.batchMode) { - name += "Batch" + Int2Str(sim.batchNum) - + "_Sim" + Int2Str(sim.simulation) - + "_Land" + Int2Str(landNum) - + "_Rep" + Int2Str(rep); - } else { - name += "Sim" + Int2Str(sim.simulation) - + "_Rep" + Int2Str(rep); - } - name += "_MovePaths.txt"; - - outMovePaths.open(name.c_str()); - if( outMovePaths.is_open() ){ - outMovePaths << "Year\tIndID\tStep\tx\ty\tStatus" << endl; - }else{ - #if RSDEBUG - DEBUGLOG << "RunModel(): UNABLE TO OPEN MOVEMENT PATHS FILE" << endl; - #endif - outMovePaths.clear(); - } - } -} -#endif - -void Landscape::outConnect(int rep,int yr) -{ -int patchnum0,patchnum1; -int npatches = (int)patches.size(); -int *emigrants = new int[npatches]; // 1D array to hold emigrants from each patch -int *immigrants = new int[npatches]; // 1D array to hold immigrants to each patch - -for (int i = 0; i < npatches; i++) { - emigrants[i] = immigrants[i] = 0; -} - -for (int i = 0; i < npatches; i++) { - patchnum0 = patches[i]->getPatchNum(); - if (patchnum0 != 0) { - for (int j = 0; j < npatches; j++) { - patchnum1 = patches[j]->getPatchNum(); - if (patchnum1 != 0) { - emigrants[i] += connectMatrix[i][j]; - immigrants[j] += connectMatrix[i][j]; - if (connectMatrix[i][j] > 0) { - outConnMat << rep << "\t" << yr - << "\t" << patchnum0 << "\t" << patchnum1 - << "\t" << connectMatrix[i][j] << endl; - } - } - } - } -} - -for (int i = 0; i < npatches; i++) { - patchnum0 = patches[i]->getPatchNum(); - if (patchnum0 != 0) { - if (patches[i]->getK() > 0.0) - { // suitable patch - outConnMat << rep << "\t" << yr - << "\t" << patchnum0 << "\t-999\t" << emigrants[i] << endl; - outConnMat << rep << "\t" << yr - << "\t-999\t" << patchnum0 << "\t" << immigrants[i] << endl; - } - } -} - -delete[] emigrants; -delete[] immigrants; - -} - -//--------------------------------------------------------------------------- - -void Landscape::resetVisits(void) { -for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - if (cells[y][x] != 0) { // not a no-data cell - cells[y][x]->resetVisits(); - } - } -} -} - -// Save SMS path visits map to raster text file -void Landscape::outVisits(int rep, int landNr) { - -string name; -simParams sim = paramsSim->getSim(); - -if (sim.batchMode) { - name = paramsSim->getDir(3) -#if RS_RCPP - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) - + "_Land" + Int2Str(landNr) + "_Rep" + Int2Str(rep) -#else - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) - + "_land" + Int2Str(landNr) + "_rep" + Int2Str(rep) -#endif -// + "_yr" + Int2Str(yr) - + "_Visits.txt"; -} -else { - name = paramsSim->getDir(3) - + "Sim" + Int2Str(sim.simulation) - + "_land" + Int2Str(landNr) + "_rep" + Int2Str(rep) -// + "_yr" + Int2Str(yr) - + "_Visits.txt"; -} -outvisits.open(name.c_str()); - -outvisits << "ncols " << dimX << endl; -outvisits << "nrows " << dimY << endl; -outvisits << "xllcorner " << minEast << endl; -outvisits << "yllcorner " << minNorth << endl; -outvisits << "cellsize " << resol << endl; -outvisits << "NODATA_value -9" << endl; - -for (int y = dimY-1; y >= 0; y--) { -#if RSDEBUG -//DebugGUI(("Landscape::drawLandscape(): y=" + Int2Str(y) -// + " cells[y]=" + Int2Str((int)cells[y])).c_str()); -#endif - for (int x = 0; x < dimX; x++) { - if (cells[y][x] == 0) { // no-data cell - outvisits << "-9 "; - } - else { - outvisits << cells[y][x]->getVisits() << " "; - } - } - outvisits << endl; -} - -outvisits.close(); outvisits.clear(); -} - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- diff --git a/RangeShiftR/src/RScore/Landscape.h b/RangeShiftR/src/RScore/Landscape.h deleted file mode 100644 index a3d974d..0000000 --- a/RangeShiftR/src/RScore/Landscape.h +++ /dev/null @@ -1,567 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Landscape - -Implements the following classes: - -InitDist - Initial species distribution - -Landscape - Landscape grid - -The Landscape is a rectangular array of Cells which are grouped together in -Patches. As far as the user is aware, the Landscape is either patch-based or -cell-based (having no Patches), but internally Patches are always present (they -each comprise only one Cell for a cell-based model). The grain of the Landscape -may be any positive integer, and is nominally in metres. - -The Landscape is either input from one or more text files in ArcGIS raster export -format, or it is generated artificially as a random or fractal binary array (in -which case, it must be cell-based). An input 'real' Landscape may hold within each -Cell either discrete habitat classes, or percent cover of habitat classes, or a -continuous quality index (1 to 100%). - -The Landscape may be dynamic, in which case the user specifies a set of changes -to be applied at certain years during each simulation. The changes may be to -habitat only, patches only (if a patch-based model) or habitats and patches. -Although the changes must be supplied as entire habitat / patch files (which -must match the original Landscape in terms of cell size and extent), internally -they are recorded as lists of dynamic habitat and patch changes. - -The initial species distribution is a rectangular array if distribution cells -(DistCell) covering the same spatial extent at the Landscape. Its grain may be -either that of the Landscape or an integer multiple of it. - -The Landscape can record a list (in the vector initcells) of Cells or Patches -to be intialised, which are specified by the user in FormSeeding. This option is -available in the GUI version only. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 2 December 2021 by Steve Palmer -------------------------------------------------------------------------------*/ - -#ifndef LandscapeH -#define LandscapeH - -//#include -//#include -#include -#include -//#include -//#include -#include - -using namespace std; - -#include "Parameters.h" -#include "Patch.h" -#include "Cell.h" -#include "Species.h" -#include "FractalGenerator.h" -#if RS_RCPP -#include -#if !RSWIN64 -#include -#endif -#include -#endif - -//--------------------------------------------------------------------------- - -// Initial species distribution - -class InitDist{ -public: - InitDist(Species*); - ~InitDist(); - int readDistribution( - string // name of species distribution file - ); - void setDistribution( - int // no. of distribution cells to be initialised (0 for all cells) - ); - void setDistCell( // Set a specified cell (by position in cells vector) - int, // index no. of DistCell in cells vector - bool // value to be set - ); - void setDistCell( // Set a specified cell (by co-ordinates) - locn, // structure holding x (column) and y (row) co-ordinates - bool - ); - bool inInitialDist( // Specified location is within the initial distribution? - locn // structure holding x (column) and y (row) co-ordinates - ); - int cellCount(void); - locn getCell( // Return the co-ordinates of a specified initial distribution cell - int // index no. of DistCell in cells vector - ); - locn getSelectedCell( // Return the co-ordinates of a specified initial distribution - // cell if it has been selected - // otherwise return negative co-ordinates - int // index no. of DistCell in cells vector - ); - locn getDimensions(void); - void resetDistribution(void); - -private: - Species *pSpecies; // pointer to species - int resol; // species distribution cell size (m) - int maxX, maxY; // dimensions - double minEast; // ) real world min co-ordinates - double minNorth; // ) read from raster file - - // list of cells in the initial distribution - // cells MUST be loaded in the sequence ascending x within descending y - std::vector cells; - -}; - - -//--------------------------------------------------------------------------- - -struct landParams { - bool patchModel; bool spDist; bool generated; - bool dynamic; - int landNum; int resol; int spResol; int nHab; int nHabMax; - int dimX,dimY,minX,minY,maxX,maxY; - short rasterType; -}; -struct landData { - int resol; int dimX,dimY,minX,minY,maxX,maxY; -}; -struct genLandParams { - bool fractal; bool continuous; - float minPct,maxPct; float propSuit; float hurst; int maxCells; -}; -struct landPix { - int pix; float gpix; -}; -struct landOrigin { - double minEast; double minNorth; -}; -struct rasterHdr { - bool ok; - int errors,ncols,nrows,cellsize; - double xllcorner,yllcorner; -}; -struct rasterdata { - bool ok; - int errors,ncols,nrows,cellsize; - double xllcorner,yllcorner; -#if RS_RCPP - bool utf; -#endif -}; -struct patchData { - Patch *pPatch; int patchNum,nCells; int x,y; -}; -struct landChange { - int chgnum,chgyear; string habfile,pchfile,costfile; -}; -struct patchChange { - int chgnum, x, y, oldpatch, newpatch; -}; -struct costChange { - int chgnum,x,y,oldcost,newcost; -}; - -class Landscape{ -public: - Landscape(); - ~Landscape(); - void resetLand(void); - - // functions to set and return parameter values - - void setLandParams( - landParams, // structure holding landscape parameters - bool // batch mode - ); - landParams getLandParams(void); - landData getLandData(void); - void setGenLandParams(genLandParams); - genLandParams getGenLandParams(void); - void setLandLimits( - int, // minimum available X - int, // minimum available Y - int, // maximum available X - int // maximum available Y - ); - void resetLandLimits(void); - void setLandPix(landPix); - - landPix getLandPix(void); - void setOrigin(landOrigin); - landOrigin getOrigin(void); - - // functions to handle habitat codes - - bool habitatsIndexed(void); - void listHabCodes(void); - void addHabCode(int); - int findHabCode(int); - int getHabCode(int); - void clearHabitats(void); - void addColour(rgb); - void changeColour(int,rgb); - rgb getColour(int); - int colourCount(void); - - // functions to handle patches and cells - - void setCellArray(void); - void addPatchNum(int); - void generatePatches(void); // create an artificial landscape - void allocatePatches(Species*); // create patches for a cell-based landscape - Patch* newPatch( - int // patch sequential no. (id no. is set to equal sequential no.) - ); - Patch* newPatch( - int, // patch sequential no. - int // patch id no. - ); - void resetPatches(void); - void addNewCellToLand( - int, // x co-ordinate - int, // y co-ordinate - float // habitat quality value - ); - void addNewCellToLand( - int, // x co-ordinate - int, // y co-ordinate - int // habitat class no. - ); - void addCellToPatch( - Cell*, // pointer to Cell - Patch* // pointer to Patch - ); - void addCellToPatch( - Cell*, // pointer to Cell - Patch*, // pointer to Patch - float // habitat quality value - ); - void addCellToPatch( - Cell*, // pointer to Cell - Patch*, // pointer to Patch - int // habitat class no. - ); - void addNewCellToPatch( - Patch*, // pointer to Patch - int, // x co-ordinate - int, // y co-ordinate - int // habitat class no. - ); - void addNewCellToPatch( - Patch*, // pointer to Patch - int, // x co-ordinate - int, // y co-ordinate - float // habitat quality value - ); - patchData getPatchData( - int // index no. of Patch in patches vector - ); - bool existsPatch( - int // Patch id no. - ); - Patch* findPatch( - int // Patch id no. - ); - int checkTotalCover(void); - void resetPatchPopns(void); - void updateCarryingCapacity( - Species*, // pointer to Species - int, // year - short // landscape change index (always zero if not dynamic) - ); - Cell* findCell( - int, // x co-ordinate - int // y co-ordinate - ); - int patchCount(void); - void updateHabitatIndices(void); - void setEnvGradient( - Species*, // pointer to Species - bool // TRUE for initial instance that gradient is set - ); - void setGlobalStoch( - int // no. of years - ); - float getGlobalStoch( - int // year - ); - void updateLocalStoch(void); - void resetCosts(void); - void resetEffCosts(void); - - // functions to handle dynamic changes - - void setDynamicLand(bool); - void addLandChange( - landChange // structure holding landscape change data - ); - int numLandChanges(void); - landChange getLandChange( - short // change number - ); - void deleteLandChanges(void); -#if RS_RCPP && !R_CMD - int readLandChange( - int, // change file number - bool, // change SMS costs? - wifstream&, // habitat file stream - wifstream&, // patch file stream - wifstream&, // cost file stream - int, // habnodata - int, // pchnodata - int // costnodata - ); -#else - int readLandChange( - int, // change file number - bool // change SMS costs? - ); -#endif - void createPatchChgMatrix(void); - void recordPatchChanges(int); - void deletePatchChgMatrix(void); - int numPatchChanges(void); - patchChange getPatchChange( - int // patch change number - ); - void createCostsChgMatrix(void); - void recordCostChanges(int); - void deleteCostsChgMatrix(void); - int numCostChanges(void); - costChange getCostChange( - int // cost change number - ); - - // functions to handle species distributions - - int newDistribution( - Species*, // pointer to Species - string // name of initial distribution file - ); - void setDistribution( - Species*, // pointer to Species - int // no. of distribution squares to initialise - ); - bool inInitialDist( // Specified cell matches one of the distn cells to be initialised? - Species*, // pointer to Species - locn // structure holding co-ordinates of Cell - ); - void deleteDistribution( - Species* // pointer to Species - ); - int distnCount(void); // Return no. of initial distributions in the Landscape - int distCellCount( // Return no. of distribution cells in an initial distribution - int // index no. of InitDist in distns vector - ); - locn getDistnCell( // Get co-ordinates of a specified cell in a specified initial distn - int, // index no. of InitDist in distns vector - int // index no. of DistCell in cells vector - ); - locn getSelectedDistnCell( // Get co-ordinates of a specified cell in a specified initial distn - // Returns negative co-ordinates if the cell is not selected - int, // index no. of InitDist in distns vector - int // index no. of DistCell in cells vector - ); - locn getDistnDimensions( // Get the dimensions of a specified initial distribution - int // index no. of InitDist in distns vector - ); - void setDistnCell( // Set a cell in a specified init distn (by posn in cells vector) - int, // index no. of InitDist in distns vector - int, // index no. of DistCell in cells vector - bool // value to be set - ); - void setDistnCell( // Set a cell in a specified init distn (by given co-ordinates) - int, // index no. of InitDist in distns vector - locn, // structure holding co-ordinates of DistCell - bool // value to be set - ); - void resetDistribution( - Species* // pointer to Species - ); - - // functions to handle initialisation cells - - int initCellCount(void); - void addInitCell( // Create a new DistCell and add to the initcells vector - int, // x co-ordinate - int // y co-ordinate - ); - locn getInitCell( - int // index no. of DistCell in initcells vector - ); - void clearInitCells(void); - - // functions to handle connectivity matrix - - void createConnectMatrix(void); - void resetConnectMatrix(void); - void incrConnectMatrix( - int, // sequential no. of origin Patch - int // sequential no. of settlement Patch - ); - void deleteConnectMatrix(void); - bool outConnectHeaders( // Write connectivity file headers - int // option - set to -999 to close the connectivity file - ); -#if RS_RCPP - void outPathsHeaders(int, int); -#endif - void outConnect( - int, // replicate no. - int // year - ); - - // functions to handle input and output - - int readLandscape( - int, // fileNum == 0 for (first) habitat file and optional patch file - // fileNum > 0 for subsequent habitat files under the %cover option - string, // habitat file name - string, // patch file name - string // cost file name (may be NULL) - ); - void listPatches(void); - int readCosts( - string // costs file name - ); - // the following four functions are implemented for the GUI version only - // in the batch version, they are defined, but empty - void setLandMap(void); - void drawLandscape( - int, // replicate no. - int, // landscape index number (always 0 if landscape is not dynamic) - int // landscape no. - ); - void drawGradient(void); // Draw environmental gradient map - void drawGlobalStoch( // Draw environmental stochasticity time-series - int // no. of years - ); - - void resetVisits(void); - void outVisits(int,int); // save SMS path visits map to raster text file - -private: - bool generated; // artificially generated? - bool patchModel; // - bool spDist; // initial species distribution loaded - bool fractal; // - bool continuous; // - bool dynamic; // landscape changes during simulation - bool habIndexed; // habitat codes have been converted to index numbers - short rasterType; // 0 = habitat codes 1 = % cover 2 = quality 9 = artificial landscape - int landNum; // landscape number - int resol; // cell size (m) - int spResol; // species distribution cell size (m) - int nHab; // no. of habitats - int nHabMax; // max. no. of habitats (used for batch input only) - int dimX,dimY; // dimensions - int minX,minY; // minimum available X and Y co-ordinates - int maxX,maxY; // maximum available X and Y co-ordinates - float minPct,maxPct; // min and max percentage of habitat in a cell - float propSuit; // proportion of suitable cells - float hurst; // Hurst exponent - int maxCells; // max. cells per patch (artificial landscapes) - int pix; // image display ratio - float gpix; // image display ratio for gradient map - double minEast; // ) real world min co-ordinates - double minNorth; // ) read from habitat raster - - // list of cells in the landscape - // cells MUST be loaded in the sequence ascending x within descending y - Cell ***cells; - - // list of patches in the landscape - can be in any sequence - std::vector patches; - - // list of patch numbers in the landscape - std::vector patchnums; - - // list of habitat codes - std::vector habCodes; - - // list of colours for habitat codes - std::vector colours; - - // list of dynamic landscape changes - std::vector landchanges; - std::vector patchchanges; - std::vector costschanges; - - // list of initial individual species distributions - std::vector distns; - - // list of cells to be initialised for ALL species - std::vector initcells; - - // patch connectivity matrix - // indexed by [start patch seq num][end patch seq num] - int **connectMatrix; - - // global environmental stochasticity (epsilon) - float *epsGlobal; // pointer to time-series - - // patch and costs change matrices (temporary - used when reading dynamic landscape) - // indexed by [descending y][x][period] - // where there are three periods, 0=original 1=previous 2=current - int ***patchChgMatrix; - int ***costsChgMatrix; - -}; - -// NOTE: the following function is not a behaviour of Landscape, as it is run by the -// batch routine to check raster files before any Landscape has been initiated -rasterdata CheckRasterFile(string); - -extern paramGrad *paramsGrad; -extern paramStoch *paramsStoch; -extern paramInit *paramsInit; -extern paramSim *paramsSim; -extern RSrandom *pRandom; - -#if RSDEBUG -extern ofstream DEBUGLOG; -extern void DebugGUI(string); -#endif - -extern void MemoLine(string); - -#if RS_RCPP -extern rasterdata landraster,patchraster,spdistraster,costsraster; -extern void EOFerrorR(string); -extern void StreamErrorR(string); -#endif - -//--------------------------------------------------------------------------- -#endif diff --git a/RangeShiftR/src/RScore/Model.cpp b/RangeShiftR/src/RScore/Model.cpp deleted file mode 100644 index 9f26886..0000000 --- a/RangeShiftR/src/RScore/Model.cpp +++ /dev/null @@ -1,2292 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Model.h" - -ofstream outPar; - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -#if RS_RCPP && !R_CMD -Rcpp::List RunModel(Landscape *pLandscape,int seqsim) -#else -int RunModel(Landscape *pLandscape,int seqsim) -#endif -{ -//int Nsuit,yr,totalInds; -int yr,totalInds; -//float gradval,gradmin,gradmax; -bool filesOK; -//int t0,t1; - -landParams ppLand = pLandscape->getLandParams(); -envGradParams grad = paramsGrad->getGradient(); -envStochParams env = paramsStoch->getStoch(); -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -//emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -initParams init = paramsInit->getInit(); -simParams sim = paramsSim->getSim(); -simView v = paramsSim->getViews(); - -//t0 = time(0); - -#if RSDEBUG -landPix p = pLandscape->getLandPix(); -DEBUGLOG << "RunModel(): reps=" << sim.reps - << " ppLand.nHab=" << ppLand.nHab - << " p.pix=" << p.pix - << endl; -//DEBUGLOG << "RunModel(): random integers:"; -//for (int i = 0; i < 5; i++) { -// int rrrr = pRandom->IRandom(1000,2000); DEBUGLOG << " " << rrrr; -//} -DEBUGLOG << endl; -#endif - -if (!ppLand.generated) { - if (!ppLand.patchModel) { // cell-based landscape - // create patches for suitable cells, adding unsuitable cells to the matrix - // NB this is an overhead here, but is necessary in case the identity of - // suitable habitats has been changed from one simulation to another (GUI or batch) - // substantial time savings may result during simulation in certain landscapes - pLandscape->allocatePatches(pSpecies); - } - pComm = new Community(pLandscape); // set up community - // set up a sub-community associated with each patch (incl. the matrix) - pLandscape->updateCarryingCapacity(pSpecies,0,0); -// if (ppLand.rasterType <= 2 && ppLand.dmgLoaded) -// pLandscape->updateDamageIndices(); - patchData ppp; - int npatches = pLandscape->patchCount(); - for (int i = 0; i < npatches; i++) { - ppp = pLandscape->getPatchData(i); -#if RSDEBUG -//DEBUGLOG << "RunModel(): i = " << i -// << " ppp.pPatch = " << ppp.pPatch << " ppp.patchNum = " << ppp.patchNum -// << endl; -#endif - pComm->addSubComm(ppp.pPatch,ppp.patchNum); // SET UP ALL SUB-COMMUNITIES -// if (i == 0 || ppp.pPatch->getK() > 0.0) { -// // SET UP SUB-COMMUNITY FOR MATRIX PATCH AND ANY PATCH HAVING NON-ZERO CARRYING CAPACITY -// pComm->addSubComm(ppp.pPatch,ppp.patchNum); -// } - } - if (init.seedType == 0 && init.freeType < 2 && init.initFrzYr > 0) { - // restrict available landscape to initialised region - pLandscape->setLandLimits(init.minSeedX,init.minSeedY, - init.maxSeedX,init.maxSeedY); - } - else { - pLandscape->resetLandLimits(); - } -} - -#if RS_RCPP && !R_CMD -Rcpp::List list_outPop; -#endif - -// Loop through replicates -for (int rep = 0; rep < sim.reps; rep++) { -#if RSDEBUG -DEBUGLOG << endl << "RunModel(): starting simulation=" << sim.simulation << " rep=" << rep << endl; -#endif -#if RS_RCPP && !R_CMD - Rcpp::Rcout << endl << "starting replicate " << rep << endl; -#else -#if BATCH - cout << endl << "starting replicate " << rep << endl; -#endif -#endif - - MemoLine(("Running replicate " + Int2Str(rep) + "...").c_str()); - - if (sim.saveVisits && !ppLand.generated) { - pLandscape->resetVisits(); - } - - patchChange patchchange; - costChange costchange; - int npatchchanges = pLandscape->numPatchChanges(); - int ncostchanges = pLandscape->numCostChanges(); - int ixpchchg = 0; - int ixcostchg = 0; -#if RSDEBUG -DEBUGLOG << "RunModel(): npatchchanges=" << npatchchanges << " ncostchanges=" << ncostchanges << endl; -#endif - - if (ppLand.generated) { -#if RSDEBUG -DEBUGLOG << endl << "RunModel(): generating new landscape ..." << endl; -#endif - // delete previous community (if any) - // Note: this must be BEFORE the landscape is reset (as a sub-community accesses - // its corresponding patch upon deletion) - if (pComm != 0) delete pComm; - // generate new cell-based landscape - MemoLine("...generating new landscape..."); - pLandscape->resetLand(); -#if RSDEBUG -DEBUGLOG << "RunModel(): finished resetting landscape" << endl << endl; -#endif - pLandscape->generatePatches(); -//#if VCL - if (v.viewLand || sim.saveMaps) { - pLandscape->setLandMap(); - pLandscape->drawLandscape(rep,0,ppLand.landNum); - } -//#endif -//#if BATCH -// if (sim.saveMaps) { -// pLandscape->drawLandscape(rep,0,ppLand.landNum); -// } -//#endif -#if RSDEBUG -DEBUGLOG << endl << "RunModel(): finished generating patches" << endl; -#endif - pComm = new Community(pLandscape); // set up community - // set up a sub-community associated with each patch (incl. the matrix) -// pLandscape->updateCarryingCapacity(pSpecies,0); - pLandscape->updateCarryingCapacity(pSpecies,0,0); - patchData ppp; - int npatches = pLandscape->patchCount(); -#if RSDEBUG -DEBUGLOG << "RunModel(): patch count is " << npatches << endl; -#endif - for (int i = 0; i < npatches; i++) { - ppp = pLandscape->getPatchData(i); -#if RSDEBUG -//DEBUGLOG << "RunModel(): i = " << i -// << " ppp.pPatch = " << ppp.pPatch << " ppp.patchNum = " << ppp.patchNum -// << endl; -#endif -#if RSWIN64 -#if LINUX_CLUSTER - pComm->addSubComm(ppp.pPatch,ppp.patchNum); // SET UP ALL SUB-COMMUNITIES -#else - SubCommunity *pSubComm = pComm->addSubComm(ppp.pPatch,ppp.patchNum); // SET UP ALL SUB-COMMUNITIES -#endif -// if (ppp.y >= 9995) { -// DEBUGLOG << "RunModel(): i=" << i << " pSubComm=" << pSubComm -// << endl; -// } -#else - pComm->addSubComm(ppp.pPatch,ppp.patchNum); // SET UP ALL SUB-COMMUNITIES -#endif -// if (i == 0 || ppp.pPatch->getK() > 0.0) { -// // SET UP SUB-COMMUNITY FOR MATRIX PATCH AND ANY PATCH HAVING NON-ZERO CARRYING CAPACITY -// pComm->addSubComm(ppp.pPatch,ppp.patchNum); -// } - } - MemoLine("...completed..."); -#if RSDEBUG -DEBUGLOG << endl << "RunModel(): finished generating populations" << endl; -#endif - } - if (init.seedType == 0 && init.freeType < 2 && init.initFrzYr > 0) { - // restrict available landscape to initialised region - pLandscape->setLandLimits(init.minSeedX,init.minSeedY, - init.maxSeedX,init.maxSeedY); - } - else { - pLandscape->resetLandLimits(); - } - - filesOK = true; - if (rep == 0) { - // open output files - if (sim.outRange) { // open Range file - if (!pComm->outRangeHeaders(pSpecies,ppLand.landNum)) { - MemoLine("UNABLE TO OPEN RANGE FILE"); - filesOK = false; - } - } - if (sim.outOccup && sim.reps > 1) - if (!pComm->outOccupancyHeaders(0)) { - MemoLine("UNABLE TO OPEN OCCUPANCY FILE(S)"); - filesOK = false; - } - if (sim.outPop) { - // open Population file - if (!pComm->outPopHeaders(pSpecies,ppLand.landNum)) { - MemoLine("UNABLE TO OPEN POPULATION FILE"); - filesOK = false; - } - } - if (sim.outTraitsCells) - if (!pComm->outTraitsHeaders(pSpecies,ppLand.landNum)) { - MemoLine("UNABLE TO OPEN TRAITS FILE"); - filesOK = false; - } - if (sim.outTraitsRows) - if (!pComm->outTraitsRowsHeaders(pSpecies,ppLand.landNum)) { - MemoLine("UNABLE TO OPEN TRAITS ROWS FILE"); - filesOK = false; - } - if (sim.outConnect && ppLand.patchModel) // open Connectivity file - if (!pLandscape->outConnectHeaders(0)) { - MemoLine("UNABLE TO OPEN CONNECTIVITY FILE"); - filesOK = false; - } - } -#if RSDEBUG -DEBUGLOG << "RunModel(): completed opening output files" << endl; -#endif - if (!filesOK) { -#if RSDEBUG -DEBUGLOG << "RunModel(): PROBLEM - closing output files" << endl; -#endif - // close any files which may be open - if (sim.outRange) { - pComm->outRangeHeaders(pSpecies,-999); - } - if (sim.outOccup && sim.reps > 1) - pComm->outOccupancyHeaders(-999); - if (sim.outPop) { - pComm->outPopHeaders(pSpecies,-999); - } - if (sim.outTraitsCells) - pComm->outTraitsHeaders(pSpecies,-999); - if (sim.outTraitsRows) - pComm->outTraitsRowsHeaders(pSpecies,-999); - if (sim.outConnect && ppLand.patchModel) - pLandscape->outConnectHeaders(-999); -#if RS_RCPP && !R_CMD - return Rcpp::List::create(Rcpp::Named("Errors") = 666); -#else - return 666; -#endif - } - - if (env.stoch && !env.local) { - // create time series in case of global environmental stochasticity - pLandscape->setGlobalStoch(sim.years+1); - } - - if (grad.gradient) { // set up environmental gradient - pLandscape->setEnvGradient(pSpecies,true); - } - - if (sim.outConnect && ppLand.patchModel) - pLandscape->createConnectMatrix(); - - // variables to control dynamic landscape - landChange landChg; landChg.chgnum = 0; landChg.chgyear = 999999; - if (!ppLand.generated && ppLand.dynamic) { - landChg = pLandscape->getLandChange(0); // get first change year - } - - // set up populations in the community - pLandscape->updateCarryingCapacity(pSpecies,0,0); -#if RSDEBUG -DEBUGLOG << "RunModel(): completed updating carrying capacity" << endl; -#endif -// if (init.seedType != 2) { - pComm->initialise(pSpecies,-1); -// } - bool updateland = false; - int landIx = 0; // landscape change index - -#if RSDEBUG -DEBUGLOG << "RunModel(): completed initialisation, rep=" << rep - << " pSpecies=" << pSpecies << endl; -#endif -#if BATCH -#if RS_RCPP && !R_CMD - Rcpp::Rcout << "RunModel(): completed initialisation " << endl; -#else - cout << "RunModel(): completed initialisation " << endl; -#endif -#endif - - // open a new individuals file for each replicate - if (sim.outInds) - pComm->outInds(rep,0,0,ppLand.landNum); - // open a new genetics file for each replicate - if (sim.outGenetics) { - pComm->outGenetics(rep,0,0,ppLand.landNum); - if (!dem.stageStruct && sim.outStartGenetic == 0) { - // write genetic data for initialised individuals of non-strucutred population - pComm->outGenetics(rep,0,0,-1); - } - } -#if RSDEBUG - // output initialised Individuals - if (sim.outInds) - pComm->outInds(rep,-1,-1,-1); -#endif -#if RS_RCPP - // open a new movement paths file for each replicate - if (sim.outPaths) - pLandscape->outPathsHeaders(rep,0); -#endif - - // years loop - MemoLine("...running..."); - for (yr = 0; yr < sim.years; yr++) { -#if RSDEBUG -DEBUGLOG << endl << "RunModel(): starting simulation=" << sim.simulation - << " rep=" << rep << " yr=" << yr << endl; -#endif -#if RS_RCPP && !R_CMD - Rcpp::checkUserInterrupt(); -#endif - bool updateCC = false; - if (yr < 4 - || (yr < 31 && yr%10 == 0) - || (yr < 301 && yr%100 == 0) - || (yr < 3001 && yr%1000 == 0) - || (yr < 30001 && yr%10000 == 0) - || (yr < 300001 && yr%100000 == 0) - || (yr < 3000001 && yr%1000000 == 0) - ) { -#if RS_RCPP && !R_CMD - Rcpp::Rcout << "starting year " << yr << "..." << endl; -#else - cout << "starting year " << yr << endl; -#endif - } - if (init.seedType == 0 && init.freeType < 2) { - // apply any range restrictions - if (yr == init.initFrzYr) { - // release initial frozen range - reset landscape to its full extent - pLandscape->resetLandLimits(); - updateCC = true; - } - if (init.restrictRange) { - if (yr > init.initFrzYr && yr < init.finalFrzYr) { - if ((yr-init.initFrzYr)%init.restrictFreq == 0) { - // apply dynamic range restriction - commStats s = pComm->getStats(); - int minY = s.maxY-init.restrictRows; - if (minY < 0) minY = 0; -#if RSDEBUG -DEBUGLOG << "RunModel(): restriction yr=" << yr - << " s.minY=" << s.minY << " s.maxY=" << s.maxY - << " init.restrictRows=" << init.restrictRows - << " minY=" << minY - << endl; -#endif - pLandscape->setLandLimits(ppLand.minX,minY,ppLand.maxX,ppLand.maxY); - updateCC = true; -#if RSDEBUG -//landData d = pLandscape->getLandData(); -//DEBUGLOG << "RunModel(): landscape yr=" << yr -// << " minX=" << d.minX << " minY=" << d.minY << " maxX=" << d.maxX << " maxY=" << d.maxY -// << endl; -#endif - } - } - if (yr == init.finalFrzYr) { - // apply final range restriction - commStats s = pComm->getStats(); -#if RSDEBUG -DEBUGLOG << "RunModel(): final restriction yr=" << yr - << " s.minY=" << s.minY << " s.maxY=" << s.maxY - << endl; -#endif - pLandscape->setLandLimits(ppLand.minX,s.minY,ppLand.maxX,s.maxY); - updateCC = true; -#if RSDEBUG -//landData d = pLandscape->getLandData(); -//DEBUGLOG << "RunModel(): landscape yr=" << yr -// << " minX=" << d.minX << " minY=" << d.minY << " maxX=" << d.maxX << " maxY=" << d.maxY -// << endl; -#endif - } - } - } - // environmental gradient, stochasticity & local extinction - // or dynamic landscape - updateland = false; - if (env.stoch || grad.gradient || ppLand.dynamic) { - if (grad.shifting && yr > grad.shift_begin && yr < grad.shift_stop) { - paramsGrad->incrOptY(); - pLandscape->setEnvGradient(pSpecies,false); - updateCC = true; - } -#if RSDEBUG -//DEBUGLOG << "RunModel(): yr=" << yr << " shift_begin=" << grad.shift_begin -// << " shift_stop=" << grad.shift_stop << " opt_y=" << grad.opt_y << endl; -#endif - if (env.stoch) { - if (env.local) pLandscape->updateLocalStoch(); - updateCC = true; - } - if (ppLand.dynamic) { -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " landChg.chgnum=" << landChg.chgnum - << " landChg.chgyear=" << landChg.chgyear - << " npatchchanges=" << npatchchanges << " ncostchanges=" << ncostchanges - << " ixpchchg=" << ixpchchg << " ixcostchg=" << ixcostchg - << endl; -#endif - if (yr == landChg.chgyear) { // apply landscape change - landIx = landChg.chgnum; - updateland = updateCC = true; - if (ppLand.patchModel) { // apply any patch changes - Patch *pPatch; - Cell *pCell; - patchchange = pLandscape->getPatchChange(ixpchchg++); - while (patchchange.chgnum <= landIx && ixpchchg <= npatchchanges) { -#if RSDEBUG -//DEBUGLOG << "RunModel(): yr=" << yr << " landIx=" << landIx -// << " npatchchanges=" << npatchchanges << " ixpchchg=" << ixpchchg -// << " patchchange.chgnum=" << patchchange.chgnum -// << " .oldpatch=" << patchchange.oldpatch -// << " .newpatch=" << patchchange.newpatch -// << " .x=" << patchchange.x << " .y=" << patchchange.y -// << endl; -#endif - // move cell from original patch to new patch - pCell = pLandscape->findCell(patchchange.x,patchchange.y); - if (patchchange.oldpatch != 0) { // not matrix - pPatch = pLandscape->findPatch(patchchange.oldpatch); - pPatch->removeCell(pCell); - } - if (patchchange.newpatch == 0) { // matrix - pPatch = 0; - } - else { - pPatch = pLandscape->findPatch(patchchange.newpatch); - pPatch->addCell(pCell,patchchange.x,patchchange.y); - } - pCell->setPatch((intptr)pPatch); - // get next patch change - patchchange = pLandscape->getPatchChange(ixpchchg++); - } - ixpchchg--; - pLandscape->resetPatches(); // reset patch limits - } - if (landChg.costfile != "NULL") { // apply any SMS cost changes -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " landChg.costfile=" << landChg.costfile << endl; -#endif - Cell *pCell; - costchange = pLandscape->getCostChange(ixcostchg++); - while (costchange.chgnum <= landIx && ixcostchg <= ncostchanges) { -#if RSDEBUG -//DEBUGLOG << "RunModel(): yr=" << yr << " landIx=" << landIx -// << " ncostchanges=" << ncostchanges << " ixcostchg=" << ixcostchg -// << " costchange.chgnum=" << costchange.chgnum -// << " .x=" << costchange.x << " .y=" << costchange.y -// << " .oldcost=" << costchange.oldcost -// << " .newcost=" << costchange.newcost -// << endl; -#endif - pCell = pLandscape->findCell(costchange.x,costchange.y); - if (pCell != 0) { - pCell->setCost(costchange.newcost); - } - costchange = pLandscape->getCostChange(ixcostchg++); - } - ixcostchg--; - pLandscape->resetEffCosts(); - } - if (landIx < pLandscape->numLandChanges()) { // get next change - landChg = pLandscape->getLandChange(landIx); - } - else { - landChg.chgyear = 9999999; - } - } - } - } // end of environmental gradient, etc. - - if (updateCC) { - pLandscape->updateCarryingCapacity(pSpecies,yr,landIx); - } - - - if (sim.outConnect && ppLand.patchModel) - pLandscape->resetConnectMatrix(); - - if (ppLand.dynamic && updateland) { -// trfrRules trfr = pSpecies->getTrfr(); - if (trfr.moveModel && trfr.moveType == 1) { // SMS - if (!trfr.costMap) pLandscape->resetCosts(); // in case habitats have changed - } - // apply effects of landscape change to species present in changed patches - pComm->patchChanges(); -#if RS_RCPP - pComm->dispersal(landIx,yr); -#else - pComm->dispersal(landIx); -#endif // RS_RCPP - } - if (init.restrictRange) { - // remove any population from region removed from restricted range - if (yr > init.initFrzYr && yr < init.finalFrzYr) { - if ((yr-init.initFrzYr)%init.restrictFreq == 0) { - pComm->patchChanges(); - } - } - } - - if (init.seedType == 2) { - // add any new initial individuals for the current year - pComm->initialise(pSpecies,yr); - } - - for(int gen = 0; gen < dem.repSeasons; gen++) // generation loop - { -#if RSDEBUG -// TEMPORARY RANDOM STREAM CHECK -//if (yr%1 == 0 && gen == 0) -if (yr%1 == 0) -{ -DEBUGLOG << endl << "RunModel(): start of gen " << gen << " in year " << yr - << " for rep " << rep << " ("; -for (int i = 0; i < 5; i++) { - int rrrr = pRandom->IRandom(1000,2000); - DEBUGLOG << " " << rrrr; -} -DEBUGLOG << " )" << endl; -} -#endif - - if (v.viewPop || (sim.saveMaps && yr%sim.mapInt == 0)) { - if (updateland && gen == 0) { - pLandscape->drawLandscape(rep,landIx,ppLand.landNum); - } - pComm->draw(rep,yr,gen,ppLand.landNum); - } - // Output and pop. visualisation before reproduction - if (v.viewPop || v.viewTraits || sim.outOccup - || sim.outTraitsCells || sim.outTraitsRows || sim.saveMaps) - PreReproductionOutput(pLandscape,pComm,rep,yr,gen); - // for non-structured population, also produce range and population output now - if (!dem.stageStruct && (sim.outRange || sim.outPop)) - RangePopOutput(pComm,rep,yr,gen); -#if RS_RCPP && !R_CMD - if ( sim.ReturnPopRaster && sim.outPop && yr >= sim.outStartPop && yr%sim.outIntPop == 0) { - list_outPop.push_back(pComm->addYearToPopList(rep,yr), "rep" + std::to_string(rep) + "_year" + std::to_string(yr)); - } -#endif - -#if RSDEBUG -//DEBUGLOG << "RunModel(): completed RangePopOutput()" -// << " Total_Size = " << Total_Size << endl; -#endif - - // apply local extinction for generation 0 only - // CHANGED TO *BEFORE* RANGE & POPN OUTPUT PRODUCTION IN v1.1, - // SO THAT NOS. OF JUVENILES BORN CAN BE REPORTED - if (!ppLand.patchModel && gen == 0) { - if (env.localExt) pComm->localExtinction(0); - if (grad.gradient && grad.gradType == 3) pComm->localExtinction(1); - } - - // reproduction - pComm->reproduction(yr); - - if (dem.stageStruct) { - if (sstruct.survival == 0) { // at reproduction - pComm->survival(0,2,1); // survival of all non-juvenile stages - } - } - - // Output and pop. visualisation AFTER reproduction - if (dem.stageStruct && (sim.outRange || sim.outPop)) - RangePopOutput(pComm,rep,yr,gen); - -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed reproduction" << endl; -#endif - - // Dispersal - - pComm->emigration(); -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed emigration" << endl; -#endif -#if RS_RCPP - pComm->dispersal(landIx,yr); -#else - pComm->dispersal(landIx); -#endif // RS_RCPP -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed dispersal" << endl; -#endif - - // survival part 0 - if (dem.stageStruct) { - if (sstruct.survival == 0) { // at reproduction - pComm->survival(0,0,1); // survival of juveniles only - } - if (sstruct.survival == 1) { // between reproduction events - pComm->survival(0,1,1); // survival of all stages - } - if (sstruct.survival == 2) { // annually - pComm->survival(0,1,0); // development only of all stages -// pComm->survival(0,1,0); // development only of all stages - } - } - else { // non-structured population - pComm->survival(0,1,1); - } -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed survival part 0" << endl; -#endif - - - // output Individuals - if (sim.outInds && yr >= sim.outStartInd && yr%sim.outIntInd == 0) - pComm->outInds(rep,yr,gen,-1); - // output Genetics - if (sim.outGenetics && yr >= sim.outStartGenetic && yr%sim.outIntGenetic == 0) - pComm->outGenetics(rep,yr,gen,-1); - - // survival part 1 - if (dem.stageStruct) { -// if (sstruct.survival != 2) { // at reproduction or between reproduction events - pComm->survival(1,0,1); -// } - } - else { // non-structured population - pComm->survival(1,0,1); - } -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed survival part 1" << endl; -#endif - - } // end of the generation loop -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " completed generation loop" << endl; -#endif - - totalInds = pComm->totalInds(); - if (totalInds <= 0) { yr++; break; } - - // Connectivity Matrix - if (sim.outConnect && ppLand.patchModel - && yr >= sim.outStartConn && yr%sim.outIntConn == 0) - pLandscape->outConnect(rep,yr); - - if (dem.stageStruct && sstruct.survival == 2) { // annual survival - all stages - pComm->survival(0,1,2); - pComm->survival(1,0,1); -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " completed annual survival" << endl; -#endif - } - - if (dem.stageStruct) { - pComm->ageIncrement(); // increment age of all individuals - if (sim.outInds && yr >= sim.outStartInd && yr%sim.outIntInd == 0) - pComm->outInds(rep,yr,-1,-1); // list any individuals dying having reached maximum age - pComm->survival(1,0,1); // delete any such individuals -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " completed Age_increment and final survival" << endl; -#endif - totalInds = pComm->totalInds(); - if (totalInds <= 0) { yr++; break; } - } - - } // end of the years loop - - // Final output and popn. visualisation -#if BATCH - if (sim.saveMaps && yr%sim.mapInt == 0) { - if (updateland) { - pLandscape->drawLandscape(rep,landIx,ppLand.landNum); - } - pComm->draw(rep,yr,0,ppLand.landNum); - } -#endif - // produce final summary output - if (v.viewPop || v.viewTraits || sim.outOccup - || sim.outTraitsCells || sim.outTraitsRows || sim.saveMaps) - PreReproductionOutput(pLandscape,pComm,rep,yr,0); - if (sim.outRange || sim.outPop) - RangePopOutput(pComm,rep,yr,0); -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " completed final summary output" << endl; -#endif - - pComm->resetPopns(); - -// if (batchMode) { -// // delete the community of species using the landscape -// pComm->resetPopns(); -// } - - //Reset the gradient optimum - if (grad.gradient) paramsGrad->resetOptY(); - - pLandscape->resetLandLimits(); -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " landIx=" << "reset" - << " npatchchanges=" << npatchchanges << " ncostchanges=" << ncostchanges - << " ixpchchg=" << ixpchchg << " ixcostchg=" << ixcostchg - << endl; -#endif - if (ppLand.patchModel && ppLand.dynamic && ixpchchg > 0) { - // apply any patch changes to reset landscape to original configuration - // (provided that at least one has already occurred) - patchChange patchchange; - Patch *pPatch; - Cell *pCell; - patchchange = pLandscape->getPatchChange(ixpchchg++); - while (patchchange.chgnum <= 666666 && ixpchchg <= npatchchanges) { -#if RSDEBUG -//DEBUGLOG << "RunModel(): yr=" << yr << " landIx=" << "reset" -// << " npatchchanges=" << npatchchanges << " ixpchchg=" << ixpchchg -// << " patchchange.chgnum=" << patchchange.chgnum -// << " .oldpatch=" << patchchange.oldpatch -// << " .newpatch=" << patchchange.newpatch -// << " .x=" << patchchange.x << " .y=" << patchchange.y -// << endl; -#endif - // move cell from original patch to new patch - pCell = pLandscape->findCell(patchchange.x,patchchange.y); - if (patchchange.oldpatch != 0) { // not matrix - pPatch = pLandscape->findPatch(patchchange.oldpatch); - pPatch->removeCell(pCell); - } - if (patchchange.newpatch == 0) { // matrix - pPatch = 0; - } - else { - pPatch = pLandscape->findPatch(patchchange.newpatch); - pPatch->addCell(pCell,patchchange.x,patchchange.y); - } - pCell->setPatch((intptr)pPatch); - // get next patch change - patchchange = pLandscape->getPatchChange(ixpchchg++); - } - ixpchchg--; - pLandscape->resetPatches(); - } - if (ppLand.dynamic) { - trfrRules trfr = pSpecies->getTrfr(); - if (trfr.moveModel && trfr.moveType == 1) { // SMS - if (ixcostchg > 0) { - // apply any cost changes to reset landscape to original configuration - // (provided that at least one has already occurred) - Cell *pCell; - costchange = pLandscape->getCostChange(ixcostchg++); - while (costchange.chgnum <= 666666 && ixcostchg <= ncostchanges) { -#if RSDEBUG -//DEBUGLOG << "RunModel(): yr=" << yr << " landIx=" << landIx -// << " ncostchanges=" << ncostchanges << " ixcostchg=" << ixcostchg -// << " costchange.chgnum=" << costchange.chgnum -// << " .x=" << costchange.x << " .y=" << costchange.y -// << " .oldcost=" << costchange.oldcost -// << " .newcost=" << costchange.newcost -// << endl; -#endif - pCell = pLandscape->findCell(costchange.x,costchange.y); - if (pCell != 0) { - pCell->setCost(costchange.newcost); - } - costchange = pLandscape->getCostChange(ixcostchg++); - } - ixcostchg--; - pLandscape->resetEffCosts(); - } - if (!trfr.costMap) pLandscape->resetCosts(); // in case habitats have changed - } - } -// if (landIx < pLandscape->numLandChanges()) { // get next change -// landChg = pLandscape->getLandChange(landIx); -// } -// else { -// landChg.chgyear = 9999999; -// } -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " completed reset" - << endl; -#endif - - if (sim.outConnect && ppLand.patchModel) - pLandscape->resetConnectMatrix(); // set connectivity matrix to zeroes - - if (sim.outInds) // close Individuals output file - pComm->outInds(rep,0,0,-999); - if (sim.outGenetics) // close Genetics output file - pComm->outGenetics(rep,0,0,-999); - - if (sim.saveVisits) { - pLandscape->outVisits(rep,ppLand.landNum); - pLandscape->resetVisits(); - } - -#if RS_RCPP - if (sim.outPaths) - pLandscape->outPathsHeaders(rep,-999); -#endif -#if RSDEBUG -DEBUGLOG << endl << "RunModel(): finished rep=" << rep << endl; -#endif - -} // end of the replicates loop - -if (sim.outConnect && ppLand.patchModel) { - pLandscape->deleteConnectMatrix(); - pLandscape->outConnectHeaders(-999); // close Connectivity Matrix file -} - -// Occupancy outputs -if (sim.outOccup && sim.reps > 1) { - MemoLine("Writing final occupancy output..."); - pComm->outOccupancy(); - pComm->outOccSuit(v.viewGraph); -// pComm->deleteOccupancy((sim.years/sim.outInt)+1); - pComm->deleteOccupancy((sim.years/sim.outIntOcc)+1); - pComm->outOccupancyHeaders(-999); - MemoLine("...finished"); -} - -if (sim.outRange) { - pComm->outRangeHeaders(pSpecies,-999); // close Range file -} -if (sim.outPop) { - pComm->outPopHeaders(pSpecies,-999); // close Population file -} -if (sim.outTraitsCells) - pComm->outTraitsHeaders(pSpecies,-999); // close Traits file -if (sim.outTraitsRows) - pComm->outTraitsRowsHeaders(pSpecies,-999); // close Traits rows file -// close Individuals & Genetics output files if open -// they can still be open if the simulation was stopped by the user -if (sim.outInds) pComm->outInds(0,0,0,-999); -if (sim.outGenetics) pComm->outGenetics(0,0,0,-999); - -MemoLine("Deleting community..."); -delete pComm; pComm = 0; -MemoLine("...finished"); - -// Write performance data -//t1 = time(0); -//RSlog << "Simulation," << sim.simulation << "," << sim.reps << "," << sim.years -// << "," << t1-t0 << endl; - -#if RS_RCPP && !R_CMD - return list_outPop; -#else - return 0; -#endif - -} - -#if RS_EMBARCADERO || LINUX_CLUSTER || RS_RCPP -// Check whether a specified directory path exists -bool is_directory(const char *pathname) { -struct stat info; -if (stat(pathname, &info) != 0) return false; // path does not exist -if (S_ISDIR(info.st_mode)) return true; -return false; -} -#endif - -//--------------------------------------------------------------------------- -bool CheckDirectory(void) -{ -bool errorfolder = false; - -string subfolder; - -subfolder = paramsSim->getDir(0) + "Inputs"; -const char *inputs = subfolder.c_str(); -if (!is_directory(inputs)) errorfolder = true; -subfolder = paramsSim->getDir(0) + "Outputs"; -const char *outputs = subfolder.c_str(); -if (!is_directory(outputs)) errorfolder = true; -subfolder = paramsSim->getDir(0) + "Output_Maps"; -const char *outputmaps = subfolder.c_str(); -if (!is_directory(outputmaps)) errorfolder = true; - -return errorfolder; -} - -//--------------------------------------------------------------------------- -//For outputs and population visualisations pre-reproduction -void PreReproductionOutput(Landscape *pLand,Community *pComm,int rep,int yr,int gen) -{ -#if RSDEBUG || VCL -landParams ppLand = pLand->getLandParams(); -#endif -simParams sim = paramsSim->getSim(); -simView v = paramsSim->getViews(); - -#if RSDEBUG -DEBUGLOG << "PreReproductionOutput(): 11111 rep=" << rep << " yr=" << yr << " gen=" << gen - << " landNum=" << ppLand.landNum << " maxX=" << ppLand.maxX << " maxY=" << ppLand.maxY - << endl; -DEBUGLOG << "PreReproductionOutput(): 11112 outRange=" << sim.outRange - << " outIntRange=" << sim.outIntRange - << " outPop=" << sim.outPop << " outIntPop=" << sim.outIntPop - << endl; -#endif - -#if RSDEBUG -//DEBUGLOG << "PreReproductionOutput(): 22222 " << endl; -#endif - -//emigCanvas ecanv; -//trfrCanvas tcanv; -traitCanvas tcanv; -//for (int i = 0; i < 6; i++) { -// ecanv.pcanvas[i] = 0; tcanv.pcanvas[i] = 0; -//} -for (int i = 0; i < NTRAITS; i++) { - tcanv.pcanvas[i] = 0; -} - -// trait outputs and visualisation - -if (v.viewTraits) { -// ecanv = SetupEmigCanvas(); -// tcanv = SetupTrfrCanvas(); -// tcanv = SetupTraitCanvas(v.viewGrad); - tcanv = SetupTraitCanvas(); -} - -if (v.viewTraits -|| ((sim.outTraitsCells && yr >= sim.outStartTraitCell && yr%sim.outIntTraitCell == 0) || - (sim.outTraitsRows && yr >= sim.outStartTraitRow && yr%sim.outIntTraitRow == 0))) -{ -// pComm->outTraits(ecanv,tcanv,pSpecies,rep,yr,gen); - pComm->outTraits(tcanv,pSpecies,rep,yr,gen); -} - -#if RSDEBUG -//DEBUGLOG << "PreReproductionOutput(): 33333 " << endl; -#endif - -if (sim.outOccup && yr%sim.outIntOcc == 0 && gen == 0) - pComm->updateOccupancy(yr/sim.outIntOcc,rep); - -#if RSDEBUG -//DEBUGLOG << "PreReproductionOutput(): 88888 " << endl; -#endif - -// Remaining graphical output actions are performed for GUI only - -#if RSDEBUG -//DEBUGLOG << "PreReproductionOutput(): finished " << endl; -#endif -} - -//For outputs and population visualisations pre-reproduction -void RangePopOutput(Community *pComm,int rep,int yr,int gen) -{ -simParams sim = paramsSim->getSim(); - -if (sim.outRange && (yr%sim.outIntRange == 0 || pComm->totalInds() <= 0)) - pComm->outRange(pSpecies,rep,yr,gen); - -if (sim.outPop && yr >= sim.outStartPop && yr%sim.outIntPop == 0) - pComm->outPop(rep,yr,gen); - -} - -//--------------------------------------------------------------------------- -void OutParameters(Landscape *pLandscape) -{ -double k; -//int nrows,ncols,nsexes,nstages; -int nsexes,nstages; - -landParams ppLand = pLandscape->getLandParams(); -genLandParams ppGenLand = pLandscape->getGenLandParams(); -envGradParams grad = paramsGrad->getGradient(); -envStochParams env = paramsStoch->getStoch(); -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -settleRules srules; -settleSteps ssteps; -settleTraits settleDD; -simParams sim = paramsSim->getSim(); - -string name; -if (sim.batchMode) - name = paramsSim->getDir(2) - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) - + "_Land" + Int2Str(ppLand.landNum) + "_Parameters.txt"; -else - name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) + "_Parameters.txt"; -outPar.open(name.c_str()); - -outPar << "RangeShifter 2.0 "; - -#if !RS_RCPP -#if RSWIN64 -outPar << " - 64 bit implementation"; -#else -outPar << " - 32 bit implementation"; -#endif -#endif -outPar << endl; - -outPar << "================ "; - -outPar << " ====================="; -outPar << endl << endl; - -outPar << "BATCH MODE \t"; -if (sim.batchMode) outPar << "yes" << endl; else outPar << "no" << endl; -#if RS_RCPP -outPar << "SEED \t" << RS_random_seed << endl; -#endif -outPar << "REPLICATES \t" << sim.reps << endl; -outPar << "YEARS \t" << sim.years << endl; -outPar << "REPRODUCTIVE SEASONS / YEAR\t" << dem.repSeasons << endl; -if (ppLand.patchModel){ - outPar << "PATCH-BASED MODEL" << endl; - outPar << "No. PATCHES \t" << pLandscape->patchCount()-1 << endl; -} -else - outPar << "CELL-BASED MODEL" << endl; -outPar << "BOUNDARIES \t"; -if (sim.absorbing) outPar << "absorbing" << endl; -else outPar << "reflective" << endl; -outPar << endl; - -outPar << "LANDSCAPE:\t"; -if (ppLand.generated) { - outPar << "artificially generated map" << endl; - outPar << "TYPE: \t"; - if (ppGenLand.continuous) outPar << "continuous \t"; - else outPar << "discrete \t"; - if (ppGenLand.fractal) outPar << "fractal"; - else outPar << "random"; - outPar << endl << "PROPORTION OF SUITABLE HABITAT (p)\t" << ppGenLand.propSuit <numLandChanges(); - for (int i = 0; i < nchanges; i++) { - chg = pLandscape->getLandChange(i); - outPar << "Change no. " << chg.chgnum << " in year " << chg.chgyear << endl; - outPar << "Landscape: " << chg.habfile << endl; - if (ppLand.patchModel) { - outPar << "Patches : " << chg.pchfile << endl; - } - if (chg.costfile != "none" && chg.costfile != "NULL") { - outPar << "Costs : " << chg.costfile << endl; - } -// outPar << "Change no. " << chg.chgnum << " in year " << chg.chgyear -// << " habitat map: " << chg.habfile << endl; - } -} - -outPar << endl << "SPECIES DISTRIBUTION LOADED: \t"; -//if (sim.initDistLoaded) -if (ppLand.spDist) -{ - outPar << "yes" << endl; - outPar << "RESOLUTION (m)\t" << ppLand.spResol << endl; - outPar << "FILE NAME: "; -#if !RS_RCPP - if (sim.batchMode) outPar << " (see batch file) " << landFile << endl; - else { - outPar << distnmapname << endl; - } -#else - outPar << name_sp_dist << endl; -#endif -} -else outPar << "no" << endl; - -outPar << endl << "ENVIRONMENTAL GRADIENT:\t "; -if (grad.gradient) -{ - switch (grad.gradType) { - case 1: - if (dem.stageStruct) outPar << "Density dependence strength (1/b)" << endl; - else outPar << "Carrying capacity (K)" << endl; - break; - case 2: - if (dem.stageStruct) outPar << "Fecundity" << endl; - else outPar << "Intrinsic growth rate (r)" << endl; - break; - case 3: - outPar << "Local extinction probability" << endl; - break; - default: - outPar << "ERROR ERROR ERROR" << endl; - ; - } - outPar << "G:\t\t " << grad.grad_inc << endl; - outPar << "optimum Y:\t " << grad.opt_y << endl; - outPar << "f:\t\t " << grad.factor << endl; - if (grad.gradType == 3) outPar << "Local extinction prob. at optimum:\t " - << grad.extProbOpt << endl; - outPar << "GRADIENT SHIFTING:\t "; - if (grad.shifting) - { - outPar << "yes" << endl; - outPar << "SHIFTING RATE (rows/year):\t " << grad.shift_rate << endl; - outPar << "SHIFTING START (year):\t\t " << grad.shift_begin << endl; - outPar << "SHIFTING STOP (year):\t\t " << grad.shift_stop << endl; - } - else outPar << "no" << endl; -} -else outPar << "no"; -outPar << endl; -outPar << "ENVIRONMENTAL STOCHASTICITY:\t"; -if (env.stoch) { - outPar << "yes" << endl; - outPar << "TYPE\t in "; - if (dem.stageStruct) { - if (env.inK) outPar << "1/b" << endl; - else outPar << "fecundity" << endl; - } - else{ - if (env.inK) outPar << "K" << endl; - else outPar << "R" << endl; - } - outPar << "SPATIAL AUTOCORRELATION\t "; - if (env.local) outPar << "local" << endl; - else outPar << "global" << endl; - outPar << "TEMPORAL AUTOCORRELATION (ac)\t" << env.ac << endl; - outPar << "AMPLITUDE (std)\t" << env.std << endl; - if (dem.stageStruct) { - if (env.inK) { - outPar << "MIN. 1/b\t" << pSpecies->getMinMax(0) - * (10000.0/(float)(ppLand.resol*ppLand.resol)) << endl; - outPar << "MAX. 1/b\t" << pSpecies->getMinMax(1) - * (10000.0/(float)(ppLand.resol*ppLand.resol)) << endl; - } - else { - outPar << "MIN. fecundity\t" << pSpecies->getMinMax(0) << endl; - outPar << "MAX. fecundity\t" << pSpecies->getMinMax(1) << endl; - } - } - else { - if (env.inK) { - outPar << "MIN. K\t" << pSpecies->getMinMax(0) - * (10000.0/(float)(ppLand.resol*ppLand.resol)) << endl; - outPar << "MAX. K\t" << pSpecies->getMinMax(1) - * (10000.0/(float)(ppLand.resol*ppLand.resol)) << endl; - } - else { - outPar << "MIN. r\t" << pSpecies->getMinMax(0) << endl; - outPar << "MAX. r\t" << pSpecies->getMinMax(1) << endl; - } - } -} -else outPar << "no" << endl; -outPar << "LOCAL EXTINCTION PROBABILITY:\t"; -if (env.localExt) outPar << env.locExtProb << endl; -else outPar << "0.0" << endl; - -outPar << endl << "SPECIES' PARAMETERS." << endl; -outPar << "REPRODUCTION:" << endl; -outPar << "TYPE: "; -switch (dem.repType) { - case 0: - outPar << "Asexual / Only female model" << endl; - break; - case 1: - outPar << "Sexual model (simple)"; - outPar << endl; - outPar << "PROP. of MALES\t" << dem.propMales << endl; - break; - case 2: - outPar << "Sexual model (explicit mating system)" << endl; - outPar << "PROP. of MALES\t" << dem.propMales << endl; - outPar << "MAX. HAREM SIZE (h)\t" << dem.harem << endl; - break; -} -outPar << "STAGE STRUCTURE:\t"; -if (dem.stageStruct){ - outPar << "yes" << endl; - outPar << "PROBABILITY OF REPRODUCING IN SUBSEQUENT SEASONS\t" << sstruct.probRep << endl; - outPar << "No. OF REP. SEASONS BEFORE SUBSEQUENT REPRODUCTIONS\t" << sstruct.repInterval << endl; - if (!ppLand.generated && ppLand.dynamic) { - outPar << "ACTION AFTER POPULATION DESTRUCTION: all individuals "; - if (sstruct.disperseOnLoss) outPar << "disperse" << endl; - else outPar << "die" << endl; - } - outPar << "No. STAGES\t" << sstruct.nStages << endl; - outPar << "MAX. AGE\t" << sstruct.maxAge << endl; - // no sex-specific demographic parameters - if (dem.repType != 2) { - outPar << "MIN. AGES:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage\t" << i << ":\t" << pSpecies->getMinAge(i,0) << "\tyears"<< endl; - } - outPar << "FECUNDITIES:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage\t" << i << ":\t" << pSpecies->getFec(i,0) << endl; - } - outPar << "DEVELOPMENT PROB.:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage\t" << i << ":\t" << pSpecies->getDev(i,0) << endl; - } - outPar << "SURVIVAL PROB.:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage\t" << i << ":\t" << pSpecies->getSurv(i,0) << endl; - } - } - // sex-specific demographic parameters - else { - outPar << "MIN. AGES:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "males " << i << ":\t" << pSpecies->getMinAge(i,1) << " years;\t"; - outPar << "females " << i << ":\t" << pSpecies->getMinAge(i,0) << " years" << endl; - } - outPar << "FECUNDITIES:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "males " << i << ":\t" << pSpecies->getFec(i,1) << endl; - outPar << "females " << i << ":\t" << pSpecies->getFec(i,0) << endl; - } - outPar << "DEVELOPMENT PROB.:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "males " << i << ":\t" << pSpecies->getDev(i,1) << endl; - outPar << "females " << i << ":\t" << pSpecies->getDev(i,0) << endl; - } - outPar << "SURVIVAL PROB.:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "males " << i << ":\t" << pSpecies->getSurv(i,1) << endl; - outPar << "females " << i << ":\t" << pSpecies->getSurv(i,0) << endl; - } - } -/* -#if RSDEBUG - outPar << endl << "TRANSITION MATRIX AS ENTERED:" << endl; - if (batchMode) { - DEBUGLOG << "outParameters(): matrix = " << matrix - << " matrix[1][1] = " << matrix[1][1] - << endl; - if (dem.repType == 2) { - nrows = sstruct.nStages*2-1; ncols = sstruct.nStages*2; - } - else { - nrows = sstruct.nStages; ncols = sstruct.nStages; - } - for (int i = 0; i < nrows; i++) { - for (int j = 0; j < ncols; j++) { - outPar << matrix[j][i] << "\t"; - } - outPar << endl; - } - } -#if VCL - else { - - // NOTE: TO PREVENT COMPILING FOR BATCH MODE, THIS CODE NEEDS TO BE INCLUDED IN COMPILER - // CONDITIONAL BLOCK AS SHOWN - -// outPar << "Row count: " << frmSpecies->transMatrix->RowCount << endl; -// outPar << "Col count: " << frmSpecies->transMatrix->ColCount << endl; - for (int i = 1; i < frmSpecies->transMatrix->RowCount; i++) { - for (int j = 1; j < frmSpecies->transMatrix->ColCount; j++) { - outPar << frmSpecies->transMatrix->Cells[j][i].ToDouble() << "\t"; - } - outPar << endl; - } - } -#endif - outPar << endl; -#endif -*/ - - outPar << "SCHEDULING OF SURVIVAL: "; - switch (sstruct.survival) { - case 0: - outPar << "At reproduction" << endl; - break; - case 1: - outPar << "Between reproductive events" << endl; - break; - case 2: - outPar << "Annually" << endl; - break; - } - - int mSize; // index for weights matrices - if (dem.repType == 2) mSize = sstruct.nStages * NSEXES; - else mSize = sstruct.nStages; - - outPar << "DENSITY-DEPENDENCE IN FECUNDITY:\t"; - if (sstruct.fecDens) { - outPar << "yes" << endl; - if (sstruct.fecStageDens) { - outPar << "STAGE'S WEIGHTS:" << endl; - for (int i = 0; i < mSize; i++) { - if (dem.repType == 2) { - outPar << "stage " << i/NSEXES << " "; - if (i%NSEXES == 0) outPar << "males : \t"; - else outPar << "females: \t"; - } - else outPar << "stage " << i << ": \t"; - for (int j = 0; j < mSize; j++) outPar << pSpecies->getDDwtFec(j,i) << "\t"; - outPar << endl; - } - } - else outPar << "not stage-dependent" << endl; - } - else outPar << "no" << endl; - - densDepParams ddparams = pSpecies->getDensDep(); - - outPar << "DENSITY-DEPENDENCE IN DEVELOPMENT:\t"; - if (sstruct.devDens) { - outPar << "yes - coefficient: " << ddparams.devCoeff << endl; - if (sstruct.devStageDens) { - outPar << "STAGE'S WEIGHTS:" << endl; - for (int i = 0; i < mSize; i++) { - if (dem.repType == 2) { - outPar << "stage " << i/NSEXES << " "; - if (i%NSEXES == 0) outPar << "males : \t"; - else outPar << "females: \t"; - } - else outPar << "stage " << i << ": \t"; - for (int j = 0; j < mSize; j++) outPar << pSpecies->getDDwtDev(j,i) << "\t"; - outPar << endl; - } - } - else outPar << "not stage-dependent" << endl; - } - else outPar << "no" << endl; - - outPar << "DENSITY-DEPENDENCE IN SURVIVAL:\t\t"; - if (sstruct.survDens) { - outPar << "yes - coefficient: " << ddparams.survCoeff << endl; - if (sstruct.survStageDens) { - outPar << "STAGE'S WEIGHTS:" << endl; - for (int i = 0; i < mSize; i++) { - if (dem.repType == 2) { - outPar << "stage " << i/NSEXES << " "; - if (i%NSEXES == 0) outPar << "males : \t"; - else outPar << "females: \t"; - } - else outPar << "stage " << i << ": \t"; - for (int j = 0; j < mSize; j++) outPar << pSpecies->getDDwtSurv(j,i) << "\t"; - outPar << endl; - } - } - else outPar << "not stage-dependent" << endl; - } - else outPar << "no" << endl; -} // end of if (dem.stageStruct) -else { // not stage-strutured - outPar << "no" << endl; - outPar << "Rmax\t" << dem.lambda << endl; - outPar << "bc\t" << dem.bc << endl; -} - -if (dem.stageStruct) { - outPar << endl << "HABITAT SPECIFIC 1/b:" << endl; -} -else { - outPar << endl << "CARRYING CAPACITIES:" << endl; -} -int nhab = ppLand.nHab; -if (ppLand.generated) { - if (ppGenLand.continuous) nhab = 1; -} -for (int i = 0; i < nhab; i++) { - k = pSpecies->getHabK(i) * (10000.0/(float)(ppLand.resol*ppLand.resol)); - if (!ppLand.generated && ppLand.rasterType == 0) { // imported & habitat codes - outPar << "Habitat " << pLandscape->getHabCode(i) << ": \t"; - } - else { - outPar << "Habitat " << i << ": "; - } - if (dem.stageStruct) outPar << "1/b "; - else outPar << "K "; - outPar << k << endl; -} - -emigTraits ep0,ep1; -emigParams eparams0,eparams1; -string sexdept = "SEX-DEPENDENT: "; -string stgdept = "STAGE-DEPENDENT: "; -string indvar = "INDIVIDUAL VARIABILITY: "; -string emigstage = "EMIGRATION STAGE: "; - -outPar << endl << "DISPERSAL - EMIGRATION:\t"; -if (emig.densDep) { - outPar << "density-dependent" << endl; - - if (emig.sexDep) { - outPar << sexdept << "yes" << endl; - if (emig.stgDep) { - outPar << stgdept << "yes" << endl; - outPar << indvar << "no" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage " << i << ":" << endl; - ep0 = pSpecies->getEmigTraits(i,0); - ep1 = pSpecies->getEmigTraits(i,1); - outPar << "D0: females "<< ep0.d0 << " males " << ep1.d0 << endl; - outPar << "alpha: females "<< ep0.alpha << " males " << ep1.alpha << endl; - outPar << "beta: females "<< ep0.beta << " males " << ep1.beta << endl; - } - } - else { // !emig.stgDep - outPar << stgdept << "no" << endl; - outPar << indvar; - if (emig.indVar) { - eparams0 = pSpecies->getEmigParams(0,0); - eparams1 = pSpecies->getEmigParams(0,1); - outPar << "yes" << endl; - if (dem.stageStruct) { - outPar << emigstage << emig.emigStage << endl; - } - outPar << "D0 females: mean " << eparams0.d0Mean << " s.d. " << eparams0.d0SD - << " scaling factor " << eparams0.d0Scale << endl; - outPar << "D0 males: mean " << eparams1.d0Mean << " s.d. " << eparams1.d0SD - << " scaling factor " << eparams1.d0Scale << endl; - outPar << "Alpha females: mean " << eparams0.alphaMean << " s.d. " << eparams0.alphaSD - << " scaling factor " << eparams0.alphaScale << endl; - outPar << "Alpha males: mean " << eparams1.alphaMean << " s.d. " << eparams1.alphaSD - << " scaling factor " << eparams1.alphaScale << endl; - outPar << "Beta females: mean " << eparams0.betaMean << " s.d. " << eparams0.betaSD - << " scaling factor " << eparams0.betaScale << endl; - outPar << "Beta males: mean " << eparams1.betaMean << " s.d. " << eparams1.betaSD - << " scaling factor " << eparams1.betaScale << endl; - } - else { - outPar << "no" << endl; - ep0 = pSpecies->getEmigTraits(0,0); - ep1 = pSpecies->getEmigTraits(0,1); - outPar << "D0: females "<< ep0.d0 << " males " << ep1.d0 << endl; - outPar << "alpha: females "<< ep0.alpha << " males " << ep1.alpha << endl; - outPar << "beta: females "<< ep0.beta << " males " << ep1.beta << endl; - } - } - } - else { // !emig.sexDep - outPar << sexdept << "no" << endl; - if (emig.stgDep) { - outPar << stgdept << "yes" << endl; - outPar << indvar << "no" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - ep0 = pSpecies->getEmigTraits(i,0); - outPar << "stage " << i << ": \t" << "D0: " << ep0.d0; - outPar<< " \talpha: " << ep0.alpha << " \tbeta: " << ep0.beta << endl; - } - } - else { // !emig.stgDep - outPar << stgdept << "no" << endl; - outPar << indvar; - if (emig.indVar) { - eparams0 = pSpecies->getEmigParams(0,0); - emigScales scale = pSpecies->getEmigScales(); - outPar << "yes" << endl; - if (dem.stageStruct) { - outPar << emigstage << emig.emigStage << endl; - } - outPar << "D0 mean: " << eparams0.d0Mean << " s.d.: " << eparams0.d0SD - << " scaling factor: " << scale.d0Scale << endl; - outPar << "Alpha mean: " << eparams0.alphaMean << " s.d.: " << eparams0.alphaSD - << " scaling factor: " << scale.alphaScale << endl; - outPar << "Beta mean: " << eparams0.betaMean << " s.d.: " << eparams0.betaSD - << " scaling factor: " << scale.betaScale << endl; - } - else{ - outPar << "no" << endl; - ep0 = pSpecies->getEmigTraits(0,0); - outPar << "D0: " << ep0.d0 << endl; - outPar << "alpha: " << ep0.alpha << endl; - outPar << "beta: " << ep0.beta << endl; - } - } - } -} -else { // not density-dependent - string initprob = "INITIAL EMIGRATION PROB. "; - outPar << "density-independent" << endl; - if (!trfr.moveModel) { // transfer by kernel - outPar << "USE FULL KERNEL TO DETERMINE EMIGRATION: "; - if (pSpecies->useFullKernel()) outPar << "yes"; - else outPar << "no"; - outPar << endl; - } - - if (emig.sexDep) { - outPar << sexdept << "yes" << endl; - if (emig.stgDep) { - outPar << stgdept << "yes" << endl; - outPar << indvar << "no" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage " << i << ": \t" << "EMIGRATION PROB.: \tfemales " - << pSpecies->getEmigD0(i,0) <<" \tmales "<< pSpecies->getEmigD0(i,1) << endl; - } - } - else { // !emig.stgDep - outPar << stgdept << "no" << endl; - outPar << indvar; - if (emig.indVar) { - eparams0 = pSpecies->getEmigParams(0,0); - eparams1 = pSpecies->getEmigParams(0,1); - emigScales scale = pSpecies->getEmigScales(); - outPar << "yes" << endl; - if (dem.stageStruct) { - outPar << emigstage << emig.emigStage << endl; - } - outPar << initprob << "mean: " << "females " << eparams0.d0Mean - << " males " << eparams1.d0Mean << endl; - outPar << initprob << "s.d.: " << "females " << eparams0.d0SD - << " males " << eparams1.d0SD << endl; - outPar << initprob << "scaling factor: " << scale.d0Scale - << endl; - } - else{ - outPar << "no" << endl; - outPar << "EMIGRATION PROB.: \tfemales "<< pSpecies->getEmigD0(0,0) - <<"\t males " << pSpecies->getEmigD0(0,1) << endl; - } - } - } - else { // !emig.sexDep - outPar << sexdept << "no" << endl; - if (emig.stgDep) { - outPar << stgdept << "yes" << endl; - outPar << indvar << "no" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage " << i << ": \t" << "EMIGRATION PROB.: " - << pSpecies->getEmigD0(i,0) << endl; - } - } - else { // !emig.stgDep - outPar << stgdept << "no" << endl; - outPar << indvar; - if (emig.indVar) { - eparams0 = pSpecies->getEmigParams(0,0); - emigScales scale = pSpecies->getEmigScales(); - outPar << "yes" << endl; - if (dem.stageStruct) { - outPar << emigstage << emig.emigStage << endl; - } - outPar << initprob << "mean: " << eparams0.d0Mean << endl; - outPar << initprob << "s.d.: " << eparams0.d0SD << endl; - outPar << initprob << "scaling factor: " << scale.d0Scale << endl; - } - else { - outPar << "no" << endl; - outPar << "EMIGRATION PROB.:\t" << pSpecies->getEmigD0(0,0) << endl; - } - } - } -} - -// Transfer - -outPar << endl << "DISPERSAL - TRANSFER: \t"; - -if (trfr.moveModel) { - bool straigtenPath; - if (trfr.moveType == 1) { // SMS - trfrSMSTraits move = pSpecies->getSMSTraits(); - straigtenPath = move.straigtenPath; - if (trfr.costMap) { - outPar << "SMS\tcosts from imported cost map" << endl; -#if !RS_RCPP - outPar << "FILE NAME: " << costmapname << endl; -#endif - } - else { - outPar << "SMS\tcosts:" << endl; - if (!ppLand.generated && ppLand.rasterType == 0) { - for (int i = 0; i < ppLand.nHab; i++) - outPar << "\thab. " << pLandscape->getHabCode(i) << "\t" - << pSpecies->getHabCost(i) << endl; - } - else { - for (int i = 0; i < ppLand.nHab; i++) - outPar << "\thab. " << i << "\t" - << pSpecies->getHabCost(i) << endl; - } - } - string pr = "PERCEPTUAL RANGE"; - outPar << pr << ": " << move.pr << endl; - outPar << pr << " METHOD: " << move.prMethod << endl; - if (!trfr.indVar) outPar << "DIRECTIONAL PERSISTENCE: " << move.dp << endl; - outPar << "MEMORY SIZE: " << move.memSize << endl; - //if (!trfr.indVar) outPar << "GOAL BIAS: " << move.gb << endl; - outPar << "GOAL TYPE: " << move.goalType << endl; - if (!trfr.indVar) { - if (move.goalType == 2) { // dispersal bias - outPar << "GOAL BIAS: " << move.gb << endl; - outPar << "ALPHA DB: " << move.alphaDB << endl; - outPar << "BETA DB: " << move.betaDB << endl; - } - } - if (trfr.indVar) { - trfrSMSParams s = pSpecies->getSMSParams(0,0); - outPar << indvar << "yes " << endl; - outPar << "DP mean: " << s.dpMean << " s.d.: " << s.dpSD - << " scaling factor: " << s.dpScale << endl; - outPar << "GB mean: " << s.gbMean << " s.d.: " << s.gbSD - << " scaling factor: " << s.gbScale << endl; - if (move.goalType == 2) { // dispersal bias - outPar << "Alpha DB mean: " << s.alphaDBMean << " s.d.: " << s.alphaDBSD - << " scaling factor: " << s.alphaDBScale << endl; - outPar << "Beta DB mean: " << s.betaDBMean << " s.d.: " << s.betaDBSD - << " scaling factor: " << s.betaDBScale << endl; - } - } - else { - outPar << indvar << "no " << endl; - } - } - else { // CRW - trfrCRWTraits move = pSpecies->getCRWTraits(); - straigtenPath = move.straigtenPath; - outPar << "CRW" << endl; - string lgth = "STEP LENGTH (m) "; - string corr = "STEP CORRELATION"; - if (trfr.indVar) { - trfrCRWParams m = pSpecies->getCRWParams(0,0); - outPar << indvar << "yes" << endl; - outPar << lgth << " mean: " << m.stepLgthMean; - outPar << " s.d.: " << m.stepLgthSD; - outPar << " scaling factor: " << m.stepLScale << endl; - outPar << corr << " mean: " << m.rhoMean; - outPar << " s.d.: " << m.rhoSD; - outPar << " scaling factor: " << m.rhoScale << endl; - } - else { - outPar << indvar << "no" << endl; - outPar << lgth << ": " << move.stepLength << endl; - outPar << corr << ": " << move.rho << endl; - } - } - outPar << "STRAIGHTEN PATH AFTER DECISION NOT TO SETTLE: "; - if (straigtenPath) outPar << "yes" << endl; - else outPar << "no" << endl; - outPar << "STEP MORTALITY:\t" << endl; - if (trfr.habMort) - { - outPar << "habitat dependent:\t" << endl; - if (!ppLand.generated && ppLand.rasterType == 0) { - for (int i = 0; i < ppLand.nHab; i++) - outPar << "\thab. " << pLandscape->getHabCode(i) << "\t" - << pSpecies->getHabMort(i) << endl; - } - else{ - for (int i = 0; i < ppLand.nHab; i++) - outPar << "\thab. " << i << "\t" - << pSpecies->getHabMort(i) << endl; - } - } - else - { - trfrCRWTraits move = pSpecies->getCRWTraits(); - outPar << "constant " << move.stepMort << endl; - } -} // end of movement process -else { // kernel - string meandist = "MEAN DISTANCE"; - string probkern = "PROB. KERNEL I"; - trfrKernTraits kern0,kern1; - trfrKernParams k0,k1; - outPar << "dispersal kernel" << endl << "TYPE: \t"; - if (trfr.twinKern) outPar << "double "; - outPar << "negative exponential" << endl; - - if (trfr.sexDep) { - outPar << sexdept << "yes" << endl; - if (trfr.stgDep) { - outPar << stgdept << "yes" << endl; - outPar << indvar << "no" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage " << i << ":" << endl; - kern0 = pSpecies->getKernTraits(i,0); - kern1 = pSpecies->getKernTraits(i,1); - outPar << meandist << " I: \tfemales "<< kern0.meanDist1 << " \tmales " << kern1.meanDist1 << endl; - if (trfr.twinKern) - { - outPar << meandist << " II: \tfemales "<< kern0.meanDist2 << " \tmales " << kern1.meanDist2 << endl; - outPar << probkern << ": \tfemales "<< kern0.probKern1 << " \tmales " << kern1.probKern1 << endl; - } - } - } - else { // !trfr.stgDep - outPar << stgdept << "no" << endl; - outPar << indvar; - if (trfr.indVar) { - k0 = pSpecies->getKernParams(0,0); - k1 = pSpecies->getKernParams(0,1); - outPar << "yes" << endl; - outPar << meandist << " I (mean): \tfemales " << k0.dist1Mean - << " \tmales " << k1.dist1Mean << endl; - outPar << meandist << " I (s.d.): \tfemales " << k0.dist1SD - << " \tmales " << k1.dist1SD << endl; - outPar << meandist << " I (scaling factor): \tfemales " << k0.dist1Scale - << " \tmales " << k1.dist1Scale << endl; - if (trfr.twinKern) - { - outPar << meandist << " II (mean): \tfemales " << k0.dist2Mean - << " \tmales " << k1.dist2Mean << endl; - outPar << meandist << " II (s.d.): \tfemales " << k0.dist2SD - << " \tmales " << k1.dist2SD << endl; - outPar << meandist << " II (scaling factor): \tfemales " << k0.dist2Scale - << " \tmales " << k1.dist2Scale << endl; - outPar << probkern << " (mean): \tfemales " << k0.PKern1Mean - << " \tmales " << k1.PKern1Mean << endl; - outPar << probkern << " (s.d.): \tfemales " << k0.PKern1SD - << " \tmales " << k1.PKern1SD << endl; - outPar << probkern << " (scaling factor): \tfemales " << k0.PKern1Scale - << " \tmales " << k1.PKern1Scale << endl; - } - } - else { - outPar << "no" << endl; - kern0 = pSpecies->getKernTraits(0,0); - kern1 = pSpecies->getKernTraits(0,1); - outPar << meandist << " I: \tfemales "<< kern0.meanDist1 << " \tmales " << kern1.meanDist1 << endl; - if (trfr.twinKern) - { - outPar << meandist << " II: \tfemales "<< kern0.meanDist2 << " \tmales " << kern1.meanDist2 << endl; - outPar << probkern << ": \tfemales "<< kern0.probKern1 << " \tmales " << kern1.probKern1 << endl; - } - } - } - } - else { // !trfr.sexDep - outPar << sexdept << "no" << endl; - if (trfr.stgDep) { - outPar << stgdept << "yes" << endl; - outPar << indvar << "no" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - kern0 = pSpecies->getKernTraits(i,0); - outPar << "stage " << i << ": \t" << meandist << " I: " << kern0.meanDist1; - if (trfr.twinKern) - { - outPar << " \t" << meandist << " II: " << kern0.meanDist2; - outPar << " \t" << probkern << ": " << kern0.probKern1; - } - outPar << endl; - } - } - else { // !trfr.stgDep - outPar << stgdept << "no" << endl; - outPar << indvar; - if (trfr.indVar) { - k0 = pSpecies->getKernParams(0,0); - outPar << "yes" << endl; - outPar << meandist << " I (mean): " << k0.dist1Mean - << " \t(s.d.): " << k0.dist1SD - << " \t(scaling factor): " << k0.dist1Scale << endl; - if (trfr.twinKern) - { - outPar << meandist << " II (mean): " << k0.dist2Mean - << " \t(s.d.): " << k0.dist2SD - << " \t(scaling factor): " << k0.dist2Scale << endl; - outPar << probkern << " (mean): " << k0.PKern1Mean - << " \t(s.d.): " << k0.PKern1SD - << " \t(scaling factor): " << k0.PKern1Scale << endl; - } - } - else{ - outPar << "no" << endl; - kern0 = pSpecies->getKernTraits(0,0); - outPar << meandist << " I: \t" << kern0.meanDist1 <getMortParams(); - if (trfr.distMort) { - outPar << "distance-dependent" << endl; - outPar << "SLOPE: " << mort.mortAlpha << " \tINFLECTION POINT: " << mort.mortBeta << endl; - } - else { - outPar << "constant" << endl << "MORTALITY PROBABILITY: " << mort.fixedMort << endl; - } -} // end of kernel transfer - -// Settlement - -outPar << endl << "DISPERSAL - SETTLEMENT:" << endl; - -if (trfr.moveModel) { - string plusmating = "+ mating requirements"; - ssteps = pSpecies->getSteps(0,0); - - outPar << "MIN. No. OF STEPS:\t " << ssteps.minSteps << endl; - outPar << "MAX. No. OF STEPS:\t "; - if (ssteps.maxSteps == 99999999) outPar << "not applied" << endl; - else outPar << ssteps.maxSteps << endl; - - if (sett.sexDep) { - nsexes = 2; - outPar << sexdept << "yes" << endl; - if (sett.stgDep) { - nstages = sstruct.nStages; - outPar << stgdept << "yes" << endl; - } - else { // !sett.stgDep - nstages = 1; - outPar << stgdept << "no" << endl; - } - } - else { // !sett.sexDep - nsexes = 1; - outPar << sexdept << "no" << endl; - if (sett.stgDep) { - nstages = sstruct.nStages; - outPar << stgdept << "yes" << endl; - } - else { // !sett.stgDep - nstages = 1; - outPar << stgdept << "no" << endl; - } - } - for (int sx = 0; sx < nsexes; sx++) { - if (sett.sexDep) { - if (sx == 0) outPar << "FEMALES:" << endl; - else outPar << "MALES:" << endl; - } - outPar << "SETTLE IF: "; - for (int i = 0; i < nstages; i++) { - if (dem.stageStruct && nstages > 1) outPar << "stage " << i << ": " << endl; - outPar << "find a suitable cell/patch "; - srules = pSpecies->getSettRules(i,sx); - if (srules.densDep) { - settleDD = pSpecies->getSettTraits(i,sx); - outPar << "+ density dependence "; - if (srules.findMate) outPar << plusmating; - outPar << endl; - if (!sett.indVar) { - outPar << "S0: " << settleDD.s0 << " AlphaS: " << settleDD.alpha - << " BetaS: " << settleDD.beta << endl; - } - } - else { - if (srules.findMate) outPar << plusmating << endl; - else outPar << "(not the natal one)" << endl; - } - if (dem.stageStruct) { - ssteps = pSpecies->getSteps(i,sx); - outPar << "MAX. No. OF STEPS/YEAR:\t "; - if (ssteps.maxStepsYr == 99999999) outPar << "not applied" << endl; - else outPar << ssteps.maxStepsYr << endl; - } - } - } - if (sett.indVar) { - settParams sparams0; - outPar << "DENSITY DEPENDENCE + " << indvar << "yes" << endl; - for (int sex = 0; sex < nsexes; sex++) { - if (sett.sexDep) { - if (sex == 0) outPar << "FEMALES:" << endl; - else outPar << "MALES:" << endl; - } - sparams0 = pSpecies->getSettParams(0,sex); - settScales scale = pSpecies->getSettScales(); - outPar << "S0 - mean: " << sparams0.s0Mean << " s.d.: " << sparams0.s0SD - << " scaling factor: " << scale.s0Scale << endl; - outPar << "AlphaS - mean: " << sparams0.alphaSMean << " s.d.: " << sparams0.alphaSSD - << " scaling factor: " << scale.alphaSScale << endl; - outPar << "BetaS - mean: " << sparams0.betaSMean << " s.d.: " << sparams0.betaSSD - << " scaling factor: " << scale.betaSScale << endl; - } - } -} -else { // kernel-based transfer - string notsuit = "IF THE ARRIVAL CELL/PATCH IS UNSUITABLE: "; - string rchoose = " randomly choose a suitable neighb. cell/patch or "; - string matereq = "MATING REQUIREMENTS: "; - if (sett.sexDep) { - nsexes = 2; - outPar << sexdept << "yes" << endl; - if (sett.stgDep) { - nstages = sstruct.nStages; - outPar << stgdept << "yes" << endl; - outPar << notsuit << endl; - } - else { - nstages = 1; - outPar << stgdept << "no" << endl; - } - } - else { - nsexes = 1; - outPar << sexdept << "no" << endl; - if (sett.stgDep) { - nstages = sstruct.nStages; - outPar << stgdept << "yes" << endl; - outPar << notsuit << endl; - } - else { - nstages = 1; - outPar << stgdept << "no" << endl; - outPar << notsuit; - } - } - for (int i = 0; i < nstages; i++) { - if (sett.stgDep) { - outPar << "stage " << i << ":" << endl; - } - for (int sx = 0; sx < nsexes; sx++) { - if (sett.sexDep) { - if (sx == 0) outPar << "FEMALES: "; - else outPar << "MALES: "; - if (!sett.stgDep) outPar << notsuit; - } - srules = pSpecies->getSettRules(i,sx); - if (srules.go2nbrLocn) { - outPar << rchoose; - if (srules.wait) outPar << "wait" << endl; - else outPar << "die" << endl; - } - else { - if (srules.wait) outPar << "wait" << endl; - else outPar << "die" << endl; - } - outPar << matereq; - if (srules.findMate) outPar << "yes" <getNTraits(); -outPar << "No. of variable traits: " << nspptraits << endl; - -genomeData d = pSpecies->getGenomeData(); -if (emig.indVar || trfr.indVar || sett.indVar || d.neutralMarkers) -{ - if (d.diploid) outPar << "DIPLOID" << endl; else outPar << "HAPLOID" << endl; - int nchromosomes = pSpecies->getNChromosomes(); - outPar << "No. of chromosomes: " << nchromosomes; - if (d.trait1Chromosome) { - outPar << endl << "No. of loci/chromosome: " << d.nLoci << endl; - } - else { - outPar << " (chrom:loci)"; - for (int i = 0; i < nchromosomes; i++) { - outPar << " " << i << ":" << pSpecies->getNLoci(i); - } - outPar << endl; - } - outPar << "Mutation probability: " << d.probMutn << endl; - outPar << "Crossover probability: " << d.probCrossover << endl; - outPar << "Initial allele s.d.: " << d.alleleSD << endl; - outPar << "Mutation s.d.: " << d.mutationSD << endl; - if (d.neutralMarkers) { - outPar << "NEUTRAL MARKERS ONLY" << endl; - } - else { - if (!d.trait1Chromosome) { - traitAllele allele; - outPar << "TRAIT MAPPING:" << endl; - outPar << "Architecture file: " << genfilename << endl; - int ntraitmaps = pSpecies->getNTraitMaps(); - outPar << "No. of traits defined: " << ntraitmaps << endl; - for (int i = 0; i < ntraitmaps; i++) { - int nalleles = pSpecies->getNTraitAlleles(i); - outPar << "Trait " << i << ": (" << pSpecies->getTraitName(i) - << ") alleles: " << nalleles << " (chrom:locus)"; - for (int j = 0; j < nalleles; j++) { - allele = pSpecies->getTraitAllele(i,j); - outPar << " " << allele.chromo << ":" << allele.locus; - } - outPar << endl; - } - if (ntraitmaps < nspptraits) { // list undefined traits - outPar << "WARNING - the following traits were not defined" - << " in the genetic architecture file:" << endl; - for (int i = ntraitmaps; i < nspptraits; i++) { - outPar << "Trait " << i << ": (" << pSpecies->getTraitName(i) - << ") all individuals have mean phenotype" << endl; - } - } - int nneutral = pSpecies->getNNeutralLoci(); - if (nneutral > 0) { - outPar << "Neutral loci: " << nneutral << " (chrom:locus)"; - for (int i = 0; i < nneutral; i++) { - allele = pSpecies->getNeutralAllele(i); - outPar << " " << allele.chromo << ":" << allele.locus; - } - outPar << endl; - } - if (d.pleiotropic) - outPar << "Genome exhibits pleiotropy" << endl; - } - } -} - -// Initialisation - -initParams init = paramsInit->getInit(); -outPar << endl << "INITIALISATION CONDITIONS:" << endl; -switch (init.seedType) { -case 0: - outPar << "Free initialisation: \t" ; - switch (init.freeType) { - case 0: - outPar << "Random \t" ; - outPar << "No. of cells/patches: " << init.nSeedPatches << endl; - break; - case 1: - outPar << "all suitable cells/patches" << endl; - break; - case 2: - outPar << "manually selected cells/patches" << endl; - break; - } - break; -case 1: - outPar << "From species distribution: \t" << endl; - switch (init.spDistType) { - case 0: - outPar << "all presence cells/patches" << endl; - break; - case 1: - outPar << "some random presence cells/patches" << endl; - break; - case 2: - outPar << "all cells/patches within selected distribution cells" << endl; - break; - } - break; -case 2: - outPar << "From initial individuals file: " << paramsSim->getDir(1) + init.indsFile << endl; - break; -case 3: - outPar << "From file" << endl; - break; -} -if (init.seedType != 2) { - outPar << "INITIAL NO. OF INDIVIDUALS: \t"; - switch (init.initDens) { - case 0: - outPar << "at carrying capacity" << endl; - break; - case 1: - outPar << "at half carrying capacity" << endl; - break; - case 2: - if (ppLand.patchModel) { - outPar << init.indsHa << " individuals per ha" << endl; - } - else { - outPar << init.indsCell << " individuals per cell" << endl; - } - break; - } - if (dem.stageStruct) { - outPar << "INITIAL STAGE PROPORTIONS:" << endl; - for (int i = 1; i < sstruct.nStages; i++) { - outPar << "stage " << i << ": " << paramsInit->getProp(i) << " \t"; - } - outPar << endl; - outPar << "Initial age distribution: "; - switch (init.initAge) { - case 0: - outPar << "lowest possible age"; - break; - case 1: - outPar << "randomised"; - break; - case 2: - outPar << "quasi-equilibrium"; - break; - } - outPar << endl; - } - outPar << "GEOGRAPHICAL CONSTRAINTS (cell numbers): " << endl; - outPar << "min X: " << init.minSeedX << " max X: " << init.maxSeedX << endl; - outPar << "min Y: " << init.minSeedY << " max Y: " << init.maxSeedY << endl; -// if (init.seedType != 1 && init.freeType < 2 && init.initFrzYr > 0) { -// outPar << "Freeze initial range until year " << init.initFrzYr << endl; -// } - if (init.seedType == 0 && init.freeType < 2) { - if (init.initFrzYr > 0) { - outPar << "Freeze initial range until year " << init.initFrzYr << endl; - } - if (init.restrictRange) { - outPar << "Restrict range to northern " << init.restrictRows - << " rows every " << init.restrictFreq << " years" << endl; - if (init.finalFrzYr < sim.years) { - outPar << "Freeze range at year " << init.finalFrzYr << endl; - } - } - } -} - -outPar << endl << "OUTPUTS:" << endl; -if (sim.outRange) { - outPar << "Range - every " << sim.outIntRange << " year"; - if (sim.outIntRange > 1) outPar << "s"; -// if (sim.outStartRange > 0) outPar << " starting year " << sim.outStartRange; - outPar << endl; -} -if (sim.outOccup) { - outPar << "Occupancy - every " << sim.outIntOcc << " year"; - if (sim.outIntOcc > 1) outPar << "s"; -// if (sim.outStartOcc > 0) outPar << " starting year " << sim.outStartOcc; - outPar << endl; -} -if (sim.outPop) { - outPar << "Populations - every " << sim.outIntPop << " year"; - if (sim.outIntPop > 1) outPar << "s"; - if (sim.outStartPop > 0) outPar << " starting year " << sim.outStartPop; - outPar << endl; -} -if (sim.outInds) { - outPar << "Individuals - every " << sim.outIntInd << " year"; - if (sim.outIntInd > 1) outPar << "s"; - if (sim.outStartInd > 0) outPar << " starting year " << sim.outStartInd; - outPar << endl; -} -if (sim.outGenetics) { - outPar << "Genetics - every " << sim.outIntGenetic << " year"; - if (sim.outIntGenetic > 1) outPar << "s"; - if (sim.outStartGenetic > 0) outPar << " starting year " << sim.outStartGenetic; - if (dem.stageStruct) { - switch (sim.outGenType) { - case 0: - outPar << " - juveniles only"; - break; - case 1: - outPar << " - all individuals"; - break; - case 2: - outPar << " - adults only"; - break; - } - } - if (sim.outGenXtab) outPar << " (as cross table)"; - outPar << endl; -} - -if (sim.outTraitsCells) { - outPar << "Traits per "; - if (ppLand.patchModel) outPar << "patch"; else outPar << "cell"; - outPar << " - every " << sim.outIntTraitCell << " year"; - if (sim.outIntTraitCell > 1) outPar << "s"; - if (sim.outStartTraitCell > 0) outPar << " starting year " << sim.outStartTraitCell; - outPar << endl; -} -if (sim.outTraitsRows) { - outPar << "Traits per row - every " << sim.outIntTraitRow << " year"; - if (sim.outIntTraitRow > 1) outPar << "s"; - if (sim.outStartTraitRow > 0) outPar << " starting year " << sim.outStartTraitRow; - outPar << endl; -} -if (sim.outConnect) { - outPar << "Connectivity matrix - every " << sim.outIntConn << " year"; - if (sim.outIntConn > 1) outPar << "s"; - if (sim.outStartConn > 0) outPar << " starting year " << sim.outStartConn; - outPar << endl; -} -#if RS_RCPP - if (sim.outPaths) { - outPar << "SMS paths - every " << sim.outIntPaths << " year"; - if (sim.outIntPaths > 1) outPar << "s"; - if (sim.outStartPaths > 0) outPar << " starting year " << sim.outStartPaths; - outPar << endl; - } -#endif -outPar << "SAVE MAPS: "; -if (sim.saveMaps) { - outPar << "yes - every " << sim.mapInt << " year"; - if (sim.mapInt > 1) outPar << "s"; - outPar << endl; -} -else outPar << "no" << endl; -outPar << "SAVE TRAITS MAPS: "; -if (sim.saveTraitMaps) { - outPar << "yes - every " << sim.traitInt << " year"; - if (sim.traitInt > 1) outPar << "s"; - outPar << endl; -} -else outPar << "no" << endl; -if (trfr.moveModel && trfr.moveType == 1) { - outPar << "SMS HEAT MAPS: "; - if (sim.saveVisits) outPar << "yes" << endl; - else outPar << "no" << endl; -} - -outPar.close(); outPar.clear(); - -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- diff --git a/RangeShiftR/src/RScore/Model.h b/RangeShiftR/src/RScore/Model.h deleted file mode 100644 index 4acf37a..0000000 --- a/RangeShiftR/src/RScore/Model.h +++ /dev/null @@ -1,149 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Model - -Implements three functions which run the model and produce output common to both -GUI and batch version. - -RunModel() handles looping through replicates, years and generations - -Further functions are declared here, but defined differently in main function of -GUI and batch versions. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 26 October 2021 by Steve Palmer -------------------------------------------------------------------------------*/ - -#ifndef ModelH -#define ModelH - -#include -#include - -//#if RS_RCPP && !R_CMD -#include "../Version.h" -//#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif - -#include "Parameters.h" -#include "Landscape.h" -#include "Community.h" -#include "SubCommunity.h" -#include "Species.h" - -#if !RS_EMBARCADERO && !LINUX_CLUSTER && !RS_RCPP -#include -using namespace std::filesystem; -#endif - -#if RSDEBUG -extern ofstream DEBUGLOG; -#endif - -#if RS_RCPP && !R_CMD -Rcpp::List RunModel( - Landscape*, // pointer to Landscape - int // sequential simulation number (always 0 for VCL version) -); -#else -int RunModel( - Landscape*, // pointer to Landscape - int // sequential simulation number (always 0 for VCL version) -); -#endif // RS_RCPP && !R_CMD -bool CheckDirectory(void); -void PreReproductionOutput( - Landscape*, // pointer to Landscape - Community*, // pointer to Community - int, // replicate - int, // year - int // generation -); -void RangePopOutput( - Community*, // pointer to Community - int, // replicate - int, // year - int // generation -); -void Outputs_Visuals_B( - int, // replicate - int, // year - int, // generation - int // Landscape number -); -void RefreshVisualCost(void); -traitCanvas SetupTraitCanvas(void); -void SetupVisualOutput(void); -void ResetVisualOutput(void); -void DrawPopnGraph( - Community*, // pointer to Community - int // year -); -void OutParameters( - Landscape* // pointer to Landscape -); - -extern paramGrad *paramsGrad; -extern paramStoch *paramsStoch; -extern Species *pSpecies; -extern paramSim *paramsSim; -extern paramInit *paramsInit; -extern Community *pComm; - -const bool batchMode = true; -extern string landFile; -extern vector hfnames; -extern string habmapname; // see FormLand.cpp (VCL) OR Main.cpp (batch) -extern string patchmapname; // see FormLand.cpp (VCL) OR Main.cpp (batch) -extern string distnmapname; // see FormLand.cpp (VCL) OR Main.cpp (batch) -extern string costmapname; // see FormMove.cpp (VCL) OR Main.cpp (batch) -extern string genfilename; // see FormGenetics.cpp (VCL) OR Main.cpp (batch) -extern RSrandom *pRandom; - -// these functions to have different version for GUI and batch applications ... -#if BATCH -extern void MemoLine(string); -#endif -void GUIsetLandScale( - int, // landscape image height (pixels) - int // landscape image width (pixels) -); - -#if RS_RCPP -extern std::uint32_t RS_random_seed; -extern string name_landscape, name_patch, name_costfile, name_sp_dist; -#endif -//--------------------------------------------------------------------------- -#endif diff --git a/RangeShiftR/src/RScore/Parameters.cpp b/RangeShiftR/src/RScore/Parameters.cpp deleted file mode 100644 index b7c6a34..0000000 --- a/RangeShiftR/src/RScore/Parameters.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Parameters.h" -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -// Environmental gradient parameters - -paramGrad::paramGrad(void) { -gradient = false; gradType = 0; grad_inc = 0.05f; -opt_y0 = opt_y = factor = extProbOpt = 0.0; -shifting = false; shift_rate = 0.5; shift_begin = 0; shift_stop = 100; -} - -paramGrad::~paramGrad() { } - -void paramGrad::setGradient(int gtype, float inc, float y, float f, float p) -{ -if (gtype > 0 && gtype < 4) -{ // valid gradient type - gradient = true; gradType = gtype; - if (inc >= 0.0 && inc <= 1.0) grad_inc = inc; - if (y >= 0.0) opt_y0 = opt_y = y; - if (f >= 0.0) factor = f; - if (p > 0.0 && p < 1.0) extProbOpt = p; -} -else { - gradient = false; gradType = 0; -} -} - -void paramGrad::setShifting(float r, int begin, int end) -{ -shifting = true; -if (r > 0.0) shift_rate = r; -if (begin >= 0) shift_begin = begin; -if (end > 0) shift_stop = end; -} - -void paramGrad::noGradient(void) { gradient = false; gradType = 0; } - -void paramGrad::noShifting(void) { shifting = false; } - -envGradParams paramGrad::getGradient(void) { -envGradParams g; -g.gradient = gradient; g.gradType = gradType; g.grad_inc = grad_inc; -g.opt_y = opt_y; g.factor = factor; g.extProbOpt = extProbOpt; -g.shifting = shifting; g.shift_rate = shift_rate; -g.shift_begin = shift_begin; g.shift_stop = shift_stop; -return g; -} - -void paramGrad::incrOptY(void) -{ if (gradient && shifting) opt_y += shift_rate; } - -void paramGrad::resetOptY(void) { opt_y = opt_y0; } - -//--------------------------------------------------------------------------- - -// Environmental stochasticity parameters - -paramStoch::paramStoch(void) { -stoch = false; local = false; inK = false; localExt = false; -ac = 0.0; std = 0.25; -locExtProb = 0.1; -} - -paramStoch::~paramStoch(void) {} - - -void paramStoch::setStoch(envStochParams e) -{ -stoch = e.stoch; local = e.local; inK = e.inK; localExt = e.localExt; -if (e.ac >= 0.0 && e.ac < 1.0) ac = e.ac; -if (e.std > 0.0 && e.std <= 1.0) std = e.std; -locExtProb = e.locExtProb; -} - -bool paramStoch::envStoch(void) { return stoch; } - -envStochParams paramStoch::getStoch(void) -{ -envStochParams e; -e.stoch = stoch; e.local = local; e.inK = inK; e.localExt = localExt; -e.ac = ac; e.std = std; -e.locExtProb = locExtProb; -return e; -} - - -//--------------------------------------------------------------------------- - -// Initialisation (seeding) parameters - -paramInit::paramInit(void) { -seedType = freeType = spDistType = initDens = 0; -initAge = initFrzYr = 0; -restrictRange = false; -restrictRows = 100; -restrictFreq = 10; -finalFrzYr = 99999999; -indsCell = 1; indsHa = 0.0; -minSeedX = 0; maxSeedX = 99999999; minSeedY = 0; maxSeedY = 99999999; -nSeedPatches = 1; nSpDistPatches = 1; -indsFile = "NULL"; -for (int i = 0; i < NSTAGES; i++) { - initProp[i] = 0.0; -} -} - -paramInit::~paramInit(void) { -initinds.clear(); -} - -void paramInit::setInit(initParams i) { -if (i.seedType >= 0 && i.seedType <= 3) seedType = i.seedType; -if (i.freeType >= 0 && i.freeType <= 2) freeType = i.freeType; -if (i.spDistType >= 0 && i.spDistType <= 2) spDistType = i.spDistType; -initDens = i.initDens; -initAge = i.initAge; -if (i.initFrzYr >= 0) initFrzYr = i.initFrzYr; -restrictRange = i.restrictRange; -if (i.restrictRows > 0) restrictRows = i.restrictRows; -if (i.restrictFreq > 0) restrictFreq = i.restrictFreq; -if (i.finalFrzYr > 0) finalFrzYr = i.finalFrzYr; -if (i.indsCell >= 1) indsCell = i.indsCell; -if (i.indsHa > 0.0) indsHa = i.indsHa; -if (i.minSeedX >= 0) minSeedX = i.minSeedX; -if (i.maxSeedX >= 0) maxSeedX = i.maxSeedX; -if (i.minSeedY >= 0) minSeedY = i.minSeedY; -if (i.maxSeedY >= 0) maxSeedY = i.maxSeedY; -if (i.nSeedPatches >= 1) nSeedPatches = i.nSeedPatches; -if (i.nSpDistPatches >= 1) nSpDistPatches = i.nSpDistPatches; -indsFile = i.indsFile; -} - -initParams paramInit::getInit(void) { -initParams i; -i.seedType = seedType; i.freeType = freeType; i.spDistType = spDistType; -i.initDens = initDens; i.initAge = initAge; -i.initFrzYr = initFrzYr; -i.restrictRange = restrictRange; -i.restrictRows = restrictRows; i.restrictFreq = restrictFreq; -i.finalFrzYr = finalFrzYr; -i.indsCell = indsCell; i.indsHa = indsHa; -i.minSeedX = minSeedX; i.minSeedY = minSeedY; -i.maxSeedX = maxSeedX; i.maxSeedY = maxSeedY; -i.nSeedPatches = nSeedPatches; i.nSpDistPatches = nSpDistPatches; -i.indsFile = indsFile; -return i; -} - -void paramInit::setProp(short stg,float p) { -if (stg >= 0 && stg < NSTAGES && p >= 0.0 && p <= 1.0) initProp[stg] = p; -} - -float paramInit::getProp(short stg) { -float p = 0.0; -if (stg >= 0 && stg < NSTAGES) p = initProp[stg]; -return p; -} - -void paramInit::addInitInd(initInd iind) { -#if RSDEBUG -//DebugGUI(("paramInit::addInitInd(): iind.patchID=" + Int2Str(iind.patchID) -// + " iind.x=" + Int2Str(iind.x) -// + " iind.y=" + Int2Str(iind.y) -// ).c_str()); -#endif -initinds.push_back(iind); -} - -initInd paramInit::getInitInd(int ix) { -initInd iind; -if (ix >= 0 && ix < (int)initinds.size()) { - iind = initinds[ix]; -} -else { - iind.year = iind.patchID = iind.x = iind.y = iind.sex = iind.age = iind.stage = 0; - iind.species = -1; -} -#if RSDEBUG -//DEBUGLOG << "paramInit::getInitInd(): ix=" << ix << " size()=" << initinds.size() -// << " iind.patchID=" << iind.patchID -// << " iind.x=" << iind.x -// << " iind.y=" << iind.y -// << endl; -#endif -return iind; -} - -void paramInit::resetInitInds(void) { initinds.clear(); } - -int paramInit::numInitInds(void) { return (int)initinds.size(); } - - -//--------------------------------------------------------------------------- - -// Simulation parameters - -paramSim::paramSim(void) { - simulation = 0; - reps = years = 1; - outIntRange = 1; -// outStartRange = outStartOcc = outStartPop = outStartInd = 0; - outStartPop = outStartInd = outStartGenetic = 0; - outStartTraitCell = outStartTraitRow = outStartConn = 0; - outIntOcc = outIntPop = outIntInd = outIntGenetic = 10; - outIntTraitCell = outIntTraitRow = outIntConn = 10; - mapInt = traitInt = 10; - slowFactor = 1; - batchMode = absorbing = false; - outRange = outOccup = outPop = outInds = false; - outGenetics = outGenXtab = false; outGenType = 0; - outTraitsCells = outTraitsRows = outConnect = false; - saveMaps = false; saveTraitMaps = false; - saveVisits = false; -#if RS_RCPP - outStartPaths = 0; outIntPaths = 0; - outPaths = false; ReturnPopRaster = false; CreatePopFile = true; -#endif - drawLoaded = false; - viewLand = false; viewPatch = false; viewGrad = false; viewCosts = false; - viewPop = false; viewTraits = false; viewPaths = false; viewGraph = false; - dir = ' '; -} - -paramSim::~paramSim(void) { } - -void paramSim::setSim(simParams s) { -if (s.batchNum >= 0) batchNum = s.batchNum; -if (s.simulation >= 0) simulation = s.simulation; -if (s.reps >= 1) reps = s.reps; -if (s.years >= 1) years = s.years; -if (s.mapInt >= 1) mapInt = s.mapInt; -if (s.traitInt >= 1) traitInt = s.traitInt; -batchMode = s.batchMode; absorbing = s.absorbing; -outRange = s.outRange; outOccup = s.outOccup; -outPop = s.outPop; outInds = s.outInds; -outGenetics = s.outGenetics; -if (s.outGenType >= 0 && s.outGenType <= 2) { - outGenType = s.outGenType; -} -outGenXtab = s.outGenXtab; -outTraitsCells = s.outTraitsCells; outTraitsRows = s.outTraitsRows; -outConnect = s.outConnect; -//if (s.outStartRange >= 0) outStartRange = s.outStartRange; -//if (s.outStartOcc >= 0) outStartOcc = s.outStartOcc; -if (s.outStartPop >= 0) outStartPop = s.outStartPop; -if (s.outStartInd >= 0) outStartInd = s.outStartInd; -if (s.outStartGenetic >= 0) outStartGenetic = s.outStartGenetic; -if (s.outStartTraitCell >= 0) outStartTraitCell = s.outStartTraitCell; -if (s.outStartTraitRow >= 0) outStartTraitRow = s.outStartTraitRow; -if (s.outStartConn >= 0) outStartConn = s.outStartConn; -if (s.outIntRange >= 1) outIntRange = s.outIntRange; -if (s.outIntOcc >= 1) outIntOcc = s.outIntOcc; -if (s.outIntPop >= 1) outIntPop = s.outIntPop; -if (s.outIntInd >= 1) outIntInd = s.outIntInd; -if (s.outIntGenetic >= 1) outIntGenetic = s.outIntGenetic; -if (s.outIntTraitCell >= 1) outIntTraitCell = s.outIntTraitCell; -if (s.outIntTraitRow >= 1) outIntTraitRow = s.outIntTraitRow; -if (s.outIntConn >= 1) outIntConn = s.outIntConn; -saveMaps = s.saveMaps; saveTraitMaps = s.saveTraitMaps; -saveVisits = s.saveVisits; -#if RS_RCPP -outStartPaths = s.outStartPaths; -outIntPaths = s.outIntPaths; -outPaths = s.outPaths; -ReturnPopRaster = s.ReturnPopRaster; -CreatePopFile = s.CreatePopFile; -#endif -drawLoaded = s.drawLoaded; -} - -simParams paramSim::getSim(void) { -simParams s; -s.batchNum = batchNum; -s.simulation = simulation; s.reps = reps; s.years = years; -s.outRange = outRange; s.outOccup = outOccup; s.outPop = outPop; s.outInds = outInds; -s.outGenetics = outGenetics; s.outGenType = outGenType; s.outGenXtab = outGenXtab; -s.outTraitsCells = outTraitsCells; s.outTraitsRows = outTraitsRows; s.outConnect = outConnect; -//s.outStartRange = outStartRange; -//s.outStartOcc = outStartOcc; -s.outStartPop = outStartPop; s.outStartInd = outStartInd; s.outStartGenetic = outStartGenetic; -s.outStartTraitCell = outStartTraitCell; s.outStartTraitRow = outStartTraitRow; -s.outStartConn = outStartConn; -s.outIntRange = outIntRange; -s.outIntOcc = outIntOcc; s.outIntPop = outIntPop; -s.outIntInd = outIntInd; s.outIntGenetic = outIntGenetic; -s.outIntTraitCell = outIntTraitCell; -s.outIntTraitRow = outIntTraitRow; -s.outIntConn = outIntConn; -s.batchMode = batchMode; -s.absorbing = absorbing; -s.saveMaps = saveMaps; s.saveTraitMaps = saveTraitMaps; -s.saveVisits = saveVisits; -s.mapInt = mapInt; s.traitInt = traitInt; -#if RS_RCPP -s.outStartPaths = outStartPaths; -s.outIntPaths = outIntPaths; -s.outPaths = outPaths; -s.ReturnPopRaster = ReturnPopRaster; -s.CreatePopFile = CreatePopFile; -#endif -s.drawLoaded = drawLoaded; -return s; -} - -int paramSim::getSimNum(void) { return simulation; } - -void paramSim::setViews(simView v) { -viewLand = v.viewLand; viewPatch = v.viewPatch; -viewGrad = v.viewGrad; viewCosts = v.viewCosts; -viewPop = v.viewPop; viewTraits = v.viewTraits; -viewPaths = v.viewPaths; viewGraph = v.viewGraph; -if (v.slowFactor > 0) slowFactor = v.slowFactor; -} - -simView paramSim::getViews(void) { -simView v; -v.viewLand = viewLand; v.viewPatch = viewPatch; -v.viewGrad = viewGrad; v.viewCosts = viewCosts; -v.viewPop = viewPop; v.viewTraits = viewTraits; -v.viewPaths = viewPaths; v.viewGraph = viewGraph; -v.slowFactor = slowFactor; -return v; -} - -void paramSim::setDir(string s) { -dir = s; -} - -// return directory name depending on option specified -string paramSim::getDir(int option) { -string s; -switch (option) { -case 0: // working directory - s = dir; - break; -#if LINUX_CLUSTER || RS_RCPP -case 1: // Inputs folder - s = dir + "Inputs/"; - break; -case 2: // Outputs folder - s = dir + "Outputs/"; - break; -case 3: // Maps folder - s = dir + "Output_Maps/"; - break; -#else -case 1: // Inputs folder - s = dir + "Inputs\\"; - break; -case 2: // Outputs folder - s = dir + "Outputs\\"; - break; -case 3: // Maps folder - s = dir + "Output_Maps\\"; - break; -#endif -default: - s = "ERROR_ERROR_ERROR"; -} -return s; -} - -#if RS_RCPP -bool paramSim::getReturnPopRaster(void) { return ReturnPopRaster; } -bool paramSim::getCreatePopFile(void) { return CreatePopFile; } -#endif - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - diff --git a/RangeShiftR/src/RScore/Parameters.h b/RangeShiftR/src/RScore/Parameters.h deleted file mode 100644 index d44cf14..0000000 --- a/RangeShiftR/src/RScore/Parameters.h +++ /dev/null @@ -1,393 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Parameters - -Implements the following classes: - -paramGrad - Environmental gradient parameters -paramInit - Initialisation (seeding) parameters -paramSim - Simulation parameters -paramStoch - Environmental stochasticity parameters - -Also declares some structures and functions used throughout the program. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 25 June 2021 by Steve Palmer - -------------------------------------------------------------------------------*/ - -#ifndef ParametersH -#define ParametersH - -//#if LINUX_CLUSTER -//#include -//#else -#include -//#endif -#include -#include -//#include -#include -#include -#include -using namespace std; -//#if RS_RCPP && !R_CMD -#include "../Version.h" -//#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif - -#include "RSrandom.h" - -#define NSTAGES 10 // maximum number of stages permitted -#define NSEXES 2 // maximum number of sexes permitted -#define PARAMDEBUG 0 -#define NTRAITS 18 // maximum number of variable traits which can be displayed - // in GUI (VCL version) -#define NSD 3.0 // no. of s.d. to use to control range for displaying traits - -#if RS_RCPP -typedef intptr_t intptr; -#else -#if RSWIN64 -typedef unsigned long long intptr; -#else -typedef unsigned int intptr; -#endif -#endif - -#if RS_RCPP - #ifndef R_EXT_CONSTANTS_H_ // the R headers define PI as a macro, so that the 'else' line results in an error - #define M_2PI 6.283185307179586 - const double PI = 3.141592653589793238462643383279502884197169399375; - #endif -#else - #define M_2PI 6.283185307179586 - const double PI = 3.141592654; -#endif - -const double SQRT2 = std::sqrt(double(2.0)); // more efficient than calculating every time - -//--------------------------------------------------------------------------- - -// Common declarations - -struct locn { int x; int y; }; -struct rgb { // colour scheme for drawing maps - int r,g,b; -}; - -const string Int2Str(const int); -#if RS_RCPP -const string Int2Str(const int, unsigned int); -#endif -const string Float2Str(const float); -const string Double2Str(const double); -const rgb draw_wheel(int); - -//--------------------------------------------------------------------------- - -// Environmental gradient parameters - -// SHOULD THIS BE PART OF LANDSCAPE OBJECT OR A SEPARATE OBJECT????????????? - -struct envGradParams { - bool gradient; bool shifting; - int gradType; float grad_inc; float opt_y; float factor; float extProbOpt; - float shift_rate; int shift_begin; int shift_stop; -}; - -class paramGrad { - -public: - paramGrad(void); - ~paramGrad(void); - void setGradient( - int, // gradient type - float, // gradient steepness - float, // optimum row (Y dimension) - float, // local scaling factor - float // local extinction probability at optimum - ); - void setShifting( - float, // shifting rate (rows/year) - int, // first year of shifting - int // last year of shifting - ); - void noGradient(void); - void noShifting(void); - envGradParams getGradient(void); - void incrOptY(void); - void resetOptY(void); - -private: - bool gradient; // there a gradient - bool shifting; // the gradient is shifting - int gradType; // 0 = none, 1 = carrying capacity, - // 2 = growth rate, 3 = local extinction probability - float grad_inc; // gradient steepness - float opt_y; // optimum row (Y dimension) - float opt_y0; // optimum row at year 0 (internal use only) - float factor; // local scaling factor - float extProbOpt; // local extinction probability at optimum (if gradient = 4, otherwise 0) - float shift_rate; // rows/year - int shift_begin; // first year of shifting - int shift_stop; // last year of shifting -}; - -//--------------------------------------------------------------------------- - -// Environmental stochasticity parameters - -// SHOULD THIS BE PART OF LANDSCAPE OBJECT OR A SEPARATE OBJECT????????????? - -struct envStochParams { - bool stoch; bool local; bool inK; bool localExt; - float ac; float std; - float locExtProb; -}; - -class paramStoch { - -public: - paramStoch(void); - ~paramStoch(void); - void setStoch(envStochParams); - bool envStoch(void); - envStochParams getStoch(void); - -private: - bool stoch; // stochasticity applied - bool local; // applied locally (if not, application is global) - bool inK; // in carrying capacity (if not, in growth rate) - bool localExt; // local extinction applied - float ac; // temporal autocorrelation coefficient - float std; // amplitude of fluctuations: sampled from N(0,std) - float locExtProb; // local extinction probability -}; - -//--------------------------------------------------------------------------- - -// Initialisation (seeding) parameters - -struct initParams { - short seedType; short freeType; short spDistType; short initDens; - short initAge; int initFrzYr; bool restrictRange; - int restrictRows; int restrictFreq; int finalFrzYr; - int indsCell; float indsHa; - int minSeedX; int maxSeedX; int minSeedY; int maxSeedY; - int nSeedPatches; int nSpDistPatches; - string indsFile; -}; - -struct initInd { - int year,patchID,x,y; short species,sex,age,stage; -}; - -class paramInit { - -public: - paramInit(void); - ~paramInit(void); - void setInit(initParams); - initParams getInit(void); - void setProp( - short, // stage - float // initial proportion - ); - float getProp( - short // stage - ); - void addInitInd(initInd); - initInd getInitInd(int); - void resetInitInds(void); - int numInitInds(void); - -private: - short seedType; // initialisation type: 0 = free, 1 = from species distn, - // 2 = initial individuals, 3 = from file - short freeType; // free initialisation type: - // 0 = random (given no.) - // 1 = all suitable cells/patches - // 2 = manually selected cells/patches - short spDistType; // species distribution initialisation type: - // 0 = all suitable cells/patches, - // 1 = some randomly chosen suitable cells/patches, - // 2 = all cells/patches within selected sp. dist. cells - short initDens; // initialisation density: - // 0 = at carrying capacity - // 1 = at half carrying capacity - // 2 = specified no. per cell or density - short initAge; // initial age distribution within each stage: - // 0 = lowest possible age - // 1 = randomised - // 2 = quasi-equilibrium - int initFrzYr; // year until which initial range is frozen - bool restrictRange; // restrict range to northern front - int restrictRows; // no. of rows to retain behind front - int restrictFreq; // frequency of range restriction - int finalFrzYr; // year after which range is frozen - int indsCell; // initial individuals / cell (cell-based model) - float indsHa; // initial density (patch-based model) - int minSeedX; // ) - int maxSeedX; // ) min. and max. of area to initialise (cell numbers) - int minSeedY; // ) only applied if seedType is 0 - int maxSeedY; // ) - int nSeedPatches; // no. of cells/patches to initialise - int nSpDistPatches; // no. of species distribution cells to initialise - string indsFile; // no. of species distribution cells to initialise - float initProp[NSTAGES]; // initial stage proportions (structured population only) - - vector initinds; // individuals to be initialised - -}; - -//--------------------------------------------------------------------------- - -// Simulation parameters - -struct simParams { - int batchNum; - int simulation; int reps; int years; -// int outStartRange; -// int outStartOcc; - int outStartPop; int outStartInd; int outStartGenetic; - int outStartTraitCell; int outStartTraitRow; int outStartConn; - int outIntRange; int outIntOcc; int outIntPop; int outIntInd; int outIntGenetic; - int outIntTraitCell; int outIntTraitRow; int outIntConn; - int mapInt; int traitInt; - bool batchMode; bool absorbing; - bool outRange; bool outOccup; bool outPop; bool outInds; - bool outGenetics; short outGenType; bool outGenXtab; - bool outTraitsCells; bool outTraitsRows; bool outConnect; - bool saveMaps; - bool drawLoaded; bool saveTraitMaps; - bool saveVisits; -#if RS_RCPP - int outStartPaths; int outIntPaths; - bool outPaths; bool ReturnPopRaster; bool CreatePopFile; -#endif -}; - -struct simView { - bool viewLand; bool viewPatch; bool viewGrad; bool viewCosts; - bool viewPop; bool viewTraits; bool viewPaths; bool viewGraph; - int slowFactor; -}; - -class paramSim { - -public: - paramSim(void); - ~paramSim(void); - void setSim(simParams); - simParams getSim(void); - int getSimNum(void); - void setViews(simView); - simView getViews(void); - void setDir(string); - string getDir(int); -#if RS_RCPP - bool getReturnPopRaster(void); - bool getCreatePopFile(void); -#endif - -private: - int batchNum; // batch number - int simulation; // simulation no. - int reps; // no. of replicates - int years; // no. of years -// int outStartRange; // output start year for range file -// int outStartOcc; // output start year for occupancy file - int outStartPop; // output start year for population file - int outStartInd; // output start year for individuals file - int outStartGenetic; // output start year for genetics file - int outStartTraitCell; // output start year for traits by cell file - int outStartTraitRow; // output start year for traits by row file - int outStartConn; // output start year for connectivity matrix - int outIntRange; // output interval for range file - int outIntOcc; // output interval for occupancy file - int outIntPop; // output interval for population file - int outIntInd; // output interval for individuals file - int outIntGenetic; // output interval for genetics file - int outIntTraitCell; // output interval for traits by cell file - int outIntTraitRow; // output interval for traits by row file - int outIntConn; // output interval for connectivity matrix - int mapInt; // output interval for maps - int traitInt; // output interval for evolving traits maps - int slowFactor; // to reduce speed of movement paths on screen - bool batchMode; // - bool absorbing; // landscape boundary and no-data regions are - // absorbing boundaries - bool outRange; // produce output range file? - bool outOccup; // produce output occupancy file? - bool outPop; // produce output population file? - bool outInds; // produce output individuals file? - bool outGenetics; // produce output genetics file? - short outGenType; // produce output genetics for: 0 = juveniles only - // 1 = all individuals, 2 = adults (i.e. final stage) only - bool outGenXtab; // produce output genetics as a cross table? - bool outTraitsCells; // produce output summary traits by cell file? - bool outTraitsRows; // produce output summary traits by row (y) file? - bool outConnect; // produce output connectivity file? - bool saveMaps; // save landscape/population maps? - bool saveVisits; // save dispersal visits heat maps? -#if RS_RCPP - int outStartPaths; - int outIntPaths; - bool outPaths; - bool ReturnPopRaster; - bool CreatePopFile; -#endif - bool drawLoaded; // draw initial distribution on landscape/population maps? - bool saveTraitMaps; // save summary traits maps? - bool viewLand; // view landscape map on screen? - bool viewPatch; // view map of landscape patches on screen? - bool viewGrad; // view gradient map on screen? - bool viewCosts; // view costs map on screen? - bool viewPop; // view population density on landscape map on screen? - bool viewTraits; // view summary traits map(s) on screen? - bool viewPaths; // view individual movement paths on screen? - bool viewGraph; // view population/occupancy graph on screen? - string dir; // full name of working directory - -}; - -#if RSDEBUG -extern ofstream DEBUGLOG; -void DebugGUI(string); -#endif - -//--------------------------------------------------------------------------- -#endif diff --git a/RangeShiftR/src/RScore/Patch.cpp b/RangeShiftR/src/RScore/Patch.cpp deleted file mode 100644 index 60421c4..0000000 --- a/RangeShiftR/src/RScore/Patch.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Patch.h" -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -Patch::Patch(int seqnum,int num) -{ -patchSeqNum = seqnum; patchNum = num; nCells = 0; -xMin = yMin = 999999999; xMax = yMax = 0; x = y = 0; -subCommPtr = 0; -localK = 0.0; -for (int sex = 0; sex < NSEXES; sex++) { - nTemp[sex] = 0; -} -changed = false; -} - -Patch::~Patch() { -cells.clear(); -popns.clear(); -} - -int Patch::getSeqNum(void) { return patchSeqNum; } - -int Patch::getPatchNum(void) { return patchNum; } - -int Patch::getNCells(void) { return nCells; } - -patchLimits Patch::getLimits(void) { -patchLimits p; -p.xMin = xMin; p.xMax = xMax; p.yMin = yMin; p.yMax = yMax; -return p; -} - -// Does the patch fall (partially) within a specified rectangle? -bool Patch::withinLimits(patchLimits rect){ -locn loc; -if (xMin <= rect.xMax && xMax >= rect.xMin && yMin <= rect.yMax && yMax >= rect.yMin) { - // patch is within the rectangle UNLESS it is irregular in shape and lies at a corner - // of the rectangle - if ((xMin >= rect.xMin && xMax <= rect.xMax) - || (yMin >= rect.yMin && yMax <= rect.yMax)) { - // patch lies within or along an edge of the initialistaion rectangle - return true; - } - else { - // check for any cell of the patch lying within the rectangle - int ncells = (int)cells.size(); - for (int i = 0; i < ncells; i++) { - loc = getCellLocn(i); - if (loc.x >= rect.xMin && loc.x <= rect.xMax - && loc.y >= rect.yMin && loc.y <= rect.yMax) { - // cell lies within the rectangle - return true; - } - } - } - } -return false; -} - -// Reset minimum and maximum co-ordinates of the patch if it has been changed -void Patch::resetLimits(void) { -if (changed) { - // remove any deleted cells - std::vector newcells; // for all retained and added cells - int ncells = (int)cells.size(); - for (int i = 0; i < ncells; i++) { - if (cells[i] != NULL) { - newcells.push_back(cells[i]); - } - } - cells.clear(); - cells = newcells; - // reset patch limits - locn loc; - xMin = yMin = 999999999; xMax = yMax = 0; - ncells = (int)cells.size(); - for (int i = 0; i < ncells; i++) { - loc = getCellLocn(i); - if (loc.x < xMin) xMin = loc.x; - if (loc.x > xMax) xMax = loc.x; - if (loc.y < yMin) yMin = loc.y; - if (loc.y > yMax) yMax = loc.y; - } - changed = false; -} -} - -// Add a cell to the patch -void Patch::addCell(Cell* pCell,int x,int y) { - cells.push_back(pCell); - nCells++; - if (x < xMin) xMin = x; - if (x > xMax) xMax = x; - if (y < yMin) yMin = y; - if (y > yMax) yMax = y; -} - -// Calculate the total carrying capacity (no. of individuals) and -// centroid co-ordinates of the patch -void Patch::setCarryingCapacity(Species *pSpecies,patchLimits landlimits, - float epsGlobal,short nHab,short rasterType,short landIx,bool gradK) { -envStochParams env = paramsStoch->getStoch(); -//Cell *pCell; -locn loc; -int xsum,ysum; -short hx; -float k,q,envval; - -localK = 0.0; // no. of suitable cells (unadjusted K > 0) in the patch -int nsuitable = 0; -double mean; - -#if RSDEBUG -//DEBUGLOG << "Patch::setCarryingCapacity(): patchNum=" << patchNum -// << " xMin=" << xMin << " yMin=" << yMin << " xMax=" << xMax << " yMax=" << yMax -// << endl; -#endif - -if (xMin > landlimits.xMax || xMax < landlimits.xMin -|| yMin > landlimits.yMax || yMax < landlimits.yMin) { - // patch lies wholely outwith current landscape limits - // NB the next statement is unnecessary, as localK has been set to zero above - // retained only for consistency in standard variant - localK = 0.0; -#if RSDEBUG -//DEBUGLOG << "Patch::setCarryingCapacity(): patchNum=" << patchNum -// << " localK=" << localK -// << endl; -#endif - return; -} - -int ncells = (int)cells.size(); -xsum = ysum = 0; -for (int i = 0; i < ncells; i++) { - if (gradK) // gradient in carrying capacity - envval = cells[i]->getEnvVal(); // environmental gradient value - else envval = 1.0; // no gradient effect - if (env.stoch && env.inK) { // environmental stochasticity in K - if (env.local) { -// pCell = getRandomCell(); -// if (pCell != 0) envval += pCell->getEps(); - envval += cells[i]->getEps(); - } - else { // global stochasticity - envval += epsGlobal; - } - } - switch (rasterType) { - case 0: // habitat codes - hx = cells[i]->getHabIndex(landIx); - k = pSpecies->getHabK(hx); - if (k > 0.0) { - nsuitable++; - localK += envval * k; - } - break; - case 1: // cover % - k = 0.0; - for (int j = 0; j < nHab; j++) { // loop through cover layers - q = cells[i]->getHabitat(j); - k += q * pSpecies->getHabK(j) / 100.0f; - } - if (k > 0.0) { - nsuitable++; - localK += envval * k; - } - break; - case 2: // habitat quality - q = cells[i]->getHabitat(landIx); - if (q > 0.0) { - nsuitable++; - localK += envval * pSpecies->getHabK(0) * q / 100.0f; - } - break; - } -#if RSDEBUG -//DEBUGLOG << "Patch::setCarryingCapacity(): patchNum=" << patchNum -// << " i=" << i << " hx=" << hx << " q=" << q << " k=" << k << " localK=" << localK -// << endl; -#endif - loc = cells[i]->getLocn(); - xsum += loc.x; ysum += loc.y; -} -#if RSDEBUG -//DEBUGLOG << "Patch::setCarryingCapacity(): patchNum=" << patchNum -// << " epsGlobal=" << epsGlobal << " localK=" << localK -// << endl; -#endif -// calculate centroid co-ordinates -if (ncells > 0) { - mean = (double)xsum / (double)ncells; - x = (int)(mean + 0.5); - mean = (double)ysum / (double)ncells; - y = (int)(mean + 0.5); -} -if (env.stoch && env.inK) { // environmental stochasticity in K - // apply min and max limits to K over the whole patch - // NB limits have been stored as N/cell rather than N/ha - float limit; - limit = pSpecies->getMinMax(0) * (float)nsuitable; - if (localK < limit) localK = limit; -#if RSDEBUG -//DEBUGLOG << "Patch::setCarryingCapacity(): patchNum=" << patchNum -// << " limit=" << limit << " localK=" << localK -// << endl; -#endif - limit = pSpecies->getMinMax(1) * (float)nsuitable; - if (localK > limit) localK = limit; -#if RSDEBUG -//DEBUGLOG << "Patch::setCarryingCapacity(): patchNum=" << patchNum -// << " limit=" << limit << " localK=" << localK -// << endl; -#endif -} -#if RSDEBUG -//DEBUGLOG << "Patch::setCarryingCapacity(): patchNum=" << patchNum -// << " localK=" << localK -// << endl; -#endif -} - - -float Patch::getK(void) { return localK; } - -// Return co-ordinates of a specified cell -locn Patch::getCellLocn(int ix) { -locn loc; loc.x = -666; loc.y = -666; -int ncells = (int)cells.size(); -if (ix >= 0 && ix < ncells) { - loc = cells[ix]->getLocn(); -} -return loc; -} -// Return pointer to a specified cell -Cell* Patch::getCell(int ix) { -int ncells = (int)cells.size(); -if (ix >= 0 && ix < ncells) return cells[ix]; -else return 0; -} -// Return co-ordinates of patch centroid -locn Patch::getCentroid(void) { -locn loc; loc.x = x; loc.y = y; -return loc; -} - -// Select a Cell within the Patch at random, and return pointer to it -// For a cell-based model, this will be the only Cell -Cell* Patch::getRandomCell(void) { -Cell *pCell = 0; -int ix; -int ncells = (int)cells.size(); -if (ncells > 0) { - if (ncells == 1) ix = 0; - else ix = pRandom->IRandom(0,ncells-1); - pCell = cells[ix]; -} -return pCell; -} - -// Remove a cell from the patch -void Patch::removeCell(Cell* pCell) { -int ncells = (int)cells.size(); -for (int i = 0; i < ncells; i++) { - if (pCell == cells[i]) { - cells[i] = NULL; i = ncells; - nCells--; - changed = true; - } -} -} - -void Patch::setSubComm(intptr sc) -{ subCommPtr = sc; } - -// Get pointer to corresponding Sub-community (cast as an integer) -intptr Patch::getSubComm(void) -{ return subCommPtr; } - -void Patch::addPopn(patchPopn pop) { -popns.push_back(pop); -} - -// Return pointer (cast as integer) to the Population of the specified Species -intptr Patch::getPopn(intptr sp) -{ -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { - if (popns[i].pSp == sp) return popns[i].pPop; -} -return 0; -} - -void Patch::resetPopn(void) { -popns.clear(); -} - -void Patch::resetPossSettlers(void) { -for (int sex = 0; sex < NSEXES; sex++) { - nTemp[sex] = 0; -} -} - -// Record the presence of a potential settler within the Patch -void Patch::incrPossSettler(Species *pSpecies,int sex) { -#if RSDEBUG -//DEBUGLOG << "Patch::incrPossSettler(): 5555: patchNum = " << patchNum -// << " sex = " << sex << endl; -#endif -// NOTE: THE FOLLOWING OPERATION WILL NEED TO BE MADE SPECIES-SPECIFIC... -if (sex >= 0 && sex < NSEXES) { - nTemp[sex]++; -} -} - -// Get number of a potential settlers within the Patch -int Patch::getPossSettlers(Species *pSpecies,int sex) { -#if RSDEBUG -//DEBUGLOG << "Patch::getPossSettlers(): 5555: patchNum = " << patchNum -// << " sex = " << sex << endl; -#endif -// NOTE: THE FOLLOWING OPERATION WILL NEED TO BE MADE SPECIES-SPECIFIC... -if (sex >= 0 && sex < NSEXES) return nTemp[sex]; -else return 0; -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - - - diff --git a/RangeShiftR/src/RScore/Patch.h b/RangeShiftR/src/RScore/Patch.h deleted file mode 100644 index 2bc30e7..0000000 --- a/RangeShiftR/src/RScore/Patch.h +++ /dev/null @@ -1,182 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Patch - -Implements the class: Patch - -A patch is a collection of one or more Cells in the the gridded Landscape, -which together provide the area in which a single demographic unit of a Species, -i.e. a Population, can reproduce. One or more Populations (of different Species) -form a Sub-community associated with the Patch. - -There is no requirement that all the Cells be adjacent, although in practice -that would usually be the case. - -Each Patch must have a unique positive integer id number supplied by the user, -and the matrix, i.e. any part of the landscape which is not a breeding patch, -is represented by Patch 0. However, as patch numbers need not be sequential, -an internal sequential number is also applied. - -For a 'cell-based model', the user supplies no patch numbers, and a separate -Patch is generated internally for each Cell, i.e. the 'cell-based model' is a -special case of the 'patch-based model' in which each Patch has a single Cell. -Moreover, there is also the 'matrix' Patch 0, which has no cells, but which -holds the disperser population whilst its Individuals are in transit. - -In a true patch-based model, each Patch hold a list of its constituent Cells, -EXCEPT for the matrix Patch 0. This is because that list would be extremely -long for a very large landscape in which suitable patches are small and/or rare, -and removing Cells from it if the landscape is dynamic would be inefficient. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 25 June 2021 by Steve Palmer - -------------------------------------------------------------------------------*/ - -#ifndef PatchH -#define PatchH - -#include -using namespace std; - -//#if RS_RCPP && !R_CMD -#include "../Version.h" -//#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif - -#include "Parameters.h" -#include "Cell.h" -#include "Species.h" - -//--------------------------------------------------------------------------- - -struct patchLimits { - int xMin,xMax,yMin,yMax; -}; -struct patchPopn { - intptr pSp,pPop; // pointers to Species and Population cast as integers -}; - -class Patch{ -public: - Patch( - int, // internal sequential number - int // patch id number - ); - ~Patch(); - int getSeqNum(void); - int getPatchNum(void); - int getNCells(void); - patchLimits getLimits(void); // Returns the minimum and maximum co-ordinates of the patch - bool withinLimits( // Does the patch fall (partially) within a specified rectangle? - patchLimits // structure holding the SW and NE co-ordinates of the rectangle - ); - void resetLimits(void); // Reset minimum and maximum co-ordinates of the patch - void addCell( - Cell*, // pointer to the Cell to be added to the Patch - int,int // x (column) and y (row) co-ordinates of the Cell - ); - locn getCellLocn( // Return co-ordinates of a specified cell - int // index no. of the Cell within the vector cells - ); - Cell* getCell( // Return pointer to a specified cell - int // index no. of the Cell within the vector cells - ); - locn getCentroid(void); // Return co-ordinates of patch centroid - void removeCell( - Cell* // pointer to the Cell to be removed from the Patch - ); - Cell* getRandomCell(void); - void setSubComm( - intptr // pointer to the Sub-community cast as an integer - ); - intptr getSubComm(void); - void addPopn( - patchPopn // structure holding pointers to Species and Population cast as integers - ); - intptr getPopn( // return pointer (cast as integer) to the Population of the Species - intptr // pointer to Species cast as integer - ); - void resetPopn(void); - void resetPossSettlers(void); - void incrPossSettler( // Record the presence of a potential settler within the Patch - Species*, // pointer to the Species - int // sex of the settler - ); - int getPossSettlers( // Get number of a potential settlers within the Patch - Species*, // pointer to the Species - int // sex of the settlers - ); - void setCarryingCapacity( // Calculate total Patch carrying capacity (no. of inds) - Species*, // pointer to the Species - patchLimits, // current min and max limits of landscape - float, // global stochasticity value (epsilon) for the current year - short, // no. of habitat classes in the Landscape - short, // rasterType (see Landscape) - short, // landscape change index (always zero if not dynamic) - bool // TRUE if there is a gradient in carrying capacity across the Landscape - ); - float getK(void); - // dummy function for batch version - void drawCells(float,int,rgb); - - private: - int patchSeqNum;// sequential patch number - patch 0 is reserved for the inter-patch matrix - int patchNum; // patch number as supplied by the user (not forced to be sequential) - int nCells; // no. of cells in the patch - int xMin,xMax,yMin,yMax; // min and max cell co-ordinates - int x,y; // centroid co-ordinates (approx.) - intptr subCommPtr; // pointer (cast as integer) to sub-community associated with the patch - // NOTE: FOR MULTI-SPECIES MODEL, PATCH WILL NEED TO STORE K FOR EACH SPECIES - float localK; // patch carrying capacity (individuals) - bool changed; -// NOTE: THE FOLLOWING ARRAY WILL NEED TO BE MADE SPECIES-SPECIFIC... - short nTemp[NSEXES]; // no. of potential settlers in each sex - - std::vector cells; - std::vector popns; - -}; - -//--------------------------------------------------------------------------- - -extern paramStoch *paramsStoch; -extern RSrandom *pRandom; - -#if RSDEBUG -extern ofstream DEBUGLOG; -#endif - -#endif diff --git a/RangeShiftR/src/RScore/Population.cpp b/RangeShiftR/src/RScore/Population.cpp deleted file mode 100644 index 05d8633..0000000 --- a/RangeShiftR/src/RScore/Population.cpp +++ /dev/null @@ -1,2252 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Population.h" -//--------------------------------------------------------------------------- - -ofstream outPop; -ofstream outInds; - -//--------------------------------------------------------------------------- - -Population::Population(void) { -nSexes = nStages = 0; -pPatch = NULL; -pSpecies = NULL; -return; -} - -Population::Population(Species *pSp,Patch *pPch,int ninds,int resol) -{ -// constructor for a Population of a specified size -#if RSDEBUG -//DEBUGLOG << "Population::Population(): this=" << this -// << " pPch=" << pPch << " ninds="<< ninds << endl; -#endif - -int n,nindivs,age = 0,minage,maxage,nAges = 0; -int cumtotal = 0; -float probmale; -double ageprob,ageprobsum; -std::vector ageProb; // for quasi-equilibrium initial age distribution -Cell *pCell; - -if (ninds > 0) { - inds.reserve(ninds); - juvs.reserve(ninds); -} - -pSpecies = pSp; -pPatch = pPch; -// record the new population in the patch -patchPopn pp; -pp.pSp = (intptr)pSpecies; pp.pPop = (intptr)this; -pPatch->addPopn(pp); -#if RSDEBUG -//DEBUGLOG << "Population::Population(): this=" << this -// << " added population to patch " << endl; -#endif - -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -//trfrSMSTraits sms = pSpecies->getSMSTraits(); -settleType sett = pSpecies->getSettle(); -genomeData gen = pSpecies->getGenomeData(); -initParams init = paramsInit->getInit(); - -// determine no. of stages and sexes of species to initialise -if (dem.stageStruct) { - nStages = sstruct.nStages; -} -else // non-structured population has 2 stages, but user only ever sees stage 1 - nStages = 2; -if (dem.repType == 0) { nSexes = 1; probmale = 0.0; } -else { nSexes = 2; probmale = dem.propMales; } - -// set up population sub-totals -for (int stg = 0; stg < NSTAGES; stg++) { - for (int sex = 0; sex < NSEXES; sex++) { - nInds[stg][sex] = 0; - } -} - -// set up local copy of minimum age table -short minAge[NSTAGES][NSEXES]; -for (int stg = 0; stg < nStages; stg++) { - for (int sex = 0; sex < nSexes; sex++) { - if (dem.stageStruct) { - if (dem.repType == 1) { // simple sexual model - // both sexes use minimum ages recorded for females - minAge[stg][sex] = pSpecies->getMinAge(stg,0); - } - else { - minAge[stg][sex] = pSpecies->getMinAge(stg,sex); - } - } - else { // non-structured population - minAge[stg][sex] = 0; - } -#if RSDEBUG -//DEBUGLOG << "Population::Population(): 1111 " -// << " minAge[" << stg << "][" << sex << "]=" << minAge[stg][sex] -// << endl; -#endif - } -} - -// individuals of new population must be >= stage 1 -for (int stg = 1; stg < nStages; stg++) { - if (dem.stageStruct) { // allocate to stages according to initialisation conditions - // final stage is treated separately to ensure that correct total - // no. of individuals is created - if (stg == nStages-1) { - n = ninds - cumtotal; - } - else { - n = (int)(ninds * paramsInit->getProp(stg) + 0.5); - cumtotal += n; - } - } - else { // non-structured - all individuals go into stage 1 - n = ninds; - } -// for (int sex = 0; sex < nSexes; sex++) { -// if (n < nSexes) n = nSexes; // to ensure at least one individual of each age is created -// subPops.push_back(new SubPop(loc,stg,sex,n/nSexes)); -// } - // establish initial age distribution - minage = maxage = stg; - if (dem.stageStruct) { - // allow for stage-dependent minimum ages (use whichever sex is greater) - if (minAge[stg][0] > 0 && minage < minAge[stg][0]) minage = minAge[stg][0]; - if (nSexes == 2 && minAge[stg][1] > 0 && minage < minAge[stg][1]) minage = minAge[stg][1]; - // allow for specified age distribution - if (init.initAge != 0) { // not lowest age - if (stg == nStages-1) maxage = sstruct.maxAge; // final stage - else { // all other stages - use female max age, as sex of individuals is not predetermined - maxage = minAge[stg+1][0] - 1; - } - if (maxage < minage) maxage = minage; - nAges = maxage - minage + 1; - if (init.initAge == 2) { // quasi-equilibrium distribution - double psurv = (double)pSpecies->getSurv(stg,0); // use female survival for the stage - ageProb.clear(); - ageprobsum = 0.0; - ageprob = 1.0; - for (int i = 0; i < nAges; i++) { - ageProb.push_back(ageprob); ageprobsum += ageprob; ageprob *= psurv; - } - for (int i = 0; i < nAges; i++) { - ageProb[i] /= ageprobsum; - if (i > 0) ageProb[i] += ageProb[i-1]; // to give cumulative probability - } - } - } - } -#if RSDEBUG -//DEBUGLOG << "Population::Population(): this=" << this -// << " n=" << n << " stg=" << stg << " minage=" << minage << " maxage=" << maxage -// << endl; -#endif - // create individuals - int sex; - nindivs = (int)inds.size(); - for (int i = 0; i < n; i++) { - pCell = pPatch->getRandomCell(); - if (dem.stageStruct) { - switch (init.initAge) { - case 0: // lowest possible age - age = minage; - break; - case 1: // randomised - if (maxage > minage) age = pRandom->IRandom(minage,maxage); - else age = minage; - break; - case 2: // quasi-equilibrium - if (nAges > 1) { - double rrr = pRandom->Random(); - int ageclass = 0; - while (rrr > ageProb[ageclass]) ageclass++; - age = minage + ageclass; - } - else age = minage; - break; - } - } - else age = stg; -#if RSDEBUG - // NOTE: CURRENTLY SETTING ALL INDIVIDUALS TO RECORD NO. OF STEPS ... - inds.push_back(new Individual(pCell,pPatch,stg,age,sstruct.repInterval, - probmale,true,trfr.moveType)); -#else - inds.push_back(new Individual(pCell,pPatch,stg,age,sstruct.repInterval, - probmale,trfr.moveModel,trfr.moveType)); -#endif - sex = inds[nindivs+i]->getSex(); - if (emig.indVar || trfr.indVar || sett.indVar || gen.neutralMarkers) - { - // individual variation - set up genetics - inds[nindivs+i]->setGenes(pSpecies,resol); - } - nInds[stg][sex]++; - } -} -#if RSDEBUG -//DEBUGLOG << "Population::Population(): this=" << this -// << " finished " << endl; -#endif -} - -Population::~Population(void) { -int ninds = (int)inds.size(); -for (int i = 0; i < ninds; i++) { - if (inds[i] != NULL) delete inds[i]; -} -inds.clear(); -int njuvs = (int)juvs.size(); -for (int i = 0; i < njuvs; i++) { - if (juvs[i] != NULL) delete juvs[i]; -} -juvs.clear(); -} - -traitsums Population::getTraits(Species *pSpecies) { -int g; -traitsums ts; -for (int i = 0; i < NSEXES; i++) { - ts.ninds[i] = 0; - ts.sumD0[i] = ts.ssqD0[i] = 0.0; - ts.sumAlpha[i] = ts.ssqAlpha[i] = 0.0; ts.sumBeta[i] = ts.ssqBeta[i] = 0.0; - ts.sumDist1[i] = ts.ssqDist1[i] = 0.0; ts.sumDist2[i] = ts.ssqDist2[i] = 0.0; - ts.sumProp1[i] = ts.ssqProp1[i] = 0.0; - ts.sumDP[i] = ts.ssqDP[i] = 0.0; - ts.sumGB[i] = ts.ssqGB[i] = 0.0; - ts.sumAlphaDB[i] = ts.ssqAlphaDB[i] = 0.0; - ts.sumBetaDB[i] = ts.ssqBetaDB[i] = 0.0; - ts.sumStepL[i] = ts.ssqStepL[i] = 0.0; ts.sumRho[i] = ts.ssqRho[i] = 0.0; - ts.sumS0[i] = ts.ssqS0[i] = 0.0; - ts.sumAlphaS[i] = ts.ssqAlphaS[i] = 0.0; ts.sumBetaS[i] = ts.ssqBetaS[i] = 0.0; -} -//locus loc; - -demogrParams dem = pSpecies->getDemogr(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); - -int ninds = (int)inds.size(); -#if RSDEBUG -//DEBUGLOG << "Population::getTraits(): ninds = " << ts.ninds[0] -//// << " nalleles = "<< nalleles -//// << " nemiggenes = " << nemiggenes << " ntrfrgenes = " << ntrfrgenes -// << endl; -#endif -for (int i = 0; i < ninds; i++) { - int sex = inds[i]->getSex(); - if (emig.sexDep || trfr.sexDep || sett.sexDep) g = sex; else g = 0; - ts.ninds[g] += 1; - // emigration traits - emigTraits e = inds[i]->getEmigTraits(); - if (emig.sexDep) g = sex; else g = 0; - ts.sumD0[g] += e.d0; ts.ssqD0[g] += e.d0 * e.d0; - ts.sumAlpha[g] += e.alpha; ts.ssqAlpha[g] += e.alpha * e.alpha; - ts.sumBeta[g] += e.beta; ts.ssqBeta[g] += e.beta * e.beta; - // transfer traits - trfrKernTraits k = inds[i]->getKernTraits(); - if (trfr.sexDep) g = sex; else g = 0; - ts.sumDist1[g] += k.meanDist1; ts.ssqDist1[g] += k.meanDist1 * k.meanDist1; - ts.sumDist2[g] += k.meanDist2; ts.ssqDist2[g] += k.meanDist2 * k.meanDist2; - ts.sumProp1[g] += k.probKern1; ts.ssqProp1[g] += k.probKern1 * k.probKern1; - trfrSMSTraits sms = inds[i]->getSMSTraits(); - g = 0; // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT - ts.sumDP[g] += sms.dp; ts.ssqDP[g] += sms.dp * sms.dp; - ts.sumGB[g] += sms.gb; ts.ssqGB[g] += sms.gb * sms.gb; - ts.sumAlphaDB[g] += sms.alphaDB; ts.ssqAlphaDB[g] += sms.alphaDB * sms.alphaDB; - ts.sumBetaDB[g] += sms.betaDB; ts.ssqBetaDB[g] += sms.betaDB * sms.betaDB; -#if RSDEBUG -//DEBUGLOG << "Population::getTraits():" -// << " i=" << i << " g=" << g -// << " sms.dp= " << sms.dp << " sms.gb= " << sms.gb -// << " ts.sumDP[g]= " << ts.sumDP[g] << " ts.ssqDP[g]= " << ts.ssqDP[g] -// << " ts.sumGB[g]= " << ts.sumGB[g] << " ts.ssqGB[g]= " << ts.ssqGB[g] -// << endl; -#endif - trfrCRWTraits c = inds[i]->getCRWTraits(); - g = 0; // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT - ts.sumStepL[g] += c.stepLength; ts.ssqStepL[g] += c.stepLength * c.stepLength; - ts.sumRho[g] += c.rho; ts.ssqRho[g] += c.rho * c.rho; - // settlement traits - settleTraits s = inds[i]->getSettTraits(); - if (sett.sexDep) g = sex; else g = 0; -// g = 0; // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT - ts.sumS0[g] += s.s0; ts.ssqS0[g] += s.s0 * s.s0; - ts.sumAlphaS[g] += s.alpha; ts.ssqAlphaS[g] += s.alpha * s.alpha; - ts.sumBetaS[g] += s.beta; ts.ssqBetaS[g] += s.beta * s.beta; -#if RSDEBUG -//DEBUGLOG << "Population::getTraits():" -// << " i=" << i << " g=" << g << " a=" << a -// << " e.d0= " << e.d0 << " e.alpha= " << e.alpha << " e.beta= " << e.beta -// << " mnd0= " << emigTraits[g]->mnD0 << " mnAlpha= " << emigTraits[g]->mnAlpha << " mnBeta= " << emigTraits[g]->mnBeta -// << " sqd0= " << emigTraits[g]->sqD0 << " sqAlpha= " << emigTraits[g]->sqAlpha << " sqBeta= " << emigTraits[g]->sqBeta -// << endl; -#endif -} - -return ts; -} - -int Population::getNInds(void) { return (int)inds.size(); } - -popStats Population::getStats(void) -{ -popStats p; -int ninds; -float fec; -bool breeders[2]; breeders[0] = breeders[1] = false; -demogrParams dem = pSpecies->getDemogr(); -p.pSpecies = pSpecies; -p.pPatch = pPatch; -p.spNum = pSpecies->getSpNum(); -p.nInds = (int)inds.size(); -p.nNonJuvs = p.nAdults = 0; -p.breeding = false; -#if RSDEBUG -//DEBUGLOG << "Population::getStats(): this=" << this -//// << " p.pSpecies=" << p.pSpecies << " p.spNum=" << p.spNum -// << " p.pPatch=" << p.pPatch << " patchNum=" << p.pPatch->getPatchNum() -// << " nStages=" << nStages << " nSexes=" << nSexes << " p.nInds=" << p.nInds -// << endl; -#endif -for (int stg = 1; stg < nStages; stg++) { - for (int sex = 0; sex < nSexes; sex++) { - ninds = nInds[stg][sex]; - p.nNonJuvs += ninds; -#if RSDEBUG -//DEBUGLOG << "Population::getStats(): this=" << this -// << " stg=" << stg << " sex=" << sex -// << " nInds[stg][sex]=" << nInds[stg][sex] << " p.nNonJuvs=" << p.nNonJuvs -// << endl; -#endif - if (ninds > 0) { - if (pSpecies->stageStructured()) { - if (dem.repType == 2) fec = pSpecies->getFec(stg,sex); - else fec = pSpecies->getFec(stg,0); - if (fec > 0.0) { breeders[sex] = true; p.nAdults += ninds; } - } - else breeders[sex] = true; - } - } -} -// is there a breeding population present? -if (nSexes == 1) { - p.breeding = breeders[0]; -} -else { - if (breeders[0] && breeders[1]) p.breeding = true; -} -#if RSDEBUG -//DEBUGLOG << "Population::getStats(): this=" << this -// << " p.nInds=" << p.nInds << " p.nAdults=" << p.nAdults << " p.nNonJuvs=" << p.nNonJuvs -// << " breeders[0]=" << breeders[0] << " breeders[1]=" << breeders[1] -// << " p.breeding=" << p.breeding -// << endl; -#endif -return p; -} - -Species* Population::getSpecies(void) { return pSpecies; } - -int Population::totalPop(void) { -int t = 0; -for (int stg = 0; stg < nStages; stg++) { - for (int sex = 0; sex < nSexes; sex++) { - t += nInds[stg][sex]; -#if RSDEBUG -//DEBUGLOG << "Population::totalPop(): this=" << this -// << " stg=" << stg << " sex=" << sex -// << " nInds[stg][sex]=" << nInds[stg][sex] << " t=" << t -// << endl; -#endif - } -} -return t; -} - -int Population::stagePop(int stg) { -int t = 0; -if (stg < 0 || stg >= nStages) return t; -for (int sex = 0; sex < nSexes; sex++) { - t += nInds[stg][sex]; -} -return t; -} - -//--------------------------------------------------------------------------- -// Remove all Individuals -void Population::extirpate(void) { -int ninds = (int)inds.size(); -for (int i = 0; i < ninds; i++) { - if (inds[i] != NULL) delete inds[i]; -} -inds.clear(); -int njuvs = (int)juvs.size(); -for (int i = 0; i < njuvs; i++) { - if (juvs[i] != NULL) delete juvs[i]; -} -juvs.clear(); -for (int sex = 0; sex < nSexes; sex++) { - for (int stg = 0; stg < nStages; stg++) { - nInds[stg][sex] = 0; - } -} -} - -//--------------------------------------------------------------------------- -// Produce juveniles and hold them in the juvs vector -void Population::reproduction(const float localK,const float envval,const int resol) -{ - -// get population size at start of reproduction -int ninds = (int)inds.size(); -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): this=" << this -//#if BUTTERFLYDISP -// << " option=" << option -//#endif // BUTTERFLYDISP -//#if RS_CONTAIN -// << " hab=" << hab -//#endif // RS_CONTAIN -// << " ninds=" << ninds -// << endl; -#endif // RSDEBUG -if (ninds == 0) return; - -int nsexes,stage,sex,njuvs,nj,nmales,nfemales; -Cell *pCell; -indStats ind; -double expected; -bool skipbreeding; - -//envGradParams grad = paramsGrad->getGradient(); -envStochParams env = paramsStoch->getStoch(); -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -genomeData gen = pSpecies->getGenomeData(); -simView v = paramsSim->getViews(); - -if (dem.repType == 0) nsexes = 1; else nsexes = 2; - -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): this=" << this -//#if RS_CONTAIN -// << " hab=" << hab -//#else -// << " pSpecies=" << pSpecies -// << " localK=" << localK << " envval=" << envval << " resol=" << resol -//#endif // RS_CONTAIN -// << " sstruct.nStages=" << sstruct.nStages << " nsexes=" << nsexes << " ninds=" << ninds -// << endl; -#endif - -// set up local copy of species fecundity table -float fec[NSTAGES][NSEXES]; -for (int stg = 0; stg < sstruct.nStages; stg++) { - for (int sex = 0; sex < nsexes; sex++) { - if (dem.stageStruct) { - if (dem.repType == 1) { // simple sexual model - // both sexes use fecundity recorded for females - fec[stg][sex] = pSpecies->getFec(stg,0); - } - else - fec[stg][sex] = pSpecies->getFec(stg,sex); -// if (sex == 0 && fec[stg][sex] > dem.lambda) dem.lambda = fec[stg][sex]; - } - else { // non-structured population - if (stg == 1) fec[stg][sex] = dem.lambda; // adults - else fec[stg][sex] = 0.0; // juveniles - } -#if RSDEBUG -//if (ninds > 0) { -//DEBUGLOG << "Population::reproduction(): fec[" << stg << "][" << sex << "] = " << fec[stg][sex] -// << endl; -//} -#endif - } -} - -if (dem.stageStruct) { -#if RSDEBUG -//if (ninds > 0) { -// DEBUGLOG << "Population::reproduction(): ninds=" << ninds << " localK=" << localK -// << " effect of density dependence:" << endl; -//} -#endif - // apply environmental effects and density dependence - // to all non-zero female non-juvenile stages - for (int stg = 1; stg < nStages; stg++) { - if (fec[stg][0] > 0.0) { - // apply any effect of environmental gradient and/or stochasticty - fec[stg][0] *= envval; - if (env.stoch && !env.inK) { - // fecundity (at low density) is constrained to lie between limits specified - // for the species - float limit; - limit = pSpecies->getMinMax(0); - if (fec[stg][0] < limit) fec[stg][0] = limit; - limit = pSpecies->getMinMax(1); - if (fec[stg][0] > limit) fec[stg][0] = limit; - } - if (sstruct.fecDens) { // apply density dependence - float effect = 0.0; - if (sstruct.fecStageDens) { // stage-specific density dependence - // NOTE: matrix entries represent effect of ROW on COLUMN - // AND males precede females - float weight = 0.0; - for (int effstg = 0; effstg < nStages; effstg++) { - for (int effsex = 0; effsex < nSexes; effsex++) { - if (dem.repType == 2) { - if (effsex == 0) weight = pSpecies->getDDwtFec(2*stg+1,2*effstg+1); - else weight = pSpecies->getDDwtFec(2*stg+1,2*effstg); - } - else { - weight = pSpecies->getDDwtFec(stg,effstg); - } - effect += (float)nInds[effstg][effsex] * weight; -#if RSDEBUG -//if (ninds > 0) { -// DEBUGLOG << " effstg=" << effstg << " effsex=" << effsex << " nInds=" << nInds[effstg][effsex]; -// DEBUGLOG << " weight=" << weight << " effect=" << effect -// << endl; -//} -#endif - } - } - } - else // not stage-specific - effect = (float)totalPop(); - if (localK > 0.0) fec[stg][0] *= exp(-effect/localK); -#if RSDEBUG -//if (ninds > 0) { -// DEBUGLOG << " eff popn=" << effect << " exponential=" << exp(-effect/localK); -// DEBUGLOG << " fec[" << stg << "][0]=" << fec[stg][0] -// << endl; -//} -#endif - } - } - } -} -else { // non-structured - set fecundity for adult females only - // apply any effect of environmental gradient and/or stochasticty - fec[1][0] *= envval; - if (env.stoch && !env.inK) { - // fecundity (at low density) is constrained to lie between limits specified - // for the species - float limit; - limit = pSpecies->getMinMax(0); - if (fec[1][0] < limit) fec[1][0] = limit; - limit = pSpecies->getMinMax(1); - if (fec[1][0] > limit) fec[1][0] = limit; - } - // apply density dependence - if (localK > 0.0) { -//#if GOBYMODEL -// ddeffect[1] = (float)ninds/localK; -//#else - if (dem.repType == 1 || dem.repType == 2) { // sexual model - // apply factor of 2 (as in manual, eqn. 6) - fec[1][0] *= 2.0; - } - fec[1][0] /= (1.0f + fabs(dem.lambda-1.0f)*pow(((float)ninds/localK),dem.bc)); -//#endif - } -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): dem.lambda=" << dem.lambda << " ninds=" << ninds -// << " localK=" << localK << " dem.bc=" << dem.bc << " fec[1][0]=" << fec[1][0] -// << endl; -#endif -} - -double propBreed; -Individual *father; -std::vector fathers; - -switch (dem.repType) { - -case 0: // asexual model - for (int i = 0; i < ninds; i++) { - stage = inds[i]->breedingFem(); -#if RSDEBUG -//DEBUGLOG << "Population::reproduction():" -// << " i=" << i << " ID=" << inds[i]->getId() << " stage=" << stage -// << endl; -#endif - if (stage > 0) { // female of breeding age - if (dem.stageStruct) { - // determine whether she must miss current breeding attempt - ind = inds[i]->getStats(); - if (ind.fallow >= sstruct.repInterval) { - if (pRandom->Bernoulli(sstruct.probRep)) skipbreeding = false; - else skipbreeding = true; - } - else skipbreeding = true; // cannot breed this time - } - else skipbreeding = false; // not structured - always breed - if (skipbreeding) { - inds[i]->incFallow(); - } - else { // attempt to breed - inds[i]->resetFallow(); - expected = fec[stage][0]; - if (expected <= 0.0) njuvs = 0; - else njuvs = pRandom->Poisson(expected); - nj = (int)juvs.size(); - pCell = pPatch->getRandomCell(); - for (int j = 0; j < njuvs; j++) { -#if RSDEBUG - // NOTE: CURRENTLY SETTING ALL INDIVIDUALS TO RECORD NO. OF STEPS ... - juvs.push_back(new Individual(pCell,pPatch,0,0,0,0.0,true,trfr.moveType)); -#else - juvs.push_back(new Individual(pCell,pPatch,0,0,0,0.0,trfr.moveModel,trfr.moveType)); -#endif - nInds[0][0]++; - if (emig.indVar || trfr.indVar || sett.indVar || gen.neutralMarkers) - { - // juv inherits genome from parent (mother) - juvs[nj+j]->setGenes(pSpecies,inds[i],0,resol); - } - } - } - } - } - break; - -case 1: // simple sexual model -case 2: // complex sexual model - // count breeding females and males - // add breeding males to list of potential fathers -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): case 1:" -// << " fec[1][0]=" << fec[1][0] << " fec[1][1]=" << fec[1][1] -// << endl; -#endif - nfemales = nmales = 0; - for (int i = 0; i < ninds; i++) { - ind = inds[i]->getStats(); - if (ind.sex == 0 && fec[ind.stage][0] > 0.0) nfemales++; - if (ind.sex == 1 && fec[ind.stage][1] > 0.0) { - fathers.push_back(inds[i]); - nmales++; -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): i=" << i << " nmales=" << nmales -// << " inds[i]=" << inds[i] << endl; -#endif - } - } -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): breeding nfemales=" << nfemales -// << " breeding nmales=" << nmales << endl; -#endif - if (nfemales > 0 && nmales > 0) - { // population can breed - if (dem.repType == 2) { // complex sexual model - // calculate proportion of eligible females which breed - propBreed = (2.0*dem.harem*nmales)/(nfemales+dem.harem*nmales); - if (propBreed > 1.0) propBreed = 1.0; -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): harem=" << dem.harem -// << " nfemales=" << nfemales << " nmales=" << nmales << " propBreed=" << propBreed -// << endl; -#endif - } - else propBreed = 1.0; - for (int i = 0; i < ninds; i++) { - stage = inds[i]->breedingFem(); - if (stage > 0 && fec[stage][0] > 0.0) { // (potential) breeding female - if (dem.stageStruct) { - // determine whether she must miss current breeding attempt - ind = inds[i]->getStats(); - if (ind.fallow >= sstruct.repInterval) { - if (pRandom->Bernoulli(sstruct.probRep)) skipbreeding = false; - else skipbreeding = true; - } - else skipbreeding = true; // cannot breed this time - } - else skipbreeding = false; // not structured - always breed - if (skipbreeding) { - inds[i]->incFallow(); - } - else { // attempt to breed - inds[i]->resetFallow(); - // NOTE: FOR COMPLEX SEXUAL MODEL, NO. OF FEMALES *ACTUALLY* BREEDING DOES NOT - // NECESSARILY EQUAL THE EXPECTED NO. FROM EQN. 7 IN THE MANUAL... - if (pRandom->Bernoulli(propBreed)) { - expected = fec[stage][0]; // breeds -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): THIS LINE SHOULD NOT APPEAR FOR GOBY MODEL" -// << " expected=" << expected -// << endl; -#endif - } - else expected = 0.0; // fails to breed - if (expected <= 0.0) njuvs = 0; - else njuvs = pRandom->Poisson(expected); -#if RSDEBUG -//DEBUGLOG << "Population::reproduction():" -// << " i " << i << " ID=" << inds[i]->getId() << " stage=" << stage -// << " expected=" << expected << " njuvs=" << njuvs << endl; -#endif - if (njuvs > 0) - { - nj = (int)juvs.size(); - // select father at random from breeding males ... - int rrr = 0; - if (nmales > 1) rrr = pRandom->IRandom(0,nmales-1); - father = fathers[rrr]; -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): i = " << i << " rrr = " << rrr -// << " father = " << father << endl; -#endif - pCell = pPatch->getRandomCell(); - for (int j = 0; j < njuvs; j++) { -#if RSDEBUG - // NOTE: CURRENTLY SETTING ALL INDIVIDUALS TO RECORD NO. OF STEPS ... - juvs.push_back(new Individual(pCell,pPatch,0,0,0,dem.propMales,true,trfr.moveType)); -#else - juvs.push_back(new Individual(pCell,pPatch,0,0,0,dem.propMales,trfr.moveModel,trfr.moveType)); -#endif - sex = juvs[nj+j]->getSex(); - nInds[0][sex]++; - if (emig.indVar || trfr.indVar || sett.indVar || gen.neutralMarkers) - { - // juv inherits genome from parents - juvs[nj+j]->setGenes(pSpecies,inds[i],father,resol); - } - } - } - } - } - } - } - fathers.clear(); - break; - -} // end of switch (dem.repType) - -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): before reprodn. " << " inds.size() = " << inds.size() -// << endl; -#endif - -// THIS MAY NOT BE CORRECT FOR MULTIPLE SPECIES IF THERE IS SOME FORM OF -// CROSS-SPECIES DENSITY-DEPENDENT FECUNDITY - -#if RSDEBUG -//DEBUGLOG << "Population::reproduction(): after reprodn. this = " << this -// << " juvs.size() = " << juvs.size() << " inds.size() = " << inds.size() -// << endl; -#endif - -} - -// Following reproduction of ALL species, add juveniles to the population prior to dispersal -void Population::fledge(void) -{ -#if RSDEBUG -//DEBUGLOG << "Population::fledge(): this=" << this -// << " ninds=" << (int)inds.size() -// << " njuvs=" << (int)juvs.size() -// << endl; -#endif -demogrParams dem = pSpecies->getDemogr(); - -if (dem.stageStruct) { // juveniles are added to the individuals vector - inds.insert(inds.end(),juvs.begin(),juvs.end()); -// nInds += nJuvs; nJuvs = 0; -} -else { // all adults die and juveniles replace adults - int ninds = (int)inds.size(); - for (int i = 0; i < ninds; i++) { - delete inds[i]; - } - inds.clear(); - for (int sex = 0; sex < nSexes; sex++) { - nInds[1][sex] = 0; // set count of adults to zero - } - inds = juvs; -} -juvs.clear(); - -} - -// Determine which individuals will disperse -void Population::emigration(float localK) -{ -int nsexes; -double disp,Pdisp,NK; -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -emigRules emig = pSpecies->getEmig(); -emigTraits eparams; -trfrRules trfr = pSpecies->getTrfr(); -indStats ind; -#if RSDEBUG -//DEBUGLOG << "Population::emigration(): this=" << this -// << " nStages=" << sstruct.nStages -//// << " emig.emigGenes[0]=" << emig.emigGenes[0] -//// << " emig.emigGenes[1]=" << emig.emigGenes[1] -// << endl; -#endif - -// to avoid division by zero, assume carrying capacity is at least one individual -// localK can be zero if there is a moving gradient or stochasticity in K -if (localK < 1.0) localK = 1.0; -NK = (float)totalPop() / localK; - -int ninds = (int)inds.size(); - -// set up local copy of emigration probability table -// used when there is no individual variability -// NB - IT IS DOUBTFUL THIS CONTRIBUTES ANY SUBSTANTIAL TIME SAVING -if (dem.repType == 0) nsexes = 1; else nsexes = 2; -double Pemig[NSTAGES][NSEXES]; - -for (int stg = 0; stg < sstruct.nStages; stg++) { - for (int sex = 0; sex < nsexes; sex++) { - if (emig.indVar) Pemig[stg][sex] = 0.0; - else { - if (emig.densDep) { - if (emig.sexDep) { - if (emig.stgDep) { - eparams = pSpecies->getEmigTraits(stg,sex); - } - else { - eparams = pSpecies->getEmigTraits(0,sex); - } - } - else { // !emig.sexDep - if (emig.stgDep) { - eparams = pSpecies->getEmigTraits(stg,0); - } - else { - eparams = pSpecies->getEmigTraits(0,0); - } - } - Pemig[stg][sex] = eparams.d0/(1.0+exp(-(NK - eparams.beta)*eparams.alpha)); -#if RSDEBUG -//if (ppLand.patch_model) { -// DEBUGLOG << "Population::emigration(): stg=" << stg << " sex=" << sex -// << " totalPop=" << totalPop() << " localK=" << localK << " NK=" << NK -// << " d0=" << eparams.d0 << " beta=" << eparams.beta << " alpha=" << eparams.alpha -// << " Pemig[stg][sex]=" << Pemig[stg][sex] -// << endl; -//} -#endif - } - else { // density-independent - if (emig.sexDep) { - if (emig.stgDep) { - Pemig[stg][sex] = pSpecies->getEmigD0(stg,sex); - } - else { // !emig.stgDep - Pemig[stg][sex] = pSpecies->getEmigD0(0,sex); - } - } - else { // !emig.sexDep - if (emig.stgDep) { - Pemig[stg][sex] = pSpecies->getEmigD0(stg,0); - } - else { // !emig.stgDep - Pemig[stg][sex] = pSpecies->getEmigD0(0,0); - } - } - } - } // end of !emig.indVar -#if RSDEBUG -//DEBUGLOG << "Population::emigration(): this=" << (int)this -// << " totalPop()=" << totalPop() -// << " Pemig[" << stg << "][" << sex << "]="<< Pemig[stg][sex] << endl; -#endif - } -} - -//#if GROUPDISP -//bool newgroup = true; -//int currentsize = 0; -//#endif // GROUPDISP - -//#if PARTMIGRN -//double cumprop[7]; -//cumprop[0] = 0.0; -//for (int i = 1; i < 7; i++) { -// cumprop[i] = cumprop[i-1] + pSpecies->getPropDispMigrn(i); -//#if RSDEBUG -//DEBUGLOG << "Population::emigration(): i=" << i -// << " cumprop[i]=" << cumprop[i] -// << endl; -//#endif -//} -//#endif // PARTMIGRN -// - -for (int i = 0; i < ninds; i++) { - ind = inds[i]->getStats(); - if (ind.status < 1) - { - if (emig.indVar) { // individual variability in emigration - if (dem.stageStruct && ind.stage != emig.emigStage) { - // emigration may not occur - Pdisp = 0.0; - } - else { // non-structured or individual is in emigration stage - eparams = inds[i]->getEmigTraits(); - if (emig.densDep) { // density-dependent - NK = (float)totalPop() / localK; - Pdisp = eparams.d0/(1.0+exp(-(NK - eparams.beta)*eparams.alpha)); - } - else { // density-independent - if (emig.sexDep) { - Pdisp = Pemig[0][ind.sex] + eparams.d0; - } - else { - Pdisp = Pemig[0][0] + eparams.d0; - } - } - } - } // end of individual variability - else { // no individual variability - - if (emig.densDep) { - if (emig.sexDep) { - if (emig.stgDep) { - Pdisp = Pemig[ind.stage][ind.sex]; - } - else { - Pdisp = Pemig[0][ind.sex]; - } - } - else { // !emig.sexDep - if (emig.stgDep) { - Pdisp = Pemig[ind.stage][0]; - } - else { - Pdisp = Pemig[0][0]; - } - } -#if RSDEBUG -//if (ppLand.patch_model) { -// DEBUGLOG << "Population::emigration(): i=" << i << " sex=" << ind.sex << " stage=" << ind.stage -// << " totalPop=" << totalPop() << " localK=" << localK << " NK=" << NK -// << " Pdisp=" << Pdisp -// << endl; -//} -#endif - } - else { // density-independent - if (emig.sexDep) { - if (emig.stgDep) { - Pdisp = Pemig[ind.stage][ind.sex]; - } - else { // !emig.stgDep - Pdisp = Pemig[0][ind.sex]; - } - } - else { // !emig.sexDep - if (emig.stgDep) { - Pdisp = Pemig[ind.stage][0]; - } - else { // !emig.stgDep - Pdisp = Pemig[0][0]; - } - } -//#if GROUPDISP -// if (emig.groupdisp) { -// if (Pdisp > 0) { -// -// } -// -// } -//#endif // GROUPDISP - } - - - } // end of no individual variability - - disp = pRandom->Bernoulli(Pdisp); -#if RSDEBUG -//DEBUGLOG << "Population::emigration(): i=" << i << " sex=" << ind.sex << " stage=" << ind.stage -// << " Pdisp=" << Pdisp << " disp=" << disp << endl; -#endif - - if (disp == 1) { // emigrant - inds[i]->setStatus(1); - } - } // end of if (ind.status < 1) condition -} // end of for loop -} - -// All individuals emigrate after patch destruction -void Population::allEmigrate(void) { -int ninds = (int)inds.size(); -for (int i = 0; i < ninds; i++) { - inds[i]->setStatus(1); -} -} - -// If an Individual has been identified as an emigrant, remove it from the Population -disperser Population::extractDisperser(int ix) { -disperser d; -indStats ind = inds[ix]->getStats(); -#if RSDEBUG -//if (ind.status > 0) { -// DEBUGLOG << "Population::extractDisperser(): ix = " << ix << " inds[ix] = " << inds[ix] -// << " indId = " << inds[ix]->getId() << " ind.status = " << ind.status -// << endl; -//} -#endif -if (ind.status == 1) { // emigrant - d.pInd = inds[ix]; d.yes = true; - inds[ix] = 0; - nInds[ind.stage][ind.sex]--; -} -else { - d.pInd = NULL; d.yes = false; -} -return d; -} - -// For an individual identified as being in the matrix population: -// if it is a settler, return its new location and remove it from the current population -// otherwise, leave it in the matrix population for possible reporting before deletion -disperser Population::extractSettler(int ix) { -disperser d; -Cell* pCell; -//Patch* pPatch; - -indStats ind = inds[ix]->getStats(); - -pCell = inds[ix]->getLocn(1); -#if RSDEBUG -//DEBUGLOG << "Population::extractSettler(): ix = " << ix << " inds[ix] = " << inds[ix] -// << " indId = " << inds[ix]->getId() << " ind.status = " << ind.status << endl; -#endif -d.pInd = inds[ix]; d.pCell = pCell; d.yes = false; -if (ind.status == 4 || ind.status == 5) { // settled - d.yes = true; - inds[ix] = 0; - nInds[ind.stage][ind.sex]--; -} -return d; -} - -// Add a specified individual to the new/current dispersal group -// Add a specified individual to the population -void Population::recruit(Individual *pInd) { -inds.push_back(pInd); -indStats ind = pInd->getStats(); -nInds[ind.stage][ind.sex]++; -#if RSDEBUG -//DEBUGLOG << "Population::recruit(): patchNum=" << pPatch->getPatchNum() -// << " indId=" << pInd->getId() -// << " nInds[" << ind.stage << "][" << ind.sex << "]=" << nInds[ind.stage][ind.sex] -// << endl; -#endif -} - -//--------------------------------------------------------------------------- - -// Transfer is run for populations in the matrix only -#if RS_RCPP // included also SEASONAL -int Population::transfer(Landscape *pLandscape,short landIx,short nextseason) -#else -int Population::transfer(Landscape *pLandscape,short landIx) -#endif -{ -int ndispersers = 0; -int disperser; -short othersex; -bool mateOK,densdepOK; -intptr patch,popn; -int patchnum; -double localK,popsize,settprob; -Patch *pPatch = 0; -Cell *pCell = 0; -indStats ind; -Population *pNewPopn = 0; -locn newloc,nbrloc; - -landData ppLand = pLandscape->getLandData(); -short reptype = pSpecies->getRepType(); -trfrRules trfr = pSpecies->getTrfr(); -settleType settletype = pSpecies->getSettle(); -settleRules sett; -settleTraits settDD; -settlePatch settle; -simParams sim = paramsSim->getSim(); - -// each individual takes one step -// for dispersal by kernel, this should be the only step taken -int ninds = (int)inds.size(); -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 0000: ninds = " << ninds -// << " ndispersers = " << ndispersers << endl; -#endif -for (int i = 0; i < ninds; i++) { -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 1111: i = " << i << " ID = " << inds[i]->getId() -// << endl; -#endif - if (trfr.moveModel) { -#if RSDEBUG -//pCell = inds[i]->getLocn(1); -//locn loc = pCell->getLocn(); -//DEBUGLOG << "Population::transfer(): 1112: i = " << i << " ID = " << inds[i]->getId() -// << " before:" << " x = " << loc.x << " y = " << loc.y -// << endl; -#endif - disperser = inds[i]->moveStep(pLandscape,pSpecies,landIx,sim.absorbing); -#if RSDEBUG -//pCell = inds[i]->getLocn(1); -//newloc = pCell->getLocn(); -//DEBUGLOG << "Population::transfer(): 1113: i = " << i << " ID = " << inds[i]->getId() -// << " after: " << " x = " << newloc.x << " y = " << newloc.y -// << endl; -#endif - } - else { - disperser = inds[i]->moveKernel(pLandscape,pSpecies,reptype,sim.absorbing); - } - ndispersers += disperser; - if (disperser) { - if (reptype > 0) - { // sexual species - record as potential settler in new patch - if (inds[i]->getStatus() == 2) - { // disperser has found a patch - pCell = inds[i]->getLocn(1); - patch = pCell->getPatch(); - if (patch != 0) { // not no-data area - pPatch = (Patch*)patch; - pPatch->incrPossSettler(pSpecies,inds[i]->getSex()); - } - } - } - } -} -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 5555: ninds=" << ninds -// << " ndispersers=" << ndispersers << endl; -#endif - -// each individual which has reached a potential patch decides whether to settle -for (int i = 0; i < ninds; i++) { - ind = inds[i]->getStats(); - if (ind.sex == 0) othersex = 1; else othersex = 0; - if (settletype.stgDep) { - if (settletype.sexDep) sett = pSpecies->getSettRules(ind.stage,ind.sex); - else sett = pSpecies->getSettRules(ind.stage,0); - } - else { - if (settletype.sexDep) sett = pSpecies->getSettRules(0,ind.sex); - else sett = pSpecies->getSettRules(0,0); - } - if (ind.status == 2) - { // awaiting settlement - pCell = inds[i]->getLocn(1); - if (pCell == 0) { - // this condition can occur in a patch-based model at the time of a dynamic landscape - // change when there is a range restriction in place, since a patch can straddle the - // range restriction and an individual forced to disperse upon patch removal could - // start its trajectory beyond the boundary of the restrictyed range - such a model is - // not good practice, but the condition must be handled by killing the individual conceerned - ind.status = 6; - } - else { - -#if RSDEBUG -//newloc = pCell->getLocn(); -//DEBUGLOG << "Population::transfer(): 6666: i=" << i << " ID=" << inds[i]->getId() -// << " sex=" << ind.sex << " status=" << ind.status -// << " pCell=" << pCell << " x=" << newloc.x << " y=" << newloc.y -// << " findMate=" << sett.findMate -//// << " wait=" << sett.wait -//// << " go2nbrLocn=" << sett.go2nbrLocn -// << endl; -#endif - - mateOK = false; - if (sett.findMate) { - // determine whether at least one individual of the opposite sex is present in the - // new population - if (matePresent(pCell,othersex)) mateOK = true; -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 7777: othersex=" << othersex -// << " this=" << this << " pNewPopn=" << pNewPopn << " popsize=" << popsize << " mateOK=" << mateOK -// << endl; -#endif - } - else { // no requirement to find a mate - mateOK = true; - } - - densdepOK = false; - settle = inds[i]->getSettPatch(); - if (sett.densDep) - { - patch = pCell->getPatch(); -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 8880: i=" << i << " patch=" << patch -// << endl; -#endif - if (patch != 0) { // not no-data area - pPatch = (Patch*)patch; - if (settle.settleStatus == 0 - || settle.pSettPatch != pPatch) - // note: second condition allows for having moved from one patch to another - // adjacent one - { -// inds[i]->resetPathOut(); // reset steps out of patch to zero - // determine whether settlement occurs in the (new) patch - localK = (double)pPatch->getK(); - popn = pPatch->getPopn((intptr)pSpecies); -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 8881: i=" << i << " patchNum=" << pPatch->getPatchNum() -// << " localK=" << localK << " popn=" << popn << endl; -#endif - if (popn == 0) { // population has not been set up in the new patch - popsize = 0.0; - } - else { - pNewPopn = (Population*)popn; - popsize = (double)pNewPopn->totalPop(); - } - if (localK > 0.0) { - // make settlement decision - if (settletype.indVar) settDD = inds[i]->getSettTraits(); -#if RS_RCPP - else settDD = pSpecies->getSettTraits(ind.stage,ind.sex); -#else - else { - if (settletype.sexDep) { - if (settletype.stgDep) - settDD = pSpecies->getSettTraits(ind.stage,ind.sex); - else - settDD = pSpecies->getSettTraits(0,ind.sex); - } - else { - if (settletype.stgDep) - settDD = pSpecies->getSettTraits(ind.stage,0); - else - settDD = pSpecies->getSettTraits(0,0); - } - } -#endif //RS_RCPP - settprob = settDD.s0 / - (1.0 + exp(-(popsize/localK - (double)settDD.beta) * (double)settDD.alpha)); -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 8888: i=" << i << " ind.stage=" << ind.stage -// << " this=" << this << " pNewPopn=" << pNewPopn << " popsize=" << popsize -// << " localK=" << localK << " alpha=" << settDD.alpha << " beta=" << settDD.beta -// << " settprob=" << settprob -// << endl; -#endif - if (pRandom->Bernoulli(settprob)) { // settlement allowed - densdepOK = true; - settle.settleStatus = 2; - } - else { // settlement procluded - settle.settleStatus = 1; - } -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 8889: i=" << i -// << " settleStatus=" << settle.settleStatus << " mateOK=" << (int)mateOK; -//if (settle.settleStatus == 2 && mateOK) { -// DEBUGLOG << " SETTLES -"; -// if (ind.sex == 1) DEBUGLOG << " MALE "; else DEBUGLOG << " FEMALE "; -//} -//DEBUGLOG << endl; -#endif - settle.pSettPatch = pPatch; - } - inds[i]->setSettPatch(settle); - } - else { - if (settle.settleStatus == 2) { // previously allowed to settle - densdepOK = true; - } - } - } - } - else { // no density-dependent settlement - densdepOK = true; - settle.settleStatus = 2; - settle.pSettPatch = pPatch; - inds[i]->setSettPatch(settle); - } - - if (mateOK && densdepOK) { // can recruit to patch - ind.status = 4; - ndispersers--; - } - else { // does not recruit - if (trfr.moveModel) { - ind.status = 1; // continue dispersing, unless ... - // ... maximum steps has been exceeded - pathSteps steps = inds[i]->getSteps(); - settleSteps settsteps = pSpecies->getSteps(ind.stage,ind.sex); - if (steps.year >= settsteps.maxStepsYr) { - ind.status = 3; // waits until next year - } - if (steps.total >= settsteps.maxSteps) { - ind.status = 6; // dies - } - } - else { // dispersal kernel - if (sett.wait) { - ind.status = 3; // wait until next dispersal event - } - else { - ind.status = 6; // (dies unless a neighbouring cell is suitable) - } - ndispersers--; - } - } - } - - inds[i]->setStatus(ind.status); - } -#if RS_RCPP - // write each individuals current movement step and status to paths file - if (trfr.moveModel && sim.outPaths) { - if(nextseason >= sim.outStartPaths && nextseason%sim.outIntPaths==0) { - inds[i]->outMovePath(nextseason); - } - } -#endif - - if (!trfr.moveModel && sett.go2nbrLocn && (ind.status == 3 || ind.status == 6)) - { - // for kernel-based transfer only ... - // determine whether recruitment to a neighbouring cell is possible -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): neighbour cell search: sett.go2nbrLocn = " << sett.go2nbrLocn -// << " ind.status = " << ind.status -// << endl; -#endif - pCell = inds[i]->getLocn(1); - newloc = pCell->getLocn(); - vector nbrlist; - for (int dx = -1; dx < 2; dx++) { - for (int dy = -1; dy < 2; dy++) { - if (dx !=0 || dy != 0) { //cell is not the current cell - nbrloc.x = newloc.x + dx; nbrloc.y = newloc.y + dy; - if (nbrloc.x >= 0 && nbrloc.x <= ppLand.maxX - && nbrloc.y >= 0 && nbrloc.y <= ppLand.maxY) { // within landscape - // add to list of potential neighbouring cells if suitable, etc. - pCell = pLandscape->findCell(nbrloc.x,nbrloc.y); - if (pCell != 0) { // not no-data area - patch = pCell->getPatch(); - if (patch != 0) { // not no-data area - pPatch = (Patch*)patch; - patchnum = pPatch->getPatchNum(); - if (patchnum > 0 && pPatch != inds[i]->getNatalPatch()) - { // not the matrix or natal patch - if (pPatch->getK() > 0.0) - { // suitable - if (sett.findMate) { - if (matePresent(pCell,othersex)) nbrlist.push_back(pCell); - } - else - nbrlist.push_back(pCell); - } - } - } - } - } - } - } - } - int listsize = (int)nbrlist.size(); - if (listsize > 0) { // there is at least one suitable neighbouring cell - if (listsize == 1) { - inds[i]->moveto(nbrlist[0]); - } - else { // select at random from the list - int rrr = pRandom->IRandom(0,listsize-1); - inds[i]->moveto(nbrlist[rrr]); - } - } - // else list empty - do nothing - individual retains its current location and status - } -} -#if RSDEBUG -//DEBUGLOG << "Population::transfer(): 9999: ninds = " << ninds -// << " ndispersers = " << ndispersers << endl; -#endif - - -return ndispersers; -} - -// Determine whether there is a potential mate present in a patch which a potential -// settler has reached -bool Population::matePresent(Cell *pCell,short othersex) -{ -int patch; -Patch *pPatch; -Population *pNewPopn; -int popsize = 0; -bool matefound = false; - -patch = (int)pCell->getPatch(); -if (patch != 0) { - pPatch = (Patch*)pCell->getPatch(); - if (pPatch->getPatchNum() > 0) { // not the matrix patch - if (pPatch->getK() > 0.0) - { // suitable - pNewPopn = (Population*)pPatch->getPopn((intptr)pSpecies); - if (pNewPopn != 0) { - // count members of other sex already resident in the patch - for (int stg = 0; stg < nStages; stg++) { - popsize += pNewPopn->nInds[stg][othersex]; - } - } - if (popsize < 1) { - // add any potential settlers of the other sex - popsize += pPatch->getPossSettlers(pSpecies,othersex); - } - } - } -} -if (popsize > 0) matefound = true; -return matefound; -} - -//--------------------------------------------------------------------------- -// Determine survival and development and record in individual's status code -// Changes are NOT applied to the Population at this stage - -// FOR MULTIPLE SPECIES, MAY NEED TO SEPARATE OUT THIS IDENTIFICATION STAGE, -// SO THAT IT CAN BE PERFORMED FOR ALL SPECIES BEFORE ANY UPDATING OF POPULATIONS - -void Population::survival0(float localK,short option0,short option1) -{ -// option0: 0 - stage 0 (juveniles) only -// 1 - all stages -// 2 - stage 1 and above (all non-juveniles) -// option1: 0 - development only (when survival is annual) -// 1 - development and survival -// 2 - survival only (when survival is annual) - -#if RSDEBUG -//DEBUGLOG << "Population::survival0():" -// << " pSpecies=" << pSpecies << " this=" << this << " PatchNum=" << pPatch->getPatchNum() -//#if SEASONAL -// << " season=" << season -//#endif // SEASONAL -// << " localK=" << localK << " option=" << option -// << endl; -#endif - -densDepParams ddparams = pSpecies->getDensDep(); -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); - -// get surrent population size -int ninds = (int)inds.size(); -if (ninds == 0) return; - -// set up local copies of species development and survival tables -int nsexes; -if (dem.repType == 0) nsexes = 1; else nsexes = 2; -float dev[NSTAGES][NSEXES]; -float surv[NSTAGES][NSEXES]; -short minAge[NSTAGES][NSEXES]; -for (int stg = 0; stg < sstruct.nStages; stg++) { - for (int sex = 0; sex < nsexes; sex++) { - if (dem.stageStruct) { - if (dem.repType == 1) { // simple sexual model - // both sexes use development and survival recorded for females - dev[stg][sex] = pSpecies->getDev(stg,0); - surv[stg][sex] = pSpecies->getSurv(stg,0); - minAge[stg][sex] = pSpecies->getMinAge(stg,0); - } - else { - dev[stg][sex] = pSpecies->getDev(stg,sex); - surv[stg][sex] = pSpecies->getSurv(stg,sex); - minAge[stg][sex] = pSpecies->getMinAge(stg,sex); - } - if (option1 == 0) surv[stg][sex] = 1.0; // development only - all survive - if (option1 == 2) dev[stg][sex] = 0.0; // survival only - none develops - } - else { // non-structured population - if (stg == 1) { // adults - dev[stg][sex] = 0.0; surv[stg][sex] = 0.0; minAge[stg][sex] = 0; - } - else { // juveniles - dev[stg][sex] = 1.0; surv[stg][sex] = 1.0; minAge[stg][sex] = 0; - } - } -#if RSDEBUG -//DEBUGLOG << "Population::survival0(): 1111 " -// << " dev[" << stg << "][" << sex << "] = " << dev[stg][sex] -// << " surv[" << stg << "][" << sex << "] = " << surv[stg][sex] -// << endl; -#endif - } -} - -if (dem.stageStruct) { -#if RSDEBUG -// DEBUGLOG << "Population::survival0(): 2222 " -// << " ninds=" << ninds << " localK=" << localK -// << " effect of density dependence:" << endl; -// for (int st = 0; st < nStages; st++) { -// for (int sx = 0; sx < nsexes; sx++) { -// DEBUGLOG << "st=" << st << " sx=" << sx << " nInds=" << nInds[st][sx] << endl; -// } -// } -#endif - // apply density dependence in development and/or survival probabilities - for (int stg = 0; stg < nStages; stg++) { - for (int sex = 0; sex < nsexes; sex++) { - if (option1 != 2 && sstruct.devDens && stg > 0) { -#if RSDEBUG -// DEBUGLOG << "DD in DEVELOPMENT for stg=" << stg << " sex=" << sex << endl; -#endif - // NB DD in development does NOT apply to juveniles, - // which must develop to stage 1 if they survive - float effect = 0.0; - if (sstruct.devStageDens) { // stage-specific density dependence - // NOTE: matrix entries represent effect of ROW on COLUMN - // AND males precede females - float weight = 0.0; - for (int effstg = 0; effstg < nStages; effstg++) { - for (int effsex = 0; effsex < nSexes; effsex++) { - if (dem.repType == 2) { - int rowincr,colincr; - if (effsex == 0) rowincr = 1; else rowincr = 0; - if (sex == 0) colincr = 1; else colincr = 0; - weight = pSpecies->getDDwtDev(2*stg+colincr,2*effstg+rowincr); - } - else { - weight = pSpecies->getDDwtDev(stg,effstg); - } - effect += (float)nInds[effstg][effsex] * weight; -#if RSDEBUG -// DEBUGLOG << " effstg=" << effstg << " effsex=" << effsex; -// DEBUGLOG << " weight=" << weight << " effect=" << effect -// << endl; -#endif - } - } - } - else // not stage-specific - effect = (float)totalPop(); - if (localK > 0.0) - dev[stg][sex] *= exp(-(ddparams.devCoeff*effect)/localK); -#if RSDEBUG -//DEBUGLOG << "Population::survival0(): 2288 " << " effect=" << effect; -//if (localK > 0.0) -// DEBUGLOG << " exp=" << exp(-(ddparams.devCoeff*effect)/localK); -//DEBUGLOG << " dev[" << stg << "][" << sex << "] = " << dev[stg][sex] -// << endl; -#endif - } // end of if (sstruct.devDens && stg > 0) - if (option1 != 0 && sstruct.survDens) { -#if RSDEBUG -// DEBUGLOG << "DD in SURVIVAL for stg=" << stg << " sex=" << sex << endl; -#endif - float effect = 0.0; - if (sstruct.survStageDens) { // stage-specific density dependence - // NOTE: matrix entries represent effect of ROW on COLUMN - // AND males precede females - float weight = 0.0; - for (int effstg = 0; effstg < nStages; effstg++) { - for (int effsex = 0; effsex < nSexes; effsex++) { - if (dem.repType == 2) { - int rowincr,colincr; - if (effsex == 0) rowincr = 1; else rowincr = 0; - if (sex == 0) colincr = 1; else colincr = 0; - weight = pSpecies->getDDwtSurv(2*stg+colincr,2*effstg+rowincr); - } - else { - weight = pSpecies->getDDwtSurv(stg,effstg); - } - effect += (float)nInds[effstg][effsex] * weight; -#if RSDEBUG -// DEBUGLOG << " effstg=" << effstg << " effsex=" << effsex; -// DEBUGLOG << " weight=" << weight << " effect=" << effect -// << endl; -#endif - } - } - } - else // not stage-specific - effect = (float)totalPop(); - if (localK > 0.0) - surv[stg][sex] *= exp(-(ddparams.survCoeff*effect)/localK); -#if RSDEBUG -//DEBUGLOG << "Population::survival0(): 3333 " << " effect=" << effect; -//if (localK > 0.0) -// DEBUGLOG << " exp = " << exp(-(ddparams.survCoeff*effect)/localK); -//DEBUGLOG << " surv[" << stg << "][" << sex << "] = " << surv[stg][sex] -// << endl; -#endif - } // end of if (sstruct.survDens) - } - } -} - -// identify which individuals die or develop -#if RSDEBUG -//DEBUGLOG << "Population::survival0():" << " ninds " << ninds -// << endl; -#endif -for (int i = 0; i < ninds; i++) { - indStats ind = inds[i]->getStats(); -#if RSDEBUG -//DEBUGLOG << "Population::survival0():" -// << " i=" << i << " indId=" << inds[i]->getId() -// << " stage=" << ind.stage << " status=" << ind.status << " sex=" << ind.sex -//#if PARTMIGRN -// << " migrnstatus=" << inds[i]->getMigrnStatus() -//#endif // PARTMIGRN -// << endl; -#endif - if ((ind.stage == 0 && option0 < 2) || (ind.stage > 0 && option0 > 0)) { - // condition for processing the stage is met... - if (ind.status < 6) { // not already doomed - double probsurv = surv[ind.stage][ind.sex]; - // does the individual survive? - if (pRandom->Bernoulli(probsurv)) { // survives - // does the individual develop? - double probdev = dev[ind.stage][ind.sex]; - if (ind.stage < nStages-1) { // not final stage -#if RSDEBUG -//DEBUGLOG << "Population::survival0():" -// << " i=" << i << " indId=" << inds[i]->getId() -// << " age=" << ind.age << " minAge[stage+1]=" << minAge[ind.stage+1][ind.sex] -// << " probdev=" << probdev -// << endl; -#endif - if (ind.age >= minAge[ind.stage+1][ind.sex]) { // old enough to enter next stage -#if RSDEBUG -//DEBUGLOG << "Population::survival0():" -// << " i=" << i << " indId=" << inds[i]->getId() << " OLD ENOUGH" -// << endl; -#endif - if (pRandom->Bernoulli(probdev)) { - inds[i]->developing(); - } - } - } - } - else { // doomed to die -#if RSDEBUG -//DEBUGLOG << "Population::survival0():" -// << " i=" << i << " indId=" << inds[i]->getId() << " DIES" -// << endl; -#endif - inds[i]->setStatus(8); - } - } - } -#if RSDEBUG -//ind = inds[i]->getStats(); -//DEBUGLOG << "Population::survival0():" -// << " i = " << i << " ID = " << inds[i]->getId() -// << " stage = " << ind.stage << " status = " << ind.status -// << endl; -#endif -} -} - -// Apply survival changes to the population -void Population::survival1(void) -{ - -int ninds = (int)inds.size(); -#if RSDEBUG -//DEBUGLOG << "Population::survival1(): this=" << this -// << " patchNum=" << pPatch->getPatchNum() << " ninds=" << ninds -// << endl; -#endif -for (int i = 0; i < ninds; i++) { - indStats ind = inds[i]->getStats(); -#if RSDEBUG -//DEBUGLOG << "Population::survival1(): i=" << i -// << " indId=" << inds[i]->getId() << " stage=" << ind.stage << " sex=" << ind.sex -// << " isDeveloping=" << ind.isDeveloping << " status=" << ind.status -// << endl; -#endif - if (ind.status > 5) { // doomed to die - delete inds[i]; - inds[i] = NULL; - nInds[ind.stage][ind.sex]--; - } - else { - if (ind.isDeveloping) { // develops to next stage - nInds[ind.stage][ind.sex]--; - inds[i]->develop(); - nInds[ind.stage+1][ind.sex]++; - } - } -} -#if RSDEBUG -//DEBUGLOG << "Population::survival1(): this=" << this -// << " patchNum=" << pPatch->getPatchNum() << " completed individuals loop" -// << endl; -#endif - -#if RSDEBUG -//for (int i = 0; i < inds.size(); i++) { -//DEBUGLOG << "Population::survival1():" << " inds[" << i << "] = " << inds[i] << endl; -//} -#endif - -// remove pointers to dead individuals -clean(); -#if RSDEBUG -//DEBUGLOG << "Population::survival1(): this=" << this -// << " patchNum=" << pPatch->getPatchNum() << " finished" -// << endl; -#endif - -} - -void Population::ageIncrement(void) { -int ninds = (int)inds.size(); -stageParams sstruct = pSpecies->getStage(); -#if RSDEBUG -//DEBUGLOG << "Population::ageIncrement():" << " inds.size() = " << inds.size() -// << endl; -#endif -for (int i = 0; i < ninds; i++) { - inds[i]->ageIncrement(sstruct.maxAge); -} -} - -//--------------------------------------------------------------------------- -// Remove zero pointers to dead or dispersed individuals -void Population::clean(void) -{ -int ninds = (int)inds.size(); -if (ninds > 0) { -// sort (inds.begin(), inds.end()); -// reverse (inds.begin(), inds.end()); -// -// while (inds.size() > 0 && inds[inds.size()-1] == NULL ) { -// inds.pop_back(); -// } - // ALTERNATIVE METHOD: AVOIDS SLOW SORTING OF POPULATION - std::vector survivors; // all surviving individuals - for (int i = 0; i < ninds; i++) { - if (inds[i] != NULL) { - survivors.push_back(inds[i]); - } - } - inds.clear(); - inds = survivors; -#if RS_RCPP - shuffle(inds.begin(), inds.end(), pRandom->getRNG() ); -#else - -#if !RSDEBUG - // do not randomise individuals in RSDEBUG mode, as the function uses rand() - // and therefore the randomisation will differ between identical runs of RS - shuffle(inds.begin(), inds.end(), pRandom->getRNG() ); -#endif // !RSDEBUG - -#endif // RS_RCPP -} -} - -//--------------------------------------------------------------------------- -// Open population file and write header record -bool Population::outPopHeaders(int landNr,bool patchModel) { - -if (landNr == -999) { // close file - if (outPop.is_open()) outPop.close(); - outPop.clear(); - return true; -} - -string name; -//landParams ppLand = pLandscape->getLandParams(); -//envStochParams env = paramsStoch->getStoch(); -simParams sim = paramsSim->getSim(); -envGradParams grad = paramsGrad->getGradient(); - -// NEED TO REPLACE CONDITIONAL COLUMNS BASED ON ATTRIBUTES OF ONE SPECIES TO COVER -// ATTRIBUTES OF *ALL* SPECIES AS DETECTED AT MODEL LEVEL -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); - -if (sim.batchMode) { - name = paramsSim->getDir(2) - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(landNr) + "_Pop.txt"; -} -else{ - name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) +"_Pop.txt"; -} -outPop.open(name.c_str()); -outPop << "Rep\tYear\tRepSeason"; -if (patchModel) outPop << "\tPatchID\tNcells"; -else outPop << "\tx\ty"; -// determine whether environmental data need be written for populations -bool writeEnv = false; -if (grad.gradient) writeEnv = true; -if (paramsStoch->envStoch()) writeEnv = true; -if (writeEnv) outPop << "\tEpsilon\tGradient\tLocal_K"; -outPop << "\tSpecies\tNInd"; -#if RSDEBUG -//DEBUGLOG << "Population::outPopHeaders(): this=" << this -// << " patchNum=" << pPatch->getPatchNum() -// << " totalPop()=" << totalPop() -// << " nStages=" << nStages << " nSexes=" << nSexes -// << endl; -#endif -if (dem.stageStruct) { - if (dem.repType == 0) - { - for (int i = 1; i < sstruct.nStages; i++) outPop << "\tNInd_stage" << i ; - outPop << "\tNJuvs"; - } - else { - for (int i = 1; i < sstruct.nStages; i++) - outPop << "\tNfemales_stage" << i << "\tNmales_stage" << i ; - outPop << "\tNJuvFemales\tNJuvMales"; - } -} -else { - if (dem.repType != 0) outPop << "\tNfemales\tNmales"; -} -outPop << endl; - -return outPop.is_open(); -} - -//--------------------------------------------------------------------------- -// Write record to population file -void Population::outPopulation(int rep,int yr,int gen,float eps, - bool patchModel,bool writeEnv,bool gradK) -{ -Cell *pCell; - -#if RSDEBUG -//DEBUGLOG << "Population::outPopulations(): this=" << this -// << " writeEnv " << (int)writeEnv -// << endl; -#endif - -// NEED TO REPLACE CONDITIONAL COLUMNS BASED ON ATTRIBUTES OF ONE SPECIES TO COVER -// ATTRIBUTES OF *ALL* SPECIES AS DETECTED AT MODEL LEVEL -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -popStats p; - -outPop << rep << "\t" << yr << "\t" << gen; -if (patchModel) { - outPop << "\t" << pPatch->getPatchNum(); - outPop << "\t" << pPatch->getNCells(); -} -else { - locn loc = pPatch->getCellLocn(0); - outPop << "\t" << loc.x << "\t" << loc.y; -} -if (writeEnv) { - if (pPatch->getPatchNum() == 0) { // matrix - outPop << "\t0\t0\t0"; - } - else { - float k = pPatch->getK(); - float envval = 0.0; - pCell = pPatch->getRandomCell(); - if (pCell != 0) envval = pCell->getEnvVal(); - outPop << "\t" << eps << "\t" << envval << "\t" << k; - } -} -#if RSDEBUG -//DEBUGLOG << "Population::outPopulation(): this=" << this -// << " patchNum=" << pPatch->getPatchNum() -// << " totalPop()=" << totalPop() -// << " nStages=" << nStages << " nSexes=" << nSexes -// << endl; -#endif -outPop << "\t" << pSpecies->getSpNum(); -if (dem.stageStruct) { - p = getStats(); - outPop << "\t" << p.nNonJuvs; - // non-juvenile stage totals from permanent array - for (int stg = 1; stg < nStages; stg++) { - for (int sex = 0; sex < nSexes; sex++) { - outPop << "\t" << nInds[stg][sex]; - } - } - // juveniles from permanent array - for (int sex = 0; sex < nSexes; sex++) { - outPop << "\t" << nInds[0][sex]; - } -} -else { // non-structured population - outPop << "\t" << totalPop(); - if (dem.repType != 0) - { // sexual model - outPop << "\t" << nInds[1][0] << "\t" << nInds[1][1]; - } -} -outPop << endl; - -/* -#if RS_ABC -obsdata obs; -if (abcYear) { - int nobs = (int)pABCmaster->NObs(); - for (int i = 0; i < nobs; i++) { - obs = pABCmaster->getObsData(i); -#if RSDEBUG -//DEBUGLOG << "Population::outPopulation(): this=" << this << " i=" << i << " yr=" << yr -// << " obs.year=" << obs.year << " obs.type=" << obs.type << " obs.name=" << obs.name -// << " obs.x=" << obs.x << " obs.y=" << obs.y -// << endl; -#endif - if (obs.year == yr && obs.type == 2) { - if (obs.name == "NInds" || obs.name == "Occupied") { - bool match = false; - if (patchModel) { - if (obs.x == pPatch->getPatchNum()) { - match = true; -#if RSDEBUG -//DEBUGLOG << "Population::outPopulation(): i=" << i << " PROCESS Population NInds" -// << " obs.id=" << obs.id << " obs.value=" << obs.value << " obs.x=" << obs.x -// << " pPatch->PatchNum()=" << pPatch->getPatchNum() -// << " totalPop()=" << totalPop() << " p.nNonJuvs=" << p.nNonJuvs -// << endl; -#endif - } - } - else { - locn loc = pPatch->getCentroid(); - if (obs.x == loc.x && obs.y == loc.y) { - match = true; -#if RSDEBUG -DEBUGLOG << "Population::outPopulation(): i=" << i << " PROCESS Population NInds" - << " obs.id=" << obs.id << " obs.value=" << obs.value << " obs.x=" - << obs.x << " obs.y=" << obs.y << " loc.x=" << loc.x << " loc.y=" << loc.y - << " totalPop()=" << totalPop() << " p.nNonJuvs=" << p.nNonJuvs - << endl; -#endif - } - } - if (match) { - if (obs.name == "NInds") { - if (dem.stageStruct) - pABCmaster->AddNewPred(sim.simulation,obs.id,rep,obs.value,p.nNonJuvs,obs.weight); - else - pABCmaster->AddNewPred(sim.simulation,obs.id,rep,obs.value,totalPop(),obs.weight); - } - else { // obs.name == "Occupied" - pABCmaster->AddNewPred(sim.simulation,obs.id,rep,obs.value,p.breeding,obs.weight); - } - } - } - } - } -} -#endif // ABC -*/ -} - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Open individuals file and write header record -void Population::outIndsHeaders(int rep,int landNr,bool patchModel) -{ - -if (landNr == -999) { // close file - if (outInds.is_open()) { - outInds.close(); outInds.clear(); - } - return; -} - -string name; -demogrParams dem = pSpecies->getDemogr(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -simParams sim = paramsSim->getSim(); - -if (sim.batchMode) { - name = paramsSim->getDir(2) - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) - + "_Land" + Int2Str(landNr) + "_Rep" + Int2Str(rep) + "_Inds.txt"; -} -else { - name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) - + "_Rep" + Int2Str(rep) +"_Inds.txt"; -} -outInds.open(name.c_str()); - -outInds << "Rep\tYear\tRepSeason\tSpecies\tIndID\tStatus"; -if (patchModel) outInds << "\tNatal_patch\tPatchID"; -else outInds << "\tNatal_X\tNatal_Y\tX\tY"; -if (dem.repType != 0) outInds << "\tSex"; -if (dem.stageStruct) outInds << "\tAge\tStage"; -if (emig.indVar) { - if (emig.densDep) outInds << "\tD0\tAlpha\tBeta"; - else outInds << "\tEP"; -} -if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 1) { // SMS - outInds << "\tDP\tGB\tAlphaDB\tBetaDB"; - } - if (trfr.moveType == 2) { // CRW - outInds << "\tStepLength\tRho"; - } - } - else { // kernel - outInds << "\tMeanDistI"; - if (trfr.twinKern) outInds << "\tMeanDistII\tPKernelI"; - } -} -if (sett.indVar) { - outInds << "\tS0\tAlphaS\tBetaS"; -} -outInds << "\tDistMoved"; -#if RSDEBUG -// ALWAYS WRITE NO. OF STEPS -outInds << "\tNsteps"; -#else -if (trfr.moveModel) outInds << "\tNsteps"; -#endif -outInds << endl; -} - -//--------------------------------------------------------------------------- -// Write records to individuals file -void Population::outIndividual(Landscape *pLandscape,int rep,int yr,int gen, - int patchNum) -{ -//int x, y, p_id; -bool writeInd; -pathSteps steps; -Cell *pCell; - -landParams ppLand = pLandscape->getLandParams(); -//landOrigin lim = pLandscape->getOrigin(); -demogrParams dem = pSpecies->getDemogr(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -short spNum = pSpecies->getSpNum(); - -int ninds = (int)inds.size(); - -for (int i = 0; i < ninds; i++) { - indStats ind = inds[i]->getStats(); - if (yr == -1) { // write all initialised individuals - writeInd = true; - outInds << rep << "\t" << yr << "\t" << dem.repSeasons-1; - } - else { - if (dem.stageStruct && gen < 0) { // write status 9 individuals only - if (ind.status == 9) { - writeInd = true; - outInds << rep << "\t" << yr << "\t" << dem.repSeasons-1; - } - else writeInd = false; - } - else { - writeInd = true; - outInds << rep << "\t" << yr << "\t" << gen; - } - } - if (writeInd) { - outInds << "\t" << spNum << "\t" << inds[i]->getId(); - if (dem.stageStruct) outInds << "\t" << ind.status; - else { // non-structured population - outInds << "\t" << ind.status; - } - pCell = inds[i]->getLocn(1); - locn loc; - if (pCell == 0) loc.x = loc.y = -1; // beyond boundary or in no-data cell - else loc = pCell->getLocn(); - pCell = inds[i]->getLocn(0); - locn natalloc = pCell->getLocn(); -//#if SEASONAL -// pCell = inds[i]->getLocn(2); -// locn prevloc = pCell->getLocn(); -//#endif - if (ppLand.patchModel) { - outInds << "\t" << inds[i]->getNatalPatch()->getPatchNum(); - if (loc.x == -1) outInds << "\t-1"; - else outInds << "\t" << patchNum; - } - else { // cell-based model - // EITHER write co-ordinates in cell units ... - outInds << "\t" << (float)natalloc.x << "\t" << natalloc.y; - outInds << "\t" << (float)loc.x << "\t" << (float)loc.y ; - // ... OR write co-ordinates in real-world units -// outInds << "\t" << (float)natalloc.x * (float)ppLand.resol + (float)lim.minEast -// << "\t" << natalloc.y * (float)ppLand.resol + (float)lim.minNorth; -// outInds << "\t" << (float)loc.x * (float)ppLand.resol + (float)lim.minEast -// << "\t" << (float)loc.y * (float)ppLand.resol + (float)lim.minNorth; - } - if (dem.repType != 0) outInds <<"\t" << ind.sex; - if (dem.stageStruct) outInds <<"\t" << ind.age <<"\t"<< ind.stage; - - if (emig.indVar) { - emigTraits e = inds[i]->getEmigTraits(); - if (emig.densDep) { - outInds << "\t" << e.d0 << "\t" << e.alpha << "\t" << e.beta; - } - else { - outInds << "\t" << e.d0; - } - } // end of if (emig.indVar) - - if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 1) { // SMS - trfrSMSTraits s = inds[i]->getSMSTraits(); - outInds << "\t" << s.dp << "\t" << s.gb; - outInds << "\t" << s.alphaDB << "\t" << s.betaDB; - } // end of SMS - if (trfr.moveType == 2) { // CRW - trfrCRWTraits c = inds[i]->getCRWTraits(); - outInds << "\t" << c.stepLength << "\t" << c.rho; -#if RSDEBUG -//DEBUGLOG << "Population::outIndividual():" -// << " patchNum=" << patchNum << " i=" << i << " ID=" << inds[i]->getId() -// << " nTrfrGenes=" << nTrfrGenes << " loc[0][0].allele[0]=" << loc[0][0].allele[0] -// << endl; -#endif - } // end of CRW - } - else { // kernel - trfrKernTraits k = inds[i]->getKernTraits(); - if (trfr.twinKern) - { - outInds << "\t" << k.meanDist1 << "\t" << k.meanDist2 << "\t" << k.probKern1; - } - else { - outInds << "\t" << k.meanDist1; - } - } - } - - if (sett.indVar) { - settleTraits s = inds[i]->getSettTraits(); - outInds << "\t" << s.s0 << "\t" << s.alpha << "\t" << s.beta; - } - - // distance moved (metres) - if (loc.x == -1) outInds << "\t-1"; - else { - float d = ppLand.resol * sqrt((float)((natalloc.x-loc.x)*(natalloc.x-loc.x) - + (natalloc.y-loc.y)*(natalloc.y-loc.y))); - outInds << "\t" << d; - } -#if RSDEBUG - // ALWAYS WRITE NO. OF STEPS - steps = inds[i]->getSteps(); - outInds << "\t" << steps.year; -#else - if (trfr.moveModel) { - steps = inds[i]->getSteps(); - outInds << "\t" << steps.year; - } -#endif - outInds << endl; - } // end of writeInd condition - -} -} - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Write records to genetics file -void Population::outGenetics(const int rep,const int year,const int landNr) -{ - -simParams sim = paramsSim->getSim(); - -if (landNr >= 0) { // open file - Genome *pGenome; - genomeData gen = pSpecies->getGenomeData(); - if (gen.trait1Chromosome) { - pGenome = new Genome(pSpecies->getNChromosomes(),pSpecies->getNLoci(0), - pSpecies->isDiploid()); - } - else { - pGenome = new Genome(pSpecies); - } - pGenome->outGenHeaders(rep,landNr,sim.outGenXtab); - delete pGenome; - return; -} - -if (landNr == -999) { // close file - Genome *pGenome = new Genome(); - pGenome->outGenHeaders(rep,landNr,sim.outGenXtab); - delete pGenome; - return; -} - -short spNum = pSpecies->getSpNum(); -short nstages = 1; -if (pSpecies->stageStructured()) { - stageParams sstruct = pSpecies->getStage(); - nstages = sstruct.nStages; -} - - -int ninds = (int)inds.size(); -for (int i = 0; i < ninds; i++) { - indStats ind = inds[i]->getStats(); - if (year == 0 || sim.outGenType == 1 - || (sim.outGenType == 0 && ind.stage == 0) - || (sim.outGenType == 2 && ind.stage == nstages-1)) { - inds[i]->outGenetics(rep,year,spNum,landNr,sim.outGenXtab); - } -} - -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - - diff --git a/RangeShiftR/src/RScore/Population.h b/RangeShiftR/src/RScore/Population.h deleted file mode 100644 index 9c8efd8..0000000 --- a/RangeShiftR/src/RScore/Population.h +++ /dev/null @@ -1,248 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Population - -Implements the Population class - -There is ONE instance of a Population for each Species within each SubCommunity -(including the matrix). The Population holds a list of all the Individuals in -the Population. - -The matrix Population(s) hold(s) Individuals which are currently in the process -of transfer through the matrix. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 22 January 2022 by Steve Palmer - -------------------------------------------------------------------------------*/ - -#ifndef PopulationH -#define PopulationH - -#include -#include -//#include -//#include -//#include -using namespace std; - -#include "Parameters.h" -#include "Individual.h" -#include "Species.h" -#include "Landscape.h" -#include "Patch.h" -#include "Cell.h" - -//--------------------------------------------------------------------------- - -struct popStats { - Species *pSpecies; Patch *pPatch; int spNum,nInds,nNonJuvs,nAdults; bool breeding; -}; -struct disperser { - Individual *pInd; Cell *pCell; bool yes; -}; -struct traitsums { // sums of trait genes for dispersal - int ninds[NSEXES]; // no. of individuals - double sumD0[NSEXES]; // sum of maximum emigration probability - double ssqD0[NSEXES]; // sum of squares of maximum emigration probability - double sumAlpha[NSEXES]; // sum of slope of emigration dens-dep reaction norm - double ssqAlpha[NSEXES]; // sum of squares of slope of emigration den-dep reaction norm - double sumBeta[NSEXES]; // sum of inflection point of emigration reaction norm - double ssqBeta[NSEXES]; // sum of squares of inflection point of emigration reaction norm - double sumDist1[NSEXES]; // sum of kernel I mean - double ssqDist1[NSEXES]; // sum of squares of kernel I mean - double sumDist2[NSEXES]; // sum of kernel II mean - double ssqDist2[NSEXES]; // sum of squares of kernel II mean - double sumProp1[NSEXES]; // sum of propn using kernel I - double ssqProp1[NSEXES]; // sum of squares of propn using kernel I - double sumDP[NSEXES]; // sum of SMS directional persistence - double ssqDP[NSEXES]; // sum of squares of SMS directional persistence - double sumGB[NSEXES]; // sum of SMS goal bias - double ssqGB[NSEXES]; // sum of squares of SMS goal bias - double sumAlphaDB[NSEXES]; // sum of SMS dispersal bias decay rate - double ssqAlphaDB[NSEXES]; // sum of squares of SMS dispersal bias decay rate - double sumBetaDB[NSEXES]; // sum of SMS dispersal bias decay infl. pt. - double ssqBetaDB[NSEXES]; // sum of squares of SMS dispersal bias decay infl. pt. - double sumStepL[NSEXES]; // sum of CRW step length - double ssqStepL[NSEXES]; // sum of squares of CRW step length - double sumRho[NSEXES]; // sum of CRW correlation coefficient - double ssqRho[NSEXES]; // sum of squares of CRW correlation coefficient - double sumS0[NSEXES]; // sum of maximum settlement probability - double ssqS0[NSEXES]; // sum of squares of maximum settlement probability - double sumAlphaS[NSEXES]; // sum of slope of settlement den-dep reaction norm - double ssqAlphaS[NSEXES]; // sum of squares of slope of settlement den-dep reaction norm - double sumBetaS[NSEXES]; // sum of inflection point of settlement reaction norm - double ssqBetaS[NSEXES]; // sum of squares of inflection point of settlement reaction norm -}; - -class Population { - -public: - Population(void); // default constructor - Population( // constructor for a Population of a specified size - Species*, // pointer to Species - Patch*, // pointer to Patch - int, // no. of Individuals - int // Landscape resolution - ); - ~Population(void); - traitsums getTraits(Species*); - popStats getStats(void); - Species* getSpecies(void); - int getNInds(void); - int totalPop(void); - int stagePop( // return no. of Individuals in a specified stage - int // stage - ); - void extirpate(void); // Remove all individuals - void reproduction( - const float, // local carrying capacity - const float, // effect of environmental gradient and/or stochasticty - const int // Landscape resolution - ); - // Following reproduction of ALL species, add juveniles to the population - void fledge(void); - void emigration( // Determine which individuals will disperse - float // local carrying capacity - ); - void allEmigrate(void); // All individuals emigrate after patch destruction - // If an individual has been identified as an emigrant, remove it from the Population - disperser extractDisperser( - int // index no. to the Individual in the inds vector - ); - // For an individual identified as being in the matrix population: - // if it is a settler, return its new location and remove it from the current population - // otherwise, leave it in the matrix population for possible reporting before deletion - disperser extractSettler( - int // index no. to the Individual in the inds vector - ); - void recruit( // Add a specified individual to the population - Individual* // pointer to Individual - ); -#if RS_RCPP - int transfer( // Executed for the Population(s) in the matrix only - Landscape*, // pointer to Landscape - short, // landscape change index - short // year - ); - // Determine whether there is a potential mate present in a patch which a potential - // settler has reached - bool matePresent( - Cell*, // pointer to the Cell which the potential settler has reached - short // sex of the required mate (0 = female, 1 = male) - ); -#else - int transfer( // Executed for the Population(s) in the matrix only - Landscape*, // pointer to Landscape - short // landscape change index - ); - // Determine whether there is a potential mate present in a patch which a potential - // settler has reached - bool matePresent( - Cell*, // pointer to the Cell which the potential settler has reached - short // sex of the required mate (0 = female, 1 = male) - ); -#endif // RS_RCPP - // Determine survival and development and record in individual's status code - // Changes are NOT applied to the Population at this stage - void survival0( - float, // local carrying capacity - short, // option0: 0 - stage 0 (juveniles) only - // 1 - all stages - // 2 - stage 1 and above (all non-juveniles) - short // option1: 0 - development only (when survival is annual) - // 1 - development and survival - // 2 - survival only (when survival is annual) - ); - void survival1(void); // Apply survival changes to the population - void ageIncrement(void); - bool outPopHeaders( // Open population file and write header record - int, // Landscape number (-999 to close the file) - bool // TRUE for a patch-based model, FALSE for a cell-based model - ); - void outPopulation( // Write record to population file - int, // replicate - int, // year - int, // generation - float, // epsilon - global stochasticity value - bool, // TRUE for a patch-based model, FALSE for a cell-based model - bool, // TRUE to write environmental data - bool // TRUE if there is a gradient in carrying capacity - ); - - void outIndsHeaders( // Open individuals file and write header record - int, // replicate - int, // Landscape number (-999 to close the file) - bool // TRUE for a patch-based model, FALSE for a cell-based model - ); - void outIndividual( // Write records to individuals file - Landscape*, // pointer to Landscape - int, // replicate - int, // year - int, // generation - int // Patch number - ); - void outGenetics( // Write records to genetics file - const int, // replicate - const int, // year - const int // landscape number - ); - void clean(void); // Remove zero pointers to dead or dispersed individuals - -private: - short nStages; - short nSexes; - Species *pSpecies; // pointer to the species - Patch *pPatch; // pointer to the patch - int nInds[NSTAGES][NSEXES]; // no. of individuals in each stage/sex - - std::vector inds; // all individuals in population except ... - std::vector juvs; // ... juveniles until reproduction of ALL species - // has been completed - -}; - -//--------------------------------------------------------------------------- - -extern paramGrad *paramsGrad; -extern paramStoch *paramsStoch; -extern paramInit *paramsInit; -extern paramSim *paramsSim; -extern RSrandom *pRandom; - -#if RSDEBUG -extern ofstream DEBUGLOG; -#endif - -//--------------------------------------------------------------------------- -#endif - diff --git a/RangeShiftR/src/RScore/README.md b/RangeShiftR/src/RScore/README.md deleted file mode 100644 index 10a8386..0000000 --- a/RangeShiftR/src/RScore/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Rangeshifter core code - -This repo contains the core simulation code for RangeShifter v2.0 diff --git a/RangeShiftR/src/RScore/RSrandom.cpp b/RangeShiftR/src/RScore/RSrandom.cpp deleted file mode 100644 index 79744c9..0000000 --- a/RangeShiftR/src/RScore/RSrandom.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -#include "RSrandom.h" - -//--------------- 2.) New version of RSrandom.cpp - -#if !RS_RCPP - - -#if RSDEBUG -#include "Parameters.h" -extern paramSim* paramsSim; -// ofstream RSRANDOMLOG; -#endif - -int RS_random_seed = 0; - -// C'tor -RSrandom::RSrandom() -{ -#if RSDEBUG - // fixed seed - RS_random_seed = 666; -#else - // random seed -#if LINUX_CLUSTER - std::random_device device; - RS_random_seed = device(); // old versions of g++ on Windows return a constant value within a given Windows - // session; in this case better use time stamp -#else - RS_random_seed = std::time(NULL); -#endif -#endif // RSDEBUG - -#if BATCH && RSDEBUG - DEBUGLOG << "RSrandom::RSrandom(): RS_random_seed=" << RS_random_seed << endl; -#endif // RSDEBUG - - // set up Mersenne Twister RNG - gen = new mt19937(RS_random_seed); - - // Set up standard uniform distribution - pRandom01 = new uniform_real_distribution(0.0, 1.0); - // Set up standard normal distribution - pNormal = new normal_distribution(0.0, 1.0); -} - -RSrandom::~RSrandom(void) -{ - delete gen; - if(pRandom01 != 0) - delete pRandom01; - if(pNormal != 0) - delete pNormal; -} - -mt19937 RSrandom::getRNG(void) -{ - return *gen; -} - -double RSrandom::Random(void) -{ - // return random number between 0 and 1 - return pRandom01->operator()(*gen); -} - -int RSrandom::IRandom(int min, int max) -{ - // return random integer in the interval min <= x <= max - uniform_int_distribution unif(min, max); - return unif(*gen); -} - -int RSrandom::Bernoulli(double p) -{ - return Random() < p; -} - -double RSrandom::Normal(double mean, double sd) -{ - return mean + sd * pNormal->operator()(*gen); -} - -int RSrandom::Poisson(double mean) -{ - poisson_distribution poiss(mean); - return poiss(*gen); -} - - -//-------------------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------------------- - -#else // if RS_RCPP - -//--------------- 3.) R package version of RSrandom.cpp - - #if RSDEBUG - #include "Parameters.h" - extern paramSim *paramsSim; - //ofstream RSRANDOMLOG; - #endif - - std::uint32_t RS_random_seed = 0; - - // C'tor - // if parameter seed is negative, a random seed will be generated, else it is used as seed - RSrandom::RSrandom(std::int64_t seed) - { - // get seed - std::vector random_seed(3); - random_seed[0] = 1967593562; - random_seed[1] = 3271254416; - if (seed < 0) { - // random seed - #if RSWIN64 - random_seed[2] = std::time(NULL) + ( seed * (-17) ); - #else - std::random_device device; - random_seed[2] = device(); - #endif - #if BATCH && RSDEBUG - DEBUGLOG << "RSrandom::RSrandom(): Generated random seed = "; - #endif - } - else{ - // fixed seed - random_seed[2] = seed; - #if BATCH && RSDEBUG - DEBUGLOG << "RSrandom::RSrandom(): Use fixed seed = "; - #endif - } - - RS_random_seed = random_seed[2]; - #if BATCH && RSDEBUG - DEBUGLOG << RS_random_seed << endl; - #endif - - // set up Mersenne Twister random number generator with seed sequence - std::seed_seq seq(random_seed.begin(),random_seed.end()); - gen = new mt19937(seq); - - // Set up standard uniform distribution - pRandom01 = new uniform_real_distribution (0.0,1.0); - // Set up standard normal distribution - pNormal = new normal_distribution (0.0,1.0); - } - - RSrandom::~RSrandom(void) { - delete gen; - if (pRandom01 != 0) delete pRandom01; - if (pNormal != 0) delete pNormal; - } - - mt19937 RSrandom::getRNG(void) { - // return random number generator - return *gen; - } - - double RSrandom::Random(void) { - // return random number between 0 and 1 - return pRandom01->operator()(*gen); - } - - int RSrandom::IRandom(int min,int max) { - // return random integer in the interval min <= x <= max - uniform_int_distribution unif(min,max); - return unif(*gen); - } - - int RSrandom::Bernoulli(double p) { - return Random() < p; - } - - double RSrandom::Normal(double mean,double sd) { - return mean + sd * pNormal->operator()(*gen); - } - - int RSrandom::Poisson(double mean) { - poisson_distribution poiss(mean); - return poiss(*gen); - } - - - /* ADDITIONAL DISTRIBUTIONS - - // Beta distribution - sample from two gamma distributions - double RSrandom::Beta(double p0,double p1) { - double g0,g1,beta; - if (p0 > 0.0 && p1 > 0.0) { // valid beta parameters - gamma_distribution gamma0(p0,1.0); - gamma_distribution gamma1(p1,1.0); - g0 = gamma0(*gen); - g1 = gamma1(*gen); - beta = g0 / (g0 + g1); - } - else { // return invalid value - beta = -666.0; - } - return beta; - } - - // Gamma distribution - double RSrandom::Gamma(double p0,double p1) { // using shape (=p0) and scale (=p1) - double p2,gamma; - if (p0 > 0.0 && p1 > 0.0) { // valid gamma parameters - p2 = 1.0 / p1; - gamma_distribution gamma0(p0,p2); // using shape/alpha (=p0) and rate/beta (=p2=1/p1) - gamma = gamma0(*gen); - } - else { // return invalid value - gamma = -666.0; - } - return gamma; - } - - // Cauchy distribution - double RSrandom::Cauchy(double loc, double scale) { - double res; - if (scale > 0.0) { // valid scale parameter - cauchy_distribution cauchy(loc,scale); - res = cauchy(*gen); - } - else { // return invalid value - res = -666.0; - } - return res; - } - - - */ - -#endif // RS_RCPP - -//--------------------------------------------------------------------------- diff --git a/RangeShiftR/src/RScore/RSrandom.h b/RangeShiftR/src/RScore/RSrandom.h deleted file mode 100644 index 9293b29..0000000 --- a/RangeShiftR/src/RScore/RSrandom.h +++ /dev/null @@ -1,140 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 RSrandom - -Implements the RSrandom class - -Authors: Steve Palmer, University of Aberdeen - Anne-Kathleen Malchow, Potsdam University - -Last updated: 12 January 2021 by Steve Palmer - -------------------------------------------------------------------------------*/ - -#ifndef RSrandomH -#define RSrandomH - -#include -#include -//#include - -//#if RS_RCPP && !R_CMD -#include "../Version.h" -//#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif - -using namespace std; - -#if RSDEBUG -extern ofstream DEBUGLOG; -#endif - - - -#if !RS_RCPP - -//--------------- 2.) New version of RSrandom.cpp - - - #include - #include - #if !LINUX_CLUSTER - #include - #endif - - class RSrandom - { - - public: - RSrandom(void); - ~RSrandom(void); - double Random(void); - int IRandom(int, int); - int Bernoulli(double); - double Normal(double, double); - int Poisson(double); - mt19937 getRNG(void); - - private: - mt19937* gen; - std::uniform_real_distribution<>* pRandom01; - std::normal_distribution<>* pNormal; - }; - - -//-------------------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------------------- - - - -//--------------- 3.) R package version of RSrandom.cpp - - -#else // if RS_RCPP - - - #include - #include - #if RSWIN64 - #include - #endif - - class RSrandom { - - public: - RSrandom(std::int64_t); // if int is negative, a random seed will be generated, else it is used as seed - ~RSrandom(void); - mt19937 getRNG(void); - double Random(void); - int IRandom(int,int); - int Bernoulli(double); - double Normal(double,double); - int Poisson(double); - /* ADDITIONAL DISTRIBUTIONS - double Beta(double,double); - double Gamma(double,double); // !! make sure correct definition is used: using shape and scale (as defined here) OR using shape/alpha and rate/beta (=1/scale) - double Cauchy(double,double); - */ - - private: - mt19937 *gen; - std::uniform_real_distribution<> *pRandom01; - std::normal_distribution<> *pNormal; - }; - - - -#endif // !RS_RCPP - - -//--------------------------------------------------------------------------- - -#endif // RSrandomH - - - diff --git a/RangeShiftR/src/RScore/RandomCheck.cpp b/RangeShiftR/src/RScore/RandomCheck.cpp deleted file mode 100644 index e18aeaa..0000000 --- a/RangeShiftR/src/RScore/RandomCheck.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "RandomCheck.h" -//--------------------------------------------------------------------------- - -ifstream inRandom; -ofstream outRandom; -ofstream outBernoulli; -ofstream outNormal; -ofstream outPoisson; -ofstream outIRandom; - -void randomCheck(void) -{ - -int samplesize,irandMin,irandMax; -double bernMean,normMean,normSD,poisMean; -string name,header; -simParams sim = paramsSim->getSim(); - - name = paramsSim->getDir(1) + "RandomCheck.txt"; - inRandom.open(name.c_str()); - if (!inRandom.is_open()) { - #if !RS_RCPP - cout << endl << "***** Error opening input file RandomCheck.txt" << endl; - #endif - inRandom.clear(); - return; - } - for (int i = 0; i < 7; i++) { - inRandom >> header; - } - inRandom >> samplesize >> bernMean >> normMean >> normSD >> poisMean >> irandMin >> irandMax; - - name = paramsSim->getDir(2) + "Random.txt"; - outRandom.open(name.c_str()); - name = paramsSim->getDir(2) + "Bernoulli.txt"; - outBernoulli.open(name.c_str()); - name = paramsSim->getDir(2) + "Normal.txt"; - outNormal.open(name.c_str()); - name = paramsSim->getDir(2) + "Poisson.txt"; - outPoisson.open(name.c_str()); - name = paramsSim->getDir(2) + "IRandom.txt"; - outIRandom.open(name.c_str()); - - for (int i = 0; i < samplesize; i++) { - outRandom << pRandom->Random() << endl; - outBernoulli << pRandom->Bernoulli(bernMean) << endl; - outNormal << pRandom->Normal(normMean,normSD) << endl; - outPoisson << pRandom->Poisson(poisMean) << endl; - outIRandom << pRandom->IRandom(irandMin,irandMax) << endl; - } - - inRandom.close(); - inRandom.clear(); - outRandom.close(); - outRandom.clear(); - outBernoulli.close(); - outBernoulli.clear(); - outNormal.close(); - outNormal.clear(); - outPoisson.close(); - outPoisson.clear(); - outIRandom.close(); - outIRandom.clear(); - -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- diff --git a/RangeShiftR/src/RScore/RandomCheck.h b/RangeShiftR/src/RScore/RandomCheck.h deleted file mode 100644 index b4f6f01..0000000 --- a/RangeShiftR/src/RScore/RandomCheck.h +++ /dev/null @@ -1,47 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#ifndef RandomCheckH -#define RandomCheckH - -#include -using namespace std; - -//#if RS_RCPP && !R_CMD -#include "../Version.h" -//#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif -#include "Parameters.h" -#include "RSrandom.h" - -void randomCheck(void); - -extern paramSim *paramsSim; -extern RSrandom *pRandom; - -//--------------------------------------------------------------------------- -#endif diff --git a/RangeShiftR/src/RScore/Species.cpp b/RangeShiftR/src/RScore/Species.cpp deleted file mode 100644 index 9aae805..0000000 --- a/RangeShiftR/src/RScore/Species.cpp +++ /dev/null @@ -1,1455 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Species.h" -//--------------------------------------------------------------------------- - -Species::Species(void) -{ -// initialise demographic parameters -repType = 0; nStages = 2; -stageStruct = false; -propMales = 0.5; harem = 1.0; bc = 1.0; lambda = 1.5; probRep = 1.0; -repSeasons = 1; -repInterval = 0; maxAge = 1000; survival = 1; -fecDens = false; fecStageDens = false; -devDens = false; devStageDens = false; -survDens = false; survStageDens = false; -disperseOnLoss = false; -for (int i = 0; i < NSTAGES; i++) { - for (int j = 0; j < NSEXES; j++) { - fec[i][j] = 0.0; dev[i][j] = 0.0; surv[i][j] = 0.0; - minAge[i][j] = 0; - } -} -devCoeff = survCoeff = 1.0; -ddwtFec = ddwtDev = ddwtSurv = 0; ddwtFecDim = ddwtDevDim = ddwtSurvDim = 0; -habK = 0; habDimK = 0; -minRK = 1.0; maxRK = 2.0; - -// initialise genome attributes -nChromosomes = nTraits = 0; -emigTrait[0] = 0; emigTrait[1] = 0; -movtTrait[0] = 0; movtTrait[1] = 0; -settTrait[0] = 0; settTrait[1] = 0; -//genomeCanRecombine = false; -diploid = true; -neutralMarkers = false; -pleiotropic = false; -trait1Chromosome = true; -probMutn = 0.0001f; -probCrossover = 0.0001f; -alleleSD = mutationSD = 0.1f; -nNLoci = 0; -nLoci = NULL; -traitdata = NULL; -traitnames = NULL; -nTraitNames = 0; - -// initialise emigration parameters -densDepEmig = false; stgDepEmig = false; sexDepEmig = false; indVarEmig = false; -emigStage = 0; -for (int i = 0; i < NSTAGES; i++) { - for (int j = 0; j < NSEXES; j++) { - d0[i][j] = 0.0; alphaEmig[i][j] = 0.0; betaEmig[i][j] = 1.0; - } -} -for (int j = 0; j < NSEXES; j++) { - d0Mean[0][j] = 0.0; alphaMean[0][j] = 0.0; betaMean[0][j] = 1.0; - d0SD[0][j] = 0.0; alphaSD[0][j] = 0.0; betaSD[0][j] = 1.0; -} -d0Scale = alphaScale = betaScale = 0.0; - -// initialise transfer parameters -moveModel = false; stgDepTrfr = false; sexDepTrfr = false; distMort = false; -indVarTrfr = false; -twinKern = false; -habMort = false; -costMap = false; -moveType = 1; -for (int i = 0; i < NSTAGES; i++) { - for (int j = 0; j < NSEXES; j++) { - meanDist1[i][j] = 100.0f; meanDist2[i][j] = 1000.0f; probKern1[i][j] = 0.99f; - } -} -for (int j = 0; j < NSEXES; j++) { - dist1Mean[0][j] = 100.0; dist1SD[0][j] = 10.0; - dist2Mean[0][j] = 1000.0; dist2SD[0][j] = 100.0; - PKern1Mean[0][j] = 0.9f; PKern1SD[0][j] = 0.01f; - stepLgthMean[0][j] = 10.0; stepLgthSD[0][j] = 1.0; - rhoMean[0][j] = 0.9f; rhoSD[0][j] = 0.01f; - dpMean[0][j] = 1.0; dpSD[0][j] = 0.1f; - gbMean[0][j] = 1.0; gbSD[0][j] = 0.1f; - alphaDBMean[0][j] = 1.0; alphaDBSD[0][j] = 0.1f; - betaDBMean[0][j] = 10.0; betaDBSD[0][j] = 1.0; -} -pr = 1; prMethod = 1; memSize = 1; goalType = 0; -dp = 1.0; gb = 1.0; alphaDB = 1.0; betaDB = 100000; -stepMort = 0.0; stepLength = 10.0; rho = 0.9f; -habStepMort = 0; habCost = 0; -//costMapFile = "NULL"; -fixedMort = 0.0; mortAlpha = 0.0; mortBeta = 1.0; -dist1Scale = dist2Scale = PKern1Scale = stepLScale = rhoScale = 0.0; -dpScale = 0.1f; gbScale = 0.1f; alphaDBScale = 0.1f; betaDBScale = 1.0; -habDimTrfr = 0; -straigtenPath = false; -fullKernel = false; - -// initialise settlement parameters -stgDepSett = false; sexDepSett = false; indVarSett = false; -minSteps = 0; maxSteps = 99999999; -for (int i = 0; i < NSTAGES; i++) { - for (int j = 0; j < NSEXES; j++) { - densDepSett[i][j] = false; wait[i][j] = false; go2nbrLocn[i][j] = false; findMate[i][j] = false; - maxStepsYr[i][j] = 99999999; - s0[i][j] = 1.0; alphaS[i][j] = 0.0; betaS[i][j] = 1.0; - } -} -for (int j = 0; j < NSEXES; j++) { - alphaSMean[0][j] = 0.0; alphaSSD[0][j] = 0.0; - betaSMean[0][j] = 0.0; betaSSD[0][j] = 0.0; - s0Mean[0][j] = 0.0; s0SD[0][j] = 0.0; -} -alphaSScale = 0.0; betaSScale = 0.0; s0Scale = 0.0; - -// initialise attributes -spNum = 0; - -} - -Species::~Species() { -// demographic parameters -if (habK != NULL) deleteHabK(); -if (ddwtFec != 0) deleteDDwtFec(); -if (ddwtDev != 0) deleteDDwtDev(); -if (ddwtSurv != 0) deleteDDwtSurv(); -// transfer parameters -if (habCost != 0 || habStepMort != 0) deleteHabCostMort(); -if (nLoci != NULL) deleteLoci(); -if (traitdata != NULL) deleteTraitData(); -if (traitnames != NULL) deleteTraitNames(); -} - -short Species::getSpNum(void) { return spNum; } - -//--------------------------------------------------------------------------- - -// Demographic functions - -void Species::setDemogr(const demogrParams d) { -if (d.repType >= 0 && d.repType <= 2) repType = d.repType; -if (d.repSeasons >= 1) repSeasons = d.repSeasons; -stageStruct = d.stageStruct; -if (d.propMales > 0.0 && d.propMales < 1.0) propMales = d.propMales; -if (d.harem > 0.0) harem = d.harem; -if (d.bc > 0.0) bc = d.bc; -if (d.lambda > 0.0) lambda = d.lambda; -} - -demogrParams Species::getDemogr(void) { -demogrParams d; -d.repType = repType; -d.repSeasons = repSeasons; -d.stageStruct = stageStruct; -d.propMales = propMales; -d.harem = harem; -d.bc = bc; -d.lambda = lambda; -return d; -} - -short Species::getRepType(void) { return repType; } - -bool Species::stageStructured(void) { return stageStruct; } - -void Species::createHabK(short nhab) { -if (nhab >= 0) { - habDimK = nhab; - if (habK != 0) deleteHabK(); - habK = new float[nhab]; - for (int i = 0; i < nhab; i++) habK[i] = 0.0; -} -} - -void Species::setHabK(short hx,float k) { -if (hx >= 0 && hx < habDimK) { - if (k >= 0.0) habK[hx] = k; -} -} - -float Species::getHabK(short hx) { -float k = 0.0; -if (hx >= 0 && hx < habDimK) k = habK[hx]; -return k; -} - -float Species::getMaxK(void) { -float k = 0.0; -for (int i = 0; i < habDimK; i++) { - if (habK[i] > k) k = habK[i]; -} -return k; -} - -void Species::deleteHabK(void) { -if (habK != 0) { - delete[] habK; habK = 0; -} -} - -void Species::setStage(const stageParams s) { -if (s.nStages > 1) nStages = s.nStages; -if (s.repInterval >= 0) repInterval = s.repInterval; -if (s.maxAge >= 1) maxAge = s.maxAge; -if (s.survival >= 0 && s.survival <= 2) survival = s.survival; -if (s.probRep > 0.0 && s.probRep <= 1.0) probRep = s.probRep; -fecDens = s.fecDens; fecStageDens = s.fecStageDens; -devDens = s.devDens; devStageDens = s.devStageDens; -survDens = s.survDens; survStageDens = s.survStageDens; -disperseOnLoss = s.disperseOnLoss; -} - -stageParams Species::getStage(void) { -stageParams s; -s.nStages = nStages; s.repInterval = repInterval; s.maxAge = maxAge; -s.survival = survival; s.probRep = probRep; -s.fecDens = fecDens; s.fecStageDens = fecStageDens; -s.devDens = devDens; s.devStageDens = devStageDens; -s.survDens = survDens; s.survStageDens = survStageDens; -s.disperseOnLoss = disperseOnLoss; -return s; -} - -void Species::setFec(short stg,short sex,float f) { -// NB fecundity for stage 0 must always be zero -if (stg > 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES && f >= 0) - fec[stg][sex] = f; -} - -float Species::getFec(short stg,short sex) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) - return fec[stg][sex]; -else return 0.0; -} - -float Species::getMaxFec(void) { -float maxfec = 0.0; -if (stageStruct) { - for (int stg = 1; stg < NSTAGES; stg++) { - if (fec[stg][0] > maxfec) maxfec = fec[stg][0]; - } -} -else maxfec = lambda; -return maxfec; -} - -void Species::setDev(short stg,short sex,float d) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES && d >= 0) - dev[stg][sex] = d; -} - -float Species::getDev(short stg,short sex) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) - return dev[stg][sex]; -else return 0.0; -} - -void Species::setSurv(short stg,short sex,float s) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES && s >= 0) - surv[stg][sex] = s; -} - -float Species::getSurv(short stg,short sex) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) - return surv[stg][sex]; -else return 0.0; -} - -void Species::setMinAge(short stg,short sex,int age) { -// NB min age for stages 0 & 1 must always be zero -if (stg > 1 && stg < NSTAGES && sex >= 0 && sex < NSEXES && age >= 0) - minAge[stg][sex] = age; -} - -short Species::getMinAge(short stg,short sex) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) - return minAge[stg][sex]; -else return 0; -} - -void Species::setDensDep(float d, float s) { -if (d > 0.0) devCoeff = d; -if (s > 0.0) survCoeff = s; -} - -densDepParams Species::getDensDep(void) { -densDepParams d; -d.devCoeff = devCoeff; d.survCoeff = survCoeff; -return d; -} - -void Species::createDDwtFec(short mSize) { -if (mSize >= 0 && mSize < (NSTAGES * NSEXES)) { - if (ddwtFec != 0) deleteDDwtFec(); - ddwtFecDim = mSize; - ddwtFec = new float *[mSize]; - for (int i = 0; i < mSize; i++) { - ddwtFec[i] = new float[mSize]; - for (int j = 0; j < mSize; j++) ddwtFec[i][j] = 1.0; - } -} -} - -void Species::setDDwtFec(short row,short col,float f) { -if (row >= 0 && row < ddwtFecDim && col >= 0 && col < ddwtFecDim) - ddwtFec[row][col] = f; -} - -float Species::getDDwtFec(short row,short col) { -if (row >= 0 && row < ddwtFecDim && col >= 0 && col < ddwtFecDim) - return ddwtFec[row][col]; -else return 0.0; -} - -void Species::deleteDDwtFec(void) { -if (ddwtFec != 0) { - for (int i = 0; i < ddwtFecDim; i++) if (ddwtFec[i] != 0) { - delete[] ddwtFec[i]; - } - delete[] ddwtFec; ddwtFec = 0; -} -} - -void Species::createDDwtDev(short mSize) { -if (mSize >= 0 && mSize < (NSTAGES * NSEXES)) { - if (ddwtDev != 0) deleteDDwtDev(); - ddwtDevDim = mSize; - ddwtDev = new float *[mSize]; - for (int i = 0; i < mSize; i++) { - ddwtDev[i] = new float[mSize]; - for (int j = 0; j < mSize; j++) ddwtDev[i][j] = 1.0; - } -} -} - -void Species::setDDwtDev(short row,short col,float f) { -if (row >= 0 && row < ddwtDevDim && col >= 0 && col < ddwtDevDim) - ddwtDev[row][col] = f; -} - -float Species::getDDwtDev(short row,short col) { -if (row >= 0 && row < ddwtDevDim && col >= 0 && col < ddwtDevDim) - return ddwtDev[row][col]; -else return 0.0; -} - -void Species::deleteDDwtDev(void) { -if (ddwtDev != 0) { - for (int i = 0; i < ddwtDevDim; i++) if (ddwtDev[i] != 0) { - delete[] ddwtDev[i]; - } - delete[] ddwtDev; ddwtDev = 0; -} -} - -void Species::createDDwtSurv(short mSize) { -if (mSize >= 0 && mSize < (NSTAGES * NSEXES)) { - if (ddwtSurv != 0) deleteDDwtSurv(); - ddwtSurvDim = mSize; - ddwtSurv = new float *[mSize]; - for (int i = 0; i < mSize; i++) { - ddwtSurv[i] = new float[mSize] ; - for (int j = 0; j < mSize; j++) ddwtSurv[i][j] = 1.0; - } -} -} - -void Species::setDDwtSurv(short row,short col, float f) { -if (row >= 0 && row < ddwtSurvDim && col >= 0 && col < ddwtSurvDim) - ddwtSurv[row][col] = f; -} - -float Species::getDDwtSurv(short row,short col) { -if (row >= 0 && row < ddwtSurvDim && col >= 0 && col < ddwtSurvDim) - return ddwtSurv[row][col]; -else return 0.0; -} - -void Species::deleteDDwtSurv(void) { -if (ddwtSurv != 0) { - for (int i = 0; i < ddwtSurvDim; i++) if (ddwtSurv[i] != 0) { - delete[] ddwtSurv[i]; - } - delete[] ddwtSurv; ddwtSurv = 0; -} -} - -// Functions to handle min/max R or K (under environmental stochasticity) -//void Species::setMinMax(float min,float max) { -void Species::setMinMax(float min, float max) { -if (min >= 0.0 && max > min) { - minRK = min; maxRK = max; -} -} -float Species::getMinMax(short opt) { -if (opt == 0) return minRK; -else return maxRK; -} - -//--------------------------------------------------------------------------- - -// Genome functions - -void Species::setGenomeData(genomeData d) { -diploid = d.diploid; -neutralMarkers = d.neutralMarkers; -trait1Chromosome = d.trait1Chromosome; -if (trait1Chromosome) { - if (d.nLoci > 0) nLoci[0] = d.nLoci; -} -if (d.probMutn >= 0.0 && d.probMutn <= 1.0) probMutn = d.probMutn; -if (d.probCrossover >= 0.0 && d.probCrossover <= 1.0) probCrossover = d.probCrossover; -if (d.alleleSD > 0.0) alleleSD = d.alleleSD; -if (d.mutationSD > 0.0) mutationSD = d.mutationSD; -} - -genomeData Species::getGenomeData(void) { -genomeData d; -d.diploid = diploid; -d.neutralMarkers = neutralMarkers; -d.pleiotropic = pleiotropic; -d.trait1Chromosome = trait1Chromosome; -if (nLoci != NULL) d.nLoci = nLoci[0]; -else d.nLoci = 0; -d.probMutn = probMutn; -d.probCrossover = probCrossover; -d.alleleSD = alleleSD; -d.mutationSD = mutationSD; -return d; -} - -bool Species::isDiploid(void) { return diploid; } - -// Chromosome functions - -void Species::setNChromosomes(int c) { -if (nLoci != NULL) deleteLoci(); -if (c > 0) { - nChromosomes = nNLoci = c; - nLoci = new short [c]; - for (int i = 0; i < nNLoci; i++) nLoci[i] = 0; -} -else nChromosomes = nNLoci = 0; -} - -int Species::getNChromosomes(void) { return nChromosomes; } - -void Species::setNLoci(const short chr,const short nloc) { -if (chr >= 0 && chr < nNLoci) { - if (nloc > 0) nLoci[chr] = nloc; - else nLoci[chr] = 0; -} -} - -int Species::getNLoci(const short chr) { -if (chr >= 0 && chr < nChromosomes) return nLoci[chr]; -else return 0; -} - -void Species::deleteLoci(void) { -if (nLoci != NULL) { delete[] nLoci; nLoci = NULL; } -} - -// Trait functions - -// Set 1:1 mapping of trait to chromosome -void Species::set1ChromPerTrait(const int nloc) { -nChromosomes = nTraits; -if (nLoci != NULL) deleteLoci(); -nLoci = new short [1]; -if (nloc > 0) nLoci[0] = nloc; -else nLoci[0] = 1; -} - -bool Species::has1ChromPerTrait(void) { return trait1Chromosome; } - -// Set trait attributes for the species -void Species::setTraits(void) { - -emigTrait[0] = 0; emigTrait[1] = 0; -movtTrait[0] = 0; movtTrait[1] = 0; -settTrait[0] = 0; settTrait[1] = 0; -nTraits = 0; -#if RSDEBUG -DebugGUI("Species::setTraits(): 0000 nChromosomes=" + Int2Str(nChromosomes) - + " nTraits=" + Int2Str(nTraits) - + " indVarEmig=" + Int2Str((int)indVarEmig) - + " indVarTrfr=" + Int2Str((int)indVarTrfr) - + " indVarSett=" + Int2Str((int)indVarSett) - ); -#endif - -if (indVarEmig) { - if (sexDepEmig) { - if (densDepEmig) nTraits += 6; else nTraits += 2; - } - else { - if (densDepEmig) nTraits += 3; else nTraits += 1; - } - emigTrait[0] = 0; emigTrait[1] = nTraits; -} -#if RSDEBUG -//DebugGUI("Species::setTraits(): 1111 nTraits=" + Int2Str(nTraits)); -#endif - -int movttraits = 0; -if (indVarTrfr) { - if (moveModel) { - if (moveType == 1) { // SMS - movttraits = 1; // in contain batch 2 - if (goalType == 2) movttraits += 3; //in contain batch 2 - } - if (moveType == 2) movttraits = 2; - } - else { - if (sexDepTrfr) { - if (twinKern) movttraits = 6; else movttraits = 2; - } - else { - if (twinKern) movttraits = 3; else movttraits = 1; - } - } - movtTrait[0] = nTraits; movtTrait[1] = movttraits; - nTraits += movttraits; -} -#if RSDEBUG -//DebugGUI("Species::setTraits(): 2222 nTraits=" + Int2Str(nTraits)); -#endif - -int setttraits = 0; -if (indVarSett) { - if (sexDepSett) setttraits = 6; else setttraits = 3; - settTrait[0] = nTraits; settTrait[1] = setttraits; - nTraits += setttraits; -} - -setTraitNames(); - -//if (trait1Chromosome) { -// nChromosomes = nTraits; -//} -#if RSDEBUG -DebugGUI("Species::setTraits(): 9999 nChromosomes=" + Int2Str(nChromosomes) - + " nTraits=" + Int2Str(nTraits)); -#endif - -} - -void Species::setTraitNames(void) { -#if RSDEBUG -//DebugGUI("Species::setTraitNames(): nTraits=" + Int2Str(nTraits) -// + " nTraitNames=" + Int2Str(nTraitNames) -// + " traitnames=" + Int2Str((int)traitnames) -// ); -//if (traitnames != NULL) { -// DebugGUI("Species::setTraitNames(): traitnames[0]=" + traitnames[0] -// ); -// if (nTraits > 1) { -// DebugGUI("Species::setTraitNames(): traitnames[1]=" + traitnames[1] -// ); -// } -//} -#endif -deleteTraitNames(); -nTraitNames = nTraits; -traitnames = new string [nTraitNames]; -int trait = 0; -if (indVarEmig) { - if (sexDepEmig) { - if (densDepEmig) { - traitnames[trait++] = "d0_F"; - traitnames[trait++] = "d0_M"; - traitnames[trait++] = "alpha_F"; - traitnames[trait++] = "alpha_M"; - traitnames[trait++] = "beta_F"; - traitnames[trait++] = "beta_M"; - } - else { - traitnames[trait++] = "d0_F"; - traitnames[trait++] = "d0_M"; - } - } - else { - traitnames[trait++] = "d0"; - if (densDepEmig) { - traitnames[trait++] = "alpha"; - traitnames[trait++] = "beta"; - } - } -} - -if (indVarTrfr) { - if (moveModel) { - if (moveType == 1) { // SMS - traitnames[trait++] = "DP"; - if (goalType == 2) { - traitnames[trait++] = "GB"; - traitnames[trait++] = "alphaDB"; - traitnames[trait++] = "betaDB"; - } - } - if (moveType == 2) { // CRW - traitnames[trait++] = "stepL"; - traitnames[trait++] = "rho"; - } - } - else { - if (sexDepTrfr) { - if (twinKern) - { - traitnames[trait++] = "meanDistI_F"; - traitnames[trait++] = "meanDistI_M"; - traitnames[trait++] = "meanDistII_F"; - traitnames[trait++] = "meanDistII_M"; - traitnames[trait++] = "probKernI_F"; - traitnames[trait++] = "probKernI_M"; - } - else { - traitnames[trait++] = "meanDistI_F"; - traitnames[trait++] = "meanDistI_M"; - } - } - else { - traitnames[trait++] = "meanDistI"; - if (twinKern) - { - traitnames[trait++] = "meanDistII"; - traitnames[trait++] = "probKernI"; - } - } - } -} - -if (indVarSett) { - if (sexDepSett) { - traitnames[trait++] = "s0_F"; - traitnames[trait++] = "s0_M"; - traitnames[trait++] = "alphaS_F"; - traitnames[trait++] = "alphaS_M"; - traitnames[trait++] = "betaS_F"; - traitnames[trait++] = "betaS_M"; - } - else { - traitnames[trait++] = "s0"; - traitnames[trait++] = "alphaS"; - traitnames[trait++] = "betaS"; - } -} -} - -void Species::deleteTraitNames(void) { -if (traitnames != NULL) { -#if RSDEBUG -//DebugGUI("Species::deleteTraitNames(): traitnames=" + Int2Str((int)traitnames) -// ); -#endif - delete[] traitnames; - traitnames = NULL; -} -} - -string Species::getTraitName(const int trait) { -string name = "not used"; -if (traitnames != NULL) { - if (trait >= 0 && trait < nTraits) { - name = traitnames[trait]; - } -} -return name; -} - -int Species::getNTraits(void) { return nTraits; } - -void Species::setTraitData(const int ntraits) { -#if RSDEBUG -//DebugGUI(("Species::setTraitData(): traitdata=" + Int2Str((int)traitdata) -// + " ntraits=" + Int2Str(ntraits) -// ).c_str()); -#endif -deleteTraitData(); -traitdata = new traitData; -if (ntraits > 0) { - traitdata->nTraitMaps = ntraits; - traitdata->traitmaps = new traitMap *[ntraits]; - for (int i = 0; i < ntraits; i++) { - traitdata->traitmaps[i] = new traitMap; - } -} -else { // neutral markers only - traitdata->nTraitMaps = 0; -} -traitdata->neutralloci = new traitMap; -traitdata->neutralloci->nAlleles = 0; -#if RSDEBUG -//DebugGUI(("Species::setTraitData(): traitdata=" + Int2Str((int)traitdata) -// + " nTraitMaps=" + Int2Str(traitdata->nTraitMaps) -// ).c_str()); -#endif -} - -void Species::deleteTraitData(void) { -if (traitdata != NULL) { -#if RSDEBUG -//DebugGUI(("Species::deleteTraitData(): traitdata=" + Int2Str((int)traitdata) -// + " nTraitMaps=" + Int2Str(traitdata->nTraitMaps) -// ).c_str()); -#endif - for (int i = 0; i < traitdata->nTraitMaps; i++) { - if (traitdata->traitmaps[i]->traitalleles != 0) { - for (int j = 0; j < traitdata->traitmaps[i]->nAlleles; j++) { - delete traitdata->traitmaps[i]->traitalleles[j]; - } - } - delete[] traitdata->traitmaps[i]; - } - deleteNeutralLoci(); - delete traitdata; - traitdata = NULL; -} -} - -int Species::getNTraitMaps(void) { -if (traitdata == NULL) return 0; -else return traitdata->nTraitMaps; -} - -void Species::setTraitMap(const short trait,const short nalleles) { -traitdata->traitmaps[trait]->nAlleles = nalleles; -traitdata->traitmaps[trait]->traitalleles = new traitAllele *[nalleles]; -for (int i = 0; i < nalleles; i++) { - traitdata->traitmaps[trait]->traitalleles[i] = new traitAllele; -} -} - -int Species::getNTraitAlleles(const int trait) { -int nalleles = 0; -if (traitdata != NULL) { - if (trait >= 0 && trait < traitdata->nTraitMaps) { - nalleles = traitdata->traitmaps[trait]->nAlleles; - } -} -return nalleles; -} - -void Species::setTraitAllele(const short trait,const short allele, - const short chr,const short loc) -{ -traitdata->traitmaps[trait]->traitalleles[allele] = new traitAllele; -if (chr >= 0 && loc >= 0) { - traitdata->traitmaps[trait]->traitalleles[allele]->chromo = chr; - traitdata->traitmaps[trait]->traitalleles[allele]->locus = loc; -} -else { - traitdata->traitmaps[trait]->traitalleles[allele]->chromo = 0; - traitdata->traitmaps[trait]->traitalleles[allele]->locus = 0; -} -} - -traitAllele Species::getTraitAllele(const short trait,const short allele) { -traitAllele a; a.chromo = 0; a.locus = 0; -if (traitdata != NULL) { - if (trait >= 0 && trait < traitdata->nTraitMaps) { - if (allele >= 0 && allele < traitdata->traitmaps[trait]->nAlleles) { - a = *traitdata->traitmaps[trait]->traitalleles[allele]; - } - } -} -return a; -} - -// Neutral loci functions - -// Identify neutral loci and determine whether there is pleiotropy -void Species::setNeutralLoci(bool neutralMarkersOnly) { -bool neutral; -int nneutral = 0; -// find minimum of no. of defined / applied traits -int ntraits; -if (traitdata == 0 ) ntraits = 0; -else ntraits = traitdata->nTraitMaps; -if (ntraits > nTraits) ntraits = nTraits; -#if RSDEBUG -//DebugGUI("Species::setNeutralLoci(): neutralMarkersOnly=" + Int2Str((int)neutralMarkersOnly) -// + " nNLoci=" + Int2Str(nNLoci) -// + " nTraits=" + Int2Str(nTraits) + " ntraits=" + Int2Str(ntraits) -//); -#endif - -// determine no. of neutral loci -deleteNeutralLoci(); -for (int i = 0; i < nNLoci; i++) { // each chromosome - for (int j = 0; j < nLoci[i]; j++) { // each locus - neutral = true; - for (int t = 0; t < ntraits; t++) { // each trait - for (int a = 0; a < traitdata->traitmaps[t]->nAlleles; a++) { -#if RSDEBUG -//DebugGUI("Species::setNeutralLoci(): i=" + Int2Str(i) -// + " j=" + Int2Str(j) + " t=" + Int2Str(t) + " a=" + Int2Str(a) -// + " chromo=" + Int2Str(traitdata->traitmaps[t]->traitalleles[a]->chromo) -// + " locus=" + Int2Str(traitdata->traitmaps[t]->traitalleles[a]->locus) -//); -#endif - if (i == traitdata->traitmaps[t]->traitalleles[a]->chromo - && j == traitdata->traitmaps[t]->traitalleles[a]->locus) { -#if RSDEBUG -//DebugGUI("Species::setNeutralLoci(): FALSE"); -#endif - neutral = false; // as locus contributes to a trait - a = 999999; - } - } - if (!neutral) t = 999999; - } - if (neutral) nneutral++; - } -} - -traitdata->neutralloci = new traitMap; -traitdata->neutralloci->nAlleles = nneutral; -if (nneutral < 1) return; - -// record neutral markers -traitdata->neutralloci->traitalleles = new traitAllele *[nneutral]; -nneutral = 0; -for (int i = 0; i < nNLoci; i++) { // each chromosome - for (int j = 0; j < nLoci[i]; j++) { // each locus - neutral = true; - for (int t = 0; t < ntraits; t++) { // each trait - for (int a = 0; a < traitdata->traitmaps[t]->nAlleles; a++) { - if (i == traitdata->traitmaps[t]->traitalleles[a]->chromo - && j == traitdata->traitmaps[t]->traitalleles[a]->locus) { - neutral = false; // as locus contributes to a trait - a = 999999; - } - } - if (!neutral) t = 999999; - } - if (neutral) { - traitdata->neutralloci->traitalleles[nneutral] = new traitAllele; - traitdata->neutralloci->traitalleles[nneutral]->chromo = i; - traitdata->neutralloci->traitalleles[nneutral]->locus = j; - nneutral++; - } - } -} - -pleiotropic = false; -if (neutralMarkersOnly) return; // pleiotropy cannot apply - -// determine whether there is pleiotropy -int chr,loc; -int nloci = 0; // maximum no. of loci on any one chromosome -for (int i = 0; i < nNLoci; i++) { - if (nloci < nLoci[i]) nloci = nLoci[i]; -} -int ***locfreq; -locfreq = new int **[nNLoci]; -for (int i = 0; i < nNLoci; i++) { - locfreq[i] = new int *[nloci]; - for (int j = 0; j < nloci; j++) { - locfreq[i][j] = new int[ntraits]; - for (int t = 0; t < ntraits; t++) locfreq[i][j][t] = 0; - } -} -for (int t = 0; t < ntraits; t++) { // each trait - for (int a = 0; a < traitdata->traitmaps[t]->nAlleles; a++) { - chr = traitdata->traitmaps[t]->traitalleles[a]->chromo; - loc = traitdata->traitmaps[t]->traitalleles[a]->locus; - locfreq[chr][loc][t]++; - } -} -#if RSDEBUG -//for (int i = 0; i < nNLoci; i++) { -// for (int j = 0; j < nloci; j++) -// for (int t = 0; t < ntraits; t++) -// DebugGUI("locfreq[" + Int2Str(i) + "][" + Int2Str(j) + "][" + Int2Str(t) -// + "]=" + Int2Str(locfreq[i][j][t])); -//} -#endif -for (int i = 0; i < nNLoci; i++) { - for (int j = 0; j < nloci; j++) { - // remove multiple contributions of a locus to a particular trait - // (i.e. prevent recording of pseudo-pleiotropy) - for (int t = 0; t < ntraits; t++) { - if (locfreq[i][j][t] > 0) locfreq[i][j][t] = 1; - } - // sum at level of chromosome/locus - for (int t = 1; t < ntraits; t++) { - locfreq[i][j][0] += locfreq[i][j][t]; - } - if (locfreq[i][j][0] > 1) pleiotropic = true; - } -} -for (int i = 0; i < nNLoci; i++) { - for (int j = 0; j < nloci; j++) { - delete[] locfreq[i][j]; - } - delete[] locfreq[i]; -} -delete[] locfreq; - -} - -void Species::deleteNeutralLoci(void) { -if (traitdata->neutralloci != NULL) { - for (int i = 0; i < traitdata->neutralloci->nAlleles; i++) { - delete traitdata->neutralloci->traitalleles[i]; - } - delete[] traitdata->neutralloci; -} -traitdata->neutralloci = NULL; -} - -int Species::getNNeutralLoci(void) { -int nn = 0; -if (traitdata != NULL) { - if (traitdata->neutralloci != NULL) { - nn = traitdata->neutralloci->nAlleles; - } -} -return nn; -} - -traitAllele Species::getNeutralAllele(const short allele) { -traitAllele a; a.chromo = 0; a.locus = 0; -if (traitdata != NULL) { - if (allele >= 0 && allele < traitdata->neutralloci->nAlleles) { - a = *traitdata->neutralloci->traitalleles[allele]; - } -} -return a; -} - -//--------------------------------------------------------------------------- - -// Emigration functions - -void Species::setEmig(const emigRules e) { -#if RSDEBUG -//DebugGUI("Species::setEmig(): e.indVar=" + Int2Str((int)e.indVar)); -#endif -densDepEmig = e.densDep; stgDepEmig = e.stgDep; sexDepEmig = e.sexDep; -indVarEmig = e.indVar; -if (e.emigStage >= 0) emigStage = e.emigStage; -//setGenome(); -} - -emigRules Species::getEmig(void) { -emigRules e; -e.densDep = densDepEmig; e.stgDep = stgDepEmig; e.sexDep = sexDepEmig; -e.indVar = indVarEmig; e.emigStage = emigStage; -e.emigTrait[0] = emigTrait[0]; e.emigTrait[1] = emigTrait[1]; -return e; -} - -void Species::setEmigTraits(const short stg,const short sex,const emigTraits e) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - if (e.d0 >= 0.0 && e.d0 <= 1.0) d0[stg][sex] = e.d0; - alphaEmig[stg][sex] = e.alpha; betaEmig[stg][sex] = e.beta; -} -} - -emigTraits Species::getEmigTraits(short stg,short sex) { -emigTraits e; -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - e.d0 = d0[stg][sex]; e.alpha = alphaEmig[stg][sex]; e.beta = betaEmig[stg][sex]; -} -else { - e.d0 = e.alpha = e.beta = 0.0; -} -return e; -} - -float Species::getEmigD0(short stg,short sex) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - return d0[stg][sex]; -} -else { - return 0.0; -} -} - -void Species::setEmigParams(const short stg,const short sex,const emigParams e) { -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < NSEXES) // implemented for stage 0 only -{ - if (e.d0Mean >= 0.0 && e.d0Mean < 1.0) d0Mean[stg][sex] = e.d0Mean; - if (e.d0SD > 0.0 && e.d0SD < 1.0) d0SD[stg][sex] = e.d0SD; -// if (e.d0MutnSize > 0.0 && e.d0MutnSize < 1.0) d0MutnSize = e.d0MutnSize; - alphaMean[stg][sex] = e.alphaMean; - if (e.alphaSD > 0.0) alphaSD[stg][sex] = e.alphaSD; -// if (e.alphaMutnSize > 0.0) alphaMutnSize = e.alphaMutnSize; - betaMean[stg][sex] = e.betaMean; - if (e.betaSD > 0.0) betaSD[stg][sex] = e.betaSD; -// if (e.betaMutnSize > 0.0) betaMutnSize = e.betaMutnSize; -} -} - -emigParams Species::getEmigParams(short stg,short sex) { -emigParams e; -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < NSEXES) // implemented for stage 0 only -{ - e.d0Mean = d0Mean[stg][sex]; e.d0SD = d0SD[stg][sex]; - e.d0Scale = d0Scale; - e.alphaMean = alphaMean[stg][sex]; e.alphaSD = alphaSD[stg][sex]; - e.alphaScale = alphaScale; - e.betaMean = betaMean[stg][sex]; e.betaSD = betaSD[stg][sex]; - e.betaScale = betaScale; -} -else { - e.d0Mean = e.alphaMean = e.betaMean = e.d0SD = e.alphaSD = e.betaSD = 0.0; - e.d0Scale = d0Scale; - e.alphaScale = alphaScale; - e.betaScale = betaScale; -} -return e; -} - -void Species::setEmigScales(const emigScales s) { -if (s.d0Scale >= 0.0 && s.d0Scale < 1.0 ) d0Scale = s.d0Scale; -if (s.alphaScale >= 0.0) alphaScale = s.alphaScale; -if (s.betaScale >= 0.0) betaScale = s.betaScale; -} - -emigScales Species::getEmigScales(void) { -emigScales s; -s.d0Scale = d0Scale; s.alphaScale = alphaScale; s.betaScale = betaScale; -return s; -} - -//--------------------------------------------------------------------------- - -// Transfer functions - -void Species::setTrfr(const trfrRules t) { -#if RSDEBUG -//DebugGUI("Species::setTrfr(): t.indVar=" + Int2Str((int)t.indVar)); -#endif -moveModel = t.moveModel; stgDepTrfr = t.stgDep; sexDepTrfr = t.sexDep; -distMort = t.distMort; indVarTrfr = t.indVar; -twinKern = t.twinKern; -habMort = t.habMort; -moveType = t.moveType; costMap = t.costMap; -//setGenome(); -} - -trfrRules Species::getTrfr(void) { -trfrRules t; -t.moveModel = moveModel; t.stgDep = stgDepTrfr; t.sexDep = sexDepTrfr; -t.distMort = distMort; t.indVar = indVarTrfr; -t.twinKern = twinKern; -t.habMort = habMort; -t.moveType = moveType; t.costMap = costMap; -t.movtTrait[0] = movtTrait[0]; t.movtTrait[1] = movtTrait[1]; -return t; -} - -void Species::setFullKernel(bool k) { -fullKernel = k; -} - -bool Species::useFullKernel(void) { return fullKernel; } - -void Species::setKernTraits(const short stg,const short sex, - const trfrKernTraits k,const int resol) -{ -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - if (k.meanDist1 > 0.0 && k.meanDist1 >= (float)resol) meanDist1[stg][sex] = k.meanDist1; - if (k.meanDist2 >= (float)resol) meanDist2[stg][sex] = k.meanDist2; - if (k.probKern1 > 0.0 && k.probKern1 < 1.0) probKern1[stg][sex] = k.probKern1; -} -} - -trfrKernTraits Species::getKernTraits(short stg,short sex) { -trfrKernTraits k; -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - k.meanDist1 = meanDist1[stg][sex]; - k.meanDist2 = meanDist2[stg][sex]; - k.probKern1 = probKern1[stg][sex]; -} -else { - k.meanDist1 = 0.0; k.meanDist2 = 0.0; k.probKern1 = 1.0; -} -return k; -} - -void Species::setMortParams(const trfrMortParams m) { -if (m.fixedMort >= 0.0 && m.fixedMort < 1.0) fixedMort = m.fixedMort; -mortAlpha = m.mortAlpha; -mortBeta = m.mortBeta; -} - -trfrMortParams Species::getMortParams(void) { -trfrMortParams m; -m.fixedMort = fixedMort; m.mortAlpha = mortAlpha; m.mortBeta = mortBeta; -return m; -} - -void Species::setMovtTraits(const trfrMovtTraits m) { -if (m.pr >= 1) pr = m.pr; -if (m.prMethod >= 1 && m.prMethod <= 3) prMethod = m.prMethod; -if (m.memSize >= 1 && m.memSize <= 14) memSize = m.memSize; -if (m.goalType >= 0 && m.goalType <= 2) goalType = m.goalType; -if (m.dp >= 1.0) dp = m.dp; -if (m.gb >= 1.0) gb = m.gb; -if (m.alphaDB > 0.0) alphaDB = m.alphaDB; -if (m.betaDB > 0) betaDB = m.betaDB; -if (m.stepMort >= 0.0 && m.stepMort < 1.0) stepMort = m.stepMort; -if (m.stepLength > 0.0) stepLength = m.stepLength; -if (m.rho > 0.0 && m.rho < 1.0) rho = m.rho; -straigtenPath = m.straigtenPath; -} - -trfrMovtTraits Species::getMovtTraits(void) { -trfrMovtTraits m; -m.pr = pr; m.prMethod = prMethod; m.memSize = memSize; m.goalType = goalType; -m.dp = dp; m.gb = gb; m.alphaDB = alphaDB; m.betaDB = betaDB; -m.stepMort = stepMort; m.stepLength = stepLength; m.rho = rho; -return m; -} - -trfrCRWTraits Species::getCRWTraits(void) { -trfrCRWTraits m; -m.stepMort = stepMort; m.stepLength = stepLength; m.rho = rho; -m.straigtenPath = straigtenPath; -return m; -} - -trfrSMSTraits Species::getSMSTraits(void) { -trfrSMSTraits m; -m.pr = pr; m.prMethod = prMethod; m.memSize = memSize; m.goalType = goalType; -m.dp = dp; m.gb = gb; m.alphaDB = alphaDB; m.betaDB = betaDB; m.stepMort = stepMort; -m.straigtenPath = straigtenPath; -return m; -} - -void Species::setKernParams(const short stg,const short sex, - const trfrKernParams k,const double resol) -{ -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < NSEXES) // implemented for stage 0 only -{ - if (k.dist1Mean > 0.0 && k.dist1Mean >= resol && k.dist1SD > 0.0) { - dist1Mean[stg][sex] = k.dist1Mean; dist1SD[stg][sex] = k.dist1SD; - } - if (k.dist2Mean > 0.0 && k.dist2Mean >= resol && k.dist2SD > 0.0) { - dist2Mean[stg][sex] = k.dist2Mean; dist2SD[stg][sex] = k.dist2SD; - } - if (k.PKern1Mean > 0.0 && k.PKern1Mean < 1.0 && k.PKern1SD > 0.0 && k.PKern1SD < 1.0 ) { - PKern1Mean[stg][sex] = k.PKern1Mean; PKern1SD[stg][sex] = k.PKern1SD; - } -} -} - -trfrKernParams Species::getKernParams(short stg,short sex) { -trfrKernParams k; -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < NSEXES) // implemented for stage 0 only -{ - k.dist1Mean = dist1Mean[stg][sex]; k.dist1SD = dist1SD[stg][sex]; - k.dist2Mean = dist2Mean[stg][sex]; k.dist2SD = dist2SD[stg][sex]; - k.PKern1Mean = PKern1Mean[stg][sex]; k.PKern1SD = PKern1SD[stg][sex]; - k.dist1Scale = dist1Scale; k.dist2Scale = dist2Scale; k.PKern1Scale = PKern1Scale; -} -else { - k.dist1Mean = 100000.0; k.dist1SD = 0.001f; k.dist1Scale = 1.0; - k.dist2Mean = 100000.0; k.dist2SD = 0.001f; k.dist2Scale = 1.0; - k.PKern1Mean = 0.5; k.PKern1SD = 0.1f; k.PKern1Scale = 0.1f; -} -return k; -} - -void Species::setSMSParams(const short stg,const short sex,const trfrSMSParams s) { -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < 1) // implemented for stage 0 & sex 0 only -{ - if (s.dpMean >= 1.0 && s.dpSD > 0.0) { - dpMean[stg][sex] = s.dpMean; dpSD[stg][sex] = s.dpSD; - } - if (s.gbMean >= 1.0 && s.gbSD > 0.0) { - gbMean[stg][sex] = s.gbMean; gbSD[stg][sex] = s.gbSD; - } - if (s.alphaDBMean > 0.0 && s.alphaDBSD > 0.0) { - alphaDBMean[stg][sex] = s.alphaDBMean; alphaDBSD[stg][sex] = s.alphaDBSD; - } - if (s.betaDBMean >= 1.0 && s.betaDBSD > 0.0) { - betaDBMean[stg][sex] = s.betaDBMean; betaDBSD[stg][sex] = s.betaDBSD; - } -} -} - -trfrSMSParams Species::getSMSParams(short stg,short sex) { -trfrSMSParams s; -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < 1) // implemented for stage 0 & sex 0 only -{ - s.dpMean = dpMean[stg][sex]; s.dpSD = dpSD[stg][sex]; - s.gbMean = gbMean[stg][sex]; s.gbSD = gbSD[stg][sex]; - s.alphaDBMean = alphaDBMean[stg][sex]; s.alphaDBSD = alphaDBSD[stg][sex]; - s.betaDBMean = betaDBMean[stg][sex]; s.betaDBSD = betaDBSD[stg][sex]; - s.dpScale = dpScale; s.gbScale = gbScale; - s.alphaDBScale = alphaDBScale; s.betaDBScale = betaDBScale; -} -else { - s.dpMean = 1.0; s.dpSD = 0.1f; s.dpScale = 0.1f; - s.gbMean = 1.0; s.gbSD = 0.1f; s.gbScale = 0.1f; - s.alphaDBMean = 1.0; s.alphaDBSD = 0.1f; s.alphaDBScale = 0.1f; - s.betaDBMean = 10.0; s.betaDBSD = 1.0; s.betaDBScale = 1.0; -} -return s; -} - -void Species::setCRWParams(const short stg,const short sex,const trfrCRWParams m) { -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < 1) // implemented for stage 0 & sex 0 only -{ - if (m.stepLgthMean > 0.0 && m.stepLgthSD > 0.0) { - stepLgthMean[stg][sex] = m.stepLgthMean; stepLgthSD[stg][sex] = m.stepLgthSD; - } - if (m.rhoMean > 0.0 && m.rhoMean < 1.0 && m.rhoSD > 0.0 && m.rhoSD < 1.0 ) { - rhoMean[stg][sex] = m.rhoMean; rhoSD[stg][sex] = m.rhoSD; - } -} -} - -trfrCRWParams Species::getCRWParams(short stg,short sex) { -trfrCRWParams m; -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < 1) // implemented for stage 0 & sex 0 only -{ - m.stepLgthMean = stepLgthMean[stg][sex]; m.stepLgthSD = stepLgthSD[stg][sex]; - m.rhoMean = rhoMean[stg][sex]; m.rhoSD = rhoSD[stg][sex]; - m.stepLScale = stepLScale; m.rhoScale = rhoScale; -} -else { - m.stepLgthMean = 1.0; m.stepLgthSD = 0.1f; m.stepLScale = 0.1f; - m.rhoMean = 0.5; m.rhoSD = 0.1f; m.rhoScale = 0.1f; -} -return m; -} - -void Species::setTrfrScales(const trfrScales s) { -if (s.dist1Scale >= 0.0) dist1Scale = s.dist1Scale; -if (s.dist2Scale >= 0.0) dist2Scale = s.dist2Scale; -if (s.PKern1Scale > 0.0 && s.PKern1Scale < 1.0) PKern1Scale = s.PKern1Scale; -if (s.dpScale > 0.0) dpScale = s.dpScale; -if (s.gbScale > 0.0) gbScale = s.gbScale; -if (s.alphaDBScale > 0.0) alphaDBScale = s.alphaDBScale; -if (s.betaDBScale > 0.0) betaDBScale = s.betaDBScale; -if (s.stepLScale > 0.0) stepLScale = s.stepLScale; -if (s.rhoScale > 0.0 && s.rhoScale < 1.0) rhoScale = s.rhoScale; -} - -trfrScales Species::getTrfrScales(void) { -trfrScales s; -s.dist1Scale = dist1Scale; s.dist2Scale = dist2Scale; s.PKern1Scale = PKern1Scale; -s.dpScale = dpScale; s.gbScale = gbScale; -s.alphaDBScale = alphaDBScale; s.betaDBScale = betaDBScale; -s.stepLScale = stepLScale; s.rhoScale = rhoScale; -return s; -} - -short Species::getMovtHabDim() { return habDimTrfr; } - -void Species::createHabCostMort(short nhab) { -if (nhab >= 0) { - habDimTrfr = nhab; - if (habCost != 0 || habStepMort != 0) deleteHabCostMort(); - habCost = new int[nhab]; - habStepMort = new double[nhab]; - for (int i = 0; i < nhab; i++) { - habCost[i] = 1; habStepMort[i] = 0.0; - } -} -} - -void Species::setHabCost(short hab,int cost) { -if (hab >= 0 && hab < habDimTrfr) { - if (cost >= 1) habCost[hab] = cost; -} -} - -void Species::setHabMort(short hab,double mort) { -if (hab >= 0 && hab < habDimTrfr) { - if (mort >= 0.0 && mort < 1.0) habStepMort[hab] = mort; -} -} - -int Species::getHabCost(short hab) { -int cost = 0; -if (hab >= 0 && hab < habDimTrfr) cost = habCost[hab]; -return cost; -} - -double Species::getHabMort(short hab) { -double pmort = 0.0; -if (hab >= 0 && hab < habDimTrfr) pmort = habStepMort[hab]; -return pmort; -} - -void Species::deleteHabCostMort(void) { -if (habCost != 0) { - delete[] habCost; habCost = 0; -} -if (habStepMort != 0) { - delete[] habStepMort; habStepMort = 0; -} -} - -//--------------------------------------------------------------------------- - -// Settlement functions - -void Species::setSettle(const settleType s) { -stgDepSett = s.stgDep; sexDepSett = s.sexDep; indVarSett = s.indVar; -} - -settleType Species::getSettle(void) { -settleType s; -s.stgDep = stgDepSett; s.sexDep = sexDepSett; s.indVar = indVarSett; -s.settTrait[0] = settTrait[0]; s.settTrait[1] = settTrait[1]; -return s; -} - -void Species::setSettRules(const short stg,const short sex,const settleRules s) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - densDepSett[stg][sex] = s.densDep; wait[stg][sex] = s.wait; - go2nbrLocn[stg][sex] = s.go2nbrLocn; findMate[stg][sex] = s.findMate; -} -} - -settleRules Species::getSettRules(short stg,short sex) { -settleRules s; -s.densDep = false; -s.findMate = false; -s.go2nbrLocn = false; -s.wait = false; -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - s.densDep = densDepSett[stg][sex]; s.wait = wait[stg][sex]; - s.go2nbrLocn = go2nbrLocn[stg][sex]; s.findMate = findMate[stg][sex]; -} -return s; -} - -void Species::setSteps(const short stg,const short sex,const settleSteps s) { -if (stg == 0 && sex == 0) { - if (s.minSteps >= 0) minSteps = s.minSteps; - else minSteps = 0; - if (s.maxSteps >= 1) maxSteps = s.maxSteps; - else maxSteps = 99999999; -} -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - if (s.maxStepsYr >= 1) maxStepsYr[stg][sex] = s.maxStepsYr; - else maxStepsYr[stg][sex] = 99999999; -} -} - -settleSteps Species::getSteps(short stg,short sex) { -settleSteps s; -s.minSteps = minSteps; -s.maxSteps = maxSteps; -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) s.maxStepsYr = maxStepsYr[stg][sex]; -else s.maxStepsYr = 99999999; -return s; -} - -void Species::setSettTraits(const short stg,const short sex,const settleTraits dd) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - if (dd.s0 > 0.0 && dd.s0 <= 1.0 ) s0[stg][sex] = dd.s0; - alphaS[stg][sex] = dd.alpha; betaS[stg][sex] = dd.beta; -} -} - -settleTraits Species::getSettTraits(short stg,short sex) { -settleTraits dd; -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - dd.s0 = s0[stg][sex]; dd.alpha = alphaS[stg][sex]; dd.beta = betaS[stg][sex]; -} -else { dd.s0 = 1.0; dd.alpha = dd.beta = 0.0; } -return dd; -} - -void Species::setSettParams(const short stg,const short sex,const settParams s) { -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < NSEXES) // implemented for stage 0 only -{ - if (s.s0Mean >= 0.0 && s.s0Mean < 1.0) s0Mean[stg][sex] = s.s0Mean; - if (s.s0SD > 0.0 && s.s0SD < 1.0) s0SD[stg][sex] = s.s0SD; - alphaSMean[stg][sex] = s.alphaSMean; - if (s.alphaSSD > 0.0) alphaSSD[stg][sex] = s.alphaSSD; - betaSMean[stg][sex] = s.betaSMean; - if (s.betaSSD > 0.0) betaSSD[stg][sex] = s.betaSSD; - if (sex == 0) { - if (s.s0Scale > 0.0 && s.s0Scale < 1.0) s0Scale = s.s0Scale; - if (s.alphaSScale > 0.0) alphaSScale = s.alphaSScale; - if (s.betaSScale > 0.0) betaSScale = s.betaSScale; - } -} -} - -settParams Species::getSettParams(short stg,short sex) { -settParams s; -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < NSEXES) // implemented for stage 0 only -{ - s.s0Mean = s0Mean[stg][sex]; s.s0SD = s0SD[stg][sex]; - s.alphaSMean = alphaSMean[stg][sex]; s.alphaSSD = alphaSSD[stg][sex]; - s.betaSMean = betaSMean[stg][sex]; s.betaSSD = betaSSD[stg][sex]; -} -else { - s.s0Mean = s.alphaSMean = s.betaSMean = s.s0SD = s.alphaSSD = s.betaSSD = 0.0; -} -s.s0Scale = s0Scale; -s.alphaSScale = alphaSScale; -s.betaSScale = betaSScale; -return s; -} - -void Species::setSettScales(const settScales s) { -if (s.s0Scale >= 0.0 && s.s0Scale < 1.0 ) s0Scale = s.s0Scale; -if (s.alphaSScale >= 0.0) alphaSScale = s.alphaSScale; -if (s.betaSScale >= 0.0) betaSScale = s.betaSScale; -} - -settScales Species::getSettScales(void) { -settScales s; -s.s0Scale = s0Scale; s.alphaSScale = alphaSScale; s.betaSScale = betaSScale; -return s; -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - diff --git a/RangeShiftR/src/RScore/Species.h b/RangeShiftR/src/RScore/Species.h deleted file mode 100644 index 3f1b100..0000000 --- a/RangeShiftR/src/RScore/Species.h +++ /dev/null @@ -1,756 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Species - -Implements the Species class - -There is ONE instance of a Species for each species within the Community -AND THIS IS CURRENTLY LIMITED TO A SINGLE SPECIES. -The class holds all the demographic and dispersal parameters of the species. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe?er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species? responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 28 July 2021 by Greta Bocedi - -------------------------------------------------------------------------------*/ - -#ifndef SpeciesH -#define SpeciesH - -//#if RS_RCPP && !R_CMD -#include "../Version.h" -//#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif -#include "Parameters.h" -#include - -// structures for demographic parameters - -struct demogrParams { - short repType; - short repSeasons; - float propMales; float harem; float bc; float lambda; - bool stageStruct; -}; -struct stageParams { - short nStages; short repInterval; short maxAge; short survival; - float probRep; - bool fecDens; bool fecStageDens; bool devDens; bool devStageDens; - bool survDens; bool survStageDens; bool disperseOnLoss; -}; -struct densDepParams { - float devCoeff; float survCoeff; -}; - -// structures for genetics - -struct genomeData { - int nLoci; - bool diploid; bool neutralMarkers; bool pleiotropic; bool trait1Chromosome; - double probMutn,probCrossover,alleleSD,mutationSD; -} ; - -struct traitAllele { - short chromo; short locus; -} ; - -struct traitMap { - short nAlleles; - traitAllele **traitalleles; -} ; - -struct traitData { - short nTraitMaps; - traitMap **traitmaps; - traitMap *neutralloci; -} ; - -// structures for emigration parameters - -struct emigRules { - bool densDep; bool stgDep; bool sexDep; bool indVar; - short emigStage; - short emigTrait[2]; -}; -struct emigTraits { - float d0; float alpha; float beta; -}; -struct emigParams { - double d0Mean; double d0SD; double d0Scale; - double alphaMean; double alphaSD; double alphaScale; - double betaMean; double betaSD; double betaScale; -}; -struct emigScales { - double d0Scale; double alphaScale; double betaScale; -}; - -// structures for transfer parameters - -struct trfrRules { - bool moveModel; bool stgDep; bool sexDep; - bool distMort; bool indVar; - bool twinKern; - bool habMort; - short moveType; bool costMap; - short movtTrait[2]; -}; -struct trfrKernTraits { - float meanDist1; float meanDist2; float probKern1; -}; -struct trfrMortParams { - float fixedMort; float mortAlpha; float mortBeta; -}; -struct trfrMovtTraits { - short pr; short prMethod; short memSize; short goalType; - float dp; float gb; float alphaDB; int betaDB; - float stepMort; float stepLength; float rho; - bool straigtenPath; -}; -struct trfrCRWTraits { - float stepMort; float stepLength; float rho; bool straigtenPath; -}; -struct trfrSMSTraits { - short pr; short prMethod; short memSize; short goalType; - float dp; float gb; float alphaDB; int betaDB; float stepMort; - bool straigtenPath; -}; -struct trfrKernParams { - double dist1Mean; double dist1SD; double dist1Scale; - double dist2Mean; double dist2SD; double dist2Scale; - double PKern1Mean; double PKern1SD; double PKern1Scale; -}; -struct trfrSMSParams { - double dpMean; double dpSD; double gbMean; double gbSD; - double alphaDBMean; double alphaDBSD; double betaDBMean; double betaDBSD; - double dpScale; double gbScale; double alphaDBScale; double betaDBScale; -}; -struct trfrCRWParams { - double stepLgthMean; double stepLgthSD; double stepLScale; - double rhoMean; double rhoSD; double rhoScale; -}; -struct trfrScales { - float dist1Scale; float dist2Scale; float PKern1Scale; - float dpScale; float gbScale; float alphaDBScale; float betaDBScale; - float stepLScale; float rhoScale; -}; - -// structures for settlement parameters - -struct settleType { - bool stgDep; bool sexDep; bool indVar; - short settTrait[2]; -}; -struct settleRules { - bool densDep; bool wait; bool go2nbrLocn; bool findMate; -}; -struct settleSteps { - int minSteps; int maxSteps; int maxStepsYr; -}; -struct settleTraits { - float s0; float alpha; float beta; -}; -struct settParams { - double s0Mean; double s0SD; double s0Scale; - double alphaSMean; double alphaSSD; double alphaSScale; - double betaSMean; double betaSSD; double betaSScale; -}; -struct settScales { - double s0Scale; double alphaSScale; double betaSScale; -}; - - -//--------------------------------------------------------------------------- - -class Species { - -public: - Species(void); - ~Species(void); - short getSpNum(void); - - // demographic parameter functions - - void createHabK( // Create habitat carrying capacity table - short // no. of habitats - ); - void setHabK( - short, // habitat index no. (NB may differ from habitat no. supplied by user) - float // carrying capacity (inds/cell) - ); - float getHabK( - short // habitat index no. (NB may differ from habitat no. supplied by user) - ); - float getMaxK(void); // return highest carrying capacity over all habitats - void deleteHabK(void); // Delete habitat carrying capacity table - void setStage( // Set stage structure parameters - const stageParams // structure holding stage structure parameters - ); - stageParams getStage(void); // Get stage structure parameters - void setDemogr( // Set general demographic parameters - const demogrParams // structure holding general demographic parameters - ); - demogrParams getDemogr(void); // Get general demographic parameters - short getRepType(void); - bool stageStructured(void); - void setDensDep( // Set demographic density dependence coefficients - float, // development coefficient - float // survival coefficient - ); - densDepParams getDensDep(void); // Get development and survival coefficients - - void setFec( // Set fecundity - short, // stage (must be > 0) - short, // sex - float // fecundity - ); - float getFec( // Get fecundity - short, // stage - short // sex - ); - void setDev( // Set development probability - short, // stage - short, // sex - float // development probability - ); - float getDev( // Get development probability - short, // stage - short // sex - ); - void setSurv( // Set survival probability - short, // stage - short, // sex - float // survival probability - ); - float getSurv( // Get survival probability - short, // stage - short // sex - ); - - float getMaxFec(void); // Get highest fecundity of any stage - void setMinAge( // Set minimum age - short, // stage - short, // sex - int // minimum age (years) (must be zero for stages 0 and 1) - ); - short getMinAge( // Get minimum age - short, // stage - short // sex - ); - void createDDwtFec( // Create fecundity weights matrix - short // matrix dimension - no. of stages * no. of sexes - ); - void setDDwtFec( // Set fecundity weights matrix element - short, // row - short, // column - float // weight - ); - float getDDwtFec( // Get fecundity weights matrix element - short, // row - short // column - ); - void deleteDDwtFec(void); // Delete fecundity weights matrix - void createDDwtDev( // Create development weights matrix - short // matrix dimension - no. of stages * no. of sexes - ); - void setDDwtDev( // Set development weights matrix element - short, // row - short, // column - float // weight - ); - float getDDwtDev( // Get development weights matrix element - short, // row - short // column - ); - void deleteDDwtDev(void); // Delete development weights matrix - void createDDwtSurv( // Create survival weights matrix - short // matrix dimension - no. of stages * no. of sexes - ); - void setDDwtSurv( // Set survival weights matrix element - short, // row - short, // column - float // weight - ); - float getDDwtSurv( // Get survival weights matrix element - short, // row - short // column - ); - void deleteDDwtSurv(void); // Delete survival weights matrix - // Functions to handle min/max R or K (under environmental stochasticity) - void setMinMax( // Set min and max values - float, // min - float // max - ); - float getMinMax( // Get min/max value - short // option: 0 = return minimum, otherwise = return maximum - ); - - - // genome functions - - void setGenomeData(genomeData); - genomeData getGenomeData(void); - bool isDiploid(void); - void setNChromosomes( // Set no. of chromosomes - int // no. of chromosomes - ); - int getNChromosomes(void); - void setNLoci( - const short, // chromosome no. - const short // locus no. - ); - int getNLoci( - const short // chromosome no. - ); - void deleteLoci(void); - void set1ChromPerTrait( // Set 1:1 mapping of trait to chromosome - const int // no. of loci on each chromosome - ); - bool has1ChromPerTrait(void); - void setTraits(void); // Set trait attributes for the species - void setTraitNames(void); - void deleteTraitNames(void); - string getTraitName( - const int // trait no. - ); - int getNTraits(void); - void setTraitData( - const int // no. of traits - ); - void deleteTraitData(void); - int getNTraitMaps(void); - void setTraitMap( - const short, // trait no. - const short // no. of alleles - ); - int getNTraitAlleles( - const int // trait no. - ); - void setTraitAllele( - const short, // trait no. - const short, // trait allele no. - const short, // chromosome no. - const short // chromosome locus no. - ); - traitAllele getTraitAllele( - const short, // trait no. - const short // trait allele no. - ); - void setNeutralLoci(bool); - void deleteNeutralLoci(void); - int getNNeutralLoci(void); - traitAllele getNeutralAllele( - const short // allele no. - ); - - // emigration parameter functions - - void setEmig( // Set emigration rules - const emigRules // structure holding emigration rules - ); - emigRules getEmig(void); // Get emigration rules - void setEmigTraits( // Set emigration trait parameters - const short, // stage - const short, // sex - const emigTraits // structure holding emigration trait parameters - ); - emigTraits getEmigTraits( // Get emigration trait parameters - short, // stage - short // sex - ); - float getEmigD0( // Get (maximum) emigration probability - short, // stage - short // sex - ); - void setEmigParams( // Set emigration initialisation parameters - const short, // stage (NB implemented for stage 0 only) - const short, // sex - const emigParams // structure holding parameters - ); - emigParams getEmigParams( // Get emigration initialisation parameters - short, // stage (NB implemented for stage 0 only) - short // sex - ); - void setEmigScales( // Set emigration mutation parameters - const emigScales // structure holding emigration mutation parameters - ); - emigScales getEmigScales(void); // Get emigration mutation parameters - - // transfer parameter functions - - void setTrfr( // Set transfer rules - const trfrRules // structure holding transfer rules - ); - trfrRules getTrfr(void); // Get transfer rules - void setFullKernel( // Set fullKernel condition - bool // fullKernel value - ); - bool useFullKernel(void); - void setKernTraits( // Set transfer by kernel parameters - const short, // stage - const short, // sex - const trfrKernTraits, // structure holding transfer by kernel parameters - const int // Landscape resolution - ); - trfrKernTraits getKernTraits( // Get transfer by kernel parameters - short, // stage - short // sex - ); - void setMortParams( // Set transfer mortality parameters - const trfrMortParams // structure holding transfer mortality parameters - ); - trfrMortParams getMortParams(void); // Get transfer mortality parameters - void setMovtTraits( // Set transfer movement model parameters - const trfrMovtTraits // structure holding transfer movement model parameters - ); - trfrMovtTraits getMovtTraits(void); // Get transfer movement model traits - trfrCRWTraits getCRWTraits(void); // Get CRW traits - trfrSMSTraits getSMSTraits(void); // Get SMS traits - void setKernParams( // Set initial transfer by kernel parameter limits - const short, // stage (NB implemented for stage 0 only) - const short, // sex - const trfrKernParams, // structure holding min and max values - const double // Landscape resolution - ); - trfrKernParams getKernParams( // Get initial transfer by kernel parameter limits - short, // stage (NB implemented for stage 0 only) - short // sex - ); - void setSMSParams( // Set initial transfer by SMS parameter limits - const short, // stage (NB implemented for stage 0 only) - const short, // sex (NB implemented for sex 0 only) - const trfrSMSParams // structure holding min and max values - ); - trfrSMSParams getSMSParams( // Get initial transfer by SMS parameter limits - short, // stage (NB implemented for stage 0 only) - short // sex (NB implemented for sex 0 only) - ); - void setCRWParams( // Set initial transfer by CRW parameter limits - const short, // stage (NB implemented for stage 0 only) - const short, // sex (NB implemented for sex 0 only) - const trfrCRWParams // structure holding min and max values - ); - trfrCRWParams getCRWParams( // Get initial transfer by CRW parameter limits - short, // stage (NB implemented for stage 0 only) - short // sex (NB implemented for sex 0 only) - ); - void setTrfrScales( // Set transfer mutation parameters - const trfrScales // structure holding transfer mutation parameters - ); - trfrScales getTrfrScales(void); // Get transfer mutation parameters - // Return dimension of habitat-dependent step mortality and costs matrices - short getMovtHabDim(void); - void createHabCostMort( // Create habitat-dependent costs and mortality matrices - short // no. of habitats - ); - void setHabCost( // Set habitat-dependent cost - short, // habitat index no. - int // cost value - ); - void setHabMort( // Set habitat-dependent per-step mortality - short, // habitat index no. - double // mortality rate - ); - int getHabCost( // Get habitat-dependent cost - short // habitat index no. - ); - double getHabMort( // Get habitat-dependent per-step mortality - short // habitat index no. - ); - void deleteHabCostMort(void); // Delete habitat-dependent costs and mortality matrices - - // settlement parameter functions - - void setSettle( // Set settlement type - const settleType // structure holding settlement type (stage- and/or sex-dependent) - ); - settleType getSettle(void); // Get settlement type - void setSettRules( // Set settlement rules - const short, // stage - const short, // sex - const settleRules // structure holding settlement rules - ); - settleRules getSettRules( // Get settlement rules - short, // stage - short // sex - ); - void setSteps( // Set path step limit parameters - const short, // stage - const short, // sex - const settleSteps // structure holding path step limit parameters - ); - settleSteps getSteps( // Set path step limit parameters - short, // stage - short // sex - ); - void setSettTraits( // Set settlement density dependence traits - const short, // stage - const short, // sex - const settleTraits // structure holding density dependence traits - ); - settleTraits getSettTraits( // Get settlement density dependence traits - short, // stage - short // sex - ); - void setSettParams( // Set settlement initialisation parameters - const short, // stage (NB implemented for stage 0 only) - const short, // sex - const settParams // structure holding parameters - ); - settParams getSettParams( // Get settlement initialisation parameters - short, // stage (NB implemented for stage 0 only) - short // sex - ); - void setSettScales( // Set settlement mutation parameters - const settScales // structure holding settlement mutation parameters - ); - settScales getSettScales(void); // Get settlement mutation parameters - -private: - - // NOTE: SEQUENCE OF PARAMETER VARIABLES MAY NEED TO BE ALTERED FOR EFFICIENTCY ... - // ... but that is of low importance, as there will only be one (or a few) instance(s) - - // demographic parameters - - short repType; // 0 = asexual, 1 = simple two sex, 2 = complex two sex - short nStages; // no. of stages (incl. juveniles) in structured population - float propMales; // proportion of males at birth in sexual model - float harem; // max harem size in complex sexual model - float bc; // competition coefficient for non-structured population - float lambda; // max intrinsic growth rate for non-structured population - float probRep; // probability of reproducing in subsequent seasons - short repSeasons; // no. of reproductive seasons per year - short repInterval; // no. of reproductive seasons between subsequent reproductions - short maxAge; // max age in structured population - short survival; // survival timing: 0 = at reprodn, 1 = between reprodns, 2 = anually - bool stageStruct; - bool fecDens; - bool fecStageDens; - bool devDens; - bool devStageDens; - bool survDens; - bool survStageDens; - bool disperseOnLoss; // individuals disperse on complete loss of patch - // (otherwise they die) - short habDimK; // dimension of carrying capacities matrix - float *habK; // habitat-specific carrying capacities (inds/cell) - float devCoeff; // density-dependent development coefficient - float survCoeff; // density-dependent survival coefficient - float **ddwtFec; // density-dependent weights matrix for fecundity - float **ddwtDev; // density-dependent weights matrix for development - float **ddwtSurv; // density-dependent weights matrix for survival - // NB for the following arrays, sex 0 is females, sex 1 is males - float fec[NSTAGES][NSEXES]; // fecundities - float dev[NSTAGES][NSEXES]; // development probabilities - float surv[NSTAGES][NSEXES]; // survival probabilities - short minAge[NSTAGES][NSEXES]; // minimum age to enter stage - // NOTE - IN THEORY, NEXT 3 VARIABLES COULD BE COMMON, BUT WE WOULD NEED TO ENSURE THAT - // ALL MATRICES ARE DELETED IF THERE IS A CHANGE IN NO. OF STAGES OR REPRODUCTION TYPE - // ***** TO BE RECONSIDERED LATER ***** - short ddwtFecDim; // dimension of density-dependent weights matrix for fecundity - short ddwtDevDim; // dimension of density-dependent weights matrix for fecundity - short ddwtSurvDim; // dimension of density-dependent weights matrix for fecundity - float minRK; // minimum ) growth rate OR carrying capacity - float maxRK; // maximum ) (under environmental stochasticity) - - // genome parameters - - short nTraits; // no. of inheritable traits - short emigTrait[2]; // to record first and no. of emigration traits - short movtTrait[2]; // to record first and no. of transfer traits - short settTrait[2]; // to record first and no. of settlement traits - bool diploid; - bool neutralMarkers; // neutral markers in absence of any adaptive traits - bool pleiotropic; - bool trait1Chromosome; // 1:1 mapping of chromosome to trait - short nChromosomes; // no. of chromosomes - double probMutn; // allelic mutation probability - double probCrossover; // crossover probability at meiosis - double alleleSD; // s.d. of initial allelic values around phenotypic value - double mutationSD; // s.d. of mutation magnitude - short nNLoci; // no. of nLoci set - short *nLoci; // no. of loci per chromosome - short nTraitNames; // no. of trait names set - traitData *traitdata; // for mapping of chromosome loci to traits - string *traitnames; // trait names for parameter output - - // emigration parameters - - bool densDepEmig; // density-dependent emigration - bool stgDepEmig; // stage-dependent emigration - bool sexDepEmig; // sex-dependent emigration - bool indVarEmig; // individual variation in emigration - short emigStage; // stage which emigrates (used for stage-strucutred population - // having individual variability in emigration probability) - // NB for the following arrays, sex 0 is females, sex 1 is males - float d0[NSTAGES][NSEXES]; // maximum emigration probability - float alphaEmig[NSTAGES][NSEXES]; // slope of density-dependent reaction norm - float betaEmig[NSTAGES][NSEXES]; // inflection point of reaction norm (in terms of N/K) - // NB Initialisation parameters are made double to avoid conversion errors (reason unclear) - // on traits maps using FloatToStr() - // As evolving traits are not stage-dependent, no. of rows can be 1 - // Indeed, they could be 1-D arrays - double d0Mean[1][NSEXES]; - double d0SD[1][NSEXES]; - double alphaMean[1][NSEXES]; - double alphaSD[1][NSEXES]; - double betaMean[1][NSEXES]; - double betaSD[1][NSEXES]; - double d0Scale; // scaling factor for d0 - double alphaScale; // scaling factor for alpha - double betaScale; // scaling factor for beta - - // transfer parameters - - bool moveModel; - bool stgDepTrfr; - bool sexDepTrfr; - bool distMort; - bool indVarTrfr; - bool twinKern; - bool habMort; // habitat-dependent mortality - float meanDist1[NSTAGES][NSEXES]; // mean of 1st dispersal kernel (m) - float meanDist2[NSTAGES][NSEXES]; // mean of 2nd dispersal kernel (m) - float probKern1[NSTAGES][NSEXES]; // probability of dispersing with the 1st kernel - // NB INITIAL limits are made double to avoid conversion errors (reason unclear) - // on traits maps using FloatToStr() - // As evolving traits are are not stage-dependent, no. of rows can be 1 - // Indeed, as they are INITIAL limits, which may subsequently be exceeded, they could be - // 1-D arrays - double dist1Mean[1][NSEXES]; // mean of initial mean of the 1st dispersal kernel (m) - double dist1SD[1][NSEXES]; // s.d. of initial mean of the 1st dispersal kernel (m) - double dist2Mean[1][NSEXES]; // mean of initial mean of the 2nd dispersal kernel (m) - double dist2SD[1][NSEXES]; // s.d. of initial mean of the 2nd dispersal kernel (m) - double PKern1Mean[1][NSEXES]; // mean of initial prob. of dispersing with 1st kernel - double PKern1SD[1][NSEXES]; // s.d. of initial prob. of dispersing with 1st kernel - float dist1Scale; // scaling factor for mean of 1st dispersal kernel (m) - float dist2Scale; // scaling factor for mean of 2nd dispersal kernel (m) - float PKern1Scale; // scaling factor for prob. of dispersing with 1st kernel - float fixedMort; // constant mortality probability - float mortAlpha; // slope for mortality distance dependence function - float mortBeta; // inflection point for mortality distance dependence function - short moveType; // 1 = SMS, 2 = CRW - short pr; // SMS perceptual range (cells) - short prMethod; // SMS perceptual range evaluation method: - // 1 = arith. mean, 2 = harmonic mean, 3 = inverse weighted arith. mean - short memSize; // SMS memory size (1-14 steps) - short goalType; // SMS goal bias type: 0 = none, 1 = towards goal, 2 = dispersal bias - float dp; // SMS directional persistence - float gb; // SMS goal bias - float alphaDB; // SMS dispersal bias decay rate - int betaDB; // SMS dispersal bias decay inflection point (no. of steps) - float stepMort; // constant per-step mortality probability for movement models - double *habStepMort; // habitat-dependent per-step mortality probability - float stepLength; // CRW step length (m) - float rho; // CRW correlation coefficient - double dpMean[1][NSEXES]; // mean of initial SMS directional persistence - double dpSD[1][NSEXES]; // s.d. of initial SMS directional persistence - double gbMean[1][NSEXES]; // mean of initial SMS goal bias - double gbSD[1][NSEXES]; // s.d. of initial SMS goal bias - double alphaDBMean[1][NSEXES]; // mean of initial SMS dispersal bias decay rate - double alphaDBSD[1][NSEXES]; // s.d. of initial SMS dispersal bias decay rate - double betaDBMean[1][NSEXES]; // mean of initial SMS dispersal bias decay infl. pt. - double betaDBSD[1][NSEXES]; // s.d. of initial SMS dispersal bias decay infl. pt. - float dpScale; // scaling factor for SMS directional persistence - float gbScale; // scaling factor for SMS goal bias - float alphaDBScale; // scaling factor for SMS dispersal bias decay rate - float betaDBScale; // scaling factor for SMS dispersal bias decay infl. pt. - double stepLgthMean[1][NSEXES]; // mean of initial step length (m) - double stepLgthSD[1][NSEXES]; // s.d. of initial step length (m) - double rhoMean[1][NSEXES]; // mean of initial correlation coefficient - double rhoSD[1][NSEXES]; // s.d. of initial correlation coefficient - float stepLScale; // scaling factor for step length (m) - float rhoScale; // scaling factor for correlation coefficient - short habDimTrfr; // dimension of habitat-dependent step mortality and costs matrices - int *habCost; // habitat costs - bool costMap; // import cost map from file? - bool straigtenPath; // straighten path after decision not to settle - bool fullKernel; // used to indicate special case when density-independent emigration - // is 1.0, and kernel-based movement within the natal cell is used - // to determine philopatry - - // settlement parameters - - bool stgDepSett; - bool sexDepSett; - bool indVarSett; // individual variation in settlement - bool densDepSett[NSTAGES][NSEXES]; - bool wait[NSTAGES][NSEXES]; // wait to continue moving next season (stage-structured model only) - bool go2nbrLocn[NSTAGES][NSEXES]; // settle in neighbouring cell/patch if available (ditto) - bool findMate[NSTAGES][NSEXES]; - int minSteps; // minimum no. of steps - int maxSteps; // maximum total no. of steps - int maxStepsYr[NSTAGES][NSEXES]; // maximum no. of steps in any one dispersal period - float s0[NSTAGES][NSEXES]; // maximum settlement probability - float alphaS[NSTAGES][NSEXES]; // slope of the settlement reaction norm to density - float betaS[NSTAGES][NSEXES]; // inflection point of the settlement reaction norm to density - double s0Mean[1][NSEXES]; // mean of initial maximum settlement probability - double s0SD[1][NSEXES]; // s.d. of initial maximum settlement probability - double alphaSMean[1][NSEXES]; // mean of initial settlement reaction norm slope - double alphaSSD[1][NSEXES]; // s.d. of initial settlement reaction norm slope - double betaSMean[1][NSEXES]; // mean of initial settlement reaction norm inflection point - double betaSSD[1][NSEXES]; // s.d. of initial settlement reaction norm inflection point - float s0Scale; // scaling factor for maximum settlement probability - float alphaSScale; // scaling factor for settlement reaction norm slope - float betaSScale; // scaling factor for settlement reaction norm inflection point - - // other attributes - - int spNum; - -}; - -/* IMPORTANT NOTE: -At the time of writing (24/4/14) the stage- and sex-dependent parameters for emigration -and dispersal (e.g. d0[NSTAGES][NSEXES]) are set according to the appropriate stage- and -sex-dependent settings; thus a species could be structured and sexual, but parameter values -are set for elements [0][0] only if emigration/transfer is stage- and sex-independent. -However, the parameters for settlement are set for ALL stages and sexes appropriate to the -species, regardless of settlement dependency. The rationale for this is that settlement -parameters need to be accessed many more times for a movement model (at each step) than -emigration or transfer parameters, and therefore there will be a performance gain in -avoiding nested if statements in Individual::moveStep() which would otherwise be required -to get the correct parameter values from the settlement arrays. Whether that particular -rationale is justified remains to be tested! -*/ - -//--------------------------------------------------------------------------- - -#if RSDEBUG -//extern ofstream DEBUGLOG; -extern void DebugGUI(string); -#endif - -//--------------------------------------------------------------------------- -#endif diff --git a/RangeShiftR/src/RScore/SubCommunity.cpp b/RangeShiftR/src/RScore/SubCommunity.cpp deleted file mode 100644 index 26685e3..0000000 --- a/RangeShiftR/src/RScore/SubCommunity.cpp +++ /dev/null @@ -1,1204 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "SubCommunity.h" -//--------------------------------------------------------------------------- - -ofstream outtraits; - -//--------------------------------------------------------------------------- - -SubCommunity::SubCommunity(Patch* pPch, int num) { -subCommNum = num; -pPatch = pPch; -// record the new sub-community no. in the patch -pPatch->setSubComm((intptr)this); -initial = false; -occupancy = 0; -} - -SubCommunity::~SubCommunity() { -pPatch->setSubComm(0); -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - delete popns[i]; -} -popns.clear(); -if (occupancy != 0) delete[] occupancy; -} - -intptr SubCommunity::getNum(void) { return subCommNum; } - -Patch* SubCommunity::getPatch(void) { return pPatch; } - -locn SubCommunity::getLocn(void) { -locn loc = pPatch->getCellLocn(0); -return loc; -} - -void SubCommunity::setInitial(bool b) { initial = b; } - -void SubCommunity::initialise(Landscape *pLandscape,Species *pSpecies) -{ -//patchLimits limits; -//locn loc; -int ncells; -landParams ppLand = pLandscape->getLandParams(); -initParams init = paramsInit->getInit(); -#if RSDEBUG -//DEBUGLOG << "SubCommunity::initialise(): subCommNum=" << subCommNum -// << " seedType="<< init.seedType -// << " popns.size()="<< popns.size() -// << endl; -#endif -// determine size of initial population -//int hx,nInds; -int nInds = 0; -if (subCommNum == 0 // matrix patch -|| !initial) // not in initial region or distribution - nInds = 0; -else { - float k = pPatch->getK(); - if (k > 0.0) { // patch is currently suitable for this species - switch (init.initDens) { - case 0: // at carrying capacity - nInds = (int)k; - break; - case 1: // at half carrying capacity - nInds = (int)(k/2.0); - break; - case 2: // specified no. per cell or density - ncells = pPatch->getNCells(); - if (ppLand.patchModel) { - nInds = (int)(init.indsHa * (float)(ncells*ppLand.resol*ppLand.resol) / 10000.0); - } - else { - nInds = init.indsCell * ncells; - } - break; - } - } - else nInds = 0; -} - -// create new population (even if it has no individuals) -//popns.push_back(new Population(pSpecies,pPatch,nInds)); -//newPopn(pSpecies,pPatch,nInds); - -// create new population only if it is non-zero or the matrix popn -if (subCommNum == 0 || nInds > 0) { - newPopn(pLandscape,pSpecies,pPatch,nInds); -} - -} - -// initialise a specified individual -void SubCommunity::initialInd(Landscape *pLandscape,Species *pSpecies, - Patch *pPatch,Cell *pCell,int ix) -{ - -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -genomeData gen = pSpecies->getGenomeData(); -short stg,age,repInt; -Individual *pInd; -float probmale; -// bool movt; -// short moveType; - -// create new population if not already in existence -int npopns = (int)popns.size(); -if (npopns < 1) { - newPopn(pLandscape,pSpecies,pPatch,0); -} - -// create new individual -initInd iind = paramsInit->getInitInd(ix); -if (dem.stageStruct) { - stg = iind.stage; age = iind.age; repInt = sstruct.repInterval; -} -else { - age = stg = 1; repInt = 0; -} -if (dem.repType == 0) { - probmale = 0.0; -} -else { - if (iind.sex == 1) probmale = 1.0; else probmale = 0.0; -} -//if (trfr.moveModel) { -// movt = true; -// if (trfr.moveType) { -// -// } -//} -pInd = new Individual(pCell,pPatch,stg,age,repInt,probmale,trfr.moveModel,trfr.moveType); - -// add new individual to the population -// NB THIS WILL NEED TO BE CHANGED FOR MULTIPLE SPECIES... -popns[0]->recruit(pInd); - -if (emig.indVar || trfr.indVar || sett.indVar || gen.neutralMarkers) -{ - // individual variation - set up genetics - landData land = pLandscape->getLandData(); - pInd->setGenes(pSpecies,land.resol); -} - -} - -// Create a new population, and return its address -Population* SubCommunity::newPopn(Landscape *pLandscape,Species *pSpecies, - Patch *pPatch,int nInds) -{ -#if RSDEBUG -//DEBUGLOG << "SubCommunity::newPopn(): subCommNum = " << subCommNum -// << " pPatch = " << pPatch << " nInds = "<< nInds << endl; -#endif -landParams land = pLandscape->getLandParams(); -int npopns = (int)popns.size(); -popns.push_back(new Population(pSpecies,pPatch,nInds,land.resol)); -#if RSDEBUG -//DEBUGLOG << "SubCommunity::newPopn(): subCommNum = " << subCommNum -// << " npopns = " << npopns << " popns[npopns] = " << popns[npopns] -// << endl; -#endif -return popns[npopns]; -} - -popStats SubCommunity::getPopStats(void) { -popStats p,pop; -p.pSpecies = 0; p.spNum = 0; p.nInds = p.nAdults = p.nNonJuvs = 0; p.breeding = false; -p.pPatch = pPatch; -// FOR SINGLE SPECIES IMPLEMENTATION, THERE IS ONLY ONE POPULATION IN THE PATCH -//p = popns[0]->getStats(); -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations -#if RSDEBUG -//DEBUGLOG << "SubCommunity::getPopStats(): npops = " << npops -// << " i = " << i -// << " popns[i] = " << popns[i] << endl; -#endif - pop = popns[i]->getStats(); - p.pSpecies = pop.pSpecies; - p.spNum = pop.spNum; - p.nInds += pop.nInds; - p.nNonJuvs += pop.nNonJuvs; - p.nAdults += pop.nAdults; - p.breeding = pop.breeding; -#if RSDEBUG -//DEBUGLOG << "SubCommunity::getPopStats():" -// << " p.pSpecies = " << p.pSpecies -// << " p.pPatch = " << p.pPatch -// << " p.spNum = " << p.spNum -// << " p.nInds = " << p.nInds -// << endl; -#endif -} -return p; -} - -void SubCommunity::resetPopns(void) { -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - delete popns[i]; -} -popns.clear(); -// clear the list of populations in the corresponding patch -pPatch->resetPopn(); -} - -void SubCommunity::resetPossSettlers(void) { -if (subCommNum == 0) return; // not applicable in the matrix -//int npops = (int)popns.size(); -//for (int i = 0; i < npops; i++) { // all populations -// popns[i]->resetPossSettlers(); -//} -pPatch->resetPossSettlers(); -} - -// Extirpate all populations according to -// option 0 - random local extinction probability -// option 1 - local extinction probability gradient -// NB only applied for cell-based model -void SubCommunity::localExtinction(int option) { -double pExtinct = 0.0; -if (option == 0) { - envStochParams env = paramsStoch->getStoch(); - if (env.localExt) pExtinct = env.locExtProb; -} -else { - envGradParams grad = paramsGrad->getGradient(); - Cell *pCell = pPatch->getRandomCell(); // get only cell in the patch - // extinction prob is complement of cell gradient value plus any non-zero prob at the optimum - pExtinct = 1.0 - pCell->getEnvVal() + grad.extProbOpt; - if (pExtinct > 1.0) pExtinct = 1.0; -} -if (pRandom->Bernoulli(pExtinct)) { - int npops = (int)popns.size(); - for (int i = 0; i < npops; i++) { // all populations - popns[i]->extirpate(); - } -} -} - -// Action in event of patch becoming unsuitable owing to landscape change -void SubCommunity::patchChange(void) { -if (subCommNum == 0) return; // no reproduction in the matrix -Species *pSpecies; -float localK = 0.0; -int npops = (int)popns.size(); -// THE FOLLOWING MAY BE MORE EFFICIENT WHILST THERE IS ONLY ONE SPECIES ... -if (npops < 1) return; -localK = pPatch->getK(); -if (localK <= 0.0) { // patch in dynamic landscape has become unsuitable - for (int i = 0; i < npops; i++) { // all populations - pSpecies = popns[i]->getSpecies(); - demogrParams dem = pSpecies->getDemogr(); - if (dem.stageStruct) { - stageParams sstruct = pSpecies->getStage(); - if (sstruct.disperseOnLoss) popns[i]->allEmigrate(); - else popns[i]->extirpate(); - } - else { // non-stage-structured species is destroyed - popns[i]->extirpate(); - } - } -} -} - -void SubCommunity::reproduction(int resol,float epsGlobal,short rasterType,bool patchModel) -{ -if (subCommNum == 0) return; // no reproduction in the matrix -float localK,envval; -//Species *pSpecies; -Cell *pCell; -envGradParams grad = paramsGrad->getGradient(); -envStochParams env = paramsStoch->getStoch(); - -int npops = (int)popns.size(); -// THE FOLLOWING MAY BE MORE EFFICIENT WHILST THERE IS ONLY ONE SPECIES ... -if (npops < 1) return; - -localK = pPatch->getK(); -if (localK > 0.0) { - if (patchModel) { - envval = 1.0; // environmental gradient is currently not applied for patch-based model - } - else { // cell-based model - if (grad.gradient && grad.gradType == 2) - { // gradient in fecundity - Cell *pCell = pPatch->getRandomCell(); // locate the only cell in the patch - envval = pCell->getEnvVal(); - } - else envval = 1.0; - } - if (env.stoch && !env.inK) { // stochasticity in fecundity - if (env.local) { - if (!patchModel) { // only permitted for cell-based model - pCell = pPatch->getRandomCell(); - if (pCell != 0) envval += pCell->getEps(); - } - } - else { // global stochasticity - envval += epsGlobal; - } - } - for (int i = 0; i < npops; i++) { // all populations - popns[i]->reproduction(localK,envval,resol); - popns[i]->fledge(); - } -} -/* -else { // patch in dynamic landscape has become unsuitable - // NB - THIS WILL NEED TO BE MADE SPECIES-SPECIFIC... - Species *pSpecies; - for (int i = 0; i < npops; i++) { // all populations - pSpecies = popns[i]->getSpecies(); - demogrParams dem = pSpecies->getDemogr(); - if (dem.stageStruct) { - stageParams sstruct = pSpecies->getStage(); - if (sstruct.disperseOnLoss) popns[i]->allEmigrate(); - else popns[i]->extirpate(); - } - else { // non-stage-structured species is destroyed - popns[i]->extirpate(); - } - } -} -*/ - -/* -#if RSDEBUG -//if (npops > 0) { -// DEBUGLOG << "SubCommunity::reproduction(): this = " << this -// << " npops = " << npops << endl; -//} -#endif -#if RSDEBUG -//DEBUGLOG << "SubCommunity::reproduction(): patchNum = " << pPatch->getPatchNum() -// << " nCells " << pPatch->getNCells() -// << " localK = " << localK -// << endl; -#endif -*/ -} - -void SubCommunity::emigration(void) -{ -if (subCommNum == 0) return; // no emigration from the matrix -float localK; -int npops = (int)popns.size(); -// THE FOLLOWING MAY BE MORE EFFICIENT WHILST THERE IS ONLY ONE SPECIES ... -if (npops < 1) return; -localK = pPatch->getK(); -// NOTE that even if K is zero, it could have been >0 in previous time-step, and there -// might be emigrants if there is non-juvenile emigration -for (int i = 0; i < npops; i++) { // all populations -// localK = pPatch->getK(); - popns[i]->emigration(localK); -} -} - -// Remove emigrants from their natal patch and add to patch 0 (matrix) -void SubCommunity::initiateDispersal(SubCommunity* matrix) { -if (subCommNum == 0) return; // no dispersal initiation in the matrix -#if RSDEBUG -//DEBUGLOG << "SubCommunity::initiateDispersal(): this=" << this -// << " subCommNum=" << subCommNum -// << endl; -#endif -popStats pop; -disperser disp; - -int npops = (int)popns.size(); -#if RSDEBUG -//DEBUGLOG << "SubCommunity::initiateDispersal(): patchNum = " << patchNum -// << " npops " << npops -// << endl; -#endif -for (int i = 0; i < npops; i++) { // all populations - pop = popns[i]->getStats(); - for (int j = 0; j < pop.nInds; j++) { -#if RSDEBUG -//DEBUGLOG << "SubCommunity::initiateDispersal(): i = " << i -// << " j " << j -// << endl; -#endif - disp = popns[i]->extractDisperser(j); - if (disp.yes) { // disperser - has already been removed from natal population - // add to matrix population - matrix->recruit(disp.pInd,pop.pSpecies); - } - } - // remove pointers to emigrants - popns[i]->clean(); -} - -} - -// Add an individual into the local population of its species in the patch -void SubCommunity::recruit(Individual *pInd,Species *pSpecies) { -#if RSDEBUG -//DEBUGLOG << "SubCommunity::recruit(): this=" << this -// << endl; -#endif -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - if (pSpecies == popns[i]->getSpecies()) { - popns[i]->recruit(pInd); - } -} -} - -// Transfer through the matrix - run for the matrix sub-community only -#if RS_RCPP // included also SEASONAL -int SubCommunity::transfer(Landscape *pLandscape,short landIx,short nextseason) -#else -int SubCommunity::transfer(Landscape *pLandscape,short landIx) -#endif // SEASONAL || RS_RCPP -{ -#if RSDEBUG -//DEBUGLOG << "SubCommunity::transfer(): this=" << this -// << endl; -#endif -int ndispersers = 0; -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations -#if RS_RCPP // included also SEASONAL - ndispersers += popns[i]->transfer(pLandscape,landIx,nextseason); -#else - ndispersers += popns[i]->transfer(pLandscape,landIx); -#endif // SEASONAL || RS_RCPP -#if RSDEBUG -//DEBUGLOG << "SubCommunity::transfer(): i = " << i -// << " this = " << this -// << " subCommNum = " << subCommNum -// << " npops = " << npops -// << " popns[i] = " << popns[i] -// << " ndispersers = " << ndispersers -// << endl; -#endif -} -return ndispersers; -} - -//--------------------------------------------------------------------------- - -// Remove emigrants from patch 0 (matrix) and transfer to sub-community -// in which their destination co-ordinates fall -// This function is executed for the matrix patch only - -void SubCommunity::completeDispersal(Landscape *pLandscape,bool connect) -{ -#if RSDEBUG -//DEBUGLOG << "SubCommunity::completeDispersal(): this=" << this -// << endl; -#endif -//popStats pop; -//int popsize,subcomm; -int popsize; -disperser settler; -Species *pSpecies; -Population *pPop; -Patch *pPrevPatch; -Patch *pNewPatch; -Cell *pPrevCell; -SubCommunity *pSubComm; - -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - pSpecies = popns[i]->getSpecies(); - popsize = popns[i]->getNInds(); -#if RSDEBUG -//DEBUGLOG << "SubCommunity::completeDispersal(): i=" << i -// << " subCommNum=" << subCommNum -// << " pPatch=" << pPatch << " patchNum=" << pPatch->getPatchNum() -// << " npops=" << npops -// << " popns[i]=" << popns[i] -// << " popsize=" << popsize -// << endl; -#endif - for (int j = 0; j < popsize; j++) { - bool settled; - settler = popns[i]->extractSettler(j); - settled = settler.yes; - if (settled) { - // settler - has already been removed from matrix population - // in popns[i]->extractSettler() -#if RSDEBUG -//locn loc = pNewCell->getLocn(); -//DEBUGLOG << "SubCommunity::completeDispersal(): j=" << j << " settled=" << settled; -//#if GROUPDISP -//if (emig.groupdisp) { -//DEBUGLOG << " groupID=" << groupsettler.pGroup->getGroupID() -// << " groupsize=" << groupsettler.groupsize -// << " status=" << groupsettler.pGroup->getStatus(); -//} -//else { -//DEBUGLOG << " settler.pInd=" << settler.pInd; -//} -//#else -//DEBUGLOG << " settler.pInd=" << settler.pInd; -//#endif // GROUPDISP -//DEBUGLOG << " loc.x=" << loc.x << " loc.y=" << loc.y << endl; -#endif // RSDEBUG - // find new patch - pNewPatch = (Patch*)settler.pCell->getPatch(); - // find population within the patch (if there is one) -// subcomm = ppatch->getSubComm(); -// if (subcomm == 0) { // no sub-community has yet been set up -// // CANNOT SET UP A NEW ONE FROM WITHIN AN EXISTING ONE!!!!! -// } - pPop = (Population*)pNewPatch->getPopn((intptr)pSpecies); -#if RSDEBUG -//DEBUGLOG << "SubCommunity::completeDispersal(): j = " << j -// << " pCell = " << pCell << " ppatch = " << ppatch << " pPop = " << pPop -// << endl; -#endif - if (pPop == 0) { // settler is the first in a previously uninhabited patch - // create a new population in the corresponding sub-community - pSubComm = (SubCommunity*)pNewPatch->getSubComm(); -#if RSDEBUG -//DEBUGLOG << "SubCommunity::completeDispersal(): j = " << j -// << " pSubComm = " << pSubComm << endl; -#endif - pPop = pSubComm->newPopn(pLandscape,pSpecies,pNewPatch,0); -#if RSDEBUG -//DEBUGLOG << "SubCommunity::completeDispersal(): j=" << j -// << " pPop=" << pPop << endl; -#endif - } - pPop->recruit(settler.pInd); - if (connect) { // increment connectivity totals - int newpatch = pNewPatch->getSeqNum(); - pPrevCell = settler.pInd->getLocn(0); // previous cell - intptr patch = pPrevCell->getPatch(); - if (patch != 0) { - pPrevPatch = (Patch*)patch; - int prevpatch = pPrevPatch->getSeqNum(); - pLandscape->incrConnectMatrix(prevpatch,newpatch); - } - } - } - else { // for group dispersal only - } - } - // remove pointers in the matrix popn to settlers - popns[i]->clean(); -#if RSDEBUG -//pop = popns[i]->getStats(); -popsize = popns[i]->getNInds(); -//DEBUGLOG << "SubCommunity::completeDispersal(): i=" << i -// << " popns[i]=" << popns[i] -//// << " pop.pPatch = " << pop.pPatch -//// << " pop.nInds = " << pop.nInds -// << " popsize=" << popsize -// << endl; -#endif -} - -} - -//--------------------------------------------------------------------------- - -void SubCommunity::survival(short part,short option0,short option1) -{ -int npops = (int)popns.size(); -if (npops < 1) return; -if (part == 0) { - float localK = pPatch->getK(); - for (int i = 0; i < npops; i++) { // all populations - popns[i]->survival0(localK,option0,option1); - } -} -else { - for (int i = 0; i < npops; i++) { // all populations - popns[i]->survival1(); - } -} -} - -void SubCommunity::ageIncrement(void) { -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - popns[i]->ageIncrement(); -} -} - -// Find the population of a given species in a given patch -Population* SubCommunity::findPop(Species *pSp,Patch *pPch) { -#if RSDEBUG -DEBUGLOG << "SubCommunity::findPop(): this=" << this - << endl; -#endif - -Population *pPop = 0; -popStats pop; -int npops = (int)popns.size(); - -for (int i = 0; i < npops; i++) { // all populations - pop = popns[i]->getStats(); - if (pop.pSpecies == pSp && pop.pPatch == pPch) { // population located - pPop = popns[i]; - break; - } - else pPop = 0; -} -return pPop; -} - -//--------------------------------------------------------------------------- - -void SubCommunity::createOccupancy(int nrows) { -if (occupancy != 0) deleteOccupancy(); -if (nrows > 0) { - occupancy = new int[nrows]; - for (int i = 0; i < nrows; i++) occupancy[i] = 0; -} -} - -void SubCommunity::updateOccupancy(int row) { -#if RSDEBUG -//DEBUGLOG << "SubCommunity::updateOccupancy(): this=" << this -// << endl; -#endif -popStats pop; -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { - pop = popns[i]->getStats(); - if (pop.nInds > 0 && pop.breeding) { - occupancy[row]++; - i = npops; - } -} -} - -int SubCommunity::getOccupancy(int row) { -if (row >= 0) return occupancy[row]; -else return 0; -} - -void SubCommunity::deleteOccupancy(void) { - delete[] occupancy; - occupancy = 0; -} - -//--------------------------------------------------------------------------- -// Open population file and write header record -bool SubCommunity::outPopHeaders(Landscape *pLandscape,Species *pSpecies,int option) -{ -bool fileOK; -Population *pPop; -landParams land = pLandscape->getLandParams(); - -if (option == -999) { // close the file - // as all populations may have been deleted, set up a dummy one - // species is not necessary - pPop = new Population(); - fileOK = pPop->outPopHeaders(-999,land.patchModel); - delete pPop; -} -else { // open the file - // as no population has yet been created, set up a dummy one - // species is necessary, as columns depend on stage and sex structure - pPop = new Population(pSpecies,pPatch,0,land.resol); - fileOK = pPop->outPopHeaders(land.landNum,land.patchModel); - delete pPop; -} -return fileOK; -} - -// Write records to population file -void SubCommunity::outPop(Landscape *pLandscape,int rep,int yr,int gen) -{ -landParams land = pLandscape->getLandParams(); -envGradParams grad = paramsGrad->getGradient(); -envStochParams env = paramsStoch->getStoch(); -bool writeEnv = false; -bool gradK = false; -if (grad.gradient) { - writeEnv = true; - if (grad.gradType == 1) gradK = true; // ... carrying capacity -} -if (env.stoch) writeEnv = true; - -// generate output for each population within the sub-community (patch) -// provided that the patch is suitable (i.e. non-zero carrying capacity) -// or the population is above zero (possible if there is stochasticity or a moving gradient) -// or it is the matrix patch in a patch-based model -int npops = (int)popns.size(); -int patchnum; -//Species* pSpecies; -Cell *pCell; -float localK; -float eps = 0.0; -if (env.stoch) { - if (env.local) { - pCell = pPatch->getRandomCell(); - if (pCell != 0) eps = pCell->getEps(); - } - else { - eps = pLandscape->getGlobalStoch(yr); - } -} - -patchnum = pPatch->getPatchNum(); -for (int i = 0; i < npops; i++) { // all populations -// pSpecies = popns[i]->getSpecies(); - localK = pPatch->getK(); - if (localK > 0.0 || (land.patchModel && patchnum == 0)) { - popns[i]->outPopulation(rep,yr,gen,eps,land.patchModel,writeEnv,gradK); - } - else { - if (popns[i]->totalPop() > 0) { - popns[i]->outPopulation(rep,yr,gen,eps,land.patchModel,writeEnv,gradK); - } - } -} -} - -// Write records to individuals file -void SubCommunity::outInds(Landscape *pLandscape,int rep,int yr,int gen,int landNr) { -landParams ppLand = pLandscape->getLandParams(); -if (landNr >= 0) { // open the file - popns[0]->outIndsHeaders(rep,landNr,ppLand.patchModel); - return; -} -if (landNr == -999) { // close the file - popns[0]->outIndsHeaders(rep,-999,ppLand.patchModel); - return; -} -// generate output for each population within the sub-community (patch) -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - popns[i]->outIndividual(pLandscape,rep,yr,gen,pPatch->getPatchNum()); -} -} - -// Write records to individuals file -void SubCommunity::outGenetics(int rep,int yr,int gen,int landNr) -{ -//landParams ppLand = pLandscape->getLandParams(); -if (landNr >= 0) { // open the file - popns[0]->outGenetics(rep,yr,landNr); - return; -} -if (landNr == -999) { // close the file - popns[0]->outGenetics(rep,yr,landNr); - return; -} -// generate output for each population within the sub-community (patch) -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - popns[i]->outGenetics(rep,yr,landNr); -} -} - -// Population size of a specified stage -int SubCommunity::stagePop(int stage) { -int popsize = 0; -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - popsize += popns[i]->stagePop(stage); -} -return popsize; -} - -// Open traits file and write header record -bool SubCommunity::outTraitsHeaders(Landscape *pLandscape,Species *pSpecies,int landNr) -{ -//Population *pPop; -landParams land = pLandscape->getLandParams(); -if (landNr == -999) { // close file - if (outtraits.is_open()) outtraits.close(); - outtraits.clear(); - return true; -} - -string name; -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -simParams sim = paramsSim->getSim(); - -string DirOut = paramsSim->getDir(2); -if (sim.batchMode) { - if (land.patchModel){ - name = DirOut - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(landNr) - + "_TraitsXpatch.txt"; - } - else{ - name = DirOut - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(landNr) - + "_TraitsXcell.txt"; - } -} -else { - if (land.patchModel){ - name = DirOut + "Sim" + Int2Str(sim.simulation) + "_TraitsXpatch.txt"; - } - else{ - name = DirOut + "Sim" + Int2Str(sim.simulation) + "_TraitsXcell.txt"; - } -} -outtraits.open(name.c_str()); - -outtraits << "Rep\tYear\tRepSeason"; -if (land.patchModel) outtraits << "\tPatchID"; -else - outtraits << "\tx\ty"; - -if (emig.indVar) { - if (emig.sexDep) { - if (emig.densDep) { - outtraits << "\tF_meanD0\tF_stdD0\tM_meanD0\tM_stdD0"; - outtraits << "\tF_meanAlpha\tF_stdAlpha\tM_meanAlpha\tM_stdAlpha"; - outtraits << "\tF_meanBeta\tF_stdBeta\tM_meanBeta\tM_stdBeta"; - } - else { - outtraits << "\tF_meanEP\tF_stdEP\tM_meanEP\tM_stdEP"; - } - } - else { - if (emig.densDep) { - outtraits << "\tmeanD0\tstdD0\tmeanAlpha\tstdAlpha"; - outtraits << "\tmeanBeta\tstdBeta"; - } - else { - outtraits << "\tmeanEP\tstdEP"; - } - } -} -if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 1) { - outtraits << "\tmeanDP\tstdDP\tmeanGB\tstdGB"; - outtraits << "\tmeanAlphaDB\tstdAlphaDB\tmeanBetaDB\tstdBetaDB"; - } - if (trfr.moveType == 2) { - outtraits << "\tmeanStepLength\tstdStepLength\tmeanRho\tstdRho"; - } - } - else { - if (trfr.sexDep) { - outtraits << "\tF_mean_distI\tF_std_distI\tM_mean_distI\tM_std_distI"; - if (trfr.twinKern) - outtraits << "\tF_mean_distII\tF_std_distII\tM_mean_distII\tM_std_distII" - << "\tF_meanPfirstKernel\tF_stdPfirstKernel" - << "\tM_meanPfirstKernel\tM_stdPfirstKernel"; - } - else { - outtraits << "\tmean_distI\tstd_distI"; - if (trfr.twinKern) - outtraits << "\tmean_distII\tstd_distII\tmeanPfirstKernel\tstdPfirstKernel"; - } - } -} -if (sett.indVar) { - if (sett.sexDep) { - outtraits << "\tF_meanS0\tF_stdS0\tM_meanS0\tM_stdS0"; - outtraits << "\tF_meanAlphaS\tF_stdAlphaS\tM_meanAlphaS\tM_stdAlphaS"; - outtraits << "\tF_meanBetaS\tF_stdBetaS\tM_meanBetaS\tM_stdBetaS"; - } - else { - outtraits << "\tmeanS0\tstdS0"; - outtraits << "\tmeanAlphaS\tstdAlphaS"; - outtraits << "\tmeanBetaS\tstdBetaS"; - } -} -outtraits << endl; - -return outtraits.is_open(); -} - -// Write records to traits file and return aggregated sums -traitsums SubCommunity::outTraits(traitCanvas tcanv, - Landscape *pLandscape,int rep,int yr,int gen,bool commlevel) -{ -int popsize,ngenes; -landParams land = pLandscape->getLandParams(); -simParams sim = paramsSim->getSim(); -bool writefile = false; -if (sim.outTraitsCells && yr%sim.outIntTraitCell == 0 && !commlevel) - writefile = true; -traitsums ts,poptraits; -for (int i = 0; i < NSEXES; i++) { - ts.ninds[i] = 0; - ts.sumD0[i] = ts.ssqD0[i] = 0.0; - ts.sumAlpha[i] = ts.ssqAlpha[i] = 0.0; ts.sumBeta[i] = ts.ssqBeta[i] = 0.0; - ts.sumDist1[i] = ts.ssqDist1[i] = 0.0; ts.sumDist2[i] = ts.ssqDist2[i] = 0.0; - ts.sumProp1[i] = ts.ssqProp1[i] = 0.0; - ts.sumDP[i] = ts.ssqDP[i] = 0.0; - ts.sumGB[i] = ts.ssqGB[i] = 0.0; - ts.sumAlphaDB[i] = ts.ssqAlphaDB[i] = 0.0; - ts.sumBetaDB[i] = ts.ssqBetaDB[i] = 0.0; - ts.sumStepL[i] = ts.ssqStepL[i] = 0.0; ts.sumRho[i] = ts.ssqRho[i] = 0.0; - ts.sumS0[i] = ts.ssqS0[i] = 0.0; - ts.sumAlphaS[i] = ts.ssqAlphaS[i] = 0.0; ts.sumBetaS[i] = ts.ssqBetaS[i] = 0.0; -} - -// generate output for each population within the sub-community (patch) -// provided that the patch is suitable (i.e. non-zero carrying capacity) -int npops = (int)popns.size(); -Species* pSpecies; -float localK; - -for (int i = 0; i < npops; i++) { // all populations - localK = pPatch->getK(); - if (localK > 0.0 && popns[i]->getNInds() > 0) { - pSpecies = popns[i]->getSpecies(); - demogrParams dem = pSpecies->getDemogr(); - emigRules emig = pSpecies->getEmig(); - trfrRules trfr = pSpecies->getTrfr(); - settleType sett = pSpecies->getSettle(); - poptraits = popns[i]->getTraits(pSpecies); - - if (writefile) { - outtraits << rep << "\t" << yr << "\t" << gen; - if (land.patchModel) { - outtraits << "\t" << pPatch->getPatchNum(); - } - else { - locn loc = pPatch->getCellLocn(0); - outtraits << "\t" << loc.x << "\t" << loc.y; - } - } - - if (emig.indVar) { - if (emig.sexDep) { // must be a sexual species - ngenes = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ngenes = 1; - } - else { // sexual reproduction - ngenes = 1; - } - } - double mnD0[2],mnAlpha[2],mnBeta[2],sdD0[2],sdAlpha[2],sdBeta[2]; - for (int g = 0; g < ngenes; g++) { - mnD0[g] = mnAlpha[g] = mnBeta[g] = sdD0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - // individuals may have been counted by sex if there was - // sex dependency in another dispersal phase - if (ngenes == 2) popsize = poptraits.ninds[g]; - else popsize = poptraits.ninds[0] + poptraits.ninds[1]; - if (popsize > 0) { - mnD0[g] = poptraits.sumD0[g] / (double)popsize; - mnAlpha[g] = poptraits.sumAlpha[g] / (double)popsize; - mnBeta[g] = poptraits.sumBeta[g] / (double)popsize; - if (popsize > 1) { - sdD0[g] = poptraits.ssqD0[g]/(double)popsize - mnD0[g]*mnD0[g]; - if (sdD0[g] > 0.0) sdD0[g] = sqrt(sdD0[g]); else sdD0[g] = 0.0; - sdAlpha[g] = poptraits.ssqAlpha[g]/(double)popsize - mnAlpha[g]*mnAlpha[g]; - if (sdAlpha[g] > 0.0) sdAlpha[g] = sqrt(sdAlpha[g]); else sdAlpha[g] = 0.0; - sdBeta[g] = poptraits.ssqBeta[g]/(double)popsize - mnBeta[g]*mnBeta[g]; - if (sdBeta[g] > 0.0) sdBeta[g] = sqrt(sdBeta[g]); else sdBeta[g] = 0.0; - } - else { - sdD0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - } - } - } - if (writefile) { - if (emig.sexDep) { - outtraits << "\t" << mnD0[0] << "\t" << sdD0[0]; - outtraits << "\t" << mnD0[1] << "\t" << sdD0[1]; - if (emig.densDep) { - outtraits << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outtraits << "\t" << mnAlpha[1] << "\t" << sdAlpha[1]; - outtraits << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - outtraits << "\t" << mnBeta[1] << "\t" << sdBeta[1]; - } - } - else { // sex-independent - outtraits << "\t" << mnD0[0] << "\t" << sdD0[0]; - if (emig.densDep) { - outtraits << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outtraits << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - } - } - } - } - - if (trfr.indVar) { - if (trfr.moveModel) { - // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT - ngenes = 1; - } - else { - if (trfr.sexDep) { // must be a sexual species - ngenes = 2; - } - else { - ngenes = 1; - } - } - double mnDist1[2], mnDist2[2], mnProp1[2], mnStepL[2], mnRho[2]; - double sdDist1[2],sdDist2[2],sdProp1[2],sdStepL[2],sdRho[2]; - double mnDP[2], mnGB[2], mnAlphaDB[2], mnBetaDB[2]; - double sdDP[2],sdGB[2],sdAlphaDB[2],sdBetaDB[2]; - for (int g = 0; g < ngenes; g++) { - mnDist1[g] = mnDist2[g] = mnProp1[g] = mnStepL[g] = mnRho[g] = 0.0; - sdDist1[g] = sdDist2[g] = sdProp1[g] = sdStepL[g] = sdRho[g] = 0.0; - mnDP[g] = mnGB[g] = mnAlphaDB[g] = mnBetaDB[g] = 0.0; - sdDP[g] = sdGB[g] = sdAlphaDB[g] = sdBetaDB[g] = 0.0; - // individuals may have been counted by sex if there was - // sex dependency in another dispersal phase - if (ngenes == 2) popsize = poptraits.ninds[g]; - else popsize = poptraits.ninds[0] + poptraits.ninds[1]; - if (popsize > 0) { - mnDist1[g] = poptraits.sumDist1[g] / (double)popsize; - mnDist2[g] = poptraits.sumDist2[g] / (double)popsize; - mnProp1[g] = poptraits.sumProp1[g] / (double)popsize; - mnStepL[g] = poptraits.sumStepL[g] / (double)popsize; - mnRho[g] = poptraits.sumRho[g] / (double)popsize; - mnDP[g] = poptraits.sumDP[g] / (double)popsize; - mnGB[g] = poptraits.sumGB[g] / (double)popsize; - mnAlphaDB[g] = poptraits.sumAlphaDB[g] / (double)popsize; - mnBetaDB[g] = poptraits.sumBetaDB[g] / (double)popsize; - if (popsize > 1) { - sdDist1[g] = poptraits.ssqDist1[g]/(double)popsize - mnDist1[g]*mnDist1[g]; - if (sdDist1[g] > 0.0) sdDist1[g] = sqrt(sdDist1[g]); else sdDist1[g] = 0.0; - sdDist2[g] = poptraits.ssqDist2[g]/(double)popsize - mnDist2[g]*mnDist2[g]; - if (sdDist2[g] > 0.0) sdDist2[g] = sqrt(sdDist2[g]); else sdDist2[g] = 0.0; - sdProp1[g] = poptraits.ssqProp1[g]/(double)popsize - mnProp1[g]*mnProp1[g]; - if (sdProp1[g] > 0.0) sdProp1[g] = sqrt(sdProp1[g]); else sdProp1[g] = 0.0; - sdStepL[g] = poptraits.ssqStepL[g]/(double)popsize - mnStepL[g]*mnStepL[g]; - if (sdStepL[g] > 0.0) sdStepL[g] = sqrt(sdStepL[g]); else sdStepL[g] = 0.0; - sdRho[g] = poptraits.ssqRho[g]/(double)popsize - mnRho[g]*mnRho[g]; - if (sdRho[g] > 0.0) sdRho[g] = sqrt(sdRho[g]); else sdRho[g] = 0.0; - sdDP[g] = poptraits.ssqDP[g]/(double)popsize - mnDP[g]*mnDP[g]; - if (sdDP[g] > 0.0) sdDP[g] = sqrt(sdDP[g]); else sdDP[g] = 0.0; - sdGB[g] = poptraits.ssqGB[g]/(double)popsize - mnGB[g]*mnGB[g]; - if (sdGB[g] > 0.0) sdGB[g] = sqrt(sdGB[g]); else sdGB[g] = 0.0; - sdAlphaDB[g] = poptraits.ssqAlphaDB[g]/(double)popsize - mnAlphaDB[g]*mnAlphaDB[g]; - if (sdAlphaDB[g] > 0.0) sdAlphaDB[g] = sqrt(sdAlphaDB[g]); else sdAlphaDB[g] = 0.0; - sdBetaDB[g] = poptraits.ssqBetaDB[g]/(double)popsize - mnBetaDB[g]*mnBetaDB[g]; - if (sdBetaDB[g] > 0.0) sdBetaDB[g] = sqrt(sdBetaDB[g]); else sdBetaDB[g] = 0.0; - } - } - } - if (writefile) { - if (trfr.moveModel) { - if (trfr.moveType == 1) { - outtraits << "\t" << mnDP[0] << "\t" << sdDP[0]; - outtraits << "\t" << mnGB[0] << "\t" << sdGB[0]; - outtraits << "\t" << mnAlphaDB[0] << "\t" << sdAlphaDB[0]; - outtraits << "\t" << mnBetaDB[0] << "\t" << sdBetaDB[0]; - } - if (trfr.moveType == 2) { - outtraits << "\t" << mnStepL[0] << "\t" << sdStepL[0]; - outtraits << "\t" << mnRho[0] << "\t" << sdRho[0]; - } - } - else { - if (trfr.sexDep) { - outtraits << "\t" << mnDist1[0] << "\t" << sdDist1[0]; - outtraits << "\t" << mnDist1[1] << "\t" << sdDist1[1]; - if (trfr.twinKern) - { - outtraits << "\t" << mnDist2[0] << "\t" << sdDist2[0]; - outtraits << "\t" << mnDist2[1] << "\t" << sdDist2[1]; - outtraits << "\t" << mnProp1[0] << "\t" << sdProp1[0]; - outtraits << "\t" << mnProp1[1] << "\t" << sdProp1[1]; - } - } - else { // sex-independent - outtraits << "\t" << mnDist1[0] << "\t" << sdDist1[0]; - if (trfr.twinKern) - { - outtraits << "\t" << mnDist2[0] << "\t" << sdDist2[0]; - outtraits << "\t" << mnProp1[0] << "\t" << sdProp1[0]; - } - } - } - } - } - - if (sett.indVar) { - if (sett.sexDep) { // must be a sexual species - ngenes = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ngenes = 1; - } - else { // sexual reproduction - ngenes = 1; - } - } - // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT -// ngenes = 1; - double mnS0[2],mnAlpha[2],mnBeta[2],sdS0[2],sdAlpha[2],sdBeta[2]; - for (int g = 0; g < ngenes; g++) { - mnS0[g] = mnAlpha[g] = mnBeta[g] = sdS0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - // individuals may have been counted by sex if there was - // sex dependency in another dispersal phase - if (ngenes == 2) popsize = poptraits.ninds[g]; - else popsize = poptraits.ninds[0] + poptraits.ninds[1]; - if (popsize > 0) { - mnS0[g] = poptraits.sumS0[g] / (double)popsize; - mnAlpha[g] = poptraits.sumAlphaS[g] / (double)popsize; - mnBeta[g] = poptraits.sumBetaS[g] / (double)popsize; - if (popsize > 1) { - sdS0[g] = poptraits.ssqS0[g]/(double)popsize - mnS0[g]*mnS0[g]; - if (sdS0[g] > 0.0) sdS0[g] = sqrt(sdS0[g]); else sdS0[g] = 0.0; - sdAlpha[g] = poptraits.ssqAlphaS[g]/(double)popsize - mnAlpha[g]*mnAlpha[g]; - if (sdAlpha[g] > 0.0) sdAlpha[g] = sqrt(sdAlpha[g]); else sdAlpha[g] = 0.0; - sdBeta[g] = poptraits.ssqBetaS[g]/(double)popsize - mnBeta[g]*mnBeta[g]; - if (sdBeta[g] > 0.0) sdBeta[g] = sqrt(sdBeta[g]); else sdBeta[g] = 0.0; - } - else { - sdS0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - } - } - } - if (writefile) { - if (sett.sexDep) { - outtraits << "\t" << mnS0[0] << "\t" << sdS0[0]; - outtraits << "\t" << mnS0[1] << "\t" << sdS0[1]; - outtraits << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outtraits << "\t" << mnAlpha[1] << "\t" << sdAlpha[1]; - outtraits << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - outtraits << "\t" << mnBeta[1] << "\t" << sdBeta[1]; - } - else { // sex-independent - outtraits << "\t" << mnS0[0] << "\t" << sdS0[0]; - outtraits << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outtraits << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - } - } - } - - if (writefile) outtraits << endl; - - for (int s = 0; s < NSEXES; s++) { - ts.ninds[s] += poptraits.ninds[s]; - ts.sumD0[s] += poptraits.sumD0[s]; ts.ssqD0[s] += poptraits.ssqD0[s]; - ts.sumAlpha[s] += poptraits.sumAlpha[s]; ts.ssqAlpha[s] += poptraits.ssqAlpha[s]; - ts.sumBeta[s] += poptraits.sumBeta[s]; ts.ssqBeta[s] += poptraits.ssqBeta[s]; - ts.sumDist1[s] += poptraits.sumDist1[s]; ts.ssqDist1[s] += poptraits.ssqDist1[s]; - ts.sumDist2[s] += poptraits.sumDist2[s]; ts.ssqDist2[s] += poptraits.ssqDist2[s]; - ts.sumProp1[s] += poptraits.sumProp1[s]; ts.ssqProp1[s] += poptraits.ssqProp1[s]; - ts.sumDP[s] += poptraits.sumDP[s]; ts.ssqDP[s] += poptraits.ssqDP[s]; - ts.sumGB[s] += poptraits.sumGB[s]; ts.ssqGB[s] += poptraits.ssqGB[s]; - ts.sumAlphaDB[s] += poptraits.sumAlphaDB[s]; ts.ssqAlphaDB[s] += poptraits.ssqAlphaDB[s]; - ts.sumBetaDB[s] += poptraits.sumBetaDB[s]; ts.ssqBetaDB[s] += poptraits.ssqBetaDB[s]; - ts.sumStepL[s] += poptraits.sumStepL[s]; ts.ssqStepL[s] += poptraits.ssqStepL[s]; - ts.sumRho[s] += poptraits.sumRho[s]; ts.ssqRho[s] += poptraits.ssqRho[s]; - ts.sumS0[s] += poptraits.sumS0[s]; ts.ssqS0[s] += poptraits.ssqS0[s]; - ts.sumAlphaS[s] += poptraits.sumAlphaS[s]; ts.ssqAlphaS[s] += poptraits.ssqAlphaS[s]; - ts.sumBetaS[s] += poptraits.sumBetaS[s]; ts.ssqBetaS[s] += poptraits.ssqBetaS[s]; -#if RSDEBUG -//DEBUGLOG << "SubCommunity::outTraits(): i=" << i << " popns[i]=" << popns[i] -// << " s=" << s -//// << " poptraits.sumRho[s]= " << poptraits.sumRho[s] -//// << " ts.sumRho[s]= " << ts.sumRho[s] -// << " poptraits.sumDP[s]= " << poptraits.sumDP[s] << " poptraits.ssqDP[s]= " << poptraits.ssqDP[s] -// << " ts.sumDP[s]= " << ts.sumDP[s] << " ts.ssqDP[s]= " << ts.ssqDP[s] -// << " poptraits.sumGB[s]= " << poptraits.sumGB[s] << " poptraits.ssqGB[s]= " << poptraits.ssqGB[s] -// << " ts.sumGB[s]= " << ts.sumGB[s] << " ts.ssqGB[s]= " << ts.ssqGB[s] -// << endl; -#endif - } - } -} -return ts; -} - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - - diff --git a/RangeShiftR/src/RScore/SubCommunity.h b/RangeShiftR/src/RScore/SubCommunity.h deleted file mode 100644 index 3f1266f..0000000 --- a/RangeShiftR/src/RScore/SubCommunity.h +++ /dev/null @@ -1,216 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 SubCommunity - -Implements the SubCommunity class - -There is ONE instance of a SubCommunity for each Patch in the Landscape -(including the matrix). The SubCommunity holds a number of Populations, one for -each Species represented in the simulation. -CURRENTLY the number of Populations withn a SubCommunity is LIMITED TO ONE. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 26 October 2021 by Steve Palmer - -------------------------------------------------------------------------------*/ - -#ifndef SubCommunityH -#define SubCommunityH - -#include -#include -using namespace std; - -//#if RS_RCPP && !R_CMD -#include "../Version.h" -//#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif - -#include "Parameters.h" -#include "Landscape.h" -#include "Population.h" - -//--------------------------------------------------------------------------- - -struct traitCanvas { // canvases for drawing variable traits - int *pcanvas[NTRAITS]; // dummy variables for batch version -}; - -class SubCommunity { - -public: - SubCommunity(Patch*,int); - ~SubCommunity(void); - intptr getNum(void); - Patch* getPatch(void); - locn getLocn(void); - - // functions to manage populations occurring in the SubCommunity - popStats getPopStats(void); - void setInitial(bool); - void initialise(Landscape*,Species*); - void initialInd(Landscape*,Species*,Patch*,Cell*,int); - Population* newPopn( // Create a new population, and return its address - Landscape*, // pointer to Landscape - Species*, // pointer to Species - Patch*, // pointer to Patch - int // no. of Individuals - ); - void resetPopns(void); - void resetPossSettlers(void); - void localExtinction( // Extirpate all populations - int // option: 0 - random local extinction probability - // 1 - local extinction probability gradient - ); - void patchChange(void); - void reproduction( - int, // Landscape resolution - float, // epsilon - global stochasticity value - short, // raster type (see Landscape) - bool // TRUE for a patch-based model, FALSE for a cell-based model - ); - void emigration(void); - // Remove emigrants from their natal patch and add to patch 0 (matrix) - void initiateDispersal( - SubCommunity* // pointer to matrix SubCommunity - ); -// Add an individual into the local population of its species in the patch - void recruit( - Individual*, // pointer to Individual - Species* // pointer to Species - ); -#if RS_RCPP // included also SEASONAL - int transfer( // Transfer through matrix - run for matrix SubCommunity only - Landscape*, // pointer to Landscape - short, // landscape change index - short // season / year - ); -#else - int transfer( // Transfer through matrix - run for matrix SubCommunity only - Landscape*, // pointer to Landscape - short // landscape change index - ); -#endif // SEASONAL || RS_RCPP - // Remove emigrants from patch 0 (matrix) and transfer to SubCommunity in which - // their destination co-ordinates fall (executed for the matrix patch only) - void completeDispersal( - Landscape*, // pointer to Landscape - bool // TRUE to increment connectivity totals - ); - void survival( - short, // part: 0 = determine survival & development, - // 1 = apply survival changes to the population - short, // option0: 0 = stage 0 (juveniles) only ) - // 1 = all stages ) used by part 0 only - // 2 = stage 1 and above (all non-juvs) ) - short // option1: 0 - development only (when survival is annual) - // 1 - development and survival - ); - void ageIncrement(void); - // Find the population of a given species in a given patch - Population* findPop(Species*,Patch*); - void createOccupancy( - int // no. of rows = (no. of years / interval) + 1 - ); - void updateOccupancy( - int // row = (no. of years / interval) - ); - int getOccupancy( - int // row = (no. of years / interval) - ); - void deleteOccupancy(void); - - bool outPopHeaders( // Open population file and write header record - Landscape*, // pointer to Landscape - Species*, // pointer to Species - int // option: -999 to close the file - ); - void outPop( // Write records to population file - Landscape*, // pointer to Landscape - int, // replicate - int, // year - int // generation - ); - - void outInds( // Write records to individuals file - Landscape*, // pointer to Landscape - int, // replicate - int, // year - int, // generation - int // Landscape number (>= 0 to open the file, -999 to close the file - // -1 to write data records) - ); - void outGenetics( // Write records to genetics file - int, // replicate - int, // year - int, // generation - int // Landscape number (>= 0 to open the file, -999 to close the file - // -1 to write data records) - ); - bool outTraitsHeaders( // Open traits file and write header record - Landscape*, // pointer to Landscape - Species*, // pointer to Species - int // Landscape number (-999 to close the file) - ); - traitsums outTraits( // Write records to traits file and return aggregated sums - traitCanvas, // pointers to canvases for drawing variable traits - // in the batch version, these are replaced by integers set to zero - Landscape*, // pointer to Landscape - int, // replicate - int, // year - int, // generation - bool // true if called to summarise data at community level - ); - int stagePop( // Population size of a specified stage - int // stage - ); - -private: - intptr subCommNum; // SubCommunity number - // 0 is reserved for the SubCommunity in the inter-patch matrix -// intptr *occupancy; // pointer to occupancy array - Patch *pPatch; - int *occupancy; // pointer to occupancy array - std::vector popns; - bool initial; // WILL NEED TO BE CHANGED FOR MULTIPLE SPECIES ... - -}; - -extern paramGrad *paramsGrad; -extern paramStoch *paramsStoch; -extern paramInit *paramsInit; - -//--------------------------------------------------------------------------- -#endif From 9ccef179210ba5ed417a7ff750b88901d13e068e Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Fri, 24 Nov 2023 15:31:15 +0000 Subject: [PATCH 16/17] rm existing rscore --- src/RScore/.github/workflows/check.yml | 26 - src/RScore/.gitignore | 87 - src/RScore/CMakeLists.txt | 30 - src/RScore/Cell.cpp | 237 -- src/RScore/Cell.h | 174 -- src/RScore/Community.cpp | 1717 -------------- src/RScore/Community.h | 231 -- src/RScore/FractalGenerator.cpp | 243 -- src/RScore/FractalGenerator.h | 85 - src/RScore/Genome.cpp | 861 ------- src/RScore/Genome.h | 251 -- src/RScore/Individual.cpp | 1858 --------------- src/RScore/Individual.h | 312 --- src/RScore/LICENSE | 674 ------ src/RScore/Landscape.cpp | 2977 ------------------------ src/RScore/Landscape.h | 567 ----- src/RScore/Main.cpp | 95 - src/RScore/Model.cpp | 2265 ------------------ src/RScore/Model.h | 149 -- src/RScore/Parameters.cpp | 398 ---- src/RScore/Parameters.h | 393 ---- src/RScore/Patch.cpp | 358 --- src/RScore/Patch.h | 182 -- src/RScore/Population.cpp | 1676 ------------- src/RScore/Population.h | 245 -- src/RScore/README.md | 3 - src/RScore/RSrandom.cpp | 283 --- src/RScore/RSrandom.h | 144 -- src/RScore/RandomCheck.cpp | 93 - src/RScore/RandomCheck.h | 47 - src/RScore/Species.cpp | 1455 ------------ src/RScore/Species.h | 755 ------ src/RScore/SubCommunity.cpp | 1204 ---------- src/RScore/SubCommunity.h | 216 -- src/RScore/Utils.cpp | 26 - src/RScore/Utils.h | 18 - 36 files changed, 20335 deletions(-) delete mode 100644 src/RScore/.github/workflows/check.yml delete mode 100644 src/RScore/.gitignore delete mode 100644 src/RScore/CMakeLists.txt delete mode 100644 src/RScore/Cell.cpp delete mode 100644 src/RScore/Cell.h delete mode 100644 src/RScore/Community.cpp delete mode 100644 src/RScore/Community.h delete mode 100644 src/RScore/FractalGenerator.cpp delete mode 100644 src/RScore/FractalGenerator.h delete mode 100644 src/RScore/Genome.cpp delete mode 100644 src/RScore/Genome.h delete mode 100644 src/RScore/Individual.cpp delete mode 100644 src/RScore/Individual.h delete mode 100644 src/RScore/LICENSE delete mode 100644 src/RScore/Landscape.cpp delete mode 100644 src/RScore/Landscape.h delete mode 100644 src/RScore/Main.cpp delete mode 100644 src/RScore/Model.cpp delete mode 100644 src/RScore/Model.h delete mode 100644 src/RScore/Parameters.cpp delete mode 100644 src/RScore/Parameters.h delete mode 100644 src/RScore/Patch.cpp delete mode 100644 src/RScore/Patch.h delete mode 100644 src/RScore/Population.cpp delete mode 100644 src/RScore/Population.h delete mode 100644 src/RScore/README.md delete mode 100644 src/RScore/RSrandom.cpp delete mode 100644 src/RScore/RSrandom.h delete mode 100644 src/RScore/RandomCheck.cpp delete mode 100644 src/RScore/RandomCheck.h delete mode 100644 src/RScore/Species.cpp delete mode 100644 src/RScore/Species.h delete mode 100644 src/RScore/SubCommunity.cpp delete mode 100644 src/RScore/SubCommunity.h delete mode 100644 src/RScore/Utils.cpp delete mode 100644 src/RScore/Utils.h diff --git a/src/RScore/.github/workflows/check.yml b/src/RScore/.github/workflows/check.yml deleted file mode 100644 index 2e86587..0000000 --- a/src/RScore/.github/workflows/check.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: check -on: push - -jobs: - check: - strategy: - matrix: - os: [windows-latest, ubuntu-latest, macos-latest] - include: - - os: windows-latest - path_to_exe: ./build/Debug/RScore.exe - - os: ubuntu-latest - path_to_exe: ./build/RScore - - os: macos-latest - path_to_exe: ./build/RScore - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v3 - - - name: build - run: | - mkdir build && cd build - cmake ../ && cmake --build . - - - name: run - run: ${{ matrix.path_to_exe }} diff --git a/src/RScore/.gitignore b/src/RScore/.gitignore deleted file mode 100644 index 0545382..0000000 --- a/src/RScore/.gitignore +++ /dev/null @@ -1,87 +0,0 @@ -.gitignore -#README.md - -# CodeLite -/.build-debug/ -/Debug/ -/Release/ -/RNG_test/ -.codelite/ -compile_commands.json -Makefile -.build-release/ -build-Release/ -*.project -*.workspace -*.mk -*.tags - -# Hidden source -/RangeShiftR/src/.* - -# Windows files -/RangeShiftR/src/*.dll - -# History files -.Rhistory -.Rapp.history - -# RStudio files -.Rproj.user/ -/RangeShiftR/.Rproj.user/ -#/RangeShiftR/RangeShiftR.Rproj -/RangeShiftR/Read-and-delete-me -/RangeShiftR/.Rhistory -#/RangeShiftR/.Rbuildignore - -# Session Data files -.RData -tags - -# User-specific files -.Ruserdata - -# Example code in package build process -*-Ex.R - -# Output files from R CMD build -*.tar.gz -/RangeShiftR/src/*.o -/RangeShiftR/src/RangeShiftR.so - - -# Windows files -/RangeShiftR/src/*.dll - -# Output files from R CMD check -/*.Rcheck/ - -# Output from Rcpp compile.attributes() -#/RangeShiftR/R/RcppExports.R -#/RangeShiftR/src/RcppExports.cpp - -# RStudio files -.Rproj.user/ - -# produced vignettes -vignettes/*.html -vignettes/*.pdf -#/RangeShiftR/man/ - -# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 -.httr-oauth - -# knitr and R markdown default cache directories -/*_cache/ -/cache/ - -# Temporary files created by R markdown -*.utf8.md -*.knit.md - -# compilation files -*.o - -# Visual Studio -.vs/ -out/ diff --git a/src/RScore/CMakeLists.txt b/src/RScore/CMakeLists.txt deleted file mode 100644 index c14a3e3..0000000 --- a/src/RScore/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -# Config file for compilation with CMake - -if (NOT batchmode) # that is, RScore as a standalone - cmake_minimum_required(VERSION 3.10) - # set the project name and version - project(RScore VERSION 2.1.0) - # specify the C++ standard - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED True) - add_executable(RScore Main.cpp Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp Utils.cpp) -else() # that is, RScore compiled as library within RangeShifter_batch - add_library(RScore Species.cpp Cell.cpp Community.cpp FractalGenerator.cpp Genome.cpp Individual.cpp Landscape.cpp Model.cpp Parameters.cpp Patch.cpp Population.cpp RandomCheck.cpp RSrandom.cpp SubCommunity.cpp Utils.cpp) -endif() - -# pass config definitions to compiler -target_compile_definitions(RScore PRIVATE RSWIN64) - -# enable LINUX_CLUSTER macro on Linux + macOS -if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin") - add_compile_definitions("LINUX_CLUSTER") -endif() - -# Debug Mode by default, unless "release" is passed -if(NOT DEFINED release) - add_compile_definitions(RSDEBUG) -endif() - -if(NOT batchmode) - target_include_directories(RScore PUBLIC "${PROJECT_BINARY_DIR}") -endif() \ No newline at end of file diff --git a/src/RScore/Cell.cpp b/src/RScore/Cell.cpp deleted file mode 100644 index 1c0f937..0000000 --- a/src/RScore/Cell.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Cell.h" - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -// Cell functions - -Cell::Cell(int xx,int yy,intptr patch,int hab) -{ -x = xx; y = yy; -pPatch = patch; -envVal = 1.0; // default - no effect of any gradient -envDev = eps = 0.0; -habIxx.push_back(hab); -#if RSDEBUG -//DebugGUI(("Cell::Cell(): this=" + Int2Str((int)this) -// + " x=" + Int2Str(x) + " y=" + Int2Str(y) -// + " habIndex=" + Int2Str(habIndex) -//).c_str()); -#endif -visits = 0; -smsData = 0; -} - -Cell::Cell(int xx,int yy,intptr patch,float hab) -{ -x = xx; y = yy; -pPatch = patch; -envVal = 1.0; // default - no effect of any gradient -envDev = eps = 0.0; -habitats.push_back(hab); -visits = 0; -smsData = 0; -} - -Cell::~Cell() { -#if RSDEBUG -//DEBUGLOG << "Cell::~Cell(): this = " << this << " smsData = " << smsData << endl; -#endif -habIxx.clear(); -habitats.clear(); -if (smsData != 0) { - if (smsData->effcosts != 0) delete smsData->effcosts; - delete smsData; -} -#if RSDEBUG -//DEBUGLOG << "Cell::~Cell(): deleted" << endl; -#endif -} - -void Cell::setHabIndex(short hx) { -#if RSDEBUG -//DebugGUI(("Cell::setHabIndex(): this=" + Int2Str((int)this) -// + " x=" + Int2Str(x) + " y=" + Int2Str(y) -// + " habIx=" + Int2Str(habIx) -//).c_str()); -#endif -if (hx < 0) habIxx.push_back(0); -else habIxx.push_back(hx); -} - -void Cell::changeHabIndex(short ix,short hx) { -if (ix >= 0 && ix < (short)habIxx.size() && hx >= 0) habIxx[ix] = hx; -else habIxx[ix] = 0; -} - -int Cell::getHabIndex(int ix) { -if (ix < 0 || ix >= (int)habIxx.size()) - // nodata cell OR should not occur, but treat as such - return -1; -else return habIxx[ix]; -} -int Cell::nHabitats(void) { -int nh = (int)habIxx.size(); -if ((int)habitats.size() > nh) nh = (int)habitats.size(); -return nh; -} - -void Cell::setHabitat(float q) { -if (q >= 0.0 && q <= 100.0) habitats.push_back(q); -else habitats.push_back(0.0); -} - -float Cell::getHabitat(int ix) { -if (ix < 0 || ix >= (int)habitats.size()) - // nodata cell OR should not occur, but treat as such - return -1.0; -else return habitats[ix]; -} - -void Cell::setPatch(intptr p) { -pPatch = p; -} -intptr Cell::getPatch(void) -{ -#if RSDEBUG -//DebugGUI(("Cell::getPatch(): this=" + Int2Str((int)this) -// + " x=" + Int2Str(x) + " y=" + Int2Str(y) -// + " habIxx[0]=" + Int2Str(habIxx[0]) + " pPatch=" + Int2Str(pPatch) -//).c_str()); -#endif -return pPatch; -} - -locn Cell::getLocn(void) { locn q; q.x = x; q.y = y; return q; } - -void Cell::setEnvDev(float d) { envDev = d; } - -float Cell::getEnvDev(void) { return envDev; } - -void Cell::setEnvVal(float e) { -if (e >= 0.0) envVal = e; -} - -float Cell::getEnvVal(void) { return envVal; } - -void Cell::updateEps(float ac,float randpart) { -eps = eps*ac + randpart; -} - -float Cell::getEps(void) { return eps; } - -// Functions to handle costs for SMS - -int Cell::getCost(void) { -int c; -if (smsData == 0) c = 0; // costs not yet set up -else c = smsData->cost; -return c; -} - -void Cell::setCost(int c) { -if (smsData == 0) { - smsData = new smscosts; - smsData->effcosts = 0; -} -smsData->cost = c; -} - -// Reset the cost and the effective cost of the cell -void Cell::resetCost(void) { -if (smsData != 0) { resetEffCosts(); delete smsData; } -smsData = 0; -} - -array3x3f Cell::getEffCosts(void) { -array3x3f a; -if (smsData == 0 || smsData->effcosts == 0) { // effective costs have not been calculated - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - a.cell[i][j] = -1.0; - } - } -} -else - a = *smsData->effcosts; -return a; -} - -void Cell::setEffCosts(array3x3f a) { -if (smsData->effcosts == 0) smsData->effcosts = new array3x3f; -*smsData->effcosts = a; -} - -// Reset the effective cost, but not the cost, of the cell -void Cell::resetEffCosts(void) { -if (smsData != 0) { - if (smsData->effcosts != 0) { - delete smsData->effcosts; - smsData->effcosts = 0; - } -} -} - -void Cell::resetVisits(void) { visits = 0; } -void Cell::incrVisits(void) { visits++; } -unsigned long int Cell::getVisits(void) { return visits; } - -//--------------------------------------------------------------------------- - -// Initial species distribution cell functions - -DistCell::DistCell(int xx,int yy) { -x = xx; y = yy; initialise = false; -} - -DistCell::~DistCell() { - -} - -void DistCell::setCell(bool init) { -initialise = init; -} - -bool DistCell::toInitialise(locn loc) { -if (loc.x == x && loc.y == y) return initialise; -else return false; -} - -bool DistCell::selected(void) { return initialise; } - -locn DistCell::getLocn(void) { -locn loc; loc.x = x; loc.y = y; return loc; -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - - - - diff --git a/src/RScore/Cell.h b/src/RScore/Cell.h deleted file mode 100644 index 5382a1e..0000000 --- a/src/RScore/Cell.h +++ /dev/null @@ -1,174 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Cell - -Implements the following classes: - -Cell - Landscape cell - -DistCell - Initial species distribution cell - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 14 January 2021 by Steve Palmer - -------------------------------------------------------------------------------*/ - -#ifndef CellH -#define CellH - -#include -using namespace std; - -#include "Parameters.h" - -//--------------------------------------------------------------------------- - -struct array3x3f { float cell[3][3]; }; // neighbourhood cell array (SMS) -struct smscosts { int cost; array3x3f *effcosts; }; // cell costs for SMS - -// Landscape cell - -class Cell{ -public: - Cell( // Constructor for habitat codes - int, // x co-ordinate - int, // y co-ordinate - intptr, // pointer (cast as integer) to the Patch to which Cell belongs - int // habitat index number - ); - Cell( // Constructor for habitat % cover or habitat quality - int, // x co-ordinate - int, // y co-ordinate - intptr, // pointer (cast as integer) to the Patch to which Cell belongs - float // habitat proportion or cell quality score - ); - ~Cell(); - void setHabIndex( - short // habitat index number - ); - void changeHabIndex( - short, // landscape change number - short // habitat index number - ); - int getHabIndex( - int // landscape change number - ); - int nHabitats(void); - void setHabitat( - float // habitat proportions or cell quality score - ); - float getHabitat( // Get habitat proportion / quality score - int // habitat index number / landscape change number - ); - void setPatch( - intptr // pointer (cast as integer) to the Patch to which Cell belongs - ); - intptr getPatch(void); - locn getLocn(void); - void setEnvDev( - float // local environmental deviation - ); - float getEnvDev(void); - void setEnvVal( - float // environmental value - ); - float getEnvVal(void); - void updateEps( // Update local environmental stochasticity (epsilon) - float, // autocorrelation coefficient - float // random adjustment - ); - float getEps(void); - void setCost( - int // cost value for SMS - ); - int getCost(void); - void resetCost(void); - array3x3f getEffCosts(void); - void setEffCosts( - array3x3f // 3 x 3 array of effective costs for neighbouring cells - ); - void resetEffCosts(void); // Reset the effective cost, but not the cost, of the cell - void resetVisits(void); - void incrVisits(void); - unsigned long int getVisits(void); - -private: - int x,y; // cell co-ordinates - intptr pPatch; // pointer (cast as integer) to the Patch to which cell belongs - // NOTE: THE FOLLOWING ENVIRONMENTAL VARIABLES COULD BE COMBINED IN A STRUCTURE - // AND ACCESSED BY A POINTER ... - float envVal; // environmental value, representing one of: - // gradient in K, r or extinction probability - float envDev; // local environmental deviation (static, in range -1.0 to +1.0) - float eps; // local environmental stochasticity (epsilon) (dynamic, from N(0,std)) - unsigned long int visits; // no. of times square is visited by dispersers - smscosts *smsData; - - vector habIxx; // habitat indices (rasterType=0) - // NB initially, habitat codes are loaded, then converted to index nos. - // once landscape is fully loaded - vector habitats; // habitat proportions (rasterType=1) or quality (rasterType=2) -}; - -//--------------------------------------------------------------------------- - -// Initial species distribution cell - -class DistCell{ -public: - DistCell( - int, // x co-ordinate - int // y co-ordinate - ); - ~DistCell(); - void setCell( - bool // TRUE if cell is to be initialised, FALSE if not - ); - bool toInitialise( - locn // structure holding co-ordinates of cell - ); - bool selected(void); - locn getLocn(void); - -private: - int x,y; // cell co-ordinates - bool initialise; // cell is to be initialised - -}; - -#if RSDEBUG -extern void DebugGUI(string); -#endif - -//--------------------------------------------------------------------------- - -#endif diff --git a/src/RScore/Community.cpp b/src/RScore/Community.cpp deleted file mode 100644 index 12b190c..0000000 --- a/src/RScore/Community.cpp +++ /dev/null @@ -1,1717 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Community.h" - -//--------------------------------------------------------------------------- - - -ofstream outrange; -ofstream outoccup,outsuit; -ofstream outtraitsrows; - -//--------------------------------------------------------------------------- - -Community::Community(Landscape *pLand) { -pLandscape = pLand; -indIx = 0; -} - -Community::~Community(void) { -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - delete subComms[i]; -} -subComms.clear(); -} - -SubCommunity* Community::addSubComm(Patch *pPch,int num) { -int nsubcomms = (int)subComms.size(); -subComms.push_back(new SubCommunity(pPch,num)); -return subComms[nsubcomms]; -} - -void Community::initialise(Species *pSpecies,int year) -{ - -int nsubcomms,npatches,ndistcells,spratio,patchnum,rr = 0; -locn distloc; -patchData pch; -patchLimits limits; -intptr ppatch,subcomm; -std::vector subcomms; -std::vector selected; -SubCommunity *pSubComm; -Patch *pPatch; -Cell *pCell; -landParams ppLand = pLandscape->getLandParams(); -initParams init = paramsInit->getInit(); - -nsubcomms = (int)subComms.size(); - -spratio = ppLand.spResol / ppLand.resol; - -#if RSDEBUG -DEBUGLOG << endl << "Community::initialise(): this=" << this - << " seedType=" << init.seedType << " freeType=" << init.freeType - << " minSeedX=" << init.minSeedX << " minSeedY=" << init.minSeedY - << " maxSeedX=" << init.maxSeedX << " maxSeedY=" << init.maxSeedY - << " indsFile=" << init.indsFile - << " nsubcomms=" << nsubcomms << " spratio=" << spratio - << endl; -#endif - -switch (init.seedType) { - -case 0: // free initialisation - - switch (init.freeType) { - - case 0: // random - // determine no. of patches / cells within the specified initialisation limits - // and record their corresponding sub-communities in a list - // parallel list records which have been selected - npatches = pLandscape->patchCount(); - limits.xMin = init.minSeedX; limits.xMax = init.maxSeedX; - limits.yMin = init.minSeedY; limits.yMax = init.maxSeedY; - for (int i = 0; i < npatches; i++) { - pch = pLandscape->getPatchData(i); - if (pch.pPatch->withinLimits(limits)) { - if (ppLand.patchModel) { - if (pch.pPatch->getPatchNum() != 0) { - subcomms.push_back(pch.pPatch->getSubComm()); - selected.push_back(false); - } - } - else { // cell-based model - is cell(patch) suitable - if (pch.pPatch->getK() > 0.0) - { - subcomms.push_back(pch.pPatch->getSubComm()); - selected.push_back(false); - } - } - } - } - // select specified no. of patches/cells at random - npatches = (int)subcomms.size(); - if (init.nSeedPatches > npatches/2) { // use backwards selection method - for (int i = 0; i < npatches; i++) selected[i] = true; - for (int i = 0; i < (npatches-init.nSeedPatches); i++) { - do { - rr = pRandom->IRandom(0,npatches-1); - } while (!selected[rr]); - selected[rr] = false; - } - } - else { // use forwards selection method - for (int i = 0; i < init.nSeedPatches; i++) { - do { - rr = pRandom->IRandom(0,npatches-1); - } while (selected[rr]); - selected[rr] = true; - } - } - // selected sub-communities for initialisation - for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->setInitial(false); - } - for (int i = 0; i < npatches; i++) { - if (selected[i]) { - pSubComm = (SubCommunity*)subcomms[i]; - pSubComm->setInitial(true); - } - } - break; - - case 1: // all suitable patches/cells - npatches = pLandscape->patchCount(); - limits.xMin = init.minSeedX; limits.xMax = init.maxSeedX; - limits.yMin = init.minSeedY; limits.yMax = init.maxSeedY; - for (int i = 0; i < npatches; i++) { - pch = pLandscape->getPatchData(i); - if (pch.pPatch->withinLimits(limits)) { - patchnum = pch.pPatch->getPatchNum(); - if (patchnum != 0) { - if (pch.pPatch->getK() > 0.0) - { // patch is suitable - subcomm = pch.pPatch->getSubComm(); - if (subcomm == 0) { - // create a sub-community in the patch - pSubComm = addSubComm(pch.pPatch,patchnum); - } - else { - pSubComm = (SubCommunity*)subcomm; - } - pSubComm->setInitial(true); - } - } - } - } - - break; - - case 2: // manually selected patches/cells - break; - - } // end of switch (init.freeType) - nsubcomms = (int)subComms.size(); - for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->initialise(pLandscape,pSpecies); - } - break; - -case 1: // from species distribution - if (ppLand.spDist) - { - // deselect all existing sub-communities - for (int i = 0; i < nsubcomms; i++) { - subComms[i]->setInitial(false); - } - // initialise from loaded species distribution - switch (init.spDistType) { - case 0: // all presence cells - pLandscape->setDistribution(pSpecies,0); // activate all patches - break; - case 1: // some randomly selected presence cells - pLandscape->setDistribution(pSpecies,init.nSpDistPatches); // activate random patches - break; - case 2: // manually selected presence cells - // cells have already been identified - no further action here - break; - } - - // THE FOLLOWING WILL HAVE TO BE CHANGED FOR MULTIPLE SPECIES... - ndistcells = pLandscape->distCellCount(0); - for (int i = 0; i < ndistcells; i++) { - distloc = pLandscape->getSelectedDistnCell(0,i); - if (distloc.x >= 0) { // distribution cell is selected - // process each landscape cell within the distribution cell - for (int x = 0; x < spratio; x++) { - for (int y = 0; y < spratio; y++) { - pCell = pLandscape->findCell(distloc.x*spratio+x,distloc.y*spratio+y); - if (pCell != 0) { // not a no-data cell - ppatch = pCell->getPatch(); - if (ppatch != 0) { - pPatch = (Patch*)ppatch; - if (pPatch->getSeqNum() != 0) { // not the matrix patch - subcomm = pPatch->getSubComm(); - if (subcomm != 0) { - pSubComm = (SubCommunity*)subcomm; - pSubComm->setInitial(true); - } - } - } - } - } - } - } - } - - nsubcomms = (int)subComms.size(); - for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->initialise(pLandscape,pSpecies); - } - } - else { - // WHAT HAPPENS IF INITIAL DISTRIBUTION IS NOT LOADED ??? .... - // should not occur - take no action - no initialisation will occur - } - break; - -case 2: // initial individuals in specified patches/cells - if (year < 0) { - // initialise matrix sub-community only - subComms[0]->initialise(pLandscape,pSpecies); - indIx = 0; // reset index for initial individuals - } - else { // add any initial individuals for the current year - initInd iind; iind.year = 0; - int ninds = paramsInit->numInitInds(); - while (indIx < ninds && iind.year <= year) { - iind = paramsInit->getInitInd(indIx); - while (iind.year == year) { -#if RSDEBUG -//DEBUGLOG << "Community::initialise(): year=" << year -// << " indIx=" << indIx << " iind.year=" << iind.year -// << " iind.patchID=" << iind.patchID << " iind.x=" << iind.x << " iind.y=" << iind.y -// << " iind.sex=" << iind.sex << " iind.age=" << iind.age << " iind.stage=" << iind.stage -// << endl; -#endif - if (ppLand.patchModel) { - if (pLandscape->existsPatch(iind.patchID)) { - pPatch = pLandscape->findPatch(iind.patchID); - if (pPatch->getK() > 0.0) - { // patch is suitable - subcomm = pPatch->getSubComm(); - if (subcomm == 0) { - // create a sub-community in the patch - pSubComm = addSubComm(pPatch,iind.patchID); - } - else { - pSubComm = (SubCommunity*)subcomm; - } - pSubComm->initialInd(pLandscape,pSpecies,pPatch,pPatch->getRandomCell(),indIx); - } - } - } - else { // cell-based model - pCell = pLandscape->findCell(iind.x,iind.y); - if (pCell != 0) { - intptr ppatch = pCell->getPatch(); - if (ppatch != 0) { - pPatch = (Patch*)ppatch; - if (pPatch->getK() > 0.0) - { // patch is suitable - subcomm = pPatch->getSubComm(); - if (subcomm == 0) { - // create a sub-community in the patch - pSubComm = addSubComm(pPatch,iind.patchID); - } - else { - pSubComm = (SubCommunity*)subcomm; - } - pSubComm->initialInd(pLandscape,pSpecies,pPatch,pCell,indIx); - } - } - } - } - indIx++; - if (indIx < ninds) { - iind = paramsInit->getInitInd(indIx); - } - else { - iind.year = 99999999; - } - } - } - } - break; - -case 3: // from file - // this condition cannot occur here, as init.seedType will have been changed to 0 or 1 - // when the initialisation file was read - break; - -} // end of switch (init.seedType) - -#if RSDEBUG -DEBUGLOG << "Community::initialise(): this=" << this - << " nsubcomms=" << nsubcomms - << endl; -#endif - -} - -// Add manually selected patches/cells to the selected set for initialisation -void Community::addManuallySelected(void) { -int npatches; -intptr subcomm,patch; -locn initloc; -Cell *pCell; -Patch *pPatch; -SubCommunity *pSubComm; - -landParams ppLand = pLandscape->getLandParams(); - -npatches = pLandscape->initCellCount(); // no. of patches/cells specified -#if RSDEBUG -DEBUGLOG << "Community::addManuallySelected(): this = " << this - << " npatches = " << npatches << endl; -#endif -// identify sub-communities to be initialised -if (ppLand.patchModel) { - for (int i = 0; i < npatches; i++) { - initloc = pLandscape->getInitCell(i); // patch number held in x-coord of list - pPatch = pLandscape->findPatch(initloc.x); - if (pPatch != 0) { - subcomm = pPatch->getSubComm(); - if (subcomm != 0) { - pSubComm = (SubCommunity*)subcomm; - pSubComm->setInitial(true); - } - } - } -} -else { // cell-based model - for (int i = 0; i < npatches; i++) { - initloc = pLandscape->getInitCell(i); - if (initloc.x >= 0 && initloc.x < ppLand.dimX - && initloc.y >= 0 && initloc.y < ppLand.dimY) { - pCell = pLandscape->findCell(initloc.x,initloc.y); - if (pCell != 0) { // not no-data cell - patch = pCell->getPatch(); -#if RSDEBUG -DEBUGLOG << "Community::initialise(): i = " << i - << " x = " << initloc.x << " y = " << initloc.y - << " pCell = " << pCell << " patch = " << patch - << endl; -#endif - if (patch != 0) { - pPatch = (Patch*)patch; - subcomm = pPatch->getSubComm(); -#if RSDEBUG -DEBUGLOG << "Community::initialise(): i = " << i - << " pPatch = " << pPatch << " subcomm = " << subcomm - << endl; -#endif - if (subcomm != 0) { - pSubComm = (SubCommunity*)subcomm; - pSubComm->setInitial(true); -#if RSDEBUG -DEBUGLOG << "Community::initialise(): i = " << i - << " pSubComm = " << pSubComm - << endl; -#endif - } - } - } - } - } -} -} - -void Community::resetPopns(void) { -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->resetPopns(); -} -// reset the individual ids to start from zero -Individual::indCounter = 0; -} - -void Community::localExtinction(int option) { -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - if (subComms[i]->getNum() > 0) { // except in matrix - subComms[i]->localExtinction(option); - } -} -} - -void Community::patchChanges(void) { -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - if (subComms[i]->getNum() > 0) { // except in matrix - subComms[i]->patchChange(); - } -} -} - -void Community::reproduction(int yr) -{ -float eps = 0.0; // epsilon for environmental stochasticity -landParams land = pLandscape->getLandParams(); -envStochParams env = paramsStoch->getStoch(); -int nsubcomms = (int)subComms.size(); -#if RSDEBUG -DEBUGLOG << "Community::reproduction(): this=" << this - << " nsubcomms=" << nsubcomms << endl; -#endif - -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - if (env.stoch) { - if (!env.local) { // global stochasticty - eps = pLandscape->getGlobalStoch(yr); - } - } - subComms[i]->reproduction(land.resol,eps,land.rasterType,land.patchModel); -} -#if RSDEBUG -DEBUGLOG << "Community::reproduction(): finished" << endl; -#endif -} - -void Community::emigration(void) -{ -int nsubcomms = (int)subComms.size(); -#if RSDEBUG -DEBUGLOG << "Community::emigration(): this=" << this - << " nsubcomms=" << nsubcomms << endl; -#endif -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->emigration(); -} -#if RSDEBUG -DEBUGLOG << "Community::emigration(): finished" << endl; -#endif -} - -#if RS_RCPP // included also SEASONAL -void Community::dispersal(short landIx,short nextseason) -#else -void Community::dispersal(short landIx) -#endif // SEASONAL || RS_RCPP -{ -#if RSDEBUG -int t0,t1,t2; -t0 = time(0); -#endif - -simParams sim = paramsSim->getSim(); - -int nsubcomms = (int)subComms.size(); -// initiate dispersal - all emigrants leave their natal community and join matrix community -SubCommunity *matrix = subComms[0]; // matrix community is always the first -for (int i = 0; i < nsubcomms; i++) { // all populations - subComms[i]->initiateDispersal(matrix); -} -#if RSDEBUG -t1 = time(0); -DEBUGLOG << "Community::dispersal(): this=" << this - << " nsubcomms=" << nsubcomms << " initiation time=" << t1-t0 << endl; -#endif - -// dispersal is undertaken by all individuals now in the matrix patch -// (even if not physically in the matrix) -int ndispersers = 0; -do { - for (int i = 0; i < nsubcomms; i++) { // all populations - subComms[i]->resetPossSettlers(); - } -#if RSDEBUG -//DEBUGLOG << "Community::dispersal() 1111: ndispersers=" << ndispersers << endl; -#endif -#if RS_RCPP // included also SEASONAL - ndispersers = matrix->transfer(pLandscape,landIx,nextseason); -#else - ndispersers = matrix->transfer(pLandscape,landIx); -#endif // SEASONAL || RS_RCPP -#if RSDEBUG -//DEBUGLOG << "Community::dispersal() 2222: ndispersers=" << ndispersers << endl; -#endif - matrix->completeDispersal(pLandscape,sim.outConnect); -#if RSDEBUG -//DEBUGLOG << "Community::dispersal() 3333: ndispersers=" << ndispersers << endl; -#endif -} while (ndispersers > 0); - -#if RSDEBUG -DEBUGLOG << "Community::dispersal(): matrix=" << matrix << endl; -t2 = time(0); -DEBUGLOG << "Community::dispersal(): transfer time=" << t2-t1 << endl; -#endif - -#if RSDEBUG -//int t3 = time(0); -//DEBUGLOG << "Community::dispersal(): completion time = " << t3-t2 << endl; -#endif - -} - -void Community::survival(short part,short option0,short option1) -{ -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all communities (including in matrix) - subComms[i]->survival(part,option0,option1); -} -} - -void Community::ageIncrement(void) { -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all communities (including in matrix) - subComms[i]->ageIncrement(); -} -} - -// Calculate total no. of individuals of all species -int Community::totalInds(void) { -popStats p; -int total = 0; -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all communities (including in matrix) - p = subComms[i]->getPopStats(); - total += p.nInds; -} -return total; -} - -// Find the population of a given species in a given patch -Population* Community::findPop(Species *pSp,Patch *pPch) { -Population *pPop = 0; -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all communities (including in matrix) - pPop = subComms[i]->findPop(pSp,pPch); - if (pPop != 0) break; -} -return pPop; -} - -//--------------------------------------------------------------------------- -void Community::createOccupancy(int nrows,int reps) { -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { - subComms[i]->createOccupancy(nrows); -} -// Initialise array for occupancy of suitable cells/patches -occSuit = new float *[nrows]; -for (int i = 0; i < nrows; i++) -{ - occSuit[i] = new float[reps]; - for (int ii = 0; ii < reps; ii++) occSuit[i][ii] = 0.0; -} -} - -void Community::updateOccupancy(int row,int rep) -{ -#if RSDEBUG -DEBUGLOG << "Community::updateOccupancy(): row=" << row << endl; -#endif -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { - subComms[i]->updateOccupancy(row); -} - -commStats s = getStats(); -occSuit[row][rep] = (float)s.occupied / (float)s.suitable; - -} - -void Community::deleteOccupancy(int nrows) { -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { - subComms[i]->deleteOccupancy(); -} - -for(int i = 0; i < nrows; i++) - delete[] occSuit[i]; -delete[] occSuit; - -} - -//--------------------------------------------------------------------------- -// Count no. of sub-communities (suitable patches) and those occupied (non-zero populations) -// Determine range margins -commStats Community::getStats(void) -{ -commStats s; -landParams ppLand = pLandscape->getLandParams(); -s.ninds = s.nnonjuvs = s.suitable = s.occupied = 0; -s.minX = ppLand.maxX; s.minY = ppLand.maxY; s.maxX = s.maxY = 0; -float localK; -popStats patchPop; -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - patchPop = subComms[i]->getPopStats(); - s.ninds += patchPop.nInds; - s.nnonjuvs += patchPop.nNonJuvs; -#if RSDEBUG -//DEBUGLOG << "Community::getStats(): i = " << i -// << " pSpecies = " << patchPop.pSpecies << " pPatch = " << patchPop.pPatch -// << " nInds = " << patchPop.nInds << endl; -#endif - if (patchPop.pPatch != 0) { // not the matrix patch -#if RSDEBUG -//DEBUGLOG << "Community::getStats(): i = " << i -// << " patchNum = " << patchPop.pPatch->getPatchNum() << endl; -#endif - if (patchPop.pPatch->getPatchNum() != 0) { // not matrix patch - localK = patchPop.pPatch->getK(); -#if RSDEBUG -//DEBUGLOG << "Community::getStats(): i= " << i -// << " pSpecies= " << patchPop.pSpecies << " pPatch= " << patchPop.pPatch -// << " patchNum= " << patchPop.pPatch->getPatchNum() << " localK= " << localK -// << " nInds= " << patchPop.nInds << " breeding= " << (int)patchPop.breeding -// << endl; -#endif - if (localK > 0.0) s.suitable++; - if (patchPop.nInds > 0 && patchPop.breeding) { - s.occupied++; - patchLimits pchlim = patchPop.pPatch->getLimits(); - if (pchlim.xMin < s.minX) s.minX = pchlim.xMin; - if (pchlim.xMax > s.maxX) s.maxX = pchlim.xMax; - if (pchlim.yMin < s.minY) s.minY = pchlim.yMin; - if (pchlim.yMax > s.maxY) s.maxY = pchlim.yMax; - } - } - } -} -return s; -} - -//--------------------------------------------------------------------------- - -// Functions to control production of output files - -// Open population file and write header record -bool Community::outPopHeaders(Species *pSpecies,int option) { -return subComms[0]->outPopHeaders(pLandscape,pSpecies,option); -} - -// Write records to population file -void Community::outPop(int rep,int yr,int gen) -{ -// generate output for each sub-community (patch) in the community -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->outPop(pLandscape,rep,yr,gen); -} - -} - - -// Write records to individuals file -void Community::outInds(int rep, int yr, int gen,int landNr) { - -if (landNr >= 0) { // open the file - subComms[0]->outInds(pLandscape,rep,yr,gen,landNr); - return; -} -if (landNr == -999) { // close the file - subComms[0]->outInds(pLandscape,rep,yr,gen,-999); - return; -} -// generate output for each sub-community (patch) in the community -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->outInds(pLandscape,rep,yr,gen,landNr); -} -} - -// Write records to genetics file -void Community::outGenetics(int rep, int yr, int gen,int landNr) { -//landParams ppLand = pLandscape->getLandParams(); -if (landNr >= 0) { // open the file - subComms[0]->outGenetics(rep,yr,gen,landNr); - return; -} -if (landNr == -999) { // close the file - subComms[0]->outGenetics(rep,yr,gen,landNr); - return; -} -// generate output for each sub-community (patch) in the community -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->outGenetics(rep,yr,gen,landNr); -} -} - -// Open range file and write header record -bool Community::outRangeHeaders(Species *pSpecies,int landNr) -{ - -if (landNr == -999) { // close the file - if (outrange.is_open()) outrange.close(); - outrange.clear(); - return true; -} - -string name; -landParams ppLand = pLandscape->getLandParams(); -envStochParams env = paramsStoch->getStoch(); -simParams sim = paramsSim->getSim(); - -// NEED TO REPLACE CONDITIONAL COLUMNS BASED ON ATTRIBUTES OF ONE SPECIES TO COVER -// ATTRIBUTES OF *ALL* SPECIES AS DETECTED AT MODEL LEVEL -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); - -#if RSDEBUG -DEBUGLOG << "Community::outRangeHeaders(): simulation=" << sim.simulation - << " sim.batchMode=" << sim.batchMode - << " landNr=" << landNr << endl; -#endif - -if (sim.batchMode) { - name = paramsSim->getDir(2) -#if RS_RCPP - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" - + Int2Str(landNr) -#else - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" - + Int2Str(landNr) -#endif - + "_Range.txt"; -} -else { - name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) + "_Range.txt"; -} -outrange.open(name.c_str()); -outrange << "Rep\tYear\tRepSeason"; -if (env.stoch && !env.local) outrange << "\tEpsilon"; - -outrange << "\tNInds"; -if (dem.stageStruct) { - for (int i = 1; i < sstruct.nStages; i++) outrange << "\tNInd_stage" << i; - outrange << "\tNJuvs"; -} -if (ppLand.patchModel) outrange << "\tNOccupPatches"; -else outrange << "\tNOccupCells"; -outrange << "\tOccup/Suit\tmin_X\tmax_X\tmin_Y\tmax_Y"; - -if (emig.indVar) { - if (emig.sexDep) { - if (emig.densDep) { - outrange << "\tF_meanD0\tF_stdD0\tM_meanD0\tM_stdD0"; - outrange << "\tF_meanAlpha\tF_stdAlpha\tM_meanAlpha\tM_stdAlpha"; - outrange << "\tF_meanBeta\tF_stdBeta\tM_meanBeta\tM_stdBeta"; - } - else { - outrange << "\tF_meanEP\tF_stdEP\tM_meanEP\tM_stdEP"; - } - } - else { - if (emig.densDep) { - outrange << "\tmeanD0\tstdD0\tmeanAlpha\tstdAlpha"; - outrange << "\tmeanBeta\tstdBeta"; - } - else { - outrange << "\tmeanEP\tstdEP"; - } - } -} -if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 1) { - outrange << "\tmeanDP\tstdDP\tmeanGB\tstdGB"; - outrange << "\tmeanAlphaDB\tstdAlphaDB\tmeanBetaDB\tstdBetaDB"; - } - if (trfr.moveType == 2) { - outrange << "\tmeanStepLength\tstdStepLength\tmeanRho\tstdRho"; - } - } - else { - if (trfr.sexDep) { - outrange << "\tF_mean_distI\tF_std_distI\tM_mean_distI\tM_std_distI"; - if (trfr.twinKern) - outrange << "\tF_mean_distII\tF_std_distII\tM_mean_distII\tM_std_distII" - << "\tF_meanPfirstKernel\tF_stdPfirstKernel" - << "\tM_meanPfirstKernel\tM_stdPfirstKernel"; - } - else { - outrange << "\tmean_distI\tstd_distI"; - if (trfr.twinKern) - outrange << "\tmean_distII\tstd_distII\tmeanPfirstKernel\tstdPfirstKernel"; - } - } -} -if (sett.indVar) { - if (sett.sexDep) { - outrange << "\tF_meanS0\tF_stdS0\tM_meanS0\tM_stdS0"; - outrange << "\tF_meanAlphaS\tF_stdAlphaS\tM_meanAlphaS\tM_stdAlphaS"; - outrange << "\tF_meanBetaS\tF_stdBetaS\tM_meanBetaS\tM_stdBetaS"; - - } - else { - outrange << "\tmeanS0\tstdS0"; - outrange << "\tmeanAlphaS\tstdAlphaS"; - outrange << "\tmeanBetaS\tstdBetaS"; - } -} -outrange << endl; - -#if RSDEBUG -DEBUGLOG << "Community::outRangeHeaders(): finished" << endl; -#endif - -return outrange.is_open(); -} - -// Write record to range file -void Community::outRange(Species *pSpecies,int rep,int yr,int gen) -{ -#if RSDEBUG -DEBUGLOG << "Community::outRange(): rep=" << rep - << " yr=" << yr << " gen=" << gen << endl; -#endif - -landParams ppLand = pLandscape->getLandParams(); -envStochParams env = paramsStoch->getStoch(); - -// NEED TO REPLACE CONDITIONAL COLUMNS BASED ON ATTRIBUTES OF ONE SPECIES TO COVER -// ATTRIBUTES OF *ALL* SPECIES AS DETECTED AT MODEL LEVEL -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); - -outrange << rep << "\t" << yr << "\t" << gen; -if (env.stoch && !env.local) // write global environmental stochasticity - outrange << "\t" << pLandscape->getGlobalStoch(yr); - -commStats s = getStats(); - -if (dem.stageStruct) { - outrange << "\t" << s.nnonjuvs; - int stagepop; - int nsubcomms = (int)subComms.size(); - // all non-juvenile stages - for (int stg = 1; stg < sstruct.nStages; stg++) { - stagepop = 0; - for (int i = 0; i < nsubcomms; i++) { // all sub-communities - stagepop += subComms[i]->stagePop(stg); - } - outrange <<"\t" << stagepop; - } - // juveniles born in current reproductive season - stagepop = 0; - for (int i = 0; i < nsubcomms; i++) { // all sub-communities - stagepop += subComms[i]->stagePop(0); - } - outrange <<"\t" << stagepop; -} -else { // non-structured species - outrange << "\t" << s.ninds; -} - -float occsuit = 0.0; -if (s.suitable > 0) occsuit = (float)s.occupied / (float)s.suitable; -outrange << "\t" << s.occupied << "\t" << occsuit; -// RANGE MINIMA AND MAXIMA NEED TO BECOME A PROPERTY OF THE SPECIES -if (s.ninds > 0) { - landOrigin origin = pLandscape->getOrigin(); - outrange << "\t" << (float)s.minX * (float)ppLand.resol + origin.minEast - << "\t" << (float)(s.maxX+1) * (float)ppLand.resol + origin.minEast - << "\t" << (float)s.minY * (float)ppLand.resol + origin.minNorth - << "\t" << (float)(s.maxY+1) * (float)ppLand.resol + origin.minNorth; -} -else - outrange <<"\t0\t0\t0\t0"; - -if (emig.indVar || trfr.indVar || sett.indVar) { // output trait means - traitsums ts; - traitsums scts; // sub-community traits - traitCanvas tcanv; - int ngenes,popsize; - - tcanv.pcanvas[0] = NULL; - - for (int i = 0; i < NSEXES; i++) { - ts.ninds[i] = 0; - ts.sumD0[i] = ts.ssqD0[i] = 0.0; - ts.sumAlpha[i] = ts.ssqAlpha[i] = 0.0; ts.sumBeta[i] = ts.ssqBeta[i] = 0.0; - ts.sumDist1[i] = ts.ssqDist1[i] = 0.0; ts.sumDist2[i] = ts.ssqDist2[i] = 0.0; - ts.sumProp1[i] = ts.ssqProp1[i] = 0.0; - ts.sumDP[i] = ts.ssqDP[i] = 0.0; - ts.sumGB[i] = ts.ssqGB[i] = 0.0; - ts.sumAlphaDB[i] = ts.ssqAlphaDB[i] = 0.0; - ts.sumBetaDB[i] = ts.ssqBetaDB[i] = 0.0; - ts.sumStepL[i] = ts.ssqStepL[i] = 0.0; ts.sumRho[i] = ts.ssqRho[i] = 0.0; - ts.sumS0[i] = ts.ssqS0[i] = 0.0; - ts.sumAlphaS[i] = ts.ssqAlphaS[i] = 0.0; ts.sumBetaS[i] = ts.ssqBetaS[i] = 0.0; - } - - int nsubcomms = (int)subComms.size(); - for (int i = 0; i < nsubcomms; i++) { // all sub-communities (incl. matrix) - scts = subComms[i]->outTraits(tcanv,pLandscape,rep,yr,gen,true); - for (int j = 0; j < NSEXES; j++) { - ts.ninds[j] += scts.ninds[j]; - ts.sumD0[j] += scts.sumD0[j]; ts.ssqD0[j] += scts.ssqD0[j]; - ts.sumAlpha[j] += scts.sumAlpha[j]; ts.ssqAlpha[j] += scts.ssqAlpha[j]; - ts.sumBeta[j] += scts.sumBeta[j]; ts.ssqBeta[j] += scts.ssqBeta[j]; - ts.sumDist1[j] += scts.sumDist1[j]; ts.ssqDist1[j] += scts.ssqDist1[j]; - ts.sumDist2[j] += scts.sumDist2[j]; ts.ssqDist2[j] += scts.ssqDist2[j]; - ts.sumProp1[j] += scts.sumProp1[j]; ts.ssqProp1[j] += scts.ssqProp1[j]; - ts.sumDP[j] += scts.sumDP[j]; ts.ssqDP[j] += scts.ssqDP[j]; - ts.sumGB[j] += scts.sumGB[j]; ts.ssqGB[j] += scts.ssqGB[j]; - ts.sumAlphaDB[j] += scts.sumAlphaDB[j]; ts.ssqAlphaDB[j] += scts.ssqAlphaDB[j]; - ts.sumBetaDB[j] += scts.sumBetaDB[j]; ts.ssqBetaDB[j] += scts.ssqBetaDB[j]; - ts.sumStepL[j] += scts.sumStepL[j]; ts.ssqStepL[j] += scts.ssqStepL[j]; - ts.sumRho[j] += scts.sumRho[j]; ts.ssqRho[j] += scts.ssqRho[j]; - ts.sumS0[j] += scts.sumS0[j]; ts.ssqS0[j] += scts.ssqS0[j]; - ts.sumAlphaS[j] += scts.sumAlphaS[j]; ts.ssqAlphaS[j] += scts.ssqAlphaS[j]; - ts.sumBetaS[j] += scts.sumBetaS[j]; ts.ssqBetaS[j] += scts.ssqBetaS[j]; -#if RSDEBUG -//DEBUGLOG << "Community::outRange(): i=" << i << " j=" << j -// << " scts.ninds[j]=" << scts.ninds[j] -// << " scts.sumD0[j]=" << scts.sumD0[j] -// << " scts.ssqD0[j]=" << scts.ssqD0[j] -// << endl; -//DEBUGLOG << "Community::outRange(): i=" << i << " j=" << j -// << " ts.ninds[j]=" << ts.ninds[j] -// << " ts.sumD0[j]=" << ts.sumD0[j] << " ts.ssqD0[j]=" << ts.ssqD0[j] -// << endl; -#endif - } - } - - if (emig.indVar) { - if (emig.sexDep) { // must be a sexual species - ngenes = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ngenes = 1; - } - else { // sexual reproduction - ngenes = 1; - } - } - double mnD0[2],mnAlpha[2],mnBeta[2],sdD0[2],sdAlpha[2],sdBeta[2]; - for (int g = 0; g < ngenes; g++) { - mnD0[g] = mnAlpha[g] = mnBeta[g] = sdD0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - // individuals may have been counted by sex if there was - // sex dependency in another dispersal phase - if (ngenes == 2) popsize = ts.ninds[g]; - else popsize = ts.ninds[0] + ts.ninds[1]; - if (popsize > 0) { - mnD0[g] = ts.sumD0[g] / (double)popsize; - mnAlpha[g] = ts.sumAlpha[g] / (double)popsize; - mnBeta[g] = ts.sumBeta[g] / (double)popsize; - if (popsize > 1) { - sdD0[g] = ts.ssqD0[g]/(double)popsize - mnD0[g]*mnD0[g]; - if (sdD0[g] > 0.0) sdD0[g] = sqrt(sdD0[g]); else sdD0[g] = 0.0; - sdAlpha[g] = ts.ssqAlpha[g]/(double)popsize - mnAlpha[g]*mnAlpha[g]; - if (sdAlpha[g] > 0.0) sdAlpha[g] = sqrt(sdAlpha[g]); else sdAlpha[g] = 0.0; - sdBeta[g] = ts.ssqBeta[g]/(double)popsize - mnBeta[g]*mnBeta[g]; - if (sdBeta[g] > 0.0) sdBeta[g] = sqrt(sdBeta[g]); else sdBeta[g] = 0.0; - } - else { - sdD0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - } - } -#if RSDEBUG -//DEBUGLOG << "Community::outRange(): ngenes=" << ngenes << " g=" << g -// << " ts.ninds[g]=" << ts.ninds[g] -// << " ts.sumD0[g]=" << ts.sumD0[g] -// << " ts.ssqD0[g]=" << ts.ssqD0[g] -// << endl; -//DEBUGLOG << "Community::outRange(): popsize=" << popsize -// << " mnD0[g]" << mnD0[g] << " sdD0[g]" << sdD0[g] -// << endl; -#endif - } - if (emig.sexDep) { - outrange << "\t" << mnD0[0] << "\t" << sdD0[0]; - outrange << "\t" << mnD0[1] << "\t" << sdD0[1]; - if (emig.densDep) { - outrange << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outrange << "\t" << mnAlpha[1] << "\t" << sdAlpha[1]; - outrange << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - outrange << "\t" << mnBeta[1] << "\t" << sdBeta[1]; - } - } - else { // sex-independent - outrange << "\t" << mnD0[0] << "\t" << sdD0[0]; - if (emig.densDep) { - outrange << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outrange << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - } - } - } - - if (trfr.indVar) { - if (trfr.moveModel) { - // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT - ngenes = 1; - } - else { - if (trfr.sexDep) { // must be a sexual species - ngenes = 2; - } - else { - ngenes = 1; - } - } - double mnDist1[2],mnDist2[2],mnProp1[2],mnStepL[2],mnRho[2]; - double sdDist1[2],sdDist2[2],sdProp1[2],sdStepL[2],sdRho[2]; - double mnDP[2],mnGB[2],mnAlphaDB[2],mnBetaDB[2]; - double sdDP[2],sdGB[2],sdAlphaDB[2],sdBetaDB[2]; - for (int g = 0; g < ngenes; g++) { - mnDist1[g] = mnDist2[g] = mnProp1[g] = mnStepL[g] = mnRho[g] = 0.0; - sdDist1[g] = sdDist2[g] = sdProp1[g] = sdStepL[g] = sdRho[g] = 0.0; - mnDP[g] = mnGB[g] = mnAlphaDB[g] = mnBetaDB[g] = 0.0; - sdDP[g] = sdGB[g] = sdAlphaDB[g] = sdBetaDB[g] = 0.0; - // individuals may have been counted by sex if there was - // sex dependency in another dispersal phase - if (ngenes == 2) popsize = ts.ninds[g]; - else popsize = ts.ninds[0] + ts.ninds[1]; - if (popsize > 0) { - mnDist1[g] = ts.sumDist1[g] / (double)popsize; - mnDist2[g] = ts.sumDist2[g] / (double)popsize; - mnProp1[g] = ts.sumProp1[g] / (double)popsize; - mnStepL[g] = ts.sumStepL[g] / (double)popsize; - mnRho[g] = ts.sumRho[g] / (double)popsize; - mnDP[g] = ts.sumDP[g] / (double)popsize; - mnGB[g] = ts.sumGB[g] / (double)popsize; - mnAlphaDB[g] = ts.sumAlphaDB[g] / (double)popsize; - mnBetaDB[g] = ts.sumBetaDB[g] / (double)popsize; - if (popsize > 1) { - sdDist1[g] = ts.ssqDist1[g]/(double)popsize - mnDist1[g]*mnDist1[g]; - if (sdDist1[g] > 0.0) sdDist1[g] = sqrt(sdDist1[g]); else sdDist1[g] = 0.0; - sdDist2[g] = ts.ssqDist2[g]/(double)popsize - mnDist2[g]*mnDist2[g]; - if (sdDist2[g] > 0.0) sdDist2[g] = sqrt(sdDist2[g]); else sdDist2[g] = 0.0; - sdProp1[g] = ts.ssqProp1[g]/(double)popsize - mnProp1[g]*mnProp1[g]; - if (sdProp1[g] > 0.0) sdProp1[g] = sqrt(sdProp1[g]); else sdProp1[g] = 0.0; - sdStepL[g] = ts.ssqStepL[g]/(double)popsize - mnStepL[g]*mnStepL[g]; - if (sdStepL[g] > 0.0) sdStepL[g] = sqrt(sdStepL[g]); else sdStepL[g] = 0.0; - sdRho[g] = ts.ssqRho[g]/(double)popsize - mnRho[g]*mnRho[g]; - if (sdRho[g] > 0.0) sdRho[g] = sqrt(sdRho[g]); else sdRho[g] = 0.0; - sdDP[g] = ts.ssqDP[g]/(double)popsize - mnDP[g]*mnDP[g]; - if (sdDP[g] > 0.0) sdDP[g] = sqrt(sdDP[g]); else sdDP[g] = 0.0; - sdGB[g] = ts.ssqGB[g]/(double)popsize - mnGB[g]*mnGB[g]; - if (sdGB[g] > 0.0) sdGB[g] = sqrt(sdGB[g]); else sdGB[g] = 0.0; - sdAlphaDB[g] = ts.ssqAlphaDB[g]/(double)popsize - mnAlphaDB[g]*mnAlphaDB[g]; - if (sdAlphaDB[g] > 0.0) sdAlphaDB[g] = sqrt(sdAlphaDB[g]); else sdAlphaDB[g] = 0.0; - sdBetaDB[g] = ts.ssqBetaDB[g]/(double)popsize - mnBetaDB[g]*mnBetaDB[g]; - if (sdBetaDB[g] > 0.0) sdBetaDB[g] = sqrt(sdBetaDB[g]); else sdBetaDB[g] = 0.0; - } - } -#if RSDEBUG -//DEBUGLOG << "Community::outRange(): ngenes=" << ngenes << " g=" << g -// << " ts.ninds[g]=" << ts.ninds[g] -// << " ts.sumDP[g]=" << ts.sumDP[g] << " ts.ssqDP[g]=" << ts.ssqDP[g] -// << " ts.sumGB[g]=" << ts.sumGB[g] << " ts.ssqGB[g]=" << ts.ssqGB[g] -// << endl; -//DEBUGLOG << "Community::outRange(): popsize=" << popsize -// << " mnDP[g]" << mnDP[g] << " sdDP[g]" << sdDP[g] -// << " mnGB[g]" << mnGB[g] << " sdGB[g]" << sdGB[g] -// << endl; -#endif - } - if (trfr.moveModel) { - if (trfr.moveType == 1) { - outrange << "\t" << mnDP[0] << "\t" << sdDP[0]; - outrange << "\t" << mnGB[0] << "\t" << sdGB[0]; - outrange << "\t" << mnAlphaDB[0] << "\t" << sdAlphaDB[0]; - outrange << "\t" << mnBetaDB[0] << "\t" << sdBetaDB[0]; - } - if (trfr.moveType == 2) { - outrange << "\t" << mnStepL[0] << "\t" << sdStepL[0]; - outrange << "\t" << mnRho[0] << "\t" << sdRho[0]; - } - } - else { - if (trfr.sexDep) { - outrange << "\t" << mnDist1[0] << "\t" << sdDist1[0]; - outrange << "\t" << mnDist1[1] << "\t" << sdDist1[1]; - if (trfr.twinKern) - { - outrange << "\t" << mnDist2[0] << "\t" << sdDist2[0]; - outrange << "\t" << mnDist2[1] << "\t" << sdDist2[1]; - outrange << "\t" << mnProp1[0] << "\t" << sdProp1[0]; - outrange << "\t" << mnProp1[1] << "\t" << sdProp1[1]; - } - } - else { // sex-independent - outrange << "\t" << mnDist1[0] << "\t" << sdDist1[0]; - if (trfr.twinKern) - { - outrange << "\t" << mnDist2[0] << "\t" << sdDist2[0]; - outrange << "\t" << mnProp1[0] << "\t" << sdProp1[0]; - } - } - } - } - - if (sett.indVar) { - if (sett.sexDep) { // must be a sexual species - ngenes = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ngenes = 1; - } - else { // sexual reproduction - ngenes = 1; - } - } - // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT - double mnS0[2],mnAlpha[2],mnBeta[2],sdS0[2],sdAlpha[2],sdBeta[2]; - for (int g = 0; g < ngenes; g++) { - mnS0[g] = mnAlpha[g] = mnBeta[g] = sdS0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - // individuals may have been counted by sex if there was - // sex dependency in another dispersal phase - if (ngenes == 2) popsize = ts.ninds[g]; - else popsize = ts.ninds[0] + ts.ninds[1]; - if (popsize > 0) { - mnS0[g] = ts.sumS0[g] / (double)popsize; - mnAlpha[g] = ts.sumAlphaS[g] / (double)popsize; - mnBeta[g] = ts.sumBetaS[g] / (double)popsize; - if (popsize > 1) { - sdS0[g] = ts.ssqS0[g]/(double)popsize - mnS0[g]*mnS0[g]; - if (sdS0[g] > 0.0) sdS0[g] = sqrt(sdS0[g]); else sdS0[g] = 0.0; - sdAlpha[g] = ts.ssqAlphaS[g]/(double)popsize - mnAlpha[g]*mnAlpha[g]; - if (sdAlpha[g] > 0.0) sdAlpha[g] = sqrt(sdAlpha[g]); else sdAlpha[g] = 0.0; - sdBeta[g] = ts.ssqBetaS[g]/(double)popsize - mnBeta[g]*mnBeta[g]; - if (sdBeta[g] > 0.0) sdBeta[g] = sqrt(sdBeta[g]); else sdBeta[g] = 0.0; - } - else { - sdS0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - } - } - } - if (sett.sexDep) { - outrange << "\t" << mnS0[0] << "\t" << sdS0[0]; - outrange << "\t" << mnS0[1] << "\t" << sdS0[1]; - outrange << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outrange << "\t" << mnAlpha[1] << "\t" << sdAlpha[1]; - outrange << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - outrange << "\t" << mnBeta[1] << "\t" << sdBeta[1]; - } - else { - outrange << "\t" << mnS0[0] << "\t" << sdS0[0]; - outrange << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outrange << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - } - } - -} - -outrange << endl; -} - -// Open occupancy file, write header record and set up occupancy array -bool Community::outOccupancyHeaders(int option) -{ -if (option == -999) { // close the files - if (outsuit.is_open()) outsuit.close(); - if (outoccup.is_open()) outoccup.close(); - outsuit.clear(); outoccup.clear(); - return true; -} - -string name, nameI; -simParams sim = paramsSim->getSim(); -//demogrParams dem = pSpecies->getDemogr(); -landParams ppLand = pLandscape->getLandParams(); -int outrows = (sim.years/sim.outIntOcc) + 1; - -name = paramsSim->getDir(2); -if (sim.batchMode) { - name += "Batch" + Int2Str(sim.batchNum) + "_"; - name += "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(ppLand.landNum); -} -else - name += "Sim" + Int2Str(sim.simulation); -name += "_Occupancy_Stats.txt"; -outsuit.open(name.c_str()); -outsuit << "Year\tMean_OccupSuit\tStd_error" << endl; - -name = paramsSim->getDir(2); -if (sim.batchMode) { - name += "Batch" + Int2Str(sim.batchNum) + "_"; - name += "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(ppLand.landNum); -} -else - name += "Sim" + Int2Str(sim.simulation); -name += "_Occupancy.txt"; -outoccup.open(name.c_str()); -if (ppLand.patchModel) { - outoccup << "PatchID"; -} -else { - outoccup << "X\tY"; -} -for (int i = 0; i < outrows; i++) - outoccup << "\t" << "Year_" << i*sim.outIntOcc; -outoccup << endl; - -// Initialise cells/patches occupancy array -createOccupancy(outrows,sim.reps); - -return outsuit.is_open() && outoccup.is_open(); -} - -void Community::outOccupancy(void) { -landParams ppLand = pLandscape->getLandParams(); -simParams sim = paramsSim->getSim(); -//streamsize prec = outoccup.precision(); -locn loc; - -int nsubcomms = (int)subComms.size(); -for (int i = 1; i < nsubcomms; i++) { // all except matrix sub-community - if (ppLand.patchModel) { - outoccup << subComms[i]->getPatch()->getPatchNum(); - } - else { - loc = subComms[i]->getLocn(); - outoccup << loc.x << "\t" << loc.y; - } - for (int row = 0; row <= (sim.years/sim.outIntOcc); row++) - { - outoccup << "\t" << (double)subComms[i]->getOccupancy(row)/(double)sim.reps; - } - outoccup << endl; -} -} - -void Community::outOccSuit(bool view) { -double sum,ss,mean,sd,se; -simParams sim = paramsSim->getSim(); -//streamsize prec = outsuit.precision(); - -#if RSDEBUG -//DEBUGLOG << "Community::outOccSuit(): sim.reps=" << sim.reps -// << " sim.years=" << sim.years << " sim.outInt=" << sim.outInt << endl; -#endif -for (int i = 0; i < (sim.years/sim.outIntOcc)+1; i++) { - sum = ss = 0.0; - for (int rep = 0; rep < sim.reps; rep++) { - sum += occSuit[i][rep]; - ss += occSuit[i][rep] * occSuit[i][rep]; -#if RSDEBUG -//DEBUGLOG << "Community::outOccSuit(): i=" << i << " rep=" << rep -// << " occSuit[i][rep]=" << occSuit[i][rep] -// << " sum=" << sum << " ss=" << ss -// << endl; -#endif - } - mean = sum/(double)sim.reps; - sd = (ss - (sum*sum/(double)sim.reps)) / (double)(sim.reps-1); -#if RSDEBUG -//DEBUGLOG << "Community::outOccSuit(): i=" << i -// << " mean=" << mean << " sd=" << sd << endl; -#endif - if (sd > 0.0) sd = sqrt(sd); - else sd = 0.0; - se = sd / sqrt((double)(sim.reps)); -#if RSDEBUG -//DEBUGLOG << "Community::outOccSuit(): i=" << i -// << " sd=" << sd << " se=" << se << endl; -#endif - -// outsuit << i*sim.outInt << "\t" << mean << "\t" << se << endl; -// if (view) viewOccSuit(i*sim.outInt,mean,se); - outsuit << i*sim.outIntOcc << "\t" << mean << "\t" << se << endl; - if (view) viewOccSuit(i*sim.outIntOcc,mean,se); -} - -} - -// Open traits file and write header record -bool Community::outTraitsHeaders(Species *pSpecies,int landNr) { -return subComms[0]->outTraitsHeaders(pLandscape,pSpecies,landNr); -} - -// Write records to traits file -/* NOTE: for summary traits by rows, which is permissible for a cell-based landscape -only, this function relies on the fact that subcommunities are created in the same -sequence as patches, which is in asecending order of x nested within descending -order of y -*/ -//void Community::outTraits(emigCanvas ecanv,trfrCanvas tcanv,Species *pSpecies, -// int rep,int yr,int gen) -void Community::outTraits(traitCanvas tcanv,Species *pSpecies, - int rep,int yr,int gen) -{ -simParams sim = paramsSim->getSim(); -simView v = paramsSim->getViews(); -landParams land = pLandscape->getLandParams(); -//demogrParams dem = pSpecies->getDemogr(); -//emigRules emig = pSpecies->getEmig(); -//trfrRules trfr = pSpecies->getTrfr(); -//locn loc; -traitsums *ts = 0; -traitsums sctraits; -if (sim.outTraitsRows && yr >= sim.outStartTraitRow && yr%sim.outIntTraitRow == 0) { - // create array of traits means, etc., one for each row - ts = new traitsums[land.dimY]; - for (int y = 0; y < land.dimY; y++) { - for (int i = 0; i < NSEXES; i++) { - ts[y].ninds[i] = 0; - ts[y].sumD0[i] = ts[y].ssqD0[i] = 0.0; - ts[y].sumAlpha[i] = ts[y].ssqAlpha[i] = 0.0; - ts[y].sumBeta[i] = ts[y].ssqBeta[i] = 0.0; - ts[y].sumDist1[i] = ts[y].ssqDist1[i] = 0.0; - ts[y].sumDist2[i] = ts[y].ssqDist2[i] = 0.0; - ts[y].sumProp1[i] = ts[y].ssqProp1[i] = 0.0; - ts[y].sumStepL[i] = ts[y].ssqStepL[i] = 0.0; - ts[y].sumRho[i] = ts[y].ssqRho[i] = 0.0; - ts[y].sumS0[i] = ts[y].ssqS0[i] = 0.0; - ts[y].sumAlphaS[i] = ts[y].ssqAlphaS[i] = 0.0; - ts[y].sumBetaS[i] = ts[y].ssqBetaS[i] = 0.0; - } - } -} -if (v.viewTraits -|| ((sim.outTraitsCells && yr >= sim.outStartTraitCell && yr%sim.outIntTraitCell == 0) || - (sim.outTraitsRows && yr >= sim.outStartTraitRow && yr%sim.outIntTraitRow == 0))) -{ - // generate output for each sub-community (patch) in the community - int nsubcomms = (int)subComms.size(); - for (int i = 1; i < nsubcomms; i++) { // // all except matrix sub-community -// sctraits = subComms[i]->outTraits(ecanv,tcanv,pLandscape,rep,yr,gen); -// sctraits = subComms[i]->outTraits(tcanv,pLandscape,rep,yr,gen,v.viewGrad); - sctraits = subComms[i]->outTraits(tcanv,pLandscape,rep,yr,gen,false); - locn loc = subComms[i]->getLocn(); - int y = loc.y; - if (sim.outTraitsRows && yr >= sim.outStartTraitRow && yr%sim.outIntTraitRow == 0) - { - for (int s = 0; s < NSEXES; s++) { - ts[y].ninds[s] += sctraits.ninds[s]; - ts[y].sumD0[s] += sctraits.sumD0[s]; ts[y].ssqD0[s] += sctraits.ssqD0[s]; - ts[y].sumAlpha[s] += sctraits.sumAlpha[s]; ts[y].ssqAlpha[s] += sctraits.ssqAlpha[s]; - ts[y].sumBeta[s] += sctraits.sumBeta[s]; ts[y].ssqBeta[s] += sctraits.ssqBeta[s]; - ts[y].sumDist1[s] += sctraits.sumDist1[s]; ts[y].ssqDist1[s] += sctraits.ssqDist1[s]; - ts[y].sumDist2[s] += sctraits.sumDist2[s]; ts[y].ssqDist2[s] += sctraits.ssqDist2[s]; - ts[y].sumProp1[s] += sctraits.sumProp1[s]; ts[y].ssqProp1[s] += sctraits.ssqProp1[s]; - ts[y].sumStepL[s] += sctraits.sumStepL[s]; ts[y].ssqStepL[s] += sctraits.ssqStepL[s]; - ts[y].sumRho[s] += sctraits.sumRho[s]; ts[y].ssqRho[s] += sctraits.ssqRho[s]; - ts[y].sumS0[s] += sctraits.sumS0[s]; ts[y].ssqS0[s] += sctraits.ssqS0[s]; - ts[y].sumAlphaS[s] += sctraits.sumAlphaS[s]; ts[y].ssqAlphaS[s] += sctraits.ssqAlphaS[s]; - ts[y].sumBetaS[s] += sctraits.sumBetaS[s]; ts[y].ssqBetaS[s] += sctraits.ssqBetaS[s]; - } - } - } - if (nsubcomms > 0 && sim.outTraitsRows - && yr >= sim.outStartTraitRow && yr%sim.outIntTraitRow == 0) { - for (int y = 0; y < land.dimY; y++) { - if ((ts[y].ninds[0]+ts[y].ninds[1]) > 0) { - writeTraitsRows(pSpecies,rep,yr,gen,y,ts[y]); - } - } - } -} -//if (sim.outTraitsRows && yr >= sim.outStartTraitRow && yr%sim.outIntTraitRow == 0) -//{ -// if (ts != 0) delete[] ts; -//} -if (ts != 0) { delete[] ts; ts = 0; } -} - -// Write records to trait rows file -void Community::writeTraitsRows(Species *pSpecies,int rep,int yr,int gen,int y, - traitsums ts) -{ -//simParams sim = paramsSim->getSim(); -//simView v = paramsSim->getViews(); -//landData land = pLandscape->getLandData(); -//landOrigin origin = pLandscape->getOrigin(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -double mn,sd; - -// calculate population size in case one phase is sex-dependent and the other is not -// (in which case numbers of individuals are recorded by sex) -int popsize = ts.ninds[0] + ts.ninds[1]; -outtraitsrows << rep << "\t" << yr << "\t" << gen - << "\t" << y; -// << "\t" << y*land.resol + origin.minNorth; -if ((emig.indVar && emig.sexDep) || (trfr.indVar && trfr.sexDep)) - outtraitsrows << "\t" << ts.ninds[0] << "\t" << ts.ninds[1]; -else - outtraitsrows << "\t" << popsize; - -if (emig.indVar) { - if (emig.sexDep) { - if (ts.ninds[0] > 0) mn = ts.sumD0[0]/(double)ts.ninds[0]; else mn = 0.0; - if (ts.ninds[0] > 1) sd = ts.ssqD0[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[1] > 0) mn = ts.sumD0[1]/(double)ts.ninds[1]; else mn = 0.0; - if (ts.ninds[1] > 1) sd = ts.ssqD0[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (emig.densDep) { - if (ts.ninds[0] > 0) mn = ts.sumAlpha[0]/(double)ts.ninds[0]; else mn = 0.0; - if (ts.ninds[0] > 1) sd = ts.ssqAlpha[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[1] > 0) mn = ts.sumAlpha[1]/(double)ts.ninds[1]; else mn = 0.0; - if (ts.ninds[1] > 1) sd = ts.ssqAlpha[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[0] > 0) mn = ts.sumBeta[0]/(double)ts.ninds[0]; else mn = 0.0; - if (ts.ninds[0] > 1) sd = ts.ssqBeta[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[1] > 0) mn = ts.sumBeta[1]/(double)ts.ninds[1]; else mn = 0.0; - if (ts.ninds[1] > 1) sd = ts.ssqBeta[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - } - } - else { // no sex dependence in emigration - if (popsize > 0) mn = ts.sumD0[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqD0[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (emig.densDep) { - if (popsize > 0) mn = ts.sumAlpha[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqAlpha[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (popsize > 0) mn = ts.sumBeta[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqBeta[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - } - } -} - -if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 2) { // CRW - // NB - CURRENTLY CANNOT BE SEX-DEPENDENT... - if (popsize > 0) mn = ts.sumStepL[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqStepL[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (popsize > 0) mn = ts.sumRho[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqRho[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; -// if (ts.ninds[0] > 0) mn = ts.sumStepL[0]/(double)ts.ninds[0]; else mn = 0.0; -// if (ts.ninds[0] > 1) sd = ts.ssqStepL[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; -// if (ts.ninds[0] > 0) mn = ts.sumRho[0]/(double)ts.ninds[0]; else mn = 0.0; -// if (ts.ninds[0] > 1) sd = ts.ssqRho[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; - } - } - else { // dispersal kernel - if (trfr.sexDep) { - if (ts.ninds[0] > 0) mn = ts.sumDist1[0]/(double)ts.ninds[0]; else mn = 0.0; - if (ts.ninds[0] > 1) sd = ts.ssqDist1[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[1] > 0) mn = ts.sumDist1[1]/(double)ts.ninds[1]; else mn = 0.0; - if (ts.ninds[1] > 1) sd = ts.ssqDist1[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (trfr.twinKern) - { - if (ts.ninds[0] > 0) mn = ts.sumDist2[0]/(double)ts.ninds[0]; else mn = 0.0; - if (ts.ninds[0] > 1) sd = ts.ssqDist2[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[1] > 0) mn = ts.sumDist2[1]/(double)ts.ninds[1]; else mn = 0.0; - if (ts.ninds[1] > 1) sd = ts.ssqDist2[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[0] > 0) mn = ts.sumProp1[0]/(double)ts.ninds[0]; else mn = 0.0; - if (ts.ninds[0] > 1) sd = ts.ssqProp1[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (ts.ninds[1] > 0) mn = ts.sumProp1[1]/(double)ts.ninds[1]; else mn = 0.0; - if (ts.ninds[1] > 1) sd = ts.ssqProp1[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - } - } - else { // sex-independent - if (popsize > 0) mn = ts.sumDist1[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqDist1[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (trfr.twinKern) - { - if (popsize > 0) mn = ts.sumDist2[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqDist2[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (popsize > 0) mn = ts.sumProp1[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqProp1[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - } - } - } -} - -if (sett.indVar) { - // NB - CURRENTLY CANNOT BE SEX-DEPENDENT... -// if (sett.sexDep) { -// if (ts.ninds[0] > 0) mn = ts.sumS0[0]/(double)ts.ninds[0]; else mn = 0.0; -// if (ts.ninds[0] > 1) sd = ts.ssqS0[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; -// if (ts.ninds[1] > 0) mn = ts.sumS0[1]/(double)ts.ninds[1]; else mn = 0.0; -// if (ts.ninds[1] > 1) sd = ts.ssqS0[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; -// if (ts.ninds[0] > 0) mn = ts.sumAlphaS[0]/(double)ts.ninds[0]; else mn = 0.0; -// if (ts.ninds[0] > 1) sd = ts.ssqAlphaS[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; -// if (ts.ninds[1] > 0) mn = ts.sumAlphaS[1]/(double)ts.ninds[1]; else mn = 0.0; -// if (ts.ninds[1] > 1) sd = ts.ssqAlphaS[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; -// if (ts.ninds[0] > 0) mn = ts.sumBetaS[0]/(double)ts.ninds[0]; else mn = 0.0; -// if (ts.ninds[0] > 1) sd = ts.ssqBetaS[0]/(double)ts.ninds[0] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; -// if (ts.ninds[1] > 0) mn = ts.sumBetaS[1]/(double)ts.ninds[1]; else mn = 0.0; -// if (ts.ninds[1] > 1) sd = ts.ssqBetaS[1]/(double)ts.ninds[1] - mn*mn; else sd = 0.0; -// if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; -// outtraitsrows << "\t" << mn << "\t" << sd; -// } -// else { // no sex dependence in settlement - if (popsize > 0) mn = ts.sumS0[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqS0[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (popsize > 0) mn = ts.sumAlphaS[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqAlphaS[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; - if (popsize > 0) mn = ts.sumBetaS[0]/(double)popsize; else mn = 0.0; - if (popsize > 1) sd = ts.ssqBetaS[0]/(double)popsize - mn*mn; else sd = 0.0; - if (sd > 0.0) sd = sqrt(sd); else sd = 0.0; - outtraitsrows << "\t" << mn << "\t" << sd; -// } -} - -outtraitsrows << endl; -} - -// Open trait rows file and write header record -bool Community::outTraitsRowsHeaders(Species *pSpecies,int landNr) { - -if (landNr == -999) { // close file - if (outtraitsrows.is_open()) outtraitsrows.close(); - outtraitsrows.clear(); - return true; -} - -string name; -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -simParams sim = paramsSim->getSim(); - -string DirOut = paramsSim->getDir(2); -if (sim.batchMode) { - name = DirOut - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(landNr) + "_TraitsXrow.txt"; -} -else { - name = DirOut + "Sim" + Int2Str(sim.simulation) + "_TraitsXrow.txt"; -} -outtraitsrows.open(name.c_str()); - -outtraitsrows << "Rep\tYear\tRepSeason\ty"; -if ((emig.indVar && emig.sexDep) || (trfr.indVar && trfr.sexDep)) - outtraitsrows << "\tN_females\tN_males"; -else - outtraitsrows << "\tN"; - -if (emig.indVar) { - if (emig.sexDep) { - if (emig.densDep) { - outtraitsrows << "\tF_meanD0\tF_stdD0\tM_meanD0\tM_stdD0"; - outtraitsrows << "\tF_meanAlpha\tF_stdAlpha\tM_meanAlpha\tM_stdAlpha"; - outtraitsrows << "\tF_meanBeta\tF_stdBeta\tM_meanBeta\tM_stdBeta"; - } - else { - outtraitsrows << "\tF_meanEP\tF_stdEP\tM_meanEP\tM_stdEP"; - } - } - else { - if (emig.densDep) { - outtraitsrows << "\tmeanD0\tstdD0\tmeanAlpha\tstdAlpha"; - outtraitsrows << "\tmeanBeta\tstdBeta"; - } - else { - outtraitsrows << "\tmeanEP\tstdEP"; - } - } -} -if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 2) { - outtraitsrows << "\tmeanStepLength\tstdStepLength\tmeanRho\tstdRho"; - } - } - else { // dispersal kernel - if (trfr.sexDep) { - outtraitsrows << "\tF_mean_distI\tF_std_distI\tM_mean_distI\tM_std_distI"; - if (trfr.twinKern) - outtraitsrows << "\tF_mean_distII\tF_std_distII\tM_mean_distII\tM_std_distII" - << "\tF_meanPfirstKernel\tF_stdPfirstKernel" - << "\tM_meanPfirstKernel\tM_stdPfirstKernel"; - } - else { - outtraitsrows << "\tmean_distI\tstd_distI"; - if (trfr.twinKern) - outtraitsrows << "\tmean_distII\tstd_distII\tmeanPfirstKernel\tstdPfirstKernel"; - } - } -} - -if (sett.indVar) { -// if (sett.sexDep) { -// outtraitsrows << "\tF_meanS0\tF_stdS0\tM_meanS0\tM_stdS0"; -// outtraitsrows << "\tF_meanAlphaS\tF_stdAlphaS\tM_meanAlphaS\tM_stdAlphaS"; -// outtraitsrows << "\tF_meanBetaS\tF_stdBetaS\tM_meanBetaS\tM_stdBetaS"; -// } -// else { - outtraitsrows << "\tmeanS0\tstdS0"; - outtraitsrows << "\tmeanAlphaS\tstdAlphaS"; - outtraitsrows << "\tmeanBetaS\tstdBetaS"; -// } -} -outtraitsrows << endl; - -return outtraitsrows.is_open(); - -} - -#if RS_RCPP && !R_CMD -Rcpp::IntegerMatrix Community::addYearToPopList(int rep, int yr) { // TODO: define new simparams to control start and interval of output - - landParams ppLand = pLandscape->getLandParams(); - Rcpp::IntegerMatrix pop_map_year(ppLand.dimY,ppLand.dimX); - intptr patch = 0; - Patch* pPatch = 0; - intptr subcomm = 0; - SubCommunity *pSubComm = 0; - popStats pop; - //pop.breeding = false; - pop.nInds = pop.nAdults = pop.nNonJuvs = 0; - - for (int y = 0; y < ppLand.dimY; y++) { - for (int x = 0; x < ppLand.dimX; x++) { - Cell *pCell = pLandscape->findCell(x,y); //if (pLandscape->cells[y][x] == 0) { - if (pCell == 0) { // no-data cell - pop_map_year(ppLand.dimY-1-y,x) = NA_INTEGER; - } else { - patch = pCell->getPatch(); - if (patch == 0) { // matrix cell - pop_map_year(ppLand.dimY-1-y,x) = 0; - } - else{ - pPatch = (Patch*)patch; - subcomm = pPatch->getSubComm(); - if (subcomm == 0) { // check if sub-community exists - pop_map_year(ppLand.dimY-1-y,x) = 0; - } else { - pSubComm = (SubCommunity*)subcomm; - pop = pSubComm->getPopStats(); - pop_map_year(ppLand.dimY-1-y,x) = pop.nInds; // use indices like this because matrix gets transposed upon casting it into a raster on R-level - //pop_map_year(ppLand.dimY-1-y,x) = pop.nAdults; - } - } - } - } - } - //list_outPop.push_back(pop_map_year, "rep" + std::to_string(rep) + "_year" + std::to_string(yr)); - return pop_map_year; -} -#endif - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- diff --git a/src/RScore/Community.h b/src/RScore/Community.h deleted file mode 100644 index 36a4a12..0000000 --- a/src/RScore/Community.h +++ /dev/null @@ -1,231 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Community - -Implements the Community class - -There is ONLY ONE instance of a Community in an individual replicate simulation. -It holds a SubCommunity for each Patch in the Landscape (including the matrix), -and is thus the highest-level entity accessed for most processing concerned with -simulated populations. - -Optionally, the Community maintains a record of the occupancy of suitable cells -or patches during the course of simulation of multiple replicates. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 25 June 2021 by Anne-Kathleen Malchow - -------------------------------------------------------------------------------*/ - -#ifndef CommunityH -#define CommunityH - -#include -#include -using namespace std; -#if RS_RCPP -#include "../Version.h" -#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif -#include "SubCommunity.h" -#include "Landscape.h" -#include "Patch.h" -#include "Cell.h" -#include "Species.h" - -//--------------------------------------------------------------------------- -struct commStats { -int ninds,nnonjuvs,suitable,occupied; -int minX,maxX,minY,maxY; -}; - -class Community { - -public: - Community(Landscape*); - ~Community(void); - SubCommunity* addSubComm(Patch*,int); - // functions to manage populations occurring in the community - void initialise( - Species*, // pointer to Species - int // year (relevent only for seedType == 2) - ); - void addManuallySelected(void); - void resetPopns(void); - void localExtinction(int); - void patchChanges(void); - void reproduction( - int // year - ); - void emigration(void); -#if RS_RCPP // included also SEASONAL - void dispersal( - short, // landscape change index - short // season / year - ); -#else - void dispersal( - short // landscape change index - ); -#endif // SEASONAL || RS_RCPP - - void survival( - short, // part: 0 = determine survival & development, - // 1 = apply survival changes to the population - short, // option0: 0 = stage 0 (juveniles) only ) - // 1 = all stages ) used by part 0 only - // 2 = stage 1 and above (all non-juvs) ) - short // option1: 0 - development only (when survival is annual) - // 1 - development and survival - ); - void ageIncrement(void); - int totalInds(void); - Population* findPop( // Find the population of a given species in a given patch - Species*, // pointer to Species - Patch* // pointer to Patch - ); - commStats getStats(void); - void createOccupancy( - int, // no. of rows = (no. of years / interval) + 1 - int // no. of replicates - ); - void updateOccupancy( - int, // row = (no. of years / interval) - int // replicate - ); - void deleteOccupancy( - int // no. of rows (as above) - ); - - bool outRangeHeaders( // Open range file and write header record - Species*, // pointer to Species - int // Landscape number (-999 to close the file) - ); - void outRange( // Write record to range file - Species*, // pointer to Species - int, // replicate - int, // year - int // generation - ); - bool outPopHeaders( // Open population file and write header record - Species*, // pointer to Species - int // option: -999 to close the file - ); - void outPop( // Write records to population file - int, // replicate - int, // year - int // generation - ); - - void outInds( // Write records to individuals file - int, // replicate - int, // year - int, // generation - int // Landscape number (>= 0 to open the file, -999 to close the file - // -1 to write data records) - ); - void outGenetics( // Write records to genetics file - int, // replicate - int, // year - int, // generation - int // Landscape number (>= 0 to open the file, -999 to close the file - // -1 to write data records) - ); - // Open occupancy file, write header record and set up occupancy array - bool outOccupancyHeaders( - int // option: -999 to close the file - ); - void outOccupancy(void); - void outOccSuit( - bool // TRUE if occupancy graph is to be viewed on screen - ); - void viewOccSuit( // Update the occupancy graph on the screen - // NULL for the batch version - int, // year - double, // mean occupancy - double // standard error of occupancy - ); - bool outTraitsHeaders( // Open traits file and write header record - Species*, // pointer to Species - int // Landscape number (-999 to close the file) - ); - bool outTraitsRowsHeaders( // Open trait rows file and write header record - Species*, // pointer to Species - int // Landscape number (-999 to close the file) - ); - void outTraits( // Write records to traits file - traitCanvas,// pointers to canvases for drawing variable traits -// emigCanvas, // pointers to canvases for drawing emigration traits -// trfrCanvas, // pointers to canvases for drawing emigration traits - // see SubCommunity.h - // in the batch version, these are replaced by integers set to zero - Species*, // pointer to Species - int, // replicate - int, // year - int // generation - ); - void writeTraitsRows( // Write records to trait rows file - Species*, // pointer to Species - int, // replicate - int, // year - int, // generation - int, // row number (Y cell co-ordinate) - traitsums // structure holding sums of trait genes for dispersal (see Population.h) - ); - void draw( // Draw the Community on the landscape map and optionally save the map - // NULL for the batch version - int, // replicate - int, // year - int, // generation - int // Landscape number - ); -#if RS_RCPP && !R_CMD - Rcpp::IntegerMatrix addYearToPopList(int,int); -#endif - -private: - Landscape *pLandscape; - int indIx; // index used to apply initial individuals - float **occSuit; // occupancy of suitable cells / patches - std::vector subComms; - -}; - -extern paramSim *paramsSim; -extern paramInit *paramsInit; - - -//--------------------------------------------------------------------------- -#endif diff --git a/src/RScore/FractalGenerator.cpp b/src/RScore/FractalGenerator.cpp deleted file mode 100644 index 7a5ccc3..0000000 --- a/src/RScore/FractalGenerator.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "FractalGenerator.h" -//--------------------------------------------------------------------------- - -vector patches; - -//----- Landscape creation -------------------------------------------------- - -land::land(): x_coord(0), y_coord(0), value(0.0), avail(0) {} - -bool compare(const land& z, const land& zz) //compares only the values of the cells -{ -return z.value < zz.value; -} - -vector& fractal_landscape(int X,int Y,double Hurst,double prop, - double maxValue,double minValue) -{ -#if RSDEBUG -DEBUGLOG << "fractal_landscape(): X=" << X << " Y=" << Y - << " Hurst=" << Hurst << " prop=" << prop - << " maxValue=" << maxValue << " minValue=" << minValue - << endl; -#endif - -int ii, jj, x, y; -int ix, iy; -//int x0, y0, size, kx, kx2, ky, ky2; -int kx,kx2,ky,ky2; - -double range; //range to draw random numbers at each iteration -double nx, ny; -double i, j; -int Nx = X; -int Ny = Y; - -double ran[5]; // to store each time the 5 random numbers for the random displacement - -int Nno; // number of cells NON suitable as habitat - -// exponents used to obtain the landscape dimensions -double pow2x = log(((double)X-1.0))/log(2.0); -double pow2y = log(((double)Y-1.0))/log(2.0); - -double **arena = new double *[X]; -for(ii = 0; ii < X; ii++) { - arena[ii] = new double[Y]; -} - -patches.clear(); -// initialise all the landscape with zeroes -for (jj = 0; jj < X; jj++) { - for (ii = 0; ii < Y; ii++) { - arena[jj][ii]=0; - } -} - -// initialisation of the four corners -arena[0][0] = 1.0 + pRandom->Random() * (maxValue-1.0); -arena[0][Y-1] = 1.0 + pRandom->Random() * (maxValue-1.0); -arena[X-1][0] = 1.0 + pRandom->Random() * (maxValue-1.0); -arena[X-1][Y-1] = 1.0 + pRandom->Random() * (maxValue-1.0); - -/////////////MIDPOINT DISPLACEMENT ALGORITHM////////////////////////////////// -kx = (Nx-1) / 2; -kx2 = 2 * kx; -ky = (Ny-1) / 2; -ky2 = 2 * ky; - -for (ii = 0; ii < 5; ii++) //random displacement -{ - ran[ii] = 1.0 + pRandom->Random() * (maxValue-1.0); -} - -//The diamond step: -arena[kx][ky] = ((arena[0][0] + arena[0][ky2] + arena[kx2][0] + arena[kx2][ky2])/4) + ran[0]; - -//The square step: -//left -arena[0][ky] = ((arena[0][0] +arena[0][ky2] + arena[kx][ky]) / 3) + ran[1]; -//top -arena[kx][0] = ((arena[0][0] + arena[kx][ky] + arena[kx2][0]) / 3) + ran[2]; -//right -arena[kx2][ky] = ((arena[kx2][0] + arena[kx][ky] + arena[kx2][ky2]) / 3) + ran[3]; -//bottom -arena[kx][ky2] = ((arena[0][ky2] + arena[kx][ky] +arena[kx2][ky2]) / 3) + ran[4]; - -range = maxValue*pow(2,-Hurst); - -i = pow2x-1; -j = pow2y-1; - -while (i > 0) { - nx = pow(2,i)+1; - kx = (int)((nx-1) / 2); - kx2 = 2 * kx; - - ny = pow(2,j)+1; - ky = (int)((ny-1) / 2); - ky2 = 2 * ky; - - ix = 0; - while (ix <= (Nx-nx)) { - iy = 0; - while (iy <= (Ny-ny)) { - for (ii = 0; ii < 5; ii++) //random displacement - { - ran[ii] = (int)(pRandom->Random() * 2.0 * range - range); - } - //The diamond step: - - arena[ix+kx][iy+ky] = ((arena[ix][iy] + arena[ix][iy+ky2] + arena[ix+ky2][iy] - + arena[ix+kx2][iy+ky2])/ 4) + ran[0]; - if (arena[ix+kx][iy+ky] < 1) arena[ix+kx][iy+ky] = 1; - - //The square step: - //left - arena[ix][iy+ky] =((arena[ix][iy] +arena[ix][iy+ky2] + arena[ix+kx][iy+ky])/3) - + ran[1]; - if (arena[ix][iy+ky] < 1) arena[ix][iy+ky] = 1; - //top - arena[ix+kx][iy] =((arena[ix][iy] + arena[ix+kx][iy+ky] + arena[ix+kx2][iy])/3) - + ran[2]; - if (arena[ix+kx][iy] < 1) arena[ix+kx][iy] = 1; - //right - arena[ix+kx2][iy+ky] = ((arena[ix+kx2][iy] + arena[ix+kx][iy+ky] + - arena[ix+kx2][iy+ky2]) / 3) + ran[3]; - if (arena[ix+kx2][iy+ky] < 1) arena[ix+kx2][iy+ky] = 1; - //bottom - arena[ix+kx][iy+ky2] = ((arena[ix][iy+ky2] + arena[ix+kx][iy+ky] + - arena[ix+kx2][iy+ky2]) / 3) + ran[4]; - if (arena[ix+kx][iy+ky2] < 1) arena[ix+kx][iy+ky2] = 1; - - iy += ((int)ny-1); - } - ix += ((int)nx-1); - } - if (i==j) j--; - i--; - - range = range*pow(2,-Hurst); //reduce the random number range -} - -// Now all the cells will be sorted and the Nno cells with the lower carrying -// capacity will be set as matrix, i.e. with K = 0 - -land *patch; - -for (x = 0; x < X; x++) // put all the cells with their values in a vector -{ - for (y = 0; y < Y; y++) - { - patch = new land; - patch->x_coord = x; - patch->y_coord = y; - patch->value = (float)arena[x][y]; - patch->avail = 1; - - patches.push_back(*patch); - - delete patch; - } -} - - -sort(patches.begin(),patches.end(),compare); // sorts the vector - -Nno = (int)(prop*X*Y); -for (ii = 0; ii < Nno; ii++) -{ - patches[ii].value = 0.0; - patches[ii].avail = 0; -} - -double min = (double)patches[Nno].value; // variables for the rescaling -double max = (double)patches[X*Y-1].value; - -double diff = max - min; -double diffK = maxValue-minValue; -double new_value; - -vector::iterator iter = patches.begin(); -while (iter != patches.end()) -{ - if (iter->value > 0) // rescale to a range of K between Kmin and Kmax - { - new_value = maxValue - diffK * (max - (double)iter->value) / diff; - - iter->value = (float)new_value; - } - else iter->value = 0; - - iter++; -} - -if (arena != NULL) { -#if RSDEBUG -//DebugGUI(("fractal_landscape(): arena=" + Int2Str((int)arena) -// + " X=" + Int2Str(X) + " Y=" + Int2Str(Y) -// ).c_str()); -#endif - for(ii = 0; ii < X; ii++) { -#if RSDEBUG -//DebugGUI(("fractal_landscape(): ii=" + Int2Str(ii) -// + " arena[ii]=" + Int2Str((int)arena[ii]) -// ).c_str()); -#endif - delete[] arena[ii]; - } - delete[] arena; -} - -return patches; - -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - diff --git a/src/RScore/FractalGenerator.h b/src/RScore/FractalGenerator.h deleted file mode 100644 index 24acbc7..0000000 --- a/src/RScore/FractalGenerator.h +++ /dev/null @@ -1,85 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 FractalGenerator - -Implements the midpoint displacement algorithm for generating a fractal Landscape, -following: - -Saupe, D. (1988). Algorithms for random fractals. In: The Science of Fractal Images -(eds. Pietgen, H.O. & Saupe, D.). Springer, New York, pp. 71–113. - - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 15 July 2021 by Anne-Kathleen Malchow - -------------------------------------------------------------------------------*/ - -#ifndef FractalGeneratorH -#define FractalGeneratorH - -#include -#include -//using namespace std; - -#include "Parameters.h" - -class land -{ - public: - land(); - int x_coord; - int y_coord; - float value; - int avail; // if 0 the patch is not available as habitat, if 1 it is - private: -}; - -// IMPORTANT NOTE: X AND Y ARE TRANSPOSED, i.e. X IS THE VERTICAL CO-ORDINATE -// ========================================================================== - -vector& fractal_landscape( - int, // X dimension (Y of LandScape) - int, // Y dimension (X of LandScape) - double, // Hurst exponent - double, // proportion of NON-suitable habitat - double, // maximum quality value - double // minimum quality value -); -bool compare(const land&, const land&); - -extern RSrandom *pRandom; -#if RSDEBUG -extern void DebugGUI(string); -#endif - -//--------------------------------------------------------------------------- -#endif diff --git a/src/RScore/Genome.cpp b/src/RScore/Genome.cpp deleted file mode 100644 index 90d030b..0000000 --- a/src/RScore/Genome.cpp +++ /dev/null @@ -1,861 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Genome.h" -//--------------------------------------------------------------------------- - -ofstream outGenetic; - -//--------------------------------------------------------------------------- - -#ifdef RSDEBUG -//std::ofstream chromdebug("chromdebug.txt"); -//std::ofstream chromdebug1("chromdebug1.txt"); -#endif - -//--------------------------------------------------------------------------- - -Chromosome::Chromosome(int nloc) -{ -#if RSDEBUG -//DEBUGLOG << "Chromosome::Chromosome(): this=" << this -// << " nloc=" << nloc -//// << " maternalLoci.size()=" << maternalLoci.size() -//// << " paternalLoci.size()=" << paternalLoci.size() -// << endl; -//DebugGUI("Chromosome::Chromosome(): this=" + Int2Str((int)this) -// + " nloc=" + Int2Str(nloc) -//// + " maternalLoci.size()=" + Int2Str((int)maternalLoci.size()) -//// + " paternalLoci.size()=" + Int2Str((int)paternalLoci.size()) -// ); -#endif -if (nloc > 0) nloci = nloc; else nloci = 1; -pLoci = new locus[nloci]; -for (int i = 0; i < nloci; i++) { - pLoci[i].allele[0] = pLoci[i].allele[1] = 0; -} -} - -Chromosome::~Chromosome() { -#if RSDEBUG -//DEBUGLOG << "Chromosome::~Chromosome(): this=" << this << endl; -#endif -#if RSDEBUG -//DEBUGLOG << "Chromosome::Chromosome(): deleting this=" << this << endl; -//DebugGUI("Chromosome::Chromosome(): deleting this=" + Int2Str((int)this)); -#endif -if (pLoci != 0) { -// for (int i = 0; i < nloci; i++) { -// delete pLoci[i]; pLoci[i] = NULL; -// } - delete[] pLoci; pLoci = NULL; -} -} - -short Chromosome::nLoci(void) { return nloci; } - -locus Chromosome::alleles(const int loc) { // return allele values at a specified locus -locus l; l.allele[0] = l.allele[1] = 0; -if (loc >= 0 && loc < nloci) { - l.allele[0] = pLoci[loc].allele[0]; l.allele[1] = pLoci[loc].allele[1]; -} -return l; -} - -double Chromosome::additive(const bool diploid) { -int sum = 0; -for (int i = 0; i < nloci; i++) { - sum += pLoci[i].allele[0]; - if (diploid) sum += pLoci[i].allele[1]; -} -#if RSDEBUG -//DEBUGLOG << "Chromosome::additive(): this=" << this -// << " sum=" << sum -// << endl; -#endif -return (double)sum / INTBASE; -} - -double Chromosome::meanvalue(const bool diploid) { -int sum = 0; -double mean; -for (int i = 0; i < nloci; i++) { - sum += pLoci[i].allele[0]; - if (diploid) sum += pLoci[i].allele[1]; -} -mean = (double)sum / (double)nloci; -if (diploid) mean /= 2.0; -mean /= INTBASE; -#if RSDEBUG -//DEBUGLOG << "Chromosome::meanvalue(): this=" << this -// << " sum=" << sum -// << " mean=" << mean -// << endl; -#endif -return mean; -} - -double Chromosome::additive(const short loc,const bool diploid) { -int sum = 0; -sum += pLoci[loc].allele[0]; -if (diploid) sum += pLoci[loc].allele[1]; -#if RSDEBUG -//DEBUGLOG << "Chromosome::additive(): this=" << this -// << " sum=" << sum -// << endl; -#endif -return (double)sum / INTBASE; -} - -/* -double Chromosome::probval(const bool diploid) { -double genval,phenval; -int sum = 0; -for (int i = 0; i < nloci; i++) { - sum += pLoci[i].allele[0]; - if (diploid) sum += pLoci[i].allele[1]; -} -genval = (double)sum / INTBASE; -phenval = 1.0 / (1.0 + exp(-genval)); -#if RSDEBUG -//DEBUGLOG << "Chromosome::probval(): this=" << this -// << " sum=" << sum -// << " genval=" << genval -// << " phenval=" << phenval -// << endl; -#endif -return phenval; -} -*/ - -// Set up chromosome at simulation initialisation -//void Chromosome::initialise(const float mean,const float sd, -// const bool diploid) { -void Chromosome::initialise(const double mean, const double sd, - const bool diploid) { -double avalue; -double intbase = INTBASE; -//// adjust mean and s.d. allowing for number of alleles determining phenotype -//double adjmean,adjsd,factor; -//if (diploid) factor = (double)(nloci * 2); else factor = (double)(nloci); -//adjmean = mean / factor; -//adjsd = sqrt(sd * sd / factor); -for (int i = 0; i < nloci; i++) { -// avalue = pRandom->Normal(adjmean,adjsd); - avalue = pRandom->Normal(mean,sd); - if (avalue > 0.0) - pLoci[i].allele[0] = (int)(avalue * intbase + 0.5); - else - pLoci[i].allele[0] = (int)(avalue * intbase - 0.5); -#if RSDEBUG -//DEBUGLOG << "Chromosome::initialise(): this=" << this -// << " mean=" << mean << " sd=" << sd -// << " i=" << i << " avalue=" << avalue -// << " allele[0]=" << pLoci[i].allele[0]; -//DEBUGLOG << endl; -#endif - if (diploid) { -// avalue = pRandom->Normal(adjmean,adjsd); - avalue = pRandom->Normal(mean,sd); - if (avalue > 0.0) - pLoci[i].allele[1] = (int)(avalue * intbase + 0.5); - else - pLoci[i].allele[1] = (int)(avalue * intbase - 0.5); -#if RSDEBUG -//DEBUGLOG << "Chromosome::initialise(): this=" << this -// << " mean=" << mean << " sd=" << sd -// << " i=" << i << " avalue=" << avalue -// << " allele[1]=" << pLoci[i].allele[1]; -//DEBUGLOG << endl; -#endif - } -} - -} - -// Set up specified locus at simulation initialisation -void Chromosome::initialise(const short locus,const short posn,const int aval) -{ -// note that initialising value is ADDED to current value to allow for pleiotropy -pLoci[locus].allele[posn] += aval; -} - -// Inherit from specified parent -void Chromosome::inherit(const Chromosome *parentChr,const short posn,const short nloc, - const double probmutn,const double probcross,const double mutnSD,const bool diploid) -{ - -// NOTE: At present for diploid genome, presence of crossover is determined at each -// locus (except first). However, Roslyn has shown that it is more efficient to sample -// crossover locations from geometric distribution if number of loci is large. -// HOW LARGE IS 'LARGE' IN THIS CASE?... - -//// adjust mutation variance for number of loci -//double mutnsd; -//if (diploid) -// mutnsd = sqrt(mutnSD * mutnSD / (double)(2*nloc)); -//else -// mutnsd = sqrt(mutnSD * mutnSD / (double)nloc); -int ix = 0; // indexes maternal and paternal strands -if (diploid) ix = pRandom->Bernoulli(0.5); // start index at random -for (int i = 0; i < nloc; i++) { - if (diploid) { - pLoci[i].allele[posn] = parentChr->pLoci[i].allele[ix]; - if (pRandom->Bernoulli(probcross)) { // crossover occurs - if (ix == 0) ix = 1; else ix = 0; - } - } - else - pLoci[i].allele[posn] = parentChr->pLoci[i].allele[0]; -#if RSDEBUG -//DEBUGLOG << "Chromosome::inherit(): this=" << this -// << " posn=" << posn << " nloc=" << nloc << " pmutn=" << pmutn -// << " i=" << i << " allele=" << pLoci[i].allele[posn] -// << endl; -#endif - if (pRandom->Bernoulli(probmutn)) { // mutation occurs - double intbase = INTBASE; -#if RSDEBUG - int oldval = pLoci[i].allele[posn]; -#endif -// double mutnvalue = pRandom->Normal(0,mutnsd); - double mutnvalue = pRandom->Normal(0,mutnSD); - if (mutnvalue > 0.0) - pLoci[i].allele[posn] += (int)(intbase * mutnvalue + 0.5); - else - pLoci[i].allele[posn] += (int)(intbase * mutnvalue - 0.5); -#if RSDEBUG -//DEBUGLOG << "Chromosome::inherit(): this=" << this -// << " probmutn=" << probmutn << " nloc=" << nloc -//// << " mutnsd=" << mutnsd -// << " mutnSD=" << mutnSD -// << " posn=" << posn << " locus=" << i << " MUTATED " -// << " old=" << oldval << " new=" << pLoci[i].allele[posn] -// << endl; -#endif -#if RSDEBUG -//MUTNLOG << 1 << endl; -MUTNLOG << mutnvalue << " " << oldval << " " << pLoci[i].allele[posn] << " " << endl; -#endif - } -#if RSDEBUG -// else { -//MUTNLOG << 0 << endl; -// } -#endif -} -} - - -//--------------------------------------------------------------------------- - -// NB THIS FUNCTION IS CURRENTLY NOT BEING CALLED TO CONSTRUCT AN INSTANCE OF Genome -// Genome(int) IS USED INSTEAD - -Genome::Genome(){ -pChromosome = NULL; -nChromosomes = 0; -} - -// Set up new genome at initialisation for 1 chromosome per trait -Genome::Genome(int nchromosomes,int nloci,bool d) { -#if RSDEBUG -//DEBUGLOG << "Genome::Genome(): this=" << this -// << " nchromosomes=" << nchromosomes << " nLoci=" << nLoci -// << endl; -#endif - -diploid = d; -if (nchromosomes > 0) nChromosomes = nchromosomes; else nChromosomes = 1; -pChromosome = new Chromosome *[nChromosomes]; -for (int i = 0; i < nChromosomes; i++) { - pChromosome[i] = new Chromosome(nloci); -// pChromosome[i]->initialise(alleleMean,alleleSD); -} - -} - -// Set up new genome at initialisation for trait mapping -Genome::Genome(Species *pSpecies) { -int nloci; -nChromosomes = pSpecies->getNChromosomes(); -diploid = pSpecies->isDiploid(); -#if RSDEBUG -//DEBUGLOG << "Genome::Genome(): this=" << this -// << " nChromosomes=" << nChromosomes -// << endl; -#endif -pChromosome = new Chromosome *[nChromosomes]; -for (int i = 0; i < nChromosomes; i++) { - nloci = pSpecies->getNLoci(i); -#if RSDEBUG -//DEBUGLOG << "Genome::Genome(): this=" << this -// << " i=" << i << " nloci=" << nloci << endl; -#endif - pChromosome[i] = new Chromosome(nloci); -} -} - -// Inherit genome from parent(s) -Genome::Genome(Species *pSpecies,Genome *mother,Genome *father) -{ -genomeData gen = pSpecies->getGenomeData(); - -nChromosomes = mother->nChromosomes; -diploid = mother->diploid; -pChromosome = new Chromosome *[nChromosomes]; - -for (int i = 0; i < nChromosomes; i++) { - pChromosome[i] = new Chromosome(mother->pChromosome[i]->nLoci()); - inherit(mother,0,i,gen.probMutn,gen.probCrossover,gen.mutationSD); - if (diploid) { - if (father == 0) { // species is hermaphrodite - inherit again from mother - inherit(mother,1,i,gen.probMutn,gen.probCrossover,gen.mutationSD); - } - else inherit(father,1,i,gen.probMutn,gen.probCrossover,gen.mutationSD); - } -} - -} - -Genome::~Genome(){ - -if (pChromosome == NULL) return; - -for (int i = 0; i < nChromosomes; i++) { - delete pChromosome[i]; -} -delete[] pChromosome; - -} - -/* -Genome::~Genome(void) -{ -if (genome != 0) { - delete genome; genome = NULL; -} -} -*/ - -//--------------------------------------------------------------------------- - -void Genome::setDiploid(bool dip) { diploid = dip; } -bool Genome::isDiploid(void) { return diploid; } -short Genome::getNChromosomes(void) { return nChromosomes; } - -//--------------------------------------------------------------------------- - -// Inherit from specified parent -void Genome::inherit(const Genome *parent,const short posn,const short chr, - const double probmutn,const double probcross,const double mutnSD) -{ -// adjust mutation variance for number of loci -//double mutnSD = sqrt(mutationSD * mutationSD / (double)nLoci); -//for (int i = 0; i < nChromosomes; i++) { -// pChromosome[i]->inherit(parent->pChromosome[i],pChromosome[i]->nLoci()); -//} -pChromosome[chr]->inherit(parent->pChromosome[chr],posn,parent->pChromosome[chr]->nLoci(), - probmutn,probcross,mutnSD,diploid); - -} - -void Genome::outGenHeaders(const int rep,const int landNr,const bool xtab) -{ - -if (landNr == -999) { // close file - if (outGenetic.is_open()) { - outGenetic.close(); outGenetic.clear(); - } - return; -} - -string name; -simParams sim = paramsSim->getSim(); - -if (sim.batchMode) { - name = paramsSim->getDir(2) - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) - + "_Land" + Int2Str(landNr) + "_Rep" + Int2Str(rep) + "_Genetics.txt"; -} -else { - name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) - + "_Rep" + Int2Str(rep) +"_Genetics.txt"; -} -outGenetic.open(name.c_str()); - -outGenetic << "Rep\tYear\tSpecies\tIndID"; -if (xtab) { - for (int i = 0; i < nChromosomes; i++) { - int nloci = pChromosome[i]->nLoci(); - for (int j = 0; j < nloci; j++) { - outGenetic << "\tChr" << i << "Loc" << j << "Allele0"; - if (diploid) outGenetic << "\tChr" << i << "Loc" << j << "Allele1"; - } - } - outGenetic << endl; -} -else { - outGenetic << "\tChromosome\tLocus\tAllele0"; - if (diploid) outGenetic << "\tAllele1"; - outGenetic << endl; -} - -} - -void Genome::outGenetics(const int rep,const int year,const int spnum, - const int indID,const bool xtab) - { -locus l; -if (xtab) { - outGenetic << rep << "\t" << year << "\t" << spnum << "\t" << indID; - for (int i = 0; i < nChromosomes; i++) { - int nloci = pChromosome[i]->nLoci(); - for (int j = 0; j < nloci; j++) { - l = pChromosome[i]->alleles(j); - outGenetic << "\t" << l.allele[0]; - if (diploid) outGenetic << "\t" << l.allele[1]; - } - } - outGenetic << endl; -} -else { - for (int i = 0; i < nChromosomes; i++) { - int nloci = pChromosome[i]->nLoci(); - for (int j = 0; j < nloci; j++) { - outGenetic << rep << "\t" << year << "\t" << spnum << "\t" - << indID << "\t" << i << "\t" << j; - l = pChromosome[i]->alleles(j); - outGenetic << "\t" << l.allele[0]; - if (diploid) outGenetic << "\t" << l.allele[1]; - outGenetic << endl; - } - } -} -} - -//--------------------------------------------------------------------------- - -// Set up new gene at initialisation for 1 chromosome per trait -//void Genome::setGene(const short chr,const short exp, -// const float traitval,const float alleleSD) -void Genome::setGene(const short chr, const short exp, - const double traitval, const double alleleSD) -// NB PARAMETER exp FOR EXPRESSION TYPE IS NOT CURRENTLY USED... -{ -#if RSDEBUG -//DEBUGLOG << "Genome::setGene(): this=" << this -// << " chr=" << chr -// << " exp=" << exp << " traitval=" << traitval -// << " alleleSD=" << alleleSD -// << endl; -#endif -if (chr >= 0 && chr < nChromosomes) { - pChromosome[chr]->initialise(traitval,alleleSD,diploid); -} -} - -// Set up trait at initialisation for trait mapping -//void Genome::setTrait(Species *pSpecies,const int trait, -// const float traitval,const float alleleSD) -void Genome::setTrait(Species* pSpecies, const int trait, - const double traitval, const double alleleSD) -{ -traitAllele allele; -int nalleles = pSpecies->getNTraitAlleles(trait); -int ntraitmaps = pSpecies->getNTraitMaps(); -#if RSDEBUG -//DEBUGLOG << "Genome::setTrait(): this=" << this << " ntraitmaps=" << ntraitmaps -// << " trait=" << trait << " traitval=" << traitval << " alleleSD=" << alleleSD -// << " nalleles=" << nalleles -// << endl; -#endif - -int avalue; -double intbase = INTBASE; -if (trait < ntraitmaps) { -// // adjust mean and s.d. allowing for number of alleles determining phenotype -// double adjmean,adjsd,factor; -// if (diploid) factor = (double)(nalleles * 2); else factor = (double)(nalleles); -// adjmean = traitval / factor; -// adjsd = sqrt(alleleSD * alleleSD / factor); - - for (int i = 0; i < nalleles; i++) { - allele = pSpecies->getTraitAllele(trait,i); -// avalue = (int)(pRandom->Normal(adjmean,adjsd) * intbase); - avalue = (int)(pRandom->Normal(traitval,alleleSD) * intbase); -#if RSDEBUG -//DEBUGLOG << "Genome::setTrait(): this=" << this -// << " i=" << i << " chromo=" << allele.chromo << " locus=" << allele.locus -// << " posn=" << 0 << " avalue=" << avalue -// << endl; -#endif - pChromosome[allele.chromo]->initialise(allele.locus,0,avalue); - if (diploid) { -// avalue = (int)(pRandom->Normal(adjmean,adjsd) * intbase); - avalue = (int)(pRandom->Normal(traitval,alleleSD) * intbase); - pChromosome[allele.chromo]->initialise(allele.locus,1,avalue); - } - } -} -else { // insufficient traits were defined - // alleles cannot be initialised - all individuals have mean phenotype -#if RSDEBUG -//DEBUGLOG << "Genome::setTrait(): this=" << this -// << " *** unable to initialise undefined trait ***" << endl; -#endif -} - -} - -// Set up trait at initialisation for trait mapping -void Genome::setNeutralLoci(Species *pSpecies,const double alleleSD) -{ -traitAllele allele; -int nneutral = pSpecies->getNNeutralLoci(); -#if RSDEBUG -//DEBUGLOG << "Genome::setNeutralLoci(): this=" << this -// << " nneutral=" << nneutral << " alleleSD=" << alleleSD -// << endl; -#endif - -//int avalue; -double avalue; -double intbase = INTBASE; -//// adjust allele s.d. for diploid genotype -//double adjsd,factor; -//if (diploid) factor = 2.0; else factor = 1.0; -//adjsd = sqrt(alleleSD * alleleSD / factor); - -for (int i = 0; i < nneutral; i++) { - allele = pSpecies->getNeutralAllele(i); -// avalue = (int)(pRandom->Normal(0.0,adjsd) * intbase); -// pChromosome[allele.chromo]->initialise(allele.locus,0,avalue); - avalue = pRandom->Normal(0.0,alleleSD); - if (avalue > 0.0) - pChromosome[allele.chromo]->initialise(allele.locus,0,(int)(avalue * intbase + 0.5)); - else - pChromosome[allele.chromo]->initialise(allele.locus,0,(int)(avalue * intbase - 0.5)); -#if RSDEBUG -//DEBUGLOG << "Genome::setNeutralLoci(): this=" << this -// << " i=" << i << " chromo=" << allele.chromo << " locus=" << allele.locus -// << " avalue=" << avalue -// << endl; -#endif - if (diploid) { -// avalue = (int)(pRandom->Normal(0.0,adjsd) * intbase); -// pChromosome[allele.chromo]->initialise(allele.locus,1,avalue); - avalue = pRandom->Normal(0.0,alleleSD); - if (avalue > 0.0) - pChromosome[allele.chromo]->initialise(allele.locus,1,(int)(avalue * intbase + 0.5)); - else - pChromosome[allele.chromo]->initialise(allele.locus,1,(int)(avalue * intbase - 0.5)); - } -} -} - -// Return a single allele, having applied mutation -// Either allele is returned with equal probability, unless the gene is sex-linked, -// in which case a male returns the allele inherited from his father and a female -// returns the allele inherited from her mother -/* -double Genome::copy(int i,int sexx) -{ -double genevalue = 0.0; -return genevalue; -} -*/ - -// Return the expressed value of a gene when species has one chromosome per trait -double Genome::express(short chr,short expr,short indsex) -{ -double genevalue = 0.0; -//if (expr == 1) { -// genevalue = pChromosome[chr]->probval(diploid); -//} -//else -//genevalue = pChromosome[chr]->additive(diploid); -genevalue = pChromosome[chr]->meanvalue(diploid); -#if RSDEBUG -//DEBUGLOG << "Genome::express(): this=" << this -// << " chr=" << chr -// << " genevalue=" << genevalue -// << endl; -#endif -return genevalue; -} -/* -// Return the expressed value of an allele -double Genome::express(short chr,short loc) -{ -double genevalue = 0.0; -//if (expr == 1) { -// genevalue = pChromosome[chr]->probval(diploid); -//} -//else -genevalue = pChromosome[chr]->additive(loc,diploid); -#if RSDEBUG -//DEBUGLOG << "Genome::express(): this=" << this -// << " expr=" << expr -// << " genevalue=" << genevalue -// << endl; -#endif -return genevalue; -} -*/ - -// Return the expressed value of a trait when genetic architecture is defined -double Genome::express(Species *pSpecies,short traitnum) -{ -double genevalue = 0.0; - -traitAllele allele; -int nalleles = pSpecies->getNTraitAlleles(traitnum); -if (nalleles > 0) { - for (int i = 0; i < nalleles; i++) { - allele = pSpecies->getTraitAllele(traitnum,i); - genevalue += pChromosome[allele.chromo]->additive(allele.locus,diploid); - } - genevalue /= (double)nalleles; - if (diploid) genevalue /= 2.0; -} - -// genevalue = pChromosome[chr]->additive(diploid); -#if RSDEBUG -//DEBUGLOG << "Genome::express(): this=" << this -// << " traitnum=" << traitnum << " nalleles=" << nalleles -// << " genevalue=" << genevalue -// << endl; -#endif -return genevalue; -} - - -locusOK Genome::getAlleles(short chr,short loc) { -locusOK l; -l.allele[0] = l.allele[1] = 0; l.ok = false; -//double intbase = INTBASE; -if (chr >= 0 && chr < nChromosomes) { - if (pChromosome[chr] != 0) { - if (loc >= 0 && loc < pChromosome[chr]->nLoci()) { - locus a = pChromosome[chr]->alleles(loc); - l.allele[0] = a.allele[0]; l.allele[1] = a.allele[1]; l.ok = true; - } - } -} -// l.allele[0] = (int)(intbase * pChromosome[0]->additive(diploid)); - -return l; -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - -// OLD CODE WHICH MIGHT BE USEFUL FOR IMPLEMENTING ALTERNATIVE FORMS OF EXPRESSION - -/* - -// Set up new genome at initialisation -Genome::Genome(int g) { -if (g < 1) return; - -genomesize = g; -genome = new gene *[genomesize]; -for (int i = 0; i < genomesize; i++) { - genome[i] = new gene; - genome[i]->expression = 0; genome[i]->mutntype = 0; - genome[i]->Pmutn = 0.0; genome[i]->mutnSize = 0.0; - genome[i]->allele[0] = genome[i]->allele[1] = 0.0; -} - -} - -// Inherit genome from parent(s) -Genome::Genome(Genome *mother,Genome *father) -{ -#if RSDEBUG -//locn currloc = currCell->getLocn(); -//DEBUGLOG << "Genome::setGenes(): indId=" << indId -// << " x=" << currloc.x << " y=" << currloc.y -// << " pSpecies=" << pSpecies -// << " mother=" << mother -// << " father=" << father -// << endl; -#endif - -genomesize = mother->genomesize; -genome = new gene *[genomesize]; -for (int i = 0; i < genomesize; i++) { - genome[i] = new gene; - genome[i]->expression = mother->genome[i]->expression; - genome[i]->mutntype = mother->genome[i]->mutntype; - genome[i]->Pmutn = mother->genome[i]->Pmutn; - genome[i]->mutnSize = mother->genome[i]->mutnSize; - genome[i]->allele[0] = mother->copy(i,0); - if (father == 0) genome[i]->allele[1] = 0.0; - else genome[i]->allele[1] = father->copy(i,1); -} - -} - -Genome::~Genome(void) -{ -if (genome != 0) { - for (int i = 0; i < genomesize; i++) { - delete genome[i]; genome[i] = NULL; - } - delete genome; genome = NULL; -} - -} - -// Set up new gene -void Genome::setGene(int i,short exp,short mtype,float pmut,float msize,double a0,double a1) -{ -if (exp >= 0 && exp <= 4) genome[i]->expression = exp; -if (mtype >= 0 && mtype <= 5) genome[i]->mutntype = mtype; -if (pmut >= 0.0 && pmut <= 1.0) genome[i]->Pmutn = pmut; -if (msize > 0.0) genome[i]->mutnSize = msize; -genome[i]->allele[0] = a0; -genome[i]->allele[1] = a1; -} - -// Return a single allele, having applied mutation -// Either allele is returned with equal probability, unless the gene is sex-linked, -// in which case a male returns the allele inherited from his father and a female -// returns the allele inherited from her mother -double Genome::copy(int i,int sexx) -{ -double genevalue,logP,logitP; - -switch (genome[i]->expression) { -case 0: // haploid - genevalue = genome[i]->allele[0]; - break; -case 1: // sex-linked gene - if (sexx == 0 || sexx == 1) genevalue = genome[i]->allele[sexx]; - else return -999999.999; // indicates error in sex of parent animal - break; -default: // otherwise - select one of the alleles at random - genevalue = genome[i]->allele[pRandom->Bernoulli(0.5)]; - ; -} -#if RSDEBUG -//DEBUGLOG << "Gene::copy(): expression=" << expression -// << " mutntype=" << mutntype -// << " Pmutn=" << Pmutn << " mutnSize=" << mutnSize -// << " allele[0]=" << allele[0] << " allele[1]=" << allele[1] -// << " genevalue=" << genevalue -// << endl; -#endif -// apply mutation to the gene -if (pRandom->Random() < genome[i]->Pmutn) { - switch (genome[i]->mutntype) { - case 0: genevalue = pRandom->Random(); break; - case 1: genevalue += pRandom->Normal(0.0,genome[i]->mutnSize); break; - case 2: - logitP = log(genevalue/(1.0-genevalue)); - logitP += pRandom->Normal(0.0,genome[i]->mutnSize); - genevalue = 1.0 / (1 + exp(-logitP)); - if (genevalue >= 1.0) genevalue = 0.999999999; - if (genevalue <= 0.0) genevalue = 0.000000001; - break; - case 3: - logP = log(genevalue); - logP += pRandom->Normal(0.0,genome[i]->mutnSize); - genevalue = exp(logP); - break; - case 4: - genevalue += pRandom->Random()*(2.0*genome[i]->mutnSize) - genome[i]->mutnSize; - break; - case 5: - genevalue += pRandom->Random()*(2.0*genome[i]->mutnSize) - genome[i]->mutnSize; - if (genevalue > 1.0) genevalue = 1.0; - if (genevalue < 0.0) genevalue = 0.0; - break; - default: genevalue = -888888.888; // error in mutation type - } -} -#if RSDEBUG -//DEBUGLOG << "Gene::copy():" -// << " allele[0]=" << allele[0] << " allele[1]=" << allele[1] -// << " genevalue=" << genevalue -// << endl; -#endif -return genevalue; -} - -// Return the expressed value of a gene -double Genome::express(int i,int sexx) -{ -double genevalue; - -switch (genome[i]->expression) { - case 0: // sex-linked gene - genevalue = genome[i]->allele[0]; - break; - case 1: // sex-linked gene - if (sexx == 0 || sexx == 1) genevalue = genome[i]->allele[sexx]; - else genevalue = -999999.999; // indicates error in sex of parent animal - break; - case 2: // dominance of greater value - genevalue = genome[i]->allele[0]; - if (genome[i]->allele[1] > genevalue) genevalue = genome[i]->allele[1]; - break; - case 3: // co-dominance (mean value) - genevalue = (genome[i]->allele[0] + genome[i]->allele[1]) / 2.0; - break; - case 4: // sex-expressed co-dominance -// NB does not differ from co-dominance other than when genes interact to determine -// phenotypic level of expression - genevalue = (genome[i]->allele[0] + genome[i]->allele[1]) / 2.0; -// if (sexx == 0 || sexx == 1) genevalue = genome[i]->allele[sexx]; -// else genevalue = -999999.999; // indicates error in sex of parent animal - break; -default: genevalue = -777777.777; // error in expression type -} - -return genevalue; - -} - -locus Genome::getAlleles(int g) { -locus l; -if (g >= 0 && g < genomesize) { - l.allele[0] = genome[g]->allele[0]; - l.allele[1] = genome[g]->allele[1]; -} -else { - l.allele[0] = l.allele[1] = 0.0; -} -return l; -} - -*/ - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - diff --git a/src/RScore/Genome.h b/src/RScore/Genome.h deleted file mode 100644 index d42c161..0000000 --- a/src/RScore/Genome.h +++ /dev/null @@ -1,251 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Genome - -Implements the Genome class - -Author: Steve Palmer & Roslyn Henry, University of Aberdeen - -Last updated: 28 July 2021 by Greta Bocedi - -------------------------------------------------------------------------------*/ - -#ifndef GenomeH -#define GenomeH - -#include -#include -//#include "maths.h" - -#include "Parameters.h" -#include "Species.h" - -#define INTBASE 100.0; // to convert integer alleles into continuous traits - -struct locus { short allele[2]; }; -struct locusOK { short allele[2]; bool ok; }; - -//--------------------------------------------------------------------------- - -class Chromosome { - -public: - Chromosome(int); - ~Chromosome(); - short nLoci(void); - double additive( // Return trait value on normalised genetic scale - const bool // diploid - ); - double meanvalue( // Return trait value on normalised genetic scale - const bool // diploid - ); - double additive( // Return trait value on normalised genetic scale - const short, // locus - const bool // diploid - ); -// double probval(const bool); - locus alleles( // Return allele values at a specified locus - const int // position of locus on chromosome - ); - void initialise( // Set up chromosome at simulation initialisation - const double, // normalised phenotypic trait value - const double, // s.d. of allelic variance (genetic scale) - const bool // diploid - ); - void initialise( // Set up specified locus at simulation initialisation - const short, // locus - const short, // position: 0 from mother, 1 from father - const int // allele value - ); - void inherit( // Inherit chromosome from specified parent - const Chromosome*, // pointer to parent's chromosome - const short, // position: 0 from mother, 1 from father - const short, // no. of loci - const double, // mutation probability - const double, // crossover probability - const double, // s.d. of mutation magnitude (genetic scale) - const bool // diploid - ); - -protected: - -private: - short nloci; - locus *pLoci; - -}; - -//--------------------------------------------------------------------------- - -class Genome{ - -public: -// -// static float delPMutation, delEffectSize, delDominance, delBackMutation ,genomeMeanRecombination; -// static int delMaxSize, delNMutations; -// static bool genomeCanRecombine, genomeCompletelyUnlinked; -// - - Genome(); - Genome(int,int,bool); - Genome(Species*); - Genome(Species*,Genome*,Genome*); - ~Genome(); - void setGene( // Set up new gene at initialisation for 1 chromosome per trait - const short, // chromosome number - const short, // expression type (NOT CURRENTLY USED) - const double, // normalised trait value - const double // s.d. of allelic variance - ); - void setTrait( // Set up trait at initialisation for trait mapping - Species*, // pointer to Species - const int, // trait number - const double, // normalised trait value - const double // s.d. of allelic variance - ); - void setNeutralLoci( // Set up neutral loci at initialisation - Species*, // pointer to Species - const double // s.d. of allelic variance - ); -// double copy(int,int); - double express( - // Return the expressed value of a gene when species has one chromosome per trait - short, // chromosome number - short, // expression type (NOT CURRENTLY USED) - short // individual's sex (NOT CURRENTLY USED) - ); -// double express( -// short, // chromosome number -// short // locus on chromosome -// ); - double express( - // Return the expressed value of a trait when genetic architecture is defined - Species*, // pointer to Species - short // trait number -// bool // true if trait is sex-dependent - ); - locusOK getAlleles( // Get allele values at a specified locus - short, // chromosome number - short // locus position on chromosome - ); - // SCFP NEW DECLARATIONS - void setDiploid(bool); - bool isDiploid(void); - void inherit( // Inherit from specified parent - const Genome*, // pointer to parent's genome - const short, // position: 0 from mother, 1 from father - const short, // chromasome number - const double, // mutation probability - const double, // crossover probability - const double // s.d. of mutation magnitude (genetic scale) - ); -// void setStaticData(genomeData); -// genomeData getStaticData(void); - short getNChromosomes(void); - void outGenHeaders( - const int, // replicate - const int, // landscape number - const bool // output as cross table? - ); - void outGenetics( - const int, // replicate - const int, // year - const int, // species number - const int, // individual ID - const bool // output as cross table? - ); - - -private: - short nChromosomes; // no. of chromosomes - bool diploid; - Chromosome **pChromosome; - -}; - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - -/* - -struct gene { - short expression; // used to control how gene is expressed: - // 0 = haploid - // 1 = sex-linked - // 2 = dominance of greater value - // 3 = co-dominance (mean value) - // 4 = sex-expressed (but not sex-linked) - short mutntype; // mutation type: - // 0 = random in [0,1] - // 1 = normal - // 2 = logit scale - // 3 = log-normal (gene must be positive) - // 4 = RS method - random in specified range - // 5 = RS method - random in specified range and constrained to [0,1] - float Pmutn; // mutation probability - float mutnSize; // mutation size (s.d. of normal distribution) - double allele[2]; // allele pair: [0] from mother, [1] from father -}; -; - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - -class Genome -{ -public: - Genome(int); - Genome(Genome*,Genome*); - ~Genome(void); - void setGene(int); - void setGene(int,short,short,float,float,double,double); // new gene - double copy(int,int); - double express(int,int); - locus getAlleles( // Get allele values at a specified locus - int // locus position within genome - ); - -private: - int genomesize; - gene **genome; - -}; - -*/ - -//--------------------------------------------------------------------------- - -extern paramSim *paramsSim; -extern RSrandom *pRandom; - -#if RSDEBUG -extern ofstream DEBUGLOG; -extern ofstream MUTNLOG; -extern void DebugGUI(string); -#endif - -//--------------------------------------------------------------------------- - -#endif diff --git a/src/RScore/Individual.cpp b/src/RScore/Individual.cpp deleted file mode 100644 index cc7bf6e..0000000 --- a/src/RScore/Individual.cpp +++ /dev/null @@ -1,1858 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - - //--------------------------------------------------------------------------- - -#include "Individual.h" -//--------------------------------------------------------------------------- - -int Individual::indCounter = 0; - -//--------------------------------------------------------------------------- - -// Individual constructor -Individual::Individual(Cell* pCell, Patch* pPatch, short stg, short a, short repInt, - float probmale, bool movt, short moveType) -{ - indId = indCounter; - indCounter++; // unique identifier for each individual - - stage = stg; - if (probmale <= 0.0) sex = 0; - else sex = pRandom->Bernoulli(probmale); - age = a; - status = 0; - - if (sex == 0 && repInt > 0) { // set no. of fallow seasons for female - fallow = pRandom->IRandom(0, repInt); - } - else fallow = 9999; - isDeveloping = false; - pPrevCell = pCurrCell = pCell; - pNatalPatch = pPatch; - if (movt) { - locn loc = pCell->getLocn(); - path = new pathData; - path->year = 0; path->total = 0; path->out = 0; - path->pSettPatch = 0; path->settleStatus = 0; -#if RS_RCPP - path->pathoutput = 1; -#endif - if (moveType == 1) { // SMS - // set up location data for SMS - smsData = new smsdata; - smsData->dp = smsData->gb = smsData->alphaDB = 1.0; - smsData->betaDB = 1; - smsData->prev.x = loc.x; smsData->prev.y = loc.y; // previous location - smsData->goal.x = loc.x; smsData->goal.y = loc.y; // goal location - initialised for dispersal bias - } - else smsData = 0; - if (moveType == 2) { // CRW - // set up continuous co-ordinates etc. for CRW movement - crw = new crwParams; - crw->xc = ((float)pRandom->Random() * 0.999f) + (float)loc.x; - crw->yc = (float)(pRandom->Random() * 0.999f) + (float)loc.y; - crw->prevdrn = (float)(pRandom->Random() * 2.0 * PI); - crw->stepL = crw->rho = 0.0; - } - else crw = 0; - } - else { - path = 0; crw = 0; smsData = 0; - } - emigtraits = 0; - kerntraits = 0; - setttraits = 0; - pGenome = 0; -} - -Individual::~Individual(void) { - if (path != 0) delete path; - if (crw != 0) delete crw; - if (smsData != 0) delete smsData; - if (emigtraits != 0) delete emigtraits; - if (kerntraits != 0) delete kerntraits; - if (setttraits != 0) delete setttraits; - - if (pGenome != 0) delete pGenome; - -} - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -// Set genes for individual variation from species initialisation parameters -void Individual::setGenes(Species* pSpecies, int resol) { - demogrParams dem = pSpecies->getDemogr(); - emigRules emig = pSpecies->getEmig(); - trfrRules trfr = pSpecies->getTrfr(); - settleType sett = pSpecies->getSettle(); - genomeData gen = pSpecies->getGenomeData(); - simParams sim = paramsSim->getSim(); - int ntraits; // first trait for all/female expression, second for male expression - - if (gen.trait1Chromosome) { - pGenome = new Genome(pSpecies->getNChromosomes(), pSpecies->getNLoci(0), - pSpecies->isDiploid()); - } - else { - pGenome = new Genome(pSpecies); - } - - int gposn = 0; // current position on genome - int expr = 0; // gene expression type - NOT CURRENTLY USED - - if (emig.indVar) { // set emigration genes - int emigposn = gposn; - double d0, alpha, beta; - emigParams eparams; - if (emig.sexDep) { // must be a sexual species - ntraits = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction (haploid) - ntraits = 1; - } - else { // sexual reproduction - ntraits = 1; - } - } - for (int g = 0; g < ntraits; g++) { // first trait for females/all, second for males - eparams = pSpecies->getEmigParams(0, g); - d0 = pRandom->Normal(0.0, eparams.d0SD) / eparams.d0Scale; - if (emig.densDep) { - alpha = pRandom->Normal(0.0, eparams.alphaSD) / eparams.alphaScale; - beta = pRandom->Normal(0.0, eparams.betaSD) / eparams.betaScale; - } - if (gen.trait1Chromosome) { - pGenome->setGene(gposn++, expr, d0, gen.alleleSD); - if (emig.densDep) { - pGenome->setGene(gposn++, expr, alpha, gen.alleleSD); - pGenome->setGene(gposn++, expr, beta, gen.alleleSD); - } - } - else { - pGenome->setTrait(pSpecies, gposn++, d0, gen.alleleSD); - if (emig.densDep) { - pGenome->setTrait(pSpecies, gposn++, alpha, gen.alleleSD); - pGenome->setTrait(pSpecies, gposn++, beta, gen.alleleSD); - } - } - } - // record phenotypic traits - if (emig.densDep) { - setEmigTraits(pSpecies, emigposn, 3, emig.sexDep); - } - else { - setEmigTraits(pSpecies, emigposn, 1, emig.sexDep); - } - } - - //int trfrposn = 0; - if (trfr.indVar) { // set transfer genes - int trfrposn = gposn; - if (trfr.sexDep) { // must be a sexual species - ntraits = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ntraits = 1; - } - else { // sexual reproduction - ntraits = 1; - } - } - if (trfr.moveModel) { - if (trfr.moveType == 1) { // set SMS genes - double dp, gb, alphaDB, betaDB; - trfrSMSParams smsparams = pSpecies->getSMSParams(0, 0); // only traits for females/all - trfrSMSTraits smstraits = pSpecies->getSMSTraits(); - dp = pRandom->Normal(0.0, smsparams.dpSD) / smsparams.dpScale; - gb = pRandom->Normal(0.0, smsparams.gbSD) / smsparams.gbScale; - if (smstraits.goalType == 2) { - alphaDB = pRandom->Normal(0.0, smsparams.alphaDBSD) / smsparams.alphaDBScale; - betaDB = pRandom->Normal(0.0, smsparams.betaDBSD) / smsparams.betaDBScale; - } - if (gen.trait1Chromosome) { - pGenome->setGene(gposn++, expr, dp, gen.alleleSD); - pGenome->setGene(gposn++, expr, gb, gen.alleleSD); - if (smstraits.goalType == 2) { - pGenome->setGene(gposn++, expr, alphaDB, gen.alleleSD); - pGenome->setGene(gposn++, expr, betaDB, gen.alleleSD); - } - } - else { - pGenome->setTrait(pSpecies, gposn++, dp, gen.alleleSD); - pGenome->setTrait(pSpecies, gposn++, gb, gen.alleleSD); - if (smstraits.goalType == 2) { - pGenome->setTrait(pSpecies, gposn++, alphaDB, gen.alleleSD); - pGenome->setTrait(pSpecies, gposn++, betaDB, gen.alleleSD); - } - } - // record phenotypic traits - if (smstraits.goalType == 2) - setSMSTraits(pSpecies, trfrposn, 4, false); - else - setSMSTraits(pSpecies, trfrposn, 2, false); - } - if (trfr.moveType == 2) { // set CRW genes - double stepL, rho; - trfrCRWParams m = pSpecies->getCRWParams(0, 0); // only traits for females/all - stepL = pRandom->Normal(0.0, m.stepLgthSD) / m.stepLScale; - rho = pRandom->Normal(0.0, m.rhoSD) / m.rhoScale; - if (gen.trait1Chromosome) { - pGenome->setGene(gposn++, expr, stepL, gen.alleleSD); - pGenome->setGene(gposn++, expr, rho, gen.alleleSD); - } - else { - pGenome->setTrait(pSpecies, gposn++, stepL, gen.alleleSD); - pGenome->setTrait(pSpecies, gposn++, rho, gen.alleleSD); - } - // record phenotypic traits - setCRWTraits(pSpecies, trfrposn, 2, false); - } - } - else { // set kernel genes - double dist1, dist2, prob1; - trfrKernParams k; - for (int g = 0; g < ntraits; g++) { // first traits for females/all, second for males - k = pSpecies->getKernParams(0, g); - dist1 = pRandom->Normal(0.0, k.dist1SD) / k.dist1Scale; - if (trfr.twinKern) - { - dist2 = pRandom->Normal(0.0, k.dist2SD) / k.dist2Scale; - prob1 = pRandom->Normal(0.0, k.PKern1SD) / k.PKern1Scale; - } - if (gen.trait1Chromosome) { - pGenome->setGene(gposn++, expr, dist1, gen.alleleSD); - if (trfr.twinKern) - { - pGenome->setGene(gposn++, expr, dist2, gen.alleleSD); - pGenome->setGene(gposn++, expr, prob1, gen.alleleSD); - } - } - else { - pGenome->setTrait(pSpecies, gposn++, dist1, gen.alleleSD); - if (trfr.twinKern) - { - pGenome->setTrait(pSpecies, gposn++, dist2, gen.alleleSD); - pGenome->setTrait(pSpecies, gposn++, prob1, gen.alleleSD); - } - } - } - // record phenotypic traits - if (trfr.twinKern) - { - setKernTraits(pSpecies, trfrposn, 3, resol, trfr.sexDep); - } - else { - setKernTraits(pSpecies, trfrposn, 1, resol, trfr.sexDep); - } - } - } - - if (sett.indVar) { - int settposn = gposn; - double s0, alpha, beta; - settParams sparams; - if (sett.sexDep) { // must be a sexual species - ntraits = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ntraits = 1; - } - else { // sexual reproduction - ntraits = 1; - } - } - for (int g = 0; g < ntraits; g++) { // first trait for females/all, second for males - if (sim.batchMode) { - sparams = pSpecies->getSettParams(0, g); - } - else { // individual variability not (yet) implemented as sex-dependent in GUI - sparams = pSpecies->getSettParams(0, 0); - } - s0 = pRandom->Normal(0.0, sparams.s0SD) / sparams.s0Scale; - alpha = pRandom->Normal(0.0, sparams.alphaSSD) / sparams.alphaSScale; - beta = pRandom->Normal(0.0, sparams.betaSSD) / sparams.betaSScale; - - if (gen.trait1Chromosome) { - pGenome->setGene(gposn++, expr, s0, gen.alleleSD); - pGenome->setGene(gposn++, expr, alpha, gen.alleleSD); - pGenome->setGene(gposn++, expr, beta, gen.alleleSD); - } - else { - pGenome->setTrait(pSpecies, gposn++, s0, gen.alleleSD); - pGenome->setTrait(pSpecies, gposn++, alpha, gen.alleleSD); - pGenome->setTrait(pSpecies, gposn++, beta, gen.alleleSD); - } - } - // record phenotypic traits - setSettTraits(pSpecies, settposn, 3, sett.sexDep); - } - - if (!gen.trait1Chromosome) { - if (gen.neutralMarkers || pSpecies->getNNeutralLoci() > 0) { - pGenome->setNeutralLoci(pSpecies, gen.alleleSD); - } - } -} - -// Inherit genome from parent(s) -void Individual::setGenes(Species* pSpecies, Individual* mother, Individual* father, - int resol) -{ - emigRules emig = pSpecies->getEmig(); - trfrRules trfr = pSpecies->getTrfr(); - settleType sett = pSpecies->getSettle(); - - Genome* pFatherGenome; - if (father == 0) pFatherGenome = 0; else pFatherGenome = father->pGenome; - - pGenome = new Genome(pSpecies, mother->pGenome, pFatherGenome); - - if (emig.indVar) { - // record emigration traits - if (father == 0) { // haploid - if (emig.densDep) { - setEmigTraits(pSpecies, 0, 3, 0); - } - else { - setEmigTraits(pSpecies, 0, 1, 0); - } - } - else { // diploid - if (emig.densDep) { - setEmigTraits(pSpecies, 0, 3, emig.sexDep); - } - else { - setEmigTraits(pSpecies, 0, 1, emig.sexDep); - } - } - } - - if (trfr.indVar) { - // record movement model traits - if (trfr.moveModel) { - if (trfr.moveType == 1) { // SMS - trfrSMSTraits s = pSpecies->getSMSTraits(); - if (s.goalType == 2) - setSMSTraits(pSpecies, trfr.movtTrait[0], 4, 0); - else - setSMSTraits(pSpecies, trfr.movtTrait[0], 2, 0); - } - if (trfr.moveType == 2) { // CRW - setCRWTraits(pSpecies, trfr.movtTrait[0], 2, 0); - } - } - else { // kernel - if (father == 0) { // haploid - if (trfr.twinKern) - { - setKernTraits(pSpecies, trfr.movtTrait[0], 3, resol, 0); - } - else { - setKernTraits(pSpecies, trfr.movtTrait[0], 1, resol, 0); - } - } - else { // diploid - if (trfr.twinKern) - { - setKernTraits(pSpecies, trfr.movtTrait[0], 3, resol, trfr.sexDep); - } - else { - setKernTraits(pSpecies, trfr.movtTrait[0], 1, resol, trfr.sexDep); - } - } - } - } - - if (sett.indVar) { - // record settlement traits - if (father == 0) { // haploid - setSettTraits(pSpecies, sett.settTrait[0], 3, 0); - } - else { // diploid - setSettTraits(pSpecies, sett.settTrait[0], 3, sett.sexDep); - } - } -} - -//--------------------------------------------------------------------------- - -// Identify whether an individual is a potentially breeding female - -// if so, return her stage, otherwise return 0 -int Individual::breedingFem(void) { - if (sex == 0) { - if (status == 0 || status == 4 || status == 5) return stage; - else return 0; - } - else return 0; -} - -int Individual::getId(void) { return indId; } - -int Individual::getSex(void) { return sex; } - -int Individual::getStatus(void) { return status; } - -indStats Individual::getStats(void) { - indStats s; - s.stage = stage; s.sex = sex; s.age = age; s.status = status; s.fallow = fallow; - s.isDeveloping = isDeveloping; - return s; -} - -Cell* Individual::getLocn(const short option) { - if (option == 0) { // return previous location - return pPrevCell; - } - else { // return current location - return pCurrCell; - } -} - -Patch* Individual::getNatalPatch(void) { return pNatalPatch; } - -void Individual::setYearSteps(int t) { - if (path != 0 && t >= 0) { - if (t >= 0) path->year = t; - else path->year = 666; - } -} - -pathSteps Individual::getSteps(void) { - pathSteps s; - if (path == 0) { - s.year = 0; s.total = 0; s.out = 0; - } - else { - s.year = path->year; s.total = path->total; s.out = path->out; - } - return s; -} - -settlePatch Individual::getSettPatch(void) { - settlePatch s; - if (path == 0) { - s.pSettPatch = 0; s.settleStatus = 0; - } - else { - s.pSettPatch = path->pSettPatch; s.settleStatus = path->settleStatus; - } - return s; -} - -void Individual::setSettPatch(const settlePatch s) { - if (path == 0) { - path = new pathData; - path->year = 0; path->total = 0; path->out = 0; path->settleStatus = 0; -#if RS_RCPP - path->pathoutput = 1; -#endif - } - if (s.settleStatus >= 0 && s.settleStatus <= 2) path->settleStatus = s.settleStatus; - path->pSettPatch = s.pSettPatch; -} - -// Set phenotypic emigration traits -void Individual::setEmigTraits(Species* pSpecies, short emiggenelocn, short nemigtraits, - bool sexdep) { - emigTraits e; e.d0 = e.alpha = e.beta = 0.0; - if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - if (nemigtraits == 3) { // emigration is density-dependent - e.d0 = (float)pGenome->express(emiggenelocn + 3 * sex, 0, 0); - e.alpha = (float)pGenome->express(emiggenelocn + 3 * sex + 1, 0, 0); - e.beta = (float)pGenome->express(emiggenelocn + 3 * sex + 2, 0, 0); - } - else { - e.d0 = (float)pGenome->express(emiggenelocn + sex, 0, 0); - } - } - else { - e.d0 = (float)pGenome->express(emiggenelocn, 0, 0); - if (nemigtraits == 3) { // emigration is density-dependent - e.alpha = (float)pGenome->express(emiggenelocn + 1, 0, 0); - e.beta = (float)pGenome->express(emiggenelocn + 2, 0, 0); - } - } - } - else { - if (sexdep) { - if (nemigtraits == 3) { // emigration is density-dependent - e.d0 = (float)pGenome->express(pSpecies, emiggenelocn + 3 * sex); - e.alpha = (float)pGenome->express(pSpecies, emiggenelocn + 3 * sex + 1); - e.beta = (float)pGenome->express(pSpecies, emiggenelocn + 3 * sex + 2); - } - else { - e.d0 = (float)pGenome->express(pSpecies, emiggenelocn + sex); - } - } - else { - e.d0 = (float)pGenome->express(pSpecies, emiggenelocn); - if (nemigtraits == 3) { // emigration is density-dependent - e.alpha = (float)pGenome->express(pSpecies, emiggenelocn + 1); - e.beta = (float)pGenome->express(pSpecies, emiggenelocn + 2); - } - } - } - } - - emigParams eparams; - if (sexdep) { - eparams = pSpecies->getEmigParams(0, sex); - } - else { - eparams = pSpecies->getEmigParams(0, 0); - } - emigtraits = new emigTraits; - emigtraits->d0 = (float)(e.d0 * eparams.d0Scale + eparams.d0Mean); - emigtraits->alpha = (float)(e.alpha * eparams.alphaScale + eparams.alphaMean); - emigtraits->beta = (float)(e.beta * eparams.betaScale + eparams.betaMean); - if (emigtraits->d0 < 0.0) emigtraits->d0 = 0.0; - if (emigtraits->d0 > 1.0) emigtraits->d0 = 1.0; - return; -} - -// Get phenotypic emigration traits -emigTraits Individual::getEmigTraits(void) { - emigTraits e; e.d0 = e.alpha = e.beta = 0.0; - if (emigtraits != 0) { - e.d0 = emigtraits->d0; - e.alpha = emigtraits->alpha; - e.beta = emigtraits->beta; - } - return e; -} - -// Set phenotypic transfer by kernel traits -void Individual::setKernTraits(Species* pSpecies, short kerngenelocn, short nkerntraits, - int resol, bool sexdep) { - trfrKernTraits k; k.meanDist1 = k.meanDist2 = k.probKern1 = 0.0; - if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - if (nkerntraits == 3) { // twin kernel - k.meanDist1 = (float)pGenome->express(kerngenelocn + 3 * sex, 0, sex); - k.meanDist2 = (float)pGenome->express(kerngenelocn + 3 * sex + 1, 0, sex); - k.probKern1 = (float)pGenome->express(kerngenelocn + 3 * sex + 2, 0, sex); - } - else { - k.meanDist1 = (float)pGenome->express(kerngenelocn + sex, 0, sex); - } - } - else { - k.meanDist1 = (float)pGenome->express(kerngenelocn, 0, 0); - if (nkerntraits == 3) { // twin kernel - k.meanDist2 = (float)pGenome->express(kerngenelocn + 1, 0, 0); - k.probKern1 = (float)pGenome->express(kerngenelocn + 2, 0, 0); - } - } - } - else { - if (sexdep) { - if (nkerntraits == 3) { // twin kernel - k.meanDist1 = (float)pGenome->express(pSpecies, kerngenelocn + 3 * sex); - k.meanDist2 = (float)pGenome->express(pSpecies, kerngenelocn + 3 * sex + 1); - k.probKern1 = (float)pGenome->express(pSpecies, kerngenelocn + 3 * sex + 2); - } - else { - k.meanDist1 = (float)pGenome->express(pSpecies, kerngenelocn + sex); - } - } - else { - k.meanDist1 = (float)pGenome->express(pSpecies, kerngenelocn); - if (nkerntraits == 3) { // twin kernel - k.meanDist2 = (float)pGenome->express(pSpecies, kerngenelocn + 1); - k.probKern1 = (float)pGenome->express(pSpecies, kerngenelocn + 2); - } - } - } - } - - trfrKernParams kparams; - if (sexdep) { - kparams = pSpecies->getKernParams(0, sex); - } - else { - kparams = pSpecies->getKernParams(0, 0); - } - kerntraits = new trfrKernTraits; - kerntraits->meanDist1 = (float)(k.meanDist1 * kparams.dist1Scale + kparams.dist1Mean); - kerntraits->meanDist2 = (float)(k.meanDist2 * kparams.dist2Scale + kparams.dist2Mean); - kerntraits->probKern1 = (float)(k.probKern1 * kparams.PKern1Scale + kparams.PKern1Mean); - if (!pSpecies->useFullKernel()) { - // kernel mean(s) may not be less than landscape resolution - if (kerntraits->meanDist1 < resol) kerntraits->meanDist1 = (float)resol; - if (kerntraits->meanDist2 < resol) kerntraits->meanDist2 = (float)resol; - } - if (kerntraits->probKern1 < 0.0) kerntraits->probKern1 = 0.0; - if (kerntraits->probKern1 > 1.0) kerntraits->probKern1 = 1.0; - return; -} - -// Get phenotypic emigration traits -trfrKernTraits Individual::getKernTraits(void) { - trfrKernTraits k; k.meanDist1 = k.meanDist2 = k.probKern1 = 0.0; - if (kerntraits != 0) { - k.meanDist1 = kerntraits->meanDist1; - k.meanDist2 = kerntraits->meanDist2; - k.probKern1 = kerntraits->probKern1; - } - return k; -} - -// Set phenotypic transfer by SMS traits -void Individual::setSMSTraits(Species* pSpecies, short SMSgenelocn, short nSMStraits, - bool sexdep) { - trfrSMSTraits s = pSpecies->getSMSTraits(); - double dp, gb, alphaDB, betaDB; - dp = gb = alphaDB = betaDB = 0.0; - if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - dp = pGenome->express(SMSgenelocn, 0, 0); - gb = pGenome->express(SMSgenelocn + 1, 0, 0); - if (nSMStraits == 4) { - alphaDB = pGenome->express(SMSgenelocn + 2, 0, 0); - betaDB = pGenome->express(SMSgenelocn + 3, 0, 0); - } - } - else { - dp = pGenome->express(SMSgenelocn, 0, 0); - gb = pGenome->express(SMSgenelocn + 1, 0, 0); - if (nSMStraits == 4) { - alphaDB = pGenome->express(SMSgenelocn + 2, 0, 0); - betaDB = pGenome->express(SMSgenelocn + 3, 0, 0); - } - } - } - else { - if (sexdep) { - dp = pGenome->express(pSpecies, SMSgenelocn); - gb = pGenome->express(pSpecies, SMSgenelocn + 1); - if (nSMStraits == 4) { - alphaDB = pGenome->express(pSpecies, SMSgenelocn + 2); - betaDB = pGenome->express(pSpecies, SMSgenelocn + 3); - } - } - else { - dp = pGenome->express(pSpecies, SMSgenelocn); - gb = pGenome->express(pSpecies, SMSgenelocn + 1); - if (nSMStraits == 4) { - alphaDB = pGenome->express(pSpecies, SMSgenelocn + 2); - betaDB = pGenome->express(pSpecies, SMSgenelocn + 3); - } - } - } - } - trfrSMSParams smsparams; - if (sexdep) { - smsparams = pSpecies->getSMSParams(0, 0); - } - else { - smsparams = pSpecies->getSMSParams(0, 0); - } - smsData->dp = (float)(dp * smsparams.dpScale + smsparams.dpMean); - smsData->gb = (float)(gb * smsparams.gbScale + smsparams.gbMean); - if (s.goalType == 2) { - smsData->alphaDB = (float)(alphaDB * smsparams.alphaDBScale + smsparams.alphaDBMean); - smsData->betaDB = (int)(betaDB * smsparams.betaDBScale + smsparams.betaDBMean + 0.5); - } - else { - smsData->alphaDB = s.alphaDB; - smsData->betaDB = s.betaDB; - } - if (smsData->dp < 1.0) smsData->dp = 1.0; - if (smsData->gb < 1.0) smsData->gb = 1.0; - if (smsData->alphaDB <= 0.0) smsData->alphaDB = 0.000001f; - if (smsData->betaDB < 1) smsData->betaDB = 1; - return; -} - -// Get phenotypic transfer by SMS traits -trfrSMSTraits Individual::getSMSTraits(void) { - trfrSMSTraits s; s.dp = s.gb = s.alphaDB = 1.0; s.betaDB = 1; - if (smsData != 0) { - s.dp = smsData->dp; s.gb = smsData->gb; - s.alphaDB = smsData->alphaDB; s.betaDB = smsData->betaDB; - } - return s; -} - -// Set phenotypic transfer by CRW traits -void Individual::setCRWTraits(Species* pSpecies, short CRWgenelocn, short nCRWtraits, - bool sexdep) { - trfrCRWTraits c; c.stepLength = c.rho = 0.0; - if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - c.stepLength = (float)pGenome->express(CRWgenelocn + sex, 0, sex); - c.rho = (float)pGenome->express(CRWgenelocn + 2 + sex, 0, sex); - } - else { - c.stepLength = (float)pGenome->express(CRWgenelocn, 0, 0); - c.rho = (float)pGenome->express(CRWgenelocn + 1, 0, 0); - } - } - else { - if (sexdep) { - c.stepLength = (float)pGenome->express(pSpecies, CRWgenelocn + sex); - c.rho = (float)pGenome->express(pSpecies, CRWgenelocn + 2 + sex); - } - else { - c.stepLength = (float)pGenome->express(pSpecies, CRWgenelocn); - c.rho = (float)pGenome->express(pSpecies, CRWgenelocn + 1); - } - } - } - - trfrCRWParams cparams; - if (sexdep) { - cparams = pSpecies->getCRWParams(0, sex); - } - else { - cparams = pSpecies->getCRWParams(0, 0); - } - crw->stepL = (float)(c.stepLength * cparams.stepLScale + cparams.stepLgthMean); - crw->rho = (float)(c.rho * cparams.rhoScale + cparams.rhoMean); - if (crw->stepL < 1.0) crw->stepL = 1.0; - if (crw->rho < 0.0) crw->rho = 0.0; - if (crw->rho > 0.999) crw->rho = 0.999f; - return; -} - -// Get phenotypic transfer by CRW traits -trfrCRWTraits Individual::getCRWTraits(void) { - trfrCRWTraits c; c.stepLength = c.rho = 0.0; - if (crw != 0) { - c.stepLength = crw->stepL; - c.rho = crw->rho; - } - return c; -} - -// Set phenotypic settlement traits -void Individual::setSettTraits(Species* pSpecies, short settgenelocn, short nsetttraits, - bool sexdep) { - settleTraits s; s.s0 = s.alpha = s.beta = 0.0; - if (pGenome != 0) { - if (pSpecies->has1ChromPerTrait()) { - if (sexdep) { - s.s0 = (float)pGenome->express(settgenelocn + 3 * sex, 0, 0); - s.alpha = (float)pGenome->express(settgenelocn + 3 * sex + 1, 0, 0); - s.beta = (float)pGenome->express(settgenelocn + 3 * sex + 2, 0, 0); - } - else { - s.s0 = (float)pGenome->express(settgenelocn, 0, 0); - s.alpha = (float)pGenome->express(settgenelocn + 1, 0, 0); - s.beta = (float)pGenome->express(settgenelocn + 2, 0, 0); - } - } - else { - if (sexdep) { - s.s0 = (float)pGenome->express(pSpecies, settgenelocn + 3 * sex); - s.alpha = (float)pGenome->express(pSpecies, settgenelocn + 3 * sex + 1); - s.beta = (float)pGenome->express(pSpecies, settgenelocn + 3 * sex + 2); - } - else { - s.s0 = (float)pGenome->express(pSpecies, settgenelocn); - s.alpha = (float)pGenome->express(pSpecies, settgenelocn + 1); - s.beta = (float)pGenome->express(pSpecies, settgenelocn + 2); - } - - } - } - - settParams sparams; - if (sexdep) { - sparams = pSpecies->getSettParams(0, sex); - } - else { - sparams = pSpecies->getSettParams(0, 0); - } - setttraits = new settleTraits; - setttraits->s0 = (float)(s.s0 * sparams.s0Scale + sparams.s0Mean); - setttraits->alpha = (float)(s.alpha * sparams.alphaSScale + sparams.alphaSMean); - setttraits->beta = (float)(s.beta * sparams.betaSScale + sparams.betaSMean); - if (setttraits->s0 < 0.0) setttraits->s0 = 0.0; - if (setttraits->s0 > 1.0) setttraits->s0 = 1.0; - return; -} - -// Get phenotypic settlement traits -settleTraits Individual::getSettTraits(void) { - settleTraits s; s.s0 = s.alpha = s.beta = 0.0; - if (setttraits != 0) { - s.s0 = setttraits->s0; - s.alpha = setttraits->alpha; - s.beta = setttraits->beta; - } - - return s; -} - - -void Individual::setStatus(short s) { - if (s >= 0 && s <= 9) status = s; - status = s; -} - -void Individual::developing(void) { - isDeveloping = true; -} - -void Individual::develop(void) { - stage++; isDeveloping = false; -} - -void Individual::ageIncrement(short maxage) { - if (status < 6) { // alive - age++; - if (age > maxage) status = 9; // exceeds max. age - dies - else { - if (path != 0) path->year = 0; // reset annual step count for movement models - if (status == 3) // waiting to continue dispersal - status = 1; - } - } -} - -void Individual::incFallow(void) { fallow++; } - -void Individual::resetFallow(void) { fallow = 0; } - -//--------------------------------------------------------------------------- -// Move to a specified neighbouring cell -void Individual::moveto(Cell* newCell) { - // check that location is indeed a neighbour of the current cell - locn currloc = pCurrCell->getLocn(); - locn newloc = newCell->getLocn(); - double d = sqrt(((double)currloc.x - (double)newloc.x) * ((double)currloc.x - (double)newloc.x) - + ((double)currloc.y - (double)newloc.y) * ((double)currloc.y - (double)newloc.y)); - if (d >= 1.0 && d < 1.5) { // ok - pCurrCell = newCell; status = 5; - } -} - -//--------------------------------------------------------------------------- -// Move to a new cell by sampling a dispersal distance from a single or double -// negative exponential kernel -// Returns 1 if still dispersing (including having found a potential patch), otherwise 0 -int Individual::moveKernel(Landscape* pLandscape, Species* pSpecies, - const short repType, const bool absorbing) -{ - - intptr patch; - int patchNum = 0; - int newX = 0, newY = 0; - int dispersing = 1; - double xrand, yrand, meandist, dist, r1, rndangle, nx, ny; - float localK; - trfrKernTraits kern; - Cell* pCell; - Patch* pPatch; - locn loc = pCurrCell->getLocn(); - - landData land = pLandscape->getLandData(); - - bool usefullkernel = pSpecies->useFullKernel(); - trfrRules trfr = pSpecies->getTrfr(); - settleRules sett = pSpecies->getSettRules(stage, sex); - - pCell = NULL; - pPatch = NULL; - - if (trfr.indVar) { // get individual's kernel parameters - kern.meanDist1 = kern.meanDist2 = kern.probKern1 = 0.0; - if (pGenome != 0) { - kern.meanDist1 = kerntraits->meanDist1; - if (trfr.twinKern) - { - kern.meanDist2 = kerntraits->meanDist2; - kern.probKern1 = kerntraits->probKern1; - } - } - } - else { // get kernel parameters for the species - if (trfr.sexDep) { - if (trfr.stgDep) { - kern = pSpecies->getKernTraits(stage, sex); - } - else { - kern = pSpecies->getKernTraits(0, sex); - } - } - else { - if (trfr.stgDep) { - kern = pSpecies->getKernTraits(stage, 0); - } - else { - kern = pSpecies->getKernTraits(0, 0); - } - } - } - - // scale the appropriate kernel mean to the cell size - if (trfr.twinKern) - { - if (pRandom->Bernoulli(kern.probKern1)) - meandist = kern.meanDist1 / (float)land.resol; - else - meandist = kern.meanDist2 / (float)land.resol; - } - else - meandist = kern.meanDist1 / (float)land.resol; - - // scaled mean may not be less than 1 unless emigration derives from the kernel - // (i.e. the 'use full kernel' option is applied) - if (!usefullkernel && meandist < 1.0) meandist = 1.0; - - int loopsteps = 0; // new counter to prevent infinite loop added 14/8/15 - do { - do { - do { - // randomise the cell within the patch, provided that the individual is still in - // its natal cell (i.e. not waiting in the matrix) - // this is because, if the patch is very large, the individual is near the centre - // and the (single) kernel mean is (not much more than) the cell size, an infinite - // loop could otherwise result, as the individual never reaches the patch edge - // (in a cell-based model, this has no effect, other than as a processing overhead) - if (status == 1) { - pCell = pNatalPatch->getRandomCell(); - if (pCell != 0) { - loc = pCell->getLocn(); - } - } - // randomise the position of the individual inside the cell - xrand = (double)loc.x + pRandom->Random() * 0.999; - yrand = (double)loc.y + pRandom->Random() * 0.999; - - r1 = 0.0000001 + pRandom->Random() * (1.0 - 0.0000001); - // dist = (-1.0*meandist)*std::log(r1); - dist = (-1.0 * meandist) * log(r1); // for LINUX_CLUSTER - - rndangle = pRandom->Random() * 2.0 * PI; - nx = xrand + dist * sin(rndangle); - ny = yrand + dist * cos(rndangle); - if (nx < 0.0) newX = -1; else newX = (int)nx; - if (ny < 0.0) newY = -1; else newY = (int)ny; -#if RSDEBUG - if (path != 0) (path->year)++; -#endif - loopsteps++; - } while (loopsteps < 1000 && - ((!absorbing && (newX < land.minX || newX > land.maxX - || newY < land.minY || newY > land.maxY)) - || (!usefullkernel && newX == loc.x && newY == loc.y)) - ); - if (loopsteps < 1000) { - if (newX < land.minX || newX > land.maxX - || newY < land.minY || newY > land.maxY) { // beyond absorbing boundary - pCell = 0; - patch = 0; - patchNum = -1; - } - else { - pCell = pLandscape->findCell(newX, newY); - if (pCell == 0) { // no-data cell - patch = 0; - patchNum = -1; - } - else { - patch = pCell->getPatch(); - if (patch == 0) { // matrix - pPatch = 0; - patchNum = 0; - } - else { - pPatch = (Patch*)patch; - patchNum = pPatch->getPatchNum(); - } - } - } - } - else { - patch = 0; - patchNum = -1; - } - } while (!absorbing && patchNum < 0 && loopsteps < 1000); // in a no-data region - } while (!usefullkernel && pPatch == pNatalPatch && loopsteps < 1000); // still in the original (natal) patch - - if (loopsteps < 1000) { - if (pCell == 0) { // beyond absorbing boundary or in no-data cell - pCurrCell = 0; - status = 6; - dispersing = 0; - } - else { - pCurrCell = pCell; - if (pPatch == 0) localK = 0.0; // matrix - else localK = pPatch->getK(); - if (patchNum > 0 && localK > 0.0) { // found a new patch - status = 2; // record as potential settler - } - else { - dispersing = 0; - // can wait in matrix if population is stage structured ... - if (pSpecies->stageStructured()) { - // ... and wait option is applied ... - if (sett.wait) { // ... it is - status = 3; // waiting - } - else // ... it is not - status = 6; // dies (unless there is a suitable neighbouring cell) - } - else - status = 6; // dies (unless there is a suitable neighbouring cell) - } - } - } - else { - status = 6; - dispersing = 0; - } - - // apply dispersal-related mortality, which may be distance-dependent - dist *= (float)land.resol; // re-scale distance moved to landscape scale - if (status < 7) { - double dispmort; - trfrMortParams mort = pSpecies->getMortParams(); - if (trfr.distMort) { - dispmort = 1.0 / (1.0 + exp(-(dist - mort.mortBeta) * mort.mortAlpha)); - } - else { - dispmort = mort.fixedMort; - } - if (pRandom->Bernoulli(dispmort)) { - status = 7; // dies - dispersing = 0; - } - } - - return dispersing; -} - -//--------------------------------------------------------------------------- -// Make a single movement step according to a mechanistic movement model -// Returns 1 if still dispersing (including having found a potential patch), otherwise 0 -int Individual::moveStep(Landscape* pLandscape, Species* pSpecies, - const short landIx, const bool absorbing) -{ - - if (status != 1) return 0; // not currently dispersing - - intptr patch; - int patchNum; - int newX, newY; - locn loc; - int dispersing = 1; - double xcnew, ycnew; - double angle; - double mortprob, rho, steplen; - movedata move; - Patch* pPatch = 0; - bool absorbed = false; - - landData land = pLandscape->getLandData(); - simParams sim = paramsSim->getSim(); - - trfrRules trfr = pSpecies->getTrfr(); - trfrCRWTraits movt = pSpecies->getCRWTraits(); - settleSteps settsteps = pSpecies->getSteps(stage, sex); - - patch = pCurrCell->getPatch(); - - if (patch == 0) { // matrix - pPatch = 0; - patchNum = 0; - } - else { - pPatch = (Patch*)patch; - patchNum = pPatch->getPatchNum(); - } - // apply step-dependent mortality risk ... - if (trfr.habMort) - { // habitat-dependent - int h = pCurrCell->getHabIndex(landIx); - if (h < 0) { // no-data cell - should not occur, but if it does, individual dies - mortprob = 1.0; - } - else mortprob = pSpecies->getHabMort(h); - } - else mortprob = movt.stepMort; - // ... unless individual has not yet left natal patch in emigration year - if (pPatch == pNatalPatch && path->out == 0 && path->year == path->total) { - mortprob = 0.0; - } - if (pRandom->Bernoulli(mortprob)) { // individual dies - status = 7; - dispersing = 0; - } - else { // take a step - (path->year)++; - (path->total)++; - if (patch == 0 || pPatch == 0 || patchNum == 0) { // not in a patch - if (path != 0) path->settleStatus = 0; // reset path settlement status - (path->out)++; - } - loc = pCurrCell->getLocn(); - newX = loc.x; newY = loc.y; - - - switch (trfr.moveType) { - - case 1: // SMS - move = smsMove(pLandscape, pSpecies, landIx, pPatch == pNatalPatch, trfr.indVar, absorbing); - if (move.dist < 0.0) { - // either INTERNAL ERROR CONDITION - INDIVIDUAL IS IN NO-DATA SQUARE - // or individual has crossed absorbing boundary ... - // ... individual dies - status = 6; - dispersing = 0; - } - else { - - // WOULD IT BE MORE EFFICIENT FOR smsMove TO RETURN A POINTER TO THE NEW CELL? ... - - patch = pCurrCell->getPatch(); - if (patch == 0) { - pPatch = 0; - } - else { - pPatch = (Patch*)patch; - } - if (sim.saveVisits && pPatch != pNatalPatch) { - pCurrCell->incrVisits(); - } - } - break; - - case 2: // CRW - if (trfr.indVar) { - if (crw != 0) { - movt.stepLength = crw->stepL; - movt.rho = crw->rho; - } - } - - steplen = movt.stepLength; if (steplen < 0.2 * land.resol) steplen = 0.2 * land.resol; - rho = movt.rho; if (rho > 0.99) rho = 0.99; - if (pPatch == pNatalPatch) { - rho = 0.99; // to promote leaving natal patch - path->out = 0; - } - if (movt.straigtenPath && path->settleStatus > 0) { - // individual is in a patch and has already determined whether to settle - rho = 0.99; // to promote leaving the patch - path->out = 0; - } - int loopsteps = 0; // new counter to prevent infinite loop added 14/8/15 - do { - do { - // new direction - if (newX < land.minX || newX > land.maxX || newY < land.minY || newY > land.maxY - || pCurrCell == 0) { - // individual has tried to go out-of-bounds or into no-data area - // allow random move to prevent repeated similar move - angle = wrpcauchy(crw->prevdrn, 0.0); - } - else - angle = wrpcauchy(crw->prevdrn, rho); - // new continuous cell coordinates - xcnew = crw->xc + sin(angle) * steplen / (float)land.resol; - ycnew = crw->yc + cos(angle) * steplen / (float)land.resol; - if (xcnew < 0.0) newX = -1; else newX = (int)xcnew; - if (ycnew < 0.0) newY = -1; else newY = (int)ycnew; - loopsteps++; - } while (!absorbing && loopsteps < 1000 && - (newX < land.minX || newX > land.maxX || newY < land.minY || newY > land.maxY)); - if (newX < land.minX || newX > land.maxX || newY < land.minY || newY > land.maxY) - pCurrCell = 0; - else - pCurrCell = pLandscape->findCell(newX, newY); - if (pCurrCell == 0) { // no-data cell or beyond absorbing boundary - patch = 0; - if (absorbing) absorbed = true; - } - else - patch = pCurrCell->getPatch(); - } while (!absorbing && pCurrCell == 0 && loopsteps < 1000); - crw->prevdrn = (float)angle; - crw->xc = (float)xcnew; crw->yc = (float)ycnew; - if (absorbed) { // beyond absorbing boundary or in no-data square - status = 6; - dispersing = 0; - pCurrCell = 0; - } - else { - if (loopsteps >= 1000) { // unable to make a move - // INTERNAL ERROR CONDITION - INDIVIDUAL IS IN NO-DATA SQUARE - // NEED TO TAKE SOME FORM OF INFORMATIVE ACTION ... - // ... individual dies as it cannot move - status = 6; - dispersing = 0; - // current cell will be invalid (zero), so set back to previous cell - pCurrCell = pPrevCell; - } - } - break; - - } // end of switch (trfr.moveType) - - if (patch > 0 // not no-data area or matrix - && path->total >= settsteps.minSteps) { - pPatch = (Patch*)patch; - if (pPatch != pNatalPatch) - { - // determine whether the new patch is potentially suitable - if (pPatch->getK() > 0.0) - { // patch is suitable - status = 2; - } - } - } - if (status != 2 && status != 6) { // suitable patch not found, not already dead - if (path->year >= settsteps.maxStepsYr) { - status = 3; // waits until next year - } - if (path->total >= settsteps.maxSteps) { - status = 6; // dies - dispersing = 0; - } - } - } // end of single movement step - - return dispersing; - -} - -//--------------------------------------------------------------------------- - -// Functions to implement the SMS algorithm - -// Move to a neighbouring cell according to the SMS algorithm -movedata Individual::smsMove(Landscape* pLand, Species* pSpecies, - const short landIx, const bool natalPatch, const bool indvar, const bool absorbing) -{ - - array3x3d nbr; // to hold weights/costs/probs of moving to neighbouring cells - array3x3d goal; // to hold weights for moving towards a goal location - array3x3f hab; // to hold weights for habitat (includes percep range) - int x2, y2; // x index from 0=W to 2=E, y index from 0=N to 2=S - int newX = 0, newY = 0; - Cell* pCell; - Cell* pNewCell = NULL; - double sum_nbrs = 0.0; - movedata move; - int cellcost, newcellcost; - locn current; - - if (pCurrCell == 0) - { - // x,y is a NODATA square - this should not occur here - // return a negative distance to indicate an error - move.dist = -69.0; move.cost = 0.0; - return move; - } - - landData land = pLand->getLandData(); - trfrSMSTraits movt = pSpecies->getSMSTraits(); - current = pCurrCell->getLocn(); - - //get weights for directional persistence.... - if ((path->out > 0 && path->out <= (movt.pr + 1)) - || natalPatch - || (movt.straigtenPath && path->settleStatus > 0)) { - // inflate directional persistence to promote leaving the patch - if (indvar) nbr = getSimDir(current.x, current.y, 10.0f * smsData->dp); - else nbr = getSimDir(current.x, current.y, 10.0f * movt.dp); - } - else { - if (indvar) nbr = getSimDir(current.x, current.y, smsData->dp); - else nbr = getSimDir(current.x, current.y, movt.dp); - } - if (natalPatch || path->settleStatus > 0) path->out = 0; - - //get weights for goal bias.... - double gb; - if (movt.goalType == 2) { // dispersal bias - int nsteps = 0; - if (path->year == path->total) { // first year of dispersal - use no. of steps outside natal patch - nsteps = path->out; - } - else { // use total no. of steps - nsteps = path->total; - } - if (indvar) { - double exp_arg = -((double)nsteps - (double)smsData->betaDB) * (-smsData->alphaDB); - if (exp_arg > 100.0) exp_arg = 100.0; // to prevent exp() overflow error - gb = 1.0 + (smsData->gb - 1.0) / (1.0 + exp(exp_arg)); - } - else { - double exp_arg = -((double)nsteps - (double)movt.betaDB) * (-movt.alphaDB); - if (exp_arg > 100.0) exp_arg = 100.0; // to prevent exp() overflow error - gb = 1.0 + (movt.gb - 1.0) / (1.0 + exp(exp_arg)); - } - } - else gb = movt.gb; - goal = getGoalBias(current.x, current.y, movt.goalType, (float)gb); - - // get habitat-dependent weights (mean effective costs, given perceptual range) - // first check if costs have already been calculated - - hab = pCurrCell->getEffCosts(); - - if (hab.cell[0][0] < 0.0) { // costs have not already been calculated - hab = getHabMatrix(pLand, pSpecies, current.x, current.y, movt.pr, movt.prMethod, - landIx, absorbing); - pCurrCell->setEffCosts(hab); - } - else { - // they have already been calculated - no action required - } - - // determine weighted effective cost for the 8 neighbours - // multiply directional persistence, goal bias and habitat habitat-dependent weights - for (y2 = 2; y2 > -1; y2--) { - for (x2 = 0; x2 < 3; x2++) { - if (x2 == 1 && y2 == 1) nbr.cell[x2][y2] = 0.0; - else { - if (x2 == 1 || y2 == 1) //not diagonal - nbr.cell[x2][y2] = nbr.cell[x2][y2] * goal.cell[x2][y2] * hab.cell[x2][y2]; - else // diagonal - nbr.cell[x2][y2] = (float)SQRT2 * nbr.cell[x2][y2] * goal.cell[x2][y2] * hab.cell[x2][y2]; - } - } - } - - // determine reciprocal of effective cost for the 8 neighbours - for (y2 = 2; y2 > -1; y2--) { - for (x2 = 0; x2 < 3; x2++) { - if (nbr.cell[x2][y2] > 0.0) nbr.cell[x2][y2] = 1.0f / nbr.cell[x2][y2]; - } - } - - // set any cells beyond the current landscape limits and any no-data cells - // to have zero probability - // increment total for re-scaling to sum to unity - - for (y2 = 2; y2 > -1; y2--) { - for (x2 = 0; x2 < 3; x2++) { - if (!absorbing) { - if ((current.y + y2 - 1) < land.minY || (current.y + y2 - 1) > land.maxY - || (current.x + x2 - 1) < land.minX || (current.x + x2 - 1) > land.maxX) - // cell is beyond current landscape limits - nbr.cell[x2][y2] = 0.0; - else { // check if no-data cell - pCell = pLand->findCell((current.x + x2 - 1), (current.y + y2 - 1)); - if (pCell == 0) nbr.cell[x2][y2] = 0.0; // no-data cell - } - } - - sum_nbrs += nbr.cell[x2][y2]; - } - } - - // scale effective costs as probabilities summing to 1 - if (sum_nbrs > 0.0) { // should always be the case, but safest to check... - for (y2 = 2; y2 > -1; y2--) { - for (x2 = 0; x2 < 3; x2++) { - nbr.cell[x2][y2] = nbr.cell[x2][y2] / (float)sum_nbrs; - } - } - } - - // set up cell selection probabilities - double cumulative[9]; - int j = 0; - cumulative[0] = nbr.cell[0][0]; - for (y2 = 0; y2 < 3; y2++) { - for (x2 = 0; x2 < 3; x2++) { - if (j != 0) cumulative[j] = cumulative[j - 1] + nbr.cell[x2][y2]; - j++; - } - } - - // select direction at random based on cell selection probabilities - // landscape boundaries and no-data cells may be reflective or absorbing - cellcost = pCurrCell->getCost(); - int loopsteps = 0; // new counter to prevent infinite loop added 14/8/15 - do { - do { - double rnd = pRandom->Random(); - j = 0; - for (y2 = 0; y2 < 3; y2++) { - for (x2 = 0; x2 < 3; x2++) { - if (rnd < cumulative[j]) { - newX = current.x + x2 - 1; - newY = current.y + y2 - 1; - if (x2 == 1 || y2 == 1) move.dist = (float)(land.resol); - else move.dist = (float)(land.resol) * (float)SQRT2; - y2 = 999; x2 = 999; //to break out of x2 and y2 loops. - } - j++; - } - } - loopsteps++; - } while (loopsteps < 1000 - && (!absorbing && (newX < land.minX || newX > land.maxX - || newY < land.minY || newY > land.maxY))); - if (loopsteps >= 1000) pNewCell = 0; - else { - if (newX < land.minX || newX > land.maxX - || newY < land.minY || newY > land.maxY) { - pNewCell = 0; - } - pNewCell = pLand->findCell(newX, newY); - } - } while (!absorbing && pNewCell == 0 && loopsteps < 1000); // no-data cell - if (loopsteps >= 1000 || pNewCell == 0) { - // unable to make a move or crossed absorbing boundary - // flag individual to die - move.dist = -123.0; - if (pNewCell == 0) pCurrCell = pNewCell; - } - else { - newcellcost = pNewCell->getCost(); - move.cost = move.dist * 0.5f * ((float)cellcost + (float)newcellcost); - // make the selected move - if ((short)memory.size() == movt.memSize) { - memory.pop(); // remove oldest memory element - } - memory.push(current); // record previous location in memory - pCurrCell = pNewCell; - } - return move; -} - -// Weight neighbouring cells on basis of current movement direction -array3x3d Individual::getSimDir(const int x, const int y, const float dp) -{ - - array3x3d d; - locn prev; - double theta; - int xx, yy; - - if (memory.empty()) - { // no previous movement, set matrix to unity - for (xx = 0; xx < 3; xx++) { - for (yy = 0; yy < 3; yy++) { - d.cell[xx][yy] = 1; - } - } - } - else { // set up the matrix dependent on relationship of previous location to current - d.cell[1][1] = 0; - prev = memory.front(); - if ((x - prev.x) == 0 && (y - prev.y) == 0) { - // back to 'square 1' (first memory location) - use previous step drn only - prev = memory.back(); - if ((x - prev.x) == 0 && (y - prev.y) == 0) { // STILL HAVE A PROBLEM! - for (xx = 0; xx < 3; xx++) { - for (yy = 0; yy < 3; yy++) { - d.cell[xx][yy] = 1.0; - } - } - return d; - } - } - else { - } - theta = atan2(((double)x - (double)prev.x), ((double)y - (double)prev.y)); - d = calcWeightings(dp, (float)theta); - - } - return d; -} - -// Weight neighbouring cells on basis of goal bias -array3x3d Individual::getGoalBias(const int x, const int y, - const int goaltype, const float gb) -{ - - array3x3d d; - double theta; - int xx, yy; - - if (goaltype == 0) { // no goal set - for (xx = 0; xx < 3; xx++) { - for (yy = 0; yy < 3; yy++) { - d.cell[xx][yy] = 1.0; - } - } - } - else { - d.cell[1][1] = 0; - if ((x - smsData->goal.x) == 0 && (y - smsData->goal.y) == 0) { - // at goal, set matrix to unity - for (xx = 0; xx < 3; xx++) { - for (yy = 0; yy < 3; yy++) { - d.cell[xx][yy] = 1.0; - } - } - return d; - } - if (goaltype == 1) { - // TEMPORARY CODE - GOAL TYPE 1 NOT YET IMPLEMENTED, AS WE HAVE NO MEANS OF - // CAPTURING THE GOAL LOCATION OF EACH INDIVIDUAL - for (xx = 0; xx < 3; xx++) { - for (yy = 0; yy < 3; yy++) { - d.cell[xx][yy] = 1.0; - } - } - return d; - } - else // goaltype == 2 - theta = atan2(((double)x - (double)smsData->goal.x), ((double)y - (double)smsData->goal.y)); - d = calcWeightings(gb, (float)theta); - } - - return d; -} - -// Calculate weightings for neighbouring cells -array3x3d Individual::calcWeightings(const double base, const double theta) { - - array3x3d d; // 3x3 array indexed from SW corner by xx and yy - int dx, dy, xx, yy; - - double i0 = 1.0; // direction of theta - lowest cost bias - double i1 = base; - double i2 = base * base; - double i3 = i2 * base; - double i4 = i3 * base; // opposite to theta - highest cost bias - - if (fabs(theta) > 7.0 * PI / 8.0) { dx = 0; dy = -1; } - else { - if (fabs(theta) > 5.0 * PI / 8.0) { dy = -1; if (theta > 0) dx = 1; else dx = -1; } - else { - if (fabs(theta) > 3.0 * PI / 8.0) { dy = 0; if (theta > 0) dx = 1; else dx = -1; } - else { - if (fabs(theta) > PI / 8.0) { dy = 1; if (theta > 0) dx = 1; else dx = -1; } - else { dy = 1; dx = 0; } - } - } - } - d.cell[1][1] = 0; // central cell has zero weighting - d.cell[dx + 1][dy + 1] = (float)i0; - d.cell[-dx + 1][-dy + 1] = (float)i4; - if (dx == 0 || dy == 0) { // theta points to a cardinal direction - d.cell[dy + 1][dx + 1] = (float)i2; d.cell[-dy + 1][-dx + 1] = (float)i2; - if (dx == 0) { // theta points N or S - xx = dx + 1; if (xx > 1) dx -= 2; yy = dy; - d.cell[xx + 1][yy + 1] = (float)i1; d.cell[-xx + 1][yy + 1] = (float)i1; - d.cell[xx + 1][-yy + 1] = (float)i3; d.cell[-xx + 1][-yy + 1] = (float)i3; - } - else { // theta points W or E - yy = dy + 1; if (yy > 1) dy -= 2; xx = dx; - d.cell[xx + 1][yy + 1] = (float)i1; d.cell[xx + 1][-yy + 1] = (float)i1; - d.cell[-xx + 1][yy + 1] = (float)i3; d.cell[-xx + 1][-yy + 1] = (float)i3; - } - } - else { // theta points to an ordinal direction - d.cell[dx + 1][-dy + 1] = (float)i2; d.cell[-dx + 1][dy + 1] = (float)i2; - xx = dx + 1; if (xx > 1) xx -= 2; d.cell[xx + 1][dy + 1] = (float)i1; - yy = dy + 1; if (yy > 1) yy -= 2; d.cell[dx + 1][yy + 1] = (float)i1; - d.cell[-xx + 1][-dy + 1] = (float)i3; d.cell[-dx + 1][-yy + 1] = (float)i3; - } - - return d; -} - -// Weight neighbouring cells on basis of (habitat) costs -array3x3f Individual::getHabMatrix(Landscape* pLand, Species* pSpecies, - const int x, const int y, const short pr, const short prmethod, const short landIx, - const bool absorbing) -{ - - array3x3f w; // array of effective costs to be returned - int ncells, x4, y4; - double weight, sumweights; - // NW and SE corners of effective cost array relative to the current cell (x,y): - int xmin = 0, ymin = 0, xmax = 0, ymax = 0; - int cost, nodatacost, h; - Cell* pCell; - - landData land = pLand->getLandData(); - if (absorbing) nodatacost = ABSNODATACOST; - else nodatacost = NODATACOST; - - for (int x2 = -1; x2 < 2; x2++) { // index of relative move in x direction - for (int y2 = -1; y2 < 2; y2++) { // index of relative move in x direction - - w.cell[x2 + 1][y2 + 1] = 0.0; // initialise costs array to zeroes - - // set up corners of perceptual range relative to current cell - if (x2 == 0 && y2 == 0) { // current cell - do nothing - xmin = 0; ymin = 0; xmax = 0; ymax = 0; - } - else { - if (x2 == 0 || y2 == 0) { // not diagonal (rook move) - if (x2 == 0) { // vertical (N-S) move - if (pr % 2 == 0) { xmin = -pr / 2; xmax = pr / 2; ymin = y2; ymax = y2 * pr; } // PR even - else { xmin = -(pr - 1) / 2; xmax = (pr - 1) / 2; ymin = y2; ymax = y2 * pr; } // PR odd - } - if (y2 == 0) { // horizontal (E-W) move - if (pr % 2 == 0) { xmin = x2; xmax = x2 * pr; ymin = -pr / 2; ymax = pr / 2; } // PR even - else { xmin = x2; xmax = x2 * pr; ymin = -(pr - 1) / 2; ymax = (pr - 1) / 2; } // PR odd - } - } - else { // diagonal (bishop move) - xmin = x2; xmax = x2 * pr; ymin = y2; ymax = y2 * pr; - } - } - if (xmin > xmax) { int z = xmax; xmax = xmin; xmin = z; } // swap xmin and xmax - if (ymin > ymax) { int z = ymax; ymax = ymin; ymin = z; } // swap ymin and ymax - - // calculate effective mean cost of cells in perceptual range - ncells = 0; weight = 0.0; sumweights = 0.0; - if (x2 != 0 || y2 != 0) { // not central cell (i.e. current cell) - for (int x3 = xmin; x3 <= xmax; x3++) { - for (int y3 = ymin; y3 <= ymax; y3++) { - // if cell is out of bounds, treat landscape as a torus - // for purpose of obtaining a cost, - if ((x + x3) < 0) x4 = x + x3 + land.maxX + 1; - else { if ((x + x3) > land.maxX) x4 = x + x3 - land.maxX - 1; else x4 = x + x3; } - if ((y + y3) < 0) y4 = y + y3 + land.maxY + 1; - else { if ((y + y3) > land.maxY) y4 = y + y3 - land.maxY - 1; else y4 = y + y3; } - if (x4 < 0 || x4 > land.maxX || y4 < 0 || y4 > land.maxY) { - // unexpected problem - e.g. due to ridiculously large PR - // treat as a no-data cell - cost = nodatacost; - } - else { - // add cost of cell to total PR cost - pCell = pLand->findCell(x4, y4); - if (pCell == 0) { // no-data cell - cost = nodatacost; - } - else { - cost = pCell->getCost(); - if (cost < 0) cost = nodatacost; - else { - if (cost == 0) { // cost not yet set for the cell - h = pCell->getHabIndex(landIx); - cost = pSpecies->getHabCost(h); - pCell->setCost(cost); - } - else { - - } - } - } - } - if (prmethod == 1) { // arithmetic mean - w.cell[x2 + 1][y2 + 1] += cost; - ncells++; - } - if (prmethod == 2) { // harmonic mean - if (cost > 0) { - w.cell[x2 + 1][y2 + 1] += (1.0f / (float)cost); - ncells++; - } - } - if (prmethod == 3) { // arithmetic mean weighted by inverse distance - if (cost > 0) { - // NB distance is still given by (x3,y3) - weight = 1.0f / (double)sqrt((pow((double)x3, 2) + pow((double)y3, 2))); - w.cell[x2 + 1][y2 + 1] += (float)(weight * (double)cost); - ncells++; sumweights += weight; - } - } - } //end of y3 loop - } //end of x3 loop - if (ncells > 0) { - if (prmethod == 1) w.cell[x2 + 1][y2 + 1] /= ncells; // arithmetic mean - if (prmethod == 2) w.cell[x2 + 1][y2 + 1] = ncells / w.cell[x2 + 1][y2 + 1]; // hyperbolic mean - if (prmethod == 3 && sumweights > 0) - w.cell[x2 + 1][y2 + 1] /= (float)sumweights; // weighted arithmetic mean - } - } - else { // central cell - // record cost if not already recorded - // has effect of preparing for storing effective costs for the cell - pCell = pLand->findCell(x, y); - cost = pCell->getCost(); - if (cost < 0) cost = nodatacost; - else { - if (cost == 0) { // cost not yet set for the cell - h = pCell->getHabIndex(landIx); - cost = pSpecies->getHabCost(h); - pCell->setCost(cost); - } - } - } - }//end of y2 loop - }//end of x2 loop - - return w; - -} - -//--------------------------------------------------------------------------- -// Write records to individuals file -void Individual::outGenetics(const int rep, const int year, const int spnum, - const int landNr, const bool xtab) -{ - if (landNr == -1) { - if (pGenome != 0) { - pGenome->outGenetics(rep, year, spnum, indId, xtab); - } - } - else { // open/close file - pGenome->outGenHeaders(rep, landNr, xtab); - } - -} - -#if RS_RCPP -//--------------------------------------------------------------------------- -// Write records to movement paths file -void Individual::outMovePath(const int year) -{ - locn loc, prev_loc; - - //if (pPatch != pNatalPatch) { - loc = pCurrCell->getLocn(); - // if still dispersing... - if (status == 1) { - // at first step, record start cell first - if (path->total == 1) { - prev_loc = pPrevCell->getLocn(); - outMovePaths << year << "\t" << indId << "\t" - << "0\t" << prev_loc.x << "\t" << prev_loc.y << "\t" - << "0\t" // status at start cell is 0 - << endl; - } - // then record current step - outMovePaths << year << "\t" << indId << "\t" - << path->total << "\t" << loc.x << "\t" << loc.y << "\t" - << status << "\t" - << endl; - } - // if not anymore dispersing... - if (status > 1 && status < 10) { - prev_loc = pPrevCell->getLocn(); - // record only if this is the first step as non-disperser - if (path->pathoutput) { - // if this is also the first step taken at all, record the start cell first - if (path->total == 1) { - outMovePaths << year << "\t" << indId << "\t" - << "0\t" << prev_loc.x << "\t" << prev_loc.y << "\t" - << "0\t" // status at start cell is 0 - << endl; - } - outMovePaths << year << "\t" << indId << "\t" - << path->total << "\t" << loc.x << "\t" << loc.y << "\t" - << status << "\t" - << endl; - // current cell will be invalid (zero), so set back to previous cell - //pPrevCell = pCurrCell; - path->pathoutput = 0; - } - } -} -#endif - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -double wrpcauchy(double location, double rho) { - double result; - - if (rho < 0.0 || rho > 1.0) { - result = location; - } - - if (rho == 0) - result = pRandom->Random() * M_2PI; - else - if (rho == 1) result = location; - else { - result = fmod(cauchy(location, -log(rho)), M_2PI); - } - return result; -} - -double cauchy(double location, double scale) { - if (scale < 0) return location; - return location + scale * tan(PI * pRandom->Random()); -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - -#if RSDEBUG - - -void testIndividual() { - - Patch* pPatch = new Patch(0, 0); - int cell_x = 2; - int cell_y = 5; - int cell_hab = 2; - Cell* pCell = new Cell(cell_x, cell_y, (intptr)pPatch, cell_hab); - - // Create an individual - short stg = 0; - short age = 0; - short repInt = 0; - float probmale = 0; - bool uses_movt_process = true; - short moveType = 1; - Individual ind(pCell, pPatch, stg, age, repInt, probmale, uses_movt_process, moveType); - - // An individual... - { - std::vector inds; - for (int i = 0; i < 2; i++) - { - inds.push_back(new Individual(pCell, pPatch, stg, age, repInt, probmale, uses_movt_process, moveType)); - } - } - - // Reproduces - // depending on whether it is sexual or not - // depending on the stage - // depending on the trait inheritance - - - // Disperses - // Emigrates - // Transfers - // Settles - - // Survives - - // Develops - -} -#endif // RSDEBUG - diff --git a/src/RScore/Individual.h b/src/RScore/Individual.h deleted file mode 100644 index bdc4ecb..0000000 --- a/src/RScore/Individual.h +++ /dev/null @@ -1,312 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Individual - -Implements the Individual class - -Various optional attributes (genes for traits, movement parameters, etc.) are -allocated dynamically and accessed by pointers if required. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 26 October 2021 by Steve Palmer - -------------------------------------------------------------------------------*/ - -#ifndef IndividualH -#define IndividualH - - -#include -#include -using namespace std; - -#include "Parameters.h" -#include "Species.h" -#include "Landscape.h" -#include "Patch.h" -#include "Cell.h" -#include "Genome.h" - -#define NODATACOST 100000 // cost to use in place of nodata value for SMS -#define ABSNODATACOST 100 // cost to use in place of nodata value for SMS - // when boundaries are absorbing - -//--------------------------------------------------------------------------- - -struct indStats { - short stage; short sex; short age; short status; short fallow; - bool isDeveloping; -}; -struct pathData { // to hold path data common to SMS and CRW models - int year, total, out; // nos. of steps - Patch* pSettPatch; // pointer to most recent patch tested for settlement - short settleStatus; // whether ind may settle in current patch - // 0 = not set, 1 = debarred through density dependence rule - // 2 = OK to settle subject to finding a mate -#if RS_RCPP - short pathoutput; -#endif -}; -struct pathSteps { // nos. of steps for movement model - int year, total, out; -}; -struct settlePatch { - Patch* pSettPatch; short settleStatus; -}; -struct crwParams { // to hold data for CRW movement model - float prevdrn; // direction of previous step (UNITS) - float xc,yc; // continuous cell co-ordinates - float stepL; // phenotypic step length (m) - float rho; // phenotypic step correlation coefficient -}; -struct array3x3d { double cell[3][3]; }; -struct movedata { float dist; float cost; }; -struct smsdata { - locn prev; // location of previous cell - locn goal; // location of goal - float dp; // directional persistence - float gb; // goal bias - float alphaDB; // dispersal bias decay rate - int betaDB; // dispersal bias decay inflection point (no. of steps) -}; - -class Individual { - -public: - static int indCounter; // used to create ID, held by class, not members of class - Individual( // Individual constructor - Cell*, // pointer to Cell - Patch*, // pointer to patch - short, // stage - short, // age - short, // reproduction interval (no. of years/seasons between breeding attempts) - float, // probability that sex is male - bool, // TRUE for a movement model, FALSE for kernel-based transfer - short // movement type: 1 = SMS, 2 = CRW - ); - ~Individual(void); - void setGenes( // Set genes for individual variation from species initialisation parameters - Species*, // pointer to Species - int // Landscape resolution - ); - void setGenes( // Inherit genome from parents - Species*, // pointer to Species - Individual*, // pointer to mother - Individual*, // pointer to father (must be 0 for an asexual Species) - int // Landscape resolution - ); - void setEmigTraits( // Set phenotypic emigration traits - Species*, // pointer to Species - short, // location of emigration genes on genome - short, // number of emigration genes - bool // TRUE if emigration is sex-dependent - ); - emigTraits getEmigTraits(void); // Get phenotypic emigration traits - - void setKernTraits( // Set phenotypic transfer by kernel traits - Species*, // pointer to Species - short, // location of kernel genes on genome - short, // number of kernel genes - int, // Landscape resolution - bool // TRUE if transfer is sex-dependent - ); - trfrKernTraits getKernTraits(void); // Get phenotypic transfer by kernel traits - - void setSMSTraits( // Set phenotypic transfer by SMS traits - Species*, // pointer to Species - short, // location of SMS genes on genome - short, // number of SMS genes - bool // TRUE if transfer is sex-dependent - ); - trfrSMSTraits getSMSTraits(void); // Get phenotypic transfer by SMS traits - void setCRWTraits( // Set phenotypic transfer by CRW traits - Species*, // pointer to Species - short, // location of CRW genes on genome - short, // number of CRW genes - bool // TRUE if transfer is sex-dependent - ); - trfrCRWTraits getCRWTraits(void); // Get phenotypic transfer by CRW traits - - void setSettTraits( // Set phenotypic settlement traits - Species*, // pointer to Species - short, // location of settlement genes on genome - short, // number of settlement genes - bool // TRUE if settlement is sex-dependent - ); - settleTraits getSettTraits(void); // Get phenotypic settlement traits - - // Identify whether an individual is a potentially breeding female - - // if so, return her stage, otherwise return 0 - int breedingFem(void); - int getId(void); - int getSex(void); - int getStatus(void); - indStats getStats(void); - Cell* getLocn( // Return location (as pointer to Cell) - const short // option: 0 = get natal locn, 1 = get current locn - ); // - Patch* getNatalPatch(void); - void setYearSteps(int); - pathSteps getSteps(void); - settlePatch getSettPatch(void); - void setSettPatch(const settlePatch); - void setStatus(short); - void developing(void); - void develop(void); - void ageIncrement( // Age by one year - short // maximum age - if exceeded, the Individual dies - ); - void incFallow(void); // Inrement no. of reproductive seasons since last reproduction - void resetFallow(void); - void moveto( // Move to a specified neighbouring cell - Cell* // pointer to the new cell - ); - // Move to a new cell by sampling a dispersal distance from a single or double - // negative exponential kernel - // Returns 1 if still dispersing (including having found a potential patch), otherwise 0 - int moveKernel( - Landscape*, // pointer to Landscape - Species*, // pointer to Species - const short, // reproduction type (see Species) - const bool // absorbing boundaries? - ); - // Make a single movement step according to a mechanistic movement model - // Returns 1 if still dispersing (including having found a potential patch), otherwise 0 - int moveStep( - Landscape*, // pointer to Landscape - Species*, // pointer to Species - const short, // landscape change index - const bool // absorbing boundaries? - ); - movedata smsMove( // Move to a neighbouring cell according to the SMS algorithm - Landscape*, // pointer to Landscape - Species*, // pointer to Species - const short, // landscape change index - const bool, // TRUE if still in (or returned to) natal patch - const bool, // individual variability? - const bool // absorbing boundaries? - ); - array3x3d getSimDir( // Weight neighbouring cells on basis of current movement direction - const int, // current x co-ordinate - const int, // current y co-ordinate - const float // directional persistence value - ); - array3x3d getGoalBias( // Weight neighbouring cells on basis of goal bias - const int, // current x co-ordinate - const int, // current y co-ordinate - const int, // goal type: 0 = none, 1 = towards goal (NOT IMPLEMENTED), 2 = dispersal bias - const float // GOAL BIAS VALUE - ); - array3x3d calcWeightings( // Calculate weightings for neighbouring cells - const double, // base for power-law (directional persistence or goal bias value) - const double // direction in which lowest (unit) weighting is to be applied - ); - array3x3f getHabMatrix( // Weight neighbouring cells on basis of (habitat) costs - Landscape*, // pointer to Landscape - Species*, // pointer to Species - const int, // current x co-ordinate - const int, // current y co-ordinate - const short, // perceptual range (cells) - const short, // perceptual range evaluation method (see Species) - const short, // landscape change index - const bool // absorbing boundaries? - ); - void outGenetics( // Write records to genetics file - const int, // replicate - const int, // year - const int, // species number - const int, // landscape number - const bool // output as cross table? - ); -#if RS_RCPP - void outMovePath( // Write records to movement paths file - const int // year - ); -#endif - -private: - int indId; - short stage; - short sex; - short age; - short status; // 0 = initial status in natal patch / philopatric recruit - // 1 = disperser - // 2 = disperser awaiting settlement in possible suitable patch - // 3 = waiting between dispersal events - // 4 = completed settlement - // 5 = completed settlement in a suitable neighbouring cell - // 6 = died during transfer by failing to find a suitable patch - // (includes exceeding maximum number of steps or crossing - // absorbing boundary) - // 7 = died during transfer by constant, step-dependent, - // habitat-dependent or distance-dependent mortality - // 8 = failed to survive annual (demographic) mortality - // 9 = exceeded maximum age - short fallow; // reproductive seasons since last reproduction - bool isDeveloping; - Cell *pPrevCell; // pointer to previous Cell - Cell *pCurrCell; // pointer to current Cell - Patch *pNatalPatch; // pointer to natal Patch - emigTraits *emigtraits; // pointer to emigration traits - trfrKernTraits *kerntraits; // pointers to transfer by kernel traits - pathData *path; // pointer to path data for movement model - crwParams *crw; // pointer to CRW traits and data - smsdata *smsData; // pointer to variables required for SMS - settleTraits *setttraits; // pointer to settlement traits - std::queue memory; // memory of last N squares visited for SMS - - Genome *pGenome; - -}; - - -//--------------------------------------------------------------------------- - -double cauchy(double location, double scale) ; -double wrpcauchy (double location, double rho = exp(double(-1))); - -extern RSrandom *pRandom; - -#if RSDEBUG -extern ofstream DEBUGLOG; -#endif - -#if RS_RCPP -extern ofstream outMovePaths; -#endif - -#if RSDEBUG -void testIndividual(); -#endif - -//--------------------------------------------------------------------------- -#endif // IndividualH diff --git a/src/RScore/LICENSE b/src/RScore/LICENSE deleted file mode 100644 index 94a9ed0..0000000 --- a/src/RScore/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program 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. - - This program 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 this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/src/RScore/Landscape.cpp b/src/RScore/Landscape.cpp deleted file mode 100644 index be63ae9..0000000 --- a/src/RScore/Landscape.cpp +++ /dev/null @@ -1,2977 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Landscape.h" -//--------------------------------------------------------------------------- - -ifstream landscape; - -ofstream outConnMat; -ofstream outvisits; -#if RS_RCPP -ofstream outMovePaths; -#endif // RS_RCPP - -//--------------------------------------------------------------------------- - -// Initial species distribution functions - -InitDist::InitDist(Species *pSp) -{ -pSpecies = pSp; -resol = 0; -maxX = 0; -maxY = 0; -minEast = 0.0; -minNorth = 0.0; -} - -InitDist::~InitDist() { -int ncells = (int)cells.size(); -for (int i = 0; i < ncells; i++) - if (cells[i] != NULL) delete cells[i]; -cells.clear(); -} - -void InitDist::setDistribution(int nInit) { -int rr = 0; -int ncells = (int)cells.size(); -if (nInit == 0) { // set all cells to be initialised - for (int i = 0; i < ncells; i++) { - cells[i]->setCell(true); - } -} -else { // set specified number of cells at random to be initialised - if (nInit > ncells/2) { // use backwards selection method - for (int i = 0; i < ncells; i++) cells[i]->setCell(true); - for (int i = 0; i < (ncells-nInit); i++) { - do { - rr = pRandom->IRandom(0,ncells-1); - } while (!cells[rr]->selected()); - cells[rr]->setCell(false); - } - } - else { // use forwards selection method - for (int i = 0; i < ncells; i++) cells[i]->setCell(false); - for (int i = 0; i < nInit; i++) { - do { - rr = pRandom->IRandom(0,ncells-1); - } while (cells[rr]->selected()); - cells[rr]->setCell(true); - } - } -} -} - -// Set a specified cell (by position in cells vector) -void InitDist::setDistCell(int ix,bool init) { -cells[ix]->setCell(init); -} - -// Set a specified cell (by co-ordinates) -void InitDist::setDistCell(locn loc,bool init) { -locn cellloc; -int ncells = (int)cells.size(); -for (int i = 0; i < ncells; i++) { - cellloc = cells[i]->getLocn(); - if (cellloc.x == loc.x && cellloc.y == loc.y) { - cells[i]->setCell(init); - i = ncells; - } -} -} - -// Specified location is within the initial distribution? -bool InitDist::inInitialDist(locn loc) { -int ncells = (int)cells.size(); -for (int i = 0; i < ncells; i++) { - if (cells[i]->toInitialise(loc)) { // cell is to be initialised - return true; - } -} -return false; -} - -int InitDist::cellCount(void) { -return (int)cells.size(); -} - -// Return the co-ordinates of a specified initial distribution cell -locn InitDist::getCell(int ix) { -locn loc; -if (ix >= 0 && ix < (int)cells.size()) { - loc = cells[ix]->getLocn(); -} -else { - loc.x = loc.y = -666; // indicates invalid index specified -} -return loc; -} - -// Return the co-ordinates of a specified initial distribution cell if it has been -// selected - otherwise return negative co-ordinates -locn InitDist::getSelectedCell(int ix) { -locn loc; loc.x = loc.y = -666; -if (ix < (int)cells.size()) { - if (cells[ix]->selected()) { - loc = cells[ix]->getLocn(); - } -} -return loc; -} - -locn InitDist::getDimensions(void) { -locn d; d.x = maxX; d.y = maxY; return d; -} - -void InitDist::resetDistribution(void) { -int ncells = (int)cells.size(); -for (int i = 0; i < ncells; i++) { - cells[i]->setCell(false); -} -} - -//--------------------------------------------------------------------------- - -// Read species initial distribution file - -int InitDist::readDistribution(string distfile) { -#if RS_RCPP -wstring header; -#else -string header; -#endif -int p,nodata; -int ncols,nrows; -#if RS_RCPP -wifstream dfile; // species distribution file input stream -#else -ifstream dfile; // species distribution file input stream -#endif - -// open distribution file -#if !RS_RCPP || RSWIN64 - dfile.open(distfile.c_str()); -#else - dfile.open(distfile, std::ios::binary); - if(spdistraster.utf) { - // apply BOM-sensitive UTF-16 facet - dfile.imbue(std::locale(dfile.getloc(), new std::codecvt_utf16)); - } -#endif -if (!dfile.is_open()) return 21; - -// read landscape data from header records of distribution file -// NB headers of all files have already been compared -dfile >> header >> ncols >> header >> nrows >> header >> minEast >> header >> minNorth - >> header >> resol >> header >> nodata; -#if RS_RCPP -if (!dfile.good()) { - // corrupt file stream - StreamErrorR(distfile); - dfile.close(); - dfile.clear(); - return 144; -} -#endif - -maxX = ncols-1; maxY = nrows-1; - -// set up bad integer value to ensure that valid values are read -int badvalue = -9; if (nodata == -9) badvalue = -99; - -for (int y = nrows-1; y >= 0; y--) { - for (int x = 0; x < ncols; x++) { - p = badvalue; -#if RS_RCPP - if(dfile >> p) { -#else - dfile >> p; -#endif -#if RSDEBUG -//DEBUGLOG << "InitDist::readDistribution():" -// << " y = " << y << " x = " << x << " p = " << p << endl; -#endif - if (p == nodata || p == 0 || p == 1) { // only valid values - if (p == 1) { // species present - cells.push_back(new DistCell(x,y)); - } - } - else { // error in file - dfile.close(); dfile.clear(); - return 22; - } -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(distfile); - dfile.close(); - dfile.clear(); - return 144; - } -#endif - } -} -#if RS_RCPP - dfile >> p; - if (!dfile.eof()) EOFerrorR(distfile); -#endif - -dfile.close(); dfile.clear(); -return 0; -} - - -//--------------------------------------------------------------------------- - -// Landscape functions - -Landscape::Landscape(void) { -patchModel = false; spDist = false; generated = false; fractal = false; continuous = false; -dynamic = false; habIndexed = false; -resol = spResol = landNum = 0; -rasterType = 0; -nHab = nHabMax = 0; -dimX = dimY = 100; -minX = minY = 0; -maxX = maxY = 99; -minPct = maxPct = propSuit = hurst = 0.0; -maxCells = 100; -gpix = 1.0; -pix = (int)gpix; -minEast = minNorth = 0.0; -cells = 0; -#if RSDEBUG -// NOTE: do NOT write to output stream before it has been opened - it will be empty -//DebugGUI("Landscape::Landscape(): this = " + Int2Str((int)this) -// + " pCell = " + Int2Str((int)pCell)); -//DEBUGLOGGUI << "Landscape::Landscape(): this = " << this << " pCell = " << pCell << endl; -#endif -connectMatrix = 0; -epsGlobal = 0; -patchChgMatrix = 0; -costsChgMatrix = 0; - -#if RSDEBUG -//DEBUGLOG << "Landscape::Landscape():" -// << " rasterType= " << rasterType << endl; -#endif -#if RSDEBUG -//MemoLine(("Landscape::Landscape(): landscape created " + Int2Str(0) -// ).c_str()); -#endif -} - -Landscape::~Landscape() { - -#if RSDEBUG -//DebugGUI(("Landscape::~Landscape(): this=" + Int2Str((int)this) + " cells=" + Int2Str((int)cells) -// + " maxX=" + Int2Str(maxX) + " maxY=" + Int2Str(maxY)).c_str()); -#endif -if (cells != 0) { - for (int y = dimY-1; y >= 0; y--) { -#if RSDEBUG -//DebugGUI(("Landscape::~Landscape(): y=" + Int2Str(y) + " cells[y]=" + Int2Str((int)cells[y])).c_str()); -#endif - for (int x = 0; x < dimX; x++) { -#if RSDEBUG -//DebugGUI(("Landscape::~Landscape(): y=" + Int2Str(y) + " x=" + Int2Str(x) -// + " cells[y][x]=" + Int2Str((int)cells[y][x])).c_str()); -#endif - if (cells[y][x] != 0) delete cells[y][x]; - } - if (cells[y] != 0) { -#if RSDEBUG -//DebugGUI(("Landscape::~Landscape(): deleting cells[y]=" + Int2Str((int)cells[y])).c_str()); -#endif -// delete cells[y]; - delete[] cells[y]; - } - } - delete[] cells; - cells = 0; -} -#if RSDEBUG -//DebugGUI(("Landscape::~Landscape(): this=" + Int2Str((int)this) -// + " cells=" + Int2Str((int)cells)).c_str()); -#endif - -int npatches = (int)patches.size(); -for (int i = 0; i < npatches; i++) - if (patches[i] != NULL) delete patches[i]; -patches.clear(); - -int ndistns = (int)distns.size(); -for (int i = 0; i < ndistns; i++) - if (distns[i] != NULL) delete distns[i]; -distns.clear(); - -int ninitcells = (int)initcells.size(); -for (int i = 0; i < ninitcells; i++) - if (initcells[i] != NULL) delete initcells[i]; -initcells.clear(); - -patchnums.clear(); -habCodes.clear(); -colours.clear(); -landchanges.clear(); -patchchanges.clear(); - -deleteConnectMatrix(); -deletePatchChgMatrix(); -if (epsGlobal != 0) delete[] epsGlobal; - -#if RSDEBUG -//MemoLine(("Landscape::~Landscape(): landscape deleted " + Int2Str(1) -// ).c_str()); -#endif -} - -// Remove all patches and cells -// Used for replicating artificial landscape without deleting the landscape itself -void Landscape::resetLand(void) { - -#if RSDEBUG -//DebugGUI("Landscape::resetLand(): starting..."); -#endif -resetLandLimits(); -int npatches = (int)patches.size(); -#if RSDEBUG -//DebugGUI(("Landscape::resetLand(): npatches=" + Int2Str(npatches) -// ).c_str()); -#endif -for (int i = 0; i < npatches; i++) if (patches[i] != NULL) delete patches[i]; -patches.clear(); -#if RSDEBUG -//DebugGUI("Landscape::resetLand(): finished resetting patches"); -#endif - -#if RSDEBUG -//DebugGUI(("Landscape::resetLand(): this=" + Int2Str((int)this) -// + " cells=" + Int2Str((int)cells)).c_str()); -#endif -if (cells != 0) { - for(int y = dimY-1; y >= 0; y--){ -#if RSDEBUG -//DebugGUI(("Landscape::resetLand(): y=" + Int2Str(y) + " cells[y]=" + Int2Str((int)cells[y])).c_str()); -#endif - for (int x = 0; x < dimX; x++) { -#if RSDEBUG -//DebugGUI(("Landscape::resetLand(): y=" + Int2Str(y) + " x=" + Int2Str(x) -// + " cells[y][x]=" + Int2Str((int)cells[y][x])).c_str()); -#endif - if (cells[y][x] != 0) delete cells[y][x]; - } - if (cells[y] != 0) { -#if RSDEBUG -//DebugGUI(("Landscape::resetLand(): deleting cells[y]=" + Int2Str((int)cells[y])).c_str()); -#endif - delete[] cells[y]; - } - } - delete[] cells; - cells = 0; -} -#if RSDEBUG -//DebugGUI(("Landscape::resetLand(): this=" + Int2Str((int)this) -// + " cells=" + Int2Str((int)cells)).c_str()); -#endif -} - -void Landscape::setLandParams(landParams ppp,bool batchMode) -{ -generated = ppp.generated; patchModel = ppp.patchModel; spDist = ppp.spDist; -dynamic = ppp.dynamic; -landNum = ppp.landNum; -if (ppp.resol > 0) resol = ppp.resol; -if (ppp.spResol > 0 && ppp.spResol%ppp.resol == 0) spResol = ppp.spResol; -if ((ppp.rasterType >= 0 && ppp.rasterType <= 2) || ppp.rasterType == 9) - rasterType = ppp.rasterType; -if (ppp.nHab >= 1) nHab = ppp.nHab; -if (ppp.nHabMax >= 1) nHabMax = ppp.nHabMax; -if (ppp.dimX > 0) dimX = ppp.dimX; -if (ppp.dimY > 0) dimY = ppp.dimY; -if (ppp.minX >= 0 && ppp.maxX >= 0 && ppp.minX <= ppp.maxX && ppp.maxX < dimX) { - minX = ppp.minX; maxX = ppp.maxX; -} -else { - minX = 0; maxX = dimX - 1; -} -if (ppp.minY >= 0 && ppp.maxY >= 0 && ppp.minY <= ppp.maxY && ppp.maxY < dimY) { - minY = ppp.minY; maxY = ppp.maxY; -} -else { - minY = 0; maxY = dimY - 1; -} -if (batchMode && rasterType == 0) { - // in batch mode, set up sequential habitat codes if not already present - if (habCodes.size() == 0) { - for (int i = 0; i < nHabMax; i++) { - habCodes.push_back(i+1); - } - } -} -} - -landParams Landscape::getLandParams(void) -{ -landParams ppp; -ppp.generated = generated; ppp.patchModel = patchModel; ppp.spDist = spDist; -ppp.dynamic = dynamic; -ppp.landNum = landNum; -ppp.resol = resol; ppp.spResol = spResol; -ppp.rasterType = rasterType; -ppp.nHab = nHab; ppp.nHabMax = nHabMax; -ppp.dimX = dimX; ppp.dimY = dimY; -ppp.minX = minX; ppp.minY = minY; -ppp.maxX = maxX; ppp.maxY = maxY; -return ppp; -} - -landData Landscape::getLandData(void) { -landData dd; -dd.resol = resol; -dd.dimX = dimX; dd.dimY = dimY; -dd.minX = minX; dd.minY = minY; -dd.maxX = maxX; dd.maxY = maxY; -return dd; -} - -void Landscape::setGenLandParams(genLandParams ppp) -{ -fractal = ppp.fractal; -continuous = ppp.continuous; -if (ppp.minPct > 0.0 && ppp.minPct < 100.0) minPct = ppp.minPct; -if (ppp.maxPct > 0.0 && ppp.maxPct <= 100.0) maxPct = ppp.maxPct; -if (ppp.propSuit >= 0.0 && ppp.propSuit <= 1.0) propSuit = ppp.propSuit; -if (ppp.hurst > 0.0 && ppp.hurst < 1.0) hurst = ppp.hurst; -if (ppp.maxCells > 0) maxCells = ppp.maxCells; -} - -genLandParams Landscape::getGenLandParams(void) -{ -genLandParams ppp; -ppp.fractal = fractal; ppp.continuous = continuous; -ppp.minPct = minPct; ppp.maxPct = maxPct; ppp.propSuit = propSuit; ppp.hurst = hurst; -ppp.maxCells = maxCells; -return ppp; -} - -void Landscape::setLandLimits(int x0,int y0,int x1,int y1) { -if (x0 >= 0 && x1 >= 0 && x0 <= x1 && x1 < dimX -&& y0 >= 0 && y1 >= 0 && y0 <= y1 && y1 < dimY) { - minX = x0; maxX = x1; minY = y0; maxY = y1; -} -} - -void Landscape::resetLandLimits(void) { -minX = minY = 0; maxX = dimX-1; maxY = dimY-1; -} - -//--------------------------------------------------------------------------- - -void Landscape::setLandPix(landPix p) { -if (p.pix > 0) pix = p.pix; -if (p.gpix > 0.0) gpix = p.gpix; -} - -landPix Landscape::getLandPix(void) { -landPix p; -p.pix = pix; p.gpix = gpix; -return p; -} - -void Landscape::setOrigin(landOrigin origin) { -minEast = origin.minEast; minNorth = origin.minNorth; -} - -landOrigin Landscape::getOrigin(void) { -landOrigin origin; -origin.minEast = minEast; origin.minNorth = minNorth; -return origin; -} - -//--------------------------------------------------------------------------- - -// Functions to handle habitat codes - -bool Landscape::habitatsIndexed(void) { return habIndexed; } - -void Landscape::listHabCodes(void) { -int nhab = (int)habCodes.size(); -#if RS_RCPP && !R_CMD -Rcpp::Rcout << endl; -for (int i = 0; i < nhab; i++) { - Rcpp::Rcout << "Habitat code[ " << i << "] = " << habCodes[i] << endl; -} -Rcpp::Rcout << endl; -#else -cout << endl; -for (int i = 0; i < nhab; i++) { - cout << "Habitat code[ " << i << "] = " << habCodes[i] << endl; -} -cout << endl; -#endif -} - -void Landscape::addHabCode(int hab) { -int nhab = (int)habCodes.size(); -bool addCode = true; -for (int i = 0; i < nhab; i++) { - if (hab == habCodes[i]) { - addCode = false; i = nhab+1; - } -} -if (addCode) { habCodes.push_back(hab); nHab++; } -} - -// Get the index number of the specified habitat in the habitats vector -int Landscape::findHabCode(int hab) { -int nhab = (int)habCodes.size(); -for (int i = 0; i < nhab; i++) { - if (hab == habCodes[i]) return i; -} -return -999; -} - -// Get the specified habitat code -int Landscape::getHabCode(int ixhab) { -if (ixhab < (int)habCodes.size()) return habCodes[ixhab]; -else return -999; -} - -void Landscape::clearHabitats(void) { -habCodes.clear(); -colours.clear(); -} - -void Landscape::addColour(rgb c) { -colours.push_back(c); -} - -void Landscape::changeColour(int i,rgb col) { -int ncolours = (int)colours.size(); -if (i >= 0 && i < ncolours) { - if (col.r >=0 && col.r <= 255 && col.g >=0 && col.g <= 255 && col.b >=0 && col.b <= 255) - colours[i] = col; -} -} - -rgb Landscape::getColour(int ix) { -return colours[ix]; -} - -int Landscape::colourCount(void) { -return (int)colours.size(); -} - -//--------------------------------------------------------------------------- -void Landscape::setCellArray(void) { -#if RSDEBUG -//DebugGUI(("Landscape::setCellArray(): start: this=" + Int2Str((int)this) -// + " cells=" + Int2Str((int)cells)).c_str()); -#endif -if (cells != 0) resetLand(); -//cells = new Cell **[maxY+1]; -cells = new Cell **[dimY]; -#if RSDEBUG -//DebugGUI(("Landscape::setCellArray(): cells=" + Int2Str((int)cells)).c_str()); -#endif -for (int y = dimY-1; y >= 0; y--) { - cells[y] = new Cell *[dimX]; -#if RSDEBUG -//DebugGUI(("Landscape::setCellArray(): y=" + Int2Str(y) -// + " cells[y]=" + Int2Str((int)cells[y])).c_str()); -#endif - for (int x = 0; x < dimX; x++) { - cells[y][x] = 0; - } -} -#if RSDEBUG -//DebugGUI(("Landscape::setCellArray(): end: this=" + Int2Str((int)this) -// + " cells=" + Int2Str((int)cells)).c_str()); -#endif -} - -void Landscape::addPatchNum(int p) { -int npatches = (int)patchnums.size(); -bool addpatch = true; -for (int i = 0; i < npatches; i++) { - if (p == patchnums[i]) { - addpatch = false; i = npatches+1; - } -} -if (addpatch) patchnums.push_back(p); -} - - -//--------------------------------------------------------------------------- -/* Create an artificial landscape (random or fractal), which can be -either binary (habitat index 0 is the matrix, 1 is suitable habitat) -or continuous (0 is the matrix, >0 is suitable habitat) */ -void Landscape::generatePatches(void) -{ -int x,y,ncells; -double p; -Patch *pPatch; -Cell *pCell; - -vector ArtLandscape; - -#if RSDEBUG -//int iiiiii = (int)fractal; -//DEBUGLOG << "Landscape::generatePatches(): (int)fractal=" << iiiiii -// << " rasterType=" << rasterType -// << " continuous=" << continuous -// << " dimX=" << dimX << " dimY=" << dimY -// << " propSuit=" << propSuit -// << " hurst=" << hurst -// << " maxPct=" << maxPct << " minPct=" << minPct -// << endl; -#endif - -setCellArray(); - -int patchnum = 0; // initial patch number for cell-based landscape -// create patch 0 - the matrix patch (even if there is no matrix) -newPatch(patchnum++); - -// as landscape generator returns cells in a random sequence, first set up all cells -// in the landscape in the correct sequence, then update them and create patches for -// habitat cells -for (int yy = dimY-1; yy >= 0; yy--) { - for (int xx = 0; xx < dimX; xx++) { -#if RSDEBUG -//DEBUGLOG << "Landscape::generatePatches(): yy=" << yy << " xx=" << xx << endl; -#endif - addNewCellToLand(xx,yy,0); - } -} - -if (continuous) rasterType = 2; -else rasterType = 0; -if (fractal) { - p = 1.0 - propSuit; - // fractal_landscape() requires Max_prop > 1 (but does not check it!) - // as in turn it calls runif(1.0,Max_prop) - double maxpct; - if (maxPct < 1.0) maxpct = 100.0; else maxpct = maxPct; - - ArtLandscape = fractal_landscape(dimY,dimX,hurst,p,maxpct,minPct); - - vector::iterator iter = ArtLandscape.begin(); - while (iter != ArtLandscape.end()) { - x = iter->y_coord; y = iter->x_coord; -#if RSDEBUG -//DEBUGLOG << "Landscape::generatePatches(): x=" << x << " y=" << y -// << " iter->avail=" << iter->avail -// << " iter->value=" << iter->value << endl; -#endif - pCell = findCell(x,y); - if (continuous) { - if (iter->value > 0.0) { // habitat - pPatch = newPatch(patchnum++); - addCellToPatch(pCell,pPatch,iter->value); - } - else { // matrix - addCellToPatch(pCell,patches[0],iter->value); - } - } - else { // discrete - if (iter->avail == 0) { // matrix - addCellToPatch(pCell,patches[0]); - } - else { // habitat - pPatch = newPatch(patchnum++); - addCellToPatch(pCell,pPatch); - pCell->changeHabIndex(0,1); - } - } - iter++; - } -} -else { // random landscape - int hab = 0; - ncells = (int)((float)(dimX) * (float)(dimY) * propSuit + 0.00001); // no. of cells to initialise -#if RSDEBUG -//DEBUGLOG << "Landscape::generatePatches(): dimX=" << dimX << " dimY=" << dimY -// << " propSuit=" << propSuit -// << " PRODUCT=" << ((float)(dimX) * (float)(dimY) * propSuit + 0.00001) -// << " ncells=" << ncells << endl; -#endif - int i = 0; - do { - do { - x = pRandom->IRandom(0,dimX-1); y = pRandom->IRandom(0,dimY-1); - pCell = findCell(x,y); - hab = pCell->getHabIndex(0); - } while (hab > 0); -#if RSDEBUG -//DEBUGLOG << "Landscape::generatePatches() 00000: y=" << y << " x=" << x -// << " i=" << i << " hab=" << hab << " patchnum=" << patchnum -// << endl; -#endif - pPatch = newPatch(patchnum++); - pCell = findCell(x,y); - addCellToPatch(pCell,pPatch); - pCell->changeHabIndex(0,1); - if (continuous) { - pCell->setHabitat((float)(minPct + pRandom->Random() * (maxPct - minPct))); - } - i++; - } while (i < ncells); - // remaining cells need to be added to the matrix patch - p = 0.0; - x = 0; - for (int yy = dimY-1; yy >= 0; yy--) { - for (int xx = 0; xx < dimX; xx++) { - pCell = findCell(xx,yy); - if (continuous) { - if (pCell->getHabitat(0) <= 0.0) - { - addCellToPatch(pCell,patches[0],(float)p); - } - } - else { // discrete - if (pCell->getHabIndex(0) == 0) { -#if RSDEBUG -//DEBUGLOG << "Landscape::generatePatches() 11111: yy=" << yy << " xx=" << xx -// << endl; -#endif - addCellToPatch(pCell,patches[0],x); - } - } - } - } -} - -#if RSDEBUG -//DEBUGLOG << "Landscape::generatePatches(): finished, no. of patches = " -// << patchCount() << endl; -#endif - -} - -//--------------------------------------------------------------------------- - -// Landscape patch-management functions - -//--------------------------------------------------------------------------- -/* Create a patch for each suitable cell of a cell-based landscape (all other -habitat cells are added to the matrix patch) */ -void Landscape::allocatePatches(Species *pSpecies) -{ -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): pSpecies=" << pSpecies -// << " N patches=" << (int)patches.size() << endl; -#endif -//int hx; -float habK; -Patch *pPatch; -Cell *pCell; - -// delete all existing patches -int npatches = (int)patches.size(); -for (int i = 0; i < npatches; i++) { -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): i=" << i -// << " patches[i]=" << patches[i] << endl; -#endif - if (patches[i] != NULL) delete patches[i]; -} -patches.clear(); -// create the matrix patch -patches.push_back(new Patch(0,0)); -Patch *matrixPatch = patches[0]; -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): npatches=" << npatches -// << " N patches=" << (int)patches.size() << endl; -#endif -int patchnum = 1; - -switch (rasterType) { - -case 0: // habitat codes - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): x=" << x << " y=" << y -// << " cells=" << cells[y][x] << endl; -#endif - if (cells[y][x] != 0) { // not no-data cell - pCell = cells[y][x]; -// hx = pCell->getHabIndex(); -// habK = pSpecies->getHabK(hx); - habK = 0.0; - int nhab = pCell->nHabitats(); - for (int i = 0; i < nhab; i++) { - habK += pSpecies->getHabK(pCell->getHabIndex(i)); -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): x=" << x << " y=" << y -// << " i=" << i -// << " cells[y][x]=" << cells[y][x] -// << " pCell=" << pCell -// << " habK=" << habK << endl; -#endif - } - if (habK > 0.0) { // cell is suitable - create a patch for it - pPatch = newPatch(patchnum++); - addCellToPatch(pCell,pPatch); - } - else { // cell is not suitable - add to the matrix patch - addCellToPatch(pCell,matrixPatch); - pPatch = 0; - } - } - } - } - break; -case 1: // habitat cover - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): x=" << x << " y=" << y -// << " cells=" << cells[y][x] << endl; -#endif - if (cells[y][x] != 0) { // not no-data cell - pCell = cells[y][x]; - habK = 0.0; - int nhab = pCell->nHabitats(); -// for (int i = 0; i < nHab; i++) - for (int i = 0; i < nhab; i++) - { - habK += pSpecies->getHabK(i) * pCell->getHabitat(i) / 100.0f; -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): x=" << x << " y=" << y -// << " i=" << i -// << " cells[y][x]=" << cells[y][x] -// << " pCell=" << pCell -// << " habK=" << habK << endl; -#endif - } - if (habK > 0.0) { // cell is suitable - create a patch for it - pPatch = newPatch(patchnum++); - addCellToPatch(pCell,pPatch); - } - else { // cell is not suitable - add to the matrix patch - addCellToPatch(pCell,matrixPatch); - pPatch = 0; - } - } - } - } - break; -case 2: // habitat quality - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): x=" << x << " y=" << y -// << " cells=" << cells[y][x] << endl; -#endif - if (cells[y][x] != 0) { // not no-data cell - pCell = cells[y][x]; - habK = 0.0; - int nhab = pCell->nHabitats(); -// for (int i = 0; i < nHab; i++) - for (int i = 0; i < nhab; i++) - { - habK += pSpecies->getHabK(0) * pCell->getHabitat(i) / 100.0f; -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): x=" << x << " y=" << y -// << " i=" << i -// << " cells[y][x]=" << cells[y][x] -// << " pCell=" << pCell -// << " habK=" << habK << endl; -#endif - } - if (habK > 0.0) { // cell is suitable (at some time) - create a patch for it - pPatch = newPatch(patchnum++); - addCellToPatch(pCell,pPatch); - } - else { // cell is never suitable - add to the matrix patch - addCellToPatch(pCell,matrixPatch); - pPatch = 0; - } - } - } - } - break; - -} // end of switch (rasterType) - -#if RSDEBUG -//DEBUGLOG << "Landscape::allocatePatches(): finished, N patches = " << (int)patches.size() << endl; -#endif - -} - -Patch* Landscape::newPatch(int num) -{ -int npatches = (int)patches.size(); -patches.push_back(new Patch(num,num)); -return patches[npatches]; -} - -Patch* Landscape::newPatch(int seqnum,int num) -{ -int npatches = (int)patches.size(); -patches.push_back(new Patch(seqnum,num)); -return patches[npatches]; -} - -void Landscape::resetPatches(void) { -int npatches = (int)patches.size(); -for (int i = 0; i < npatches; i++) { - patches[i]->resetLimits(); -} -} - -void Landscape::addNewCellToLand(int x,int y,float q) { -if (q < 0.0) // no-data cell - no Cell created - cells[y][x] = 0; -else - cells[y][x] = new Cell(x,y,0,q); -} - -void Landscape::addNewCellToLand(int x,int y,int hab) { -if (hab < 0) // no-data cell - no Cell created - cells[y][x] = 0; -else - cells[y][x] = new Cell(x,y,0,hab); -} - -void Landscape::addNewCellToPatch(Patch *pPatch,int x,int y,float q) { -if (q < 0.0) { // no-data cell - no Cell created - cells[y][x] = 0; -} -else { // create the new cell - cells[y][x] = new Cell(x,y,(intptr)pPatch,q); - if (pPatch != 0) { // not the matrix patch - // add the cell to the patch - pPatch->addCell(cells[y][x],x,y); - } -} -} - -void Landscape::addNewCellToPatch(Patch *pPatch,int x,int y,int hab) { -if (hab < 0) // no-data cell - no Cell created - cells[y][x] = 0; -else { // create the new cell - cells[y][x] = new Cell(x,y,(intptr)pPatch,hab); - if (pPatch != 0) { // not the matrix patch - // add the cell to the patch - pPatch->addCell(cells[y][x],x,y); - } -} -} - -void Landscape::addCellToPatch(Cell *pCell,Patch *pPatch) { -pCell->setPatch((intptr)pPatch); -locn loc = pCell->getLocn(); -// add the cell to the patch -pPatch->addCell(pCell,loc.x,loc.y); -} - -void Landscape::addCellToPatch(Cell *pCell,Patch *pPatch,float q) { -pCell->setPatch((intptr)pPatch); -// update the habitat type of the cell -pCell->setHabitat(q); -locn loc = pCell->getLocn(); -// add the cell to the patch -pPatch->addCell(pCell,loc.x,loc.y); -} - -void Landscape::addCellToPatch(Cell *pCell,Patch *pPatch,int hab) { -pCell->setPatch((intptr)pPatch); -// update the habitat type of the cell -pCell->setHabIndex(hab); -locn loc = pCell->getLocn(); -// add the cell to the patch -pPatch->addCell(pCell,loc.x,loc.y); -} - -patchData Landscape::getPatchData(int ix) { -patchData ppp; -ppp.pPatch = patches[ix]; ppp.patchNum = patches[ix]->getPatchNum(); -ppp.nCells = patches[ix]->getNCells(); -locn randloc; randloc.x = -666; randloc.y = -666; -Cell *pCell = patches[ix]->getRandomCell(); -if (pCell != 0) { - randloc = pCell->getLocn(); -} -ppp.x = randloc.x; ppp.y = randloc.y; -return ppp; -} - -bool Landscape::existsPatch(int num) { -int npatches = (int)patches.size(); -for (int i = 0; i < npatches; i++) { - if (num == patches[i]->getPatchNum()) return true; -} -return false; -} - -Patch* Landscape::findPatch(int num) { -int npatches = (int)patches.size(); -for (int i = 0; i < npatches; i++) { - if (num == patches[i]->getPatchNum()) return patches[i]; -} -return 0; -} - -void Landscape::resetPatchPopns(void) { -int npatches = (int)patches.size(); -for (int i = 0; i < npatches; i++) { - patches[i]->resetPopn(); -} -} - -void Landscape::updateCarryingCapacity(Species *pSpecies,int yr,short landIx) { -envGradParams grad = paramsGrad->getGradient(); -bool gradK = false; -if (grad.gradient && grad.gradType == 1) gradK = true; // gradient in carrying capacity -patchLimits landlimits; -landlimits.xMin = minX; landlimits.xMax = maxX; -landlimits.yMin = minY; landlimits.yMax = maxY; -#if RSDEBUG -//DEBUGLOG << "Landscape::updateCarryingCapacity(): yr=" << yr -// << " xMin=" << landlimits.xMin << " yMin=" << landlimits.yMin -// << " xMax=" << landlimits.xMax << " yMax=" << landlimits.yMax -// << endl; -#endif -int npatches = (int)patches.size(); -for (int i = 0; i < npatches; i++) { - if (patches[i]->getPatchNum() != 0) { // not matrix patch - patches[i]->setCarryingCapacity(pSpecies,landlimits, - getGlobalStoch(yr),nHab,rasterType,landIx,gradK); - } -} - -} - -Cell* Landscape::findCell(int x,int y) { -if (x >= 0 && x < dimX && y >= 0 && y < dimY) return cells[y][x]; -else return 0; -} - -int Landscape::patchCount(void) { -return (int)patches.size(); -} - -void Landscape::listPatches(void) { -patchLimits p; -int npatches = (int)patches.size(); -#if RS_RCPP && !R_CMD -Rcpp::Rcout << endl; -for (int i = 0; i < npatches; i++) { - p = patches[i]->getLimits(); - Rcpp::Rcout << "Patch " << patches[i]->getPatchNum() - << " xMin = " << p.xMin << " xMax = " << p.xMax - << " \tyMin = " << p.yMin << " yMax = " << p.yMax - << endl; -} -Rcpp::Rcout << endl; -#else -cout << endl; -for (int i = 0; i < npatches; i++) { - p = patches[i]->getLimits(); - cout << "Patch " << patches[i]->getPatchNum() - << " xMin = " << p.xMin << " xMax = " << p.xMax - << " \tyMin = " << p.yMin << " yMax = " << p.yMax - << endl; -} -cout << endl; -#endif -} - -// Check that total cover of any cell does not exceed 100% -// and identify matrix cells -int Landscape::checkTotalCover(void) { -if (rasterType != 1) return 0; // not appropriate test -int nCells = 0; -for(int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - if (cells[y][x] != 0) - { // not a no-data cell - float sumCover = 0.0; - for (int i = 0; i < nHab; i++) { - sumCover += cells[y][x]->getHabitat(i); -#if RSDEBUG -//DebugGUI(("Landscape::checkTotalCover(): y=" + Int2Str(y) -// + " x=" + Int2Str(x) -// + " i=" + Int2Str(i) -// + " sumCover=" + Float2Str(sumCover) -// ).c_str()); -#endif - } - if (sumCover > 100.00001) nCells++; // decimal part to allow for floating point error - if (sumCover <= 0.0) // cell is a matrix cell - cells[y][x]->setHabIndex(0); - else - cells[y][x]->setHabIndex(1); - } - } -} -return nCells; -} - -// Convert habitat codes stored on loading habitat codes landscape to -// sequential sorted index numbers -void Landscape::updateHabitatIndices(void) { -// sort codes -sort (habCodes.begin(),habCodes.end()); -nHab = (int)habCodes.size(); -// convert codes in landscape -int h; -int changes = (int)landchanges.size(); -#if RSDEBUG -//DebugGUI(("Landscape::updateHabitatIndices(): nHab=" + Int2Str(nHab) -// + " changes=" + Int2Str(changes) -// ).c_str()); -#endif -for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - if (cells[y][x] != 0) { // not a no-data cell - for (int c = 0; c <= changes; c++) { - h = cells[y][x]->getHabIndex(c); -#if RSDEBUG -//DebugGUI(("Landscape::updateHabitatIndices() 00000: y=" + Int2Str(y) -// + " x=" + Int2Str(x) + " c=" + Int2Str(c) + " h=" + Int2Str(h) -// ).c_str()); -#endif - if (h >= 0) { - h = findHabCode(h); -#if RSDEBUG -//DebugGUI(("Landscape::updateHabitatIndices() 11111: y=" + Int2Str(y) -// + " x=" + Int2Str(x) + " c=" + Int2Str(c) + " h=" + Int2Str(h) -// ).c_str()); -#endif - cells[y][x]->changeHabIndex(c,h); - } - } - } - } -} -habIndexed = true; -} - -void Landscape::setEnvGradient(Species *pSpecies,bool initial) -{ -float dist_from_opt,dev; -float habK; -//int hab; -double envval; -// gradient parameters -envGradParams grad = paramsGrad->getGradient(); -#if RSDEBUG -//DEBUGLOG << "Landscape::setEnvGradient(): grad.opt_y = " << grad.opt_y -// << " grad.grad_inc = " << grad.grad_inc << " grad.factor " << grad.factor -// << endl; -#endif -for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - // NB: gradient lies in range 0-1 for all types, and is applied when necessary... - // ... implies gradient increment will be dimensionless in range 0-1 (but << 1) - if (cells[y][x] != 0) { // not no-data cell - habK = 0.0; - int nhab = cells[y][x]->nHabitats(); - for (int i = 0; i < nhab; i++) { - switch (rasterType) { - case 0: - habK += pSpecies->getHabK(cells[y][x]->getHabIndex(i)); - break; - case 1: - habK += pSpecies->getHabK(i) * cells[y][x]->getHabitat(i) / 100.0f; - break; - case 2: - habK += pSpecies->getHabK(0) * cells[y][x]->getHabitat(i) / 100.0f; - break; - } - } -#if RSDEBUG -//DEBUGLOG << "Landscape::setEnvGradient(): y=" << y << " x=" << x -// << " dist_from_opt=" << dist_from_opt << " rasterType=" << rasterType << " hab=" << hab -// << endl; -#endif - if (habK > 0.0) { // suitable cell - if (initial) { // set local environmental deviation - cells[y][x]->setEnvDev((float)pRandom->Random()*(2.0f) - 1.0f); - } - dist_from_opt = (float)(fabs((double)grad.opt_y - (double)y)); - dev = cells[y][x]->getEnvDev(); - envval = 1.0 - dist_from_opt*grad.grad_inc + dev*grad.factor; -#if RSDEBUG -//DEBUGLOG << "Landscape::setEnvGradient(): y=" << y << " x=" << x -// << " dist_from_opt=" << dist_from_opt << " dev=" << dev << " p=" << p -// << endl; -#endif - if (envval < 0.000001) envval = 0.0; - if (envval > 1.0) envval = 1.0; - } - else envval = 0.0; - cells[y][x]->setEnvVal((float)envval); - } - } -} - -} - -void Landscape::setGlobalStoch(int nyears) { -envStochParams env = paramsStoch->getStoch(); -if (epsGlobal != 0) delete[] epsGlobal; -epsGlobal = new float[nyears]; -epsGlobal[0] = (float)(pRandom->Normal(0.0,env.std)*sqrt(1.0-(env.ac*env.ac))); -for (int i = 1; i < nyears; i++){ - epsGlobal[i] = (float)(env.ac*epsGlobal[i-1] + pRandom->Normal(0.0,env.std)*sqrt(1.0-(env.ac*env.ac))); -} -} - -float Landscape::getGlobalStoch(int yr) { -if (epsGlobal != 0 && yr >= 0) { - return epsGlobal[yr]; -} -else return 0.0; -} - -void Landscape::updateLocalStoch(void) { -envStochParams env = paramsStoch->getStoch(); -float randpart; -for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - if (cells[y][x] != 0) { // not a no-data cell - randpart = (float)(pRandom->Normal(0.0,env.std) * sqrt(1.0-(env.ac*env.ac))); -#if RSDEBUG -//DEBUGLOG << "Landscape::updateLocalStoch(): y=" << y << " x=" << x -// << " env.std= " << env.std << " env.ac= " << env.ac << " randpart= " << randpart -// << endl; -#endif - cells[y][x]->updateEps((float)env.ac,randpart); - } - } -} - -} - -void Landscape::resetCosts(void) { -for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - if (cells[y][x] != 0) { // not a no-data cell - cells[y][x]->resetCost(); - } - } -} -} - -void Landscape::resetEffCosts(void) { -for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - if (cells[y][x] != 0) { // not a no-data cell - cells[y][x]->resetEffCosts(); - } - } -} -} - -//--------------------------------------------------------------------------- - -// Dynamic landscape functions - -void Landscape::setDynamicLand(bool dyn) { dynamic = dyn; } - -void Landscape::addLandChange(landChange c) { -#if RSDEBUG -//DebugGUI(("Landscape::addLandChange(): chgnum=" + Int2Str(c.chgnum) -// + " chgyear=" + Int2Str(c.chgyear) -// ).c_str()); -#endif -landchanges.push_back(c); -} - -int Landscape::numLandChanges(void) { return (int)landchanges.size(); } - -landChange Landscape::getLandChange(short ix) { -landChange c; c.chgnum = c.chgyear = 0; -c.habfile = c.pchfile = c.costfile = "none"; -int nchanges = (int)landchanges.size(); -if (ix < nchanges) c = landchanges[ix]; -return c; -} - -void Landscape::deleteLandChanges(void) { -while (landchanges.size() > 0) landchanges.pop_back(); -landchanges.clear(); -} - -#if RS_RCPP && !R_CMD -int Landscape::readLandChange(int filenum, bool costs, wifstream& hfile, wifstream& pfile, wifstream& cfile, int habnodata, int pchnodata, int costnodata) -#else -int Landscape::readLandChange(int filenum,bool costs) -#endif -{ - -#if RSDEBUG -DEBUGLOG << "Landscape::readLandChange(): filenum=" << filenum << " costs=" << int(costs) - << endl; -#endif - -#if RS_RCPP -wstring header; -#else -string header; -int ncols,nrows,habnodata,costnodata,pchnodata; -costnodata = 0; -pchnodata = 0; -#endif -int h = 0,p = 0,c = 0, pchseq = 0; -float hfloat,pfloat,cfloat; -simParams sim = paramsSim->getSim(); - -if (filenum < 0) return 19; - -//if (patchModel && (rasterType == 0 || rasterType == 2)) { -// if (filenum == 0) { // first change -// createPatchChgMatrix(); -// } -// pchseq = patchCount(); -//} -if (patchModel) pchseq = patchCount(); - -#if !RS_RCPP - ifstream hfile; // habitat file input stream - ifstream pfile; // patch file input stream - ifstream cfile; // costs file input stream -#endif - -#if !RS_RCPP || R_CMD -// open habitat file and optionally also patch and costs files -hfile.open(landchanges[filenum].habfile.c_str()); -if (!hfile.is_open()) return 30; -if (patchModel) { - pfile.open(landchanges[filenum].pchfile.c_str()); - if (!pfile.is_open()) { - hfile.close(); hfile.clear(); - return 31; - } -} -if (costs) { - cfile.open(landchanges[filenum].costfile.c_str()); - if (!cfile.is_open()) { - hfile.close(); hfile.clear(); - if (pfile.is_open()) { - pfile.close(); pfile.clear(); - } - return 32; - } -} - -// read header records of habitat (and patch) file(s) -// NB headers of all files have already been compared -hfile >> header >> ncols >> header >> nrows >> header >> hfloat >> header >> hfloat - >> header >> hfloat >> header >> habnodata; -if (patchModel) { - for (int i = 0; i < 5; i++) pfile >> header >> pfloat; - pfile >> header >> pchnodata; -} -if (costs) { - for (int i = 0; i < 5; i++) cfile >> header >> cfloat; - cfile >> header >> costnodata; -} -#endif - -// set up bad float values to ensure that valid values are read -float badhfloat = -9.0; if (habnodata == -9) badhfloat = -99.0; -float badpfloat = -9.0; if (pchnodata == -9) badpfloat = -99.0; -float badcfloat = -9.0; if (costnodata == -9) badcfloat = -99.0; - -switch (rasterType) { - -case 0: // raster with habitat codes - 100% habitat each cell - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - hfloat = badhfloat; -#if RS_RCPP - if(hfile >> hfloat) { -#else - hfile >> hfloat; -#endif - h = (int)hfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR("habitatchgfile"); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 171; - } -#endif - if (patchModel) { - pfloat = badpfloat; -#if RS_RCPP - if(pfile >> pfloat) { -#else - pfile >> pfloat; -#endif - p = (int)pfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR("patchchgfile"); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 172; - } -#endif - } - if (costs) { - cfloat = badcfloat; -#if RS_RCPP - if(cfile >> cfloat) { -#else - cfile >> cfloat; -#endif - c = (int)cfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR("costchgfile"); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 173; - } -#endif - } -#if RSDEBUG -//DebugGUI(("Landscape::readLandscape(): x=" + Int2Str(x) + " y=" + Int2Str(y) -// + " h=" + Int2Str(h) + " p=" + Int2Str(p) -//).c_str()); -#endif - if (cells[y][x] != 0) { // not a no data cell (in initial landscape) - if (h == habnodata) { // invalid no data cell in change map - hfile.close(); hfile.clear(); - return 36; - } - else { - if (h < 0 || (sim.batchMode && (h < 1 || h > nHabMax))) { - // invalid habitat code - hfile.close(); hfile.clear(); - if (patchModel) { pfile.close(); pfile.clear(); } - return 33; - } - else { - addHabCode(h); - cells[y][x]->setHabIndex(h); - } - } - if (patchModel) { - if (p < 0 || p == pchnodata) { // invalid patch code - #if RS_RCPP && !R_CMD - if (p == pchnodata) Rcpp::Rcout << "Found patch NA in valid habitat cell." << std::endl; - else Rcpp::Rcout << "Found negative patch ID in valid habitat cell." << std::endl; - #endif - hfile.close(); hfile.clear(); - pfile.close(); pfile.clear(); - return 34; - } - else { - patchChgMatrix[y][x][2] = p; - if (p > 0 && !existsPatch(p)) { - addPatchNum(p); - newPatch(pchseq++,p); - } - } - } - if (costs) { - if (c < 1) { // invalid cost - hfile.close(); hfile.clear(); - if (pfile.is_open()) { - pfile.close(); pfile.clear(); - } - return 38; - } - else { - costsChgMatrix[y][x][2] = c; - } - } - } - } - } -#if RS_RCPP - hfile >> hfloat; - if (!hfile.eof()) EOFerrorR("habitatchgfile"); - if (patchModel) - { - pfile >> pfloat; - if (!pfile.eof()) EOFerrorR("patchchgfile"); - } - if (costs) - { - cfile >> cfloat; - if (!cfile.eof()) EOFerrorR("costchgfile"); - } -#endif - break; - - case 2: // habitat quality - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - hfloat = badhfloat; -#if RS_RCPP - if(hfile >> hfloat) { -#else - hfile >> hfloat; -#endif - h = (int)hfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR("habitatchgfile"); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 172; - } -#endif - if (patchModel) { - pfloat = badpfloat; -#if RS_RCPP - if(pfile >> pfloat) { -#else - pfile >> pfloat; -#endif - p = (int)pfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR("patchchgfile"); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 175; - } -#endif - } - if (costs) { - cfloat = badcfloat; -#if RS_RCPP - if(cfile >> cfloat) { -#else - cfile >> cfloat; -#endif - c = (int)cfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR("costchgfile"); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 173; - } -#endif - } -#if RSDEBUG -//MemoLine(("y=" + Int2Str(y) + " x=" + Int2Str(x) + " hfloat=" + Float2Str(hfloat) -// + " p=" + Int2Str(p)).c_str()); -#endif - if (cells[y][x] != 0) { // not a no data cell (in initial landscape) - if (h == habnodata) { // invalid no data cell in change map - hfile.close(); hfile.clear(); - if (patchModel) { pfile.close(); pfile.clear(); } - return 36; - } - else { - if (hfloat < 0.0 || hfloat > 100.0) { // invalid quality score - hfile.close(); hfile.clear(); - if (patchModel) { pfile.close(); pfile.clear(); } - return 37; - } - else { - cells[y][x]->setHabitat(hfloat); - } - } - if (patchModel) { - if (p < 0 || p == pchnodata) { // invalid patch code - #if RS_RCPP && !R_CMD - if (p == pchnodata) Rcpp::Rcout << "Found patch NA in valid habitat cell." << std::endl; - else Rcpp::Rcout << "Found negative patch ID in valid habitat cell." << std::endl; - #endif - hfile.close(); hfile.clear(); - pfile.close(); pfile.clear(); - return 34; - } - else { - patchChgMatrix[y][x][2] = p; - if (p > 0 && !existsPatch(p)) { - addPatchNum(p); - newPatch(pchseq++,p); - } - } - } - if (costs) { - if (c < 1) { // invalid cost - hfile.close(); hfile.clear(); - if (pfile.is_open()) { - pfile.close(); pfile.clear(); - } - return 38; - } - else { - costsChgMatrix[y][x][2] = c; - } - } - } - } - } -#if RS_RCPP - hfile >> hfloat; - if (!hfile.eof()) EOFerrorR("habitatchgfile"); - if (patchModel) - { - pfile >> pfloat; - if (!pfile.eof()) EOFerrorR("patchchgfile"); - } - if (costs) - { - cfile >> cfloat; - if (!cfile.eof()) EOFerrorR("costchgfile"); - } -#endif - break; - -default: - break; -} - -if (hfile.is_open()) { hfile.close(); hfile.clear(); } -if (pfile.is_open()) { pfile.close(); pfile.clear(); } -if (cfile.is_open()) { cfile.close(); cfile.clear(); } -return 0; - -} - -// Create & initialise patch change matrix -void Landscape::createPatchChgMatrix(void) -{ -intptr patch; -Patch *pPatch; -Cell *pCell; -if (patchChgMatrix != 0) deletePatchChgMatrix(); -patchChgMatrix = new int **[dimY]; -for(int y = dimY-1; y >= 0; y--){ - patchChgMatrix[y] = new int *[dimX]; - for (int x = 0; x < dimX; x++) { - patchChgMatrix[y][x] = new int [3]; - pCell = findCell(x,y); - if (pCell == 0) { // no-data cell - patchChgMatrix[y][x][0] = patchChgMatrix[y][x][1] = 0; - } - else { - // record initial patch number - patch = pCell->getPatch(); - if (patch == 0) { // matrix cell - patchChgMatrix[y][x][0] = patchChgMatrix[y][x][1] = 0; - } - else { - pPatch = (Patch*)patch; - patchChgMatrix[y][x][0] = patchChgMatrix[y][x][1] = pPatch->getPatchNum(); - } - } - patchChgMatrix[y][x][2] = 0; -#if RSDEBUG -//DebugGUI(("Landscape::createPatchChgMatrix(): y=" + Int2Str(y) -// + " x=" + Int2Str(x) -// + " patchChgMatrix[y][x][0]=" + Int2Str(patchChgMatrix[y][x][0]) -// + " [1]=" + Int2Str(patchChgMatrix[y][x][1]) -// + " [2]=" + Int2Str(patchChgMatrix[y][x][2]) -// ).c_str()); -#endif - } -} -} - -void Landscape::recordPatchChanges(int landIx) { -if (patchChgMatrix == 0) return; // should not occur -patchChange chg; - -for(int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - if (landIx == 0) { // reset to original landscape - if (patchChgMatrix[y][x][0] != patchChgMatrix[y][x][2]) { - // record change of patch for current cell - chg.chgnum = 666666; chg.x = x; chg.y = y; - chg.oldpatch = patchChgMatrix[y][x][2]; - chg.newpatch = patchChgMatrix[y][x][0]; - patchchanges.push_back(chg); -#if RSDEBUG -//DebugGUI(("Landscape::recordPatchChanges(): landIx=" + Int2Str(landIx) -// + " chg.chgnum=" + Int2Str(chg.chgnum) -// + " chg.x=" + Int2Str(chg.x) -// + " chg.y=" + Int2Str(chg.y) -// + " chg.oldpatch=" + Int2Str(chg.oldpatch) -// + " chg.newpatch=" + Int2Str(chg.newpatch) -// ).c_str()); -#endif - } - } - else { // any other change - if (patchChgMatrix[y][x][2] != patchChgMatrix[y][x][1]) { - // record change of patch for current cell - chg.chgnum = landIx; chg.x = x; chg.y = y; - chg.oldpatch = patchChgMatrix[y][x][1]; - chg.newpatch = patchChgMatrix[y][x][2]; - patchchanges.push_back(chg); -#if RSDEBUG -//DebugGUI(("Landscape::recordPatchChanges(): landIx=" + Int2Str(landIx) -// + " chg.chgnum=" + Int2Str(chg.chgnum) -// + " chg.x=" + Int2Str(chg.x) -// + " chg.y=" + Int2Str(chg.y) -// + " chg.oldpatch=" + Int2Str(chg.oldpatch) -// + " chg.newpatch=" + Int2Str(chg.newpatch) -// ).c_str()); -#endif - } - } - // reset cell for next landscape change - patchChgMatrix[y][x][1] = patchChgMatrix[y][x][2]; - } -} - -} - -int Landscape::numPatchChanges(void) { return (int)patchchanges.size(); } - -patchChange Landscape::getPatchChange(int i) { -patchChange c; c.chgnum = 99999999; c.x = c.y = c.oldpatch = c.newpatch = -1; -if (i >= 0 && i < (int)patchchanges.size()) c = patchchanges[i]; -return c; -} - -void Landscape::deletePatchChgMatrix(void) { -if (patchChgMatrix != 0) { - for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - delete[] patchChgMatrix[y][x]; - } - delete[] patchChgMatrix[y]; - } -} -patchChgMatrix = 0; -} - -// Create & initialise costs change matrix -void Landscape::createCostsChgMatrix(void) -{ -//intptr patch; -//Patch *pPatch; -Cell *pCell; -if (costsChgMatrix != 0) deleteCostsChgMatrix(); -costsChgMatrix = new int **[dimY]; -for(int y = dimY-1; y >= 0; y--){ - costsChgMatrix[y] = new int *[dimX]; - for (int x = 0; x < dimX; x++) { - costsChgMatrix[y][x] = new int [3]; - pCell = findCell(x,y); - if (pCell == 0) { // no-data cell - costsChgMatrix[y][x][0] = costsChgMatrix[y][x][1] = 0; - } - else { - // record initial cost - costsChgMatrix[y][x][0] = costsChgMatrix[y][x][1] = pCell->getCost(); - } - costsChgMatrix[y][x][2] = 0; -#if RSDEBUG -//DebugGUI(("Landscape::createCostsChgMatrix(): y=" + Int2Str(y) -// + " x=" + Int2Str(x) -// + " costsChgMatrix[y][x][0]=" + Int2Str(costsChgMatrix[y][x][0]) -// + " [1]=" + Int2Str(costsChgMatrix[y][x][1]) -// + " [2]=" + Int2Str(costsChgMatrix[y][x][2]) -// ).c_str()); -#endif - } -} -} - -void Landscape::recordCostChanges(int landIx) { -#if RSDEBUG -DEBUGLOG << "Landscape::recordCostChanges(): landIx=" << landIx << endl; -#endif -if (costsChgMatrix == 0) return; // should not occur -costChange chg; - -for(int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - if (landIx == 0) { // reset to original landscape - if (costsChgMatrix[y][x][0] != costsChgMatrix[y][x][2]) { - // record change of cost for current cell - chg.chgnum = 666666; chg.x = x; chg.y = y; - chg.oldcost = costsChgMatrix[y][x][2]; - chg.newcost = costsChgMatrix[y][x][0]; - costschanges.push_back(chg); -#if RSDEBUG -//DebugGUI(("Landscape::recordCostsChanges(): landIx=" + Int2Str(landIx) -// + " chg.chgnum=" + Int2Str(chg.chgnum) -// + " chg.x=" + Int2Str(chg.x) -// + " chg.y=" + Int2Str(chg.y) -// + " chg.oldcost=" + Int2Str(chg.oldcost) -// + " chg.newcost=" + Int2Str(chg.newcost) -// ).c_str()); -#endif - } - } - else { // any other change -#if RSDEBUG -//if (x < 20 && y == 0) { -// DEBUGLOG << "Landscape::recordCostChanges(): x=" << x << " y=" << y -// << " costsChgMatrix[y][x][0]=" << costsChgMatrix[y][x][0] -// << " costsChgMatrix[y][x][1]=" << costsChgMatrix[y][x][1] -// << " costsChgMatrix[y][x][2]=" << costsChgMatrix[y][x][2] -// << endl; -//} -#endif - if (costsChgMatrix[y][x][2] != costsChgMatrix[y][x][1]) { - // record change of cost for current cell - chg.chgnum = landIx; chg.x = x; chg.y = y; - chg.oldcost = costsChgMatrix[y][x][1]; - chg.newcost = costsChgMatrix[y][x][2]; - costschanges.push_back(chg); -#if RSDEBUG -//DebugGUI(("Landscape::recordCostsChanges(): landIx=" + Int2Str(landIx) -// + " chg.chgnum=" + Int2Str(chg.chgnum) -// + " chg.x=" + Int2Str(chg.x) -// + " chg.y=" + Int2Str(chg.y) -// + " chg.oldcost=" + Int2Str(chg.oldcost) -// + " chg.newcost=" + Int2Str(chg.newcost) -// ).c_str()); -#endif - } - } - // reset cell for next landscape change - costsChgMatrix[y][x][1] = costsChgMatrix[y][x][2]; - } -} - -} - -int Landscape::numCostChanges(void) { return (int)costschanges.size(); } - -costChange Landscape::getCostChange(int i) { -costChange c; c.chgnum = 99999999; c.x = c.y = c.oldcost = c.newcost = -1; -if (i >= 0 && i < (int)costschanges.size()) c = costschanges[i]; -return c; -} - -void Landscape::deleteCostsChgMatrix(void) { -if (costsChgMatrix != 0) { - for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - delete[] costsChgMatrix[y][x]; - } - delete[] costsChgMatrix[y]; - } -} -costsChgMatrix = 0; -} - -//--------------------------------------------------------------------------- - -// Species distribution functions - -int Landscape::newDistribution(Species *pSpecies, string distname) { -int readcode; -int ndistns = (int)distns.size(); -distns.push_back(new InitDist(pSpecies)); -readcode = distns[ndistns]->readDistribution(distname); -if (readcode != 0) { // error encountered - // delete the distribution created above - delete distns[ndistns]; - distns.pop_back(); -} -return readcode; -} - -void Landscape::setDistribution(Species *pSpecies,int nInit) { -// WILL NEED TO SELECT DISTRIBUTION FOR CORRECT SPECIES ... -// ... CURRENTLY IT IS THE ONLY ONE -distns[0]->setDistribution(nInit); -} - -// Specified cell match one of the distribution cells to be initialised? -bool Landscape::inInitialDist(Species *pSpecies,locn loc) { -// convert landscape co-ordinates to distribution co-ordinates -locn initloc; -initloc.x = loc.x * resol / spResol; -initloc.y = loc.y * resol / spResol; -// WILL HAVE TO GET CORRECT SPECIES WHEN THERE ARE MULTIPLE SPECIES ... -bool initialise = distns[0]->inInitialDist(initloc); -return initialise; -} - -void Landscape::deleteDistribution(Species *pSpecies) { -// WILL NEED TO SELECT DISTRIBUTION FOR CORRECT SPECIES ... -// ... CURRENTLY IT IS THE ONLY ONE ... -// ... FOR MULTIPLE SPECIES IT MAY BE BETTER TO USE A DYNAMIC ARRAY FOR -// SPECIES DISTRIBUTIONS INDEXED BY SPECIES NUMBER, RATHER THAN A VECTOR -if (distns[0] != 0) delete distns[0]; distns.clear(); -} - -// Return no. of initial distributions -int Landscape::distnCount(void) { -return (int)distns.size(); -} - -int Landscape::distCellCount(int dist) { -return distns[dist]->cellCount(); -} - -// Set a cell in a specified initial distribution (by position in cells vector) -void Landscape::setDistnCell(int dist,int ix,bool init) { -distns[dist]->setDistCell(ix,init); -} - -// Set a cell in a specified initial distribution (by given co-ordinates) -void Landscape::setDistnCell(int dist,locn loc,bool init) { -distns[dist]->setDistCell(loc,init); -} - -// Get the co-ordinates of a specified cell in a specified initial distribution -locn Landscape::getDistnCell(int dist,int ix) { -return distns[dist]->getCell(ix); -} - -// Get the co-ordinates of a specified cell in a specified initial distribution -// Returns negative co-ordinates if the cell is not selected -locn Landscape::getSelectedDistnCell(int dist,int ix) { -return distns[dist]->getSelectedCell(ix); -} - -// Get the dimensions of a specified initial distribution -locn Landscape::getDistnDimensions(int dist) { -return distns[dist]->getDimensions(); -} - -// Reset the distribution for a given species so that all cells are deselected -void Landscape::resetDistribution(Species *pSp) { -// CURRENTLY WORKS FOR FIRST SPECIES ONLY ... -distns[0]->resetDistribution(); -} - -//--------------------------------------------------------------------------- - -// Initialisation cell functions - -int Landscape::initCellCount(void) { -return (int)initcells.size(); -} - -void Landscape::addInitCell(int x,int y) { -initcells.push_back(new DistCell(x,y)); -} - -locn Landscape::getInitCell(int ix) { -return initcells[ix]->getLocn(); -} - -void Landscape::clearInitCells(void) { -int ncells = (int)initcells.size(); -for (int i = 0; i < ncells; i++) { - delete initcells[i]; -} -initcells.clear(); -} - -//--------------------------------------------------------------------------- - -// Read landscape file(s) -// Returns error code or zero if read correctly - -int Landscape::readLandscape(int fileNum,string habfile,string pchfile,string costfile) -{ -// fileNum == 0 for (first) habitat file and optional patch file -// fileNum > 0 for subsequent habitat files under the %cover option - -#if RS_RCPP -wstring header; -#else -string header; -#endif -int h,seq,p,habnodata; -int pchnodata = 0; -int ncols,nrows; -float hfloat,pfloat; -Patch *pPatch; -simParams sim = paramsSim->getSim(); - -if (fileNum < 0) return 19; - -#if RS_RCPP - wifstream hfile; // habitat file input stream - wifstream pfile; // patch file input stream -#else - ifstream hfile; // habitat file input stream - ifstream pfile; // patch file input stream -#endif -initParams init = paramsInit->getInit(); - -// open habitat file and optionally also patch file -#if !RS_RCPP || RSWIN64 -hfile.open(habfile.c_str()); -#else -hfile.open(habfile, std::ios::binary); -if(landraster.utf) { - // apply BOM-sensitive UTF-16 facet - hfile.imbue(std::locale(hfile.getloc(), new std::codecvt_utf16)); -} -#endif -if (!hfile.is_open()) return 11; -if (fileNum == 0) { - if (patchModel) { -#if !RS_RCPP || RSWIN64 - pfile.open(pchfile.c_str()); -#else - pfile.open(pchfile, std::ios::binary); - if(patchraster.utf) { - // apply BOM-sensitive UTF-16 facet - pfile.imbue(std::locale(pfile.getloc(), new std::codecvt_utf16)); - } -#endif - if (!pfile.is_open()) { - hfile.close(); hfile.clear(); - return 12; - } - } -} - -// read landscape data from header records of habitat file -// NB headers of all files have already been compared -hfile >> header >> ncols >> header >> nrows >> header >> minEast >> header >> minNorth - >> header >> resol >> header >> habnodata; - -#if RS_RCPP - if (!hfile.good()) { - // corrupt file stream - StreamErrorR(habfile); - hfile.close(); - hfile.clear(); - if (patchModel) { - pfile.close(); - pfile.clear(); - } - return 131; - } -#endif - -dimX = ncols; dimY = nrows; minX = maxY = 0; maxX = dimX-1; maxY = dimY-1; -if (fileNum == 0) { - // set initialisation limits to landscape limits - init.minSeedX = init.minSeedY = 0; - init.maxSeedX = maxX; init.maxSeedY = maxY; - paramsInit->setInit(init); -} - -if (fileNum == 0) { - if (patchModel) { - for (int i = 0; i < 5; i++) pfile >> header >> pfloat; - pfile >> header >> pchnodata; - } -#if RS_RCPP - if (!pfile.good()) { - // corrupt file stream - StreamErrorR(pchfile); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 135; - } -#endif - setCellArray(); -} - - -// set up bad float values to ensure that valid values are read -float badhfloat = -9.0; if (habnodata == -9) badhfloat = -99.0; -float badpfloat = -9.0; if (pchnodata == -9) badpfloat = -99.0; - -seq = 0; // initial sequential patch landscape -p = 0; // initial patch number for cell-based landscape -// create patch 0 - the matrix patch (even if there is no matrix) -if (fileNum == 0) newPatch(seq++,p++); - -switch (rasterType) { - -case 0: // raster with habitat codes - 100% habitat each cell - if (fileNum > 0) return 19; // error condition - should not occur - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - hfloat = badhfloat; -#if RS_RCPP - if(hfile >> hfloat) { -#else - hfile >> hfloat; -#endif - h = (int)hfloat; - if (patchModel) { - pfloat = badpfloat; -#if RS_RCPP - if(pfile >> pfloat) { -#else - pfile >> pfloat; -#endif - p = (int)pfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(pchfile); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 132; - } -#endif - } -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(habfile); - hfile.close(); - hfile.clear(); - if (patchModel) { - pfile.close(); - pfile.clear(); - } - return 135; - } -#endif - -#if RSDEBUG -//DebugGUI(("Landscape::readLandscape(): x=" + Int2Str(x) + " y=" + Int2Str(y) -// + " h=" + Int2Str(h) + " p=" + Int2Str(p) -//).c_str()); -#endif - if (h == habnodata) - addNewCellToLand(x,y,-1); // add cell only to landscape - else { - - // THERE IS AN ANOMALY HERE - CURRENTLY HABITAT 0 IS OK FOR GUI VERSION BUT - // NOT ALLOWED FOR BATCH VERSION (HABITATS MUST BE 1...n) - // SHOULD WE MAKE THE TWO VERSIONS AGREE? ... - - if (h < 0 || (sim.batchMode && (h < 1 || h > nHabMax))) { - // invalid habitat code - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "Found invalid habitat code." << std::endl; - #endif - hfile.close(); hfile.clear(); - if (patchModel) { - pfile.close(); pfile.clear(); - } - return 13; - } - else { - addHabCode(h); - if (patchModel) { - if (p < 0 || p == pchnodata) { // invalid patch code - #if RS_RCPP && !R_CMD - if (p == pchnodata) Rcpp::Rcout << "Found patch NA in valid habitat cell." << std::endl; - else Rcpp::Rcout << "Found negative patch ID in valid habitat cell." << std::endl; - #endif - hfile.close(); hfile.clear(); - pfile.close(); pfile.clear(); - return 14; - } - if (p == 0) { // cell is in the matrix - addNewCellToPatch(0,x,y,h); - } - else { - if (existsPatch(p)) { - pPatch = findPatch(p); - addNewCellToPatch(pPatch,x,y,h); -// addNewCellToPatch(findPatch(p),x,y,h); - } - else { - pPatch = newPatch(seq++,p); - addNewCellToPatch(pPatch,x,y,h); - } - } - } - else { // cell-based model - // add cell to landscape (patches created later) - addNewCellToLand(x,y,h); - } - } - } - } - } -#if RS_RCPP - hfile >> hfloat; - if (!hfile.eof()) EOFerrorR(habfile); - if (patchModel) - { - pfile >> pfloat; - if (!pfile.eof()) EOFerrorR(pchfile); - } -#endif - break; - -case 1: // multiple % cover - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - hfloat = badhfloat; -#if RS_RCPP - if(hfile >> hfloat) { -#else - hfile >> hfloat; -#endif - h = (int)hfloat; - if (fileNum == 0) { // first habitat cover layer - if (patchModel) { - pfloat = badpfloat; -#if RS_RCPP - if(pfile >> pfloat) { -#else - pfile >> pfloat; -#endif - p = (int)pfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(pchfile); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 135; - } -#endif - } //end if patchmodel - -#if RSDEBUG -//MemoLine(("y=" + Int2Str(y) + " x=" + Int2Str(x) + " hfloat=" + Float2Str(hfloat) -// + " p=" + Int2Str(p)).c_str()); -#endif - if (h == habnodata) { - addNewCellToLand(x,y,-1); // add cell only to landscape - } - else { - if (hfloat < 0.0 || hfloat > 100.0) { // invalid cover score - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "Found invalid habitat cover score." << std::endl; - #endif - hfile.close(); hfile.clear(); - if (patchModel) { - pfile.close(); pfile.clear(); - } - return 17; - } - else { - if (patchModel) { - if (p < 0 || p == pchnodata) { // invalid patch code - #if RS_RCPP && !R_CMD - if (p == pchnodata) Rcpp::Rcout << "Found patch NA in valid habitat cell." << std::endl; - else Rcpp::Rcout << "Found negative patch ID in valid habitat cell." << std::endl; - #endif - hfile.close(); hfile.clear(); - pfile.close(); pfile.clear(); - return 14; - } - if (p == 0) { // cell is in the matrix - addNewCellToPatch(0,x,y,hfloat); - } - else { - if (existsPatch(p)) { - pPatch = findPatch(p); - addNewCellToPatch(pPatch,x,y,hfloat); -// addNewCellToPatch(findPatch(p),x,y,hfloat); - } - else { - pPatch = newPatch(seq++,p); - addNewCellToPatch(pPatch,x,y,hfloat); - } - } - } - else { // cell-based model - // add cell to landscape (patches created later) - addNewCellToLand(x,y,hfloat); - } - } - } - } - else { // additional habitat cover layers - if (h != habnodata) { - if (hfloat < 0.0 || hfloat > 100.0) { // invalid cover score - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "Found invalid habitat cover score." << std::endl; - #endif - hfile.close(); hfile.clear(); - if (patchModel) { - pfile.close(); pfile.clear(); - } - return 17; - } - else { - cells[y][x]->setHabitat(hfloat); - } - } // end of h != habnodata - } -#if RS_RCPP - } else { // couldn't read from hfile - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(habfile); - hfile.close(); - hfile.clear(); - if (patchModel) { - pfile.close(); - pfile.clear(); - } - return 133; - } -#endif - - } - } - habIndexed = true; // habitats are already numbered 1...n in correct order -#if RS_RCPP - hfile >> hfloat; - if (!hfile.eof()) EOFerrorR(habfile); - if (patchModel) - { - pfile >> pfloat; - if (!pfile.eof()) EOFerrorR(pchfile); - } -#endif - break; - -case 2: // habitat quality - if (fileNum > 0) return 19; // error condition - should not occur - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - hfloat = badhfloat; -#if RS_RCPP - if(hfile >> hfloat) { -#else - hfile >> hfloat; -#endif - h = (int)hfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(habfile); - hfile.close(); - hfile.clear(); - if (patchModel) { - pfile.close(); - pfile.clear(); - } - return 134; - } -#endif - if (patchModel) { - pfloat = badpfloat; -#if RS_RCPP - if(pfile >> pfloat) { -#else - pfile >> pfloat; -#endif - p = (int)pfloat; -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(pchfile); - hfile.close(); - hfile.clear(); - pfile.close(); - pfile.clear(); - return 135; - } -#endif - } -#if RSDEBUG -//MemoLine(("y=" + Int2Str(y) + " x=" + Int2Str(x) + " hfloat=" + Float2Str(hfloat) -// + " p=" + Int2Str(p)).c_str()); -#endif - if (h == habnodata) { - addNewCellToLand(x,y,-1); // add cell only to landscape - } - else { - if (hfloat < 0.0 || hfloat > 100.0) { // invalid quality score - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "Found invalid habitat quality score." << std::endl; - #endif - hfile.close(); hfile.clear(); - if (patchModel) { - pfile.close(); pfile.clear(); - } - return 17; - } - else { - if (patchModel) { - if (p < 0 || p == pchnodata) { // invalid patch code - #if RS_RCPP && !R_CMD - if (p == pchnodata) Rcpp::Rcout << "Found patch NA in valid habitat cell." << std::endl; - else Rcpp::Rcout << "Found negative patch ID in valid habitat cell." << std::endl; - #endif - hfile.close(); hfile.clear(); - pfile.close(); pfile.clear(); - return 14; - } - if (p == 0) { // cell is in the matrix - addNewCellToPatch(0,x,y,hfloat); - } - else { - if (existsPatch(p)) { - pPatch = findPatch(p); - addNewCellToPatch(pPatch,x,y,hfloat); -// addNewCellToPatch(findPatch(p),x,y,hfloat); - } - else { - addPatchNum(p); - pPatch = newPatch(seq++,p); - addNewCellToPatch(pPatch,x,y,hfloat); - } - } - } - else { // cell-based model - // add cell to landscape (patches created later) - addNewCellToLand(x,y,hfloat); - } - } - } - } - } -#if RS_RCPP - hfile >> hfloat; - if (!hfile.eof()) EOFerrorR(habfile); - if (patchModel) - { - pfile >> pfloat; - if (!pfile.eof()) EOFerrorR(pchfile); - } -#endif - break; - -default: - break; -} // end switch(rasterType) - -if (hfile.is_open()) { hfile.close(); hfile.clear(); } -if (pfile.is_open()) { pfile.close(); pfile.clear(); } - -if (sim.batchMode) { - if (costfile != "NULL") { - int retcode = readCosts(costfile); - if (retcode < 0) return 54; - } -} - -return 0; - -} - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -int Landscape::readCosts(string fname) -{ - -#if RS_RCPP - wifstream costs; // cost map file input stream -#else - ifstream costs; // cost map file input stream -#endif - -//int hc,maxYcost,maxXcost,NODATACost,hab; -int hc,maxYcost,maxXcost,NODATACost; -float minLongCost, minLatCost; int resolCost; -float fcost; -#if RS_RCPP -wstring header; -#else -string header; -#endif -Cell *pCell; -#if !RS_RCPP -simView v = paramsSim->getViews(); -#endif - -int maxcost = 0; - -#if RSDEBUG -#if BATCH -//DEBUGLOG << "Landscape::readCosts(): fname=" << fname << endl; -#endif -#endif - // open cost file -#if !RS_RCPP || RSWIN64 - costs.open(fname.c_str()); -#else - costs.open(fname, std::ios::binary); - if(costsraster.utf) { - // apply BOM-sensitive UTF-16 facet - costs.imbue(std::locale(costs.getloc(), new std::codecvt_utf16)); - } -#endif -//if (!costs.is_open()) { -// MessageDlg("COSTS IS NOT OPEN!!!!!", -// mtError, TMsgDlgButtons() << mbRetry,0); -//} -//else { -// MessageDlg("Costs is open!", -// mtError, TMsgDlgButtons() << mbRetry,0); -//} -// read headers and check that they correspond to the landscape ones -costs >> header; -#if RS_RCPP - if (!costs.good()) { - // corrupt file stream - StreamErrorR(fname); - costs.close(); - costs.clear(); - return -181; - } - if (header != L"ncols" && header != L"NCOLS") { -#else - if (header != "ncols" && header != "NCOLS") { -#endif -// MessageDlg("The selected file is not a raster.", -// MessageDlg("Header problem in import_CostsLand()", -// mtError, TMsgDlgButtons() << mbRetry,0); - costs.close(); costs.clear(); - return -1; -} -costs >> maxXcost >> header >> maxYcost >> header >> minLongCost; -costs >> header >> minLatCost >> header >> resolCost >> header >> NODATACost; - -#if !RS_RCPP -MemoLine("Loading costs map. Please wait..."); -#endif - -for (int y = maxYcost - 1; y > -1; y--){ - for (int x = 0; x < maxXcost; x++){ -#if RS_RCPP - if(costs >> fcost) { -#else - costs >> fcost; -#endif - hc = (int)fcost; // read as float and convert to int -#if RS_RCPP - } else { - // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif - StreamErrorR(fname); - costs.close(); - costs.clear(); - return -181; - } -#endif - if ( hc < 1 && hc != NODATACost ) { -#if RSDEBUG -#if BATCH -// DEBUGLOG << "Landscape::readCosts(): x=" << x << " y=" << y -// << " fcost=" << fcost << " hc=" << hc -// << endl; -#endif -#endif -#if RS_RCPP && !R_CMD - Rcpp::Rcout << "Cost map my only contain values of 1 or higher, but found " << fcost << "." << endl; -#endif - // error - zero / negative cost not allowed -// MessageDlg("Error in the costs map file : zero or negative cost detected." -// , mtError, TMsgDlgButtons() << mbOK,0); - costs.close(); costs.clear(); - return -999; - } - pCell = findCell(x,y); - if (pCell != 0) { // not no-data cell - pCell->setCost(hc); - if (hc > maxcost) maxcost = hc; - } - } -} -#if RS_RCPP - costs >> fcost; - if (costs.eof()) { - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "Costs map loaded." << endl; - #endif - } - else EOFerrorR(fname); -#else - MemoLine("Costs map loaded."); -#endif - -costs.close(); costs.clear(); - -return maxcost; - -} - -//--------------------------------------------------------------------------- - -rasterdata CheckRasterFile(string fname) -{ -rasterdata r; -string header; -int inint; -ifstream infile; - -r.ok = true; -r.errors = r.ncols = r.nrows = r.cellsize = 0; -r.xllcorner = r.yllcorner = 0.0; - -infile.open(fname.c_str()); -if (infile.is_open()) { - infile >> header >> r.ncols; -#if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " r.ncols=" + Int2Str(r.ncols) - ).c_str()); -#endif - if (header != "ncols" && header != "NCOLS") r.errors++; - infile >> header >> r.nrows; -#if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " r.nrows=" + Int2Str(r.nrows) - ).c_str()); -#endif - if (header != "nrows" && header != "NROWS") r.errors++; - infile >> header >> r.xllcorner; -#if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " r.xllcorner=" + Float2Str(r.xllcorner) - ).c_str()); -#endif - if (header != "xllcorner" && header != "XLLCORNER") r.errors++; - infile >> header >> r.yllcorner; -#if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " r.yllcorner=" + Float2Str(r.yllcorner) - ).c_str()); -#endif - if (header != "yllcorner" && header != "YLLCORNER") r.errors++; - infile >> header >> r.cellsize; -#if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " r.cellsize=" + Int2Str(r.cellsize) - ).c_str()); -#endif - if (header != "cellsize" && header != "CELLSIZE") r.errors++; - infile >> header >> inint; -#if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " inint=" + Int2Str(inint) - ).c_str()); -#endif - if (header != "NODATA_value" && header != "NODATA_VALUE") r.errors++; - infile.close(); - infile.clear(); - if (r.errors > 0) r.ok = false; -} -else { - r.ok = false; r.errors = -111; -} -infile.clear(); - -return r; -} - -//--------------------------------------------------------------------------- - -// Patch connectivity functions - -// Create & initialise connectivity matrix -void Landscape::createConnectMatrix(void) -{ -if (connectMatrix != 0) deleteConnectMatrix(); -int npatches = (int)patches.size(); -#if RSDEBUG -//DEBUGLOG << "Landscape::createConnectMatrix(): npatches=" << npatches << endl; -#endif -connectMatrix = new int *[npatches]; -for (int i = 0; i < npatches; i++) { - connectMatrix[i] = new int[npatches]; - for (int j = 0; j < npatches; j++) connectMatrix[i][j] = 0; -} -} - -// Re-initialise connectivity matrix -void Landscape::resetConnectMatrix(void) -{ -if (connectMatrix != 0) { - int npatches = (int)patches.size(); - for (int i = 0; i < npatches; i++) { - for (int j = 0; j < npatches; j++) connectMatrix[i][j] = 0; - } -} -} - -// Increment connectivity count between two specified patches -void Landscape::incrConnectMatrix(int p0,int p1) { -int npatches = (int)patches.size(); -if (connectMatrix == 0 || p0 < 0 || p0 >= npatches || p1 < 0 || p1 >= npatches) return; -connectMatrix[p0][p1]++; -} - -// Delete connectivity matrix -void Landscape::deleteConnectMatrix(void) -{ -if (connectMatrix != 0) { - int npatches = (int)patches.size(); - for (int j = 0; j < npatches; j++) { - if (connectMatrix[j] != 0) - delete connectMatrix[j]; - } - delete[] connectMatrix; - connectMatrix = 0; -} -} - -// Write connectivity file headers -bool Landscape::outConnectHeaders(int option) -{ -if (option == -999) { // close the file - if (outConnMat.is_open()) outConnMat.close(); - outConnMat.clear(); - return true; -} - -simParams sim = paramsSim->getSim(); - -string name = paramsSim->getDir(2); -if (sim.batchMode) { - name += "Batch" + Int2Str(sim.batchNum) + "_"; - name += "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(landNum); -} -else - name += "Sim" + Int2Str(sim.simulation); -name += "_Connect.txt"; -outConnMat.open(name.c_str()); - -outConnMat << "Rep\tYear\tStartPatch\tEndPatch\tNinds" << endl; - -return outConnMat.is_open(); -} - -#if RS_RCPP -// Write movement paths file headers -void Landscape::outPathsHeaders(int rep, int option) -{ - if (option == -999) { // close the file - if (outMovePaths.is_open()) outMovePaths.close(); - outMovePaths.clear(); - } - if (option == 0) { // open the file and write header - - simParams sim = paramsSim->getSim(); - string name = paramsSim->getDir(2); - if (sim.batchMode) { - name += "Batch" + Int2Str(sim.batchNum) - + "_Sim" + Int2Str(sim.simulation) - + "_Land" + Int2Str(landNum) - + "_Rep" + Int2Str(rep); - } else { - name += "Sim" + Int2Str(sim.simulation) - + "_Rep" + Int2Str(rep); - } - name += "_MovePaths.txt"; - - outMovePaths.open(name.c_str()); - if( outMovePaths.is_open() ){ - outMovePaths << "Year\tIndID\tStep\tx\ty\tStatus" << endl; - }else{ - #if RSDEBUG - DEBUGLOG << "RunModel(): UNABLE TO OPEN MOVEMENT PATHS FILE" << endl; - #endif - outMovePaths.clear(); - } - } -} -#endif - -void Landscape::outConnect(int rep,int yr) -{ -int patchnum0,patchnum1; -int npatches = (int)patches.size(); -int *emigrants = new int[npatches]; // 1D array to hold emigrants from each patch -int *immigrants = new int[npatches]; // 1D array to hold immigrants to each patch - -for (int i = 0; i < npatches; i++) { - emigrants[i] = immigrants[i] = 0; -} - -for (int i = 0; i < npatches; i++) { - patchnum0 = patches[i]->getPatchNum(); - if (patchnum0 != 0) { - for (int j = 0; j < npatches; j++) { - patchnum1 = patches[j]->getPatchNum(); - if (patchnum1 != 0) { - emigrants[i] += connectMatrix[i][j]; - immigrants[j] += connectMatrix[i][j]; - if (connectMatrix[i][j] > 0) { - outConnMat << rep << "\t" << yr - << "\t" << patchnum0 << "\t" << patchnum1 - << "\t" << connectMatrix[i][j] << endl; - } - } - } - } -} - -for (int i = 0; i < npatches; i++) { - patchnum0 = patches[i]->getPatchNum(); - if (patchnum0 != 0) { - if (patches[i]->getK() > 0.0) - { // suitable patch - outConnMat << rep << "\t" << yr - << "\t" << patchnum0 << "\t-999\t" << emigrants[i] << endl; - outConnMat << rep << "\t" << yr - << "\t-999\t" << patchnum0 << "\t" << immigrants[i] << endl; - } - } -} - -delete[] emigrants; -delete[] immigrants; - -} - -//--------------------------------------------------------------------------- - -void Landscape::resetVisits(void) { -for(int y = dimY-1; y >= 0; y--){ - for (int x = 0; x < dimX; x++) { - if (cells[y][x] != 0) { // not a no-data cell - cells[y][x]->resetVisits(); - } - } -} -} - -// Save SMS path visits map to raster text file -void Landscape::outVisits(int rep, int landNr) { - -string name; -simParams sim = paramsSim->getSim(); - -if (sim.batchMode) { - name = paramsSim->getDir(3) -#if RS_RCPP - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) - + "_Land" + Int2Str(landNr) + "_Rep" + Int2Str(rep) -#else - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) - + "_land" + Int2Str(landNr) + "_rep" + Int2Str(rep) -#endif -// + "_yr" + Int2Str(yr) - + "_Visits.txt"; -} -else { - name = paramsSim->getDir(3) - + "Sim" + Int2Str(sim.simulation) - + "_land" + Int2Str(landNr) + "_rep" + Int2Str(rep) -// + "_yr" + Int2Str(yr) - + "_Visits.txt"; -} -outvisits.open(name.c_str()); - -outvisits << "ncols " << dimX << endl; -outvisits << "nrows " << dimY << endl; -outvisits << "xllcorner " << minEast << endl; -outvisits << "yllcorner " << minNorth << endl; -outvisits << "cellsize " << resol << endl; -outvisits << "NODATA_value -9" << endl; - -for (int y = dimY-1; y >= 0; y--) { -#if RSDEBUG -//DebugGUI(("Landscape::drawLandscape(): y=" + Int2Str(y) -// + " cells[y]=" + Int2Str((int)cells[y])).c_str()); -#endif - for (int x = 0; x < dimX; x++) { - if (cells[y][x] == 0) { // no-data cell - outvisits << "-9 "; - } - else { - outvisits << cells[y][x]->getVisits() << " "; - } - } - outvisits << endl; -} - -outvisits.close(); outvisits.clear(); -} - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- diff --git a/src/RScore/Landscape.h b/src/RScore/Landscape.h deleted file mode 100644 index a3d974d..0000000 --- a/src/RScore/Landscape.h +++ /dev/null @@ -1,567 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Landscape - -Implements the following classes: - -InitDist - Initial species distribution - -Landscape - Landscape grid - -The Landscape is a rectangular array of Cells which are grouped together in -Patches. As far as the user is aware, the Landscape is either patch-based or -cell-based (having no Patches), but internally Patches are always present (they -each comprise only one Cell for a cell-based model). The grain of the Landscape -may be any positive integer, and is nominally in metres. - -The Landscape is either input from one or more text files in ArcGIS raster export -format, or it is generated artificially as a random or fractal binary array (in -which case, it must be cell-based). An input 'real' Landscape may hold within each -Cell either discrete habitat classes, or percent cover of habitat classes, or a -continuous quality index (1 to 100%). - -The Landscape may be dynamic, in which case the user specifies a set of changes -to be applied at certain years during each simulation. The changes may be to -habitat only, patches only (if a patch-based model) or habitats and patches. -Although the changes must be supplied as entire habitat / patch files (which -must match the original Landscape in terms of cell size and extent), internally -they are recorded as lists of dynamic habitat and patch changes. - -The initial species distribution is a rectangular array if distribution cells -(DistCell) covering the same spatial extent at the Landscape. Its grain may be -either that of the Landscape or an integer multiple of it. - -The Landscape can record a list (in the vector initcells) of Cells or Patches -to be intialised, which are specified by the user in FormSeeding. This option is -available in the GUI version only. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 2 December 2021 by Steve Palmer -------------------------------------------------------------------------------*/ - -#ifndef LandscapeH -#define LandscapeH - -//#include -//#include -#include -#include -//#include -//#include -#include - -using namespace std; - -#include "Parameters.h" -#include "Patch.h" -#include "Cell.h" -#include "Species.h" -#include "FractalGenerator.h" -#if RS_RCPP -#include -#if !RSWIN64 -#include -#endif -#include -#endif - -//--------------------------------------------------------------------------- - -// Initial species distribution - -class InitDist{ -public: - InitDist(Species*); - ~InitDist(); - int readDistribution( - string // name of species distribution file - ); - void setDistribution( - int // no. of distribution cells to be initialised (0 for all cells) - ); - void setDistCell( // Set a specified cell (by position in cells vector) - int, // index no. of DistCell in cells vector - bool // value to be set - ); - void setDistCell( // Set a specified cell (by co-ordinates) - locn, // structure holding x (column) and y (row) co-ordinates - bool - ); - bool inInitialDist( // Specified location is within the initial distribution? - locn // structure holding x (column) and y (row) co-ordinates - ); - int cellCount(void); - locn getCell( // Return the co-ordinates of a specified initial distribution cell - int // index no. of DistCell in cells vector - ); - locn getSelectedCell( // Return the co-ordinates of a specified initial distribution - // cell if it has been selected - // otherwise return negative co-ordinates - int // index no. of DistCell in cells vector - ); - locn getDimensions(void); - void resetDistribution(void); - -private: - Species *pSpecies; // pointer to species - int resol; // species distribution cell size (m) - int maxX, maxY; // dimensions - double minEast; // ) real world min co-ordinates - double minNorth; // ) read from raster file - - // list of cells in the initial distribution - // cells MUST be loaded in the sequence ascending x within descending y - std::vector cells; - -}; - - -//--------------------------------------------------------------------------- - -struct landParams { - bool patchModel; bool spDist; bool generated; - bool dynamic; - int landNum; int resol; int spResol; int nHab; int nHabMax; - int dimX,dimY,minX,minY,maxX,maxY; - short rasterType; -}; -struct landData { - int resol; int dimX,dimY,minX,minY,maxX,maxY; -}; -struct genLandParams { - bool fractal; bool continuous; - float minPct,maxPct; float propSuit; float hurst; int maxCells; -}; -struct landPix { - int pix; float gpix; -}; -struct landOrigin { - double minEast; double minNorth; -}; -struct rasterHdr { - bool ok; - int errors,ncols,nrows,cellsize; - double xllcorner,yllcorner; -}; -struct rasterdata { - bool ok; - int errors,ncols,nrows,cellsize; - double xllcorner,yllcorner; -#if RS_RCPP - bool utf; -#endif -}; -struct patchData { - Patch *pPatch; int patchNum,nCells; int x,y; -}; -struct landChange { - int chgnum,chgyear; string habfile,pchfile,costfile; -}; -struct patchChange { - int chgnum, x, y, oldpatch, newpatch; -}; -struct costChange { - int chgnum,x,y,oldcost,newcost; -}; - -class Landscape{ -public: - Landscape(); - ~Landscape(); - void resetLand(void); - - // functions to set and return parameter values - - void setLandParams( - landParams, // structure holding landscape parameters - bool // batch mode - ); - landParams getLandParams(void); - landData getLandData(void); - void setGenLandParams(genLandParams); - genLandParams getGenLandParams(void); - void setLandLimits( - int, // minimum available X - int, // minimum available Y - int, // maximum available X - int // maximum available Y - ); - void resetLandLimits(void); - void setLandPix(landPix); - - landPix getLandPix(void); - void setOrigin(landOrigin); - landOrigin getOrigin(void); - - // functions to handle habitat codes - - bool habitatsIndexed(void); - void listHabCodes(void); - void addHabCode(int); - int findHabCode(int); - int getHabCode(int); - void clearHabitats(void); - void addColour(rgb); - void changeColour(int,rgb); - rgb getColour(int); - int colourCount(void); - - // functions to handle patches and cells - - void setCellArray(void); - void addPatchNum(int); - void generatePatches(void); // create an artificial landscape - void allocatePatches(Species*); // create patches for a cell-based landscape - Patch* newPatch( - int // patch sequential no. (id no. is set to equal sequential no.) - ); - Patch* newPatch( - int, // patch sequential no. - int // patch id no. - ); - void resetPatches(void); - void addNewCellToLand( - int, // x co-ordinate - int, // y co-ordinate - float // habitat quality value - ); - void addNewCellToLand( - int, // x co-ordinate - int, // y co-ordinate - int // habitat class no. - ); - void addCellToPatch( - Cell*, // pointer to Cell - Patch* // pointer to Patch - ); - void addCellToPatch( - Cell*, // pointer to Cell - Patch*, // pointer to Patch - float // habitat quality value - ); - void addCellToPatch( - Cell*, // pointer to Cell - Patch*, // pointer to Patch - int // habitat class no. - ); - void addNewCellToPatch( - Patch*, // pointer to Patch - int, // x co-ordinate - int, // y co-ordinate - int // habitat class no. - ); - void addNewCellToPatch( - Patch*, // pointer to Patch - int, // x co-ordinate - int, // y co-ordinate - float // habitat quality value - ); - patchData getPatchData( - int // index no. of Patch in patches vector - ); - bool existsPatch( - int // Patch id no. - ); - Patch* findPatch( - int // Patch id no. - ); - int checkTotalCover(void); - void resetPatchPopns(void); - void updateCarryingCapacity( - Species*, // pointer to Species - int, // year - short // landscape change index (always zero if not dynamic) - ); - Cell* findCell( - int, // x co-ordinate - int // y co-ordinate - ); - int patchCount(void); - void updateHabitatIndices(void); - void setEnvGradient( - Species*, // pointer to Species - bool // TRUE for initial instance that gradient is set - ); - void setGlobalStoch( - int // no. of years - ); - float getGlobalStoch( - int // year - ); - void updateLocalStoch(void); - void resetCosts(void); - void resetEffCosts(void); - - // functions to handle dynamic changes - - void setDynamicLand(bool); - void addLandChange( - landChange // structure holding landscape change data - ); - int numLandChanges(void); - landChange getLandChange( - short // change number - ); - void deleteLandChanges(void); -#if RS_RCPP && !R_CMD - int readLandChange( - int, // change file number - bool, // change SMS costs? - wifstream&, // habitat file stream - wifstream&, // patch file stream - wifstream&, // cost file stream - int, // habnodata - int, // pchnodata - int // costnodata - ); -#else - int readLandChange( - int, // change file number - bool // change SMS costs? - ); -#endif - void createPatchChgMatrix(void); - void recordPatchChanges(int); - void deletePatchChgMatrix(void); - int numPatchChanges(void); - patchChange getPatchChange( - int // patch change number - ); - void createCostsChgMatrix(void); - void recordCostChanges(int); - void deleteCostsChgMatrix(void); - int numCostChanges(void); - costChange getCostChange( - int // cost change number - ); - - // functions to handle species distributions - - int newDistribution( - Species*, // pointer to Species - string // name of initial distribution file - ); - void setDistribution( - Species*, // pointer to Species - int // no. of distribution squares to initialise - ); - bool inInitialDist( // Specified cell matches one of the distn cells to be initialised? - Species*, // pointer to Species - locn // structure holding co-ordinates of Cell - ); - void deleteDistribution( - Species* // pointer to Species - ); - int distnCount(void); // Return no. of initial distributions in the Landscape - int distCellCount( // Return no. of distribution cells in an initial distribution - int // index no. of InitDist in distns vector - ); - locn getDistnCell( // Get co-ordinates of a specified cell in a specified initial distn - int, // index no. of InitDist in distns vector - int // index no. of DistCell in cells vector - ); - locn getSelectedDistnCell( // Get co-ordinates of a specified cell in a specified initial distn - // Returns negative co-ordinates if the cell is not selected - int, // index no. of InitDist in distns vector - int // index no. of DistCell in cells vector - ); - locn getDistnDimensions( // Get the dimensions of a specified initial distribution - int // index no. of InitDist in distns vector - ); - void setDistnCell( // Set a cell in a specified init distn (by posn in cells vector) - int, // index no. of InitDist in distns vector - int, // index no. of DistCell in cells vector - bool // value to be set - ); - void setDistnCell( // Set a cell in a specified init distn (by given co-ordinates) - int, // index no. of InitDist in distns vector - locn, // structure holding co-ordinates of DistCell - bool // value to be set - ); - void resetDistribution( - Species* // pointer to Species - ); - - // functions to handle initialisation cells - - int initCellCount(void); - void addInitCell( // Create a new DistCell and add to the initcells vector - int, // x co-ordinate - int // y co-ordinate - ); - locn getInitCell( - int // index no. of DistCell in initcells vector - ); - void clearInitCells(void); - - // functions to handle connectivity matrix - - void createConnectMatrix(void); - void resetConnectMatrix(void); - void incrConnectMatrix( - int, // sequential no. of origin Patch - int // sequential no. of settlement Patch - ); - void deleteConnectMatrix(void); - bool outConnectHeaders( // Write connectivity file headers - int // option - set to -999 to close the connectivity file - ); -#if RS_RCPP - void outPathsHeaders(int, int); -#endif - void outConnect( - int, // replicate no. - int // year - ); - - // functions to handle input and output - - int readLandscape( - int, // fileNum == 0 for (first) habitat file and optional patch file - // fileNum > 0 for subsequent habitat files under the %cover option - string, // habitat file name - string, // patch file name - string // cost file name (may be NULL) - ); - void listPatches(void); - int readCosts( - string // costs file name - ); - // the following four functions are implemented for the GUI version only - // in the batch version, they are defined, but empty - void setLandMap(void); - void drawLandscape( - int, // replicate no. - int, // landscape index number (always 0 if landscape is not dynamic) - int // landscape no. - ); - void drawGradient(void); // Draw environmental gradient map - void drawGlobalStoch( // Draw environmental stochasticity time-series - int // no. of years - ); - - void resetVisits(void); - void outVisits(int,int); // save SMS path visits map to raster text file - -private: - bool generated; // artificially generated? - bool patchModel; // - bool spDist; // initial species distribution loaded - bool fractal; // - bool continuous; // - bool dynamic; // landscape changes during simulation - bool habIndexed; // habitat codes have been converted to index numbers - short rasterType; // 0 = habitat codes 1 = % cover 2 = quality 9 = artificial landscape - int landNum; // landscape number - int resol; // cell size (m) - int spResol; // species distribution cell size (m) - int nHab; // no. of habitats - int nHabMax; // max. no. of habitats (used for batch input only) - int dimX,dimY; // dimensions - int minX,minY; // minimum available X and Y co-ordinates - int maxX,maxY; // maximum available X and Y co-ordinates - float minPct,maxPct; // min and max percentage of habitat in a cell - float propSuit; // proportion of suitable cells - float hurst; // Hurst exponent - int maxCells; // max. cells per patch (artificial landscapes) - int pix; // image display ratio - float gpix; // image display ratio for gradient map - double minEast; // ) real world min co-ordinates - double minNorth; // ) read from habitat raster - - // list of cells in the landscape - // cells MUST be loaded in the sequence ascending x within descending y - Cell ***cells; - - // list of patches in the landscape - can be in any sequence - std::vector patches; - - // list of patch numbers in the landscape - std::vector patchnums; - - // list of habitat codes - std::vector habCodes; - - // list of colours for habitat codes - std::vector colours; - - // list of dynamic landscape changes - std::vector landchanges; - std::vector patchchanges; - std::vector costschanges; - - // list of initial individual species distributions - std::vector distns; - - // list of cells to be initialised for ALL species - std::vector initcells; - - // patch connectivity matrix - // indexed by [start patch seq num][end patch seq num] - int **connectMatrix; - - // global environmental stochasticity (epsilon) - float *epsGlobal; // pointer to time-series - - // patch and costs change matrices (temporary - used when reading dynamic landscape) - // indexed by [descending y][x][period] - // where there are three periods, 0=original 1=previous 2=current - int ***patchChgMatrix; - int ***costsChgMatrix; - -}; - -// NOTE: the following function is not a behaviour of Landscape, as it is run by the -// batch routine to check raster files before any Landscape has been initiated -rasterdata CheckRasterFile(string); - -extern paramGrad *paramsGrad; -extern paramStoch *paramsStoch; -extern paramInit *paramsInit; -extern paramSim *paramsSim; -extern RSrandom *pRandom; - -#if RSDEBUG -extern ofstream DEBUGLOG; -extern void DebugGUI(string); -#endif - -extern void MemoLine(string); - -#if RS_RCPP -extern rasterdata landraster,patchraster,spdistraster,costsraster; -extern void EOFerrorR(string); -extern void StreamErrorR(string); -#endif - -//--------------------------------------------------------------------------- -#endif diff --git a/src/RScore/Main.cpp b/src/RScore/Main.cpp deleted file mode 100644 index 42f783b..0000000 --- a/src/RScore/Main.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - -#if LINUX_CLUSTER || R_CMD -#include -#else -#include -#endif - -#include -#include -#include -#include -#include "Individual.h" -#include "Community.h" -#include "RSrandom.h" -#include "Utils.h" -#include "Parameters.h" -#include "Landscape.h" -#include "Species.h" -#include "SubCommunity.h" - -using namespace std; - -void run_unit_tests() { - cout << "******* Unit test output *******" << endl; - testRSrandom(); - testIndividual(); - cout << endl << "************************" << endl; -} - -// Global vars -string habmapname, patchmapname, distnmapname; -string costmapname, genfilename; -string landFile; -paramGrad* paramsGrad; -paramStoch* paramsStoch; -paramInit* paramsInit; -paramSim* paramsSim; -RSrandom* pRandom; -ofstream DEBUGLOG; -ofstream MUTNLOG; -vector hfnames; -Species* pSpecies; -Community* pComm; -void DebugGUI(string msg) { - // nothing -} -void MemoLine(string msg) { - /// nothing -} -traitCanvas SetupTraitCanvas(void) { - traitCanvas tcanv; - for (int i = 0; i < NTRAITS; i++) { tcanv.pcanvas[i] = 0; } - return tcanv; -} -void Landscape::setLandMap(void) { } -void Landscape::drawLandscape(int rep, int yr, int landnum) { } -void Community::viewOccSuit(int year, double mn, double se) { } -void Community::draw(int rep, int yr, int gen, int landNum) { } - -#if LINUX_CLUSTER || RS_RCPP -int main(int argc, char* argv[]) -#else -int _tmain(int argc, _TCHAR* argv[]) -#endif -{ -#ifdef NDEBUG - cout << "This code is only for running tests and not meant to run in release." << endl; - return 1; -# else - assert(0.1 > 0.0); // assert does run correctly - run_unit_tests(); - cout << "All tests have completed." << endl; - return 0; // if tests succeed, we are happy -# endif // NDEBUG -} diff --git a/src/RScore/Model.cpp b/src/RScore/Model.cpp deleted file mode 100644 index 64b5d87..0000000 --- a/src/RScore/Model.cpp +++ /dev/null @@ -1,2265 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Model.h" - -ofstream outPar; - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -#if RS_RCPP && !R_CMD -Rcpp::List RunModel(Landscape *pLandscape,int seqsim) -#else -int RunModel(Landscape *pLandscape,int seqsim) -#endif -{ -//int Nsuit,yr,totalInds; -int yr,totalInds; -//float gradval,gradmin,gradmax; -bool filesOK; -//int t0,t1; - -landParams ppLand = pLandscape->getLandParams(); -envGradParams grad = paramsGrad->getGradient(); -envStochParams env = paramsStoch->getStoch(); -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -//emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -initParams init = paramsInit->getInit(); -simParams sim = paramsSim->getSim(); -simView v = paramsSim->getViews(); - -//t0 = time(0); - -#if RSDEBUG -landPix p = pLandscape->getLandPix(); -DEBUGLOG << "RunModel(): reps=" << sim.reps - << " ppLand.nHab=" << ppLand.nHab - << " p.pix=" << p.pix - << endl; -//DEBUGLOG << "RunModel(): random integers:"; -//for (int i = 0; i < 5; i++) { -// int rrrr = pRandom->IRandom(1000,2000); DEBUGLOG << " " << rrrr; -//} -DEBUGLOG << endl; -#endif - -if (!ppLand.generated) { - if (!ppLand.patchModel) { // cell-based landscape - // create patches for suitable cells, adding unsuitable cells to the matrix - // NB this is an overhead here, but is necessary in case the identity of - // suitable habitats has been changed from one simulation to another (GUI or batch) - // substantial time savings may result during simulation in certain landscapes - pLandscape->allocatePatches(pSpecies); - } - pComm = new Community(pLandscape); // set up community - // set up a sub-community associated with each patch (incl. the matrix) - pLandscape->updateCarryingCapacity(pSpecies,0,0); -// if (ppLand.rasterType <= 2 && ppLand.dmgLoaded) -// pLandscape->updateDamageIndices(); - patchData ppp; - int npatches = pLandscape->patchCount(); - for (int i = 0; i < npatches; i++) { - ppp = pLandscape->getPatchData(i); -#if RSDEBUG -//DEBUGLOG << "RunModel(): i = " << i -// << " ppp.pPatch = " << ppp.pPatch << " ppp.patchNum = " << ppp.patchNum -// << endl; -#endif - pComm->addSubComm(ppp.pPatch,ppp.patchNum); // SET UP ALL SUB-COMMUNITIES -// if (i == 0 || ppp.pPatch->getK() > 0.0) { -// // SET UP SUB-COMMUNITY FOR MATRIX PATCH AND ANY PATCH HAVING NON-ZERO CARRYING CAPACITY -// pComm->addSubComm(ppp.pPatch,ppp.patchNum); -// } - } - if (init.seedType == 0 && init.freeType < 2 && init.initFrzYr > 0) { - // restrict available landscape to initialised region - pLandscape->setLandLimits(init.minSeedX,init.minSeedY, - init.maxSeedX,init.maxSeedY); - } - else { - pLandscape->resetLandLimits(); - } -} - -#if RS_RCPP && !R_CMD -Rcpp::List list_outPop; -#endif - -// Loop through replicates -for (int rep = 0; rep < sim.reps; rep++) { -#if RSDEBUG -DEBUGLOG << endl << "RunModel(): starting simulation=" << sim.simulation << " rep=" << rep << endl; -#endif -#if RS_RCPP && !R_CMD - Rcpp::Rcout << endl << "starting replicate " << rep << endl; -#else -#if BATCH - cout << endl << "starting replicate " << rep << endl; -#endif -#endif - - MemoLine(("Running replicate " + Int2Str(rep) + "...").c_str()); - - if (sim.saveVisits && !ppLand.generated) { - pLandscape->resetVisits(); - } - - patchChange patchchange; - costChange costchange; - int npatchchanges = pLandscape->numPatchChanges(); - int ncostchanges = pLandscape->numCostChanges(); - int ixpchchg = 0; - int ixcostchg = 0; -#if RSDEBUG -DEBUGLOG << "RunModel(): npatchchanges=" << npatchchanges << " ncostchanges=" << ncostchanges << endl; -#endif - - if (ppLand.generated) { -#if RSDEBUG -DEBUGLOG << endl << "RunModel(): generating new landscape ..." << endl; -#endif - // delete previous community (if any) - // Note: this must be BEFORE the landscape is reset (as a sub-community accesses - // its corresponding patch upon deletion) - if (pComm != 0) delete pComm; - // generate new cell-based landscape - MemoLine("...generating new landscape..."); - pLandscape->resetLand(); -#if RSDEBUG -DEBUGLOG << "RunModel(): finished resetting landscape" << endl << endl; -#endif - pLandscape->generatePatches(); - if (v.viewLand || sim.saveMaps) { - pLandscape->setLandMap(); - pLandscape->drawLandscape(rep,0,ppLand.landNum); - } -#if RSDEBUG -DEBUGLOG << endl << "RunModel(): finished generating patches" << endl; -#endif - pComm = new Community(pLandscape); // set up community - // set up a sub-community associated with each patch (incl. the matrix) -// pLandscape->updateCarryingCapacity(pSpecies,0); - pLandscape->updateCarryingCapacity(pSpecies,0,0); - patchData ppp; - int npatches = pLandscape->patchCount(); -#if RSDEBUG -DEBUGLOG << "RunModel(): patch count is " << npatches << endl; -#endif - for (int i = 0; i < npatches; i++) { - ppp = pLandscape->getPatchData(i); -#if RSDEBUG -//DEBUGLOG << "RunModel(): i = " << i -// << " ppp.pPatch = " << ppp.pPatch << " ppp.patchNum = " << ppp.patchNum -// << endl; -#endif -#if RSWIN64 -#if LINUX_CLUSTER - pComm->addSubComm(ppp.pPatch,ppp.patchNum); // SET UP ALL SUB-COMMUNITIES -#else - SubCommunity *pSubComm = pComm->addSubComm(ppp.pPatch,ppp.patchNum); // SET UP ALL SUB-COMMUNITIES -#endif -// if (ppp.y >= 9995) { -// DEBUGLOG << "RunModel(): i=" << i << " pSubComm=" << pSubComm -// << endl; -// } -#else - pComm->addSubComm(ppp.pPatch,ppp.patchNum); // SET UP ALL SUB-COMMUNITIES -#endif -// if (i == 0 || ppp.pPatch->getK() > 0.0) { -// // SET UP SUB-COMMUNITY FOR MATRIX PATCH AND ANY PATCH HAVING NON-ZERO CARRYING CAPACITY -// pComm->addSubComm(ppp.pPatch,ppp.patchNum); -// } - } - MemoLine("...completed..."); -#if RSDEBUG -DEBUGLOG << endl << "RunModel(): finished generating populations" << endl; -#endif - } - if (init.seedType == 0 && init.freeType < 2 && init.initFrzYr > 0) { - // restrict available landscape to initialised region - pLandscape->setLandLimits(init.minSeedX,init.minSeedY, - init.maxSeedX,init.maxSeedY); - } - else { - pLandscape->resetLandLimits(); - } - - filesOK = true; - if (rep == 0) { - // open output files - if (sim.outRange) { // open Range file - if (!pComm->outRangeHeaders(pSpecies,ppLand.landNum)) { - MemoLine("UNABLE TO OPEN RANGE FILE"); - filesOK = false; - } - } - if (sim.outOccup && sim.reps > 1) - if (!pComm->outOccupancyHeaders(0)) { - MemoLine("UNABLE TO OPEN OCCUPANCY FILE(S)"); - filesOK = false; - } - if (sim.outPop) { - // open Population file - if (!pComm->outPopHeaders(pSpecies,ppLand.landNum)) { - MemoLine("UNABLE TO OPEN POPULATION FILE"); - filesOK = false; - } - } - if (sim.outTraitsCells) - if (!pComm->outTraitsHeaders(pSpecies,ppLand.landNum)) { - MemoLine("UNABLE TO OPEN TRAITS FILE"); - filesOK = false; - } - if (sim.outTraitsRows) - if (!pComm->outTraitsRowsHeaders(pSpecies,ppLand.landNum)) { - MemoLine("UNABLE TO OPEN TRAITS ROWS FILE"); - filesOK = false; - } - if (sim.outConnect && ppLand.patchModel) // open Connectivity file - if (!pLandscape->outConnectHeaders(0)) { - MemoLine("UNABLE TO OPEN CONNECTIVITY FILE"); - filesOK = false; - } - } -#if RSDEBUG -DEBUGLOG << "RunModel(): completed opening output files" << endl; -#endif - if (!filesOK) { -#if RSDEBUG -DEBUGLOG << "RunModel(): PROBLEM - closing output files" << endl; -#endif - // close any files which may be open - if (sim.outRange) { - pComm->outRangeHeaders(pSpecies,-999); - } - if (sim.outOccup && sim.reps > 1) - pComm->outOccupancyHeaders(-999); - if (sim.outPop) { - pComm->outPopHeaders(pSpecies,-999); - } - if (sim.outTraitsCells) - pComm->outTraitsHeaders(pSpecies,-999); - if (sim.outTraitsRows) - pComm->outTraitsRowsHeaders(pSpecies,-999); - if (sim.outConnect && ppLand.patchModel) - pLandscape->outConnectHeaders(-999); -#if RS_RCPP && !R_CMD - return Rcpp::List::create(Rcpp::Named("Errors") = 666); -#else - return 666; -#endif - } - - if (env.stoch && !env.local) { - // create time series in case of global environmental stochasticity - pLandscape->setGlobalStoch(sim.years+1); - } - - if (grad.gradient) { // set up environmental gradient - pLandscape->setEnvGradient(pSpecies,true); - } - - if (sim.outConnect && ppLand.patchModel) - pLandscape->createConnectMatrix(); - - // variables to control dynamic landscape - landChange landChg; landChg.chgnum = 0; landChg.chgyear = 999999; - if (!ppLand.generated && ppLand.dynamic) { - landChg = pLandscape->getLandChange(0); // get first change year - } - - // set up populations in the community - pLandscape->updateCarryingCapacity(pSpecies,0,0); -#if RSDEBUG -DEBUGLOG << "RunModel(): completed updating carrying capacity" << endl; -#endif -// if (init.seedType != 2) { - pComm->initialise(pSpecies,-1); -// } - bool updateland = false; - int landIx = 0; // landscape change index - -#if RSDEBUG -DEBUGLOG << "RunModel(): completed initialisation, rep=" << rep - << " pSpecies=" << pSpecies << endl; -#endif -#if BATCH && RS_RCPP && !R_CMD - Rcpp::Rcout << "RunModel(): completed initialisation " << endl; -#endif - - // open a new individuals file for each replicate - if (sim.outInds) - pComm->outInds(rep,0,0,ppLand.landNum); - // open a new genetics file for each replicate - if (sim.outGenetics) { - pComm->outGenetics(rep,0,0,ppLand.landNum); - if (!dem.stageStruct && sim.outStartGenetic == 0) { - // write genetic data for initialised individuals of non-strucutred population - pComm->outGenetics(rep,0,0,-1); - } - } -#if RSDEBUG - // output initialised Individuals - if (sim.outInds) - pComm->outInds(rep,-1,-1,-1); -#endif -#if RS_RCPP - // open a new movement paths file for each replicate - if (sim.outPaths) - pLandscape->outPathsHeaders(rep,0); -#endif - - // years loop - MemoLine("...running..."); - for (yr = 0; yr < sim.years; yr++) { -#if RSDEBUG -DEBUGLOG << endl << "RunModel(): starting simulation=" << sim.simulation - << " rep=" << rep << " yr=" << yr << endl; -#endif -#if RS_RCPP && !R_CMD - Rcpp::checkUserInterrupt(); -#endif - bool updateCC = false; - if (yr < 4 - || (yr < 31 && yr%10 == 0) - || (yr < 301 && yr%100 == 0) - || (yr < 3001 && yr%1000 == 0) - || (yr < 30001 && yr%10000 == 0) - || (yr < 300001 && yr%100000 == 0) - || (yr < 3000001 && yr%1000000 == 0) - ) { -#if RS_RCPP && !R_CMD - Rcpp::Rcout << "starting year " << yr << "..." << endl; -#else - cout << "starting year " << yr << endl; -#endif - } - if (init.seedType == 0 && init.freeType < 2) { - // apply any range restrictions - if (yr == init.initFrzYr) { - // release initial frozen range - reset landscape to its full extent - pLandscape->resetLandLimits(); - updateCC = true; - } - if (init.restrictRange) { - if (yr > init.initFrzYr && yr < init.finalFrzYr) { - if ((yr-init.initFrzYr)%init.restrictFreq == 0) { - // apply dynamic range restriction - commStats s = pComm->getStats(); - int minY = s.maxY-init.restrictRows; - if (minY < 0) minY = 0; -#if RSDEBUG -DEBUGLOG << "RunModel(): restriction yr=" << yr - << " s.minY=" << s.minY << " s.maxY=" << s.maxY - << " init.restrictRows=" << init.restrictRows - << " minY=" << minY - << endl; -#endif - pLandscape->setLandLimits(ppLand.minX,minY,ppLand.maxX,ppLand.maxY); - updateCC = true; -#if RSDEBUG -//landData d = pLandscape->getLandData(); -//DEBUGLOG << "RunModel(): landscape yr=" << yr -// << " minX=" << d.minX << " minY=" << d.minY << " maxX=" << d.maxX << " maxY=" << d.maxY -// << endl; -#endif - } - } - if (yr == init.finalFrzYr) { - // apply final range restriction - commStats s = pComm->getStats(); -#if RSDEBUG -DEBUGLOG << "RunModel(): final restriction yr=" << yr - << " s.minY=" << s.minY << " s.maxY=" << s.maxY - << endl; -#endif - pLandscape->setLandLimits(ppLand.minX,s.minY,ppLand.maxX,s.maxY); - updateCC = true; -#if RSDEBUG -//landData d = pLandscape->getLandData(); -//DEBUGLOG << "RunModel(): landscape yr=" << yr -// << " minX=" << d.minX << " minY=" << d.minY << " maxX=" << d.maxX << " maxY=" << d.maxY -// << endl; -#endif - } - } - } - // environmental gradient, stochasticity & local extinction - // or dynamic landscape - updateland = false; - if (env.stoch || grad.gradient || ppLand.dynamic) { - if (grad.shifting && yr > grad.shift_begin && yr < grad.shift_stop) { - paramsGrad->incrOptY(); - pLandscape->setEnvGradient(pSpecies,false); - updateCC = true; - } -#if RSDEBUG -//DEBUGLOG << "RunModel(): yr=" << yr << " shift_begin=" << grad.shift_begin -// << " shift_stop=" << grad.shift_stop << " opt_y=" << grad.opt_y << endl; -#endif - if (env.stoch) { - if (env.local) pLandscape->updateLocalStoch(); - updateCC = true; - } - if (ppLand.dynamic) { -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " landChg.chgnum=" << landChg.chgnum - << " landChg.chgyear=" << landChg.chgyear - << " npatchchanges=" << npatchchanges << " ncostchanges=" << ncostchanges - << " ixpchchg=" << ixpchchg << " ixcostchg=" << ixcostchg - << endl; -#endif - if (yr == landChg.chgyear) { // apply landscape change - landIx = landChg.chgnum; - updateland = updateCC = true; - if (ppLand.patchModel) { // apply any patch changes - Patch *pPatch; - Cell *pCell; - patchchange = pLandscape->getPatchChange(ixpchchg++); - while (patchchange.chgnum <= landIx && ixpchchg <= npatchchanges) { -#if RSDEBUG -//DEBUGLOG << "RunModel(): yr=" << yr << " landIx=" << landIx -// << " npatchchanges=" << npatchchanges << " ixpchchg=" << ixpchchg -// << " patchchange.chgnum=" << patchchange.chgnum -// << " .oldpatch=" << patchchange.oldpatch -// << " .newpatch=" << patchchange.newpatch -// << " .x=" << patchchange.x << " .y=" << patchchange.y -// << endl; -#endif - // move cell from original patch to new patch - pCell = pLandscape->findCell(patchchange.x,patchchange.y); - if (patchchange.oldpatch != 0) { // not matrix - pPatch = pLandscape->findPatch(patchchange.oldpatch); - pPatch->removeCell(pCell); - } - if (patchchange.newpatch == 0) { // matrix - pPatch = 0; - } - else { - pPatch = pLandscape->findPatch(patchchange.newpatch); - pPatch->addCell(pCell,patchchange.x,patchchange.y); - } - pCell->setPatch((intptr)pPatch); - // get next patch change - patchchange = pLandscape->getPatchChange(ixpchchg++); - } - ixpchchg--; - pLandscape->resetPatches(); // reset patch limits - } - if (landChg.costfile != "NULL") { // apply any SMS cost changes -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " landChg.costfile=" << landChg.costfile << endl; -#endif - Cell *pCell; - costchange = pLandscape->getCostChange(ixcostchg++); - while (costchange.chgnum <= landIx && ixcostchg <= ncostchanges) { -#if RSDEBUG -//DEBUGLOG << "RunModel(): yr=" << yr << " landIx=" << landIx -// << " ncostchanges=" << ncostchanges << " ixcostchg=" << ixcostchg -// << " costchange.chgnum=" << costchange.chgnum -// << " .x=" << costchange.x << " .y=" << costchange.y -// << " .oldcost=" << costchange.oldcost -// << " .newcost=" << costchange.newcost -// << endl; -#endif - pCell = pLandscape->findCell(costchange.x,costchange.y); - if (pCell != 0) { - pCell->setCost(costchange.newcost); - } - costchange = pLandscape->getCostChange(ixcostchg++); - } - ixcostchg--; - pLandscape->resetEffCosts(); - } - if (landIx < pLandscape->numLandChanges()) { // get next change - landChg = pLandscape->getLandChange(landIx); - } - else { - landChg.chgyear = 9999999; - } - } - } - } // end of environmental gradient, etc. - - if (updateCC) { - pLandscape->updateCarryingCapacity(pSpecies,yr,landIx); - } - - - if (sim.outConnect && ppLand.patchModel) - pLandscape->resetConnectMatrix(); - - if (ppLand.dynamic && updateland) { -// trfrRules trfr = pSpecies->getTrfr(); - if (trfr.moveModel && trfr.moveType == 1) { // SMS - if (!trfr.costMap) pLandscape->resetCosts(); // in case habitats have changed - } - // apply effects of landscape change to species present in changed patches - pComm->patchChanges(); -#if RS_RCPP - pComm->dispersal(landIx,yr); -#else - pComm->dispersal(landIx); -#endif // RS_RCPP - } - if (init.restrictRange) { - // remove any population from region removed from restricted range - if (yr > init.initFrzYr && yr < init.finalFrzYr) { - if ((yr-init.initFrzYr)%init.restrictFreq == 0) { - pComm->patchChanges(); - } - } - } - - if (init.seedType == 2) { - // add any new initial individuals for the current year - pComm->initialise(pSpecies,yr); - } - - for(int gen = 0; gen < dem.repSeasons; gen++) // generation loop - { -#if RSDEBUG -// TEMPORARY RANDOM STREAM CHECK -//if (yr%1 == 0 && gen == 0) -if (yr%1 == 0) -{ -DEBUGLOG << endl << "RunModel(): start of gen " << gen << " in year " << yr - << " for rep " << rep << " ("; -for (int i = 0; i < 5; i++) { - int rrrr = pRandom->IRandom(1000,2000); - DEBUGLOG << " " << rrrr; -} -DEBUGLOG << " )" << endl; -} -#endif - - if (v.viewPop || (sim.saveMaps && yr%sim.mapInt == 0)) { - if (updateland && gen == 0) { - pLandscape->drawLandscape(rep,landIx,ppLand.landNum); - } - pComm->draw(rep,yr,gen,ppLand.landNum); - } - // Output and pop. visualisation before reproduction - if (v.viewPop || v.viewTraits || sim.outOccup - || sim.outTraitsCells || sim.outTraitsRows || sim.saveMaps) - PreReproductionOutput(pLandscape,pComm,rep,yr,gen); - // for non-structured population, also produce range and population output now - if (!dem.stageStruct && (sim.outRange || sim.outPop)) - RangePopOutput(pComm,rep,yr,gen); -#if RS_RCPP && !R_CMD - if ( sim.ReturnPopRaster && sim.outPop && yr >= sim.outStartPop && yr%sim.outIntPop == 0) { - list_outPop.push_back(pComm->addYearToPopList(rep,yr), "rep" + std::to_string(rep) + "_year" + std::to_string(yr)); - } -#endif - -#if RSDEBUG -//DEBUGLOG << "RunModel(): completed RangePopOutput()" -// << " Total_Size = " << Total_Size << endl; -#endif - - // apply local extinction for generation 0 only - // CHANGED TO *BEFORE* RANGE & POPN OUTPUT PRODUCTION IN v1.1, - // SO THAT NOS. OF JUVENILES BORN CAN BE REPORTED - if (!ppLand.patchModel && gen == 0) { - if (env.localExt) pComm->localExtinction(0); - if (grad.gradient && grad.gradType == 3) pComm->localExtinction(1); - } - - // reproduction - pComm->reproduction(yr); - - if (dem.stageStruct) { - if (sstruct.survival == 0) { // at reproduction - pComm->survival(0,2,1); // survival of all non-juvenile stages - } - } - - // Output and pop. visualisation AFTER reproduction - if (dem.stageStruct && (sim.outRange || sim.outPop)) - RangePopOutput(pComm,rep,yr,gen); - -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed reproduction" << endl; -#endif - - // Dispersal - - pComm->emigration(); -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed emigration" << endl; -#endif -#if RS_RCPP - pComm->dispersal(landIx,yr); -#else - pComm->dispersal(landIx); -#endif // RS_RCPP -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed dispersal" << endl; -#endif - - // survival part 0 - if (dem.stageStruct) { - if (sstruct.survival == 0) { // at reproduction - pComm->survival(0,0,1); // survival of juveniles only - } - if (sstruct.survival == 1) { // between reproduction events - pComm->survival(0,1,1); // survival of all stages - } - if (sstruct.survival == 2) { // annually - pComm->survival(0,1,0); // development only of all stages -// pComm->survival(0,1,0); // development only of all stages - } - } - else { // non-structured population - pComm->survival(0,1,1); - } -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed survival part 0" << endl; -#endif - - - // output Individuals - if (sim.outInds && yr >= sim.outStartInd && yr%sim.outIntInd == 0) - pComm->outInds(rep,yr,gen,-1); - // output Genetics - if (sim.outGenetics && yr >= sim.outStartGenetic && yr%sim.outIntGenetic == 0) - pComm->outGenetics(rep,yr,gen,-1); - - // survival part 1 - if (dem.stageStruct) { -// if (sstruct.survival != 2) { // at reproduction or between reproduction events - pComm->survival(1,0,1); -// } - } - else { // non-structured population - pComm->survival(1,0,1); - } -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed survival part 1" << endl; -#endif - - } // end of the generation loop -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " completed generation loop" << endl; -#endif - - totalInds = pComm->totalInds(); - if (totalInds <= 0) { yr++; break; } - - // Connectivity Matrix - if (sim.outConnect && ppLand.patchModel - && yr >= sim.outStartConn && yr%sim.outIntConn == 0) - pLandscape->outConnect(rep,yr); - - if (dem.stageStruct && sstruct.survival == 2) { // annual survival - all stages - pComm->survival(0,1,2); - pComm->survival(1,0,1); -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " completed annual survival" << endl; -#endif - } - - if (dem.stageStruct) { - pComm->ageIncrement(); // increment age of all individuals - if (sim.outInds && yr >= sim.outStartInd && yr%sim.outIntInd == 0) - pComm->outInds(rep,yr,-1,-1); // list any individuals dying having reached maximum age - pComm->survival(1,0,1); // delete any such individuals -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " completed Age_increment and final survival" << endl; -#endif - totalInds = pComm->totalInds(); - if (totalInds <= 0) { yr++; break; } - } - - } // end of the years loop - - // Final output and popn. visualisation -#if BATCH - if (sim.saveMaps && yr%sim.mapInt == 0) { - if (updateland) { - pLandscape->drawLandscape(rep,landIx,ppLand.landNum); - } - pComm->draw(rep,yr,0,ppLand.landNum); - } -#endif - // produce final summary output - if (v.viewPop || v.viewTraits || sim.outOccup - || sim.outTraitsCells || sim.outTraitsRows || sim.saveMaps) - PreReproductionOutput(pLandscape,pComm,rep,yr,0); - if (sim.outRange || sim.outPop) - RangePopOutput(pComm,rep,yr,0); -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " completed final summary output" << endl; -#endif - - pComm->resetPopns(); - -// if (batchMode) { -// // delete the community of species using the landscape -// pComm->resetPopns(); -// } - - //Reset the gradient optimum - if (grad.gradient) paramsGrad->resetOptY(); - - pLandscape->resetLandLimits(); -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " landIx=" << "reset" - << " npatchchanges=" << npatchchanges << " ncostchanges=" << ncostchanges - << " ixpchchg=" << ixpchchg << " ixcostchg=" << ixcostchg - << endl; -#endif - if (ppLand.patchModel && ppLand.dynamic && ixpchchg > 0) { - // apply any patch changes to reset landscape to original configuration - // (provided that at least one has already occurred) - patchChange patchchange; - Patch *pPatch; - Cell *pCell; - patchchange = pLandscape->getPatchChange(ixpchchg++); - while (patchchange.chgnum <= 666666 && ixpchchg <= npatchchanges) { -#if RSDEBUG -//DEBUGLOG << "RunModel(): yr=" << yr << " landIx=" << "reset" -// << " npatchchanges=" << npatchchanges << " ixpchchg=" << ixpchchg -// << " patchchange.chgnum=" << patchchange.chgnum -// << " .oldpatch=" << patchchange.oldpatch -// << " .newpatch=" << patchchange.newpatch -// << " .x=" << patchchange.x << " .y=" << patchchange.y -// << endl; -#endif - // move cell from original patch to new patch - pCell = pLandscape->findCell(patchchange.x,patchchange.y); - if (patchchange.oldpatch != 0) { // not matrix - pPatch = pLandscape->findPatch(patchchange.oldpatch); - pPatch->removeCell(pCell); - } - if (patchchange.newpatch == 0) { // matrix - pPatch = 0; - } - else { - pPatch = pLandscape->findPatch(patchchange.newpatch); - pPatch->addCell(pCell,patchchange.x,patchchange.y); - } - pCell->setPatch((intptr)pPatch); - // get next patch change - patchchange = pLandscape->getPatchChange(ixpchchg++); - } - ixpchchg--; - pLandscape->resetPatches(); - } - if (ppLand.dynamic) { - trfrRules trfr = pSpecies->getTrfr(); - if (trfr.moveModel && trfr.moveType == 1) { // SMS - if (ixcostchg > 0) { - // apply any cost changes to reset landscape to original configuration - // (provided that at least one has already occurred) - Cell *pCell; - costchange = pLandscape->getCostChange(ixcostchg++); - while (costchange.chgnum <= 666666 && ixcostchg <= ncostchanges) { -#if RSDEBUG -//DEBUGLOG << "RunModel(): yr=" << yr << " landIx=" << landIx -// << " ncostchanges=" << ncostchanges << " ixcostchg=" << ixcostchg -// << " costchange.chgnum=" << costchange.chgnum -// << " .x=" << costchange.x << " .y=" << costchange.y -// << " .oldcost=" << costchange.oldcost -// << " .newcost=" << costchange.newcost -// << endl; -#endif - pCell = pLandscape->findCell(costchange.x,costchange.y); - if (pCell != 0) { - pCell->setCost(costchange.newcost); - } - costchange = pLandscape->getCostChange(ixcostchg++); - } - ixcostchg--; - pLandscape->resetEffCosts(); - } - if (!trfr.costMap) pLandscape->resetCosts(); // in case habitats have changed - } - } -// if (landIx < pLandscape->numLandChanges()) { // get next change -// landChg = pLandscape->getLandChange(landIx); -// } -// else { -// landChg.chgyear = 9999999; -// } -#if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " completed reset" - << endl; -#endif - - if (sim.outConnect && ppLand.patchModel) - pLandscape->resetConnectMatrix(); // set connectivity matrix to zeroes - - if (sim.outInds) // close Individuals output file - pComm->outInds(rep,0,0,-999); - if (sim.outGenetics) // close Genetics output file - pComm->outGenetics(rep,0,0,-999); - - if (sim.saveVisits) { - pLandscape->outVisits(rep,ppLand.landNum); - pLandscape->resetVisits(); - } - -#if RS_RCPP - if (sim.outPaths) - pLandscape->outPathsHeaders(rep,-999); -#endif -#if RSDEBUG -DEBUGLOG << endl << "RunModel(): finished rep=" << rep << endl; -#endif - -} // end of the replicates loop - -if (sim.outConnect && ppLand.patchModel) { - pLandscape->deleteConnectMatrix(); - pLandscape->outConnectHeaders(-999); // close Connectivity Matrix file -} - -// Occupancy outputs -if (sim.outOccup && sim.reps > 1) { - MemoLine("Writing final occupancy output..."); - pComm->outOccupancy(); - pComm->outOccSuit(v.viewGraph); -// pComm->deleteOccupancy((sim.years/sim.outInt)+1); - pComm->deleteOccupancy((sim.years/sim.outIntOcc)+1); - pComm->outOccupancyHeaders(-999); - MemoLine("...finished"); -} - -if (sim.outRange) { - pComm->outRangeHeaders(pSpecies,-999); // close Range file -} -if (sim.outPop) { - pComm->outPopHeaders(pSpecies,-999); // close Population file -} -if (sim.outTraitsCells) - pComm->outTraitsHeaders(pSpecies,-999); // close Traits file -if (sim.outTraitsRows) - pComm->outTraitsRowsHeaders(pSpecies,-999); // close Traits rows file -// close Individuals & Genetics output files if open -// they can still be open if the simulation was stopped by the user -if (sim.outInds) pComm->outInds(0,0,0,-999); -if (sim.outGenetics) pComm->outGenetics(0,0,0,-999); - -MemoLine("Deleting community..."); -delete pComm; pComm = 0; -MemoLine("...finished"); - -// Write performance data -//t1 = time(0); -//RSlog << "Simulation," << sim.simulation << "," << sim.reps << "," << sim.years -// << "," << t1-t0 << endl; - -#if RS_RCPP && !R_CMD - return list_outPop; -#else - return 0; -#endif - -} - -#if RS_EMBARCADERO || LINUX_CLUSTER || RS_RCPP -// Check whether a specified directory path exists -bool is_directory(const char *pathname) { -struct stat info; -if (stat(pathname, &info) != 0) return false; // path does not exist -if (S_ISDIR(info.st_mode)) return true; -return false; -} -#endif - -//--------------------------------------------------------------------------- -bool CheckDirectory(void) -{ -bool errorfolder = false; - -string subfolder; - -subfolder = paramsSim->getDir(0) + "Inputs"; -const char *inputs = subfolder.c_str(); -if (!is_directory(inputs)) errorfolder = true; -subfolder = paramsSim->getDir(0) + "Outputs"; -const char *outputs = subfolder.c_str(); -if (!is_directory(outputs)) errorfolder = true; -subfolder = paramsSim->getDir(0) + "Output_Maps"; -const char *outputmaps = subfolder.c_str(); -if (!is_directory(outputmaps)) errorfolder = true; - -return errorfolder; -} - -//--------------------------------------------------------------------------- -//For outputs and population visualisations pre-reproduction -void PreReproductionOutput(Landscape *pLand,Community *pComm,int rep,int yr,int gen) -{ -#if RSDEBUG -landParams ppLand = pLand->getLandParams(); -#endif -simParams sim = paramsSim->getSim(); -simView v = paramsSim->getViews(); - -#if RSDEBUG -DEBUGLOG << "PreReproductionOutput(): 11111 rep=" << rep << " yr=" << yr << " gen=" << gen - << " landNum=" << ppLand.landNum << " maxX=" << ppLand.maxX << " maxY=" << ppLand.maxY - << endl; -DEBUGLOG << "PreReproductionOutput(): 11112 outRange=" << sim.outRange - << " outIntRange=" << sim.outIntRange - << " outPop=" << sim.outPop << " outIntPop=" << sim.outIntPop - << endl; -#endif - -#if RSDEBUG -//DEBUGLOG << "PreReproductionOutput(): 22222 " << endl; -#endif - -//emigCanvas ecanv; -//trfrCanvas tcanv; -traitCanvas tcanv; -//for (int i = 0; i < 6; i++) { -// ecanv.pcanvas[i] = 0; tcanv.pcanvas[i] = 0; -//} -for (int i = 0; i < NTRAITS; i++) { - tcanv.pcanvas[i] = 0; -} - -// trait outputs and visualisation - -if (v.viewTraits) { -// ecanv = SetupEmigCanvas(); -// tcanv = SetupTrfrCanvas(); -// tcanv = SetupTraitCanvas(v.viewGrad); - tcanv = SetupTraitCanvas(); -} - -if (v.viewTraits -|| ((sim.outTraitsCells && yr >= sim.outStartTraitCell && yr%sim.outIntTraitCell == 0) || - (sim.outTraitsRows && yr >= sim.outStartTraitRow && yr%sim.outIntTraitRow == 0))) -{ -// pComm->outTraits(ecanv,tcanv,pSpecies,rep,yr,gen); - pComm->outTraits(tcanv,pSpecies,rep,yr,gen); -} - -#if RSDEBUG -//DEBUGLOG << "PreReproductionOutput(): 33333 " << endl; -#endif - -if (sim.outOccup && yr%sim.outIntOcc == 0 && gen == 0) - pComm->updateOccupancy(yr/sim.outIntOcc,rep); - -#if RSDEBUG -//DEBUGLOG << "PreReproductionOutput(): 88888 " << endl; -#endif - -// Remaining graphical output actions are performed for GUI only - -#if RSDEBUG -//DEBUGLOG << "PreReproductionOutput(): finished " << endl; -#endif -} - -//For outputs and population visualisations pre-reproduction -void RangePopOutput(Community *pComm,int rep,int yr,int gen) -{ -simParams sim = paramsSim->getSim(); - -if (sim.outRange && (yr%sim.outIntRange == 0 || pComm->totalInds() <= 0)) - pComm->outRange(pSpecies,rep,yr,gen); - -if (sim.outPop && yr >= sim.outStartPop && yr%sim.outIntPop == 0) - pComm->outPop(rep,yr,gen); - -} - -//--------------------------------------------------------------------------- -void OutParameters(Landscape *pLandscape) -{ -double k; -//int nrows,ncols,nsexes,nstages; -int nsexes,nstages; - -landParams ppLand = pLandscape->getLandParams(); -genLandParams ppGenLand = pLandscape->getGenLandParams(); -envGradParams grad = paramsGrad->getGradient(); -envStochParams env = paramsStoch->getStoch(); -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -settleRules srules; -settleSteps ssteps; -settleTraits settleDD; -simParams sim = paramsSim->getSim(); - -string name; -if (sim.batchMode) - name = paramsSim->getDir(2) - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) - + "_Land" + Int2Str(ppLand.landNum) + "_Parameters.txt"; -else - name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) + "_Parameters.txt"; -outPar.open(name.c_str()); - -outPar << "RangeShifter 2.0 "; - -#if !RS_RCPP -#if RSWIN64 -outPar << " - 64 bit implementation"; -#else -outPar << " - 32 bit implementation"; -#endif -#endif -outPar << endl; - -outPar << "================ "; - -outPar << " ====================="; -outPar << endl << endl; - -outPar << "BATCH MODE \t"; -if (sim.batchMode) outPar << "yes" << endl; else outPar << "no" << endl; -#if RS_RCPP -outPar << "SEED \t" << RS_random_seed << endl; -#endif -outPar << "REPLICATES \t" << sim.reps << endl; -outPar << "YEARS \t" << sim.years << endl; -outPar << "REPRODUCTIVE SEASONS / YEAR\t" << dem.repSeasons << endl; -if (ppLand.patchModel){ - outPar << "PATCH-BASED MODEL" << endl; - outPar << "No. PATCHES \t" << pLandscape->patchCount()-1 << endl; -} -else - outPar << "CELL-BASED MODEL" << endl; -outPar << "BOUNDARIES \t"; -if (sim.absorbing) outPar << "absorbing" << endl; -else outPar << "reflective" << endl; -outPar << endl; - -outPar << "LANDSCAPE:\t"; -if (ppLand.generated) { - outPar << "artificially generated map" << endl; - outPar << "TYPE: \t"; - if (ppGenLand.continuous) outPar << "continuous \t"; - else outPar << "discrete \t"; - if (ppGenLand.fractal) outPar << "fractal"; - else outPar << "random"; - outPar << endl << "PROPORTION OF SUITABLE HABITAT (p)\t" << ppGenLand.propSuit <numLandChanges(); - for (int i = 0; i < nchanges; i++) { - chg = pLandscape->getLandChange(i); - outPar << "Change no. " << chg.chgnum << " in year " << chg.chgyear << endl; - outPar << "Landscape: " << chg.habfile << endl; - if (ppLand.patchModel) { - outPar << "Patches : " << chg.pchfile << endl; - } - if (chg.costfile != "none" && chg.costfile != "NULL") { - outPar << "Costs : " << chg.costfile << endl; - } -// outPar << "Change no. " << chg.chgnum << " in year " << chg.chgyear -// << " habitat map: " << chg.habfile << endl; - } -} - -outPar << endl << "SPECIES DISTRIBUTION LOADED: \t"; -//if (sim.initDistLoaded) -if (ppLand.spDist) -{ - outPar << "yes" << endl; - outPar << "RESOLUTION (m)\t" << ppLand.spResol << endl; - outPar << "FILE NAME: "; -#if !RS_RCPP - if (sim.batchMode) outPar << " (see batch file) " << landFile << endl; - else { - outPar << distnmapname << endl; - } -#else - outPar << name_sp_dist << endl; -#endif -} -else outPar << "no" << endl; - -outPar << endl << "ENVIRONMENTAL GRADIENT:\t "; -if (grad.gradient) -{ - switch (grad.gradType) { - case 1: - if (dem.stageStruct) outPar << "Density dependence strength (1/b)" << endl; - else outPar << "Carrying capacity (K)" << endl; - break; - case 2: - if (dem.stageStruct) outPar << "Fecundity" << endl; - else outPar << "Intrinsic growth rate (r)" << endl; - break; - case 3: - outPar << "Local extinction probability" << endl; - break; - default: - outPar << "ERROR ERROR ERROR" << endl; - ; - } - outPar << "G:\t\t " << grad.grad_inc << endl; - outPar << "optimum Y:\t " << grad.opt_y << endl; - outPar << "f:\t\t " << grad.factor << endl; - if (grad.gradType == 3) outPar << "Local extinction prob. at optimum:\t " - << grad.extProbOpt << endl; - outPar << "GRADIENT SHIFTING:\t "; - if (grad.shifting) - { - outPar << "yes" << endl; - outPar << "SHIFTING RATE (rows/year):\t " << grad.shift_rate << endl; - outPar << "SHIFTING START (year):\t\t " << grad.shift_begin << endl; - outPar << "SHIFTING STOP (year):\t\t " << grad.shift_stop << endl; - } - else outPar << "no" << endl; -} -else outPar << "no"; -outPar << endl; -outPar << "ENVIRONMENTAL STOCHASTICITY:\t"; -if (env.stoch) { - outPar << "yes" << endl; - outPar << "TYPE\t in "; - if (dem.stageStruct) { - if (env.inK) outPar << "1/b" << endl; - else outPar << "fecundity" << endl; - } - else{ - if (env.inK) outPar << "K" << endl; - else outPar << "R" << endl; - } - outPar << "SPATIAL AUTOCORRELATION\t "; - if (env.local) outPar << "local" << endl; - else outPar << "global" << endl; - outPar << "TEMPORAL AUTOCORRELATION (ac)\t" << env.ac << endl; - outPar << "AMPLITUDE (std)\t" << env.std << endl; - if (dem.stageStruct) { - if (env.inK) { - outPar << "MIN. 1/b\t" << pSpecies->getMinMax(0) - * (10000.0/(float)(ppLand.resol*ppLand.resol)) << endl; - outPar << "MAX. 1/b\t" << pSpecies->getMinMax(1) - * (10000.0/(float)(ppLand.resol*ppLand.resol)) << endl; - } - else { - outPar << "MIN. fecundity\t" << pSpecies->getMinMax(0) << endl; - outPar << "MAX. fecundity\t" << pSpecies->getMinMax(1) << endl; - } - } - else { - if (env.inK) { - outPar << "MIN. K\t" << pSpecies->getMinMax(0) - * (10000.0/(float)(ppLand.resol*ppLand.resol)) << endl; - outPar << "MAX. K\t" << pSpecies->getMinMax(1) - * (10000.0/(float)(ppLand.resol*ppLand.resol)) << endl; - } - else { - outPar << "MIN. r\t" << pSpecies->getMinMax(0) << endl; - outPar << "MAX. r\t" << pSpecies->getMinMax(1) << endl; - } - } -} -else outPar << "no" << endl; -outPar << "LOCAL EXTINCTION PROBABILITY:\t"; -if (env.localExt) outPar << env.locExtProb << endl; -else outPar << "0.0" << endl; - -outPar << endl << "SPECIES' PARAMETERS." << endl; -outPar << "REPRODUCTION:" << endl; -outPar << "TYPE: "; -switch (dem.repType) { - case 0: - outPar << "Asexual / Only female model" << endl; - break; - case 1: - outPar << "Sexual model (simple)"; - outPar << endl; - outPar << "PROP. of MALES\t" << dem.propMales << endl; - break; - case 2: - outPar << "Sexual model (explicit mating system)" << endl; - outPar << "PROP. of MALES\t" << dem.propMales << endl; - outPar << "MAX. HAREM SIZE (h)\t" << dem.harem << endl; - break; -} -outPar << "STAGE STRUCTURE:\t"; -if (dem.stageStruct){ - outPar << "yes" << endl; - outPar << "PROBABILITY OF REPRODUCING IN SUBSEQUENT SEASONS\t" << sstruct.probRep << endl; - outPar << "No. OF REP. SEASONS BEFORE SUBSEQUENT REPRODUCTIONS\t" << sstruct.repInterval << endl; - if (!ppLand.generated && ppLand.dynamic) { - outPar << "ACTION AFTER POPULATION DESTRUCTION: all individuals "; - if (sstruct.disperseOnLoss) outPar << "disperse" << endl; - else outPar << "die" << endl; - } - outPar << "No. STAGES\t" << sstruct.nStages << endl; - outPar << "MAX. AGE\t" << sstruct.maxAge << endl; - // no sex-specific demographic parameters - if (dem.repType != 2) { - outPar << "MIN. AGES:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage\t" << i << ":\t" << pSpecies->getMinAge(i,0) << "\tyears"<< endl; - } - outPar << "FECUNDITIES:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage\t" << i << ":\t" << pSpecies->getFec(i,0) << endl; - } - outPar << "DEVELOPMENT PROB.:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage\t" << i << ":\t" << pSpecies->getDev(i,0) << endl; - } - outPar << "SURVIVAL PROB.:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage\t" << i << ":\t" << pSpecies->getSurv(i,0) << endl; - } - } - // sex-specific demographic parameters - else { - outPar << "MIN. AGES:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "males " << i << ":\t" << pSpecies->getMinAge(i,1) << " years;\t"; - outPar << "females " << i << ":\t" << pSpecies->getMinAge(i,0) << " years" << endl; - } - outPar << "FECUNDITIES:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "males " << i << ":\t" << pSpecies->getFec(i,1) << endl; - outPar << "females " << i << ":\t" << pSpecies->getFec(i,0) << endl; - } - outPar << "DEVELOPMENT PROB.:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "males " << i << ":\t" << pSpecies->getDev(i,1) << endl; - outPar << "females " << i << ":\t" << pSpecies->getDev(i,0) << endl; - } - outPar << "SURVIVAL PROB.:" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "males " << i << ":\t" << pSpecies->getSurv(i,1) << endl; - outPar << "females " << i << ":\t" << pSpecies->getSurv(i,0) << endl; - } - } -/* -#if RSDEBUG - outPar << endl << "TRANSITION MATRIX AS ENTERED:" << endl; - if (batchMode) { - DEBUGLOG << "outParameters(): matrix = " << matrix - << " matrix[1][1] = " << matrix[1][1] - << endl; - if (dem.repType == 2) { - nrows = sstruct.nStages*2-1; ncols = sstruct.nStages*2; - } - else { - nrows = sstruct.nStages; ncols = sstruct.nStages; - } - for (int i = 0; i < nrows; i++) { - for (int j = 0; j < ncols; j++) { - outPar << matrix[j][i] << "\t"; - } - outPar << endl; - } - } - outPar << endl; -#endif -*/ - - outPar << "SCHEDULING OF SURVIVAL: "; - switch (sstruct.survival) { - case 0: - outPar << "At reproduction" << endl; - break; - case 1: - outPar << "Between reproductive events" << endl; - break; - case 2: - outPar << "Annually" << endl; - break; - } - - int mSize; // index for weights matrices - if (dem.repType == 2) mSize = sstruct.nStages * NSEXES; - else mSize = sstruct.nStages; - - outPar << "DENSITY-DEPENDENCE IN FECUNDITY:\t"; - if (sstruct.fecDens) { - outPar << "yes" << endl; - if (sstruct.fecStageDens) { - outPar << "STAGE'S WEIGHTS:" << endl; - for (int i = 0; i < mSize; i++) { - if (dem.repType == 2) { - outPar << "stage " << i/NSEXES << " "; - if (i%NSEXES == 0) outPar << "males : \t"; - else outPar << "females: \t"; - } - else outPar << "stage " << i << ": \t"; - for (int j = 0; j < mSize; j++) outPar << pSpecies->getDDwtFec(j,i) << "\t"; - outPar << endl; - } - } - else outPar << "not stage-dependent" << endl; - } - else outPar << "no" << endl; - - densDepParams ddparams = pSpecies->getDensDep(); - - outPar << "DENSITY-DEPENDENCE IN DEVELOPMENT:\t"; - if (sstruct.devDens) { - outPar << "yes - coefficient: " << ddparams.devCoeff << endl; - if (sstruct.devStageDens) { - outPar << "STAGE'S WEIGHTS:" << endl; - for (int i = 0; i < mSize; i++) { - if (dem.repType == 2) { - outPar << "stage " << i/NSEXES << " "; - if (i%NSEXES == 0) outPar << "males : \t"; - else outPar << "females: \t"; - } - else outPar << "stage " << i << ": \t"; - for (int j = 0; j < mSize; j++) outPar << pSpecies->getDDwtDev(j,i) << "\t"; - outPar << endl; - } - } - else outPar << "not stage-dependent" << endl; - } - else outPar << "no" << endl; - - outPar << "DENSITY-DEPENDENCE IN SURVIVAL:\t\t"; - if (sstruct.survDens) { - outPar << "yes - coefficient: " << ddparams.survCoeff << endl; - if (sstruct.survStageDens) { - outPar << "STAGE'S WEIGHTS:" << endl; - for (int i = 0; i < mSize; i++) { - if (dem.repType == 2) { - outPar << "stage " << i/NSEXES << " "; - if (i%NSEXES == 0) outPar << "males : \t"; - else outPar << "females: \t"; - } - else outPar << "stage " << i << ": \t"; - for (int j = 0; j < mSize; j++) outPar << pSpecies->getDDwtSurv(j,i) << "\t"; - outPar << endl; - } - } - else outPar << "not stage-dependent" << endl; - } - else outPar << "no" << endl; -} // end of if (dem.stageStruct) -else { // not stage-strutured - outPar << "no" << endl; - outPar << "Rmax\t" << dem.lambda << endl; - outPar << "bc\t" << dem.bc << endl; -} - -if (dem.stageStruct) { - outPar << endl << "HABITAT SPECIFIC 1/b:" << endl; -} -else { - outPar << endl << "CARRYING CAPACITIES:" << endl; -} -int nhab = ppLand.nHab; -if (ppLand.generated) { - if (ppGenLand.continuous) nhab = 1; -} -for (int i = 0; i < nhab; i++) { - k = pSpecies->getHabK(i) * (10000.0/(float)(ppLand.resol*ppLand.resol)); - if (!ppLand.generated && ppLand.rasterType == 0) { // imported & habitat codes - outPar << "Habitat " << pLandscape->getHabCode(i) << ": \t"; - } - else { - outPar << "Habitat " << i << ": "; - } - if (dem.stageStruct) outPar << "1/b "; - else outPar << "K "; - outPar << k << endl; -} - -emigTraits ep0,ep1; -emigParams eparams0,eparams1; -string sexdept = "SEX-DEPENDENT: "; -string stgdept = "STAGE-DEPENDENT: "; -string indvar = "INDIVIDUAL VARIABILITY: "; -string emigstage = "EMIGRATION STAGE: "; - -outPar << endl << "DISPERSAL - EMIGRATION:\t"; -if (emig.densDep) { - outPar << "density-dependent" << endl; - - if (emig.sexDep) { - outPar << sexdept << "yes" << endl; - if (emig.stgDep) { - outPar << stgdept << "yes" << endl; - outPar << indvar << "no" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage " << i << ":" << endl; - ep0 = pSpecies->getEmigTraits(i,0); - ep1 = pSpecies->getEmigTraits(i,1); - outPar << "D0: females "<< ep0.d0 << " males " << ep1.d0 << endl; - outPar << "alpha: females "<< ep0.alpha << " males " << ep1.alpha << endl; - outPar << "beta: females "<< ep0.beta << " males " << ep1.beta << endl; - } - } - else { // !emig.stgDep - outPar << stgdept << "no" << endl; - outPar << indvar; - if (emig.indVar) { - eparams0 = pSpecies->getEmigParams(0,0); - eparams1 = pSpecies->getEmigParams(0,1); - outPar << "yes" << endl; - if (dem.stageStruct) { - outPar << emigstage << emig.emigStage << endl; - } - outPar << "D0 females: mean " << eparams0.d0Mean << " s.d. " << eparams0.d0SD - << " scaling factor " << eparams0.d0Scale << endl; - outPar << "D0 males: mean " << eparams1.d0Mean << " s.d. " << eparams1.d0SD - << " scaling factor " << eparams1.d0Scale << endl; - outPar << "Alpha females: mean " << eparams0.alphaMean << " s.d. " << eparams0.alphaSD - << " scaling factor " << eparams0.alphaScale << endl; - outPar << "Alpha males: mean " << eparams1.alphaMean << " s.d. " << eparams1.alphaSD - << " scaling factor " << eparams1.alphaScale << endl; - outPar << "Beta females: mean " << eparams0.betaMean << " s.d. " << eparams0.betaSD - << " scaling factor " << eparams0.betaScale << endl; - outPar << "Beta males: mean " << eparams1.betaMean << " s.d. " << eparams1.betaSD - << " scaling factor " << eparams1.betaScale << endl; - } - else { - outPar << "no" << endl; - ep0 = pSpecies->getEmigTraits(0,0); - ep1 = pSpecies->getEmigTraits(0,1); - outPar << "D0: females "<< ep0.d0 << " males " << ep1.d0 << endl; - outPar << "alpha: females "<< ep0.alpha << " males " << ep1.alpha << endl; - outPar << "beta: females "<< ep0.beta << " males " << ep1.beta << endl; - } - } - } - else { // !emig.sexDep - outPar << sexdept << "no" << endl; - if (emig.stgDep) { - outPar << stgdept << "yes" << endl; - outPar << indvar << "no" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - ep0 = pSpecies->getEmigTraits(i,0); - outPar << "stage " << i << ": \t" << "D0: " << ep0.d0; - outPar<< " \talpha: " << ep0.alpha << " \tbeta: " << ep0.beta << endl; - } - } - else { // !emig.stgDep - outPar << stgdept << "no" << endl; - outPar << indvar; - if (emig.indVar) { - eparams0 = pSpecies->getEmigParams(0,0); - emigScales scale = pSpecies->getEmigScales(); - outPar << "yes" << endl; - if (dem.stageStruct) { - outPar << emigstage << emig.emigStage << endl; - } - outPar << "D0 mean: " << eparams0.d0Mean << " s.d.: " << eparams0.d0SD - << " scaling factor: " << scale.d0Scale << endl; - outPar << "Alpha mean: " << eparams0.alphaMean << " s.d.: " << eparams0.alphaSD - << " scaling factor: " << scale.alphaScale << endl; - outPar << "Beta mean: " << eparams0.betaMean << " s.d.: " << eparams0.betaSD - << " scaling factor: " << scale.betaScale << endl; - } - else{ - outPar << "no" << endl; - ep0 = pSpecies->getEmigTraits(0,0); - outPar << "D0: " << ep0.d0 << endl; - outPar << "alpha: " << ep0.alpha << endl; - outPar << "beta: " << ep0.beta << endl; - } - } - } -} -else { // not density-dependent - string initprob = "INITIAL EMIGRATION PROB. "; - outPar << "density-independent" << endl; - if (!trfr.moveModel) { // transfer by kernel - outPar << "USE FULL KERNEL TO DETERMINE EMIGRATION: "; - if (pSpecies->useFullKernel()) outPar << "yes"; - else outPar << "no"; - outPar << endl; - } - - if (emig.sexDep) { - outPar << sexdept << "yes" << endl; - if (emig.stgDep) { - outPar << stgdept << "yes" << endl; - outPar << indvar << "no" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage " << i << ": \t" << "EMIGRATION PROB.: \tfemales " - << pSpecies->getEmigD0(i,0) <<" \tmales "<< pSpecies->getEmigD0(i,1) << endl; - } - } - else { // !emig.stgDep - outPar << stgdept << "no" << endl; - outPar << indvar; - if (emig.indVar) { - eparams0 = pSpecies->getEmigParams(0,0); - eparams1 = pSpecies->getEmigParams(0,1); - emigScales scale = pSpecies->getEmigScales(); - outPar << "yes" << endl; - if (dem.stageStruct) { - outPar << emigstage << emig.emigStage << endl; - } - outPar << initprob << "mean: " << "females " << eparams0.d0Mean - << " males " << eparams1.d0Mean << endl; - outPar << initprob << "s.d.: " << "females " << eparams0.d0SD - << " males " << eparams1.d0SD << endl; - outPar << initprob << "scaling factor: " << scale.d0Scale - << endl; - } - else{ - outPar << "no" << endl; - outPar << "EMIGRATION PROB.: \tfemales "<< pSpecies->getEmigD0(0,0) - <<"\t males " << pSpecies->getEmigD0(0,1) << endl; - } - } - } - else { // !emig.sexDep - outPar << sexdept << "no" << endl; - if (emig.stgDep) { - outPar << stgdept << "yes" << endl; - outPar << indvar << "no" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage " << i << ": \t" << "EMIGRATION PROB.: " - << pSpecies->getEmigD0(i,0) << endl; - } - } - else { // !emig.stgDep - outPar << stgdept << "no" << endl; - outPar << indvar; - if (emig.indVar) { - eparams0 = pSpecies->getEmigParams(0,0); - emigScales scale = pSpecies->getEmigScales(); - outPar << "yes" << endl; - if (dem.stageStruct) { - outPar << emigstage << emig.emigStage << endl; - } - outPar << initprob << "mean: " << eparams0.d0Mean << endl; - outPar << initprob << "s.d.: " << eparams0.d0SD << endl; - outPar << initprob << "scaling factor: " << scale.d0Scale << endl; - } - else { - outPar << "no" << endl; - outPar << "EMIGRATION PROB.:\t" << pSpecies->getEmigD0(0,0) << endl; - } - } - } -} - -// Transfer - -outPar << endl << "DISPERSAL - TRANSFER: \t"; - -if (trfr.moveModel) { - bool straigtenPath; - if (trfr.moveType == 1) { // SMS - trfrSMSTraits move = pSpecies->getSMSTraits(); - straigtenPath = move.straigtenPath; - if (trfr.costMap) { - outPar << "SMS\tcosts from imported cost map" << endl; -#if !RS_RCPP - outPar << "FILE NAME: " << costmapname << endl; -#endif - } - else { - outPar << "SMS\tcosts:" << endl; - if (!ppLand.generated && ppLand.rasterType == 0) { - for (int i = 0; i < ppLand.nHab; i++) - outPar << "\thab. " << pLandscape->getHabCode(i) << "\t" - << pSpecies->getHabCost(i) << endl; - } - else { - for (int i = 0; i < ppLand.nHab; i++) - outPar << "\thab. " << i << "\t" - << pSpecies->getHabCost(i) << endl; - } - } - string pr = "PERCEPTUAL RANGE"; - outPar << pr << ": " << move.pr << endl; - outPar << pr << " METHOD: " << move.prMethod << endl; - if (!trfr.indVar) outPar << "DIRECTIONAL PERSISTENCE: " << move.dp << endl; - outPar << "MEMORY SIZE: " << move.memSize << endl; - //if (!trfr.indVar) outPar << "GOAL BIAS: " << move.gb << endl; - outPar << "GOAL TYPE: " << move.goalType << endl; - if (!trfr.indVar) { - if (move.goalType == 2) { // dispersal bias - outPar << "GOAL BIAS: " << move.gb << endl; - outPar << "ALPHA DB: " << move.alphaDB << endl; - outPar << "BETA DB: " << move.betaDB << endl; - } - } - if (trfr.indVar) { - trfrSMSParams s = pSpecies->getSMSParams(0,0); - outPar << indvar << "yes " << endl; - outPar << "DP mean: " << s.dpMean << " s.d.: " << s.dpSD - << " scaling factor: " << s.dpScale << endl; - outPar << "GB mean: " << s.gbMean << " s.d.: " << s.gbSD - << " scaling factor: " << s.gbScale << endl; - if (move.goalType == 2) { // dispersal bias - outPar << "Alpha DB mean: " << s.alphaDBMean << " s.d.: " << s.alphaDBSD - << " scaling factor: " << s.alphaDBScale << endl; - outPar << "Beta DB mean: " << s.betaDBMean << " s.d.: " << s.betaDBSD - << " scaling factor: " << s.betaDBScale << endl; - } - } - else { - outPar << indvar << "no " << endl; - } - } - else { // CRW - trfrCRWTraits move = pSpecies->getCRWTraits(); - straigtenPath = move.straigtenPath; - outPar << "CRW" << endl; - string lgth = "STEP LENGTH (m) "; - string corr = "STEP CORRELATION"; - if (trfr.indVar) { - trfrCRWParams m = pSpecies->getCRWParams(0,0); - outPar << indvar << "yes" << endl; - outPar << lgth << " mean: " << m.stepLgthMean; - outPar << " s.d.: " << m.stepLgthSD; - outPar << " scaling factor: " << m.stepLScale << endl; - outPar << corr << " mean: " << m.rhoMean; - outPar << " s.d.: " << m.rhoSD; - outPar << " scaling factor: " << m.rhoScale << endl; - } - else { - outPar << indvar << "no" << endl; - outPar << lgth << ": " << move.stepLength << endl; - outPar << corr << ": " << move.rho << endl; - } - } - outPar << "STRAIGHTEN PATH AFTER DECISION NOT TO SETTLE: "; - if (straigtenPath) outPar << "yes" << endl; - else outPar << "no" << endl; - outPar << "STEP MORTALITY:\t" << endl; - if (trfr.habMort) - { - outPar << "habitat dependent:\t" << endl; - if (!ppLand.generated && ppLand.rasterType == 0) { - for (int i = 0; i < ppLand.nHab; i++) - outPar << "\thab. " << pLandscape->getHabCode(i) << "\t" - << pSpecies->getHabMort(i) << endl; - } - else{ - for (int i = 0; i < ppLand.nHab; i++) - outPar << "\thab. " << i << "\t" - << pSpecies->getHabMort(i) << endl; - } - } - else - { - trfrCRWTraits move = pSpecies->getCRWTraits(); - outPar << "constant " << move.stepMort << endl; - } -} // end of movement process -else { // kernel - string meandist = "MEAN DISTANCE"; - string probkern = "PROB. KERNEL I"; - trfrKernTraits kern0,kern1; - trfrKernParams k0,k1; - outPar << "dispersal kernel" << endl << "TYPE: \t"; - if (trfr.twinKern) outPar << "double "; - outPar << "negative exponential" << endl; - - if (trfr.sexDep) { - outPar << sexdept << "yes" << endl; - if (trfr.stgDep) { - outPar << stgdept << "yes" << endl; - outPar << indvar << "no" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - outPar << "stage " << i << ":" << endl; - kern0 = pSpecies->getKernTraits(i,0); - kern1 = pSpecies->getKernTraits(i,1); - outPar << meandist << " I: \tfemales "<< kern0.meanDist1 << " \tmales " << kern1.meanDist1 << endl; - if (trfr.twinKern) - { - outPar << meandist << " II: \tfemales "<< kern0.meanDist2 << " \tmales " << kern1.meanDist2 << endl; - outPar << probkern << ": \tfemales "<< kern0.probKern1 << " \tmales " << kern1.probKern1 << endl; - } - } - } - else { // !trfr.stgDep - outPar << stgdept << "no" << endl; - outPar << indvar; - if (trfr.indVar) { - k0 = pSpecies->getKernParams(0,0); - k1 = pSpecies->getKernParams(0,1); - outPar << "yes" << endl; - outPar << meandist << " I (mean): \tfemales " << k0.dist1Mean - << " \tmales " << k1.dist1Mean << endl; - outPar << meandist << " I (s.d.): \tfemales " << k0.dist1SD - << " \tmales " << k1.dist1SD << endl; - outPar << meandist << " I (scaling factor): \tfemales " << k0.dist1Scale - << " \tmales " << k1.dist1Scale << endl; - if (trfr.twinKern) - { - outPar << meandist << " II (mean): \tfemales " << k0.dist2Mean - << " \tmales " << k1.dist2Mean << endl; - outPar << meandist << " II (s.d.): \tfemales " << k0.dist2SD - << " \tmales " << k1.dist2SD << endl; - outPar << meandist << " II (scaling factor): \tfemales " << k0.dist2Scale - << " \tmales " << k1.dist2Scale << endl; - outPar << probkern << " (mean): \tfemales " << k0.PKern1Mean - << " \tmales " << k1.PKern1Mean << endl; - outPar << probkern << " (s.d.): \tfemales " << k0.PKern1SD - << " \tmales " << k1.PKern1SD << endl; - outPar << probkern << " (scaling factor): \tfemales " << k0.PKern1Scale - << " \tmales " << k1.PKern1Scale << endl; - } - } - else { - outPar << "no" << endl; - kern0 = pSpecies->getKernTraits(0,0); - kern1 = pSpecies->getKernTraits(0,1); - outPar << meandist << " I: \tfemales "<< kern0.meanDist1 << " \tmales " << kern1.meanDist1 << endl; - if (trfr.twinKern) - { - outPar << meandist << " II: \tfemales "<< kern0.meanDist2 << " \tmales " << kern1.meanDist2 << endl; - outPar << probkern << ": \tfemales "<< kern0.probKern1 << " \tmales " << kern1.probKern1 << endl; - } - } - } - } - else { // !trfr.sexDep - outPar << sexdept << "no" << endl; - if (trfr.stgDep) { - outPar << stgdept << "yes" << endl; - outPar << indvar << "no" << endl; - for (int i = 0; i < sstruct.nStages; i++) { - kern0 = pSpecies->getKernTraits(i,0); - outPar << "stage " << i << ": \t" << meandist << " I: " << kern0.meanDist1; - if (trfr.twinKern) - { - outPar << " \t" << meandist << " II: " << kern0.meanDist2; - outPar << " \t" << probkern << ": " << kern0.probKern1; - } - outPar << endl; - } - } - else { // !trfr.stgDep - outPar << stgdept << "no" << endl; - outPar << indvar; - if (trfr.indVar) { - k0 = pSpecies->getKernParams(0,0); - outPar << "yes" << endl; - outPar << meandist << " I (mean): " << k0.dist1Mean - << " \t(s.d.): " << k0.dist1SD - << " \t(scaling factor): " << k0.dist1Scale << endl; - if (trfr.twinKern) - { - outPar << meandist << " II (mean): " << k0.dist2Mean - << " \t(s.d.): " << k0.dist2SD - << " \t(scaling factor): " << k0.dist2Scale << endl; - outPar << probkern << " (mean): " << k0.PKern1Mean - << " \t(s.d.): " << k0.PKern1SD - << " \t(scaling factor): " << k0.PKern1Scale << endl; - } - } - else{ - outPar << "no" << endl; - kern0 = pSpecies->getKernTraits(0,0); - outPar << meandist << " I: \t" << kern0.meanDist1 <getMortParams(); - if (trfr.distMort) { - outPar << "distance-dependent" << endl; - outPar << "SLOPE: " << mort.mortAlpha << " \tINFLECTION POINT: " << mort.mortBeta << endl; - } - else { - outPar << "constant" << endl << "MORTALITY PROBABILITY: " << mort.fixedMort << endl; - } -} // end of kernel transfer - -// Settlement - -outPar << endl << "DISPERSAL - SETTLEMENT:" << endl; - -if (trfr.moveModel) { - string plusmating = "+ mating requirements"; - ssteps = pSpecies->getSteps(0,0); - - outPar << "MIN. No. OF STEPS:\t " << ssteps.minSteps << endl; - outPar << "MAX. No. OF STEPS:\t "; - if (ssteps.maxSteps == 99999999) outPar << "not applied" << endl; - else outPar << ssteps.maxSteps << endl; - - if (sett.sexDep) { - nsexes = 2; - outPar << sexdept << "yes" << endl; - if (sett.stgDep) { - nstages = sstruct.nStages; - outPar << stgdept << "yes" << endl; - } - else { // !sett.stgDep - nstages = 1; - outPar << stgdept << "no" << endl; - } - } - else { // !sett.sexDep - nsexes = 1; - outPar << sexdept << "no" << endl; - if (sett.stgDep) { - nstages = sstruct.nStages; - outPar << stgdept << "yes" << endl; - } - else { // !sett.stgDep - nstages = 1; - outPar << stgdept << "no" << endl; - } - } - for (int sx = 0; sx < nsexes; sx++) { - if (sett.sexDep) { - if (sx == 0) outPar << "FEMALES:" << endl; - else outPar << "MALES:" << endl; - } - outPar << "SETTLE IF: "; - for (int i = 0; i < nstages; i++) { - if (dem.stageStruct && nstages > 1) outPar << "stage " << i << ": " << endl; - outPar << "find a suitable cell/patch "; - srules = pSpecies->getSettRules(i,sx); - if (srules.densDep) { - settleDD = pSpecies->getSettTraits(i,sx); - outPar << "+ density dependence "; - if (srules.findMate) outPar << plusmating; - outPar << endl; - if (!sett.indVar) { - outPar << "S0: " << settleDD.s0 << " AlphaS: " << settleDD.alpha - << " BetaS: " << settleDD.beta << endl; - } - } - else { - if (srules.findMate) outPar << plusmating << endl; - else outPar << "(not the natal one)" << endl; - } - if (dem.stageStruct) { - ssteps = pSpecies->getSteps(i,sx); - outPar << "MAX. No. OF STEPS/YEAR:\t "; - if (ssteps.maxStepsYr == 99999999) outPar << "not applied" << endl; - else outPar << ssteps.maxStepsYr << endl; - } - } - } - if (sett.indVar) { - settParams sparams0; - outPar << "DENSITY DEPENDENCE + " << indvar << "yes" << endl; - for (int sex = 0; sex < nsexes; sex++) { - if (sett.sexDep) { - if (sex == 0) outPar << "FEMALES:" << endl; - else outPar << "MALES:" << endl; - } - sparams0 = pSpecies->getSettParams(0,sex); - settScales scale = pSpecies->getSettScales(); - outPar << "S0 - mean: " << sparams0.s0Mean << " s.d.: " << sparams0.s0SD - << " scaling factor: " << scale.s0Scale << endl; - outPar << "AlphaS - mean: " << sparams0.alphaSMean << " s.d.: " << sparams0.alphaSSD - << " scaling factor: " << scale.alphaSScale << endl; - outPar << "BetaS - mean: " << sparams0.betaSMean << " s.d.: " << sparams0.betaSSD - << " scaling factor: " << scale.betaSScale << endl; - } - } -} -else { // kernel-based transfer - string notsuit = "IF THE ARRIVAL CELL/PATCH IS UNSUITABLE: "; - string rchoose = " randomly choose a suitable neighb. cell/patch or "; - string matereq = "MATING REQUIREMENTS: "; - if (sett.sexDep) { - nsexes = 2; - outPar << sexdept << "yes" << endl; - if (sett.stgDep) { - nstages = sstruct.nStages; - outPar << stgdept << "yes" << endl; - outPar << notsuit << endl; - } - else { - nstages = 1; - outPar << stgdept << "no" << endl; - } - } - else { - nsexes = 1; - outPar << sexdept << "no" << endl; - if (sett.stgDep) { - nstages = sstruct.nStages; - outPar << stgdept << "yes" << endl; - outPar << notsuit << endl; - } - else { - nstages = 1; - outPar << stgdept << "no" << endl; - outPar << notsuit; - } - } - for (int i = 0; i < nstages; i++) { - if (sett.stgDep) { - outPar << "stage " << i << ":" << endl; - } - for (int sx = 0; sx < nsexes; sx++) { - if (sett.sexDep) { - if (sx == 0) outPar << "FEMALES: "; - else outPar << "MALES: "; - if (!sett.stgDep) outPar << notsuit; - } - srules = pSpecies->getSettRules(i,sx); - if (srules.go2nbrLocn) { - outPar << rchoose; - if (srules.wait) outPar << "wait" << endl; - else outPar << "die" << endl; - } - else { - if (srules.wait) outPar << "wait" << endl; - else outPar << "die" << endl; - } - outPar << matereq; - if (srules.findMate) outPar << "yes" <getNTraits(); -outPar << "No. of variable traits: " << nspptraits << endl; - -genomeData d = pSpecies->getGenomeData(); -if (emig.indVar || trfr.indVar || sett.indVar || d.neutralMarkers) -{ - if (d.diploid) outPar << "DIPLOID" << endl; else outPar << "HAPLOID" << endl; - int nchromosomes = pSpecies->getNChromosomes(); - outPar << "No. of chromosomes: " << nchromosomes; - if (d.trait1Chromosome) { - outPar << endl << "No. of loci/chromosome: " << d.nLoci << endl; - } - else { - outPar << " (chrom:loci)"; - for (int i = 0; i < nchromosomes; i++) { - outPar << " " << i << ":" << pSpecies->getNLoci(i); - } - outPar << endl; - } - outPar << "Mutation probability: " << d.probMutn << endl; - outPar << "Crossover probability: " << d.probCrossover << endl; - outPar << "Initial allele s.d.: " << d.alleleSD << endl; - outPar << "Mutation s.d.: " << d.mutationSD << endl; - if (d.neutralMarkers) { - outPar << "NEUTRAL MARKERS ONLY" << endl; - } - else { - if (!d.trait1Chromosome) { - traitAllele allele; - outPar << "TRAIT MAPPING:" << endl; - outPar << "Architecture file: " << genfilename << endl; - int ntraitmaps = pSpecies->getNTraitMaps(); - outPar << "No. of traits defined: " << ntraitmaps << endl; - for (int i = 0; i < ntraitmaps; i++) { - int nalleles = pSpecies->getNTraitAlleles(i); - outPar << "Trait " << i << ": (" << pSpecies->getTraitName(i) - << ") alleles: " << nalleles << " (chrom:locus)"; - for (int j = 0; j < nalleles; j++) { - allele = pSpecies->getTraitAllele(i,j); - outPar << " " << allele.chromo << ":" << allele.locus; - } - outPar << endl; - } - if (ntraitmaps < nspptraits) { // list undefined traits - outPar << "WARNING - the following traits were not defined" - << " in the genetic architecture file:" << endl; - for (int i = ntraitmaps; i < nspptraits; i++) { - outPar << "Trait " << i << ": (" << pSpecies->getTraitName(i) - << ") all individuals have mean phenotype" << endl; - } - } - int nneutral = pSpecies->getNNeutralLoci(); - if (nneutral > 0) { - outPar << "Neutral loci: " << nneutral << " (chrom:locus)"; - for (int i = 0; i < nneutral; i++) { - allele = pSpecies->getNeutralAllele(i); - outPar << " " << allele.chromo << ":" << allele.locus; - } - outPar << endl; - } - if (d.pleiotropic) - outPar << "Genome exhibits pleiotropy" << endl; - } - } -} - -// Initialisation - -initParams init = paramsInit->getInit(); -outPar << endl << "INITIALISATION CONDITIONS:" << endl; -switch (init.seedType) { -case 0: - outPar << "Free initialisation: \t" ; - switch (init.freeType) { - case 0: - outPar << "Random \t" ; - outPar << "No. of cells/patches: " << init.nSeedPatches << endl; - break; - case 1: - outPar << "all suitable cells/patches" << endl; - break; - case 2: - outPar << "manually selected cells/patches" << endl; - break; - } - break; -case 1: - outPar << "From species distribution: \t" << endl; - switch (init.spDistType) { - case 0: - outPar << "all presence cells/patches" << endl; - break; - case 1: - outPar << "some random presence cells/patches" << endl; - break; - case 2: - outPar << "all cells/patches within selected distribution cells" << endl; - break; - } - break; -case 2: - outPar << "From initial individuals file: " << paramsSim->getDir(1) + init.indsFile << endl; - break; -case 3: - outPar << "From file" << endl; - break; -} -if (init.seedType != 2) { - outPar << "INITIAL NO. OF INDIVIDUALS: \t"; - switch (init.initDens) { - case 0: - outPar << "at carrying capacity" << endl; - break; - case 1: - outPar << "at half carrying capacity" << endl; - break; - case 2: - if (ppLand.patchModel) { - outPar << init.indsHa << " individuals per ha" << endl; - } - else { - outPar << init.indsCell << " individuals per cell" << endl; - } - break; - } - if (dem.stageStruct) { - outPar << "INITIAL STAGE PROPORTIONS:" << endl; - for (int i = 1; i < sstruct.nStages; i++) { - outPar << "stage " << i << ": " << paramsInit->getProp(i) << " \t"; - } - outPar << endl; - outPar << "Initial age distribution: "; - switch (init.initAge) { - case 0: - outPar << "lowest possible age"; - break; - case 1: - outPar << "randomised"; - break; - case 2: - outPar << "quasi-equilibrium"; - break; - } - outPar << endl; - } - outPar << "GEOGRAPHICAL CONSTRAINTS (cell numbers): " << endl; - outPar << "min X: " << init.minSeedX << " max X: " << init.maxSeedX << endl; - outPar << "min Y: " << init.minSeedY << " max Y: " << init.maxSeedY << endl; -// if (init.seedType != 1 && init.freeType < 2 && init.initFrzYr > 0) { -// outPar << "Freeze initial range until year " << init.initFrzYr << endl; -// } - if (init.seedType == 0 && init.freeType < 2) { - if (init.initFrzYr > 0) { - outPar << "Freeze initial range until year " << init.initFrzYr << endl; - } - if (init.restrictRange) { - outPar << "Restrict range to northern " << init.restrictRows - << " rows every " << init.restrictFreq << " years" << endl; - if (init.finalFrzYr < sim.years) { - outPar << "Freeze range at year " << init.finalFrzYr << endl; - } - } - } -} - -outPar << endl << "OUTPUTS:" << endl; -if (sim.outRange) { - outPar << "Range - every " << sim.outIntRange << " year"; - if (sim.outIntRange > 1) outPar << "s"; -// if (sim.outStartRange > 0) outPar << " starting year " << sim.outStartRange; - outPar << endl; -} -if (sim.outOccup) { - outPar << "Occupancy - every " << sim.outIntOcc << " year"; - if (sim.outIntOcc > 1) outPar << "s"; -// if (sim.outStartOcc > 0) outPar << " starting year " << sim.outStartOcc; - outPar << endl; -} -if (sim.outPop) { - outPar << "Populations - every " << sim.outIntPop << " year"; - if (sim.outIntPop > 1) outPar << "s"; - if (sim.outStartPop > 0) outPar << " starting year " << sim.outStartPop; - outPar << endl; -} -if (sim.outInds) { - outPar << "Individuals - every " << sim.outIntInd << " year"; - if (sim.outIntInd > 1) outPar << "s"; - if (sim.outStartInd > 0) outPar << " starting year " << sim.outStartInd; - outPar << endl; -} -if (sim.outGenetics) { - outPar << "Genetics - every " << sim.outIntGenetic << " year"; - if (sim.outIntGenetic > 1) outPar << "s"; - if (sim.outStartGenetic > 0) outPar << " starting year " << sim.outStartGenetic; - if (dem.stageStruct) { - switch (sim.outGenType) { - case 0: - outPar << " - juveniles only"; - break; - case 1: - outPar << " - all individuals"; - break; - case 2: - outPar << " - adults only"; - break; - } - } - if (sim.outGenXtab) outPar << " (as cross table)"; - outPar << endl; -} - -if (sim.outTraitsCells) { - outPar << "Traits per "; - if (ppLand.patchModel) outPar << "patch"; else outPar << "cell"; - outPar << " - every " << sim.outIntTraitCell << " year"; - if (sim.outIntTraitCell > 1) outPar << "s"; - if (sim.outStartTraitCell > 0) outPar << " starting year " << sim.outStartTraitCell; - outPar << endl; -} -if (sim.outTraitsRows) { - outPar << "Traits per row - every " << sim.outIntTraitRow << " year"; - if (sim.outIntTraitRow > 1) outPar << "s"; - if (sim.outStartTraitRow > 0) outPar << " starting year " << sim.outStartTraitRow; - outPar << endl; -} -if (sim.outConnect) { - outPar << "Connectivity matrix - every " << sim.outIntConn << " year"; - if (sim.outIntConn > 1) outPar << "s"; - if (sim.outStartConn > 0) outPar << " starting year " << sim.outStartConn; - outPar << endl; -} -#if RS_RCPP - if (sim.outPaths) { - outPar << "SMS paths - every " << sim.outIntPaths << " year"; - if (sim.outIntPaths > 1) outPar << "s"; - if (sim.outStartPaths > 0) outPar << " starting year " << sim.outStartPaths; - outPar << endl; - } -#endif -outPar << "SAVE MAPS: "; -if (sim.saveMaps) { - outPar << "yes - every " << sim.mapInt << " year"; - if (sim.mapInt > 1) outPar << "s"; - outPar << endl; -} -else outPar << "no" << endl; -outPar << "SAVE TRAITS MAPS: "; -if (sim.saveTraitMaps) { - outPar << "yes - every " << sim.traitInt << " year"; - if (sim.traitInt > 1) outPar << "s"; - outPar << endl; -} -else outPar << "no" << endl; -if (trfr.moveModel && trfr.moveType == 1) { - outPar << "SMS HEAT MAPS: "; - if (sim.saveVisits) outPar << "yes" << endl; - else outPar << "no" << endl; -} - -outPar.close(); outPar.clear(); - -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- diff --git a/src/RScore/Model.h b/src/RScore/Model.h deleted file mode 100644 index 5bd02bd..0000000 --- a/src/RScore/Model.h +++ /dev/null @@ -1,149 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Model - -Implements three functions which run the model and produce output common to both -GUI and batch version. - -RunModel() handles looping through replicates, years and generations - -Further functions are declared here, but defined differently in main function of -GUI and batch versions. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 26 October 2021 by Steve Palmer -------------------------------------------------------------------------------*/ - -#ifndef ModelH -#define ModelH - -#include -#include - -#if RS_RCPP -#include "../Version.h" -#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif - -#include "Parameters.h" -#include "Landscape.h" -#include "Community.h" -#include "SubCommunity.h" -#include "Species.h" - -#if !RS_EMBARCADERO && !LINUX_CLUSTER && !RS_RCPP -#include -using namespace std::filesystem; -#endif - -#if RSDEBUG -extern ofstream DEBUGLOG; -#endif - -#if RS_RCPP && !R_CMD -Rcpp::List RunModel( - Landscape*, // pointer to Landscape - int // sequential simulation number -); -#else -int RunModel( - Landscape*, // pointer to Landscape - int // sequential simulation number -); -#endif // RS_RCPP && !R_CMD -bool CheckDirectory(void); -void PreReproductionOutput( - Landscape*, // pointer to Landscape - Community*, // pointer to Community - int, // replicate - int, // year - int // generation -); -void RangePopOutput( - Community*, // pointer to Community - int, // replicate - int, // year - int // generation -); -void Outputs_Visuals_B( - int, // replicate - int, // year - int, // generation - int // Landscape number -); -void RefreshVisualCost(void); -traitCanvas SetupTraitCanvas(void); -void SetupVisualOutput(void); -void ResetVisualOutput(void); -void DrawPopnGraph( - Community*, // pointer to Community - int // year -); -void OutParameters( - Landscape* // pointer to Landscape -); - -extern paramGrad *paramsGrad; -extern paramStoch *paramsStoch; -extern Species *pSpecies; -extern paramSim *paramsSim; -extern paramInit *paramsInit; -extern Community *pComm; - -const bool batchMode = true; -extern string landFile; -extern vector hfnames; -extern string habmapname; // see Main.cpp (batch) -extern string patchmapname; // see Main.cpp (batch) -extern string distnmapname; // see Main.cpp (batch) -extern string costmapname; // see Main.cpp (batch) -extern string genfilename; // see Main.cpp (batch) -extern RSrandom *pRandom; - -// these functions to have different version for GUI and batch applications ... -#if BATCH -extern void MemoLine(string); -#endif -void GUIsetLandScale( - int, // landscape image height (pixels) - int // landscape image width (pixels) -); - -#if RS_RCPP -extern std::uint32_t RS_random_seed; -extern string name_landscape, name_patch, name_costfile, name_sp_dist; -#endif -//--------------------------------------------------------------------------- -#endif diff --git a/src/RScore/Parameters.cpp b/src/RScore/Parameters.cpp deleted file mode 100644 index b7c6a34..0000000 --- a/src/RScore/Parameters.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Parameters.h" -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -// Environmental gradient parameters - -paramGrad::paramGrad(void) { -gradient = false; gradType = 0; grad_inc = 0.05f; -opt_y0 = opt_y = factor = extProbOpt = 0.0; -shifting = false; shift_rate = 0.5; shift_begin = 0; shift_stop = 100; -} - -paramGrad::~paramGrad() { } - -void paramGrad::setGradient(int gtype, float inc, float y, float f, float p) -{ -if (gtype > 0 && gtype < 4) -{ // valid gradient type - gradient = true; gradType = gtype; - if (inc >= 0.0 && inc <= 1.0) grad_inc = inc; - if (y >= 0.0) opt_y0 = opt_y = y; - if (f >= 0.0) factor = f; - if (p > 0.0 && p < 1.0) extProbOpt = p; -} -else { - gradient = false; gradType = 0; -} -} - -void paramGrad::setShifting(float r, int begin, int end) -{ -shifting = true; -if (r > 0.0) shift_rate = r; -if (begin >= 0) shift_begin = begin; -if (end > 0) shift_stop = end; -} - -void paramGrad::noGradient(void) { gradient = false; gradType = 0; } - -void paramGrad::noShifting(void) { shifting = false; } - -envGradParams paramGrad::getGradient(void) { -envGradParams g; -g.gradient = gradient; g.gradType = gradType; g.grad_inc = grad_inc; -g.opt_y = opt_y; g.factor = factor; g.extProbOpt = extProbOpt; -g.shifting = shifting; g.shift_rate = shift_rate; -g.shift_begin = shift_begin; g.shift_stop = shift_stop; -return g; -} - -void paramGrad::incrOptY(void) -{ if (gradient && shifting) opt_y += shift_rate; } - -void paramGrad::resetOptY(void) { opt_y = opt_y0; } - -//--------------------------------------------------------------------------- - -// Environmental stochasticity parameters - -paramStoch::paramStoch(void) { -stoch = false; local = false; inK = false; localExt = false; -ac = 0.0; std = 0.25; -locExtProb = 0.1; -} - -paramStoch::~paramStoch(void) {} - - -void paramStoch::setStoch(envStochParams e) -{ -stoch = e.stoch; local = e.local; inK = e.inK; localExt = e.localExt; -if (e.ac >= 0.0 && e.ac < 1.0) ac = e.ac; -if (e.std > 0.0 && e.std <= 1.0) std = e.std; -locExtProb = e.locExtProb; -} - -bool paramStoch::envStoch(void) { return stoch; } - -envStochParams paramStoch::getStoch(void) -{ -envStochParams e; -e.stoch = stoch; e.local = local; e.inK = inK; e.localExt = localExt; -e.ac = ac; e.std = std; -e.locExtProb = locExtProb; -return e; -} - - -//--------------------------------------------------------------------------- - -// Initialisation (seeding) parameters - -paramInit::paramInit(void) { -seedType = freeType = spDistType = initDens = 0; -initAge = initFrzYr = 0; -restrictRange = false; -restrictRows = 100; -restrictFreq = 10; -finalFrzYr = 99999999; -indsCell = 1; indsHa = 0.0; -minSeedX = 0; maxSeedX = 99999999; minSeedY = 0; maxSeedY = 99999999; -nSeedPatches = 1; nSpDistPatches = 1; -indsFile = "NULL"; -for (int i = 0; i < NSTAGES; i++) { - initProp[i] = 0.0; -} -} - -paramInit::~paramInit(void) { -initinds.clear(); -} - -void paramInit::setInit(initParams i) { -if (i.seedType >= 0 && i.seedType <= 3) seedType = i.seedType; -if (i.freeType >= 0 && i.freeType <= 2) freeType = i.freeType; -if (i.spDistType >= 0 && i.spDistType <= 2) spDistType = i.spDistType; -initDens = i.initDens; -initAge = i.initAge; -if (i.initFrzYr >= 0) initFrzYr = i.initFrzYr; -restrictRange = i.restrictRange; -if (i.restrictRows > 0) restrictRows = i.restrictRows; -if (i.restrictFreq > 0) restrictFreq = i.restrictFreq; -if (i.finalFrzYr > 0) finalFrzYr = i.finalFrzYr; -if (i.indsCell >= 1) indsCell = i.indsCell; -if (i.indsHa > 0.0) indsHa = i.indsHa; -if (i.minSeedX >= 0) minSeedX = i.minSeedX; -if (i.maxSeedX >= 0) maxSeedX = i.maxSeedX; -if (i.minSeedY >= 0) minSeedY = i.minSeedY; -if (i.maxSeedY >= 0) maxSeedY = i.maxSeedY; -if (i.nSeedPatches >= 1) nSeedPatches = i.nSeedPatches; -if (i.nSpDistPatches >= 1) nSpDistPatches = i.nSpDistPatches; -indsFile = i.indsFile; -} - -initParams paramInit::getInit(void) { -initParams i; -i.seedType = seedType; i.freeType = freeType; i.spDistType = spDistType; -i.initDens = initDens; i.initAge = initAge; -i.initFrzYr = initFrzYr; -i.restrictRange = restrictRange; -i.restrictRows = restrictRows; i.restrictFreq = restrictFreq; -i.finalFrzYr = finalFrzYr; -i.indsCell = indsCell; i.indsHa = indsHa; -i.minSeedX = minSeedX; i.minSeedY = minSeedY; -i.maxSeedX = maxSeedX; i.maxSeedY = maxSeedY; -i.nSeedPatches = nSeedPatches; i.nSpDistPatches = nSpDistPatches; -i.indsFile = indsFile; -return i; -} - -void paramInit::setProp(short stg,float p) { -if (stg >= 0 && stg < NSTAGES && p >= 0.0 && p <= 1.0) initProp[stg] = p; -} - -float paramInit::getProp(short stg) { -float p = 0.0; -if (stg >= 0 && stg < NSTAGES) p = initProp[stg]; -return p; -} - -void paramInit::addInitInd(initInd iind) { -#if RSDEBUG -//DebugGUI(("paramInit::addInitInd(): iind.patchID=" + Int2Str(iind.patchID) -// + " iind.x=" + Int2Str(iind.x) -// + " iind.y=" + Int2Str(iind.y) -// ).c_str()); -#endif -initinds.push_back(iind); -} - -initInd paramInit::getInitInd(int ix) { -initInd iind; -if (ix >= 0 && ix < (int)initinds.size()) { - iind = initinds[ix]; -} -else { - iind.year = iind.patchID = iind.x = iind.y = iind.sex = iind.age = iind.stage = 0; - iind.species = -1; -} -#if RSDEBUG -//DEBUGLOG << "paramInit::getInitInd(): ix=" << ix << " size()=" << initinds.size() -// << " iind.patchID=" << iind.patchID -// << " iind.x=" << iind.x -// << " iind.y=" << iind.y -// << endl; -#endif -return iind; -} - -void paramInit::resetInitInds(void) { initinds.clear(); } - -int paramInit::numInitInds(void) { return (int)initinds.size(); } - - -//--------------------------------------------------------------------------- - -// Simulation parameters - -paramSim::paramSim(void) { - simulation = 0; - reps = years = 1; - outIntRange = 1; -// outStartRange = outStartOcc = outStartPop = outStartInd = 0; - outStartPop = outStartInd = outStartGenetic = 0; - outStartTraitCell = outStartTraitRow = outStartConn = 0; - outIntOcc = outIntPop = outIntInd = outIntGenetic = 10; - outIntTraitCell = outIntTraitRow = outIntConn = 10; - mapInt = traitInt = 10; - slowFactor = 1; - batchMode = absorbing = false; - outRange = outOccup = outPop = outInds = false; - outGenetics = outGenXtab = false; outGenType = 0; - outTraitsCells = outTraitsRows = outConnect = false; - saveMaps = false; saveTraitMaps = false; - saveVisits = false; -#if RS_RCPP - outStartPaths = 0; outIntPaths = 0; - outPaths = false; ReturnPopRaster = false; CreatePopFile = true; -#endif - drawLoaded = false; - viewLand = false; viewPatch = false; viewGrad = false; viewCosts = false; - viewPop = false; viewTraits = false; viewPaths = false; viewGraph = false; - dir = ' '; -} - -paramSim::~paramSim(void) { } - -void paramSim::setSim(simParams s) { -if (s.batchNum >= 0) batchNum = s.batchNum; -if (s.simulation >= 0) simulation = s.simulation; -if (s.reps >= 1) reps = s.reps; -if (s.years >= 1) years = s.years; -if (s.mapInt >= 1) mapInt = s.mapInt; -if (s.traitInt >= 1) traitInt = s.traitInt; -batchMode = s.batchMode; absorbing = s.absorbing; -outRange = s.outRange; outOccup = s.outOccup; -outPop = s.outPop; outInds = s.outInds; -outGenetics = s.outGenetics; -if (s.outGenType >= 0 && s.outGenType <= 2) { - outGenType = s.outGenType; -} -outGenXtab = s.outGenXtab; -outTraitsCells = s.outTraitsCells; outTraitsRows = s.outTraitsRows; -outConnect = s.outConnect; -//if (s.outStartRange >= 0) outStartRange = s.outStartRange; -//if (s.outStartOcc >= 0) outStartOcc = s.outStartOcc; -if (s.outStartPop >= 0) outStartPop = s.outStartPop; -if (s.outStartInd >= 0) outStartInd = s.outStartInd; -if (s.outStartGenetic >= 0) outStartGenetic = s.outStartGenetic; -if (s.outStartTraitCell >= 0) outStartTraitCell = s.outStartTraitCell; -if (s.outStartTraitRow >= 0) outStartTraitRow = s.outStartTraitRow; -if (s.outStartConn >= 0) outStartConn = s.outStartConn; -if (s.outIntRange >= 1) outIntRange = s.outIntRange; -if (s.outIntOcc >= 1) outIntOcc = s.outIntOcc; -if (s.outIntPop >= 1) outIntPop = s.outIntPop; -if (s.outIntInd >= 1) outIntInd = s.outIntInd; -if (s.outIntGenetic >= 1) outIntGenetic = s.outIntGenetic; -if (s.outIntTraitCell >= 1) outIntTraitCell = s.outIntTraitCell; -if (s.outIntTraitRow >= 1) outIntTraitRow = s.outIntTraitRow; -if (s.outIntConn >= 1) outIntConn = s.outIntConn; -saveMaps = s.saveMaps; saveTraitMaps = s.saveTraitMaps; -saveVisits = s.saveVisits; -#if RS_RCPP -outStartPaths = s.outStartPaths; -outIntPaths = s.outIntPaths; -outPaths = s.outPaths; -ReturnPopRaster = s.ReturnPopRaster; -CreatePopFile = s.CreatePopFile; -#endif -drawLoaded = s.drawLoaded; -} - -simParams paramSim::getSim(void) { -simParams s; -s.batchNum = batchNum; -s.simulation = simulation; s.reps = reps; s.years = years; -s.outRange = outRange; s.outOccup = outOccup; s.outPop = outPop; s.outInds = outInds; -s.outGenetics = outGenetics; s.outGenType = outGenType; s.outGenXtab = outGenXtab; -s.outTraitsCells = outTraitsCells; s.outTraitsRows = outTraitsRows; s.outConnect = outConnect; -//s.outStartRange = outStartRange; -//s.outStartOcc = outStartOcc; -s.outStartPop = outStartPop; s.outStartInd = outStartInd; s.outStartGenetic = outStartGenetic; -s.outStartTraitCell = outStartTraitCell; s.outStartTraitRow = outStartTraitRow; -s.outStartConn = outStartConn; -s.outIntRange = outIntRange; -s.outIntOcc = outIntOcc; s.outIntPop = outIntPop; -s.outIntInd = outIntInd; s.outIntGenetic = outIntGenetic; -s.outIntTraitCell = outIntTraitCell; -s.outIntTraitRow = outIntTraitRow; -s.outIntConn = outIntConn; -s.batchMode = batchMode; -s.absorbing = absorbing; -s.saveMaps = saveMaps; s.saveTraitMaps = saveTraitMaps; -s.saveVisits = saveVisits; -s.mapInt = mapInt; s.traitInt = traitInt; -#if RS_RCPP -s.outStartPaths = outStartPaths; -s.outIntPaths = outIntPaths; -s.outPaths = outPaths; -s.ReturnPopRaster = ReturnPopRaster; -s.CreatePopFile = CreatePopFile; -#endif -s.drawLoaded = drawLoaded; -return s; -} - -int paramSim::getSimNum(void) { return simulation; } - -void paramSim::setViews(simView v) { -viewLand = v.viewLand; viewPatch = v.viewPatch; -viewGrad = v.viewGrad; viewCosts = v.viewCosts; -viewPop = v.viewPop; viewTraits = v.viewTraits; -viewPaths = v.viewPaths; viewGraph = v.viewGraph; -if (v.slowFactor > 0) slowFactor = v.slowFactor; -} - -simView paramSim::getViews(void) { -simView v; -v.viewLand = viewLand; v.viewPatch = viewPatch; -v.viewGrad = viewGrad; v.viewCosts = viewCosts; -v.viewPop = viewPop; v.viewTraits = viewTraits; -v.viewPaths = viewPaths; v.viewGraph = viewGraph; -v.slowFactor = slowFactor; -return v; -} - -void paramSim::setDir(string s) { -dir = s; -} - -// return directory name depending on option specified -string paramSim::getDir(int option) { -string s; -switch (option) { -case 0: // working directory - s = dir; - break; -#if LINUX_CLUSTER || RS_RCPP -case 1: // Inputs folder - s = dir + "Inputs/"; - break; -case 2: // Outputs folder - s = dir + "Outputs/"; - break; -case 3: // Maps folder - s = dir + "Output_Maps/"; - break; -#else -case 1: // Inputs folder - s = dir + "Inputs\\"; - break; -case 2: // Outputs folder - s = dir + "Outputs\\"; - break; -case 3: // Maps folder - s = dir + "Output_Maps\\"; - break; -#endif -default: - s = "ERROR_ERROR_ERROR"; -} -return s; -} - -#if RS_RCPP -bool paramSim::getReturnPopRaster(void) { return ReturnPopRaster; } -bool paramSim::getCreatePopFile(void) { return CreatePopFile; } -#endif - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - diff --git a/src/RScore/Parameters.h b/src/RScore/Parameters.h deleted file mode 100644 index b029491..0000000 --- a/src/RScore/Parameters.h +++ /dev/null @@ -1,393 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Parameters - -Implements the following classes: - -paramGrad - Environmental gradient parameters -paramInit - Initialisation (seeding) parameters -paramSim - Simulation parameters -paramStoch - Environmental stochasticity parameters - -Also declares some structures and functions used throughout the program. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 25 June 2021 by Steve Palmer - -------------------------------------------------------------------------------*/ - -#ifndef ParametersH -#define ParametersH - -//#if LINUX_CLUSTER -//#include -//#else -#include -//#endif -#include -#include -//#include -#include -#include -#include -using namespace std; -#if RS_RCPP -#include "../Version.h" -#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif - -#include "RSrandom.h" - -#define NSTAGES 10 // maximum number of stages permitted -#define NSEXES 2 // maximum number of sexes permitted -#define PARAMDEBUG 0 -#define NTRAITS 18 // maximum number of variable traits which can be displayed - // in GUI (VCL version) -#define NSD 3.0 // no. of s.d. to use to control range for displaying traits - -#if RS_RCPP -typedef intptr_t intptr; -#else -#if RSWIN64 -typedef unsigned long long intptr; -#else -typedef unsigned int intptr; -#endif -#endif - -#if RS_RCPP - #ifndef R_EXT_CONSTANTS_H_ // the R headers define PI as a macro, so that the 'else' line results in an error - #define M_2PI 6.283185307179586 - const double PI = 3.141592653589793238462643383279502884197169399375; - #endif -#else - #define M_2PI 6.283185307179586 - const double PI = 3.141592654; -#endif - -const double SQRT2 = std::sqrt(double(2.0)); // more efficient than calculating every time - -//--------------------------------------------------------------------------- - -// Common declarations - -struct locn { int x; int y; }; -struct rgb { // colour scheme for drawing maps - int r,g,b; -}; - -const string Int2Str(const int); -#if RS_RCPP -const string Int2Str(const int, unsigned int); -#endif -const string Float2Str(const float); -const string Double2Str(const double); -const rgb draw_wheel(int); - -//--------------------------------------------------------------------------- - -// Environmental gradient parameters - -// SHOULD THIS BE PART OF LANDSCAPE OBJECT OR A SEPARATE OBJECT????????????? - -struct envGradParams { - bool gradient; bool shifting; - int gradType; float grad_inc; float opt_y; float factor; float extProbOpt; - float shift_rate; int shift_begin; int shift_stop; -}; - -class paramGrad { - -public: - paramGrad(void); - ~paramGrad(void); - void setGradient( - int, // gradient type - float, // gradient steepness - float, // optimum row (Y dimension) - float, // local scaling factor - float // local extinction probability at optimum - ); - void setShifting( - float, // shifting rate (rows/year) - int, // first year of shifting - int // last year of shifting - ); - void noGradient(void); - void noShifting(void); - envGradParams getGradient(void); - void incrOptY(void); - void resetOptY(void); - -private: - bool gradient; // there a gradient - bool shifting; // the gradient is shifting - int gradType; // 0 = none, 1 = carrying capacity, - // 2 = growth rate, 3 = local extinction probability - float grad_inc; // gradient steepness - float opt_y; // optimum row (Y dimension) - float opt_y0; // optimum row at year 0 (internal use only) - float factor; // local scaling factor - float extProbOpt; // local extinction probability at optimum (if gradient = 4, otherwise 0) - float shift_rate; // rows/year - int shift_begin; // first year of shifting - int shift_stop; // last year of shifting -}; - -//--------------------------------------------------------------------------- - -// Environmental stochasticity parameters - -// SHOULD THIS BE PART OF LANDSCAPE OBJECT OR A SEPARATE OBJECT????????????? - -struct envStochParams { - bool stoch; bool local; bool inK; bool localExt; - float ac; float std; - float locExtProb; -}; - -class paramStoch { - -public: - paramStoch(void); - ~paramStoch(void); - void setStoch(envStochParams); - bool envStoch(void); - envStochParams getStoch(void); - -private: - bool stoch; // stochasticity applied - bool local; // applied locally (if not, application is global) - bool inK; // in carrying capacity (if not, in growth rate) - bool localExt; // local extinction applied - float ac; // temporal autocorrelation coefficient - float std; // amplitude of fluctuations: sampled from N(0,std) - float locExtProb; // local extinction probability -}; - -//--------------------------------------------------------------------------- - -// Initialisation (seeding) parameters - -struct initParams { - short seedType; short freeType; short spDistType; short initDens; - short initAge; int initFrzYr; bool restrictRange; - int restrictRows; int restrictFreq; int finalFrzYr; - int indsCell; float indsHa; - int minSeedX; int maxSeedX; int minSeedY; int maxSeedY; - int nSeedPatches; int nSpDistPatches; - string indsFile; -}; - -struct initInd { - int year,patchID,x,y; short species,sex,age,stage; -}; - -class paramInit { - -public: - paramInit(void); - ~paramInit(void); - void setInit(initParams); - initParams getInit(void); - void setProp( - short, // stage - float // initial proportion - ); - float getProp( - short // stage - ); - void addInitInd(initInd); - initInd getInitInd(int); - void resetInitInds(void); - int numInitInds(void); - -private: - short seedType; // initialisation type: 0 = free, 1 = from species distn, - // 2 = initial individuals, 3 = from file - short freeType; // free initialisation type: - // 0 = random (given no.) - // 1 = all suitable cells/patches - // 2 = manually selected cells/patches - short spDistType; // species distribution initialisation type: - // 0 = all suitable cells/patches, - // 1 = some randomly chosen suitable cells/patches, - // 2 = all cells/patches within selected sp. dist. cells - short initDens; // initialisation density: - // 0 = at carrying capacity - // 1 = at half carrying capacity - // 2 = specified no. per cell or density - short initAge; // initial age distribution within each stage: - // 0 = lowest possible age - // 1 = randomised - // 2 = quasi-equilibrium - int initFrzYr; // year until which initial range is frozen - bool restrictRange; // restrict range to northern front - int restrictRows; // no. of rows to retain behind front - int restrictFreq; // frequency of range restriction - int finalFrzYr; // year after which range is frozen - int indsCell; // initial individuals / cell (cell-based model) - float indsHa; // initial density (patch-based model) - int minSeedX; // ) - int maxSeedX; // ) min. and max. of area to initialise (cell numbers) - int minSeedY; // ) only applied if seedType is 0 - int maxSeedY; // ) - int nSeedPatches; // no. of cells/patches to initialise - int nSpDistPatches; // no. of species distribution cells to initialise - string indsFile; // no. of species distribution cells to initialise - float initProp[NSTAGES]; // initial stage proportions (structured population only) - - vector initinds; // individuals to be initialised - -}; - -//--------------------------------------------------------------------------- - -// Simulation parameters - -struct simParams { - int batchNum; - int simulation; int reps; int years; -// int outStartRange; -// int outStartOcc; - int outStartPop; int outStartInd; int outStartGenetic; - int outStartTraitCell; int outStartTraitRow; int outStartConn; - int outIntRange; int outIntOcc; int outIntPop; int outIntInd; int outIntGenetic; - int outIntTraitCell; int outIntTraitRow; int outIntConn; - int mapInt; int traitInt; - bool batchMode; bool absorbing; - bool outRange; bool outOccup; bool outPop; bool outInds; - bool outGenetics; short outGenType; bool outGenXtab; - bool outTraitsCells; bool outTraitsRows; bool outConnect; - bool saveMaps; - bool drawLoaded; bool saveTraitMaps; - bool saveVisits; -#if RS_RCPP - int outStartPaths; int outIntPaths; - bool outPaths; bool ReturnPopRaster; bool CreatePopFile; -#endif -}; - -struct simView { - bool viewLand; bool viewPatch; bool viewGrad; bool viewCosts; - bool viewPop; bool viewTraits; bool viewPaths; bool viewGraph; - int slowFactor; -}; - -class paramSim { - -public: - paramSim(void); - ~paramSim(void); - void setSim(simParams); - simParams getSim(void); - int getSimNum(void); - void setViews(simView); - simView getViews(void); - void setDir(string); - string getDir(int); -#if RS_RCPP - bool getReturnPopRaster(void); - bool getCreatePopFile(void); -#endif - -private: - int batchNum; // batch number - int simulation; // simulation no. - int reps; // no. of replicates - int years; // no. of years -// int outStartRange; // output start year for range file -// int outStartOcc; // output start year for occupancy file - int outStartPop; // output start year for population file - int outStartInd; // output start year for individuals file - int outStartGenetic; // output start year for genetics file - int outStartTraitCell; // output start year for traits by cell file - int outStartTraitRow; // output start year for traits by row file - int outStartConn; // output start year for connectivity matrix - int outIntRange; // output interval for range file - int outIntOcc; // output interval for occupancy file - int outIntPop; // output interval for population file - int outIntInd; // output interval for individuals file - int outIntGenetic; // output interval for genetics file - int outIntTraitCell; // output interval for traits by cell file - int outIntTraitRow; // output interval for traits by row file - int outIntConn; // output interval for connectivity matrix - int mapInt; // output interval for maps - int traitInt; // output interval for evolving traits maps - int slowFactor; // to reduce speed of movement paths on screen - bool batchMode; // - bool absorbing; // landscape boundary and no-data regions are - // absorbing boundaries - bool outRange; // produce output range file? - bool outOccup; // produce output occupancy file? - bool outPop; // produce output population file? - bool outInds; // produce output individuals file? - bool outGenetics; // produce output genetics file? - short outGenType; // produce output genetics for: 0 = juveniles only - // 1 = all individuals, 2 = adults (i.e. final stage) only - bool outGenXtab; // produce output genetics as a cross table? - bool outTraitsCells; // produce output summary traits by cell file? - bool outTraitsRows; // produce output summary traits by row (y) file? - bool outConnect; // produce output connectivity file? - bool saveMaps; // save landscape/population maps? - bool saveVisits; // save dispersal visits heat maps? -#if RS_RCPP - int outStartPaths; - int outIntPaths; - bool outPaths; - bool ReturnPopRaster; - bool CreatePopFile; -#endif - bool drawLoaded; // draw initial distribution on landscape/population maps? - bool saveTraitMaps; // save summary traits maps? - bool viewLand; // view landscape map on screen? - bool viewPatch; // view map of landscape patches on screen? - bool viewGrad; // view gradient map on screen? - bool viewCosts; // view costs map on screen? - bool viewPop; // view population density on landscape map on screen? - bool viewTraits; // view summary traits map(s) on screen? - bool viewPaths; // view individual movement paths on screen? - bool viewGraph; // view population/occupancy graph on screen? - string dir; // full name of working directory - -}; - -#if RSDEBUG -extern ofstream DEBUGLOG; -void DebugGUI(string); -#endif - -//--------------------------------------------------------------------------- -#endif diff --git a/src/RScore/Patch.cpp b/src/RScore/Patch.cpp deleted file mode 100644 index 60421c4..0000000 --- a/src/RScore/Patch.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Patch.h" -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -Patch::Patch(int seqnum,int num) -{ -patchSeqNum = seqnum; patchNum = num; nCells = 0; -xMin = yMin = 999999999; xMax = yMax = 0; x = y = 0; -subCommPtr = 0; -localK = 0.0; -for (int sex = 0; sex < NSEXES; sex++) { - nTemp[sex] = 0; -} -changed = false; -} - -Patch::~Patch() { -cells.clear(); -popns.clear(); -} - -int Patch::getSeqNum(void) { return patchSeqNum; } - -int Patch::getPatchNum(void) { return patchNum; } - -int Patch::getNCells(void) { return nCells; } - -patchLimits Patch::getLimits(void) { -patchLimits p; -p.xMin = xMin; p.xMax = xMax; p.yMin = yMin; p.yMax = yMax; -return p; -} - -// Does the patch fall (partially) within a specified rectangle? -bool Patch::withinLimits(patchLimits rect){ -locn loc; -if (xMin <= rect.xMax && xMax >= rect.xMin && yMin <= rect.yMax && yMax >= rect.yMin) { - // patch is within the rectangle UNLESS it is irregular in shape and lies at a corner - // of the rectangle - if ((xMin >= rect.xMin && xMax <= rect.xMax) - || (yMin >= rect.yMin && yMax <= rect.yMax)) { - // patch lies within or along an edge of the initialistaion rectangle - return true; - } - else { - // check for any cell of the patch lying within the rectangle - int ncells = (int)cells.size(); - for (int i = 0; i < ncells; i++) { - loc = getCellLocn(i); - if (loc.x >= rect.xMin && loc.x <= rect.xMax - && loc.y >= rect.yMin && loc.y <= rect.yMax) { - // cell lies within the rectangle - return true; - } - } - } - } -return false; -} - -// Reset minimum and maximum co-ordinates of the patch if it has been changed -void Patch::resetLimits(void) { -if (changed) { - // remove any deleted cells - std::vector newcells; // for all retained and added cells - int ncells = (int)cells.size(); - for (int i = 0; i < ncells; i++) { - if (cells[i] != NULL) { - newcells.push_back(cells[i]); - } - } - cells.clear(); - cells = newcells; - // reset patch limits - locn loc; - xMin = yMin = 999999999; xMax = yMax = 0; - ncells = (int)cells.size(); - for (int i = 0; i < ncells; i++) { - loc = getCellLocn(i); - if (loc.x < xMin) xMin = loc.x; - if (loc.x > xMax) xMax = loc.x; - if (loc.y < yMin) yMin = loc.y; - if (loc.y > yMax) yMax = loc.y; - } - changed = false; -} -} - -// Add a cell to the patch -void Patch::addCell(Cell* pCell,int x,int y) { - cells.push_back(pCell); - nCells++; - if (x < xMin) xMin = x; - if (x > xMax) xMax = x; - if (y < yMin) yMin = y; - if (y > yMax) yMax = y; -} - -// Calculate the total carrying capacity (no. of individuals) and -// centroid co-ordinates of the patch -void Patch::setCarryingCapacity(Species *pSpecies,patchLimits landlimits, - float epsGlobal,short nHab,short rasterType,short landIx,bool gradK) { -envStochParams env = paramsStoch->getStoch(); -//Cell *pCell; -locn loc; -int xsum,ysum; -short hx; -float k,q,envval; - -localK = 0.0; // no. of suitable cells (unadjusted K > 0) in the patch -int nsuitable = 0; -double mean; - -#if RSDEBUG -//DEBUGLOG << "Patch::setCarryingCapacity(): patchNum=" << patchNum -// << " xMin=" << xMin << " yMin=" << yMin << " xMax=" << xMax << " yMax=" << yMax -// << endl; -#endif - -if (xMin > landlimits.xMax || xMax < landlimits.xMin -|| yMin > landlimits.yMax || yMax < landlimits.yMin) { - // patch lies wholely outwith current landscape limits - // NB the next statement is unnecessary, as localK has been set to zero above - // retained only for consistency in standard variant - localK = 0.0; -#if RSDEBUG -//DEBUGLOG << "Patch::setCarryingCapacity(): patchNum=" << patchNum -// << " localK=" << localK -// << endl; -#endif - return; -} - -int ncells = (int)cells.size(); -xsum = ysum = 0; -for (int i = 0; i < ncells; i++) { - if (gradK) // gradient in carrying capacity - envval = cells[i]->getEnvVal(); // environmental gradient value - else envval = 1.0; // no gradient effect - if (env.stoch && env.inK) { // environmental stochasticity in K - if (env.local) { -// pCell = getRandomCell(); -// if (pCell != 0) envval += pCell->getEps(); - envval += cells[i]->getEps(); - } - else { // global stochasticity - envval += epsGlobal; - } - } - switch (rasterType) { - case 0: // habitat codes - hx = cells[i]->getHabIndex(landIx); - k = pSpecies->getHabK(hx); - if (k > 0.0) { - nsuitable++; - localK += envval * k; - } - break; - case 1: // cover % - k = 0.0; - for (int j = 0; j < nHab; j++) { // loop through cover layers - q = cells[i]->getHabitat(j); - k += q * pSpecies->getHabK(j) / 100.0f; - } - if (k > 0.0) { - nsuitable++; - localK += envval * k; - } - break; - case 2: // habitat quality - q = cells[i]->getHabitat(landIx); - if (q > 0.0) { - nsuitable++; - localK += envval * pSpecies->getHabK(0) * q / 100.0f; - } - break; - } -#if RSDEBUG -//DEBUGLOG << "Patch::setCarryingCapacity(): patchNum=" << patchNum -// << " i=" << i << " hx=" << hx << " q=" << q << " k=" << k << " localK=" << localK -// << endl; -#endif - loc = cells[i]->getLocn(); - xsum += loc.x; ysum += loc.y; -} -#if RSDEBUG -//DEBUGLOG << "Patch::setCarryingCapacity(): patchNum=" << patchNum -// << " epsGlobal=" << epsGlobal << " localK=" << localK -// << endl; -#endif -// calculate centroid co-ordinates -if (ncells > 0) { - mean = (double)xsum / (double)ncells; - x = (int)(mean + 0.5); - mean = (double)ysum / (double)ncells; - y = (int)(mean + 0.5); -} -if (env.stoch && env.inK) { // environmental stochasticity in K - // apply min and max limits to K over the whole patch - // NB limits have been stored as N/cell rather than N/ha - float limit; - limit = pSpecies->getMinMax(0) * (float)nsuitable; - if (localK < limit) localK = limit; -#if RSDEBUG -//DEBUGLOG << "Patch::setCarryingCapacity(): patchNum=" << patchNum -// << " limit=" << limit << " localK=" << localK -// << endl; -#endif - limit = pSpecies->getMinMax(1) * (float)nsuitable; - if (localK > limit) localK = limit; -#if RSDEBUG -//DEBUGLOG << "Patch::setCarryingCapacity(): patchNum=" << patchNum -// << " limit=" << limit << " localK=" << localK -// << endl; -#endif -} -#if RSDEBUG -//DEBUGLOG << "Patch::setCarryingCapacity(): patchNum=" << patchNum -// << " localK=" << localK -// << endl; -#endif -} - - -float Patch::getK(void) { return localK; } - -// Return co-ordinates of a specified cell -locn Patch::getCellLocn(int ix) { -locn loc; loc.x = -666; loc.y = -666; -int ncells = (int)cells.size(); -if (ix >= 0 && ix < ncells) { - loc = cells[ix]->getLocn(); -} -return loc; -} -// Return pointer to a specified cell -Cell* Patch::getCell(int ix) { -int ncells = (int)cells.size(); -if (ix >= 0 && ix < ncells) return cells[ix]; -else return 0; -} -// Return co-ordinates of patch centroid -locn Patch::getCentroid(void) { -locn loc; loc.x = x; loc.y = y; -return loc; -} - -// Select a Cell within the Patch at random, and return pointer to it -// For a cell-based model, this will be the only Cell -Cell* Patch::getRandomCell(void) { -Cell *pCell = 0; -int ix; -int ncells = (int)cells.size(); -if (ncells > 0) { - if (ncells == 1) ix = 0; - else ix = pRandom->IRandom(0,ncells-1); - pCell = cells[ix]; -} -return pCell; -} - -// Remove a cell from the patch -void Patch::removeCell(Cell* pCell) { -int ncells = (int)cells.size(); -for (int i = 0; i < ncells; i++) { - if (pCell == cells[i]) { - cells[i] = NULL; i = ncells; - nCells--; - changed = true; - } -} -} - -void Patch::setSubComm(intptr sc) -{ subCommPtr = sc; } - -// Get pointer to corresponding Sub-community (cast as an integer) -intptr Patch::getSubComm(void) -{ return subCommPtr; } - -void Patch::addPopn(patchPopn pop) { -popns.push_back(pop); -} - -// Return pointer (cast as integer) to the Population of the specified Species -intptr Patch::getPopn(intptr sp) -{ -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { - if (popns[i].pSp == sp) return popns[i].pPop; -} -return 0; -} - -void Patch::resetPopn(void) { -popns.clear(); -} - -void Patch::resetPossSettlers(void) { -for (int sex = 0; sex < NSEXES; sex++) { - nTemp[sex] = 0; -} -} - -// Record the presence of a potential settler within the Patch -void Patch::incrPossSettler(Species *pSpecies,int sex) { -#if RSDEBUG -//DEBUGLOG << "Patch::incrPossSettler(): 5555: patchNum = " << patchNum -// << " sex = " << sex << endl; -#endif -// NOTE: THE FOLLOWING OPERATION WILL NEED TO BE MADE SPECIES-SPECIFIC... -if (sex >= 0 && sex < NSEXES) { - nTemp[sex]++; -} -} - -// Get number of a potential settlers within the Patch -int Patch::getPossSettlers(Species *pSpecies,int sex) { -#if RSDEBUG -//DEBUGLOG << "Patch::getPossSettlers(): 5555: patchNum = " << patchNum -// << " sex = " << sex << endl; -#endif -// NOTE: THE FOLLOWING OPERATION WILL NEED TO BE MADE SPECIES-SPECIFIC... -if (sex >= 0 && sex < NSEXES) return nTemp[sex]; -else return 0; -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - - - diff --git a/src/RScore/Patch.h b/src/RScore/Patch.h deleted file mode 100644 index 2f086d7..0000000 --- a/src/RScore/Patch.h +++ /dev/null @@ -1,182 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Patch - -Implements the class: Patch - -A patch is a collection of one or more Cells in the the gridded Landscape, -which together provide the area in which a single demographic unit of a Species, -i.e. a Population, can reproduce. One or more Populations (of different Species) -form a Sub-community associated with the Patch. - -There is no requirement that all the Cells be adjacent, although in practice -that would usually be the case. - -Each Patch must have a unique positive integer id number supplied by the user, -and the matrix, i.e. any part of the landscape which is not a breeding patch, -is represented by Patch 0. However, as patch numbers need not be sequential, -an internal sequential number is also applied. - -For a 'cell-based model', the user supplies no patch numbers, and a separate -Patch is generated internally for each Cell, i.e. the 'cell-based model' is a -special case of the 'patch-based model' in which each Patch has a single Cell. -Moreover, there is also the 'matrix' Patch 0, which has no cells, but which -holds the disperser population whilst its Individuals are in transit. - -In a true patch-based model, each Patch hold a list of its constituent Cells, -EXCEPT for the matrix Patch 0. This is because that list would be extremely -long for a very large landscape in which suitable patches are small and/or rare, -and removing Cells from it if the landscape is dynamic would be inefficient. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 25 June 2021 by Steve Palmer - -------------------------------------------------------------------------------*/ - -#ifndef PatchH -#define PatchH - -#include -using namespace std; - -#if RS_RCPP -#include "../Version.h" -#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif - -#include "Parameters.h" -#include "Cell.h" -#include "Species.h" - -//--------------------------------------------------------------------------- - -struct patchLimits { - int xMin,xMax,yMin,yMax; -}; -struct patchPopn { - intptr pSp,pPop; // pointers to Species and Population cast as integers -}; - -class Patch{ -public: - Patch( - int, // internal sequential number - int // patch id number - ); - ~Patch(); - int getSeqNum(void); - int getPatchNum(void); - int getNCells(void); - patchLimits getLimits(void); // Returns the minimum and maximum co-ordinates of the patch - bool withinLimits( // Does the patch fall (partially) within a specified rectangle? - patchLimits // structure holding the SW and NE co-ordinates of the rectangle - ); - void resetLimits(void); // Reset minimum and maximum co-ordinates of the patch - void addCell( - Cell*, // pointer to the Cell to be added to the Patch - int,int // x (column) and y (row) co-ordinates of the Cell - ); - locn getCellLocn( // Return co-ordinates of a specified cell - int // index no. of the Cell within the vector cells - ); - Cell* getCell( // Return pointer to a specified cell - int // index no. of the Cell within the vector cells - ); - locn getCentroid(void); // Return co-ordinates of patch centroid - void removeCell( - Cell* // pointer to the Cell to be removed from the Patch - ); - Cell* getRandomCell(void); - void setSubComm( - intptr // pointer to the Sub-community cast as an integer - ); - intptr getSubComm(void); - void addPopn( - patchPopn // structure holding pointers to Species and Population cast as integers - ); - intptr getPopn( // return pointer (cast as integer) to the Population of the Species - intptr // pointer to Species cast as integer - ); - void resetPopn(void); - void resetPossSettlers(void); - void incrPossSettler( // Record the presence of a potential settler within the Patch - Species*, // pointer to the Species - int // sex of the settler - ); - int getPossSettlers( // Get number of a potential settlers within the Patch - Species*, // pointer to the Species - int // sex of the settlers - ); - void setCarryingCapacity( // Calculate total Patch carrying capacity (no. of inds) - Species*, // pointer to the Species - patchLimits, // current min and max limits of landscape - float, // global stochasticity value (epsilon) for the current year - short, // no. of habitat classes in the Landscape - short, // rasterType (see Landscape) - short, // landscape change index (always zero if not dynamic) - bool // TRUE if there is a gradient in carrying capacity across the Landscape - ); - float getK(void); - // dummy function for batch version - void drawCells(float,int,rgb); - - private: - int patchSeqNum;// sequential patch number - patch 0 is reserved for the inter-patch matrix - int patchNum; // patch number as supplied by the user (not forced to be sequential) - int nCells; // no. of cells in the patch - int xMin,xMax,yMin,yMax; // min and max cell co-ordinates - int x,y; // centroid co-ordinates (approx.) - intptr subCommPtr; // pointer (cast as integer) to sub-community associated with the patch - // NOTE: FOR MULTI-SPECIES MODEL, PATCH WILL NEED TO STORE K FOR EACH SPECIES - float localK; // patch carrying capacity (individuals) - bool changed; -// NOTE: THE FOLLOWING ARRAY WILL NEED TO BE MADE SPECIES-SPECIFIC... - short nTemp[NSEXES]; // no. of potential settlers in each sex - - std::vector cells; - std::vector popns; - -}; - -//--------------------------------------------------------------------------- - -extern paramStoch *paramsStoch; -extern RSrandom *pRandom; - -#if RSDEBUG -extern ofstream DEBUGLOG; -#endif - -#endif diff --git a/src/RScore/Population.cpp b/src/RScore/Population.cpp deleted file mode 100644 index 4af1e84..0000000 --- a/src/RScore/Population.cpp +++ /dev/null @@ -1,1676 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - - //--------------------------------------------------------------------------- - -#include "Population.h" -//--------------------------------------------------------------------------- - -ofstream outPop; -ofstream outInds; - -//--------------------------------------------------------------------------- - -Population::Population(void) { - nSexes = nStages = 0; - pPatch = NULL; - pSpecies = NULL; - return; -} - -Population::Population(Species* pSp, Patch* pPch, int ninds, int resol) -{ - // constructor for a Population of a specified size - - int n, nindivs, age = 0, minage, maxage, nAges = 0; - int cumtotal = 0; - float probmale; - double ageprob, ageprobsum; - std::vector ageProb; // for quasi-equilibrium initial age distribution - Cell* pCell; - - if (ninds > 0) { - inds.reserve(ninds); - juvs.reserve(ninds); - } - - pSpecies = pSp; - pPatch = pPch; - // record the new population in the patch - patchPopn pp; - pp.pSp = (intptr)pSpecies; pp.pPop = (intptr)this; - pPatch->addPopn(pp); - - demogrParams dem = pSpecies->getDemogr(); - stageParams sstruct = pSpecies->getStage(); - emigRules emig = pSpecies->getEmig(); - trfrRules trfr = pSpecies->getTrfr(); - settleType sett = pSpecies->getSettle(); - genomeData gen = pSpecies->getGenomeData(); - initParams init = paramsInit->getInit(); - - // determine no. of stages and sexes of species to initialise - if (dem.stageStruct) { - nStages = sstruct.nStages; - } - else // non-structured population has 2 stages, but user only ever sees stage 1 - nStages = 2; - if (dem.repType == 0) { nSexes = 1; probmale = 0.0; } - else { nSexes = 2; probmale = dem.propMales; } - - // set up population sub-totals - for (int stg = 0; stg < NSTAGES; stg++) { - for (int sex = 0; sex < NSEXES; sex++) { - nInds[stg][sex] = 0; - } - } - - // set up local copy of minimum age table - short minAge[NSTAGES][NSEXES]; - for (int stg = 0; stg < nStages; stg++) { - for (int sex = 0; sex < nSexes; sex++) { - if (dem.stageStruct) { - if (dem.repType == 1) { // simple sexual model - // both sexes use minimum ages recorded for females - minAge[stg][sex] = pSpecies->getMinAge(stg, 0); - } - else { - minAge[stg][sex] = pSpecies->getMinAge(stg, sex); - } - } - else { // non-structured population - minAge[stg][sex] = 0; - } - } - } - - // individuals of new population must be >= stage 1 - for (int stg = 1; stg < nStages; stg++) { - if (dem.stageStruct) { // allocate to stages according to initialisation conditions - // final stage is treated separately to ensure that correct total - // no. of individuals is created - if (stg == nStages - 1) { - n = ninds - cumtotal; - } - else { - n = (int)(ninds * paramsInit->getProp(stg) + 0.5); - cumtotal += n; - } - } - else { // non-structured - all individuals go into stage 1 - n = ninds; - } - // establish initial age distribution - minage = maxage = stg; - if (dem.stageStruct) { - // allow for stage-dependent minimum ages (use whichever sex is greater) - if (minAge[stg][0] > 0 && minage < minAge[stg][0]) minage = minAge[stg][0]; - if (nSexes == 2 && minAge[stg][1] > 0 && minage < minAge[stg][1]) minage = minAge[stg][1]; - // allow for specified age distribution - if (init.initAge != 0) { // not lowest age - if (stg == nStages - 1) maxage = sstruct.maxAge; // final stage - else { // all other stages - use female max age, as sex of individuals is not predetermined - maxage = minAge[stg + 1][0] - 1; - } - if (maxage < minage) maxage = minage; - nAges = maxage - minage + 1; - if (init.initAge == 2) { // quasi-equilibrium distribution - double psurv = (double)pSpecies->getSurv(stg, 0); // use female survival for the stage - ageProb.clear(); - ageprobsum = 0.0; - ageprob = 1.0; - for (int i = 0; i < nAges; i++) { - ageProb.push_back(ageprob); ageprobsum += ageprob; ageprob *= psurv; - } - for (int i = 0; i < nAges; i++) { - ageProb[i] /= ageprobsum; - if (i > 0) ageProb[i] += ageProb[i - 1]; // to give cumulative probability - } - } - } - } - // create individuals - int sex; - nindivs = (int)inds.size(); - for (int i = 0; i < n; i++) { - pCell = pPatch->getRandomCell(); - if (dem.stageStruct) { - switch (init.initAge) { - case 0: // lowest possible age - age = minage; - break; - case 1: // randomised - if (maxage > minage) age = pRandom->IRandom(minage, maxage); - else age = minage; - break; - case 2: // quasi-equilibrium - if (nAges > 1) { - double rrr = pRandom->Random(); - int ageclass = 0; - while (rrr > ageProb[ageclass]) ageclass++; - age = minage + ageclass; - } - else age = minage; - break; - } - } - else age = stg; -#if RSDEBUG - // NOTE: CURRENTLY SETTING ALL INDIVIDUALS TO RECORD NO. OF STEPS ... - inds.push_back(new Individual(pCell, pPatch, stg, age, sstruct.repInterval, - probmale, true, trfr.moveType)); -#else - inds.push_back(new Individual(pCell, pPatch, stg, age, sstruct.repInterval, - probmale, trfr.moveModel, trfr.moveType)); -#endif - sex = inds[nindivs + i]->getSex(); - if (emig.indVar || trfr.indVar || sett.indVar || gen.neutralMarkers) - { - // individual variation - set up genetics - inds[nindivs + i]->setGenes(pSpecies, resol); - } - nInds[stg][sex]++; - } - } -} - -Population::~Population(void) { - int ninds = (int)inds.size(); - for (int i = 0; i < ninds; i++) { - if (inds[i] != NULL) delete inds[i]; - } - inds.clear(); - int njuvs = (int)juvs.size(); - for (int i = 0; i < njuvs; i++) { - if (juvs[i] != NULL) delete juvs[i]; - } - juvs.clear(); -} - -traitsums Population::getTraits(Species* pSpecies) { - int g; - traitsums ts; - for (int i = 0; i < NSEXES; i++) { - ts.ninds[i] = 0; - ts.sumD0[i] = ts.ssqD0[i] = 0.0; - ts.sumAlpha[i] = ts.ssqAlpha[i] = 0.0; ts.sumBeta[i] = ts.ssqBeta[i] = 0.0; - ts.sumDist1[i] = ts.ssqDist1[i] = 0.0; ts.sumDist2[i] = ts.ssqDist2[i] = 0.0; - ts.sumProp1[i] = ts.ssqProp1[i] = 0.0; - ts.sumDP[i] = ts.ssqDP[i] = 0.0; - ts.sumGB[i] = ts.ssqGB[i] = 0.0; - ts.sumAlphaDB[i] = ts.ssqAlphaDB[i] = 0.0; - ts.sumBetaDB[i] = ts.ssqBetaDB[i] = 0.0; - ts.sumStepL[i] = ts.ssqStepL[i] = 0.0; ts.sumRho[i] = ts.ssqRho[i] = 0.0; - ts.sumS0[i] = ts.ssqS0[i] = 0.0; - ts.sumAlphaS[i] = ts.ssqAlphaS[i] = 0.0; ts.sumBetaS[i] = ts.ssqBetaS[i] = 0.0; - } - - demogrParams dem = pSpecies->getDemogr(); - emigRules emig = pSpecies->getEmig(); - trfrRules trfr = pSpecies->getTrfr(); - settleType sett = pSpecies->getSettle(); - - int ninds = (int)inds.size(); - for (int i = 0; i < ninds; i++) { - int sex = inds[i]->getSex(); - if (emig.sexDep || trfr.sexDep || sett.sexDep) g = sex; else g = 0; - ts.ninds[g] += 1; - // emigration traits - emigTraits e = inds[i]->getEmigTraits(); - if (emig.sexDep) g = sex; else g = 0; - ts.sumD0[g] += e.d0; ts.ssqD0[g] += e.d0 * e.d0; - ts.sumAlpha[g] += e.alpha; ts.ssqAlpha[g] += e.alpha * e.alpha; - ts.sumBeta[g] += e.beta; ts.ssqBeta[g] += e.beta * e.beta; - // transfer traits - trfrKernTraits k = inds[i]->getKernTraits(); - if (trfr.sexDep) g = sex; else g = 0; - ts.sumDist1[g] += k.meanDist1; ts.ssqDist1[g] += k.meanDist1 * k.meanDist1; - ts.sumDist2[g] += k.meanDist2; ts.ssqDist2[g] += k.meanDist2 * k.meanDist2; - ts.sumProp1[g] += k.probKern1; ts.ssqProp1[g] += k.probKern1 * k.probKern1; - trfrSMSTraits sms = inds[i]->getSMSTraits(); - g = 0; // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT - ts.sumDP[g] += sms.dp; ts.ssqDP[g] += sms.dp * sms.dp; - ts.sumGB[g] += sms.gb; ts.ssqGB[g] += sms.gb * sms.gb; - ts.sumAlphaDB[g] += sms.alphaDB; ts.ssqAlphaDB[g] += sms.alphaDB * sms.alphaDB; - ts.sumBetaDB[g] += sms.betaDB; ts.ssqBetaDB[g] += sms.betaDB * sms.betaDB; - trfrCRWTraits c = inds[i]->getCRWTraits(); - g = 0; // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT - ts.sumStepL[g] += c.stepLength; ts.ssqStepL[g] += c.stepLength * c.stepLength; - ts.sumRho[g] += c.rho; ts.ssqRho[g] += c.rho * c.rho; - // settlement traits - settleTraits s = inds[i]->getSettTraits(); - if (sett.sexDep) g = sex; else g = 0; - ts.sumS0[g] += s.s0; ts.ssqS0[g] += s.s0 * s.s0; - ts.sumAlphaS[g] += s.alpha; ts.ssqAlphaS[g] += s.alpha * s.alpha; - ts.sumBetaS[g] += s.beta; ts.ssqBetaS[g] += s.beta * s.beta; - } - - return ts; -} - -int Population::getNInds(void) { return (int)inds.size(); } - -popStats Population::getStats(void) -{ - popStats p; - int ninds; - float fec; - bool breeders[2]; breeders[0] = breeders[1] = false; - demogrParams dem = pSpecies->getDemogr(); - p.pSpecies = pSpecies; - p.pPatch = pPatch; - p.spNum = pSpecies->getSpNum(); - p.nInds = (int)inds.size(); - p.nNonJuvs = p.nAdults = 0; - p.breeding = false; - for (int stg = 1; stg < nStages; stg++) { - for (int sex = 0; sex < nSexes; sex++) { - ninds = nInds[stg][sex]; - p.nNonJuvs += ninds; - - if (ninds > 0) { - if (pSpecies->stageStructured()) { - if (dem.repType == 2) fec = pSpecies->getFec(stg, sex); - else fec = pSpecies->getFec(stg, 0); - if (fec > 0.0) { breeders[sex] = true; p.nAdults += ninds; } - } - else breeders[sex] = true; - } - } - } - // is there a breeding population present? - if (nSexes == 1) { - p.breeding = breeders[0]; - } - else { - if (breeders[0] && breeders[1]) p.breeding = true; - } - return p; -} - -Species* Population::getSpecies(void) { return pSpecies; } - -int Population::totalPop(void) { - int t = 0; - for (int stg = 0; stg < nStages; stg++) { - for (int sex = 0; sex < nSexes; sex++) { - t += nInds[stg][sex]; - } - } - return t; -} - -int Population::stagePop(int stg) { - int t = 0; - if (stg < 0 || stg >= nStages) return t; - for (int sex = 0; sex < nSexes; sex++) { - t += nInds[stg][sex]; - } - return t; -} - -//--------------------------------------------------------------------------- -// Remove all Individuals -void Population::extirpate(void) { - int ninds = (int)inds.size(); - for (int i = 0; i < ninds; i++) { - if (inds[i] != NULL) delete inds[i]; - } - inds.clear(); - int njuvs = (int)juvs.size(); - for (int i = 0; i < njuvs; i++) { - if (juvs[i] != NULL) delete juvs[i]; - } - juvs.clear(); - for (int sex = 0; sex < nSexes; sex++) { - for (int stg = 0; stg < nStages; stg++) { - nInds[stg][sex] = 0; - } - } -} - -//--------------------------------------------------------------------------- -// Produce juveniles and hold them in the juvs vector -void Population::reproduction(const float localK, const float envval, const int resol) -{ - - // get population size at start of reproduction - int ninds = (int)inds.size(); - if (ninds == 0) return; - - int nsexes, stage, sex, njuvs, nj, nmales, nfemales; - Cell* pCell; - indStats ind; - double expected; - bool skipbreeding; - - envStochParams env = paramsStoch->getStoch(); - demogrParams dem = pSpecies->getDemogr(); - stageParams sstruct = pSpecies->getStage(); - emigRules emig = pSpecies->getEmig(); - trfrRules trfr = pSpecies->getTrfr(); - settleType sett = pSpecies->getSettle(); - genomeData gen = pSpecies->getGenomeData(); - simView v = paramsSim->getViews(); - - if (dem.repType == 0) nsexes = 1; else nsexes = 2; - - // set up local copy of species fecundity table - float fec[NSTAGES][NSEXES]; - for (int stg = 0; stg < sstruct.nStages; stg++) { - for (int sex = 0; sex < nsexes; sex++) { - if (dem.stageStruct) { - if (dem.repType == 1) { // simple sexual model - // both sexes use fecundity recorded for females - fec[stg][sex] = pSpecies->getFec(stg, 0); - } - else fec[stg][sex] = pSpecies->getFec(stg, sex); - } - else { // non-structured population - if (stg == 1) fec[stg][sex] = dem.lambda; // adults - else fec[stg][sex] = 0.0; // juveniles - } - } - } - - if (dem.stageStruct) { - // apply environmental effects and density dependence - // to all non-zero female non-juvenile stages - for (int stg = 1; stg < nStages; stg++) { - if (fec[stg][0] > 0.0) { - // apply any effect of environmental gradient and/or stochasticty - fec[stg][0] *= envval; - if (env.stoch && !env.inK) { - // fecundity (at low density) is constrained to lie between limits specified - // for the species - float limit; - limit = pSpecies->getMinMax(0); - if (fec[stg][0] < limit) fec[stg][0] = limit; - limit = pSpecies->getMinMax(1); - if (fec[stg][0] > limit) fec[stg][0] = limit; - } - if (sstruct.fecDens) { // apply density dependence - float effect = 0.0; - if (sstruct.fecStageDens) { // stage-specific density dependence - // NOTE: matrix entries represent effect of ROW on COLUMN - // AND males precede females - float weight = 0.0; - for (int effstg = 0; effstg < nStages; effstg++) { - for (int effsex = 0; effsex < nSexes; effsex++) { - if (dem.repType == 2) { - if (effsex == 0) weight = pSpecies->getDDwtFec(2 * stg + 1, 2 * effstg + 1); - else weight = pSpecies->getDDwtFec(2 * stg + 1, 2 * effstg); - } - else { - weight = pSpecies->getDDwtFec(stg, effstg); - } - effect += (float)nInds[effstg][effsex] * weight; - } - } - } - else // not stage-specific - effect = (float)totalPop(); - if (localK > 0.0) fec[stg][0] *= exp(-effect / localK); - } - } - } - } - else { // non-structured - set fecundity for adult females only - // apply any effect of environmental gradient and/or stochasticty - fec[1][0] *= envval; - if (env.stoch && !env.inK) { - // fecundity (at low density) is constrained to lie between limits specified - // for the species - float limit; - limit = pSpecies->getMinMax(0); - if (fec[1][0] < limit) fec[1][0] = limit; - limit = pSpecies->getMinMax(1); - if (fec[1][0] > limit) fec[1][0] = limit; - } - // apply density dependence - if (localK > 0.0) { - if (dem.repType == 1 || dem.repType == 2) { // sexual model - // apply factor of 2 (as in manual, eqn. 6) - fec[1][0] *= 2.0; - } - fec[1][0] /= (1.0f + fabs(dem.lambda - 1.0f) * pow(((float)ninds / localK), dem.bc)); - } - } - - double propBreed; - Individual* father; - std::vector fathers; - - switch (dem.repType) { - - case 0: // asexual model - for (int i = 0; i < ninds; i++) { - stage = inds[i]->breedingFem(); - if (stage > 0) { // female of breeding age - if (dem.stageStruct) { - // determine whether she must miss current breeding attempt - ind = inds[i]->getStats(); - if (ind.fallow >= sstruct.repInterval) { - if (pRandom->Bernoulli(sstruct.probRep)) skipbreeding = false; - else skipbreeding = true; - } - else skipbreeding = true; // cannot breed this time - } - else skipbreeding = false; // not structured - always breed - if (skipbreeding) { - inds[i]->incFallow(); - } - else { // attempt to breed - inds[i]->resetFallow(); - expected = fec[stage][0]; - if (expected <= 0.0) njuvs = 0; - else njuvs = pRandom->Poisson(expected); - nj = (int)juvs.size(); - pCell = pPatch->getRandomCell(); - for (int j = 0; j < njuvs; j++) { -#if RSDEBUG - // NOTE: CURRENTLY SETTING ALL INDIVIDUALS TO RECORD NO. OF STEPS ... - juvs.push_back(new Individual(pCell, pPatch, 0, 0, 0, 0.0, true, trfr.moveType)); -#else - juvs.push_back(new Individual(pCell, pPatch, 0, 0, 0, 0.0, trfr.moveModel, trfr.moveType)); -#endif - nInds[0][0]++; - if (emig.indVar || trfr.indVar || sett.indVar || gen.neutralMarkers) - { - // juv inherits genome from parent (mother) - juvs[nj + j]->setGenes(pSpecies, inds[i], 0, resol); - } - } - } - } - } - break; - - case 1: // simple sexual model - case 2: // complex sexual model - // count breeding females and males - // add breeding males to list of potential fathers - - nfemales = nmales = 0; - for (int i = 0; i < ninds; i++) { - ind = inds[i]->getStats(); - if (ind.sex == 0 && fec[ind.stage][0] > 0.0) nfemales++; - if (ind.sex == 1 && fec[ind.stage][1] > 0.0) { - fathers.push_back(inds[i]); - nmales++; - } - } - if (nfemales > 0 && nmales > 0) - { // population can breed - if (dem.repType == 2) { // complex sexual model - // calculate proportion of eligible females which breed - propBreed = (2.0 * dem.harem * nmales) / (nfemales + dem.harem * nmales); - if (propBreed > 1.0) propBreed = 1.0; - } - else propBreed = 1.0; - for (int i = 0; i < ninds; i++) { - stage = inds[i]->breedingFem(); - if (stage > 0 && fec[stage][0] > 0.0) { // (potential) breeding female - if (dem.stageStruct) { - // determine whether she must miss current breeding attempt - ind = inds[i]->getStats(); - if (ind.fallow >= sstruct.repInterval) { - if (pRandom->Bernoulli(sstruct.probRep)) skipbreeding = false; - else skipbreeding = true; - } - else skipbreeding = true; // cannot breed this time - } - else skipbreeding = false; // not structured - always breed - if (skipbreeding) { - inds[i]->incFallow(); - } - else { // attempt to breed - inds[i]->resetFallow(); - // NOTE: FOR COMPLEX SEXUAL MODEL, NO. OF FEMALES *ACTUALLY* BREEDING DOES NOT - // NECESSARILY EQUAL THE EXPECTED NO. FROM EQN. 7 IN THE MANUAL... - if (pRandom->Bernoulli(propBreed)) { - expected = fec[stage][0]; // breeds - } - else expected = 0.0; // fails to breed - if (expected <= 0.0) njuvs = 0; - else njuvs = pRandom->Poisson(expected); - if (njuvs > 0) - { - nj = (int)juvs.size(); - // select father at random from breeding males ... - int rrr = 0; - if (nmales > 1) rrr = pRandom->IRandom(0, nmales - 1); - father = fathers[rrr]; - pCell = pPatch->getRandomCell(); - for (int j = 0; j < njuvs; j++) { -#if RSDEBUG - // NOTE: CURRENTLY SETTING ALL INDIVIDUALS TO RECORD NO. OF STEPS ... - juvs.push_back(new Individual(pCell, pPatch, 0, 0, 0, dem.propMales, true, trfr.moveType)); -#else - juvs.push_back(new Individual(pCell, pPatch, 0, 0, 0, dem.propMales, trfr.moveModel, trfr.moveType)); -#endif - sex = juvs[nj + j]->getSex(); - nInds[0][sex]++; - if (emig.indVar || trfr.indVar || sett.indVar || gen.neutralMarkers) - { - // juv inherits genome from parents - juvs[nj + j]->setGenes(pSpecies, inds[i], father, resol); - } - } - } - } - } - } - } - fathers.clear(); - break; - - } // end of switch (dem.repType) - -// THIS MAY NOT BE CORRECT FOR MULTIPLE SPECIES IF THERE IS SOME FORM OF -// CROSS-SPECIES DENSITY-DEPENDENT FECUNDITY -} - -// Following reproduction of ALL species, add juveniles to the population prior to dispersal -void Population::fledge(void) -{ - demogrParams dem = pSpecies->getDemogr(); - - if (dem.stageStruct) { // juveniles are added to the individuals vector - inds.insert(inds.end(), juvs.begin(), juvs.end()); - } - else { // all adults die and juveniles replace adults - int ninds = (int)inds.size(); - for (int i = 0; i < ninds; i++) { - delete inds[i]; - } - inds.clear(); - for (int sex = 0; sex < nSexes; sex++) { - nInds[1][sex] = 0; // set count of adults to zero - } - inds = juvs; - } - juvs.clear(); - -} - -// Determine which individuals will disperse -void Population::emigration(float localK) -{ - int nsexes; - double disp, Pdisp, NK; - demogrParams dem = pSpecies->getDemogr(); - stageParams sstruct = pSpecies->getStage(); - emigRules emig = pSpecies->getEmig(); - emigTraits eparams; - trfrRules trfr = pSpecies->getTrfr(); - indStats ind; - -// to avoid division by zero, assume carrying capacity is at least one individual -// localK can be zero if there is a moving gradient or stochasticity in K - if (localK < 1.0) localK = 1.0; - NK = (float)totalPop() / localK; - - int ninds = (int)inds.size(); - - // set up local copy of emigration probability table - // used when there is no individual variability - // NB - IT IS DOUBTFUL THIS CONTRIBUTES ANY SUBSTANTIAL TIME SAVING - if (dem.repType == 0) nsexes = 1; else nsexes = 2; - double Pemig[NSTAGES][NSEXES]; - - for (int stg = 0; stg < sstruct.nStages; stg++) { - for (int sex = 0; sex < nsexes; sex++) { - if (emig.indVar) Pemig[stg][sex] = 0.0; - else { - if (emig.densDep) { - if (emig.sexDep) { - if (emig.stgDep) { - eparams = pSpecies->getEmigTraits(stg, sex); - } - else { - eparams = pSpecies->getEmigTraits(0, sex); - } - } - else { // !emig.sexDep - if (emig.stgDep) { - eparams = pSpecies->getEmigTraits(stg, 0); - } - else { - eparams = pSpecies->getEmigTraits(0, 0); - } - } - Pemig[stg][sex] = eparams.d0 / (1.0 + exp(-(NK - eparams.beta) * eparams.alpha)); - } - else { // density-independent - if (emig.sexDep) { - if (emig.stgDep) { - Pemig[stg][sex] = pSpecies->getEmigD0(stg, sex); - } - else { // !emig.stgDep - Pemig[stg][sex] = pSpecies->getEmigD0(0, sex); - } - } - else { // !emig.sexDep - if (emig.stgDep) { - Pemig[stg][sex] = pSpecies->getEmigD0(stg, 0); - } - else { // !emig.stgDep - Pemig[stg][sex] = pSpecies->getEmigD0(0, 0); - } - } - } - } // end of !emig.indVar - } - } - - for (int i = 0; i < ninds; i++) { - ind = inds[i]->getStats(); - if (ind.status < 1) - { - if (emig.indVar) { // individual variability in emigration - if (dem.stageStruct && ind.stage != emig.emigStage) { - // emigration may not occur - Pdisp = 0.0; - } - else { // non-structured or individual is in emigration stage - eparams = inds[i]->getEmigTraits(); - if (emig.densDep) { // density-dependent - NK = (float)totalPop() / localK; - Pdisp = eparams.d0 / (1.0 + exp(-(NK - eparams.beta) * eparams.alpha)); - } - else { // density-independent - if (emig.sexDep) { - Pdisp = Pemig[0][ind.sex] + eparams.d0; - } - else { - Pdisp = Pemig[0][0] + eparams.d0; - } - } - } - } // end of individual variability - else { // no individual variability - - if (emig.densDep) { - if (emig.sexDep) { - if (emig.stgDep) { - Pdisp = Pemig[ind.stage][ind.sex]; - } - else { - Pdisp = Pemig[0][ind.sex]; - } - } - else { // !emig.sexDep - if (emig.stgDep) { - Pdisp = Pemig[ind.stage][0]; - } - else { - Pdisp = Pemig[0][0]; - } - } - } - else { // density-independent - if (emig.sexDep) { - if (emig.stgDep) { - Pdisp = Pemig[ind.stage][ind.sex]; - } - else { // !emig.stgDep - Pdisp = Pemig[0][ind.sex]; - } - } - else { // !emig.sexDep - if (emig.stgDep) { - Pdisp = Pemig[ind.stage][0]; - } - else { // !emig.stgDep - Pdisp = Pemig[0][0]; - } - } - } - - - } // end of no individual variability - - disp = pRandom->Bernoulli(Pdisp); - - if (disp == 1) { // emigrant - inds[i]->setStatus(1); - } - } // end of if (ind.status < 1) condition - } // end of for loop -} - -// All individuals emigrate after patch destruction -void Population::allEmigrate(void) { - int ninds = (int)inds.size(); - for (int i = 0; i < ninds; i++) { - inds[i]->setStatus(1); - } -} - -// If an Individual has been identified as an emigrant, remove it from the Population -disperser Population::extractDisperser(int ix) { - disperser d; - indStats ind = inds[ix]->getStats(); - if (ind.status == 1) { // emigrant - d.pInd = inds[ix]; d.yes = true; - inds[ix] = 0; - nInds[ind.stage][ind.sex]--; - } - else { - d.pInd = NULL; d.yes = false; - } - return d; -} - -// For an individual identified as being in the matrix population: -// if it is a settler, return its new location and remove it from the current population -// otherwise, leave it in the matrix population for possible reporting before deletion -disperser Population::extractSettler(int ix) { - disperser d; - Cell* pCell; - - indStats ind = inds[ix]->getStats(); - - pCell = inds[ix]->getLocn(1); - d.pInd = inds[ix]; d.pCell = pCell; d.yes = false; - if (ind.status == 4 || ind.status == 5) { // settled - d.yes = true; - inds[ix] = 0; - nInds[ind.stage][ind.sex]--; - } - return d; -} - -// Add a specified individual to the new/current dispersal group -// Add a specified individual to the population -void Population::recruit(Individual* pInd) { - inds.push_back(pInd); - indStats ind = pInd->getStats(); - nInds[ind.stage][ind.sex]++; -} - -//--------------------------------------------------------------------------- - -// Transfer is run for populations in the matrix only -#if RS_RCPP // included also SEASONAL -int Population::transfer(Landscape* pLandscape, short landIx, short nextseason) -#else -int Population::transfer(Landscape* pLandscape, short landIx) -#endif -{ - int ndispersers = 0; - int disperser; - short othersex; - bool mateOK, densdepOK; - intptr patch, popn; - int patchnum; - double localK, popsize, settprob; - Patch* pPatch = 0; - Cell* pCell = 0; - indStats ind; - Population* pNewPopn = 0; - locn newloc, nbrloc; - - landData ppLand = pLandscape->getLandData(); - short reptype = pSpecies->getRepType(); - trfrRules trfr = pSpecies->getTrfr(); - settleType settletype = pSpecies->getSettle(); - settleRules sett; - settleTraits settDD; - settlePatch settle; - simParams sim = paramsSim->getSim(); - - // each individual takes one step - // for dispersal by kernel, this should be the only step taken - int ninds = (int)inds.size(); - for (int i = 0; i < ninds; i++) { - if (trfr.moveModel) { - disperser = inds[i]->moveStep(pLandscape, pSpecies, landIx, sim.absorbing); - } - else { - disperser = inds[i]->moveKernel(pLandscape, pSpecies, reptype, sim.absorbing); - } - ndispersers += disperser; - if (disperser) { - if (reptype > 0) - { // sexual species - record as potential settler in new patch - if (inds[i]->getStatus() == 2) - { // disperser has found a patch - pCell = inds[i]->getLocn(1); - patch = pCell->getPatch(); - if (patch != 0) { // not no-data area - pPatch = (Patch*)patch; - pPatch->incrPossSettler(pSpecies, inds[i]->getSex()); - } - } - } - } - } - -// each individual which has reached a potential patch decides whether to settle - for (int i = 0; i < ninds; i++) { - ind = inds[i]->getStats(); - if (ind.sex == 0) othersex = 1; else othersex = 0; - if (settletype.stgDep) { - if (settletype.sexDep) sett = pSpecies->getSettRules(ind.stage, ind.sex); - else sett = pSpecies->getSettRules(ind.stage, 0); - } - else { - if (settletype.sexDep) sett = pSpecies->getSettRules(0, ind.sex); - else sett = pSpecies->getSettRules(0, 0); - } - if (ind.status == 2) - { // awaiting settlement - pCell = inds[i]->getLocn(1); - if (pCell == 0) { - // this condition can occur in a patch-based model at the time of a dynamic landscape - // change when there is a range restriction in place, since a patch can straddle the - // range restriction and an individual forced to disperse upon patch removal could - // start its trajectory beyond the boundary of the restrictyed range - such a model is - // not good practice, but the condition must be handled by killing the individual conceerned - ind.status = 6; - } - else { - mateOK = false; - if (sett.findMate) { - // determine whether at least one individual of the opposite sex is present in the - // new population - if (matePresent(pCell, othersex)) mateOK = true; - } - else { // no requirement to find a mate - mateOK = true; - } - - densdepOK = false; - settle = inds[i]->getSettPatch(); - if (sett.densDep) - { - patch = pCell->getPatch(); - if (patch != 0) { // not no-data area - pPatch = (Patch*)patch; - if (settle.settleStatus == 0 - || settle.pSettPatch != pPatch) - // note: second condition allows for having moved from one patch to another - // adjacent one - { - // determine whether settlement occurs in the (new) patch - localK = (double)pPatch->getK(); - popn = pPatch->getPopn((intptr)pSpecies); - if (popn == 0) { // population has not been set up in the new patch - popsize = 0.0; - } - else { - pNewPopn = (Population*)popn; - popsize = (double)pNewPopn->totalPop(); - } - if (localK > 0.0) { - // make settlement decision - if (settletype.indVar) settDD = inds[i]->getSettTraits(); -#if RS_RCPP - else settDD = pSpecies->getSettTraits(ind.stage, ind.sex); -#else - else { - if (settletype.sexDep) { - if (settletype.stgDep) - settDD = pSpecies->getSettTraits(ind.stage, ind.sex); - else - settDD = pSpecies->getSettTraits(0, ind.sex); - } - else { - if (settletype.stgDep) - settDD = pSpecies->getSettTraits(ind.stage, 0); - else - settDD = pSpecies->getSettTraits(0, 0); - } - } -#endif //RS_RCPP - settprob = settDD.s0 / - (1.0 + exp(-(popsize / localK - (double)settDD.beta) * (double)settDD.alpha)); - - if (pRandom->Bernoulli(settprob)) { // settlement allowed - densdepOK = true; - settle.settleStatus = 2; - } - else { // settlement procluded - settle.settleStatus = 1; - } - settle.pSettPatch = pPatch; - } - inds[i]->setSettPatch(settle); - } - else { - if (settle.settleStatus == 2) { // previously allowed to settle - densdepOK = true; - } - } - } - } - else { // no density-dependent settlement - densdepOK = true; - settle.settleStatus = 2; - settle.pSettPatch = pPatch; - inds[i]->setSettPatch(settle); - } - - if (mateOK && densdepOK) { // can recruit to patch - ind.status = 4; - ndispersers--; - } - else { // does not recruit - if (trfr.moveModel) { - ind.status = 1; // continue dispersing, unless ... - // ... maximum steps has been exceeded - pathSteps steps = inds[i]->getSteps(); - settleSteps settsteps = pSpecies->getSteps(ind.stage, ind.sex); - if (steps.year >= settsteps.maxStepsYr) { - ind.status = 3; // waits until next year - } - if (steps.total >= settsteps.maxSteps) { - ind.status = 6; // dies - } - } - else { // dispersal kernel - if (sett.wait) { - ind.status = 3; // wait until next dispersal event - } - else { - ind.status = 6; // (dies unless a neighbouring cell is suitable) - } - ndispersers--; - } - } - } - - inds[i]->setStatus(ind.status); - } -#if RS_RCPP - // write each individuals current movement step and status to paths file - if (trfr.moveModel && sim.outPaths) { - if (nextseason >= sim.outStartPaths && nextseason % sim.outIntPaths == 0) { - inds[i]->outMovePath(nextseason); - } - } -#endif - - if (!trfr.moveModel && sett.go2nbrLocn && (ind.status == 3 || ind.status == 6)) - { - // for kernel-based transfer only ... - // determine whether recruitment to a neighbouring cell is possible - - pCell = inds[i]->getLocn(1); - newloc = pCell->getLocn(); - vector nbrlist; - for (int dx = -1; dx < 2; dx++) { - for (int dy = -1; dy < 2; dy++) { - if (dx != 0 || dy != 0) { //cell is not the current cell - nbrloc.x = newloc.x + dx; nbrloc.y = newloc.y + dy; - if (nbrloc.x >= 0 && nbrloc.x <= ppLand.maxX - && nbrloc.y >= 0 && nbrloc.y <= ppLand.maxY) { // within landscape - // add to list of potential neighbouring cells if suitable, etc. - pCell = pLandscape->findCell(nbrloc.x, nbrloc.y); - if (pCell != 0) { // not no-data area - patch = pCell->getPatch(); - if (patch != 0) { // not no-data area - pPatch = (Patch*)patch; - patchnum = pPatch->getPatchNum(); - if (patchnum > 0 && pPatch != inds[i]->getNatalPatch()) - { // not the matrix or natal patch - if (pPatch->getK() > 0.0) - { // suitable - if (sett.findMate) { - if (matePresent(pCell, othersex)) nbrlist.push_back(pCell); - } - else - nbrlist.push_back(pCell); - } - } - } - } - } - } - } - } - int listsize = (int)nbrlist.size(); - if (listsize > 0) { // there is at least one suitable neighbouring cell - if (listsize == 1) { - inds[i]->moveto(nbrlist[0]); - } - else { // select at random from the list - int rrr = pRandom->IRandom(0, listsize - 1); - inds[i]->moveto(nbrlist[rrr]); - } - } - // else list empty - do nothing - individual retains its current location and status - } - } - return ndispersers; -} - -// Determine whether there is a potential mate present in a patch which a potential -// settler has reached -bool Population::matePresent(Cell* pCell, short othersex) -{ - int patch; - Patch* pPatch; - Population* pNewPopn; - int popsize = 0; - bool matefound = false; - - patch = (int)pCell->getPatch(); - if (patch != 0) { - pPatch = (Patch*)pCell->getPatch(); - if (pPatch->getPatchNum() > 0) { // not the matrix patch - if (pPatch->getK() > 0.0) - { // suitable - pNewPopn = (Population*)pPatch->getPopn((intptr)pSpecies); - if (pNewPopn != 0) { - // count members of other sex already resident in the patch - for (int stg = 0; stg < nStages; stg++) { - popsize += pNewPopn->nInds[stg][othersex]; - } - } - if (popsize < 1) { - // add any potential settlers of the other sex - popsize += pPatch->getPossSettlers(pSpecies, othersex); - } - } - } - } - if (popsize > 0) matefound = true; - return matefound; -} - -//--------------------------------------------------------------------------- -// Determine survival and development and record in individual's status code -// Changes are NOT applied to the Population at this stage - -// FOR MULTIPLE SPECIES, MAY NEED TO SEPARATE OUT THIS IDENTIFICATION STAGE, -// SO THAT IT CAN BE PERFORMED FOR ALL SPECIES BEFORE ANY UPDATING OF POPULATIONS - -void Population::survival0(float localK, short option0, short option1) -{ - // option0: 0 - stage 0 (juveniles) only - // 1 - all stages - // 2 - stage 1 and above (all non-juveniles) - // option1: 0 - development only (when survival is annual) - // 1 - development and survival - // 2 - survival only (when survival is annual) - - densDepParams ddparams = pSpecies->getDensDep(); - demogrParams dem = pSpecies->getDemogr(); - stageParams sstruct = pSpecies->getStage(); - - // get surrent population size - int ninds = (int)inds.size(); - if (ninds == 0) return; - - // set up local copies of species development and survival tables - int nsexes; - if (dem.repType == 0) nsexes = 1; else nsexes = 2; - float dev[NSTAGES][NSEXES]; - float surv[NSTAGES][NSEXES]; - short minAge[NSTAGES][NSEXES]; - for (int stg = 0; stg < sstruct.nStages; stg++) { - for (int sex = 0; sex < nsexes; sex++) { - if (dem.stageStruct) { - if (dem.repType == 1) { // simple sexual model - // both sexes use development and survival recorded for females - dev[stg][sex] = pSpecies->getDev(stg, 0); - surv[stg][sex] = pSpecies->getSurv(stg, 0); - minAge[stg][sex] = pSpecies->getMinAge(stg, 0); - } - else { - dev[stg][sex] = pSpecies->getDev(stg, sex); - surv[stg][sex] = pSpecies->getSurv(stg, sex); - minAge[stg][sex] = pSpecies->getMinAge(stg, sex); - } - if (option1 == 0) surv[stg][sex] = 1.0; // development only - all survive - if (option1 == 2) dev[stg][sex] = 0.0; // survival only - none develops - } - else { // non-structured population - if (stg == 1) { // adults - dev[stg][sex] = 0.0; surv[stg][sex] = 0.0; minAge[stg][sex] = 0; - } - else { // juveniles - dev[stg][sex] = 1.0; surv[stg][sex] = 1.0; minAge[stg][sex] = 0; - } - } - } - } - - if (dem.stageStruct) { - // apply density dependence in development and/or survival probabilities - for (int stg = 0; stg < nStages; stg++) { - for (int sex = 0; sex < nsexes; sex++) { - if (option1 != 2 && sstruct.devDens && stg > 0) { -#if RSDEBUG - // DEBUGLOG << "DD in DEVELOPMENT for stg=" << stg << " sex=" << sex << endl; -#endif - // NB DD in development does NOT apply to juveniles, - // which must develop to stage 1 if they survive - float effect = 0.0; - if (sstruct.devStageDens) { // stage-specific density dependence - // NOTE: matrix entries represent effect of ROW on COLUMN - // AND males precede females - float weight = 0.0; - for (int effstg = 0; effstg < nStages; effstg++) { - for (int effsex = 0; effsex < nSexes; effsex++) { - if (dem.repType == 2) { - int rowincr, colincr; - if (effsex == 0) rowincr = 1; else rowincr = 0; - if (sex == 0) colincr = 1; else colincr = 0; - weight = pSpecies->getDDwtDev(2 * stg + colincr, 2 * effstg + rowincr); - } - else { - weight = pSpecies->getDDwtDev(stg, effstg); - } - effect += (float)nInds[effstg][effsex] * weight; - } - } - } - else // not stage-specific - effect = (float)totalPop(); - if (localK > 0.0) - dev[stg][sex] *= exp(-(ddparams.devCoeff * effect) / localK); - } // end of if (sstruct.devDens && stg > 0) - if (option1 != 0 && sstruct.survDens) { - float effect = 0.0; - if (sstruct.survStageDens) { // stage-specific density dependence - // NOTE: matrix entries represent effect of ROW on COLUMN - // AND males precede females - float weight = 0.0; - for (int effstg = 0; effstg < nStages; effstg++) { - for (int effsex = 0; effsex < nSexes; effsex++) { - if (dem.repType == 2) { - int rowincr, colincr; - if (effsex == 0) rowincr = 1; else rowincr = 0; - if (sex == 0) colincr = 1; else colincr = 0; - weight = pSpecies->getDDwtSurv(2 * stg + colincr, 2 * effstg + rowincr); - } - else { - weight = pSpecies->getDDwtSurv(stg, effstg); - } - effect += (float)nInds[effstg][effsex] * weight; - } - } - } - else // not stage-specific - effect = (float)totalPop(); - if (localK > 0.0) - surv[stg][sex] *= exp(-(ddparams.survCoeff * effect) / localK); - } // end of if (sstruct.survDens) - } - } - } - - // identify which individuals die or develop - for (int i = 0; i < ninds; i++) { - indStats ind = inds[i]->getStats(); - if ((ind.stage == 0 && option0 < 2) || (ind.stage > 0 && option0 > 0)) { - // condition for processing the stage is met... - if (ind.status < 6) { // not already doomed - double probsurv = surv[ind.stage][ind.sex]; - // does the individual survive? - if (pRandom->Bernoulli(probsurv)) { // survives - // does the individual develop? - double probdev = dev[ind.stage][ind.sex]; - if (ind.stage < nStages - 1) { // not final stage - if (ind.age >= minAge[ind.stage + 1][ind.sex]) { // old enough to enter next stage - if (pRandom->Bernoulli(probdev)) { - inds[i]->developing(); - } - } - } - } - else { // doomed to die - inds[i]->setStatus(8); - } - } - } - } -} - -// Apply survival changes to the population -void Population::survival1(void) -{ - - int ninds = (int)inds.size(); - for (int i = 0; i < ninds; i++) { - indStats ind = inds[i]->getStats(); - if (ind.status > 5) { // doomed to die - delete inds[i]; - inds[i] = NULL; - nInds[ind.stage][ind.sex]--; - } - else { - if (ind.isDeveloping) { // develops to next stage - nInds[ind.stage][ind.sex]--; - inds[i]->develop(); - nInds[ind.stage + 1][ind.sex]++; - } - } - } - -// remove pointers to dead individuals - clean(); -} - -void Population::ageIncrement(void) { - int ninds = (int)inds.size(); - stageParams sstruct = pSpecies->getStage(); - for (int i = 0; i < ninds; i++) { - inds[i]->ageIncrement(sstruct.maxAge); - } -} - -//--------------------------------------------------------------------------- -// Remove zero pointers to dead or dispersed individuals -void Population::clean(void) -{ - int ninds = (int)inds.size(); - if (ninds > 0) { - // ALTERNATIVE METHOD: AVOIDS SLOW SORTING OF POPULATION - std::vector survivors; // all surviving individuals - for (int i = 0; i < ninds; i++) { - if (inds[i] != NULL) { - survivors.push_back(inds[i]); - } - } - inds.clear(); - inds = survivors; -#if RS_RCPP - shuffle(inds.begin(), inds.end(), pRandom->getRNG()); -#else - -#if !RSDEBUG - // do not randomise individuals in RSDEBUG mode, as the function uses rand() - // and therefore the randomisation will differ between identical runs of RS - shuffle(inds.begin(), inds.end(), pRandom->getRNG()); -#endif // !RSDEBUG - -#endif // RS_RCPP - } -} - -//--------------------------------------------------------------------------- -// Open population file and write header record -bool Population::outPopHeaders(int landNr, bool patchModel) { - - if (landNr == -999) { // close file - if (outPop.is_open()) outPop.close(); - outPop.clear(); - return true; - } - - string name; - simParams sim = paramsSim->getSim(); - envGradParams grad = paramsGrad->getGradient(); - - // NEED TO REPLACE CONDITIONAL COLUMNS BASED ON ATTRIBUTES OF ONE SPECIES TO COVER - // ATTRIBUTES OF *ALL* SPECIES AS DETECTED AT MODEL LEVEL - demogrParams dem = pSpecies->getDemogr(); - stageParams sstruct = pSpecies->getStage(); - - if (sim.batchMode) { - name = paramsSim->getDir(2) - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(landNr) + "_Pop.txt"; - } - else { - name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) + "_Pop.txt"; - } - outPop.open(name.c_str()); - outPop << "Rep\tYear\tRepSeason"; - if (patchModel) outPop << "\tPatchID\tNcells"; - else outPop << "\tx\ty"; - // determine whether environmental data need be written for populations - bool writeEnv = false; - if (grad.gradient) writeEnv = true; - if (paramsStoch->envStoch()) writeEnv = true; - if (writeEnv) outPop << "\tEpsilon\tGradient\tLocal_K"; - outPop << "\tSpecies\tNInd"; - if (dem.stageStruct) { - if (dem.repType == 0) - { - for (int i = 1; i < sstruct.nStages; i++) outPop << "\tNInd_stage" << i; - outPop << "\tNJuvs"; - } - else { - for (int i = 1; i < sstruct.nStages; i++) - outPop << "\tNfemales_stage" << i << "\tNmales_stage" << i; - outPop << "\tNJuvFemales\tNJuvMales"; - } - } - else { - if (dem.repType != 0) outPop << "\tNfemales\tNmales"; - } - outPop << endl; - - return outPop.is_open(); -} - -//--------------------------------------------------------------------------- -// Write record to population file -void Population::outPopulation(int rep, int yr, int gen, float eps, - bool patchModel, bool writeEnv, bool gradK) -{ - Cell* pCell; -// NEED TO REPLACE CONDITIONAL COLUMNS BASED ON ATTRIBUTES OF ONE SPECIES TO COVER -// ATTRIBUTES OF *ALL* SPECIES AS DETECTED AT MODEL LEVEL - demogrParams dem = pSpecies->getDemogr(); - stageParams sstruct = pSpecies->getStage(); - popStats p; - - outPop << rep << "\t" << yr << "\t" << gen; - if (patchModel) { - outPop << "\t" << pPatch->getPatchNum(); - outPop << "\t" << pPatch->getNCells(); - } - else { - locn loc = pPatch->getCellLocn(0); - outPop << "\t" << loc.x << "\t" << loc.y; - } - if (writeEnv) { - if (pPatch->getPatchNum() == 0) { // matrix - outPop << "\t0\t0\t0"; - } - else { - float k = pPatch->getK(); - float envval = 0.0; - pCell = pPatch->getRandomCell(); - if (pCell != 0) envval = pCell->getEnvVal(); - outPop << "\t" << eps << "\t" << envval << "\t" << k; - } - } - outPop << "\t" << pSpecies->getSpNum(); - if (dem.stageStruct) { - p = getStats(); - outPop << "\t" << p.nNonJuvs; - // non-juvenile stage totals from permanent array - for (int stg = 1; stg < nStages; stg++) { - for (int sex = 0; sex < nSexes; sex++) { - outPop << "\t" << nInds[stg][sex]; - } - } - // juveniles from permanent array - for (int sex = 0; sex < nSexes; sex++) { - outPop << "\t" << nInds[0][sex]; - } - } - else { // non-structured population - outPop << "\t" << totalPop(); - if (dem.repType != 0) - { // sexual model - outPop << "\t" << nInds[1][0] << "\t" << nInds[1][1]; - } - } - outPop << endl; -} - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Open individuals file and write header record -void Population::outIndsHeaders(int rep, int landNr, bool patchModel) -{ - - if (landNr == -999) { // close file - if (outInds.is_open()) { - outInds.close(); outInds.clear(); - } - return; - } - - string name; - demogrParams dem = pSpecies->getDemogr(); - emigRules emig = pSpecies->getEmig(); - trfrRules trfr = pSpecies->getTrfr(); - settleType sett = pSpecies->getSettle(); - simParams sim = paramsSim->getSim(); - - if (sim.batchMode) { - name = paramsSim->getDir(2) - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) - + "_Land" + Int2Str(landNr) + "_Rep" + Int2Str(rep) + "_Inds.txt"; - } - else { - name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) - + "_Rep" + Int2Str(rep) + "_Inds.txt"; - } - outInds.open(name.c_str()); - - outInds << "Rep\tYear\tRepSeason\tSpecies\tIndID\tStatus"; - if (patchModel) outInds << "\tNatal_patch\tPatchID"; - else outInds << "\tNatal_X\tNatal_Y\tX\tY"; - if (dem.repType != 0) outInds << "\tSex"; - if (dem.stageStruct) outInds << "\tAge\tStage"; - if (emig.indVar) { - if (emig.densDep) outInds << "\tD0\tAlpha\tBeta"; - else outInds << "\tEP"; - } - if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 1) { // SMS - outInds << "\tDP\tGB\tAlphaDB\tBetaDB"; - } - if (trfr.moveType == 2) { // CRW - outInds << "\tStepLength\tRho"; - } - } - else { // kernel - outInds << "\tMeanDistI"; - if (trfr.twinKern) outInds << "\tMeanDistII\tPKernelI"; - } - } - if (sett.indVar) { - outInds << "\tS0\tAlphaS\tBetaS"; - } - outInds << "\tDistMoved"; -#if RSDEBUG - // ALWAYS WRITE NO. OF STEPS - outInds << "\tNsteps"; -#else - if (trfr.moveModel) outInds << "\tNsteps"; -#endif - outInds << endl; -} - -//--------------------------------------------------------------------------- -// Write records to individuals file -void Population::outIndividual(Landscape* pLandscape, int rep, int yr, int gen, - int patchNum) -{ - //int x, y, p_id; - bool writeInd; - pathSteps steps; - Cell* pCell; - - landParams ppLand = pLandscape->getLandParams(); - demogrParams dem = pSpecies->getDemogr(); - emigRules emig = pSpecies->getEmig(); - trfrRules trfr = pSpecies->getTrfr(); - settleType sett = pSpecies->getSettle(); - short spNum = pSpecies->getSpNum(); - - int ninds = (int)inds.size(); - - for (int i = 0; i < ninds; i++) { - indStats ind = inds[i]->getStats(); - if (yr == -1) { // write all initialised individuals - writeInd = true; - outInds << rep << "\t" << yr << "\t" << dem.repSeasons - 1; - } - else { - if (dem.stageStruct && gen < 0) { // write status 9 individuals only - if (ind.status == 9) { - writeInd = true; - outInds << rep << "\t" << yr << "\t" << dem.repSeasons - 1; - } - else writeInd = false; - } - else { - writeInd = true; - outInds << rep << "\t" << yr << "\t" << gen; - } - } - if (writeInd) { - outInds << "\t" << spNum << "\t" << inds[i]->getId(); - if (dem.stageStruct) outInds << "\t" << ind.status; - else { // non-structured population - outInds << "\t" << ind.status; - } - pCell = inds[i]->getLocn(1); - locn loc; - if (pCell == 0) loc.x = loc.y = -1; // beyond boundary or in no-data cell - else loc = pCell->getLocn(); - pCell = inds[i]->getLocn(0); - locn natalloc = pCell->getLocn(); - if (ppLand.patchModel) { - outInds << "\t" << inds[i]->getNatalPatch()->getPatchNum(); - if (loc.x == -1) outInds << "\t-1"; - else outInds << "\t" << patchNum; - } - else { // cell-based model - outInds << "\t" << (float)natalloc.x << "\t" << natalloc.y; - outInds << "\t" << (float)loc.x << "\t" << (float)loc.y; - } - if (dem.repType != 0) outInds << "\t" << ind.sex; - if (dem.stageStruct) outInds << "\t" << ind.age << "\t" << ind.stage; - - if (emig.indVar) { - emigTraits e = inds[i]->getEmigTraits(); - if (emig.densDep) { - outInds << "\t" << e.d0 << "\t" << e.alpha << "\t" << e.beta; - } - else { - outInds << "\t" << e.d0; - } - } // end of if (emig.indVar) - - if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 1) { // SMS - trfrSMSTraits s = inds[i]->getSMSTraits(); - outInds << "\t" << s.dp << "\t" << s.gb; - outInds << "\t" << s.alphaDB << "\t" << s.betaDB; - } // end of SMS - if (trfr.moveType == 2) { // CRW - trfrCRWTraits c = inds[i]->getCRWTraits(); - outInds << "\t" << c.stepLength << "\t" << c.rho; - } // end of CRW - } - else { // kernel - trfrKernTraits k = inds[i]->getKernTraits(); - if (trfr.twinKern) - { - outInds << "\t" << k.meanDist1 << "\t" << k.meanDist2 << "\t" << k.probKern1; - } - else { - outInds << "\t" << k.meanDist1; - } - } - } - - if (sett.indVar) { - settleTraits s = inds[i]->getSettTraits(); - outInds << "\t" << s.s0 << "\t" << s.alpha << "\t" << s.beta; - } - - // distance moved (metres) - if (loc.x == -1) outInds << "\t-1"; - else { - float d = ppLand.resol * sqrt((float)((natalloc.x - loc.x) * (natalloc.x - loc.x) - + (natalloc.y - loc.y) * (natalloc.y - loc.y))); - outInds << "\t" << d; - } -#if RSDEBUG - // ALWAYS WRITE NO. OF STEPS - steps = inds[i]->getSteps(); - outInds << "\t" << steps.year; -#else - if (trfr.moveModel) { - steps = inds[i]->getSteps(); - outInds << "\t" << steps.year; - } -#endif - outInds << endl; - } // end of writeInd condition - } -} - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Write records to genetics file -void Population::outGenetics(const int rep, const int year, const int landNr) -{ - - simParams sim = paramsSim->getSim(); - - if (landNr >= 0) { // open file - Genome* pGenome; - genomeData gen = pSpecies->getGenomeData(); - if (gen.trait1Chromosome) { - pGenome = new Genome(pSpecies->getNChromosomes(), pSpecies->getNLoci(0), - pSpecies->isDiploid()); - } - else { - pGenome = new Genome(pSpecies); - } - pGenome->outGenHeaders(rep, landNr, sim.outGenXtab); - delete pGenome; - return; - } - - if (landNr == -999) { // close file - Genome* pGenome = new Genome(); - pGenome->outGenHeaders(rep, landNr, sim.outGenXtab); - delete pGenome; - return; - } - - short spNum = pSpecies->getSpNum(); - short nstages = 1; - if (pSpecies->stageStructured()) { - stageParams sstruct = pSpecies->getStage(); - nstages = sstruct.nStages; - } - - int ninds = (int)inds.size(); - for (int i = 0; i < ninds; i++) { - indStats ind = inds[i]->getStats(); - if (year == 0 || sim.outGenType == 1 - || (sim.outGenType == 0 && ind.stage == 0) - || (sim.outGenType == 2 && ind.stage == nstages - 1)) { - inds[i]->outGenetics(rep, year, spNum, landNr, sim.outGenXtab); - } - } - -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - - diff --git a/src/RScore/Population.h b/src/RScore/Population.h deleted file mode 100644 index fd1fa66..0000000 --- a/src/RScore/Population.h +++ /dev/null @@ -1,245 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Population - -Implements the Population class - -There is ONE instance of a Population for each Species within each SubCommunity -(including the matrix). The Population holds a list of all the Individuals in -the Population. - -The matrix Population(s) hold(s) Individuals which are currently in the process -of transfer through the matrix. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 22 January 2022 by Steve Palmer - -------------------------------------------------------------------------------*/ - -#ifndef PopulationH -#define PopulationH - -#include -#include -using namespace std; - -#include "Parameters.h" -#include "Individual.h" -#include "Species.h" -#include "Landscape.h" -#include "Patch.h" -#include "Cell.h" - -//--------------------------------------------------------------------------- - -struct popStats { - Species *pSpecies; Patch *pPatch; int spNum,nInds,nNonJuvs,nAdults; bool breeding; -}; -struct disperser { - Individual *pInd; Cell *pCell; bool yes; -}; -struct traitsums { // sums of trait genes for dispersal - int ninds[NSEXES]; // no. of individuals - double sumD0[NSEXES]; // sum of maximum emigration probability - double ssqD0[NSEXES]; // sum of squares of maximum emigration probability - double sumAlpha[NSEXES]; // sum of slope of emigration dens-dep reaction norm - double ssqAlpha[NSEXES]; // sum of squares of slope of emigration den-dep reaction norm - double sumBeta[NSEXES]; // sum of inflection point of emigration reaction norm - double ssqBeta[NSEXES]; // sum of squares of inflection point of emigration reaction norm - double sumDist1[NSEXES]; // sum of kernel I mean - double ssqDist1[NSEXES]; // sum of squares of kernel I mean - double sumDist2[NSEXES]; // sum of kernel II mean - double ssqDist2[NSEXES]; // sum of squares of kernel II mean - double sumProp1[NSEXES]; // sum of propn using kernel I - double ssqProp1[NSEXES]; // sum of squares of propn using kernel I - double sumDP[NSEXES]; // sum of SMS directional persistence - double ssqDP[NSEXES]; // sum of squares of SMS directional persistence - double sumGB[NSEXES]; // sum of SMS goal bias - double ssqGB[NSEXES]; // sum of squares of SMS goal bias - double sumAlphaDB[NSEXES]; // sum of SMS dispersal bias decay rate - double ssqAlphaDB[NSEXES]; // sum of squares of SMS dispersal bias decay rate - double sumBetaDB[NSEXES]; // sum of SMS dispersal bias decay infl. pt. - double ssqBetaDB[NSEXES]; // sum of squares of SMS dispersal bias decay infl. pt. - double sumStepL[NSEXES]; // sum of CRW step length - double ssqStepL[NSEXES]; // sum of squares of CRW step length - double sumRho[NSEXES]; // sum of CRW correlation coefficient - double ssqRho[NSEXES]; // sum of squares of CRW correlation coefficient - double sumS0[NSEXES]; // sum of maximum settlement probability - double ssqS0[NSEXES]; // sum of squares of maximum settlement probability - double sumAlphaS[NSEXES]; // sum of slope of settlement den-dep reaction norm - double ssqAlphaS[NSEXES]; // sum of squares of slope of settlement den-dep reaction norm - double sumBetaS[NSEXES]; // sum of inflection point of settlement reaction norm - double ssqBetaS[NSEXES]; // sum of squares of inflection point of settlement reaction norm -}; - -class Population { - -public: - Population(void); // default constructor - Population( // constructor for a Population of a specified size - Species*, // pointer to Species - Patch*, // pointer to Patch - int, // no. of Individuals - int // Landscape resolution - ); - ~Population(void); - traitsums getTraits(Species*); - popStats getStats(void); - Species* getSpecies(void); - int getNInds(void); - int totalPop(void); - int stagePop( // return no. of Individuals in a specified stage - int // stage - ); - void extirpate(void); // Remove all individuals - void reproduction( - const float, // local carrying capacity - const float, // effect of environmental gradient and/or stochasticty - const int // Landscape resolution - ); - // Following reproduction of ALL species, add juveniles to the population - void fledge(void); - void emigration( // Determine which individuals will disperse - float // local carrying capacity - ); - void allEmigrate(void); // All individuals emigrate after patch destruction - // If an individual has been identified as an emigrant, remove it from the Population - disperser extractDisperser( - int // index no. to the Individual in the inds vector - ); - // For an individual identified as being in the matrix population: - // if it is a settler, return its new location and remove it from the current population - // otherwise, leave it in the matrix population for possible reporting before deletion - disperser extractSettler( - int // index no. to the Individual in the inds vector - ); - void recruit( // Add a specified individual to the population - Individual* // pointer to Individual - ); -#if RS_RCPP - int transfer( // Executed for the Population(s) in the matrix only - Landscape*, // pointer to Landscape - short, // landscape change index - short // year - ); - // Determine whether there is a potential mate present in a patch which a potential - // settler has reached - bool matePresent( - Cell*, // pointer to the Cell which the potential settler has reached - short // sex of the required mate (0 = female, 1 = male) - ); -#else - int transfer( // Executed for the Population(s) in the matrix only - Landscape*, // pointer to Landscape - short // landscape change index - ); - // Determine whether there is a potential mate present in a patch which a potential - // settler has reached - bool matePresent( - Cell*, // pointer to the Cell which the potential settler has reached - short // sex of the required mate (0 = female, 1 = male) - ); -#endif // RS_RCPP - // Determine survival and development and record in individual's status code - // Changes are NOT applied to the Population at this stage - void survival0( - float, // local carrying capacity - short, // option0: 0 - stage 0 (juveniles) only - // 1 - all stages - // 2 - stage 1 and above (all non-juveniles) - short // option1: 0 - development only (when survival is annual) - // 1 - development and survival - // 2 - survival only (when survival is annual) - ); - void survival1(void); // Apply survival changes to the population - void ageIncrement(void); - bool outPopHeaders( // Open population file and write header record - int, // Landscape number (-999 to close the file) - bool // TRUE for a patch-based model, FALSE for a cell-based model - ); - void outPopulation( // Write record to population file - int, // replicate - int, // year - int, // generation - float, // epsilon - global stochasticity value - bool, // TRUE for a patch-based model, FALSE for a cell-based model - bool, // TRUE to write environmental data - bool // TRUE if there is a gradient in carrying capacity - ); - - void outIndsHeaders( // Open individuals file and write header record - int, // replicate - int, // Landscape number (-999 to close the file) - bool // TRUE for a patch-based model, FALSE for a cell-based model - ); - void outIndividual( // Write records to individuals file - Landscape*, // pointer to Landscape - int, // replicate - int, // year - int, // generation - int // Patch number - ); - void outGenetics( // Write records to genetics file - const int, // replicate - const int, // year - const int // landscape number - ); - void clean(void); // Remove zero pointers to dead or dispersed individuals - -private: - short nStages; - short nSexes; - Species *pSpecies; // pointer to the species - Patch *pPatch; // pointer to the patch - int nInds[NSTAGES][NSEXES]; // no. of individuals in each stage/sex - - std::vector inds; // all individuals in population except ... - std::vector juvs; // ... juveniles until reproduction of ALL species - // has been completed - -}; - -//--------------------------------------------------------------------------- - -extern paramGrad *paramsGrad; -extern paramStoch *paramsStoch; -extern paramInit *paramsInit; -extern paramSim *paramsSim; -extern RSrandom *pRandom; - -#if RSDEBUG -extern ofstream DEBUGLOG; -#endif - -//--------------------------------------------------------------------------- -#endif - diff --git a/src/RScore/README.md b/src/RScore/README.md deleted file mode 100644 index 10a8386..0000000 --- a/src/RScore/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Rangeshifter core code - -This repo contains the core simulation code for RangeShifter v2.0 diff --git a/src/RScore/RSrandom.cpp b/src/RScore/RSrandom.cpp deleted file mode 100644 index 1b9f523..0000000 --- a/src/RScore/RSrandom.cpp +++ /dev/null @@ -1,283 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -#include "RSrandom.h" - -//--------------- 2.) New version of RSrandom.cpp - -#if !RS_RCPP - -#if RSDEBUG -#include "Parameters.h" -extern paramSim* paramsSim; -// ofstream RSRANDOMLOG; -#endif - -int RS_random_seed = 0; - -// C'tor -RSrandom::RSrandom() -{ -#if RSDEBUG - // fixed seed - RS_random_seed = 666; -#else - // random seed -#if LINUX_CLUSTER - std::random_device device; - RS_random_seed = device(); // old versions of g++ on Windows return a constant value within a given Windows - // session; in this case better use time stamp -#else - RS_random_seed = std::time(NULL); -#endif -#endif // RSDEBUG - -#if BATCH && RSDEBUG - DEBUGLOG << "RSrandom::RSrandom(): RS_random_seed=" << RS_random_seed << endl; -#endif // RSDEBUG - - // set up Mersenne Twister RNG - gen = new mt19937(RS_random_seed); - - // Set up standard uniform distribution - pRandom01 = new uniform_real_distribution(0.0, 1.0); - // Set up standard normal distribution - pNormal = new normal_distribution(0.0, 1.0); -} - -RSrandom::~RSrandom(void) -{ - delete gen; - if(pRandom01 != 0) - delete pRandom01; - if(pNormal != 0) - delete pNormal; -} - -mt19937 RSrandom::getRNG(void) -{ - return *gen; -} - -double RSrandom::Random(void) -{ - // return random number between 0 and 1 - return pRandom01->operator()(*gen); -} - -int RSrandom::IRandom(int min, int max) -{ - // return random integer in the interval min <= x <= max - uniform_int_distribution unif(min, max); - return unif(*gen); -} - -int RSrandom::Bernoulli(double p) -{ - if (p < 0) throw runtime_error("Bernoulli's p cannot be negative.\n"); - if (p > 1) throw runtime_error("Bernoulli's p cannot be above 1.\n"); - return Random() < p; -} - -double RSrandom::Normal(double mean, double sd) -{ - return mean + sd * pNormal->operator()(*gen); -} - -int RSrandom::Poisson(double mean) -{ - poisson_distribution poiss(mean); - return poiss(*gen); -} - - -//-------------------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------------------- - -#else // if RS_RCPP - -//--------------- 3.) R package version of RSrandom.cpp - - #if RSDEBUG - #include "Parameters.h" - extern paramSim *paramsSim; - //ofstream RSRANDOMLOG; - #endif - - std::uint32_t RS_random_seed = 0; - - // C'tor - // if parameter seed is negative, a random seed will be generated, else it is used as seed - RSrandom::RSrandom(std::int64_t seed) - { - // get seed - std::vector random_seed(3); - random_seed[0] = 1967593562; - random_seed[1] = 3271254416; - if (seed < 0) { - // random seed - #if RSWIN64 - random_seed[2] = std::time(NULL) + ( seed * (-17) ); - #else - std::random_device device; - random_seed[2] = device(); - #endif - #if BATCH && RSDEBUG - DEBUGLOG << "RSrandom::RSrandom(): Generated random seed = "; - #endif - } - else{ - // fixed seed - random_seed[2] = seed; - #if BATCH && RSDEBUG - DEBUGLOG << "RSrandom::RSrandom(): Use fixed seed = "; - #endif - } - - RS_random_seed = random_seed[2]; - #if BATCH && RSDEBUG - DEBUGLOG << RS_random_seed << endl; - #endif - - // set up Mersenne Twister random number generator with seed sequence - std::seed_seq seq(random_seed.begin(),random_seed.end()); - gen = new mt19937(seq); - - // Set up standard uniform distribution - pRandom01 = new uniform_real_distribution (0.0,1.0); - // Set up standard normal distribution - pNormal = new normal_distribution (0.0,1.0); - } - - RSrandom::~RSrandom(void) { - delete gen; - if (pRandom01 != 0) delete pRandom01; - if (pNormal != 0) delete pNormal; - } - - mt19937 RSrandom::getRNG(void) { - // return random number generator - return *gen; - } - - double RSrandom::Random(void) { - // return random number between 0 and 1 - return pRandom01->operator()(*gen); - } - - int RSrandom::IRandom(int min,int max) { - // return random integer in the interval min <= x <= max - uniform_int_distribution unif(min,max); - return unif(*gen); - } - - int RSrandom::Bernoulli(double p) { - if (p < 0) throw runtime_error("Bernoulli's p cannot be negative.\n"); - if (p > 1) throw runtime_error("Bernoulli's p cannot be above 1.\n"); - return Random() < p; - } - - double RSrandom::Normal(double mean,double sd) { - return mean + sd * pNormal->operator()(*gen); - } - - int RSrandom::Poisson(double mean) { - poisson_distribution poiss(mean); - return poiss(*gen); - } - - - /* ADDITIONAL DISTRIBUTIONS - - // Beta distribution - sample from two gamma distributions - double RSrandom::Beta(double p0,double p1) { - double g0,g1,beta; - if (p0 > 0.0 && p1 > 0.0) { // valid beta parameters - gamma_distribution gamma0(p0,1.0); - gamma_distribution gamma1(p1,1.0); - g0 = gamma0(*gen); - g1 = gamma1(*gen); - beta = g0 / (g0 + g1); - } - else { // return invalid value - beta = -666.0; - } - return beta; - } - - // Gamma distribution - double RSrandom::Gamma(double p0,double p1) { // using shape (=p0) and scale (=p1) - double p2,gamma; - if (p0 > 0.0 && p1 > 0.0) { // valid gamma parameters - p2 = 1.0 / p1; - gamma_distribution gamma0(p0,p2); // using shape/alpha (=p0) and rate/beta (=p2=1/p1) - gamma = gamma0(*gen); - } - else { // return invalid value - gamma = -666.0; - } - return gamma; - } - - // Cauchy distribution - double RSrandom::Cauchy(double loc, double scale) { - double res; - if (scale > 0.0) { // valid scale parameter - cauchy_distribution cauchy(loc,scale); - res = cauchy(*gen); - } - else { // return invalid value - res = -666.0; - } - return res; - } - - - */ - -#endif // RS_RCPP - - -#if RSDEBUG - void testRSrandom() { - - { - // Bernoulli distribution - // Abuse cases - assert_error("Bernoulli's p cannot be negative.\n", []{ - RSrandom rsr; - rsr.Bernoulli(-0.3); - }); - assert_error("Bernoulli's p cannot be above 1.\n", [] { - RSrandom rsr; - rsr.Bernoulli(1.1); - }); - // Use cases - RSrandom rsr; - assert(rsr.Bernoulli(0) == 0); - assert(rsr.Bernoulli(1) == 1); - int bern_trial = rsr.Bernoulli(0.5); - assert(bern_trial == 0 || bern_trial == 1); - } - } -#endif // RSDEBUG -//--------------------------------------------------------------------------- diff --git a/src/RScore/RSrandom.h b/src/RScore/RSrandom.h deleted file mode 100644 index 0e61c19..0000000 --- a/src/RScore/RSrandom.h +++ /dev/null @@ -1,144 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 RSrandom - -Implements the RSrandom class - -Authors: Steve Palmer, University of Aberdeen - Anne-Kathleen Malchow, Potsdam University - -Last updated: 12 January 2021 by Steve Palmer - -------------------------------------------------------------------------------*/ - -#ifndef RSrandomH -#define RSrandomH - -#include -#include -#include -#include "Utils.h" - -#if RS_RCPP -#include "../Version.h" -#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif - -using namespace std; - -#if RSDEBUG -extern ofstream DEBUGLOG; -#endif - - - -#if !RS_RCPP - -//--------------- 2.) New version of RSrandom.cpp - - - #include - #include - #if !LINUX_CLUSTER - #include - #endif - - class RSrandom - { - - public: - RSrandom(void); - ~RSrandom(void); - double Random(void); - int IRandom(int, int); - int Bernoulli(double); - double Normal(double, double); - int Poisson(double); - mt19937 getRNG(void); - - private: - mt19937* gen; - std::uniform_real_distribution<>* pRandom01; - std::normal_distribution<>* pNormal; - }; - - -//-------------------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------------------- - - - -//--------------- 3.) R package version of RSrandom.cpp - - -#else // if RS_RCPP - - - #include - #include - #if RSWIN64 - #include - #endif - - class RSrandom { - - public: - RSrandom(std::int64_t); // if int is negative, a random seed will be generated, else it is used as seed - ~RSrandom(void); - mt19937 getRNG(void); - double Random(void); - int IRandom(int,int); - int Bernoulli(double); - double Normal(double,double); - int Poisson(double); - /* ADDITIONAL DISTRIBUTIONS - double Beta(double,double); - double Gamma(double,double); // !! make sure correct definition is used: using shape and scale (as defined here) OR using shape/alpha and rate/beta (=1/scale) - double Cauchy(double,double); - */ - - private: - mt19937 *gen; - std::uniform_real_distribution<> *pRandom01; - std::normal_distribution<> *pNormal; - }; - - - -#endif // !RS_RCPP - -#if RSDEBUG - void testRSrandom(); -#endif // RSDEBUG - -//--------------------------------------------------------------------------- - -#endif // RSrandomH - - - diff --git a/src/RScore/RandomCheck.cpp b/src/RScore/RandomCheck.cpp deleted file mode 100644 index e18aeaa..0000000 --- a/src/RScore/RandomCheck.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "RandomCheck.h" -//--------------------------------------------------------------------------- - -ifstream inRandom; -ofstream outRandom; -ofstream outBernoulli; -ofstream outNormal; -ofstream outPoisson; -ofstream outIRandom; - -void randomCheck(void) -{ - -int samplesize,irandMin,irandMax; -double bernMean,normMean,normSD,poisMean; -string name,header; -simParams sim = paramsSim->getSim(); - - name = paramsSim->getDir(1) + "RandomCheck.txt"; - inRandom.open(name.c_str()); - if (!inRandom.is_open()) { - #if !RS_RCPP - cout << endl << "***** Error opening input file RandomCheck.txt" << endl; - #endif - inRandom.clear(); - return; - } - for (int i = 0; i < 7; i++) { - inRandom >> header; - } - inRandom >> samplesize >> bernMean >> normMean >> normSD >> poisMean >> irandMin >> irandMax; - - name = paramsSim->getDir(2) + "Random.txt"; - outRandom.open(name.c_str()); - name = paramsSim->getDir(2) + "Bernoulli.txt"; - outBernoulli.open(name.c_str()); - name = paramsSim->getDir(2) + "Normal.txt"; - outNormal.open(name.c_str()); - name = paramsSim->getDir(2) + "Poisson.txt"; - outPoisson.open(name.c_str()); - name = paramsSim->getDir(2) + "IRandom.txt"; - outIRandom.open(name.c_str()); - - for (int i = 0; i < samplesize; i++) { - outRandom << pRandom->Random() << endl; - outBernoulli << pRandom->Bernoulli(bernMean) << endl; - outNormal << pRandom->Normal(normMean,normSD) << endl; - outPoisson << pRandom->Poisson(poisMean) << endl; - outIRandom << pRandom->IRandom(irandMin,irandMax) << endl; - } - - inRandom.close(); - inRandom.clear(); - outRandom.close(); - outRandom.clear(); - outBernoulli.close(); - outBernoulli.clear(); - outNormal.close(); - outNormal.clear(); - outPoisson.close(); - outPoisson.clear(); - outIRandom.close(); - outIRandom.clear(); - -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- diff --git a/src/RScore/RandomCheck.h b/src/RScore/RandomCheck.h deleted file mode 100644 index 45c6b82..0000000 --- a/src/RScore/RandomCheck.h +++ /dev/null @@ -1,47 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#ifndef RandomCheckH -#define RandomCheckH - -#include -using namespace std; - -#if RS_RCPP -#include "../Version.h" -#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif -#include "Parameters.h" -#include "RSrandom.h" - -void randomCheck(void); - -extern paramSim *paramsSim; -extern RSrandom *pRandom; - -//--------------------------------------------------------------------------- -#endif diff --git a/src/RScore/Species.cpp b/src/RScore/Species.cpp deleted file mode 100644 index 727e3c3..0000000 --- a/src/RScore/Species.cpp +++ /dev/null @@ -1,1455 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "Species.h" -//--------------------------------------------------------------------------- - -Species::Species(void) -{ -// initialise demographic parameters -repType = 0; nStages = 2; -stageStruct = false; -propMales = 0.5; harem = 1.0; bc = 1.0; lambda = 1.5; probRep = 1.0; -repSeasons = 1; -repInterval = 0; maxAge = 1000; survival = 1; -fecDens = false; fecStageDens = false; -devDens = false; devStageDens = false; -survDens = false; survStageDens = false; -disperseOnLoss = false; -for (int i = 0; i < NSTAGES; i++) { - for (int j = 0; j < NSEXES; j++) { - fec[i][j] = 0.0; dev[i][j] = 0.0; surv[i][j] = 0.0; - minAge[i][j] = 0; - } -} -devCoeff = survCoeff = 1.0; -ddwtFec = ddwtDev = ddwtSurv = 0; ddwtFecDim = ddwtDevDim = ddwtSurvDim = 0; -habK = 0; habDimK = 0; -minRK = 1.0; maxRK = 2.0; - -// initialise genome attributes -nChromosomes = nTraits = 0; -emigTrait[0] = 0; emigTrait[1] = 0; -movtTrait[0] = 0; movtTrait[1] = 0; -settTrait[0] = 0; settTrait[1] = 0; -//genomeCanRecombine = false; -diploid = true; -neutralMarkers = false; -pleiotropic = false; -trait1Chromosome = true; -probMutn = 0.0001f; -probCrossover = 0.0001f; -alleleSD = mutationSD = 0.1f; -nNLoci = 0; -nLoci = NULL; -traitdata = NULL; -traitnames = NULL; -nTraitNames = 0; - -// initialise emigration parameters -densDepEmig = false; stgDepEmig = false; sexDepEmig = false; indVarEmig = false; -emigStage = 0; -for (int i = 0; i < NSTAGES; i++) { - for (int j = 0; j < NSEXES; j++) { - d0[i][j] = 0.0; alphaEmig[i][j] = 0.0; betaEmig[i][j] = 1.0; - } -} -for (int j = 0; j < NSEXES; j++) { - d0Mean[0][j] = 0.0; alphaMean[0][j] = 0.0; betaMean[0][j] = 1.0; - d0SD[0][j] = 0.0; alphaSD[0][j] = 0.0; betaSD[0][j] = 1.0; -} -d0Scale = alphaScale = betaScale = 0.0; - -// initialise transfer parameters -moveModel = false; stgDepTrfr = false; sexDepTrfr = false; distMort = false; -indVarTrfr = false; -twinKern = false; -habMort = false; -costMap = false; -moveType = 1; -for (int i = 0; i < NSTAGES; i++) { - for (int j = 0; j < NSEXES; j++) { - meanDist1[i][j] = 100.0f; meanDist2[i][j] = 1000.0f; probKern1[i][j] = 0.99f; - } -} -for (int j = 0; j < NSEXES; j++) { - dist1Mean[0][j] = 100.0; dist1SD[0][j] = 10.0; - dist2Mean[0][j] = 1000.0; dist2SD[0][j] = 100.0; - PKern1Mean[0][j] = 0.9f; PKern1SD[0][j] = 0.01f; - stepLgthMean[0][j] = 10.0; stepLgthSD[0][j] = 1.0; - rhoMean[0][j] = 0.9f; rhoSD[0][j] = 0.01f; - dpMean[0][j] = 1.0; dpSD[0][j] = 0.1f; - gbMean[0][j] = 1.0; gbSD[0][j] = 0.1f; - alphaDBMean[0][j] = 1.0; alphaDBSD[0][j] = 0.1f; - betaDBMean[0][j] = 10.0; betaDBSD[0][j] = 1.0; -} -pr = 1; prMethod = 1; memSize = 1; goalType = 0; -dp = 1.0; gb = 1.0; alphaDB = 1.0; betaDB = 100000; -stepMort = 0.0; stepLength = 10.0; rho = 0.9f; -habStepMort = 0; habCost = 0; -//costMapFile = "NULL"; -fixedMort = 0.0; mortAlpha = 0.0; mortBeta = 1.0; -dist1Scale = dist2Scale = PKern1Scale = stepLScale = rhoScale = 0.0; -dpScale = 0.1f; gbScale = 0.1f; alphaDBScale = 0.1f; betaDBScale = 1.0; -habDimTrfr = 0; -straigtenPath = false; -fullKernel = false; - -// initialise settlement parameters -stgDepSett = false; sexDepSett = false; indVarSett = false; -minSteps = 0; maxSteps = 99999999; -for (int i = 0; i < NSTAGES; i++) { - for (int j = 0; j < NSEXES; j++) { - densDepSett[i][j] = false; wait[i][j] = false; go2nbrLocn[i][j] = false; findMate[i][j] = false; - maxStepsYr[i][j] = 99999999; - s0[i][j] = 1.0; alphaS[i][j] = 0.0; betaS[i][j] = 1.0; - } -} -for (int j = 0; j < NSEXES; j++) { - alphaSMean[0][j] = 0.0; alphaSSD[0][j] = 0.0; - betaSMean[0][j] = 0.0; betaSSD[0][j] = 0.0; - s0Mean[0][j] = 0.0; s0SD[0][j] = 0.0; -} -alphaSScale = 0.0; betaSScale = 0.0; s0Scale = 0.0; - -// initialise attributes -spNum = 0; - -} - -Species::~Species() { -// demographic parameters -if (habK != NULL) deleteHabK(); -if (ddwtFec != 0) deleteDDwtFec(); -if (ddwtDev != 0) deleteDDwtDev(); -if (ddwtSurv != 0) deleteDDwtSurv(); -// transfer parameters -if (habCost != 0 || habStepMort != 0) deleteHabCostMort(); -if (nLoci != NULL) deleteLoci(); -if (traitdata != NULL) deleteTraitData(); -if (traitnames != NULL) deleteTraitNames(); -} - -short Species::getSpNum(void) { return spNum; } - -//--------------------------------------------------------------------------- - -// Demographic functions - -void Species::setDemogr(const demogrParams d) { -if (d.repType >= 0 && d.repType <= 2) repType = d.repType; -if (d.repSeasons >= 1) repSeasons = d.repSeasons; -stageStruct = d.stageStruct; -if (d.propMales > 0.0 && d.propMales < 1.0) propMales = d.propMales; -if (d.harem > 0.0) harem = d.harem; -if (d.bc > 0.0) bc = d.bc; -if (d.lambda > 0.0) lambda = d.lambda; -} - -demogrParams Species::getDemogr(void) { -demogrParams d; -d.repType = repType; -d.repSeasons = repSeasons; -d.stageStruct = stageStruct; -d.propMales = propMales; -d.harem = harem; -d.bc = bc; -d.lambda = lambda; -return d; -} - -short Species::getRepType(void) { return repType; } - -bool Species::stageStructured(void) { return stageStruct; } - -void Species::createHabK(short nhab) { -if (nhab >= 0) { - habDimK = nhab; - if (habK != 0) deleteHabK(); - habK = new float[nhab]; - for (int i = 0; i < nhab; i++) habK[i] = 0.0; -} -} - -void Species::setHabK(short hx,float k) { -if (hx >= 0 && hx < habDimK) { - if (k >= 0.0) habK[hx] = k; -} -} - -float Species::getHabK(short hx) { -float k = 0.0; -if (hx >= 0 && hx < habDimK) k = habK[hx]; -return k; -} - -float Species::getMaxK(void) { -float k = 0.0; -for (int i = 0; i < habDimK; i++) { - if (habK[i] > k) k = habK[i]; -} -return k; -} - -void Species::deleteHabK(void) { -if (habK != 0) { - delete[] habK; habK = 0; -} -} - -void Species::setStage(const stageParams s) { -if (s.nStages > 1) nStages = s.nStages; -if (s.repInterval >= 0) repInterval = s.repInterval; -if (s.maxAge >= 1) maxAge = s.maxAge; -if (s.survival >= 0 && s.survival <= 2) survival = s.survival; -if (s.probRep > 0.0 && s.probRep <= 1.0) probRep = s.probRep; -fecDens = s.fecDens; fecStageDens = s.fecStageDens; -devDens = s.devDens; devStageDens = s.devStageDens; -survDens = s.survDens; survStageDens = s.survStageDens; -disperseOnLoss = s.disperseOnLoss; -} - -stageParams Species::getStage(void) { -stageParams s; -s.nStages = nStages; s.repInterval = repInterval; s.maxAge = maxAge; -s.survival = survival; s.probRep = probRep; -s.fecDens = fecDens; s.fecStageDens = fecStageDens; -s.devDens = devDens; s.devStageDens = devStageDens; -s.survDens = survDens; s.survStageDens = survStageDens; -s.disperseOnLoss = disperseOnLoss; -return s; -} - -void Species::setFec(short stg,short sex,float f) { -// NB fecundity for stage 0 must always be zero -if (stg > 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES && f >= 0) - fec[stg][sex] = f; -} - -float Species::getFec(short stg,short sex) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) - return fec[stg][sex]; -else return 0.0; -} - -float Species::getMaxFec(void) { -float maxfec = 0.0; -if (stageStruct) { - for (int stg = 1; stg < NSTAGES; stg++) { - if (fec[stg][0] > maxfec) maxfec = fec[stg][0]; - } -} -else maxfec = lambda; -return maxfec; -} - -void Species::setDev(short stg,short sex,float d) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES && d >= 0) - dev[stg][sex] = d; -} - -float Species::getDev(short stg,short sex) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) - return dev[stg][sex]; -else return 0.0; -} - -void Species::setSurv(short stg,short sex,float s) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES && s >= 0) - surv[stg][sex] = s; -} - -float Species::getSurv(short stg,short sex) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) - return surv[stg][sex]; -else return 0.0; -} - -void Species::setMinAge(short stg,short sex,int age) { -// NB min age for stages 0 & 1 must always be zero -if (stg > 1 && stg < NSTAGES && sex >= 0 && sex < NSEXES && age >= 0) - minAge[stg][sex] = age; -} - -short Species::getMinAge(short stg,short sex) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) - return minAge[stg][sex]; -else return 0; -} - -void Species::setDensDep(float d, float s) { -if (d > 0.0) devCoeff = d; -if (s > 0.0) survCoeff = s; -} - -densDepParams Species::getDensDep(void) { -densDepParams d; -d.devCoeff = devCoeff; d.survCoeff = survCoeff; -return d; -} - -void Species::createDDwtFec(short mSize) { -if (mSize >= 0 && mSize < (NSTAGES * NSEXES)) { - if (ddwtFec != 0) deleteDDwtFec(); - ddwtFecDim = mSize; - ddwtFec = new float *[mSize]; - for (int i = 0; i < mSize; i++) { - ddwtFec[i] = new float[mSize]; - for (int j = 0; j < mSize; j++) ddwtFec[i][j] = 1.0; - } -} -} - -void Species::setDDwtFec(short row,short col,float f) { -if (row >= 0 && row < ddwtFecDim && col >= 0 && col < ddwtFecDim) - ddwtFec[row][col] = f; -} - -float Species::getDDwtFec(short row,short col) { -if (row >= 0 && row < ddwtFecDim && col >= 0 && col < ddwtFecDim) - return ddwtFec[row][col]; -else return 0.0; -} - -void Species::deleteDDwtFec(void) { -if (ddwtFec != 0) { - for (int i = 0; i < ddwtFecDim; i++) if (ddwtFec[i] != 0) { - delete[] ddwtFec[i]; - } - delete[] ddwtFec; ddwtFec = 0; -} -} - -void Species::createDDwtDev(short mSize) { -if (mSize >= 0 && mSize < (NSTAGES * NSEXES)) { - if (ddwtDev != 0) deleteDDwtDev(); - ddwtDevDim = mSize; - ddwtDev = new float *[mSize]; - for (int i = 0; i < mSize; i++) { - ddwtDev[i] = new float[mSize]; - for (int j = 0; j < mSize; j++) ddwtDev[i][j] = 1.0; - } -} -} - -void Species::setDDwtDev(short row,short col,float f) { -if (row >= 0 && row < ddwtDevDim && col >= 0 && col < ddwtDevDim) - ddwtDev[row][col] = f; -} - -float Species::getDDwtDev(short row,short col) { -if (row >= 0 && row < ddwtDevDim && col >= 0 && col < ddwtDevDim) - return ddwtDev[row][col]; -else return 0.0; -} - -void Species::deleteDDwtDev(void) { -if (ddwtDev != 0) { - for (int i = 0; i < ddwtDevDim; i++) if (ddwtDev[i] != 0) { - delete[] ddwtDev[i]; - } - delete[] ddwtDev; ddwtDev = 0; -} -} - -void Species::createDDwtSurv(short mSize) { -if (mSize >= 0 && mSize < (NSTAGES * NSEXES)) { - if (ddwtSurv != 0) deleteDDwtSurv(); - ddwtSurvDim = mSize; - ddwtSurv = new float *[mSize]; - for (int i = 0; i < mSize; i++) { - ddwtSurv[i] = new float[mSize] ; - for (int j = 0; j < mSize; j++) ddwtSurv[i][j] = 1.0; - } -} -} - -void Species::setDDwtSurv(short row,short col, float f) { -if (row >= 0 && row < ddwtSurvDim && col >= 0 && col < ddwtSurvDim) - ddwtSurv[row][col] = f; -} - -float Species::getDDwtSurv(short row,short col) { -if (row >= 0 && row < ddwtSurvDim && col >= 0 && col < ddwtSurvDim) - return ddwtSurv[row][col]; -else return 0.0; -} - -void Species::deleteDDwtSurv(void) { -if (ddwtSurv != 0) { - for (int i = 0; i < ddwtSurvDim; i++) if (ddwtSurv[i] != 0) { - delete[] ddwtSurv[i]; - } - delete[] ddwtSurv; ddwtSurv = 0; -} -} - -// Functions to handle min/max R or K (under environmental stochasticity) -//void Species::setMinMax(float min,float max) { -void Species::setMinMax(float min, float max) { -if (min >= 0.0 && max > min) { - minRK = min; maxRK = max; -} -} -float Species::getMinMax(short opt) { -if (opt == 0) return minRK; -else return maxRK; -} - -//--------------------------------------------------------------------------- - -// Genome functions - -void Species::setGenomeData(genomeData d) { -diploid = d.diploid; -neutralMarkers = d.neutralMarkers; -trait1Chromosome = d.trait1Chromosome; -if (trait1Chromosome) { - if (d.nLoci > 0) nLoci[0] = d.nLoci; -} -if (d.probMutn >= 0.0 && d.probMutn <= 1.0) probMutn = d.probMutn; -if (d.probCrossover >= 0.0 && d.probCrossover <= 1.0) probCrossover = d.probCrossover; -if (d.alleleSD > 0.0) alleleSD = d.alleleSD; -if (d.mutationSD > 0.0) mutationSD = d.mutationSD; -} - -genomeData Species::getGenomeData(void) { -genomeData d; -d.diploid = diploid; -d.neutralMarkers = neutralMarkers; -d.pleiotropic = pleiotropic; -d.trait1Chromosome = trait1Chromosome; -if (nLoci != NULL) d.nLoci = nLoci[0]; -else d.nLoci = 0; -d.probMutn = probMutn; -d.probCrossover = probCrossover; -d.alleleSD = alleleSD; -d.mutationSD = mutationSD; -return d; -} - -bool Species::isDiploid(void) { return diploid; } - -// Chromosome functions - -void Species::setNChromosomes(int c) { -if (nLoci != NULL) deleteLoci(); -if (c > 0) { - nChromosomes = nNLoci = c; - nLoci = new short [c]; - for (int i = 0; i < nNLoci; i++) nLoci[i] = 0; -} -else nChromosomes = nNLoci = 0; -} - -int Species::getNChromosomes(void) { return nChromosomes; } - -void Species::setNLoci(const short chr,const short nloc) { -if (chr >= 0 && chr < nNLoci) { - if (nloc > 0) nLoci[chr] = nloc; - else nLoci[chr] = 0; -} -} - -int Species::getNLoci(const short chr) { -if (chr >= 0 && chr < nChromosomes) return nLoci[chr]; -else return 0; -} - -void Species::deleteLoci(void) { -if (nLoci != NULL) { delete[] nLoci; nLoci = NULL; } -} - -// Trait functions - -// Set 1:1 mapping of trait to chromosome -void Species::set1ChromPerTrait(const int nloc) { -nChromosomes = nTraits; -if (nLoci != NULL) deleteLoci(); -nLoci = new short [1]; -if (nloc > 0) nLoci[0] = nloc; -else nLoci[0] = 1; -} - -bool Species::has1ChromPerTrait(void) { return trait1Chromosome; } - -// Set trait attributes for the species -void Species::setTraits(void) { - -emigTrait[0] = 0; emigTrait[1] = 0; -movtTrait[0] = 0; movtTrait[1] = 0; -settTrait[0] = 0; settTrait[1] = 0; -nTraits = 0; -#if RSDEBUG -DebugGUI("Species::setTraits(): 0000 nChromosomes=" + Int2Str(nChromosomes) - + " nTraits=" + Int2Str(nTraits) - + " indVarEmig=" + Int2Str((int)indVarEmig) - + " indVarTrfr=" + Int2Str((int)indVarTrfr) - + " indVarSett=" + Int2Str((int)indVarSett) - ); -#endif - -if (indVarEmig) { - if (sexDepEmig) { - if (densDepEmig) nTraits += 6; else nTraits += 2; - } - else { - if (densDepEmig) nTraits += 3; else nTraits += 1; - } - emigTrait[0] = 0; emigTrait[1] = nTraits; -} -#if RSDEBUG -//DebugGUI("Species::setTraits(): 1111 nTraits=" + Int2Str(nTraits)); -#endif - -int movttraits = 0; -if (indVarTrfr) { - if (moveModel) { - if (moveType == 1) { // SMS - movttraits = 1; // in contain batch 2 - if (goalType == 2) movttraits += 3; //in contain batch 2 - } - if (moveType == 2) movttraits = 2; - } - else { - if (sexDepTrfr) { - if (twinKern) movttraits = 6; else movttraits = 2; - } - else { - if (twinKern) movttraits = 3; else movttraits = 1; - } - } - movtTrait[0] = nTraits; movtTrait[1] = movttraits; - nTraits += movttraits; -} -#if RSDEBUG -//DebugGUI("Species::setTraits(): 2222 nTraits=" + Int2Str(nTraits)); -#endif - -int setttraits = 0; -if (indVarSett) { - if (sexDepSett) setttraits = 6; else setttraits = 3; - settTrait[0] = nTraits; settTrait[1] = setttraits; - nTraits += setttraits; -} - -setTraitNames(); - -//if (trait1Chromosome) { -// nChromosomes = nTraits; -//} -#if RSDEBUG -DebugGUI("Species::setTraits(): 9999 nChromosomes=" + Int2Str(nChromosomes) - + " nTraits=" + Int2Str(nTraits)); -#endif - -} - -void Species::setTraitNames(void) { -#if RSDEBUG -//DebugGUI("Species::setTraitNames(): nTraits=" + Int2Str(nTraits) -// + " nTraitNames=" + Int2Str(nTraitNames) -// + " traitnames=" + Int2Str((int)traitnames) -// ); -//if (traitnames != NULL) { -// DebugGUI("Species::setTraitNames(): traitnames[0]=" + traitnames[0] -// ); -// if (nTraits > 1) { -// DebugGUI("Species::setTraitNames(): traitnames[1]=" + traitnames[1] -// ); -// } -//} -#endif -deleteTraitNames(); -nTraitNames = nTraits; -traitnames = new string [nTraitNames]; -int trait = 0; -if (indVarEmig) { - if (sexDepEmig) { - if (densDepEmig) { - traitnames[trait++] = "d0_F"; - traitnames[trait++] = "d0_M"; - traitnames[trait++] = "alpha_F"; - traitnames[trait++] = "alpha_M"; - traitnames[trait++] = "beta_F"; - traitnames[trait++] = "beta_M"; - } - else { - traitnames[trait++] = "d0_F"; - traitnames[trait++] = "d0_M"; - } - } - else { - traitnames[trait++] = "d0"; - if (densDepEmig) { - traitnames[trait++] = "alpha"; - traitnames[trait++] = "beta"; - } - } -} - -if (indVarTrfr) { - if (moveModel) { - if (moveType == 1) { // SMS - traitnames[trait++] = "DP"; - if (goalType == 2) { - traitnames[trait++] = "GB"; - traitnames[trait++] = "alphaDB"; - traitnames[trait++] = "betaDB"; - } - } - if (moveType == 2) { // CRW - traitnames[trait++] = "stepL"; - traitnames[trait++] = "rho"; - } - } - else { - if (sexDepTrfr) { - if (twinKern) - { - traitnames[trait++] = "meanDistI_F"; - traitnames[trait++] = "meanDistI_M"; - traitnames[trait++] = "meanDistII_F"; - traitnames[trait++] = "meanDistII_M"; - traitnames[trait++] = "probKernI_F"; - traitnames[trait++] = "probKernI_M"; - } - else { - traitnames[trait++] = "meanDistI_F"; - traitnames[trait++] = "meanDistI_M"; - } - } - else { - traitnames[trait++] = "meanDistI"; - if (twinKern) - { - traitnames[trait++] = "meanDistII"; - traitnames[trait++] = "probKernI"; - } - } - } -} - -if (indVarSett) { - if (sexDepSett) { - traitnames[trait++] = "s0_F"; - traitnames[trait++] = "s0_M"; - traitnames[trait++] = "alphaS_F"; - traitnames[trait++] = "alphaS_M"; - traitnames[trait++] = "betaS_F"; - traitnames[trait++] = "betaS_M"; - } - else { - traitnames[trait++] = "s0"; - traitnames[trait++] = "alphaS"; - traitnames[trait++] = "betaS"; - } -} -} - -void Species::deleteTraitNames(void) { -if (traitnames != NULL) { -#if RSDEBUG -//DebugGUI("Species::deleteTraitNames(): traitnames=" + Int2Str((int)traitnames) -// ); -#endif - delete[] traitnames; - traitnames = NULL; -} -} - -string Species::getTraitName(const int trait) { -string name = "not used"; -if (traitnames != NULL) { - if (trait >= 0 && trait < nTraits) { - name = traitnames[trait]; - } -} -return name; -} - -int Species::getNTraits(void) { return nTraits; } - -void Species::setTraitData(const int ntraits) { -#if RSDEBUG -//DebugGUI(("Species::setTraitData(): traitdata=" + Int2Str((int)traitdata) -// + " ntraits=" + Int2Str(ntraits) -// ).c_str()); -#endif -deleteTraitData(); -traitdata = new traitData; -if (ntraits > 0) { - traitdata->nTraitMaps = ntraits; - traitdata->traitmaps = new traitMap *[ntraits]; - for (int i = 0; i < ntraits; i++) { - traitdata->traitmaps[i] = new traitMap; - } -} -else { // neutral markers only - traitdata->nTraitMaps = 0; -} -traitdata->neutralloci = new traitMap; -traitdata->neutralloci->nAlleles = 0; -#if RSDEBUG -//DebugGUI(("Species::setTraitData(): traitdata=" + Int2Str((int)traitdata) -// + " nTraitMaps=" + Int2Str(traitdata->nTraitMaps) -// ).c_str()); -#endif -} - -void Species::deleteTraitData(void) { -if (traitdata != NULL) { -#if RSDEBUG -//DebugGUI(("Species::deleteTraitData(): traitdata=" + Int2Str((int)traitdata) -// + " nTraitMaps=" + Int2Str(traitdata->nTraitMaps) -// ).c_str()); -#endif - for (int i = 0; i < traitdata->nTraitMaps; i++) { - if (traitdata->traitmaps[i]->traitalleles != 0) { - for (int j = 0; j < traitdata->traitmaps[i]->nAlleles; j++) { - delete traitdata->traitmaps[i]->traitalleles[j]; - } - } - delete[] traitdata->traitmaps[i]; - } - deleteNeutralLoci(); - delete traitdata; - traitdata = NULL; -} -} - -int Species::getNTraitMaps(void) { -if (traitdata == NULL) return 0; -else return traitdata->nTraitMaps; -} - -void Species::setTraitMap(const short trait,const short nalleles) { -traitdata->traitmaps[trait]->nAlleles = nalleles; -traitdata->traitmaps[trait]->traitalleles = new traitAllele *[nalleles]; -for (int i = 0; i < nalleles; i++) { - traitdata->traitmaps[trait]->traitalleles[i] = new traitAllele; -} -} - -int Species::getNTraitAlleles(const int trait) { -int nalleles = 0; -if (traitdata != NULL) { - if (trait >= 0 && trait < traitdata->nTraitMaps) { - nalleles = traitdata->traitmaps[trait]->nAlleles; - } -} -return nalleles; -} - -void Species::setTraitAllele(const short trait,const short allele, - const short chr,const short loc) -{ -traitdata->traitmaps[trait]->traitalleles[allele] = new traitAllele; -if (chr >= 0 && loc >= 0) { - traitdata->traitmaps[trait]->traitalleles[allele]->chromo = chr; - traitdata->traitmaps[trait]->traitalleles[allele]->locus = loc; -} -else { - traitdata->traitmaps[trait]->traitalleles[allele]->chromo = 0; - traitdata->traitmaps[trait]->traitalleles[allele]->locus = 0; -} -} - -traitAllele Species::getTraitAllele(const short trait,const short allele) { -traitAllele a; a.chromo = 0; a.locus = 0; -if (traitdata != NULL) { - if (trait >= 0 && trait < traitdata->nTraitMaps) { - if (allele >= 0 && allele < traitdata->traitmaps[trait]->nAlleles) { - a = *traitdata->traitmaps[trait]->traitalleles[allele]; - } - } -} -return a; -} - -// Neutral loci functions - -// Identify neutral loci and determine whether there is pleiotropy -void Species::setNeutralLoci(bool neutralMarkersOnly) { -bool neutral; -int nneutral = 0; -// find minimum of no. of defined / applied traits -int ntraits; -if (traitdata == 0 ) ntraits = 0; -else ntraits = traitdata->nTraitMaps; -if (ntraits > nTraits) ntraits = nTraits; -#if RSDEBUG -//DebugGUI("Species::setNeutralLoci(): neutralMarkersOnly=" + Int2Str((int)neutralMarkersOnly) -// + " nNLoci=" + Int2Str(nNLoci) -// + " nTraits=" + Int2Str(nTraits) + " ntraits=" + Int2Str(ntraits) -//); -#endif - -// determine no. of neutral loci -deleteNeutralLoci(); -for (int i = 0; i < nNLoci; i++) { // each chromosome - for (int j = 0; j < nLoci[i]; j++) { // each locus - neutral = true; - for (int t = 0; t < ntraits; t++) { // each trait - for (int a = 0; a < traitdata->traitmaps[t]->nAlleles; a++) { -#if RSDEBUG -//DebugGUI("Species::setNeutralLoci(): i=" + Int2Str(i) -// + " j=" + Int2Str(j) + " t=" + Int2Str(t) + " a=" + Int2Str(a) -// + " chromo=" + Int2Str(traitdata->traitmaps[t]->traitalleles[a]->chromo) -// + " locus=" + Int2Str(traitdata->traitmaps[t]->traitalleles[a]->locus) -//); -#endif - if (i == traitdata->traitmaps[t]->traitalleles[a]->chromo - && j == traitdata->traitmaps[t]->traitalleles[a]->locus) { -#if RSDEBUG -//DebugGUI("Species::setNeutralLoci(): FALSE"); -#endif - neutral = false; // as locus contributes to a trait - a = 999999; - } - } - if (!neutral) t = 999999; - } - if (neutral) nneutral++; - } -} - -traitdata->neutralloci = new traitMap; -traitdata->neutralloci->nAlleles = nneutral; -if (nneutral < 1) return; - -// record neutral markers -traitdata->neutralloci->traitalleles = new traitAllele *[nneutral]; -nneutral = 0; -for (int i = 0; i < nNLoci; i++) { // each chromosome - for (int j = 0; j < nLoci[i]; j++) { // each locus - neutral = true; - for (int t = 0; t < ntraits; t++) { // each trait - for (int a = 0; a < traitdata->traitmaps[t]->nAlleles; a++) { - if (i == traitdata->traitmaps[t]->traitalleles[a]->chromo - && j == traitdata->traitmaps[t]->traitalleles[a]->locus) { - neutral = false; // as locus contributes to a trait - a = 999999; - } - } - if (!neutral) t = 999999; - } - if (neutral) { - traitdata->neutralloci->traitalleles[nneutral] = new traitAllele; - traitdata->neutralloci->traitalleles[nneutral]->chromo = i; - traitdata->neutralloci->traitalleles[nneutral]->locus = j; - nneutral++; - } - } -} - -pleiotropic = false; -if (neutralMarkersOnly) return; // pleiotropy cannot apply - -// determine whether there is pleiotropy -int chr,loc; -int nloci = 0; // maximum no. of loci on any one chromosome -for (int i = 0; i < nNLoci; i++) { - if (nloci < nLoci[i]) nloci = nLoci[i]; -} -int ***locfreq; -locfreq = new int **[nNLoci]; -for (int i = 0; i < nNLoci; i++) { - locfreq[i] = new int *[nloci]; - for (int j = 0; j < nloci; j++) { - locfreq[i][j] = new int[ntraits]; - for (int t = 0; t < ntraits; t++) locfreq[i][j][t] = 0; - } -} -for (int t = 0; t < ntraits; t++) { // each trait - for (int a = 0; a < traitdata->traitmaps[t]->nAlleles; a++) { - chr = traitdata->traitmaps[t]->traitalleles[a]->chromo; - loc = traitdata->traitmaps[t]->traitalleles[a]->locus; - locfreq[chr][loc][t]++; - } -} -#if RSDEBUG -//for (int i = 0; i < nNLoci; i++) { -// for (int j = 0; j < nloci; j++) -// for (int t = 0; t < ntraits; t++) -// DebugGUI("locfreq[" + Int2Str(i) + "][" + Int2Str(j) + "][" + Int2Str(t) -// + "]=" + Int2Str(locfreq[i][j][t])); -//} -#endif -for (int i = 0; i < nNLoci; i++) { - for (int j = 0; j < nloci; j++) { - // remove multiple contributions of a locus to a particular trait - // (i.e. prevent recording of pseudo-pleiotropy) - for (int t = 0; t < ntraits; t++) { - if (locfreq[i][j][t] > 0) locfreq[i][j][t] = 1; - } - // sum at level of chromosome/locus - for (int t = 1; t < ntraits; t++) { - locfreq[i][j][0] += locfreq[i][j][t]; - } - if (locfreq[i][j][0] > 1) pleiotropic = true; - } -} -for (int i = 0; i < nNLoci; i++) { - for (int j = 0; j < nloci; j++) { - delete[] locfreq[i][j]; - } - delete[] locfreq[i]; -} -delete[] locfreq; - -} - -void Species::deleteNeutralLoci(void) { -if (traitdata->neutralloci != NULL) { - for (int i = 0; i < traitdata->neutralloci->nAlleles; i++) { - delete traitdata->neutralloci->traitalleles[i]; - } - delete[] traitdata->neutralloci; -} -traitdata->neutralloci = NULL; -} - -int Species::getNNeutralLoci(void) { -int nn = 0; -if (traitdata != NULL) { - if (traitdata->neutralloci != NULL) { - nn = traitdata->neutralloci->nAlleles; - } -} -return nn; -} - -traitAllele Species::getNeutralAllele(const short allele) { -traitAllele a; a.chromo = 0; a.locus = 0; -if (traitdata != NULL) { - if (allele >= 0 && allele < traitdata->neutralloci->nAlleles) { - a = *traitdata->neutralloci->traitalleles[allele]; - } -} -return a; -} - -//--------------------------------------------------------------------------- - -// Emigration functions - -void Species::setEmig(const emigRules e) { -#if RSDEBUG -//DebugGUI("Species::setEmig(): e.indVar=" + Int2Str((int)e.indVar)); -#endif -densDepEmig = e.densDep; stgDepEmig = e.stgDep; sexDepEmig = e.sexDep; -indVarEmig = e.indVar; -if (e.emigStage >= 0) emigStage = e.emigStage; -//setGenome(); -} - -emigRules Species::getEmig(void) { -emigRules e; -e.densDep = densDepEmig; e.stgDep = stgDepEmig; e.sexDep = sexDepEmig; -e.indVar = indVarEmig; e.emigStage = emigStage; -e.emigTrait[0] = emigTrait[0]; e.emigTrait[1] = emigTrait[1]; -return e; -} - -void Species::setEmigTraits(const short stg,const short sex,const emigTraits e) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - if (e.d0 >= 0.0 && e.d0 <= 1.0) d0[stg][sex] = e.d0; - alphaEmig[stg][sex] = e.alpha; betaEmig[stg][sex] = e.beta; -} -} - -emigTraits Species::getEmigTraits(short stg,short sex) { -emigTraits e; -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - e.d0 = d0[stg][sex]; e.alpha = alphaEmig[stg][sex]; e.beta = betaEmig[stg][sex]; -} -else { - e.d0 = e.alpha = e.beta = 0.0; -} -return e; -} - -float Species::getEmigD0(short stg,short sex) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - return d0[stg][sex]; -} -else { - return 0.0; -} -} - -void Species::setEmigParams(const short stg,const short sex,const emigParams e) { -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < NSEXES) // implemented for stage 0 only -{ - if (e.d0Mean >= 0.0 && e.d0Mean < 1.0) d0Mean[stg][sex] = e.d0Mean; - if (e.d0SD > 0.0 && e.d0SD < 1.0) d0SD[stg][sex] = e.d0SD; -// if (e.d0MutnSize > 0.0 && e.d0MutnSize < 1.0) d0MutnSize = e.d0MutnSize; - alphaMean[stg][sex] = e.alphaMean; - if (e.alphaSD > 0.0) alphaSD[stg][sex] = e.alphaSD; -// if (e.alphaMutnSize > 0.0) alphaMutnSize = e.alphaMutnSize; - betaMean[stg][sex] = e.betaMean; - if (e.betaSD > 0.0) betaSD[stg][sex] = e.betaSD; -// if (e.betaMutnSize > 0.0) betaMutnSize = e.betaMutnSize; -} -} - -emigParams Species::getEmigParams(short stg,short sex) { -emigParams e; -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < NSEXES) // implemented for stage 0 only -{ - e.d0Mean = d0Mean[stg][sex]; e.d0SD = d0SD[stg][sex]; - e.d0Scale = d0Scale; - e.alphaMean = alphaMean[stg][sex]; e.alphaSD = alphaSD[stg][sex]; - e.alphaScale = alphaScale; - e.betaMean = betaMean[stg][sex]; e.betaSD = betaSD[stg][sex]; - e.betaScale = betaScale; -} -else { - e.d0Mean = e.alphaMean = e.betaMean = e.d0SD = e.alphaSD = e.betaSD = 0.0; - e.d0Scale = d0Scale; - e.alphaScale = alphaScale; - e.betaScale = betaScale; -} -return e; -} - -void Species::setEmigScales(const emigScales s) { -if (s.d0Scale >= 0.0 && s.d0Scale < 1.0 ) d0Scale = s.d0Scale; -if (s.alphaScale >= 0.0) alphaScale = s.alphaScale; -if (s.betaScale >= 0.0) betaScale = s.betaScale; -} - -emigScales Species::getEmigScales(void) { -emigScales s; -s.d0Scale = d0Scale; s.alphaScale = alphaScale; s.betaScale = betaScale; -return s; -} - -//--------------------------------------------------------------------------- - -// Transfer functions - -void Species::setTrfr(const trfrRules t) { -#if RSDEBUG -//DebugGUI("Species::setTrfr(): t.indVar=" + Int2Str((int)t.indVar)); -#endif -moveModel = t.moveModel; stgDepTrfr = t.stgDep; sexDepTrfr = t.sexDep; -distMort = t.distMort; indVarTrfr = t.indVar; -twinKern = t.twinKern; -habMort = t.habMort; -moveType = t.moveType; costMap = t.costMap; -//setGenome(); -} - -trfrRules Species::getTrfr(void) { -trfrRules t; -t.moveModel = moveModel; t.stgDep = stgDepTrfr; t.sexDep = sexDepTrfr; -t.distMort = distMort; t.indVar = indVarTrfr; -t.twinKern = twinKern; -t.habMort = habMort; -t.moveType = moveType; t.costMap = costMap; -t.movtTrait[0] = movtTrait[0]; t.movtTrait[1] = movtTrait[1]; -return t; -} - -void Species::setFullKernel(bool k) { -fullKernel = k; -} - -bool Species::useFullKernel(void) { return fullKernel; } - -void Species::setKernTraits(const short stg,const short sex, - const trfrKernTraits k,const int resol) -{ -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - if (k.meanDist1 > 0.0 && k.meanDist1 >= (float)resol) meanDist1[stg][sex] = k.meanDist1; - if (k.meanDist2 >= (float)resol) meanDist2[stg][sex] = k.meanDist2; - if (k.probKern1 > 0.0 && k.probKern1 < 1.0) probKern1[stg][sex] = k.probKern1; -} -} - -trfrKernTraits Species::getKernTraits(short stg,short sex) { -trfrKernTraits k; -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - k.meanDist1 = meanDist1[stg][sex]; - k.meanDist2 = meanDist2[stg][sex]; - k.probKern1 = probKern1[stg][sex]; -} -else { - k.meanDist1 = 0.0; k.meanDist2 = 0.0; k.probKern1 = 1.0; -} -return k; -} - -void Species::setMortParams(const trfrMortParams m) { -if (m.fixedMort >= 0.0 && m.fixedMort < 1.0) fixedMort = m.fixedMort; -mortAlpha = m.mortAlpha; -mortBeta = m.mortBeta; -} - -trfrMortParams Species::getMortParams(void) { -trfrMortParams m; -m.fixedMort = fixedMort; m.mortAlpha = mortAlpha; m.mortBeta = mortBeta; -return m; -} - -void Species::setMovtTraits(const trfrMovtTraits m) { -if (m.pr >= 1) pr = m.pr; -if (m.prMethod >= 1 && m.prMethod <= 3) prMethod = m.prMethod; -if (m.memSize >= 1 && m.memSize <= 14) memSize = m.memSize; -if (m.goalType >= 0 && m.goalType <= 2) goalType = m.goalType; -if (m.dp >= 1.0) dp = m.dp; -if (m.gb >= 1.0) gb = m.gb; -if (m.alphaDB > 0.0) alphaDB = m.alphaDB; -if (m.betaDB > 0) betaDB = m.betaDB; -if (m.stepMort >= 0.0 && m.stepMort < 1.0) stepMort = m.stepMort; -if (m.stepLength > 0.0) stepLength = m.stepLength; -if (m.rho > 0.0 && m.rho < 1.0) rho = m.rho; -straigtenPath = m.straigtenPath; -} - -trfrMovtTraits Species::getMovtTraits(void) { -trfrMovtTraits m; -m.pr = pr; m.prMethod = prMethod; m.memSize = memSize; m.goalType = goalType; -m.dp = dp; m.gb = gb; m.alphaDB = alphaDB; m.betaDB = betaDB; -m.stepMort = stepMort; m.stepLength = stepLength; m.rho = rho; -return m; -} - -trfrCRWTraits Species::getCRWTraits(void) { -trfrCRWTraits m; -m.stepMort = stepMort; m.stepLength = stepLength; m.rho = rho; -m.straigtenPath = straigtenPath; -return m; -} - -trfrSMSTraits Species::getSMSTraits(void) { -trfrSMSTraits m; -m.pr = pr; m.prMethod = prMethod; m.memSize = memSize; m.goalType = goalType; -m.dp = dp; m.gb = gb; m.alphaDB = alphaDB; m.betaDB = betaDB; m.stepMort = stepMort; -m.straigtenPath = straigtenPath; -return m; -} - -void Species::setKernParams(const short stg,const short sex, - const trfrKernParams k,const double resol) -{ -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < NSEXES) // implemented for stage 0 only -{ - if (k.dist1Mean > 0.0 && k.dist1Mean >= resol && k.dist1SD > 0.0) { - dist1Mean[stg][sex] = k.dist1Mean; dist1SD[stg][sex] = k.dist1SD; - } - if (k.dist2Mean > 0.0 && k.dist2Mean >= resol && k.dist2SD > 0.0) { - dist2Mean[stg][sex] = k.dist2Mean; dist2SD[stg][sex] = k.dist2SD; - } - if (k.PKern1Mean > 0.0 && k.PKern1Mean < 1.0 && k.PKern1SD > 0.0 && k.PKern1SD < 1.0 ) { - PKern1Mean[stg][sex] = k.PKern1Mean; PKern1SD[stg][sex] = k.PKern1SD; - } -} -} - -trfrKernParams Species::getKernParams(short stg,short sex) { -trfrKernParams k; -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < NSEXES) // implemented for stage 0 only -{ - k.dist1Mean = dist1Mean[stg][sex]; k.dist1SD = dist1SD[stg][sex]; - k.dist2Mean = dist2Mean[stg][sex]; k.dist2SD = dist2SD[stg][sex]; - k.PKern1Mean = PKern1Mean[stg][sex]; k.PKern1SD = PKern1SD[stg][sex]; - k.dist1Scale = dist1Scale; k.dist2Scale = dist2Scale; k.PKern1Scale = PKern1Scale; -} -else { - k.dist1Mean = 100000.0; k.dist1SD = 0.001f; k.dist1Scale = 1.0; - k.dist2Mean = 100000.0; k.dist2SD = 0.001f; k.dist2Scale = 1.0; - k.PKern1Mean = 0.5; k.PKern1SD = 0.1f; k.PKern1Scale = 0.1f; -} -return k; -} - -void Species::setSMSParams(const short stg,const short sex,const trfrSMSParams s) { -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < 1) // implemented for stage 0 & sex 0 only -{ - if (s.dpMean >= 1.0 && s.dpSD > 0.0) { - dpMean[stg][sex] = s.dpMean; dpSD[stg][sex] = s.dpSD; - } - if (s.gbMean >= 1.0 && s.gbSD > 0.0) { - gbMean[stg][sex] = s.gbMean; gbSD[stg][sex] = s.gbSD; - } - if (s.alphaDBMean > 0.0 && s.alphaDBSD > 0.0) { - alphaDBMean[stg][sex] = s.alphaDBMean; alphaDBSD[stg][sex] = s.alphaDBSD; - } - if (s.betaDBMean >= 1.0 && s.betaDBSD > 0.0) { - betaDBMean[stg][sex] = s.betaDBMean; betaDBSD[stg][sex] = s.betaDBSD; - } -} -} - -trfrSMSParams Species::getSMSParams(short stg,short sex) { -trfrSMSParams s; -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < 1) // implemented for stage 0 & sex 0 only -{ - s.dpMean = dpMean[stg][sex]; s.dpSD = dpSD[stg][sex]; - s.gbMean = gbMean[stg][sex]; s.gbSD = gbSD[stg][sex]; - s.alphaDBMean = alphaDBMean[stg][sex]; s.alphaDBSD = alphaDBSD[stg][sex]; - s.betaDBMean = betaDBMean[stg][sex]; s.betaDBSD = betaDBSD[stg][sex]; - s.dpScale = dpScale; s.gbScale = gbScale; - s.alphaDBScale = alphaDBScale; s.betaDBScale = betaDBScale; -} -else { - s.dpMean = 1.0; s.dpSD = 0.1f; s.dpScale = 0.1f; - s.gbMean = 1.0; s.gbSD = 0.1f; s.gbScale = 0.1f; - s.alphaDBMean = 1.0; s.alphaDBSD = 0.1f; s.alphaDBScale = 0.1f; - s.betaDBMean = 10.0; s.betaDBSD = 1.0; s.betaDBScale = 1.0; -} -return s; -} - -void Species::setCRWParams(const short stg,const short sex,const trfrCRWParams m) { -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < 1) // implemented for stage 0 & sex 0 only -{ - if (m.stepLgthMean > 0.0 && m.stepLgthSD > 0.0) { - stepLgthMean[stg][sex] = m.stepLgthMean; stepLgthSD[stg][sex] = m.stepLgthSD; - } - if (m.rhoMean > 0.0 && m.rhoMean < 1.0 && m.rhoSD > 0.0 && m.rhoSD < 1.0 ) { - rhoMean[stg][sex] = m.rhoMean; rhoSD[stg][sex] = m.rhoSD; - } -} -} - -trfrCRWParams Species::getCRWParams(short stg,short sex) { -trfrCRWParams m; -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < 1) // implemented for stage 0 & sex 0 only -{ - m.stepLgthMean = stepLgthMean[stg][sex]; m.stepLgthSD = stepLgthSD[stg][sex]; - m.rhoMean = rhoMean[stg][sex]; m.rhoSD = rhoSD[stg][sex]; - m.stepLScale = stepLScale; m.rhoScale = rhoScale; -} -else { - m.stepLgthMean = 1.0; m.stepLgthSD = 0.1f; m.stepLScale = 0.1f; - m.rhoMean = 0.5; m.rhoSD = 0.1f; m.rhoScale = 0.1f; -} -return m; -} - -void Species::setTrfrScales(const trfrScales s) { -if (s.dist1Scale >= 0.0) dist1Scale = s.dist1Scale; -if (s.dist2Scale >= 0.0) dist2Scale = s.dist2Scale; -if (s.PKern1Scale > 0.0 && s.PKern1Scale < 1.0) PKern1Scale = s.PKern1Scale; -if (s.dpScale > 0.0) dpScale = s.dpScale; -if (s.gbScale > 0.0) gbScale = s.gbScale; -if (s.alphaDBScale > 0.0) alphaDBScale = s.alphaDBScale; -if (s.betaDBScale > 0.0) betaDBScale = s.betaDBScale; -if (s.stepLScale > 0.0) stepLScale = s.stepLScale; -if (s.rhoScale > 0.0 && s.rhoScale < 1.0) rhoScale = s.rhoScale; -} - -trfrScales Species::getTrfrScales(void) { -trfrScales s; -s.dist1Scale = dist1Scale; s.dist2Scale = dist2Scale; s.PKern1Scale = PKern1Scale; -s.dpScale = dpScale; s.gbScale = gbScale; -s.alphaDBScale = alphaDBScale; s.betaDBScale = betaDBScale; -s.stepLScale = stepLScale; s.rhoScale = rhoScale; -return s; -} - -short Species::getMovtHabDim() { return habDimTrfr; } - -void Species::createHabCostMort(short nhab) { -if (nhab >= 0) { - habDimTrfr = nhab; - if (habCost != 0 || habStepMort != 0) deleteHabCostMort(); - habCost = new int[nhab]; - habStepMort = new double[nhab]; - for (int i = 0; i < nhab; i++) { - habCost[i] = 1; habStepMort[i] = 0.0; - } -} -} - -void Species::setHabCost(short hab,int cost) { -if (hab >= 0 && hab < habDimTrfr) { - if (cost >= 1) habCost[hab] = cost; -} -} - -void Species::setHabMort(short hab,double mort) { -if (hab >= 0 && hab < habDimTrfr) { - if (mort >= 0.0 && mort < 1.0) habStepMort[hab] = mort; -} -} - -int Species::getHabCost(short hab) { -int cost = 0; -if (hab >= 0 && hab < habDimTrfr) cost = habCost[hab]; -return cost; -} - -double Species::getHabMort(short hab) { -double pmort = 0.0; -if (hab >= 0 && hab < habDimTrfr) pmort = habStepMort[hab]; -return pmort; -} - -void Species::deleteHabCostMort(void) { -if (habCost != 0) { - delete[] habCost; habCost = 0; -} -if (habStepMort != 0) { - delete[] habStepMort; habStepMort = 0; -} -} - -//--------------------------------------------------------------------------- - -// Settlement functions - -void Species::setSettle(const settleType s) { -stgDepSett = s.stgDep; sexDepSett = s.sexDep; indVarSett = s.indVar; -} - -settleType Species::getSettle(void) { -settleType s; -s.stgDep = stgDepSett; s.sexDep = sexDepSett; s.indVar = indVarSett; -s.settTrait[0] = settTrait[0]; s.settTrait[1] = settTrait[1]; -return s; -} - -void Species::setSettRules(const short stg,const short sex,const settleRules s) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - densDepSett[stg][sex] = s.densDep; wait[stg][sex] = s.wait; - go2nbrLocn[stg][sex] = s.go2nbrLocn; findMate[stg][sex] = s.findMate; -} -} - -settleRules Species::getSettRules(short stg,short sex) { -settleRules s; -s.densDep = false; -s.findMate = false; -s.go2nbrLocn = false; -s.wait = false; -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - s.densDep = densDepSett[stg][sex]; s.wait = wait[stg][sex]; - s.go2nbrLocn = go2nbrLocn[stg][sex]; s.findMate = findMate[stg][sex]; -} -return s; -} - -void Species::setSteps(const short stg,const short sex,const settleSteps s) { -if (stg == 0 && sex == 0) { - if (s.minSteps >= 0) minSteps = s.minSteps; - else minSteps = 0; - if (s.maxSteps >= 1) maxSteps = s.maxSteps; - else maxSteps = 99999999; -} -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - if (s.maxStepsYr >= 1) maxStepsYr[stg][sex] = s.maxStepsYr; - else maxStepsYr[stg][sex] = 99999999; -} -} - -settleSteps Species::getSteps(short stg,short sex) { -settleSteps s; -s.minSteps = minSteps; -s.maxSteps = maxSteps; -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) s.maxStepsYr = maxStepsYr[stg][sex]; -else s.maxStepsYr = 99999999; -return s; -} - -void Species::setSettTraits(const short stg,const short sex,const settleTraits dd) { -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - if (dd.s0 > 0.0 && dd.s0 <= 1.0 ) s0[stg][sex] = dd.s0; - alphaS[stg][sex] = dd.alpha; betaS[stg][sex] = dd.beta; -} -} - -settleTraits Species::getSettTraits(short stg,short sex) { -settleTraits dd; -if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { - dd.s0 = s0[stg][sex]; dd.alpha = alphaS[stg][sex]; dd.beta = betaS[stg][sex]; -} -else { dd.s0 = 1.0; dd.alpha = dd.beta = 0.0; } -return dd; -} - -void Species::setSettParams(const short stg,const short sex,const settParams s) { -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < NSEXES) // implemented for stage 0 only -{ - if (s.s0Mean >= 0.0 && s.s0Mean < 1.0) s0Mean[stg][sex] = s.s0Mean; - if (s.s0SD > 0.0 && s.s0SD < 1.0) s0SD[stg][sex] = s.s0SD; - alphaSMean[stg][sex] = s.alphaSMean; - if (s.alphaSSD > 0.0) alphaSSD[stg][sex] = s.alphaSSD; - betaSMean[stg][sex] = s.betaSMean; - if (s.betaSSD > 0.0) betaSSD[stg][sex] = s.betaSSD; - if (sex == 0) { - if (s.s0Scale > 0.0 && s.s0Scale < 1.0) s0Scale = s.s0Scale; - if (s.alphaSScale > 0.0) alphaSScale = s.alphaSScale; - if (s.betaSScale > 0.0) betaSScale = s.betaSScale; - } -} -} - -settParams Species::getSettParams(short stg,short sex) { -settParams s; -//if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) -if (stg >= 0 && stg < 1 && sex >= 0 && sex < NSEXES) // implemented for stage 0 only -{ - s.s0Mean = s0Mean[stg][sex]; s.s0SD = s0SD[stg][sex]; - s.alphaSMean = alphaSMean[stg][sex]; s.alphaSSD = alphaSSD[stg][sex]; - s.betaSMean = betaSMean[stg][sex]; s.betaSSD = betaSSD[stg][sex]; -} -else { - s.s0Mean = s.alphaSMean = s.betaSMean = s.s0SD = s.alphaSSD = s.betaSSD = 0.0; -} -s.s0Scale = s0Scale; -s.alphaSScale = alphaSScale; -s.betaSScale = betaSScale; -return s; -} - -void Species::setSettScales(const settScales s) { -if (s.s0Scale >= 0.0 && s.s0Scale < 1.0 ) s0Scale = s.s0Scale; -if (s.alphaSScale >= 0.0) alphaSScale = s.alphaSScale; -if (s.betaSScale >= 0.0) betaSScale = s.betaSScale; -} - -settScales Species::getSettScales(void) { -settScales s; -s.s0Scale = s0Scale; s.alphaSScale = alphaSScale; s.betaSScale = betaSScale; -return s; -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - diff --git a/src/RScore/Species.h b/src/RScore/Species.h deleted file mode 100644 index 55dbacf..0000000 --- a/src/RScore/Species.h +++ /dev/null @@ -1,755 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 Species - -Implements the Species class - -There is ONE instance of a Species for each species within the Community -AND THIS IS CURRENTLY LIMITED TO A SINGLE SPECIES. -The class holds all the demographic and dispersal parameters of the species. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 28 July 2021 by Greta Bocedi - -------------------------------------------------------------------------------*/ - -#ifndef SpeciesH -#define SpeciesH - -#if RS_RCPP -#include "../Version.h" -#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif -#include "Parameters.h" - -// structures for demographic parameters - -struct demogrParams { - short repType; - short repSeasons; - float propMales; float harem; float bc; float lambda; - bool stageStruct; -}; -struct stageParams { - short nStages; short repInterval; short maxAge; short survival; - float probRep; - bool fecDens; bool fecStageDens; bool devDens; bool devStageDens; - bool survDens; bool survStageDens; bool disperseOnLoss; -}; -struct densDepParams { - float devCoeff; float survCoeff; -}; - -// structures for genetics - -struct genomeData { - int nLoci; - bool diploid; bool neutralMarkers; bool pleiotropic; bool trait1Chromosome; - double probMutn,probCrossover,alleleSD,mutationSD; -} ; - -struct traitAllele { - short chromo; short locus; -} ; - -struct traitMap { - short nAlleles; - traitAllele **traitalleles; -} ; - -struct traitData { - short nTraitMaps; - traitMap **traitmaps; - traitMap *neutralloci; -} ; - -// structures for emigration parameters - -struct emigRules { - bool densDep; bool stgDep; bool sexDep; bool indVar; - short emigStage; - short emigTrait[2]; -}; -struct emigTraits { - float d0; float alpha; float beta; -}; -struct emigParams { - double d0Mean; double d0SD; double d0Scale; - double alphaMean; double alphaSD; double alphaScale; - double betaMean; double betaSD; double betaScale; -}; -struct emigScales { - double d0Scale; double alphaScale; double betaScale; -}; - -// structures for transfer parameters - -struct trfrRules { - bool moveModel; bool stgDep; bool sexDep; - bool distMort; bool indVar; - bool twinKern; - bool habMort; - short moveType; bool costMap; - short movtTrait[2]; -}; -struct trfrKernTraits { - float meanDist1; float meanDist2; float probKern1; -}; -struct trfrMortParams { - float fixedMort; float mortAlpha; float mortBeta; -}; -struct trfrMovtTraits { - short pr; short prMethod; short memSize; short goalType; - float dp; float gb; float alphaDB; int betaDB; - float stepMort; float stepLength; float rho; - bool straigtenPath; -}; -struct trfrCRWTraits { - float stepMort; float stepLength; float rho; bool straigtenPath; -}; -struct trfrSMSTraits { - short pr; short prMethod; short memSize; short goalType; - float dp; float gb; float alphaDB; int betaDB; float stepMort; - bool straigtenPath; -}; -struct trfrKernParams { - double dist1Mean; double dist1SD; double dist1Scale; - double dist2Mean; double dist2SD; double dist2Scale; - double PKern1Mean; double PKern1SD; double PKern1Scale; -}; -struct trfrSMSParams { - double dpMean; double dpSD; double gbMean; double gbSD; - double alphaDBMean; double alphaDBSD; double betaDBMean; double betaDBSD; - double dpScale; double gbScale; double alphaDBScale; double betaDBScale; -}; -struct trfrCRWParams { - double stepLgthMean; double stepLgthSD; double stepLScale; - double rhoMean; double rhoSD; double rhoScale; -}; -struct trfrScales { - float dist1Scale; float dist2Scale; float PKern1Scale; - float dpScale; float gbScale; float alphaDBScale; float betaDBScale; - float stepLScale; float rhoScale; -}; - -// structures for settlement parameters - -struct settleType { - bool stgDep; bool sexDep; bool indVar; - short settTrait[2]; -}; -struct settleRules { - bool densDep; bool wait; bool go2nbrLocn; bool findMate; -}; -struct settleSteps { - int minSteps; int maxSteps; int maxStepsYr; -}; -struct settleTraits { - float s0; float alpha; float beta; -}; -struct settParams { - double s0Mean; double s0SD; double s0Scale; - double alphaSMean; double alphaSSD; double alphaSScale; - double betaSMean; double betaSSD; double betaSScale; -}; -struct settScales { - double s0Scale; double alphaSScale; double betaSScale; -}; - - -//--------------------------------------------------------------------------- - -class Species { - -public: - Species(void); - ~Species(void); - short getSpNum(void); - - // demographic parameter functions - - void createHabK( // Create habitat carrying capacity table - short // no. of habitats - ); - void setHabK( - short, // habitat index no. (NB may differ from habitat no. supplied by user) - float // carrying capacity (inds/cell) - ); - float getHabK( - short // habitat index no. (NB may differ from habitat no. supplied by user) - ); - float getMaxK(void); // return highest carrying capacity over all habitats - void deleteHabK(void); // Delete habitat carrying capacity table - void setStage( // Set stage structure parameters - const stageParams // structure holding stage structure parameters - ); - stageParams getStage(void); // Get stage structure parameters - void setDemogr( // Set general demographic parameters - const demogrParams // structure holding general demographic parameters - ); - demogrParams getDemogr(void); // Get general demographic parameters - short getRepType(void); - bool stageStructured(void); - void setDensDep( // Set demographic density dependence coefficients - float, // development coefficient - float // survival coefficient - ); - densDepParams getDensDep(void); // Get development and survival coefficients - - void setFec( // Set fecundity - short, // stage (must be > 0) - short, // sex - float // fecundity - ); - float getFec( // Get fecundity - short, // stage - short // sex - ); - void setDev( // Set development probability - short, // stage - short, // sex - float // development probability - ); - float getDev( // Get development probability - short, // stage - short // sex - ); - void setSurv( // Set survival probability - short, // stage - short, // sex - float // survival probability - ); - float getSurv( // Get survival probability - short, // stage - short // sex - ); - - float getMaxFec(void); // Get highest fecundity of any stage - void setMinAge( // Set minimum age - short, // stage - short, // sex - int // minimum age (years) (must be zero for stages 0 and 1) - ); - short getMinAge( // Get minimum age - short, // stage - short // sex - ); - void createDDwtFec( // Create fecundity weights matrix - short // matrix dimension - no. of stages * no. of sexes - ); - void setDDwtFec( // Set fecundity weights matrix element - short, // row - short, // column - float // weight - ); - float getDDwtFec( // Get fecundity weights matrix element - short, // row - short // column - ); - void deleteDDwtFec(void); // Delete fecundity weights matrix - void createDDwtDev( // Create development weights matrix - short // matrix dimension - no. of stages * no. of sexes - ); - void setDDwtDev( // Set development weights matrix element - short, // row - short, // column - float // weight - ); - float getDDwtDev( // Get development weights matrix element - short, // row - short // column - ); - void deleteDDwtDev(void); // Delete development weights matrix - void createDDwtSurv( // Create survival weights matrix - short // matrix dimension - no. of stages * no. of sexes - ); - void setDDwtSurv( // Set survival weights matrix element - short, // row - short, // column - float // weight - ); - float getDDwtSurv( // Get survival weights matrix element - short, // row - short // column - ); - void deleteDDwtSurv(void); // Delete survival weights matrix - // Functions to handle min/max R or K (under environmental stochasticity) - void setMinMax( // Set min and max values - float, // min - float // max - ); - float getMinMax( // Get min/max value - short // option: 0 = return minimum, otherwise = return maximum - ); - - - // genome functions - - void setGenomeData(genomeData); - genomeData getGenomeData(void); - bool isDiploid(void); - void setNChromosomes( // Set no. of chromosomes - int // no. of chromosomes - ); - int getNChromosomes(void); - void setNLoci( - const short, // chromosome no. - const short // locus no. - ); - int getNLoci( - const short // chromosome no. - ); - void deleteLoci(void); - void set1ChromPerTrait( // Set 1:1 mapping of trait to chromosome - const int // no. of loci on each chromosome - ); - bool has1ChromPerTrait(void); - void setTraits(void); // Set trait attributes for the species - void setTraitNames(void); - void deleteTraitNames(void); - string getTraitName( - const int // trait no. - ); - int getNTraits(void); - void setTraitData( - const int // no. of traits - ); - void deleteTraitData(void); - int getNTraitMaps(void); - void setTraitMap( - const short, // trait no. - const short // no. of alleles - ); - int getNTraitAlleles( - const int // trait no. - ); - void setTraitAllele( - const short, // trait no. - const short, // trait allele no. - const short, // chromosome no. - const short // chromosome locus no. - ); - traitAllele getTraitAllele( - const short, // trait no. - const short // trait allele no. - ); - void setNeutralLoci(bool); - void deleteNeutralLoci(void); - int getNNeutralLoci(void); - traitAllele getNeutralAllele( - const short // allele no. - ); - - // emigration parameter functions - - void setEmig( // Set emigration rules - const emigRules // structure holding emigration rules - ); - emigRules getEmig(void); // Get emigration rules - void setEmigTraits( // Set emigration trait parameters - const short, // stage - const short, // sex - const emigTraits // structure holding emigration trait parameters - ); - emigTraits getEmigTraits( // Get emigration trait parameters - short, // stage - short // sex - ); - float getEmigD0( // Get (maximum) emigration probability - short, // stage - short // sex - ); - void setEmigParams( // Set emigration initialisation parameters - const short, // stage (NB implemented for stage 0 only) - const short, // sex - const emigParams // structure holding parameters - ); - emigParams getEmigParams( // Get emigration initialisation parameters - short, // stage (NB implemented for stage 0 only) - short // sex - ); - void setEmigScales( // Set emigration mutation parameters - const emigScales // structure holding emigration mutation parameters - ); - emigScales getEmigScales(void); // Get emigration mutation parameters - - // transfer parameter functions - - void setTrfr( // Set transfer rules - const trfrRules // structure holding transfer rules - ); - trfrRules getTrfr(void); // Get transfer rules - void setFullKernel( // Set fullKernel condition - bool // fullKernel value - ); - bool useFullKernel(void); - void setKernTraits( // Set transfer by kernel parameters - const short, // stage - const short, // sex - const trfrKernTraits, // structure holding transfer by kernel parameters - const int // Landscape resolution - ); - trfrKernTraits getKernTraits( // Get transfer by kernel parameters - short, // stage - short // sex - ); - void setMortParams( // Set transfer mortality parameters - const trfrMortParams // structure holding transfer mortality parameters - ); - trfrMortParams getMortParams(void); // Get transfer mortality parameters - void setMovtTraits( // Set transfer movement model parameters - const trfrMovtTraits // structure holding transfer movement model parameters - ); - trfrMovtTraits getMovtTraits(void); // Get transfer movement model traits - trfrCRWTraits getCRWTraits(void); // Get CRW traits - trfrSMSTraits getSMSTraits(void); // Get SMS traits - void setKernParams( // Set initial transfer by kernel parameter limits - const short, // stage (NB implemented for stage 0 only) - const short, // sex - const trfrKernParams, // structure holding min and max values - const double // Landscape resolution - ); - trfrKernParams getKernParams( // Get initial transfer by kernel parameter limits - short, // stage (NB implemented for stage 0 only) - short // sex - ); - void setSMSParams( // Set initial transfer by SMS parameter limits - const short, // stage (NB implemented for stage 0 only) - const short, // sex (NB implemented for sex 0 only) - const trfrSMSParams // structure holding min and max values - ); - trfrSMSParams getSMSParams( // Get initial transfer by SMS parameter limits - short, // stage (NB implemented for stage 0 only) - short // sex (NB implemented for sex 0 only) - ); - void setCRWParams( // Set initial transfer by CRW parameter limits - const short, // stage (NB implemented for stage 0 only) - const short, // sex (NB implemented for sex 0 only) - const trfrCRWParams // structure holding min and max values - ); - trfrCRWParams getCRWParams( // Get initial transfer by CRW parameter limits - short, // stage (NB implemented for stage 0 only) - short // sex (NB implemented for sex 0 only) - ); - void setTrfrScales( // Set transfer mutation parameters - const trfrScales // structure holding transfer mutation parameters - ); - trfrScales getTrfrScales(void); // Get transfer mutation parameters - // Return dimension of habitat-dependent step mortality and costs matrices - short getMovtHabDim(void); - void createHabCostMort( // Create habitat-dependent costs and mortality matrices - short // no. of habitats - ); - void setHabCost( // Set habitat-dependent cost - short, // habitat index no. - int // cost value - ); - void setHabMort( // Set habitat-dependent per-step mortality - short, // habitat index no. - double // mortality rate - ); - int getHabCost( // Get habitat-dependent cost - short // habitat index no. - ); - double getHabMort( // Get habitat-dependent per-step mortality - short // habitat index no. - ); - void deleteHabCostMort(void); // Delete habitat-dependent costs and mortality matrices - - // settlement parameter functions - - void setSettle( // Set settlement type - const settleType // structure holding settlement type (stage- and/or sex-dependent) - ); - settleType getSettle(void); // Get settlement type - void setSettRules( // Set settlement rules - const short, // stage - const short, // sex - const settleRules // structure holding settlement rules - ); - settleRules getSettRules( // Get settlement rules - short, // stage - short // sex - ); - void setSteps( // Set path step limit parameters - const short, // stage - const short, // sex - const settleSteps // structure holding path step limit parameters - ); - settleSteps getSteps( // Set path step limit parameters - short, // stage - short // sex - ); - void setSettTraits( // Set settlement density dependence traits - const short, // stage - const short, // sex - const settleTraits // structure holding density dependence traits - ); - settleTraits getSettTraits( // Get settlement density dependence traits - short, // stage - short // sex - ); - void setSettParams( // Set settlement initialisation parameters - const short, // stage (NB implemented for stage 0 only) - const short, // sex - const settParams // structure holding parameters - ); - settParams getSettParams( // Get settlement initialisation parameters - short, // stage (NB implemented for stage 0 only) - short // sex - ); - void setSettScales( // Set settlement mutation parameters - const settScales // structure holding settlement mutation parameters - ); - settScales getSettScales(void); // Get settlement mutation parameters - -private: - - // NOTE: SEQUENCE OF PARAMETER VARIABLES MAY NEED TO BE ALTERED FOR EFFICIENTCY ... - // ... but that is of low importance, as there will only be one (or a few) instance(s) - - // demographic parameters - - short repType; // 0 = asexual, 1 = simple two sex, 2 = complex two sex - short nStages; // no. of stages (incl. juveniles) in structured population - float propMales; // proportion of males at birth in sexual model - float harem; // max harem size in complex sexual model - float bc; // competition coefficient for non-structured population - float lambda; // max intrinsic growth rate for non-structured population - float probRep; // probability of reproducing in subsequent seasons - short repSeasons; // no. of reproductive seasons per year - short repInterval; // no. of reproductive seasons between subsequent reproductions - short maxAge; // max age in structured population - short survival; // survival timing: 0 = at reprodn, 1 = between reprodns, 2 = anually - bool stageStruct; - bool fecDens; - bool fecStageDens; - bool devDens; - bool devStageDens; - bool survDens; - bool survStageDens; - bool disperseOnLoss; // individuals disperse on complete loss of patch - // (otherwise they die) - short habDimK; // dimension of carrying capacities matrix - float *habK; // habitat-specific carrying capacities (inds/cell) - float devCoeff; // density-dependent development coefficient - float survCoeff; // density-dependent survival coefficient - float **ddwtFec; // density-dependent weights matrix for fecundity - float **ddwtDev; // density-dependent weights matrix for development - float **ddwtSurv; // density-dependent weights matrix for survival - // NB for the following arrays, sex 0 is females, sex 1 is males - float fec[NSTAGES][NSEXES]; // fecundities - float dev[NSTAGES][NSEXES]; // development probabilities - float surv[NSTAGES][NSEXES]; // survival probabilities - short minAge[NSTAGES][NSEXES]; // minimum age to enter stage - // NOTE - IN THEORY, NEXT 3 VARIABLES COULD BE COMMON, BUT WE WOULD NEED TO ENSURE THAT - // ALL MATRICES ARE DELETED IF THERE IS A CHANGE IN NO. OF STAGES OR REPRODUCTION TYPE - // ***** TO BE RECONSIDERED LATER ***** - short ddwtFecDim; // dimension of density-dependent weights matrix for fecundity - short ddwtDevDim; // dimension of density-dependent weights matrix for fecundity - short ddwtSurvDim; // dimension of density-dependent weights matrix for fecundity - float minRK; // minimum ) growth rate OR carrying capacity - float maxRK; // maximum ) (under environmental stochasticity) - - // genome parameters - - short nTraits; // no. of inheritable traits - short emigTrait[2]; // to record first and no. of emigration traits - short movtTrait[2]; // to record first and no. of transfer traits - short settTrait[2]; // to record first and no. of settlement traits - bool diploid; - bool neutralMarkers; // neutral markers in absence of any adaptive traits - bool pleiotropic; - bool trait1Chromosome; // 1:1 mapping of chromosome to trait - short nChromosomes; // no. of chromosomes - double probMutn; // allelic mutation probability - double probCrossover; // crossover probability at meiosis - double alleleSD; // s.d. of initial allelic values around phenotypic value - double mutationSD; // s.d. of mutation magnitude - short nNLoci; // no. of nLoci set - short *nLoci; // no. of loci per chromosome - short nTraitNames; // no. of trait names set - traitData *traitdata; // for mapping of chromosome loci to traits - string *traitnames; // trait names for parameter output - - // emigration parameters - - bool densDepEmig; // density-dependent emigration - bool stgDepEmig; // stage-dependent emigration - bool sexDepEmig; // sex-dependent emigration - bool indVarEmig; // individual variation in emigration - short emigStage; // stage which emigrates (used for stage-strucutred population - // having individual variability in emigration probability) - // NB for the following arrays, sex 0 is females, sex 1 is males - float d0[NSTAGES][NSEXES]; // maximum emigration probability - float alphaEmig[NSTAGES][NSEXES]; // slope of density-dependent reaction norm - float betaEmig[NSTAGES][NSEXES]; // inflection point of reaction norm (in terms of N/K) - // NB Initialisation parameters are made double to avoid conversion errors (reason unclear) - // on traits maps using FloatToStr() - // As evolving traits are not stage-dependent, no. of rows can be 1 - // Indeed, they could be 1-D arrays - double d0Mean[1][NSEXES]; - double d0SD[1][NSEXES]; - double alphaMean[1][NSEXES]; - double alphaSD[1][NSEXES]; - double betaMean[1][NSEXES]; - double betaSD[1][NSEXES]; - double d0Scale; // scaling factor for d0 - double alphaScale; // scaling factor for alpha - double betaScale; // scaling factor for beta - - // transfer parameters - - bool moveModel; - bool stgDepTrfr; - bool sexDepTrfr; - bool distMort; - bool indVarTrfr; - bool twinKern; - bool habMort; // habitat-dependent mortality - float meanDist1[NSTAGES][NSEXES]; // mean of 1st dispersal kernel (m) - float meanDist2[NSTAGES][NSEXES]; // mean of 2nd dispersal kernel (m) - float probKern1[NSTAGES][NSEXES]; // probability of dispersing with the 1st kernel - // NB INITIAL limits are made double to avoid conversion errors (reason unclear) - // on traits maps using FloatToStr() - // As evolving traits are are not stage-dependent, no. of rows can be 1 - // Indeed, as they are INITIAL limits, which may subsequently be exceeded, they could be - // 1-D arrays - double dist1Mean[1][NSEXES]; // mean of initial mean of the 1st dispersal kernel (m) - double dist1SD[1][NSEXES]; // s.d. of initial mean of the 1st dispersal kernel (m) - double dist2Mean[1][NSEXES]; // mean of initial mean of the 2nd dispersal kernel (m) - double dist2SD[1][NSEXES]; // s.d. of initial mean of the 2nd dispersal kernel (m) - double PKern1Mean[1][NSEXES]; // mean of initial prob. of dispersing with 1st kernel - double PKern1SD[1][NSEXES]; // s.d. of initial prob. of dispersing with 1st kernel - float dist1Scale; // scaling factor for mean of 1st dispersal kernel (m) - float dist2Scale; // scaling factor for mean of 2nd dispersal kernel (m) - float PKern1Scale; // scaling factor for prob. of dispersing with 1st kernel - float fixedMort; // constant mortality probability - float mortAlpha; // slope for mortality distance dependence function - float mortBeta; // inflection point for mortality distance dependence function - short moveType; // 1 = SMS, 2 = CRW - short pr; // SMS perceptual range (cells) - short prMethod; // SMS perceptual range evaluation method: - // 1 = arith. mean, 2 = harmonic mean, 3 = inverse weighted arith. mean - short memSize; // SMS memory size (1-14 steps) - short goalType; // SMS goal bias type: 0 = none, 1 = towards goal, 2 = dispersal bias - float dp; // SMS directional persistence - float gb; // SMS goal bias - float alphaDB; // SMS dispersal bias decay rate - int betaDB; // SMS dispersal bias decay inflection point (no. of steps) - float stepMort; // constant per-step mortality probability for movement models - double *habStepMort; // habitat-dependent per-step mortality probability - float stepLength; // CRW step length (m) - float rho; // CRW correlation coefficient - double dpMean[1][NSEXES]; // mean of initial SMS directional persistence - double dpSD[1][NSEXES]; // s.d. of initial SMS directional persistence - double gbMean[1][NSEXES]; // mean of initial SMS goal bias - double gbSD[1][NSEXES]; // s.d. of initial SMS goal bias - double alphaDBMean[1][NSEXES]; // mean of initial SMS dispersal bias decay rate - double alphaDBSD[1][NSEXES]; // s.d. of initial SMS dispersal bias decay rate - double betaDBMean[1][NSEXES]; // mean of initial SMS dispersal bias decay infl. pt. - double betaDBSD[1][NSEXES]; // s.d. of initial SMS dispersal bias decay infl. pt. - float dpScale; // scaling factor for SMS directional persistence - float gbScale; // scaling factor for SMS goal bias - float alphaDBScale; // scaling factor for SMS dispersal bias decay rate - float betaDBScale; // scaling factor for SMS dispersal bias decay infl. pt. - double stepLgthMean[1][NSEXES]; // mean of initial step length (m) - double stepLgthSD[1][NSEXES]; // s.d. of initial step length (m) - double rhoMean[1][NSEXES]; // mean of initial correlation coefficient - double rhoSD[1][NSEXES]; // s.d. of initial correlation coefficient - float stepLScale; // scaling factor for step length (m) - float rhoScale; // scaling factor for correlation coefficient - short habDimTrfr; // dimension of habitat-dependent step mortality and costs matrices - int *habCost; // habitat costs - bool costMap; // import cost map from file? - bool straigtenPath; // straighten path after decision not to settle - bool fullKernel; // used to indicate special case when density-independent emigration - // is 1.0, and kernel-based movement within the natal cell is used - // to determine philopatry - - // settlement parameters - - bool stgDepSett; - bool sexDepSett; - bool indVarSett; // individual variation in settlement - bool densDepSett[NSTAGES][NSEXES]; - bool wait[NSTAGES][NSEXES]; // wait to continue moving next season (stage-structured model only) - bool go2nbrLocn[NSTAGES][NSEXES]; // settle in neighbouring cell/patch if available (ditto) - bool findMate[NSTAGES][NSEXES]; - int minSteps; // minimum no. of steps - int maxSteps; // maximum total no. of steps - int maxStepsYr[NSTAGES][NSEXES]; // maximum no. of steps in any one dispersal period - float s0[NSTAGES][NSEXES]; // maximum settlement probability - float alphaS[NSTAGES][NSEXES]; // slope of the settlement reaction norm to density - float betaS[NSTAGES][NSEXES]; // inflection point of the settlement reaction norm to density - double s0Mean[1][NSEXES]; // mean of initial maximum settlement probability - double s0SD[1][NSEXES]; // s.d. of initial maximum settlement probability - double alphaSMean[1][NSEXES]; // mean of initial settlement reaction norm slope - double alphaSSD[1][NSEXES]; // s.d. of initial settlement reaction norm slope - double betaSMean[1][NSEXES]; // mean of initial settlement reaction norm inflection point - double betaSSD[1][NSEXES]; // s.d. of initial settlement reaction norm inflection point - float s0Scale; // scaling factor for maximum settlement probability - float alphaSScale; // scaling factor for settlement reaction norm slope - float betaSScale; // scaling factor for settlement reaction norm inflection point - - // other attributes - - int spNum; - -}; - -/* IMPORTANT NOTE: -At the time of writing (24/4/14) the stage- and sex-dependent parameters for emigration -and dispersal (e.g. d0[NSTAGES][NSEXES]) are set according to the appropriate stage- and -sex-dependent settings; thus a species could be structured and sexual, but parameter values -are set for elements [0][0] only if emigration/transfer is stage- and sex-independent. -However, the parameters for settlement are set for ALL stages and sexes appropriate to the -species, regardless of settlement dependency. The rationale for this is that settlement -parameters need to be accessed many more times for a movement model (at each step) than -emigration or transfer parameters, and therefore there will be a performance gain in -avoiding nested if statements in Individual::moveStep() which would otherwise be required -to get the correct parameter values from the settlement arrays. Whether that particular -rationale is justified remains to be tested! -*/ - -//--------------------------------------------------------------------------- - -#if RSDEBUG -//extern ofstream DEBUGLOG; -extern void DebugGUI(string); -#endif - -//--------------------------------------------------------------------------- -#endif diff --git a/src/RScore/SubCommunity.cpp b/src/RScore/SubCommunity.cpp deleted file mode 100644 index 26685e3..0000000 --- a/src/RScore/SubCommunity.cpp +++ /dev/null @@ -1,1204 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -//--------------------------------------------------------------------------- - -#include "SubCommunity.h" -//--------------------------------------------------------------------------- - -ofstream outtraits; - -//--------------------------------------------------------------------------- - -SubCommunity::SubCommunity(Patch* pPch, int num) { -subCommNum = num; -pPatch = pPch; -// record the new sub-community no. in the patch -pPatch->setSubComm((intptr)this); -initial = false; -occupancy = 0; -} - -SubCommunity::~SubCommunity() { -pPatch->setSubComm(0); -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - delete popns[i]; -} -popns.clear(); -if (occupancy != 0) delete[] occupancy; -} - -intptr SubCommunity::getNum(void) { return subCommNum; } - -Patch* SubCommunity::getPatch(void) { return pPatch; } - -locn SubCommunity::getLocn(void) { -locn loc = pPatch->getCellLocn(0); -return loc; -} - -void SubCommunity::setInitial(bool b) { initial = b; } - -void SubCommunity::initialise(Landscape *pLandscape,Species *pSpecies) -{ -//patchLimits limits; -//locn loc; -int ncells; -landParams ppLand = pLandscape->getLandParams(); -initParams init = paramsInit->getInit(); -#if RSDEBUG -//DEBUGLOG << "SubCommunity::initialise(): subCommNum=" << subCommNum -// << " seedType="<< init.seedType -// << " popns.size()="<< popns.size() -// << endl; -#endif -// determine size of initial population -//int hx,nInds; -int nInds = 0; -if (subCommNum == 0 // matrix patch -|| !initial) // not in initial region or distribution - nInds = 0; -else { - float k = pPatch->getK(); - if (k > 0.0) { // patch is currently suitable for this species - switch (init.initDens) { - case 0: // at carrying capacity - nInds = (int)k; - break; - case 1: // at half carrying capacity - nInds = (int)(k/2.0); - break; - case 2: // specified no. per cell or density - ncells = pPatch->getNCells(); - if (ppLand.patchModel) { - nInds = (int)(init.indsHa * (float)(ncells*ppLand.resol*ppLand.resol) / 10000.0); - } - else { - nInds = init.indsCell * ncells; - } - break; - } - } - else nInds = 0; -} - -// create new population (even if it has no individuals) -//popns.push_back(new Population(pSpecies,pPatch,nInds)); -//newPopn(pSpecies,pPatch,nInds); - -// create new population only if it is non-zero or the matrix popn -if (subCommNum == 0 || nInds > 0) { - newPopn(pLandscape,pSpecies,pPatch,nInds); -} - -} - -// initialise a specified individual -void SubCommunity::initialInd(Landscape *pLandscape,Species *pSpecies, - Patch *pPatch,Cell *pCell,int ix) -{ - -demogrParams dem = pSpecies->getDemogr(); -stageParams sstruct = pSpecies->getStage(); -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -genomeData gen = pSpecies->getGenomeData(); -short stg,age,repInt; -Individual *pInd; -float probmale; -// bool movt; -// short moveType; - -// create new population if not already in existence -int npopns = (int)popns.size(); -if (npopns < 1) { - newPopn(pLandscape,pSpecies,pPatch,0); -} - -// create new individual -initInd iind = paramsInit->getInitInd(ix); -if (dem.stageStruct) { - stg = iind.stage; age = iind.age; repInt = sstruct.repInterval; -} -else { - age = stg = 1; repInt = 0; -} -if (dem.repType == 0) { - probmale = 0.0; -} -else { - if (iind.sex == 1) probmale = 1.0; else probmale = 0.0; -} -//if (trfr.moveModel) { -// movt = true; -// if (trfr.moveType) { -// -// } -//} -pInd = new Individual(pCell,pPatch,stg,age,repInt,probmale,trfr.moveModel,trfr.moveType); - -// add new individual to the population -// NB THIS WILL NEED TO BE CHANGED FOR MULTIPLE SPECIES... -popns[0]->recruit(pInd); - -if (emig.indVar || trfr.indVar || sett.indVar || gen.neutralMarkers) -{ - // individual variation - set up genetics - landData land = pLandscape->getLandData(); - pInd->setGenes(pSpecies,land.resol); -} - -} - -// Create a new population, and return its address -Population* SubCommunity::newPopn(Landscape *pLandscape,Species *pSpecies, - Patch *pPatch,int nInds) -{ -#if RSDEBUG -//DEBUGLOG << "SubCommunity::newPopn(): subCommNum = " << subCommNum -// << " pPatch = " << pPatch << " nInds = "<< nInds << endl; -#endif -landParams land = pLandscape->getLandParams(); -int npopns = (int)popns.size(); -popns.push_back(new Population(pSpecies,pPatch,nInds,land.resol)); -#if RSDEBUG -//DEBUGLOG << "SubCommunity::newPopn(): subCommNum = " << subCommNum -// << " npopns = " << npopns << " popns[npopns] = " << popns[npopns] -// << endl; -#endif -return popns[npopns]; -} - -popStats SubCommunity::getPopStats(void) { -popStats p,pop; -p.pSpecies = 0; p.spNum = 0; p.nInds = p.nAdults = p.nNonJuvs = 0; p.breeding = false; -p.pPatch = pPatch; -// FOR SINGLE SPECIES IMPLEMENTATION, THERE IS ONLY ONE POPULATION IN THE PATCH -//p = popns[0]->getStats(); -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations -#if RSDEBUG -//DEBUGLOG << "SubCommunity::getPopStats(): npops = " << npops -// << " i = " << i -// << " popns[i] = " << popns[i] << endl; -#endif - pop = popns[i]->getStats(); - p.pSpecies = pop.pSpecies; - p.spNum = pop.spNum; - p.nInds += pop.nInds; - p.nNonJuvs += pop.nNonJuvs; - p.nAdults += pop.nAdults; - p.breeding = pop.breeding; -#if RSDEBUG -//DEBUGLOG << "SubCommunity::getPopStats():" -// << " p.pSpecies = " << p.pSpecies -// << " p.pPatch = " << p.pPatch -// << " p.spNum = " << p.spNum -// << " p.nInds = " << p.nInds -// << endl; -#endif -} -return p; -} - -void SubCommunity::resetPopns(void) { -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - delete popns[i]; -} -popns.clear(); -// clear the list of populations in the corresponding patch -pPatch->resetPopn(); -} - -void SubCommunity::resetPossSettlers(void) { -if (subCommNum == 0) return; // not applicable in the matrix -//int npops = (int)popns.size(); -//for (int i = 0; i < npops; i++) { // all populations -// popns[i]->resetPossSettlers(); -//} -pPatch->resetPossSettlers(); -} - -// Extirpate all populations according to -// option 0 - random local extinction probability -// option 1 - local extinction probability gradient -// NB only applied for cell-based model -void SubCommunity::localExtinction(int option) { -double pExtinct = 0.0; -if (option == 0) { - envStochParams env = paramsStoch->getStoch(); - if (env.localExt) pExtinct = env.locExtProb; -} -else { - envGradParams grad = paramsGrad->getGradient(); - Cell *pCell = pPatch->getRandomCell(); // get only cell in the patch - // extinction prob is complement of cell gradient value plus any non-zero prob at the optimum - pExtinct = 1.0 - pCell->getEnvVal() + grad.extProbOpt; - if (pExtinct > 1.0) pExtinct = 1.0; -} -if (pRandom->Bernoulli(pExtinct)) { - int npops = (int)popns.size(); - for (int i = 0; i < npops; i++) { // all populations - popns[i]->extirpate(); - } -} -} - -// Action in event of patch becoming unsuitable owing to landscape change -void SubCommunity::patchChange(void) { -if (subCommNum == 0) return; // no reproduction in the matrix -Species *pSpecies; -float localK = 0.0; -int npops = (int)popns.size(); -// THE FOLLOWING MAY BE MORE EFFICIENT WHILST THERE IS ONLY ONE SPECIES ... -if (npops < 1) return; -localK = pPatch->getK(); -if (localK <= 0.0) { // patch in dynamic landscape has become unsuitable - for (int i = 0; i < npops; i++) { // all populations - pSpecies = popns[i]->getSpecies(); - demogrParams dem = pSpecies->getDemogr(); - if (dem.stageStruct) { - stageParams sstruct = pSpecies->getStage(); - if (sstruct.disperseOnLoss) popns[i]->allEmigrate(); - else popns[i]->extirpate(); - } - else { // non-stage-structured species is destroyed - popns[i]->extirpate(); - } - } -} -} - -void SubCommunity::reproduction(int resol,float epsGlobal,short rasterType,bool patchModel) -{ -if (subCommNum == 0) return; // no reproduction in the matrix -float localK,envval; -//Species *pSpecies; -Cell *pCell; -envGradParams grad = paramsGrad->getGradient(); -envStochParams env = paramsStoch->getStoch(); - -int npops = (int)popns.size(); -// THE FOLLOWING MAY BE MORE EFFICIENT WHILST THERE IS ONLY ONE SPECIES ... -if (npops < 1) return; - -localK = pPatch->getK(); -if (localK > 0.0) { - if (patchModel) { - envval = 1.0; // environmental gradient is currently not applied for patch-based model - } - else { // cell-based model - if (grad.gradient && grad.gradType == 2) - { // gradient in fecundity - Cell *pCell = pPatch->getRandomCell(); // locate the only cell in the patch - envval = pCell->getEnvVal(); - } - else envval = 1.0; - } - if (env.stoch && !env.inK) { // stochasticity in fecundity - if (env.local) { - if (!patchModel) { // only permitted for cell-based model - pCell = pPatch->getRandomCell(); - if (pCell != 0) envval += pCell->getEps(); - } - } - else { // global stochasticity - envval += epsGlobal; - } - } - for (int i = 0; i < npops; i++) { // all populations - popns[i]->reproduction(localK,envval,resol); - popns[i]->fledge(); - } -} -/* -else { // patch in dynamic landscape has become unsuitable - // NB - THIS WILL NEED TO BE MADE SPECIES-SPECIFIC... - Species *pSpecies; - for (int i = 0; i < npops; i++) { // all populations - pSpecies = popns[i]->getSpecies(); - demogrParams dem = pSpecies->getDemogr(); - if (dem.stageStruct) { - stageParams sstruct = pSpecies->getStage(); - if (sstruct.disperseOnLoss) popns[i]->allEmigrate(); - else popns[i]->extirpate(); - } - else { // non-stage-structured species is destroyed - popns[i]->extirpate(); - } - } -} -*/ - -/* -#if RSDEBUG -//if (npops > 0) { -// DEBUGLOG << "SubCommunity::reproduction(): this = " << this -// << " npops = " << npops << endl; -//} -#endif -#if RSDEBUG -//DEBUGLOG << "SubCommunity::reproduction(): patchNum = " << pPatch->getPatchNum() -// << " nCells " << pPatch->getNCells() -// << " localK = " << localK -// << endl; -#endif -*/ -} - -void SubCommunity::emigration(void) -{ -if (subCommNum == 0) return; // no emigration from the matrix -float localK; -int npops = (int)popns.size(); -// THE FOLLOWING MAY BE MORE EFFICIENT WHILST THERE IS ONLY ONE SPECIES ... -if (npops < 1) return; -localK = pPatch->getK(); -// NOTE that even if K is zero, it could have been >0 in previous time-step, and there -// might be emigrants if there is non-juvenile emigration -for (int i = 0; i < npops; i++) { // all populations -// localK = pPatch->getK(); - popns[i]->emigration(localK); -} -} - -// Remove emigrants from their natal patch and add to patch 0 (matrix) -void SubCommunity::initiateDispersal(SubCommunity* matrix) { -if (subCommNum == 0) return; // no dispersal initiation in the matrix -#if RSDEBUG -//DEBUGLOG << "SubCommunity::initiateDispersal(): this=" << this -// << " subCommNum=" << subCommNum -// << endl; -#endif -popStats pop; -disperser disp; - -int npops = (int)popns.size(); -#if RSDEBUG -//DEBUGLOG << "SubCommunity::initiateDispersal(): patchNum = " << patchNum -// << " npops " << npops -// << endl; -#endif -for (int i = 0; i < npops; i++) { // all populations - pop = popns[i]->getStats(); - for (int j = 0; j < pop.nInds; j++) { -#if RSDEBUG -//DEBUGLOG << "SubCommunity::initiateDispersal(): i = " << i -// << " j " << j -// << endl; -#endif - disp = popns[i]->extractDisperser(j); - if (disp.yes) { // disperser - has already been removed from natal population - // add to matrix population - matrix->recruit(disp.pInd,pop.pSpecies); - } - } - // remove pointers to emigrants - popns[i]->clean(); -} - -} - -// Add an individual into the local population of its species in the patch -void SubCommunity::recruit(Individual *pInd,Species *pSpecies) { -#if RSDEBUG -//DEBUGLOG << "SubCommunity::recruit(): this=" << this -// << endl; -#endif -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - if (pSpecies == popns[i]->getSpecies()) { - popns[i]->recruit(pInd); - } -} -} - -// Transfer through the matrix - run for the matrix sub-community only -#if RS_RCPP // included also SEASONAL -int SubCommunity::transfer(Landscape *pLandscape,short landIx,short nextseason) -#else -int SubCommunity::transfer(Landscape *pLandscape,short landIx) -#endif // SEASONAL || RS_RCPP -{ -#if RSDEBUG -//DEBUGLOG << "SubCommunity::transfer(): this=" << this -// << endl; -#endif -int ndispersers = 0; -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations -#if RS_RCPP // included also SEASONAL - ndispersers += popns[i]->transfer(pLandscape,landIx,nextseason); -#else - ndispersers += popns[i]->transfer(pLandscape,landIx); -#endif // SEASONAL || RS_RCPP -#if RSDEBUG -//DEBUGLOG << "SubCommunity::transfer(): i = " << i -// << " this = " << this -// << " subCommNum = " << subCommNum -// << " npops = " << npops -// << " popns[i] = " << popns[i] -// << " ndispersers = " << ndispersers -// << endl; -#endif -} -return ndispersers; -} - -//--------------------------------------------------------------------------- - -// Remove emigrants from patch 0 (matrix) and transfer to sub-community -// in which their destination co-ordinates fall -// This function is executed for the matrix patch only - -void SubCommunity::completeDispersal(Landscape *pLandscape,bool connect) -{ -#if RSDEBUG -//DEBUGLOG << "SubCommunity::completeDispersal(): this=" << this -// << endl; -#endif -//popStats pop; -//int popsize,subcomm; -int popsize; -disperser settler; -Species *pSpecies; -Population *pPop; -Patch *pPrevPatch; -Patch *pNewPatch; -Cell *pPrevCell; -SubCommunity *pSubComm; - -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - pSpecies = popns[i]->getSpecies(); - popsize = popns[i]->getNInds(); -#if RSDEBUG -//DEBUGLOG << "SubCommunity::completeDispersal(): i=" << i -// << " subCommNum=" << subCommNum -// << " pPatch=" << pPatch << " patchNum=" << pPatch->getPatchNum() -// << " npops=" << npops -// << " popns[i]=" << popns[i] -// << " popsize=" << popsize -// << endl; -#endif - for (int j = 0; j < popsize; j++) { - bool settled; - settler = popns[i]->extractSettler(j); - settled = settler.yes; - if (settled) { - // settler - has already been removed from matrix population - // in popns[i]->extractSettler() -#if RSDEBUG -//locn loc = pNewCell->getLocn(); -//DEBUGLOG << "SubCommunity::completeDispersal(): j=" << j << " settled=" << settled; -//#if GROUPDISP -//if (emig.groupdisp) { -//DEBUGLOG << " groupID=" << groupsettler.pGroup->getGroupID() -// << " groupsize=" << groupsettler.groupsize -// << " status=" << groupsettler.pGroup->getStatus(); -//} -//else { -//DEBUGLOG << " settler.pInd=" << settler.pInd; -//} -//#else -//DEBUGLOG << " settler.pInd=" << settler.pInd; -//#endif // GROUPDISP -//DEBUGLOG << " loc.x=" << loc.x << " loc.y=" << loc.y << endl; -#endif // RSDEBUG - // find new patch - pNewPatch = (Patch*)settler.pCell->getPatch(); - // find population within the patch (if there is one) -// subcomm = ppatch->getSubComm(); -// if (subcomm == 0) { // no sub-community has yet been set up -// // CANNOT SET UP A NEW ONE FROM WITHIN AN EXISTING ONE!!!!! -// } - pPop = (Population*)pNewPatch->getPopn((intptr)pSpecies); -#if RSDEBUG -//DEBUGLOG << "SubCommunity::completeDispersal(): j = " << j -// << " pCell = " << pCell << " ppatch = " << ppatch << " pPop = " << pPop -// << endl; -#endif - if (pPop == 0) { // settler is the first in a previously uninhabited patch - // create a new population in the corresponding sub-community - pSubComm = (SubCommunity*)pNewPatch->getSubComm(); -#if RSDEBUG -//DEBUGLOG << "SubCommunity::completeDispersal(): j = " << j -// << " pSubComm = " << pSubComm << endl; -#endif - pPop = pSubComm->newPopn(pLandscape,pSpecies,pNewPatch,0); -#if RSDEBUG -//DEBUGLOG << "SubCommunity::completeDispersal(): j=" << j -// << " pPop=" << pPop << endl; -#endif - } - pPop->recruit(settler.pInd); - if (connect) { // increment connectivity totals - int newpatch = pNewPatch->getSeqNum(); - pPrevCell = settler.pInd->getLocn(0); // previous cell - intptr patch = pPrevCell->getPatch(); - if (patch != 0) { - pPrevPatch = (Patch*)patch; - int prevpatch = pPrevPatch->getSeqNum(); - pLandscape->incrConnectMatrix(prevpatch,newpatch); - } - } - } - else { // for group dispersal only - } - } - // remove pointers in the matrix popn to settlers - popns[i]->clean(); -#if RSDEBUG -//pop = popns[i]->getStats(); -popsize = popns[i]->getNInds(); -//DEBUGLOG << "SubCommunity::completeDispersal(): i=" << i -// << " popns[i]=" << popns[i] -//// << " pop.pPatch = " << pop.pPatch -//// << " pop.nInds = " << pop.nInds -// << " popsize=" << popsize -// << endl; -#endif -} - -} - -//--------------------------------------------------------------------------- - -void SubCommunity::survival(short part,short option0,short option1) -{ -int npops = (int)popns.size(); -if (npops < 1) return; -if (part == 0) { - float localK = pPatch->getK(); - for (int i = 0; i < npops; i++) { // all populations - popns[i]->survival0(localK,option0,option1); - } -} -else { - for (int i = 0; i < npops; i++) { // all populations - popns[i]->survival1(); - } -} -} - -void SubCommunity::ageIncrement(void) { -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - popns[i]->ageIncrement(); -} -} - -// Find the population of a given species in a given patch -Population* SubCommunity::findPop(Species *pSp,Patch *pPch) { -#if RSDEBUG -DEBUGLOG << "SubCommunity::findPop(): this=" << this - << endl; -#endif - -Population *pPop = 0; -popStats pop; -int npops = (int)popns.size(); - -for (int i = 0; i < npops; i++) { // all populations - pop = popns[i]->getStats(); - if (pop.pSpecies == pSp && pop.pPatch == pPch) { // population located - pPop = popns[i]; - break; - } - else pPop = 0; -} -return pPop; -} - -//--------------------------------------------------------------------------- - -void SubCommunity::createOccupancy(int nrows) { -if (occupancy != 0) deleteOccupancy(); -if (nrows > 0) { - occupancy = new int[nrows]; - for (int i = 0; i < nrows; i++) occupancy[i] = 0; -} -} - -void SubCommunity::updateOccupancy(int row) { -#if RSDEBUG -//DEBUGLOG << "SubCommunity::updateOccupancy(): this=" << this -// << endl; -#endif -popStats pop; -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { - pop = popns[i]->getStats(); - if (pop.nInds > 0 && pop.breeding) { - occupancy[row]++; - i = npops; - } -} -} - -int SubCommunity::getOccupancy(int row) { -if (row >= 0) return occupancy[row]; -else return 0; -} - -void SubCommunity::deleteOccupancy(void) { - delete[] occupancy; - occupancy = 0; -} - -//--------------------------------------------------------------------------- -// Open population file and write header record -bool SubCommunity::outPopHeaders(Landscape *pLandscape,Species *pSpecies,int option) -{ -bool fileOK; -Population *pPop; -landParams land = pLandscape->getLandParams(); - -if (option == -999) { // close the file - // as all populations may have been deleted, set up a dummy one - // species is not necessary - pPop = new Population(); - fileOK = pPop->outPopHeaders(-999,land.patchModel); - delete pPop; -} -else { // open the file - // as no population has yet been created, set up a dummy one - // species is necessary, as columns depend on stage and sex structure - pPop = new Population(pSpecies,pPatch,0,land.resol); - fileOK = pPop->outPopHeaders(land.landNum,land.patchModel); - delete pPop; -} -return fileOK; -} - -// Write records to population file -void SubCommunity::outPop(Landscape *pLandscape,int rep,int yr,int gen) -{ -landParams land = pLandscape->getLandParams(); -envGradParams grad = paramsGrad->getGradient(); -envStochParams env = paramsStoch->getStoch(); -bool writeEnv = false; -bool gradK = false; -if (grad.gradient) { - writeEnv = true; - if (grad.gradType == 1) gradK = true; // ... carrying capacity -} -if (env.stoch) writeEnv = true; - -// generate output for each population within the sub-community (patch) -// provided that the patch is suitable (i.e. non-zero carrying capacity) -// or the population is above zero (possible if there is stochasticity or a moving gradient) -// or it is the matrix patch in a patch-based model -int npops = (int)popns.size(); -int patchnum; -//Species* pSpecies; -Cell *pCell; -float localK; -float eps = 0.0; -if (env.stoch) { - if (env.local) { - pCell = pPatch->getRandomCell(); - if (pCell != 0) eps = pCell->getEps(); - } - else { - eps = pLandscape->getGlobalStoch(yr); - } -} - -patchnum = pPatch->getPatchNum(); -for (int i = 0; i < npops; i++) { // all populations -// pSpecies = popns[i]->getSpecies(); - localK = pPatch->getK(); - if (localK > 0.0 || (land.patchModel && patchnum == 0)) { - popns[i]->outPopulation(rep,yr,gen,eps,land.patchModel,writeEnv,gradK); - } - else { - if (popns[i]->totalPop() > 0) { - popns[i]->outPopulation(rep,yr,gen,eps,land.patchModel,writeEnv,gradK); - } - } -} -} - -// Write records to individuals file -void SubCommunity::outInds(Landscape *pLandscape,int rep,int yr,int gen,int landNr) { -landParams ppLand = pLandscape->getLandParams(); -if (landNr >= 0) { // open the file - popns[0]->outIndsHeaders(rep,landNr,ppLand.patchModel); - return; -} -if (landNr == -999) { // close the file - popns[0]->outIndsHeaders(rep,-999,ppLand.patchModel); - return; -} -// generate output for each population within the sub-community (patch) -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - popns[i]->outIndividual(pLandscape,rep,yr,gen,pPatch->getPatchNum()); -} -} - -// Write records to individuals file -void SubCommunity::outGenetics(int rep,int yr,int gen,int landNr) -{ -//landParams ppLand = pLandscape->getLandParams(); -if (landNr >= 0) { // open the file - popns[0]->outGenetics(rep,yr,landNr); - return; -} -if (landNr == -999) { // close the file - popns[0]->outGenetics(rep,yr,landNr); - return; -} -// generate output for each population within the sub-community (patch) -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - popns[i]->outGenetics(rep,yr,landNr); -} -} - -// Population size of a specified stage -int SubCommunity::stagePop(int stage) { -int popsize = 0; -int npops = (int)popns.size(); -for (int i = 0; i < npops; i++) { // all populations - popsize += popns[i]->stagePop(stage); -} -return popsize; -} - -// Open traits file and write header record -bool SubCommunity::outTraitsHeaders(Landscape *pLandscape,Species *pSpecies,int landNr) -{ -//Population *pPop; -landParams land = pLandscape->getLandParams(); -if (landNr == -999) { // close file - if (outtraits.is_open()) outtraits.close(); - outtraits.clear(); - return true; -} - -string name; -emigRules emig = pSpecies->getEmig(); -trfrRules trfr = pSpecies->getTrfr(); -settleType sett = pSpecies->getSettle(); -simParams sim = paramsSim->getSim(); - -string DirOut = paramsSim->getDir(2); -if (sim.batchMode) { - if (land.patchModel){ - name = DirOut - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(landNr) - + "_TraitsXpatch.txt"; - } - else{ - name = DirOut - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(landNr) - + "_TraitsXcell.txt"; - } -} -else { - if (land.patchModel){ - name = DirOut + "Sim" + Int2Str(sim.simulation) + "_TraitsXpatch.txt"; - } - else{ - name = DirOut + "Sim" + Int2Str(sim.simulation) + "_TraitsXcell.txt"; - } -} -outtraits.open(name.c_str()); - -outtraits << "Rep\tYear\tRepSeason"; -if (land.patchModel) outtraits << "\tPatchID"; -else - outtraits << "\tx\ty"; - -if (emig.indVar) { - if (emig.sexDep) { - if (emig.densDep) { - outtraits << "\tF_meanD0\tF_stdD0\tM_meanD0\tM_stdD0"; - outtraits << "\tF_meanAlpha\tF_stdAlpha\tM_meanAlpha\tM_stdAlpha"; - outtraits << "\tF_meanBeta\tF_stdBeta\tM_meanBeta\tM_stdBeta"; - } - else { - outtraits << "\tF_meanEP\tF_stdEP\tM_meanEP\tM_stdEP"; - } - } - else { - if (emig.densDep) { - outtraits << "\tmeanD0\tstdD0\tmeanAlpha\tstdAlpha"; - outtraits << "\tmeanBeta\tstdBeta"; - } - else { - outtraits << "\tmeanEP\tstdEP"; - } - } -} -if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 1) { - outtraits << "\tmeanDP\tstdDP\tmeanGB\tstdGB"; - outtraits << "\tmeanAlphaDB\tstdAlphaDB\tmeanBetaDB\tstdBetaDB"; - } - if (trfr.moveType == 2) { - outtraits << "\tmeanStepLength\tstdStepLength\tmeanRho\tstdRho"; - } - } - else { - if (trfr.sexDep) { - outtraits << "\tF_mean_distI\tF_std_distI\tM_mean_distI\tM_std_distI"; - if (trfr.twinKern) - outtraits << "\tF_mean_distII\tF_std_distII\tM_mean_distII\tM_std_distII" - << "\tF_meanPfirstKernel\tF_stdPfirstKernel" - << "\tM_meanPfirstKernel\tM_stdPfirstKernel"; - } - else { - outtraits << "\tmean_distI\tstd_distI"; - if (trfr.twinKern) - outtraits << "\tmean_distII\tstd_distII\tmeanPfirstKernel\tstdPfirstKernel"; - } - } -} -if (sett.indVar) { - if (sett.sexDep) { - outtraits << "\tF_meanS0\tF_stdS0\tM_meanS0\tM_stdS0"; - outtraits << "\tF_meanAlphaS\tF_stdAlphaS\tM_meanAlphaS\tM_stdAlphaS"; - outtraits << "\tF_meanBetaS\tF_stdBetaS\tM_meanBetaS\tM_stdBetaS"; - } - else { - outtraits << "\tmeanS0\tstdS0"; - outtraits << "\tmeanAlphaS\tstdAlphaS"; - outtraits << "\tmeanBetaS\tstdBetaS"; - } -} -outtraits << endl; - -return outtraits.is_open(); -} - -// Write records to traits file and return aggregated sums -traitsums SubCommunity::outTraits(traitCanvas tcanv, - Landscape *pLandscape,int rep,int yr,int gen,bool commlevel) -{ -int popsize,ngenes; -landParams land = pLandscape->getLandParams(); -simParams sim = paramsSim->getSim(); -bool writefile = false; -if (sim.outTraitsCells && yr%sim.outIntTraitCell == 0 && !commlevel) - writefile = true; -traitsums ts,poptraits; -for (int i = 0; i < NSEXES; i++) { - ts.ninds[i] = 0; - ts.sumD0[i] = ts.ssqD0[i] = 0.0; - ts.sumAlpha[i] = ts.ssqAlpha[i] = 0.0; ts.sumBeta[i] = ts.ssqBeta[i] = 0.0; - ts.sumDist1[i] = ts.ssqDist1[i] = 0.0; ts.sumDist2[i] = ts.ssqDist2[i] = 0.0; - ts.sumProp1[i] = ts.ssqProp1[i] = 0.0; - ts.sumDP[i] = ts.ssqDP[i] = 0.0; - ts.sumGB[i] = ts.ssqGB[i] = 0.0; - ts.sumAlphaDB[i] = ts.ssqAlphaDB[i] = 0.0; - ts.sumBetaDB[i] = ts.ssqBetaDB[i] = 0.0; - ts.sumStepL[i] = ts.ssqStepL[i] = 0.0; ts.sumRho[i] = ts.ssqRho[i] = 0.0; - ts.sumS0[i] = ts.ssqS0[i] = 0.0; - ts.sumAlphaS[i] = ts.ssqAlphaS[i] = 0.0; ts.sumBetaS[i] = ts.ssqBetaS[i] = 0.0; -} - -// generate output for each population within the sub-community (patch) -// provided that the patch is suitable (i.e. non-zero carrying capacity) -int npops = (int)popns.size(); -Species* pSpecies; -float localK; - -for (int i = 0; i < npops; i++) { // all populations - localK = pPatch->getK(); - if (localK > 0.0 && popns[i]->getNInds() > 0) { - pSpecies = popns[i]->getSpecies(); - demogrParams dem = pSpecies->getDemogr(); - emigRules emig = pSpecies->getEmig(); - trfrRules trfr = pSpecies->getTrfr(); - settleType sett = pSpecies->getSettle(); - poptraits = popns[i]->getTraits(pSpecies); - - if (writefile) { - outtraits << rep << "\t" << yr << "\t" << gen; - if (land.patchModel) { - outtraits << "\t" << pPatch->getPatchNum(); - } - else { - locn loc = pPatch->getCellLocn(0); - outtraits << "\t" << loc.x << "\t" << loc.y; - } - } - - if (emig.indVar) { - if (emig.sexDep) { // must be a sexual species - ngenes = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ngenes = 1; - } - else { // sexual reproduction - ngenes = 1; - } - } - double mnD0[2],mnAlpha[2],mnBeta[2],sdD0[2],sdAlpha[2],sdBeta[2]; - for (int g = 0; g < ngenes; g++) { - mnD0[g] = mnAlpha[g] = mnBeta[g] = sdD0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - // individuals may have been counted by sex if there was - // sex dependency in another dispersal phase - if (ngenes == 2) popsize = poptraits.ninds[g]; - else popsize = poptraits.ninds[0] + poptraits.ninds[1]; - if (popsize > 0) { - mnD0[g] = poptraits.sumD0[g] / (double)popsize; - mnAlpha[g] = poptraits.sumAlpha[g] / (double)popsize; - mnBeta[g] = poptraits.sumBeta[g] / (double)popsize; - if (popsize > 1) { - sdD0[g] = poptraits.ssqD0[g]/(double)popsize - mnD0[g]*mnD0[g]; - if (sdD0[g] > 0.0) sdD0[g] = sqrt(sdD0[g]); else sdD0[g] = 0.0; - sdAlpha[g] = poptraits.ssqAlpha[g]/(double)popsize - mnAlpha[g]*mnAlpha[g]; - if (sdAlpha[g] > 0.0) sdAlpha[g] = sqrt(sdAlpha[g]); else sdAlpha[g] = 0.0; - sdBeta[g] = poptraits.ssqBeta[g]/(double)popsize - mnBeta[g]*mnBeta[g]; - if (sdBeta[g] > 0.0) sdBeta[g] = sqrt(sdBeta[g]); else sdBeta[g] = 0.0; - } - else { - sdD0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - } - } - } - if (writefile) { - if (emig.sexDep) { - outtraits << "\t" << mnD0[0] << "\t" << sdD0[0]; - outtraits << "\t" << mnD0[1] << "\t" << sdD0[1]; - if (emig.densDep) { - outtraits << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outtraits << "\t" << mnAlpha[1] << "\t" << sdAlpha[1]; - outtraits << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - outtraits << "\t" << mnBeta[1] << "\t" << sdBeta[1]; - } - } - else { // sex-independent - outtraits << "\t" << mnD0[0] << "\t" << sdD0[0]; - if (emig.densDep) { - outtraits << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outtraits << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - } - } - } - } - - if (trfr.indVar) { - if (trfr.moveModel) { - // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT - ngenes = 1; - } - else { - if (trfr.sexDep) { // must be a sexual species - ngenes = 2; - } - else { - ngenes = 1; - } - } - double mnDist1[2], mnDist2[2], mnProp1[2], mnStepL[2], mnRho[2]; - double sdDist1[2],sdDist2[2],sdProp1[2],sdStepL[2],sdRho[2]; - double mnDP[2], mnGB[2], mnAlphaDB[2], mnBetaDB[2]; - double sdDP[2],sdGB[2],sdAlphaDB[2],sdBetaDB[2]; - for (int g = 0; g < ngenes; g++) { - mnDist1[g] = mnDist2[g] = mnProp1[g] = mnStepL[g] = mnRho[g] = 0.0; - sdDist1[g] = sdDist2[g] = sdProp1[g] = sdStepL[g] = sdRho[g] = 0.0; - mnDP[g] = mnGB[g] = mnAlphaDB[g] = mnBetaDB[g] = 0.0; - sdDP[g] = sdGB[g] = sdAlphaDB[g] = sdBetaDB[g] = 0.0; - // individuals may have been counted by sex if there was - // sex dependency in another dispersal phase - if (ngenes == 2) popsize = poptraits.ninds[g]; - else popsize = poptraits.ninds[0] + poptraits.ninds[1]; - if (popsize > 0) { - mnDist1[g] = poptraits.sumDist1[g] / (double)popsize; - mnDist2[g] = poptraits.sumDist2[g] / (double)popsize; - mnProp1[g] = poptraits.sumProp1[g] / (double)popsize; - mnStepL[g] = poptraits.sumStepL[g] / (double)popsize; - mnRho[g] = poptraits.sumRho[g] / (double)popsize; - mnDP[g] = poptraits.sumDP[g] / (double)popsize; - mnGB[g] = poptraits.sumGB[g] / (double)popsize; - mnAlphaDB[g] = poptraits.sumAlphaDB[g] / (double)popsize; - mnBetaDB[g] = poptraits.sumBetaDB[g] / (double)popsize; - if (popsize > 1) { - sdDist1[g] = poptraits.ssqDist1[g]/(double)popsize - mnDist1[g]*mnDist1[g]; - if (sdDist1[g] > 0.0) sdDist1[g] = sqrt(sdDist1[g]); else sdDist1[g] = 0.0; - sdDist2[g] = poptraits.ssqDist2[g]/(double)popsize - mnDist2[g]*mnDist2[g]; - if (sdDist2[g] > 0.0) sdDist2[g] = sqrt(sdDist2[g]); else sdDist2[g] = 0.0; - sdProp1[g] = poptraits.ssqProp1[g]/(double)popsize - mnProp1[g]*mnProp1[g]; - if (sdProp1[g] > 0.0) sdProp1[g] = sqrt(sdProp1[g]); else sdProp1[g] = 0.0; - sdStepL[g] = poptraits.ssqStepL[g]/(double)popsize - mnStepL[g]*mnStepL[g]; - if (sdStepL[g] > 0.0) sdStepL[g] = sqrt(sdStepL[g]); else sdStepL[g] = 0.0; - sdRho[g] = poptraits.ssqRho[g]/(double)popsize - mnRho[g]*mnRho[g]; - if (sdRho[g] > 0.0) sdRho[g] = sqrt(sdRho[g]); else sdRho[g] = 0.0; - sdDP[g] = poptraits.ssqDP[g]/(double)popsize - mnDP[g]*mnDP[g]; - if (sdDP[g] > 0.0) sdDP[g] = sqrt(sdDP[g]); else sdDP[g] = 0.0; - sdGB[g] = poptraits.ssqGB[g]/(double)popsize - mnGB[g]*mnGB[g]; - if (sdGB[g] > 0.0) sdGB[g] = sqrt(sdGB[g]); else sdGB[g] = 0.0; - sdAlphaDB[g] = poptraits.ssqAlphaDB[g]/(double)popsize - mnAlphaDB[g]*mnAlphaDB[g]; - if (sdAlphaDB[g] > 0.0) sdAlphaDB[g] = sqrt(sdAlphaDB[g]); else sdAlphaDB[g] = 0.0; - sdBetaDB[g] = poptraits.ssqBetaDB[g]/(double)popsize - mnBetaDB[g]*mnBetaDB[g]; - if (sdBetaDB[g] > 0.0) sdBetaDB[g] = sqrt(sdBetaDB[g]); else sdBetaDB[g] = 0.0; - } - } - } - if (writefile) { - if (trfr.moveModel) { - if (trfr.moveType == 1) { - outtraits << "\t" << mnDP[0] << "\t" << sdDP[0]; - outtraits << "\t" << mnGB[0] << "\t" << sdGB[0]; - outtraits << "\t" << mnAlphaDB[0] << "\t" << sdAlphaDB[0]; - outtraits << "\t" << mnBetaDB[0] << "\t" << sdBetaDB[0]; - } - if (trfr.moveType == 2) { - outtraits << "\t" << mnStepL[0] << "\t" << sdStepL[0]; - outtraits << "\t" << mnRho[0] << "\t" << sdRho[0]; - } - } - else { - if (trfr.sexDep) { - outtraits << "\t" << mnDist1[0] << "\t" << sdDist1[0]; - outtraits << "\t" << mnDist1[1] << "\t" << sdDist1[1]; - if (trfr.twinKern) - { - outtraits << "\t" << mnDist2[0] << "\t" << sdDist2[0]; - outtraits << "\t" << mnDist2[1] << "\t" << sdDist2[1]; - outtraits << "\t" << mnProp1[0] << "\t" << sdProp1[0]; - outtraits << "\t" << mnProp1[1] << "\t" << sdProp1[1]; - } - } - else { // sex-independent - outtraits << "\t" << mnDist1[0] << "\t" << sdDist1[0]; - if (trfr.twinKern) - { - outtraits << "\t" << mnDist2[0] << "\t" << sdDist2[0]; - outtraits << "\t" << mnProp1[0] << "\t" << sdProp1[0]; - } - } - } - } - } - - if (sett.indVar) { - if (sett.sexDep) { // must be a sexual species - ngenes = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ngenes = 1; - } - else { // sexual reproduction - ngenes = 1; - } - } - // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT -// ngenes = 1; - double mnS0[2],mnAlpha[2],mnBeta[2],sdS0[2],sdAlpha[2],sdBeta[2]; - for (int g = 0; g < ngenes; g++) { - mnS0[g] = mnAlpha[g] = mnBeta[g] = sdS0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - // individuals may have been counted by sex if there was - // sex dependency in another dispersal phase - if (ngenes == 2) popsize = poptraits.ninds[g]; - else popsize = poptraits.ninds[0] + poptraits.ninds[1]; - if (popsize > 0) { - mnS0[g] = poptraits.sumS0[g] / (double)popsize; - mnAlpha[g] = poptraits.sumAlphaS[g] / (double)popsize; - mnBeta[g] = poptraits.sumBetaS[g] / (double)popsize; - if (popsize > 1) { - sdS0[g] = poptraits.ssqS0[g]/(double)popsize - mnS0[g]*mnS0[g]; - if (sdS0[g] > 0.0) sdS0[g] = sqrt(sdS0[g]); else sdS0[g] = 0.0; - sdAlpha[g] = poptraits.ssqAlphaS[g]/(double)popsize - mnAlpha[g]*mnAlpha[g]; - if (sdAlpha[g] > 0.0) sdAlpha[g] = sqrt(sdAlpha[g]); else sdAlpha[g] = 0.0; - sdBeta[g] = poptraits.ssqBetaS[g]/(double)popsize - mnBeta[g]*mnBeta[g]; - if (sdBeta[g] > 0.0) sdBeta[g] = sqrt(sdBeta[g]); else sdBeta[g] = 0.0; - } - else { - sdS0[g] = sdAlpha[g] = sdBeta[g] = 0.0; - } - } - } - if (writefile) { - if (sett.sexDep) { - outtraits << "\t" << mnS0[0] << "\t" << sdS0[0]; - outtraits << "\t" << mnS0[1] << "\t" << sdS0[1]; - outtraits << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outtraits << "\t" << mnAlpha[1] << "\t" << sdAlpha[1]; - outtraits << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - outtraits << "\t" << mnBeta[1] << "\t" << sdBeta[1]; - } - else { // sex-independent - outtraits << "\t" << mnS0[0] << "\t" << sdS0[0]; - outtraits << "\t" << mnAlpha[0] << "\t" << sdAlpha[0]; - outtraits << "\t" << mnBeta[0] << "\t" << sdBeta[0]; - } - } - } - - if (writefile) outtraits << endl; - - for (int s = 0; s < NSEXES; s++) { - ts.ninds[s] += poptraits.ninds[s]; - ts.sumD0[s] += poptraits.sumD0[s]; ts.ssqD0[s] += poptraits.ssqD0[s]; - ts.sumAlpha[s] += poptraits.sumAlpha[s]; ts.ssqAlpha[s] += poptraits.ssqAlpha[s]; - ts.sumBeta[s] += poptraits.sumBeta[s]; ts.ssqBeta[s] += poptraits.ssqBeta[s]; - ts.sumDist1[s] += poptraits.sumDist1[s]; ts.ssqDist1[s] += poptraits.ssqDist1[s]; - ts.sumDist2[s] += poptraits.sumDist2[s]; ts.ssqDist2[s] += poptraits.ssqDist2[s]; - ts.sumProp1[s] += poptraits.sumProp1[s]; ts.ssqProp1[s] += poptraits.ssqProp1[s]; - ts.sumDP[s] += poptraits.sumDP[s]; ts.ssqDP[s] += poptraits.ssqDP[s]; - ts.sumGB[s] += poptraits.sumGB[s]; ts.ssqGB[s] += poptraits.ssqGB[s]; - ts.sumAlphaDB[s] += poptraits.sumAlphaDB[s]; ts.ssqAlphaDB[s] += poptraits.ssqAlphaDB[s]; - ts.sumBetaDB[s] += poptraits.sumBetaDB[s]; ts.ssqBetaDB[s] += poptraits.ssqBetaDB[s]; - ts.sumStepL[s] += poptraits.sumStepL[s]; ts.ssqStepL[s] += poptraits.ssqStepL[s]; - ts.sumRho[s] += poptraits.sumRho[s]; ts.ssqRho[s] += poptraits.ssqRho[s]; - ts.sumS0[s] += poptraits.sumS0[s]; ts.ssqS0[s] += poptraits.ssqS0[s]; - ts.sumAlphaS[s] += poptraits.sumAlphaS[s]; ts.ssqAlphaS[s] += poptraits.ssqAlphaS[s]; - ts.sumBetaS[s] += poptraits.sumBetaS[s]; ts.ssqBetaS[s] += poptraits.ssqBetaS[s]; -#if RSDEBUG -//DEBUGLOG << "SubCommunity::outTraits(): i=" << i << " popns[i]=" << popns[i] -// << " s=" << s -//// << " poptraits.sumRho[s]= " << poptraits.sumRho[s] -//// << " ts.sumRho[s]= " << ts.sumRho[s] -// << " poptraits.sumDP[s]= " << poptraits.sumDP[s] << " poptraits.ssqDP[s]= " << poptraits.ssqDP[s] -// << " ts.sumDP[s]= " << ts.sumDP[s] << " ts.ssqDP[s]= " << ts.ssqDP[s] -// << " poptraits.sumGB[s]= " << poptraits.sumGB[s] << " poptraits.ssqGB[s]= " << poptraits.ssqGB[s] -// << " ts.sumGB[s]= " << ts.sumGB[s] << " ts.ssqGB[s]= " << ts.ssqGB[s] -// << endl; -#endif - } - } -} -return ts; -} - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - - diff --git a/src/RScore/SubCommunity.h b/src/RScore/SubCommunity.h deleted file mode 100644 index ece9281..0000000 --- a/src/RScore/SubCommunity.h +++ /dev/null @@ -1,216 +0,0 @@ -/*---------------------------------------------------------------------------- - * - * Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, 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 . - * - --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -RangeShifter v2.0 SubCommunity - -Implements the SubCommunity class - -There is ONE instance of a SubCommunity for each Patch in the Landscape -(including the matrix). The SubCommunity holds a number of Populations, one for -each Species represented in the simulation. -CURRENTLY the number of Populations withn a SubCommunity is LIMITED TO ONE. - -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K. -and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial -eco-evolutionary dynamics and species’ responses to environmental changes. -Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162 - -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen - -Last updated: 26 October 2021 by Steve Palmer - -------------------------------------------------------------------------------*/ - -#ifndef SubCommunityH -#define SubCommunityH - -#include -#include -using namespace std; - -#if RS_RCPP -#include "../Version.h" -#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif - -#include "Parameters.h" -#include "Landscape.h" -#include "Population.h" - -//--------------------------------------------------------------------------- - -struct traitCanvas { // canvases for drawing variable traits - int *pcanvas[NTRAITS]; // dummy variables for batch version -}; - -class SubCommunity { - -public: - SubCommunity(Patch*,int); - ~SubCommunity(void); - intptr getNum(void); - Patch* getPatch(void); - locn getLocn(void); - - // functions to manage populations occurring in the SubCommunity - popStats getPopStats(void); - void setInitial(bool); - void initialise(Landscape*,Species*); - void initialInd(Landscape*,Species*,Patch*,Cell*,int); - Population* newPopn( // Create a new population, and return its address - Landscape*, // pointer to Landscape - Species*, // pointer to Species - Patch*, // pointer to Patch - int // no. of Individuals - ); - void resetPopns(void); - void resetPossSettlers(void); - void localExtinction( // Extirpate all populations - int // option: 0 - random local extinction probability - // 1 - local extinction probability gradient - ); - void patchChange(void); - void reproduction( - int, // Landscape resolution - float, // epsilon - global stochasticity value - short, // raster type (see Landscape) - bool // TRUE for a patch-based model, FALSE for a cell-based model - ); - void emigration(void); - // Remove emigrants from their natal patch and add to patch 0 (matrix) - void initiateDispersal( - SubCommunity* // pointer to matrix SubCommunity - ); -// Add an individual into the local population of its species in the patch - void recruit( - Individual*, // pointer to Individual - Species* // pointer to Species - ); -#if RS_RCPP // included also SEASONAL - int transfer( // Transfer through matrix - run for matrix SubCommunity only - Landscape*, // pointer to Landscape - short, // landscape change index - short // season / year - ); -#else - int transfer( // Transfer through matrix - run for matrix SubCommunity only - Landscape*, // pointer to Landscape - short // landscape change index - ); -#endif // SEASONAL || RS_RCPP - // Remove emigrants from patch 0 (matrix) and transfer to SubCommunity in which - // their destination co-ordinates fall (executed for the matrix patch only) - void completeDispersal( - Landscape*, // pointer to Landscape - bool // TRUE to increment connectivity totals - ); - void survival( - short, // part: 0 = determine survival & development, - // 1 = apply survival changes to the population - short, // option0: 0 = stage 0 (juveniles) only ) - // 1 = all stages ) used by part 0 only - // 2 = stage 1 and above (all non-juvs) ) - short // option1: 0 - development only (when survival is annual) - // 1 - development and survival - ); - void ageIncrement(void); - // Find the population of a given species in a given patch - Population* findPop(Species*,Patch*); - void createOccupancy( - int // no. of rows = (no. of years / interval) + 1 - ); - void updateOccupancy( - int // row = (no. of years / interval) - ); - int getOccupancy( - int // row = (no. of years / interval) - ); - void deleteOccupancy(void); - - bool outPopHeaders( // Open population file and write header record - Landscape*, // pointer to Landscape - Species*, // pointer to Species - int // option: -999 to close the file - ); - void outPop( // Write records to population file - Landscape*, // pointer to Landscape - int, // replicate - int, // year - int // generation - ); - - void outInds( // Write records to individuals file - Landscape*, // pointer to Landscape - int, // replicate - int, // year - int, // generation - int // Landscape number (>= 0 to open the file, -999 to close the file - // -1 to write data records) - ); - void outGenetics( // Write records to genetics file - int, // replicate - int, // year - int, // generation - int // Landscape number (>= 0 to open the file, -999 to close the file - // -1 to write data records) - ); - bool outTraitsHeaders( // Open traits file and write header record - Landscape*, // pointer to Landscape - Species*, // pointer to Species - int // Landscape number (-999 to close the file) - ); - traitsums outTraits( // Write records to traits file and return aggregated sums - traitCanvas, // pointers to canvases for drawing variable traits - // in the batch version, these are replaced by integers set to zero - Landscape*, // pointer to Landscape - int, // replicate - int, // year - int, // generation - bool // true if called to summarise data at community level - ); - int stagePop( // Population size of a specified stage - int // stage - ); - -private: - intptr subCommNum; // SubCommunity number - // 0 is reserved for the SubCommunity in the inter-patch matrix -// intptr *occupancy; // pointer to occupancy array - Patch *pPatch; - int *occupancy; // pointer to occupancy array - std::vector popns; - bool initial; // WILL NEED TO BE CHANGED FOR MULTIPLE SPECIES ... - -}; - -extern paramGrad *paramsGrad; -extern paramStoch *paramsStoch; -extern paramInit *paramsInit; - -//--------------------------------------------------------------------------- -#endif diff --git a/src/RScore/Utils.cpp b/src/RScore/Utils.cpp deleted file mode 100644 index 9d36b92..0000000 --- a/src/RScore/Utils.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "Utils.h" - -const string Int2Str(const int x) -{ - ostringstream o; - if (!(o << x)) return "ERROR"; - return o.str(); -} -const string Float2Str(const float x) { - ostringstream o; - if (!(o << x)) return "ERROR"; - return o.str(); -} -const string Double2Str(const double x) { - ostringstream o; - if (!(o << x)) return "ERROR"; - return o.str(); -} - -// Evaluate a lambda and assert we get the correct error -void assert_error(const string& exptd_err_msg, void (*lambda)(void)) { - string err_msg{ "No error.\n" }; - try { lambda(); } // evaluate - catch (exception& e) { err_msg = e.what(); } - assert(err_msg == exptd_err_msg); -} \ No newline at end of file diff --git a/src/RScore/Utils.h b/src/RScore/Utils.h deleted file mode 100644 index 34854a7..0000000 --- a/src/RScore/Utils.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef UtilsH -#define UtilsH - -#include -#include -#include - -#include -using namespace std; - -const string Int2Str(const int x); -const string Float2Str(const float x); -const string Double2Str(const double x); - -// Evaluate a lambda and assert we get the correct error -void assert_error(const string& exptd_err_msg, void (*x)(void)); - -#endif // UtilsH From f6e9df703768c6911582b3aa25fec21976962fd8 Mon Sep 17 00:00:00 2001 From: Theo Pannetier Date: Fri, 24 Nov 2023 16:26:44 +0000 Subject: [PATCH 17/17] build RangeShiftR excluding RScore/Main.cpp --- RangeShiftR/src/Makevars | 7 ++++++- RangeShiftR/src/Makevars.win | 9 +++++++-- RangeShiftR/src/Rinterface.cpp | 29 ----------------------------- 3 files changed, 13 insertions(+), 32 deletions(-) diff --git a/RangeShiftR/src/Makevars b/RangeShiftR/src/Makevars index 5744dce..06bd40d 100644 --- a/RangeShiftR/src/Makevars +++ b/RangeShiftR/src/Makevars @@ -1,4 +1,9 @@ -SOURCES = $(wildcard RScore/*.cpp) +# all except RScore/main.cpp +SOURCES = RScore/Cell.cpp RScore/Community.cpp RScore/FractalGenerator.cpp \ + RScore/Genome.cpp RScore/Individual.cpp RScore/Landscape.cpp \ + RScore/Model.cpp RScore/Parameters.cpp RScore/Patch.cpp \ + RScore/Population.cpp RScore/RandomCheck.cpp RScore/RSrandom.cpp \ + RScore/Species.cpp RScore/SubCommunity.cpp RScore/Utils.cpp OBJECTS = Rinterface.o RcppExports.o $(SOURCES:.cpp=.o) diff --git a/RangeShiftR/src/Makevars.win b/RangeShiftR/src/Makevars.win index 477f4d0..2130c9e 100644 --- a/RangeShiftR/src/Makevars.win +++ b/RangeShiftR/src/Makevars.win @@ -1,7 +1,12 @@ -SOURCES = $(wildcard RScore/*.cpp) +# all except RScore/main.cpp +SOURCES = RScore/Cell.cpp RScore/Community.cpp RScore/FractalGenerator.cpp \ + RScore/Genome.cpp RScore/Individual.cpp RScore/Landscape.cpp \ + RScore/Model.cpp RScore/Parameters.cpp RScore/Patch.cpp \ + RScore/Population.cpp RScore/RandomCheck.cpp RScore/RSrandom.cpp \ + RScore/Species.cpp RScore/SubCommunity.cpp RScore/Utils.cpp OBJECTS = Rinterface.o RcppExports.o $(SOURCES:.cpp=.o) CXX_STD = CXX11 -PKG_CXXFLAGS = -DRSWIN64 -w +PKG_CXXFLAGS = -DRSWIN64 -DRS_RCPP -w #PKG_CXXFLAGS = -H \ No newline at end of file diff --git a/RangeShiftR/src/Rinterface.cpp b/RangeShiftR/src/Rinterface.cpp index 6a597b5..3ee8ca4 100644 --- a/RangeShiftR/src/Rinterface.cpp +++ b/RangeShiftR/src/Rinterface.cpp @@ -4066,35 +4066,6 @@ void StreamErrorR(string filename) /* Batch mode of v2.0 currently has no facility to save maps (unless initiated from GUI). */ -const string Int2Str(const int x) -{ - ostringstream o; - if(!(o << x)) - return "ERROR"; - return o.str(); -} -const string Int2Str(const int x, unsigned int width) -{ - ostringstream o; - if(!(o << std::setfill('0') << std::setw(width) << x)) - return "ERROR"; - return o.str(); -} -const string Float2Str(const float x) -{ - ostringstream o; - if(!(o << x)) - return "ERROR"; - return o.str(); -} -const string Double2Str(const double x) -{ - ostringstream o; - if(!(o << x)) - return "ERROR"; - return o.str(); -} - void MemoLine(string msg) { // dummy function for batch version