39e533cc9ffcb46d9c484dc09a387a031a739391 Merge parents 1c86690 f642bab kate Mon Sep 24 16:35:53 2018 -0700 Updating from master diff --cc src/hg/lib/interact.c index 1d74ada,e27d480..43f4404 --- src/hg/lib/interact.c +++ src/hg/lib/interact.c @@@ -333,135 -333,139 +333,233 @@@ if (aDist < 0) { if (bDist < 0) return 0; return 1; } if (bDist < 0) return -1; // same chromosome return aDist - bDist; } struct interact *interactLoadAndValidate(char **row) /* Load a interact from row fetched with select * from interact - * from database, validating fields. Dispose of this with interactFree(). */ + * from database, validating fields. Dispose of this with interactFree(). + * This currently differs from auto-gened only by it's handling of color field */ // TODO: more validating { struct interact *ret; AllocVar(ret); ret->chrom = cloneString(row[0]); ret->chromStart = sqlUnsigned(row[1]); ret->chromEnd = sqlUnsigned(row[2]); ret->name = cloneString(row[3]); ret->score = sqlUnsigned(row[4]); ret->value = sqlDouble(row[5]); ret->exp = cloneString(row[6]); - ret->color = bedParseColor(row[7]); + ret->color = bedParseColor(row[7]); // handle #NNNNNN, and HTML color (as well as rgb) ret->sourceChrom = cloneString(row[8]); ret->sourceStart = sqlUnsigned(row[9]); ret->sourceEnd = sqlUnsigned(row[10]); ret->sourceName = cloneString(row[11]); ret->sourceStrand = cloneString(row[12]); ret->targetChrom = cloneString(row[13]); ret->targetStart = sqlUnsigned(row[14]); ret->targetEnd = sqlUnsigned(row[15]); ret->targetName = cloneString(row[16]); ret->targetStrand = cloneString(row[17]); return ret; } +void interactRegionCenters(struct interact *inter, int *sourceCenter, int *targetCenter) +/* Return genomic position of endpoint centers */ +{ +assert(sourceCenter); +assert(targetCenter); +*sourceCenter = interactRegionCenter(inter->sourceStart, inter->sourceEnd); +*targetCenter = interactRegionCenter(inter->targetStart, inter->targetEnd); +} + +struct bed *interactToBed(struct interact *inter) +/* Convert an interact to a BED12 (actually, BED15+label) */ +{ +struct bed *bed = NULL; +AllocVar(bed); + +bed->chrom = inter->chrom; +// expand extents to edges of endpoints +// NOTE: this should be changed in schema defn +//bed->chromStart = inter->chromStart; +bed->chromStart = min(inter->sourceStart, inter->targetStart); +//bed->chromEnd = inter->chromEnd; +bed->chromEnd = max(inter->sourceEnd, inter->targetEnd); +bed->thickStart = bed->chromStart; +bed->thickEnd = bed->chromEnd; +bed->name = inter->name; +bed->score = inter->score; +bed->itemRgb = inter->color; +AllocArray(bed->blockSizes, 2); +AllocArray(bed->chromStarts, 2); + +char *strand = "+"; +if (differentString(inter->sourceChrom, inter->targetChrom)) + { + // inter-chromosomal + bed->blockCount = 1; + bed->blockSizes[0] = inter->chromEnd - inter->chromStart; + bed->chromStarts[0] = 0; + if sameString(bed->chrom, inter->targetChrom) + strand = "-"; + } +else + { + // same chromosome + int sourceCenter, targetCenter; + interactRegionCenters(inter, &sourceCenter, &targetCenter); + if (targetCenter < sourceCenter) + { + strand = "-"; + if (inter->sourceStart <= inter->targetEnd) + { + // overlapping - use thickStart/End to delineate + bed->blockCount = 1; + bed->blockSizes[0] = bed->chromEnd - bed->chromStart; + bed->chromStarts[0] = 0; + bed->thickStart = targetCenter; + bed->thickEnd = sourceCenter; + } + else + { + bed->blockCount = 2; + bed->blockSizes[1] = inter->sourceEnd - inter->sourceStart; + bed->blockSizes[0] = inter->targetEnd - inter->targetStart; + bed->chromStarts[1] = inter->sourceStart - bed->chromStart; + bed->chromStarts[0] = 0; + } + } + else + { + // forward direction + if (inter->targetStart <= inter->sourceEnd) + { + // overlapping - use thickStart/End to delineate + bed->blockCount = 1; + bed->blockSizes[0] = bed->chromEnd - bed->chromStart; + bed->chromStarts[0] = 0; + bed->thickStart = sourceCenter; + bed->thickEnd = targetCenter; + } + else + { + bed->blockCount = 2; + bed->blockSizes[0] = inter->sourceEnd - inter->sourceStart; + bed->blockSizes[1] = inter->targetEnd - inter->targetStart; + bed->chromStarts[0] = 0; + bed->chromStarts[1] = inter->targetStart - bed->chromStart; + } + } + } +strcpy(bed->strand, strand); +bed->label = bed->name; +return bed; +} + + struct interact *interactLoadAllAndValidate(char *fileName) + /* Load all interact from a whitespace-separated file. + * Dispose of this with interactFreeList(). */ + { + struct interact *list = NULL, *el; + struct lineFile *lf = lineFileOpen(fileName, TRUE); + char *row[18]; + while (lineFileRow(lf, row)) + { + el = interactLoadAndValidate(row); + slAddHead(&list, el); + } + lineFileClose(&lf); + slReverse(&list); + return list; + } + + void interactOutputCustom(struct interact *el, FILE *f, char sep, char lastSep) + /* Print out interact. Separate fields with sep. Follow last field with lastSep. + * Differs from auto-gen'ed by printing rgb color */ + { + if (sep == ',') fputc('"',f); + fprintf(f, "%s", el->chrom); + if (sep == ',') fputc('"',f); + fputc(sep,f); + fprintf(f, "%u", el->chromStart); + fputc(sep,f); + fprintf(f, "%u", el->chromEnd); + fputc(sep,f); + if (sep == ',') fputc('"',f); + fprintf(f, "%s", el->name); + if (sep == ',') fputc('"',f); + fputc(sep,f); + fprintf(f, "%u", el->score); + fputc(sep,f); + fprintf(f, "%g", el->value); + fputc(sep,f); + if (sep == ',') fputc('"',f); + fprintf(f, "%s", el->exp); + if (sep == ',') fputc('"',f); + fputc(sep,f); + + // print rgb color + bedOutputRgb(f, el->color); + + fputc(sep,f); + if (sep == ',') fputc('"',f); + fprintf(f, "%s", el->sourceChrom); + if (sep == ',') fputc('"',f); + fputc(sep,f); + fprintf(f, "%u", el->sourceStart); + fputc(sep,f); + fprintf(f, "%u", el->sourceEnd); + fputc(sep,f); + if (sep == ',') fputc('"',f); + fprintf(f, "%s", el->sourceName); + if (sep == ',') fputc('"',f); + fputc(sep,f); + if (sep == ',') fputc('"',f); + fprintf(f, "%s", el->sourceStrand); + if (sep == ',') fputc('"',f); + fputc(sep,f); + if (sep == ',') fputc('"',f); + fprintf(f, "%s", el->targetChrom); + if (sep == ',') fputc('"',f); + fputc(sep,f); + fprintf(f, "%u", el->targetStart); + fputc(sep,f); + fprintf(f, "%u", el->targetEnd); + fputc(sep,f); + if (sep == ',') fputc('"',f); + fprintf(f, "%s", el->targetName); + if (sep == ',') fputc('"',f); + fputc(sep,f); + if (sep == ',') fputc('"',f); + fprintf(f, "%s", el->targetStrand); + if (sep == ',') fputc('"',f); + fputc(lastSep,f); + } + + void interactFixRange(struct interact *inter) + /* Set values for chromStart/chromEnd based on source and target start/ends */ + { + int chromStart = min(inter->sourceStart, inter->targetStart); + int chromEnd = max(inter->sourceEnd, inter->targetEnd); + if (inter->chromStart != chromStart) + { + warn("Fixed chromStart: %d to %d. ", inter->chromStart, chromStart); + inter->chromStart = chromStart; + } + if (inter->chromEnd != chromEnd) + { + warn("Fixed chromEnd: %d to %d. ", inter->chromEnd, chromEnd); + inter->chromEnd = chromEnd; + } + } ++