diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..dd84ea7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..8a18e08 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for RangeShifter +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/improve-existing-content.md b/.github/ISSUE_TEMPLATE/improve-existing-content.md new file mode 100644 index 0000000..8950ab1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/improve-existing-content.md @@ -0,0 +1,10 @@ +--- +name: Improve existing content +about: 'Make a suggestion to improve the R package ' +title: '' +labels: '' +assignees: '' + +--- + + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..57a075e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,93 @@ +# The RangeShifter platform - An eco-evolutionary modelling framework + +## How to contribute + +Thank you for your interest in contributing to the RangeShifter platform. +In this document we will give you guidance on how to contribute to the RangeShifter project regarding issues, bug fixing and adding new features. We distinguish between contributing to the RangeShifter core code and the different interfaces - in this case the R package. + +## Repo structure + +![Rangeshifter repo structure](RangeShiftR/man/figures/RS_repos.png) + +RangeShifter is distributed with three user interfaces, each living in their own repo: + +- the RangeShifter GUI (clickable Windows interface)* +- RangeShifter Batch Mode (command line interface) +- the RangeShiftR package (R interface) + +All three share the same source code for the core simulation (i.e., the actual model), which lives in its own repo (RScore). Each of the interfaces keeps a copy of this core code in a subfolder called RScore, kept in sync with the RScore repo via a git subtree (see [Git subtree usage section](https://github.com/RangeShifter/RScore?tab=readme-ov-file#usage-git-subtree). + +⚠️ If you wish to propose a change to the core code of the simulation, please do so *in the [RScore](https://github.com/RangeShifter/RScore) repo*, rather than in the RScore folder of either interface. + +*The RangeShifter GUI is currently being rewritten, and is not open source yet. + +## Roles + +#### Maintainers + +- [@JetteReeg](https://github.com/JetteReeg): RScore repo and lead in R package +- [@TheoPannetier](https://github.com/TheoPannetier): RScore repo and lead in batch mode + +Maintainers are responsible for coordinating development efforts and ensuring that RangeShifter keeps building continuously. + +#### Developers + +Regular contributors and members of the [RangeShifter development team](https://github.com/orgs/RangeShifter/people), including maintainers. + +#### Contributors + +Anyone who whishes to make changes to RangeShifter's code, including regular developers. + +## Branching policy + +![](RangeShiftR/man/figures/branches.png) + +This policy applies to RScore and all three RangeShifter interfaces. +RangeShifter uses the following branching structure: + +- `main` is the default branch, where stable releases live. Because it contains the version of RangeShifter that users normally interact with, it must be stable and build at all times. + Only maintainers should make significant changes to `main`, normally by merging `develop` into `main` to make newly developed features and bug fixes available to users, and marking a release while doing so. +- `develop` is the development branch containing new, in-development features. It is the reference branch for all developers. Contributors may make small changes and bug fixes directly to `develop` but should ensure that new changes do not break the build. If one happens to break `develop`, it should be their top priority to fix it as this will disrupt the work of all other contributors. + Larger changes should instead be developed on feature branches. +- Larger changes should be first developed on feature (e.g. `cmake`, `mutualism`, etc.) or contributor (e.g., `theo`) branches. Contributors are welcome to experiment and break such branches at any time, as this will not impact users or other contributors. + + When progress is deemed satisfactory, changes can be brought to `develop`. Please open a pull request on GitHub, and assign at least one maintainer as a reviewer. As a pre-requisite, RangeShifter must build on the branch before merging. Please enter a descriptive title and use the description field to describe what you have changed. + + In the meantime, we encourage contributors to work in small and frequent commits, and to merge `develop` into their branch often to update their branch with newest changes. + +If you need a reminder on the main git commands related to committing and branching, head to the [Git cheatsheet](https://github.com/RangeShifter/RScore/blob/main/git_cheatsheet.md). + +## Contributing to the RangeShifter core code + +Any changes (issues, bugs, features) regarding the actual RangeShifter core code should be done in [this](https://github.com/RangeShifter/RScore) repository and can afterwards be synced with all interfaces using the git subtree feature (see [Git subtree](https://github.com/RangeShifter/RScore?tab=readme-ov-file#usage-git-subtree) section in the README). + +Please check the [contributing guidelines for the RScore code](https://github.com/RangeShifter/RScore/blob/main/CONTRIBUTING.md). + +## Contributing to the RangeShiftR package + +Please follow these guidelines for issues, bugs or new features related to the RangeShiftR-package. + +### Issues and bugs + +Issues should be used for reporting technical problems and bugs with the R package or suggest improvements e.g. in the documentation. +General and more conceptual questions regarding the application and settings of RangeShifter parameters should be asked in the [discussion forum](https://github.com/RangeShifter/RangeshiftR-tutorials/discussions) and answered by the broader RangeShifter community. + +#### Create a new issue + +If you encounter a technical problem, find a bug related to the RangeShiftR package or would like to suggest an improvement to the R package, please search if [a related issue already exists](https://github.com/RangeShifter/RangeShiftR-package-dev/issues). If you can't find a related issue, you can open a new issue using a relevant [issue form](https://github.com/RangeShifter/RangeShiftR-package-dev/issues/new/choose). To propose a bug fix (thank you!!), please create and work on your own branch or fork, from either `main` or `develop` (preferred), and open a pull request when your fix is ready to be merged into the original branch. + +As a prerequisite for merging, please ensure that the R package is build correctly. GitHub Action will soon be used for ensuring a successfull build of the R package interface on all operating systems (i.e. R CMD CHECK needs to run without warnings). + +Maintainers will review the pull request, possibly request changes, and eventually integrate the bug fix into the RangeShiftR package. + +### New feature + +Do you have an idea of a new feature in the RangeShiftR package that should be integrated and is of use for other RangeShiftR users? +Please get in touch with the RangeShifter development team directly (rangeshiftr@uni-potsdam.de) to discuss a collaboration. + +⚠️ We advise to contact the developer team as early as possible if you plan on implementing a new feature of the R package interface. This could prevent simultaneous development of the same feature and coordinate potential joint development. + +Alternatively, proceed as with the bug fix above: create your own branch _from `develop`_ and work from there, and submit a pull request when your new features are ready to join the core code. +We recommend that you update your branch regularly to new changes on `develop` (using `git merge develop`) to reduce the risk of merge conflicts or your version getting out-of-touch in the late stages of development. +We also recommend that you work in small commits, as this makes the code easier to debug, and makes it easier for maintainers to understand your contributions when reviewing a pull request. + diff --git a/LICENSE b/LICENSE index 94a9ed0..f288702 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. + 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. @@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found. 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 . + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. @@ -664,11 +664,11 @@ 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/README.md b/README.md index bf20fb5..7d04a8b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,69 @@ -# RangeshiftR +# RangeShiftR -R-package that provides interface to RangeShifter simulation software \ No newline at end of file +The RangeShiftR package implements the RangeShifter simulation platform for R. + +[RangeShifter](https://rangeshifter.github.io/) +is a state-of-the-art eco-evolutionary modelling platform that is becoming +increasingly used worldwide for both theoretical and applied purposes +[(Bocedi et al. 2014)](https://besjournals.onlinelibrary.wiley.com/doi/full/10.1111/2041-210X.12162). + +RangeShifter is a spatially-explicit, individual-based simulation platform that +allows modelling species’ range dynamics, such as expansion and shifting, and +patch connectivity by linking complex local population dynamics and dispersal +behaviour, while also taking into account inter-individual variability and +evolutionary processes. RangeShifter is highly flexible in terms of the spatial +resolution and extent, and regarding the complexity of the considered ecological +processes. Due to its modular structure, the level of detail in demographic and +dispersal processes can be easily adapted to different research questions and +available data. + + +## Installation + +RangeShiftR is only available from this github repository. +(It may move to CRAN in the future.) + +RangeShiftR has to be built from source and requires the package `Rcpp` as +well as a functional C++ compiler toolchain. + +```r +# Install RangeShiftR from GitHub: +devtools::install_github("RangeShifter/RangeShiftR-pkg", ref="main", subdir="RangeShiftR") +``` + +## Usage and help + +Please refer to our [website](https://rangeshifter.github.io/) for more information about RangeShifter simulation +platform. RangeShifter is accompanied by extensive documentation. + +For getting acquainted with the software, we recommend to first read the [manual](https://raw.githubusercontent.com/RangeShifter/RangeShifter-software-and-documentation/master/RangeShifter_v2.0_UserManual.pdf) to understand the conceptual underpinnings of RangeShifter. + +Analogous to the RangeShifter GUI, we provide [tutorials](https://rangeshifter.github.io/RangeshiftR-tutorials/) to learn the different features of RangeshiftR using example applications from Bocedi et al. (2014, 2021) and Malchow et al. (2021). These cover some of the main features of RangeShifter, and help becoming familiar with the software. + +If you have any further question related to the general concepts and usage of RangeShifter, please browse earlier topics in the [forum pages](https://github.com/RangeShifter/RangeshiftR-tutorials/discussions) or add a new one. Often it is also helpful to review [published studies](https://rangeshifter.github.io/site/references/) using the RangeShifter modelling platform. + +For technical questions related to the RangeShiftR package interface and which cannot be answered with the documentation provided above, please browse the [issues section](https://github.com/RangeShifter/RangeShiftR-package-dev/issues) of this repository and open a new issues if required. We also offer *technical support* for the RangeShiftR package via mail (rangeshiftr@uni-potsdam.de) if you follow the guidelines of how to ask for help, e.g. guidelines given by [StackOverflow](https://stackoverflow.com/help/how-to-ask): + +## Contributing + +See [Contributing guidelines](https://github.com/RangeShifter/RangeShiftR-package-dev/blob/main/CONTRIBUTING.md) + +## See also + +- [Compiled software and documentation](https://github.com/RangeShifter/RangeShifter-software-and-documentation) +- [RScore](https://github.com/RangeShifter/RScore), source for RangeShifter's core code +- [RangeShifter batch mode](https://github.com/RangeShifter/RangeShifter_batch_dev), source for the batch mode interface + +## Maintainer + +- [@JetteReeg](https://github.com/JetteReeg) + +## References + + - Bocedi G, Palmer SCF, Pe’er G, Heikkinen RK, Matsinos YG, Watts K, Travis JMJ (2014). + *RangeShifter: A Platform for Modelling Spatial Eco-Evolutionary Dynamics and + Species’ Responses to Environmental Changes.* Methods in Ecology and Evolution 5: 388–96. + + - Bocedi G, Palmer SCF, Malchow AK, Zurell D, Watts K, Travis JMJ (2021) RangeShifter 2.0: An extended and enhanced platform for modelling spatial eco-evolutionary dynamics and species’ responses to environmental changes. Ecography 44:1453-1462. + + - Malchow AK, Bocedi G, Palmer SCF, Travis JMJ, Zurell D (2021) RangeShiftR: an R package for individual-based simulation of spatial eco-evolutionary dynamics and species’ responses to environmental change. Ecography 4: 1443-1452. diff --git a/RangeShiftR/DESCRIPTION b/RangeShiftR/DESCRIPTION index 98d345b..b3eea41 100644 --- a/RangeShiftR/DESCRIPTION +++ b/RangeShiftR/DESCRIPTION @@ -1,30 +1,31 @@ Package: RangeShiftR Type: Package Title: An R package for individual-based simulation of spatial eco-evolutionary dynamics and species' responses to environmental changes -Version: 1.0.4 +Version: 1.1.2 Authors@R: c( person("Anne-Kathleen", "Malchow", email = "rangeshiftr@uni-potsdam.de", role = c("aut", "cre")), person("Greta", "Bocedi", role = c("aut")), person("Stephen C.F.", "Palmer", role = c("aut")), person("Justin M.J.", "Travis", role = c("aut")), + person("Jette", "Wolff", role= c("aut")), person("Damaris", "Zurell", role = c("aut")) ) -Date: 2021-08-04 +Date: 2025-09-26 URL: https://rangeshifter.github.io/RangeshiftR-tutorials/ Description: RangeShiftR provides individual-based simulations of spatial eco-evolutionary dynamics. It is based on the C++ software RangeShifter, making it flexible and fast. RangeShiftR models the processes of demography, dispersal and evolution in an inter-dependent way, offering substantial complexity in the corresponding modelling choices. It is entirely open-source and aims to facilitate the application of individual-based and mechanistic modelling to eco-evolutionary questions. License: GPL-3 Depends: R (>= 3.6) -SystemRequirements: C++11 +SystemRequirements: C++20 Imports: Rcpp (>= 1.0.0), - raster (>= 3.0.0), Rdpack (>= 0.7), methods, - rmarkdown + rmarkdown, + terra RdMacros: Rdpack LinkingTo: Rcpp Encoding: UTF-8 -RoxygenNote: 7.1.2 +RoxygenNote: 7.3.3 Collate: 'Rfunctions.R' 'plotProbs.R' diff --git a/RangeShiftR/NAMESPACE b/RangeShiftR/NAMESPACE index da1d129..e294623 100644 --- a/RangeShiftR/NAMESPACE +++ b/RangeShiftR/NAMESPACE @@ -19,7 +19,6 @@ export(SMSpathLengths) export(Settlement) export(Simulation) export(StageStructure) -export(createODD) export(getLocalisedEquilPop) export(plotAbundance) export(plotOccupancy) diff --git a/RangeShiftR/R/RangeShiftR.R b/RangeShiftR/R/RangeShiftR.R index 9423a1c..a3d8919 100644 --- a/RangeShiftR/R/RangeShiftR.R +++ b/RangeShiftR/R/RangeShiftR.R @@ -51,8 +51,8 @@ NULL # Show start-up message upon loading the package .onAttach <- function(libname, pkgname) { - packageStartupMessage("RangeshiftR version 1.0.4 (10.05.2022)\n", - "Copyright (C) 2020-2022 Anne-Kathleen Malchow, Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Damaris Zurell\n\n", + packageStartupMessage("RangeshiftR version 1.1.2 (26.09.2025)\n", + "Copyright (C) 2020-2025 Anne-Kathleen Malchow, Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Jette Wolff, Damaris Zurell\n\n", "This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.\n", "You are welcome to redistribute it and/or modify it under certain conditions;\n", "type 'RangeShiftR_license()' for details.\n") @@ -69,8 +69,8 @@ NULL #' @export RangeShiftR_license <- function () { - cat("\nRangeshiftR version 1.0.4 (10.05.2022)\n") - cat("Copyright (C) 2020-2022 Anne-Kathleen Malchow, Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Damaris Zurell\n\n") + cat("\nRangeshiftR version 1.1.2 (26.09.2025)\n") + cat("Copyright (C) 2020-2024 Anne-Kathleen Malchow, Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Jette Wolff, Damaris Zurell\n\n") cat("This program is free software: you can redistribute it and/or modify\n") cat("it under the terms of the GNU General Public License as published by\n") cat("the Free Software Foundation, either version 3 of the License, or\n") diff --git a/RangeShiftR/R/class_DemogParams.R b/RangeShiftR/R/class_DemogParams.R index 39327ec..82f1e5c 100644 --- a/RangeShiftR/R/class_DemogParams.R +++ b/RangeShiftR/R/class_DemogParams.R @@ -69,13 +69,13 @@ #' 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 \ifelse{html}{\out{φ1}}{\eqn{φ_1}} \tab | \tab \ifelse{html}{\out{φ2}}{\eqn{φ_2}} \cr +#' \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} #' -#' In a female-only model (\code{ReproductionType=0}), φ represents the number of female offspring per female and reproductive event. \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 #' 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 φ 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{φ}} 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 @@ -84,12 +84,11 @@ #' \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}. +#' \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}. #' #' 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 φ (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, +#' 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}. #' Only the first approach allows straightforward direct comparison with standard analytical matrix models. #' @@ -496,7 +495,7 @@ setMethod("plotProbs", "StagesParams", function(x, stage = NULL, sex = NULL, xma 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(SexDep) {leg.txt <- c(leg.txt, paste0("Stage ",this.stage, ifelse(this.sex," male"," female")))} + 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) } diff --git a/RangeShiftR/R/class_DispersalParams.R b/RangeShiftR/R/class_DispersalParams.R index 4f8b360..8ec6d9e 100644 --- a/RangeShiftR/R/class_DispersalParams.R +++ b/RangeShiftR/R/class_DispersalParams.R @@ -328,7 +328,7 @@ setMethod("show", "EmigrationParams", function(object){ print(object@EmigProb) if (object@IndVar) { cat(" TraitScaleFactor =", object@TraitScaleFactor, "\n") - if (!is.na(object@EmigStage) && length(object@EmigStage)!=0) { + if (!anyNA(object@EmigStage) && length(object@EmigStage)!=0) { cat(" EmigStage =", object@EmigStage, "\n") } } @@ -2098,7 +2098,7 @@ setValidity("DispersalParams", function(object) { msg <- c(msg, "Dispersal(): Settlement can only be density-dependent (DensDep = TRUE) if a movement process is used as transfer method!") } }else{ - if (object@Settlement@MaxSteps<=0 && all(object@Transfer@StepMort<=0) ) { + if (any(object@Settlement@MaxSteps<=0) && all(object@Transfer@StepMort<=0) ) { msg <- c(msg, "Dispersal(): At least one of the two options MaxSteps and StepMort must be set (>0) if a movement process is used as transfer method!") } } diff --git a/RangeShiftR/R/class_InitialisationParams.R b/RangeShiftR/R/class_InitialisationParams.R index 11ea367..6fccbf7 100644 --- a/RangeShiftR/R/class_InitialisationParams.R +++ b/RangeShiftR/R/class_InitialisationParams.R @@ -229,27 +229,33 @@ setValidity('InitialisationParams', function(object){ } min.set = FALSE max.set = FALSE - if (length(object@minX) != 1){ - msg <- c(msg, 'Minimum X coordinate (minX) must be of length 1!') + if (length(object@minX) > 1){ + msg <- c(msg, 'Minimum X coordinate (minX) must be of length 1 or missing!') } else{ - if (object@minX < 0 && object@minX != -9){ - msg <- c(msg, 'Minimum X coordinate (minX) has to be greater or equal 0!') + if (length(object@minX) == 1){ + if (object@minX < 0 && object@minX != -9L){ + msg <- c(msg, 'Minimum X coordinate (minX) has to be greater or equal 0!') + } + else min.set = ifelse(object@minX==-9L,FALSE,TRUE) } - else min.set = TRUE + # else min.set = TRUE } - if (length(object@maxX) != 1){ - msg <- c(msg, 'Maximum X coordinate (maxX) must be of length 1!') + if (length(object@maxX) > 1){ + msg <- c(msg, 'Maximum X coordinate (maxX) must be of length 1 or missing!') } else{ - if (object@maxX < 0 && object@maxX != -9){ - msg <- c(msg, 'Maximum X coordinate (maxX) has to be greater or equal 0!') + if (length(object@maxX) == 1){ + if (object@maxX < 0 && object@maxX != -9L){ + msg <- c(msg, 'Maximum X coordinate (maxX) has to be greater or equal 0!') + } + else max.set = ifelse(object@maxX==-9L,FALSE,TRUE) } - else max.set = TRUE + # else max.set = TRUE } - if(min.set && max.set && object@minX > 0){ + if(min.set && max.set){ Xextend = object@maxX - object@minX - if (object@maxX <= object@minX){ + if (Xextend <= 0){ msg <- c(msg, 'maxX has to be larger than minX!') Xextend = FALSE } @@ -257,27 +263,33 @@ setValidity('InitialisationParams', function(object){ else {Xextend = FALSE} min.set = FALSE max.set = FALSE - if (length(object@minY) != 1){ - msg <- c(msg, 'Minimum Y coordinate (minY) must be of length 1!') + if (length(object@minY) > 1){ + msg <- c(msg, 'Minimum Y coordinate (minY) must be of length 1 or missing!') } else{ - if (object@minY < 0 && object@minY != -9){ - msg <- c(msg, 'Minimum Y coordinate (minY) has to be greater or equal 0!') + if (length(object@minY) == 1){ + if (object@minY < 0 && object@minY != -9L){ + msg <- c(msg, 'Minimum Y coordinate (minY) has to be greater or equal 0!') + } + else min.set = ifelse(object@minY==-9L,FALSE,TRUE) } - else min.set = TRUE + # else min.set = TRUE } - if (length(object@maxY) != 1){ - msg <- c(msg, 'Maximum Y coordinate (maxY) must be of length 1!') + if (length(object@maxY) > 1){ + msg <- c(msg, 'Maximum Y coordinate (maxY) must be of length 1 or missing!') } else{ - if (object@maxY < 0 && object@maxY != -9){ - msg <- c(msg, 'Maximum Y coordinate (maxY) has to be greater or equal 0!') + if (length(object@maxY) == 1){ + if (object@maxY < 0 && object@maxY != -9L){ + msg <- c(msg, 'Maximum Y coordinate (maxY) has to be greater or equal 0!') + } + else max.set = ifelse(object@maxY==-9L,FALSE,TRUE) } - else max.set = TRUE + # else max.set = TRUE } - if(min.set && max.set && object@minY > 0){ + if(min.set && max.set){ Yextend = object@maxY - object@minY - if (object@maxY <= object@minY){ + if (Yextend <= 0){ msg <- c(msg, 'maxY has to be larger than minY!') Yextend = FALSE } diff --git a/RangeShiftR/R/class_RSparams.R b/RangeShiftR/R/class_RSparams.R index 8546b50..b417103 100644 --- a/RangeShiftR/R/class_RSparams.R +++ b/RangeShiftR/R/class_RSparams.R @@ -110,7 +110,7 @@ setValidity("RSparams", function(object) { rows = object@control@stages offset = 1 if (object@dispersal@Emigration@IndVar) { - if (is.na(object@dispersal@Emigration@EmigStage) || length(object@dispersal@Emigration@EmigStage)!=1) { + if (anyNA(object@dispersal@Emigration@EmigStage) || length(object@dispersal@Emigration@EmigStage)!=1) { msg <- c(msg, "Emigration(): EmigStage (exactly 1) must be set!") } else { @@ -178,7 +178,7 @@ setValidity("RSparams", function(object) { } # check sex column of EmigProb if (object@dispersal@Emigration@SexDep) { - if(any(object@dispersal@Emigration@EmigProb[,offset]!=0 && object@dispersal@Emigration@EmigProb[,offset]!=1)){ + if(any( !object@dispersal@Emigration@EmigProb[,offset] %in% c(0,1) )){ msg <- c(msg, paste0(offset,". column of emigration probability traits matrix (EmigProb) must contain the sex numbers (0 for female, 1 for male)!")) } else { @@ -312,7 +312,7 @@ setValidity("RSparams", function(object) { } if (object@dispersal@Transfer@SexDep) { # check sex column of Distances matrix - if(any(object@dispersal@Transfer@Distances[,offset]!=0 && object@dispersal@Transfer@Distances[,offset]!=1)){ + if(any( !object@dispersal@Transfer@Distances[,offset] %in% c(0,1) )){ msg <- c(msg, paste0(offset,". column of dispersal kernel traits (Distances) matrix must contain the sex numbers (0 for female, 1 for male)!")) } else { @@ -711,7 +711,7 @@ setValidity("RSparams", function(object) { } } if (object@control@stagestruct) { - if (is.na(object@init@InitAge) || length(object@init@InitAge) == 0){ + if (anyNA(object@init@InitAge) || length(object@init@InitAge) == 0){ msg <- c(msg, 'Initialise(): InitAge must be set!') } else { @@ -720,7 +720,7 @@ setValidity("RSparams", function(object) { } } if (object@init@InitType != 2) { - if ( is.na(object@init@PropStages) || length(object@init@PropStages) == 0 ){ + if ( anyNA(object@init@PropStages) || length(object@init@PropStages) == 0 ){ msg <- c(msg, 'Initialise(): PropStages must be set!') } else { diff --git a/RangeShiftR/R/output_handling.R b/RangeShiftR/R/output_handling.R index f7464f7..e69fdb3 100644 --- a/RangeShiftR/R/output_handling.R +++ b/RangeShiftR/R/output_handling.R @@ -188,30 +188,37 @@ setMethod("ColonisationStats", "data.frame", function(x, y = NULL, years = numer } #require('raster') - if(class(y) == "RasterLayer" || class(y) == "RasterStack" ){ + # if(class(y) == "RasterLayer" || class(y) == "RasterStack" ){ # old raster + if(class(y) == "RasterLayer" || class(y) == "RasterStack" ){ # if users use raster package, transform to SpatRaster + y <- terra::rast(y) + } + if( class(y) == "SpatRaster" ){ onelayer = FALSE - if(class(y) == "RasterLayer") onelayer = TRUE - if(class(y) == "RasterStack") if(length(y@layers)==1 ) onelayer = TRUE + # if(class(y) == "RasterLayer") onelayer = TRUE + # if(class(y) == "RasterStack") if(length(y@layers)==1 ) onelayer = TRUE + if(length(names(y)) == 1) onelayer = TRUE + # if(length(y) > 1) if(length(y@layers)==1 ) onelayer = TRUE + if(patchbased){ # non-dynamic landscape if(onelayer){ # initialise output rasters - if(class(y) == "RasterStack") y <- y[[1]] + if(class(y) == "SpatRaster") y <- y[[1]] patch_occ_prob <- patch_col_time <- y # denote matrix with NA - raster::values(patch_occ_prob)[raster::values(y)==0] <- raster::values(patch_col_time)[raster::values(y)==0] <- NA + terra::values(patch_occ_prob)[terra::values(y)==0] <- terra::values(patch_col_time)[terra::values(y)==0] <- NA # init all habitat patches to also address those that never had a population (these don't occur in RS output) - raster::values(patch_occ_prob)[raster::values(y) >0] <- 0 - raster::values(patch_col_time)[raster::values(y) >0] <- -9 + terra::values(patch_occ_prob)[terra::values(y) >0] <- 0 + terra::values(patch_col_time)[terra::values(y) >0] <- -9 # fill output rasters #if(length(years)>1){ - patch_outstack <- raster::stack() + patch_outstack <- terra::rast() for (j in 1:length(years)){ - patch_outstack <- raster::addLayer(patch_outstack, patch_occ_prob) + patch_outstack <- c(patch_outstack, patch_occ_prob) for (i in patches){ - raster::values(patch_outstack[[j]])[raster::values(y)==i] <- occ_prob[occ_prob$patch==i,paste(years[j])] + terra::values(patch_outstack[[j]])[terra::values(y)==i] <- occ_prob[occ_prob$patch==i,paste(years[j])] } } #} @@ -223,7 +230,7 @@ setMethod("ColonisationStats", "data.frame", function(x, y = NULL, years = numer #} for (i in patches){ - raster::values(patch_col_time)[raster::values(y)==i] <- ifelse(is.na(col_time_mean[paste(i)]),-9,col_time_mean[paste(i)]) + terra::values(patch_col_time)[terra::values(y)==i] <- ifelse(is.na(col_time_mean[paste(i)]),-9,col_time_mean[paste(i)]) } return(list(occ_prob=occ_prob, col_time=col_time, map_occ_prob=patch_outstack, map_col_time=patch_col_time)) @@ -234,17 +241,17 @@ setMethod("ColonisationStats", "data.frame", function(x, y = NULL, years = numer if(!onelayer){ N_layers <- length(years)+1 - if( length(y@layers) != N_layers ){ + if( length(names(y)) != N_layers ){ warning("ColonisationStats(): Number of raster layers must be either 1 or number of years plus 1.", call. = FALSE) } else{ # initialise output rasters patch_outstack <- y # denote matrix with NA - raster::values(patch_outstack)[raster::values(y)==0] <- NA + terra::values(patch_outstack)[terra::values(y)==0] <- NA # all habitat patches to address those that never had a population - raster::values(patch_outstack)[raster::values(y)>0] <- 0.0 - raster::values(patch_outstack[[N_layers]])[raster::values(y[[N_layers]])>0] <- -9 + terra::values(patch_outstack)[terra::values(y)>0] <- 0.0 + terra::values(patch_outstack[[N_layers]])[terra::values(y[[N_layers]])>0] <- -9 # fill output rasters for (i in patches){ @@ -252,10 +259,10 @@ setMethod("ColonisationStats", "data.frame", function(x, y = NULL, years = numer # raster::values(patch_outstack[[1]])[raster::values(y[[1]])==i] <- occ_prob[occ_prob$patch==i,"occ_prob"] #}else { for (j in 1:length(years)){ - raster::values(patch_outstack[[j]])[raster::values(y[[j]])==i] <- occ_prob[occ_prob$patch==i,paste(years[j])] + terra::values(patch_outstack[[j]])[terra::values(y[[j]])==i] <- occ_prob[occ_prob$patch==i,paste(years[j])] } #} - raster::values(patch_outstack[[N_layers]])[raster::values(y[[N_layers]])==i] <- ifelse(is.na(col_time_mean[paste(i)]),-9,col_time_mean[paste(i)]) + terra::values(patch_outstack[[N_layers]])[terra::values(y[[N_layers]])==i] <- ifelse(is.na(col_time_mean[paste(i)]),-9,col_time_mean[paste(i)]) } return(list(occ_prob=occ_prob, col_time=col_time, map_occ_prob=patch_outstack[[-N_layers]], map_col_time=patch_outstack[[N_layers]])) @@ -266,26 +273,28 @@ setMethod("ColonisationStats", "data.frame", function(x, y = NULL, years = numer if(onelayer){ # initialise output rasters - if(class(y) == "RasterStack") y <- y[[1]] + if(class(y) == "SpatRaster") y <- y[[1]] patch_occ_prob <- patch_col_time <- y # init all habitat patches to also address those that never had a population (these don't occur in RS output) - raster::values(patch_occ_prob)[!is.na(raster::values(y))] <- 0 - raster::values(patch_col_time)[!is.na(raster::values(y))] <- -9 + terra::values(patch_occ_prob)[!is.na(terra::values(y))] <- 0 + terra::values(patch_col_time)[!is.na(terra::values(y))] <- -9 # make value index from patchIDs value_ix <- floor(patches/(10^digitsY))+(nrow(y)-patches%%(10^digitsY))*ncol(y) # fill output rasters #if(length(years)>1){ - patch_outstack <- raster::stack() + patch_outstack <- terra::rast() for (j in 1:length(years)){ - patch_outstack <- raster::addLayer(patch_outstack, patch_occ_prob) - raster::values(patch_outstack[[j]])[value_ix] <- occ_prob[,j+2] + patch_outstack <- c(patch_outstack, patch_occ_prob) + terra::values(patch_outstack[[j]])[value_ix] <- occ_prob[,j+2] } + crs(patch_outstack) <- NA #} else{ # raster::values(patch_occ_prob)[value_ix] <- occ_prob[,1] # patch_outstack <- patch_occ_prob #} - raster::values(patch_col_time)[value_ix] <- ifelse(is.na(col_time_mean[]),-9,col_time_mean[]) + terra::values(patch_col_time)[value_ix] <- ifelse(is.na(col_time_mean[]),-9,col_time_mean[]) + 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)) @@ -322,36 +331,36 @@ setMethod("ColonisationStats", "RSparams", function(x, y = getwd(), years = nume # non-dynamic landscape if(length(x@land@LandscapeFile)==1){ - patch_r <- try(raster::raster(paste0(dirpath, "Inputs/", x@land@PatchFile))) + patch_r <- try(terra::rast(paste0(dirpath, "Inputs/", x@land@PatchFile))) if( class(patch_r) == "try-error" ) warning("ColonisationStats(): Couldn't read patch raster file ", x@land@PatchFile , call. = FALSE) - if( class(pop_df) == "data.frame" & class(patch_r) == "RasterLayer" ) res <- ColonisationStats(pop_df,patch_r,years) + if( class(pop_df) == "data.frame" & class(patch_r) == "SpatRaster" ) res <- ColonisationStats(pop_df,patch_r,years) } # dynamic landscape else{ - patch_r <- raster::stack() + patch_r <- terra::rast() # rasters for occ_prob output for(year in years){ current <- which(x@land@DynamicLandYears == max(x@land@DynamicLandYears[x@land@DynamicLandYears<=year]) ) - patch_curr <- try(raster::raster(paste0(dirpath, "Inputs/", x@land@PatchFile[current]))) + patch_curr <- try(terra::rast(paste0(dirpath, "Inputs/", x@land@PatchFile[current]))) if ( class(patch_curr) == "try-error" ) warning("ColonisationStats(): Couldn't read patch raster file nr ", current , " for this simulation.", call. = FALSE) - else patch_r <- raster::addLayer(patch_r , patch_curr) + else patch_r <- c(patch_r, patch_curr) } # rasters for col_time output year <- max(pop_df$Year) current <- which(x@land@DynamicLandYears == max(x@land@DynamicLandYears[x@land@DynamicLandYears<=year]) ) - patch_curr <- try(raster::raster(paste0(dirpath, "Inputs/", x@land@PatchFile[current]))) + patch_curr <- try(terra::rast(paste0(dirpath, "Inputs/", x@land@PatchFile[current]))) if ( class(patch_curr) == "try-error" ) warning("ColonisationStats(): Couldn't read patch raster file nr ", current , " for this simulation.", call. = FALSE) - else patch_r <- raster::addLayer(patch_r , patch_curr) + else patch_r <- c(patch_r , patch_curr) - if(class(pop_df) == "data.frame" & length(patch_r@layers)==(length(years)+1) ) res <- ColonisationStats(pop_df,patch_r,years) + if(class(pop_df) == "data.frame" & 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 - patch_r <- try(raster::raster(paste0(dirpath, "Inputs/", x@land@LandscapeFile[1]))) + patch_r <- try(terra::rast(paste0(dirpath, "Inputs/", x@land@LandscapeFile[1]))) if ( class(patch_r) == "try-error" ) warning("ColonisationStats(): Couldn't read patch raster file nr ", current , " for this simulation.", call. = FALSE) - if(class(pop_df) == "data.frame" & class(patch_r) == "RasterLayer" ) res <- ColonisationStats(pop_df,patch_r,years) + if(class(pop_df) == "data.frame" & class(patch_r) == "SpatRaster" ) res <- ColonisationStats(pop_df,patch_r,years) } }else { # no maps requested if(class(pop_df) == "data.frame") res <- ColonisationStats(pop_df,NULL,years) @@ -874,29 +883,5 @@ setMethod("getLocalisedEquilPop", "DemogParams", function(demog, DensDep_values, return(res) }) -## ---- ODD documentation ----- - -#' Creating ODD template file for a specific RangeShiftR parameter master object -#' -#' This function creates an ODD template file for a specific RangeShiftR parameter master object \code{s}. It only creates a new file, if the \code{filename} doesn't exist in the folder. -#' If the \code{filename} already exists, it only renders the document to either pdf, word or md. -#' @usage createODD(filename, s, type) -#' -#' @param filename Name of the R markdown file and document to be created -#' @param s RangeShiftR parameter object -#' @param type file type of the rendering process output. Can be either "pdf_document", "doc_document" or "md_document" -#' @export -setGeneric("createODD", function(filename, s, type,...) standardGeneric("createODD") ) -setMethod("createODD", c(filename = "character", s="RSparams", type="character"), function(filename="ODD_protocol_template.Rmd", s, type="pdf_document"){ - if(!file.exists(filename)) { - unlink(c("RS_flowchart.png", "RS_flowchart_2.png", "style-template.docx", "RS_ODD.json", "ecography.csl")) - rmarkdown::draft(filename, template = "ODD_protocoll", package = "RangeShiftR", edit = FALSE) - } - if (type=="pdf_document") format <- "pdf" - if (type=="md_document") format <- "md" - if (type=="rtf_document") format <- "word" - if (type=="word_document") format <- "word" - rmarkdown::render(input = filename, output_format = type, params=list(format = format)) -}) diff --git a/RangeShiftR/R/plotProbs.R b/RangeShiftR/R/plotProbs.R index aec6a9e..bcd6b00 100644 --- a/RangeShiftR/R/plotProbs.R +++ b/RangeShiftR/R/plotProbs.R @@ -51,7 +51,19 @@ #' \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{\link[RangeShiftR]{StageStructure}}: plot fecundity as well as survival and development probabilities +#' \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} +#' +#' 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))}} +#' +#' 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) )}} #' } #' @export setGeneric("plotProbs", function(x, ...) standardGeneric("plotProbs") ) diff --git a/RangeShiftR/man/RangeShiftR-package.Rd b/RangeShiftR/man/RangeShiftR-package.Rd index 286270c..8f27d9f 100644 --- a/RangeShiftR/man/RangeShiftR-package.Rd +++ b/RangeShiftR/man/RangeShiftR-package.Rd @@ -43,6 +43,7 @@ Authors: \item Greta Bocedi \item Stephen C.F. Palmer \item Justin M.J. Travis + \item Jette Wolff \item Damaris Zurell } diff --git a/RangeShiftR/man/StageStructure.Rd b/RangeShiftR/man/StageStructure.Rd index 914e20e..60a492a 100644 --- a/RangeShiftR/man/StageStructure.Rd +++ b/RangeShiftR/man/StageStructure.Rd @@ -61,13 +61,13 @@ while Bernoulli trials \eqn{Bern}(\ifelse{html}{\out{σi}}{\eqn{ 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 \ifelse{html}{\out{φ1}}{\eqn{φ_1}} \tab | \tab \ifelse{html}{\out{φ2}}{\eqn{φ_2}} \cr +\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} -In a female-only model (\code{ReproductionType=0}), φ represents the number of female offspring per female and reproductive event. \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 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 φ 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{φ}} 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 @@ -76,12 +76,11 @@ An example transition matrix for a 3-staged explicit sexual population model \in \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}. +\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}. 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 φ (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, +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}. Only the first approach allows straightforward direct comparison with standard analytical matrix models. diff --git a/RangeShiftR/man/createODD.Rd b/RangeShiftR/man/createODD.Rd deleted file mode 100644 index ef720a0..0000000 --- a/RangeShiftR/man/createODD.Rd +++ /dev/null @@ -1,19 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/output_handling.R -\name{createODD} -\alias{createODD} -\title{Creating ODD template file for a specific RangeShiftR parameter master object} -\usage{ -createODD(filename, s, type) -} -\arguments{ -\item{filename}{Name of the R markdown file and document to be created} - -\item{s}{RangeShiftR parameter object} - -\item{type}{file type of the rendering process output. Can be either "pdf_document", "doc_document" or "md_document"} -} -\description{ -This function creates an ODD template file for a specific RangeShiftR parameter master object \code{s}. It only creates a new file, if the \code{filename} doesn't exist in the folder. -If the \code{filename} already exists, it only renders the document to either pdf, word or md. -} diff --git a/RangeShiftR/man/figures/RSRlogo.png b/RangeShiftR/man/figures/RSRlogo.png new file mode 100644 index 0000000..ae378b7 Binary files /dev/null and b/RangeShiftR/man/figures/RSRlogo.png differ diff --git a/RangeShiftR/man/figures/RS_repos.png b/RangeShiftR/man/figures/RS_repos.png new file mode 100644 index 0000000..b138a01 Binary files /dev/null and b/RangeShiftR/man/figures/RS_repos.png differ diff --git a/RangeShiftR/man/figures/branches.png b/RangeShiftR/man/figures/branches.png new file mode 100644 index 0000000..12e3a96 Binary files /dev/null and b/RangeShiftR/man/figures/branches.png differ diff --git a/RangeShiftR/man/plotProbs.Rd b/RangeShiftR/man/plotProbs.Rd index 66c321c..29d6497 100644 --- a/RangeShiftR/man/plotProbs.Rd +++ b/RangeShiftR/man/plotProbs.Rd @@ -33,6 +33,18 @@ Available methods and their options: \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{\link[RangeShiftR]{StageStructure}}: plot fecundity as well as survival and development probabilities + \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} + + 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))}} + + 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) )}} } } diff --git a/RangeShiftR/src/Makevars b/RangeShiftR/src/Makevars index 5744dce..c96b97d 100644 --- a/RangeShiftR/src/Makevars +++ b/RangeShiftR/src/Makevars @@ -1,7 +1,13 @@ -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 = -O2 +PKG_CXXFLAGS = -O2 -DRS_RCPP -DBATCH +#PKG_CXXFLAGS = -DRSDEBUG # PKG_CXXFLAGS = -Wall -pedantic diff --git a/RangeShiftR/src/Makevars.win b/RangeShiftR/src/Makevars.win index 477f4d0..00e503c 100644 --- a/RangeShiftR/src/Makevars.win +++ b/RangeShiftR/src/Makevars.win @@ -1,7 +1,13 @@ -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 -DBATCH -w +#PKG_CXXFLAGS = -DRSDEBUG #PKG_CXXFLAGS = -H \ No newline at end of file diff --git a/RangeShiftR/src/RScore/.github/workflows/check.yml b/RangeShiftR/src/RScore/.github/workflows/check.yml new file mode 100644 index 0000000..2e86587 --- /dev/null +++ b/RangeShiftR/src/RScore/.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 }} diff --git a/RangeShiftR/src/RScore/.gitignore b/RangeShiftR/src/RScore/.gitignore index 31831ca..9bd72d2 100644 --- a/RangeShiftR/src/RScore/.gitignore +++ b/RangeShiftR/src/RScore/.gitignore @@ -11,11 +11,9 @@ compile_commands.json Makefile .build-release/ build-Release/ -*.txt *.project *.workspace *.mk -*.txt *.tags # Hidden source @@ -83,3 +81,7 @@ vignettes/*.pdf # compilation files *.o + +# Visual Studio files +.vs/ +out/ diff --git a/RangeShiftR/src/RScore/CMakeLists.txt b/RangeShiftR/src/RScore/CMakeLists.txt new file mode 100644 index 0000000..c14a3e3 --- /dev/null +++ b/RangeShiftR/src/RScore/CMakeLists.txt @@ -0,0 +1,30 @@ +# 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/RangeShiftR/src/RScore/CONTRIBUTING.md b/RangeShiftR/src/RScore/CONTRIBUTING.md new file mode 100644 index 0000000..e1b62ff --- /dev/null +++ b/RangeShiftR/src/RScore/CONTRIBUTING.md @@ -0,0 +1,81 @@ +# The RangeShifter platform - An eco-evolutionary modelling framework + +## How to contribute + +Thank you for your interest in contributing to the RangeShifter platform. +In this document we will give you guidance on how to contribute to the RangeShifter project regarding issues, bug fixing and adding new features. + +## Repo structure + +![Rangeshifter repo structure](RS_repos.png) + +RangeShifter is distributed with three user interfaces, each living in their own repo: + +- the RangeShifter GUI (clickable Windows interface)* +- RangeShifter Batch Mode (command line interface) +- the RangeShiftR package (R interface) + +All three share the same source code for the core simulation (i.e., the actual model), which lives in this repo (RScore). Each of the interfaces keeps a copy of this core code in a subfolder called RScore, kept in sync with the RScore repo via a git subtree (see Git subtree usage section). + +⚠️ If you wish to propose a change to one of the interfaces, please do so in the corresponding repo: [RangeShifter batch mode](https://github.com/RangeShifter/RangeShifter_batch_dev), [RangeShiftR package](https://github.com/RangeShifter/RangeShiftR-package-dev). + +*The RangeShifter GUI is currently being rewritten, and is not open source yet. + +## Roles + +#### Maintainers + +- [@JetteReeg](https://github.com/JetteReeg): RScore repo and lead in R package +- [@TheoPannetier](https://github.com/TheoPannetier): RScore repo and lead in batch mode + +Maintainers are responsible for coordinating development efforts and ensuring that RangeShifter keeps building continuously. + +#### Developers + +Regular contributors and members of the [RangeShifter development team](https://github.com/orgs/RangeShifter/people), including maintainers. + +#### Contributors + +Anyone who whishes to make changes to RangeShifter's code, including regular developers. + +## Branching policy + +![](branches.png) + +*Check out the [Git cheatsheet](https://github.com/RangeShifter/RScore/blob/main/git_cheatsheet.md) for a reminder on the main git commands* + +This policy applies to RScore and all three RangeShifter interfaces. +RangeShifter uses the following branching structure: + +- `main` is the default branch, where stable releases live. Because it contains the version of RangeShifter that users normally interact with, it must be stable and build at all times. +Only maintainers should make significant changes to `main`, normally by merging `develop` into `main` to make newly developed features available to users, and marking a release while doing so. +- `develop` is the development branch containing new, in-development features. It is the reference branch for all developers. Contributors may make small changes directly to `develop` but should ensure that new changes do not break the build. If one happens to break `develop`, it should be their top priority to fix it as this will disrupt the work of all other contributors. +Larger changes should instead be developed on feature branches. +- Larger changes should be first developed on feature (e.g. `cmake`, `mutualism`, etc.) or contributor (e.g., `theo`) branches. Contributors are welcome to experiment and break such branches at any time, as this will not impact users or other contributors. + +When progress is deemed satisfactory, changes can be brought to `develop`. Please open a pull request on GitHub, and assign at least one maintainer as a reviewer. As a pre-requisite, RangeShifter must build on the branch before merging. Please enter a descriptive title and use the description field to describe what you have changed. + +In the meantime, we encourage contributors to work in small and frequent commits, and to merge `develop` into their branch often to update their branch with newest changes. + +### Contributing to RangeShifter core code + +Any changes regarding the RangeShifter core code should be done in this repository and can afterwards be synced with all interfaces using the git subtree feature (see [Git subtree](https://github.com/RangeShifter/RScore/tree/main?tab=readme-ov-file#usage-git-subtree) section in the README). + +#### Bugs + +To report a bug, please [open an issue](https://github.com/RangeShifter/RangeShiftR-package-dev/issues/new), using the Bug Report template. +Please do check if a related issue has already open on one of the other interfaces ([here](https://github.com/RangeShifter/RangeShifter_batch-dev/issues) for the batch interface or [here](https://github.com/RangeShifter/RangeShiftR-package-dev) for the R package interface). +To propose a bug fix (thank you!!), please create and work on your own branch or fork, from either `main` or `develop` (preferred), and open a pull request when your fix is ready to be merged into the original branch. + +Maintainers will review the pull request, possibly request changes, and eventually integrate the bug fix into RScore, and update the subtrees to bring the fix to all interfaces. + +#### New features + +Do you have an idea of a new feature in the RangeShifter platform that should be integrated and is of use for other RangeShifter users? +Please get in touch with the RangeShifter development team (rangeshiftr@uni-potsdam.de) to discuss a collaboration. + +⚠️ We advise to contact the developer team as early as possible if you plan on implementing a new feature. This could prevent simultaneous development of the same feature and coordinate potential joint development. + +Alternatively, proceed as with the bug fix above: create your own branch or fork _from `develop`_ and work from there, and submit a pull request when your new features are ready to join the core code. +We recommend that you update your branch regularly to new changes on `develop` (using `git merge develop`) to reduce the risk of merge conflicts or your version getting out-of-touch in the late stages of development. +We also recommend that you work in small commits, as this makes the code easier to debug, and makes it easier for maintainers to understand your contributions when reviewing a pull request. diff --git a/RangeShiftR/src/RScore/Community.cpp b/RangeShiftR/src/RScore/Community.cpp index bfdf938..286dc6a 100644 --- a/RangeShiftR/src/RScore/Community.cpp +++ b/RangeShiftR/src/RScore/Community.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 "Community.h" @@ -28,574 +28,553 @@ ofstream outrange; -ofstream outoccup,outsuit; +ofstream outoccup, outsuit; ofstream outtraitsrows; //--------------------------------------------------------------------------- -Community::Community(Landscape *pLand) { -pLandscape = pLand; -indIx = 0; +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(); + 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]; +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) +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(); + 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(); + nsubcomms = (int)subComms.size(); -spratio = ppLand.spResol / ppLand.resol; + 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; + 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); + 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); + 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; + // 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; + 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); + // selected sub-communities for initialisation + for (int i = 0; i < nsubcomms; i++) { // all sub-communities + subComms[i]->setInitial(false); } - } - break; + 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; + 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); } - 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 + + 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; - // 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); - } - } + 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); + } } - - 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 } - } - else { - // WHAT HAPPENS IF INITIAL DISTRIBUTION IS NOT LOADED ??? .... - // should not occur - take no action - no initialisation will occur - } - break; + 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) + 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 (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); + pSubComm = addSubComm(pPatch, iind.patchID); } else { pSubComm = (SubCommunity*)subcomm; } - pSubComm->initialInd(pLandscape,pSpecies,pPatch,pCell,indIx); + pSubComm->initialInd(pLandscape, pSpecies, pPatch, pPatch->getRandomCell(), indIx); } } } - } - indIx++; - if (indIx < ninds) { - iind = paramsInit->getInitInd(indIx); - } - else { - iind.year = 99999999; + 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; + 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; + 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) + } // end of switch (init.seedType) #if RSDEBUG -DEBUGLOG << "Community::initialise(): this=" << this - << " nsubcomms=" << nsubcomms - << endl; + 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; + int npatches; + intptr subcomm, patch; + locn initloc; + Cell* pCell; + Patch* pPatch; + SubCommunity* pSubComm; -landParams ppLand = pLandscape->getLandParams(); + landParams ppLand = pLandscape->getLandParams(); -npatches = pLandscape->initCellCount(); // no. of patches/cells specified + npatches = pLandscape->initCellCount(); // no. of patches/cells specified #if RSDEBUG -DEBUGLOG << "Community::addManuallySelected(): this = " << this - << " npatches = " << npatches << endl; + 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); + // 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(); + 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; + 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 (patch != 0) { + pPatch = (Patch*)patch; + subcomm = pPatch->getSubComm(); #if RSDEBUG -DEBUGLOG << "Community::initialise(): i = " << i - << " pPatch = " << pPatch << " subcomm = " << subcomm - << endl; + DEBUGLOG << "Community::initialise(): i = " << i + << " pPatch = " << pPatch << " subcomm = " << subcomm + << endl; #endif - if (subcomm != 0) { - pSubComm = (SubCommunity*)subcomm; - pSubComm->setInitial(true); + if (subcomm != 0) { + pSubComm = (SubCommunity*)subcomm; + pSubComm->setInitial(true); #if RSDEBUG -DEBUGLOG << "Community::initialise(): i = " << i - << " pSubComm = " << pSubComm - << endl; + 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; + 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); + 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(); + 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(); + 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; + 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); + 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); } - subComms[i]->reproduction(land.resol,eps,land.rasterType,land.patchModel); -} #if RSDEBUG -DEBUGLOG << "Community::reproduction(): finished" << endl; + DEBUGLOG << "Community::reproduction(): finished" << endl; #endif } -void Community::emigration(void) +void Community::emigration(void) { -int nsubcomms = (int)subComms.size(); + int nsubcomms = (int)subComms.size(); #if RSDEBUG -DEBUGLOG << "Community::emigration(): this=" << this - << " nsubcomms=" << nsubcomms << endl; + DEBUGLOG << "Community::emigration(): this=" << this + << " nsubcomms=" << nsubcomms << endl; #endif -for (int i = 0; i < nsubcomms; i++) { // all sub-communities - subComms[i]->emigration(); -} + for (int i = 0; i < nsubcomms; i++) { // all sub-communities + subComms[i]->emigration(); + } #if RSDEBUG -DEBUGLOG << "Community::emigration(): finished" << endl; + DEBUGLOG << "Community::emigration(): finished" << endl; #endif } #if RS_RCPP // included also SEASONAL -void Community::dispersal(short landIx,short nextseason) +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); + 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 + simParams sim = paramsSim->getSim(); -// dispersal is undertaken by all individuals now in the matrix patch -// (even if not physically in the matrix) -int ndispersers = 0; -do { + 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]->resetPossSettlers(); + subComms[i]->initiateDispersal(matrix); } #if RSDEBUG -//DEBUGLOG << "Community::dispersal() 1111: ndispersers=" << ndispersers << endl; + 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 RS_RCPP // included also SEASONAL - ndispersers = matrix->transfer(pLandscape,landIx,nextseason); + ndispersers = matrix->transfer(pLandscape, landIx, nextseason); #else - ndispersers = matrix->transfer(pLandscape,landIx); + 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 + matrix->completeDispersal(pLandscape, sim.outConnect); + } while (ndispersers > 0); #if RSDEBUG -//int t3 = time(0); -//DEBUGLOG << "Community::dispersal(): completion time = " << t3-t2 << endl; + DEBUGLOG << "Community::dispersal(): matrix=" << matrix << endl; + t2 = time(0); + DEBUGLOG << "Community::dispersal(): transfer time=" << t2 - t1 << endl; #endif } -void Community::survival(short part,short option0,short option1) +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); -} + 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(); -} + 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; + 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; +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::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) +void Community::updateOccupancy(int row, int rep) { #if RSDEBUG -DEBUGLOG << "Community::updateOccupancy(): row=" << row << endl; + DEBUGLOG << "Community::updateOccupancy(): row=" << row << endl; #endif -int nsubcomms = (int)subComms.size(); -for (int i = 0; i < nsubcomms; i++) { - subComms[i]->updateOccupancy(row); -} + 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; + 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(); -} + 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; + for (int i = 0; i < nrows; i++) + delete[] occSuit[i]; + delete[] occSuit; } @@ -604,49 +583,33 @@ delete[] occSuit; // 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; + 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 (patchPop.pPatch != 0) { // not the matrix patch + if (patchPop.pPatch->getPatchNum() != 0) { // not matrix patch + localK = patchPop.pPatch->getK(); + 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; + return s; } //--------------------------------------------------------------------------- @@ -654,650 +617,593 @@ 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); +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) +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); -} + // 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) { +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); -} + 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); -} +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) +bool Community::outRangeHeaders(Species* pSpecies, int landNr) { -if (landNr == -999) { // close the file - if (outrange.is_open()) outrange.close(); - outrange.clear(); - return true; -} + 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(); + 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(); + // 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; + DEBUGLOG << "Community::outRangeHeaders(): simulation=" << sim.simulation + << " sim.batchMode=" << sim.batchMode + << " landNr=" << landNr << endl; #endif -if (sim.batchMode) { - name = paramsSim->getDir(2) + if (sim.batchMode) { + name = paramsSim->getDir(2) #if RS_RCPP - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" - + Int2Str(landNr) + + "Batch" + Int2Str(sim.batchNum) + "_" + + "Sim" + Int2Str(sim.simulation) + "_Land" + + Int2Str(landNr) #else - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) + "_Land" - + Int2Str(landNr) + + "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"; - } + + "_Range.txt"; } else { - if (emig.densDep) { - outrange << "\tmeanD0\tstdD0\tmeanAlpha\tstdAlpha"; - outrange << "\tmeanBeta\tstdBeta"; + 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 { - outrange << "\tmeanEP\tstdEP"; + 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"; + 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"; + } } - 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" + 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 << "\tmean_distI\tstd_distI"; - if (trfr.twinKern) - outrange << "\tmean_distII\tstd_distII\tmeanPfirstKernel\tstdPfirstKernel"; + outrange << "\tmeanS0\tstdS0"; + outrange << "\tmeanAlphaS\tstdAlphaS"; + outrange << "\tmeanBetaS\tstdBetaS"; } } -} -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; + outrange << endl; #if RSDEBUG -DEBUGLOG << "Community::outRangeHeaders(): finished" << endl; + DEBUGLOG << "Community::outRangeHeaders(): finished" << endl; #endif -return outrange.is_open(); + return outrange.is_open(); } // Write record to range file -void Community::outRange(Species *pSpecies,int rep,int yr,int gen) +void Community::outRange(Species* pSpecies, int rep, int yr, int gen) { #if RSDEBUG -DEBUGLOG << "Community::outRange(): rep=" << rep - << " yr=" << yr << " gen=" << gen << endl; + 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++) { + 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(stg); + stagepop += subComms[i]->stagePop(0); } - outrange <<"\t" << stagepop; + 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); + else { // non-structured species + outrange << "\t" << s.ninds; } - 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; + 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"; - 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 || trfr.indVar || sett.indVar) { // output trait means + traitsums ts; + traitsums scts; // sub-community traits + traitCanvas tcanv; + int ngenes, popsize; - if (emig.indVar) { - if (emig.sexDep) { // must be a sexual species - ngenes = 2; + 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; } - else { - if (dem.repType == 0) { // asexual reproduction - ngenes = 1; - } - else { // sexual reproduction - ngenes = 1; + + 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]; } } - 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; + + if (emig.indVar) { + if (emig.sexDep) { // must be a sexual species + ngenes = 2; + } + else { + if (dem.repType == 0) { // asexual reproduction + ngenes = 1; } - else { - sdD0[g] = sdAlpha[g] = sdBeta[g] = 0.0; + else { // sexual reproduction + ngenes = 1; } } -#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]; + 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; + } + } } - } - 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 (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 { + if (trfr.indVar) { + if (trfr.moveModel) { + // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT 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; + else { + if (trfr.sexDep) { // must be a sexual species + ngenes = 2; + } + else { + ngenes = 1; } } -#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]; + 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; + } + } } - } - 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]; + 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 { // 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]; + 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; + if (sett.indVar) { + if (sett.sexDep) { // must be a sexual species + ngenes = 2; } - } - // 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 { + if (dem.repType == 0) { // asexual reproduction + ngenes = 1; } - else { - sdS0[g] = sdAlpha[g] = sdBeta[g] = 0.0; + 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]; + } } - 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; + 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; -} + 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; + string name, nameI; + simParams sim = paramsSim->getSim(); + 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; + 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); + // Initialise cells/patches occupancy array + createOccupancy(outrows, sim.reps); -return outsuit.is_open() && outoccup.is_open(); + 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; + landParams ppLand = pLandscape->getLandParams(); + simParams sim = paramsSim->getSim(); + 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; + 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; } - 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 + double sum, ss, mean, sd, se; + simParams sim = paramsSim->getSim(); + 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]; + } + mean = sum / (double)sim.reps; + sd = (ss - (sum * sum / (double)sim.reps)) / (double)(sim.reps - 1); + if (sd > 0.0) sd = sqrt(sd); + else sd = 0.0; + se = sd / sqrt((double)(sim.reps)); + outsuit << i * sim.outIntOcc << "\t" << mean << "\t" << se << endl; + if (view) viewOccSuit(i * sim.outIntOcc, mean, se); } - 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); +bool Community::outTraitsHeaders(Species* pSpecies, int landNr) { + return subComms[0]->outTraitsHeaders(pLandscape, pSpecies, landNr); } // Write records to traits file @@ -1306,366 +1212,306 @@ only, this function relies on the fact that subcommunities are created in the sa 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) +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; + simParams sim = paramsSim->getSim(); + simView v = paramsSim->getViews(); + landParams land = pLandscape->getLandParams(); + 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 (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(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 (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; } + 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, +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; - } - } -} + 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; + if ((emig.indVar && emig.sexDep) || (trfr.indVar && trfr.sexDep)) + outtraitsrows << "\t" << ts.ninds[0] << "\t" << ts.ninds[1]; + else + outtraitsrows << "\t" << popsize; -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 (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 (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 (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 (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; + 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 { // 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; + 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 (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 (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 (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 (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 (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 (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 (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 (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; } } - 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; + 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 (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 (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 (sett.indVar) { + 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 (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 (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; + outtraitsrows << endl; } // Open trait rows file and write header record -bool Community::outTraitsRowsHeaders(Species *pSpecies,int landNr) { +bool Community::outTraitsRowsHeaders(Species* pSpecies, int landNr) { -if (landNr == -999) { // close file - if (outtraitsrows.is_open()) outtraitsrows.close(); - outtraitsrows.clear(); - return true; -} + 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"; - } + 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 { - if (emig.densDep) { - outtraitsrows << "\tmeanD0\tstdD0\tmeanAlpha\tstdAlpha"; - outtraitsrows << "\tmeanBeta\tstdBeta"; + 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 { - outtraitsrows << "\tmeanEP\tstdEP"; + 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"; + 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" + 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"; + } + 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 { + if (sett.indVar) { outtraitsrows << "\tmeanS0\tstdS0"; outtraitsrows << "\tmeanAlphaS\tstdAlphaS"; outtraitsrows << "\tmeanBetaS\tstdBetaS"; -// } -} -outtraitsrows << endl; + } + outtraitsrows << endl; -return outtraitsrows.is_open(); + return outtraitsrows.is_open(); } @@ -1673,42 +1519,41 @@ return outtraitsrows.is_open(); 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); + Rcpp::IntegerMatrix pop_map_year(ppLand.dimY, ppLand.dimX); intptr patch = 0; Patch* pPatch = 0; intptr subcomm = 0; - SubCommunity *pSubComm = 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) { + Cell* pCell = pLandscape->findCell(x, y); if (pCell == 0) { // no-data cell - pop_map_year(ppLand.dimY-1-y,x) = NA_INTEGER; - } else { + 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; + pop_map_year(ppLand.dimY - 1 - y, x) = 0; } - else{ + 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 { + 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; + 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 } } } } } - //list_outPop.push_back(pop_map_year, "rep" + std::to_string(rep) + "_year" + std::to_string(yr)); - return pop_map_year; + return pop_map_year; } #endif diff --git a/RangeShiftR/src/RScore/Community.h b/RangeShiftR/src/RScore/Community.h index 6a07b5b..c55b333 100644 --- a/RangeShiftR/src/RScore/Community.h +++ b/RangeShiftR/src/RScore/Community.h @@ -52,13 +52,7 @@ Last updated: 25 June 2021 by Anne-Kathleen Malchow #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" @@ -103,12 +97,12 @@ class Community { void survival( short, // part: 0 = determine survival & development, - // 1 = apply survival changes to the population + // 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) ) + // 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 + // 1 - development and survival ); void ageIncrement(void); int totalInds(void); @@ -187,8 +181,6 @@ class Community { ); 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 diff --git a/RangeShiftR/src/RScore/Genome.cpp b/RangeShiftR/src/RScore/Genome.cpp index 90d030b..59a68b1 100644 --- a/RangeShiftR/src/RScore/Genome.cpp +++ b/RangeShiftR/src/RScore/Genome.cpp @@ -1,26 +1,23 @@ /*---------------------------------------------------------------------------- - * - * 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 "Genome.h" //--------------------------------------------------------------------------- @@ -29,242 +26,125 @@ 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; -} + 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; -} + if (pLoci != 0) { + 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; + 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; + int sum = 0; + for (int i = 0; i < nloci; i++) { + sum += pLoci[i].allele[0]; + if (diploid) sum += pLoci[i].allele[1]; + } + 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; + 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; + 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::additive(const short loc, const bool diploid) { + int sum = 0; + sum += pLoci[loc].allele[0]; + if (diploid) sum += pLoci[loc].allele[1]; + 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); +void Chromosome::initialise(const double mean, const double sd, + const bool diploid) { + double avalue; + double intbase = INTBASE; + + for (int i = 0; i < nloci; i++) { + avalue = pRandom->Normal(mean, sd); if (avalue > 0.0) - pLoci[i].allele[1] = (int)(avalue * intbase + 0.5); + pLoci[i].allele[0] = (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 + pLoci[i].allele[0] = (int)(avalue * intbase - 0.5); + if (diploid) { + 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); + } } -} } // Set up specified locus at simulation initialisation -void Chromosome::initialise(const short locus,const short posn,const int aval) +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; + // 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) +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; + // 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?... + + 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); + pLoci[i].allele[posn] = parentChr->pLoci[i].allele[0]; + if (pRandom->Bernoulli(probmutn)) { // mutation occurs + double intbase = INTBASE; #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; + int oldval = pLoci[i].allele[posn]; #endif + 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 -//MUTNLOG << 1 << endl; -MUTNLOG << mutnvalue << " " << oldval << " " << pLoci[i].allele[posn] << " " << endl; + MUTNLOG << mutnvalue << " " << oldval << " " << pLoci[i].allele[posn] << " " << endl; #endif + } } -#if RSDEBUG -// else { -//MUTNLOG << 0 << endl; -// } -#endif -} } @@ -273,92 +153,68 @@ MUTNLOG << mutnvalue << " " << oldval << " " << pLoci[i].allele[posn] << " " << // 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; +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 +Genome::Genome(int nchromosomes, int nloci, bool d) { -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); -} + 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); + } } // 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); -} +Genome::Genome(Species* pSpecies) { + int nloci; + nChromosomes = pSpecies->getNChromosomes(); + diploid = pSpecies->isDiploid(); + pChromosome = new Chromosome * [nChromosomes]; + for (int i = 0; i < nChromosomes; i++) { + nloci = pSpecies->getNLoci(i); + pChromosome[i] = new Chromosome(nloci); + } } // Inherit genome from parent(s) -Genome::Genome(Species *pSpecies,Genome *mother,Genome *father) +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); + 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); } - else inherit(father,1,i,gen.probMutn,gen.probCrossover,gen.mutationSD); } -} } -Genome::~Genome(){ +Genome::~Genome() { -if (pChromosome == NULL) return; + if (pChromosome == NULL) return; -for (int i = 0; i < nChromosomes; i++) { - delete pChromosome[i]; -} -delete[] pChromosome; + 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; } @@ -368,493 +224,195 @@ 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) +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); + 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) +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(); + if (landNr == -999) { // close file + if (outGenetic.is_open()) { + outGenetic.close(); outGenetic.clear(); + } + return; } - 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()); + string name; + simParams sim = paramsSim->getSim(); -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"; + 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; } - 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]; +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; } - 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; + 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... + 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); -} + 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) + 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); + traitAllele allele; + int nalleles = pSpecies->getNTraitAlleles(trait); + int ntraitmaps = pSpecies->getNTraitMaps(); + + int avalue; + double intbase = INTBASE; + if (trait < ntraitmaps) { + for (int i = 0; i < nalleles; i++) { + allele = pSpecies->getTraitAllele(trait, i); + avalue = (int)(pRandom->Normal(traitval, alleleSD) * intbase); + pChromosome[allele.chromo]->initialise(allele.locus, 0, avalue); + if (diploid) { + 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 -} + else { // insufficient traits were defined + // alleles cannot be initialised - all individuals have mean phenotype + } } // Set up trait at initialisation for trait mapping -void Genome::setNeutralLoci(Species *pSpecies,const double alleleSD) +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); + traitAllele allele; + int nneutral = pSpecies->getNNeutralLoci(); + + double avalue; + double intbase = INTBASE; + for (int i = 0; i < nneutral; i++) { + allele = pSpecies->getNeutralAllele(i); + avalue = pRandom->Normal(0.0, alleleSD); if (avalue > 0.0) - pChromosome[allele.chromo]->initialise(allele.locus,1,(int)(avalue * intbase + 0.5)); + pChromosome[allele.chromo]->initialise(allele.locus, 0, (int)(avalue * intbase + 0.5)); else - pChromosome[allele.chromo]->initialise(allele.locus,1,(int)(avalue * intbase - 0.5)); + pChromosome[allele.chromo]->initialise(allele.locus, 0, (int)(avalue * intbase - 0.5)); + if (diploid) { + 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 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; + double genevalue = 0.0; + genevalue = pChromosome[chr]->meanvalue(diploid); + return genevalue; } -*/ // Return the expressed value of a trait when genetic architecture is defined -double Genome::express(Species *pSpecies,short traitnum) +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; + 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; } + return genevalue; } -// 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 +locusOK Genome::getAlleles(short chr, short loc) { + locusOK l; + l.allele[0] = l.allele[1] = 0; l.ok = false; + 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; + } + } } -} -#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; + return l; } -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 index d42c161..4f01ede 100644 --- a/RangeShiftR/src/RScore/Genome.h +++ b/RangeShiftR/src/RScore/Genome.h @@ -1,43 +1,29 @@ /*---------------------------------------------------------------------------- - * - * 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 . - * + * --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ - -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" @@ -65,7 +51,6 @@ class Chromosome { 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 ); @@ -93,25 +78,19 @@ class Chromosome { private: short nloci; - locus *pLoci; + locus* pLoci; }; //--------------------------------------------------------------------------- -class Genome{ +class Genome { public: -// -// static float delPMutation, delEffectSize, delDominance, delBackMutation ,genomeMeanRecombination; -// static int delMaxSize, delNMutations; -// static bool genomeCanRecombine, genomeCompletelyUnlinked; -// - Genome(); - Genome(int,int,bool); + Genome(int, int, bool); Genome(Species*); - Genome(Species*,Genome*,Genome*); + Genome(Species*, Genome*, Genome*); ~Genome(); void setGene( // Set up new gene at initialisation for 1 chromosome per trait const short, // chromosome number @@ -129,22 +108,16 @@ class Genome{ 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 + // 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 + // 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 @@ -161,8 +134,6 @@ class Genome{ 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 @@ -181,64 +152,15 @@ class Genome{ private: short nChromosomes; // no. of chromosomes bool diploid; - Chromosome **pChromosome; - -}; - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- + 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; +extern paramSim* paramsSim; +extern RSrandom* pRandom; #if RSDEBUG extern ofstream DEBUGLOG; diff --git a/RangeShiftR/src/RScore/Individual.cpp b/RangeShiftR/src/RScore/Individual.cpp index 357f175..73f6f6f 100644 --- a/RangeShiftR/src/RScore/Individual.cpp +++ b/RangeShiftR/src/RScore/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,72 @@ 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 +104,300 @@ 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; + + 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 +405,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 +419,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 +848,408 @@ 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; -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)++; + 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; } - 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? ... - patch = pCurrCell->getPatch(); - //int patchnum; - if (patch == 0) { - pPatch = 0; - //patchnum = 0; + 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 { - 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 (dispersing == 1 && + 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 +1258,479 @@ 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) +movedata Individual::smsMove(Landscape* pLand, Species* pSpecies, + const short landIx, const bool natalPatch, const bool indvar, const bool absorbing) { -// 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 = -9, newY = -9; + 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 = "<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++; } - 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; + } else{ + pNewCell = pLand->findCell(newX, newY); // would also return 0 if outside boundary } } - loopsteps++; - } while (loopsteps < 1000 - && (!absorbing && (newX < land.minX || newX > land.maxX - || newY < land.minY || newY > land.maxY))); - if (loopsteps >= 1000) pNewCell = 0; + } while (!absorbing && pNewCell == 0 && loopsteps < 1000); // no-data cell + if (loopsteps >= 1000 || pNewCell == 0 || (newX == -9 || newY== -9)) { // if no cell was found + // unable to make a move or crossed absorbing boundary + // flag individual to die + move.dist = -123.0; + if (pNewCell == 0) pCurrCell = pNewCell; + } else { - if (newX < land.minX || newX > land.maxX - || newY < land.minY || newY > land.maxY) { - pNewCell = 0; - } - pNewCell = pLand->findCell(newX,newY); + 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; } -} -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; + 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 +1787,76 @@ void Individual::outMovePath(const int year) //--------------------------------------------------------------------------- -double wrpcauchy (double location, double rho) { -double result; +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); + 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 can move to a neighbouring cell + //ind.moveto(); + + // Gets its sex drawn from pmale + + // Can age or develop + + // + + // 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/RangeShiftR/src/RScore/Individual.h b/RangeShiftR/src/RScore/Individual.h index d843d7e..bdc4ecb 100644 --- a/RangeShiftR/src/RScore/Individual.h +++ b/RangeShiftR/src/RScore/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/RangeShiftR/src/RScore/Landscape.cpp b/RangeShiftR/src/RScore/Landscape.cpp index be63ae9..f1c810a 100644 --- a/RangeShiftR/src/RScore/Landscape.cpp +++ b/RangeShiftR/src/RScore/Landscape.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 "Landscape.h" //--------------------------------------------------------------------------- @@ -37,119 +37,119 @@ ofstream outMovePaths; // Initial species distribution functions -InitDist::InitDist(Species *pSp) +InitDist::InitDist(Species* pSp) { -pSpecies = pSp; -resol = 0; -maxX = 0; -maxY = 0; -minEast = 0.0; -minNorth = 0.0; + 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(); + 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); + 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 { // 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); + 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); +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; +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; + 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; + return false; } int InitDist::cellCount(void) { -return (int)cells.size(); + 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; + 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(); + locn loc; loc.x = loc.y = -666; + if (ix < (int)cells.size()) { + if (cells[ix]->selected()) { + loc = cells[ix]->getLocn(); + } } -} -return loc; + return loc; } locn InitDist::getDimensions(void) { -locn d; d.x = maxX; d.y = maxY; return d; + 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); -} + int ncells = (int)cells.size(); + for (int i = 0; i < ncells; i++) { + cells[i]->setCell(false); + } } //--------------------------------------------------------------------------- @@ -158,64 +158,62 @@ for (int i = 0; i < ncells; i++) { int InitDist::readDistribution(string distfile) { #if RS_RCPP -wstring header; + wstring header; #else -string header; + string header; #endif -int p,nodata; -int ncols,nrows; + int p, nodata; + int ncols, nrows; #if RS_RCPP -wifstream dfile; // species distribution file input stream + wifstream dfile; // species distribution file input stream #else -ifstream dfile; // species distribution file input stream + ifstream dfile; // species distribution file input stream #endif -// open distribution file + // open distribution file #if !RS_RCPP || RSWIN64 dfile.open(distfile.c_str()); #else dfile.open(distfile, std::ios::binary); - if(spdistraster.utf) { + 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; + 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 >> resol >> header >> nodata; + >> header >> tmpresol >> header >> nodata; +resol = (int) tmpresol; #if RS_RCPP -if (!dfile.good()) { - // corrupt file stream - StreamErrorR(distfile); - dfile.close(); - dfile.clear(); - return 144; -} + if (!dfile.good()) { + // corrupt file stream + StreamErrorR(distfile); + dfile.close(); + dfile.clear(); + return 144; + } #endif -maxX = ncols-1; maxY = nrows-1; + 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; + // 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; + for (int y = nrows - 1; y >= 0; y--) { + for (int x = 0; x < ncols; x++) { + p = badvalue; #if RS_RCPP - if(dfile >> p) { + if (dfile >> p) { #else - dfile >> p; -#endif -#if RSDEBUG -//DEBUGLOG << "InitDist::readDistribution():" -// << " y = " << y << " x = " << x << " p = " << p << endl; + dfile >> p; #endif if (p == nodata || p == 0 || p == 1) { // only valid values if (p == 1) { // species present - cells.push_back(new DistCell(x,y)); + cells.push_back(new DistCell(x, y)); } } else { // error in file @@ -223,26 +221,27 @@ for (int y = nrows-1; y >= 0; y--) { 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; - } + } + 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); +dfile >> p; +if (!dfile.eof()) EOFerrorR(distfile); #endif -dfile.close(); dfile.clear(); -return 0; + dfile.close(); dfile.clear(); + return 0; } @@ -251,268 +250,203 @@ 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 + 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; + connectMatrix = 0; + epsGlobal = 0; + patchChgMatrix = 0; + costsChgMatrix = 0; } 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]; + if (cells != 0) { + for (int y = dimY - 1; y >= 0; y--) { + + for (int x = 0; x < dimX; x++) { + + if (cells[y][x] != 0) delete cells[y][x]; + } + if (cells[y] != 0) { + delete[] cells[y]; + } } + delete[] cells; + cells = 0; } - 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 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 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(); + 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(); + patchnums.clear(); + habCodes.clear(); + colours.clear(); + landchanges.clear(); + patchchanges.clear(); -deleteConnectMatrix(); -deletePatchChgMatrix(); -if (epsGlobal != 0) delete[] epsGlobal; + 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 + resetLandLimits(); + int npatches = (int)patches.size(); + for (int i = 0; i < npatches; i++) if (patches[i] != NULL) delete patches[i]; + patches.clear(); -#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]; + if (cells != 0) { + for (int y = dimY - 1; y >= 0; y--) { + for (int x = 0; x < dimX; x++) { + if (cells[y][x] != 0) delete cells[y][x]; + } + if (cells[y] != 0) { + delete[] cells[y]; + } } + delete[] cells; + cells = 0; } - 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) +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); + 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; + 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; + 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; + 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; + 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::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; + 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; + 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; + landPix p; + p.pix = pix; p.gpix = gpix; + return p; } void Landscape::setOrigin(landOrigin origin) { -minEast = origin.minEast; minNorth = origin.minNorth; + minEast = origin.minEast; minNorth = origin.minNorth; } landOrigin Landscape::getOrigin(void) { -landOrigin origin; -origin.minEast = minEast; origin.minNorth = minNorth; -return origin; + landOrigin origin; + origin.minEast = minEast; origin.minNorth = minNorth; + return origin; } //--------------------------------------------------------------------------- @@ -522,110 +456,94 @@ return origin; bool Landscape::habitatsIndexed(void) { return habIndexed; } void Landscape::listHabCodes(void) { -int nhab = (int)habCodes.size(); + 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; + 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; + 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; + 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++; } + 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; + 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; + if (ixhab < (int)habCodes.size()) return habCodes[ixhab]; + else return -999; } void Landscape::clearHabitats(void) { -habCodes.clear(); -colours.clear(); + habCodes.clear(); + colours.clear(); } void Landscape::addColour(rgb c) { -colours.push_back(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; -} +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]; + return colours[ix]; } int Landscape::colourCount(void) { -return (int)colours.size(); + 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 (cells != 0) resetLand(); + cells = new Cell * *[dimY]; + for (int y = dimY - 1; y >= 0; y--) { + cells[y] = new Cell * [dimX]; + 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; + 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); + if (addpatch) patchnums.push_back(p); } @@ -635,147 +553,106 @@ 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; + int x, y, ncells; + double p; + Patch* pPatch; + Cell* pCell; -vector ArtLandscape; + 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); + 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++) { + 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; + 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); + 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]); + vector::iterator iter = ArtLandscape.begin(); + while (iter != ArtLandscape.end()) { + x = iter->y_coord; y = iter->x_coord; + 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 { // habitat - pPatch = newPatch(patchnum++); - addCellToPatch(pCell,pPatch); - pCell->changeHabIndex(0,1); + else { // discrete + if (iter->avail == 0) { // matrix + addCellToPatch(pCell, patches[0]); + } + else { // habitat + pPatch = newPatch(patchnum++); + addCellToPatch(pCell, pPatch); + pCell->changeHabIndex(0, 1); + } } + iter++; } - 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 { + else { // random landscape + int hab = 0; + ncells = (int)((float)(dimX) * (float)(dimY)*propSuit + 0.00001); // no. of cells to initialise + int i = 0; 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); + do { + x = pRandom->IRandom(0, dimX - 1); y = pRandom->IRandom(0, dimY - 1); + pCell = findCell(x, y); + hab = pCell->getHabIndex(0); + } while (hab > 0); + pPatch = newPatch(patchnum++); + pCell = findCell(x, y); + addCellToPatch(pCell, pPatch); + pCell->changeHabIndex(0, 1); if (continuous) { - if (pCell->getHabitat(0) <= 0.0) - { - addCellToPatch(pCell,patches[0],(float)p); - } + pCell->setHabitat((float)(minPct + pRandom->Random() * (maxPct - minPct))); } - else { // discrete - if (pCell->getHabIndex(0) == 0) { -#if RSDEBUG -//DEBUGLOG << "Landscape::generatePatches() 11111: yy=" << yy << " xx=" << xx -// << endl; -#endif - addCellToPatch(pCell,patches[0],x); + 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) { + addCellToPatch(pCell, patches[0], x); + } } } } } } -#if RSDEBUG -//DEBUGLOG << "Landscape::generatePatches(): finished, no. of patches = " -// << patchCount() << endl; -#endif - -} - //--------------------------------------------------------------------------- // Landscape patch-management functions @@ -783,518 +660,419 @@ else { // random landscape //--------------------------------------------------------------------------- /* 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) +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; + float habK; + Patch* pPatch; + Cell* pCell; -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; + // delete all existing patches + int npatches = (int)patches.size(); + for (int i = 0; i < npatches; i++) { + if (patches[i] != NULL) delete patches[i]; + } + patches.clear(); + // create the matrix patch + patches.push_back(new Patch(0, 0)); + Patch* matrixPatch = patches[0]; + 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 (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++) { + habK += pSpecies->getHabK(pCell->getHabIndex(i)); + } + 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 1: // habitat cover + for (int y = dimY - 1; y >= 0; y--) { + for (int x = 0; x < dimX; x++) { + 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++) + { + habK += pSpecies->getHabK(i) * pCell->getHabitat(i) / 100.0f; + } + 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; + case 2: // habitat quality + for (int y = dimY - 1; y >= 0; y--) { + for (int x = 0; x < dimX; x++) { + + 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 (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 + break; + } // end of switch (rasterType) } -Patch* Landscape::newPatch(int num) +Patch* Landscape::newPatch(int num) { -int npatches = (int)patches.size(); -patches.push_back(new Patch(num,num)); -return patches[npatches]; + int npatches = (int)patches.size(); + patches.push_back(new Patch(num, num)); + return patches[npatches]; } -Patch* Landscape::newPatch(int seqnum,int num) +Patch* Landscape::newPatch(int seqnum, int num) { -int npatches = (int)patches.size(); -patches.push_back(new Patch(seqnum,num)); -return patches[npatches]; + 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(); -} + 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, 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::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, 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::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) { + 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, 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); +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; + 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; + 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; + 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(); -} + 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); +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; + 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; +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(); + return (int)patches.size(); } void Landscape::listPatches(void) { -patchLimits p; -int npatches = (int)patches.size(); + 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; + 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; + 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 (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 (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); } - 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; + 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); + // sort codes + sort(habCodes.begin(), habCodes.end()); + nHab = (int)habCodes.size(); + // convert codes in landscape + int h; + int changes = (int)landchanges.size(); + 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 (h >= 0) { + h = findHabCode(h); + + cells[y][x]->changeHabIndex(c, h); + } } } } } -} -habIndexed = true; + habIndexed = true; } -void Landscape::setEnvGradient(Species *pSpecies,bool initial) +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; + float dist_from_opt, dev; + float habK; + double envval; + // gradient parameters + envGradParams grad = paramsGrad->getGradient(); + 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); + + 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 (envval < 0.000001) envval = 0.0; + if (envval > 1.0) envval = 1.0; } - 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); } - 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))); -} + 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; + 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); + 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))); + 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(); + 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(); + 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(); + } } } } -} //--------------------------------------------------------------------------- @@ -1303,62 +1081,50 @@ for(int y = dimY-1; y >= 0; y--){ 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); + 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; + 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(); + 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) +int Landscape::readLandChange(int filenum, bool costs) #endif { #if RSDEBUG -DEBUGLOG << "Landscape::readLandChange(): filenum=" << filenum << " costs=" << int(costs) - << endl; + DEBUGLOG << "Landscape::readLandChange(): filenum=" << filenum << " costs=" << int(costs) + << endl; #endif #if RS_RCPP -wstring header; + wstring header; #else -string header; -int ncols,nrows,habnodata,costnodata,pchnodata; -costnodata = 0; -pchnodata = 0; + 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(); + 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 (filenum < 0) return 19; + if (patchModel) pchseq = patchCount(); #if !RS_RCPP ifstream hfile; // habitat file input stream @@ -1367,643 +1133,583 @@ if (patchModel) pchseq = patchCount(); #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; + // 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(); + 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; } - 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; -} + // 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; + // 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) { + 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; + 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) { + if (hfile >> hfloat) { #else - hfile >> hfloat; + hfile >> hfloat; #endif - h = (int)hfloat; + 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; - } + } + else { + // corrupt file stream +#if RS_RCPP && !R_CMD + Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; #endif - if (patchModel) { - pfloat = badpfloat; + StreamErrorR("habitatchgfile"); + hfile.close(); + hfile.clear(); + pfile.close(); + pfile.clear(); + return 171; + } +#endif + if (patchModel) { + pfloat = badpfloat; #if RS_RCPP - if(pfile >> pfloat) { + if (pfile >> pfloat) { #else - pfile >> pfloat; + pfile >> pfloat; #endif - p = (int)pfloat; + 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; - } + } + else { + // corrupt file stream +#if RS_RCPP && !R_CMD + Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; #endif - } - if (costs) { - cfloat = badcfloat; + StreamErrorR("patchchgfile"); + hfile.close(); + hfile.clear(); + pfile.close(); + pfile.clear(); + return 172; + } +#endif + } + if (costs) { + cfloat = badcfloat; #if RS_RCPP - if(cfile >> cfloat) { + if (cfile >> cfloat) { #else - cfile >> cfloat; + cfile >> cfloat; #endif - c = (int)cfloat; + 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; - } + } + 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 (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; } -#if RSDEBUG -//DebugGUI(("Landscape::readLandscape(): x=" + Int2Str(x) + " y=" + Int2Str(y) -// + " h=" + Int2Str(h) + " p=" + Int2Str(p) -//).c_str()); + 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 - 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); - } - } + 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 (costs) { + if (c < 1) { // invalid cost +#if RS_RCPP + Rcpp::Rcout << "Found invalid cost value of " << c << " in cell x " << x << " and y " << y << std::endl; +#endif + hfile.close(); hfile.clear(); + if (pfile.is_open()) { + pfile.close(); pfile.clear(); } + return 38; + } + else { + costsChgMatrix[y][x][2] = c; } } } + } // for x + } // for y #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"); - } + 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; + break; case 2: // habitat quality - for (int y = dimY-1; y >= 0; y--) { - for (int x = 0; x < dimX; x++) { - hfloat = badhfloat; + for (int y = dimY - 1; y >= 0; y--) { + for (int x = 0; x < dimX; x++) { + hfloat = badhfloat; #if RS_RCPP - if(hfile >> hfloat) { + if (hfile >> hfloat) { #else - hfile >> hfloat; + hfile >> hfloat; #endif - h = (int)hfloat; + 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; - } + } + else { + // corrupt file stream +#if RS_RCPP && !R_CMD + Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; #endif - if (patchModel) { - pfloat = badpfloat; + StreamErrorR("habitatchgfile"); + hfile.close(); + hfile.clear(); + pfile.close(); + pfile.clear(); + return 172; + } +#endif + if (patchModel) { + pfloat = badpfloat; #if RS_RCPP - if(pfile >> pfloat) { + if (pfile >> pfloat) { #else - pfile >> pfloat; + pfile >> pfloat; #endif - p = (int)pfloat; + 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; + 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) { + if (cfile >> cfloat) { #else - cfile >> cfloat; + cfile >> cfloat; #endif - c = (int)cfloat; + 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()); + 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 (cells[y][x] != 0) { // not a no data cell (in initial landscape) - if (h == habnodata) { // invalid no data cell in change map + } + 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 36; + return 37; } 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); + 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 (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(); + } + if (costs) { + if (c < 1) { // invalid cost +#if RS_RCPP + Rcpp::Rcout << "Found invalid cost value of " << c << "in cell x " << x << " and y " << y << std::endl; +#endif + hfile.close(); hfile.clear(); + if (pfile.is_open()) { pfile.close(); pfile.clear(); - return 34; - } - else { - patchChgMatrix[y][x][2] = p; - if (p > 0 && !existsPatch(p)) { - addPatchNum(p); - newPatch(pchseq++,p); - } } + return 38; } - 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; - } + else { + costsChgMatrix[y][x][2] = c; } } } - } + } // end x + } // end y #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"); - } + 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; + 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; + 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 + 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 { - pPatch = (Patch*)patch; - patchChgMatrix[y][x][0] = patchChgMatrix[y][x][1] = pPatch->getPatchNum(); + // 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; } - 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 + 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); + } } + 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); + } + } + // reset cell for next landscape change + patchChgMatrix[y][x][1] = patchChgMatrix[y][x][2]; } - // 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; + 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]; + 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]; } - delete[] patchChgMatrix[y]; } -} -patchChgMatrix = 0; + 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(); + 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; } - 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()); + 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); + } } - } - 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 + else { // any other change + 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); + } } + // reset cell for next landscape change + costsChgMatrix[y][x][1] = costsChgMatrix[y][x][2]; } - // 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; + 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]; + 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]; } - delete[] costsChgMatrix[y]; } -} -costsChgMatrix = 0; + 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; +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); +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; +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(); +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(); + return (int)distns.size(); } int Landscape::distCellCount(int dist) { -return distns[dist]->cellCount(); + 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); +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); +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); +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); +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(); + 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(); +void Landscape::resetDistribution(Species* pSp) { + // CURRENTLY WORKS FOR FIRST SPECIES ONLY ... + distns[0]->resetDistribution(); } //--------------------------------------------------------------------------- @@ -2011,23 +1717,23 @@ distns[0]->resetDistribution(); // Initialisation cell functions int Landscape::initCellCount(void) { -return (int)initcells.size(); + return (int)initcells.size(); } -void Landscape::addInitCell(int x,int y) { -initcells.push_back(new DistCell(x,y)); +void Landscape::addInitCell(int x, int y) { + initcells.push_back(new DistCell(x, y)); } locn Landscape::getInitCell(int ix) { -return initcells[ix]->getLocn(); + 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(); + int ncells = (int)initcells.size(); + for (int i = 0; i < ncells; i++) { + delete initcells[i]; + } + initcells.clear(); } //--------------------------------------------------------------------------- @@ -2035,24 +1741,24 @@ 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) +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 + // 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; + wstring header; #else -string header; + string header; #endif -int h,seq,p,habnodata; -int pchnodata = 0; -int ncols,nrows; -float hfloat,pfloat; -Patch *pPatch; -simParams sim = paramsSim->getSim(); + 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 (fileNum < 0) return 19; #if RS_RCPP wifstream hfile; // habitat file input stream @@ -2061,41 +1767,43 @@ if (fileNum < 0) return 19; ifstream hfile; // habitat file input stream ifstream pfile; // patch file input stream #endif -initParams init = paramsInit->getInit(); + initParams init = paramsInit->getInit(); -// open habitat file and optionally also patch file + // open habitat file and optionally also patch file #if !RS_RCPP || RSWIN64 -hfile.open(habfile.c_str()); + 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)); -} + 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 (!hfile.is_open()) return 11; + if (fileNum == 0) { + if (patchModel) { #if !RS_RCPP || RSWIN64 - pfile.open(pchfile.c_str()); + 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)); - } + 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; + 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 >> resol >> header >> habnodata; + >> header >> tmpresol >> header >> habnodata; +resol = (int) tmpresol; #if RS_RCPP if (!hfile.good()) { @@ -2111,70 +1819,71 @@ hfile >> header >> ncols >> header >> nrows >> header >> minEast >> header >> mi } #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; + 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; - } + if (!pfile.good()) { + // corrupt file stream + StreamErrorR(pchfile); + hfile.close(); + hfile.clear(); + pfile.close(); + pfile.clear(); + return 135; + } #endif - setCellArray(); -} + 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; + // 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++); + 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) { + 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; + 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) { + if (hfile >> hfloat) { #else - hfile >> hfloat; + hfile >> hfloat; #endif - h = (int)hfloat; - if (patchModel) { - pfloat = badpfloat; + h = (int)hfloat; + if (patchModel) { + pfloat = badpfloat; #if RS_RCPP - if(pfile >> pfloat) { + if (pfile >> pfloat) { #else - pfile >> pfloat; + pfile >> pfloat; #endif p = (int)pfloat; #if RS_RCPP - } else { + } + else { // corrupt file stream - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; - #endif +#if RS_RCPP && !R_CMD + Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; +#endif StreamErrorR(pchfile); hfile.close(); hfile.clear(); @@ -2183,100 +1892,95 @@ case 0: // raster with habitat codes - 100% habitat each cell 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; + 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 (h == habnodata) + addNewCellToLand(x, y, -1); // add cell only to landscape + else { -#if RSDEBUG -//DebugGUI(("Landscape::readLandscape(): x=" + Int2Str(x) + " y=" + Int2Str(y) -// + " h=" + Int2Str(h) + " p=" + Int2Str(p) -//).c_str()); + // 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 - if (h == habnodata) - addNewCellToLand(x,y,-1); // add cell only to landscape + hfile.close(); hfile.clear(); + if (patchModel) { + pfile.close(); pfile.clear(); + } + return 13; + } 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) { + 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; } - 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 (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); - } +hfile >> hfloat; +if (!hfile.eof()) EOFerrorR(habfile); +if (patchModel) +{ + pfile >> pfloat; + if (!pfile.eof()) EOFerrorR(pchfile); +} #endif - break; +break; case 1: // multiple % cover - for (int y = dimY-1; y >= 0; y--) { + for (int y = dimY - 1; y >= 0; y--) { for (int x = 0; x < dimX; x++) { hfloat = badhfloat; #if RS_RCPP - if(hfile >> hfloat) { + if (hfile >> hfloat) { #else hfile >> hfloat; #endif @@ -2285,110 +1989,107 @@ case 1: // multiple % cover if (patchModel) { pfloat = badpfloat; #if RS_RCPP - if(pfile >> pfloat) { + 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; } + 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()); + 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 - if (h == habnodata) { - addNewCellToLand(x,y,-1); // add cell only to landscape + hfile.close(); hfile.clear(); + if (patchModel) { + pfile.close(); pfile.clear(); + } + return 17; } 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) { + 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; } - 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); + 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 { - 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); - } + 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 { // 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(); +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(); + pfile.close(); pfile.clear(); } - return 133; + 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 } @@ -2407,105 +2108,103 @@ case 1: // multiple % cover case 2: // habitat quality if (fileNum > 0) return 19; // error condition - should not occur - for (int y = dimY-1; y >= 0; y--) { + for (int y = dimY - 1; y >= 0; y--) { for (int x = 0; x < dimX; x++) { hfloat = badhfloat; #if RS_RCPP - if(hfile >> hfloat) { + 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; } + else { + // corrupt file stream +#if RS_RCPP && !R_CMD + Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; #endif - if (patchModel) { - pfloat = badpfloat; + 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) { + if (pfile >> pfloat) { #else - pfile >> pfloat; + pfile >> pfloat; #endif - p = (int)pfloat; + 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; - } + } + else { + // corrupt file stream +#if RS_RCPP && !R_CMD + Rcpp::Rcout << "At (x,y) = " << x << "," << y << " :" << std::endl; #endif - } -#if RSDEBUG -//MemoLine(("y=" + Int2Str(y) + " x=" + Int2Str(x) + " hfloat=" + Float2Str(hfloat) -// + " p=" + Int2Str(p)).c_str()); + StreamErrorR(pchfile); + hfile.close(); + hfile.clear(); + pfile.close(); + pfile.clear(); + return 135; + } #endif - if (h == habnodata) { - addNewCellToLand(x,y,-1); // add cell only to landscape + } + 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(); } - 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 + 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(); - if (patchModel) { - pfile.close(); pfile.clear(); - } - return 17; + pfile.close(); pfile.clear(); + return 14; + } + if (p == 0) { // cell is in the matrix + addNewCellToPatch(0, x, y, hfloat); } 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); - } - } + if (existsPatch(p)) { + pPatch = findPatch(p); + addNewCellToPatch(pPatch, x, y, hfloat); + // addNewCellToPatch(findPatch(p),x,y,hfloat); } - else { // cell-based model - // add cell to landscape (patches created later) - addNewCellToLand(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 @@ -2521,19 +2220,19 @@ case 2: // habitat quality default: break; -} // end switch(rasterType) + } // end switch(rasterType) -if (hfile.is_open()) { hfile.close(); hfile.clear(); } -if (pfile.is_open()) { pfile.close(); pfile.clear(); } + 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; + if (sim.batchMode) { + if (costfile != "NULL") { + int retcode = readCosts(costfile); + if (retcode < 0) return 54; + } } -} -return 0; + return 0; } @@ -2552,47 +2251,34 @@ int Landscape::readCosts(string fname) 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; + //int hc,maxYcost,maxXcost,NODATACost,hab; + int hc, maxYcost, maxXcost, NODATACost; + float minLongCost, minLatCost; int resolCost; + float fcost; #if RS_RCPP -wstring header; + wstring header; #else -string header; + string header; #endif -Cell *pCell; + Cell* pCell; #if !RS_RCPP -simView v = paramsSim->getViews(); + simView v = paramsSim->getViews(); #endif -int maxcost = 0; + 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) { + 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; + // read headers and check that they correspond to the landscape ones + costs >> header; #if RS_RCPP if (!costs.good()) { // corrupt file stream @@ -2605,73 +2291,77 @@ costs >> header; #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; } +double tmpresolCost; costs >> maxXcost >> header >> maxYcost >> header >> minLongCost; -costs >> header >> minLatCost >> header >> resolCost >> header >> NODATACost; +costs >> header >> minLatCost >> header >> tmpresolCost >> header >> NODATACost; +resolCost = (int) tmpresolCost; #if !RS_RCPP -MemoLine("Loading costs map. Please wait..."); + MemoLine("Loading costs map. Please wait..."); #endif -for (int y = maxYcost - 1; y > -1; y--){ - for (int x = 0; x < maxXcost; x++){ + for (int y = maxYcost - 1; y > -1; y--) { + for (int x = 0; x < maxXcost; x++) { #if RS_RCPP - if(costs >> fcost) { + if (costs >> fcost) { #else - costs >> fcost; + costs >> fcost; #endif - hc = (int)fcost; // read as float and convert to int + 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; + } + 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 RS_RCPP && !R_CMD - Rcpp::Rcout << "Cost map my only contain values of 1 or higher, but found " << fcost << "." << endl; + Rcpp::Rcout << "Cost map may only contain values of 1 or higher, but found " << fcost << "." << endl; +#endif + // error - zero / negative cost not allowed + costs.close(); costs.clear(); + return -999; + } + pCell = findCell(x, y); + if (pCell != 0) { // not no-data cell + if (hc > 0){ // only if cost value is above 0 in a data cell + pCell->setCost(hc); + if (hc > maxcost) maxcost = hc; + } else { // if cost value is below 0 +#if RS_RCPP && !R_CMD + Rcpp::Rcout << "Cost map may only contain values of 1 or higher in habiat cells, but found " << hc << " in cell x: " << x << " y: " << y << "." << 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; + // costs.close(); costs.clear(); // not sure if it should stop at this point + // return -999; + } + + } // end not no data vell } } -} #if RS_RCPP - costs >> fcost; - if (costs.eof()) { - #if RS_RCPP && !R_CMD - Rcpp::Rcout << "Costs map loaded." << endl; - #endif - } - else EOFerrorR(fname); +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."); +MemoLine("Costs map loaded."); #endif costs.close(); costs.clear(); @@ -2684,63 +2374,65 @@ 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; + 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()); + DebugGUI(("CheckRasterFile(): header=" + header + " r.ncols=" + Int2Str(r.ncols) + ).c_str()); #endif - if (header != "ncols" && header != "NCOLS") r.errors++; - infile >> header >> r.nrows; + if (header != "ncols" && header != "NCOLS") r.errors++; + infile >> header >> r.nrows; #if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " r.nrows=" + Int2Str(r.nrows) - ).c_str()); + DebugGUI(("CheckRasterFile(): header=" + header + " r.nrows=" + Int2Str(r.nrows) + ).c_str()); #endif - if (header != "nrows" && header != "NROWS") r.errors++; - infile >> header >> r.xllcorner; + if (header != "nrows" && header != "NROWS") r.errors++; + infile >> header >> r.xllcorner; #if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " r.xllcorner=" + Float2Str(r.xllcorner) - ).c_str()); + DebugGUI(("CheckRasterFile(): header=" + header + " r.xllcorner=" + Float2Str(r.xllcorner) + ).c_str()); #endif - if (header != "xllcorner" && header != "XLLCORNER") r.errors++; - infile >> header >> r.yllcorner; + if (header != "xllcorner" && header != "XLLCORNER") r.errors++; + infile >> header >> r.yllcorner; #if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " r.yllcorner=" + Float2Str(r.yllcorner) - ).c_str()); + DebugGUI(("CheckRasterFile(): header=" + header + " r.yllcorner=" + Float2Str(r.yllcorner) + ).c_str()); #endif - if (header != "yllcorner" && header != "YLLCORNER") r.errors++; - infile >> header >> r.cellsize; + 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()); + DebugGUI(("CheckRasterFile(): header=" + header + " r.cellsize=" + Int2Str(r.cellsize) + ).c_str()); #endif - if (header != "cellsize" && header != "CELLSIZE") r.errors++; - infile >> header >> inint; + if (header != "cellsize" && header != "CELLSIZE") r.errors++; + infile >> header >> inint; #if RSDEBUG -DebugGUI(("CheckRasterFile(): header=" + header + " inint=" + Int2Str(inint) - ).c_str()); + DebugGUI(("CheckRasterFile(): header=" + header + " inint=" + Int2Str(inint) + ).c_str()); #endif - if (header != "NODATA_value" && header != "NODATA_VALUE") r.errors++; - infile.close(); + 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(); - if (r.errors > 0) r.ok = false; -} -else { - r.ok = false; r.errors = -111; -} -infile.clear(); -return r; + return r; } //--------------------------------------------------------------------------- @@ -2750,74 +2442,74 @@ return r; // Create & initialise connectivity matrix void Landscape::createConnectMatrix(void) { -if (connectMatrix != 0) deleteConnectMatrix(); -int npatches = (int)patches.size(); + if (connectMatrix != 0) deleteConnectMatrix(); + int npatches = (int)patches.size(); #if RSDEBUG -//DEBUGLOG << "Landscape::createConnectMatrix(): npatches=" << npatches << endl; + //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; -} + 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; + 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]++; +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]; + 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; } - 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; -} + if (option == -999) { // close the file + if (outConnMat.is_open()) outConnMat.close(); + outConnMat.clear(); + return true; + } -simParams sim = paramsSim->getSim(); + 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()); + 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; + outConnMat << "Rep\tYear\tStartPatch\tEndPatch\tNinds" << endl; -return outConnMat.is_open(); + return outConnMat.is_open(); } #if RS_RCPP @@ -2834,140 +2526,136 @@ void Landscape::outPathsHeaders(int rep, int option) string name = paramsSim->getDir(2); if (sim.batchMode) { name += "Batch" + Int2Str(sim.batchNum) - + "_Sim" + Int2Str(sim.simulation) - + "_Land" + Int2Str(landNum) - + "_Rep" + Int2Str(rep); - } else { + + "_Sim" + Int2Str(sim.simulation) + + "_Land" + Int2Str(landNum) + + "_Rep" + Int2Str(rep); + } + else { name += "Sim" + Int2Str(sim.simulation) - + "_Rep" + Int2Str(rep); + + "_Rep" + Int2Str(rep); } name += "_MovePaths.txt"; outMovePaths.open(name.c_str()); - if( outMovePaths.is_open() ){ + if (outMovePaths.is_open()) { outMovePaths << "Year\tIndID\tStep\tx\ty\tStatus" << endl; - }else{ - #if RSDEBUG + } + else { +#if RSDEBUG DEBUGLOG << "RunModel(): UNABLE TO OPEN MOVEMENT PATHS FILE" << endl; - #endif +#endif outMovePaths.clear(); } } } #endif -void Landscape::outConnect(int rep,int yr) +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 + 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++) { + 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) { + 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; + 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; + 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(); + 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(); + string name; + simParams sim = paramsSim->getSim(); -if (sim.batchMode) { - name = paramsSim->getDir(3) + if (sim.batchMode) { + name = paramsSim->getDir(3) #if RS_RCPP - + "Batch" + Int2Str(sim.batchNum) + "_" - + "Sim" + Int2Str(sim.simulation) - + "_Land" + Int2Str(landNr) + "_Rep" + Int2Str(rep) + + "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()); + + "Batch" + Int2Str(sim.batchNum) + "_" + + "Sim" + Int2Str(sim.simulation) + + "_land" + Int2Str(landNr) + "_rep" + Int2Str(rep) #endif - for (int x = 0; x < dimX; x++) { - if (cells[y][x] == 0) { // no-data cell - outvisits << "-9 "; - } - else { - outvisits << cells[y][x]->getVisits() << " "; + + "_Visits.txt"; + } + else { + name = paramsSim->getDir(3) + + "Sim" + Int2Str(sim.simulation) + + "_land" + Int2Str(landNr) + "_rep" + Int2Str(rep) + + "_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--) { + 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 << endl; -} -outvisits.close(); outvisits.clear(); + outvisits.close(); outvisits.clear(); } //--------------------------------------------------------------------------- diff --git a/RangeShiftR/src/RScore/Landscape.h b/RangeShiftR/src/RScore/Landscape.h index a3d974d..2a414cc 100644 --- a/RangeShiftR/src/RScore/Landscape.h +++ b/RangeShiftR/src/RScore/Landscape.h @@ -71,12 +71,8 @@ Last updated: 2 December 2021 by Steve Palmer #ifndef LandscapeH #define LandscapeH -//#include -//#include #include #include -//#include -//#include #include using namespace std; @@ -144,7 +140,6 @@ class InitDist{ }; - //--------------------------------------------------------------------------- struct landParams { diff --git a/RangeShiftR/src/RScore/Main.cpp b/RangeShiftR/src/RScore/Main.cpp new file mode 100644 index 0000000..0d15cdb --- /dev/null +++ b/RangeShiftR/src/RScore/Main.cpp @@ -0,0 +1,102 @@ +/*---------------------------------------------------------------------------- + * + * 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 + try + { + run_unit_tests(); + } + catch (const std::exception& e) + { + cerr << endl << "Error: " << e.what() << endl; + } + cout << "All tests have completed." << endl; + return 0; // if tests succeed, we are happy +# endif // NDEBUG +} diff --git a/RangeShiftR/src/RScore/Model.cpp b/RangeShiftR/src/RScore/Model.cpp index 9f26886..3134f8d 100644 --- a/RangeShiftR/src/RScore/Model.cpp +++ b/RangeShiftR/src/RScore/Model.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 "Model.h" @@ -29,89 +29,68 @@ ofstream outPar; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #if RS_RCPP && !R_CMD -Rcpp::List RunModel(Landscape *pLandscape,int seqsim) +Rcpp::List RunModel(Landscape* pLandscape, int seqsim) #else -int RunModel(Landscape *pLandscape,int seqsim) +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 + int yr, totalInds; + bool filesOK; + + landParams ppLand = pLandscape->getLandParams(); + envGradParams grad = paramsGrad->getGradient(); + envStochParams env = paramsStoch->getStoch(); + demogrParams dem = pSpecies->getDemogr(); + stageParams sstruct = pSpecies->getStage(); + trfrRules trfr = pSpecies->getTrfr(); + initParams init = paramsInit->getInit(); + simParams sim = paramsSim->getSim(); + simView v = paramsSim->getViews(); -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(); + landPix p = pLandscape->getLandPix(); + DEBUGLOG << "RunModel(): reps=" << sim.reps + << " ppLand.nHab=" << ppLand.nHab + << " p.pix=" << p.pix + << endl; + 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); + patchData ppp; + int npatches = pLandscape->patchCount(); + for (int i = 0; i < npatches; i++) { + ppp = pLandscape->getPatchData(i); + pComm->addSubComm(ppp.pPatch, ppp.patchNum); // SET UP ALL SUB-COMMUNITIES + } + 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; + Rcpp::List list_outPop; #endif -// Loop through replicates -for (int rep = 0; rep < sim.reps; rep++) { + // Loop through replicates + for (int rep = 0; rep < sim.reps; rep++) { #if RSDEBUG -DEBUGLOG << endl << "RunModel(): starting simulation=" << sim.simulation << " rep=" << rep << endl; + DEBUGLOG << endl << "RunModel(): starting simulation=" << sim.simulation << " rep=" << rep << endl; #endif #if RS_RCPP && !R_CMD Rcpp::Rcout << endl << "starting replicate " << rep << endl; @@ -121,768 +100,666 @@ DEBUGLOG << endl << "RunModel(): starting simulation=" << sim.simulation << " re #endif #endif - MemoLine(("Running replicate " + Int2Str(rep) + "...").c_str()); + MemoLine(("Running replicate " + Int2Str(rep) + "...").c_str()); - if (sim.saveVisits && !ppLand.generated) { - pLandscape->resetVisits(); - } + 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; + 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; + DEBUGLOG << "RunModel(): npatchchanges=" << npatchchanges << " ncostchanges=" << ncostchanges << endl; #endif - if (ppLand.generated) { + 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 + 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 << endl << "RunModel(): finished generating patches" << endl; + DEBUGLOG << "RunModel(): finished resetting landscape" << endl << 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(); + pLandscape->generatePatches(); + if (v.viewLand || sim.saveMaps) { + pLandscape->setLandMap(); + pLandscape->drawLandscape(rep, 0, ppLand.landNum); + } #if RSDEBUG -DEBUGLOG << "RunModel(): patch count is " << npatches << endl; + DEBUGLOG << endl << "RunModel(): finished generating patches" << endl; #endif - for (int i = 0; i < npatches; i++) { - ppp = pLandscape->getPatchData(i); + pComm = new Community(pLandscape); // set up community + // set up a sub-community associated with each patch (incl. the matrix) + pLandscape->updateCarryingCapacity(pSpecies, 0, 0); + patchData ppp; + int npatches = pLandscape->patchCount(); #if RSDEBUG -//DEBUGLOG << "RunModel(): i = " << i -// << " ppp.pPatch = " << ppp.pPatch << " ppp.patchNum = " << ppp.patchNum -// << endl; + DEBUGLOG << "RunModel(): patch count is " << npatches << endl; #endif + for (int i = 0; i < npatches; i++) { + ppp = pLandscape->getPatchData(i); #if RSWIN64 #if LINUX_CLUSTER - pComm->addSubComm(ppp.pPatch,ppp.patchNum); // SET UP ALL SUB-COMMUNITIES + 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 + 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 + 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..."); + } + MemoLine("...completed..."); #if RSDEBUG -DEBUGLOG << endl << "RunModel(): finished generating populations" << endl; + 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 (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); } - 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; + 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.outConnect && ppLand.patchModel) // open Connectivity file - if (!pLandscape->outConnectHeaders(0)) { - MemoLine("UNABLE TO OPEN CONNECTIVITY 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; + DEBUGLOG << "RunModel(): completed opening output files" << endl; #endif - if (!filesOK) { + 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); + 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); + return Rcpp::List::create(Rcpp::Named("Errors") = 666); #else - return 666; + return 666; #endif - } + } - if (env.stoch && !env.local) { - // create time series in case of global environmental stochasticity - pLandscape->setGlobalStoch(sim.years+1); - } + 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 (grad.gradient) { // set up environmental gradient + pLandscape->setEnvGradient(pSpecies, true); + } - if (sim.outConnect && ppLand.patchModel) - pLandscape->createConnectMatrix(); + 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 - } + // 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); + // set up populations in the community + pLandscape->updateCarryingCapacity(pSpecies, 0, 0); #if RSDEBUG -DEBUGLOG << "RunModel(): completed updating carrying capacity" << endl; + 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 (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; + 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); + // 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); + // 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); + pLandscape->outPathsHeaders(rep, 0); #endif - // years loop - MemoLine("...running..."); - for (yr = 0; yr < sim.years; yr++) { + // 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; + 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) - ) { + 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; + Rcpp::Rcout << "starting year " << yr << "..." << endl; #else - cout << "starting year " << yr << endl; + 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 + 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 (yr == init.finalFrzYr) { + // apply final 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; + DEBUGLOG << "RunModel(): final restriction yr=" << yr + << " s.minY=" << s.minY << " s.maxY=" << s.maxY + << endl; #endif - pLandscape->setLandLimits(ppLand.minX,minY,ppLand.maxX,ppLand.maxY); + 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 } } - 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); + } + // 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 -//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 (env.stoch) { + if (env.local) pLandscape->updateLocalStoch(); + updateCC = true; + } + if (ppLand.dynamic) { #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 + 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) { + // 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 = 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++); } - pCell->setPatch((intptr)pPatch); - // get next patch change - patchchange = pLandscape->getPatchChange(ixpchchg++); + ixpchchg--; + pLandscape->resetPatches(); // reset patch limits } - 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 (landChg.costfile != "NULL") { // apply any SMS cost changes #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; + DEBUGLOG << "RunModel(): yr=" << yr << " landChg.costfile=" << landChg.costfile << endl; #endif - pCell = pLandscape->findCell(costchange.x,costchange.y); - if (pCell != 0) { - pCell->setCost(costchange.newcost); - } + Cell* pCell; costchange = pLandscape->getCostChange(ixcostchg++); + while (costchange.chgnum <= landIx && ixcostchg <= ncostchanges) { + 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; } - 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); } - } // end of environmental gradient, etc. - if (updateCC) { - pLandscape->updateCarryingCapacity(pSpecies,yr,landIx); - } - - if (sim.outConnect && ppLand.patchModel) - pLandscape->resetConnectMatrix(); + 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 (ppLand.dynamic && updateland) { + 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); + pComm->dispersal(landIx, yr); #else - pComm->dispersal(landIx); + 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.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); - } + 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 - { + 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; -} + // TEMPORARY RANDOM STREAM CHECK + 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); + 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); } - 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); + // 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; + 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 - // 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); - } + if (!ppLand.patchModel && gen == 0) { + if (env.localExt) pComm->localExtinction(0); + if (grad.gradient && grad.gradType == 3) pComm->localExtinction(1); + } - // reproduction - pComm->reproduction(yr); + // reproduction + pComm->reproduction(yr); - if (dem.stageStruct) { - if (sstruct.survival == 0) { // at reproduction - pComm->survival(0,2,1); // survival of all non-juvenile stages + 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); + // 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; + DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed reproduction" << endl; #endif - // Dispersal + // Dispersal - pComm->emigration(); + pComm->emigration(); #if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed emigration" << endl; + DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed emigration" << endl; #endif #if RS_RCPP - pComm->dispersal(landIx,yr); + pComm->dispersal(landIx, yr); #else - pComm->dispersal(landIx); + pComm->dispersal(landIx); #endif // RS_RCPP #if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed dispersal" << endl; + 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 + // 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 + } } - 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); } - } - else { // non-structured population - pComm->survival(0,1,1); - } #if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed survival part 0" << endl; + 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); + 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); + 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); - } + // survival part 1 + if (dem.stageStruct) { + 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; + DEBUGLOG << "RunModel(): yr=" << yr << " gen=" << gen << " completed survival part 1" << endl; #endif - } // end of the generation loop + } // end of the generation loop #if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " completed generation loop" << endl; + DEBUGLOG << "RunModel(): yr=" << yr << " completed generation loop" << endl; #endif - totalInds = pComm->totalInds(); - if (totalInds <= 0) { yr++; break; } + 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); + // 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 (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; + 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 (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; + DEBUGLOG << "RunModel(): yr=" << yr << " completed Age_increment and final survival" << endl; #endif - totalInds = pComm->totalInds(); - if (totalInds <= 0) { yr++; break; } - } + totalInds = pComm->totalInds(); + if (totalInds <= 0) { yr++; break; } + } - } // end of the years loop + } // end of the years loop - // Final output and popn. visualisation + // Final output and popn. visualisation #if BATCH - if (sim.saveMaps && yr%sim.mapInt == 0) { - if (updateland) { - pLandscape->drawLandscape(rep,landIx,ppLand.landNum); + if (sim.saveMaps && yr % sim.mapInt == 0) { + if (updateland) { + pLandscape->drawLandscape(rep, landIx, ppLand.landNum); + } + pComm->draw(rep, yr, 0, 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); + || sim.outTraitsCells || sim.outTraitsRows || sim.saveMaps) + PreReproductionOutput(pLandscape, pComm, rep, yr, 0); if (sim.outRange || sim.outPop) - RangePopOutput(pComm,rep,yr,0); + RangePopOutput(pComm, rep, yr, 0); #if RSDEBUG -DEBUGLOG << "RunModel(): yr=" << yr << " completed final summary output" << endl; + DEBUGLOG << "RunModel(): yr=" << yr << " completed final summary output" << endl; #endif - pComm->resetPopns(); - -// if (batchMode) { -// // delete the community of species using the landscape -// pComm->resetPopns(); -// } + pComm->resetPopns(); - //Reset the gradient optimum - if (grad.gradient) paramsGrad->resetOptY(); + //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) { + pLandscape->resetLandLimits(); #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; + 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) { + // 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 = 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++); } - pCell->setPatch((intptr)pPatch); - // get next patch change - patchchange = pLandscape->getPatchChange(ixpchchg++); + ixpchchg--; + pLandscape->resetPatches(); } - 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++); + 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) { + + pCell = pLandscape->findCell(costchange.x, costchange.y); + if (pCell != 0) { + pCell->setCost(costchange.newcost); } - ixcostchg--; - pLandscape->resetEffCosts(); + costchange = pLandscape->getCostChange(ixcostchg++); + } + ixcostchg--; + pLandscape->resetEffCosts(); + } + if (!trfr.costMap) pLandscape->resetCosts(); // in case habitats have changed } - 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; + DEBUGLOG << "RunModel(): yr=" << yr << " completed reset" + << endl; #endif - if (sim.outConnect && ppLand.patchModel) - pLandscape->resetConnectMatrix(); // set connectivity matrix to zeroes + 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.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 (sim.saveVisits) { + pLandscape->outVisits(rep, ppLand.landNum); + pLandscape->resetVisits(); + } #if RS_RCPP - if (sim.outPaths) - pLandscape->outPathsHeaders(rep,-999); + if (sim.outPaths) + pLandscape->outPathsHeaders(rep, -999); #endif #if RSDEBUG -DEBUGLOG << endl << "RunModel(): finished rep=" << rep << endl; + DEBUGLOG << endl << "RunModel(): finished rep=" << rep << endl; #endif -} // end of the replicates loop + } // end of the replicates loop -if (sim.outConnect && ppLand.patchModel) { - pLandscape->deleteConnectMatrix(); - pLandscape->outConnectHeaders(-999); // close Connectivity Matrix file -} + 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"); -} + // Occupancy outputs + if (sim.outOccup && sim.reps > 1) { + MemoLine("Writing final occupancy output..."); + pComm->outOccupancy(); + pComm->outOccSuit(v.viewGraph); + 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 (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"); #if RS_RCPP && !R_CMD return list_outPop; @@ -892,199 +769,171 @@ MemoLine("...finished"); } -#if RS_EMBARCADERO || LINUX_CLUSTER || RS_RCPP +#if 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; +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; + bool errorfolder = false; -string subfolder; + 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; + 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; + return errorfolder; } //--------------------------------------------------------------------------- //For outputs and population visualisations pre-reproduction -void PreReproductionOutput(Landscape *pLand,Community *pComm,int rep,int yr,int gen) +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; + landParams ppLand = pLand->getLandParams(); #endif + simParams sim = paramsSim->getSim(); + simView v = paramsSim->getViews(); #if RSDEBUG -//DEBUGLOG << "PreReproductionOutput(): 22222 " << endl; + 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 -//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++) { + traitCanvas tcanv; + 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 + // trait outputs and visualisation -// Remaining graphical output actions are performed for GUI only + if (v.viewTraits) { + tcanv = SetupTraitCanvas(); + } -#if RSDEBUG -//DEBUGLOG << "PreReproductionOutput(): finished " << endl; -#endif + if (v.viewTraits + || ((sim.outTraitsCells && yr >= sim.outStartTraitCell && yr % sim.outIntTraitCell == 0) || + (sim.outTraitsRows && yr >= sim.outStartTraitRow && yr % sim.outIntTraitRow == 0))) + { + pComm->outTraits(tcanv, pSpecies, rep, yr, gen); + } + if (sim.outOccup && yr % sim.outIntOcc == 0 && gen == 0) + pComm->updateOccupancy(yr / sim.outIntOcc, rep); } //For outputs and population visualisations pre-reproduction -void RangePopOutput(Community *pComm,int rep,int yr,int gen) +void RangePopOutput(Community* pComm, int rep, int yr, int gen) { -simParams sim = paramsSim->getSim(); + simParams sim = paramsSim->getSim(); -if (sim.outRange && (yr%sim.outIntRange == 0 || pComm->totalInds() <= 0)) - pComm->outRange(pSpecies,rep,yr,gen); + 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); + if (sim.outPop && yr >= sim.outStartPop && yr % sim.outIntPop == 0) + pComm->outPop(rep, yr, gen); } //--------------------------------------------------------------------------- -void OutParameters(Landscape *pLandscape) +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) + 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()); + else + name = paramsSim->getDir(2) + "Sim" + Int2Str(sim.simulation) + "_Parameters.txt"; + outPar.open(name.c_str()); -outPar << "RangeShifter 2.0 "; + outPar << "RangeShifter 2.0 "; #if !RS_RCPP #if RSWIN64 -outPar << " - 64 bit implementation"; + outPar << " - 64 bit implementation"; #else -outPar << " - 32 bit implementation"; + outPar << " - 32 bit implementation"; #endif #endif -outPar << endl; + outPar << endl; -outPar << "================ "; + outPar << "================ "; -outPar << " ====================="; -outPar << endl << endl; + outPar << " ====================="; + outPar << endl << endl; -outPar << "BATCH MODE \t"; -if (sim.batchMode) outPar << "yes" << endl; else outPar << "no" << 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; + 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 <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 << endl; + if (ppGenLand.fractal) outPar << "HURST EXPONENT\t" << ppGenLand.hurst << endl; + } + else { + outPar << "imported map" << endl; + outPar << "TYPE: \t"; + switch (ppLand.rasterType) { case 0: outPar << "habitat codes" << endl; break; @@ -1094,165 +943,162 @@ else { case 2: outPar << "habitat quality" << endl; break; - } - outPar << "FILE NAME: "; + } + outPar << "FILE NAME: "; #if RS_RCPP - if (ppLand.dynamic) { - outPar << name_landscape << endl; - } - else{ - outPar << name_landscape << endl; - } - if (ppLand.patchModel) { - outPar << "PATCH FILE: " << name_patch << endl; - } - if (trfr.costMap) { - outPar << "COSTS FILE: " << name_costfile << endl; - } -#else - if (sim.batchMode) outPar << " (see batch file) " << landFile << endl; - else { - outPar << habmapname << endl; - if (ppLand.rasterType == 1) { // habitat % cover - list additional layers - for (int i = 0; i < ppLand.nHab-1; i++) { - outPar << " "<< hfnames[i] << endl; - } + if (ppLand.dynamic) { + outPar << name_landscape << endl; } - if (ppLand.patchModel) { - outPar << "PATCH FILE: " << patchmapname << endl; + else { + outPar << name_landscape << endl; } - } -#endif - outPar << "No. HABITATS:\t" << ppLand.nHab << endl; -} -outPar << "RESOLUTION (m): \t" << ppLand.resol << endl; -outPar << "DIMENSIONS: X " << ppLand.dimX << " Y " << ppLand.dimY << endl; -outPar << "AVAILABLE: min.X " << ppLand.minX << " min.Y " << ppLand.minY - << " max.X " << ppLand.maxX << " max.Y " << ppLand.maxY << endl; -if (!ppLand.generated && ppLand.dynamic) { - landChange chg; - outPar << "DYNAMIC LANDSCAPE: " << endl; - int nchanges = pLandscape->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; + outPar << "PATCH FILE: " << name_patch << endl; } - if (chg.costfile != "none" && chg.costfile != "NULL") { - outPar << "Costs : " << chg.costfile << endl; + if (trfr.costMap) { + outPar << "COSTS FILE: " << name_costfile << endl; + } +#else + if (sim.batchMode) outPar << " (see batch file) " << landFile << endl; + else { + outPar << habmapname << endl; + if (ppLand.rasterType == 1) { // habitat % cover - list additional layers + for (int i = 0; i < ppLand.nHab - 1; i++) { + outPar << " " << hfnames[i] << endl; + } + } + if (ppLand.patchModel) { + outPar << "PATCH FILE: " << patchmapname << endl; + } + } +#endif + outPar << "No. HABITATS:\t" << ppLand.nHab << endl; + } + outPar << "RESOLUTION (m): \t" << ppLand.resol << endl; + outPar << "DIMENSIONS: X " << ppLand.dimX << " Y " << ppLand.dimY << endl; + outPar << "AVAILABLE: min.X " << ppLand.minX << " min.Y " << ppLand.minY + << " max.X " << ppLand.maxX << " max.Y " << ppLand.maxY << endl; + if (!ppLand.generated && ppLand.dynamic) { + landChange chg; + outPar << "DYNAMIC LANDSCAPE: " << endl; + int nchanges = pLandscape->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: "; + outPar << endl << "SPECIES DISTRIBUTION LOADED: \t"; + 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; - } + if (sim.batchMode) outPar << " (see batch file) " << landFile << endl; + else { + outPar << distnmapname << endl; + } #else - outPar << name_sp_dist << endl; + 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) + else outPar << "no" << endl; + + outPar << endl << "ENVIRONMENTAL GRADIENT:\t "; + if (grad.gradient) { - 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; + 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; } - 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 << "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 { - 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; + 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 { - outPar << "MIN. r\t" << pSpecies->getMinMax(0) << endl; - outPar << "MAX. r\t" << pSpecies->getMinMax(1) << endl; + 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) { + 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; @@ -1265,854 +1111,846 @@ switch (dem.repType) { 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; - } + break; } -/* -#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; + 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 { - 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 << "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 << 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 << "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; } - 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 << "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; + } - 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"; + 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 << "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 << "not stage-dependent" << endl; - } - else outPar << "no" << endl; + else outPar << "no" << endl; - densDepParams ddparams = pSpecies->getDensDep(); + 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"; + 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 << "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 << "not stage-dependent" << endl; - } - else outPar << "no" << 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"; + 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 << "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 << "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; } - 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"; + if (dem.stageStruct) { + outPar << endl << "HABITAT SPECIFIC 1/b:" << endl; } else { - outPar << "Habitat " << i << ": "; + outPar << endl << "CARRYING CAPACITIES:" << endl; } - 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; + 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 { - 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.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; + 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; } - 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 { // !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; - } + 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; + 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; } - 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); + 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.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; + 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; } - 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; + 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 + // Transfer -outPar << endl << "DISPERSAL - TRANSFER: \t"; + 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 (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; + 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" + 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; + 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; + 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 { - 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; + 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" + 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" + } + 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 + { + 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 { - 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.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; + 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; } - 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 <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 << endl; + if (trfr.twinKern) + { + outPar << meandist << " II: \t" << kern0.meanDist2 << endl; + outPar << probkern << ": \t" << kern0.probKern1 << endl; + } } } } - } - - outPar << "DISPERSAL MORTALITY: "; - trfrMortParams mort = pSpecies->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 << "DISPERSAL MORTALITY: "; + trfrMortParams mort = pSpecies->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 -outPar << endl << "DISPERSAL - SETTLEMENT:" << endl; + // Settlement -if (trfr.moveModel) { - string plusmating = "+ mating requirements"; - ssteps = pSpecies->getSteps(0,0); + outPar << endl << "DISPERSAL - SETTLEMENT:" << endl; - 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 (trfr.moveModel) { + string plusmating = "+ mating requirements"; - 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; + nsexes = 2; + outPar << sexdept << "yes" << endl; + if (sett.stgDep) { + nstages = sstruct.nStages; + outPar << stgdept << "yes" << endl; + for (int i = 0; i < nstages; i++) { + if (dem.stageStruct && nstages > 1) outPar << "stage " << i << ": " << endl; + for (int sx = 0; sx < nsexes; sx++) { + if (sx == 0) outPar << "FEMALES:" << endl; + else outPar << "MALES:" << endl; + ssteps = pSpecies->getSteps(i, sx); + + 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; + } } } - else { - if (srules.findMate) outPar << plusmating << endl; - else outPar << "(not the natal one)" << endl; + else { // !sett.stgDep + nstages = 1; + outPar << stgdept << "no" << endl; + for (int sx = 0; sx < nsexes; sx++) { + if (sx == 0) outPar << "FEMALES:" << endl; + else outPar << "MALES:" << endl; + ssteps = pSpecies->getSteps(0, sx); + + 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 (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; + } + else { // !sett.sexDep + nsexes = 1; + outPar << sexdept << "no" << endl; + if (sett.stgDep) { + nstages = sstruct.nStages; + outPar << stgdept << "yes" << endl; + for (int i = 0; i < nstages; i++) { + if (dem.stageStruct && nstages > 1) outPar << "stage " << i << ": " << endl; + ssteps = pSpecies->getSteps(i, 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; + } + } + else { // !sett.stgDep + nstages = 1; + outPar << stgdept << "no" << endl; + 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.indVar) { - settParams sparams0; - outPar << "DENSITY DEPENDENCE + " << indvar << "yes" << endl; - for (int sex = 0; sex < nsexes; sex++) { + for (int sx = 0; sx < nsexes; sx++) { if (sett.sexDep) { - if (sex == 0) outPar << "FEMALES:" << endl; + if (sx == 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; + 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; + } + } } - else { - nstages = 1; - outPar << stgdept << "no" << 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 { - nsexes = 1; - outPar << sexdept << "no" << endl; - if (sett.stgDep) { - nstages = sstruct.nStages; - outPar << stgdept << "yes" << endl; - outPar << notsuit << 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 { - 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; + nsexes = 1; + outPar << sexdept << "no" << endl; + if (sett.stgDep) { + nstages = sstruct.nStages; + outPar << stgdept << "yes" << endl; + outPar << notsuit << endl; } else { - if (srules.wait) outPar << "wait" << endl; - else outPar << "die" << endl; + 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" << endl; + else outPar << "no" << endl; } - outPar << matereq; - if (srules.findMate) outPar << "yes" <getNTraits(); -outPar << "No. of variable traits: " << nspptraits << endl; + outPar << endl << "GENETICS:" << endl; + int nspptraits = pSpecies->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); + 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; } - 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++) { + 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) - << ") all individuals have mean phenotype" << endl; + << ") alleles: " << nalleles << " (chrom:locus)"; + for (int j = 0; j < nalleles; j++) { + allele = pSpecies->getTraitAllele(i, j); + outPar << " " << allele.chromo << ":" << allele.locus; + } + outPar << 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; + 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; + } } - outPar << 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; } - if (d.pleiotropic) - outPar << "Genome exhibits pleiotropy" << endl; } } -} -// Initialisation + // Initialisation -initParams init = paramsInit->getInit(); -outPar << endl << "INITIALISATION CONDITIONS:" << endl; -switch (init.seedType) { -case 0: - outPar << "Free initialisation: \t" ; - switch (init.freeType) { + initParams init = paramsInit->getInit(); + outPar << endl << "INITIALISATION CONDITIONS:" << endl; + switch (init.seedType) { case 0: - outPar << "Random \t" ; - outPar << "No. of cells/patches: " << init.nSeedPatches << endl; + 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 << "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) { + outPar << "From species distribution: \t" << endl; + switch (init.spDistType) { case 0: outPar << "all presence cells/patches" << endl; break; @@ -2122,139 +1960,134 @@ case 1: 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; - } + outPar << "From initial individuals file: " << paramsSim->getDir(1) + init.indsFile << endl; + break; + case 3: + outPar << "From file" << 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) { + if (init.seedType != 2) { + outPar << "INITIAL NO. OF INDIVIDUALS: \t"; + switch (init.initDens) { case 0: - outPar << "lowest possible age"; + outPar << "at carrying capacity" << endl; break; case 1: - outPar << "randomised"; + outPar << "at half carrying capacity" << endl; break; case 2: - outPar << "quasi-equilibrium"; + if (ppLand.patchModel) { + outPar << init.indsHa << " individuals per ha" << endl; + } + else { + outPar << init.indsCell << " individuals per cell" << endl; + } 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; + 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 == 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; - } + outPar << endl << "OUTPUTS:" << endl; + if (sim.outRange) { + outPar << "Range - every " << sim.outIntRange << " year"; + if (sim.outIntRange > 1) outPar << "s"; + outPar << endl; + } + if (sim.outOccup) { + outPar << "Occupancy - every " << sim.outIntOcc << " year"; + if (sim.outIntOcc > 1) outPar << "s"; + 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.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 (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"; @@ -2263,27 +2096,27 @@ if (sim.outConnect) { 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; + 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(); + outPar.close(); outPar.clear(); } diff --git a/RangeShiftR/src/RScore/Model.h b/RangeShiftR/src/RScore/Model.h index 4acf37a..f48d155 100644 --- a/RangeShiftR/src/RScore/Model.h +++ b/RangeShiftR/src/RScore/Model.h @@ -49,14 +49,6 @@ Last updated: 26 October 2021 by Steve Palmer #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" @@ -75,12 +67,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 +117,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/RangeShiftR/src/RScore/Parameters.cpp b/RangeShiftR/src/RScore/Parameters.cpp index b7c6a34..5cfb3d7 100644 --- a/RangeShiftR/src/RScore/Parameters.cpp +++ b/RangeShiftR/src/RScore/Parameters.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 "Parameters.h" //--------------------------------------------------------------------------- @@ -30,34 +30,34 @@ // 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; + 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; -} + 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; + 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; } @@ -65,16 +65,18 @@ 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; + 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; } +{ + if (gradient && shifting) opt_y += shift_rate; +} void paramGrad::resetOptY(void) { opt_y = opt_y0; } @@ -83,9 +85,9 @@ 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; + stoch = false; local = false; inK = false; localExt = false; + ac = 0.0; std = 0.25; + locExtProb = 0.1; } paramStoch::~paramStoch(void) {} @@ -93,21 +95,21 @@ 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; + 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; + 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; } @@ -116,100 +118,87 @@ 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; -} + 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(); + 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; + 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; + 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; +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; + 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); + 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; + 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; + } + return iind; } void paramInit::resetInitInds(void) { initinds.clear(); } @@ -225,7 +214,6 @@ 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; @@ -251,140 +239,136 @@ paramSim::paramSim(void) { 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 (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.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; + outStartPaths = s.outStartPaths; + outIntPaths = s.outIntPaths; + outPaths = s.outPaths; + ReturnPopRaster = s.ReturnPopRaster; + CreatePopFile = s.CreatePopFile; #endif -drawLoaded = s.drawLoaded; + 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; + 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.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; + s.outStartPaths = outStartPaths; + s.outIntPaths = outIntPaths; + s.outPaths = outPaths; + s.ReturnPopRaster = ReturnPopRaster; + s.CreatePopFile = CreatePopFile; #endif -s.drawLoaded = drawLoaded; -return s; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + default: + s = "ERROR_ERROR_ERROR"; + } + return s; } #if RS_RCPP diff --git a/RangeShiftR/src/RScore/Parameters.h b/RangeShiftR/src/RScore/Parameters.h index d44cf14..9cc51d2 100644 --- a/RangeShiftR/src/RScore/Parameters.h +++ b/RangeShiftR/src/RScore/Parameters.h @@ -60,13 +60,6 @@ Last updated: 25 June 2021 by Steve Palmer #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" diff --git a/RangeShiftR/src/RScore/Patch.h b/RangeShiftR/src/RScore/Patch.h index 2bc30e7..4095908 100644 --- a/RangeShiftR/src/RScore/Patch.h +++ b/RangeShiftR/src/RScore/Patch.h @@ -68,14 +68,6 @@ Last updated: 25 June 2021 by Steve Palmer #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" diff --git a/RangeShiftR/src/RScore/Population.cpp b/RangeShiftR/src/RScore/Population.cpp index 05d8633..3dbb6a2 100644 --- a/RangeShiftR/src/RScore/Population.cpp +++ b/RangeShiftR/src/RScore/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,665 +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 -//#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; + // get population size at start of reproduction + int ninds = (int)inds.size(); + if (ninds == 0) return; -#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 + 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(); @@ -704,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); } } } @@ -1390,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; } //--------------------------------------------------------------------------- @@ -1454,794 +1107,562 @@ 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) { -#if RSDEBUG -// DEBUGLOG << "DD in DEVELOPMENT for stg=" << stg << " sex=" << sex << endl; -#endif + for (int stg = 0; stg < nStages; stg++) { + for (int sex = 0; sex < nsexes; sex++) { + if (option1 != 2 && sstruct.devDens && stg > 0) { // 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/RangeShiftR/src/RScore/Population.h b/RangeShiftR/src/RScore/Population.h index 9c8efd8..fd1fa66 100644 --- a/RangeShiftR/src/RScore/Population.h +++ b/RangeShiftR/src/RScore/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/RangeShiftR/src/RScore/README.md b/RangeShiftR/src/RScore/README.md index e977e67..832f354 100644 --- a/RangeShiftR/src/RScore/README.md +++ b/RangeShiftR/src/RScore/README.md @@ -1 +1,76 @@ -# Rangeshifter core code \ No newline at end of file +# RangeShifter core code + +This repo contains the core simulation code for RangeShifter v2.0 and is not meant to be compiled or run on its own. + + + +If you are only interested in using RangeShifter, you can ignore this and head to the repo of one of the interfaces: + +- [WIP] RangeShifter GUI + +- [RangeShiftR](https://github.com/RangeShifter/RangeShiftR-pkg) + +- [RangeShifter-batch](https://github.com/RangeShifter/RangeShifter_batch) + +## Usage: git subtree + +In order to ensure that the same version of RangeShifter's core code is used by all three interfaces (RangeShiftR, RangeShifter-batch and the GUI), each interface repo keeps a copy of RScore as a git subtree. In this section, we describe how to use the git subtrees to update the subfolder and copy this repo anew. + +First, in a local clone of one of the interface repos, add a remote named `RScore` pointing to the RScore repo. This will be convenient as a shortcut for git subtree commands. + +```bash +git remote add RScore https://github.com/RangeShifter/RScore.git +``` + +### Pulling new changes + +To update the RScore subfolder with new changes made to the RScore repo, one can use the `git subtree pull` command: + +```bash +git subtree pull --prefix RScore +``` + +Note the path must match the location of the RScore subfolder, and the branch must match the one the subtree was originally added from (by default, this should be `main`). + +e.g. for RangeShifter-batch, use: + +```bash +git subtree pull --prefix src/RScore RScore main +``` + +while for RangeShiftR, use: + +```bash +git subtree pull --prefix RangeShiftR/src/RScore RScore main +``` + +### Pushing new changes to RScore + +```bash +git subtree push --prefix RScore +``` + +e.g., from RangeShifter-batch's `main` to RScore's `main`: + +```bash +git subtree push --prefix src/RScore RScore main +``` + +### Switching the subfolder to a new branch + +There is unfortunately to do so. To track a different branch of RScore, one must delete the RScore subfolder (via git) and import the subtree again: + +```bash +git rm src/RScore -r +git commit -m "switching subtree branch" +git subtree add --prefix src/RScore RScore +``` + +## Contributing to RangeShifter core code + +See [CONTRIBUTING](https://github.com/RangeShifter/RScore/blob/main/CONTRIBUTING.md). + +## Maintainers + +- [@JetteReeg](https://github.com/JetteReeg) +- [@TheoPannetier](https://github.com/TheoPannetier) diff --git a/RangeShiftR/src/RScore/RS_repos.png b/RangeShiftR/src/RScore/RS_repos.png new file mode 100644 index 0000000..b138a01 Binary files /dev/null and b/RangeShiftR/src/RScore/RS_repos.png differ diff --git a/RangeShiftR/src/RScore/RScore_logo.png b/RangeShiftR/src/RScore/RScore_logo.png new file mode 100644 index 0000000..dfce267 Binary files /dev/null and b/RangeShiftR/src/RScore/RScore_logo.png differ diff --git a/RangeShiftR/src/RScore/RSrandom.cpp b/RangeShiftR/src/RScore/RSrandom.cpp index 79744c9..8f638d7 100644 --- a/RangeShiftR/src/RScore/RSrandom.cpp +++ b/RangeShiftR/src/RScore/RSrandom.cpp @@ -1,31 +1,30 @@ /*---------------------------------------------------------------------------- - * - * 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 "RSrandom.h" //--------------- 2.) New version of RSrandom.cpp -#if !RS_RCPP - +#if !RS_RCPP #if RSDEBUG #include "Parameters.h" @@ -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; } @@ -112,7 +113,7 @@ int RSrandom::Poisson(double mean) //-------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- -#else // if RS_RCPP +#else // if RS_RCPP //--------------- 3.) R package version of RSrandom.cpp @@ -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 && !RS_RCPP + 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/RangeShiftR/src/RScore/RSrandom.h b/RangeShiftR/src/RScore/RSrandom.h index 9293b29..9767245 100644 --- a/RangeShiftR/src/RScore/RSrandom.h +++ b/RangeShiftR/src/RScore/RSrandom.h @@ -38,15 +38,8 @@ Last updated: 12 January 2021 by Steve Palmer #include #include -//#include - -//#if RS_RCPP && !R_CMD -#include "../Version.h" -//#endif - -//#if !RS_RCPP && R_CMD -//#include "../../Batch/Version.h" -//#endif +#include +#include "Utils.h" using namespace std; @@ -54,13 +47,8 @@ using namespace std; extern ofstream DEBUGLOG; #endif - - #if !RS_RCPP - //--------------- 2.) New version of RSrandom.cpp - - #include #include #if !LINUX_CLUSTER @@ -131,6 +119,9 @@ extern ofstream DEBUGLOG; #endif // !RS_RCPP +#if RSDEBUG + void testRSrandom(); +#endif // RSDEBUG //--------------------------------------------------------------------------- diff --git a/RangeShiftR/src/RScore/RandomCheck.h b/RangeShiftR/src/RScore/RandomCheck.h index b4f6f01..b4992d2 100644 --- a/RangeShiftR/src/RScore/RandomCheck.h +++ b/RangeShiftR/src/RScore/RandomCheck.h @@ -28,13 +28,6 @@ #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" diff --git a/RangeShiftR/src/RScore/Species.cpp b/RangeShiftR/src/RScore/Species.cpp index 727e3c3..d91a3e4 100644 --- a/RangeShiftR/src/RScore/Species.cpp +++ b/RangeShiftR/src/RScore/Species.cpp @@ -1,154 +1,152 @@ /*---------------------------------------------------------------------------- - * - * 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 "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++) { + // 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; + 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++) { - d0[i][j] = 0.0; alphaEmig[i][j] = 0.0; betaEmig[i][j] = 1.0; + 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++) { - 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++) { + 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; + 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; + + 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; minSteps[i][j] = 0; maxSteps[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++) { - 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; + 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; } -} -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; + alphaSScale = 0.0; betaSScale = 0.0; s0Scale = 0.0; -// initialise attributes -spNum = 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(); + // 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; } @@ -158,25 +156,25 @@ 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; + 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; + 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; } @@ -184,237 +182,236 @@ 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; -} + 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; -} +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 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; + 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; -} + 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; + 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; + 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; +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::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]; + 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; + 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; +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; +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; +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; +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; +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; +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; + 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; + 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; + 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; +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; +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]; + if (ddwtFec != 0) { + for (int i = 0; i < ddwtFecDim; i++) if (ddwtFec[i] != 0) { + delete[] ddwtFec[i]; + } + delete[] ddwtFec; ddwtFec = 0; } - 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; + 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; +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; +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]; + if (ddwtDev != 0) { + for (int i = 0; i < ddwtDevDim; i++) if (ddwtDev[i] != 0) { + delete[] ddwtDev[i]; + } + delete[] ddwtDev; ddwtDev = 0; } - 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; + 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; +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; +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]; + if (ddwtSurv != 0) { + for (int i = 0; i < ddwtSurvDim; i++) if (ddwtSurv[i] != 0) { + delete[] ddwtSurv[i]; + } + delete[] ddwtSurv; ddwtSurv = 0; } - 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; -} +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; + if (opt == 0) return minRK; + else return maxRK; } //--------------------------------------------------------------------------- @@ -422,31 +419,31 @@ 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; + 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; + 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; } @@ -454,42 +451,42 @@ 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; + 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; -} +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; + if (chr >= 0 && chr < nChromosomes) return nLoci[chr]; + else return 0; } void Species::deleteLoci(void) { -if (nLoci != NULL) { delete[] nLoci; nLoci = NULL; } + 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; + 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; } @@ -497,458 +494,392 @@ 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; + 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) + 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 (indVarEmig) { + if (sexDepEmig) { + if (densDepEmig) nTraits += 6; else nTraits += 2; + } + else { + if (densDepEmig) nTraits += 3; else nTraits += 1; } - if (moveType == 2) movttraits = 2; + emigTrait[0] = 0; emigTrait[1] = nTraits; } - else { - if (sexDepTrfr) { - if (twinKern) movttraits = 6; else movttraits = 2; + + 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 (twinKern) movttraits = 3; else movttraits = 1; + 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; } - 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; -} + int setttraits = 0; + if (indVarSett) { + if (sexDepSett) setttraits = 6; else setttraits = 3; + settTrait[0] = nTraits; settTrait[1] = setttraits; + nTraits += setttraits; + } -setTraitNames(); + setTraitNames(); -//if (trait1Chromosome) { -// nChromosomes = nTraits; -//} #if RSDEBUG -DebugGUI("Species::setTraits(): 9999 nChromosomes=" + Int2Str(nChromosomes) - + " nTraits=" + Int2Str(nTraits)); + 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"; + 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_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"; + traitnames[trait++] = "d0"; + if (densDepEmig) { + traitnames[trait++] = "alpha"; + traitnames[trait++] = "beta"; } } - 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"; + + if (indVarTrfr) { + if (moveModel) { + if (moveType == 1) { // SMS + traitnames[trait++] = "DP"; + if (goalType == 2) { + traitnames[trait++] = "GB"; + traitnames[trait++] = "alphaDB"; + traitnames[trait++] = "betaDB"; + } } - else { - traitnames[trait++] = "meanDistI_F"; - traitnames[trait++] = "meanDistI_M"; + if (moveType == 2) { // CRW + traitnames[trait++] = "stepL"; + traitnames[trait++] = "rho"; } } else { - traitnames[trait++] = "meanDistI"; - if (twinKern) - { - traitnames[trait++] = "meanDistII"; - traitnames[trait++] = "probKernI"; + 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"; + 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; -} + if (traitnames != NULL) { + 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]; + string name = "not used"; + if (traitnames != NULL) { + if (trait >= 0 && trait < nTraits) { + name = traitnames[trait]; + } } -} -return name; + 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; + 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 + else { // neutral markers only + traitdata->nTraitMaps = 0; + } + traitdata->neutralloci = new traitMap; + traitdata->neutralloci->nAlleles = 0; } 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]; + if (traitdata != NULL) { + 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]; } - delete[] traitdata->traitmaps[i]; + deleteNeutralLoci(); + delete traitdata; + traitdata = NULL; } - deleteNeutralLoci(); - delete traitdata; - traitdata = NULL; -} } int Species::getNTraitMaps(void) { -if (traitdata == NULL) return 0; -else return traitdata->nTraitMaps; + 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; -} +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; + int nalleles = 0; + if (traitdata != NULL) { + if (trait >= 0 && trait < traitdata->nTraitMaps) { + nalleles = traitdata->traitmaps[trait]->nAlleles; + } } -} -return nalleles; + return nalleles; } -void Species::setTraitAllele(const short trait,const short allele, - const short chr,const short loc) +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; -} + 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]; +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; + 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 + 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; // 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; + 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 (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) t = 999999; + if (neutral) nneutral++; } - 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; + } + + 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++; } - 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 + 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; + // 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]; } -} -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]++; + 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; + } } -} -#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; + 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]++; } - // sum at level of chromosome/locus - for (int t = 1; t < ntraits; t++) { - locfreq[i][j][0] += locfreq[i][j][t]; + } + 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; } - 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]; + for (int i = 0; i < nNLoci; i++) { + for (int j = 0; j < nloci; j++) { + delete[] locfreq[i][j]; + } + delete[] locfreq[i]; } - delete[] locfreq[i]; -} -delete[] locfreq; + delete[] locfreq; } void Species::deleteNeutralLoci(void) { -if (traitdata->neutralloci != NULL) { - for (int i = 0; i < traitdata->neutralloci->nAlleles; i++) { - delete traitdata->neutralloci->traitalleles[i]; + if (traitdata->neutralloci != NULL) { + for (int i = 0; i < traitdata->neutralloci->nAlleles; i++) { + delete traitdata->neutralloci->traitalleles[i]; + } + delete[] traitdata->neutralloci; } - delete[] traitdata->neutralloci; -} -traitdata->neutralloci = NULL; + traitdata->neutralloci = NULL; } int Species::getNNeutralLoci(void) { -int nn = 0; -if (traitdata != NULL) { - if (traitdata->neutralloci != NULL) { - nn = traitdata->neutralloci->nAlleles; + int nn = 0; + if (traitdata != NULL) { + if (traitdata->neutralloci != NULL) { + nn = traitdata->neutralloci->nAlleles; + } } -} -return nn; + 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]; + 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; + return a; } //--------------------------------------------------------------------------- @@ -956,97 +887,88 @@ 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(); + densDepEmig = e.densDep; stgDepEmig = e.stgDep; sexDepEmig = e.sexDep; + indVarEmig = e.indVar; + if (e.emigStage >= 0) emigStage = e.emigStage; } 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; + 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; -} +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; +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; -} +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; +void Species::setEmigParams(const short stg, const short sex, const emigParams e) { + 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; + alphaMean[stg][sex] = e.alphaMean; + if (e.alphaSD > 0.0) alphaSD[stg][sex] = e.alphaSD; + betaMean[stg][sex] = e.betaMean; + if (e.betaSD > 0.0) betaSD[stg][sex] = e.betaSD; + } } -return e; + +emigParams Species::getEmigParams(short stg, short sex) { + emigParams e; + 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; + 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; + emigScales s; + s.d0Scale = d0Scale; s.alphaScale = alphaScale; s.betaScale = betaScale; + return s; } //--------------------------------------------------------------------------- @@ -1054,278 +976,268 @@ 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(); + 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; } 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; + 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; + fullKernel = k; } bool Species::useFullKernel(void) { return fullKernel; } -void Species::setKernTraits(const short stg,const short sex, - const trfrKernTraits k,const int resol) +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; -} + 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; +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; + 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; + 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; + 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; + 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; + 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; + 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 +void Species::setKernParams(const short stg, const short sex, + const trfrKernParams k, const double resol) { - if (k.dist1Mean > 0.0 && k.dist1Mean >= resol && k.dist1SD > 0.0) { - dist1Mean[stg][sex] = k.dist1Mean; dist1SD[stg][sex] = k.dist1SD; + 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; + } } - if (k.dist2Mean > 0.0 && k.dist2Mean >= resol && k.dist2SD > 0.0) { - dist2Mean[stg][sex] = k.dist2Mean; dist2SD[stg][sex] = k.dist2SD; +} + +trfrKernParams Species::getKernParams(short stg, short sex) { + trfrKernParams k; + 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; } - 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; + 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; } -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 < 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; + } + } } -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; +trfrSMSParams Species::getSMSParams(short stg, short sex) { + trfrSMSParams s; + 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; } - 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; + 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; } -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 < 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; + } + } } -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; +trfrCRWParams Species::getCRWParams(short stg, short sex) { + trfrCRWParams m; + 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; } - 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; + 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; } -} -} - -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; + 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; + 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; + 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; + 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::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; -} +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; + 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; + 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; -} + if (habCost != 0) { + delete[] habCost; habCost = 0; + } + if (habStepMort != 0) { + delete[] habStepMort; habStepMort = 0; + } } //--------------------------------------------------------------------------- @@ -1333,120 +1245,122 @@ if (habStepMort != 0) { // Settlement functions void Species::setSettle(const settleType s) { -stgDepSett = s.stgDep; sexDepSett = s.sexDep; indVarSett = s.indVar; + 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; + 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; -} +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; +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; -} +void Species::setSteps(const short stg, const short sex, const settleSteps s) { + if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { + if (s.maxStepsYr >= 1) maxStepsYr[stg][sex] = s.maxStepsYr; + else maxStepsYr[stg][sex] = 99999999; + if (s.minSteps >= 0) minSteps[stg][sex] = s.minSteps; + else minSteps[stg][sex] = 0; + if (s.maxSteps >= 1) maxSteps[stg][sex] = s.maxSteps; + else maxSteps[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; +settleSteps Species::getSteps(short stg, short sex) { + settleSteps s; + if (stg >= 0 && stg < NSTAGES && sex >= 0 && sex < NSEXES) { + s.maxStepsYr = maxStepsYr[stg][sex]; + s.minSteps = minSteps[stg][sex]; + s.maxSteps = maxSteps[stg][sex]; + } + else { + s.maxStepsYr = 99999999; + s.minSteps = 0; + s.maxSteps = 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; -} +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; +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 < 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; + } + } } -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; +settParams Species::getSettParams(short stg, short sex) { + settParams s; + 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; + 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; + 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 index a6d0ee9..8b6c07f 100644 --- a/RangeShiftR/src/RScore/Species.h +++ b/RangeShiftR/src/RScore/Species.h @@ -1,63 +1,56 @@ /*---------------------------------------------------------------------------- - * - * 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 . - * + * --------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------------ -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. + RangeShifter v2.0 Species -For full details of RangeShifter, please see: -Bocedi G., Palmer S.C.F., Peer 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 + Implements the Species class -Authors: Greta Bocedi & Steve Palmer, University of Aberdeen + 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. -Last updated: 28 July 2021 by Greta Bocedi + 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" // structures for demographic parameters struct demogrParams { - short repType; + short repType; short repSeasons; float propMales; float harem; float bc; float lambda; bool stageStruct; @@ -77,23 +70,23 @@ struct densDepParams { struct genomeData { int nLoci; bool diploid; bool neutralMarkers; bool pleiotropic; bool trait1Chromosome; - double probMutn,probCrossover,alleleSD,mutationSD; -} ; + double probMutn, probCrossover, alleleSD, mutationSD; +}; struct traitAllele { short chromo; short locus; -} ; +}; struct traitMap { short nAlleles; - traitAllele **traitalleles; -} ; + traitAllele** traitalleles; +}; struct traitData { short nTraitMaps; - traitMap **traitmaps; - traitMap *neutralloci; -} ; + traitMap** traitmaps; + traitMap* neutralloci; +}; // structures for emigration parameters @@ -117,10 +110,10 @@ struct emigScales { // structures for transfer parameters struct trfrRules { - bool moveModel; bool stgDep; bool sexDep; + bool moveModel; bool stgDep; bool sexDep; bool distMort; bool indVar; - bool twinKern; - bool habMort; + bool twinKern; + bool habMort; short moveType; bool costMap; short movtTrait[2]; }; @@ -171,7 +164,7 @@ struct settleType { short settTrait[2]; }; struct settleRules { - bool densDep; bool wait; bool go2nbrLocn; bool findMate; + bool densDep; bool wait; bool go2nbrLocn; bool findMate; }; struct settleSteps { int minSteps; int maxSteps; int maxStepsYr; @@ -227,7 +220,7 @@ class Species { float // survival coefficient ); densDepParams getDensDep(void); // Get development and survival coefficients - + void setFec( // Set fecundity short, // stage (must be > 0) short, // sex @@ -255,7 +248,7 @@ class Species { short, // stage short // sex ); - + float getMaxFec(void); // Get highest fecundity of any stage void setMinAge( // Set minimum age short, // stage @@ -561,14 +554,14 @@ class Species { bool survDens; bool survStageDens; bool disperseOnLoss; // individuals disperse on complete loss of patch - // (otherwise they die) + // (otherwise they die) short habDimK; // dimension of carrying capacities matrix - float *habK; // habitat-specific carrying capacities (inds/cell) + 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 + 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 @@ -599,10 +592,10 @@ class Species { 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* 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 + traitData* traitdata; // for mapping of chromosome loci to traits + string* traitnames; // trait names for parameter output // emigration parameters @@ -611,8 +604,8 @@ class Species { 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 + // 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) @@ -662,7 +655,7 @@ class Species { 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 + // 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 @@ -670,7 +663,7 @@ class Species { 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 + 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 @@ -692,14 +685,14 @@ class Species { 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 + 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 + // is 1.0, and kernel-based movement within the natal cell is used + // to determine philopatry - // settlement parameters +// settlement parameters bool stgDepSett; bool sexDepSett; @@ -708,8 +701,8 @@ class Species { 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 minSteps[NSTAGES][NSEXES]; // minimum no. of steps + int maxSteps[NSTAGES][NSEXES]; // 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 diff --git a/RangeShiftR/src/RScore/SubCommunity.cpp b/RangeShiftR/src/RScore/SubCommunity.cpp index 26685e3..d908892 100644 --- a/RangeShiftR/src/RScore/SubCommunity.cpp +++ b/RangeShiftR/src/RScore/SubCommunity.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 "SubCommunity.h" //--------------------------------------------------------------------------- @@ -30,22 +30,22 @@ 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; + 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; + 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; } @@ -53,192 +53,142 @@ intptr SubCommunity::getNum(void) { return subCommNum; } Patch* SubCommunity::getPatch(void) { return pPatch; } locn SubCommunity::getLocn(void) { -locn loc = pPatch->getCellLocn(0); -return loc; + locn loc = pPatch->getCellLocn(0); + return loc; } void SubCommunity::setInitial(bool b) { initial = b; } -void SubCommunity::initialise(Landscape *pLandscape,Species *pSpecies) +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; + int ncells; + landParams ppLand = pLandscape->getLandParams(); + initParams init = paramsInit->getInit(); + // determine size of initial population + 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; } - break; } + else nInds = 0; + } + // create new population only if it is non-zero or the matrix popn + if (subCommNum == 0 || nInds > 0) { + newPopn(pLandscape, pSpecies, pPatch, nInds); } - 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) +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); -} + 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; + + // 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 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; + } + 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) +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]; + landParams land = pLandscape->getLandParams(); + int npopns = (int)popns.size(); + popns.push_back(new Population(pSpecies, pPatch, nInds, land.resol)); + 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; + 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 + int npops = (int)popns.size(); + for (int i = 0; i < npops; i++) { // all populations + 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; + } + 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(); + 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(); + if (subCommNum == 0) return; // not applicable in the matrix + pPatch->resetPossSettlers(); } // Extirpate all populations according to @@ -246,225 +196,159 @@ pPatch->resetPossSettlers(); // 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(); + 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(); + 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) +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(); + if (subCommNum == 0) return; // no reproduction in the matrix + float localK, envval; + 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 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 { // 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; } - 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(); + 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; + } } - else { // non-stage-structured species is destroyed - popns[i]->extirpate(); + for (int i = 0; i < npops; i++) { // all populations + popns[i]->reproduction(localK, envval, resol); + popns[i]->fledge(); } } } -*/ - -/* -#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) +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); -} + 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 + 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; + if (subCommNum == 0) return; // no dispersal initiation in the matrix + 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); + int npops = (int)popns.size(); + for (int i = 0; i < npops; i++) { // all populations + pop = popns[i]->getStats(); + for (int j = 0; j < pop.nInds; j++) { + 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(); } - // 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); +void SubCommunity::recruit(Individual* pInd, Species* pSpecies) { + 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) +#if RS_RCPP +int SubCommunity::transfer(Landscape* pLandscape, short landIx, short nextseason) #else -int SubCommunity::transfer(Landscape *pLandscape,short landIx) -#endif // SEASONAL || RS_RCPP +int SubCommunity::transfer(Landscape* pLandscape, short landIx) +#endif // 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); + int ndispersers = 0; + int npops = (int)popns.size(); + for (int i = 0; i < npops; i++) { // all populations +#if RS_RCPP + 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; + ndispersers += popns[i]->transfer(pLandscape, landIx); +#endif // RS_RCPP + + } + return ndispersers; } //--------------------------------------------------------------------------- @@ -473,194 +357,130 @@ return ndispersers; // in which their destination co-ordinates fall // This function is executed for the matrix patch only -void SubCommunity::completeDispersal(Landscape *pLandscape,bool connect) +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) { + 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(); + 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); + pNewPatch = (Patch*)settler.pCell->getPatch(); + // find population within the patch (if there is one) + pPop = (Population*)pNewPatch->getPopn((intptr)pSpecies); + 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(); + pPop = pSubComm->newPopn(pLandscape, pSpecies, pNewPatch, 0); + } + 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 + } } - else { // for group dispersal only - } + // remove pointers in the matrix popn to settlers + popns[i]->clean(); } - // 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) +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); + 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(); + 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(); -} + 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) { +Population* SubCommunity::findPop(Species* pSp, Patch* pPch) { #if RSDEBUG -DEBUGLOG << "SubCommunity::findPop(): this=" << this - << endl; + DEBUGLOG << "SubCommunity::findPop(): this=" << this + << endl; #endif -Population *pPop = 0; -popStats pop; -int npops = (int)popns.size(); + 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; + 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; } - else pPop = 0; -} -return pPop; + 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; -} + 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; + 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; + if (row >= 0) return occupancy[row]; + else return 0; } void SubCommunity::deleteOccupancy(void) { @@ -670,529 +490,513 @@ void SubCommunity::deleteOccupancy(void) { //--------------------------------------------------------------------------- // Open population file and write header record -bool SubCommunity::outPopHeaders(Landscape *pLandscape,Species *pSpecies,int option) +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; + 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) +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); + 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; -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); + // 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; + 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); + } } - else { - if (popns[i]->totalPop() > 0) { - popns[i]->outPopulation(rep,yr,gen,eps,land.patchModel,writeEnv,gradK); + + patchnum = pPatch->getPatchNum(); + for (int i = 0; i < npops; i++) { // all populations + 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()); -} +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) +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); -} + 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; + 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) +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"; + landParams land = pLandscape->getLandParams(); + if (landNr == -999) { // close file + if (outtraits.is_open()) outtraits.close(); + outtraits.clear(); + return true; } - 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"; + + 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 { - outtraits << "\tF_meanEP\tF_stdEP\tM_meanEP\tM_stdEP"; + name = DirOut + + "Batch" + Int2Str(sim.batchNum) + "_" + + "Sim" + Int2Str(sim.simulation) + "_Land" + Int2Str(landNr) + + "_TraitsXcell.txt"; } } else { - if (emig.densDep) { - outtraits << "\tmeanD0\tstdD0\tmeanAlpha\tstdAlpha"; - outtraits << "\tmeanBeta\tstdBeta"; + if (land.patchModel) { + name = DirOut + "Sim" + Int2Str(sim.simulation) + "_TraitsXpatch.txt"; } else { - outtraits << "\tmeanEP\tstdEP"; + name = DirOut + "Sim" + Int2Str(sim.simulation) + "_TraitsXcell.txt"; } } -} -if (trfr.indVar) { - if (trfr.moveModel) { - if (trfr.moveType == 1) { - outtraits << "\tmeanDP\tstdDP\tmeanGB\tstdGB"; - outtraits << "\tmeanAlphaDB\tstdAlphaDB\tmeanBetaDB\tstdBetaDB"; + 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"; + } } - if (trfr.moveType == 2) { - outtraits << "\tmeanStepLength\tstdStepLength\tmeanRho\tstdRho"; + else { + if (emig.densDep) { + outtraits << "\tmeanD0\tstdD0\tmeanAlpha\tstdAlpha"; + outtraits << "\tmeanBeta\tstdBeta"; + } + else { + outtraits << "\tmeanEP\tstdEP"; + } } } - 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" + 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 << "\tmean_distI\tstd_distI"; - if (trfr.twinKern) - outtraits << "\tmean_distII\tstd_distII\tmeanPfirstKernel\tstdPfirstKernel"; + outtraits << "\tmeanS0\tstdS0"; + outtraits << "\tmeanAlphaS\tstdAlphaS"; + outtraits << "\tmeanBetaS\tstdBetaS"; } } -} -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; + outtraits << endl; -return outtraits.is_open(); + 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) + 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; -} + 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; + // 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; - } - } + 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 (emig.indVar) { - if (emig.sexDep) { // must be a sexual species - ngenes = 2; - } - else { - if (dem.repType == 0) { // asexual reproduction - ngenes = 1; + if (writefile) { + outtraits << rep << "\t" << yr << "\t" << gen; + if (land.patchModel) { + outtraits << "\t" << pPatch->getPatchNum(); } - else { // sexual reproduction - ngenes = 1; + else { + locn loc = pPatch->getCellLocn(0); + outtraits << "\t" << loc.x << "\t" << loc.y; } } - 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; + + if (emig.indVar) { + if (emig.sexDep) { // must be a sexual species + ngenes = 2; + } + else { + if (dem.repType == 0) { // asexual reproduction + ngenes = 1; } - else { - sdD0[g] = sdAlpha[g] = sdBeta[g] = 0.0; + else { // sexual reproduction + ngenes = 1; } } - } - 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]; + 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; + } } } - 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 (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 { + if (trfr.indVar) { + if (trfr.moveModel) { + // CURRENTLY INDIVIDUAL VARIATION CANNOT BE SEX-DEPENDENT 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; + else { + if (trfr.sexDep) { // must be a sexual species + ngenes = 2; } - } - } - 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]; + else { + ngenes = 1; } - if (trfr.moveType == 2) { - outtraits << "\t" << mnStepL[0] << "\t" << sdStepL[0]; - outtraits << "\t" << mnRho[0] << "\t" << sdRho[0]; + } + 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; + } } } - 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]; + 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 { // 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]; + 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; + if (sett.indVar) { + if (sett.sexDep) { // must be a sexual species + ngenes = 2; } - } - // 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 { + if (dem.repType == 0) { // asexual reproduction + ngenes = 1; } - else { - sdS0[g] = sdAlpha[g] = sdBeta[g] = 0.0; + else { // sexual reproduction + ngenes = 1; } } - } - 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]; + // 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 = 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; + } + } } - 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) { + 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 + 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]; + } } } -} -return ts; + return ts; } //--------------------------------------------------------------------------- diff --git a/RangeShiftR/src/RScore/SubCommunity.h b/RangeShiftR/src/RScore/SubCommunity.h index 3f1266f..3eef73a 100644 --- a/RangeShiftR/src/RScore/SubCommunity.h +++ b/RangeShiftR/src/RScore/SubCommunity.h @@ -32,9 +32,9 @@ 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., Peer G., Heikkinen R.K., Matsinos Y.G., Watts K. +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. +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 @@ -50,14 +50,6 @@ Last updated: 26 October 2021 by Steve Palmer #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" @@ -111,7 +103,7 @@ class SubCommunity { Individual*, // pointer to Individual Species* // pointer to Species ); -#if RS_RCPP // included also SEASONAL +#if RS_RCPP int transfer( // Transfer through matrix - run for matrix SubCommunity only Landscape*, // pointer to Landscape short, // landscape change index @@ -122,7 +114,7 @@ class SubCommunity { Landscape*, // pointer to Landscape short // landscape change index ); -#endif // SEASONAL || RS_RCPP +#endif // 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( @@ -200,7 +192,6 @@ class SubCommunity { 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; diff --git a/RangeShiftR/src/RScore/Utils.cpp b/RangeShiftR/src/RScore/Utils.cpp new file mode 100644 index 0000000..9d36b92 --- /dev/null +++ b/RangeShiftR/src/RScore/Utils.cpp @@ -0,0 +1,26 @@ +#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/RangeShiftR/src/RScore/Utils.h b/RangeShiftR/src/RScore/Utils.h new file mode 100644 index 0000000..34854a7 --- /dev/null +++ b/RangeShiftR/src/RScore/Utils.h @@ -0,0 +1,18 @@ +#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 diff --git a/RangeShiftR/src/RScore/branches.png b/RangeShiftR/src/RScore/branches.png new file mode 100644 index 0000000..12e3a96 Binary files /dev/null and b/RangeShiftR/src/RScore/branches.png differ diff --git a/RangeShiftR/src/RScore/git_cheatsheet.md b/RangeShiftR/src/RScore/git_cheatsheet.md new file mode 100644 index 0000000..53ca175 --- /dev/null +++ b/RangeShiftR/src/RScore/git_cheatsheet.md @@ -0,0 +1,107 @@ +# Git Cheatsheet + +Quick reference on Git usage for RangeShifter contributors + +#### Creating a local copy of this repo + +```bash +git clone https://github.com/RangeShifter/RScore.git +``` + +#### Enquire about the current state of changes + +``` +git status +``` +This will display whether the local branch is up-to-date with its GitHub counterpart, what files have been changed and if they are staged for commit or not. + +#### Updating the active branch with latest changes (pulling) + +```bash +git pull +``` + +#### Updating the active branch with another branch (merging) + +```bash +git merge +``` + +Merging may trigger a merge conflict is the same lines have been changed on both branches. See Solving Merge Conflict below. + +#### Staging changes to be committed +Changes to local files must first be added to the commit queue ("staged") before being committed. + +```bash +git add # single file +git add . # entire active folder +``` + +#### Creating a commit + +```bash +git commit -m "commit message" +``` + +A good commit message is concise, but descriptive. + +#### Uploading local commits to GitHub (pushing) + +```bash +git push +``` + +#### Switching to an existing branch + +```bash +git checkout +``` +Switching does not update the new active branch with GitHub automatically, so make sure to pull after switching! + +#### Creating a new branch from active branch + +```bash +git branch +``` +You will also need to set the corresponding branch on `origin` (GitHub) before you can push: + +```bash +git push --set-upstream origin +``` + +New branches can also be created on GitHub (drop-down button in the top-left corner of the main page). +New branches on GitHub are brought to the local copy with the next pull. + +#### Deleting a branch locally + +```bash +git branch -d +``` + +#### Instruct Git to not track some files + +Open `.gitignore` and add the path to the files or folders to exclude from the git history. +Check with `git status` that the files are indeed not tracked by git anymore. + +#### Solving a merge conflict +Merge conflicts can arise when multiple contributors simulatneously change the same line of code. +In such cases, git is incapable of deciding which version should be kept and asks for human input. +Git tells you which files are affected by the conflict. +Open each file and resolve **each** section that looks like this: + +``` +After opening the box, we can affirm that +<<<<<<<<<<< HEAD # delete this line +Shroedinger's cat is alive. # delete either this... +================ # delete this line +Shroedinger's cat is dead. # ... or this (or keep both, or none, or a different solution) +>>>>>>>>>>> SHA # delete this line +What an insightful result! +``` + +Ctrl+F "HEAD" is really helpful for finding the conflicts in large files. +When you are done, create a commit stating e.g. "solved merge conflict" and push. + +## Git subtrees + +See [Git subtrees](https://github.com/RangeShifter/RScore/tree/development-guidelines#usage-git-subtree) section in README. diff --git a/RangeShiftR/src/Rinterface.cpp b/RangeShiftR/src/Rinterface.cpp index 9c20049..dd1e36c 100644 --- a/RangeShiftR/src/Rinterface.cpp +++ b/RangeShiftR/src/Rinterface.cpp @@ -1,25 +1,25 @@ /*---------------------------------------------------------------------------- - * + * * Copyright (C) 2020 Anne-Kathleen Malchow, Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Damaris Zurell - * + * * This file is part of RangeShiftR. - * + * * RangeShiftR 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 RangeShiftR. If not, see . - * + * --------------------------------------------------------------------------*/ - - + + /*------------------------------------------------------------------------------ RangeShifter v2.0 Main @@ -68,11 +68,7 @@ ofstream rsLog; // performance log for recording simulation times, etc. int batchnum; int patchmodel, resolution, landtype, maxNhab, speciesdist, distresolution; int reproductn; -#if SEASONAL -int nseasons; -#else int repseasons; -#endif // SEASONAL int stagestruct, stages, transfer; int sexesDem; // no. of explicit sexes for demographic model int sexesDisp; // no. of explicit sexes for dispersal model @@ -80,12 +76,6 @@ int firstsimul; int fileNtraits; // no. of traits defined in genetic architecture file rasterdata landraster,patchraster,spdistraster,costsraster; // rasterdata landraster; -#if RS_CONTAIN -rasterdata damageraster; -#endif // RS_CONTAIN -#if SPATIALMORT -rasterdata mortraster; -#endif // SPATIALMORT // ...including names of the input files // string parameterFile; // string landFile; @@ -381,13 +371,6 @@ Rcpp::List BatchMainR(std::string dirpath, Rcpp::S4 ParMaster) errors++; } -#if SEASONAL - if (landtype != 0) { - BatchError(filetype,-999,0,"LandType"); - batchlog << "LandType must be 0 for a seasonal model" << endl; - errors++; - } -#else if(landtype != 0 && landtype != 2 && landtype != 9) { BatchErrorR(filetype, -999, 0, "LandType"); Rcpp::Rcout << "LandType must be 0, 2 or 9" << endl; @@ -399,7 +382,6 @@ Rcpp::List BatchMainR(std::string dirpath, Rcpp::S4 ParMaster) errors++; } } -#endif // SEASONAL if(landtype == 0) { // raster with unique habitat codes if(maxNhab < 2) { @@ -445,17 +427,10 @@ Rcpp::List BatchMainR(std::string dirpath, Rcpp::S4 ParMaster) } } -#if GROUPDISP - if(reproductn < 0 || reproductn > 3) { - BatchErrorR(filetype, -999, 3, "Reproduction"); - errors++; - } -#else if(reproductn < 0 || reproductn > 2) { BatchErrorR(filetype, -999, 2, "Reproduction"); errors++; } -#endif else { switch(reproductn) { case 0: { @@ -473,40 +448,18 @@ Rcpp::List BatchMainR(std::string dirpath, Rcpp::S4 ParMaster) sexesDisp = 2; break; } -#if GROUPDISP - case 3: { - sexesDem = 1; - sexesDisp = 1; - break; - } -#endif } } -#if SEASONAL - if (nseasons < 2) { - BatchError(filetype,-999,12,"NSeasons"); - errors++; - } -#else if(repseasons < 1) { BatchErrorR(filetype, -999, 11, "RepSeasons"); errors++; } -#endif -#if SEASONAL - if (stagestruct != 1) { - BatchError(filetype,-999,0," "); - errors++; - batchlog << "StageStruct must be 1 for a partial migration model" << endl; - } -#else if(stagestruct < 0 || stagestruct > 1) { BatchErrorR(filetype, -999, 1, "StageStruct"); errors++; } -#endif if(stagestruct) { if(stages < 2 || stages > NSTAGES) { @@ -518,32 +471,10 @@ Rcpp::List BatchMainR(std::string dirpath, Rcpp::S4 ParMaster) stages = 2; } -#if RS_CONTAIN - if (transfer < 0 || transfer > 4) { - BatchError(filetype,-999,4,"Transfer"); - errors++; - } else { - if (stagestruct || transfer < 3) b.transfer = transfer; - else { - BatchError(filetype,-999,0," "); - errors++; - batchlog << "Transfer option " << transfer - << " is not allowed for a non-structured species" << endl; - } - } -#else if(transfer < 0 || transfer > 2) { BatchErrorR(filetype, -999, 2, "Transfer"); errors++; } -#endif // RS_CONTAIN - -#if RS_ABC - if(nABCsamples < 1) { - BatchErrorR(filetype, -999, 10, "ABCsamplesize"); - errors++; - } -#endif if(errors > 0) { // terminate batch error checking @@ -609,9 +540,6 @@ Rcpp::List BatchMainR(std::string dirpath, Rcpp::S4 ParMaster) //Rcpp::RNGScope rngScope; -#if RANDOMCHECK - randomCheck(); -#else Rcpp::List list_outPop; if(errors == 0) { Rcpp::Rcout << endl << "Run Simulation(s)"; @@ -624,7 +552,6 @@ Rcpp::List BatchMainR(std::string dirpath, Rcpp::S4 ParMaster) list_outPop = RunBatchR(nSimuls, nLandscapes, ParMaster); } -#endif #if RSDEBUG if(DEBUGLOG.is_open()) { @@ -739,13 +666,6 @@ bool ReadLandParamsR(Landscape* pLandscape, Rcpp::S4 ParMaster) if(!patchmodel && name_patch != "NULL") Rcpp::Rcout << "PatchFile must be NULL in a cell-based model!" << endl; name_sp_dist = Rcpp::as(LandParamsR.slot("SpDistFile")); -#if RS_CONTAIN - name_damage = Rcpp::as(LandParamsR.slot("DamageFile")); -#endif // RS_CONTAIN -#if SPATIALMORT - name_mort1 = Rcpp::as(LandParamsR.slot("MortFile1")); - name_mort2 = Rcpp::as(LandParamsR.slot("MortFile2")); -#endif // SPATIALMORT if(landtype == 2) ppLand.nHab = 1; // habitat quality landscape has one habitat class @@ -996,96 +916,6 @@ bool ReadLandParamsR(Landscape* pLandscape, Rcpp::S4 ParMaster) } } -#if RS_CONTAIN - // check economic / environmental damage map filename /* *** not implemented in R-version - /* - ftype = "DamageFile"; - bLandFile >> intext; - if (intext != "NULL") { - if (true) { - fname = indir + intext; - damageraster = CheckRasterFile(fname); - if (damageraster.ok) { - if (damageraster.cellsize == resolution) { - if (damageraster.ncols == landraster.ncols - && damageraster.nrows == landraster.nrows - && damageraster.cellsize == landraster.cellsize - && (int)damageraster.xllcorner == (int)landraster.xllcorner - && (int)damageraster.yllcorner == (int)landraster.yllcorner) { - batchlog << ftype << " headers OK: " << fname << endl; - } else { - batchlog << "*** Headers of " << ftype << " " << fname - << " do not match headers of LandscapeFile" << endl; - errors++; - } - } else { - batchlog << msgresol0 << ftype << " " << fname - << msgresol1 << endl; - errors++; - } - } else { - errors++; - if (damageraster.errors == -111) - OpenError(ftype,fname); - else - FormatError(fname,damageraster.errors); - } - } - }*/ -#endif // RS_CONTAIN - -#if SPATIALMORT - // check mortality map filenames /* *** not implemented in R-version - /* - bool filenull[2]; - for (int mm = 0; mm < 2; mm++) { - int fnum = mm+1; - ftype = "MortFile" + Int2Str(fnum); - bLandFile >> intext; - if (intext == "NULL") { - filenull[mm] = true; - } - else { - filenull[mm] = false; - fname = indir + intext; - mortraster = CheckRasterFile(fname); - if (mortraster.ok) { - if (mortraster.cellsize == resolution) { - if (mortraster.ncols == landraster.ncols - && mortraster.nrows == landraster.nrows - && mortraster.cellsize == landraster.cellsize - && (int)mortraster.xllcorner == (int)landraster.xllcorner - && (int)mortraster.yllcorner == (int)landraster.yllcorner) { - batchlog << ftype << " headers OK: " << fname << endl; - } - else { - batchlog << "*** Headers of " << ftype << " " << fname - << " do not match headers of LandscapeFile" << endl; - errors++; - } - } - else { - batchlog << "*** Resolution of " << ftype << " " << fname - << " does not match Resolution in Control file" << endl; - errors++; - } - } - else { - errors++; - if (mortraster.errors == -111) - OpenError(ftype,fname); - else - FormatError(fname,mortraster.errors); - } - } - } - if ((filenull[0] && !filenull[1]) || (!filenull[0] && filenull[1])) { - batchlog << "*** There must be either two spatial mortality files," - << " or both must be NULL to omit spatial mortality" << endl; - errors++; - }*/ -#endif // SPATIALMORT - } pLandscape->setLandParams(ppLand, true); @@ -1188,8 +1018,9 @@ int ReadDynLandR(Landscape *pLandscape, Rcpp::S4 LandParamsR) hfile >> header >> yllcorner; if (header != L"yllcorner" && header != L"YLLCORNER") errors++; - - hfile >> header >> cellsize; + double tmpcellsize; + hfile >> header >> tmpcellsize; + cellsize = (int) tmpcellsize; if (header != L"cellsize" && header != L"CELLSIZE") errors++; hfile >> header >> habnodata; @@ -1285,7 +1116,9 @@ int ReadDynLandR(Landscape *pLandscape, Rcpp::S4 LandParamsR) pfile >> header >> yllcorner; if (header != L"yllcorner" && header != L"YLLCORNER") errors++; - pfile >> header >> cellsize; + double tmpcellsize; + pfile >> header >> tmpcellsize; + cellsize = (int) tmpcellsize; if (header != L"cellsize" && header != L"CELLSIZE") errors++; pfile >> header >> pchnodata; @@ -1385,10 +1218,12 @@ int ReadDynLandR(Landscape *pLandscape, Rcpp::S4 LandParamsR) cfile >> header >> yllcorner; if (header != L"yllcorner" && header != L"YLLCORNER") errors++; - cfile >> header >> cellsize; + double tmpcellsize; + cfile >> header >> tmpcellsize; + cellsize = (int) tmpcellsize; if (header != L"cellsize" && header != L"CELLSIZE") errors++; - cfile >> header >> pchnodata; + cfile >> header >> costnodata; if (header != L"NODATA_value" && header != L"NODATA_VALUE") errors++; if (errors > 0) { @@ -1515,9 +1350,6 @@ int ReadParametersR(Landscape* pLandscape, Rcpp::S4 ParMaster) DEBUGLOG << "ReadParametersR(): simulation = " << sim.simulation << " reps = " << sim.reps << " years = " << sim.years << endl; #endif -#if SPATIALMORT - // parameters >> sim.mortChgYear; -#endif int iiii, gradType, shift_begin, shift_stop; float grad_inc, opt_y, f, optEXT, shift_rate; @@ -1564,18 +1396,6 @@ int ReadParametersR(Landscape* pLandscape, Rcpp::S4 ParMaster) // Not required for EnvStoch = 0; stochasticity in carrying capacity is allowed for an artificial landscape only env.inK = Rcpp::as(ParamParamsR.slot("EnvStochType")); -#if BUTTERFLYDISP - // parameters >> iiii; - // if (iiii == 1) env.fromFile = true; - // else env.fromFile = false; - // string envfile; - // parameters >> envfile; - // if (env.fromFile) - // { - // envstochfilename = paramsSim->getDir(1) + envfile; - // } -#endif - // as from v1.1, there is just one pair of min & max values, // which are attributes of the species // ULTIMATELY, THE PARAMETER FILE SHOULD HAVE ONLY TWO COLUMNS ... @@ -1602,50 +1422,22 @@ int ReadParametersR(Landscape* pLandscape, Rcpp::S4 ParMaster) env.locExtProb = Rcpp::as(ParamParamsR.slot("LocalExtProb")); paramsStoch->setStoch(env); -#if BUTTERFLYDISP - // parameters >> iiii; - // if (dem.stageStruct) dem.dispersal = 1; - // else dem.dispersal = iiii; -#endif - dem.propMales = Rcpp::as(DemogParamsR.slot("PropMales")); dem.harem = Rcpp::as(DemogParamsR.slot("Harem")); dem.bc = Rcpp::as(DemogParamsR.slot("bc")); dem.lambda = Rcpp::as(DemogParamsR.slot("Rmax")); -#if !GROUPDISP pSpecies->setDemogr(dem); -#endif float k; if(landtype == 9) { // artificial landscape // only one value of K is read, but the first 'habitat' is the matrix where K = 0 -#if SEASONAL - pSpecies->createHabK(2,1); -#else pSpecies->createHabK(2); -#endif // SEASONAL k = Rcpp::as(LandParamsR.slot("K_or_DensDep")); k *= ((double)(pow(paramsLand.resol, double(2)))) / 10000.0; -#if SEASONAL - pSpecies->setHabK(0,1,0); - pSpecies->setHabK(1,1,k); -#else pSpecies->setHabK(0,0); pSpecies->setHabK(1,k); -#endif // SEASONAL } else { -#if SEASONAL - pSpecies->createHabK(paramsLand.nHabMax,dem.nSeasons); - Rcpp::NumericVector k_vec; - k_vec = Rcpp::as(LandParamsR.slot("K_or_DensDep")); - for (int j = 0; j < dem.nSeasons; j++) { - for (int i = 0; i < paramsLand.nHabMax; i++) { - k = k_vec[i] * ((double)(pow(paramsLand.resol, double(2)))) / 10000.0; - pSpecies->setHabK(i,j,k); - } - } -#else pSpecies->createHabK(paramsLand.nHabMax); Rcpp::NumericVector k_vec; k_vec = Rcpp::as(LandParamsR.slot("K_or_DensDep")); @@ -1653,43 +1445,14 @@ int ReadParametersR(Landscape* pLandscape, Rcpp::S4 ParMaster) k = k_vec[i] * ((double)(pow(paramsLand.resol, double(2)))) / 10000.0; pSpecies->setHabK(i,k); } -#endif // SEASONAL } #if RSDEBUG DEBUGLOG << "ReadParametersR(): dem.lambda = " << dem.lambda -#if SEASONAL - << " habK[0] = " << pSpecies->getHabK(0,0) -#else << " habK[0] = " << pSpecies->getHabK(0) -#endif // SEASONAL << " nHabMax = " << paramsLand.nHabMax << endl; #endif -#if GROUPDISP -// ADDITIONAL PARAMETERS FOR GROUP DISPERSAL MODEL -// parameters >> iiii; -// if (iiii == 1) dem.selfing = true; -// else dem.selfing = false; -// parameters >> dem.paternity >> dem.propLocal >> dem.propNghbr; -// pSpecies->setDemogr(dem); -#if PEDIGREE -// parameters >> sim.relMatSize; -#endif -#endif -#if SOCIALMODEL - // ADDITIONAL PARAMETERS FOR PROBIS SOCIAL POLYMORPHISM MODEL - // socialParams soc; - // parameters >> soc.asocK >> soc.asocRmax >> soc.asocBc >> soc.ra >> soc.rs - // >> soc.Ta >> soc.Ts >> soc.dK >> soc.alpha; - // parameters >> soc.asocK >> soc.asocRmax >> soc.asocBc - // >> soc.Ta >> soc.Ts >> soc.Ca >> soc.Cs >> soc.dK >> soc.alpha; - // parameters >> soc.socMean >> soc.socSD >> soc.socScale - // >> soc.asocK >> soc.asocRmax >> soc.asocBc - // >> soc.Ta >> soc.Ts >> soc.ca >> soc.cs >> soc.ba >> soc.bs >> soc.dK >> soc.alpha; - // pSpecies->setSocialParams(soc); -#endif - // Output start years sim.outStartPop = Rcpp::as(ParamParamsR.slot("OutStartPop")); sim.outStartInd = Rcpp::as(ParamParamsR.slot("OutStartInd")); @@ -1698,9 +1461,6 @@ int ReadParametersR(Landscape* pLandscape, Rcpp::S4 ParMaster) sim.outStartTraitRow = Rcpp::as(ParamParamsR.slot("OutStartTraitRow")); sim.outStartConn = Rcpp::as(ParamParamsR.slot("OutStartConn")); sim.outStartPaths = Rcpp::as(ParamParamsR.slot("OutStartPaths")); -#if RS_CONTAIN - sim.OutStartDamage = Rcpp::as(ParamParamsR.slot("OutStartDamage")); -#endif // Output intervals sim.outIntRange = Rcpp::as(ParamParamsR.slot("OutIntRange")); sim.outIntOcc = Rcpp::as(ParamParamsR.slot("OutIntOcc")); @@ -1756,13 +1516,6 @@ int ReadParametersR(Landscape* pLandscape, Rcpp::S4 ParMaster) else sim.outPaths = false; -#if RS_CONTAIN - sim.OutIntDamage = Rcpp::as(ParamParamsR.slot("OutIntDamage")); - if (sim.outIntDamage > 0) - sim.outDamage = true; - else sim.outDamage = false; -#endif - if(sim.outOccup && sim.reps < 2) error = 103; if(paramsLand.patchModel) { @@ -1813,72 +1566,12 @@ int ReadStageStructureR(Rcpp::S4 ParMaster) #endif // int simulation; // simulation = Rcpp::as(StagesParamsR.slot("Simulation")); //Must match simulation numbers in ParamParams -#if GOBYMODEL - /* PARSE: - bStageStructFile >> infloat; // no check required on initial phenotype mean - bStageStructFile >> initPhenSD; - if (initPhenSD <= 0.0) { BatchError(filetype,line,10,"InitPhenSD"); errors++; } - bStageStructFile >> initPhenScale; - if (initPhenScale <= 0.0) { BatchError(filetype,line,10,"InitPhenScale"); errors++; } - if (initPhenSD > initPhenScale) { BatchError(filetype,line,3,"InitPhenSD","InitPhenScale"); errors++; } - bStageStructFile >> fasocial; - if (fasocial <= 0.0) { BatchError(filetype,line,10,"Fasocial"); errors++; } - * READ: - socialParams soc; - ssfile >> soc.socMean >> soc.socSD >> soc.socScale >> sstruct.asocF; - // pSpecies->setSocialParams(soc); */ -#endif sstruct.disperseOnLoss = Rcpp::as(StagesParamsR.slot("PostDestructn")); sstruct.probRep = Rcpp::as(StagesParamsR.slot("PRep")); sstruct.repInterval = Rcpp::as(StagesParamsR.slot("RepInterval")); sstruct.maxAge = Rcpp::as(StagesParamsR.slot("MaxAge")); -#if RS_CONTAIN - habdemfile = Rcpp::as(StagesParamsR.slot("HabDemFile")); - trmatrix = Rcpp::as(StagesParamsR.slot("TransMatrix")); - /* - * PARSING... - * - * READING: - pSpecies->resetDem(-1); // reset demography for all habitats - if (habdemfile == "NULL") { - dem.habDepDem = false; - } else { - dem.habDepDem = true; - hdfile.open((Inputs+habdemfile).c_str()); - ReadHabDemFile(sstruct.nStages,sexesDem); - hdfile.close(); - hdfile.clear(); - } - pSpecies->setDemogr(dem); - if (trmatrix != "NULL") { - #if SEASONAL - for (int i = 0; i < dem.nSeasons; i++) { - tmfile.open((Inputs+name).c_str()); - ReadTransitionMatrix(sstruct.nStages,sexesDem,0,i); - tmfile.close(); tmfile.clear(); - } - #else - tmfile.open((Inputs+name).c_str()); - ReadTransitionMatrix(sstruct.nStages,sexesDem,0,0); - tmfile.close(); tmfile.clear(); - #endif // SEASONAL - }*/ -#else -#if SEASONAL - seasonmatrix = Rcpp::as(StagesParamsR.slot("SeasonFile")); - /* - * PARSING... - * - * READING: - seasonfile.open((Inputs+seasonmatrix).c_str()); - ReadSeasonFile(1,dem.nSeasons); - seasonfile.close(); seasonfile.clear(); - }*/ -#else trmatrix = Rcpp::as(StagesParamsR.slot("TransMatrix")); // parsing is done on R-level -#endif // SEASONAL -#endif // RS_CONTAIN minAge = Rcpp::as(StagesParamsR.slot("MinAge")); // Store Transition matrix: @@ -1921,7 +1614,7 @@ int ReadStageStructureR(Rcpp::S4 ParMaster) ss = (float)trmatrix(i - 1, i); // survival prob else ss = (float)trmatrix(i, i); - if((i + 2) != matrixsize) + if((i + 2) != matrixsize && (i + 1) != matrixsize) dd = (float)trmatrix(i + 1, i); // development prob else dd = 0.0; @@ -1999,42 +1692,6 @@ int ReadStageStructureR(Rcpp::S4 ParMaster) #endif } -#if PARTMIGRN - bStageStructFile >> header; - if (header != "PropPhilRes" ) errors++; - bStageStructFile >> header; - if (header != "PropPhilMigFxd" ) errors++; - bStageStructFile >> header; - if (header != "PropPhilMigVar" ) errors++; - bStageStructFile >> header; - if (header != "PropDispRes" ) errors++; - bStageStructFile >> header; - if (header != "PropDispMigFxd" ) errors++; - bStageStructFile >> header; - if (header != "PropDispMigVar" ) errors++; - bStageStructFile >> header; - if (header != "ResetMigrn" ) errors++; - /* - * PARSING... - * - * ReadING... - */ -#endif // PARTMIGRN -#if SEASONAL - bStageStructFile >> header; - if (header != "ExtremeFile" ) errors++; - /* - * PARSING... - * - * READING: - if (name != "NULL") { - pLandscape->resetExtEvents(); - extremefile.open((Inputs+name).c_str()); - ReadExtremeFile(pLandscape,nseasons); - extremefile.close(); extremefile.clear(); - }*/ -#endif // SEASONAL - pSpecies->setStage(sstruct); if(sstruct.devDens || sstruct.survDens) { pSpecies->setDensDep(devCoeff, survCoeff); @@ -2057,9 +1714,6 @@ int ReadEmigrationR(Rcpp::S4 ParMaster) int Nlines, emigstage, stage, sex, offset; Rcpp::NumericMatrix EmigMatrix; Rcpp::NumericVector EmigScalesVec; -#if GOBYMODEL - // float asocD; -#endif demogrParams dem = pSpecies->getDemogr(); stageParams sstruct = pSpecies->getStage(); emigRules emig = pSpecies->getEmig(); @@ -2093,25 +1747,6 @@ int ReadEmigrationR(Rcpp::S4 ParMaster) if(!dem.stageStruct && emig.stgDep) error = 303; -#if GROUPDISP - // int groupdisp; - // float groupmean; - // emigFile >> groupdisp >> groupmean; - // if (firstline) { - // if (groupdisp == 1) emig.groupdisp = true; - // else emig.groupdisp = false; - // emig.groupmean = groupmean; - // pSpecies->setEmig(emig); - // } -#endif -#if GOBYMODEL - // emigFile >> asocD; - // if (firstline) { - // emig.asocD = asocD; - // pSpecies->setEmig(emig); - // } -#endif - // no.of lines according to known stage- and sex-dependency and corresponding column offset if(emig.stgDep) { if(emig.sexDep) { @@ -2231,11 +1866,7 @@ int ReadTransferR(Landscape* pLandscape, Rcpp::S4 ParMaster) << " paramsLand.generated=" << paramsLand.generated << " paramsLand.rasterType=" << paramsLand.rasterType << " trfr.moveModel=" << trfr.moveModel -#if RS_CONTAIN - << " trfr.kernType=" << trfr.kernType -#else << " trfr.twinKern=" << trfr.twinKern -#endif << endl; #endif @@ -2270,9 +1901,6 @@ int ReadTransferR(Landscape* pLandscape, Rcpp::S4 ParMaster) string CostsFile; trfrSMSParams smsparams; trfrCRWParams mparams; -#if TEMPMORT - // string MortFile; -#endif Rcpp::NumericVector ReadVec; switch(TransferType) { @@ -2288,11 +1916,7 @@ int ReadTransferR(Landscape* pLandscape, Rcpp::S4 ParMaster) // simulation numbers in ParamParams trfr.stgDep = Rcpp::as(TransParamsR.slot("StageDep")); // Stage-dependent transfer. Must be 0 if IndVar is 1 trfr.sexDep = Rcpp::as(TransParamsR.slot("SexDep")); // Sex-dependent transfer. -#if RS_CONTAIN - trfr.kernType = Rcpp::as(TransParamsR.slot("KernType")); -#else trfr.twinKern = Rcpp::as(TransParamsR.slot("DoubleKernel")); // 0 = negative exponential; 1 = double negative exponential -#endif trfr.distMort = Rcpp::as(TransParamsR.slot("DistMort")); // Distance-dependent mortality trfr.indVar = Rcpp::as(TransParamsR.slot("IndVar")); @@ -2524,66 +2148,6 @@ int ReadTransferR(Landscape* pLandscape, Rcpp::S4 ParMaster) pSpecies->setTrfrScales(scale); } -#if TEMPMORT - /*bTransferFile >> header; - if (header != "StraightenPath" ) errors++; - bTransferFile >> header; - if (header != "SMtype" ) errors++; - bTransferFile >> header; - if (header != "SMconst" ) errors++; - bTransferFile >> header; - if (header != "MortFile" ) errors++; - * - * PARSING: - ftype = "MortFile"; - if (smtype == 2) { - if (intext == "NULL") { - BatchError(filetype,line,0," "); errors++; - batchlog << ftype << " is required if SMtype = 2" << endl; - } - else { - checkfile = true; - for (i = 0; i < (int)mortfiles.size(); i++) { - if (intext == mortfiles[i]) { // file has already been checked - checkfile = false; - } - } - if (checkfile) { - fname = indir + intext; - batchlog << "Checking " << ftype << " " << fname << endl; - bMortFile.open(fname.c_str()); - if (bMortFile.is_open()) { - int err = ParseMortFile(); - if (err == 0) FileHeadersOK(ftype); else errors++; - bMortFile.close(); - } - else { - OpenError(ftype,fname); errors++; - } - if (bMortFile.is_open()) bMortFile.close(); - bMortFile.clear(); - } // end of checkfile - mortfiles.push_back(intext); - } // end of intext != NULL - } - else { - if (intext != "NULL") { - BatchError(filetype,line,0," "); errors++; - batchlog << ftype << " should be NULL if SMtype is not 2" << endl; - } - } - * - * READING: - * - ransFile >> jjjj >> trfr.smType >> move.stepMort >> MortFile; - #if RSDEBUG - DEBUGLOG << "ReadTransfer(): MortFile=" << MortFile << endl; - #endif - if (trfr.smType == 2) { - mortfilename = paramsSim->getDir(1) + MortFile; - ReadMortalities(mortfilename); - } */ -#else movt.straigtenPath = Rcpp::as(TransParamsR.slot("StraightenPath")); // Straighten path after decision not to settle? // Mortality @@ -2617,15 +2181,10 @@ int ReadTransferR(Landscape* pLandscape, Rcpp::S4 ParMaster) } } } -#endif // TEMPMORT #if RSDEBUG -#if TEMPMORT - DEBUGLOG << "ReadTransferR(): SMtype=" << trfr.smType << " SMconst=" << movt.stepMort << endl; -#else DEBUGLOG << "ReadTransferR(): SMtype=" << trfr.habMort << " SMconst=" << movt.stepMort << endl; -#endif #endif // Costs @@ -2711,9 +2270,6 @@ int ReadTransferR(Landscape* pLandscape, Rcpp::S4 ParMaster) } } -#if TEMPMORT - transFile >> trfr.smType >> movt.stepMort >> jjjj; -#endif movt.straigtenPath = Rcpp::as(TransParamsR.slot("StraightenPath")); // Straighten path after decision not to settle? pSpecies->setTrfrScales(scale); @@ -2757,20 +2313,11 @@ int ReadTransferR(Landscape* pLandscape, Rcpp::S4 ParMaster) } } } -#if EVOLSMS - if(trfr.smType == 1 && paramsLand.rasterType != 0) - error = 434; -#else if(trfr.habMort && paramsLand.rasterType != 0) error = 434; // habitat percentage landscape cant have habitat-dependent mortality -#endif #if RSDEBUG -#if EVOLSMS - DEBUGLOG << "ReadTransferR(): SMtype=" << trfr.smType << " SMconst=" << movt.stepMort << endl; -#else DEBUGLOG << "ReadTransferR(): SMtype=" << trfr.habMort << " SMconst=" << movt.stepMort << endl; -#endif #endif pSpecies->setTrfr(trfr); @@ -2780,218 +2327,6 @@ int ReadTransferR(Landscape* pLandscape, Rcpp::S4 ParMaster) } break; // end of CRW -#if RS_CONTAIN - /* - case 3: { // 2Dt dispersal kernel - * - * PARSING: - * - batchlog << "Checking 2DT dispersal kernel format file" << endl; - bTransferFile >> header; if (header != "DistMort" ) errors++; - bTransferFile >> header; if (header != "U0Kernel1" ) errors++; - bTransferFile >> header; if (header != "P0Kernel1" ) errors++; - bTransferFile >> header; if (header != "U0Kernel2" ) errors++; - bTransferFile >> header; if (header != "P0Kernel2" ) errors++; - bTransferFile >> header; if (header != "PropKernel1" ) errors++; - bTransferFile >> header; if (header != "MortProb" ) errors++; - bTransferFile >> header; if (header != "Slope" ) errors++; - bTransferFile >> header; if (header != "InflPoint" ) errors++; - break; - - // read and validate columns relating to stage and sex-dependency and to IIV - current = CheckStageSex(filetype,line,simul,prev,0,0,0,0,0,true,false); - if (current.newsimul) simuls++; - errors += current.errors; - prev = current; - // validate mortality - bTransferFile >> distmort; - if (distmort < 0 || distmort > 1) { - BatchError(filetype,line,1,"DistMort"); errors++; - } - // read remaining columns of the current record - bTransferFile >> u0Kernel1 >> p0Kernel1 >> u0Kernel2 >> p0Kernel2 >> propKernel1; - bTransferFile >> mortProb >> slope >> inflPoint; - - if (u0Kernel1 < 0.0) { - BatchError(filetype,line,19,"U0Kernel1"); errors++; - } - if (p0Kernel1 < 0.0) { - BatchError(filetype,line,19,"P0Kernel1"); errors++; - } - if (u0Kernel2 < 0.0) { - BatchError(filetype,line,19,"U0Kernel2"); errors++; - } - if (p0Kernel2 < 0.0) { - BatchError(filetype,line,19,"P0Kernel2"); errors++; - } - if (propKernel1 < 0.0 || propKernel1 > 1.0) { - BatchError(filetype,line,20,"PropKernel1"); errors++; - } - - if (distmort) { // distance-dependent mortality - // WHAT CONDITIONS APPLY TO MORTALITY SLOPE AND INFLECTION POINT? - } - else { // constant mortality - if (mortProb < 0.0 || mortProb >= 1.0) { - BatchError(filetype,line,20,"MortProb"); errors++; - } - } - * - * READING: - * - - trfr2Dt t2; - - transFile >> simulation >> iiii; - if (iiii == 0) trfr.distMort = false; else trfr.distMort = true; - - transFile >> t2.u0Kernel1 >> t2.p0Kernel1 >> t2.u0Kernel2 >> t2.p0Kernel2 - >> t2.propKernel1; - pSpecies->setTrfr2Dt(t2); - - // mortality - trfrMortParams mort; - transFile >> mort.fixedMort >> mort.mortAlpha >> mort.mortBeta; - pSpecies->setMortParams(mort); - - #if RSDEBUG - DEBUGLOG << "ReadTransfer(): simulation=" << simulation - << " trfr.distMort=" << trfr.distMort - << " t2.u0Kernel1=" << t2.u0Kernel1 << " t2.p0Kernel1=" << t2.p0Kernel1 - << " t2.u0Kernel2=" << t2.u0Kernel2 << " t2.p0Kernel2=" << t2.p0Kernel2 - << " t2.propKernel1=" << t2.propKernel1 << " mort.fixedMort=" << mort.fixedMort - << endl; - #endif - - pSpecies->setTrfr(trfr); - - break; - } // end of 2Dt dispersal kernel - - case 4: { // WALD dispersal kernel - * - * PARSING: - * - batchlog << "Checking WALD dispersal kernel format file" << endl; - bTransferFile >> header; if (header != "DistMort" ) errors++; - bTransferFile >> header; if (header != "MeanU" ) errors++; - bTransferFile >> header; if (header != "SigmaW" ) errors++; - bTransferFile >> header; if (header != "Hc" ) errors++; - for (i = 1; i < stages; i++) { - colheader = "Hr" + Int2Str(i); - bTransferFile >> header; if (header != colheader ) hrerrors++; - } - bTransferFile >> header; if (header != "Vt" ) errors++; - bTransferFile >> header; if (header != "Kappa" ) errors++; - bTransferFile >> header; if (header != "DirnMean" ) errors++; - bTransferFile >> header; if (header != "DirnSD" ) errors++; - bTransferFile >> header; if (header != "MortProb" ) errors++; - bTransferFile >> header; if (header != "Slope" ) errors++; - bTransferFile >> header; if (header != "InflPoint" ) errors++; - break; - // read and validate columns relating to stage and sex-dependency and to IIV - current = CheckStageSex(filetype,line,simul,prev,0,0,0,0,0,true,false); - if (current.newsimul) simuls++; - errors += current.errors; - prev = current; - // validate mortality - bTransferFile >> distmort; - if (distmort < 0 || distmort > 1) { - BatchError(filetype,line,1,"DistMort"); - errors++; - } - // read remaining columns of the current record - bTransferFile >> meanU >> sigma_w >> hc; - if (meanU <= 0.0) { - BatchError(filetype,line,10,"MeanU"); - errors++; - } - if (sigma_w <= 0.0) { - BatchError(filetype,line,10,"SigmaW"); - errors++; - } - if (hc <= 0.0) { - BatchError(filetype,line,10,"Hc"); - errors++; - } - for (int i = 1; i < stages; i++) { - bTransferFile >> hr; - colheader = "Hr" + Int2Str(i); - if (hr <= 0.0) { - BatchError(filetype,line,10,colheader); - errors++; - } - if (hr > hc) { - BatchError(filetype,line,3,colheader,"Hc"); - errors++; - } - } - bTransferFile >> vt >> kappa >> dirnmean >> dirnsd; - if (vt <= 0.0) { - BatchError(filetype,line,10,"Vt"); - errors++; - } - if (kappa <= 0.0) { - BatchError(filetype,line,10,"Kappa"); - errors++; - } - if (dirnmean < 0.0 || dirnmean >= 360.0) { - BatchError(filetype,line,0," "); - errors++; - batchlog << "DirnMean must be >= 0.0 and < 360.0" << endl; - } - if (dirnsd <= 0.0) { - BatchError(filetype,line,10,"DirnSD"); - errors++; - } - bTransferFile >> mortProb >> slope >> inflPoint; - if (distmort) { // distance-dependent mortality - // WHAT CONDITIONS APPLY TO MORTALITY SLOPE AND INFLECTION POINT? - } else { // constant mortality - if (mortProb < 0.0 || mortProb >= 1.0) { - BatchError(filetype,line,20,"MortProb"); - errors++; - } - } - * - * READING: - * - - trfrWald w; - - transFile >> simulation >> iiii; - if (iiii == 0) trfr.distMort = false; else trfr.distMort = true; - - transFile >> w.meanU >> w.sigma_w >> w.hc; - for (int i = 1; i < sstruct.nStages; i++) { - float hr; - transFile >> hr; - pSpecies->setTrfrHr(hr,i); - } - transFile >> w.vt >> w.kappa >> w.meanDirn >> w.sdDirn; - pSpecies->setTrfrWald(w); - - // mortality - trfrMortParams m; - transFile >> m.fixedMort >> m.mortAlpha >> m.mortBeta; - pSpecies->setMortParams(m); - - #if RSDEBUG - DEBUGLOG << "ReadTransfer(): simulation=" << simulation - << " trfr.distMort=" << trfr.distMort - << " w.meanU=" << w.meanU << " w.sigma_w=" << w.sigma_w - << " w.hc=" << w.hc << " w.vt=" << w.vt - << " w.meanDirn=" << w.meanDirn << " w.sdDirn=" << w.sdDirn - << " m.fixedMort=" << m.fixedMort - << endl; - #endif - pSpecies->setTrfr(trfr); - - break; - } // end of WALD dispersal kernel - - */ -#endif // RS_CONTAIN default: error = 440; } // end of switch (TransferType) @@ -3026,20 +2361,12 @@ int ReadSettlementR(Rcpp::S4 ParMaster) settleTraits settleDD = pSpecies->getSettTraits(0,0); settParams sparams = pSpecies->getSettParams(0,0); -#if GOBYMODEL - float alphaSasoc, betaSasoc; -#endif - // int simulation; // simulation = Rcpp::as(SettleParamsR.slot("Simulation")); // REMOVED in R-interface // Must match simulation // numbers in ParamParams sett.stgDep = Rcpp::as(SettleParamsR.slot("StageDep")); // Stage-dependent settlement. sett.sexDep = Rcpp::as(SettleParamsR.slot("SexDep")); // Sex-dependent settlement. -#if RS_CONTAIN - if (transfer == 0 || transfer == 3 || transfer == 4) { -#else if (transfer == 0) { -#endif // RS_CONTAIN // dispersal kernel // dispersal kernel sett.indVar = false; if(dem.repType == 0) { @@ -3164,14 +2491,6 @@ int ReadSettlementR(Rcpp::S4 ParMaster) } else { ssteps.maxStepsYr = (int)MaxStepsYr(line); } -#if GOBYMODEL - settFile >> alphaSasoc >> betaSasoc; - if(firstline) { - sett.alphaSasoc = alphaSasoc; - sett.betaSasoc = betaSasoc; - pSpecies->setSettle(sett); - } -#endif if(densdep) { if(sett.indVar) { sparams.s0Mean = (float)SettleCondMatrix( @@ -3208,12 +2527,21 @@ int ReadSettlementR(Rcpp::S4 ParMaster) srules.findMate = findmate; pSpecies->setSettRules(0, 0, srules); pSpecies->setSteps(0, 0, ssteps); + if (dem.repType > 0) { + pSpecies->setSettRules(0, 1, srules); + pSpecies->setSteps(0, 1, ssteps); + } if(srules.densDep) { - if(sett.indVar) - pSpecies->setSettParams(0, 0, sparams); - else - pSpecies->setSettTraits(0, 0, settleDD); + if(sett.indVar){ + pSpecies->setSettParams(0, 0, sparams); + if (dem.repType > 0) pSpecies->setSettParams(0, 1, sparams); + } + else { + pSpecies->setSettTraits(0, 0, settleDD); + if (dem.repType > 0) pSpecies->setSettTraits(0, 1, settleDD); + } } + if(dem.stageStruct) { // model is structured - also set parameters for all stages for(int i = 1; i < sstruct.nStages; i++) { pSpecies->setSettRules(i, 0, srules); @@ -3896,9 +3224,6 @@ Rcpp::List RunBatchR(int nSimuls, int nLandscapes, Rcpp::S4 ParMaster) int read_error; bool params_ok; simParams sim = paramsSim->getSim(); -#if SEASONAL - demogrParams dem = pSpecies->getDemogr(); -#endif Rcpp::List list_outPop; Landscape* pLandscape = NULL; // pointer to landscape @@ -3929,7 +3254,7 @@ Rcpp::List RunBatchR(int nSimuls, int nLandscapes, Rcpp::S4 ParMaster) #if RSDEBUG rsLog << "WARNING,***** RSDEBUG mode is active *****,,," << endl; #endif -#if GROUPDISP || RS_ABC || RS_RCPP +#if RS_RCPP rsLog << "RNG SEED,,,," << RS_random_seed << endl; #endif @@ -4042,22 +3367,6 @@ Rcpp::List RunBatchR(int nSimuls, int nLandscapes, Rcpp::S4 ParMaster) DEBUGLOG << "RunBatchR(): j=" << j << " spDist=" << paramsLand.spDist << endl; #endif -#if SPATIALMORT - // optional spatial mortality files - if(name_mortfile[0] != "NULL") { - string mname[2]; - mname[0] = paramsSim->getDir(1) + name_mortfile[0]; - mname[1] = paramsSim->getDir(1) + name_mortfile[1]; - landcode = pLandscape->readMortalityFiles(mname[0], mname[1]); - if(landcode != 0) { - Rcpp::Rcout << endl - << "Error reading mortality files for landscape " << land_nr << " - aborting" << endl; - rsLog << "Landscape," << land_nr << ",ERROR,CODE," << landcode << endl; - landOK = false; - } - } -#endif - if(landOK) { t01 = time(0); rsLog << "Landscape," << land_nr << ",,," << t01 - t00 << endl; @@ -4069,10 +3378,6 @@ Rcpp::List RunBatchR(int nSimuls, int nLandscapes, Rcpp::S4 ParMaster) if(landOK) { // Open all other batch files and read header records -#if VIRTUALECOLOGIST - if(virtEcolFile != "NULL") - ReadVirtEcol(0); -#endif // nSimuls is the total number of lines (simulations) in // the batch and is set in the control function @@ -4141,26 +3446,9 @@ Rcpp::List RunBatchR(int nSimuls, int nLandscapes, Rcpp::S4 ParMaster) rsLog << msgsim << sim.simulation << msgerr << read_error << msgabt << endl; params_ok = false; } -#if VIRTUALECOLOGIST - if(virtEcolFile == "NULL") { - // no virtual ecologist - paramsSim->setVirtEcol(false); - } else { - paramsSim->setVirtEcol(true); - read_error = ReadVirtEcol(1); - if(read_error) { - rsLog << msgsim << sim.simulation << msgerr << read_error << msgabt << endl; - params_ok = false; - } - } -#endif if(params_ok) { simParams sim = paramsSim->getSim(); -#if RS_ABC - - ABCmain(pLandscape); -#else #if RSDEBUG DEBUGLOG << endl @@ -4187,8 +3475,6 @@ Rcpp::List RunBatchR(int nSimuls, int nLandscapes, Rcpp::S4 ParMaster) // << endl; #endif -#endif // RS_ABC - t01 = time(0); rsLog << msgsim << sim.simulation << "," << sim.reps << "," << sim.years << "," << t01 - t00 << endl; @@ -4196,17 +3482,9 @@ Rcpp::List RunBatchR(int nSimuls, int nLandscapes, Rcpp::S4 ParMaster) else { Rcpp::Rcout << endl << "Error in reading parameter file(s)... see RS log." << endl; } -#if VCL - if(stopRun) - break; -#endif } // end of nSimuls for loop // close input files -#if VIRTUALECOLOGIST - if(virtEcolFile != "NULL") - ReadVirtEcol(9); -#endif // if (landtype != 9) { if (pLandscape != NULL) { @@ -4215,10 +3493,6 @@ Rcpp::List RunBatchR(int nSimuls, int nLandscapes, Rcpp::S4 ParMaster) } } // end of landOK condition -#if VCL - if(stopRun) - break; -#endif } // end of nLandscapes loop @@ -4388,12 +3662,15 @@ rasterdata ParseRasterHead(string file) infile >> header >> r.yllcorner; if (header != L"yllcorner" && header != L"YLLCORNER") r.errors++; - infile >> header >> r.cellsize; + double tmpcellsize; + infile >> header >> tmpcellsize; if (header != L"cellsize" && header != L"CELLSIZE") r.errors++; + r.cellsize = (int) tmpcellsize; infile >> header >> inint; if (header != L"NODATA_value" && header != L"NODATA_VALUE") r.errors++; + if (r.errors > 0) r.ok = false; } else { @@ -4704,11 +3981,6 @@ void BatchErrorR(string filename, int line, int option, string fieldname) case 222: Rcpp::Rcout << "Simulation numbers must be sequential integers"; break; -#if SEASONAL - case 223: - Rcpp::Rcout << "Season numbers must be sequential integers"; - break; -#endif case 333: Rcpp::Rcout << "No. of " << fieldname << " columns must equal max. no. of habitats (" << maxNhab << ") and be sequentially numbered starting from 1"; @@ -4806,35 +4078,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 diff --git a/RangeShiftR/src/Rinterface.h b/RangeShiftR/src/Rinterface.h index 46b9738..4771775 100644 --- a/RangeShiftR/src/Rinterface.h +++ b/RangeShiftR/src/Rinterface.h @@ -1,25 +1,25 @@ /*---------------------------------------------------------------------------- - * + * * Copyright (C) 2020 Anne-Kathleen Malchow, Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Damaris Zurell - * + * * This file is part of RangeShiftR. - * + * * RangeShiftR 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 RangeShiftR. If not, see . - * + * --------------------------------------------------------------------------*/ - - + + /*------------------------------------------------------------------------------ RangeShifter v2.0 Rinterface @@ -54,7 +54,6 @@ Author: Anne-Kathleen Malchow, Humboldt University Berlin using namespace std; #include -#include "Version.h" #include "RScore/Parameters.h" #include "RScore/Landscape.h" #include "RScore/Species.h" diff --git a/RangeShiftR/src/Version.cpp b/RangeShiftR/src/Version.cpp deleted file mode 100644 index febcff8..0000000 --- a/RangeShiftR/src/Version.cpp +++ /dev/null @@ -1,35 +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 RS_EMBARCADERO -#pragma hdrstop -#endif - -#include "Version.h" - -#if RS_EMBARCADERO -#pragma package(smart_init) -#endif -//--------------------------------------------------------------------------- - - \ No newline at end of file diff --git a/RangeShiftR/src/Version.h b/RangeShiftR/src/Version.h deleted file mode 100644 index 9f3c0dc..0000000 --- a/RangeShiftR/src/Version.h +++ /dev/null @@ -1,35 +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 . - * - --------------------------------------------------------------------------*/ - -//Last updated: 26 November 2020 by Greta Bocedi - -//--------------------------------------------------------------------------- - -#ifndef VersionH -#define VersionH - -#define RSDEBUG 0 -#define LINUX_CLUSTER 0 -#define RS_RCPP 1 - - -//--------------------------------------------------------------------------- -#endif