@Override public T get( final int... keys ) { StringBuilder logEntry = new StringBuilder(); logEntry.append(logEntryLabel); logEntry.append("\t"); logEntry.append(NestedIntegerArrayOperation.GET); logEntry.append("\t"); // empty field for the datum value for ( int key : keys ) { logEntry.append("\t"); logEntry.append(key); } log.println(logEntry.toString()); return super.get(keys); }
/** * Combines the recalibration data for table1 and table2 into table1 * * Note that table1 is the destination, so it is modified * * @param table1 the destination table to merge table2 into * @param table2 the source table to merge into table1 */ public static void combineTables(final NestedIntegerArray<RecalDatum> table1, final NestedIntegerArray<RecalDatum> table2) { if ( table1 == null ) throw new IllegalArgumentException("table1 cannot be null"); if ( table2 == null ) throw new IllegalArgumentException("table2 cannot be null"); if ( ! Arrays.equals(table1.getDimensions(), table2.getDimensions())) throw new IllegalArgumentException("Table1 " + Utils.join(",", table1.getDimensions()) + " not equal to " + Utils.join(",", table2.getDimensions())); for (final NestedIntegerArray.Leaf<RecalDatum> row : table2.getAllLeaves()) { final RecalDatum myDatum = table1.get(row.keys); if (myDatum == null) table1.put(row.value, row.keys); else myDatum.combine(row.value); } }
@Test(dataProvider = "CombineTablesProvider") public void testCombineTables(final List<Row> table1, final List<Row> table2) { final NestedIntegerArray<RecalDatum> nia1 = makeTable(table1); final NestedIntegerArray<RecalDatum> nia2 = makeTable(table2); final List<Row> expectedRows = makeExpected(table1, table2); final NestedIntegerArray<RecalDatum> expected = makeTable(expectedRows); RecalUtils.combineTables(nia1, nia2); Assert.assertEquals(nia1.getDimensions(), expected.getDimensions()); Assert.assertEquals(nia1.getAllValues().size(), expected.getAllValues().size()); for ( final NestedIntegerArray.Leaf<RecalDatum> leaf : expected.getAllLeaves() ) { final RecalDatum actual = nia1.get(leaf.keys); Assert.assertEquals(actual.getNumMismatches(), leaf.value.getNumMismatches()); Assert.assertEquals(actual.getNumObservations(), leaf.value.getNumObservations()); } }
/** * Finalize, if appropriate, all derived data in recalibrationTables. * * Called once after all calls to updateDataForRead have been issued. * * Assumes that all of the principal tables (by quality score) have been completely updated, * and walks over this data to create summary data tables like by read group table. */ public void finalizeData() { if ( finalized ) throw new IllegalStateException("FinalizeData() has already been called"); // merge all of the thread-local tables finalRecalibrationTables = mergeThreadLocalRecalibrationTables(); final NestedIntegerArray<RecalDatum> byReadGroupTable = finalRecalibrationTables.getReadGroupTable(); final NestedIntegerArray<RecalDatum> byQualTable = finalRecalibrationTables.getQualityScoreTable(); // iterate over all values in the qual table for ( final NestedIntegerArray.Leaf<RecalDatum> leaf : byQualTable.getAllLeaves() ) { final int rgKey = leaf.keys[0]; final int eventIndex = leaf.keys[2]; final RecalDatum rgDatum = byReadGroupTable.get(rgKey, eventIndex); final RecalDatum qualDatum = leaf.value; if ( rgDatum == null ) { // create a copy of qualDatum, and initialize byReadGroup table with it byReadGroupTable.put(new RecalDatum(qualDatum), rgKey, eventIndex); } else { // combine the qual datum with the existing datum in the byReadGroup table rgDatum.combine(qualDatum); } } finalized = true; }
@Test public void testCombineEmptyOther() { final RecalibrationTables merged = new RecalibrationTables(covariates, numReadGroups); merged.combine(tables); for ( int i = 0; i < tables.numTables(); i++ ) { NestedIntegerArray<RecalDatum> table = tables.getTable(i); NestedIntegerArray<RecalDatum> mergedTable = merged.getTable(i); Assert.assertEquals(table.getAllLeaves().size(), mergedTable.getAllLeaves().size()); for ( final NestedIntegerArray.Leaf<RecalDatum> leaf : table.getAllLeaves() ) { final RecalDatum mergedValue = mergedTable.get(leaf.keys); Assert.assertNotNull(mergedValue); Assert.assertEquals(mergedValue.getNumObservations(), leaf.value.getNumObservations()); Assert.assertEquals(mergedValue.getNumMismatches(), leaf.value.getNumMismatches()); } } }
/** * Increments the RecalDatum at the specified position in the specified table, or put a new item there * if there isn't already one. * * Does this in a thread-safe way WITHOUT being synchronized: relies on the behavior of NestedIntegerArray.put() * to return false if another thread inserts a new item at our position in the middle of our put operation. * * @param table the table that holds/will hold our item * @param qual qual for this event * @param isError error value for this event * @param keys location in table of our item */ public static void incrementDatumOrPutIfNecessary( final NestedIntegerArray<RecalDatum> table, final byte qual, final double isError, final int... keys ) { final RecalDatum existingDatum = table.get(keys); if ( existingDatum == null ) { // No existing item, try to put a new one if ( ! table.put(createDatumObject(qual, isError), keys) ) { // Failed to put a new item because another thread came along and put an item here first. // Get the newly-put item and increment it (item is guaranteed to exist at this point) table.get(keys).increment(1L, isError); } } else { // Easy case: already an item here, so increment it existingDatum.increment(1L, isError); } }
@Test public void testCombine1() { final RecalibrationTables merged = new RecalibrationTables(covariates, numReadGroups); fillTable(merged); merged.combine(tables); for ( int i = 0; i < tables.numTables(); i++ ) { NestedIntegerArray<RecalDatum> table = tables.getTable(i); NestedIntegerArray<RecalDatum> mergedTable = merged.getTable(i); Assert.assertEquals(table.getAllLeaves().size(), mergedTable.getAllLeaves().size()); for ( final NestedIntegerArray.Leaf<RecalDatum> leaf : table.getAllLeaves() ) { final RecalDatum mergedValue = mergedTable.get(leaf.keys); Assert.assertNotNull(mergedValue); Assert.assertEquals(mergedValue.getNumObservations(), leaf.value.getNumObservations() * 2); Assert.assertEquals(mergedValue.getNumMismatches(), leaf.value.getNumMismatches() * 2); } } }
/** * Updates the current RecalDatum element in the delta table. * * If it doesn't have an element yet, it creates an RecalDatum element and adds it to the delta table. * * @param deltaTable the delta table * @param deltaKey the key to the table * @param recalDatum the recal datum to combine with the accuracyDatum element in the table */ private static void addToDeltaTable(final NestedIntegerArray<RecalDatum> deltaTable, final int[] deltaKey, final RecalDatum recalDatum) { final RecalDatum deltaDatum = deltaTable.get(deltaKey); // check if we already have a RecalDatum for this key if (deltaDatum == null) // if we don't have a key yet, create a new one with the same values as the current datum deltaTable.put(new RecalDatum(recalDatum), deltaKey); else // if we do have a datum, combine it with this one deltaDatum.combine(recalDatum); }
@Test public void testCombinePartial() { final RecalibrationTables merged = new RecalibrationTables(covariates, numReadGroups); for ( final int rg : combineStates) { RecalUtils.incrementDatumOrPutIfNecessary(merged.getTable(3), qualByte, 1, rg, 0, 0, 0); } merged.combine(tables); for ( int i = 0; i < tables.numTables(); i++ ) { NestedIntegerArray<RecalDatum> table = tables.getTable(i); NestedIntegerArray<RecalDatum> mergedTable = merged.getTable(i); Assert.assertEquals(table.getAllLeaves().size(), mergedTable.getAllLeaves().size()); for ( final NestedIntegerArray.Leaf<RecalDatum> leaf : table.getAllLeaves() ) { final RecalDatum mergedValue = mergedTable.get(leaf.keys); Assert.assertNotNull(mergedValue); final int delta = i == 3 && leaf.keys[1] == 0 && leaf.keys[2] == 0 && leaf.keys[3] == 0 ? 1 : 0; Assert.assertEquals(mergedValue.getNumObservations(), leaf.value.getNumObservations() + delta); Assert.assertEquals(mergedValue.getNumMismatches(), leaf.value.getNumMismatches() + delta); } } } }
final RecalDatum empiricalQualRG = recalibrationTables.getReadGroupTable().get(rgKey, errorModel.ordinal()); final RecalDatum empiricalQualQS = recalibrationTables.getQualityScoreTable().get(keySet[0], keySet[1], errorModel.ordinal()); final List<RecalDatum> empiricalQualCovs = new ArrayList<RecalDatum>(); for (int i = 2; i < requestedCovariates.length; i++) { continue; empiricalQualCovs.add(recalibrationTables.getTable(i).get(keySet[0], keySet[1], keySet[i], errorModel.ordinal()));