d781bc31ad6c4a86a3b8e1f0e78827a08c544128
tdreszer
Fri Oct 1 11:05:56 2010 -0700
Fixing git mess (I hope) created from an accidental 'git add .'
diff --git src/hg/hgTracks/hgTracks.c.old src/hg/hgTracks/hgTracks.c.old
deleted file mode 100644
index f68887d..0000000
--- src/hg/hgTracks/hgTracks.c.old
+++ /dev/null
@@ -1,5646 +0,0 @@
-/* hgTracks - the original, and still the largest module for the UCSC Human Genome
- * Browser main cgi script. Currently contains most of the track framework, though
- * there's quite a bit of other framework type code in simpleTracks.c. The main
- * routine got moved to create a new entry point to the bulk of the code for the
- * hgRenderTracks web service. See mainMain.c for the main used by the hgTracks CGI. */
-
-#include "common.h"
-#include "hCommon.h"
-#include "linefile.h"
-#include "portable.h"
-#include "memalloc.h"
-#include "localmem.h"
-#include "obscure.h"
-#include "dystring.h"
-#include "hash.h"
-#include "jksql.h"
-#include "gfxPoly.h"
-#include "memgfx.h"
-#include "hvGfx.h"
-#include "psGfx.h"
-#include "cheapcgi.h"
-#include "hPrint.h"
-#include "htmshell.h"
-#include "cart.h"
-#include "hdb.h"
-#include "hui.h"
-#include "hgFind.h"
-#include "hgTracks.h"
-#include "trashDir.h"
-#include "grp.h"
-#include "versionInfo.h"
-#include "web.h"
-#include "cds.h"
-#include "cutterTrack.h"
-#include "wikiTrack.h"
-#include "ctgPos.h"
-#include "bed.h"
-#include "bigBed.h"
-#include "bigWig.h"
-#include "bedCart.h"
-#include "customTrack.h"
-#include "cytoBand.h"
-#include "ensFace.h"
-#include "liftOver.h"
-#include "pcrResult.h"
-#include "wikiLink.h"
-#include "jsHelper.h"
-#include "mafTrack.h"
-#include "hgConfig.h"
-#include "encode.h"
-#include "agpFrag.h"
-#include "imageV2.h"
-#include "suggest.h"
-#include "searchTracks.h"
-
-static char const rcsid[] = "$Id: doMiddle.c,v 1.1651 2010/06/11 17:53:06 larrym Exp $";
-
-/* These variables persist from one incarnation of this program to the
- * next - living mostly in the cart. */
-boolean baseShowPos; /* TRUE if should display full position at top of base track */
-boolean baseShowAsm; /* TRUE if should display assembly info at top of base track */
-boolean baseShowScaleBar; /* TRUE if should display scale bar at very top of base track */
-boolean baseShowRuler; /* TRUE if should display the basic ruler in the base track (default) */
-char *baseTitle = NULL; /* Title it should display top of base track (optional)*/
-static char *userSeqString = NULL; /* User sequence .fa/.psl file. */
-
-/* These variables are set by getPositionFromCustomTracks() at the very
- * beginning of tracksDisplay(), and then used by loadCustomTracks(). */
-char *ctFileName = NULL; /* Custom track file. */
-struct customTrack *ctList = NULL; /* Custom tracks. */
-boolean hasCustomTracks = FALSE; /* whether any custom tracks are for this db*/
-struct slName *browserLines = NULL; /* Custom track "browser" lines. */
-
-boolean withNextItemArrows = FALSE; /* Display next feature (gene) navigation buttons near center labels? */
-boolean withPriorityOverride = FALSE; /* Display priority for each track to allow reordering */
-
-int gfxBorder = hgDefaultGfxBorder; /* Width of graphics border. */
-int guidelineSpacing = 12; /* Pixels between guidelines. */
-
-boolean withIdeogram = TRUE; /* Display chromosome ideogram? */
-
-int rulerMode = tvHide; /* on, off, full */
-
-char *rulerMenu[] =
-/* dropdown for ruler visibility */
- {
- "hide",
- "dense",
- "full"
- };
-
-char *protDbName; /* Name of proteome database for this genome. */
-#define MAX_CONTROL_COLUMNS 6
-#define LOW 1
-#define MEDIUM 2
-#define BRIGHT 3
-#define MAXCHAINS 50000000
-boolean hgDebug = FALSE; /* Activate debugging code. Set to true by hgDebug=on in command line*/
-int imagePixelHeight = 0;
-boolean dragZooming = TRUE;
-struct hash *oldVars = NULL;
-
-boolean hideControls = FALSE; /* Hide all controls? */
-boolean trackImgOnly = FALSE; /* caller wants just the track image and track table html */
-boolean ideogramToo = FALSE; /* caller wants the ideoGram (when requesting just one track) */
-
-/* Structure returned from findGenomePos.
- * We use this to to expand any tracks to full
- * that were found to contain the searched-upon
- * position string */
-struct hgPositions *hgp = NULL;
-
-
-/* Other global variables. */
-struct group *groupList = NULL; /* List of all tracks. */
-char *browserName; /* Test or public browser */
-char *organization; /* UCSC */
-
-
-struct track *trackFindByName(struct track *tracks, char *trackName)
-/* find a track in tracks by name, recursively searching subtracks */
-{
-struct track *track;
-for (track = tracks; track != NULL; track = track->next)
- {
- if (sameString(track->track, trackName))
- return track;
- else if (track->subtracks != NULL)
- {
- struct track *st = trackFindByName(track->subtracks, trackName);
- if (st != NULL)
- return st;
- }
- }
-return NULL;
-}
-
-int tgCmpPriority(const void *va, const void *vb)
-/* Compare to sort based on priority; use shortLabel as secondary sort key. */
-{
-const struct track *a = *((struct track **)va);
-const struct track *b = *((struct track **)vb);
-float dif = a->group->priority - b->group->priority;
-
-if (dif == 0)
- dif = a->priority - b->priority;
-if (dif < 0)
- return -1;
-else if (dif == 0.0)
- /* secondary sort on label */
- return strcasecmp(a->shortLabel, b->shortLabel);
-else
- return 1;
-}
-
-int trackRefCmpPriority(const void *va, const void *vb)
-/* Compare based on priority. */
-{
-const struct trackRef *a = *((struct trackRef **)va);
-const struct trackRef *b = *((struct trackRef **)vb);
-return tgCmpPriority(&a->track, &b->track);
-}
-
-int gCmpPriority(const void *va, const void *vb)
-/* Compare groups based on priority. */
-{
-const struct group *a = *((struct group **)va);
-const struct group *b = *((struct group **)vb);
-float dif = a->priority - b->priority;
-
-if (dif == 0)
- return 0;
-if (dif < 0)
- return -1;
-else if (dif == 0.0)
- return 0;
-else
- return 1;
-}
-
-void changeTrackVis(struct group *groupList, char *groupTarget, int changeVis)
-/* Change track visibilities. If groupTarget is
- * NULL then set visibility for tracks in all groups. Otherwise,
- * just set it for the given group. If vis is -2, then visibility is
- * unchanged. If -1 then set visibility to default, otherwise it should
- * be tvHide, tvDense, etc.
- * If we are going back to default visibility, then reset the track
- * ordering also. */
-{
-struct group *group;
-if (changeVis == -2)
- return;
-for (group = groupList; group != NULL; group = group->next)
- {
- struct trackRef *tr;
- if (groupTarget == NULL || sameString(group->name,groupTarget))
- {
- static char pname[512];
- /* if default vis then reset group priority */
- if (changeVis == -1)
- group->priority = group->defaultPriority;
- for (tr = group->trackList; tr != NULL; tr = tr->next)
- {
- struct track *track = tr->track;
- struct trackDb *tdb = track->tdb;
- if (changeVis == -1) // to default
- {
- if(tdbIsComposite(tdb))
- {
- safef(pname, sizeof(pname),"%s.*",track->track); //to remove all settings associated with this composite!
- cartRemoveLike(cart,pname);
- struct track *subTrack;
- for(subTrack = track->subtracks;subTrack != NULL; subTrack = subTrack->next)
- {
- subTrack->visibility = tdb->visibility;
- cartRemove(cart, subTrack->track);
- }
- }
-
- /* restore defaults */
- if (tdbIsSuperTrackChild(tdb) || tdbIsCompositeChild(tdb))
- {
- assert(tdb->parent != NULL && tdb->parent->track);
- cartRemove(cart, tdb->parent->track);
- if (withPriorityOverride)
- {
- safef(pname, sizeof(pname), "%s.priority",tdb->parent->track);
- cartRemove(cart, pname);
- }
- }
-
- track->visibility = tdb->visibility;
- cartRemove(cart, track->track);
-
- /* set the track priority back to the default value */
- if (withPriorityOverride)
- {
- safef(pname, sizeof(pname), "%s.priority",track->track);
- cartRemove(cart, pname);
- track->priority = track->defaultPriority;
- }
- }
- else // to changeVis value (Usually tvHide)
- {
- /* change to specified visibility */
- if (tdbIsSuperTrackChild(tdb))
- {
- assert(tdb->parent != NULL);
- /* Leave supertrack members alone -- only change parent */
- struct trackDb *parentTdb = tdb->parent;
- if ((changeVis == tvHide && !parentTdb->isShow) ||
- (changeVis != tvHide && parentTdb->isShow))
- {
- /* remove if setting to default vis */
- cartRemove(cart, parentTdb->track);
- }
- else
- cartSetString(cart, parentTdb->track,
- changeVis == tvHide ? "hide" : "show");
- }
- else // Not super child
- {
- if (changeVis == tdb->visibility)
- /* remove if setting to default vis */
- cartRemove(cart, track->track);
- else
- cartSetString(cart, track->track, hStringFromTv(changeVis));
- track->visibility = changeVis;
- }
-
- #ifdef SUBTRACKS_HAVE_VIS
- // Whether super child or not, if its a composite, then handle the children
- if (tdbIsComposite(tdb))
- {
- struct track *subtrack;
- for(subtrack=track->subtracks;subtrack!=NULL;subtrack=subtrack->next)
- {
- if (changeVis == tvHide)
- cartRemove(cart, subtrack->track); // Since subtrack level vis is an override, simply remove it to hide it
- else
- cartSetString(cart, subtrack->track, hStringFromTv(changeVis));
- subtrack->visibility = changeVis;
- }
- }
- #endif///def SUBTRACKS_HAVE_VIS
- }
- }
- }
- }
-slSort(&groupList, gCmpPriority);
-}
-
-int trackOffsetX()
-/* Return x offset where track display proper begins. */
-{
-int x = gfxBorder;
-if (withLeftLabels)
- x += tl.leftLabelWidth + gfxBorder;
-return x;
-}
-
-
-static void mapBoxTrackUi(struct hvGfx *hvg, int x, int y, int width,
- int height, char *name, char *shortLabel, char *id)
-/* Print out image map rectangle that invokes hgTrackUi. */
-{
-x = hvGfxAdjXW(hvg, x, width);
-char *url = trackUrl(name, chromName);
-
-if(theImgBox && curImgTrack)
- {
- struct imgSlice *curSlice = imgTrackSliceGetByType(curImgTrack,stButton);
- if(curSlice)
- sliceAddLink(curSlice,url,shortLabel);
- }
-else
- {
- hPrintf(" \n");
- }
-freeMem(url);
-}
-
-static void mapBoxToggleComplement(struct hvGfx *hvg, int x, int y, int width, int height,
- struct track *toggleGroup, char *chrom,
- int start, int end, char *message)
-/*print out a box along the DNA bases that toggles a cart variable
- * "complement" to complement the DNA bases at the top by the ruler*/
-{
-struct dyString *ui = uiStateUrlPart(toggleGroup);
-x = hvGfxAdjXW(hvg, x, width);
-if(theImgBox && curImgTrack)
- {
- char link[512];
- safef(link,sizeof(link),"%s?complement_%s=%d&%s",
- hgTracksName(), database, !cartUsualBooleanDb(cart, database, COMPLEMENT_BASES_VAR, FALSE),ui->string);
- imgTrackAddMapItem(curImgTrack,link,(char *)(message != NULL?message:NULL),x, y, x+width, y+height, NULL);
- }
-else
- {
- hPrintf(" string);
- freeDyString(&ui);
- if (message != NULL)
- mapStatusMessage("%s", message);
- hPrintf(">\n");
- }
-}
-
-char *trackUrl(char *mapName, char *chromName)
-/* Return hgTrackUi url; chromName is optional. */
-{
-char *encodedMapName = cgiEncode(mapName);
-char buf[2048];
-if(chromName == NULL)
- safef(buf, sizeof(buf), "%s?%s=%u&g=%s", hgTrackUiName(), cartSessionVarName(), cartSessionId(cart), encodedMapName);
-else
- safef(buf, sizeof(buf), "%s?%s=%u&c=%s&g=%s", hgTrackUiName(), cartSessionVarName(), cartSessionId(cart), chromName, encodedMapName);
-freeMem(encodedMapName);
-return(cloneString(buf));
-}
-
-void smallBreak()
-/* Draw small horizontal break */
-{
-hPrintf(" \n");
-}
-
-static int trackPlusLabelHeight(struct track *track, int fontHeight)
-/* Return the sum of heights of items in this track (or subtrack as it may be)
- * and the center label(s) above the items (if any). */
-{
-int y = track->totalHeight(track, limitVisibility(track));
-if (isCenterLabelIncluded(track))
- y += fontHeight;
-if (tdbIsComposite(track->tdb))
- {
- struct track *subtrack;
- for (subtrack = track->subtracks; subtrack != NULL; subtrack = subtrack->next)
- {
- if (isSubtrackVisible(subtrack) && isCenterLabelIncluded(subtrack))
- y += fontHeight;
- }
- }
-return y;
-}
-
-void drawColoredButtonBox(struct hvGfx *hvg, int x, int y, int w, int h,
- int enabled, Color shades[])
-/* draw button box, providing shades of the desired button color */
-{
-int light = shades[1], mid = shades[2], dark = shades[4];
-if (enabled)
- {
- hvGfxBox(hvg, x, y, w, 1, light);
- hvGfxBox(hvg, x, y+1, 1, h-1, light);
- hvGfxBox(hvg, x+1, y+1, w-2, h-2, mid);
- hvGfxBox(hvg, x+1, y+h-1, w-1, 1, dark);
- hvGfxBox(hvg, x+w-1, y+1, 1, h-1, dark);
- }
-else /* try to make the button look as if
- * it is already depressed */
- {
- hvGfxBox(hvg, x, y, w, 1, dark);
- hvGfxBox(hvg, x, y+1, 1, h-1, dark);
- hvGfxBox(hvg, x+1, y+1, w-2, h-2, light);
- hvGfxBox(hvg, x+1, y+h-1, w-1, 1, light);
- hvGfxBox(hvg, x+w-1, y+1, 1, h-1, light);
- }
-}
-
-void drawGrayButtonBox(struct hvGfx *hvg, int x, int y, int w, int h, int enabled)
-/* Draw a gray min-raised looking button. */
-{
- drawColoredButtonBox(hvg, x, y, w, h, enabled, shadesOfGray);
-}
-
-void drawBlueButtonBox(struct hvGfx *hvg, int x, int y, int w, int h, int enabled)
-/* Draw a blue min-raised looking button. */
-{
- drawColoredButtonBox(hvg, x, y, w, h, enabled, shadesOfSea);
-}
-
-void drawButtonBox(struct hvGfx *hvg, int x, int y, int w, int h, int enabled)
-/* Draw a standard (gray) min-raised looking button. */
-{
- drawGrayButtonBox(hvg, x, y, w, h, enabled);
-}
-
-void beforeFirstPeriod( char *str )
-{
-char *t = rindex( str, '.' );
-
-if( t == NULL )
- return;
-else
- str[strlen(str) - strlen(t)] = '\0';
-}
-
-static void drawBases(struct hvGfx *hvg, int x, int y, int width, int height,
- Color color, MgFont *font, boolean complementSeq,
- struct dnaSeq *thisSeq)
-/* Draw evenly spaced bases. */
-{
-struct dnaSeq *seq;
-
-if (thisSeq == NULL)
- seq = hDnaFromSeq(database, chromName, winStart, winEnd, dnaUpper);
-else
- seq = thisSeq;
-
-if (complementSeq)
- complement(seq->dna, seq->size);
-spreadBasesString(hvg, x, y, width, height, color, font,
- seq->dna, seq->size, FALSE);
-
-if (thisSeq == NULL)
- freeDnaSeq(&seq);
-}
-
-void drawComplementArrow( struct hvGfx *hvg, int x, int y,
- int width, int height, MgFont *font)
-/* Draw arrow and create clickbox for complementing ruler bases */
-{
-boolean baseCmpl = cartUsualBooleanDb(cart, database, COMPLEMENT_BASES_VAR, FALSE);
-// reverse arrow when base complement doesn't match display
-char *text = (baseCmpl == revCmplDisp) ? "--->" : "<---";
-hvGfxTextRight(hvg, x, y, width, height, MG_BLACK, font, text);
-mapBoxToggleComplement(hvg, x, y, width, height, NULL, chromName, winStart, winEnd,
- "complement bases");
-}
-
-struct track *chromIdeoTrack(struct track *trackList)
-/* Find chromosome ideogram track */
-{
-struct track *track;
-for(track = trackList; track != NULL; track = track->next)
- {
- if(sameString(track->track, "cytoBandIdeo"))
- {
- if (hTableExists(database, track->table))
- return track;
- else
- return NULL;
- }
- }
-return NULL;
-}
-
-void removeTrackFromGroup(struct track *track)
-/* Remove track from group it is part of. */
-{
-struct trackRef *tr = NULL;
-for(tr = track->group->trackList; tr != NULL; tr = tr->next)
- {
- if(tr->track == track)
- {
- slRemoveEl(&track->group->trackList, tr);
- break;
- }
- }
-}
-
-
-void fillInStartEndBands(struct track *ideoTrack, char *startBand, char *endBand, int buffSize)
-/* Loop through the bands and fill in the one that the current window starts
- on and ends on. */
-{
-struct cytoBand *cb = NULL, *cbList = ideoTrack->items;
-for(cb = cbList; cb != NULL; cb = cb->next)
- {
- /* If the start or end is encompassed by this band fill
- it in. */
- if(winStart >= cb->chromStart &&
- winStart <= cb->chromEnd)
- {
- safef(startBand, buffSize, "%s", cb->name);
- }
- /* End is > rather than >= due to odditiy in the
- cytoband track where the starts and ends of two
- bands overlaps by one. */
- if(winEnd > cb->chromStart &&
- winEnd <= cb->chromEnd)
- {
- safef(endBand, buffSize, "%s", cb->name);
- }
- }
-}
-
-void makeChromIdeoImage(struct track **pTrackList, char *psOutput,
- struct tempName *ideoTn)
-/* Make an ideogram image of the chromsome and our position in it. If the
- * ideoTn parameter is not NULL, it is filled in if the ideogram is created. */
-{
-struct track *ideoTrack = NULL;
-MgFont *font = tl.font;
-char *mapName = "ideoMap";
-struct hvGfx *hvg;
-boolean doIdeo = TRUE;
-boolean ideogramAvail = FALSE;
-int ideoWidth = round(.8 *tl.picWidth);
-int ideoHeight = 0;
-int textWidth = 0;
-struct tempName gifTn;
-if (ideoTn == NULL)
- ideoTn = &gifTn; // not returning value
-
-ideoTrack = chromIdeoTrack(*pTrackList);
-
-/* If no ideogram don't draw. */
-if(ideoTrack == NULL)
- doIdeo = FALSE;
-else if(trackImgOnly && !ideogramToo)
- {
- doIdeo = FALSE;
- }
-else
- {
- ideogramAvail = TRUE;
- /* Remove the track from the group and track list. */
- removeTrackFromGroup(ideoTrack);
- slRemoveEl(pTrackList, ideoTrack);
-
- /* 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;
- }
-if(doIdeo)
- {
- char startBand[16];
- char endBand[16];
- char title[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);
- }
- else
- {
-#ifdef USE_PNG
- trashDirFile(ideoTn, "hgtIdeo", "hgtIdeo", ".png");
- hvg = hvGfxOpenPng(ideoWidth, ideoHeight, ideoTn->forCgi, FALSE);
-#else
- trashDirFile(ideoTn, "hgtIdeo", "hgtIdeo", ".gif");
- hvg = hvGfxOpenGif(ideoWidth, ideoHeight, ideoTn->forCgi, FALSE);
-#endif
- }
- hvg->rc = revCmplDisp;
- initColors(hvg);
- ideoTrack->ixColor = hvGfxFindRgb(hvg, &ideoTrack->color);
- ideoTrack->ixAltColor = hvGfxFindRgb(hvg, &ideoTrack->altColor);
- hvGfxSetClip(hvg, 0, gfxBorder, ideoWidth, ideoTrack->height);
- if(sameString(startBand, endBand))
- safef(title, sizeof(title), "%s (%s)", chromName, startBand);
- else
- safef(title, sizeof(title), "%s (%s-%s)", chromName, startBand, endBand);
- textWidth = mgFontStringWidth(font, title);
- hvGfxTextCentered(hvg, 2, gfxBorder, textWidth, ideoTrack->height, MG_BLACK, font, title);
- ideoTrack->drawItems(ideoTrack, winStart, winEnd, hvg, textWidth+4, gfxBorder, ideoWidth-textWidth-4,
- font, ideoTrack->ixColor, ideoTrack->limitedVis);
- hvGfxUnclip(hvg);
- /* Save out picture and tell html file about it. */
- hvGfxClose(&hvg);
- /* Finish map. */
- if (!psOutput)
- hPrintf(" \n");
- }
-hPrintf("
");
-if (doIdeo && !psOutput)
- {
- hPrintf(" ");
- hPrintf(" ",
- ideoTn->forHtml, ideoWidth, ideoHeight, mapName);
- hPrintf(" ");
- hPrintf("
\n");
- }
-else
- hPrintf(" \n");
-if(ideoTrack != NULL)
- {
- ideoTrack->limitedVisSet = TRUE;
- ideoTrack->limitedVis = tvHide; /* Don't draw in main gif. */
- }
-}
-
-char *pcrResultMapItemName(struct track *tg, void *item)
-/* Stitch accession and display name back together (if necessary). */
-{
-struct linkedFeatures *lf = item;
-return pcrResultItemAccName(lf->name, lf->extra);
-}
-
-void pcrResultLoad(struct track *tg)
-/* Load locations of primer matches into linkedFeatures items. */
-{
-char *pslFileName, *primerFileName;
-struct targetDb *target;
-if (! pcrResultParseCart(database, cart, &pslFileName, &primerFileName, &target))
- return;
-
-/* Don't free psl -- used in drawing phase by baseColor code. */
-struct psl *pslList = pslLoadAll(pslFileName), *psl;
-struct linkedFeatures *itemList = NULL;
-if (target != NULL)
- {
- int rowOffset = hOffsetPastBin(database, chromName, target->pslTable);
- struct sqlConnection *conn = hAllocConn(database);
- struct sqlResult *sr;
- char **row;
- char query[2048];
- struct psl *tpsl;
- for (tpsl = pslList; tpsl != NULL; tpsl = tpsl->next)
- {
- char *itemAcc = pcrResultItemAccession(tpsl->tName);
- char *itemName = pcrResultItemName(tpsl->tName);
- /* Query target->pslTable to get target-to-genomic mapping: */
- safef(query, sizeof(query), "select * from %s where qName = '%s'",
- target->pslTable, itemAcc);
- sr = sqlGetResult(conn, query);
- while ((row = sqlNextRow(sr)) != NULL)
- {
- struct psl *gpsl = pslLoad(row+rowOffset);
- if (sameString(gpsl->tName, chromName) && gpsl->tStart < winEnd && gpsl->tEnd > winStart)
- {
- struct psl *trimmed = pslTrimToQueryRange(gpsl, tpsl->tStart,
- tpsl->tEnd);
- struct linkedFeatures *lf;
- char *targetStyle = cartUsualString(cart,
- PCR_RESULT_TARGET_STYLE, PCR_RESULT_TARGET_STYLE_DEFAULT);
- if (sameString(targetStyle, PCR_RESULT_TARGET_STYLE_TALL))
- {
- lf = lfFromPslx(gpsl, 1, FALSE, FALSE, tg);
- lf->tallStart = trimmed->tStart;
- lf->tallEnd = trimmed->tEnd;
- }
- else
- {
- lf = lfFromPslx(trimmed, 1, FALSE, FALSE, tg);
- }
- lf->name = cloneString(itemAcc);
- char extraInfo[512];
- safef(extraInfo, sizeof(extraInfo), "%s|%d|%d",
- (itemName ? itemName : ""), tpsl->tStart, tpsl->tEnd);
- lf->extra = cloneString(extraInfo);
- slAddHead(&itemList, lf);
- }
- }
- }
- hFreeConn(&conn);
- }
-else
- for (psl = pslList; psl != NULL; psl = psl->next)
- if (sameString(psl->tName, chromName) && psl->tStart < winEnd && psl->tEnd > winStart)
- {
- struct linkedFeatures *lf =
- lfFromPslx(psl, 1, FALSE, FALSE, tg);
- lf->name = cloneString("");
- lf->extra = cloneString("");
- slAddHead(&itemList, lf);
- }
-slSort(&itemList, linkedFeaturesCmp);
-tg->items = itemList;
-}
-
-char *pcrResultTrackItemName(struct track *tg, void *item)
-/* If lf->extra is non-empty, return it (display name for item).
- * Otherwise default to item name. */
-{
-struct linkedFeatures *lf = item;
-char *extra = (char *)lf->extra;
-if (isNotEmpty(extra))
- {
- static char displayName[512];
- safecpy(displayName, sizeof(displayName), extra);
- char *ptr = strchr(displayName, '|');
- if (ptr != NULL)
- *ptr = '\0';
- if (isNotEmpty(displayName))
- return displayName;
- }
-return lf->name;
-}
-
-struct track *pcrResultTg()
-/* Make track of hgPcr results (alignments of user's submitted primers). */
-{
-struct trackDb *tdb = pcrResultFakeTdb();
-struct track *tg = trackFromTrackDb(tdb);
-tg->loadItems = pcrResultLoad;
-tg->itemName = pcrResultTrackItemName;
-tg->mapItemName = pcrResultMapItemName;
-tg->exonArrows = TRUE;
-tg->hasUi = TRUE;
-return tg;
-}
-
-struct track *linkedFeaturesTg()
-/* Return generic track for linked features. */
-{
-struct track *tg = trackNew();
-linkedFeaturesMethods(tg);
-tg->colorShades = shadesOfGray;
-return tg;
-}
-
-void setTgDarkLightColors(struct track *tg, int r, int g, int b)
-/* Set track color to r,g,b. Set altColor to a lighter version
- * of the same. */
-{
-tg->colorShades = NULL;
-tg->color.r = r;
-tg->color.g = g;
-tg->color.b = b;
-tg->altColor.r = (r+255)/2;
-tg->altColor.g = (g+255)/2;
-tg->altColor.b = (b+255)/2;
-}
-
-void parseSs(char *ss, char **retPsl, char **retFa)
-/* Parse out ss variable into components. */
-{
-static char buf[1024];
-char *words[2];
-int wordCount;
-
-safecpy(buf, sizeof(buf), ss);
-wordCount = chopLine(buf, words);
-if (wordCount < 2)
- errAbort("Badly formated ss variable");
-*retPsl = words[0];
-*retFa = words[1];
-}
-
-boolean ssFilesExist(char *ss)
-/* Return TRUE if both files in ss exist. */
-{
-char *faFileName, *pslFileName;
-parseSs(ss, &pslFileName, &faFileName);
-return fileExists(pslFileName) && fileExists(faFileName);
-}
-
-void loadUserPsl(struct track *tg)
-/* Load up hgBlat results from table into track items. */
-{
-char *ss = userSeqString;
-char buf2[3*512];
-char *faFileName, *pslFileName;
-struct lineFile *f;
-struct psl *psl;
-struct linkedFeatures *lfList = NULL, *lf;
-enum gfType qt, tt;
-int sizeMul = 1;
-
-parseSs(ss, &pslFileName, &faFileName);
-pslxFileOpen(pslFileName, &qt, &tt, &f);
-if (qt == gftProt)
- {
- setTgDarkLightColors(tg, 0, 80, 150);
- tg->colorShades = NULL;
- sizeMul = 3;
- }
-tg->itemName = linkedFeaturesName;
-while ((psl = pslNext(f)) != NULL)
- {
- if (sameString(psl->tName, chromName) && psl->tStart < winEnd && psl->tEnd > winStart)
- {
- lf = lfFromPslx(psl, sizeMul, TRUE, FALSE, tg);
- sprintf(buf2, "%s %s", ss, psl->qName);
- lf->extra = cloneString(buf2);
- slAddHead(&lfList, lf);
- /* Don't free psl -- used in drawing phase by baseColor code. */
- }
- else
- pslFree(&psl);
- }
-slSort(&lfList, linkedFeaturesCmpStart);
-lineFileClose(&f);
-tg->items = lfList;
-}
-
-static void addUserSeqBaseAndIndelSettings(struct trackDb *tdb)
-/* If user sequence is a dna or rna alignment, add settings to enable
- * base-level differences and indel display. */
-{
-enum gfType qt, tt;
-struct lineFile *lf;
-char *faFileName, *pslFileName;
-parseSs(userSeqString, &pslFileName, &faFileName);
-pslxFileOpen(pslFileName, &qt, &tt, &lf);
-lineFileClose(&lf);
-if (qt != gftProt)
- {
- if (tdb->settingsHash == NULL)
- tdb->settingsHash = hashNew(0);
- hashAdd(tdb->settingsHash, BASE_COLOR_DEFAULT, cloneString("diffBases"));
- hashAdd(tdb->settingsHash, BASE_COLOR_USE_SEQUENCE, cloneString("ss"));
- hashAdd(tdb->settingsHash, SHOW_DIFF_BASES_ALL_SCALES, cloneString("."));
- hashAdd(tdb->settingsHash, INDEL_DOUBLE_INSERT, cloneString("on"));
- hashAdd(tdb->settingsHash, INDEL_QUERY_INSERT, cloneString("on"));
- hashAdd(tdb->settingsHash, INDEL_POLY_A, cloneString("on"));
- }
-}
-
-struct track *userPslTg()
-/* Make track of user pasted sequence. */
-{
-struct track *tg = linkedFeaturesTg();
-struct trackDb *tdb;
-tg->track = "hgUserPsl";
-tg->table = tg->track;
-tg->canPack = TRUE;
-tg->visibility = tvPack;
-tg->longLabel = "Your Sequence from Blat Search";
-tg->shortLabel = "Blat Sequence";
-tg->loadItems = loadUserPsl;
-tg->mapItemName = lfMapNameFromExtra;
-tg->priority = 100;
-tg->defaultPriority = tg->priority;
-tg->groupName = "map";
-tg->defaultGroupName = cloneString(tg->groupName);
-tg->exonArrows = TRUE;
-
-/* better to create the tdb first, then use trackFromTrackDb */
-AllocVar(tdb);
-tdb->track = cloneString(tg->track);
-tdb->table = cloneString(tg->table);
-tdb->visibility = tg->visibility;
-tdb->shortLabel = cloneString(tg->shortLabel);
-tdb->longLabel = cloneString(tg->longLabel);
-tdb->grp = cloneString(tg->groupName);
-tdb->priority = tg->priority;
-tdb->type = cloneString("psl");
-trackDbPolish(tdb);
-addUserSeqBaseAndIndelSettings(tdb);
-tg->tdb = tdb;
-return tg;
-}
-
-char *oligoMatchSeq()
-/* Return sequence for oligo matching. */
-{
-char *s = cartOptionalString(cart, oligoMatchVar);
-if (s != NULL)
- {
- int len;
- tolowers(s);
- dnaFilter(s, s);
- len = strlen(s);
- if (len < 2)
- s = NULL;
- }
-if (s == NULL)
- s = cloneString(oligoMatchDefault);
-return s;
-}
-
-char *oligoMatchName(struct track *tg, void *item)
-/* Return name for oligo, which is just the base position. */
-{
-struct bed *bed = item;
-static char buf[22];
-buf[0] = bed->strand[0];
-sprintLongWithCommas(buf+1, bed->chromStart+1);
-return buf;
-}
-
-char *dnaInWindow()
-/* This returns the DNA in the window, all in lower case. */
-{
-static struct dnaSeq *seq = NULL;
-if (seq == NULL)
- seq = hDnaFromSeq(database, chromName, winStart, winEnd, dnaLower);
-return seq->dna;
-}
-
-
-void oligoMatchLoad(struct track *tg)
-/* Create track of perfect matches to oligo on either strand. */
-{
-char *dna = dnaInWindow();
-char *fOligo = oligoMatchSeq();
-int oligoSize = strlen(fOligo);
-char *rOligo = cloneString(fOligo);
-char *rMatch = NULL, *fMatch = NULL;
-struct bed *bedList = NULL, *bed;
-char strand;
-int count = 0, maxCount = 1000000;
-
-if (oligoSize >= 2)
- {
- fMatch = stringIn(fOligo, dna);
- reverseComplement(rOligo, oligoSize);
- if (sameString(rOligo, fOligo))
- rOligo = NULL;
- else
- rMatch = stringIn(rOligo, dna);
- for (;;)
- {
- char *oneMatch = NULL;
- if (rMatch == NULL)
- {
- if (fMatch == NULL)
- break;
- else
- {
- oneMatch = fMatch;
- fMatch = stringIn(fOligo, fMatch+1);
- strand = '+';
- }
- }
- else if (fMatch == NULL)
- {
- oneMatch = rMatch;
- rMatch = stringIn(rOligo, rMatch+1);
- strand = '-';
- }
- else if (rMatch < fMatch)
- {
- oneMatch = rMatch;
- rMatch = stringIn(rOligo, rMatch+1);
- strand = '-';
- }
- else
- {
- oneMatch = fMatch;
- fMatch = stringIn(fOligo, fMatch+1);
- strand = '+';
- }
- if (count < maxCount)
- {
- ++count;
- AllocVar(bed);
- bed->chromStart = winStart + (oneMatch - dna);
- bed->chromEnd = bed->chromStart + oligoSize;
- bed->strand[0] = strand;
- slAddHead(&bedList, bed);
- }
- else
- break;
- }
- slReverse(&bedList);
- if (count < maxCount)
- tg->items = bedList;
- else
- warn("More than %d items in %s, suppressing display", maxCount, tg->shortLabel);
- }
-}
-
-struct track *oligoMatchTg()
-/* Make track of perfect matches to oligomer. */
-{
-struct track *tg = trackNew();
-char *oligo = oligoMatchSeq();
-int oligoSize = strlen(oligo);
-char *medOligo = cloneString(oligo);
-static char longLabel[80];
-struct trackDb *tdb;
-
-/* Generate abbreviated strings. */
-if (oligoSize >= 30)
- {
- memset(medOligo + 30-3, '.', 3);
- medOligo[30] = 0;
- }
-touppers(medOligo);
-
-bedMethods(tg);
-tg->track = "oligoMatch";
-tg->table = tg->track;
-tg->canPack = TRUE;
-tg->visibility = tvHide;
-tg->hasUi = TRUE;
-tg->shortLabel = cloneString(OLIGO_MATCH_TRACK_LABEL);
-safef(longLabel, sizeof(longLabel),
- "Perfect Matches to Short Sequence (%s)", medOligo);
-tg->longLabel = longLabel;
-tg->loadItems = oligoMatchLoad;
-tg->itemName = oligoMatchName;
-tg->mapItemName = oligoMatchName;
-tg->priority = 99;
-tg->defaultPriority = tg->priority;
-tg->groupName = "map";
-tg->defaultGroupName = cloneString(tg->groupName);
-
-AllocVar(tdb);
-tdb->track = cloneString(tg->track);
-tdb->table = cloneString(tg->table);
-tdb->visibility = tg->visibility;
-tdb->shortLabel = cloneString(tg->shortLabel);
-tdb->longLabel = cloneString(tg->longLabel);
-tdb->grp = cloneString(tg->groupName);
-tdb->priority = tg->priority;
-trackDbPolish(tdb);
-tg->tdb = tdb;
-return tg;
-}
-
-static int doLeftLabels(struct track *track, struct hvGfx *hvg, MgFont *font,
- int y)
-/* Draw left labels. Return y coord. */
-{
-struct slList *prev = NULL;
-
-/* for sample tracks */
-double minRangeCutoff, maxRangeCutoff;
-double minRange, maxRange;
-double min0, max0;
-char minRangeStr[32];
-char maxRangeStr[32];
-
-int ymin, ymax;
-int start;
-int newy;
-char o4[256];
-char o5[256];
-struct slList *item;
-enum trackVisibility vis = track->limitedVis;
-enum trackVisibility savedVis = vis;
-Color labelColor = (track->labelColor ?
- track->labelColor : track->ixColor);
-int fontHeight = mgFontLineHeight(font);
-int tHeight = trackPlusLabelHeight(track, fontHeight);
-if (vis == tvHide)
- return y;
-
-/* if a track can do its own left labels, do them after drawItems */
-if (track->drawLeftLabels != NULL)
- return y + tHeight;
-
-/* Wiggle tracks depend upon clipping. They are reporting
- * totalHeight artifically high by 1 so this will leave a
- * blank area one pixel high below the track.
- */
-if (sameString("wig",track->tdb->type) || sameString("bedGraph",track->tdb->type))
- hvGfxSetClip(hvg, leftLabelX, y, leftLabelWidth, tHeight-1);
-else
- hvGfxSetClip(hvg, leftLabelX, y, leftLabelWidth, tHeight);
-
-minRange = 0.0;
-safef( o4, sizeof(o4),"%s.min.cutoff", track->track);
-safef( o5, sizeof(o5),"%s.max.cutoff", track->track);
-minRangeCutoff = max( atof(cartUsualString(cart,o4,"0.0"))-0.1,
- track->minRange );
-maxRangeCutoff = min( atof(cartUsualString(cart,o5,"1000.0"))+0.1,
- track->maxRange);
-if( sameString( track->table, "humMusL" ) ||
- sameString( track->table, "musHumL" ) ||
- sameString( track->table, "mm3Rn2L" ) ||
- sameString( track->table, "hg15Mm3L" ) ||
- sameString( track->table, "mm3Hg15L" ) ||
- sameString( track->table, "regpotent" ) ||
- sameString( track->table, "HMRConservation" ) )
- {
- int binCount = round(1.0/track->scaleRange);
- minRange = whichSampleBin( minRangeCutoff, track->minRange, track->maxRange, binCount );
- maxRange = whichSampleBin( maxRangeCutoff, track->minRange, track->maxRange ,binCount );
- min0 = whichSampleNum( minRange, track->minRange,track->maxRange, binCount );
- max0 = whichSampleNum( maxRange, track->minRange, track->maxRange, binCount );
- sprintf( minRangeStr, " " );
- sprintf( maxRangeStr, " " );
- if( vis == tvFull && track->heightPer >= 74 )
- {
- samplePrintYAxisLabel( hvg, y+5, track, "1.0", min0, max0 );
- samplePrintYAxisLabel( hvg, y+5, track, "2.0", min0, max0 );
- samplePrintYAxisLabel( hvg, y+5, track, "3.0", min0, max0 );
- samplePrintYAxisLabel( hvg, y+5, track, "4.0", min0, max0 );
- samplePrintYAxisLabel( hvg, y+5, track, "5.0", min0, max0 );
- samplePrintYAxisLabel( hvg, y+5, track, "6.0", min0, max0 );
- }
- }
-else
- {
- sprintf( minRangeStr, "%d", (int)round(minRangeCutoff));
- sprintf( maxRangeStr, "%d", (int)round(maxRangeCutoff));
- }
-/* special label handling for wigMaf type tracks -- they
- display a left label in pack mode. To use the full mode
- labeling, temporarily set visibility to full.
- Restore savedVis later */
-if (startsWith("wigMaf", track->tdb->type) || startsWith("maf", track->tdb->type))
- vis = tvFull;
-
-switch (vis)
- {
- case tvHide:
- break; /* Do nothing; */
- case tvPack:
- case tvSquish:
- y += tHeight;
- break;
- case tvFull:
- if (isCenterLabelIncluded(track))
- y += fontHeight;
- start = 1;
-
- if( track->subType == lfSubSample && track->items == NULL )
- y += track->height;
-
- for (item = track->items; item != NULL; item = item->next)
- {
- char *rootName;
- char *name = track->itemName(track, item);
- int itemHeight = track->itemHeight(track, item);
- newy = y;
-
- if (track->itemLabelColor != NULL)
- labelColor = track->itemLabelColor(track, item, hvg);
-
- /* Do some fancy stuff for sample tracks.
- * Draw y-value limits for 'sample' tracks. */
- if (track->subType == lfSubSample )
- {
- if( prev == NULL )
- newy += itemHeight;
- else
- newy += sampleUpdateY(name,
- track->itemName(track, prev), itemHeight);
- if( newy == y )
- continue;
-
- if( track->heightPer > (3 * fontHeight ) )
- {
- ymax = y - (track->heightPer / 2) + (fontHeight / 2);
- ymin = y + (track->heightPer / 2) - (fontHeight / 2);
- hvGfxTextRight(hvg, leftLabelX, ymin, leftLabelWidth-1,
- itemHeight, track->ixAltColor,
- font, minRangeStr );
- hvGfxTextRight(hvg, leftLabelX, ymax, leftLabelWidth-1,
- itemHeight, track->ixAltColor,
- font, maxRangeStr );
- }
- prev = item;
-
- rootName = cloneString( name );
- beforeFirstPeriod( rootName );
- if( sameString( track->table, "humMusL" ) ||
- sameString( track->table, "hg15Mm3L" ))
- hvGfxTextRight(hvg, leftLabelX, y, leftLabelWidth - 1,
- itemHeight, track->ixColor, font, "Mouse Cons");
- else if( sameString( track->table, "musHumL" ) ||
- sameString( track->table, "mm3Hg15L"))
- hvGfxTextRight(hvg, leftLabelX, y, leftLabelWidth - 1,
- itemHeight, track->ixColor, font, "Human Cons");
- else if( sameString( track->table, "mm3Rn2L" ))
- hvGfxTextRight(hvg, leftLabelX, y, leftLabelWidth - 1,
- itemHeight, track->ixColor, font, "Rat Cons");
- else
- hvGfxTextRight(hvg, leftLabelX, y, leftLabelWidth - 1,
- itemHeight, track->ixColor, font, rootName );
- freeMem( rootName );
- start = 0;
- y = newy;
- }
- else
- {
- /* standard item labeling */
- if (highlightItem(track, item))
- {
- int nameWidth = mgFontStringWidth(font, name);
- int boxStart = leftLabelX + leftLabelWidth - 2 - nameWidth;
- hvGfxBox(hvg, boxStart, y, nameWidth+1, itemHeight - 1,
- labelColor);
- hvGfxTextRight(hvg, leftLabelX, y, leftLabelWidth-1,
- itemHeight, MG_WHITE, font, name);
- }
- else
- hvGfxTextRight(hvg, leftLabelX, y, leftLabelWidth - 1,
- itemHeight, labelColor, font, name);
- y += itemHeight;
- }
- }
- break;
- case tvDense:
-
- if (isCenterLabelIncluded(track))
- y += fontHeight;
-
- /*draw y-value limits for 'sample' tracks.
- * (always puts 0-100% range)*/
- if( track->subType == lfSubSample &&
- track->heightPer > (3 * fontHeight ) )
- {
- ymax = y - (track->heightPer / 2) + (fontHeight / 2);
- ymin = y + (track->heightPer / 2) - (fontHeight / 2);
- hvGfxTextRight(hvg, leftLabelX, ymin,
- leftLabelWidth-1, track->lineHeight,
- track->ixAltColor, font, minRangeStr );
- hvGfxTextRight(hvg, leftLabelX, ymax,
- leftLabelWidth-1, track->lineHeight,
- track->ixAltColor, font, maxRangeStr );
- }
- hvGfxTextRight(hvg, leftLabelX, y, leftLabelWidth-1,
- track->lineHeight, labelColor, font,
- track->shortLabel);
- y += track->height;
- break;
- }
-/* NOTE: might want to just restore savedVis here for all track types,
- but I'm being cautious... */
-if (sameString(track->tdb->type, "wigMaf"))
- vis = savedVis;
-hvGfxUnclip(hvg);
-return y;
-}
-
-static void doLabelNextItemButtons(struct track *track, struct track *parentTrack, struct hvGfx *hvg, MgFont *font, int y,
- int trackPastTabX, int trackPastTabWidth, int fontHeight,
- int insideHeight, Color labelColor)
-/* If the track allows label next-item buttons (next gene), draw them. */
-/* The button will cause hgTracks to run again with the additional CGI */
-/* vars nextItem=trackName or prevItem=trackName, which will then */
-/* signal the browser to find the next thing on the track before it */
-/* does anything else. */
-{
-int portWidth = insideWidth;
-int portX = insideX;
-#ifdef IMAGEv2_DRAG_SCROLL
-// If a portal was established, then set the portal dimensions
-int portalStart,chromStart;
-double basesPerPixel;
-if (imgBoxPortalDimensions(theImgBox,&chromStart,NULL,NULL,NULL,&portalStart,NULL,&portWidth,&basesPerPixel))
- {
- portX = (int)((portalStart - chromStart) / basesPerPixel);
- portX += gfxBorder;
- if (withLeftLabels)
- portX += tl.leftLabelWidth + gfxBorder;
- portWidth = portWidth-gfxBorder-insideX;
- }
-#endif//def IMAGEv2_DRAG_SCROLL
-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);
-mapBoxReinvoke(hvg, portX, y + 1, arrowButtonWidth, insideHeight, NULL,
- NULL, 0, 0, (revCmplDisp ? "Next item" : "Prev item"), buttonText);
-mapBoxToggleVis(hvg, portX + arrowButtonWidth, y + 1, portWidth - (2 * arrowButtonWidth),
- insideHeight, (theImgBox ? track : parentTrack));
-safef(buttonText, ArraySize(buttonText), "hgt.nextItem=%s", track->track);
-mapBoxReinvoke(hvg, portX + portWidth - arrowButtonWidth, y + 1, arrowButtonWidth, insideHeight, NULL,
- NULL, 0, 0, (revCmplDisp ? "Prev item" : "Next item"), buttonText);
-}
-
-static int doCenterLabels(struct track *track, struct track *parentTrack,
- struct hvGfx *hvg, MgFont *font, int y)
-/* Draw center labels. Return y coord */
-{
-if (track->limitedVis != tvHide)
- {
- if (isCenterLabelIncluded(track))
- {
- int trackPastTabX = (withLeftLabels ? trackTabWidth : 0);
- int trackPastTabWidth = tl.picWidth - trackPastTabX;
- int fontHeight = mgFontLineHeight(font);
- int insideHeight = fontHeight-1;
- boolean toggleDone = FALSE;
- char *label = track->longLabel;
- if (isCenterLabelConditional(track))
- label = track->tdb->parent->longLabel;
- Color labelColor = (track->labelColor ?
- track->labelColor : track->ixColor);
- hvGfxTextCentered(hvg, insideX, y+1, insideWidth, insideHeight,
- labelColor, font, label);
- if (track->nextItemButtonable && track->nextPrevItem && !tdbIsComposite(track->tdb))
- {
- if (withNextItemArrows || trackDbSettingOn(track->tdb, "nextItemButton"))
- {
- doLabelNextItemButtons(track, parentTrack, hvg, font, y, trackPastTabX,
- trackPastTabWidth, fontHeight, insideHeight, labelColor);
- toggleDone = TRUE;
- }
- }
- if (!toggleDone)
- mapBoxToggleVis(hvg, trackPastTabX, y+1,trackPastTabWidth, insideHeight,
- (theImgBox ? track : parentTrack));
- y += fontHeight;
- }
- y += track->totalHeight(track, track->limitedVis);
- }
-return y;
-}
-
-static int doDrawItems(struct track *track, struct hvGfx *hvg, MgFont *font,
- int y, long *lastTime)
-/* Draw track items. Return y coord */
-{
-int fontHeight = mgFontLineHeight(font);
-int pixWidth = tl.picWidth;
-if (isCenterLabelIncluded(track))
- y += fontHeight;
-if (track->limitedVis == tvPack)
- {
- hvGfxSetClip(hvg, gfxBorder+trackTabWidth+1, y,
- pixWidth-2*gfxBorder-trackTabWidth-1, track->height);
- }
-else
- hvGfxSetClip(hvg, insideX, y, insideWidth, track->height);
-track->drawItems(track, winStart, winEnd, hvg, insideX, y, insideWidth,
- font, track->ixColor, track->limitedVis);
-if (measureTiming && lastTime)
- {
- long thisTime = clock1000();
- track->drawTime = thisTime - *lastTime;
- *lastTime = thisTime;
- }
-hvGfxUnclip(hvg);
-y += track->totalHeight(track, track->limitedVis);
-return y;
-}
-
-static int doMapItems(struct track *track, struct hvGfx *hvg, int fontHeight, int y)
-/* Draw map boxes around track items */
-{
-char *type = track->tdb->type;
-int newy;
-int trackPastTabX = (withLeftLabels ? trackTabWidth : 0);
-int trackPastTabWidth = tl.picWidth - trackPastTabX;
-int start = 1;
-struct slList *item;
-boolean isWig = (sameString("wig", type) || startsWith("wig ", type) ||
- startsWith("bedGraph", type));
-
-if (isCenterLabelIncluded(track))
- y += fontHeight;
-if (track->mapsSelf)
- {
- return y+track->height;
- }
-if (track->subType == lfSubSample && track->items == NULL)
- y += track->lineHeight;
-
-/* override doMapItems for hapmapLd track */
-/* does not scale with subtracks right now, so this is commented out until it can be fixed
-if (startsWith("hapmapLd",track->table))
- {
- y += round((double)(scaleForPixels(insideWidth)*insideWidth/2));
- return y;
- }
-*/
-for (item = track->items; item != NULL; item = item->next)
- {
- int height = track->itemHeight(track, item);
-
- /*wiggle tracks don't always increment height (y-value) here*/
- if( track->subType == lfSubSample )
- {
- newy = y;
- if( !start && item->next != NULL )
- {
- newy += sampleUpdateY( track->itemName(track, item),
- track->itemName(track, item->next),
- height );
- }
- else if( item->next != NULL || start )
- newy += height;
- start = 0;
- y = newy;
- }
- else
- {
- if (track->mapItem == NULL)
- track->mapItem = genericMapItem;
- if (!track->mapsSelf)
- {
- track->mapItem(track, hvg, item, track->itemName(track, item),
- track->mapItemName(track, item),
- track->itemStart(track, item),
- track->itemEnd(track, item), trackPastTabX,
- y, trackPastTabWidth,height);
- }
- y += height;
- }
- }
-/* Wiggle track's ->height is actually one less than what it returns from
- * totalHeight()... I think the least disruptive way to account for this
- * (and not touch Ryan Weber's Sample stuff) is to just correct here if
- * we see wiggle or bedGraph: */
-if (isWig)
- y++;
-return y;
-}
-
-static int doOwnLeftLabels(struct track *track, struct hvGfx *hvg,
- MgFont *font, int y)
-/* Track draws it own, custom left labels */
-{
-int fontHeight = mgFontLineHeight(font);
-int tHeight = trackPlusLabelHeight(track, fontHeight);
-Color labelColor = (track->labelColor ? track->labelColor : track->ixColor);
-hvGfxSetClip(hvg, leftLabelX, y, leftLabelWidth, tHeight);
-track->drawLeftLabels(track, winStart, winEnd,
- hvg, leftLabelX, y, leftLabelWidth, tHeight,
- isCenterLabelIncluded(track), font, labelColor,
- track->limitedVis);
-hvGfxUnclip(hvg);
-y += tHeight;
-return y;
-}
-
-// defined below:
-static int getMaxWindowToDraw(struct trackDb *tdb);
-
-int doTrackMap(struct track *track, struct hvGfx *hvg, int y, int fontHeight,
- int trackPastTabX, int trackPastTabWidth)
-/* Write out the map for this track. Return the new offset. */
-{
-int mapHeight = 0;
-switch (track->limitedVis)
- {
- case tvPack:
- case tvSquish:
- y += trackPlusLabelHeight(track, fontHeight);
- break;
- case tvFull:
- if (!nextItemCompatible(track))
- {
- if (trackIsCompositeWithSubtracks(track)) //TODO: Change when tracks->subtracks are always set for composite
- {
- if (isCenterLabelIncluded(track))
- y += fontHeight;
- struct track *subtrack;
- for (subtrack = track->subtracks; subtrack != NULL;subtrack = subtrack->next)
- {
- if (isSubtrackVisible(subtrack))
- {
- if(subtrack->limitedVis == tvFull)
- y = doMapItems(subtrack, hvg, fontHeight, y);
- else
- {
- if (isCenterLabelIncluded(subtrack))
- y += fontHeight;
- if(theImgBox && subtrack->limitedVis == tvDense)
- mapBoxToggleVis(hvg, trackPastTabX, y, trackPastTabWidth, track->lineHeight, subtrack);
- y += subtrack->totalHeight(subtrack, subtrack->limitedVis);
- }
- }
- }
- }
- else
- y = doMapItems(track, hvg, fontHeight, y);
- }
- else
- y += trackPlusLabelHeight(track, fontHeight);
- break;
- case tvDense:
- if (isCenterLabelIncluded(track))
- y += fontHeight;
- if (tdbIsComposite(track->tdb))
- mapHeight = track->height;
- else
- mapHeight = track->lineHeight;
- int maxWinToDraw = getMaxWindowToDraw(track->tdb);
- if (maxWinToDraw <= 1 || (winEnd - winStart) <= maxWinToDraw)
- mapBoxToggleVis(hvg, trackPastTabX, y, trackPastTabWidth, mapHeight, track);
- y += mapHeight;
- break;
- case tvHide:
- default:
- break; /* Do nothing; */
- }
-return y;
-}
-
-int computeScaleBar(int numBases, char scaleText[], int scaleTextSize)
-/* Do some scalebar calculations and return the number of bases the scalebar will span. */
-{
-char *baseWord = "bases";
-int scaleBases = 0;
-int scaleBasesTextNum = 0;
-int numFigs = (int)log10(numBases);
-int frontNum = (int)(numBases/pow(10,numFigs));
-if (frontNum == 1)
- {
- numFigs--;
- scaleBases = 5 * pow(10, numFigs);
- scaleBasesTextNum = 5 * pow(10, numFigs % 3);
- }
-else if ((frontNum > 1) && (frontNum <= 4))
- {
- scaleBases = pow(10, numFigs);
- scaleBasesTextNum = pow(10, numFigs % 3);
- }
-else if (frontNum > 4)
- {
- scaleBases = 2 * pow(10, numFigs);
- scaleBasesTextNum = 2 * pow(10, numFigs % 3);
- }
-if ((numFigs >= 3) && (numFigs < 6))
- baseWord = "kb";
-else if ((numFigs >= 6) && (numFigs < 9))
- baseWord = "Mb";
-safef(scaleText, scaleTextSize, "%d %s", scaleBasesTextNum, baseWord);
-return scaleBases;
-}
-
-enum trackVisibility limitedVisFromComposite(struct track *subtrack)
-/* returns the subtrack visibility which may be limited by composite with multi-view dropdowns. */
-{
-#ifdef SUBTRACKS_HAVE_VIS
-if (tdbIsCompositeChild(subtrack->tdb))
- {
- if (fourStateVisible(subtrackFourStateChecked(subtrack->tdb,cart))) // Don't need all 4 states here. Visible=checked&&enabled
- {
- char *var = cartOptionalString(cart, subtrack->track);
- if (var)
- {
- subtrack->visibility = hTvFromString(var);
-
- if (subtrack->limitedVisSet)
- subtrack->limitedVis = tvMin(subtrack->visibility,subtrack->limitedVis);
- else
- {
- if (subtrack->visibility != tvHide && slCount(subtrack->items) == 0)
- subtrack->loadItems(subtrack);
-
- limitVisibility(subtrack);
- }
- return hTvFromString(var);
- }
- }
- else
- return tvHide;
- }
-#endif///def SUBTRACKS_HAVE_VIS
-
-enum trackVisibility vis = subtrack->limitedVis == tvHide ?
- subtrack->visibility :
- tvMin(subtrack->visibility,subtrack->limitedVis);
-struct trackDb *tdb = subtrack->tdb;
-if(tdbIsCompositeChild(tdb))
- {
- struct trackDb *parentTdb = tdbGetComposite(tdb);
- assert(parentTdb != NULL);
-
- char *viewName = NULL;
- if (subgroupFind(tdb,"view",&viewName))
- {
- int len = strlen(parentTdb->track) + strlen(viewName) + 10;
-
- // Create the view dropdown var name. This needs to have the view name surrounded by dots
- // in the middle for the javascript to work.
- char ddName[len];
- safef(ddName,len,"%s.%s.vis", parentTdb->track,viewName);
- char * fromParent = cartOptionalString(cart, ddName);
- if(fromParent)
- vis = tvMin(vis,hTvFromString(fromParent));
- else
- vis = tvMin(vis,visCompositeViewDefault(parentTdb,viewName));
- subgroupFree(&viewName);
- }
- }
-return vis;
-}
-
-static int makeRulerZoomBoxes(struct hvGfx *hvg, struct cart *cart, int winStart,int winEnd,
- int insideWidth,int seqBaseCount,int rulerClickY,int rulerClickHeight)
-/* Make hit boxes that will zoom program around ruler. */
-{
-int boxes = 30;
-int winWidth = winEnd - winStart;
-int newWinWidth = winWidth;
-int i, ws, we = 0, ps, pe = 0;
-int mid, ns, ne;
-double wScale = (double)winWidth/boxes;
-double pScale = (double)insideWidth/boxes;
-char message[32];
-char *zoomType = cartCgiUsualString(cart, RULER_BASE_ZOOM_VAR, ZOOM_3X);
-
-safef(message, sizeof(message), "%s zoom", zoomType);
-if (sameString(zoomType, ZOOM_1PT5X))
- newWinWidth = winWidth/1.5;
-else if (sameString(zoomType, ZOOM_3X))
- newWinWidth = winWidth/3;
-else if (sameString(zoomType, ZOOM_10X))
- newWinWidth = winWidth/10;
-else if (sameString(zoomType, ZOOM_BASE))
- newWinWidth = insideWidth/tl.mWidth;
-else
- errAbort("invalid zoom type %s", zoomType);
-
-if (newWinWidth < 1)
- newWinWidth = 1;
-
-for (i=1; i<=boxes; ++i)
- {
- ps = pe;
- ws = we;
- pe = round(pScale*i);
- we = round(wScale*i);
- mid = (ws + we)/2 + winStart;
- ns = mid-newWinWidth/2;
- ne = ns + newWinWidth;
- if (ns < 0)
- {
- ns = 0;
- ne -= ns;
- }
- if (ne > seqBaseCount)
- {
- ns -= (ne - seqBaseCount);
- ne = seqBaseCount;
- }
- if(!dragZooming)
- {
- mapBoxJumpTo(hvg, ps+insideX,rulerClickY,pe-ps,rulerClickHeight,
- chromName, ns, ne, message);
- }
- }
-return newWinWidth;
-}
-
-static int doDrawRuler(struct hvGfx *hvg,int *newWinWidth,int *rulerClickHeight,
- int rulerHeight, int yAfterRuler, int yAfterBases, MgFont *font,
- int fontHeight,boolean rulerCds)
-/* draws the ruler. */
-{
-int scaleBarPad = 2;
-int scaleBarHeight = fontHeight;
-int scaleBarTotalHeight = fontHeight + 2 * scaleBarPad;
-int titleHeight = fontHeight;
-int baseHeight = fontHeight;
-//int yAfterBases = yAfterRuler;
-int showPosHeight = fontHeight;
-int codonHeight = fontHeight;
-struct dnaSeq *seq = NULL;
-int rulerClickY = 0;
-*rulerClickHeight = rulerHeight;
-
-int y = rulerClickY;
-hvGfxSetClip(hvg, insideX, y, insideWidth, yAfterRuler-y+1);
-int relNumOff = winStart;
-
-if (baseTitle)
- {
- hvGfxTextCentered(hvg, insideX, y, insideWidth, titleHeight,MG_BLACK, font, baseTitle);
- *rulerClickHeight += titleHeight;
- y += titleHeight;
- }
-if (baseShowPos||baseShowAsm)
- {
- char txt[256];
- char numBuf[SMALLBUF];
- char *freezeName = NULL;
- freezeName = hFreezeFromDb(database);
- sprintLongWithCommas(numBuf, winEnd-winStart);
- if(freezeName == NULL)
- freezeName = "Unknown";
- if (baseShowPos&&baseShowAsm)
- safef(txt,sizeof(txt),"%s %s %s (%s bp)",organism,
- freezeName, addCommasToPos(database, position), numBuf);
- else if (baseShowPos)
- safef(txt,sizeof(txt),"%s (%s bp)",addCommasToPos(database, position),numBuf);
- else
- safef(txt,sizeof(txt),"%s %s",organism,freezeName);
- hvGfxTextCentered(hvg, insideX, y, insideWidth, showPosHeight,MG_BLACK, font, txt);
- *rulerClickHeight += showPosHeight;
- freez(&freezeName);
- y += showPosHeight;
- }
-if (baseShowScaleBar)
- {
- char scaleText[32];
- int numBases = winEnd-winStart;
- int scaleBases = computeScaleBar(numBases, scaleText, sizeof(scaleText));
- int scalePixels = (int)((double)insideWidth*scaleBases/numBases);
- int scaleBarX = insideX + (int)(((double)insideWidth-scalePixels)/2);
- int scaleBarEndX = scaleBarX + scalePixels;
- int scaleBarY = y + 0.5 * scaleBarTotalHeight;
- *rulerClickHeight += scaleBarTotalHeight;
- hvGfxTextRight(hvg, insideX, y + scaleBarPad,
- (scaleBarX-2)-insideX, scaleBarHeight, MG_BLACK, font, scaleText);
- hvGfxLine(hvg, scaleBarX, scaleBarY, scaleBarEndX, scaleBarY, MG_BLACK);
- hvGfxLine(hvg, scaleBarX, y+scaleBarPad, scaleBarX,
- y+scaleBarTotalHeight-scaleBarPad, MG_BLACK);
- hvGfxLine(hvg, scaleBarEndX, y+scaleBarPad, scaleBarEndX,
- y+scaleBarTotalHeight-scaleBarPad, MG_BLACK);
- y += scaleBarTotalHeight;
- }
-if (baseShowRuler)
- {
- hvGfxDrawRulerBumpText(hvg, insideX, y, rulerHeight, insideWidth, MG_BLACK,
- font, relNumOff, winBaseCount, 0, 1);
- }
-*newWinWidth = makeRulerZoomBoxes(hvg, cart,winStart,winEnd,insideWidth,seqBaseCount,rulerClickY,*rulerClickHeight);
-
-if (zoomedToBaseLevel || rulerCds)
- {
- Color baseColor = MG_BLACK;
- int start, end, chromSize;
- struct dnaSeq *extraSeq;
- /* extraSeq has extra leading & trailing bases
- * for translation in to amino acids */
- boolean complementRulerBases =
- cartUsualBooleanDb(cart, database, COMPLEMENT_BASES_VAR, FALSE);
- // gray bases if not matching the direction of display
- if (complementRulerBases != revCmplDisp)
- baseColor = MG_GRAY;
-
- /* get sequence, with leading & trailing 3 bases
- * used for amino acid translation */
- start = max(winStart - 3, 0);
- chromSize = hChromSize(database, chromName);
- end = min(winEnd + 3, chromSize);
- extraSeq = hDnaFromSeq(database, chromName, start, end, dnaUpper);
- if (start != winStart - 3 || end != winEnd + 3)
- {
- /* at chromosome boundaries, pad with N's to assure
- * leading & trailing 3 bases */
- char header[4] = "NNN", trailer[4] = "NNN";
- int size = winEnd - winStart + 6;
- char *padded = (char *)needMem(size+1);
- header[max(3 - winStart, 0)] = 0;
- trailer[max(winEnd - chromSize + 3, 0)] = 0;
- safef(padded, size+1, "%s%s%s", header, extraSeq->dna, trailer);
- extraSeq = newDnaSeq(padded, strlen(padded), extraSeq->name);
- }
-
- /* for drawing bases, must clip off leading and trailing 3 bases */
- seq = cloneDnaSeq(extraSeq);
- seq = newDnaSeq(seq->dna+3, seq->size-6, seq->name);
-
- if (zoomedToBaseLevel)
- drawBases(hvg, insideX, y+rulerHeight, insideWidth, baseHeight,
- baseColor, font, complementRulerBases, seq);
-
- /* set up clickable area to toggle ruler visibility */
- {
- char newRulerVis[100];
- safef(newRulerVis, 100, "%s=%s", RULER_TRACK_NAME,
- rulerMode == tvFull ?
- rulerMenu[tvDense] :
- rulerMenu[tvFull]);
- mapBoxReinvoke(hvg, insideX, y+rulerHeight, insideWidth,baseHeight,
- NULL, NULL, 0, 0, "", newRulerVis);
- }
- if (rulerCds)
- {
- /* display codons */
- int frame;
- int firstFrame = 0;
- int mod; // for determining frame ordering on display
- struct simpleFeature *sfList;
- double scale = scaleForWindow(insideWidth, winStart, winEnd);
-
- /* WARNING: tricky code to assure that an amino acid
- * stays in the same frame line on the browser during panning.
- * There may be a simpler way... */
- if (complementRulerBases)
- mod = (chromSize - winEnd) % 3;
- else
- mod = winStart % 3;
- if (mod == 0)
- firstFrame = 0;
- else if (mod == 1)
- firstFrame = 2;
- else if (mod == 2)
- firstFrame = 1;
-
- y = yAfterBases;
- if (complementRulerBases)
- reverseComplement(extraSeq->dna, extraSeq->size);
- for (frame = 0; frame < 3; frame++, y += codonHeight)
- {
- /* reference frame to start of chromosome */
- int refFrame = (firstFrame + frame) % 3;
-
- /* create list of codons in the specified coding frame */
- sfList = baseColorCodonsFromDna(refFrame, winStart, winEnd,
- extraSeq, complementRulerBases);
- /* draw the codons in the list, with alternating colors */
- baseColorDrawRulerCodons(hvg, sfList, scale, insideX, y,
- codonHeight, font, winStart, MAXPIXELS,
- zoomedToCodonLevel);
- }
- }
- }
-hvGfxUnclip(hvg);
-return y;
-}
-
-static void rAddToTrackHash(struct hash *trackHash, struct track *trackList)
-/* Add list and any children of list to hash. */
-{
-struct track *track;
-for (track = trackList; track != NULL; track = track->next)
- {
- hashAddUnique(trackHash, track->track, track);
- rAddToTrackHash(trackHash, track->subtracks);
- }
-}
-
-static void makeGlobalTrackHash(struct track *trackList)
-/* Start a global track hash. */
-{
-trackHash = newHash(8);
-rAddToTrackHash(trackHash, trackList);
-}
-
-
-void makeActiveImage(struct track *trackList, char *psOutput)
-/* Make image and image map. */
-{
-struct track *track;
-MgFont *font = tl.font;
-struct hvGfx *hvg;
-struct tempName gifTn;
-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;
-int showPosHeight = fontHeight;
-int rulerHeight = fontHeight;
-int baseHeight = fontHeight;
-int basePositionHeight = rulerHeight;
-int codonHeight = fontHeight;
-int rulerTranslationHeight = codonHeight * 3; // 3 frames
-int yAfterRuler = gfxBorder;
-int yAfterBases = yAfterRuler; // differs if base-level translation shown
-boolean rulerCds = zoomedToCdsColorLevel;
-int rulerClickHeight = 0;
-int newWinWidth = 0;
-
-/* Figure out dimensions and allocate drawing space. */
-pixWidth = tl.picWidth;
-
-leftLabelX = gfxBorder;
-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 hvGfx *hvgSide = NULL; // Strategy an extra pointer to a side image that can be built if needed
-//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;
-if(theImgBox)
-// theImgBox is a global for now to avoid huge rewrite of hgTracks. It is started
-// prior to this in doTrackForm()
- {
- rulerTtl = (dragZooming?"drag select or click to zoom":"click to zoom 3x");
- hPrintf(" \n", database);
- hPrintf(" \n", chromName);
- hPrintf(" \n", winStart);
- hPrintf(" \n", winEnd);
- hPrintf(" \n", tl.picWidth);
- #ifdef IMAGEv2_DRAG_SCROLL
- // If a portal was established, then set the global dimensions to the entire image size
- if(imgBoxPortalDimensions(theImgBox,&winStart,&winEnd,&(tl.picWidth),NULL,NULL,NULL,NULL,NULL))
- {
- pixWidth = tl.picWidth;
- winBaseCount = winEnd - winStart;
- insideWidth = tl.picWidth-gfxBorder-insideX;
- }
- #endif//def IMAGEv2_DRAG_SCROLL
- memset((char *)sliceWidth, 0,sizeof(sliceWidth));
- memset((char *)sliceOffsetX,0,sizeof(sliceOffsetX));
- if (withLeftLabels)
- {
- sliceWidth[stButton] = trackTabWidth + 1;
- sliceWidth[stSide] = leftLabelWidth - sliceWidth[stButton] + 2;
- sliceOffsetX[stSide] = (revCmplDisp? (tl.picWidth - sliceWidth[stSide] - sliceWidth[stButton]) : sliceWidth[stButton]);
- sliceOffsetX[stButton] = (revCmplDisp? (tl.picWidth - sliceWidth[stButton]) : 0);
- }
- sliceOffsetX[stData] = (revCmplDisp?0:sliceWidth[stSide] + sliceWidth[stButton]);
- sliceWidth[stData] = tl.picWidth - (sliceWidth[stSide] + sliceWidth[stButton]);
- }
-struct flatTracks *flatTracks = NULL;
-struct flatTracks *flatTrack = NULL;
-
-if (rulerMode != tvFull)
- {
- rulerCds = FALSE;
- }
-
-/* Figure out height of each visible track. */
-pixHeight = gfxBorder;
-if (rulerMode != tvHide)
- {
- if (!baseShowRuler && !baseTitle && !baseShowPos && !baseShowAsm && !baseShowScaleBar && !zoomedToBaseLevel && !rulerCds)
- {
- warn("Can't turn everything off in base position track. Turning ruler back on");
- baseShowRuler = TRUE;
- cartSetBoolean(cart, BASE_SHOWRULER, TRUE);
- }
-
- if (baseTitle)
- basePositionHeight += titleHeight;
-
- if (baseShowPos||baseShowAsm)
- basePositionHeight += showPosHeight;
-
- if (baseShowScaleBar)
- basePositionHeight += scaleBarTotalHeight;
-
- if (!baseShowRuler)
- {
- basePositionHeight -= rulerHeight;
- rulerHeight = 0;
- }
-
- if (zoomedToBaseLevel)
- basePositionHeight += baseHeight;
-
- yAfterRuler += basePositionHeight;
- yAfterBases = yAfterRuler;
- pixHeight += basePositionHeight;
- if (rulerCds)
- {
- yAfterRuler += rulerTranslationHeight;
- pixHeight += rulerTranslationHeight;
- }
- }
-
-boolean safeHeight = TRUE;
-/* firefox on Linux worked almost up to 34,000 at the default 620 width */
-#define maxSafeHeight 32000
-/* Hash tracks/subtracks, limit visibility and calculate total image height: */
-for (track = trackList; track != NULL; track = track->next)
- {
- limitVisibility(track);
- if (!safeHeight)
- {
- track->limitedVis = tvHide;
- track->limitedVisSet = TRUE;
- continue;
- }
-#ifndef SUBTRACKS_HAVE_VIS
- if (track->limitedVis != tvHide)
-#endif///ndef SUBTRACKS_HAVE_VIS
- {
- if (tdbIsComposite(track->tdb))
- {
- struct track *subtrack;
- for (subtrack = track->subtracks; subtrack != NULL;
- subtrack = subtrack->next)
- {
- if (!isSubtrackVisible(subtrack))
- continue;
-
- // If the composite track has "view" based drop downs, set visibility based upon those
- enum trackVisibility vis = limitedVisFromComposite(subtrack);
- if(subtrack->visibility != vis)
- {
- subtrack->visibility = vis;
- if (subtrack->limitedVisSet)
- {
- subtrack->limitedVis = tvMin(vis, subtrack->limitedVis);
- }
- else
- {
- subtrack->limitedVis = tvMin(vis,subtrack->visibility);
- subtrack->limitedVisSet = (subtrack->limitedVis != tvHide && subtrack->visibility != subtrack->limitedVis);
- }
- }
- if (!subtrack->limitedVisSet && track->limitedVisSet)
- {
- subtrack->visibility = track->visibility;
- subtrack->limitedVis = track->limitedVis;
- subtrack->limitedVisSet = track->limitedVisSet;
- }
-
- #ifdef SUBTRACKS_HAVE_VIS
- if (subtrack->limitedVis != tvHide)
- #endif///def SUBTRACKS_HAVE_VIS
- {
- subtrack->hasUi = track->hasUi;
- flatTracksAdd(&flatTracks,subtrack,cart);
- }
- }
- }
- else
- #ifdef SUBTRACKS_HAVE_VIS
- if (track->limitedVis != tvHide)
- #endif///def SUBTRACKS_HAVE_VIS
- flatTracksAdd(&flatTracks,track,cart);
- if (maxSafeHeight < (pixHeight+trackPlusLabelHeight(track,fontHeight)))
- {
- char numBuf[SMALLBUF];
- sprintLongWithCommas(numBuf, maxSafeHeight);
- printf("warning: image is over %s pixels high at "
- "track '%s', remaining tracks set to hide "
- "for this view. \n", numBuf, track->tdb->shortLabel);
- safeHeight = FALSE;
- track->limitedVis = tvHide;
- track->limitedVisSet = TRUE;
- }
- }
- }
-flatTracksSort(&flatTracks); // Now we should have a perfectly good flat track list!
-struct track *prevTrack = NULL;
-for (flatTrack = flatTracks,prevTrack=NULL; flatTrack != NULL; flatTrack = flatTrack->next)
- {
- track = flatTrack->track;
- if (maxSafeHeight < (pixHeight+trackPlusLabelHeight(track,fontHeight)))
- {
- char numBuf[SMALLBUF];
- sprintLongWithCommas(numBuf, maxSafeHeight);
- printf("warning: image is over %s pixels high at "
- "track '%s', remaining tracks set to hide "
- "for this view. \n", numBuf, track->tdb->shortLabel);
- safeHeight = FALSE;
- track->limitedVis = tvHide;
- track->limitedVisSet = TRUE;
- }
- if (track->limitedVis != tvHide)
- {
- track->prevTrack = prevTrack; // Important for keeping track of conditional center labels!
- pixHeight += trackPlusLabelHeight(track, fontHeight);
- prevTrack = track;
- }
- }
-
-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
-
-#ifdef USE_PNG
- trashDirFile(&gifTn, "hgt", "hgt", ".png");
- hvg = hvGfxOpenPng(pixWidth, pixHeight, gifTn.forCgi, transparentImage);
-#else //ifndef
- trashDirFile(&gifTn, "hgt", "hgt", ".gif");
- hvg = hvGfxOpenGif(pixWidth, pixHeight, gifTn.forCgi, transparentImage);
-#endif //ndef USE_PNG
-
- if(theImgBox)
- {
- // Adds one single image for all tracks (COULD: build the track by track images)
- theOneImg = imgBoxImageAdd(theImgBox,gifTn.forHtml,NULL,pixWidth, pixHeight,FALSE);
- theSideImg = theOneImg; // Unlkess this is overwritten below, there is a single image
- }
- hvgSide = hvg; // Unlkess this is overwritten below, there is a single image
-
- if (theImgBox && theImgBox->showPortal && withLeftLabels)
- {
- // TODO: It would be great to make the images smaller, but keeping both the same full size for now
- struct tempName gifTnSide;
- #ifdef USE_PNG
- trashDirFile(&gifTnSide, "hgt", "side", ".png");
- hvgSide = hvGfxOpenPng(pixWidth, pixHeight, gifTnSide.forCgi, transparentImage);
- #else //ifndef
- trashDirFile(&gifTnSide, "hgt", "side", ".gif");
- hvgSide = hvGfxOpenGif(pixWidth, pixHeight, gifTnSide.forCgi, transparentImage);
- #endif //ndef USE_PNG
-
- // Also add the side image
- theSideImg = imgBoxImageAdd(theImgBox,gifTnSide.forHtml,NULL,pixWidth, pixHeight,FALSE);
- hvgSide->rc = revCmplDisp;
- initColors(hvgSide);
- }
- }
-hvg->rc = revCmplDisp;
-initColors(hvg);
-
-/* Start up client side map. */
-hPrintf("\n", mapName);
-
-/* Find colors to draw in. */
-findTrackColors(hvg, trackList);
-
-// 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 centerlabel, not reorderable
- }
-
- for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
- {
- track = flatTrack->track;
- if (track->limitedVis != tvHide)
- {
- #ifdef SUBTRACKS_HAVE_VIS
- if(track->labelColor == track->ixColor && track->ixColor == 0)
- track->ixColor = hvGfxFindRgb(hvg, &track->color);
- #endif//def SUBTRACKS_HAVE_VIS
- int order = flatTrack->order;
- curImgTrack = imgBoxTrackFindOrAdd(theImgBox,track->tdb,NULL,track->limitedVis,isCenterLabelIncluded(track),order);
- }
- }
- }
-
-
-/* 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
- sliceHeight = height + 1;
- sliceOffsetY = 0;
- curImgTrack = imgBoxTrackFind(theImgBox,NULL,RULER_TRACK_NAME);
- curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stButton,NULL,NULL,sliceWidth[stButton],sliceHeight,sliceOffsetX[stButton],sliceOffsetY); // flatTracksButton is all html, no jpg
- }
- 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)
- {
- y += trackPlusLabelHeight(track, fontHeight);
- yEnd = y;
- h = yEnd - yStart - 1;
-
- /* alternate button colors for track groups*/
- if (track->group != lastGroup)
- grayButtonGroup = !grayButtonGroup;
- lastGroup = track->group;
- if (grayButtonGroup)
- drawGrayButtonBox(hvgSide, trackTabX, yStart, trackTabWidth,
- h, track->hasUi);
- else
- drawBlueButtonBox(hvgSide, trackTabX, yStart, trackTabWidth,
- h, track->hasUi);
- if(theImgBox)
- {
- // Mini-buttons (side label slice) for tracks
- sliceHeight = yEnd - yStart;
- sliceOffsetY = yStart - 1;
- curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
- curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stButton,NULL,NULL,sliceWidth[stButton],sliceHeight,sliceOffsetX[stButton],sliceOffsetY); // flatTracksButton is all html, no jpg
- }
- if (track->hasUi)
- {
- if(tdbIsCompositeChild(track->tdb))
- {
- struct trackDb *parent = tdbGetComposite(track->tdb);
- mapBoxTrackUi(hvgSide, trackTabX, yStart, trackTabWidth, (yEnd - yStart - 1),
- 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;
- }
-
-if (withLeftLabels)
- {
- 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);
- curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stSide,theSideImg,NULL,sliceWidth[stSide],sliceHeight,sliceOffsetX[stSide],sliceOffsetY);
- curMap = 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);
- y += showPosHeight;
- }
- if (baseShowScaleBar)
- {
- y += scaleBarPad;
- hvGfxTextRight(hvgSide, leftLabelX, y, leftLabelWidth-1, scaleBarHeight,
- MG_BLACK, font, SCALE_BAR_LABEL);
- y += scaleBarHeight + scaleBarPad;
- }
- if (baseShowRuler)
- {
- char rulerLabel[SMALLBUF];
- char *shortChromName = cloneString(chromName);
- safef(rulerLabel,ArraySize(rulerLabel),":%s",shortChromName);
- int labelWidth = mgFontStringWidth(font,rulerLabel);
- while ((labelWidth > 0) && (labelWidth > leftLabelWidth))
- {
- int len = strlen(shortChromName);
- shortChromName[len-1] = 0;
- safef(rulerLabel,ArraySize(rulerLabel),":%s",shortChromName);
- labelWidth = mgFontStringWidth(font,rulerLabel);
- }
- if (hvgSide->rc)
- safef(rulerLabel,ArraySize(rulerLabel),":%s",shortChromName);
- else
- safef(rulerLabel,ArraySize(rulerLabel),"%s:",shortChromName);
- hvGfxTextRight(hvgSide, leftLabelX, y, leftLabelWidth-1, rulerHeight,
- MG_BLACK, font, rulerLabel);
- y += rulerHeight;
- freeMem(shortChromName);
- }
- if (zoomedToBaseLevel || rulerCds)
- {
- /* disable complement toggle for HIV because HIV is single stranded RNA */
- if (!hIsGsidServer())
- drawComplementArrow(hvgSide,leftLabelX, y,
- leftLabelWidth-1, baseHeight, font);
- 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
- sliceHeight = trackPlusLabelHeight(track, fontHeight);
- sliceOffsetY = y;
- curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
- curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stSide,theSideImg,NULL,sliceWidth[stSide],sliceHeight,sliceOffsetX[stSide],sliceOffsetY);
- curMap = sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot
- }
- y = doLeftLabels(track, hvgSide, font, y);
- }
- }
-else
- {
- leftLabelX = leftLabelWidth = 0;
- }
-
-/* Draw guidelines. */
-if (withGuidelines)
- {
- //if(theImgBox)
- // TODO: We should be making transparent data images and a separate background img for guidelines.
- // This will allow the guidelines to dragscroll while the center labels are static.
- // NOTE: The background image could easily be a reusable file, based upon zoom level and width. Height could propbaby easily be stretched.
- // struct image *bgImg = imgBoxImageAdd(theImgBox,gifBg.forHtml,
- // (char *)(dragZooming?"click or drag mouse in base position track to zoom in" : NULL),
- // pixWidth, pixHeight,FALSE);
- struct hvGfx *bgImg = hvg; // Default to the one image
- if(theImgBox)
- {
- struct tempName gifBg;
- #ifdef USE_PNG
- trashDirFile(&gifBg, "hgt", "bg", ".png"); // TODO: We could have a few static files by (pixHeight*pixWidth) And I doubt pixHeight is needed!
- bgImg = hvGfxOpenPng(pixWidth, pixHeight, gifBg.forCgi, TRUE);
- #else //ifndef
- trashDirFile(&gifBg, "hgt", "bg", ".gif");
- bgImg = hvGfxOpenGif(pixWidth, pixHeight, gifBg.forCgi, TRUE);
- #endif //ndef USE_PNG
- bgImg->rc = revCmplDisp;
- imgBoxImageAdd(theImgBox,gifBg.forHtml,NULL,pixWidth, pixHeight,TRUE); // Adds BG image
- }
- int height = pixHeight - 2*gfxBorder;
- int x;
- Color lightBlue = hvGfxFindRgb(bgImg, &guidelineColor);
-
- hvGfxSetClip(bgImg, insideX, gfxBorder, insideWidth, height);
- y = gfxBorder;
-
- for (x = insideX+guidelineSpacing-1; xnext)
- {
- 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);
- curMap = sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot
- if (isCenterLabelConditional(track))
- imgTrackUpdateCenterLabelSeen(curImgTrack,isCenterLabelConditionallySeen(track)?clNowSeen:clNotSeen);
- }
- y = doCenterLabels(track, track, hvg, font, y);
- }
- hvGfxUnclip(hvg);
- }
-
-/* Draw tracks. */
- {
- long lastTime = 0;
- y = yAfterRuler;
- if (measureTiming)
- lastTime = clock1000();
- for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
- {
- track = flatTrack->track;
- if (track->limitedVis == tvHide)
- continue;
-
- int centerLabelHeight = (isCenterLabelIncluded(track) ? fontHeight : 0);
- int yStart = y + centerLabelHeight;
- int yEnd = y + trackPlusLabelHeight(track, fontHeight);
- if(theImgBox)
- {
- // data slice of tracks
- sliceOffsetY = yStart;
- sliceHeight = yEnd - yStart - 1;
- curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
- if(sliceHeight > 0)
- {
- curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stData,theOneImg,NULL,sliceWidth[stData],sliceHeight,sliceOffsetX[stData],sliceOffsetY);
- curMap = sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot
- }
- }
- y = doDrawItems(track, hvg, font, y, &lastTime);
-
- if (theImgBox && track->limitedVis == tvDense && tdbIsCompositeChild(track->tdb))
- mapBoxToggleVis(hvg, 0, yStart,tl.picWidth, sliceHeight,track); // Strange mabBoxToggleLogic handles reverse complement itself so x=0, width=tl.picWidth
-
- if(yEnd!=y)
- warn("Slice height does not add up. Expecting %d != %d actual",yEnd - yStart - 1,y-yStart);
- }
- y++;
- }
-/* if a track can draw its left labels, now is the time since it
- * knows what exactly happened during drawItems
- */
-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
- sliceHeight = trackPlusLabelHeight(track, fontHeight);
- sliceOffsetY = y;
- curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
- curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stSide,theSideImg,NULL,sliceWidth[stSide],sliceHeight,sliceOffsetX[stSide],sliceOffsetY);
- curMap = sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot
- }
-
- if (track->drawLeftLabels != NULL)
- y = doOwnLeftLabels(track, hvgSide, font, y);
- else
- y += trackPlusLabelHeight(track, fontHeight);
- }
- }
-
-
-/* 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
- sliceHeight = trackPlusLabelHeight(track, fontHeight);
- sliceOffsetY = y;
- curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
- }
- y = doTrackMap(track, hvg, y, fontHeight, trackPastTabX, trackPastTabWidth);
- }
- }
-
-/* Finish map. */
-hPrintf(" \n");
-
-hPrintf(" \n", dragZooming ? 1 : 0);
-if(rulerClickHeight)
- {
- hPrintf(" \n", rulerClickHeight);
- }
-if(newWinWidth)
- {
- hPrintf(" \n", newWinWidth);
- }
-
-/* Save out picture and tell html file about it. */
-if(hvgSide != hvg)
- hvGfxClose(&hvgSide);
-hvGfxClose(&hvg);
-if(theImgBox)
- {
- imageBoxDraw(theImgBox);
- #ifdef IMAGEv2_DRAG_SCROLL
- // If a portal was established, then set the global dimensions back to the portal size
- if(imgBoxPortalDimensions(theImgBox,NULL,NULL,NULL,NULL,&winStart,&winEnd,&(tl.picWidth),NULL))
- {
- pixWidth = tl.picWidth;
- winBaseCount = winEnd - winStart;
- insideWidth = tl.picWidth-gfxBorder-insideX;
- }
- #endif//def IMAGEv2_DRAG_SCROLL
- imgBoxFree(&theImgBox);
- }
-else
- {
- char *titleAttr = dragZooming ? "title='click or drag mouse in base position track to zoom in'" : "";
- hPrintf(" \n");
- }
-flatTracksFree(&flatTracks);
-}
-
-static void printEnsemblAnchor(char *database, char* archive,
- char *chrName, int start, int end)
-/* Print anchor to Ensembl display on same window. */
-{
-char *scientificName = hScientificName(database);
-char *dir = ensOrgNameFromScientificName(scientificName);
-struct dyString *ensUrl;
-char *name;
-int localStart, localEnd;
-
-name = chrName;
-
-if (sameWord(scientificName, "Takifugu rubripes"))
- {
- /* for Fugu, must give scaffold, not chr coordinates */
- /* Also, must give "chrom" as "scaffold_N", name below. */
- if (differentWord(chromName,"chrM") &&
- !hScaffoldPos(database, chromName, winStart, winEnd,
- &name, &localStart, &localEnd))
- /* position doesn't appear on Ensembl browser.
- * Ensembl doesn't show scaffolds < 2K */
- return;
- }
-else if (sameWord(scientificName, "Gasterosteus aculeatus"))
- {
- if (differentWord("chrM", chrName))
- {
- char *fixupName = replaceChars(chrName, "chr", "group");
- name = fixupName;
- }
- }
-else if (sameWord(scientificName, "Ciona intestinalis"))
- {
- if (stringIn("chr0", chrName))
- {
- char *fixupName = replaceChars(chrName, "chr0", "chr");
- name = fixupName;
- }
- }
-else if (sameWord(scientificName, "Saccharomyces cerevisiae"))
- {
- if (stringIn("2micron", chrName))
- {
- char *fixupName = replaceChars(chrName, "2micron", "2-micron");
- name = fixupName;
- }
- }
-
-if (sameWord(chrName, "chrM"))
- name = "chrMt";
-localStart = start;
-localEnd = end + 1; // Ensembl base-1 display coordinates
-ensUrl = ensContigViewUrl(database, dir, name, seqBaseCount, localStart, localEnd, archive);
-hPrintf("", ensUrl->string);
-/* NOTE: you can not freeMem(dir) because sometimes it is a literal
- * constant */
-freeMem(scientificName);
-dyStringFree(&ensUrl);
-}
-
-void makeHgGenomeTrackVisible(struct track *track)
-/* This turns on a track clicked from hgGenome, even if it was previously */
-/* hidden manually and there are cart vars to support that. */
-{
-struct hashEl *hels;
-struct hashEl *hel;
-char prefix[SMALLBUF];
-/* First check if the click was from hgGenome. If not, leave. */
-/* get the names of the tracks in the cart */
-safef(prefix, sizeof(prefix), "%s_", hggGraphPrefix);
-hels = cartFindPrefix(cart, prefix);
-/* loop through them and compare them to the track passed into this */
-/* function. */
-for (hel = hels; hel != NULL; hel = hel->next)
- {
- struct trackDb *subtrack;
- char *subtrackName = hel->val;
- /* check non-subtrack. */
- if (sameString(track->tdb->track, subtrackName))
- {
- track->visibility = tvFull;
- track->tdb->visibility = tvFull;
- cartSetString(cart, track->tdb->track, "full");
- }
- else if (track->tdb->subtracks != NULL)
- {
- struct slRef *tdbRef, *tdbRefList = trackDbListGetRefsToDescendants(track->tdb->subtracks);
- for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next)
- {
- subtrack = tdbRef->val;
- if (sameString(subtrack->track, subtrackName))
- {
- char selName[SMALLBUF];
- track->visibility = tvFull;
- cartSetString(cart, track->tdb->track, "full");
- track->tdb->visibility = tvFull;
- subtrack->visibility = tvFull;
- safef(selName, sizeof(selName), "%s_sel", subtrackName);
- cartSetBoolean(cart, selName, TRUE);
- }
- }
- slFreeList(&tdbRefList);
- }
- }
-hashElFreeList(&hels);
-}
-
-struct sqlConnection *remoteTrackConnection(struct track *tg)
-/* Get a connection to remote database as specified in remoteSql settings... */
-{
-if (!tg->isRemoteSql)
- {
- internalErr();
- return NULL;
- }
-else
- {
- return sqlConnectRemote(tg->remoteSqlHost, tg->remoteSqlUser, tg->remoteSqlPassword,
- tg->remoteSqlDatabase);
- }
-}
-
-void addTdbListToTrackList(struct trackDb *tdbList, char *trackNameFilter,
- struct track **pTrackList)
-/* Convert a list of trackDb's to tracks, and append these to trackList. */
-{
-struct trackDb *tdb, *next;
-struct track *track;
-TrackHandler handler;
-tdbSortPrioritiesFromCart(cart, &tdbList);
-for (tdb = tdbList; tdb != NULL; tdb = next)
- {
- next = tdb->next;
- if(trackNameFilter != NULL && strcmp(trackNameFilter, tdb->track))
- // suppress loading & display of all tracks except for the one passed in via trackNameFilter
- continue;
- track = trackFromTrackDb(tdb);
- track->hasUi = TRUE;
- if (slCount(tdb->subtracks) != 0)
- {
- tdbSortPrioritiesFromCart(cart, &(tdb->subtracks));
- if (trackDbLocalSetting(tdb, "compositeTrack"))
- makeCompositeTrack(track, tdb);
- else if (trackDbLocalSetting(tdb, "container"))
- makeContainerTrack(track, tdb);
- }
- else
- {
- handler = lookupTrackHandler(tdb->table);
- if (handler != NULL)
- handler(track);
- }
- 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");
-struct trackDb *tdbList;
-if(trackNameFilter == NULL)
- tdbList = hTrackDb(database, chromName);
-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);
-}
-
-void ctLoadSimpleBed(struct track *tg)
-/* Load the items in one custom track - just move beds in
- * window... */
-{
-struct customTrack *ct = tg->customPt;
-struct bed *bed, *nextBed, *list = NULL;
-int scoreFilter = getScoreFilter(ct->tdb->track);
-
-if (ct->dbTrack)
- {
- int fieldCount = ct->fieldCount;
- int rowOffset;
- char **row;
- struct sqlConnection *conn =
- hAllocConn(CUSTOM_TRASH);
- struct sqlResult *sr = NULL;
-
- sr = hRangeQuery(conn, ct->dbTableName, chromName, winStart, winEnd,
- NULL, &rowOffset);
- while ((row = sqlNextRow(sr)) != NULL)
- {
- bed = bedLoadN(row+rowOffset, fieldCount);
- if (scoreFilter && bed->score < scoreFilter)
- continue;
- slAddHead(&list, bed);
- }
- hFreeConn(&conn);
- }
-else
- {
- for (bed = ct->bedList; bed != NULL; bed = nextBed)
- {
- nextBed = bed->next;
- if (bed->chromStart < winEnd && bed->chromEnd > winStart
- && sameString(chromName, bed->chrom))
- {
- if (scoreFilter && bed->score < scoreFilter)
- continue;
- slAddHead(&list, bed);
- }
- }
- }
-slSort(&list, bedCmp);
-tg->items = list;
-}
-
-void ctLoadBed9(struct track *tg)
-/* Convert bed info in window to linked feature. */
-{
-struct customTrack *ct = tg->customPt;
-struct bed *bed;
-struct linkedFeatures *lfList = NULL, *lf;
-boolean useItemRgb = FALSE;
-int scoreFilter = getScoreFilter(ct->tdb->track);
-
-useItemRgb = bedItemRgb(ct->tdb);
-
-if (ct->dbTrack)
- {
- int rowOffset;
- char **row;
- struct sqlConnection *conn = hAllocConn(CUSTOM_TRASH);
- struct sqlResult *sr = NULL;
-
- sr = hRangeQuery(conn, ct->dbTableName, chromName, winStart, winEnd,
- NULL, &rowOffset);
- while ((row = sqlNextRow(sr)) != NULL)
- {
- bed = bedLoadN(row+rowOffset, 9);
- if (scoreFilter && bed->score < scoreFilter)
- continue;
- bed8To12(bed);
- lf = lfFromBed(bed);
- if (useItemRgb)
- {
- lf->extra = (void *)USE_ITEM_RGB; /* signal for coloring */
- lf->filterColor=bed->itemRgb;
- }
- slAddHead(&lfList, lf);
- }
- hFreeConn(&conn);
- }
-else
- {
- for (bed = ct->bedList; bed != NULL; bed = bed->next)
- {
- if (scoreFilter && bed->score < scoreFilter)
- continue;
- if (bed->chromStart < winEnd && bed->chromEnd > winStart
- && sameString(chromName, bed->chrom))
- {
- bed8To12(bed);
- lf = lfFromBed(bed);
- if (useItemRgb)
- {
- lf->extra = (void *)USE_ITEM_RGB; /* signal for coloring */
- lf->filterColor=bed->itemRgb;
- }
- slAddHead(&lfList, lf);
- }
- }
- }
-slReverse(&lfList);
-slSort(&lfList, linkedFeaturesCmp);
-tg->items = lfList;
-}
-
-
-void ctLoadBed8(struct track *tg)
-/* Convert bed info in window to linked feature. */
-{
-struct customTrack *ct = tg->customPt;
-struct bed *bed;
-struct linkedFeatures *lfList = NULL, *lf;
-int scoreFilter = getScoreFilter(ct->tdb->track);
-
-if (ct->dbTrack)
- {
- int fieldCount = ct->fieldCount;
- int rowOffset;
- char **row;
- struct sqlConnection *conn = hAllocConn(CUSTOM_TRASH);
- struct sqlResult *sr = NULL;
-
- sr = hRangeQuery(conn, ct->dbTableName, chromName, winStart, winEnd,
- NULL, &rowOffset);
- while ((row = sqlNextRow(sr)) != NULL)
- {
- bed = bedLoadN(row+rowOffset, fieldCount);
- if (scoreFilter && bed->score < scoreFilter)
- continue;
- bed8To12(bed);
- lf = lfFromBed(bed);
- slAddHead(&lfList, lf);
- }
- hFreeConn(&conn);
- }
-else
- {
- for (bed = ct->bedList; bed != NULL; bed = bed->next)
- {
- if (scoreFilter && bed->score < scoreFilter)
- continue;
- if (bed->chromStart < winEnd && bed->chromEnd > winStart
- && sameString(chromName, bed->chrom))
- {
- bed8To12(bed);
- lf = lfFromBed(bed);
- slAddHead(&lfList, lf);
- }
- }
- }
-slReverse(&lfList);
-slSort(&lfList, linkedFeaturesCmp);
-tg->items = lfList;
-}
-
-void ctLoadGappedBed(struct track *tg)
-/* Convert bed info in window to linked feature. */
-{
-struct customTrack *ct = tg->customPt;
-struct bed *bed;
-struct linkedFeatures *lfList = NULL, *lf;
-boolean useItemRgb = FALSE;
-int scoreFilter = getScoreFilter(ct->tdb->track);
-
-useItemRgb = bedItemRgb(ct->tdb);
-
-if (ct->dbTrack)
- {
- int fieldCount = ct->fieldCount;
- int rowOffset;
- char **row;
- struct sqlConnection *conn = hAllocConn(CUSTOM_TRASH);
- struct sqlResult *sr = NULL;
-
- sr = hRangeQuery(conn, ct->dbTableName, chromName, winStart, winEnd,
- NULL, &rowOffset);
- while ((row = sqlNextRow(sr)) != NULL)
- {
- bed = bedLoadN(row+rowOffset, fieldCount);
- lf = lfFromBed(bed);
- if (scoreFilter && bed->score < scoreFilter)
- continue;
- if (useItemRgb)
- {
- lf->extra = (void *)USE_ITEM_RGB; /* signal for coloring */
- lf->filterColor=bed->itemRgb;
- }
- slAddHead(&lfList, lf);
- }
- hFreeConn(&conn);
- }
-else
- {
- for (bed = ct->bedList; bed != NULL; bed = bed->next)
- {
- if (scoreFilter && bed->score < scoreFilter)
- continue;
- if (bed->chromStart < winEnd && bed->chromEnd > winStart
- && sameString(chromName, bed->chrom))
- {
- lf = lfFromBed(bed);
- if (useItemRgb)
- {
- lf->extra = (void *)USE_ITEM_RGB; /* signal for coloring */
- lf->filterColor=bed->itemRgb;
- }
- slAddHead(&lfList, lf);
- }
- }
- }
-slReverse(&lfList);
-slSort(&lfList, linkedFeaturesCmp);
-tg->items = lfList;
-}
-
-void ctLoadColoredExon(struct track *tg)
-/* Convert bed info in window to linked features series for custom track. */
-{
-struct customTrack *ct = tg->customPt;
-struct bed *bed;
-struct linkedFeaturesSeries *lfsList = NULL, *lfs;
-if (ct->dbTrack)
- {
- int fieldCount = ct->fieldCount;
- int rowOffset;
- char **row;
- struct sqlConnection *conn = hAllocConn(CUSTOM_TRASH);
- struct sqlResult *sr = NULL;
- sr = hRangeQuery(conn, ct->dbTableName, chromName, winStart, winEnd,
- NULL, &rowOffset);
- while ((row = sqlNextRow(sr)) != NULL)
- {
- bed = bedLoadN(row+rowOffset, fieldCount);
- lfs = lfsFromColoredExonBed(bed);
- slAddHead(&lfsList, lfs);
- }
- hFreeConn(&conn);
- }
-else
- {
- for (bed = ct->bedList; bed != NULL; bed = bed->next)
- {
- if (bed->chromStart < winEnd && bed->chromEnd > winStart
- && sameString(chromName, bed->chrom))
- {
- lfs = lfsFromColoredExonBed(bed);
- slAddHead(&lfsList, lfs);
- }
- }
- }
-slReverse(&lfsList);
-slSort(&lfsList, linkedFeaturesSeriesCmp);
-tg->items = lfsList;
-}
-
-char *ctMapItemName(struct track *tg, void *item)
-/* Return composite item name for custom tracks. */
-{
-char *itemName = tg->itemName(tg, item);
-static char buf[256];
-if (strlen(itemName) > 0)
- sprintf(buf, "%s %s", ctFileName, itemName);
-else
- sprintf(buf, "%s NoItemName", ctFileName);
-return buf;
-}
-
-
-void coloredExonMethodsFromCt(struct track *tg)
-/* same as coloredExonMethods but different loader. */
-{
-linkedFeaturesSeriesMethods(tg);
-tg->loadItems = ctLoadColoredExon;
-tg->canPack = TRUE;
-}
-
-struct track *newCustomTrack(struct customTrack *ct)
-/* Make up a new custom track. */
-{
-struct track *tg = NULL;
-struct trackDb *tdb = ct->tdb;
-boolean useItemRgb = FALSE;
-char *typeOrig = tdb->type;
-char *typeDupe = cloneString(typeOrig);
-char *typeParam = typeDupe;
-char *type = nextWord(&typeParam);
-
-if (ct->dbTrack)
- {
- // make sure we can connect
- struct sqlConnection *conn = hAllocConn(CUSTOM_TRASH);
- hFreeConn(&conn);
- }
-
-useItemRgb = bedItemRgb(tdb);
-
-if (sameString(type, "maf"))
- {
- tg = trackFromTrackDb(tdb);
- tg->canPack = TRUE;
-
- wigMafMethods(tg, tdb, 0, NULL);
- if (!ct->dbTrack)
- errAbort("custom maf tracks must be in database");
-
- struct mafPriv *mp;
- AllocVar(mp);
- mp->ct = ct;
-
- tg->customPt = mp;
- tg->nextItemButtonable = FALSE;
- }
-else if (sameString(type, "wig"))
- {
- tg = trackFromTrackDb(tdb);
- if (ct->dbTrack)
- tg->loadItems = wigLoadItems;
- else
- tg->loadItems = ctWigLoadItems;
- tg->customPt = ct;
- tg->nextItemButtonable = FALSE;
- }
-else if (sameString(type, "bigWig"))
- {
- tg = trackFromTrackDb(tdb);
- tg->bbiFile = ct->bbiFile;
- tg->nextItemButtonable = FALSE;
- }
-else if (sameString(type, "bigBed"))
- {
- struct bbiFile *bbi = ct->bbiFile;
-
- /* Find field counts, and from that revise the tdb->type to be more complete. */
- char extra = (bbi->fieldCount > bbi->definedFieldCount ? '+' : '.');
- char typeBuf[64];
- safef(typeBuf, sizeof(typeBuf), "bigBed %d %c", bbi->definedFieldCount, extra);
- tdb->type = cloneString(typeBuf);
-
- /* Finish wrapping track around tdb. */
- tg = trackFromTrackDb(tdb);
- tg->bbiFile = bbi;
- tg->nextItemButtonable = FALSE;
- }
-else if (sameString(type, "bedGraph"))
- {
- tg = trackFromTrackDb(tdb);
- tg->canPack = FALSE;
- tg->customPt = ct;
- ct->wigFile = ctFileName;
- tg->mapItemName = ctMapItemName;
- tg->nextItemButtonable = FALSE;
- }
-else if (sameString(type, "bed"))
- {
- tg = trackFromTrackDb(tdb);
- if (ct->fieldCount < 8)
- {
- tg->loadItems = ctLoadSimpleBed;
- }
- else if (useItemRgb && ct->fieldCount == 9)
- {
- tg->loadItems = ctLoadBed9;
- }
- else if (ct->fieldCount < 12)
- {
- tg->loadItems = ctLoadBed8;
- }
- else if (ct->fieldCount == 15)
- {
- char *theType = trackDbSetting(tdb, "type");
- if (theType && sameString(theType, "expRatio"))
- {
- tg = trackFromTrackDb(tdb);
- expRatioMethodsFromCt(tg);
- }
- else
- tg->loadItems = ctLoadGappedBed;
- }
- else
- {
- tg->loadItems = ctLoadGappedBed;
- }
- tg->mapItemName = ctMapItemName;
- tg->canPack = TRUE;
- tg->nextItemButtonable = TRUE;
- tg->customPt = ct;
- }
-else if (sameString(type, "chromGraph"))
- {
- tdb->type = NULL; /* Swap out type for the moment. */
- tg = trackFromTrackDb(tdb);
- chromGraphMethodsCt(tg);
- tg->nextItemButtonable = FALSE;
- tdb->type = typeOrig;
- }
-else if (sameString(type, "array"))
- {
- tg = trackFromTrackDb(tdb);
- expRatioMethodsFromCt(tg);
- tg->nextItemButtonable = TRUE;
- tg->customPt = ct;
- }
-else if (sameString(type, "coloredExon"))
- {
- tg = trackFromTrackDb(tdb);
- coloredExonMethodsFromCt(tg);
- tg->nextItemButtonable = TRUE;
- tg->customPt = ct;
- }
-else if (sameString(type, "encodePeak"))
- {
- tg = trackFromTrackDb(tdb);
- encodePeakMethodsCt(tg);
- tg->nextItemButtonable = TRUE;
- tg->customPt = ct;
- }
-else if (sameString(type, "bam"))
- {
- tg = trackFromTrackDb(tdb);
- tg->customPt = ct;
- bamMethods(tg);
- tg->mapItemName = ctMapItemName;
- hashAdd(tdb->settingsHash, BASE_COLOR_USE_SEQUENCE, cloneString("lfExtra"));
- hashAdd(tdb->settingsHash, BASE_COLOR_DEFAULT, cloneString("diffBases"));
- hashAdd(tdb->settingsHash, SHOW_DIFF_BASES_ALL_SCALES, cloneString("."));
- hashAdd(tdb->settingsHash, INDEL_DOUBLE_INSERT, cloneString("on"));
- hashAdd(tdb->settingsHash, INDEL_QUERY_INSERT, cloneString("on"));
- hashAdd(tdb->settingsHash, INDEL_POLY_A, cloneString("on"));
- hashAdd(tdb->settingsHash, "showDiffBasesMaxZoom", cloneString("100"));
- }
-else if (sameString(type, "makeItems"))
- {
- tg = trackFromTrackDb(tdb);
- makeItemsMethods(tg);
- tg->nextItemButtonable = TRUE;
- tg->customPt = ct;
- }
-else if (sameString(type, "bedDetail"))
- {
- tg = trackFromTrackDb(tdb);
- bedDetailCtMethods(tg, ct);
- tg->mapItemName = ctMapItemName; /* must be here to see ctMapItemName */
- }
-else if (sameString(type, "pgSnp"))
- {
- tg = trackFromTrackDb(tdb);
- pgSnpCtMethods(tg);
- //tg->mapItemName = ctMapItemName;
- tg->customPt = ct;
- }
-else
- {
- errAbort("Unrecognized custom track type %s", type);
- }
-if (!ct->dbTrack)
- tg->nextItemButtonable = FALSE;
-tg->hasUi = TRUE;
-freez(&typeDupe);
-return tg;
-}
-
-char *getPositionFromCustomTracks()
-/* Parses custom track data to get the position variable
- * return - The first chromosome position variable found in the
- * custom track data. */
-{
-char *pos = NULL;
-struct slName *bl = NULL;
-
-ctList = customTracksParseCart(database, cart, &browserLines, &ctFileName);
-
-for (bl = browserLines; bl != NULL; bl = bl->next)
- {
- char *words[96];
- int wordCount;
- char *dupe = cloneString(bl->name);
-
- wordCount = chopLine(dupe, words);
- if (wordCount >= 3)
- {
- char *command = words[1];
- if (sameString(command, "position"))
- pos = cloneString(words[2]);
- }
- freez(&dupe);
- if (pos != NULL)
- break;
- }
-return pos;
-}
-
-void loadCustomTracks(struct track **pTrackList)
-/* Load up custom tracks and append to list. */
-{
-struct customTrack *ct;
-struct track *tg;
-struct slName *bl;
-
-/* build up browser lines from cart variables set by hgCustom */
-char *visAll = cartCgiUsualString(cart, "hgt.visAllFromCt", NULL);
-if (visAll)
- {
- char buf[SMALLBUF];
- safef(buf, sizeof buf, "browser %s %s", visAll, "all");
- slAddTail(&browserLines, slNameNew(buf));
- }
-struct hashEl *visEl;
-struct hashEl *visList = cartFindPrefix(cart, "hgtct.");
-for (visEl = visList; visEl != NULL; visEl = visEl->next)
- {
- char buf[256];
- safef(buf, sizeof buf, "browser %s %s", cartString(cart, visEl->name),
- chopPrefix(cloneString(visEl->name)));
- slAddTail(&browserLines, slNameNew(buf));
- cartRemove(cart, visEl->name);
- }
-hashElFreeList(&visList);
-
-/* The loading is now handled by getPositionFromCustomTracks(). */
-/* Process browser commands in custom track. */
-for (bl = browserLines; bl != NULL; bl = bl->next)
- {
- char *words[96];
- int wordCount;
-
- wordCount = chopLine(bl->name, words);
- if (wordCount > 1)
- {
- char *command = words[1];
- if (sameString(command, "hide")
- || sameString(command, "dense")
- || sameString(command, "pack")
- || sameString(command, "squish")
- || sameString(command, "full"))
- {
- if (wordCount > 2)
- {
- int i;
- for (i=2; inext)
- {
- if (toAll || sameString(s, tg->track))
- {
- if (hTvFromString(command) == tg->tdb->visibility)
- /* remove if setting to default vis */
- cartRemove(cart, tg->track);
- else
- cartSetString(cart, tg->track, command);
- /* hide or show supertrack enclosing this track */
- if (tdbIsSuperTrackChild(tg->tdb))
- {
- assert(tg->tdb->parentName != NULL);
- cartSetString(cart, tg->tdb->parentName,
- (sameString(command, "hide") ?
- "hide" : "show"));
- }
- }
- }
- }
- }
- }
- else if (sameString(command, "position"))
- {
- if (wordCount < 3)
- errAbort("Expecting 3 words in browser position line");
- if (!hgIsChromRange(database, words[2]))
- errAbort("browser position needs to be in chrN:123-456 format");
- hgParseChromRange(database, words[2], &chromName, &winStart, &winEnd);
-
- /*Fix a start window of -1 that is returned when a custom track position
- begins at 0
- */
- if (winStart < 0)
- {
- winStart = 0;
- }
- }
- else if (sameString(command, "pix"))
- {
- if (wordCount != 3)
- errAbort("Expecting 3 words in pix line");
- trackLayoutSetPicWidth(&tl, words[2]);
- }
- }
- }
-for (ct = ctList; ct != NULL; ct = ct->next)
- {
- hasCustomTracks = TRUE;
- tg = newCustomTrack(ct);
- slAddHead(pTrackList, tg);
- }
-}
-
-void addTracksFromDataHub(char *hubUrl, struct track **pTrackList)
-/* Load up stuff from data hub and append to list. The hubUrl points to
- * a trackDb.ra format file. */
-{
-/* Squirrel away hub directory for later. */
-char hubDir[PATH_LEN];
-splitPath(hubUrl, hubDir, NULL, NULL);
-
-/* Load trackDb.ra file and make it into proper trackDb tree */
-struct trackDb *tdb, *tdbList = trackDbFromRa(hubUrl);
-for (tdb = tdbList; tdb != NULL; tdb = tdb->next)
- {
- trackDbFieldsFromSettings(tdb);
- trackDbPolish(tdb);
- }
-trackDbLinkUpGenerations(tdbList);
-addTdbListToTrackList(tdbList, NULL, pTrackList);
-}
-
-void loadDataHubs(struct track **pTrackList)
-/* Load up stuff from data hubs and append to list. */
-{
-char *dataHubs = cloneString(cartUsualString(cart, "dataHubs", NULL));
-if (dataHubs == NULL)
- return;
-int hubCount = chopByWhite(dataHubs, NULL, 10);
-char *hubArrays[hubCount];
-chopByWhite(dataHubs, hubArrays, hubCount);
-int i;
-for (i = 0; i%u",
-chromName, winEnd, winStart);
-sr = sqlGetResult(conn, query);
-
-int itemCount = 0;
-struct agpFrag *agpItem = NULL;
-while ((row = sqlNextRow(sr)) != NULL)
- {
- agpFragFree(&agpItem); // if there is a second one
- agpItem = agpFragLoad(row+1);
- ++itemCount;
- if (itemCount > 1)
- break;
- }
-sqlFreeResult(&sr);
-hFreeConn(&conn);
-if (1 == itemCount)
- { // verify *entirely* within single contig
- if ((winEnd <= agpItem->chromEnd) &&
- (winStart >= agpItem->chromStart))
- {
- int agpStart = winStart - agpItem->chromStart;
- int agpEnd = agpStart + winEnd - winStart;
- hPuts("");
- printEnsemblAnchor(database, archive, agpItem->frag,
- agpStart, agpEnd);
- hPrintf("%s ", "Ensembl");
- }
- }
-agpFragFree(&agpItem); // the one we maybe used
-}
-
-void hotLinks()
-/* Put up the hot links bar. */
-{
-boolean gotBlat = hIsBlatIndexedDatabase(database);
-struct dyString *uiVars = uiStateUrlPart(NULL);
-char *orgEnc = cgiEncode(organism);
-boolean psOutput = cgiVarExists("hgt.psOutput");
-
-hPrintf("\n");
-hPrintf("\n");
-hPrintf("\n");
-hPrintf("Home ",
- orgEnc, database, cartSessionVarName(), cartSessionId(cart));
-
-if (hIsGisaidServer())
- {
- /* disable hgGateway for gisaid for now */
- //hPrintf(" Sequence View Gateway ", orgEnc, database);
- hPrintf(
- " %s ",
- '%', '%',
- cartSessionVarName(),
- cartSessionId(cart),
- "Select Subjects");
- }
-else
-if (hIsGsidServer())
- {
- hPrintf(" Sequence View Gateway ", orgEnc, database);
- hPrintf(
- " %s ",
- '%', '%', "Select Subjects");
- }
-else
- {
- hPrintf(" Genomes ", orgEnc, database, cartSessionVarName(), cartSessionId(cart));
- }
-if (psOutput)
- {
- hPrintf(" Genome Browser ", orgEnc, database, cartSessionVarName(), cartSessionId(cart));
- }
-if (gotBlat)
- {
- hPrintf(" Blat ", uiVars->string);
- }
-if (hIsGisaidServer())
- {
- hPrintf(" %s ",
- database,
- cartSessionVarName(),
- cartSessionId(cart),
- "Table View");
- }
-else if (hIsGsidServer())
- {
- hPrintf(" %s ",
- database, "Table View");
- }
-else
- {
- /* disable TB for CGB servers */
- if (!hIsCgbServer())
- {
- hPrintf(" %s ",
- database, chromName, winStart+1, winEnd,
- cartSessionVarName(),
- cartSessionId(cart),
- "Tables");
- }
- }
-
-if (hgNearOk(database))
- {
- hPrintf(" %s ",
- uiVars->string, "Gene Sorter");
- }
-if (hgPcrOk(database))
- {
- hPrintf(" PCR ", uiVars->string);
- }
-if (!psOutput)
- {
- hPrintf(" "
- " %s ", hgcNameAndSettings(),
- winStart, chromName, winStart, winEnd, database, uiVars->string, "DNA");
- }
-
-if (!psOutput)
- {
- /* disable Convert function for CGB servers for the time being */
- if (!hIsCgbServer())
- if (liftOverChainForDb(database) != NULL)
- {
- hPrintf(" string, database, chromName, winStart+1, winEnd);
- hPrintf("\" class=\"topbar\">Convert ");
- }
- }
-
-/* see if hgFixed.trackVersion exists */
-boolean trackVersionExists = hTableExists("hgFixed", "trackVersion");
-char ensVersionString[256];
-char ensDateReference[256];
-ensVersionString[0] = 0;
-ensDateReference[0] = 0;
-if (trackVersionExists)
- {
- struct sqlConnection *conn = hAllocConn("hgFixed");
- char query[256];
- safef(query, sizeof(query), "select version,dateReference from hgFixed.trackVersion where db = '%s' order by updateTime DESC limit 1", database);
- struct sqlResult *sr = sqlGetResult(conn, query);
- char **row;
-
- while ((row = sqlNextRow(sr)) != NULL)
- {
- safef(ensVersionString, sizeof(ensVersionString), "Ensembl %s",
- row[0]);
- safef(ensDateReference, sizeof(ensDateReference), "%s",
- row[1]);
- }
- sqlFreeResult(&sr);
- hFreeConn(&conn);
- }
-
-if (!psOutput)
- {
- if (differentWord(database,"susScr2"))
- {
- /* Print Ensembl anchor for latest assembly of organisms we have
- * supported by Ensembl == if versionString from trackVersion exists */
- if (sameWord(database,"hg19"))
- {
- hPrintf(" ");
- printEnsemblAnchor(database, NULL, chromName, winStart, winEnd);
- hPrintf("%s ", "Ensembl");
- }
- else if (sameWord(database,"hg18"))
- {
- hPrintf(" ");
- printEnsemblAnchor(database, "ncbi36", chromName, winStart, winEnd);
- hPrintf("%s ", "Ensembl");
- }
- else if (ensVersionString[0])
- {
- char *archive = NULL;
- if (ensDateReference[0] && differentWord("current", ensDateReference))
- archive = cloneString(ensDateReference);
- /* Can we perhaps map from a UCSC random chrom to an Ensembl contig ? */
- if (sameWord(database,"oryCun2") || isUnknownChrom(database, chromName))
- {
- // which table to check
- char *ctgPos = "ctgPos";
- if (sameWord(database,"oryCun2"))
- ctgPos = "ctgPos2";
-
- if (sameWord(database,"fr2"))
- fr2ScaffoldEnsemblLink(archive);
- else if (hTableExists(database, ctgPos))
- /* see if we are entirely within a single contig */
- {
- struct sqlConnection *conn = hAllocConn(database);
- struct sqlResult *sr = NULL;
- char **row = NULL;
- char query[256];
- safef(query, sizeof(query),
- "select * from %s where chrom = '%s' and chromStart<%u and chromEnd>%u",
- ctgPos, chromName, winEnd, winStart);
- sr = sqlGetResult(conn, query);
-
- int itemCount = 0;
- struct ctgPos *ctgItem = NULL;
- while ((row = sqlNextRow(sr)) != NULL)
- {
- ctgPosFree(&ctgItem); // if there is a second one
- ctgItem = ctgPosLoad(row);
- ++itemCount;
- if (itemCount > 1)
- break;
- }
- sqlFreeResult(&sr);
- hFreeConn(&conn);
- if (1 == itemCount)
- { // verify *entirely* within single contig
- if ((winEnd <= ctgItem->chromEnd) &&
- (winStart >= ctgItem->chromStart))
- {
- int ctgStart = winStart - ctgItem->chromStart;
- int ctgEnd = ctgStart + winEnd - winStart;
- hPrintf(" ");
- printEnsemblAnchor(database, archive, ctgItem->contig,
- ctgStart, ctgEnd);
- hPrintf("%s ", "Ensembl");
- }
- }
- ctgPosFree(&ctgItem); // the one we maybe used
- }
- }
- else
- {
- hPrintf(" ");
- printEnsemblAnchor(database, archive, chromName, winStart, winEnd);
- hPrintf("%s ", "Ensembl");
- }
- }
- }
- }
-
-if (!psOutput)
- {
- /* Print NCBI MapView anchor */
- if (sameString(database, "hg18"))
- {
- hPrintf(" ",
- skipChr(chromName), winStart+1, winEnd);
- hPrintf("%s ", "NCBI");
- }
- if (sameString(database, "hg19"))
- {
- hPrintf(" ",
- skipChr(chromName), winStart+1, winEnd);
- hPrintf("%s ", "NCBI");
- }
- if (sameString(database, "mm8"))
- {
- hPrintf("");
- hPrintf("",
- skipChr(chromName), winStart+1, winEnd);
- hPrintf("%s ", "NCBI");
- }
- if (sameString(database, "danRer2"))
- {
- hPrintf("");
- hPrintf("",
- skipChr(chromName), winStart+1, winEnd);
- hPrintf("%s ", "NCBI");
- }
- if (sameString(database, "galGal3"))
- {
- hPrintf("");
- hPrintf("",
- skipChr(chromName), winStart+1, winEnd);
- hPrintf("%s ", "NCBI");
- }
- if (sameString(database, "canFam2"))
- {
- hPrintf("");
- hPrintf("",
- skipChr(chromName), winStart+1, winEnd);
- hPrintf("%s ", "NCBI");
- }
- if (sameString(database, "rheMac2"))
- {
- hPrintf("");
- hPrintf("",
- skipChr(chromName), winStart+1, winEnd);
- hPrintf("%s ", "NCBI");
- }
- if (sameString(database, "panTro2"))
- {
- hPrintf("");
- hPrintf("",
- skipChr(chromName), winStart+1, winEnd);
- hPrintf("%s ", "NCBI");
- }
- if (sameString(database, "anoGam1"))
- {
- hPrintf("");
- hPrintf("",
- skipChr(chromName), winStart+1, winEnd);
- hPrintf("%s ", "NCBI");
- }
- if (startsWith("oryLat", database))
- {
- hPrintf(" %s ",
- skipChr(chromName), winStart+1, winEnd, "UTGB");
- }
- if (sameString(database, "cb3"))
- {
- hPrintf(" %s ",
- skipChr(chromName), winStart+1, winEnd, "WormBase");
- }
- if (sameString(database, "ce4"))
- {
- hPrintf(" %s ",
- skipChr(chromName), winStart+1, winEnd, "WormBase");
- }
- if (sameString(database, "ce2"))
- {
- hPrintf(" %s ",
- skipChr(chromName), winStart+1, winEnd, "WormBase");
- }
- }
-
-if (!psOutput)
- {
- hPrintf(" %s ",cartSessionVarName(),
- cartSessionId(cart), "PDF/PS");
- }
-
-if (!psOutput)
- {
- if (wikiLinkEnabled())
- {
- printf(" Session ",
- cartSessionVarName(), cartSessionId(cart));
- }
- }
-if (hIsGisaidServer())
- {
- //hPrintf(" %s \n", "Help");
- hPrintf(" %s \n", "Help");
- }
-else
-if (hIsGsidServer())
- {
- hPrintf(" %s \n", "Help");
- }
-else
- {
- hPrintf(" %s \n", "Help");
- }
-hPuts("
");
-hPuts("
");
-hPuts("
\n");
-}
-
-static void setSuperTrackHasVisibleMembers(struct trackDb *tdb)
-/* Determine if any member tracks are visible -- currently
- * recording this in the parent's visibility setting */
-{
-tdb->visibility = tvDense;
-}
-
-boolean superTrackHasVisibleMembers(struct trackDb *tdb)
-/* Determine if any member tracks are visible -- currently
- * recording this in the parent's visibility setting */
-{
-if (!tdbIsSuper(tdb))
- return FALSE;
-return (tdb->visibility != tvHide);
-}
-
-static void groupTracks(struct track **pTrackList, struct group **pGroupList,
- int vis)
-/* Make up groups and assign tracks to groups.
- * If vis is -1, restore default groups to tracks. */
-{
-struct group *unknown = NULL;
-struct group *group, *list = NULL;
-struct hash *hash = newHash(8);
-struct track *track;
-struct trackRef *tr;
-struct grp* grps = hLoadGrps(database);
-struct grp *grp;
-
-/* build group objects from database. */
-for (grp = grps; grp != NULL; grp = grp->next)
- {
- /* deal with group reordering */
- float priority = grp->priority;
- if (withPriorityOverride)
- {
- char cartVar[512];
- safef(cartVar, sizeof(cartVar), "%s.priority",grp->name);
- if (vis != -1)
- priority = (float)cartUsualDouble(cart, cartVar, grp->priority);
- if (priority == grp->priority)
- cartRemove(cart, cartVar);
- }
- /* create group object; add to list and hash */
- AllocVar(group);
- group->name = cloneString(grp->name);
- group->label = cloneString(grp->label);
- group->defaultPriority = grp->priority;
- group->priority = priority;
- group->defaultIsClosed = grp->defaultIsClosed;
- slAddHead(&list, group);
- hashAdd(hash, grp->name, group);
- }
-grpFreeList(&grps);
-
-/* Loop through tracks and fill in their groups.
- * If necessary make up an unknown group. */
-for (track = *pTrackList; track != NULL; track = track->next)
- {
- /* handle track reordering feature -- change group assigned to track */
- if (withPriorityOverride)
- {
- char *groupName = NULL;
- char cartVar[256];
-
- /* belt and suspenders -- accomodate inconsistent track/trackDb
- * creation. Note -- with code cleanup, these default variables
- * could be retired, and the tdb versions used as defaults */
- if (!track->defaultGroupName)
- {
- if (track->tdb && track->tdb->grp)
- track->defaultGroupName = cloneString(track->tdb->grp);
- else
- track->defaultGroupName = cloneString("other");
- }
- if (tdbIsSuperTrackChild(track->tdb))
- {
- assert(track->tdb->parentName != NULL);
- /* supertrack member must be in same group as its super */
- /* determine supertrack group */
- safef(cartVar, sizeof(cartVar), "%s.group",track->tdb->parentName);
- groupName = cloneString( //1
- cartUsualString(cart, cartVar, track->tdb->parent->grp));
- track->tdb->parent->grp = cloneString(groupName); //2
- }
- else
- {
- /* get group */
- safef(cartVar, sizeof(cartVar), "%s.group",track->track);
- groupName = cloneString( //1
- cartUsualString(cart, cartVar, track->defaultGroupName));
- }
- if (vis == -1)
- groupName = track->defaultGroupName; //0
- track->groupName = cloneString(groupName); // wasting a few clones! //3
- if (sameString(groupName, track->defaultGroupName))
- cartRemove(cart, cartVar);
-
- /* get priority */
- safef(cartVar, sizeof(cartVar), "%s.priority",track->track);
- float priority = (float)cartUsualDouble(cart, cartVar,
- track->defaultPriority);
- /* remove cart variables that are the same as the trackDb settings */
-/* UGLY - add me back when tdb->priority is no longer pre-clobbered by cart var value
- if (priority == track->defaultPriority)
- cartRemove(cart, cartVar);
-*/
- track->priority = priority;
- }
-
- /* assign group object to track */
- if (track->groupName == NULL)
- group = NULL;
- else
- group = hashFindVal(hash, track->groupName);
- if (group == NULL)
- {
- if (unknown == NULL)
- {
- AllocVar(unknown);
- unknown->name = cloneString("other");
- unknown->label = cloneString("other");
- unknown->priority = 1000000;
- slAddHead(&list, unknown);
- }
- group = unknown;
- }
- track->group = group;
- }
-
-/* Sort tracks by combined group/track priority, and
- * then add references to track to group. */
-slSort(pTrackList, tgCmpPriority);
-for (track = *pTrackList; track != NULL; track = track->next)
- {
- AllocVar(tr);
- tr->track = track;
- slAddHead(&track->group->trackList, tr);
- }
-
-/* Straighten things out, clean up, and go home. */
-for (group = list; group != NULL; group = group->next)
- slReverse(&group->trackList);
-slSort(&list, gCmpPriority);
-hashFree(&hash);
-*pGroupList = list;
-}
-
-void groupTrackListAddSuper(struct cart *cart, struct group *group)
-/* Construct a new track list that includes supertracks, sort by priority,
- * and determine if supertracks have visible members.
- * Replace the group track list with this new list.
- * Shared by hgTracks and configure page to expand track list,
- * in contexts where no track display functions (which don't understand
- * supertracks) are invoked. */
-{
-struct trackRef *newList = NULL, *tr, *ref;
-struct hash *superHash = hashNew(8);
-
-if (!group || !group->trackList)
- return;
-for (tr = group->trackList; tr != NULL; tr = tr->next)
- {
- struct track *track = tr->track;
- AllocVar(ref);
- ref->track = track;
- slAddHead(&newList, ref);
- if (tdbIsSuperTrackChild(track->tdb))
- {
- assert(track->tdb->parentName != NULL);
- if (hTvFromString(cartUsualString(cart, track->track,
- hStringFromTv(track->tdb->visibility))) != tvHide)
- setSuperTrackHasVisibleMembers(track->tdb->parent);
- if (hashLookup(superHash, track->tdb->parentName))
- /* ignore supertrack if it's already been handled */
- continue;
- /* create track and reference for the supertrack */
- struct track *superTrack = trackFromTrackDb(track->tdb->parent);
- superTrack->hasUi = TRUE;
- superTrack->group = group;
- superTrack->groupName = cloneString(group->name);
- superTrack->defaultGroupName = cloneString(group->name);
-
- /* handle track reordering */
- char cartVar[256];
- safef(cartVar, sizeof(cartVar), "%s.priority",track->tdb->parentName);
- float priority = (float)cartUsualDouble(cart, cartVar,
- track->tdb->parent->priority);
- /* remove cart variables that are the same as the trackDb settings */
- if (priority == track->tdb->parent->priority)
- cartRemove(cart, cartVar);
- superTrack->priority = priority;
-
- AllocVar(ref);
- ref->track = superTrack;
- slAddHead(&newList, ref);
- hashAdd(superHash, track->tdb->parentName, track->tdb->parent);
- }
- }
-slSort(&newList, trackRefCmpPriority);
-hashFree(&superHash);
-/* we could free the old track list here, but it's a trivial amount of mem */
-group->trackList = newList;
-}
-
-void topButton(char *var, char *label)
-/* create a 3 or 4-char wide button for top line of display.
- * 3 chars wide for odd-length labels, 4 for even length.
- * Pad with spaces so label is centered */
-{
-char paddedLabel[5] = " ";
-int len = strlen(label);
-if (len > 4)
- {
- /* truncate */
- /* or maybe errabort ? */
- label[3] = 0;
- len = 4;
- }
-if (len % 2 != 0)
- paddedLabel[3] = 0;
-if (len == strlen(paddedLabel))
- strcpy(paddedLabel, label);
-else
- {
- int i;
- for (i=0; itdb))
- {
- assert(track->tdb->parent != NULL);
- if (sameString("hide", cartUsualString(cart, track->tdb->parent->track,
- track->tdb->parent->isShow ? "show" : "hide")))
- track->visibility = tvHide;
- }
-}
-
-struct track *rFindTrackWithTable(char *tableName, struct track *trackList)
-/* Recursively search through track list looking for first one that matches table. */
-{
-struct track *track;
-for (track = trackList; track != NULL; track = track->next)
- {
- if (sameString(tableName, track->table))
- return track;
- struct track *subTrack = rFindTrackWithTable(tableName, track->subtracks);
- if (subTrack != NULL)
- return subTrack;
- }
-return NULL;
-}
-
-static void setSearchedTrackToPackOrFull(struct track *trackList)
-/* Open track associated with search position if any. Also open its parents
- * if any. At the moment parents include composites but not supertracks. */
-{
-if (NULL != hgp && NULL != hgp->tableList && NULL != hgp->tableList->name)
- {
- char *tableName = hgp->tableList->name;
- struct track *matchTrack = rFindTrackWithTable(tableName, trackList);
- if (matchTrack != NULL)
- {
- struct track *track;
- for (track = matchTrack; track != NULL; track = track->parent)
- cartSetString(cart, track->track, hCarefulTrackOpenVis(database, track->track));
- }
- }
-}
-
-
-struct track *getTrackList( struct group **pGroupList, int vis)
-/* Return list of all tracks, organizing by groups.
- * If vis is -1, restore default groups to tracks.
- * Shared by hgTracks and configure page. */
-{
-struct track *track, *trackList = NULL;
-registerTrackHandlers();
-/* Load regular tracks, blatted tracks, and custom tracks.
- * Best to load custom last. */
-loadFromTrackDb(&trackList);
-if (pcrResultParseCart(database, cart, NULL, NULL, NULL))
- slSafeAddHead(&trackList, pcrResultTg());
-if (userSeqString != NULL) slSafeAddHead(&trackList, userPslTg());
-slSafeAddHead(&trackList, oligoMatchTg());
-if (restrictionEnzymesOk())
- {
- slSafeAddHead(&trackList, cuttersTg());
- }
-if (wikiTrackEnabled(database, NULL))
- addWikiTrack(&trackList);
-#ifdef SOON
-loadDataHubs(&trackList);
-#endif /* SOON */
-loadCustomTracks(&trackList);
-groupTracks(&trackList, pGroupList, vis);
-setSearchedTrackToPackOrFull(trackList);
-if (cgiOptionalString( "hideTracks"))
- changeTrackVis(groupList, NULL, tvHide);
-
-/* Get visibility values if any from ui. */
-for (track = trackList; track != NULL; track = track->next)
- {
- char *s = cartOptionalString(cart, track->track);
- if (cgiOptionalString("hideTracks"))
- {
- s = cgiOptionalString(track->track);
- if (s != NULL && (hTvFromString(s) != track->tdb->visibility))
- {
- cartSetString(cart, track->track, s);
- }
- }
- if (s != NULL && !track->limitedVisSet)
- track->visibility = hTvFromString(s);
- if (tdbIsComposite(track->tdb) && track->visibility != tvHide)
- {
- struct trackDb *parent = track->tdb->parent;
- char *parentShow = NULL;
- if (parent)
- parentShow = cartUsualString(cart, parent->track,
- parent->isShow ? "show" : "hide");
- if (!parent || sameString(parentShow, "show"))
- compositeTrackVis(track);
- }
- }
-if (measureTiming)
- uglyTime("getTrackList");
-return trackList;
-}
-
-void doNextPrevItem(boolean goNext, char *trackName)
-/* In case a next item arrow was clicked on a track, change */
-/* position (i.e. winStart, winEnd, etc.) based on what track it was */
-{
-struct track *track = trackFindByName(trackList, trackName);
-if ((track != NULL) && (track->nextPrevItem != NULL))
- track->nextPrevItem(track, goNext);
-}
-
-char *collapseGroupVar(char *name)
-/* Construct cart variable name for collapsing group */
-{
-static char varName[256];
-safef(varName, sizeof(varName),
- "%s%s_%s_%s", "hgt", "group", name, "close");
-return (cloneString(varName));
-}
-
-boolean isCollapsedGroup(struct group *grp)
-/* Determine if group is collapsed */
-{
-return cartUsualInt(cart, collapseGroupVar(grp->name), grp->defaultIsClosed);
-}
-
-void collapseGroupGoodies(boolean isOpen, boolean wantSmallImage,
- char **img, char **indicator, char **otherState)
-/* Get image, char representation of image, and 'otherState' (1 or 0)
- * for a group, based on whether it is collapsed, and whether we want
- * larger or smaller image for collapse box */
-{
-if (otherState)
- *otherState = (isOpen ? "1" : "0");
-if (indicator)
- *indicator = (isOpen ? "-" : "+");
-if (img)
- {
- if (wantSmallImage)
- *img = (isOpen ? "../images/remove_sm.gif" : "../images/add_sm.gif");
- else
- *img = (isOpen ? "../images/remove.gif" : "../images/add.gif");
- }
-}
-
-void collapseGroup(char *name, boolean doCollapse)
-/* Set cart variable to cause group to collapse */
-{
-cartSetBoolean(cart, collapseGroupVar(name), doCollapse);
-}
-
-void myControlGridStartCell(struct controlGrid *cg, boolean isOpen, char *id)
-/* Start a new cell in control grid; support Javascript open/collapsing by including id's in tr's.
- id is used as id prefix (a counter is added to make id's unique). */
-{
-static int counter = 1;
-if (cg->columnIx == cg->columns)
- controlGridEndRow(cg);
-if (!cg->rowOpen)
- {
-#if 0
- /* This is unnecessary, b/c we can just use a blank display attribute to show the element rather
- than figuring out what the browser specific string is to turn on display of the tr;
- however, we may want to put in browser specific strings in the future, so I'm leaving this
- code in as a reference. */
- char *ua = getenv("HTTP_USER_AGENT");
- char *display = ua && stringIn("MSIE", ua) ? "block" : "table-row";
-#endif
- // use counter to ensure unique tr id's (prefix is used to find tr's in javascript).
- printf("", isOpen ? "" : "style='display: none' ", id, counter++);
- cg->rowOpen = TRUE;
- }
-if (cg->align)
- printf("", cg->align);
-else
- printf(" ");
-}
-
-static void pruneRedundantCartVis(struct track *trackList)
-/* When the config page or track form has been submitted, there usually
- * are many track visibility cart variables that have not been changed
- * from the default. To keep down cart bloat, prune those out before we
- * save the cart. changeTrackVis does this too, but this is for the
- * more common case where track visibilities are tweaked. */
-{
-struct track *track;
-if (measureTiming)
- uglyTime("Done with trackForm");
-for (track = trackList; track != NULL; track = track->next)
- {
- char *cartVis = cartOptionalString(cart, track->track);
- if (cartVis != NULL && hTvFromString(cartVis) == track->tdb->visibility)
- cartRemove(cart, track->track);
- }
-if (measureTiming)
- {
- uglyTime("Pruned redundant vis from cart");
- }
-}
-
-static int getMaxWindowToDraw(struct trackDb *tdb)
-/* If trackDb setting maxWindowToDraw exists and is a sensible size, return it, else 0. */
-{
-if (tdb == NULL)
- return 0;
-char *maxWinToDraw = trackDbSettingClosestToHome(tdb, "maxWindowToDraw");
-if (isNotEmpty(maxWinToDraw))
- {
- unsigned maxWTD = sqlUnsigned(maxWinToDraw);
- if (maxWTD > 1)
- return maxWTD;
- }
-return 0;
-}
-
-static void drawMaxWindowWarning(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg,
- int xOff, int yOff, int width, MgFont *font, Color color,
- enum trackVisibility vis)
-/* This is a stub drawItems handler to be swapped in for the usual drawItems when the window
- * size is larger than the threshold specified by trackDb setting maxWindowToDraw. */
-{
-int maxWinToDraw = getMaxWindowToDraw(tg->tdb);
-char commafied[256];
-sprintLongWithCommas(commafied, maxWinToDraw);
-char message[512];
-safef(message, sizeof(message), "zoom in to <= %s bases to view items", commafied);
-Color yellow = hvGfxFindRgb(hvg, &undefinedYellowColor);
-hvGfxBox(hvg, xOff, yOff, width, tg->heightPer, yellow);
-hvGfxTextCentered(hvg, xOff, yOff, width, tg->heightPer, MG_BLACK, font, message);
-}
-
-static void dontLoadItems(struct track *tg)
-/* No-op loadItems when we aren't going to try. */
-{
-}
-
-static void checkMaxWindowToDraw(struct track *tg)
-/* If (winEnd - winStart) > trackDb setting maxWindowToDraw, force track to a dense line
- * that will ask the user to zoom in closer to see track items and return TRUE so caller
- * can skip loading items. */
-{
-int maxWinToDraw = getMaxWindowToDraw(tg->tdb);
-if (tdbIsComposite(tg->tdb))
- {
- struct track *subtrack;
- for (subtrack = tg->subtracks; subtrack != NULL; subtrack = subtrack->next)
- {
- if (!isSubtrackVisible(subtrack))
- continue;
- maxWinToDraw = getMaxWindowToDraw(subtrack->tdb);
- if (maxWinToDraw > 1 && (winEnd - winStart) > maxWinToDraw)
- {
- subtrack->loadItems = dontLoadItems;
- subtrack->drawItems = drawMaxWindowWarning;
- subtrack->limitedVis = tvDense;
- subtrack->limitedVisSet = TRUE;
- }
- }
- }
-else if (maxWinToDraw > 1 && (winEnd - winStart) > maxWinToDraw)
- {
- tg->loadItems = dontLoadItems;
- tg->drawItems = drawMaxWindowWarning;
- tg->limitedVis = tvDense;
- tg->limitedVisSet = TRUE;
- }
-}
-
-void printTrackInitJavascript(struct track *trackList)
-{
-hPrintf(" \n", hgtJsCommand, hgtJsCommand);
-hPrintf("\n");
-}
-
-void jsCommandDispatch(char *command, struct track *trackList)
-/* Dispatch a command sent to us from some javaScript event.
- * This gets executed after the track list is built, but before
- * the track->loadItems methods are called. */
-{
-if (startsWithWord("makeItems", command))
- makeItemsJsCommand(command, trackList, trackHash);
-else
- warn("Unrecognized jsCommand %s", command);
-}
-
-#ifdef SUBTRACKS_HAVE_VIS
-static void parentChildCartCleanup(struct track *trackList,struct cart *newCart,struct hash *oldVars)
-/* When composite/view settings changes, remove subtrack specific vis
- When superTrackChild is found and selected, shape superTrack to match. */
-{
-struct track *track = trackList;
-for (;track != NULL; track = track->next)
- {
- if (tdbIsMultiTrack(track->tdb))
- if(cartTdbTreeMatchSubtrackVis(cart,track->tdb)) // Note, this is done for found multi-track kids but composites are only straightened up in hgTrackUi
- track->visibility = tdbVisLimitedByAncestry(cart,track->tdb,FALSE);
-
- if (cartTdbTreeCleanupOverrides(track->tdb,newCart,oldVars))
- { // Need to update track visibility
- if (tdbIsSuperTrackChild(track->tdb))
- {
- // Unfortunately, since supertracks are not in trackList, this occurs on superChildren,
- // So now we need to find the supertrack and take changed cart values of its children
- struct slRef *childRef;
- for(childRef = track->tdb->parent->children;childRef != NULL;childRef = childRef->next)
- {
- struct trackDb * childTdb = childRef->val;
- struct track *child = hashFindVal(trackHash, childTdb->track);
- char *cartVis = cartOptionalString(cart,child->track);
- if (cartVis)
- child->visibility = hTvFromString(cartVis);
- }
- }
- }
- }
-}
-#endif///def SUBTRACKS_HAVE_VIS
-
-void doTrackForm(char *psOutput, struct tempName *ideoTn)
-/* Make the tracks display form with the zoom/scroll buttons and the active
- * image. If the ideoTn parameter is not NULL, it is filled in if the
- * ideogram is created. */
-{
-struct group *group;
-struct track *track;
-char *freezeName = NULL;
-boolean hideAll = cgiVarExists("hgt.hideAll");
-boolean defaultTracks = cgiVarExists("hgt.reset");
-boolean showedRuler = FALSE;
-boolean showTrackControls = cartUsualBoolean(cart, "trackControlsOnMain", TRUE);
-long thisTime = 0, lastTime = 0;
-char *clearButtonJavascript;
-
-basesPerPixel = ((float)winBaseCount) / ((float)insideWidth);
-zoomedToBaseLevel = (winBaseCount <= insideWidth / tl.mWidth);
-zoomedToCodonLevel = (ceil(winBaseCount/3) * tl.mWidth) <= insideWidth;
-zoomedToCdsColorLevel = (winBaseCount <= insideWidth*3);
-
-if (psOutput != NULL)
- {
- hPrintDisable();
- hideControls = TRUE;
- withNextItemArrows = FALSE;
- withNextExonArrows = FALSE;
- hgFindMatches = NULL;
- }
-
-/* Tell browser where to go when they click on image. */
-hPrintf("