/** * Method that combines the fingerprint evidence across all the read groups for the same sample * and then produces a matrix of LOD scores for comparing every sample with every other sample. */ private void crossCheckSamples(final List<Fingerprint> fingerprints, final PrintStream out) { final SortedMap<String, Fingerprint> sampleFps = FingerprintChecker.mergeFingerprintsBySample(fingerprints); final SortedSet<String> samples = (SortedSet<String>) sampleFps.keySet(); // Print header row out.print("\t"); for (final String sample : samples) { out.print(sample); out.print("\t"); } out.println(); // Print results rows for (final String sample : samples) { out.print(sample); final Fingerprint fp = sampleFps.get(sample); for (final String otherSample : samples) { final MatchResults results = FingerprintChecker.calculateMatchResults( fp, sampleFps.get(otherSample), GENOTYPING_ERROR_RATE, LOSS_OF_HET_RATE); out.print("\t"); out.print(formatUtil.format(results.getLOD())); } out.println(); } }
/** * Method that pairwise checks every pair of read groups and reports a LOD score for the two read * groups coming from the same sample. */ private int crossCheckReadGroups( final Map<SAMReadGroupRecord, Fingerprint> fingerprints, final PrintStream out) { int mismatches = 0; int unexpectedMatches = 0; final List<SAMReadGroupRecord> readGroupRecords = new ArrayList<>(fingerprints.keySet()); final List<String> output = new ArrayList<>(); for (int i = 0; i < readGroupRecords.size(); i++) { final SAMReadGroupRecord lhsRg = readGroupRecords.get(i); for (int j = i + 1; j < readGroupRecords.size(); j++) { final SAMReadGroupRecord rhsRg = readGroupRecords.get(j); final boolean expectedToMatch = EXPECT_ALL_READ_GROUPS_TO_MATCH || lhsRg.getSample().equals(rhsRg.getSample()); final MatchResults results = FingerprintChecker.calculateMatchResults( fingerprints.get(lhsRg), fingerprints.get(rhsRg), GENOTYPING_ERROR_RATE, LOSS_OF_HET_RATE); if (expectedToMatch) { if (results.getLOD() < LOD_THRESHOLD) { mismatches++; output.add(getMatchDetails(UNEXPECTED_MISMATCH, results, lhsRg, rhsRg)); } else { if (!OUTPUT_ERRORS_ONLY) { output.add(getMatchDetails(EXPECTED_MATCH, results, lhsRg, rhsRg)); } } } else { if (results.getLOD() > -LOD_THRESHOLD) { unexpectedMatches++; output.add(getMatchDetails(UNEXPECTED_MATCH, results, lhsRg, rhsRg)); } else { if (!OUTPUT_ERRORS_ONLY) { output.add(getMatchDetails(EXPECTED_MISMATCH, results, lhsRg, rhsRg)); } } } } } if (!output.isEmpty()) { out.println( "RESULT\tLOD_SCORE\tLOD_SCORE_TUMOR_NORMAL\tLOD_SCORE_NORMAL_TUMOR\tLEFT_RUN_BARCODE\tLEFT_LANE\tLEFT_MOLECULAR_BARCODE_SEQUENCE\tLEFT_LIBRARY\tLEFT_SAMPLE\t" + "RIGHT_RUN_BARCODE\tRIGHT_LANE\tRIGHT_MOLECULAR_BARCODE_SEQUENCE\tRIGHT_LIBRARY\tRIGHT_SAMPLE"); out.println(String.join("\n", output)); } if (mismatches + unexpectedMatches > 0) { log.info("WARNING: At least two read groups did not relate as expected."); return EXIT_CODE_WHEN_MISMATCH; } else { log.info("All read groups related as expected."); return 0; } }
@Override protected int doWork() { // Check inputs for (final File f : INPUT) IOUtil.assertFileIsReadable(f); IOUtil.assertFileIsReadable(HAPLOTYPE_MAP); if (OUTPUT != null) IOUtil.assertFileIsWritable(OUTPUT); final HaplotypeMap map = new HaplotypeMap(HAPLOTYPE_MAP); final FingerprintChecker checker = new FingerprintChecker(map); checker.setAllowDuplicateReads(ALLOW_DUPLICATE_READS); log.info("Done checking input files, moving onto fingerprinting files."); List<File> unrolledFiles = IOUtil.unrollFiles(INPUT, BamFileIoUtils.BAM_FILE_EXTENSION, IOUtil.SAM_FILE_EXTENSION); final Map<SAMReadGroupRecord, Fingerprint> fpMap = checker.fingerprintSamFiles(unrolledFiles, NUM_THREADS, 1, TimeUnit.DAYS); final List<Fingerprint> fingerprints = new ArrayList<>(fpMap.values()); log.info("Finished generating fingerprints from BAM files, moving on to cross-checking."); // Setup the output final PrintStream out; if (OUTPUT != null) { out = new PrintStream(IOUtil.openFileForWriting(OUTPUT), true); } else { out = System.out; } if (this.CROSSCHECK_SAMPLES) { crossCheckSamples(fingerprints, out); return 0; } else if (this.CROSSCHECK_LIBRARIES) { crossCheckLibraries(fpMap, out); return 0; } else { return crossCheckReadGroups(fpMap, out); } }