struct bed *findBedsFromGp(struct genomeBit *gp, struct bed *bedList) /* Look through the bed list for beds that are contained in the genome bit. */ { struct bed *bed = NULL, *retList = NULL, *bedClone = NULL; boolean unique = TRUE; for(bed = bedList; bed != NULL; bed = bed->next) { if(bed->chromStart > gp->chromStart && bed->chromEnd < gp->chromEnd && sameString(bed->chrom, gp->chrom)) { if(retList != NULL) { if(unique) { unique = FALSE; warn("More than one bed for genome bit %s:%d-%d.", gp->chrom, gp->chromStart, gp->chromEnd); multipleBedForGp++; } } bedClone = cloneBed(bed); slAddHead(&retList, bedClone); } } return retList; }
struct bed *bedFilterByWildNames(struct bed *bedList, struct slName *wildNames) /* Given a bed list and a list of names that may include wildcard characters, * return the list of bed items whose name matches at least one wildName. */ { struct bed *bedListOut = NULL, *bed=NULL; struct slName *wildName=NULL; for (bed=bedList; bed != NULL; bed=bed->next) { for (wildName=wildNames; wildName != NULL; wildName=wildName->next) { if (bed->name == NULL) errAbort("bedFilterByWildNames: bed item at %s:%d-%d has no name.", bed->chrom, bed->chromStart+1, bed->chromEnd); if (wildMatch(wildName->name, bed->name)) { struct bed *newBed = cloneBed(bed); slAddHead(&bedListOut, newBed); break; } } } slReverse(&bedListOut); return bedListOut; }
struct bed *bedFilterListInRange(struct bed *bedListIn, struct bedFilter *bf, char *chrom, int winStart, int winEnd) /* Given a bed list, a position range, and a bedFilter which specifies * constraints on bed fields, return the list of bed items that meet * the constraints. If chrom is NULL, position range is ignored. */ { struct bed *bedListOut = NULL, *bed; for (bed=bedListIn; bed != NULL; bed=bed->next) { boolean passes = TRUE; if (chrom != NULL) { passes &= (sameString(bed->chrom, chrom) && (bed->chromStart < winEnd) && (bed->chromEnd > winStart)); } if (bf != NULL && passes) { passes &= bedFilterOne(bf, bed); } if (passes) { struct bed *newBed = cloneBed(bed); slAddHead(&bedListOut, newBed); } } slReverse(&bedListOut); return(bedListOut); }
void outputBed(struct cassetteSeq *cseq, FILE *primerBed) /* Output a bed linked features track to see where primers are. */ { struct bed *bed = NULL; struct bed *cbed = cseq->bed; int leftStart=0, rightStart =0; bed = cloneBed(cbed); if(cseq->leftPrimer == NULL || cseq->rightPrimer == NULL) return; leftStart = calcGenomePos(cbed, cseq->leftPrimer, cseq->seq); rightStart = calcGenomePos(cbed, cseq->rightPrimer, cseq->seq); if(sameString(bed->strand, "+")) { bed->chromStart = bed->thickStart = leftStart; bed->chromStarts[0] = 0; bed->blockSizes[0] = strlen(cseq->leftPrimer); bed->chromStarts[1] = rightStart - leftStart; bed->blockSizes[1] = strlen(cseq->leftPrimer); bed->chromEnd = bed->thickEnd = bed->chromStarts[1] + bed->chromStart + bed->blockSizes[1]; } else { bed->chromStart = bed->thickStart = rightStart; bed->chromStarts[0] = 0; bed->blockSizes[0] = strlen(cseq->rightPrimer); bed->chromStarts[1] = leftStart - rightStart; bed->blockSizes[1] = strlen(cseq->rightPrimer); bed->chromEnd = bed->thickEnd = bed->chromStarts[1] + bed->chromStart + bed->blockSizes[1]; } bed->blockCount = 2; checkBedMatchesSeqs(cseq, bed); bedTabOutN(bed, 12, primerBed); bedFree(&bed); }
struct cassetteSeq *cassetteSeqFromBed(struct bed *bed, int targetExon) /* Consruct a cassetteSeq from a bed using the targetExon. */ { struct cassetteSeq *cseq = NULL; int i=0; char buff[1024]; int bedSize=0; int seqSize=0; int targetStart=0; /* Make sure the target exon is valid. */ if(targetExon >= bed->blockCount) errAbort("pickCassettePcrPrimers::cassetteSeqFromBed() - Got request" "for %d targetExon, but only %d exons present in %s\n", targetExon, bed->blockCount, bed->name); AllocVar(cseq); AllocVar(cseq->seq); snprintf(buff, sizeof(buff), "%s:%d-%d_%s", bed->chrom, bed->chromStart, bed->chromEnd, bed->name); cseq->name = cloneString(buff); bedSize = countBedSize(bed) + 1; cseq->seq->dna = needMem(sizeof(char)*bedSize); cseq->bed = cloneBed(bed); for(i=0; i<bed->blockCount; i++) { struct dnaSeq *seq = NULL; int chromStart = bed->chromStarts[i] + bed->chromStart; int chromEnd = bed->blockSizes[i] + chromStart; seq = hChromSeq(bed->chrom, chromStart, chromEnd); sprintf(cseq->seq->dna+seqSize, "%s", seq->dna); if(targetExon == i) targetStart = seqSize; seqSize += bed->blockSizes[i]; dnaSeqFree(&seq); } cseq->seq->size = seqSize; if(sameString(bed->strand, "-")) { reverseComplement(cseq->seq->dna, cseq->seq->size); targetStart = cseq->seq->size - targetStart - bed->blockSizes[targetExon]; } cseq->targetStart = targetStart; cseq->targetEnd = targetStart + bed->blockSizes[targetExon]; snprintf(cseq->strand, sizeof(cseq->strand), "%s", bed->strand); return cseq; }
struct bed *bedFilterByNameHash(struct bed *bedList, struct hash *nameHash) /* Given a bed list and a hash of names to keep, return the list of bed * items whose name is in nameHash. */ { struct bed *bedListOut = NULL, *bed=NULL; for (bed=bedList; bed != NULL; bed=bed->next) { if (bed->name == NULL) errAbort("bedFilterByNameHash: bed item at %s:%d-%d has no name.", bed->chrom, bed->chromStart+1, bed->chromEnd); if (hashLookup(nameHash, bed->name) != NULL) { struct bed *newBed = cloneBed(bed); slAddHead(&bedListOut, newBed); } } slReverse(&bedListOut); return bedListOut; }
static struct bed* subset_beds(char* sectionString, struct bed** pRegions, struct hash* chromHash) /* in the situation where both a regions bed file is given AND the filename specifies subsections, */ /* intersect the two. For simplictity sake, */ { struct bed* fname_ranges = parseSectionString(sectionString, chromHash); struct bed* bed; struct bed* subset = NULL; struct bed* regions = *pRegions; slSort(&fname_ranges, bedCmp); bed = fname_ranges; while (bed != NULL) { /* each iteration of the loop should be a separate chrom */ struct bed* region; struct rbTree* tree = rangeTreeNew(); while ((bed != NULL) && (bed->next != NULL) && (sameString(bed->chrom, bed->next->chrom))) { rangeTreeAdd(tree, bed->chromStart, bed->chromEnd); bed = bed->next; } rangeTreeAdd(tree, bed->chromStart, bed->chromEnd); /* now we're at a point that we're dealing only with one chromosome. */ for (region = regions; region != NULL; region = region->next) { if (sameString(region->chrom, bed->chrom) && rangeTreeOverlaps(tree, region->chromStart, region->chromEnd) && rangeTreeFindEnclosing(tree, region->chromStart, region->chromEnd)) { struct bed* clone = cloneBed(region); slAddHead(&subset, clone); } else if (sameString(region->chrom, bed->chrom) && rangeTreeOverlaps(tree, region->chromStart, region->chromEnd)) errAbort("range specified in file overlaps but is not contained by range specified on command-line"); } rangeTreeFree(&tree); bed = bed->next; } if (subset == NULL) { errAbort("no ranges specified in file were contained in ranges specified on command-line"); } slReverse(&subset); bedFreeList(&fname_ranges); bedFreeList(pRegions); return subset; }
boolean doGetBedOrCt(struct sqlConnection *conn, boolean doCt, boolean doCtFile, boolean redirectToGb) /* Actually output bed or custom track. Return TRUE unless no results. */ { char *db = cloneString(database); char *table = curTable; struct hTableInfo *hti = getHti(db, table, conn); struct featureBits *fbList = NULL, *fbPtr; struct customTrack *ctNew = NULL; boolean doCtHdr = (cartUsualBoolean(cart, hgtaPrintCustomTrackHeaders, FALSE) || doCt || doCtFile); char *ctWigOutType = cartCgiUsualString(cart, hgtaCtWigOutType, outWigData); char *fbQual = fbOptionsToQualifier(); char fbTQ[128]; int fields = hTableInfoBedFieldCount(hti); boolean gotResults = FALSE; struct region *region, *regionList = getRegions(); boolean isBedGr = isBedGraph(curTable); boolean isBgWg = isBigWigTable(curTable); boolean needSubtrackMerge = anySubtrackMerge(database, curTable); boolean doDataPoints = FALSE; boolean isWig = isWiggle(database, table); struct wigAsciiData *wigDataList = NULL; struct dataVector *dataVectorList = NULL; boolean doRgb = bedItemRgb(hTrackDbForTrack(db, curTable)); if (!cartUsualBoolean(cart, hgtaDoGreatOutput, FALSE) && !doCt) { textOpen(); } if (cartUsualBoolean(cart, hgtaDoGreatOutput, FALSE)) fputs("#", stdout); if ((isWig || isBedGr || isBgWg) && sameString(outWigData, ctWigOutType)) doDataPoints = TRUE; for (region = regionList; region != NULL; region = region->next) { struct bed *bedList = NULL, *bed; struct lm *lm = lmInit(64*1024); struct dataVector *dv = NULL; if (isWig && doDataPoints) { if (needSubtrackMerge) { dv = wiggleDataVector(curTrack, curTable, conn, region); if (dv != NULL) slAddHead(&dataVectorList, dv); } else { int count = 0; struct wigAsciiData *wigData = NULL; struct wigAsciiData *asciiData; struct wigAsciiData *next; wigData = getWiggleAsData(conn, curTable, region); for (asciiData = wigData; asciiData; asciiData = next) { next = asciiData->next; if (asciiData->count) { slAddHead(&wigDataList, asciiData); ++count; } } slReverse(&wigDataList); } } else if (isBedGr && doDataPoints) { dv = bedGraphDataVector(curTable, conn, region); if (dv != NULL) slAddHead(&dataVectorList, dv); } else if (isBgWg && doDataPoints) { dv = bigWigDataVector(curTable, conn, region); if (dv != NULL) slAddHead(&dataVectorList, dv); } else if (isWig || isBgWg) { dv = wiggleDataVector(curTrack, curTable, conn, region); bedList = dataVectorToBedList(dv); dataVectorFree(&dv); } else if (isBedGr) { bedList = getBedGraphAsBed(conn, curTable, region); } else { bedList = cookedBedList(conn, curTable, region, lm, &fields); } /* this is a one-time only initial creation of the custom track * structure to receive the results. gotResults turns it off after * the first time. */ if (doCtHdr && !gotResults && ((bedList != NULL) || (wigDataList != NULL) || (dataVectorList != NULL))) { ctNew = beginCustomTrack(table, fields, doCt, (isWig || isBedGr || isBgWg), doDataPoints); } if (doDataPoints && (wigDataList || dataVectorList)) gotResults = TRUE; else { if ((fbQual == NULL) || (fbQual[0] == 0)) { for (bed = bedList; bed != NULL; bed = bed->next) { if (bed->name != NULL) { subChar(bed->name, ' ', '_'); } if (doCt) { struct bed *dupe = cloneBed(bed); /* Out of local memory. */ slAddHead(&ctNew->bedList, dupe); } else { if (doRgb) bedTabOutNitemRgb(bed, fields, stdout); else bedTabOutN(bed, fields, stdout); } gotResults = TRUE; } } else { safef(fbTQ, sizeof(fbTQ), "%s:%s", hti->rootName, fbQual); fbList = fbFromBed(db, fbTQ, hti, bedList, 0, 0, FALSE, FALSE); if (fields >= 6) fields = 6; else if (fields >= 4) fields = 4; else fields = 3; if (doCt && ctNew) { ctNew->fieldCount = fields; safef(ctNew->tdb->type, strlen(ctNew->tdb->type)+1, "bed %d", fields); } for (fbPtr=fbList; fbPtr != NULL; fbPtr=fbPtr->next) { if (fbPtr->name != NULL) { char *ptr = strchr(fbPtr->name, ' '); if (ptr != NULL) *ptr = 0; } if (doCt) { struct bed *fbBed = fbToBedOne(fbPtr); slAddHead(&ctNew->bedList, fbBed ); } else { if (fields >= 6) hPrintf("%s\t%d\t%d\t%s\t%d\t%c\n", fbPtr->chrom, fbPtr->start, fbPtr->end, fbPtr->name, 0, fbPtr->strand); else if (fields >= 4) hPrintf("%s\t%d\t%d\t%s\n", fbPtr->chrom, fbPtr->start, fbPtr->end, fbPtr->name); else hPrintf("%s\t%d\t%d\n", fbPtr->chrom, fbPtr->start, fbPtr->end); } gotResults = TRUE; } featureBitsFreeList(&fbList); } } bedList = NULL; lmCleanup(&lm); } if (!gotResults) { hPrintf(NO_RESULTS); } else if (doCt) { int wigDataSize = 0; /* Load existing custom tracks and add this new one: */ struct customTrack *ctList = getCustomTracks(); removeNamedCustom(&ctList, ctNew->tdb->table); if (doDataPoints) { if (needSubtrackMerge || isBedGr || isBgWg) { slReverse(&dataVectorList); wigDataSize = dataVectorWriteWigAscii(dataVectorList, ctNew->wigAscii, 0, NULL); // TODO: see if can make prettier wig output here that // doesn't necessarily have one value per base } else { struct wiggleDataStream *wds = NULL; /* create an otherwise empty wds so we can print out the list */ wds = wiggleDataStreamNew(); wds->ascii = wigDataList; wigDataSize = wds->asciiOut(wds, db, ctNew->wigAscii, TRUE, FALSE); #if defined(DEBUG) /* dbg */ /* allow file readability for debug */ chmod(ctNew->wigAscii, 0666); #endif wiggleDataStreamFree(&wds); } } else slReverse(&ctNew->bedList); slAddHead(&ctList, ctNew); /* Save the custom tracks out to file (overwrite the old file): */ customTracksSaveCart(db, cart, ctList); /* Put up redirect-to-browser page. */ if (redirectToGb) { char browserUrl[256]; char headerText[512]; int redirDelay = 3; safef(browserUrl, sizeof(browserUrl), "%s?%s&db=%s", hgTracksName(), cartSidUrlString(cart), database); safef(headerText, sizeof(headerText), "<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"%d;URL=%s\">", redirDelay, browserUrl); webStartHeader(cart, database, headerText, "Table Browser: %s %s: %s", hOrganism(database), freezeName, "get custom track"); if (doDataPoints) { hPrintf("There are %d data points in custom track. ", wigDataSize); } else { hPrintf("There are %d items in custom track. ", slCount(ctNew->bedList)); } hPrintf("You will be automatically redirected to the genome browser in\n" "%d seconds, or you can \n" "<A HREF=\"%s\">click here to continue</A>.\n", redirDelay, browserUrl); } } else if (doDataPoints) { if (needSubtrackMerge || isBedGr || isBgWg) { slReverse(&dataVectorList); dataVectorWriteWigAscii(dataVectorList, "stdout", 0, NULL); } else { /* create an otherwise empty wds so we can print out the list */ struct wiggleDataStream *wds = NULL; wds = wiggleDataStreamNew(); wds->ascii = wigDataList; wds->asciiOut(wds, db, "stdout", TRUE, FALSE); wiggleDataStreamFree(&wds); } } return gotResults; }