ba31086d08e0c051ad23953fc9bb462e9135cb58
galt
Wed Feb 24 13:06:05 2016 -0800
Removing DEBUG warnings from hgTracks multi-region code.
diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index 743d1c0..ca571e3 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -620,69 +620,65 @@
struct track *ideoTrack = NULL;
MgFont *font = tl.font;
char *mapName = "ideoMap";
struct hvGfx *hvg;
boolean doIdeo = TRUE;
int ideoWidth = round(.8 *tl.picWidth);
int ideoHeight = 0;
int textWidth = 0;
struct tempName pngTn;
boolean nukeIdeoFromList = FALSE;
if (ideoTn == NULL)
ideoTn = &pngTn; // not returning value
ideoTrack = chromIdeoTrack(*pTrackList);
-//warn("makeChromIdeoImage ideoTrack=%lu ideoTrack->track=%s", (unsigned long) ideoTrack, ideoTrack ? ideoTrack->track : ""); // DEBUG REMOVE
-
/* If no ideogram don't draw. */
if(ideoTrack == NULL)
{
doIdeo = FALSE;
}
else if(trackImgOnly && !ideogramToo)
{
doIdeo = FALSE;
}
else
{
- //warn("makeChromIdeoImage about to remove track from group and tracklist"); // DEBUG REMOVE
/* Remove the track from the group and track list. */
removeTrackFromGroup(ideoTrack);
slRemoveEl(pTrackList, ideoTrack);
nukeIdeoFromList = TRUE;
/* Fix for hide all button hiding the ideogram as well. */
if(withIdeogram && ideoTrack->items == NULL)
{
ideoTrack->visibility = tvDense;
ideoTrack->loadItems(ideoTrack);
}
limitVisibility(ideoTrack);
/* If hidden don't draw. */
if(ideoTrack->limitedVis == tvHide || !withIdeogram)
doIdeo = FALSE;
}
// TODO use DIV in future (can update entire div at once in hgTracks.js)
//hPrintf("
\n");
// FYI from testing, I see that there is code that inserts warning error messages
// right before ideoMap, so any changes to that name or adding the DIV would require
// updating the warning-insertion target name.
if(doIdeo)
{
- //warn("makeChromIdeoImage doIdeo = TRUE"); // DEBUG REMOVE
char startBand[16];
char endBand[16];
char title[64]; // was 32
startBand[0] = endBand[0] = '\0';
fillInStartEndBands(ideoTrack, startBand, endBand, sizeof(startBand));
/* Start up client side map. */
if (!psOutput)
hPrintf("
\n", mapName);
/* Draw the ideogram. */
ideoHeight = gfxBorder + ideoTrack->height;
if (psOutput)
{
trashDirFile(ideoTn, "hgtIdeo", "hgtIdeo", ".ps");
hvg = hvGfxOpenPostScript(ideoWidth, ideoHeight, ideoTn->forCgi);
}
@@ -1421,50 +1417,46 @@
portWidth = portWidth-gfxBorder-insideX;
}
int arrowWidth = insideHeight;
int arrowButtonWidth = arrowWidth + 2 * NEXT_ITEM_ARROW_BUFFER;
int rightButtonX = portX + portWidth - arrowButtonWidth - 1;
char buttonText[256];
Color fillColor = lightGrayIndex();
labelColor = blackIndex();
hvGfxNextItemButton(hvg, rightButtonX + NEXT_ITEM_ARROW_BUFFER, y, arrowWidth, arrowWidth,
labelColor, fillColor, TRUE);
hvGfxNextItemButton(hvg, portX + NEXT_ITEM_ARROW_BUFFER, y, arrowWidth, arrowWidth,
labelColor, fillColor, FALSE);
safef(buttonText, ArraySize(buttonText), "hgt.prevItem=%s", track->track);
-// warn("portX=%d y+1=%d portWidth=%d arrowButtonWidth=%d track=%s", portX, y+1, portWidth, arrowButtonWidth, track->track); // DEBUG REMOVE
-
mapBoxReinvoke(hvg, portX, y + 1, arrowButtonWidth, insideHeight, track, FALSE,
NULL, 0, 0, (revCmplDisp ? "Next item" : "Prev item"), buttonText);
#ifdef IMAGEv2_SHORT_TOGGLE
char *label = (theImgBox ? track->longLabel : parentTrack->longLabel);
int width = portWidth - (2 * arrowButtonWidth);
int x = portX + arrowButtonWidth;
// make toggle cover only actual label
int size = mgFontStringWidth(font,label) + 12; // get close enough to the label
if (width > size)
{
x += width/2 - size/2;
width = size;
}
mapBoxToggleVis(hvg, x, y + 1, width, insideHeight, (theImgBox ? track : parentTrack));
#else///ifndef IMAGEv2_SHORT_TOGGLE
-//warn("portX+arrowButtonWidth=%d y+1=%d portWidth-(2*arrowButtonWidth)=%d arrowButtonWidth=%d track=%s",
- //portX + arrowButtonWidth, y+1, portWidth - (2 * arrowButtonWidth), arrowButtonWidth, track->track); // DEBUG REMOVE
mapBoxToggleVis(hvg, portX + arrowButtonWidth, y + 1, portWidth - (2 * arrowButtonWidth),
insideHeight, (theImgBox ? track : parentTrack));
#endif///ndef IMAGEv2_SHORT_TOGGLE
// use the last window globals instead of the first
struct window *w=windows;
while(w->next)
w = w->next;
setGlobalsFromWindow(w); // use last window
safef(buttonText, ArraySize(buttonText), "hgt.nextItem=%s", track->track);
mapBoxReinvoke(hvg, portX + portWidth - arrowButtonWidth, y + 1, arrowButtonWidth, insideHeight,
track, FALSE, NULL, 0, 0, (revCmplDisp ? "Prev item" : "Next item"), buttonText);
setGlobalsFromWindow(windows); // restore first window
@@ -2085,44 +2077,41 @@
// store highlight information
{
char *db;
char *chrom;
long chromStart;
long chromEnd;
char *hexColor;
};
struct highlightVar *parseHighlightInfo()
// Parse highlight info from cart var
// db.chrom:start-end#hexColor
{
struct highlightVar *h = NULL;
char *highlightDef = cartOptionalString(cart, "highlight");
-//warn("parseHighlightInfo highlight=%s", highlightDef); // DEBUG REMOVE
if(highlightDef)
{
AllocVar(h);
h->db = cloneNextWordByDelimiter(&highlightDef,'.');
h->chrom = cloneNextWordByDelimiter(&highlightDef,':');
// long to handle virt chrom coordinates
h->chromStart = atol(cloneNextWordByDelimiter(&highlightDef,'-'));
h->chromEnd = atol(cloneNextWordByDelimiter(&highlightDef,'#'));
h->chromStart--; // Not zero based
if (highlightDef && *highlightDef != '\0')
h->hexColor = cloneString(highlightDef);
- //verbose(1, "DEBUG GALT highlightRegion() db=%s chrom=%s chromStart=%ld chromEnd=%ld virtChromName=%s winStart=%ld winEnd=%ld\n",
- //h->db, h->chrom, h->chromStart, h->chromEnd, virtChromName, virtWinStart, virtWinEnd); // DEBUG REMOVE
}
return h;
}
void highlightRegion(struct cart *cart, struct hvGfx *hvg, int imagePixelHeight)
// Highlights a region in the image. Only done if theImgBox is not defined.
// Thus it is done for ps/pdf and view image but the hgTracks image is highlighted via js
{
struct highlightVar *h = parseHighlightInfo();
if(h && theImgBox == NULL) // Only highlight region when imgBox is not used. (pdf and show-image)
{
if (virtualSingleChrom()) // DISGUISE VMODE
{
if ((h->db && sameString(h->db, database))
@@ -2192,32 +2181,30 @@
//void menuBarAppendExtTools()
///* printf a little javascript that adds entries to a menu */
//{
// char url[SMALLBUF];
// safef(url,ArraySize(url),"hgTracks?%s=%s&hgt.redirectTool=crispor",cartSessionVarName(), cartSessionId(cart));
// printf("\n");
//}
-//--- GALT
-
char *rgbColorToString(struct rgbColor color)
/* make rgbColor into printable string */
{
char buf[256];
safef(buf, sizeof buf, "rgbColor r:%d g:%d b:%d", color.r, color.g, color.b);
return cloneString(buf);
}
char *trackDumpString(struct track *track)
/* Write out info on track to string */
{
struct dyString *dy = dyStringNew(256);
dyStringPrintf(dy, "next: %lu\n", (unsigned long)track->next);
// struct track *next; /* Next on list. */
@@ -2569,114 +2556,107 @@
char *dash = strchr(vPos, '-');
if (!dash)
errAbort("position has no dash");
*colon = 0;
*dash = 0;
*pChrom = cloneString(vPos);
*pStart = atoi(colon+1) - 1;
*pEnd = atoi(dash+1);
}
char *disguisePositionVirtSingleChrom(char *position) // DISGUISE VMODE
/* Hide the virt position, convert to real single chrom span.
* position should be virt chrom span.
* Can handle anything in the virt single chrom. */
{
-//warn("disguisePosition position="+position); // DEBUG REMOVE
/* parse Virt position */
char *chrom = NULL;
long start = 0;
long end = 0;
parseVPosition(position, &chrom, &start, &end);
if (!sameString(chrom, "virt"))
return position; // return original
-//warn("start="+start+" end="+end); // DEBUG REMOVE
struct window *windows = makeWindowListFromVirtChrom(start, end);
char *nonVirtChromName = windows->chromName;
if (!sameString(nonVirtChromName, chromName))
return position; // return original
int nonVirtWinStart = windows->winStart;
int nonVirtWinEnd = windows->winEnd;
struct window *w;
for (w=windows->next; w; w=w->next)
{
- //warn("w->chromName=%s w->winStart=%d w->winEnd=%d",w->chromName, w->winStart, w->winEnd); // DEBUG REMOVE
if (!sameString(w->chromName, nonVirtChromName))
return position; // return original
if (w->winEnd < nonVirtWinEnd)
return position; // return original
nonVirtWinEnd = w->winEnd;
}
char nvPos[256];
safef(nvPos, sizeof nvPos, "%s:%d-%d", nonVirtChromName, nonVirtWinStart+1, nonVirtWinEnd);
slFreeList(&windows);
return cloneString(nvPos);
}
char *undisguisePosition(char *position) // UN-DISGUISE VMODE
/* Find the virt position
* position should be real chrom span.
* Limitation: can only convert things in the current windows set. */
{
-//warn("undisguisePosition position="+position); // DEBUG REMOVE
/* parse NonVirt position */
char *chrom = NULL;
int start = 0;
int end = 0;
parseNVPosition(position, &chrom, &start, &end);
if (!sameString(chrom, chromName))
return position; // return original
long newStart = -1;
long newEnd = -1;
struct window *lastW = NULL;
struct window *w = NULL;
-//warn("start="+start+" end="+end); // DEBUG REMOVE
for (w = windows; w; w=w->next)
{
// double check chrom is same thoughout all windows, otherwise warning, return original value
if (!sameString(w->chromName, chromName))
{
return position; // return original
}
// check that the regions are ascending and non-overlapping
if (lastW && w->winStart < lastW->winEnd)
{
return position; // return original
}
// overlap with position?
// if intersection,
if (w->winEnd > start && end > w->winStart)
{
int s = max(start, w->winStart);
int e = min(end, w->winEnd);
long cs = s - w->winStart + w->virtStart;
long ce = e - w->winStart + w->virtStart;
- //warn("cs="+cs+" ce="+ce); // DEBUG REMOVE
if (newStart == -1)
newStart = cs;
newEnd = ce;
}
lastW = w;
}
if (newStart == -1) // none of the windows intersected with the position
return position; // return original
// return new virt undisguised position as a string
char newPos[1024];
safef (newPos, sizeof newPos, "virt:%ld-%ld", (newStart+1), newEnd);
-//warn("undisguisePosition newPos="+newPos); // DEBUG REMOVE
return cloneString(newPos);
}
char *windowsSpanPosition()
/* Return a position string that spans all the windows.
* Windows should be on same chrom and ascending and non-overlapping.*/
{
char buf[256];
char *chromName = windows->chromName;
int start = windows->winStart;
struct window *w = windows, *last = NULL;
while(w->next) // find last window
{
last = w;
@@ -2747,72 +2727,69 @@
}
}
v->start = virtRegion->start - leftWindowPadding;
v->end = virtRegion->end + rightWindowPadding;
if (v->start < 0)
v->start = 0;
if (v->end >= chromSize)
v->end = chromSize;
regionBases += (v->end - v->start);
slAddHead(&newList, v);
lastVirtRegion = virtRegion;
lastChrom = virtRegion->chrom;
++regionCount;
}
-//warn("After padding, %d regions", regionCount); // DEBUG REMOVE
slReverse(&newList);
-virtRegionList = newList; // update new list -- TODO should the old one be freed? if so, the chrom name should use cloneString
+virtRegionList = newList; // update new list --
+// TODO should the old one be freed? if so, the chrom name should use cloneString
}
void makeVirtChrom()
/* build virtual chrom array from virt region list */
{
virtRegionCount = slCount(virtRegionList);
AllocArray(virtChrom, virtRegionCount);
struct virtRegion *v;
int i = 0;
long totalBases = 0;
for(v=virtRegionList;v;v=v->next,++i)
{
virtChrom[i].virtPos = totalBases;
virtChrom[i].virtRegion = v;
totalBases += (v->end - v->start);
- //warn("virtChrom[%d] .virtPos=%ld", i, virtChrom[i].virtPos); // DEBUG REMOVE
}
virtSeqBaseCount = totalBases;
}
void virtChromBinarySearch(long target, long *resultIndex, int *resultOffset)
/* Do a binary search for the target position in the virtual chrom.
* Return virtChrom Index and Offset if found.
* Return -1 if target out of range. TODO maybe change to errAbort*/
{
//The binary search will either return match or out-of-range.
long index = -1;
int offset = -1;
long a = 0; // start of the array
long b = virtRegionCount - 1; // end of array where N = count of regions
if (target >=0 && target < virtSeqBaseCount)
{
while(1)
{
long c = (a + b) / 2;
- //warn("target=%ld a=%ld b=%ld c=%ld virtRegionCount=%d", target, a, b, c, virtRegionCount); // DEBUG REMOVE
-
if (a > b)
{
index = b;
break;
}
else if (target == virtChrom[c].virtPos)
{
// (exact match)
index = c;
break;
}
else if (target > virtChrom[c].virtPos)
{
a = c + 1;
}
@@ -2880,32 +2857,30 @@
errAbort("unexpected error. virtWinEnd=%ld out of range. virtSeqBaseCount=%ld", virtWinEnd, virtSeqBaseCount);
if (virtWinEnd - virtWinStart < 1)
errAbort("unexpected error. virtual window size < 1 base. virtWinStart=%ld virtWinEnd=%ld virtSeqBaseCount=%ld", virtWinStart, virtWinEnd, virtSeqBaseCount);
long virtIndexStart;
int virtOffsetStart;
virtChromBinarySearch(virtWinStart, &virtIndexStart, &virtOffsetStart);
if (virtIndexStart == -1)
errAbort("unexpected failure to find target virtWinStart %ld in virtChrom Array", virtWinStart);
long virtIndexEnd;
int virtOffsetEnd;
virtChromBinarySearch(virtWinEnd, &virtIndexEnd, &virtOffsetEnd);
if (virtIndexEnd == -1)
errAbort("unexpected failure to find target virtWinEnd %ld in virtChrom Array", virtWinEnd);
-//warn("after binary searches, virtIndexStart=%ld virtOffsetStart=%d , virtIndexEnd=%ld virtOffsetEnd=%d", virtIndexStart, virtOffsetStart, virtIndexEnd, virtOffsetEnd); // DEBUG REMOVE
-
// create new windows list from virt chrom
struct window *windows = NULL;
long i = virtIndexStart;
int winCount = 0;
long basesInWindows = 0; // TODO not actually using this variable
for(i=virtIndexStart; i <= virtIndexEnd; ++i)
{
struct window *w;
AllocVar(w);
w->organism = organism; // obsolete
w->database = database; // obsolete
struct virtRegion *v = virtChrom[i].virtRegion;
long virtPos = virtChrom[i].virtPos;
w->chromName = v->chrom;
if (i == virtIndexStart)
@@ -2960,47 +2935,43 @@
nonVirtWinEnd = w->winEnd;
}
// TODO Also consider preserving the original bases in windows width (with clipping).
char nvPos[256];
safef(nvPos, sizeof nvPos, "%s:%d-%d", nonVirtChromName, nonVirtWinStart+1, nonVirtWinEnd);
return cloneString(nvPos);
}
char *nonVirtPositionFromHighlightPos()
/* Must have created the virtual chrom first.
* Currently just a hack to use windows,
* use the (first) window(s) from that to get real chrom name start end */
{
struct highlightVar *h = parseHighlightInfo();
-//if (h)
-// warn("remapHighlightPos h-> chrom=%s chromStart=%ld chromEnd=%ld", h->chrom, h->chromStart, h->chromEnd); // DEBUG REMOVE
-
if (!(h && h->db && sameString(h->db, database) && sameString(h->chrom,"virt")))
return NULL;
struct window *windows = makeWindowListFromVirtChrom(h->chromStart, h->chromEnd);
char *nonVirtChromName = windows->chromName;
int nonVirtWinStart = windows->winStart;
int nonVirtWinEnd = windows->winEnd;
// Extending this through more of the windows,
// if it is on the same chrom and maybe not too far separated.
struct window *w;
for (w=windows->next; w; w=w->next)
{
- //warn("w->chromName=%s w->winStart=%d w->winEnd=%d",w->chromName, w->winStart, w->winEnd); // DEBUG REMOVE
if (sameString(w->chromName, nonVirtChromName) && w->winEnd > nonVirtWinEnd)
nonVirtWinEnd = w->winEnd;
}
// TODO Also consider preserving the original bases in windows width (with clipping).
char nvPos[256];
safef(nvPos, sizeof nvPos, "%s.%s:%d-%d#%s", h->db, nonVirtChromName, nonVirtWinStart+1, nonVirtWinEnd, h->hexColor);
return cloneString(nvPos);
}
void allocPixelsToWindows()
/* Allocate pixels to windows, sets insideWidth and insideX
*
* TODO currently uses a strategy that places a window at a pixel location
* directly, because of round-off and missing small windows this can occasionally
* lead to gaps not covered by any pixel. Consider replacing it with something
@@ -3009,56 +2980,41 @@
{
double pixelsPerBase = (double)fullInsideWidth / virtWinBaseCount;
long basesUsed = 0;
int windowsTooSmall = 0;
struct window **pWindows = &windows;
struct window *window;
int winCount = slCount(windows);
for(window=windows;window;window=window->next)
{
int basesInWindow = window->winEnd - window->winStart;
int pixelsInWindow = 0.5 + (double)basesInWindow * pixelsPerBase; // should this round up ? + 0.5?
window->insideWidth = pixelsInWindow;
window->insideX = fullInsideX + basesUsed * pixelsPerBase;
basesUsed += basesInWindow;
- //warn("window x = %d width = %d x + width=%d basesInWindow=%d",
- //window->insideX, window->insideWidth, window->insideX + window->insideWidth, basesInWindow); // DEBUG REMOVE
-
if (pixelsInWindow < 1) // remove windows less than one pixel from the list
{
- //if (windowsTooSmall < 5)
- // warn("window x = %d width = %d x + width=%d", window->insideX, window->insideWidth, window->insideX + window->insideWidth);
*pWindows = window->next;
--winCount;
++windowsTooSmall;
}
else
{
pWindows = &window->next;
}
}
-//if (windowsTooSmall > 0)
-// warn("Summary: %d windowsTooSmall: (pixelsInWindow < 1)", windowsTooSmall);
-
-//warn("winCount=%d slCount(windows)=%d #LessThan1Pixel=%d fullInsideWidth=%d virtWinBaseCount=%ld basesUsed=%ld",
- //winCount, slCount(windows), windowsTooSmall, fullInsideWidth, virtWinBaseCount, basesUsed);
-
-// DEBUG REMOVE:
-// nextExonArrows are working now
-//if (winCount >= 2)
-// withNextExonArrows = FALSE; /* Display next exon navigation buttons near center labels? */
}
struct positionMatch *virtChromSearchForPosition(char *chrom, int start, int end, boolean findNearest)
/* Search the virtual chrom for the query chrom, start, end position
*
* TODO GALT: Intially this can be a simple brute-force search of the entire virtChrom array.
*
* However, this will need to be upgraded to using a rangeTree or similar structure
* to rapidly return multiple regions that overlap the query position.
* */
{
struct positionMatch *list=NULL, *p;
int nearestRegion = -1;
boolean nearestAfter = TRUE;
int nearestDistance = INT_MAX;
@@ -3104,32 +3060,30 @@
v = virtChrom[i].virtRegion;
virtPos = virtChrom[i].virtPos;
AllocVar(p);
if (nearestAfter)
{
p->virtStart = virtPos;
p->virtEnd = p->virtStart + (end - start);
}
else
{
p->virtEnd = virtPos + (v->end - v->start);
p->virtStart = p->virtEnd - (end - start);
}
if (p->virtEnd > virtSeqBaseCount)
p->virtEnd = virtSeqBaseCount;
- //warn("findNearest: nearestRegion=%d nearestDistance=%d p->virtStart=%ld p->virtEnd=%ld ",
- //nearestRegion, nearestDistance, p->virtStart, p->virtEnd); // DEBUG REMOVE
slAddHead(&list, p);
}
slReverse(&list);
return list;
}
int matchVPosCompare(const void *elem1, const void *elem2)
/* compare elements based on vPos */
{
const struct positionMatch *a = *((struct positionMatch **)elem1);
const struct positionMatch *b = *((struct positionMatch **)elem2);
if (a->virtStart == b->virtStart)
errAbort("matchVPosCompare error should not happen: 2 elements being sorted have the same virtStart=%ld", a->virtStart);
else if (a->virtStart > b->virtStart)
return 1;
@@ -3195,33 +3149,30 @@
}
if (!m)
break;
lastStart = m->virtStart;
lastEnd = m->virtEnd;
lastM = m;
}
slReverse(&newList);
return newList;
}
// ----------------------------------
-static void checkMaxWindowToDraw(struct track *tg); // forward declaration // DEBUG REMOVE?
-
-
void initVirtRegionsFromSOD1Hardwired()
/* create a testing regionlist from SOD1 (uc002ypa.3) hardwired */
{
virtRegionList = NULL;
char *chrom="chr21";
//int exonStarts[] = {33031934,33036102,33038761,33039570,33040783};
//int exonEnds[] = {33032154,33036199,33038831,33039688,33041243};
// BASE-level zoom in two 20 bp exons and their on-screen junction
int exonStarts[] = {33032134,33036102};
int exonEnds[] = {33032154,33036122};
int i;
for(i=0; ichrom))
{
found = TRUE;
break;
}
offset += (v->end - v->start);
slAddHead(&before, v);
@@ -3365,39 +3315,30 @@
v->end = chromSize;
defaultVirtWinEnd += haploSize;
if (defaultVirtWinEnd > chromSize)
defaultVirtWinEnd = chromSize;
slAddHead(&virtRegionList, v);
slReverse(&virtRegionList);
hFreeConn(&conn);
defaultVirtWinStart += offset;
defaultVirtWinEnd += offset;
// concatenate the 3 lists.
virtRegionList = slCat(before,slCat(virtRegionList,after));
-// DEBUG REMOVE testing
-//warn("initSingleAltHaplotype: offset=%ld", offset);
-//long testOffset = 0;
-//for (v=virtRegionList; v; v=v->next)
-// {
-// testOffset += (v->end - v->start);
-// warn("%s:%d-%d cumuulative offset %ld", v->chrom, v->start, v->end, testOffset);
-// }
-
return TRUE;
}
void initVirtRegionsFromKnownCanonicalGenes(char *table)
// OBSOLETED by initVirtRegionsFromEMGeneTableExons()
/* Create a regionlist from knownCanonical genes (not exons) */
// I was not expecting it, but 20% of the KC genes overlap with others.
// Some are cDNAs, some are non-coding RNAs, some just look like junk.
// But I have to add special logic to accomodate them.
// Currently I just merge until there is no more overlap,
// and then I start a new region. So 30K regions should reduce to about 24K regions or less.
{
struct sqlConnection *conn = hAllocConn(database);
virtRegionList = NULL;
@@ -3566,31 +3507,30 @@
int rowOffset = 0;
char query[256];
int padding = emPadding;
if (sameString(virtModeType, "geneMostly"))
padding = gmPadding;
// knownCanonical Hash
struct hash *kcHash = NULL;
if (knownCanonical) // filter out alt splicing variants
{
// load up hash of canonical transcriptIds
sqlSafef(query, sizeof(query), "select transcript from %s"
//" where chrom not like '%%_hap_%%' and chrom not like '%%_random'"
, knownCanonical);
if (virtualSingleChrom())
sqlSafefAppend(query, sizeof(query), " where chrom='%s'", chromName);
- //warn("query = [%s]", query); // DEBUG REMOVE
kcHash = newHash(10);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
hashAdd(kcHash, row[0], NULL);
}
sqlFreeResult(&sr);
}
// knownToTag basic hash
struct hash *ktHash = NULL;
if (knownToTag) // filter out all but Basic
{
// load up hash of canonical transcriptIds
sqlSafef(query, sizeof(query), "select name from %s where value='basic'", knownToTag);
ktHash = newHash(10);
@@ -3601,31 +3541,30 @@
}
sqlFreeResult(&sr);
}
setEMGeneTrack();
if (!emGeneTable)
errAbort("Unexpected error, emGeneTable=NULL in initVirtRegionsFromEMGeneTableExons");
if (hIsBinned(database, emGeneTable)) // skip first bin column if any
++rowOffset;
sqlSafef(query, sizeof(query), "select * from %s", emGeneTable);
if (virtualSingleChrom())
sqlSafefAppend(query, sizeof(query), " where chrom='%s'", chromName);
// TODO GALT may have to change this to in-memory sorting?
// refGene is out of order because of genbank continuous loading
// also, using where chrom= causes it to use indexes which disturb order returned.
sqlSafefAppend(query, sizeof(query), " order by chrom, txStart");
-//warn("query = [%s]", query); // DEBUG REMOVE
sr = sqlGetResult(conn, query);
char chrom[256] = "";
int start = -1;
int end = -1;
char lastChrom[256] = "";
int lastStart = -1;
int lastEnd = -1;
int chromSize = -1;
char lastChromSizeChrom[256] = "";
boolean firstTime = TRUE;
boolean isEOF = FALSE;
struct kce *kceList = NULL, *bestKce, *prevKce;
struct genePred *gene = NULL;
while (1)
@@ -3633,250 +3572,231 @@
while(1) // get input if possible
{
boolean readIt = FALSE;
if (!gene)
readIt = TRUE;
if (isEOF)
readIt = FALSE;
if (readIt)
{
row = sqlNextRow(sr);
if (row)
{
gene = genePredLoad(row+rowOffset);
- //warn("GALT loaded gene %s\n", gene->name); // DEBUG REMOVE
if (geneMostly)
convertGenePredGeneToExon(gene);
if (!sameString(lastChromSizeChrom, gene->chrom))
{
chromSize = hChromSize(database, gene->chrom);
safecpy(lastChromSizeChrom, sizeof lastChromSizeChrom, gene->chrom);
}
if (padding > 0)
padExons(gene, chromSize, padding); // handle padding
}
else
{
isEOF = TRUE;
}
}
if (gene && !showNoncoding && (gene->cdsStart == gene->cdsEnd))
{
- //warn("GALT skip non-coding gene %s cdsStart==cdsEnd", gene->name); // DEBUG REMOVE
+ //skip non-coding gene
genePredFree(&gene);
}
if (gene && knownCanonical && !hashLookup(kcHash, gene->name))
{
- //warn("GALT skip not in knownCanonical hash gene %s", gene->name); // DEBUG REMOVE
+ //skip gene not in knownCanonical hash
genePredFree(&gene);
}
if (gene && knownToTag && !hashLookup(ktHash, gene->name))
{
- //warn("GALT skip not in knownToTag Basic hash gene %s", gene->name); // DEBUG REMOVE
+ // skip gene not in knownToTag Basic hash
genePredFree(&gene);
}
boolean transferIt = FALSE;
if (gene && !kceList)
{
transferIt = TRUE;
}
else if (gene && kceList)
{
// TODO need to check the chrom equality first
int best = findBestKce(kceList, &bestKce, &prevKce);
- //warn("GALT check chrom gene->chrom=%s, lastChrom=%s, chrom=%s", gene->chrom, lastChrom, chrom); // DEBUG REMOVE
if (sameString(gene->chrom, chrom))
{
- //warn("GALT best=%d gene %s exonStart[0]=%d", best, gene->name, gene->exonStarts[0]); // DEBUG REMOVE
if (gene->exonStarts[0] < best)
transferIt = TRUE;
}
}
if (transferIt)
{
- //warn("GALT transferred gene %s to kcelist", gene->name); // DEBUG REMOVE
// add gene to kce list
struct kce *kce;
AllocVar(kce);
kce->gene = gene;
kce->exonNumber = 0;
slAddHead(&kceList, kce);
safecpy(chrom, sizeof chrom, gene->chrom);
gene = NULL; // do not free since it is still in use
}
- //warn("GALT readIt=%d transferIt=%d", readIt, transferIt); // DEBUG REMOVE
if (gene && kceList && !transferIt)
break;
if (isEOF && !gene)
{
if (kceList) // flush out the last of the items in kcelist
findBestKce(kceList, &bestKce, &prevKce);
break;
}
}
boolean printIt = FALSE;
if (kceList)
{
safecpy(chrom, sizeof chrom, bestKce->gene->chrom);
start = bestKce->gene->exonStarts[bestKce->exonNumber];
end = bestKce->gene->exonEnds[bestKce->exonNumber];
- //warn("GALT GOT DATA chrom=%s start=%d end=%d lastChrom=%s lastStart=%d lastEnd=%d",
- //chrom, start, end, lastChrom, lastStart, lastEnd); // DEBUG REMOVE
-
if (sameString(chrom, lastChrom))
{
if (start <= lastEnd)
{
- //warn("GALT overlap extend start=%d <= lastEnd=%d, end=%d", start, lastEnd, end); // DEBUG REMOVE
- // overlap detected in knownCanonical
- // extend current region
+ // overlap detected, extend current region
if (end > lastEnd)
{
lastEnd = end;
}
}
else
{
printIt = TRUE;
}
}
else
{
printIt = TRUE;
}
}
else
{
printIt = TRUE;
isEOF = TRUE;
}
- //warn("GALT printIt=%d", printIt); // DEBUG REMOVE
-
if (printIt)
{
if (firstTime)
{
firstTime = FALSE;
}
else
{
- //warn("GALT adding region %s:%d-%d", lastChrom, lastStart, lastEnd); // DEBUG REMOVE
struct virtRegion *v;
AllocVar(v);
v->chrom = cloneString(lastChrom);
v->start = lastStart;
v->end = lastEnd;
v->strand[0] = '.'; // TODO we should probably just remove the strand field
v->strand[1] = 0;
slAddHead(&virtRegionList, v);
}
}
if (isEOF && !kceList && !gene)
break;
if (printIt)
{
safecpy(lastChrom, sizeof lastChrom, chrom);
lastStart = start;
lastEnd = end;
}
- //warn("used up %s exon# %d", bestKce->gene->name, bestKce->exonNumber); // DEBUG REMOVE
- // TODO update or remove current thing from kceList
++bestKce->exonNumber;
if (bestKce->exonNumber >= bestKce->gene->exonCount)
{ // remove from kceList
genePredFree(&bestKce->gene);
if (prevKce)
prevKce->next = bestKce->next;
else
kceList = bestKce->next;
freeMem(bestKce);
}
}
sqlFreeResult(&sr);
slReverse(&virtRegionList);
hashFree(&kcHash);
hashFree(&ktHash);
hFreeConn(&conn);
}
void testRegionList()
/* check if it is ascending non-overlapping regions.
(this is not always a requirement in the most general case, i.e. user-regions)
*/
{
char lastChrom[256];
int lastEnd = -1;
struct virtRegion *v;
-warn("testRegionList() started DEBUG."); // DEBUG REMOVE
for (v=virtRegionList; v; v=v->next)
{
if (sameString(v->chrom,lastChrom))
{
if (v->end < v->start)
errAbort("check of region list reveals invalid region %s:%d-%d", v->chrom, v->start, v->end);
if (lastEnd > v->start)
errAbort("check of region list reveals overlapping regions region %s:%d-%d lastEnd=%d", v->chrom, v->start, v->end, lastEnd);
}
else
{
safecpy(lastChrom, sizeof lastChrom, v->chrom);
}
lastEnd = v->end;
}
-warn("testRegionList() completed OK.");
}
// multi-window variables global to hgTracks
void setGlobalsFromWindow(struct window *window)
/* set global window values */
{
currentWindow = window;
organism = window->organism;
database = window->database;
chromName = window->chromName;
winStart = window->winStart;
winEnd = window->winEnd;
insideX = window->insideX;
insideWidth = window->insideWidth;
winBaseCount = winEnd - winStart;
}
void initExonStep()
/* create exon-like pattern with exonSize and stepSize */
{
int winCount = cartUsualInt(cart, "demo2NumWindows", demo2NumWindows);
int i;
-//int avgWidth = fullInsideWidth/winCount ; // can shrink down to 1 ok! // DEBUG REMOVE
-//int x = fullInsideX;
int exonSize = cartUsualInt(cart, "demo2WindowSize", demo2WindowSize); //200; //9974; //200;
int intronSize = cartUsualInt(cart, "demo2StepSize", demo2StepSize); //200; //15000; // really using it like stepSize as that allows overlapping windows.
struct virtRegion *v;
for(i=0;ichrom = "chr21";
v->start = 33031597 - 1 + i*(intronSize);
v->end = v->start + exonSize; //33041570;
slAddHead(&virtRegionList, v);
}
slReverse(&virtRegionList);
//if (winCount >= 2)
// withNextExonArrows = FALSE; /* Display next exon navigation buttons near center labels? */
@@ -3892,39 +3812,36 @@
int winCount = 0;
char *query =
"NOSQLINJ select chrom, size from chromInfo"
" where chrom like 'chr%'"
" and chrom not like '%_random'"
" and chrom not like 'chrUn%'";
// allow alternate haplotypes for now
//" and chrom not like '%_hap%'"
//" and chrom not like '%_alt'"
//warn("%s",query);
struct virtRegion *v;
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
unsigned chromSize = sqlUnsigned(row[1]);
- //warn("chrom=%s size=%d", row[0], chromSize);
AllocVar(v);
v->chrom = cloneString(row[0]);
v->start = 1 - 1;
v->end = chromSize;
slAddHead(&virtRegionList, v);
++winCount;
- //if (winCount >= 2) // DEBUG HACK REMOVE
- //break;
}
sqlFreeResult(&sr);
hFreeConn(&conn);
slReverse(&virtRegionList);
}
void initWindowsAltLoci()
/* initialize window list showing alt (alternate haplotype)*/
{
struct virtRegion *v;
//chr1:153520530-153700530
AllocVar(v);
@@ -3945,150 +3862,135 @@
AllocVar(v);
v->chrom = "chr1";
v->start = 153865739 - 1;
v->end = 154045739;
slAddHead(&virtRegionList, v);
slReverse(&virtRegionList);
}
boolean initVirtRegionsFromBedUrl(time_t *bedDateTime)
/* Read custom regions from BED URL */
{
multiRegionsBedUrl = cartUsualString(cart, "multiRegionsBedUrl", multiRegionsBedUrl);
int bedPadding = 0; // default no padding
-//warn("initVirtRegionsFromBedUrl got here multiRegionsBedUrl=%s", multiRegionsBedUrl); // DEBUG REMOVE
// TODO add some checks for db change? save in cart var?
if (sameString(multiRegionsBedUrl,""))
{
warn("No BED URL specified.");
return FALSE;
}
if (!strstr(multiRegionsBedUrl,"://"))
{
warn("No protocol specified in BED URL %s", multiRegionsBedUrl);
return FALSE;
}
struct lineFile *lf = lineFileUdcMayOpen(multiRegionsBedUrl, FALSE);
if (!lf)
{
warn("Unable to open [%s] with udc", multiRegionsBedUrl);
return FALSE;
}
*bedDateTime = udcTimeFromCache(multiRegionsBedUrl, NULL);
-//warn("unix time = %ld on BED file %s", (long)*bedDateTime, multiRegionsBedUrl); // DEBUG REMOVE
char *line;
int lineSize;
int expectedFieldCount = -1;
struct bed *bed, *bedList = NULL;
while (lineFileNext(lf, &line, &lineSize))
{
// Process comments for keywords like database, shortDesc, and maybe others
if (startsWith("#",line))
{
if (startsWith("#database ",line))
{
char *dbFromBed = line+strlen("#database ");
- //warn("got #database setting: %s, current database %s", dbFromBed, database); // DEBUG REMOVE
if (!sameString(database,dbFromBed))
{
warn("Multi-Region BED URL error: The database (%s) specified in input does not match current database %s",
dbFromBed, database);
return FALSE;
}
}
if (startsWith("#shortDesc ",line))
{
virtModeShortDescr = cloneString(line+strlen("#shortDesc "));
- //warn("got #shortDesc setting: %s", virtModeShortDescr); // DEBUG REMOVE
}
if (startsWith("#padding ",line))
{
bedPadding = sqlSigned(line+strlen("#padding "));
- //warn("got #padding setting: %d", bedPadding); // DEBUG REMOVE
}
continue;
}
char *row[15];
int numFields = chopByWhite(line, row, ArraySize(row));
if (numFields < 3)
{
warn("%s doesn't appear to be in BED format. 3 or more fields required, got %d",
multiRegionsBedUrl, numFields);
return FALSE;
}
if (expectedFieldCount == -1)
{
expectedFieldCount = numFields;
- //warn("got expectedFieldCount=%d", expectedFieldCount); // DEBUG REMOVE
}
else
{
- //warn("got numFields=%d, expectedFieldCount=%d", numFields, expectedFieldCount); // DEBUG REMOVE
if (numFields != expectedFieldCount)
errAbort("Multi-Region BED was detected to have %d columns. But this row has %d columns. "
"All rows except comment lines should have the same number of columns", numFields, expectedFieldCount);
}
- //warn("got about to call load and validate bed"); // DEBUG REMOVE
-
AllocVar(bed);
// All fields are standard BED fields, no bedplus fields supported at this time.
// note: this function does not validate chrom name or end beyond chrom size
loadAndValidateBed(row, numFields, numFields+0, lf, bed, NULL, TRUE);
bed->chrom=cloneString(bed->chrom); // loadAndValidateBed does not do it for speed. but bedFree needs it.
struct chromInfo *ci = hGetChromInfo(database, bed->chrom);
if (ci == NULL)
{
warn("Couldn't find chromosome/scaffold %s in database", bed->chrom);
return FALSE;
}
if (bed->chromEnd > ci->size)
{
warn("BED chromEnd %u > size %u for chromosome/scaffold %s", bed->chromEnd, ci->size, bed->chrom);
return FALSE;
}
slAddHead(&bedList, bed);
- //warn("got after load and validate bed"); // DEBUG REMOVE
-
struct virtRegion *v;
if (numFields < 12)
{
AllocVar(v);
v->chrom = cloneString(bed->chrom);
v->start = bed->chromStart;
v->end = bed->chromEnd;
slAddHead(&virtRegionList, v);
- //warn("got BED region %s %d %d", v->chrom, v->start, v->end); // DEBUG REMOVE
}
else
{
int e;
- //warn("got BED12 blockCount=%d bed->chrom=%s", bed->blockCount, bed->chrom); // DEBUG REMOVE
for (e = 0; e < bed->blockCount; ++e)
{
- //warn("got BED12 exon blockSizes[e]=%d chromStarts[e]=%d", bed->blockSizes[e], bed->chromStarts[e]); // DEBUG REMOVE
AllocVar(v);
v->chrom = cloneString(bed->chrom);
v->start = bed->chromStart + bed->chromStarts[e];
v->end = v->start + bed->blockSizes[e];
- //warn("got BED12 exon region %s %d %d", v->chrom, v->start, v->end); // DEBUG REMOVE
slAddHead(&virtRegionList, v);
}
}
}
lineFileClose(&lf);
bedFreeList(&bedList);
slReverse(&virtRegionList);
if (bedPadding > 0)
padVirtRegions(bedPadding);
return TRUE;
}
// TODO OBSOLETED by lastDbPosCart
boolean restoreCartSetting(char *cartSetting)
@@ -4142,71 +4044,61 @@
void dySaveCartSetting(struct dyString *dy, char *cartVar, boolean saveBoth)
/* Grab var and value from cart, save as var=val to dy string. */
{
if (dy->stringSize > 0)
dyStringAppend(dy, " ");
dyStringPrintf(dy, "%s=%s", cartVar, cartUsualString(cart, cartVar, NULL));
if (saveBoth)
lastDbPosSaveCartSetting(cartVar);
}
boolean initRegionList()
/* initialize window list */
{
-//warn("initRegionList got here 0");
// TODO GALT
-// if we are going to support windows from any org and db,
-// then we are going to have to loosen up assumptions
-// about trackList consistencey across windows.
-// But it seems like much of the rest of the code would work.
-// Not sure about speed either -- but might be ok.
-//
// update, well by 2015-04-28 it seems like we are not going to support windows from other assemblies
// due to difficulties with tracklist.
-
struct virtRegion *v;
virtRegionList = NULL;
virtModeExtraState = ""; // This is state that determines if the virtChrom has changed
lastDbPosCart = cartOfNothing(); // USED to store and restore cart settings related to position and virtMode
struct dyString *dy = dyStringNew(256); // used to build virtModeExtraState
if (sameString(virtModeType, "default"))
{
- //warn("demo type single original window"); // DEBUG REMOVE
// Single window same as normal window
// mostly good to test nothing was broken with single window
AllocVar(v);
v->chrom = chromName;
v->start = 0;
v->end = hChromSize(database, chromName);
virtWinStart = winStart;
virtWinEnd = winEnd;
slAddHead(&virtRegionList, v);
slReverse(&virtRegionList);
}
else if (sameString(virtModeType, "exonMostly")
|| sameString(virtModeType, "geneMostly"))
{
- //warn("emGeneTable %s", emGeneTable); // DEBUG REMOVE
// Gencode settings: comprehensive, alt-splice, non-coding
char *knownCanonical = NULL; // show splice-variants, not filtered out via knownCanonical
boolean showNoncoding = TRUE; // show non-coding where cdsStart==cdsEnd
char *knownToTag = NULL; // show comprehensive set not filtered by knownToTag
char varName[SMALLBUF];
boolean geneMostly = FALSE;
lastDbPosSaveCartSetting("emGeneTable");
//DISGUISE makes obsolete dySaveCartSetting(dy, "emGeneTable");
//DISGUISE makes obsolete dySaveCartSetting(dy, "emPadding");
if (sameString(virtModeType, "geneMostly"))
geneMostly = TRUE;
if (sameString(emGeneTable, "knownGene"))
@@ -4238,273 +4130,244 @@
{
knownToTag = "knownToTag";
}
}
}
if (sameString(emGeneTable, "refGene"))
{
char varName[SMALLBUF];
safef(varName, sizeof(varName), "%s.hideNoncoding", emGeneTable);
showNoncoding = !cartUsualBoolean(cart, varName, FALSE);
//DISGUISE makes obsolete dySaveCartSetting(dy, varName);
}
initVirtRegionsFromEMGeneTableExons(showNoncoding, knownCanonical, knownToTag, geneMostly);
- //warn("slCount(virtRegionList)=%d", slCount(virtRegionList)); // DEBUG REMOVE
if (!virtRegionList)
{
warn("No genes found on chrom %s for track %s, returning to default view", chromName, emGeneTrack->shortLabel);
return FALSE; // regionList is empty, nothing found.
}
if (geneMostly)
virtModeShortDescr = "genes";
else
virtModeShortDescr = "exons";
// DISGUISE makes obsolete dyStringPrintf(dy," %s %s", dy->string, knownCanonical, knownToTag);
}
else if (sameString(virtModeType, "kcGenes")) // TODO obsolete
{
- //warn("demo KnownCanonical gene regions genome-wide."); // DEBUG REMOVE
initVirtRegionsFromKnownCanonicalGenes("knownCanonical");
virtModeShortDescr = "genes";
}
else if (sameString(virtModeType, "customUrl"))
{
- //warn("custom regions from BED URL."); // DEBUG REMOVE
+ // custom regions from BED URL
virtModeShortDescr = "customUrl"; // can be overridden by comment in input bed file
time_t bedDateTime = 0;
if (!initVirtRegionsFromBedUrl(&bedDateTime))
{
return FALSE; // return to default mode
}
dySaveCartSetting(dy, "multiRegionsBedUrl", TRUE);
dyStringPrintf(dy, " %ld", (long)bedDateTime);
}
else if (sameString(virtModeType, "singleTrans"))
{
- //warn("Single Transcript Id"); // DEBUG REMOVE
singleTransId = cartUsualString(cart, "singleTransId", singleTransId);
if (sameString(singleTransId, ""))
{
warn("Single transcript Id should not be blank");
return FALSE; // return to default mode
}
setEMGeneTrack();
dySaveCartSetting(dy, "singleTransId", TRUE);
}
else if (sameString(virtModeType, "singleAltHaplo"))
{
- //warn("Single Haplotype Id"); // DEBUG REMOVE
- singleAltHaploId = cartUsualString(cart, "singleAltHaploId", singleAltHaploId); // currently default is chr6_cox_hap2
+ singleAltHaploId = cartUsualString(cart, "singleAltHaploId", singleAltHaploId); // default is chr6_cox_hap2
initAllChroms(); // we want to default to full genome view.
if (!initSingleAltHaplotype(singleAltHaploId))
{
virtRegionList = NULL;
return FALSE; // return to default mode
}
virtModeShortDescr = "alt haplo"; // was "single haplo" but that might confuse some users.
dySaveCartSetting(dy, "singleAltHaploId", TRUE);
}
else if (sameString(virtModeType, "allChroms"))
- {
+ { // TODO more work on this mode
//warn("show all regular chromosomes (not alts)\n"
- //"Warning must turn off all tracks except big*"); // DEBUG REMOVE
+ //"Warning must turn off all tracks except big*");
initAllChroms();
}
else if (sameString(virtModeType, "demo1"))
{
- //warn("demo two windows on two chroms (default posn chr21, and same loc on chr22"); // DEBUG REMOVE
-
- // NOTE we are losing the ability to specify org and db
+ // demo two windows on two chroms (default posn chr21, and same loc on chr22
//chr21:33,031,597-33,041,570
AllocVar(v);
//chr21:33,031,597-33,041,570
v->chrom = "chr21";
v->start = 33031597 - 1;
v->end = 33041570;
slAddHead(&virtRegionList, v);
struct virtRegion *v2;
AllocVar(v2);
//chr22:33,031,597-33,041,570
//window2->organism = "Mouse";
//window2->database = "mm10";
//window2->database = "hg38";
v2->chrom = "chr22";
v2->start = 33031597 - 1;
v2->end = 33041570;
slAddHead(&virtRegionList, v2);
slReverse(&virtRegionList);
}
else if (sameString(virtModeType, "demo2"))
{
- //warn("demo multiple (70) windows on one chrom chr21 def posn, window size and step exon-like"); // DEBUG REMOVE
+ // demo multiple (70) windows on one chrom chr21 def posn, window size and step exon-like
initExonStep();
}
else if (sameString(virtModeType, "demo4"))
{
- //warn("demo multiple (20) windows showing exons from TITIN gene uc031rqd.1."); // DEBUG REMOVE
+ // demo multiple (20) windows showing exons from TITIN gene uc031rqd.1.
initVirtRegionsFromEmGeneTable("uc031rqd.1"); // TITIN // "uc002ypa.3"); // SOD1
}
else if (sameString(virtModeType, "demo5"))
{
- //warn("demo alt locus on hg38\n"
- //"Shows alt chrom surrounded by preceding and following regions of same size from reference genome "); // DEBUG REMOVE
+ // demo alt locus on hg38
+ // Shows alt chrom surrounded by preceding and following regions of same size from reference genome.
initWindowsAltLoci();
}
else if (sameString(virtModeType, "demo6"))
{
- //warn("demo SOD1\n"
- //"Shows zoomed in exon-exon junction from SOD1 gene, between exon1 and exon2."); // DEBUG REMOVE
+ // demo SOD1
+ // Shows zoomed in exon-exon junction from SOD1 gene, between exon1 and exon2.
initVirtRegionsFromSOD1Hardwired();
}
else
{
- //warn("unrecognized virtModeType = %s", virtModeType);
+ // Unrecognized virtModeType
return FALSE; // return to default mode
}
virtModeExtraState = dyStringCannibalize(&dy);
if (!virtRegionList)
return FALSE; // regionList is empty, nothing found.
return TRUE;
}
boolean isLimitedVisHiddenForAllWindows(struct track *track)
/* Check if track limitedVis == hidden for all windows.
* Return true if all are hidden */
{
boolean result = TRUE;
for(;track;track=track->nextWindow)
if (track->limitedVis != tvHide)
result = FALSE;
return result;
}
boolean isTypeBedLike(struct track *track)
/* Check if track type is BED-like packable thing (but not rmsk or joinedRmsk) */
{ // TODO GALT do we have all the types needed?
// TODO could it be as simple as whether track->items exists?
char *typeLine = track->tdb->type, *words[8], *type;
int wordCount;
-//warn("track %s has type %s", track->track, typeLine);
if (typeLine == NULL)
return FALSE;
wordCount = chopLine(cloneString(typeLine), words);
if (wordCount <= 0)
return FALSE;
type = words[0];
-//warn("track %s has type word[0] = %s, canPack=%d", track->track, type, track->canPack);
if (
( sameWord(type, "bed")
|| sameWord(type, "bed5FloatScore")
|| sameWord(type, "bed6FloatScore")
|| sameWord(type, "bedDetail")
|| sameWord(type, "bigBed")
|| sameWord(type, "bigGenePred")
|| sameWord(type, "broadPeak")
|| sameWord(type, "chain")
|| sameWord(type, "factorSource")
|| sameWord(type, "genePred")
|| sameWord(type, "gvf")
|| sameWord(type, "narrowPeak")
|| sameWord(type, "psl")
//|| track->loadItems == loadSimpleBed
//|| track->bedSize >= 3 // should pick up several ENCODE BED-Plus types.
)
&& track->canPack
)
{
- //warn("track %s is BEDLIKE", track->track);
return TRUE;
}
-//warn("track %s is NOT BEDLIKE", track->track);
return FALSE;
}
boolean isTypeUseItemNameAsKey(struct track *track)
/* Check if track type is like expRatio and key is just item name. */
{
-
char *typeLine = track->tdb->type, *words[8], *type;
int wordCount;
-//warn("track %s has type %s", track->track, typeLine);
if (typeLine == NULL)
return FALSE;
wordCount = chopLine(cloneString(typeLine), words);
if (wordCount <= 0)
return FALSE;
type = words[0];
-//warn("track %s has type word[0] = %s", track->track, type);
if (sameWord(type, "expRatio"))
{
- //warn("track %s is like expRatio, needs one row per item", track->track);
+ // track is like expRatio, needs one row per item
return TRUE;
}
-
-//warn("track %s is NOT like expRatio, which needs only one row per item", track->track);
return FALSE;
}
void setFlatTrackMaxHeight(struct flatTracks *flatTrack, int fontHeight)
/* for each flatTrack, figure out maximum height needed from all windows */
{
struct track *track = flatTrack->track;
int maxHeight = 0;
struct track *winTrack;
struct window *window;
for (window=windows, winTrack=track; window; window=window->next, winTrack=winTrack->nextWindow)
{
setGlobalsFromWindow(window);
int trackHeight = trackPlusLabelHeight(winTrack, fontHeight);
- //warn("track %s height=%d isCenterLabelIncluded(winTrack)=%d\n", winTrack->track, trackHeight, isCenterLabelIncluded(winTrack)); // DEBUG REMOVE
- //fflush(stdout); // DEBUG REMOVE
-
if (trackHeight > maxHeight)
maxHeight = trackHeight;
}
setGlobalsFromWindow(windows); // first window
flatTrack->maxHeight = maxHeight;
-
-//warn("track %s maxHeight=%d\n", track->track, maxHeight); // DEBUG REMOVE
-//fflush(stdout); // DEBUG REMOVE
}
void makeActiveImage(struct track *trackList, char *psOutput)
/* Make image and image map. */
{
-
-boolean galtDebug = FALSE;
-
-if (galtDebug)
-warn("makeActiveImage begins");
-
-struct window *window = NULL;
-
struct track *track;
MgFont *font = tl.font;
struct hvGfx *hvg;
struct tempName pngTn;
char *mapName = "map";
int fontHeight = mgFontLineHeight(font);
int trackPastTabX = (withLeftLabels ? trackTabWidth : 0);
int trackTabX = gfxBorder;
int trackPastTabWidth = tl.picWidth - trackPastTabX;
int pixWidth, pixHeight;
int y=0;
int titleHeight = fontHeight;
int scaleBarPad = 2;
int scaleBarHeight = fontHeight;
int scaleBarTotalHeight = fontHeight + 2 * scaleBarPad;
@@ -4528,32 +4391,30 @@
leftLabelWidth = insideX - gfxBorder*3;
struct image *theOneImg = NULL; // No need to be global, only the map needs to be global
struct image *theSideImg = NULL; // Because dragScroll drags off end of image,
// the side label gets seen. Therefore we need 2 images!!
//struct imgTrack *curImgTrack = NULL; // Make this global for now to avoid huge rewrite
struct imgSlice *curSlice = NULL; // No need to be global, only the map needs to be global
//struct mapSet *curMap = NULL; // Make this global for now to avoid huge rewrite
// Set up imgBox dimensions
int sliceWidth[stMaxSliceTypes]; // Just being explicit
int sliceOffsetX[stMaxSliceTypes];
int sliceHeight = 0;
int sliceOffsetY = 0;
char *rulerTtl = NULL;
-//warn("theImgBox=%lu", (unsigned long)theImgBox); // DEBUG REMOVE
-
if (theImgBox)
// if theImgBox == NULL then we are rendering a simple single image such as right-click View image.
// theImgBox is a global for now to avoid huge rewrite of hgTracks. It is started
// prior to this in doTrackForm()
{
rulerTtl = "drag select or click to zoom";
hPrintf(" \n", database);
hPrintf(" \n", chromName);
hPrintf(" \n", winStart);
hPrintf(" \n", winEnd);
hPrintf(" \n", tl.picWidth);
// If a portal was established, then set the global dimensions to the entire expanded image size
if (imgBoxPortalDimensions(theImgBox,&virtWinStart,&virtWinEnd,&(tl.picWidth),NULL,NULL,NULL,NULL,NULL))
{
pixWidth = tl.picWidth;
@@ -4617,192 +4478,164 @@
yAfterBases = yAfterRuler;
pixHeight += basePositionHeight;
if (rulerCds)
{
yAfterRuler += rulerTranslationHeight;
pixHeight += rulerTranslationHeight;
}
}
/* Hash tracks/subtracks, limit visibility and calculate total image height: */
// For multiple windows, sets height and visibility
// as well as making the flatTrack list.
-if (galtDebug)
-warn("organism=%s database=%s", organism, database); // DEBUG REMOVE
-
// TODO there is a chance that for pack and squish
// I might need to trigger a track-height check here
// since it is after all items are loaded for all windows
// but before things are checked for overflow or limitedVis?
// The fixed non-overflow tracks like knownGene used to initialize
// ss and track height during loadItems(). That was delayed
// because we now need all windows to be fully loaded before
// calculating their joint ss layout and height.
// set heights and visibilities.
-if (galtDebug)
-warn("set heights and visibilities"); // DEBUG REMOVE
+struct window *window = NULL;
for(window=windows;window;window=window->next)
{
- //warn("**** window=%lu insideX=%d insideWidth=%d", (unsigned long) window, window->insideX, window->insideWidth); // DEBUG REMOVE
setGlobalsFromWindow(window);
trackList = window->trackList;
for (track = trackList; track != NULL; track = track->next)
{
if (tdbIsCompositeChild(track->tdb)) // When single track is requested via AJAX,
limitedVisFromComposite(track); // it could be a subtrack
else
{
- //warn("DEBUG REMOVE regular track %s", track->track); // DEBUG REMOVE
limitVisibility(track);
}
if (tdbIsComposite(track->tdb))
{
struct track *subtrack;
for (subtrack = track->subtracks; subtrack != NULL; subtrack = subtrack->next)
{
if (!isSubtrackVisible(subtrack))
continue;
// subtrack vis can be explicit or inherited from composite/view.
// Then it could be limited because of pixel height
limitedVisFromComposite(subtrack);
if (subtrack->limitedVis != tvHide)
{
subtrack->hasUi = track->hasUi;
}
}
}
-
- //warn("heights and vis: track %s vis=%d limitedVis==%d limitedVisSet=%d", track->track, track->visibility, track->limitedVis, track->limitedVisSet); // DEBUG REMOVE
}
}
trackList = windows->trackList;
setGlobalsFromWindow(windows); // first window
// Construct flatTracks
-if (galtDebug)
-warn("Construct flatTracks");
for (track = trackList; track != NULL; track = track->next)
{
- //warn("construct flat track %s vis=%d limitedVis==%d", track->track, track->visibility, track->limitedVis); // DEBUG REMOVE
if (tdbIsComposite(track->tdb))
{
struct track *subtrack;
for (subtrack = track->subtracks; subtrack != NULL; subtrack = subtrack->next)
{
if (!isSubtrackVisible(subtrack))
continue;
- //warn("about to call isLimitedVisHiddenForAllWindows(%s) on subtrack", subtrack->track);
if (!isLimitedVisHiddenForAllWindows(subtrack))
{
- //warn("adding flatTrack subtrack (%s)", subtrack->track); // DEBUG REMOVE
flatTracksAdd(&flatTracks,subtrack,cart);
}
}
}
else
{
- //warn("about to call isLimitedVisHiddenForAllWindows(%s) on track", track->track);// DEBUG REMOVE
if (!isLimitedVisHiddenForAllWindows(track))
{
- //warn("adding flatTrack track (%s)", track->track); // DEBUG REMOVE
flatTracksAdd(&flatTracks,track,cart);
}
}
}
-//warn("slCount(flatTracks)=%d", slCount(flatTracks)); // DEBUG REMOVE
flatTracksSort(&flatTracks); // Now we should have a perfectly good flat track list!
// for each track, figure out maximum height needed from all windows
-if (galtDebug)
-warn("for each track, figure out maximum height needed from all windows");
for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
{
track = flatTrack->track;
if (track->limitedVis == tvHide)
{
- //warn("flat track %s limitedVis==tvHide. why?", track->track); // DEBUG REMOVE
continue;
}
setFlatTrackMaxHeight(flatTrack, fontHeight);
}
-//warn("got done with flatTrack->maxHeight");
-
// fill out track->prevTrack, and check for maxSafeHeight
-if (galtDebug)
-warn("fill out track->prevTrack, and check for maxSafeHeight");
boolean safeHeight = TRUE;
/* firefox on Linux worked almost up to 34,000 at the default 620 width */
#define maxSafeHeight 32000
struct track *prevTrack = NULL;
for (flatTrack = flatTracks,prevTrack=NULL; flatTrack != NULL; flatTrack = flatTrack->next)
{
track = flatTrack->track;
assert(track->limitedVis != tvHide);
// ORIG int totalHeight = pixHeight+trackPlusLabelHeight(track,fontHeight);
- //warn("track %s flat maxHeight=%d", track->track, flatTrack->maxHeight); // DEBUG REMOVE
int totalHeight = pixHeight+flatTrack->maxHeight;
if (totalHeight > maxSafeHeight)
{
char numBuf[SMALLBUF];
sprintLongWithCommas(numBuf, maxSafeHeight);
if (safeHeight) // Only one message
warn("Image is over %s pixels high (%d pix) at the following track which is now "
"hidden: \"%s\".%s", numBuf, totalHeight, track->tdb->longLabel,
(flatTrack->next != NULL ?
" Additional tracks may have also been hidden at this zoom level." : ""));
safeHeight = FALSE;
struct track *winTrack;
for(winTrack=track;winTrack;winTrack=winTrack->nextWindow)
{
track->limitedVis = tvHide;
track->limitedVisSet = TRUE;
}
}
if (!isLimitedVisHiddenForAllWindows(track))
{
- //warn("setting winTracks ->prevTrack to %lu for all windows", (unsigned long) prevTrack); // DEBUG REMOVE
struct track *winTrack;
for(winTrack=track;winTrack;winTrack=winTrack->nextWindow)
{ // TODO this is currently still only using one prev track value.
winTrack->prevTrack = prevTrack; // Important for keeping track of conditional center labels!
}
// ORIG pixHeight += trackPlusLabelHeight(track, fontHeight);
if (!theImgBox) // prevTrack may have altered the height, so recalc height
setFlatTrackMaxHeight(flatTrack, fontHeight);
pixHeight += flatTrack->maxHeight;
prevTrack = track;
}
}
-if (galtDebug)
-warn("About to allocate hvg png pixWidth=%d, pixHeight=%d", pixWidth, pixHeight);
-fflush(stdout); // DEBUG REMOVE
-
+// allocate hvg png of pixWidth, pixHeight
imagePixelHeight = pixHeight;
if (psOutput)
{
hvg = hvGfxOpenPostScript(pixWidth, pixHeight, psOutput);
hvgSide = hvg; // Always only one image
}
else
{
boolean transparentImage = FALSE;
if (theImgBox!=NULL)
transparentImage = TRUE; // transparent because BG (blue ruler lines) is separate image
if (measureTiming)
measureTime("Time at start of obtaining trash hgt png image file");
trashDirFile(&pngTn, "hgt", "hgt", ".png");
@@ -4849,57 +4682,50 @@
// Good to go ahead and add all imgTracks regardless of buttons, left label, centerLabel, etc.
if (theImgBox)
{
if (rulerMode != tvHide)
{
curImgTrack = imgBoxTrackFindOrAdd(theImgBox,NULL,RULER_TRACK_NAME,rulerMode,FALSE,
IMG_FIXEDPOS); // No tdb, no centerLbl, not reorderable
}
for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
{
track = flatTrack->track;
if (!isLimitedVisHiddenForAllWindows(track))
{
- //warn("hvGfxFindRgb !isLimitedVisHiddenForAllWindows(%s)", track->track); // DEBUG REMOVE
struct track *winTrack;
for (winTrack=track; winTrack; winTrack=winTrack->nextWindow)
{
- //warn("hvGfxFindRgb (%s) winTrack labelColor=%d ixColor=%d color=%s", track->track, winTrack->labelColor, winTrack->ixColor, rgbColorToString(winTrack->color)); // DEBUG REMOVE
if (winTrack->labelColor == winTrack->ixColor && winTrack->ixColor == 0)
{
- //warn("hvGfxFindRgb got here window : %s %s %s:%d-%d offset %d width %d", // DEBUG REMOVE
- //window->organism, window->database, window->chromName, window->winStart+1, window->winEnd, window->insideX, window->insideWidth);
-
winTrack->ixColor = hvGfxFindRgb(hvg, &winTrack->color);
-
}
}
int order = flatTrack->order;
curImgTrack = imgBoxTrackFindOrAdd(theImgBox,track->tdb,NULL,track->limitedVis,
isCenterLabelIncluded(track),order);
if (trackShouldUseAjaxRetrieval(track))
imgTrackMarkForAjaxRetrieval(curImgTrack,TRUE);
}
}
}
/* Draw mini-buttons. */
-if (galtDebug)
-warn("Draw mini-buttons.");
+
if (withLeftLabels && psOutput == NULL)
{
int butOff;
boolean grayButtonGroup = FALSE;
struct group *lastGroup = NULL;
y = gfxBorder;
if (rulerMode != tvHide)
{
/* draw button for Base Position pseudo-track */
int height = basePositionHeight;
if (rulerCds)
height += rulerTranslationHeight;
if (theImgBox)
{
// Mini-buttons (side label slice) for ruler
@@ -4914,45 +4740,44 @@
{ // advanced features off // TODO: Should remove wasted pixels too
drawGrayButtonBox(hvgSide, trackTabX, y, trackTabWidth, height, TRUE);
}
mapBoxTrackUi(hvgSide, trackTabX, y, trackTabWidth, height,
RULER_TRACK_NAME, RULER_TRACK_LABEL, "ruler");
y += height + 1;
}
for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
{
track = flatTrack->track;
int h, yStart = y, yEnd;
if (track->limitedVis != tvHide)
{
// ORIG y += trackPlusLabelHeight(track, fontHeight);
- y += flatTrack->maxHeight; // DEBUG REMOVE
+ y += flatTrack->maxHeight;
yEnd = y;
h = yEnd - yStart - 1;
/* alternate button colors for track groups*/
if (track->group != lastGroup)
grayButtonGroup = !grayButtonGroup;
lastGroup = track->group;
if (theImgBox)
{
// Mini-buttons (side label slice) for tracks
sliceHeight = yEnd - yStart;
sliceOffsetY = yStart - 1;
curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
- //warn("GTEX 2: track %s, sliceHeight=%d\n", track->shortLabel, sliceHeight);
curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stButton,NULL,NULL,
sliceWidth[stButton],sliceHeight,
sliceOffsetX[stButton],sliceOffsetY);
}
else if (!trackImgOnly) // Side buttons only need to be drawn when drawing page
{ // with js advanced features off
if (grayButtonGroup)
drawGrayButtonBox(hvgSide, trackTabX, yStart, trackTabWidth, h, track->hasUi);
else
drawBlueButtonBox(hvgSide, trackTabX, yStart, trackTabWidth, h, track->hasUi);
}
if (track->hasUi)
{
if (tdbIsCompositeChild(track->tdb))
@@ -4962,51 +4787,49 @@
parent->track, parent->shortLabel, track->track);
}
else
mapBoxTrackUi(hvgSide, trackTabX, yStart, trackTabWidth, h, track->track,
track->shortLabel, track->track);
}
}
}
butOff = trackTabX + trackTabWidth;
leftLabelX += butOff;
leftLabelWidth -= butOff;
}
/* Draw left labels. */
-if (galtDebug)
-warn("Draw left labels");
+
if (withLeftLabels)
{
if (theImgBox == NULL)
{
Color lightRed = hvGfxFindColorIx(hvgSide, 255, 180, 180);
hvGfxBox(hvgSide, leftLabelX + leftLabelWidth, 0,
gfxBorder, pixHeight, lightRed);
}
y = gfxBorder;
if (rulerMode != tvHide)
{
if (theImgBox)
{
// side label slice for ruler
sliceHeight = basePositionHeight + (rulerCds ? rulerTranslationHeight : 0) + 1;
sliceOffsetY = 0;
curImgTrack = imgBoxTrackFind(theImgBox,NULL,RULER_TRACK_NAME);
- //warn("GTEX 3: track %s, sliceHeight=%d\n", track->shortLabel, sliceHeight);
curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stSide,theSideImg,NULL,
sliceWidth[stSide],sliceHeight,
sliceOffsetX[stSide],sliceOffsetY);
(void) sliceMapFindOrStart(curSlice,RULER_TRACK_NAME,NULL); // No common linkRoot
}
if (baseTitle)
{
hvGfxTextRight(hvgSide, leftLabelX, y, leftLabelWidth-1, titleHeight,
MG_BLACK, font, WIN_TITLE_LABEL);
y += titleHeight;
}
if (baseShowPos||baseShowAsm)
{
hvGfxTextRight(hvgSide, leftLabelX, y, leftLabelWidth-1, showPosHeight,
MG_BLACK, font, WIN_POS_LABEL);
@@ -5049,72 +4872,67 @@
if (zoomedToBaseLevel)
y += baseHeight;
}
if (rulerCds)
y += rulerTranslationHeight;
}
for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
{
track = flatTrack->track;
if (track->limitedVis == tvHide)
continue;
if (theImgBox)
{
// side label slice for tracks
//ORIG sliceHeight = trackPlusLabelHeight(track, fontHeight);
- sliceHeight = flatTrack->maxHeight; // DEBUG REMOVE
+ sliceHeight = flatTrack->maxHeight;
sliceOffsetY = y;
curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
- //warn("GTEX 4: track %s, sliceHeight=%d\n", track->shortLabel, sliceHeight);
curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stSide,theSideImg,NULL,
sliceWidth[stSide],sliceHeight,
sliceOffsetX[stSide],sliceOffsetY);
(void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot
}
if (trackShouldUseAjaxRetrieval(track))
y += REMOTE_TRACK_HEIGHT;
else
{
#ifdef IMAGEv2_NO_LEFTLABEL_ON_FULL
if (theImgBox && track->limitedVis != tvDense)
y += sliceHeight;
else
#endif ///def IMAGEv2_NO_LEFTLABEL_ON_FULL
{
setGlobalsFromWindow(windows); // use GLOBALS from first window
int ynew = doLeftLabels(track, hvgSide, font, y);
- //setGlobalsFromWindow(windows); // first window // REMOVE? this is the same as above
-
- y += flatTrack->maxHeight; // DEBUG REMOVE
+ y += flatTrack->maxHeight;
if ((ynew - y) > flatTrack->maxHeight)
{ // TODO should be errAbort?
warn("doLeftLabels(y=%d) returned new y value %d that is too high - should be %d at most.",
y, ynew, flatTrack->maxHeight);
}
}
}
}
}
else
{
leftLabelX = leftLabelWidth = 0;
}
/* Draw guidelines. */
-if (galtDebug)
-warn("Draw guidelines"); // OR window separators in virtMode multi-window mode
if (virtMode && emAltHighlight)
withGuidelines = TRUE; // we cannot draw the alternating backgrounds without guidelines layer
if (withGuidelines)
{
struct hvGfx *bgImg = hvg; // Default to the one image
boolean exists = FALSE;
if (theImgBox)
{
struct tempName gifBg;
char base[64];
if (virtMode) // window separators
{
safecpy(base,sizeof(base),"winSeparators"); // non-reusable temp file
@@ -5169,187 +4987,160 @@
{
int x;
Color lightBlue = hvGfxFindRgb(bgImg, &guidelineColor);
for (x = fullInsideX+guidelineSpacing-1; xshortLabel, sliceHeight);
curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stData,theOneImg,rulerTtl,
sliceWidth[stData],sliceHeight,
sliceOffsetX[stData],sliceOffsetY);
(void) sliceMapFindOrStart(curSlice,RULER_TRACK_NAME,NULL); // No common linkRoot
}
// need to have real winBaseCount to draw ruler scale
for (window=windows; window; window=window->next)
{
-
- // DETAILS
- // warn("window : %s %s %s:%d-%d offset %d width %d window=%lu", // DEBUG REMOVE
- // window->organism, window->database, window->chromName, window->winStart+1, window->winEnd,
- // window->insideX, window->insideWidth, (unsigned long) window);
-
setGlobalsFromWindow(window);
if (theImgBox)
{
// Show window positions as mouseover
if (virtMode)
{
char position[256];
safef(position, sizeof position, "%s:%d-%d", window->chromName, window->winStart+1, window->winEnd);
int x = window->insideX;
if (revCmplDisp)
x = tl.picWidth - (x + window->insideWidth);
imgTrackAddMapItem(curImgTrack, "#", position,
x, sliceOffsetY, x+window->insideWidth, sliceOffsetY+sliceHeight, RULER_TRACK_NAME);
}
}
y = doDrawRuler(hvg,&rulerClickHeight,rulerHeight,yAfterRuler,yAfterBases,font,
fontHeight,rulerCds, scaleBarTotalHeight, window);
}
setGlobalsFromWindow(windows); // first window
}
/* Draw center labels. */
-if (galtDebug)
-warn("Draw center labels.");
+
if (withCenterLabels)
{
- setGlobalsFromWindow(windows); // use GLOBALS from first window
+ setGlobalsFromWindow(windows); // first window
hvGfxSetClip(hvg, fullInsideX, gfxBorder, fullInsideWidth, pixHeight - 2*gfxBorder);
y = yAfterRuler;
for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
{
track = flatTrack->track;
if (track->limitedVis == tvHide)
continue;
if (theImgBox)
{
// center label slice of tracks Must always make, even if the centerLabel is empty
sliceHeight = fontHeight;
sliceOffsetY = y;
curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stCenter,theOneImg,NULL,
sliceWidth[stData],sliceHeight,
sliceOffsetX[stData],sliceOffsetY);
(void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot
if (isCenterLabelConditional(track)) // sometimes calls track height, especially when no data there
{
- //warn("isCenterLabelConditional(track)=TRUE %s", track->track);
imgTrackUpdateCenterLabelSeen(curImgTrack,isCenterLabelConditionallySeen(track) ?
clNowSeen : clNotSeen);
}
}
if (trackShouldUseAjaxRetrieval(track))
{
- //warn("trackShouldUseAjaxRetrieval(%s)", track->track); // DEBUG REMOVE
y += REMOTE_TRACK_HEIGHT;
}
else
{
int savey = y; // GALT
- //warn("calling doCenterLabels fullInsideWidth=%d", fullInsideWidth); // DEBUG REMOVE
y = doCenterLabels(track, track, hvg, font, y, fullInsideWidth); // calls track height
// TODO GALT why do I just pass track here instead of parentTrack? Did I lose something?
// have to look at old code to see.
-
- y = savey + flatTrack->maxHeight; // GALT
+ y = savey + flatTrack->maxHeight;
}
}
hvGfxUnclip(hvg);
setGlobalsFromWindow(windows); // first window
}
-//warn("Start window draw: %s:%d-%d offset %d width %d",
- // chromName, winStart+1, winEnd, insideX, insideWidth);
-
/* Draw tracks. */
-if (galtDebug)
-warn("Draw tracks");
-
- {
+ { // brace allows local vars
long lastTime = 0;
y = yAfterRuler;
if (measureTiming)
lastTime = clock1000();
for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
{
track = flatTrack->track;
// parallelize more this?:
//ORIG if (track->limitedVis == tvHide)
if (isLimitedVisHiddenForAllWindows(track))
continue;
- //warn("flatTrack->track->track: %s", flatTrack->track->track); // DEBUG REMOVE
- //fflush(stdout); // DEBUG REMOVE
int centerLabelHeight = (isCenterLabelIncluded(track) ? fontHeight : 0);
- //warn("flatTrack->track->track: %s isCenterLabelIncluded(track): %d "
- // "trackPlusLabelHeight(track, fontHeight): %d",
- //flatTrack->track->track, isCenterLabelIncluded(track), trackPlusLabelHeight(track, fontHeight)); // DEBUG REMOVE
int yStart = y + centerLabelHeight;
// ORIG int yEnd = y + trackPlusLabelHeight(track, fontHeight);
- int yEnd = y + flatTrack->maxHeight; // DEBUG REMOVE
+ int yEnd = y + flatTrack->maxHeight;
if (theImgBox)
{
// data slice of tracks
sliceOffsetY = yStart;
sliceHeight = yEnd - yStart - 1;
curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
if (sliceHeight > 0)
{
- //warn("GTEX 7: track %s, sliceHeight=%d\n", track->shortLabel, sliceHeight);
curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stData,theOneImg,NULL,
sliceWidth[stData],sliceHeight,
sliceOffsetX[stData],sliceOffsetY);
(void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot
}
}
if (trackShouldUseAjaxRetrieval(track))
y += REMOTE_TRACK_HEIGHT;
else
{
int savey = y;
struct track *winTrack;
// do preDraw
if (track->preDrawItems)
@@ -5368,133 +5159,128 @@
}
}
}
setGlobalsFromWindow(windows); // first window
// do preDrawMultiRegion across all windows, e.g. wig autoScale
if (track->preDrawMultiRegion)
{
track->preDrawMultiRegion(track);
}
// doDrawItems
for (window=windows, winTrack=track; window; window=window->next, winTrack=winTrack->nextWindow)
{
setGlobalsFromWindow(window);
- //warn("Draw tracks track dump %s\n", makeTrackDumpLink(track)); // DEBUG REMOVE
if (winTrack->limitedVis == tvHide)
{
warn("Draw tracks skipping %s because winTrack->limitedVis=hide", winTrack->track);
continue;
}
if (insideWidth >= 1) // do not try to draw if width < 1.
{
int ynew = doDrawItems(winTrack, hvg, font, y, &lastTime);
- //warn("y=%d ynew=%d (ynew-y)=%d flatTrack->maxHeight=%d", y, ynew, ynew - y, flatTrack->maxHeight);
if ((ynew-y) > flatTrack->maxHeight) // so compiler does not complain ynew is not used.
errAbort("oops track too high!");
}
}
setGlobalsFromWindow(windows); // first window
y = savey + flatTrack->maxHeight;
}
if (theImgBox && track->limitedVis == tvDense && tdbIsCompositeChild(track->tdb))
mapBoxToggleVis(hvg, 0, yStart,tl.picWidth, sliceHeight,track);
// Strange mapBoxToggleLogic handles reverse complement itself so x=0,width=tl.picWidth
if (yEnd != y)
warn("Slice height for track %s does not add up. Expecting %d != %d actual",
track->shortLabel, yEnd - yStart - 1, y - yStart);
}
y++;
}
-if (galtDebug)
-warn("post draw tracks leftLabels");
+/* post draw tracks leftLabels */
/* if a track can draw its left labels, now is the time since it
* knows what exactly happened during drawItems
*/
// TODO GALT Parellelize or not?
if (withLeftLabels)
{
y = yAfterRuler;
for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
{
track = flatTrack->track;
if (track->limitedVis == tvHide)
continue;
if (theImgBox)
{
// side label slice of tracks
// ORIG sliceHeight = trackPlusLabelHeight(track, fontHeight);
- sliceHeight = flatTrack->maxHeight; // DEBUG REMOVE
+ sliceHeight = flatTrack->maxHeight;
sliceOffsetY = y;
curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
- //warn("WARN 8: track %s, sliceHeight=%d\n", track->shortLabel, sliceHeight);
curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stSide,theSideImg,NULL,
sliceWidth[stSide],sliceHeight,
sliceOffsetX[stSide],sliceOffsetY);
(void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot
}
if (trackShouldUseAjaxRetrieval(track))
y += REMOTE_TRACK_HEIGHT;
#ifdef IMAGEv2_NO_LEFTLABEL_ON_FULL
else if (track->drawLeftLabels != NULL
&& (theImgBox == NULL || track->limitedVis == tvDense))
#else ///ndef IMAGEv2_NO_LEFTLABEL_ON_FULL
else if (track->drawLeftLabels != NULL)
#endif ///ndef IMAGEv2_NO_LEFTLABEL_ON_FULL
{ // TODO parallelize?
setGlobalsFromWindow(windows);
y = doOwnLeftLabels(track, hvgSide, font, y);
setGlobalsFromWindow(windows); // first window
}
else
// ORIG y += trackPlusLabelHeight(track, fontHeight);
- y += flatTrack->maxHeight; // DEBUG REMOVE
+ y += flatTrack->maxHeight;
}
}
/* Make map background. */
-if (galtDebug)
-warn("Make map background");
+
y = yAfterRuler;
for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
{
track = flatTrack->track;
if (track->limitedVis != tvHide)
{
if (theImgBox)
{
// Set imgTrack in case any map items will be set
// ORIG sliceHeight = trackPlusLabelHeight(track, fontHeight);
- sliceHeight = flatTrack->maxHeight; // DEBUG REMOVE
+ sliceHeight = flatTrack->maxHeight;
sliceOffsetY = y;
curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
}
// TODO Parallelize?
setGlobalsFromWindow(windows); // first window
doTrackMap(track, hvg, y, fontHeight, trackPastTabX, trackPastTabWidth);
// ORIG y += trackPlusLabelHeight(track, fontHeight);
- y += flatTrack->maxHeight; // DEBUG REMOVE
+ y += flatTrack->maxHeight;
}
}
/* Finish map. */
hPrintf(" \n");
// turn off inPlaceUpdate when rows in imgTbl can arbitrarily reappear and disappear (see redmine #7306 and #6944)
jsonObjectAdd(jsonForClient, "inPlaceUpdate", newJsonBoolean(withLeftLabels && withCenterLabels));
jsonObjectAdd(jsonForClient, "rulerClickHeight", newJsonNumber(rulerClickHeight));
if(newWinWidth)
{
jsonObjectAdd(jsonForClient, "newWinWidth", newJsonNumber(newWinWidth));
}
/* Save out picture and tell html file about it. */
@@ -5682,31 +5468,30 @@
if (cgiVarExists("hgGenomeClick"))
makeHgGenomeTrackVisible(track);
if (track->loadItems == NULL)
warn("No load handler for %s; possible missing trackDb `type' or `subTrack' attribute", tdb->track);
else if (track->drawItems == NULL)
warn("No draw handler for %s", tdb->track);
else
slAddHead(pTrackList, track);
}
}
void loadFromTrackDb(struct track **pTrackList)
/* Load tracks from database, consulting handler list. */
{
char *trackNameFilter = cartOptionalString(cart, "hgt.trackNameFilter");
-//warn("DEBUG loadFromTrackDb:: hgt.trackNameFilter=%s\n", trackNameFilter); // DEBUG REMOVE GALT
struct trackDb *tdbList;
if(trackNameFilter == NULL)
tdbList = hTrackDb(database);
else
tdbList = hTrackDbForTrack(database, trackNameFilter);
addTdbListToTrackList(tdbList, trackNameFilter, pTrackList);
}
static int getScoreFilter(char *trackName)
/* check for score filter configuration setting */
{
char optionScoreStr[256];
safef(optionScoreStr, sizeof(optionScoreStr), "%s.scoreFilter", trackName);
return cartUsualInt(cart, optionScoreStr, 0);
@@ -7470,31 +7255,30 @@
/////////////////
// NEED TO LOAD ALL WINDOWS NOW
//
// Need to load one window at a time!
//
// The use of the global values for a window
// means that differerent threads cannot use different global window values.
// Threads must run on just one window value at a time.
//
// Begin by making a copy of the track structure for visible tracks
// for all windows.
-//warn("copy track structures for multiple windows"); // DEBUG REMOVE
// COPY TRACK STRUCTURES for other windows.
// TODO: due to an issue where some loading code is modifying the visibility
// of subtracks from hide to visible, I am forced to remove the optimization
// of cloning ONLY non-hidden tracks and subtracks. If the offending code
// can be identified and moved into a step proceding the track cloning,
// then we can return to that optimization.
// if (track->visibility != tvHide)
// if (subtrack->visibility != tvHide)
windows->trackList = trackList; // save current track list in window
struct window *window;
for (window=windows; window->next; window=window->next)
{
struct track *newTrackList = NULL;
@@ -7520,52 +7304,44 @@
{
//if (subtrack->visibility != tvHide) // Unable to use this optimization at present
{
struct track *subcopy;
AllocVar(subcopy);
memmove(subcopy,subtrack,sizeof(struct track));
subcopy->next = NULL;
subcopy->bbiFile = NULL; // bigDataUrl custom tracks have already been opened, will re-open for other windows.
subcopy->nextWindow = NULL;
subcopy->prevWindow = subtrack;
slAddHead(©->subtracks, subcopy);
subtrack->nextWindow = subcopy;
}
}
slReverse(©->subtracks);
- //warn("%s track subs: %d copy subs: %d", track->track, slCount(track->subtracks), slCount(copy->subtracks));
}
}
slReverse(&newTrackList);
trackList = newTrackList;
window->next->trackList = trackList; // save new track list in window
}
trackList = windows->trackList; // restore original track list
-// DEBUG REMOVE verify results.
-//for (window=windows; window; window=window->next)
-// {
-// warn("%s %d", window->chromName, slCount(window->trackList));
-// }
-
// Loop over each window loading all tracks
-//warn("Loop over each window loading all tracks"); // DEBUG REMOVE
trackLoadingInProgress = TRUE;
// TEMP HACK GALT REMOVE
bool loadHack = FALSE; //TRUE; // probably should only be tried on non-wiggle tracks
-//warn ("loadHack = %d", loadHack); // DEBUG REMOVE
+//warn ("loadHack = %d", loadHack); // TODO
int lastWinEnd = 0;
for (window=windows; window; window=window->next)
lastWinEnd = window->winEnd;
for (window=windows; window; window=window->next)
{
trackList = window->trackList; // set track list
setGlobalsFromWindow(window);
// TEMP HACK GALT REMOVE
if (loadHack)
{
if (currentWindow == windows) // first window
winEnd = lastWinEnd; // so now we load the entire span inside the first window.
}
@@ -7585,96 +7361,77 @@
AllocArray(threads, ptMax);
/* Create threads */
int pt;
for (pt = 0; pt < ptMax; ++pt)
{
int rc = pthread_create(&threads[pt], NULL, remoteParallelLoad, &threads[pt]);
if (rc)
{
errAbort("Unexpected error %d from pthread_create(): %s",rc,strerror(rc));
}
}
}
}
// TODO GALT
- //warn("slCount(trackList) just before load regular tracks: %d", slCount(trackList)); // DEBUG REMOVE
- int visCount = 0; // DEBUG REMOVE
/* load regular tracks */
for (track = trackList; track != NULL; track = track->next)
{
if (track->visibility != tvHide)
{
- ++visCount; // DEBUG REMOVE
if (!track->parallelLoading)
{
if (measureTiming)
lastTime = clock1000();
- //warn("load regular tracks BEFORE load and check max window to draw %s\n", makeTrackDumpLink(track)); // DEBUG REMOVE
checkMaxWindowToDraw(track);
- //warn("load regular tracks BEFORE check if wiggling %s\n", makeTrackDumpLink(track)); // DEBUG REMOVE
checkIfWiggling(cart, track);
- //warn("load regular tracks ABOUT to call loadItems() %s\n", makeTrackDumpLink(track)); // DEBUG REMOVE
-
if (!loadHack)
{
- track->loadItems(track); // DEBUG RESTORE !!!
+ track->loadItems(track);
}
else
{
// TEMP HACK GALT REMOVE
if (currentWindow == windows) // first window
{
track->loadItems(track);
}
else
{
track->items = track->prevWindow->items; // just point to the previous windows items (faster than loading)
// apparently loadItems is setting some other fields that we want, but which ones?
track->visibility = track->prevWindow->visibility;
track->limitedVis = track->prevWindow->limitedVis;
track->limitedVisSet = track->prevWindow->limitedVisSet;
track->height = track->prevWindow->height;
track->lineHeight = track->prevWindow->lineHeight;
track->heightPer = track->prevWindow->heightPer;
// TODO does this work for subtracks or parents/children?
}
}
- // DEBUG REMOVE how many visible subtracks?
- int visSubCount = 0;
- struct track *sub;
- for (sub=track->subtracks; sub; sub=sub->next)
- if (sub->visibility != tvHide)
- ++visSubCount;
-
- //warn("load regular tracks AFTER loadItems #%d %s type %s subtracks %d vis %d %s\n",
- //visCount, track->track, trackDbSetting(track->tdb, "type"),
- //slCount(track->subtracks), visSubCount, makeTrackDumpLink(track)); // DEBUG REMOVE
-
if (measureTiming)
{
thisTime = clock1000();
track->loadTime = thisTime - lastTime;
}
}
}
}
- //warn("after load regular tracks: %d", visCount); // DEBUG REMOVE
if (ptMax > 0)
{
// TODO GALT parallel actually not sure if anything to worry about here
/* wait for remote parallel load to finish */
remoteParallelLoadWait(atoi(cfgOptionDefault("parallelFetch.timeout", "90"))); // wait up to default 90 seconds.
if (measureTiming)
measureTime("Waiting for parallel (%d threads for %d tracks) remote data fetch", ptMax, pfdListCount);
}
}
trackLoadingInProgress = FALSE;
setGlobalsFromWindow(windows); // first window // restore globals
trackList = windows->trackList; // restore track list
@@ -7721,45 +7478,36 @@
}
}
if (theImgBox)
{
// If a portal was established, then set the global dimensions back to the portal size
if (imgBoxPortalDimensions(theImgBox,NULL,NULL,NULL,NULL,&virtWinStart,&virtWinEnd,&(tl.picWidth),NULL))
{
virtWinBaseCount = virtWinEnd - virtWinStart;
fullInsideWidth = tl.picWidth-gfxBorder-fullInsideX;
}
}
/* Center everything from now on. */
hPrintf("
\n");
-// OLD WAY
-//jsonObjectAdd(jsonForClient, "winStart", newJsonNumber(winStart));
-//jsonObjectAdd(jsonForClient, "winEnd", newJsonNumber(winEnd));
-//jsonObjectAdd(jsonForClient, "chromName", newJsonString(chromName));
-// DONE instead of trying to add new variables here,
-// see if we can pass the virt versions in as if they were the original variables.
-// That way less of hgTracks.js would need to be changed.
jsonObjectAdd(jsonForClient, "winStart", newJsonNumber(virtWinStart));
jsonObjectAdd(jsonForClient, "winEnd", newJsonNumber(virtWinEnd));
jsonObjectAdd(jsonForClient, "chromName", newJsonString(virtChromName));
// Tell javascript about multiple windows info
-// GALT TODO if end up not using this information, turn this off
-// as it sends several K of extra data on a view with many windows.
if (virtMode)
{
// pre windows
long preVWinStart = virtWinStart - virtWinBaseCount;
if (preVWinStart < 0)
preVWinStart = 0;
long preVWinEnd = virtWinStart;
struct window *preWindows = makeWindowListFromVirtChrom(preVWinStart, preVWinEnd);
struct jsonElement *jsonForList = newJsonList(NULL);
for(window=preWindows;window;window=window->next)
{
struct jsonElement *jsonForWindow = NULL;
jsonForWindow = newJsonObject(newHash(8));
jsonObjectAdd(jsonForWindow, "chromName", newJsonString(window->chromName));
jsonObjectAdd(jsonForWindow, "winStart", newJsonNumber(window->winStart));
@@ -7918,31 +7666,30 @@
if (showTrackControls)
{
/* Break into a second form so that zooming and scrolling
* can be done with a 'GET' so that user can back up from details
* page without Internet Explorer popping up an annoying dialog.
* Do rest of page as a 'POST' so that the ultra-long URL from
* all the track controls doesn't break things. IE URL limit
* is 2000 bytes, but some firewalls impose a ~1000 byte limit.
* As a side effect of breaking up the page into two forms
* we need to repeat the position in a hidden variable here
* so that zoom/scrolling always has current position to work
* from. */
// This 'dirty' field is used to check if js/ajax changes to the page have occurred.
// If so and it is reached by the back button, a page reload will occur instead.
char buf[256];
- // DEBUG RESTORE
if (virtualSingleChrom()) // DISGUISE VMODE
safef(buf, sizeof buf, "%s", windowsSpanPosition());
else
safef(buf, sizeof buf, "%s:%ld-%ld", virtChromName, virtWinStart+1, virtWinEnd);
hPrintf(" \n");
hPrintf(" ", buf);
hPrintf("\n%s", trackGroupsHidden1->string);
hPrintf(" \n");
hPrintf("