void RecordOutputMgr::printClosest(RecordKeyVector &keyList, const vector<int> *dists) { //The first time we print a record is when we print any header, because the header //hasn't been read from the query file until after the first record has also been read. checkForHeader(); const ContextClosest *context = static_cast<const ContextClosest *>(_context); bool deleteBlocks = false; const Record *keyRec = keyList.getKey(); RecordKeyVector blockList(keyRec); if (keyRec->getType() == FileRecordTypeChecker::BAM_RECORD_TYPE) { _bamBlockMgr->getBlocks(blockList, deleteBlocks); _currBamBlockList = &blockList; } if (!keyList.empty()) { int distCount = 0; for (RecordKeyVector::const_iterator_type iter = keyList.begin(); iter != keyList.end(); iter = keyList.next()) { const Record *hitRec = *iter; printKey(keyRec, keyRec->getStartPosStr(), keyRec->getEndPosStr()); tab(); addDbFileId(hitRec->getFileIdx()); printKey(hitRec, hitRec->getStartPosStr(), hitRec->getEndPosStr()); if (dists != NULL) { tab(); int dist = (*dists)[distCount]; //if not using sign distance, use absolute value instead. dist = context->signDistance() ? dist : abs(dist); _outBuf.append(dist); distCount++; } newline(); if (needsFlush()) flush(); } } else { printKey(keyRec, keyRec->getStartPosStr(), keyRec->getEndPosStr()); tab(); // need to add a dummy file id if multiple DB files are used if (_context->getNumInputFiles() > 2) { _outBuf.append('.'); tab(); } null(false, true); if (context->reportDistance()) { tab(); _outBuf.append(-1); } newline(); } if (deleteBlocks) { _bamBlockMgr->deleteBlocks(blockList); _currBamBlockList = NULL; } return; }
void RecordOutputMgr::printClosest(RecordKeyVector &keyList, const vector<int> *dists) { const ContextClosest *context = static_cast<const ContextClosest *>(_context); bool deleteBlocks = false; RecordKeyVector blockList(keyList.getKey()); if (keyList.getKey()->getType() == FileRecordTypeChecker::BAM_RECORD_TYPE) { _bamBlockMgr->getBlocks(blockList, deleteBlocks); _currBamBlockList = &blockList; } if (!keyList.empty()) { int distCount = 0; for (RecordKeyVector::const_iterator_type iter = keyList.begin(); iter != keyList.end(); iter = keyList.next()) { printKey(keyList.getKey()); tab(); addDbFileId((*iter)->getFileIdx()); (*iter)->print(_outBuf); if (dists != NULL) { tab(); _outBuf.append((*dists)[distCount]); distCount++; } newline(); if (needsFlush()) flush(); } } else { printKey(keyList.getKey()); tab(); null(true, false); if (context->reportDistance()) { tab(); _outBuf.append(-1); } newline(); } if (deleteBlocks) { _bamBlockMgr->deleteBlocks(blockList); _currBamBlockList = NULL; } return; }
void RecordOutputMgr::reportOverlapDetail(const Record *keyRecord, const Record *hitRecord, int hitIdx) { //get the max start and min end as strings. const_cast<Record *>(hitRecord)->undoZeroLength(); const QuickString *startStr = NULL; const QuickString *endStr = NULL; int maxStart = 0; int minEnd = 0; int keyStart = keyRecord->getStartPos(); int keyEnd = keyRecord->getEndPos(); int hitStart = hitRecord->getStartPos(); int hitEnd = hitRecord->getEndPos(); if ( keyStart>= hitStart) { //the key start is after the hit start, but we need to check and make sure the hit end is at least after the keyStart. //The reason for this is that, in some rare cases, such as both the key and hit having been zero length intervals, //the normal process for intersection that allows us to simply report the maxStart and minEnd do not necessarily apply. if (hitEnd >= keyStart) { //this is ok. We have a normal intersection where the key comes after the hit. maxStart = keyStart; startStr = &(keyRecord->getStartPosStr()); minEnd = min(keyEnd, hitEnd); endStr = keyRecord->getEndPos() < hitRecord->getEndPos() ? &(keyRecord->getEndPosStr()) : &(hitRecord->getEndPosStr()); } else { //this is the weird case of not a "real" intersection. The keyStart is greater than the hitEnd. So just report the key as is. maxStart = keyStart; minEnd = keyEnd; startStr = &(keyRecord->getStartPosStr()); endStr = &(keyRecord->getEndPosStr()); } } else { //all of the above, but backwards. keyStart is before hitStart. if (keyEnd >= hitStart) { //normal intersection, key first maxStart = hitStart; startStr = &(hitRecord->getStartPosStr()); minEnd = min(keyEnd, hitEnd); endStr = keyRecord->getEndPos() < hitRecord->getEndPos() ? &(keyRecord->getEndPosStr()) : &(hitRecord->getEndPosStr()); } else { //this is the weird case of not a "real" intersection. The hitStart is greater than the keyEnd. So just report the hit as is. maxStart = hitStart; minEnd = hitEnd; startStr = &(hitRecord->getStartPosStr()); endStr = &(hitRecord->getEndPosStr()); } } if (!(static_cast<ContextIntersect *>(_context))->getWriteA() && !(static_cast<ContextIntersect *>(_context))->getWriteB() && !(static_cast<ContextIntersect *>(_context))->getWriteOverlap() && !(static_cast<ContextIntersect *>(_context))->getLeftJoin()) { printKey(keyRecord, *startStr, *endStr); newline(); if (needsFlush()) flush(); } else if (((static_cast<ContextIntersect *>(_context))->getWriteA() && (static_cast<ContextIntersect *>(_context))->getWriteB()) || (static_cast<ContextIntersect *>(_context))->getLeftJoin()) { printKey(keyRecord); tab(); addDbFileId(hitRecord->getFileIdx()); hitRecord->print(_outBuf); newline(); if (needsFlush()) flush(); } else if ((static_cast<ContextIntersect *>(_context))->getWriteA()) { printKey(keyRecord); newline(); if (needsFlush()) flush(); } else if ((static_cast<ContextIntersect *>(_context))->getWriteB()) { printKey(keyRecord, *startStr, *endStr); tab(); addDbFileId(hitRecord->getFileIdx()); hitRecord->print(_outBuf); newline(); if (needsFlush()) flush(); } else if ((static_cast<ContextIntersect *>(_context))->getWriteOverlap()) { int printOverlapBases = 0; if (_context->getObeySplits()) { printOverlapBases = _splitInfo->getOverlapBases(hitIdx); } else { printOverlapBases = minEnd - maxStart; } printKey(keyRecord); tab(); addDbFileId(hitRecord->getFileIdx()); hitRecord->print(_outBuf); tab(); int2str(printOverlapBases, _outBuf, true); newline(); if (needsFlush()) flush(); } const_cast<Record *>(keyRecord)->adjustZeroLength(); }
void RecordOutputMgr::reportOverlapDetail(const Record *keyRecord, const Record *hitRecord, int hitIdx) { // overlap interval is defined by min(e1,e2) - max(s1,s2) int maxStart = max(keyRecord->getStartPos(), hitRecord->getStartPos()); int minEnd = min(keyRecord->getEndPos(), hitRecord->getEndPos()); // need to undo our conversion of 1-based start coordinates to 0-based if (!keyRecord->isZeroBased()) maxStart++; // all of the different printing scenarios based upon the options used. if (!(static_cast<ContextIntersect *>(_context))->getWriteA() && !(static_cast<ContextIntersect *>(_context))->getWriteB() && !(static_cast<ContextIntersect *>(_context))->getWriteOverlap() && !(static_cast<ContextIntersect *>(_context))->getLeftJoin()) { const_cast<Record *>(keyRecord)->undoZeroLength(); printKey(keyRecord, maxStart, minEnd); } else if (((static_cast<ContextIntersect *>(_context))->getWriteA() && (static_cast<ContextIntersect *>(_context))->getWriteB()) || (static_cast<ContextIntersect *>(_context))->getLeftJoin()) { const_cast<Record *>(keyRecord)->undoZeroLength(); printKey(keyRecord); tab(); const_cast<Record *>(hitRecord)->undoZeroLength(); addDbFileId(hitRecord->getFileIdx()); hitRecord->print(_outBuf); } else if ((static_cast<ContextIntersect *>(_context))->getWriteA()) { const_cast<Record *>(keyRecord)->undoZeroLength(); printKey(keyRecord); } else if ((static_cast<ContextIntersect *>(_context))->getWriteB()) { printKey(keyRecord, maxStart, minEnd); tab(); addDbFileId(hitRecord->getFileIdx()); const_cast<Record *>(hitRecord)->undoZeroLength(); hitRecord->print(_outBuf); } else if ((static_cast<ContextIntersect *>(_context))->getWriteOverlap()) { int printOverlapBases = 0; if (_context->getObeySplits()) { printOverlapBases = _context->getSplitBlockInfo()->getOverlapBases(hitIdx); } else { // if one of the records was zerolength, the number of // overlapping bases needs to be corrected if (keyRecord->isZeroLength() || hitRecord->isZeroLength ()) { maxStart++; minEnd--; } printOverlapBases = minEnd - maxStart; } const_cast<Record *>(keyRecord)->undoZeroLength(); printKey(keyRecord); tab(); addDbFileId(hitRecord->getFileIdx()); const_cast<Record *>(hitRecord)->undoZeroLength(); hitRecord->print(_outBuf); tab(); int2str(printOverlapBases, _outBuf, true); } newline(); if (needsFlush()) flush(); const_cast<Record *>(hitRecord)->adjustZeroLength(); }