void intersectOnChrom(char *db, struct sqlConnection *conn, char *chrom, char *track1, char *track2) /* Do intersection on one chromosome. */ { int chromSize = hChromSize(chrom); struct lm *lm = lmInit(0); struct bed *bedList1, *bedList2, *andBed; struct featureBits *fb1, *fb2; Bits *bit1, *bit2; int fieldCount1, fieldCount2; struct binKeeper *bk2; uglyTime(NULL); scanChromTable(conn, chrom, track1); scanChromTable(conn, chrom, track2); uglyTime("Scan tracks"); bedList1 = getChromAsBed(conn, db, track1, chrom, lm, &fieldCount1); bedList2 = getChromAsBed(conn, db, track2, chrom, lm, &fieldCount2); uglyTime("Tracks as bed"); uglyf("%d items with %d fields in %s, ", slCount(bedList1), fieldCount1, track1); uglyf("%d items with %d fields in %s\n", slCount(bedList2), fieldCount2, track2); bit1 = bitAlloc(chromSize+8); bit2 = bitAlloc(chromSize+8); uglyTime("bitAlloc"); fb1 = fbList(db, chrom, track1, bedList1, chromSize); fb2 = fbList(db, chrom, track1, bedList1, chromSize); uglyTime("bed to featureBits list"); fbOrBits(bit1, chromSize, fb1, 0); fbOrBits(bit2, chromSize, fb2, 0); uglyTime("or into bits"); bitAnd(bit1, bit2, chromSize); uglyTime("Anding bitfields"); andBed = bitsToBed4List(bit1, chromSize, chrom, 0, 0, chromSize, lm); uglyTime("Converting bitfield to bed 4"); bitCountAllOverlaps(bedList1, bit2, fieldCount2); uglyTime("Counting overlaps in track1 with bitfield of track2"); bk2 = fbToBinKeeper(fb2, chromSize); uglyTime("Adding featureBits list from track 2 into binKeeper."); bkCountAllOverlaps(bedList1, bk2, fieldCount2); uglyTime("Count overlaps in track1 with binKeeper of track2"); featureBitsFreeList(&fb1); featureBitsFreeList(&fb2); uglyTime("free featureBits"); bitFree(&bit1); bitFree(&bit2); uglyTime("bitFree"); }
void netToAxt(char *netName, char *chainName, char *tNibDir, char *qNibDir, char *axtName) /* netToAxt - Convert net (and chain) to axt.. */ { Bits *usedBits = findUsedIds(netName); struct hash *chainHash; struct chainNet *net; struct lineFile *lf = lineFileOpen(netName, TRUE); FILE *f = mustOpen(axtName, "w"); struct dnaSeq *tChrom = NULL; struct nibTwoCache *qNtc = nibTwoCacheNew(qNibDir); char *gapFileName = optionVal("gapOut", NULL); FILE *gapFile = NULL; if (gapFileName) gapFile = mustOpen(gapFileName, "w"); lineFileSetMetaDataOutput(lf, f); chainHash = chainReadUsedSwap(chainName, qChain, usedBits); bitFree(&usedBits); while ((net = chainNetRead(lf)) != NULL) { verbose(1, "Processing %s\n", net->name); tChrom = nibTwoLoadOne(tNibDir, net->name); if (tChrom->size != net->size) errAbort("Size mismatch on %s. Net/nib out of sync or possibly nib dirs swapped?", tChrom->name); rConvert(net->fillList, tChrom, qNtc, qNibDir, chainHash, f, gapFile); freeDnaSeq(&tChrom); chainNetFree(&net); } nibTwoCacheFree(&qNtc); }
void makeDeletes(struct sqlConnection *conn, struct chromInfo *chrom, FILE *f) /* Generate SQL that kills tet alignments on simple repeats. */ { struct wabaChromHit *wchList = NULL, *wch; struct rmskOut ro; int tetSize; int repSize; int start, end; int delCount = 0; int totCount = 0; Bits *b = NULL; printf(" Loading all tet alignments on %s...\n", chrom->chrom); wchList = wchLoadAll(conn, chrom->chrom); printf(" Got %d alignments\n", slCount(wchList)); b = getMaskedBits(conn, chrom); for (wch = wchList; wch != NULL; wch = wch->next) { tetSize = wch->chromEnd - wch->chromStart; repSize = bitCountRange(b, wch->chromStart, tetSize); ++totCount; if (repSize * 2 > tetSize) { ++delCount; makeDelete(chrom->chrom, wch, f); } } bitFree(&b); if (totCount > 0) printf("Deleted %d of %d (%4.2f%%)\n", delCount, totCount, (100.0)*delCount/(double)totCount); wchFreeList(&wchList); }
boolean cutBetween(struct segment *a, struct segment *b, int overlapStart, int overlapEnd, int overlapSize, boolean splitGene, int crossover) /* Try and cut out redundant parts where a and b overlap. * Don't cut a gene unless splitGene is true. Don't * cut a feature unless crossover point is specified (> 0) */ { if (crossover < 0) { Bits *bits = bitAlloc(overlapSize); genesToBits(a->geneList, bits, overlapStart, overlapEnd, splitGene); genesToBits(b->geneList, bits, overlapStart, overlapEnd, splitGene); featuresToBits(a->suboptList, bits, overlapStart, overlapEnd); featuresToBits(b->suboptList, bits, overlapStart, overlapEnd); crossover = findCrossover(bits, overlapStart, overlapEnd); bitFree(&bits); } if (crossover >= 0) { removeOutside(0, crossover, a); removeOutside(crossover, BIGNUM, b); return TRUE; } else return FALSE; }
static void basesCoveredFromBits(struct covStats *cov) /* Calculate basesCovered from bits for each item on list. */ { int regionSize = cov->region->end - cov->region->start; cov->basesCovered = bitCountRange(cov->bits, 0, regionSize); bitFree(&cov->bits); }
void bitmapToMaskArray(struct hash *bitmapHash, struct hash *tbHash) /* Translate each bitmap in bitmapHash into an array of mask coordinates * in the corresponding twoBit in tbHash. Assume tbHash's mask array is * empty at the start -- we allocate it here. Free bitmap when done. */ { struct hashCookie cookie = hashFirst(tbHash); struct hashEl *hel = NULL; while ((hel = hashNext(&cookie)) != NULL) { char *seqName = hel->name; struct twoBit *tb = (struct twoBit *)(hel->val); struct hashEl *bHel = hashLookup(bitmapHash, seqName); Bits *bits; unsigned start=0, end=0; assert(tb != NULL); assert(tb->maskBlockCount == 0); if (bHel == NULL) errAbort("Missing bitmap for seq \"%s\"", seqName); bits = (Bits *)bHel->val; if (bits != NULL) { struct lm *lm = lmInit(0); struct unsignedRange *rangeList = NULL, *range = NULL; int i; for (;;) { start = bitFindSet(bits, end, tb->size); if (start >= tb->size) break; end = bitFindClear(bits, start, tb->size); if (end > start) { lmAllocVar(lm, range); range->start = start; range->size = (end - start); slAddHead(&rangeList, range); } } slReverse(&rangeList); tb->maskBlockCount = slCount(rangeList); if (tb->maskBlockCount > 0) { AllocArray(tb->maskStarts, tb->maskBlockCount); AllocArray(tb->maskSizes, tb->maskBlockCount); for (i = 0, range = rangeList; range != NULL; i++, range = range->next) { tb->maskStarts[i] = range->start; tb->maskSizes[i] = range->size; } } lmCleanup(&lm); bitFree(&bits); bHel->val = NULL; } } }
void covStatsFree(struct covStats **pCov) /* Free up memory associated with covStats. */ { struct covStats *cov = *pCov; if (cov != NULL) { bitFree(&cov->bits); freez(pCov); } }
void visiMatchFree(struct visiMatch **pMatch) /* Free up memory associated with visiMatch */ { struct visiMatch *match = *pMatch; if (match != NULL) { bitFree(&match->wordBits); freez(pMatch); } }
void freeDnaSeq(struct dnaSeq **pSeq) /* Free up DNA seq. (And unlink underlying resource node.) */ { struct dnaSeq *seq = *pSeq; if (seq == NULL) return; freeMem(seq->name); freeMem(seq->dna); bitFree(&seq->mask); freez(pSeq); }
void visiMatchFree(struct visiMatch **pMatch) /* Free up memory associated with visiMatch */ { struct visiMatch *match = *pMatch; if (match != NULL) { #ifdef OLD bitFree(&match->wordBits); #endif /* OLD */ freez(pMatch); } }
void statsOnSpan(char *database, struct sqlConnection *conn, struct region *r, char *axtBestDir, struct stats *stats, FILE *f, struct scoredWindow **pWinList) /* Gather region info on one chromosome/region. */ { char *chrom = r->chrom; int chromSize = hChromSize(database, chrom); Bits *maskBits = bitAlloc(chromSize); Bits *aliBits = bitAlloc(chromSize); Bits *matchBits = bitAlloc(chromSize); Bits *geneBits = bitAlloc(chromSize); /* Set up aliBits and matchBits for to be turned on * where bases align, and where bases align and match. * Zero both bitmaps in areas that are transcribed. */ setAliBits(axtBestDir, chrom, chromSize, aliBits, matchBits); maskFeatures(database, conn, chrom, chromSize, maskBits); bitNot(maskBits, chromSize); bitAnd(aliBits, maskBits, chromSize); bitAnd(matchBits, maskBits, chromSize); /* Set up maskBits to have 0's on gaps in genome */ bitClear(maskBits, chromSize); fbOrTableBits(database, maskBits, "gap", chrom, chromSize, conn); bitNot(maskBits, chromSize); /* Set up bitmap for Ensemble or mRNA. */ fbOrTableBits(database, geneBits, "ensGene", chrom, chromSize, conn); fbOrTableBits(database, geneBits, "mrna", chrom, chromSize, conn); /* Calculate various stats on windows. */ addToStats(stats, aliBits, matchBits, geneBits, maskBits, r, f, pWinList); /* Cleanup */ bitFree(&geneBits); bitFree(&maskBits); bitFree(&aliBits); bitFree(&matchBits); }
void searchOneMaskTrim(struct dnaSeq *seq, boolean isProt, struct genoFind *gf, FILE *outFile, struct hash *maskHash, long long *retTotalSize, int *retCount) /* Search a single sequence against a single genoFind index. */ { boolean maskQuery = (qMask != NULL); boolean lcMask = (qMask != NULL && sameWord(qMask, "lower")); Bits *qMaskBits = maskQuerySeq(seq, isProt, maskQuery, lcMask); struct dnaSeq trimmedSeq; ZeroVar(&trimmedSeq); trimSeq(seq, &trimmedSeq); if (qType == gftRna || qType == gftRnaX) memSwapChar(trimmedSeq.dna, trimmedSeq.size, 'u', 't'); searchOne(&trimmedSeq, gf, outFile, isProt, maskHash, qMaskBits); *retTotalSize += seq->size; *retCount += 1; bitFree(&qMaskBits); }
void chromFeatureBits(struct sqlConnection *conn,char *database, char *chrom, int tableCount, char *tables[], FILE *bedFile, FILE *faFile, FILE *binFile, struct bed *bedRegionList, FILE *bedOutFile, int chromSize, int *retChromBits, int *retFirstTableBits, int *retSecondTableBits) /* featureBits - Correlate tables via bitmap projections and booleans * on one chromosome. */ { int i; Bits *acc = NULL; Bits *bits = NULL; char *table; acc = bitAlloc(chromSize); bits = bitAlloc(chromSize); for (i=0; i<tableCount; ++i) { boolean not = FALSE; table = tables[i]; if (table[0] == '!') { not = TRUE; ++table; } if (i == 0) { orTable(database, acc, table, chrom, chromSize, conn); if (not) bitNot(acc, chromSize); if (retFirstTableBits != NULL) *retFirstTableBits = bitCountRange(acc, 0, chromSize); } else { bitClear(bits, chromSize); orTable(database, bits, table, chrom, chromSize, conn); if (not) bitNot(bits, chromSize); if (i == 1 && retSecondTableBits != NULL) *retSecondTableBits = bitCountRange(bits, 0, chromSize); /* feature/bug - the above does not respect minSize */ if (orLogic) bitOr(acc, bits, chromSize); else bitAnd(acc, bits, chromSize); } } if (notResults) bitNot(acc, chromSize); *retChromBits = bitCountRange(acc, 0, chromSize); if (bedFile != NULL || faFile != NULL) { minSize = optionInt("minSize", minSize); bitsToBed(database, acc, chrom, chromSize, bedFile, faFile, minSize); } if (binFile != NULL) { binSize = optionInt("binSize", binSize); binOverlap = optionInt("binOverlap", binOverlap); bitsToBins(acc, chrom, chromSize, binFile, binSize, binOverlap); } if (bedOutFile != NULL) bitsToRegions(acc, chrom, chromSize, bedRegionList, bedOutFile); bitFree(&acc); bitFree(&bits); }
struct bbiInterval *intersectedFilteredBbiIntervalsOnRegion(struct sqlConnection *conn, struct bbiFile *bwf, struct region *region, enum wigCompare filterCmp, double filterLl, double filterUl, struct lm *lm) /* Get list of bbiIntervals (more-or-less bedGraph things from bigWig) out of bigWig file * and if necessary apply filter and intersection. Return list which is allocated in lm. */ { char *chrom = region->chrom; int chromSize = hChromSize(database, chrom); struct bbiInterval *iv, *ivList = bigWigIntervalQuery(bwf, chrom, region->start, region->end, lm); /* Run filter if necessary */ if (filterCmp != wigNoOp_e) { struct bbiInterval *next, *newList = NULL; for (iv = ivList; iv != NULL; iv = next) { next = iv->next; if (wigCompareValFilter(iv->val, filterCmp, filterLl, filterUl)) { slAddHead(&newList, iv); } } slReverse(&newList); ivList = newList; } /* Run intersection if necessary */ if (anyIntersection()) { boolean isBpWise = intersectionIsBpWise(); Bits *bits2 = bitsForIntersectingTable(conn, region, chromSize, isBpWise); struct bbiInterval *next, *newList = NULL; double moreThresh = cartCgiUsualDouble(cart, hgtaMoreThreshold, 0)*0.01; double lessThresh = cartCgiUsualDouble(cart, hgtaLessThreshold, 100)*0.01; char *op = cartString(cart, hgtaIntersectOp); for (iv = ivList; iv != NULL; iv = next) { next = iv->next; int start = iv->start; int size = iv->end - start; int overlap = bitCountRange(bits2, start, size); if (isBpWise) { if (overlap == size) { slAddHead(&newList, iv); } else if (overlap > 0) { /* Here we have to break things up. */ double val = iv->val; struct bbiInterval *partIv = iv; // Reuse memory for first interval int s = iv->start, end = iv->end; for (;;) { s = bitFindSet(bits2, s, end); if (s >= end) break; int bitsSet = bitFindClear(bits2, s, end) - s; if (partIv == NULL) lmAllocVar(lm, partIv); partIv->start = s; partIv->end = s + bitsSet; partIv->val = val; slAddHead(&newList, partIv); partIv = NULL; s += bitsSet; if (s >= end) break; } } } else { double coverage = (double)overlap/size; if (intersectOverlapFilter(op, moreThresh, lessThresh, coverage)) { slAddHead(&newList, iv); } } } slReverse(&newList); ivList = newList; bitFree(&bits2); } return ivList; }
void splitByGap(char *inName, int pieceSize, char *outRoot, long long estSize) /* Split up file into pieces at most pieceSize bases long, at gap boundaries * if possible. */ { off_t pieces = (estSize + pieceSize-1)/pieceSize; int digits = digitsBaseTen(pieces); int minGapSize = optionInt("minGapSize", 1000); boolean noGapDrops = optionExists("noGapDrops"); int maxN = optionInt("maxN", pieceSize-1); boolean oneFile = optionExists("oneFile"); char fileName[512]; char dirOnly[256], noPath[128]; int pos, pieceIx = 0, writeCount = 0; struct dnaSeq seq; struct lineFile *lf = lineFileOpen(inName, TRUE); FILE *f = NULL; Bits *bits = NULL; int seqCount = 0; char *outFile = optionVal("out", NULL); char *liftFile = optionVal("lift", NULL); FILE *lift = NULL; ZeroVar(&seq); if (minGapSize < 1) errAbort("ERROR: minGapSize must be > 0"); splitPath(outRoot, dirOnly, noPath, NULL); if (oneFile) { sprintf(fileName, "%s.fa", outRoot); f = mustOpen(fileName, "w"); } else fileName[0] = '\0'; if (liftFile) lift = mustOpen(liftFile, "w"); while (faMixedSpeedReadNext(lf, &seq.dna, &seq.size, &seq.name)) { bits = bitAlloc(seq.size); setBitsN(seq.dna, seq.size, bits); ++seqCount; if (outFile != NULL) { if (seqCount > 1) errAbort("Can only handle in files with one sequence using out option"); bitsForOut(outFile, seq.size, bits); } pos = 0; while (pos < seq.size) { boolean gotGap = FALSE; int gapStart = 0; int gapSize = 0; int endSize = seq.size - pos; int thisSize = min(endSize, pieceSize); int startGapLen = 0; if (seq.dna[pos] == 'n' || seq.dna[pos] == 'N') { startGapLen = bitFindClear(bits, pos, endSize) - pos; verbose(3,"#\tstarting gap at %d for length: %d\n", pos, startGapLen ); } /* if a block is all gap for longer than minGapSize, then * keep it all together in one large piece */ if (startGapLen > minGapSize) { if (noGapDrops) { writeOneByGap(oneFile, outRoot, digits, &pieceIx, f, noPath, pos, startGapLen, &seq, lift, &writeCount, fileName); } else verbose(3,"#\tbeginning gap of %d size skipped\n", startGapLen); thisSize = startGapLen; } else if (thisSize > 0 && bitCountRange(bits, pos, thisSize) <= maxN) { if (endSize>pieceSize) /* otherwise chops tiny piece at very end */ { gotGap = findLastGap(&(seq.dna[pos]), thisSize, endSize, minGapSize, &gapStart, &gapSize); if (gotGap) thisSize = gapStart; } writeOneByGap(oneFile, outRoot, digits, &pieceIx, f, noPath, pos, thisSize, &seq, lift, &writeCount, fileName); } pos += thisSize; if (gotGap) { /* last block is all gap, write it all out */ /*if ((pos + gapSize) >= seq.size)*/ if (noGapDrops) { writeOneByGap(oneFile, outRoot, digits, &pieceIx, f, noPath, pos, gapSize, &seq ,lift, &writeCount, fileName); verbose(3, "#\tadding gapSize %d to pos %d -> %d and writing gap\n", gapSize, pos, pos+gapSize); } else verbose(3,"#\tadding gapSize %d to pos %d -> %d\n", gapSize, pos, pos+gapSize); pos += gapSize; } } bitFree(&bits); } carefulClose(&f); carefulClose(&lift); lineFileClose(&lf); printf("%d pieces of %d written\n", writeCount, pieceIx); }
void splitByCount(char *inName, int pieceSize, char *outRoot, off_t estSize, int extra) /* Split up file into pieces pieceSize long. */ { off_t pieces = (estSize + pieceSize-1)/pieceSize; int digits = digitsBaseTen(pieces); int maxN = optionInt("maxN", pieceSize-1); boolean oneFile = optionExists("oneFile"); char fileName[PATH_LEN]; char dirOnly[PATH_LEN], noPath[128]; int pos, pieceIx = 0, writeCount = 0; struct dnaSeq seq; struct lineFile *lf = lineFileOpen(inName, TRUE); FILE *f = NULL; Bits *bits = NULL; int seqCount = 0; char *outFile = optionVal("out", NULL); char *liftFile = optionVal("lift", NULL); FILE *lift = NULL; ZeroVar(&seq); splitPath(outRoot, dirOnly, noPath, NULL); if (oneFile) { sprintf(fileName, "%s.fa", outRoot); f = mustOpen(fileName, "w"); } if (liftFile) lift = mustOpen(liftFile, "w"); /* Count number of N's from s[0] to s[size-1]. * Treat any parts past end of string as N's. */ while (faMixedSpeedReadNext(lf, &seq.dna, &seq.size, &seq.name)) { bits = bitAlloc(seq.size); setBitsN(seq.dna, seq.size, bits); ++seqCount; if (outFile != NULL) { if (seqCount > 1) errAbort("Can only handle in files with one sequence using out option"); bitsForOut(outFile, seq.size, bits); } for (pos = 0; pos < seq.size; pos += pieceSize) { char numOut[128]; int thisSize = seq.size - pos; if (thisSize > (pieceSize + extra)) thisSize = pieceSize + extra; if ((thisSize <= extra) && (pos > 0)) break; /* nobody wants duplicate smaller than extra overhang */ if (bitCountRange(bits, pos, thisSize) <= maxN) { if (!oneFile) { mkOutPath(fileName, outRoot, digits, pieceIx); f = mustOpen(fileName, "w"); } sprintf(numOut, "%s%0*d", noPath, digits, pieceIx); faWriteNext(f, numOut, seq.dna + pos, thisSize); if (lift) fprintf(lift, "%d\t%s\t%d\t%s\t%d\n", pos, numOut, thisSize, seq.name, seq.size); ++writeCount; if (!oneFile) carefulClose(&f); } pieceIx++; } bitFree(&bits); } carefulClose(&f); carefulClose(&lift); lineFileClose(&lf); printf("%d pieces of %d written\n", writeCount, pieceIx); }
struct bed *getRegionAsMergedBed( char *db, char *table, /* Database and table. */ struct region *region, /* Region to get data for. */ char *filter, /* Filter to add to SQL where clause if any. */ struct hash *idHash, /* Restrict to id's in this hash if non-NULL. */ struct lm *lm, /* Where to allocate memory. */ int *retFieldCount) /* Number of fields. */ /* Return a bed list of all items in the given range in subtrack-merged table. * Cleanup result via lmCleanup(&lm) rather than bedFreeList. */ { if (! anySubtrackMerge(db, table)) return getRegionAsBed(db, table, region, filter, idHash, lm, retFieldCount); else { struct hTableInfo *hti = getHtiOnDb(database, table); int chromSize = hChromSize(database, region->chrom); Bits *bits1 = NULL; Bits *bits2 = NULL; struct bed *bedMerged = NULL; struct trackDb *subtrack = NULL; char *primaryType = findTypeForTable(database,curTrack,table, ctLookupName); char *op = cartString(cart, hgtaSubtrackMergeOp); boolean isBpWise = (sameString(op, "and") || sameString(op, "or")); double moreThresh = cartDouble(cart, hgtaSubtrackMergeMoreThreshold); double lessThresh = cartDouble(cart, hgtaSubtrackMergeLessThreshold); boolean firstTime = TRUE; if (sameString(op, "cat")) { struct bed *bedList = getRegionAsBed(db, table, region, filter, idHash, lm, retFieldCount); struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(curTrack->subtracks); struct slRef *tdbRef; for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next) { subtrack = tdbRef->val; if (! sameString(curTable, subtrack->table) && isSubtrackMerged(subtrack->table) && sameString(subtrack->type, primaryType)) { struct bed *bedList2 = getRegionAsBed(db, subtrack->table, region, NULL, idHash, lm, retFieldCount); bedList = slCat(bedList, bedList2); } } slFreeList(&tdbRefList); return bedList; } bits1 = bitAlloc(chromSize+8); bits2 = bitAlloc(chromSize+8); /* If doing a base-pair-wise operation, then start with the primary * subtrack's ranges in bits1, and AND/OR all the selected subtracks' * ranges into bits1. If doing a non-bp-wise intersection, then * start with all bits clear in bits1, and then OR selected subtracks' * ranges into bits1. */ if (isBpWise) { struct lm *lm2 = lmInit(64*1024); struct bed *bedList1 = getRegionAsBed(db, table, region, filter, idHash, lm2, retFieldCount); bedOrBits(bits1, chromSize, bedList1, hti->hasBlocks, 0); lmCleanup(&lm2); } struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(curTrack->subtracks); struct slRef *tdbRef; for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next) { subtrack = tdbRef->val; if (! sameString(curTable, subtrack->table) && isSubtrackMerged(subtrack->table) && sameString(subtrack->type, primaryType)) { struct hTableInfo *hti2 = getHtiOnDb(database, subtrack->table); struct lm *lm2 = lmInit(64*1024); struct bed *bedList2 = getRegionAsBed(db, subtrack->table, region, NULL, idHash, lm2, NULL); if (firstTime) firstTime = FALSE; else bitClear(bits2, chromSize); bedOrBits(bits2, chromSize, bedList2, hti2->hasBlocks, 0); if (sameString(op, "and")) bitAnd(bits1, bits2, chromSize); else bitOr(bits1, bits2, chromSize); lmCleanup(&lm2); } } slFreeList(&tdbRefList); if (isBpWise) { bedMerged = bitsToBed4List(bits1, chromSize, region->chrom, 1, region->start, region->end, lm); if (retFieldCount != NULL) *retFieldCount = 4; } else { struct bed *bedList1 = getRegionAsBed(db, table, region, filter, idHash, lm, retFieldCount); bedMerged = filterBedByOverlap(bedList1, hti->hasBlocks, op, moreThresh, lessThresh, bits1, chromSize); } bitFree(&bits1); bitFree(&bits2); return bedMerged; } }
static struct bed *intersectOnRegion( struct sqlConnection *conn, /* Open connection to database. */ struct region *region, /* Region to work inside */ char *table1, /* Table input list is from. */ struct bed *bedList1, /* List before intersection, should be * all within region. */ struct lm *lm, /* Local memory pool. */ int *retFieldCount) /* Field count. */ /* Intersect bed list, consulting CGI vars to figure out * with what table and how. Return intersected result, * which is independent from input. This potentially will * chew up bedList1. */ { /* Grab parameters for intersection from cart. */ double moreThresh = cartCgiUsualDouble(cart, hgtaMoreThreshold, 0); double lessThresh = cartCgiUsualDouble(cart, hgtaLessThreshold, 100); boolean invTable = cartCgiUsualBoolean(cart, hgtaInvertTable, FALSE); char *op = intersectOp(); /* --- TODO MIKE - replace bedList2, bits2 with baseMask stuff. */ /* Load up intersecting bedList2 (to intersect with) */ int chromSize = hChromSize(database, region->chrom); boolean isBpWise = (sameString("and", op) || sameString("or", op)); Bits *bits2 = bitsForIntersectingTable(conn, region, chromSize, isBpWise); /* Set up some other local vars. */ struct hTableInfo *hti1 = getHti(database, table1, conn); struct bed *intersectedBedList = NULL; /* Produce intersectedBedList. */ if (isBpWise) { /* --- TODO MIKE - replace, bits1 with baseMask stuff. */ /* Base-pair-wise operation: get bitmap for primary table too */ Bits *bits1 = bitAlloc(chromSize+8); boolean hasBlocks = hti1->hasBlocks; if (retFieldCount != NULL && (*retFieldCount < 12)) hasBlocks = FALSE; bedOrBits(bits1, chromSize, bedList1, hasBlocks, 0); /* invert inputs if necessary */ if (invTable) bitNot(bits1, chromSize); /* do the intersection/union */ if (sameString("and", op)) bitAnd(bits1, bits2, chromSize); else bitOr(bits1, bits2, chromSize); /* clip to region if necessary: */ if (region->start > 0) bitClearRange(bits1, 0, region->start); if (region->end < chromSize) bitClearRange(bits1, region->end, (chromSize - region->end)); /* translate back to bed */ intersectedBedList = bitsToBed4List(bits1, chromSize, region->chrom, 1, region->start, region->end, lm); if (retFieldCount != NULL) *retFieldCount = 4; bitFree(&bits1); } else intersectedBedList = filterBedByOverlap(bedList1, hti1->hasBlocks, op, moreThresh, lessThresh, bits2, chromSize); bitFree(&bits2); return intersectedBedList; }