/** * Creates a new calculator providing its ploidy and number of genotyping alleles. */ protected GenotypeLikelihoodCalculator(final int ploidy, final int alleleCount, final int[][] alleleFirstGenotypeOffsetByPloidy, final GenotypeAlleleCounts[][] genotypeTableByPloidy, final double[] ploidyLog10) { this.alleleFirstGenotypeOffsetByPloidy = alleleFirstGenotypeOffsetByPloidy; genotypeAlleleCounts = genotypeTableByPloidy[ploidy]; this.alleleCount = alleleCount; this.ploidy = ploidy; genotypeCount = this.alleleFirstGenotypeOffsetByPloidy[ploidy][alleleCount]; alleleHeap = new IntMaxHeap(ploidy); readLikelihoodsByGenotypeIndex = new double[genotypeCount][]; this.ploidyLog10 = ploidyLog10; // The number of possible components is limited by distinct allele count and ploidy. maximumDistinctAllelesInGenotype = Math.min(ploidy, alleleCount); genotypeAllelesAndCounts = new int[maximumDistinctAllelesInGenotype*2]; }
/** * Give a list of alleles, returns the likelihood array index. * * <p>This operation is <b>thread-unsafe</b>.</p> * * @param alleleIndices the indices of the alleles in the genotype, there should be as many repetition of an * index as copies of that allele in the genotype. Allele indices do not need to be sorted in * any particular way. * * @return never {@code null}. */ public int allelesToIndex(final int... alleleIndices) { // Special case ploidy == 0. if (ploidy == 0) return 0; alleleHeap.clear(); alleleHeap.add(alleleIndices); return alleleHeapToIndex(); }
/** * Transforms the content of the heap into an index. * * <p> * The heap contents are flushed as a result, so is left ready for another use. * </p> * * @return a valid likelihood index. */ private int alleleHeapToIndex() { if (alleleHeap.size() != ploidy) throw new IllegalArgumentException("the sum of allele counts must be equal to the ploidy of the calculator"); if (alleleHeap.peek() >= alleleCount) throw new IllegalArgumentException("invalid allele " + alleleHeap.peek() + " more than the maximum " + (alleleCount - 1)); int result = 0; for (int p = ploidy; p > 0; p--) { final int allele = alleleHeap.remove(); if (allele < 0) throw new IllegalArgumentException("invalid allele " + allele + " must be equal or greater than 0 "); result += alleleFirstGenotypeOffsetByPloidy[p][allele]; } return result; }
/** * Adds a new element to the heap. * * <p>The heap with grow if it runs out of capacity to hold the new element</p> * * @param v the new element. */ public void add(final int v) { // Double capacity if overflow: ensureCapacity(size + 1); addWithoutCheckingCapacity(v); }
@Test(dataProvider = "capacityData", dependsOnMethods = {"testEmptynessAndSize"}) public void testClear(final int initialCapacity, final int elementCount) { final IntMaxHeap heap = new IntMaxHeap(initialCapacity); final Random rnd = Utils.getRandomGenerator(); for (int i = 0; i < elementCount; i++) { final int v = rnd.nextInt(); heap.add(v); } heap.clear(); Assert.assertEquals(heap.size(),0); Assert.assertTrue(heap.isEmpty()); }
@Test(dataProvider = "capacityData", dependsOnMethods = {"testCapacity"}) public void testPeek(final int initialCapacity, final int elementCount) { final IntMaxHeap heap = new IntMaxHeap(initialCapacity); final Random rnd = Utils.getRandomGenerator(); int top = rnd.nextInt(); heap.add(top); Assert.assertEquals(heap.peek(),top); for (int i = 1; i < elementCount; i++) { final int v = rnd.nextInt(); if (v > top) top = v; heap.add(v); Assert.assertEquals(heap.peek(),top); } }
@Test(dataProvider = "capacityData") public void testCapacity(final int initialCapacity, final int elementCount) { final IntMaxHeap heap = new IntMaxHeap(initialCapacity); final Random rnd = Utils.getRandomGenerator(); for (int i = 0; i < elementCount; i++) { final int v = rnd.nextInt(); heap.add(v); } }
alleleHeap.clear(); GenotypeAlleleCounts alleleCounts = genotypeAlleleCounts[0]; for (int i = 0; i < resultLength; i++) {
/** * Performs the genotype mapping per new genotype index. * * @param newGenotypeIndex the target new genotype index. * @param alleleCounts tha correspond to {@code newGenotypeIndex}. * @param oldToNewAlleleIndexMap the allele mapping. * @param destination where to store the new genotype index mapping to old. * @param sortedAlleleCountsBuffer a buffer to re-use to get the genotype-allele-count's sorted allele counts. */ private void genotypeIndexMapPerGenotypeIndex(final int newGenotypeIndex, final GenotypeAlleleCounts alleleCounts, final int[] oldToNewAlleleIndexMap, final int[] destination, final int[] sortedAlleleCountsBuffer) { final int distinctAlleleCount = alleleCounts.distinctAlleleCount(); alleleCounts.copyAlleleCounts(sortedAlleleCountsBuffer,0); for (int j = 0, jj = 0; j < distinctAlleleCount; j++) { final int oldIndex = sortedAlleleCountsBuffer[jj++]; final int repeats = sortedAlleleCountsBuffer[jj++]; final int newIndex = oldToNewAlleleIndexMap[oldIndex]; if (newIndex < 0 || newIndex >= alleleCount) throw new IllegalArgumentException("found invalid new allele index (" + newIndex + ") for old index (" + oldIndex + ")"); for (int k = 0; k < repeats; k++) alleleHeap.add(newIndex); } final int genotypeIndex = alleleHeapToIndex(); // this cleans the heap for the next use. destination[newGenotypeIndex] = genotypeIndex; }
/** * Returns the minimum element of the heap and removes it. * * @throws IllegalStateException if the heap is empty. * * @return the minimum element in the heap before removing it. */ public int remove() { if (size == 0) throw new IllegalArgumentException("the heap is empty"); final int result = values[0]; removeUpdate(); return result; }
@Test(dataProvider = "capacityData", dependsOnMethods = {"testCapacity"}) public void testAddArray(final int initialCapacity, final int elementCount) { final IntMaxHeap addHeap = new IntMaxHeap(initialCapacity); final IntMaxHeap arrayAddHeap = new IntMaxHeap(initialCapacity); final Random rnd = Utils.getRandomGenerator(); final int[] values = new int[elementCount]; for (int i = 0; i < elementCount; i++) { final int v = rnd.nextInt(); values[i] = v; addHeap.add(v); } arrayAddHeap.add(values); Assert.assertEquals(arrayAddHeap.size(),addHeap.size()); while (!arrayAddHeap.isEmpty()) Assert.assertEquals(arrayAddHeap.remove(),addHeap.remove()); }
/** * Add several integers into the heap. * @param v values to add. */ public void add(final int ... v) { if (v == null) throw new IllegalArgumentException("the input array cannot be null"); ensureCapacity(v.length + size); for (int i : v) addWithoutCheckingCapacity(i); }
@Test(dataProvider = "capacityData",dependsOnMethods = {"testCapacity"}) public void testEmptynessAndSize(final int initialCapacity, final int elementCount) { final IntMaxHeap heap = new IntMaxHeap(initialCapacity); final Random rnd = Utils.getRandomGenerator(); Assert.assertEquals(heap.size(),0); Assert.assertTrue(heap.isEmpty()); for (int i = 0; i < elementCount; i++) { final int v = rnd.nextInt(); heap.add(v); Assert.assertEquals(heap.size(),i+1); Assert.assertFalse(heap.isEmpty()); } }
if ((alleleCountArray.length & 1) != 0) throw new IllegalArgumentException("the allele counts array cannot have odd length"); alleleHeap.clear(); for (int i = 0; i < alleleCountArray.length; i += 2) { final int index = alleleCountArray[i]; throw new IllegalArgumentException("no allele count can be less than 0"); for (int j = 0; j < count; j++) alleleHeap.add(index);
@Test(dataProvider = "capacityData", dependsOnMethods = {"testEmptynessAndSize"}) public void testRemove(final int initialCapacity, final int elementCount) { final IntMaxHeap heap = new IntMaxHeap(initialCapacity); final Random rnd = Utils.getRandomGenerator(); final List<Integer> values = new ArrayList<>(elementCount); for (int i = 0; i < elementCount; i++) { final int v = rnd.nextInt(); values.add(v); heap.add(v); } Collections.sort(values, Collections.reverseOrder()); for (int i = 0; i < elementCount; i++) { Assert.assertEquals(heap.remove(),(int)values.get(i), "element-count = " + elementCount + ", initial-capacity = " + initialCapacity); Assert.assertEquals(heap.size(),elementCount - i - 1); } }