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.fxit src/hg/hgTracks/hgTracks.c.fxit deleted file mode 100644 index a96ef4e..0000000 --- src/hg/hgTracks/hgTracks.c.fxit +++ /dev/null @@ -1,5631 +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("<AREA SHAPE=RECT COORDS=\"%d,%d,%d,%d\" ", x, y, x+width, y+height); - hPrintf("HREF=\"%s\"", url); - mapStatusMessage("%s controls", shortLabel); - 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("<AREA SHAPE=RECT COORDS=\"%d,%d,%d,%d\" ", x, y, x+width, y+height); - hPrintf("HREF=\"%s?complement_%s=%d", - hgTracksName(), database, !cartUsualBooleanDb(cart, database, COMPLEMENT_BASES_VAR, FALSE)); - hPrintf("&%s\"", ui->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("<FONT SIZE=1><BR></FONT>\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("<MAP Name=%s>\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("</MAP>\n"); - } -hPrintf("<TABLE BORDER=0 CELLPADDING=0>"); -if (doIdeo && !psOutput) - { - hPrintf("<TR><TD HEIGHT=5></TD></TR>"); - hPrintf("<TR><TD><IMG SRC = \"%s\" BORDER=1 WIDTH=%d HEIGHT=%d USEMAP=#%s id='chrom'>", - ideoTn->forHtml, ideoWidth, ideoHeight, mapName); - hPrintf("</TD></TR>"); - hPrintf("<TR><TD HEIGHT=5></TD></TR></TABLE>\n"); - } -else - hPrintf("<TR><TD HEIGHT=10></TD></TR></TABLE>\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 = trackDbCompositeParent(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("<input type='hidden' name='db' value='%s'>\n", database); - hPrintf("<input type='hidden' name='c' value='%s'>\n", chromName); - hPrintf("<input type='hidden' name='l' value='%d'>\n", winStart); - hPrintf("<input type='hidden' name='r' value='%d'>\n", winEnd); - hPrintf("<input type='hidden' name='pix' value='%d'>\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',<BR>remaining tracks set to hide " - "for this view.<BR>\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',<BR>remaining tracks set to hide " - "for this view.<BR>\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("<MAP id='map' Name=%s>\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 = trackDbCompositeParent(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; x<pixWidth; x += guidelineSpacing) - hvGfxBox(bgImg, x, y, 1, height, lightBlue); - hvGfxUnclip(bgImg); - if(bgImg != hvg) - hvGfxClose(&bgImg); - } - -/* Show ruler at top. */ -if (rulerMode != tvHide) - { - if(theImgBox) - { - // data slice for ruler - sliceHeight = basePositionHeight + (rulerCds ? rulerTranslationHeight : 0) + 1; - sliceOffsetY = 0; - curImgTrack = imgBoxTrackFind(theImgBox,NULL,RULER_TRACK_NAME); - curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stData,theOneImg,rulerTtl,sliceWidth[stData],sliceHeight,sliceOffsetX[stData],sliceOffsetY); - curMap = sliceMapFindOrStart(curSlice,RULER_TRACK_NAME,NULL); // No common linkRoot - } - y = doDrawRuler(hvg,&newWinWidth,&rulerClickHeight,rulerHeight,yAfterRuler,yAfterBases,font,fontHeight,rulerCds); - } - -/* Draw center labels. */ -if (withCenterLabels) - { - hvGfxSetClip(hvg, insideX, gfxBorder, insideWidth, pixHeight - 2*gfxBorder); - y = yAfterRuler; - for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next) - { - track = flatTrack->track; - if (track->limitedVis == tvHide) - continue; - - if(theImgBox) - { - // center label slice of tracks Must always make, even if the centerLabel is empty - sliceHeight = fontHeight; - sliceOffsetY = y; - curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL); - curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stCenter,theOneImg,NULL,sliceWidth[stData],sliceHeight,sliceOffsetX[stData],sliceOffsetY); - 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("</MAP>\n"); - -hPrintf("<input type='hidden' id='hgt.dragSelection' name='dragSelection' value='%d'>\n", dragZooming ? 1 : 0); -if(rulerClickHeight) - { - hPrintf("<input type='hidden' id='hgt.rulerClickHeight' name='rulerClickHeight' value='%d'>\n", rulerClickHeight); - } -if(newWinWidth) - { - hPrintf("<input type='hidden' id='hgt.newWinWidth' name='newWinWidth' value='%d'>\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("<IMG SRC='%s' BORDER=1 WIDTH=%d HEIGHT=%d USEMAP=#%s %s id='trackMap'", - gifTn.forHtml, pixWidth, pixHeight, mapName, titleAttr); - hPrintf("><BR>\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("<A HREF=\"%s\" TARGET=_blank class=\"topbar\">", 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 - { - 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; i<wordCount; ++i) - { - char *s = words[i]; - struct track *tg; - boolean toAll = sameWord(s, "all"); - for (tg = *pTrackList; tg != NULL; tg = tg->next) - { - 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<hubCount; ++i) - { - addTracksFromDataHub(hubArrays[i], pTrackList); - } -} - -boolean restrictionEnzymesOk() -/* Check to see if it's OK to do restriction enzymes. */ -{ -return (hTableExists("hgFixed", "cutters") && - hTableExists("hgFixed", "rebaseRefs") && - hTableExists("hgFixed", "rebaseCompanies")); -} - -void fr2ScaffoldEnsemblLink(char *archive) -/* print out Ensembl link to appropriate scaffold there */ -{ -struct sqlConnection *conn = hAllocConn(database); -struct sqlResult *sr = NULL; -char **row = NULL; -char query[256]; -safef(query, sizeof(query), -"select * from chrUn_gold where chrom = '%s' and chromStart<%u and chromEnd>%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("<TD ALIGN=CENTER>"); - printEnsemblAnchor(database, archive, agpItem->frag, - agpStart, agpEnd); - hPrintf("%s</A></TD>", "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("<TABLE WIDTH=\"100%%\" BGCOLOR=\"#000000\" BORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"1\"><TR><TD>\n"); -hPrintf("<TABLE WIDTH=\"100%%\" BGCOLOR=\"#2636D1\" BORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\"><TR>\n"); -hPrintf("<TD><TABLE BORDER=\"0\"><TR>\n"); -hPrintf("<TD ALIGN=CENTER><A HREF=\"../index.html?org=%s&db=%s&%s=%u\" class=\"topbar\">Home</A> </TD>", - orgEnc, database, cartSessionVarName(), cartSessionId(cart)); - -if (hIsGisaidServer()) - { - /* disable hgGateway for gisaid for now */ - //hPrintf("<TD ALIGN=CENTER> <A HREF=\"../cgi-bin/hgGateway?org=%s&db=%s\" class=\"topbar\">Sequence View Gateway</A> </TD>", orgEnc, database); - hPrintf( - "<TD ALIGN=CENTER> <A HREF=\"../cgi-bin/gisaidTable?gisaidTable.do.advFilter=filter+%c28now+on%c29&fromProg=hgTracks&%s=%u\" class=\"topbar\">%s</A> </TD>", - '%', '%', - cartSessionVarName(), - cartSessionId(cart), - "Select Subjects"); - } -else -if (hIsGsidServer()) - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"../cgi-bin/hgGateway?org=%s&db=%s\" class=\"topbar\">Sequence View Gateway</A> </TD>", orgEnc, database); - hPrintf( - "<TD ALIGN=CENTER> <A HREF=\"../cgi-bin/gsidTable?gsidTable.do.advFilter=filter+%c28now+on%c29&fromProg=hgTracks\" class=\"topbar\">%s</A> </TD>", - '%', '%', "Select Subjects"); - } -else - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"../cgi-bin/hgGateway?org=%s&db=%s&%s=%u\" class=\"topbar\">Genomes</A> </TD>", orgEnc, database, cartSessionVarName(), cartSessionId(cart)); - } -if (psOutput) - { - hPrintf("<TD ALIGN=CENTER nowrap> <A HREF=\"../cgi-bin/hgTracks?hgTracksConfigPage=notSetorg=%s&db=%s&%s=%u\" class='topbar'>Genome Browser</A> </TD>", orgEnc, database, cartSessionVarName(), cartSessionId(cart)); - } -if (gotBlat) - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"../cgi-bin/hgBlat?%s\" class=\"topbar\">Blat</A> </TD>", uiVars->string); - } -if (hIsGisaidServer()) - { - hPrintf("<TD ALIGN=CENTER nowrap> <A HREF=\"../cgi-bin/gisaidTable?db=%s&%s=%u\" class=\"topbar\">%s</A> </TD>", - database, - cartSessionVarName(), - cartSessionId(cart), - "Table View"); - } -else if (hIsGsidServer()) - { - hPrintf("<TD ALIGN=CENTER nowrap> <A HREF=\"../cgi-bin/gsidTable?db=%s\" class=\"topbar\">%s</A> </TD>", - database, "Table View"); - } -else - { - /* disable TB for CGB servers */ - if (!hIsCgbServer()) - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"../cgi-bin/hgTables?db=%s&position=%s:%d-%d&%s=%u\" class=\"topbar\">%s</A> </TD>", - database, chromName, winStart+1, winEnd, - cartSessionVarName(), - cartSessionId(cart), - "Tables"); - } - } - -if (hgNearOk(database)) - { - hPrintf("<TD ALIGN=CENTER nowrap> <A HREF=\"../cgi-bin/hgNear?%s\" class=\"topbar\">%s</A> </TD>", - uiVars->string, "Gene Sorter"); - } -if (hgPcrOk(database)) - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"../cgi-bin/hgPcr?%s\" class=\"topbar\">PCR</A> </TD>", uiVars->string); - } -if (!psOutput) - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"%s&o=%d&g=getDna&i=mixed&c=%s&l=%d&r=%d&db=%s&%s\" class=\"topbar\">" - " %s </A> </TD>", 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("<TD ALIGN=CENTER> <A HREF=\""); - hPrintf("../cgi-bin/hgConvert?%s&db=%s&position=%s:%d-%d", - uiVars->string, database, chromName, winStart+1, winEnd); - hPrintf("\" class=\"topbar\">Convert</A> </TD>"); - } - } - -/* 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("<TD ALIGN=CENTER> "); - printEnsemblAnchor(database, NULL, chromName, winStart, winEnd); - hPrintf("%s</A> </TD>", "Ensembl"); - } - else if (sameWord(database,"hg18")) - { - hPrintf("<TD ALIGN=CENTER> "); - printEnsemblAnchor(database, "ncbi36", chromName, winStart, winEnd); - hPrintf("%s</A> </TD>", "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("<TD ALIGN=CENTER> "); - printEnsemblAnchor(database, archive, ctgItem->contig, - ctgStart, ctgEnd); - hPrintf("%s</A> </TD>", "Ensembl"); - } - } - ctgPosFree(&ctgItem); // the one we maybe used - } - } - else - { - hPrintf("<TD ALIGN=CENTER> "); - printEnsemblAnchor(database, archive, chromName, winStart, winEnd); - hPrintf("%s</A> </TD>", "Ensembl"); - } - } - } - } - -if (!psOutput) - { - /* Print NCBI MapView anchor */ - if (sameString(database, "hg18")) - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"http://www.ncbi.nlm.nih.gov/mapview/maps.cgi?taxid=9606&CHR=%s&BEG=%d&END=%d&build=36\" TARGET=_blank class=\"topbar\">", - skipChr(chromName), winStart+1, winEnd); - hPrintf("%s</A> </TD>", "NCBI"); - } - if (sameString(database, "hg19")) - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"http://www.ncbi.nlm.nih.gov/mapview/maps.cgi?taxid=9606&CHR=%s&BEG=%d&END=%d&build=37\" TARGET=_blank class=\"topbar\">", - skipChr(chromName), winStart+1, winEnd); - hPrintf("%s</A> </TD>", "NCBI"); - } - if (sameString(database, "mm8")) - { - hPrintf("<TD ALIGN=CENTER>"); - hPrintf("<A HREF=\"http://www.ncbi.nlm.nih.gov/mapview/maps.cgi?taxid=10090&CHR=%s&BEG=%d&END=%d\" TARGET=_blank class=\"topbar\">", - skipChr(chromName), winStart+1, winEnd); - hPrintf("%s</A> </TD>", "NCBI"); - } - if (sameString(database, "danRer2")) - { - hPrintf("<TD ALIGN=CENTER>"); - hPrintf("<A HREF=\"http://www.ncbi.nlm.nih.gov/mapview/maps.cgi?taxid=7955&CHR=%s&BEG=%d&END=%d\" TARGET=_blank class=\"topbar\">", - skipChr(chromName), winStart+1, winEnd); - hPrintf("%s</A> </TD>", "NCBI"); - } - if (sameString(database, "galGal3")) - { - hPrintf("<TD ALIGN=CENTER>"); - hPrintf("<A HREF=\"http://www.ncbi.nlm.nih.gov/mapview/maps.cgi?taxid=9031&CHR=%s&BEG=%d&END=%d\" TARGET=_blank class=\"topbar\">", - skipChr(chromName), winStart+1, winEnd); - hPrintf("%s</A> </TD>", "NCBI"); - } - if (sameString(database, "canFam2")) - { - hPrintf("<TD ALIGN=CENTER>"); - hPrintf("<A HREF=\"http://www.ncbi.nlm.nih.gov/mapview/maps.cgi?taxid=9615&CHR=%s&BEG=%d&END=%d\" TARGET=_blank class=\"topbar\">", - skipChr(chromName), winStart+1, winEnd); - hPrintf("%s</A> </TD>", "NCBI"); - } - if (sameString(database, "rheMac2")) - { - hPrintf("<TD ALIGN=CENTER>"); - hPrintf("<A HREF=\"http://www.ncbi.nlm.nih.gov/mapview/maps.cgi?taxid=9544&CHR=%s&BEG=%d&END=%d\" TARGET=_blank class=\"topbar\">", - skipChr(chromName), winStart+1, winEnd); - hPrintf("%s</A> </TD>", "NCBI"); - } - if (sameString(database, "panTro2")) - { - hPrintf("<TD ALIGN=CENTER>"); - hPrintf("<A HREF=\"http://www.ncbi.nlm.nih.gov/mapview/maps.cgi?taxid=9598&CHR=%s&BEG=%d&END=%d\" TARGET=_blank class=\"topbar\">", - skipChr(chromName), winStart+1, winEnd); - hPrintf("%s</A> </TD>", "NCBI"); - } - if (sameString(database, "anoGam1")) - { - hPrintf("<TD ALIGN=CENTER>"); - hPrintf("<A HREF=\"http://www.ncbi.nlm.nih.gov/mapview/maps.cgi?taxid=7165&CHR=%s&BEG=%d&END=%d\" TARGET=_blank class=\"topbar\">", - skipChr(chromName), winStart+1, winEnd); - hPrintf("%s</A> </TD>", "NCBI"); - } - if (startsWith("oryLat", database)) - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"http://medaka.utgenome.org/browser_ens_jump.php?revision=version1.0&chr=chromosome%s&start=%d&end=%d\" TARGET=_blank class=\"topbar\">%s</A> </TD>", - skipChr(chromName), winStart+1, winEnd, "UTGB"); - } - if (sameString(database, "cb3")) - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"http://www.wormbase.org/db/seq/gbrowse/briggsae?name=%s:%d-%d\" TARGET=_blank class=\"topbar\">%s</A> </TD>", - skipChr(chromName), winStart+1, winEnd, "WormBase"); - } - if (sameString(database, "ce4")) - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"http://ws170.wormbase.org/db/seq/gbrowse/wormbase?name=%s:%d-%d\" TARGET=_blank class=\"topbar\">%s</A> </TD>", - skipChr(chromName), winStart+1, winEnd, "WormBase"); - } - if (sameString(database, "ce2")) - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"http://ws120.wormbase.org/db/seq/gbrowse/wormbase?name=%s:%d-%d\" TARGET=_blank class=\"topbar\">%s</A> </TD>", - skipChr(chromName), winStart+1, winEnd, "WormBase"); - } - } - -if (!psOutput) - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"../cgi-bin/hgTracks?%s=%u&hgt.psOutput=on\" id='pdfLink' class=\"topbar\">%s</A> </TD>",cartSessionVarName(), - cartSessionId(cart), "PDF/PS"); - } - -if (!psOutput) - { - if (wikiLinkEnabled()) - { - printf("<TD ALIGN=CENTER> <A HREF=\"../cgi-bin/hgSession?%s=%u" - "&hgS_doMainPage=1\" class=\"topbar\">Session</A> </TD>", - cartSessionVarName(), cartSessionId(cart)); - } - } -if (hIsGisaidServer()) - { - //hPrintf("<TD ALIGN=CENTER> <A HREF=\"/goldenPath/help/gisaidTutorial.html#SequenceView\" TARGET=_blank class=\"topbar\">%s</A> </TD>\n", "Help"); - hPrintf("<TD ALIGN=CENTER> <A HREF=\"../cgi-bin/hgNotYet\" TARGET=_blank class=\"topbar\">%s</A> </TD>\n", "Help"); - } -else -if (hIsGsidServer()) - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"/goldenPath/help/gsidTutorial.html#SequenceView\" TARGET=_blank class=\"topbar\">%s</A> </TD>\n", "Help"); - } -else - { - hPrintf("<TD ALIGN=CENTER> <A HREF=\"../goldenPath/help/hgTracksHelp.html\" TARGET=_blank class=\"topbar\">%s</A> </TD>\n", "Help"); - } -hPuts("<TD colspan=20> </TD></TR></TABLE></TD>"); -hPuts("</TR></TABLE>"); -hPuts("</TD></TR></TABLE>\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; i<len; i++) - paddedLabel[i+1] = label[i]; - } -hButton(var, paddedLabel); -} - -void limitSuperTrackVis(struct track *track) -/* Limit track visibility by supertrack parent */ -{ -if(tdbIsSuperTrackChild(track->tdb)) - { - 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("<tr %sid='%s-%d'>", isOpen ? "" : "style='display: none' ", id, counter++); - cg->rowOpen = TRUE; - } -if (cg->align) - printf("<td align=%s>", cg->align); -else - printf("<td>"); -} - -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("<input type='hidden' id='%s' name='%s' value=''>\n", hgtJsCommand, hgtJsCommand); -hPrintf("<script type='text/javascript'>\n"); -hPrintf( "function hgTracksInitTracks()\n{\n"); - -struct track *track; -for (track = trackList; track != NULL; track = track->next) - { - if (startsWithWord("makeItems", track->tdb->type) ) - hPrintf("setUpMakeItemsDrag(\"%s\");\n", track->track); - } - -hPrintf( "}\n"); -hPrintf("</script>\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 (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("<FORM ACTION=\"%s\" NAME=\"TrackHeaderForm\" id=\"TrackHeaderForm\" METHOD=\"GET\">\n\n", hgTracksName()); -hPrintf("<input type='hidden' id='hgt.insideX' name='insideX' value='%d'>\n", insideX); -hPrintf("<input type='hidden' id='hgt.revCmplDisp' name='revCmplDisp' value='%d'>\n", revCmplDisp); -if (!psOutput) cartSaveSession(cart); -clearButtonJavascript = "document.TrackHeaderForm.position.value=''; document.getElementById('suggest').value='';"; - -/* See if want to include sequence search results. */ -userSeqString = cartOptionalString(cart, "ss"); -if (userSeqString && !ssFilesExist(userSeqString)) - { - userSeqString = NULL; - cartRemove(cart, "ss"); - } -if (!hideControls) - hideControls = cartUsualBoolean(cart, "hideControls", FALSE); -if (measureTiming) - uglyTime("Time before getTrackList"); -trackList = getTrackList(&groupList, defaultTracks ? -1 : -2); -makeGlobalTrackHash(trackList); -#ifdef SOON -if (measureTiming) - uglyTime("getTrackList"); -#endif /* SOON */ - -// honor defaultImgOrder -if(cgiVarExists("hgt.defaultImgOrder")) - { - char wildCard[32]; - safef(wildCard,sizeof(wildCard),"*_%s",IMG_ORDER_VAR); - cartRemoveLike(cart, wildCard); - } -#ifdef SUBTRACKS_HAVE_VIS -parentChildCartCleanup(trackList,cart,oldVars); // Subtrack settings must be removed when composite/view settings are updated -#endif///def SUBTRACKS_HAVE_VIS - -/* Honor hideAll and visAll variables */ -if (hideAll || defaultTracks) - { - int vis = (hideAll ? tvHide : -1); - changeTrackVis(groupList, NULL, vis); - } - -/* Before loading items, deal with the next/prev item arrow buttons if pressed. */ -if (cgiVarExists("hgt.nextItem")) - doNextPrevItem(TRUE, cgiUsualString("hgt.nextItem", NULL)); -else if (cgiVarExists("hgt.prevItem")) - doNextPrevItem(FALSE, cgiUsualString("hgt.prevItem", NULL)); - -if(advancedJavascriptFeaturesEnabled(cart) && !psOutput && !cgiVarExists("hgt.imageV1")) - { - // Start an imagebox (global for now to avoid huge rewrite of hgTracks) - // Set up imgBox dimensions - int sideSliceWidth = 0; // Just being explicit - if (withLeftLabels) - sideSliceWidth = (insideX - gfxBorder*3) + 2; - theImgBox = imgBoxStart(database,chromName,winStart,winEnd,(!revCmplDisp),sideSliceWidth,tl.picWidth); - #ifdef IMAGEv2_DRAG_SCROLL - // Define a portal with a default expansion size, then set the global dimensions to the full image size - if(imgBoxPortalDefine(theImgBox,&winStart,&winEnd,&(tl.picWidth),0)) - { - winBaseCount = winEnd - winStart; - insideWidth = tl.picWidth-gfxBorder-insideX; - } - #endif//def IMAGEv2_DRAG_SCROLL - } - -char *jsCommand = cartCgiUsualString(cart, hgtJsCommand, ""); -if (!isEmpty(jsCommand)) - { - cartRemove(cart, hgtJsCommand); - jsCommandDispatch(jsCommand, trackList); - } - -/* Tell tracks to load their items. */ -for (track = trackList; track != NULL; track = track->next) - { - /* adjust track visibility based on supertrack just before load loop */ - if (tdbIsSuperTrackChild(track->tdb)) - limitSuperTrackVis(track); - - /* remove cart priority variables if they are set - to the default values in the trackDb */ - if(!hTrackOnChrom(track->tdb, chromName)) - { - track->limitedVis = tvHide; - track->limitedVisSet = TRUE; - } - else if (track->visibility != tvHide) - { - if (measureTiming) - lastTime = clock1000(); - checkMaxWindowToDraw(track); - track->loadItems(track); - - if (measureTiming) - { - thisTime = clock1000(); - track->loadTime = thisTime - lastTime; - } - } - } - -printTrackInitJavascript(trackList); - -/* Generate two lists of hidden variables for track group visibility. Kludgy, - but required b/c we have two different navigation forms on this page, but - we want open/close changes in the bottom form to be submitted even if the user - submits via the top form. */ -struct dyString *trackGroupsHidden1 = newDyString(1000); -struct dyString *trackGroupsHidden2 = newDyString(1000); -for (group = groupList; group != NULL; group = group->next) - { - if (group->trackList != NULL) - { - int looper; - for(looper=1;looper<=2;looper++) - { - boolean isOpen = !isCollapsedGroup(group); - char buf[1000]; - safef(buf, sizeof(buf), "<input type='hidden' name=\"%s\" id=\"%s_%d\" value=\"%s\">\n", collapseGroupVar(group->name), collapseGroupVar(group->name), looper, isOpen ? "0" : "1"); - dyStringAppend(looper == 1 ? trackGroupsHidden1 : trackGroupsHidden2, buf); - } - } - } - -#ifdef IMAGEv2_DRAG_SCROLL -if(theImgBox) - { - // 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)) - { - winBaseCount = winEnd - winStart; - insideWidth = tl.picWidth-gfxBorder-insideX; - } - } -#endif//def IMAGEv2_DRAG_SCROLL -/* Center everything from now on. */ -hPrintf("<CENTER>\n"); - -if(trackImgOnly) - { - /* Make clickable image and map. */ - makeActiveImage(trackList, psOutput); - fflush(stdout); - // bail out b/c we are done - return; - } - - -if (!hideControls) - { - /* set white-space to nowrap to prevent buttons from wrapping when screen is - * narrow */ - hPrintf("<DIV STYLE=\"white-space:nowrap;\">\n"); - hotLinks(); - - /* Show title . */ - freezeName = hFreezeFromDb(database); - if(freezeName == NULL) - freezeName = "Unknown"; - hPrintf("<FONT SIZE=5><B>"); - if (startsWith("zoo",database) ) - { - hPrintf("%s %s on %s June 2002 Assembly %s target1", - organization, browserName, organism, freezeName); - } - else - { - if (sameString(organism, "Archaea")) - { - hPrintf("%s %s on Archaeon %s Assembly", - organization, browserName, freezeName); - } - else - { - if (stringIn(database, freezeName)) - hPrintf("%s %s on %s %s Assembly", - organization, browserName, organism, freezeName); - else - hPrintf("%s %s on %s %s Assembly (%s)", - organization, browserName, organism, freezeName, database); - } - } - hPrintf("</B></FONT><BR>\n"); - - /* This is a clear submit button that browsers will use by default when enter is pressed in position box. */ - hPrintf("<INPUT TYPE=IMAGE BORDER=0 NAME=\"hgt.dummyEnterButton\" src=\"../images/DOT.gif\">"); - /* Put up scroll and zoom controls. */ -#ifndef USE_NAVIGATION_LINKS - hWrites("move "); - hButtonWithMsg("hgt.left3", "<<<", "move 95% to the left"); - hButtonWithMsg("hgt.left2", " <<", "move 47.5% to the left"); - hButtonWithMsg("hgt.left1", " < ", "move 10% to the left"); - hButtonWithMsg("hgt.right1", " > ", "move 10% to the right"); - hButtonWithMsg("hgt.right2", ">> ", "move 47.5% to the right"); - hButtonWithMsg("hgt.right3", ">>>", "move 95% to the right"); - hWrites(" zoom in "); - /* use button maker that determines padding, so we can share constants */ - topButton("hgt.in1", ZOOM_1PT5X); - topButton("hgt.in2", ZOOM_3X); - topButton("hgt.in3", ZOOM_10X); - topButton("hgt.inBase", ZOOM_BASE); - hWrites(" zoom out "); - topButton("hgt.out1", ZOOM_1PT5X); - topButton("hgt.out2", ZOOM_3X); - topButton("hgt.out3", ZOOM_10X); - hWrites("<BR>\n"); -#endif//ndef USE_NAVIGATION_LINKS - - if (showTrackControls) - { - /* Break into a second form so that zooming and scrolling - * can be done with a 'GET' so that user can back up from details - * page without Internet Explorer popping up an annoying dialog. - * Do rest of page as a 'POST' so that the ultra-long URL from - * all the track controls doesn't break things. IE URL limit - * is 2000 bytes, but some firewalls impose a ~1000 byte limit. - * As a side effect of breaking up the page into two forms - * we need to repeat the position in a hidden variable here - * so that zoom/scrolling always has current position to work - * from. */ - hPrintf("<INPUT TYPE=HIDDEN id='positionHidden' NAME=\"position\" " - "VALUE=\"%s:%d-%d\">", chromName, winStart+1, winEnd); - hPrintf("\n%s", trackGroupsHidden1->string); - hPrintf("</CENTER></FORM>\n"); - hPrintf("<FORM ACTION=\"%s\" NAME=\"TrackForm\" id=\"TrackForm\" METHOD=\"POST\">\n\n", hgTracksName()); - hPrintf("%s", trackGroupsHidden2->string); - freeDyString(&trackGroupsHidden1); - freeDyString(&trackGroupsHidden2); - if (!psOutput) cartSaveSession(cart); /* Put up hgsid= as hidden variable. */ - clearButtonJavascript = "document.TrackForm.position.value=''; document.getElementById('suggest').value='';"; - hPrintf("<CENTER>"); - } - - - /* Make line that says position. */ - { - char buf[256]; - char *survey = cfgOptionEnv("HGDB_SURVEY", "survey"); - char *surveyLabel = cfgOptionEnv("HGDB_SURVEY_LABEL", "surveyLabel"); - char *javascript = "onchange=\"document.location = '/cgi-bin/hgTracks?db=' + document.TrackForm.db.options[document.TrackForm.db.selectedIndex].value;\""; - if (containsStringNoCase(database, "zoo")) - { - hPuts("Organism "); - printAssemblyListHtmlExtra(database, javascript); - } - - sprintf(buf, "%s:%d-%d", chromName, winStart+1, winEnd); - position = cloneString(buf); - hWrites("position/search "); - hTextVar("position", addCommasToPos(database, position), 30); - sprintLongWithCommas(buf, winEnd - winStart); - if(dragZooming && assemblySupportsGeneSuggest(database)) - hWrites(" <a title='click for help on gene search box' target='_blank' href='../goldenPath/help/geneSearchBox.html'>gene</a> <input type='text' size='8' name='hgt.suggest' id='suggest'>\n"); - hWrites(" "); - hButtonWithOnClick("hgt.jump", "jump", NULL, "jumpButtonOnClick()"); - hOnClickButton(clearButtonJavascript,"clear"); - hPrintf(" size <span id='size'>%s</span> bp. ", buf); - hWrites(" "); - hButton("hgTracksConfigPage", "configure"); - //hPrintf(" <FONT SIZE=3><A STYLE=\"text-decoration:none; padding:2px; background-color:yellow; border:solid 1px\" HREF=\"http://www.surveymonkey.com/s.asp?u=881163743177\" TARGET=_BLANK><EM><B>Your feedback</B></EM></A></FONT>\n"); - if (survey && differentWord(survey, "off")) - hPrintf(" <FONT SIZE=3><A STYLE=\"background-color:yellow;\" HREF=\"%s\" TARGET=_BLANK><EM><B>%s</B></EM></A></FONT>\n", survey, surveyLabel ? surveyLabel : "Take survey"); - // info for drag selection javascript - hPrintf("<input type='hidden' id='hgt.winStart' name='winStart' value='%d'>\n", winStart); - hPrintf("<input type='hidden' id='hgt.winEnd' name='winEnd' value='%d'>\n", winEnd); - hPrintf("<input type='hidden' id='hgt.chromName' name='chromName' value='%s'>\n", chromName); - - hPutc('\n'); - - } - } - -/* Make chromsome ideogram gif and map. */ -makeChromIdeoImage(&trackList, psOutput, ideoTn); - -#ifdef USE_NAVIGATION_LINKS - hPrintf("<TABLE BORDER=0 CELLPADDING=0 width='%d'><tr style='font-size:small;'>\n",tl.picWidth);//min(tl.picWidth, 800)); - hPrintf("<td width='40' align='left'><a href='?hgt.left3=1' title='move 95% to the left'><<<</a>\n"); - hPrintf("<td width='30' align='left'><a href='?hgt.left2=1' title='move 47.5% to the left'><<</a>\n"); - #ifdef IMAGEv2_DRAG_SCROLL - if(!advancedJavascriptFeaturesEnabled(cart)) - #endif//def IMAGEv2_DRAG_SCROLL - hPrintf("<td width='20' align='left'><a href='?hgt.left1=1' title='move 10% to the left'><</a>\n"); - - hPrintf("<td> </td>\n"); // Without 'width=' this cell expand to table with, forcing other cells to the sides. - hPrintf("<td width='40' align='left'><a href='?hgt.in1=1' title='zoom in 1.5x'>> <</a>\n"); - hPrintf("<td width='60' align='left'><a href='?hgt.in2=1' title='zoom in 3x'>>> <<</a>\n"); - hPrintf("<td width='80' align='left'><a href='?hgt.in3=1' title='zoom in 10x'>>>> <<<</a>\n"); - hPrintf("<td width='40' align='left'><a href='?hgt.inBase=1' title='zoom in to base range'>><i>base</i><</a>\n"); - - hPrintf("<td> </td>\n"); // Without 'width=' this cell expand to table with, forcing other cells to the sides. - hPrintf("<td width='40' align='right'><a href='?hgt.out1=1' title='zoom out 1.5x'>< ></a>\n"); - hPrintf("<td width='60' align='right'><a href='?hgt.out2=1' title='zoom out 3x'><< >></a>\n"); - hPrintf("<td width='80' align='right'><a href='?hgt.out3=1' title='zoom out 10x'><<< >>></a>\n"); - hPrintf("<td> </td>\n"); // Without 'width=' this cell expand to table with, forcing other cells to the sides. - #ifdef IMAGEv2_DRAG_SCROLL - if(!advancedJavascriptFeaturesEnabled(cart)) - #endif//ndef IMAGEv2_DRAG_SCROLL - hPrintf("<td width='20' align='right'><a href='?hgt.right1=1' title='move 10% to the right'>></a>\n"); - - hPrintf("<td width='30' align='right'><a href='?hgt.right2=1' title='move 47.5% to the right'>>></a>\n"); - hPrintf("<td width='40' align='right'><a href='?hgt.right3=1' title='move 95% to the right'>>>></a>\n"); - hPrintf("</tr></table>\n"); -#endif//def USE_NAVIGATION_LINKS - -/* Make clickable image and map. */ -makeActiveImage(trackList, psOutput); -fflush(stdout); - -if(trackImgOnly) - // bail out b/c we are done - return; - -if (!hideControls) - { - struct controlGrid *cg = NULL; - - /* note a trick of WIDTH=27 going on here. The 6,15,6 widths following - * go along with this trick */ - hPrintf("<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=1 WIDTH=%d COLS=%d><TR>\n", - tl.picWidth, 27); -#ifndef USE_NAVIGATION_LINKS - hPrintf("<TD COLSPAN=6 ALIGN=left NOWRAP>"); - hPrintf("move start<BR>"); - hButton("hgt.dinkLL", " < "); - hTextVar("dinkL", cartUsualString(cart, "dinkL", "2.0"), 3); - hButton("hgt.dinkLR", " > "); - hPrintf("</TD>"); - hPrintf("<td width='30'> </td>\n"); -#endif//ndef USE_NAVIGATION_LINKS - hPrintf("<TD COLSPAN=15 style=\"white-space:normal\">"); // allow this text to wrap - hWrites("Click on a feature for details. "); - hWrites(dragZooming ? "Click or drag in the base position track to zoom in. " : "Click on base position to zoom in around cursor. "); - hWrites("Click side bars for track options. "); - hWrites("Drag side bars or labels up or down to reorder tracks. "); -#ifdef IMAGEv2_DRAG_SCROLL - hWrites("Drag tracks left or right to new position. "); -#endif//def IMAGEv2_DRAG_SCROLL -//#if !defined(IMAGEv2_DRAG_SCROLL) && !defined(USE_NAVIGATION_LINKS) - hPrintf("</TD>"); -#ifndef USE_NAVIGATION_LINKS - hPrintf("<td width='30'> </td>\n"); - hPrintf("<TD COLSPAN=6 ALIGN=right NOWRAP>"); - hPrintf("move end<BR>"); - hButton("hgt.dinkRL", " < "); - hTextVar("dinkR", cartUsualString(cart, "dinkR", "2.0"), 3); - hButton("hgt.dinkRR", " > "); - hPrintf("</TD>"); -#endif//ndef USE_NAVIGATION_LINKS - hPrintf("</TR></TABLE>\n"); - // smallBreak(); - - /* Display bottom control panel. */ - -#ifdef TRACK_SEARCH - if(isSearchTracksSupported(database)) - { - hPrintf("<input type='submit' name='%s' value='find tracks'>", searchTracks); - hPrintf(" "); - } -#endif - hButton("hgt.reset", "default tracks"); - hPrintf(" "); - hButton("hgt.defaultImgOrder", "default order"); - // if (showTrackControls) - always show "hide all", Hiram 2008-06-26 - { - hPrintf(" "); - hButton("hgt.hideAll", "hide all"); - } - - hPrintf(" "); - hOnClickButton("document.customTrackForm.submit();return false;", - hasCustomTracks ? - CT_MANAGE_BUTTON_LABEL : CT_ADD_BUTTON_LABEL); - - hPrintf(" "); - hButton("hgTracksConfigPage", "configure"); - hPrintf(" "); - - if (!hIsGsidServer()) - { - hButton("hgt.toggleRevCmplDisp", "reverse"); - hPrintf(" "); - } - - hButton("hgt.refresh", "refresh"); - - hPrintf("<BR>\n"); - - if( chromosomeColorsMade ) - { - hPrintf("<B>Chromosome Color Key:</B><BR> "); - hPrintf("<IMG SRC = \"../images/new_colorchrom.gif\" BORDER=1 WIDTH=596 HEIGHT=18 ><BR>\n"); - } - - if (showTrackControls) - { - /* Display viewing options for each track. */ - /* Chuck: This is going to be wrapped in a table so that - * the controls don't wrap around randomly */ - hPrintf("<table border=0 cellspacing=1 cellpadding=1 width=%d>\n", CONTROL_TABLE_WIDTH); - hPrintf("<tr><td align='left'>\n"); - - hButtonWithOnClick("hgt.collapseGroups", "collapse all", "collapse all track groups", "return setAllTrackGroupVisibility(false)"); - hPrintf("</td>"); - - hPrintf("<td colspan='%d' align='CENTER' nowrap>" - "Use drop-down controls below and press refresh to alter tracks " - "displayed.<BR>" - "Tracks with lots of items will automatically be displayed in " - "more compact modes.</td>\n", MAX_CONTROL_COLUMNS - 2); - - hPrintf("<td align='right'>"); - hButtonWithOnClick("hgt.expandGroups", "expand all", "expand all track groups", "return setAllTrackGroupVisibility(true)"); - hPrintf("</td></tr>"); - - if (!hIsGsidServer()) - { - cg = startControlGrid(MAX_CONTROL_COLUMNS, "left"); - } - else - { - /* 4 cols fit GSID's display better */ - cg = startControlGrid(4, "left"); - } - boolean isFirstNotCtGroup = TRUE; - for (group = groupList; group != NULL; group = group->next) - { - if (group->trackList == NULL) - continue; - - struct trackRef *tr; - - /* check if group section should be displayed */ - char *otherState; - char *indicator; - char *indicatorImg; - boolean isOpen = !isCollapsedGroup(group); - collapseGroupGoodies(isOpen, TRUE, &indicatorImg, - &indicator, &otherState); - hPrintf("<TR>"); - cg->rowOpen = TRUE; - if (!hIsGsidServer()) - { - hPrintf("<th align=\"left\" colspan=%d BGCOLOR=#536ED3>", - MAX_CONTROL_COLUMNS); - } - else - { - hPrintf("<th align=\"left\" colspan=%d BGCOLOR=#536ED3>", - MAX_CONTROL_COLUMNS-1); - } - hPrintf("<table width='100%%'><tr><td align='left'>"); - hPrintf("\n<A NAME=\"%sGroup\"></A>",group->name); - hPrintf("<A HREF=\"%s?%s&%s=%s#%sGroup\" class='bigBlue'><IMG height='18' width='18' onclick=\"return toggleTrackGroupVisibility(this, '%s');\" id=\"%s_button\" src=\"%s\" alt=\"%s\" class='bigBlue'></A> ", - hgTracksName(), cartSidUrlString(cart), - collapseGroupVar(group->name), - otherState, group->name, - group->name, group->name, indicatorImg, indicator); - hPrintf("</td><td align='center' width='100%%'>\n"); - hPrintf("<B>%s</B>", wrapWhiteFont(group->label)); - hPrintf("</td><td align='right'>\n"); - hPrintf("<input type='submit' name='hgt.refresh' value='refresh'>\n"); - hPrintf("</td></tr></table></th>\n"); - controlGridEndRow(cg); - - /* First track group that is not custom track group gets ruler, - * unless it's collapsed. */ - if (!showedRuler && isFirstNotCtGroup && - differentString(group->name, "user")) - { - char *url = trackUrl(RULER_TRACK_NAME, chromName); - showedRuler = TRUE; - myControlGridStartCell(cg, isOpen, group->name); - hPrintf("<A HREF=\"%s\">", url); - hPrintf(" %s<BR> ", RULER_TRACK_LABEL); - hPrintf("</A>"); - hDropListClassWithStyle("ruler", rulerMenu, - sizeof(rulerMenu)/sizeof(char *), rulerMenu[rulerMode], - rulerMode == tvHide ? "hiddenText" : "normalText", - TV_DROPDOWN_STYLE); - controlGridEndCell(cg); - freeMem(url); - } - if (differentString(group->name, "user")) - isFirstNotCtGroup = FALSE; - - /* Add supertracks to track list, sort by priority and - * determine if they have visible member tracks */ - groupTrackListAddSuper(cart, group); - - /* Display track controls */ - for (tr = group->trackList; tr != NULL; tr = tr->next) - { - struct track *track = tr->track; - if (tdbIsSuperTrackChild(track->tdb)) - /* don't display supertrack members */ - continue; - myControlGridStartCell(cg, isOpen, group->name); - if (track->hasUi) - { - char *url = trackUrl(track->track, chromName); - char *longLabel = replaceChars(track->longLabel, "\"", """); - if(trackDbSetting(track->tdb, "wgEncode") != NULL) - hPrintf("<a title='encode project' href='../ENCODE'><img height='16' width='16' src='../images/encodeThumbnail.jpg'></a>\n"); - hPrintf("<A HREF=\"%s\" title=\"%s\">", url, longLabel); - freeMem(url); - freeMem(longLabel); - } - hPrintf(" %s", track->shortLabel); - if (tdbIsSuper(track->tdb)) - hPrintf("..."); - hPrintf("<BR> "); - if (track->hasUi) - hPrintf("</A>"); - - if (hTrackOnChrom(track->tdb, chromName)) - { - if (tdbIsSuper(track->tdb)) - superTrackDropDown(cart, track->tdb, - superTrackHasVisibleMembers(track->tdb)); - else - { - /* check for option of limiting visibility to one mode */ - hTvDropDownClassVisOnly(track->track, track->visibility, - track->canPack, (track->visibility == tvHide) ? - "hiddenText" : "normalText", - trackDbSetting(track->tdb, "onlyVisibility")); - } - } - else - /* If track is not on this chrom print an informational - message for the user. */ - hPrintf("[No data-%s]", chromName); - controlGridEndCell(cg); - } - /* now finish out the table */ - if (group->next != NULL) - controlGridEndRow(cg); - } - endControlGrid(&cg); - } - - if (measureTiming) - { - hPrintf("track, load time, draw time, total<BR>\n"); - for (track = trackList; track != NULL; track = track->next) - { - if (track->visibility == tvHide) - continue; - if (trackIsCompositeWithSubtracks(track)) //TODO: Change when tracks->subtracks are always set for composite - { - struct track *subtrack; - for (subtrack = track->subtracks; subtrack != NULL; - subtrack = subtrack->next) - if (isSubtrackVisible(subtrack)) - hPrintf("%s, %d, %d, %d<BR>\n", subtrack->shortLabel, - subtrack->loadTime, subtrack->drawTime, - subtrack->loadTime + subtrack->drawTime); - } - else - { - hPrintf("%s, %d, %d, %d<BR>\n", - track->shortLabel, track->loadTime, track->drawTime, - track->loadTime + track->drawTime); - if (startsWith("wigMaf", track->tdb->type)) - if (track->subtracks) - if (track->subtracks->loadTime) - hPrintf(" %s wiggle, load %d<BR>\n", - track->shortLabel, track->subtracks->loadTime); - } - } - } - hPrintf("</DIV>\n"); - } -if (showTrackControls) - hButton("hgt.refresh", "refresh"); -hPrintf("</CENTER>\n"); - -#ifdef SLOW -/* We'll rely on the end of program to do the cleanup. - * It turns out that the 'free' routine on Linux is - * quite slow. For chromosome level views the browser - * spends about 1/3 of it's time doing the cleanup - * below if it's enabled. Since we really don't - * need to reclaim this memory at this point I'm - * taking this out. Please don't delete the code though. - * I'll like to keep it for testing now and then. -jk. */ - -/* Clean up. */ -for (track = trackList; track != NULL; track = track->next) - { - if (track->visibility != tvHide) - { - if (track->freeItems != NULL) - track->freeItems(track); - lmCleanup(&track->lm); - } - } -#endif /* SLOW */ -hPrintf("</FORM>\n"); - -/* hidden form for custom tracks CGI */ -hPrintf("<FORM ACTION='%s' NAME='customTrackForm'>", hgCustomName()); -cartSaveSession(cart); -hPrintf("</FORM>\n"); - -pruneRedundantCartVis(trackList); -} - -static void toggleRevCmplDisp() -/* toggle the reverse complement display mode */ -{ -// forces complement bases to match display -revCmplDisp = !revCmplDisp; -cartSetBooleanDb(cart, database, REV_CMPL_DISP, revCmplDisp); -cartSetBooleanDb(cart, database, COMPLEMENT_BASES_VAR, revCmplDisp); -} - -void zoomToSize(int newSize) -/* Zoom so that center stays in same place, - * but window is new size. If necessary move - * center a little bit to keep it from going past - * edges. */ -{ -int center = ((long long int)winStart + (long long int)winEnd)/2; -if (center < 0) - errAbort("zoomToSize: error computing center: %d = (%d + %d)/2\n", - center, winStart, winEnd); -if (newSize > seqBaseCount) - newSize = seqBaseCount; -winStart = center - newSize/2; -winEnd = winStart + newSize; -if (winStart <= 0) - { - winStart = 0; - winEnd = newSize; - } -else if (winEnd > seqBaseCount) - { - winEnd = seqBaseCount; - winStart = winEnd - newSize; - } -winBaseCount = winEnd - winStart; -} - -void zoomAroundCenter(double amount) -/* Set ends so as to zoom around center by scaling amount. */ -{ -double newSizeDbl = (winBaseCount*amount + 0.5); -int newSize; -if (newSizeDbl > seqBaseCount) - newSize = seqBaseCount; -else if (newSizeDbl < 1.0) - newSize = 1; -else - newSize = (int)newSizeDbl; -zoomToSize(newSize); -} - -void zoomToBaseLevel() -/* Set things so that it's zoomed to base level. */ -{ -zoomToSize(insideWidth/tl.mWidth); -if (rulerMode == tvHide) - cartSetString(cart, "ruler", "dense"); -} - -void relativeScroll(double amount) -/* Scroll percentage of visible window. */ -{ -int offset; -int newStart, newEnd; -if (revCmplDisp) - amount = -amount; -offset = (int)(amount * winBaseCount); -/* Make sure don't scroll of ends. */ -newStart = winStart + offset; -newEnd = winEnd + offset; -if (newStart < 0) - offset = -winStart; -else if (newEnd > seqBaseCount) - offset = seqBaseCount - winEnd; - -/* Move window. */ -winStart += offset; -winEnd += offset; -} - -void dinkWindow(boolean start, int dinkAmount) -/* Move one end or other of window a little. */ -{ -if (revCmplDisp) - { - start = !start; - dinkAmount = -dinkAmount; - } -if (start) - { - winStart += dinkAmount; - if (winStart < 0) winStart = 0; - } -else - { - winEnd += dinkAmount; - if (winEnd > seqBaseCount) - winEnd = seqBaseCount; - } -} - -int dinkSize(char *var) -/* Return size to dink. */ -{ -char *stringVal = cartOptionalString(cart, var); -double x; -int insideX = trackOffsetX(); /* The global versions of these are not yet set */ -int insideWidth = tl.picWidth-gfxBorder-insideX; -double guideBases = (double)guidelineSpacing * (double)(winEnd - winStart) - / ((double)insideWidth); - -if (stringVal == NULL || !isdigit(stringVal[0])) - { - stringVal = "1"; - cartSetString(cart, var, stringVal); - } -x = atof(stringVal); -int ret = round(x*guideBases); - -return (ret == 0) ? 1 : ret; -} - -void handlePostscript() -/* Deal with Postscript output. */ -{ -struct tempName psTn, ideoPsTn; -char *pdfFile = NULL, *ideoPdfFile = NULL; -ZeroVar(&ideoPsTn); -trashDirFile(&psTn, "hgt", "hgt", ".eps"); - -hotLinks(); -printf("<H1>PostScript/PDF Output</H1>\n"); -printf("PostScript images can be printed at high resolution " - "and edited by many drawing programs such as Adobe " - "Illustrator."); -doTrackForm(psTn.forCgi, &ideoPsTn); - -// postscript -printf("<UL>\n"); -printf("<LI><A HREF=\"%s\">Click here</A> " - "to download the current browser graphic in PostScript. ", psTn.forCgi); -if (strlen(ideoPsTn.forCgi)) - printf("<LI><A HREF=\"%s\">Click here</A> " - "to download the current chromosome ideogram in PostScript. ", ideoPsTn.forCgi); -printf("</UL>\n"); - -pdfFile = convertEpsToPdf(psTn.forCgi); -if (strlen(ideoPsTn.forCgi)) - ideoPdfFile = convertEpsToPdf(ideoPsTn.forCgi); -if(pdfFile != NULL) - { - printf("<BR>PDF can be viewed with Adobe Acrobat Reader.\n"); - printf("<UL>\n"); - printf("<LI><A TARGET=_blank HREF=\"%s\">Click here</A> " - "to download the current browser graphic in PDF.", pdfFile); - if (ideoPdfFile != NULL) - printf("<LI><A TARGET=_blank HREF=\"%s\">Click here</A> " - "to download the current chromosome ideogram in PDF.", ideoPdfFile); - printf("</UL>\n"); - freez(&pdfFile); - freez(&ideoPdfFile); - } -else - printf("<BR><BR>PDF format not available"); - - #define RETURN_BUTTON "<FORM ACTION='../cgi-bin/hgTracks' NAME='TrackHeaderForm' id='TrackHeaderForm' METHOD='GET'><INPUT TYPE=SUBMIT ID='ChangeToNameToSetSomething' VALUE='Return to Browser'></FORM>" - printf(RETURN_BUTTON); -} - -boolean isGenome(char *pos) -/* Return TRUE if pos is genome. */ -{ -pos = trimSpaces(pos); -return(sameWord(pos, "genome") || sameWord(pos, "hgBatch")); -} - -void setRulerMode() -/* Set the rulerMode variable from cart. */ -{ -char *s = cartUsualString(cart, RULER_TRACK_NAME, "dense"); -if (sameWord(s, "full") || sameWord(s, "on")) - rulerMode = tvFull; -else if (sameWord(s, "dense")) - rulerMode = tvDense; -else - rulerMode = tvHide; -} - -void setLayoutGlobals() -/* Figure out basic dimensions of display. */ -{ -withIdeogram = cartUsualBoolean(cart, "ideogram", TRUE); -withLeftLabels = cartUsualBoolean(cart, "leftLabels", TRUE); -withCenterLabels = cartUsualBoolean(cart, "centerLabels", TRUE); -withGuidelines = cartUsualBoolean(cart, "guidelines", TRUE); -withNextItemArrows = cartUsualBoolean(cart, "nextItemArrows", FALSE); -withNextExonArrows = cartUsualBoolean(cart, "nextExonArrows", TRUE); -if (!hIsGsidServer()) - { - revCmplDisp = cartUsualBooleanDb(cart, database, REV_CMPL_DISP, FALSE); - } -withPriorityOverride = cartUsualBoolean(cart, configPriorityOverride, FALSE); -insideX = trackOffsetX(); -insideWidth = tl.picWidth-gfxBorder-insideX; - -} - -void tracksDisplay() -/* Put up main tracks display. This routine handles zooming and - * scrolling. */ -{ -char newPos[256]; -char *defaultPosition = hDefaultPos(database); -char titleVar[256]; -position = getPositionFromCustomTracks(); -if (NULL == position) - { - position = cloneString(cartUsualString(cart, "position", NULL)); - } - -/* default if not set at all, as would happen if it came from a URL with no - * position. Otherwise tell them to go back to the gateway. Also recognize - * "default" as specifying the default position. */ -if (((position == NULL) || sameString(position, "default")) - && (defaultPosition != NULL)) - position = cloneString(defaultPosition); -if (sameString(position, "")) - { - hUserAbort("Please go back and enter a coordinate rangeor a search term in the \"position\" field.<br>For example: chr22:20100000-20200000.\n"); - } - -chromName = NULL; -winStart = 0; -if (isGenome(position) || NULL == - (hgp = findGenomePos(database, position, &chromName, &winStart, &winEnd, cart))) - { - if (winStart == 0) /* number of positions found */ - { - freeMem(position); - position = cloneString(cartUsualString(cart, "lastPosition", defaultPosition)); - hgp = findGenomePos(database, position, &chromName, &winStart, &winEnd,cart); - if(hgp != NULL && position != defaultPosition) - cartSetString(cart, "position", position); - } - } - -/* After position is found set up hash of matches that should - be drawn with names highlighted for easy identification. */ -createHgFindMatchHash(); - -/* This means that no single result was found -I.e., multiple results may have been found and are printed out prior to this code*/ -if (NULL == chromName) - { - return; - } - -seqBaseCount = hChromSize(database, chromName); -winBaseCount = winEnd - winStart; - -/* Figure out basic dimensions of display. This - * needs to be done early for the sake of the - * zooming and dinking routines. */ -setLayoutGlobals(); - -baseShowPos = cartUsualBoolean(cart, BASE_SHOWPOS, FALSE); -baseShowAsm = cartUsualBoolean(cart, BASE_SHOWASM, FALSE); -baseShowScaleBar = cartUsualBoolean(cart, BASE_SCALE_BAR, TRUE); -baseShowRuler = cartUsualBoolean(cart, BASE_SHOWRULER, TRUE); -safef(titleVar,sizeof(titleVar),"%s_%s", BASE_TITLE, database); -baseTitle = cartUsualString(cart, titleVar, ""); -if (sameString(baseTitle, "")) - baseTitle = NULL; - -if (cgiVarExists("hgt.toggleRevCmplDisp")) - toggleRevCmplDisp(); -setRulerMode(); - -/* Do zoom/scroll if they hit it. */ -if (cgiVarExists("hgt.left3")) - relativeScroll(-0.95); -else if (cgiVarExists("hgt.left2")) - relativeScroll(-0.475); -else if (cgiVarExists("hgt.left1")) - relativeScroll(-0.1); -else if (cgiVarExists("hgt.right1")) - relativeScroll(0.1); -else if (cgiVarExists("hgt.right2")) - relativeScroll(0.475); -else if (cgiVarExists("hgt.right3")) - relativeScroll(0.95); -else if (cgiVarExists("hgt.inBase")) - zoomToBaseLevel(); -else if (cgiVarExists("hgt.in3")) - zoomAroundCenter(1.0/10.0); -else if (cgiVarExists("hgt.in2")) - zoomAroundCenter(1.0/3.0); -else if (cgiVarExists("hgt.in1")) - zoomAroundCenter(1.0/1.5); -else if (cgiVarExists("hgt.out1")) - zoomAroundCenter(1.5); -else if (cgiVarExists("hgt.out2")) - zoomAroundCenter(3.0); -else if (cgiVarExists("hgt.out3")) - zoomAroundCenter(10.0); -else if (cgiVarExists("hgt.dinkLL")) - dinkWindow(TRUE, -dinkSize("dinkL")); -else if (cgiVarExists("hgt.dinkLR")) - dinkWindow(TRUE, dinkSize("dinkL")); -else if (cgiVarExists("hgt.dinkRL")) - dinkWindow(FALSE, -dinkSize("dinkR")); -else if (cgiVarExists("hgt.dinkRR")) - dinkWindow(FALSE, dinkSize("dinkR")); - -/* Clip chromosomal position to fit. */ -if (winEnd < winStart) - { - int temp = winEnd; - winEnd = winStart; - winStart = temp; - } -else if (winStart == winEnd) - { - winStart -= 1; - winEnd += 1; - } - -if (winStart < 0) - { - winStart = 0; - } - -if (winEnd > seqBaseCount) - { - winEnd = seqBaseCount; - } - -if (winStart > seqBaseCount) - { - winStart = seqBaseCount - 1000; - } - -winBaseCount = winEnd - winStart; -if (winBaseCount <= 0) - hUserAbort("Window out of range on %s", chromName); -/* Save computed position in cart. */ -sprintf(newPos, "%s:%d-%d", chromName, winStart+1, winEnd); -cartSetString(cart, "org", organism); -cartSetString(cart, "db", database); -cartSetString(cart, "position", newPos); -if (cgiVarExists("hgt.psOutput")) - handlePostscript(); -else - doTrackForm(NULL, NULL); -} - -void chromInfoTotalRow(int count, long long total) -/* Make table row with total number of sequences and size from chromInfo. */ -{ -cgiSimpleTableRowStart(); -cgiSimpleTableFieldStart(); -printf("Total: %d", count); -cgiTableFieldEnd(); -cgiSimpleTableFieldStart(); -printLongWithCommas(stdout, total); -cgiTableFieldEnd(); -cgiTableRowEnd(); -} - -void chromInfoRowsChrom() -/* Make table rows of chromosomal chromInfo name & size, sorted by name. */ -{ -struct slName *chromList = hAllChromNames(database); -struct slName *chromPtr = NULL; -long long total = 0; - -slSort(&chromList, chrSlNameCmp); -for (chromPtr = chromList; chromPtr != NULL; chromPtr = chromPtr->next) - { - unsigned size = hChromSize(database, chromPtr->name); - cgiSimpleTableRowStart(); - cgiSimpleTableFieldStart(); - printf("<A HREF=\"%s?%s=%u&position=%s\">%s</A>", - hgTracksName(), cartSessionVarName(), cartSessionId(cart), - chromPtr->name, chromPtr->name); - cgiTableFieldEnd(); - cgiTableFieldStartAlignRight(); - printLongWithCommas(stdout, size); - puts(" "); - cgiTableFieldEnd(); - cgiTableRowEnd(); - total += size; - } -chromInfoTotalRow(slCount(chromList), total); -slFreeList(&chromList); -} - -void chromInfoRowsNonChrom(int limit) -/* Make table rows of non-chromosomal chromInfo name & size, sorted by size. */ -{ -struct sqlConnection *conn = hAllocConn(database); -struct sqlResult *sr = NULL; -char **row = NULL; -long long total = 0; -char query[512]; -char msg1[512], msg2[512]; -int seqCount = 0; -boolean truncating; - -seqCount = sqlQuickNum(conn, "select count(*) from chromInfo"); -truncating = (limit > 0) && (seqCount > limit); - -if (!truncating) - { - sr = sqlGetResult(conn, "select chrom,size from chromInfo order by size desc"); - } -else - { - - safef(query, sizeof(query), "select chrom,size from chromInfo order by size desc limit %d", limit); - sr = sqlGetResult(conn, query); - } - -while ((row = sqlNextRow(sr)) != NULL) - { - unsigned size = sqlUnsigned(row[1]); - cgiSimpleTableRowStart(); - cgiSimpleTableFieldStart(); - printf("<A HREF=\"%s?%s=%u&position=%s\">%s</A>", - hgTracksName(), cartSessionVarName(), cartSessionId(cart), - row[0], row[0]); - cgiTableFieldEnd(); - cgiTableFieldStartAlignRight(); - printLongWithCommas(stdout, size); - puts(" "); - cgiTableFieldEnd(); - cgiTableRowEnd(); - total += size; - } -if (!truncating) - { - chromInfoTotalRow(seqCount, total); - } -else - { - safef(msg1, sizeof(msg1), "Limit reached"); - safef(msg2, sizeof(msg2), "%d rows displayed", limit); - cgiSimpleTableRowStart(); - cgiSimpleTableFieldStart(); - puts(msg1); - cgiTableFieldEnd(); - cgiSimpleTableFieldStart(); - puts(msg2); - cgiTableFieldEnd(); - sqlFreeResult(&sr); - safef(query, sizeof(query), "select count(*),sum(size) from chromInfo"); - sr = sqlGetResult(conn, query); - if ((row = sqlNextRow(sr)) != NULL) - { - unsigned scafCount = sqlUnsigned(row[0]); - unsigned totalSize = sqlUnsigned(row[1]); - cgiTableRowEnd(); - safef(msg1, sizeof(msg1), "contig/scaffold<BR>count:"); - safef(msg2, sizeof(msg2), "total size:"); - cgiSimpleTableRowStart(); - cgiSimpleTableFieldStart(); - puts(msg1); - cgiTableFieldEnd(); - cgiSimpleTableFieldStart(); - puts(msg2); - cgiTableFieldEnd(); - cgiTableRowEnd(); - cgiSimpleTableRowStart(); - cgiSimpleTableFieldStart(); - printLongWithCommas(stdout, scafCount); - cgiTableFieldEnd(); - cgiSimpleTableFieldStart(); - printLongWithCommas(stdout, totalSize); - cgiTableFieldEnd(); - } - cgiTableRowEnd(); - } -sqlFreeResult(&sr); -hFreeConn(&conn); -} - -void chromInfoPage() -/* Show list of chromosomes (or scaffolds, etc) on which this db is based. */ -{ -char *position = cartUsualString(cart, "position", hDefaultPos(database)); -char *defaultChrom = hDefaultChrom(database); -char *freeze = hFreezeFromDb(database); -struct dyString *title = dyStringNew(512); -if (stringIn(database, freeze)) - dyStringPrintf(title, "%s %s Browser Sequences", - hOrganism(database), freeze); -else - dyStringPrintf(title, "%s %s (%s) Browser Sequences", - hOrganism(database), freeze, database); -webStartWrapperDetailedNoArgs(cart, database, "", title->string, FALSE, FALSE, FALSE, FALSE); -printf("<FORM ACTION=\"%s\" NAME=\"posForm\" METHOD=GET>\n", hgTracksName()); -cartSaveSession(cart); - -puts("Enter a position, or click on a sequence name to view the entire " - "sequence in the genome browser.<P>"); -puts("position "); -hTextVar("position", addCommasToPos(database, position), 30); -cgiMakeButton("Submit", "submit"); -puts("<P>"); - -hTableStart(); -cgiSimpleTableRowStart(); -cgiSimpleTableFieldStart(); -puts("Sequence name "); -cgiTableFieldEnd(); -cgiSimpleTableFieldStart(); -puts("Length (bp) including gaps "); -cgiTableFieldEnd(); -cgiTableRowEnd(); - -if ((startsWith("chr", defaultChrom) || startsWith("Group", defaultChrom)) && - hChromCount(database) < 100) - chromInfoRowsChrom(); -else - chromInfoRowsNonChrom(1000); - -hTableEnd(); - -hgPositionsHelpHtml(organism, database); -puts("</FORM>"); -dyStringFree(&title); -webEndSectionTables(); -} - - -void resetVars() -/* Reset vars except for position and database. */ -{ -static char *except[] = {"db", "position", NULL}; -char *cookieName = hUserCookie(); -int sessionId = cgiUsualInt(cartSessionVarName(), 0); -char *hguidString = findCookieData(cookieName); -int userId = (hguidString == NULL ? 0 : atoi(hguidString)); -struct cart *oldCart = cartNew(userId, sessionId, NULL, NULL); -cartRemoveExcept(oldCart, except); -cartCheckout(&oldCart); -cgiVarExcludeExcept(except); -} - -void doMiddle(struct cart *theCart) -/* Print the body of an html file. */ -{ -char *debugTmp = NULL; -/* Uncomment this to see parameters for debugging. */ -/* struct dyString *state = NULL; */ -/* Initialize layout and database. */ -cart = theCart; - -/* #if 1 this to see parameters for debugging. */ -/* Be careful though, it breaks if custom track - * is more than 4k */ -#if 0 -state = cgiUrlString(); -printf("State: %s\n", state->string); -#endif -getDbAndGenome(cart, &database, &organism, oldVars); - -protDbName = hPdbFromGdb(database); -debugTmp = cartUsualString(cart, "hgDebug", "off"); -if(sameString(debugTmp, "on")) - hgDebug = TRUE; -else - hgDebug = FALSE; - -if (hIsGisaidServer()) - { - validateGisaidUser(cart); - } - -setUdcCacheDir(); - -initTl(); -measureTiming = isNotEmpty(cartOptionalString(cart, "measureTiming")); - -char *configPageCall = cartCgiUsualString(cart, "hgTracksConfigPage", "notSet"); - -dragZooming = advancedJavascriptFeaturesEnabled(cart); - -/* Do main display. */ - -if (cartUsualBoolean(cart, "hgt.trackImgOnly", FALSE)) - { - trackImgOnly = TRUE; - ideogramToo = cartUsualBoolean(cart, "hgt.ideogramToo", FALSE); - hideControls = TRUE; - withNextItemArrows = FALSE; - withNextExonArrows = FALSE; - hgFindMatches = NULL; // XXXX necessary ??? - } - -hWrites(commonCssStyles()); -jsIncludeFile("jquery.js", NULL); -jsIncludeFile("utils.js", NULL); -if(dragZooming) - { - jsIncludeFile("jquery.imgareaselect.js", NULL); - jsIncludeFile("ajax.js", NULL); - hPrintf("<link href='../style/autocomplete.css' rel='stylesheet' type='text/css' />\n"); - jsIncludeFile("jquery.autocomplete.js", NULL); - jsIncludeFile("autocomplete.js", NULL); - } -jsIncludeFile("hgTracks.js", NULL); - -#ifdef LOWELAB -jsIncludeFile("lowetooltip.js", NULL); -#endif - -#if defined(CONTEXT_MENU) || defined(TRACK_SEARCH) -hPrintf("<link href='../style/jquery.contextmenu.css' rel='stylesheet' type='text/css' />\n"); -hPrintf("<link href='../style/jquery-ui.css' rel='stylesheet' type='text/css' />\n"); -#ifdef CONTEXT_MENU -jsIncludeFile("jquery.contextmenu.js", NULL); -#endif/// def CONTEXT_MENU -jsIncludeFile("jquery-ui.js", NULL); - -//if (!trackImgOnly) - { -hPrintf("<div id='hgTrackUiDialog' style='display: none'></div>\n"); -// XXXX stole this and '.hidden' from bioInt.css - needs work -hPrintf("<div id='warning' class='ui-state-error ui-corner-all hidden' style='font-size: 0.75em; display: none;' onclick='$(this).hide();'><p><span class='ui-icon ui-icon-alert' style='float: left; margin-right: 0.3em;'></span><strong></strong><span id='warningText'></span> (click to hide)</p></div>\n"); - } -#endif/// defined(CONTEXT_MENU) || defined(TRACK_SEARCH) -if (cartVarExists(cart, "chromInfoPage")) - { - cartRemove(cart, "chromInfoPage"); - chromInfoPage(); - } -else if (sameWord(configPageCall, "configure") || - sameWord(configPageCall, "configure tracks and display")) - { - cartRemove(cart, "hgTracksConfigPage"); - configPage(); - } -else if (cartVarExists(cart, configHideAll)) - { - cartRemove(cart, configHideAll); - configPageSetTrackVis(tvHide); - } -else if (cartVarExists(cart, configShowAll)) - { - cartRemove(cart, configShowAll); - configPageSetTrackVis(tvDense); - } -else if (cartVarExists(cart, configDefaultAll)) - { - cartRemove(cart, configDefaultAll); - configPageSetTrackVis(-1); - } -else if (cartVarExists(cart, configHideAllGroups)) - { - cartRemove(cart, configHideAllGroups); - struct grp *grp = NULL, *grps = hLoadGrps(database); - for (grp = grps; grp != NULL; grp = grp->next) - collapseGroup(grp->name, TRUE); - configPageSetTrackVis(-2); - } -else if (cartVarExists(cart, configShowAllGroups)) - { - cartRemove(cart, configShowAllGroups); - struct grp *grp = NULL, *grps = hLoadGrps(database); - for (grp = grps; grp != NULL; grp = grp->next) - collapseGroup(grp->name, FALSE); - configPageSetTrackVis(-2); - } -else if (cartVarExists(cart, configHideEncodeGroups)) - { - /* currently not used */ - cartRemove(cart, configHideEncodeGroups); - struct grp *grp = NULL, *grps = hLoadGrps(database); - for (grp = grps; grp != NULL; grp = grp->next) - if (startsWith("encode", grp->name)) - collapseGroup(grp->name, TRUE); - configPageSetTrackVis(-2); - } -else if (cartVarExists(cart, configShowEncodeGroups)) - { - /* currently not used */ - cartRemove(cart, configShowEncodeGroups); - struct grp *grp = NULL, *grps = hLoadGrps(database); - for (grp = grps; grp != NULL; grp = grp->next) - if (startsWith("encode", grp->name)) - collapseGroup(grp->name, FALSE); - configPageSetTrackVis(-2); - } -#ifdef TRACK_SEARCH -else if (cartVarExists(cart, searchTracks)) - { - doSearchTracks(groupList); - } -#endif -else - { - tracksDisplay(); - } -} - -void doDown(struct cart *cart) -{ -printf("<H2>The Browser is Being Updated</H2>\n"); -printf("The browser is currently unavailable. We are in the process of\n"); -printf("updating the database and the display software with a number of\n"); -printf("new tracks, including some gene predictions. Please try again tomorrow.\n"); -} -