-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNeutralStatsManager.h
More file actions
195 lines (145 loc) · 7.04 KB
/
Copy pathNeutralStatsManager.h
File metadata and controls
195 lines (145 loc) · 7.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#ifndef NEUTRALSTATSH
#define NEUTRALSTATSH
#include "Species.h"
#include "Landscape.h"
/*----------------------------------------------------------------------------
*
* Copyright (C) 2026 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, Roslyn Henry, Théo Pannetier, Jette Wolff, Damaris Zurell
*
* This file is part of RangeShifter.
*
* RangeShifter is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RangeShifter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RangeShifter. If not, see <https://www.gnu.org/licenses/>.
*
* File Created by Roslyn Henry March 2023. Code adapted from NEMO (https://nemo2.sourceforge.io/)
--------------------------------------------------------------------------*/
using namespace std;
// Patch * patch matrix to store pairwise Fst calculations
/** Creates an array of doubles of size = rows*cols, taken from NEMO **/
struct PatchMatrix
{
public:
PatchMatrix(unsigned int nRows = 0, unsigned int nCols = 0) :
rows{ nRows },
cols{ nCols },
nbCells{nCols * nRows} {
value.resize(nbCells);
};
// Get value at specified position
double get(unsigned int i, unsigned int j) {
if (i >= cols || j >= rows)
throw runtime_error("PatchMatrix::get() out of range!\n");
else return value[i * cols + j];
}
int getNbCells() { return nbCells; };
/** Sets element at row i and column j to value val **/
void set(unsigned int i, unsigned int j, double val) {
if (i >= cols || j >= rows)
throw runtime_error("PatchMatrix::set() out of range!\n");
else value[i * cols + j] = val;
}
/** Assigns a value to all elements of the matrix. */
void setAll(double val)
{
for (unsigned int i = 0; i < nbCells; ++i) value[i] = val;
}
private:
unsigned int rows, cols, nbCells;
vector<double> value;
};
// Counts of NEUTRAL allele occurrences in populations
// for neutral statistics calculations
struct NeutralCountsTable {
public:
NeutralCountsTable(int maxNbNeutralAlleles) : alleleTallies(maxNbNeutralAlleles), alleleFrequencies(maxNbNeutralAlleles), alleleHeterozygoteTallies(maxNbNeutralAlleles) {};
void reset() {
fill(alleleTallies.begin(), alleleTallies.end(), 0); fill(alleleFrequencies.begin(), alleleFrequencies.end(), 0);
fill(alleleHeterozygoteTallies.begin(), alleleHeterozygoteTallies.end(), 0);
}
// Getters
int getTally(int whichAllele) { return alleleTallies[whichAllele]; };
double getFrequency(int whichAllele) { return alleleFrequencies[whichAllele]; };
int getHeteroTally(int whichAllele) {
return alleleHeterozygoteTallies[whichAllele];
};
// Setters / increments
void incrementTally(int whichAllele) { alleleTallies[whichAllele]++; };
void incrementTallyBy(int count, int whichAllele) { this->alleleTallies[whichAllele] += count; }
void incrementHeteroTally(int whichAllele) { this->alleleHeterozygoteTallies[whichAllele]++; }
void setFrequencies(int sampleSize) {
for (int i = 0; i < alleleFrequencies.size(); i++) {
alleleFrequencies[i] = sampleSize > 0 ? static_cast<double>(alleleTallies[i]) / sampleSize : 0.0;
}
};
private:
// Tallies, one for each possible allele (so absolute max size is 255)
vector<int> alleleTallies; // number of occurrences of each allele in pop
vector<double> alleleFrequencies; // frequency of each allele in pop
vector<int> alleleHeterozygoteTallies; // nb of times each allele is found in a heterozygous pair
};
// Handles calculations of neutral statistics
class NeutralStatsManager {
public:
NeutralStatsManager(const int& nbSampledPatches, const int nLoci);
// Count alleles and their frequencies in all pops and community
void updateAllNeutralTables(Species* pSpecies, Landscape* pLandscape, set<int> const& patchList);
void resetCommNeutralTables();
void calcAllelicDiversityMetrics(set<int> const& patchList, const int nInds, Species* pSpecies, Landscape* pLandscape);
// Heterozygosity calculations
void calculateHo(set<int> const& patchList, const int totalNbSampledInds, const int nbrLoci, Species* pSpecies, Landscape* pLandscape);
void calculateHs(set<int> const& patchList, const int nbrLoci, Species* pSpecies, Landscape* pLandscape);
void calculateHt(Species* pSpecies, Landscape* pLandscape, const int nLoci, const int nAlleles);
void calculatePerLocusHo(set<int> const& patchList, const int totalNbSampledInds, const int nbrLoci, Species* pSpecies, Landscape* pLandscape);
// F-stats calculations
void calculateFstatWC(set<int> const& patchList, const int nbSampledIndsInComm, const int nLoci, const int nAlleles, Species* pSpecies, Landscape* pLandscape, bool isPairwise);
void calculatePairwiseFst(set<int> const& patchList, const int nLoci, const int nAlleles, Species* pSpecies, Landscape* pLandscape);
//void calcPairwiseWeightedFst(set<int> const& patchList, const int nInds, const int nLoci, Species* pSpecies, Landscape* pLandscape);
// Getters
int getNbPopulatedSampledPatches() const { return nbExtantPops; }
int getTotalNbSampledInds() const { return totalNbSampledInds; }
double getMeanNbAllPerLocusPerPatch() const { return meanNbAllelesPerLocusPerPatch; }
double getMeanNbAllPerLocus() const { return meanNbAllelesPerLocus; }
double getMeanFixdAllelesPerPatch() const { return meanNbFixedLociPerPatch; }
double getTotalFixdAlleles() const { return meanFixedLoci; }
double getHo() const { return ho; }
double getHs() const { return hs; }
double getHt() const { return ht; }
double getPerLocusHo(int i) const { return perLocusHo[i]; }
double getFstWC() const { return fst; }
double getFisWC() const { return fis; }
double getFitWC() const { return fit; }
//double getWeightedFst() { return weightedFst; }
double getPerLocusFst(int i) const { return perLocusFst[i]; }
double getPerLocusFis(int i) const { return perLocusFis[i]; }
double getPerLocusFit(int i) const { return perLocusFit[i]; }
double getPairwiseFst(int i, int j) { return pairwiseFstMatrix.get(i, j); }
private:
int nbExtantPops, totalNbSampledInds;
vector<NeutralCountsTable> commNeutralCountTables; // community-level tallies of allele counts and freqs
double meanNbAllelesPerLocusPerPatch, meanNbAllelesPerLocus;
double meanNbFixedLociPerPatch, meanFixedLoci;
double ho; // observed heterozygosity
double hs; // expected population-level heterozygosity
double ht; // expected community-level heterozygosity
vector<double> perLocusHo; // Per-locus observed heterozygosity
// F-statistics
// Weir & Cockerham (1984) F-stat estimates.
double fst, fis, fit;
// Weir & Hill (2002) F-stat estimates
double weightedFst;
// Per-locus F-stats (Weir & Cockerham).
vector<double> perLocusFst, perLocusFis, perLocusFit;
// Pairwise Fst matrix
PatchMatrix pairwiseFstMatrix;
};
#endif