void FragmentCollector::add( const alignment::BamTemplate &bamTemplate, const unsigned fragmentIndex, const unsigned barcodeIdx) { ISAAC_ASSERT_MSG(2 >= bamTemplate.getFragmentCount(), "Expected paired or single-ended data"); const alignment::FragmentMetadata &fragment = bamTemplate.getFragmentMetadata(fragmentIndex); ISAAC_THREAD_CERR_DEV_TRACE_CLUSTER_ID(fragment.getCluster().getId(), "FragmentCollector::add: " << fragment); FragmentBuffer::IndexRecord &recordStart = buffer_.initialize(fragment.getCluster().getId(), fragment.getReadIndex()); recordStart.fStrandPos_ = fragment.getFStrandReferencePosition(); storeBclAndCigar(fragment, recordStart); if (2 == bamTemplate.getFragmentCount()) { const alignment::FragmentMetadata &mate = bamTemplate.getMateFragmentMetadata(fragment); if (fragment.isNoMatch()) { ISAAC_ASSERT_MSG(mate.isNoMatch(), "If mate is not a no-match, fragment must be a shadow. fragment: " << fragment << " mate:" << mate); recordStart.fragmentHeader() = io::FragmentHeader(bamTemplate, fragment, mate, barcodeIdx, 0); } else { const unsigned mateStorageBin = binIndexMap_.getBinIndex(mate.getFStrandReferencePosition()); recordStart.fragmentHeader() = io::FragmentHeader(bamTemplate, fragment, mate, barcodeIdx, mateStorageBin); } } else { recordStart.fragmentHeader() = io::FragmentHeader(bamTemplate, fragment, barcodeIdx); } }
/** * \brief Removes entries designating the same alignment location and strand * * This is important not only to avoid repetitive processing but also to avoid good alignments * scored poorly because they are present multiple times in the list. * * \param removeUnaligned if true, entries with !isAlignment() are removed * * \postcondition the fragmentList is ordered * \postcondition The fragmentList contains unique alignments only */ void FragmentBuilder::consolidateDuplicateAlignments( FragmentMetadataList &fragmentList, const bool removeUnaligned, std::size_t &perfectFound) { ISAAC_THREAD_CERR_DEV_TRACE_CLUSTER_ID(fragmentList[0].getCluster().getId(), "consolidateDuplicateFragments initial size: " << fragmentList.size()); perfectFound = 0; // although initially matches arrive ordered by location, gapped alignment might have moved the // start position of some. std::sort(fragmentList.begin(), fragmentList.end()); FragmentMetadataList::iterator lastFragment = fragmentList.begin(); while(fragmentList.end() != lastFragment && removeUnaligned && !lastFragment->isAligned()) { ++lastFragment; } lastFragment = fragmentList.erase(fragmentList.begin(), lastFragment); if (2 <= fragmentList.size()) { ISAAC_THREAD_CERR_DEV_TRACE_CLUSTER_ID(fragmentList[0].getCluster().getId(), " keeping " << *lastFragment); perfectFound += lastFragment->isPerfectMatch(); for (FragmentMetadataList::iterator currentFragment = lastFragment + 1; fragmentList.end() != currentFragment; ++currentFragment) { if (removeUnaligned && !currentFragment->isAligned()) { ISAAC_THREAD_CERR_DEV_TRACE_CLUSTER_ID(fragmentList[0].getCluster().getId(), " ignoring " << *currentFragment); } else if (*lastFragment == *currentFragment) { ISAAC_THREAD_CERR_DEV_TRACE_CLUSTER_ID(fragmentList[0].getCluster().getId(), " merging " << *currentFragment); lastFragment->mergeAnchors(*currentFragment); ISAAC_THREAD_CERR_DEV_TRACE_CLUSTER_ID(fragmentList[0].getCluster().getId(), " merged " << *lastFragment); } else { ISAAC_THREAD_CERR_DEV_TRACE_CLUSTER_ID(fragmentList[0].getCluster().getId(), " keeping " << *currentFragment); perfectFound += currentFragment->isPerfectMatch(); ++lastFragment; if (lastFragment != currentFragment) { *lastFragment = *currentFragment; } } } fragmentList.resize(1 + lastFragment - fragmentList.begin()); } ISAAC_THREAD_CERR_DEV_TRACE_CLUSTER_ID( fragmentList[0].getCluster().getId(), "consolidateDuplicateFragments consolidated size: " << fragmentList.size() << " found " << perfectFound << " perfect alignments"); }