• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DEploid-dev / DEploid / 062add94-a5b5-4fd4-a562-e213ecc8da7c

20 Jan 2025 05:00PM UTC coverage: 86.049% (-0.1%) from 86.156%
062add94-a5b5-4fd4-a562-e213ecc8da7c

push

circleci

web-flow
Merge pull request #377 from DEploid-dev/shajoezhu-patch-1

Update config.yml

5545 of 6444 relevant lines covered (86.05%)

5298085.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.82
/src/ibd.cpp
1
/*
2
 * dEploid is used for deconvoluting Plasmodium falciparum genome from
3
 * mix-infected patient sample.
4
 *
5
 * Copyright (C) 2016-2017 University of Oxford
6
 *
7
 * Author: Sha (Joe) Zhu
8
 *
9
 * This file is part of dEploid.
10
 *
11
 * dEploid is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation, either version 3 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 */
25

26
#include <set>
27
#include <vector>
28
#include <iostream>
29
#include <algorithm>
30
#include <cassert>
31
#include <limits>
32
#include "ibd.hpp"
33

34
IBDconfiguration::IBDconfiguration() {}
133✔
35

36

37
void IBDconfiguration::buildIBDconfiguration(size_t k) {
64✔
38
    this->setKstrain(k);
39
    this->enumerateOp();
64✔
40
    this->makePairList();
64✔
41
    this->makePairToEmission();
64✔
42
    this->findUniqueState();
64✔
43
    this->findEffectiveK();
64✔
44
}
64✔
45

46

47
IBDconfiguration::~IBDconfiguration() {}
197✔
48

49

50
void IBDconfiguration::enumerateOp() {
64✔
51
    // #For each configuration, identify which pairs are IBD
52
    this->op = enumerateBinaryMatrixOfK(nchoose2(this->kStrain()));
64✔
53
}
64✔
54

55

56
void IBDconfiguration::makePairList() {
64✔
57
    // #Make a map of pairs to pair value
58
    assert(pairList.size() == 0);
59
    for ( size_t i = 0; i < this->kStrain(); i++ ) {  // 0-indexed
305✔
60
        for ( size_t j = i+1; j < this->kStrain(); j++ ) {
624✔
61
            pairList.push_back(vector <size_t> ({i, j}));
766✔
62
        }
63
    }
64
    assert(pairList.size() == (size_t)nchoose2(this->kStrain()));
65
}
64✔
66

67

68
void IBDconfiguration::makePairToEmission() {
64✔
69
    assert(pairToEmission.size() == 0);
70
    for ( vector<int> tmpOp : op ) {
30,286✔
71
        vector <int> tmpRow = makeTmpRow();
30,222✔
72
        // for ( size_t i = 0 ; i <(*opIt).size(); i++) {
73
            // cout << (*opIt)[i] << " ";
74
        // }
75
        // cout<<endl;
76

77
        vector <size_t> ii = findWhichIsOne(tmpOp);
60,444✔
78
        if (ii.size() > 0) {
30,222✔
79
            vector < vector <size_t> > tmpIBDPairs;
80
            for (size_t j = 0; j < ii.size(); j++) {
179,973✔
81
                tmpIBDPairs.push_back(pairList[ii[j]]);
149,815✔
82
            }
83

84
            int tmpIndex = (tmpIBDPairs.size()-1);
30,158✔
85
            while (tmpIndex >= 0) {
179,973✔
86
                tmpRow[tmpIBDPairs[tmpIndex][0]] =
149,815✔
87
                        tmpRow[tmpIBDPairs[tmpIndex][1]];
149,815✔
88
                tmpIndex--;
149,815✔
89
            }
90
        }
30,158✔
91
        pairToEmission.push_back(tmpRow);
30,222✔
92
    }
93
}
64✔
94

95

96
vector <int> IBDconfiguration::makeTmpRow() {
30,222✔
97
    vector <int> ret(this->kStrain());
30,222✔
98
    for (size_t i =0; i < ret.size(); i++) {
180,634✔
99
        ret[i] = static_cast<int>(i);
150,412✔
100
    }
101
    return ret;
30,222✔
102
}
103

104

105
vector <size_t> IBDconfiguration::findWhichIsOne(vector <int> tmpOp) {
30,222✔
106
    vector <size_t> ret;
107
    for (size_t i = 0; i < tmpOp.size(); i++) {
329,852✔
108
        if (tmpOp[i] == 1) {
299,630✔
109
            ret.push_back(i);
149,815✔
110
        }
111
    }
112
    return ret;
30,222✔
113
}
114

115

116
void IBDconfiguration::findUniqueState() {
64✔
117
    assert(states.size() == 0);
118
    states = unique(this->pairToEmission);
64✔
119
}
64✔
120

121

122
void IBDconfiguration::findEffectiveK() {
64✔
123
    assert(effectiveK.size() == 0);
124
    for (vector<int> state : states) {
1,762✔
125
        set <int> tmpSet(state.begin(), state.end());
1,698✔
126
        effectiveK.push_back(tmpSet.size());
1,698✔
127
    }
128
    assert(effectiveK.size() == states.size());
129
}
64✔
130

131

132
vector <string> IBDconfiguration::getIBDconfigureHeader() {
6✔
133
    vector <string> ret;
134
    for (size_t i = 0; i < this->states.size(); i++) {
34✔
135
        string tmp;
136
        for (size_t j = 0; j < this->states[i].size(); j++) {
119✔
137
            stringstream tmp_ss;
91✔
138
            tmp_ss << this->states[i][j];
91✔
139
            tmp += tmp_ss.str() + ((j < (this->states[i].size()-1)) ? "-":"");
273✔
140
        }
91✔
141
        ret.push_back(tmp);
28✔
142
    }
143
    return ret;
6✔
144
}
×
145

146

147
Hprior::Hprior() {}
126✔
148

149

150
void Hprior::buildHprior(size_t kStrain, const vector <double> &plaf) {
58✔
151
    ibdConfig.buildIBDconfiguration(kStrain);
58✔
152
    this->effectiveK = ibdConfig.effectiveK;
58✔
153
    this->nState_ = 0;
58✔
154
    this->plaf_ = plaf;
58✔
155
    this->setKstrain(kStrain);
156
    this->setnLoci(this->plaf_.size());
157
    vector < vector<int> > hSetBase = enumerateBinaryMatrixOfK(this->kStrain());
58✔
158
    size_t stateI = 0;
58✔
159
    for ( vector<int> state : ibdConfig.states ) {
1,612✔
160
        set <int> stateUnique(state.begin(), state.end());
1,554✔
161
        assert(stateUnique.size() == effectiveK[stateI]);
162
        vector < vector<int> > hSetBaseTmp = hSetBase;
1,554✔
163
        for (size_t j = 0; j < (size_t)this->kStrain(); j++) {
9,054✔
164
            for ( size_t i = 0; i < hSetBase.size(); i++ ) {
237,660✔
165
                hSetBaseTmp[i][j] = hSetBase[i][state[j]];
230,160✔
166
            }
167
        }
168

169
        vector < vector<int> > hSetBaseTmpUnique = unique(hSetBaseTmp);  // uu
1,554✔
170
        size_t sizeOfhSetBaseTmpUnique = hSetBaseTmpUnique.size();
1,554✔
171
        stateIdxFreq.push_back(sizeOfhSetBaseTmpUnique);
1,554✔
172

173
        for (size_t i = 0; i < sizeOfhSetBaseTmpUnique; i++) {
14,542✔
174
            int tmpSum = 0;
175
            for (int uniqSt : stateUnique) {
55,896✔
176
                tmpSum += hSetBaseTmpUnique[i][uniqSt];
42,908✔
177
            }
178
            // sumOfVec(hSetBaseTmpUnique[i]);
179
            int tmpDiff = stateUnique.size()-tmpSum;
12,988✔
180
            vector <double> hPriorTmp(nLoci());
12,988✔
181
            for (size_t site = 0; site < nLoci(); site++) {
137,860✔
182
                hPriorTmp[site] =
124,872✔
183
                        pow(plaf_[site], static_cast<double>(tmpSum))*
124,872✔
184
                        pow((1.0-plaf_[site]), static_cast<double>(tmpDiff));
124,872✔
185
            }
186
            priorProb.push_back(hPriorTmp);
12,988✔
187
            hSet.push_back(hSetBaseTmpUnique[i]);
12,988✔
188

189
            nState_++;
12,988✔
190
            stateIdx.push_back(stateI);
12,988✔
191
        }
192
        stateI++;
1,554✔
193
    }
1,554✔
194
}
58✔
195

196

197
void Hprior::transposePriorProbs() {
49✔
198
    assert(priorProbTrans.size() == 0);
199
    for ( size_t i = 0; i < nLoci(); i++ ) {
3,758✔
200
        vector <double> priorProbTransTmp(nState());
3,709✔
201
        for ( size_t j = 0; j < nState(); j++ ) {
123,451✔
202
            priorProbTransTmp[j] = priorProb[j][i];
119,742✔
203
        }
204
        priorProbTrans.push_back(priorProbTransTmp);
3,709✔
205
    }
206
}
49✔
207

208

209
vector <string> Hprior::getIBDconfigureHeader() {
×
210
    return this->ibdConfig.getIBDconfigureHeader();
×
211
}
212

213

214
Hprior::~Hprior() {}
436✔
215

216

217
vector < vector<int> > unique(const vector < vector<int> > &mat ) {
1,618✔
218
    vector < vector<int> > ret;
219
    ret.push_back(mat[0]);
1,618✔
220
    for (size_t i = 1; i < mat.size(); i++) {
76,710✔
221
        bool aNewState = true;
222
        for (vector<int> state : ret) {
1,142,683✔
223
            if ( twoVectorsAreSame(state, mat[i]) ) {
3,388,845✔
224
                aNewState = false;
225
                break;
226
            }
227
        }
228
        if ( aNewState ) {
229
            ret.push_back(mat[i]);
13,068✔
230
        }
231
    }
232

233
    return ret;
1,618✔
234
}
×
235

236

237
vector < vector<int> > enumerateBinaryMatrixOfK(size_t k) {
124✔
238
    // This function enumerate all possible binary combinations of k elements
239
    int ksq = pow(2, k);
124✔
240
    vector < vector<int> > ret;
241
    for (int i = 0; i < ksq; i++) {
32,470✔
242
        ret.push_back(convertIntToBinary(i, k));
64,692✔
243
    }
244
    return ret;
124✔
245
}
×
246

247

248
vector<int> convertIntToBinary(int x, size_t len) {
32,352✔
249
    vector<int> ret(len);
32,352✔
250
    size_t idx = 0;
251
    while (x) {
315,065✔
252
        ret[idx] = (x&1) ? 1:0;
282,717✔
253
        idx++;
282,717✔
254
        if ( idx > len ) {
282,717✔
255
            throw OutOfVectorSize();
4✔
256
        }
257
        x >>= 1;
282,713✔
258
    }
259
    reverse(ret.begin(), ret.end());
260
    return ret;
32,348✔
261
}
262

263

264
int nchoose2(int n) {
72✔
265
    if ( n < 2 ) {
72✔
266
        throw InvalidInput("Input must be at least 2!");
6✔
267
    }
268
    int ret = n*(n-1)/2;
69✔
269
    return ret;
69✔
270
}
271

272

273
bool twoVectorsAreSame(vector<int> vec1, vector<int> vec2) {
1,129,615✔
274
    if (vec1.size() != vec2.size()) {
1,129,615✔
275
        throw InvalidInput("Input vectors have different length!");
×
276
    }
277

278
    bool ret = true;
279
    for (size_t i = 0; i < vec1.size(); i++) {
1,858,381✔
280
        if (vec1[i] != vec2[i]) {
1,796,357✔
281
            ret = false;
282
            break;
283
        }
284
    }
285
    return ret;
1,129,615✔
286
}
287

288

289
IBDpath::IBDpath() {}
234✔
290

291

292
void IBDpath::init(const DEploidIO &dEploidIO, RandomGenerator* rg) {
49✔
293
    this->ibdRg_ = rg;
49✔
294
    this->setNLoci(dEploidIO.nLoci());
295
    this->setKstrain(dEploidIO.kStrain_.getValue());
296
    this->setTheta(1.0 / static_cast<double>(kStrain()));
49✔
297

298
    this->IBDpathChangeAt = vector <double> (this->nLoci());
49✔
299

300
    // compute likelihood surface
301
    this->makeLlkSurf(dEploidIO.altCount_, dEploidIO.refCount_);
98✔
302

303
    // initialize haplotype prior
304
    this->hprior.buildHprior(kStrain(), dEploidIO.plaf_);
49✔
305
    this->hprior.transposePriorProbs();
49✔
306

307
    this->makeIbdTransProbs();
49✔
308

309
    // initialize fm
310
    this->fSumState = vector <double> (this->hprior.nPattern());
98✔
311

312
    // initialize ibdConfigurePath
313
    this->ibdConfigurePath = vector <size_t> (this->nLoci());
98✔
314
    this->viterbiPath = vector <size_t> (this->nLoci());
98✔
315

316
    // initialize recombination probabilities;
317
    this->ibdRecombProbs = IBDrecombProbs(dEploidIO.position_,
98✔
318
                                          dEploidIO.nLoci());
49✔
319
    this->ibdRecombProbs.computeRecombProbs(
49✔
320
                                        dEploidIO.averageCentimorganDistance(),
321
                                        dEploidIO.parameterG(),
322
                                        dEploidIO.useConstRecomb(),
323
                                        dEploidIO.constRecombProb());
324
    this->currentIBDpathChangeAt = vector <double> (this->nLoci());
49✔
325

326
    this->computeUniqueEffectiveKCount();
49✔
327
}
49✔
328

329

330
void IBDpath::ibdSamplePath(vector <double> statePrior) {
4,203✔
331
    int lociIdx = this->nLoci()-1;
4,203✔
332
    vector <double> tmpProp = fm[lociIdx];
4,203✔
333
    (void)normalizeBySum(tmpProp);
4,203✔
334
    ibdConfigurePath[lociIdx] = sampleIndexGivenProp(this->ibdRg_, tmpProp);
4,203✔
335

336
    assert(this->fm.size() == nLoci());
337
    while (lociIdx > 0) {
1,775,490✔
338
        lociIdx--;
1,771,287✔
339
        vector <double> vNoRecomb = vecProd(
340
        this->ibdTransProbs[this->hprior.stateIdx[ibdConfigurePath[lociIdx+1]]],
1,771,287✔
341
        fm[lociIdx]);
1,771,287✔
342
        assert(vNoRecomb.size() == this->hprior.nState());
343
        vector <double> vRecomb = fm[lociIdx];
1,771,287✔
344
        assert(vRecomb.size() == this->hprior.nState());
345
        vector <double> prop(this->hprior.nState());
1,771,287✔
346
        for (size_t i = 0; i < prop.size(); i++) {
12,579,105✔
347
            prop[i] = vNoRecomb[i]*this->ibdRecombProbs.pNoRec_[lociIdx] +
10,807,818✔
348
                        vRecomb[i]*this->ibdRecombProbs.pRec_[lociIdx] *
10,807,818✔
349
                        statePrior[ibdConfigurePath[lociIdx+1]];
10,807,818✔
350
        }
351
        tmpProp = prop;
1,771,287✔
352
        (void)normalizeBySum(tmpProp);
1,771,287✔
353
        ibdConfigurePath[lociIdx] = sampleIndexGivenProp(this->ibdRg_, tmpProp);
3,542,574✔
354
        assert(ibdConfigurePath[lociIdx] < this->hprior.nState());
355
        assert(ibdConfigurePath[lociIdx] >= 0);
356
    }
357
}
4,203✔
358

359

360
vector <size_t> IBDpath::findWhichIsSomething(vector <size_t> tmpOp,
1,338✔
361
                                              size_t something) {
362
    vector <size_t> ret;
363
    for (size_t i = 0; i < tmpOp.size(); i++) {
570,510✔
364
        if (tmpOp[i] == something) {
569,172✔
365
            ret.push_back(i);
11,278✔
366
        }
367
    }
368
    return ret;
1,338✔
369
}
370

371

372
void IBDpath::buildPathProbabilityForPainting(vector <double> proportion) {
8✔
373
    // vector <double> effectiveKPrior =
374
    //                    this->computeEffectiveKPrior(this->theta());
375
    vector <double> effectiveKPrior = vector <double> (this->hprior.nPattern(),
376
                                                1.0/this->hprior.nPattern());
8✔
377
    vector <double> statePrior = this->computeStatePrior(effectiveKPrior);
8✔
378
    // First building the path likelihood
379
    this->computeIbdPathFwdProb(proportion, statePrior);
16✔
380
    // Reshape Fwd
381
    vector < vector <double>> reshapedFwd = reshapeProbs(this->fm);
8✔
382

383
    this->computeIbdPathBwdProb(proportion, effectiveKPrior, statePrior);
24✔
384
    // Reshape Bwd
385
    vector < vector <double>> reshapedBwd = reshapeProbs(this->bwd);
8✔
386

387
    // Combine Fwd Bwd
388
    this->combineFwdBwd(reshapedFwd, reshapedBwd);
8✔
389
}
16✔
390

391

392

393
void IBDpath::computeIbdPathBwdProb(vector <double> proportion,
9✔
394
                                    vector <double> effectiveKPrior,
395
                                    vector <double> statePrior) {
396
    // # assuming each ibd state has equal probabilities,
397
    // # transform it into ibd configurations
398
    // dout << " start building ibd bwd "<< endl;
399
    vector <double> tmp = vector <double> (hprior.stateIdxFreq.size());
9✔
400
    assert(effectiveKPrior.size() == hprior.stateIdxFreq.size());
401
    for (size_t i = 0; i < tmp.size(); i++) {
93✔
402
        tmp[i] = effectiveKPrior[i] /
84✔
403
                   static_cast<double>(hprior.stateIdxFreq[i]);
84✔
404
    }
405

406
    vector <double> tmpBw = vector <double> (hprior.nState());
9✔
407
    for (size_t j = 0; j < tmpBw.size(); j++) {
615✔
408
        for (size_t i = 0; i < tmp.size(); i++) {
25,806✔
409
            tmpBw[j] += tmp[i] * ibdTransProbs[i][j];
25,200✔
410
        }
411
    }
412

413
    this->bwd.push_back(tmpBw);
9✔
414
    for ( size_t rev_siteI = 1; rev_siteI < this->nLoci(); rev_siteI++ ) {
2,639✔
415
        size_t siteI = this->nLoci()-rev_siteI;
2,630✔
416

417
        vector<double> lk = computeLlkOfStatesAtSiteI(proportion, siteI);
5,260✔
418
        vector <double> bSumState = vector <double> (hprior.nPattern());
2,630✔
419
        for (size_t i = 0; i < bSumState.size(); i++) {
15,864✔
420
            for (size_t j = 0; j < hprior.nState(); j++) {
992,278✔
421
                bSumState[i] += ibdTransProbs[i][j]*this->bwd.back()[j];
979,044✔
422
            }
423
        }
424
        vector <double> vNoRecomb(hprior.nState());
2,630✔
425
        for (size_t i = 0; i < hprior.stateIdx.size(); i++) {
72,914✔
426
            vNoRecomb[i] = bSumState[hprior.stateIdx[i]];
70,284✔
427
        }
428

429
        for (size_t i = 0; i < hprior.nState(); i++) {
72,914✔
430
            tmpBw[i] = 0;
70,284✔
431
            for (size_t j = 0; j < lk.size(); j++) {
6,416,004✔
432
                tmpBw[i] += (lk[j] * bwd.back()[j]) *
6,345,720✔
433
                            this->ibdRecombProbs.pRec_[siteI-1];
6,345,720✔
434
            }
435
            tmpBw[i] *= statePrior[i];
70,284✔
436
            tmpBw[i] += lk[i] * (this->ibdRecombProbs.pNoRec_[siteI-1]) *
70,284✔
437
                        vNoRecomb[i];
438
            tmpBw[i] *= hprior.priorProb[i][siteI];
70,284✔
439
        }
440
        normalizeBySum(tmpBw);
2,630✔
441
        this->bwd.push_back(tmpBw);
2,630✔
442
    }
443
    reverse(bwd.begin(), bwd.end());
9✔
444
}
9✔
445

446

447
void IBDpath::computeIbdPathFwdProb(vector <double> proportion,
4,212✔
448
                                    vector <double> statePrior) {
449
    this->fm.clear();
450
    vector <double> vPrior = vecProd(statePrior,
451
                                     this->hprior.priorProbTrans[0]);
4,212✔
452

453
    vector <double> lk = computeLlkOfStatesAtSiteI(proportion, 0);
4,212✔
454
    this->updateFmAtSiteI(vPrior, lk);
4,212✔
455
    for ( size_t siteI = 1; siteI < this->nLoci(); siteI++ ) {
1,778,129✔
456
        vector <double> vNoRec;
457
        for ( size_t stateIdxTmp : hprior.stateIdx ) {
12,652,019✔
458
            vNoRec.push_back(this->fSumState[stateIdxTmp]);
10,878,102✔
459
        }
460
        for ( size_t i = 0; i < hprior.nState(); i++ ) {
12,652,019✔
461
            vPrior[i] = (vNoRec[i] * this->ibdRecombProbs.pNoRec_[siteI] +
10,878,102✔
462
                         fSum * this->ibdRecombProbs.pRec_[siteI] *
10,878,102✔
463
                         statePrior[i]) *
10,878,102✔
464
                         hprior.priorProbTrans[siteI][i];
465
        }
466

467
        lk = computeLlkOfStatesAtSiteI(proportion, siteI);
3,547,834✔
468
        this->updateFmAtSiteI(vPrior, lk);
1,773,917✔
469

470
        viterbiPath[siteI] = distance(fSumState.begin(),
1,773,917✔
471
                       max_element(fSumState.begin(), fSumState.end()));
472
    }
473
}
4,212✔
474

475

476
void IBDpath::updateFmAtSiteI(const vector <double> & prior,
1,778,129✔
477
                              const vector <double> & llk) {
478
    vector <double> postAtSiteI = vecProd(prior, llk);
1,778,129✔
479
    normalizeBySum(postAtSiteI);
1,778,129✔
480
    this->fm.push_back(postAtSiteI);
1,778,129✔
481
    this->fSum = sumOfVec(postAtSiteI);
1,778,129✔
482
    for (size_t i = 0; i < fSumState.size(); i++) {
5,372,577✔
483
        this->fSumState[i] = 0;
3,594,448✔
484
        for ( size_t j = 0; j < hprior.nState(); j++ ) {
40,132,960✔
485
            this->fSumState[i] += ibdTransProbs[i][j]*postAtSiteI[j];
36,538,512✔
486
        }
487
    }
488
}
1,778,129✔
489

490

491
double IBDpath::bestPath(vector <double> proportion, double err) {
5✔
492
    double sumLLK = 0.0;
493
    for (size_t i = 0; i < nLoci(); i++) {
2,620✔
494
        vector <double> tmp;
495
        for (size_t j = 0; j < fm[i].size(); j++) {
70,577✔
496
            tmp.push_back(exp(log(fm[i][j])+log(bwd[i][j])));
67,962✔
497
        }
498
        normalizeBySum(tmp);
2,615✔
499
        size_t indx = distance(tmp.begin(),
500
                               max_element(tmp.begin(), tmp.end()));
2,615✔
501

502
        vector <int> hSetI = this->hprior.hSet[indx];
2,615✔
503
        double qs = 0;
504
        for (size_t j = 0; j < this->kStrain(); j++) {
9,033✔
505
            qs += static_cast<double>(hSetI[j]) * proportion[j];
6,418✔
506
        }
507
        double qs2 = qs*(1-err) + (1-qs)*err;
2,615✔
508

509
        if ( (qs > 0) & (qs < 1) ) {
2,615✔
510
            sumLLK += logBetaPdf(qs2, this->llkSurf[i][0], this->llkSurf[i][1]);
1,211✔
511
        }
512
    }
513
    return sumLLK;
5✔
514
}
515

516

517
double IBDpath::findViterbiPath(vector <double> proportion, double err) {
×
518
    vector <double> effectiveKPrior = vector <double> (this->hprior.nPattern(),
519
                                                1.0/this->hprior.nPattern());
×
520
    vector <double> statePrior = this->computeStatePrior(effectiveKPrior);
×
521
    // First building the path likelihood
522
    this->computeIbdPathFwdProb(proportion, statePrior);
×
523

524
    double sumLLK = 0.0;
525
    for (size_t i = 0; i < nLoci(); i++) {
×
526
        vector <double> tmp;
527
        for (size_t j = 0; j < fm[i].size(); j++) {
×
528
            tmp.push_back(exp(log(fm[i][j])));
×
529
        }
530
        normalizeBySum(tmp);
×
531
        size_t indx = distance(tmp.begin(),
532
                               max_element(tmp.begin(), tmp.end()));
×
533

534
        vector <int> hSetI = this->hprior.hSet[indx];
×
535
        double qs = 0;
536
        for (size_t j = 0; j < this->kStrain(); j++) {
×
537
            qs += static_cast<double>(hSetI[j]) * proportion[j];
×
538
        }
539
        double qs2 = qs*(1-err) + (1-qs)*err;
×
540

541
        if ( (qs > 0) & (qs < 1) ) {
×
542
            sumLLK += logBetaPdf(qs2, this->llkSurf[i][0], this->llkSurf[i][1]);
×
543
        }
544
    }
545
    return sumLLK;
×
546
}
547

548

549
void IBDpath::combineFwdBwd(const vector < vector <double>> &reshapedFwd,
8✔
550
                            const vector < vector <double>> &reshapedBwd) {
551
    for (size_t i = 0; i < nLoci(); i++) {
2,641✔
552
        vector <double> tmp;
553
        for (size_t j = 0; j < reshapedFwd[i].size(); j++) {
15,939✔
554
            tmp.push_back(exp(log(reshapedFwd[i][j])+log(reshapedBwd[i][j])));
13,306✔
555
        }
556
        normalizeBySum(tmp);
2,633✔
557
        fwdbwd.push_back(tmp);
2,633✔
558
    }
559
}
8✔
560

561

562
void IBDpath::makeIbdTransProbs() {
49✔
563
    assert(this->ibdTransProbs.size() == 0);
564
    for ( size_t i = 0; i < hprior.nPattern(); i++ ) {
1,387✔
565
        vector <double> transProbRow(hprior.nState());
1,338✔
566
        vector <size_t> wi = findWhichIsSomething(hprior.stateIdx, i);
2,676✔
567
        for (size_t wii : wi) {
12,616✔
568
            transProbRow[wii] = 1;
11,278✔
569
        }
570
        ibdTransProbs.push_back(transProbRow);
1,338✔
571
    }
572
}
49✔
573

574

575
vector <string> IBDpath::getIBDprobsHeader() {
6✔
576
    return this->hprior.getIBDconfigureHeader();
6✔
577
}
578

579

580
vector < vector <double> > IBDpath::reshapeProbs(
18✔
581
        const vector < vector <double> >& probs) {
582
    assert(this->nLoci() == probs.size());
583
    vector < vector <double> > ret;
584
    for (size_t siteIndex = 0; siteIndex < this->nLoci(); siteIndex++) {
5,296✔
585
        size_t previousStateIdx = 0;
586
        vector <double> tmpRow;
587
        double cumProb = 0;
5,278✔
588
        for (size_t prob_ij = 0; prob_ij < probs[siteIndex].size(); prob_ij++) {
147,058✔
589
            cumProb += probs[siteIndex][prob_ij];
141,780✔
590
            if (previousStateIdx != this->hprior.stateIdx[prob_ij]) {
141,780✔
591
                cumProb -= probs[siteIndex][prob_ij];
21,358✔
592
                previousStateIdx++;
21,358✔
593
                tmpRow.push_back(cumProb);
21,358✔
594
                cumProb = probs[siteIndex][prob_ij];
21,358✔
595
            }
596
        }
597
        tmpRow.push_back(cumProb);
5,278✔
598
        normalizeBySum(tmpRow);
5,278✔
599
        ret.push_back(tmpRow);
5,278✔
600
    }
601
    return ret;
18✔
602
}
×
603

604

605
vector <double> IBDpath::computeEffectiveKPrior(double theta) {
4,203✔
606
    // #Calculate state prior given theta (theta is prob IBD)
607
    vector <double> pr0(this->kStrain());
4,203✔
608
    for (int i = 0; i < static_cast<int>(pr0.size()); i++) {
13,212✔
609
        pr0[i] = binomialPdf(i, static_cast<int>(this->kStrain()-1), theta);
9,009✔
610
    }
611
    vector <double> effectiveKPrior;
612
    for (size_t effectiveKtmp : this->hprior.effectiveK) {
22,659✔
613
        int effectiveKidx = effectiveKtmp-1;
18,456✔
614
        assert(effectiveKidx >= 0);
615
        assert(effectiveKidx < static_cast<int>(this->kStrain()));
616
        effectiveKPrior.push_back(
617
            pr0[effectiveKidx]/uniqueEffectiveKCount[effectiveKidx]);
18,456✔
618
    }
619
    return effectiveKPrior;
4,203✔
620
}
621

622

623
vector <double> IBDpath::computeStatePrior(vector <double> effectiveKPrior) {
4,214✔
624
    vector <double> ret;
625
    for (size_t stateIdxTmp : this->hprior.stateIdx) {
120,114✔
626
        ret.push_back(effectiveKPrior[stateIdxTmp]);
115,900✔
627
    }
628
    return ret;
4,214✔
629
}
630

631

632
void IBDpath::computeAndUpdateTheta() {
4,203✔
633
    vector <size_t> obsState;
634
    size_t previousState = 0;
635
    size_t atSiteI = 0;
636
    for (size_t a : this->ibdConfigurePath) {
1,779,693✔
637
        if (a != previousState) {
1,775,490✔
638
            obsState.push_back(a);
848,474✔
639
        }
640
        if (this->hprior.stateIdx[a] != this->hprior.stateIdx[previousState]) {
1,775,490✔
641
            this->IBDpathChangeAt[atSiteI] += 1.0;
176,294✔
642
            this->currentIBDpathChangeAt[atSiteI] = 1.0;
176,294✔
643
        } else {
644
            this->currentIBDpathChangeAt[atSiteI] = 0.0;
1,599,196✔
645
        }
646
        previousState = a;
647
        atSiteI++;
1,775,490✔
648
    }
649

650
    size_t sumOfKeffStates = 0;
651
    size_t sccs = 0;
652
    for (size_t obs : obsState) {
852,677✔
653
        sumOfKeffStates += this->hprior.effectiveK[obs] - 1;
848,474✔
654
        sccs += this->kStrain() - this->hprior.effectiveK[obs];
848,474✔
655
    }
656
    this->setTheta(rBeta(sccs+1.0, sumOfKeffStates+1.0, this->ibdRg_));
4,203✔
657
}
4,203✔
658

659

660
void IBDpath::computeUniqueEffectiveKCount() {
50✔
661
    this->uniqueEffectiveKCount = vector <int> (this->kStrain());
100✔
662
    for (size_t effectiveKtmp : this->hprior.effectiveK) {
1,440✔
663
        int effectiveKidx = effectiveKtmp-1;
1,390✔
664
        assert(effectiveKidx >= 0);
665
        this->uniqueEffectiveKCount[effectiveKidx]++;
1,390✔
666
    }
667
}
50✔
668

669

670
void IBDpath::makeLlkSurf(vector <double> altCount, vector <double> refCount,
49✔
671
                          double scalingConst, double err, size_t gridSize) {
672
    double pGridSpacing = 1.0 / static_cast<double>(gridSize+1);
49✔
673
    vector <double> pGrid;
674
    pGrid.push_back(pGridSpacing);
49✔
675
    for (size_t i = 1; i < gridSize; i++) {
4,851✔
676
        pGrid.push_back(pGrid.back() + pGridSpacing);
4,802✔
677
    }
678
    assert(pGrid.size() == gridSize);
679

680
    assert(llkSurf.size() == 0);
681

682
    for (size_t i = 0 ; i < altCount.size(); i++) {
3,758✔
683
        double alt = altCount[i];
3,709✔
684
        double ref = refCount[i];
3,709✔
685

686
        vector <double> ll;
687
        for ( double unadjustedP : pGrid ) {
370,900✔
688
            ll.push_back(log(calcSiteLikelihood(ref,
367,191✔
689
                                                alt,
690
                                                unadjustedP,
691
                                                err,
692
                                                scalingConst)));
693
        }
694

695
        double llmax = max_value(ll);
696
        vector <double> ln;
697
        for ( double lltmp : ll ) {
370,900✔
698
            ln.push_back(exp(lltmp-llmax));
367,191✔
699
        }
700

701
        double lnSum = sumOfVec(ln);
702
        for (size_t i = 0; i < ln.size(); i++) {
370,900✔
703
            ln[i] = ln[i]/lnSum;
367,191✔
704
        }
705

706
        vector <double> tmpVec1 = vecProd(ln, pGrid);
3,709✔
707
        double mn = sumOfVec(tmpVec1);
708
        vector <double> pGridSq = vecProd(pGrid, pGrid);
3,709✔
709
        vector <double> tmpVec2 = vecProd(ln, pGridSq);
3,709✔
710
        double vr = sumOfVec(tmpVec2) - mn*mn;
3,709✔
711

712
        double comm = (mn*(1.0-mn)/vr-1.0);
3,709✔
713
        llkSurf.push_back(vector <double> {mn*comm, (1-mn)*comm});
7,418✔
714
    }
715
    assert(llkSurf.size() == this->nLoci());
716
}
49✔
717

718

719
vector <double> IBDpath::computeLlkOfStatesAtSiteI(vector<double> proportion,
1,780,759✔
720
                                                   size_t siteI, double err ) {
721
    vector <double> llks;
722
    for ( vector <int> hSetI : this->hprior.hSet ) {
12,845,017✔
723
        double qs = 0;
724
        for ( size_t j = 0; j < this->kStrain() ; j++ ) {
34,252,440✔
725
            qs += static_cast<double>(hSetI[j]) * proportion[j];
23,188,182✔
726
        }
727
        double qs2 = qs*(1-err) + (1-qs)*err;
11,064,258✔
728
        llks.push_back(
729
            logBetaPdf(qs2, this->llkSurf[siteI][0], this->llkSurf[siteI][1]));
11,064,258✔
730
    }
731

732
    double maxllk = max_value(llks);
733
    vector <double> ret;
734
    for ( double llk : llks ) {
12,845,017✔
735
        double normalized = exp(llk-maxllk);
11,064,258✔
736
        if ( normalized == 0 ) {
11,064,258✔
737
            // normalized = std::numeric_limits< double >::min();
738
            normalized = 2.22507e-308;
256,672✔
739
        }
740
        ret.push_back(normalized);
11,064,258✔
741
    }
742
    return ret;
1,780,759✔
743
}
744

745

746
IBDpath::~IBDpath() {}
468✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc