const BoxList BoxLib::complementIn (const Box& b, const BoxList& bl) { BL_ASSERT(bl.ixType() == b.ixType()); BoxList newb(b.ixType()); newb.complementIn(b,bl); return newb; }
std::vector<Box> octreeSolid::get8ChildrenBox(Vec3f leftDownf, Vec3f rightUpf) { Vec3f mid = (leftDownf + rightUpf)/2; Vec3f pt[3] = {leftDownf, mid, rightUpf}; std::vector<Box> boxes; for (int i = 0; i <= 1; i ++) { for (int j = 0; j <= 1; j ++) { for (int k = 0; k <= 1; k ++) { Vec3f ld = Vec3f(pt[i][0], pt[j][1], pt[k][2]); Vec3f ru = Vec3f(pt[i+1][0], pt[j+1][1], pt[k+1][2]); Box newb(ld, ru); boxes.push_back(newb); } } } return boxes; }
bool abColumn::mergeWithNext(abAbacus *abacus, bool highQuality) { abColumn *lcolumn = this; abColumn *rcolumn = next(); abColumn *ncolumn = next()->next(); // The column after rcolumn. assert(lcolumn != NULL); assert(rcolumn != NULL); assert(lcolumn->next() == rcolumn); assert(rcolumn->prev() == lcolumn); #if 0 lcolumn->checkLinks(); rcolumn->checkLinks(); #endif // If both columns have a non-gap (for a single read), we cannot merge. for (uint32 ii=0; ii<lcolumn->_beadsLen; ii++) { uint32 jj = lcolumn->_beads[ii].nextOffset(); if ((jj < UINT16_MAX) && (lcolumn->_beads[ii].base() != '-') && (rcolumn->_beads[jj].base() != '-')) return(false); } #if 0 fprintf(stderr, "MERGE columns %d %p <- %d %p\n", lcolumn->position(), lcolumn, rcolumn->position(), rcolumn); fprintf(stderr, "rcolumn links\n"); rcolumn->showLinks(); lcolumn->checkLinks(); rcolumn->checkLinks(); ncolumn->checkLinks(); #endif // OK to merge. Merge all the bases from the right column to the current column. We already // checked that whenever the right column has a base, the left column has a gap, so just march // down the right column and move those bases over! for (uint16 rr=0; rr<rcolumn->_beadsLen; rr++) { uint16 ll = rcolumn->_beads[rr].prevOffset(); // Ignore the gaps. if (rcolumn->_beads[rr].base() == '-') continue; // Oh, great. We just found the end of a read. We need to link in the gap (in lcolumn) // before we can swap. Correction: we need to ADD a gap (in lcolumn) before we can swap. if (ll == UINT16_MAX) { //fprintf(stderr, "EXTEND READ at rr=%d\n", rr); ll = lcolumn->extendRead(rcolumn, rr); } // The simple case: just swap the contents. #if 0 fprintf(stderr, "mergeWithNext()-- swap beads lcolumn %d %c and rcolumn %d %c\n", ll, lcolumn->_beads[ll].base(), rr, rcolumn->_beads[rr].base()); #endif #ifdef BASECOUNT lcolumn->baseCountDecr(lcolumn->_beads[ll].base()); rcolumn->baseCountDecr(rcolumn->_beads[rr].base()); // We don't really care about rcolumn. #endif swap(lcolumn->_beads[ll], rcolumn->_beads[rr]); #ifdef BASECOUNT lcolumn->baseCountIncr(lcolumn->_beads[ll].base()); rcolumn->baseCountIncr(rcolumn->_beads[rr].base()); #endif // While we're here, update the bead-to-read maps. beadID oldb(rcolumn, rr); beadID newb(lcolumn, ll); map<beadID,uint32>::iterator fit = abacus->fbeadToRead.find(oldb); // Does old bead exist map<beadID,uint32>::iterator lit = abacus->lbeadToRead.find(oldb); // in either map? if (fit != abacus->fbeadToRead.end()) { uint32 rid = fit->second; //fprintf(stderr, "mergeWithNext()-- move fbeadToRead from %p/%d to %p/%d for read %d\n", // rcolumn, rr, lcolumn, ll, rid); abacus->fbeadToRead.erase(fit); // Remove the old bead to read pointer abacus->fbeadToRead[newb] = rid; // Add a new bead to read pointer abacus->readTofBead[rid] = newb; // Update the read to bead pointer } if (lit != abacus->lbeadToRead.end()) { uint32 rid = lit->second; //fprintf(stderr, "mergeWithNext()-- move lbeadToRead from %p/%d to %p/%d for read %d\n", // rcolumn, rr, lcolumn, ll, rid); abacus->lbeadToRead.erase(lit); abacus->lbeadToRead[newb] = rid; abacus->readTolBead[rid] = newb; } } // The rcolumn should now be full of gaps. (We could just test that baseCount('-') == depth() for (uint32 rr=0; rr<rcolumn->_beadsLen; rr++) assert(rcolumn->_beads[rr].base() == '-'); #if 0 lcolumn->checkLinks(); rcolumn->checkLinks(); ncolumn->checkLinks(); #endif // To make checkLinks() work, we need to unlink rcolumn from the column list right now. if (rcolumn->_prevColumn) rcolumn->_prevColumn->_nextColumn = rcolumn->_nextColumn; if (rcolumn->_nextColumn) rcolumn->_nextColumn->_prevColumn = rcolumn->_prevColumn; assert(ncolumn == rcolumn->next()); assert(ncolumn == next()); // Before the rcolumn can be removed, we need to unlink it from the bead link list. If there is a column after rcolumn, // we need to move rcolumn's link pointers to lcolumn (prev) and ncolumn (next). // // The actual example (,'s indicate no bases because the read ended): // // 1234 Column 2 is merged into column 1, and then we delete column 2. // 1 -aa-aaa // 2 gaaT,,, Column 1 read 4 has _beads position 3. (next = 1) // 3 gaaT,,, Column 2 read 4 has _beads position 1. (prev = 3, next = 1) // 4 -aa-aaa Column 3 read 4 has _beads position 1. (prev = 1) // 5 -aa-aaa When column 2 is deleted, we're left with a busted link back from col 3 read 4; it should be 3 // 6 gaa,,,, if (ncolumn != NULL) { for (uint32 rr=0; rr<rcolumn->_beadsLen; rr++) { uint16 bl = rcolumn->_beads[rr].prevOffset(); // back link from deleted column to lcolumn -> set as ncolumns back link (known as ll above) uint16 fl = rcolumn->_beads[rr].nextOffset(); // forw link from deleted column to ncolumn -> set as lcolumns forw link if (bl != UINT16_MAX) lcolumn->_beads[bl]._nextOffset = fl; if (fl != UINT16_MAX) ncolumn->_beads[fl]._prevOffset = bl; } } lcolumn->checkLinks(); ncolumn->checkLinks(); // Now, finally, we're done. Remove the old column, recall the base, and do a final check. //fprintf(stderr, "mergeWithNext()-- Remove rcolumn %d %p\n", rcolumn->position(), rcolumn); delete rcolumn; baseCall(highQuality); return(true); }