d540e9dca3211faf36fab80fa3b640d4bd6ee288
max
Tue Jan 23 06:18:20 2024 -0800
adding phase mouseover, refs #32487
diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c
index 0aca981..5d0d0c3 100644
--- src/hg/hgTracks/simpleTracks.c
+++ src/hg/hgTracks/simpleTracks.c
@@ -2830,43 +2830,46 @@
}
else
{
exonText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "exonText" , "Exon" );
intronText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "intronText", "Intron");
}
while (exon != NULL)
/* Make a stupid list of exons separate from what's given. */
/* It seems like lf->components isn't necessarily sorted. */
{
refAdd(&exonList, exon);
exon = exon->next;
}
/* Now sort it. */
slSort(&exonList, exonSlRefCmp);
+
numExons = slCount(exonList);
+struct genePred *gp = lf->original;
boolean revStrand = (lf->orientation == -1);
int eLast = -1;
int s = -1;
int e = -1;
char mouseOverText[256];
boolean isExon = TRUE;
int picStart = insideX;
int picEnd = picStart + insideWidth;
if (lButton)
picStart += buttonW;
if (rButton)
picEnd -= buttonW;
+
for (ref = exonList; TRUE; )
{
exon = ref->val;
if (isExon)
{
s = exon->start;
e = exon->end;
}
else
{
s = eLast;
e = exon->start;
}
// skip exons and introns that are completely outside the window
if (!(s > winEnd) || (e < winStart))
@@ -2898,40 +2901,85 @@
{
exonIntronText = intronText;
--numExonIntrons; // introns are one fewer than exons
}
char strandChar;
if (!revStrand) {
exonIntronNumber = exonIx;
strandChar = '+';
}
else {
exonIntronNumber = numExonIntrons-exonIx+1;
strandChar = '-';
}
+ // we still need to show the existing mouseover text
char* existingText = lf->mouseOver;
if (isEmpty(existingText))
existingText = lf->name;
+ // construct a string that tells the user about the codon frame situation of this exon
+ char *frameText = "";
+ if (gp->exonFrames && isExon)
+ {
+ // start/end-phases are in the direction of transcription:
+ // if transcript is on + strand, the start phase is the exonFrame value, and the end phase is the next exonFrame (3' on DNA) value
+ // if transcript is on - strand, the start phase is the previous (=3' on DNA) exonFrame and the end phase is the exonFrame
+ int startPhase = gp->exonFrames[exonIx-1];
+ int endPhase = -1;
+ if (!revStrand)
+ endPhase = gp->exonFrames[exonIx];
+ else
+ if (exonIx>1)
+ endPhase = gp->exonFrames[exonIx-2];
+
+ if (gp->exonFrames[exonIx-1]==-1) // UTRs don't have a frame at all
+ {
+ frameText = ", untranslated region";
+ }
+ else
+ {
+ //printf("%s %d %d %s_ex_%d_frame_%d
", chromName, s, e, gp->name, exonIx, startPhase);
+ char buf[256];
+ char *exonNote = "";
+ if (exonIntronNumber", exonIx, numExons);
+ ////int nextExonFrame = gp->exonFrames[nextExIx];
+ //printf("nextExIx %d, nextExonFrame %d, endPhase %d
", nextExIx, nextExonFrame, endPhase);
+
+ if (startPhase==endPhase)
+ exonNote = " → in-frame exon";
+ safef(buf, sizeof(buf), ", start-end codon phase %d-%d%s", startPhase, endPhase, exonNote);
+ }
+ else
+ {
+ if (startPhase==0)
+ exonNote = " → in-frame exon";
+ safef(buf, sizeof(buf), ", start codon phase %d%s", startPhase, exonNote);
+ }
+ frameText = buf;
+ }
+ }
+
if (!isEmpty(existingText))
- safef(mouseOverText, sizeof(mouseOverText), "%s, strand %c, %s %d of %d",
- existingText, strandChar, exonIntronText, exonIntronNumber, numExonIntrons);
+ safef(mouseOverText, sizeof(mouseOverText), "%s, strand %c, %s %d of %d%s",
+ existingText, strandChar, exonIntronText, exonIntronNumber, numExonIntrons, frameText);
else
- safef(mouseOverText, sizeof(mouseOverText), "strand %c, %s %d of %d",
- strandChar, exonIntronText, exonIntronNumber, numExonIntrons);
+ safef(mouseOverText, sizeof(mouseOverText), "strand %c, %s %d of %d%s",
+ strandChar, exonIntronText, exonIntronNumber, numExonIntrons, frameText);
if (w > 0) // draw exon or intron if width is greater than 0
{
// temporarily remove the mouseOver from the lf, since linkedFeatureMapItem will always
// prefer a lf->mouseOver over the itemName
char *oldMouseOver = lf->mouseOver;
lf->mouseOver = NULL;
tg->mapItem(tg, hvg, item, mouseOverText, tg->mapItemName(tg, item),
sItem, eItem, sx, y, w, heightPer);
// and restore the mouseOver
lf->mouseOver = oldMouseOver;
picStart = ex; // prevent pileups. is this right? add 1? does it work?
}
}