95ac3b9a9a4696a6ff59dc4dc8cb057b6a43c898
kate
Fri Aug 23 16:10:24 2019 -0700
Add multi-region link for all regions in interact cluster. refs #24037
diff --git src/hg/hgc/interactClick.c src/hg/hgc/interactClick.c
index e12f974..3b3483f 100644
--- src/hg/hgc/interactClick.c
+++ src/hg/hgc/interactClick.c
@@ -144,96 +144,145 @@
if (differentString(name, inter->sourceName) && differentString(name, inter->targetName))
continue;
}
}
minStart = inter->chromStart < minStart ? inter->chromStart : minStart;
maxEnd = inter->chromEnd > maxEnd ? inter->chromEnd : maxEnd;
slAddHead(&filtered, ipr);
}
*retStart = minStart;
*retEnd = maxEnd;
// consider sorting on score or position
return filtered;
}
-static char *makeInteractRegionFile(struct interact *inter)
+static char *makeInteractRegionFile(char *name, struct interact *inters)
/* Create bed file in trash directory with end coordinates for multi-region mode */
{
struct tempName mrTn;
trashDirFile(&mrTn, "hgt", "custRgn_interact", ".bed");
FILE *f = fopen(mrTn.forCgi, "w");
if (f == NULL)
errAbort("can't create temp file %s", mrTn.forCgi);
char regionInfo[1024];
// TODO: check chrom bounds
int padding = 200;
//cartSetBoolean(cart, "emAltHighlight", TRUE);
safef(regionInfo, sizeof regionInfo, "#padding %d\n", padding);
mustWrite(f, regionInfo, strlen(regionInfo));
//warn("%s", regionInfo);
-safef(regionInfo, sizeof regionInfo, "#shortDesc %s\n", inter->name);
+safef(regionInfo, sizeof regionInfo, "#shortDesc %s\n", name);
mustWrite(f, regionInfo, strlen(regionInfo));
//warn("%s", regionInfo);
-char *region1Chrom = inter->sourceChrom, *region2Chrom = inter->targetChrom;
-int region1Start = inter->sourceStart, region1End = inter->sourceEnd;
-int region2Start = inter->targetStart, region2End = inter->targetEnd;
-if (sameString(inter->sourceChrom, inter->targetChrom))
- {
- if (inter->sourceStart > inter->targetStart)
- {
- region1Start = inter->targetStart;
- region1End = inter->targetEnd;
- region2Start = inter->sourceStart;
- region2End = inter->sourceEnd;
- }
+
+struct interact *inter = NULL;
+struct bed *region, *regions = NULL;
+struct hash *uniqRegions = hashNew(0);
+for (inter = inters; inter != NULL; inter = inter->next)
+ {
+ char buf[256];
+ //safef(buf, sizeof buf, "%s:%d-%d", region1->chrom, region1->chromStart, region1->chromEnd);
+ safef(buf, sizeof buf, "%s:%d-%d", inter->sourceChrom, inter->sourceStart, inter->sourceEnd);
+ if (!hashLookup(uniqRegions, buf))
+ {
+ hashAdd(uniqRegions, cloneString(buf), NULL);
+ AllocVar(region);
+ region->chrom = inter->sourceChrom;
+ region->chromStart = inter->sourceStart;
+ region->chromEnd = inter->sourceEnd;
+ slAddHead(®ions, region);
}
-else
- {
- if (sameString(inter->chrom, inter->targetChrom))
- {
- region1Chrom = inter->targetChrom;
- region1Start = inter->targetStart;
- region1End = inter->targetEnd;
- region2Chrom = inter->sourceChrom;
- region2Start = inter->sourceStart;
- region2End = inter->sourceEnd;
+ //safef(buf, sizeof buf, "%s:%d-%d", region2->chrom, region2->chromStart, region2->chromEnd);
+ safef(buf, sizeof buf, "%s:%d-%d", inter->targetChrom, inter->targetStart, inter->targetEnd);
+ if (!hashLookup(uniqRegions, buf))
+ {
+ hashAdd(uniqRegions, cloneString(buf), NULL);
+ AllocVar(region);
+ region->chrom = inter->chrom;
+ region->chromStart = inter->targetStart;
+ region->chromEnd = inter->targetEnd;
+ slAddHead(®ions, region);
}
}
-safef(regionInfo, sizeof regionInfo, "%s\t%d\t%d\n"
- "%s\t%d\t%d\n",
- region1Chrom, region1Start, region1End,
- region2Chrom, region2Start, region2End);
+slSort(®ions, bedCmp);
+for (region = regions; region != NULL; region = region->next)
+ {
+ safef(regionInfo, sizeof regionInfo, "%s\t%d\t%d\n",
+ region->chrom, region->chromStart, region->chromEnd);
mustWrite(f, regionInfo, strlen(regionInfo));
//warn("%s", regionInfo);
+ }
fclose(f);
// create SHA1 file; used to see if file has changed
unsigned char hash[SHA_DIGEST_LENGTH];
SHA1((const unsigned char *)regionInfo, strlen(regionInfo), hash);
char newSha1[(SHA_DIGEST_LENGTH + 1) * 2];
hexBinaryString(hash, SHA_DIGEST_LENGTH, newSha1, (SHA_DIGEST_LENGTH + 1) * 2);
char sha1File[1024];
safef(sha1File, sizeof sha1File, "%s.sha1", mrTn.forCgi);
f = mustOpen(sha1File, "w");
mustWrite(f, newSha1, strlen(newSha1));
carefulClose(&f);
return cloneString(mrTn.forCgi);
}
+static void multiRegionLink(char *name, struct interact *inters)
+// Print link to multi-region view of ends if appropriate
+// (or provide a link to remove if already in this mode)
+{
+if (inters->next == NULL && interactEndsOverlap(inters))
+ return;
+char *virtShortDesc = cartOptionalString(cart, "virtShortDesc");
+boolean isVirtMode = cartUsualBoolean(cart, "virtMode", FALSE);
+//warn("virtShortDesc: %s, name: %s", virtShortDesc, name);
+if (isVirtMode && virtShortDesc && sameString(virtShortDesc, name))
+ {
+ printf("
Show interaction%s in "
+ ""
+ " normal browser view (exit multi-region view)",
+ inters->next != NULL ? "s" : "");
+ }
+else
+ {
+ char *regionFile = makeInteractRegionFile(name, inters);
+ //warn("regionFile: %s", regionFile);
+ printf("
Show interaction ends in "
+ ""
+ " multi-region browser view (custom region mode)",
+ name, cgiEncode(regionFile));
+ if (isVirtMode)
+ printf(" or "
+ ""
+ " normal browser view");
+ }
+printf(" ");
+printf("(Help)\n");
+}
+
void doInteractRegionDetails(struct trackDb *tdb, struct interact *inter)
{
/* print info for both regions */
/* Use different labels:
1) directional (source/target)
2) non-directional same chrom (lower/upper)
3) non-directional other chrom (this/other)
*/
char startBuf[1024], endBuf[1024], sizeBuf[1024];
printf("Interaction region: ");
if (interactOtherChrom(inter))
printf("across chromosomes
");
else
{
sprintLongWithCommas(startBuf, inter->chromStart+1);
@@ -289,124 +338,112 @@
sprintLongWithCommas(endBuf, region2End);
sprintLongWithCommas(sizeBuf, region2End - region2Start);
printf("%s region: %s "
"%s:%s-%s %s",
region2Label, region2Name, region2Chrom, region2Start+1, region2End,
region2Chrom, startBuf, endBuf,
inter->targetStrand[0] == '.' ? "" : inter->targetStrand);
printf(" %s bp
\n", sizeBuf);
int distance = interactRegionDistance(inter);
if (distance > 0)
{
// same chrom
sprintLongWithCommas(sizeBuf, distance);
printf("Distance between midpoints: %s bp
\n", sizeBuf);
}
-
-// print link to multi-region view of ends if appropriate
-// (or provide a link to remove if already in this mode)
-
-if (trackDbSettingOn(tdb, "interactMultiRegion") && !interactEndsOverlap(inter))
- {
- char *virtShortDesc = cartOptionalString(cart, "virtShortDesc");
- //warn("virtShortDesc: %s", virtShortDesc);
- if (virtShortDesc && sameString(virtShortDesc, inter->name))
- {
- printf("
"
- "Show interaction in normal browser view (exit multi-region view)");
- }
- else
- {
- char *regionFile = makeInteractRegionFile(inter);
- //warn("regionFile: %s", regionFile);
- printf("
"
- "Show both ends of interaction in multi-region browser view (custom region mode)",
- inter->name, cgiEncode(regionFile));
- }
- printf(" ");
- printf("(Help)\n");
- }
-
-#ifdef TODO /* TODO: get count and score stats of all interactions in window ?*/
-double *scores;
-AllocArray(scores, count);
-#endif
}
void doInteractItemDetails(struct trackDb *tdb, struct interactPlusRow *ipr, char *item,
- boolean isMultiple)
+ boolean isMultiple, boolean doMultiRegion)
/* Details of interaction item */
{
struct interact *inter = ipr->interact;
struct slPair *fields = getFields(tdb, ipr->row);
printCustomUrlWithFields(tdb, inter->name, inter->name, TRUE, fields);
if (!isEmptyTextField(inter->name))
printf("Interaction: %s
\n", inter->name);
printf("Score: %d
\n", inter->score);
printf("Value: %0.3f
\n", inter->value);
if (!isEmptyTextField(inter->exp))
printf("Experiment: %s
\n", inter->exp);
puts("
"); if (!isMultiple) + { doInteractRegionDetails(tdb, inter); + if (doMultiRegion) + multiRegionLink(inter->name, inter); + } +} + +static struct interact *iprsToInters(struct interactPlusRow *iprs) +/* Create list of interacts from interactPlusRows */ +{ +struct interactPlusRow *ipr; +struct interact *inters = NULL; +for (ipr = iprs; ipr != NULL; ipr = ipr->next) + slAddHead(&inters, ipr->interact); +return inters; } void doInteractDetails(struct trackDb *tdb, char *item) /* Details of interaction items */ { char *chrom = cartString(cart, "c"); int start = cartInt(cart, "o"); int end = cartInt(cart, "t"); char *foot = cgiOptionalString("foot"); +boolean doMultiRegion = trackDbSettingOn(tdb, "interactMultiRegion"); int minStart, maxEnd; struct interactPlusRow *iprs = getInteractions(tdb, chrom, start, end, item, foot, &minStart, &maxEnd); start = minStart; end = maxEnd; if (iprs == NULL) errAbort("Can't find interaction %s", item ? item : ""); int count = slCount(iprs); char *clusterMode = interactUiClusterMode(cart, tdb->track, tdb); if (count > 1 || clusterMode) { printf("Interactions: %d
", count);
+ struct interact *inters = iprsToInters(iprs);
if (clusterMode || foot)
{
char startBuf[1024], endBuf[1024], sizeBuf[1024];
sprintLongWithCommas(startBuf, start + 1);
sprintLongWithCommas(endBuf, end);
sprintLongWithCommas(sizeBuf, end - start + 1);
printf("%s interactions region: "
"%s:%s-%s ",
item, chrom, start+1, end, chrom, startBuf, endBuf);
printf(" %s bp
\n", sizeBuf);
}
else
{
- doInteractRegionDetails(tdb, iprs->interact);
+ // overlapping items, same start/end/name
+ doInteractRegionDetails(tdb, inters);
}
+ if (doMultiRegion)
+ multiRegionLink(item, inters);
printf("