Program Listing for File SpatialTree.h¶
↰ Return to documentation for file (necsim/SpatialTree.h
)
// This file is part of necsim project which is released under MIT license.
// See file **LICENSE.txt** or visit https://opensource.org/licenses/MIT) for full license details.
//
#ifndef SPATIALTREE_H
#define SPATIALTREE_H
#include <cstdio>
#include <fstream>
#include <vector>
#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <ctime>
#include <sqlite3.h>
#ifndef WIN_INSTALL
#include <unistd.h>
#endif
#include <algorithm>
#include <stdexcept>
#include <memory>
// extra boost include - this requires the installation of boost on the system
// note that this requires compilation with the -lboost_filesystem and -lboost_system linkers.
#include <boost/filesystem.hpp>
// include fast-csv-parser by Ben Strasser (available from https://github.com/ben-strasser/fast-cpp-csv-parser)
// for fast file reading
#ifdef use_csv
#include "fast-cpp-csv-parser/csv.h"
#endif
//#ifndef sql_ram
//#define sql_ram
//#endif
// other includes for required files
#include "Tree.h"
#include "Matrix.h"
#include "RNGController.h"
#include "SimParameters.h"
#include "DataPoint.h"
#include "TreeNode.h"
#include "SpeciesList.h"
#include "Landscape.h"
#include "Community.h"
#include "setup.h"
#include "DispersalCoordinator.h"
#include "ActivityMap.h"
#include "Logging.h"
#include "GillespieCalculator.h"
using namespace std;
namespace necsim
{
class SpatialTree : public virtual Tree
{
protected:
// Our dispersal coordinator for getting dispersal distances and managing calls from the landscape
DispersalCoordinator dispersal_coordinator;
// Death probability values across the landscape
shared_ptr<ActivityMap> death_map;
// Reproduction probability values across the landscape
shared_ptr<ActivityMap> reproduction_map;
// A lineage_indices of new variables which will contain the relevant information for maps and grids.
// strings containing the file names to be imported.
string fine_map_input, coarse_map_input;
string historical_fine_map_input, historical_coarse_map_input;
// Landscape object containing both the coarse and fine maps for checking whether or not there is habitat at a
// particular location.
shared_ptr<Landscape> landscape;
// An indexing spatial positioning of the lineages
Matrix<SpeciesList> grid;
unsigned long desired_specnum;
// contains the DataMask for where we should start lineages from.
DataMask samplegrid;
// The gillespie variables
double gillespie_threshold;
// Matrix of all the probabilities at every location in the map.
Matrix<GillespieProbability> probabilities;
// Vector used for holding the priority queue as a binary heap
vector<GillespieHeapNode> heap;
// Index to heap position, or UNUSED if cell is not used.
Matrix<unsigned long> cellToHeapPositions;
// matrix of self-dispersal probabilities;
Matrix<double> self_dispersal_probabilities;
// Total number of individuals present in the simulated world
unsigned long global_individuals;
// Mean death rate across the simulated world
double summed_death_rate;
// Defines a cell that is unused
static const unsigned long UNUSED = static_cast<unsigned long>(-1);
#ifdef DEBUG
unsigned long gillespie_speciation_events{0};
pair<EventType, CellEventType> last_event;
#endif // DEBUG
public:
SpatialTree() : Tree(), dispersal_coordinator(), death_map(make_shared<ActivityMap>()),
reproduction_map(make_shared<ActivityMap>()), fine_map_input("none"), coarse_map_input("none"),
historical_fine_map_input("none"), historical_coarse_map_input("none"),
landscape(make_shared<Landscape>()), grid(), desired_specnum(1), samplegrid(),
gillespie_threshold(0.0), probabilities(), heap(), cellToHeapPositions(),
self_dispersal_probabilities(), global_individuals(0), summed_death_rate(1.0)
{
}
~SpatialTree() override = default;
void runFileChecks() override;
void checkFolders();
void setParameters() override;
// Imports the maps using the variables stored in the class. This function must be run after the set_mapvars() in
// order to function correctly.
void importMaps();
void importActivityMaps();
unsigned long getInitialCount() override;
void setupDispersalCoordinator();
void setup() override;
unsigned long fillObjects(const unsigned long &initial_count) override;
unsigned long getIndividualsSampled(const long &x,
const long &y,
const long &x_wrap,
const long &y_wrap,
const double ¤t_gen);
unsigned long getNumberLineagesAtLocation(const MapLocation &location) const;
unsigned long getNumberIndividualsAtLocation(const MapLocation &location) const;
void removeOldPosition(const unsigned long &chosen) override;
void calcMove();
long double calcMinMax(const unsigned long ¤t);
void calcNewPos();
void calcWrappedCoalescence(const unsigned long &nwrap);
void switchPositions(const unsigned long &chosen) override;
void calcNextStep() override;
unsigned long estSpecnum();
#ifdef historical_mode
void historicalStepChecks();
#endif
void incrementGeneration() override;
void updateStepCoalescenceVariables() override;
void recordLineagePosition();
void addLineages(double generation_in) override;
string simulationParametersSqlInsertion() override;
void simPause() override;
void dumpMap(shared_ptr<ofstream> out);
void dumpGrid(shared_ptr<ofstream> out);
void simResume() override;
void loadGridSave(shared_ptr<ifstream> in1);
void loadMapSave(shared_ptr<ifstream> in1);
void verifyActivityMaps();
void addWrappedLineage(unsigned long numstart, long x, long y);
unsigned long countCellExpansion(const long &x,
const long &y,
const long &xwrap,
const long &ywrap,
const double &generationin,
vector<TreeNode> &data_added);
void expandCell(long x,
long y,
long x_wrap,
long y_wrap,
double generation_in,
unsigned long add,
vector<TreeNode> &data_added,
vector<DataPoint> &active_added);
void addGillespie(const double &g_threshold) override;
bool runSimulationGillespie() override;
void runGillespieLoop();
void setupGillespie();
void setupGillespieLineages();
void setupGillespieMaps();
Cell getCellOfMapLocation(const MapLocation &location);
void findLocations();
void checkMapEvents();
void checkSampleEvents();
void gillespieCellEvent(GillespieProbability &origin);
void gillespieUpdateMap();
void gillespieSampleIndividuals();
void gillespieCoalescenceEvent(GillespieProbability &origin);
void gillespieDispersalEvent(GillespieProbability &origin);
void gillespieSpeciationEvent(GillespieProbability &origin);
void gillespieLocationRemainingCheck(GillespieProbability &location);
template<typename T> double getLocalDeathRate(const T &location) const;
template<typename T> double getLocalSelfDispersalRate(const T &location) const;
void clearGillespieObjects();
void setStepVariable(const necsim::GillespieProbability &origin,
const unsigned long &chosen,
const unsigned long &coal_chosen);
// void updateHeapOrigin(GillespieProbability &origin)
// {
// // If cell is still inhabited
// {
// Cell pos = convertMapLocationToCell(origin.getMapLocation());
//
// // Update probability and times of origin
// updateInhabitedCellOnHeap(pos);
//
// }
// // Else
// {
// std::pop_heap(heap.begin(), heap.end());
// heap.pop_back();
// }
// }
void gillespieUpdateGeneration(const unsigned long &lineage);
// void updateHeapDestination(GillespieProbability &destination)
// {
// // If dispersal to other cell
//
// Cell pos = convertMapLocationToCell(destination.getMapLocation());
//
// // If cell is already inhabited
// {
// // Update probability and times of destination
// updateInhabitedCellOnHeap(pos);
// }
// // Else
// {
// heap.emplace_back(GillespieHeapNode(pos,
// (destination.calcTimeToNextEvent(summed_death_rate,
// getNumberIndividualsAtLocation(
// destination
// .getMapLocation()),
// global_individuals) + generation),
// &cellToHeapPositions.get(pos.y, pos.x)));
// std::push_heap(heap.begin(), heap.end());
// }
// }
void updateCellCoalescenceProbability(GillespieProbability &origin, const unsigned long &n);
void updateInhabitedCellOnHeap(const Cell &pos);
void updateAllProbabilities();
void removeHeapTop();
template<typename T> Cell convertMapLocationToCell(const T &location) const
{
unsigned long x = landscape->convertSampleXToFineX(location.x, location.xwrap);
unsigned long y = landscape->convertSampleXToFineX(location.y, location.ywrap);
return Cell(x, y);
}
void createEventList();
void sortEvents();
template<bool restoreHeap = true> void addNewEvent(const unsigned long &x, const unsigned long &y);
void addLocation(const MapLocation &location);
void setupGillespieProbability(GillespieProbability &gp, const MapLocation &location);
void fullSetupGillespieProbability(GillespieProbability &gp, const MapLocation &location);
double calculateCoalescenceProbability(const MapLocation &location) const;
template<typename T> double convertGlobalGenerationsToLocalGenerations(const T &location, const double g) const
{
return g * getLocalDeathRate(location) / (summed_death_rate / (double) global_individuals);
}
unsigned long selectRandomLineage(const MapLocation &location) const;
pair<unsigned long, unsigned long> selectTwoRandomLineages(const MapLocation &location) const;
vector<unsigned long> detectLineages(const MapLocation &location) const;
void assignNonSpeciationProbability(const unsigned long chosen);
#ifdef DEBUG
void validateHeap();
void debugDispersal();
void validateLocations();
void validateLineages() override;
void debugAddingLineage(unsigned long numstart, long x, long y);
void runChecks(const unsigned long &chosen, const unsigned long &coalchosen) override;
void validateGillespie() const;
void validateSpeciationEvents() const;
unsigned long countSpeciationEvents() const;
void checkNoSpeciation(const unsigned long &chosen) const;
#endif
};
};
#endif // SPATIALTREE_H