private void setGprobs(DuoBaumLevel level, double[] gtProbsA, double[] gtProbsB) { int m = level.marker(); int nGenotypes = gl.marker(m).nGenotypes(); int base = gl.markers().sumGenotypes(m); for (int j = 0; j < nGenotypes; ++j) { gtProbsA[base + j] = level.gtProbsA(j); gtProbsB[base + j] = level.gtProbsB(j); } }
private int initialRandomState(DuoBaumLevel level) { double d = random.nextDouble(); double sum = 0.0; for (int j = 0, n = level.size(); j < n; ++j) { sum += level.forwardValue(j); if (d <= sum) { return j; } } assert false; return level.size() - 1; // error in finite bit arithmetic encountered }
/** * Returns a list of {@code this.nCopies()} sampled haplotype pairs for the specified parent * ({@code sampleA}) and offspring ({@code sampleB}). Haplotype pairs are sampled conditional on * the HMM with transition probabilities determined by {@code this.dag()} and emission * probabilities determined by {@code this.gl()}. Posterior genotype probabilities for the parent * and offspring are written to {@code gtProbsA} and {@code gtProbsB} respectively. The posterior * probability of the {@code j}-th genotype for the {@code k}-th marker is stored at index {@code * gl.markers().sumGenotypes(k) + j} in the {@code gtProbsA} and {@code gtProbsB} arrays. The * contract for this method is unspecified if no parent haplotype pairs or no offspring haplotype * pairs are consistent with the HMM. * * @param sampleA the sample index of the parent. * @param sampleB the sample index of the offspring. * @param gtProbsA an array to which posterior genotype probabilities for the parent will be * written. * @param gtProbsB an array to which posterior genotype probabilities for the offspring will be * written. * @return a list of {@code this.nCopies()} sampled haplotype pairs for the specified individuals. * @throws IndexOutOfBoundsException if {@code sampleA<0 || sampleA>=this.gl().nSamples()} * @throws IndexOutOfBoundsException if {@code sampleB<0 || sampleB>=this.gl().nSamples()} * @throws IllegalArgumentException if {@code gtProbsA.length!=this.gl().markers().sumGenotypes()} * @throws IllegalArgumentException if {@code gtProbsB.length!=this.gl().markers().sumGenotypes()} * @throws NullPointerException if {@code gtProbsA==null || gtProbsB==null} */ public List<HapPair> sample(int sampleA, int sampleB, double[] gtProbsA, double[] gtProbsB) { checkGprobs(gtProbsA, gtProbsB); forwardAlgorithm(sampleA, sampleB); initSampleAlleles(currentLevel(), sampleA, sampleB); currentLevel().setInitialBackwardValues(bwdNodes); setGprobs(currentLevel(), gtProbsA, gtProbsB); for (int j = nMarkers - 2; j >= 0; --j) { DuoBaumLevel level = previousLevel(sampleA, sampleB); sampleAlleles(level, sampleA, sampleB); level.setBackwardValues(bwdNodes); setGprobs(level, gtProbsA, gtProbsB); } return hapList(sampleA, sampleB); }
private void forwardAlgorithm(int sampleA, int sampleB) { DuoBaumLevel.initializeNodes(fwdNodes); this.windowIndex = -1; this.arrayIndex = levels.length - 1; for (int marker = 0; marker < nMarkers; ++marker) { nextLevel().setForwardValues(fwdNodes, marker, sampleA, sampleB); } }
private void initSampleAlleles(DuoBaumLevel level, int sampleA, int sampleB) { int m = level.marker(); for (int copy = 0; copy < nCopies; ++copy) { int state = initialRandomState(level); nodeAB1[copy] = level.parentNodeAB1(state); nodeA2[copy] = level.parentNodeA2(state); nodeB2[copy] = level.parentNodeB2(state); nodeValue[copy] = parentSum(level, sampleA, sampleB, state); allelesAB1[copy][m] = level.symbolAB1(state); allelesA2[copy][m] = level.symbolA2(state); allelesB2[copy][m] = level.symbolB2(state); } }
private int randomPreviousState( DuoBaumLevel level, int nodeAB1, int nodeA2, int nodeB2, double nodeValue) { double d = random.nextDouble() * nodeValue; double sum = 0.0; for (int j = 0, n = level.size(); j < n; ++j) { if (nodeAB1 == level.childNodeAB1(j) && nodeA2 == level.childNodeA2(j) && nodeB2 == level.childNodeB2(j)) { sum += level.forwardValue(j); if (d <= sum) { return j; } } } return level.size() - 1; // error in finite bit arithmetic encountered }
private double parentSum(DuoBaumLevel level, int sampleA, int sampleB, int state) { int marker = level.marker(); double fwdValue = level.forwardValuesSum() * level.forwardValue(state); int edgeAB1 = level.edgeAB1(state); int edgeA2 = level.edgeA2(state); int edgeB2 = level.edgeB2(state); double tpAB1 = dag.condEdgeProb(marker, edgeAB1); double tpA2 = dag.condEdgeProb(marker, edgeA2); double tpB2 = dag.condEdgeProb(marker, edgeB2); byte symbolAB1 = dag.symbol(marker, edgeAB1); byte symbolA2 = dag.symbol(marker, edgeA2); byte symbolB2 = dag.symbol(marker, edgeB2); double epA = gl.gl(marker, sampleA, symbolAB1, symbolA2); double epB = gl.gl(marker, sampleB, symbolAB1, symbolB2); return fwdValue / ((epA * epB) * (tpAB1 * tpA2 * tpB2)); }