Skip to content

Commit

Permalink
per locus fst are computed separately, fix #72
Browse files Browse the repository at this point in the history
  • Loading branch information
TheoPannetier committed Sep 3, 2024
1 parent 62a7d5c commit 9fabc91
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 2 deletions.
7 changes: 5 additions & 2 deletions NeutralStatsManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ void NeutralStatsManager::calculateFstatWC(set<int> const& patchList, const int
inverseNbar = 1.0 / nBarMinusOne;
inverseNtotal = 1.0 / totalSampleSize;

double var;
double var, intermediateTerm;
double s2, pBar, hBar;
double s2Denom = (nbPops - 1) * nBar;
double rTerm = static_cast<double>(nbPops - 1) / nbPops;
Expand All @@ -320,8 +320,11 @@ void NeutralStatsManager::calculateFstatWC(set<int> const& patchList, const int
double numFst = 0.0, numFis = 0.0, numFit = 0.0;
double denomFst = 0.0, denomFis = 0.0, denomFit = 0.0;

double a_l = 0, b_l = 0, c_l = 0, intermediateTerm;
for (int l = 0; l < nLoci; ++l) {

// Sums of a_u, b_u, c_u for all alleles u at locus l
double a_l = 0, b_l = 0, c_l = 0;

for (int u = 0; u < nAlleles; ++u) {

s2 = hBar = 0;
Expand Down
87 changes: 87 additions & 0 deletions unit_tests/testNeutralStats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,93 @@ void testNeutralStats() {
);
assert(pNeutralStatistics->getFstWC() == refWeirCockerhamDiploidFst);
}

// Multi-locus case
// First locus has no variation between individuals, all heterozygotes (Fst = 0)
// Second locus has different fixed alleles between both populations (Fst = 1)
{
// Patch setup
const int nbPatches = 2;
const int nbIndsPerPop = 10;
// Genetic setup
const int genomeSz = 3;
const bool isDiploid{ true };
const set<int> genePositions = { 0, 2 }; // position 1 is arbitrarily empty
const float maxAlleleVal = 1;
unsigned char alleleValPopA = char(0);
unsigned char alleleValPopB = char(1);
map<int, vector<unsigned char>> genotypePop1;
map<int, vector<unsigned char>> genotypePop2;
// First locus: all heterozygotes, same genotype
genotypePop1.emplace(0, vector<unsigned char>{alleleValPopA, alleleValPopB});
genotypePop2.emplace(0, vector<unsigned char>{alleleValPopA, alleleValPopB});
// Second locus: different fixed alleles
genotypePop1.emplace(2, vector<unsigned char>{alleleValPopA, alleleValPopA});
genotypePop2.emplace(2, vector<unsigned char>{alleleValPopB, alleleValPopB});

// Create two-patches landscape
Landscape* pLandscape = new Landscape;
vector<Patch*> patches(nbPatches);
vector<Cell*> cells(nbPatches);
set<int> patchList;
for (int i = 0; i < nbPatches; i++) {
patches[i] = pLandscape->newPatch(i);
cells[i] = new Cell(0, 0, (intptr)patches[i], 0);
patches[i]->addCell(cells[i], 0, 0);
patchList.insert(patches[i]->getPatchNum());
}
const string indSampling = "all";
const set<int> stgToSample = { 1 };

// Create species trait structure
Species* pSpecies = new Species();
pSpecies->setDemogr(createDefaultDiploidDemogrParams());
pSpecies->setGeneticParameters(
set<int>{genomeSz - 1}, // single chromosome
genomeSz,
0.0, // no recombination
patchList,
indSampling,
stgToSample,
1
);
const int nbLoci = genePositions.size();
SpeciesTrait* spTr = createTestNeutralSpTrait(maxAlleleVal, genePositions, isDiploid);
pSpecies->addTrait(TraitType::NEUTRAL, *spTr);

// Initialise populations
const int indStg = 1;
for (int p = 0; p < patches.size(); p++) {
Population* pPop = new Population(pSpecies, patches[p], 0, 1);
// create individuals and add to pop
for (int i = 0; i < nbIndsPerPop; i++) {
Individual* pInd = new Individual(cells[p], patches[p], indStg, 0, 0, 0.0, false, 1);
pInd->setUpGenes(pSpecies, 1.0);
pInd->overrideGenotype(NEUTRAL, p == 0 ? genotypePop1 : genotypePop2);
pPop->recruit(pInd);
}
pPop->sampleIndsWithoutReplacement(indSampling, { indStg });
}

// Compute F-stats
auto pNeutralStatistics = make_unique<NeutralStatsManager>(nbPatches, nbLoci);
pNeutralStatistics->updateAllNeutralTables(
pSpecies,
pLandscape,
patchList
);
const int maxNbNeutralAlleles = static_cast<int>(maxAlleleVal) + 1;
pNeutralStatistics->calculateFstatWC(
patchList,
nbIndsPerPop * patchList.size(),
nbLoci,
maxNbNeutralAlleles,
pSpecies,
pLandscape
);
assert(pNeutralStatistics->getPerLocusFst(0) == 0.0);
assert(pNeutralStatistics->getPerLocusFst(1) == 1.0);
}
}

#endif // RSDEBUG

0 comments on commit 9fabc91

Please sign in to comment.