示例#1
0
static void verifySubTracks(struct trackDb *tdbList, struct hash *compositeHash)
/* Verify subGroup relelated settings in subtracks, assisted by compositeHash */
{
struct trackDb *tdb;

for (tdb = tdbList; tdb != NULL; tdb = tdb->next)
    {
    struct slRef *child;
    if (trackDbLocalSetting(tdb, "compositeTrack"))
	{
	struct slRef *childList = trackDbListGetRefsToDescendantLeaves(
	    tdb->subtracks);

	verbose(2,"verifying %s child %p\n",tdb->track, childList);
	for (child = childList; child != NULL; child = child->next)
	    {
	    struct trackDb *childTdb = child->val;
	    verbose(2, "  checking child %s\n",childTdb->track);

	    /* Look for some ancestor in composite hash and set sgd to it. */
	    struct subGroupData *sgd =  hashFindVal(compositeHash, tdb->track);
	    verbose(2, "looking for %s in compositeHash got %p\n",
		tdb->track, sgd);
	    assert(sgd != NULL);
	    checkOneSubGroups(tdb->track, childTdb, sgd);
	    }
        }
    }
}
示例#2
0
static void addTablesAccordingToTrackType(char *db, struct slName **pList, struct hash *uniqHash,
                                          struct trackDb *track)
/* Parse out track->type and if necessary add some tables from it. */
{
struct slName *name;
char *trackDupe = cloneString(track->type);
if (trackDupe != NULL && trackDupe[0] != 0)
    {
    char *s = trackDupe;
    char *type = nextWord(&s);
    if (sameString(type, "wigMaf"))
        {
	static char *wigMafAssociates[] = {"frames", "summary"};
	int i;
	for (i=0; i<ArraySize(wigMafAssociates); ++i)
	    {
	    char *setting = wigMafAssociates[i];
	    char *table = trackDbSetting(track, setting);
            if (table != NULL)
                {
                name = slNameNew(table);
                slAddHead(pList, name);
                hashAdd(uniqHash, table, NULL);
                }
	    }
        /* include conservation wiggle tables */
        struct consWiggle *wig, *wiggles = wigMafWiggles(db, track);
        slReverse(&wiggles);
        for (wig = wiggles; wig != NULL; wig = wig->next)
            {
            name = slNameNew(wig->table);
            slAddHead(pList, name);
            hashAdd(uniqHash, wig->table, NULL);
            }
	}
    if (track->subtracks)
        {
        struct slName *subList = NULL;
	struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(track->subtracks);
	slSort(&tdbRefList, trackDbRefCmp);
	struct slRef *tdbRef;
	for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next)
            {
	    struct trackDb *subTdb = tdbRef->val;
	    name = slNameNew(subTdb->table);
	    slAddTail(&subList, name);
	    hashAdd(uniqHash, subTdb->table, NULL);
            }
        pList = slCat(pList, subList);
        }
    }
freez(&trackDupe);
}
示例#3
0
static void doOutWig(struct trackDb *track, char *table, struct sqlConnection *conn,
	enum wigOutputType wigOutType)
{
struct region *regionList = getRegions(), *region;
int maxOut = 0, outCount, curOut = 0;
char *shortLabel = table, *longLabel = table;

if (track == NULL)
    errAbort("Sorry, can't find necessary track information for %s.  "
	     "If you reached this page by selecting \"All tables\" as the "
	     "group, please go back and select the same table via a regular "
	     "track group if possible.",
	     table);

maxOut = bigFileMaxOutput();

if (cartUsualBoolean(cart, hgtaDoGreatOutput, FALSE))
    fputs("#", stdout);
else
    textOpen();

if (track != NULL)
    {
    if (!sameString(track->table, table) && track->subtracks != NULL)
	{
	struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(track->subtracks);
	struct slRef *tdbRef;
	for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next)
	    {
	    struct trackDb *tdb = tdbRef->val;
	    if (sameString(tdb->table, table))
		{
		track = tdb;
		break;
		}
	    }
	slFreeList(&tdbRefList);
	}
    shortLabel = track->shortLabel;
    longLabel = track->longLabel;
    }
wigDataHeader(shortLabel, longLabel, NULL, wigOutType);

for (region = regionList; region != NULL; region = region->next)
    {
    int curMaxOut = maxOut - curOut;
    if (anySubtrackMerge(database, table))
	outCount = mergedWigOutRegion(table, conn, region, curMaxOut,
				      wigOutType);
    else if (startsWithWord("bedGraph", track->type))
	outCount = bedGraphOutRegion(table, conn, region, curMaxOut,
				     wigOutType);
    else if (startsWithWord("mathWig", track->type))
        outCount = mathWigOutRegion(track, table, conn, region, curMaxOut, wigOutType);
    else if (startsWithWord("bigWig", track->type))
        outCount = bigWigOutRegion(table, conn, region, curMaxOut, wigOutType);
    else
	outCount = wigOutRegion(table, conn, region, curMaxOut,
				wigOutType, NULL, 0);
    curOut += outCount;
    if (curOut >= maxOut)
        break;
    }
if (curOut >= maxOut)
    errAbort("Reached output limit of %d data values, please make region smaller,\n\tor set a higher output line limit with the filter settings.", curOut);
}
示例#4
0
struct dataVector *mergedWigDataVector(char *table,
	struct sqlConnection *conn, struct region *region)
/* Perform the specified subtrack merge wiggle-operation on table and
 * all other selected subtracks and intersect if necessary. */
{
struct trackDb *tdb1 = hTrackDbForTrack(database, table);
struct trackTable *tt1 = trackTableNew(tdb1, table, conn);
struct dataVector *dataVector1 = dataVectorFetchOneRegion(tt1, region, conn);
struct trackDb *cTdb = hCompositeTrackDbForSubtrack(database, tdb1);
int numSubtracks = 1;
char *op = cartString(cart, hgtaSubtrackMergeWigOp);
boolean requireAll = cartBoolean(cart, hgtaSubtrackMergeRequireAll);
boolean useMinScore = cartBoolean(cart, hgtaSubtrackMergeUseMinScore);
float minScore = atof(cartString(cart, hgtaSubtrackMergeMinScore));

if (cTdb == NULL)
    errAbort("mergedWigDataVector: could not find parent/composite trackDb "
	     "entry for subtrack %s", table);

if (dataVector1 == NULL)
    {
    return NULL;
    }

struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(cTdb->subtracks);
struct slRef *tdbRef;
for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next)
    {
    struct trackDb *sTdb = tdbRef->val;
    if (isSubtrackMerged(sTdb->table) &&
	! sameString(tdb1->table, sTdb->table) &&
	hSameTrackDbType(tdb1->type, sTdb->type))
	{
	struct trackTable *tt2 = trackTableNew(sTdb, sTdb->table, conn);
	struct dataVector *dataVector2 = dataVectorFetchOneRegion(tt2, region,
								  conn);
	numSubtracks++;
	if (dataVector2 == NULL)
	    {
	    if (requireAll)
		{
		freeDataVector(&dataVector1);
		return NULL;
		}
	    continue;
	    }
	if (sameString(op, "average") || sameString(op, "sum"))
	    dataVectorSum(dataVector1, dataVector2, requireAll);
	else if (sameString(op, "product"))
	    dataVectorProduct(dataVector1, dataVector2, requireAll);
	else if (sameString(op, "min"))
	    dataVectorMin(dataVector1, dataVector2, requireAll);
	else if (sameString(op, "max"))
	    dataVectorMax(dataVector1, dataVector2, requireAll);
	else
	    errAbort("mergedWigOutRegion: unknown WigOp %s", op);
	dataVectorFree(&dataVector2);
	}
    }
slFreeList(&tdbRefList);
if (sameString(op, "average"))
    dataVectorNormalize(dataVector1, numSubtracks);
if (useMinScore)
    dataVectorFilterMin(dataVector1, minScore);

intersectDataVector(table, dataVector1, region, conn);

return dataVector1;
}
char *describeSubtrackMerge(char *linePrefix)
/* Return a multi-line string that describes the specified subtrack merge,
 * with each line beginning with linePrefix. */
{
struct dyString *dy = dyStringNew(512);
struct trackDb *primary = subTdbFind(curTrack,curTable), *tdb = NULL;
dyStringAppend(dy, linePrefix);
dyStringPrintf(dy, "Subtrack merge, primary table = %s (%s)\n",
	       curTable, primary->longLabel);
dyStringAppend(dy, linePrefix);
dyStringPrintf(dy, "Subtrack merge operation: ");
if (isWiggle(database, curTable) || isBedGraph(curTable) || isBigWigTable(curTable))
    {
    char *op = cartString(cart, hgtaSubtrackMergeWigOp);
    dyStringPrintf(dy, "%s of %s and selected subtracks:\n", op, curTable);
    }
else
    {
    char *op = cartString(cart, hgtaSubtrackMergeOp);
    if (sameString(op, "any"))
	dyStringPrintf(dy, "All %s records that have any overlap with "
		       "any other selected subtrack:\n",
		       curTable);
    else if (sameString(op, "none"))
	dyStringPrintf(dy, "All %s records that have no overlap with "
		       "any other selected subtrack:\n",
		       curTable);
    else if (sameString(op, "more"))
	{
	dyStringPrintf(dy, "All %s records that have at least %s ",
		       curTable,
		       cartString(cart, hgtaNextSubtrackMergeMoreThreshold));
	dyStringPrintf(dy, " %% overlap with any other selected subtrack:\n");
	}
    else if (sameString(op, "less"))
	{
	dyStringPrintf(dy, "All %s records that have at most %s ",
		       curTable,
		       cartString(cart, hgtaNextSubtrackMergeLessThreshold));
	dyStringPrintf(dy, " %% overlap with any other selected subtrack:\n");

	}
    else if (sameString(op, "cat"))
	dyStringPrintf(dy, "All %s records, as well as all records from "
		       "all other selected subtracks:\n", curTable);
    else if (sameString(op, "and"))
	dyStringPrintf(dy, "Base-pair-wise intersection (AND) of %s and "
		       "other selected subtracks:\n", curTable);
    else if (sameString(op, "or"))
	dyStringPrintf(dy, "Base-pair-wise union (OR) of %s and other "
		       "selected subtracks:\n",
       curTable);
    else
	errAbort("describeSubtrackMerge: unrecognized op %s", op);
    }
struct slRef *tdbRef, *tdbRefList = trackDbListGetRefsToDescendantLeaves(curTrack->subtracks);
for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next)
    {
    tdb = tdbRef->val;
    if (!sameString(tdb->table, curTable) &&
	isSubtrackMerged(tdb->table) &&
	sameString(tdb->type, primary->type))
	{
	dyStringAppend(dy, linePrefix);
	dyStringPrintf(dy, "  %s (%s)\n", tdb->table, tdb->longLabel);
	}
    }
return dyStringCannibalize(&dy);
}
示例#6
0
struct bed *getRegionAsMergedBed(
	char *db, char *table, 	/* Database and table. */
	struct region *region,  /* Region to get data for. */
	char *filter, 		/* Filter to add to SQL where clause if any. */
	struct hash *idHash, 	/* Restrict to id's in this hash if non-NULL. */
	struct lm *lm,		/* Where to allocate memory. */
	int *retFieldCount)	/* Number of fields. */
/* Return a bed list of all items in the given range in subtrack-merged table.
 * Cleanup result via lmCleanup(&lm) rather than bedFreeList.  */
{
if (! anySubtrackMerge(db, table))
    return getRegionAsBed(db, table, region, filter, idHash, lm, retFieldCount);
else
    {
    struct hTableInfo *hti = getHtiOnDb(database, table);
    int chromSize = hChromSize(database, region->chrom);
    Bits *bits1 = NULL;
    Bits *bits2 = NULL;
    struct bed *bedMerged = NULL;
    struct trackDb *subtrack = NULL;
    char *primaryType = findTypeForTable(database,curTrack,table, ctLookupName);
    char *op = cartString(cart, hgtaSubtrackMergeOp);
    boolean isBpWise = (sameString(op, "and") || sameString(op, "or"));
    double moreThresh = cartDouble(cart, hgtaSubtrackMergeMoreThreshold);
    double lessThresh = cartDouble(cart, hgtaSubtrackMergeLessThreshold);
    boolean firstTime = TRUE;
    if (sameString(op, "cat"))
	{
	struct bed *bedList = getRegionAsBed(db, table, region, filter,
					     idHash, lm, retFieldCount);
	struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(curTrack->subtracks);
	struct slRef *tdbRef;
	for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next)
	    {
	    subtrack = tdbRef->val;
	    if (! sameString(curTable, subtrack->table) &&
		isSubtrackMerged(subtrack->table) &&
		sameString(subtrack->type, primaryType))
		{
		struct bed *bedList2 =
		    getRegionAsBed(db, subtrack->table, region, NULL,
				   idHash, lm, retFieldCount);
		bedList = slCat(bedList, bedList2);
		}
	    }
	slFreeList(&tdbRefList);
	return bedList;
	}
    bits1 = bitAlloc(chromSize+8);
    bits2 = bitAlloc(chromSize+8);
    /* If doing a base-pair-wise operation, then start with the primary
     * subtrack's ranges in bits1, and AND/OR all the selected subtracks'
     * ranges into bits1.  If doing a non-bp-wise intersection, then
     * start with all bits clear in bits1, and then OR selected subtracks'
     * ranges into bits1.  */
    if (isBpWise)
	{
	struct lm *lm2 = lmInit(64*1024);
	struct bed *bedList1 = getRegionAsBed(db, table, region, filter,
					      idHash, lm2, retFieldCount);
	bedOrBits(bits1, chromSize, bedList1, hti->hasBlocks, 0);
	lmCleanup(&lm2);
	}
    struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(curTrack->subtracks);
    struct slRef *tdbRef;
    for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next)
	{
	subtrack = tdbRef->val;
	if (! sameString(curTable, subtrack->table) &&
	    isSubtrackMerged(subtrack->table) &&
	    sameString(subtrack->type, primaryType))
	    {
	    struct hTableInfo *hti2 = getHtiOnDb(database, subtrack->table);
	    struct lm *lm2 = lmInit(64*1024);
	    struct bed *bedList2 =
		getRegionAsBed(db, subtrack->table, region, NULL, idHash,
			       lm2, NULL);
	    if (firstTime)
		firstTime = FALSE;
	    else
		bitClear(bits2, chromSize);
	    bedOrBits(bits2, chromSize, bedList2, hti2->hasBlocks, 0);
	    if (sameString(op, "and"))
		bitAnd(bits1, bits2, chromSize);
	    else
		bitOr(bits1, bits2, chromSize);
	    lmCleanup(&lm2);
	    }
	}
    slFreeList(&tdbRefList);
    if (isBpWise)
	{
	bedMerged = bitsToBed4List(bits1, chromSize, region->chrom, 1,
				   region->start, region->end, lm);
	if (retFieldCount != NULL)
	    *retFieldCount = 4;
	}
    else
	{
	struct bed *bedList1 = getRegionAsBed(db, table, region, filter,
					      idHash, lm, retFieldCount);
	bedMerged = filterBedByOverlap(bedList1, hti->hasBlocks, op,
				       moreThresh, lessThresh, bits1,
				       chromSize);
	}
    bitFree(&bits1);
    bitFree(&bits2);
    return bedMerged;
    }
}
示例#7
0
void showMainControlTable(struct sqlConnection *conn)
/* Put up table with main controls for main page. */
{
struct grp *selGroup;
boolean isWig = FALSE, isPositional = FALSE, isMaf = FALSE, isBedGr = FALSE,
        isChromGraphCt = FALSE, isPal = FALSE, isArray = FALSE, isBam = FALSE, isVcf = FALSE, isHalSnake = FALSE, isLongTabix = FALSE;
boolean gotClade = hGotClade();
struct hTableInfo *hti = NULL;

hPrintf("<TABLE BORDER=0>\n");

/* Print clade, genome and assembly line. */
    {
    if (gotClade)
        {
        hPrintf("<TR><TD><B>clade:</B>\n");
        printCladeListHtml(hGenome(database), onChangeClade());
        nbSpaces(3);
        hPrintf("<B>genome:</B>\n");
        printGenomeListForCladeHtml(database, onChangeOrg());
        }
    else
        {
        hPrintf("<TR><TD><B>genome:</B>\n");
        printGenomeListHtml(database, onChangeOrg());
        }
    nbSpaces(3);
    hPrintf("<B>assembly:</B>\n");
    printAssemblyListHtml(database, onChangeDb());
    hPrintf("</TD></TR>\n");
    }

/* Print group and track line. */
    {
    hPrintf("<TR><TD>");
    selGroup = showGroupField(hgtaGroup, onChangeGroupOrTrack(), conn, hAllowAllTables());
    nbSpaces(3);
    curTrack = showTrackField(selGroup, hgtaTrack, onChangeGroupOrTrack(), FALSE);
    nbSpaces(3);
    boolean hasCustomTracks = FALSE;
    struct trackDb *t;
    for (t = fullTrackList;  t != NULL;  t = t->next)
        {
        if (isCustomTrack(t->table))
            {
            hasCustomTracks = TRUE;
            break;
            }
        }
    hOnClickButton("document.customTrackForm.submit();return false;",
                   hasCustomTracks ? CT_MANAGE_BUTTON_LABEL : CT_ADD_BUTTON_LABEL);

    hPrintf(" ");
    if (hubConnectTableExists())
	hOnClickButton("document.trackHubForm.submit();return false;", "track hubs");

    hPrintf("</TD></TR>\n");
    }

/* Print table line. */
    {
    hPrintf("<TR><TD>");
    curTable = showTableField(curTrack, hgtaTable, TRUE);
    if (isHubTrack(curTable) || (strchr(curTable, '.') == NULL))  /* In same database */
        {
        hti = getHti(database, curTable, conn);
        isPositional = htiIsPositional(hti);
        }
    isLongTabix = isLongTabixTable( curTable);
    isBam = isBamTable( curTable);
    isVcf = isVcfTable(curTable, NULL);
    isWig = isWiggle(database, curTable);
    if (isBigWigTable(curTable))
        {
        isPositional = TRUE;
        isWig = TRUE;
        }
    isHalSnake = isHalTable( curTable);
    isMaf = isMafTable(database, curTrack, curTable);
    isBedGr = isBedGraph(curTable);
    isArray = isMicroarray(curTrack, curTable);
    struct trackDb *tdb = findTdbForTable(database, curTrack, curTable, ctLookupName);
    isPal = isPalCompatible(conn, tdb, curTable);
    nbSpaces(1);
    if (isCustomTrack(curTable))
        {
        isChromGraphCt = isChromGraph(tdb);
        }
    cgiMakeButton(hgtaDoSchema, "describe table schema");
    hPrintf("</TD></TR>\n");
    }

if (curTrack == NULL)
    {
    struct trackDb *tdb = hTrackDbForTrack(database, curTable);
    struct trackDb *cTdb = hCompositeTrackDbForSubtrack(database, tdb);
    if (cTdb)
        curTrack = cTdb;
    else
        curTrack = tdb;
    isMaf = isMafTable(database, curTrack, curTable);
    }

/* Region line */
{
char *regionType = cartUsualString(cart, hgtaRegionType, hgtaRegionTypeGenome);
char *range = cartUsualString(cart, hgtaRange, "");
if (isPositional)
    {
    boolean doEncode = FALSE; 

    if (!trackHubDatabase(database))
	doEncode = sqlTableExists(conn, "encodeRegions");

    hPrintf("<TR><TD><B>region:</B>\n");

    /* If regionType not allowed force it to "genome". */
    if ((sameString(regionType, hgtaRegionTypeUserRegions) &&
	 userRegionsFileName() == NULL) ||
	(sameString(regionType, hgtaRegionTypeEncode) && !doEncode))
	regionType = hgtaRegionTypeGenome;
    // Is "genome" is not allowed because of tdb 'tableBrowser noGenome'?
    boolean disableGenome = ((curTrack && cartTrackDbIsNoGenome(database, curTrack->table)) ||
                             (curTable && cartTrackDbIsNoGenome(database, curTable)));
    // If "genome" is selected but not allowed, force it to "range":
    if (sameString(regionType, hgtaRegionTypeGenome) && disableGenome)
        regionType = hgtaRegionTypeRange;
    jsTrackingVar("regionType", regionType);
    if (disableGenome)
        {
        makeRegionButtonExtraHtml(hgtaRegionTypeGenome, regionType, "DISABLED");
        hPrintf("&nbsp;<span"NO_GENOME_CLASS">genome (unavailable for selected track)</span>"
                "&nbsp;");
        }
    else
        {
        makeRegionButton(hgtaRegionTypeGenome, regionType);
        hPrintf("&nbsp;genome&nbsp;");
        }
    if (doEncode)
        {
	makeRegionButton(hgtaRegionTypeEncode, regionType);
	hPrintf("&nbsp;ENCODE Pilot regions&nbsp;");
	}
    makeRegionButton(hgtaRegionTypeRange, regionType);
    hPrintf("&nbsp;position&nbsp;");
    hPrintf("<INPUT TYPE=TEXT NAME=\"%s\" SIZE=26 VALUE=\"%s\" onFocus=\"%s\">\n",
    	hgtaRange, range, jsRadioUpdate(hgtaRegionType, "regionType", "range"));
    cgiMakeButton(hgtaDoLookupPosition, "lookup");
    hPrintf("&nbsp;");
    if (userRegionsFileName() != NULL)
	{
	makeRegionButton(hgtaRegionTypeUserRegions, regionType);
	hPrintf("&nbsp;defined regions&nbsp;");
	cgiMakeButton(hgtaDoSetUserRegions, "change");
	hPrintf("&nbsp;");
	cgiMakeButton(hgtaDoClearUserRegions, "clear");
	}
    else
	cgiMakeButton(hgtaDoSetUserRegions, "define regions");
    hPrintf("</TD></TR>\n");
    }
else
    {
    /* Need to put at least stubs of cgi variables in for JavaScript to work. */
    jsTrackingVar("regionType", regionType);
    cgiMakeHiddenVar(hgtaRange, range);
    cgiMakeHiddenVar(hgtaRegionType, regionType);
    }

/* Select identifiers line (if applicable). */
if (!isWig && getIdField(database, curTrack, curTable, hti) != NULL)
    {
    hPrintf("<TR><TD><B>identifiers (names/accessions):</B>\n");
    cgiMakeButton(hgtaDoPasteIdentifiers, "paste list");
    hPrintf(" ");
    cgiMakeButton(hgtaDoUploadIdentifiers, "upload list");
    if (identifierFileName() != NULL)
        {
	hPrintf("&nbsp;");
	cgiMakeButton(hgtaDoClearIdentifiers, "clear list");
	}
    hPrintf("</TD></TR>\n");
    }
}

/* microarray options */
/*   button for option page here (median/log-ratio, etc)  */

/* Filter line. */
{
hPrintf("<TR><TD><B>filter:</B>\n");
if (anyFilter())
    {
    cgiMakeButton(hgtaDoFilterPage, "edit");
    hPrintf(" ");
    cgiMakeButton(hgtaDoClearFilter, "clear");
    if (isWig || isBedGr)
	wigShowFilter(conn);
    }
else
    {
    cgiMakeButton(hgtaDoFilterPage, "create");
    }
hPrintf("</TD></TR>\n");
}

/* Composite track subtrack merge line. */
boolean canSubtrackMerge = (curTrack && tdbIsComposite(curTrack) && !isBam && !isVcf && !isLongTabix);
if (canSubtrackMerge)
    {
    hPrintf("<TR><TD><B>subtrack merge:</B>\n");
    if (anySubtrackMerge(database, curTable))
	{
	cgiMakeButton(hgtaDoSubtrackMergePage, "edit");
	hPrintf(" ");
	cgiMakeButton(hgtaDoClearSubtrackMerge, "clear");
	}
    else
	{
	cgiMakeButton(hgtaDoSubtrackMergePage, "create");
	}
    hPrintf("</TD></TR>\n");
    }

/* Intersection line. */
if (isPositional)
    {
    if (anyIntersection())
        {
	hPrintf("<TR><TD><B>intersection with %s:</B>\n",
		cartString(cart, hgtaIntersectTable));
	cgiMakeButton(hgtaDoIntersectPage, "edit");
	hPrintf(" ");
	cgiMakeButton(hgtaDoClearIntersect, "clear");
        hPrintf("</TD></TR>\n");
	}
    else if (canIntersect(database, curTable))
        {
	hPrintf("<TR><TD><B>intersection:</B>\n");
	cgiMakeButton(hgtaDoIntersectPage, "create");
        hPrintf("</TD></TR>\n");
	}
    }

/* Correlation line. */
struct trackDb *tdb = findTdbForTable(database, curTrack, curTable, ctLookupName);
if (correlateTrackTableOK(tdb, curTable))
    {
    char *table2 = cartUsualString(cart, hgtaCorrelateTable, "none");
    hPrintf("<TR><TD><B>correlation:</B>\n");
    if (differentWord(table2, "none") && strlen(table2) && ! isNoGenomeDisabled(database, table2))
        {
        struct grp *groupList = fullGroupList;
        struct grp *selGroup = findSelectedGroup(groupList, hgtaCorrelateGroup);
        struct trackDb *tdb2 = findSelectedTrack(fullTrackList, selGroup,hgtaCorrelateTrack);
        if (tdbIsComposite(tdb2))
            {
	    struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(tdb2->subtracks);
	    struct slRef *tdbRef;
	    for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next)
                {
		struct trackDb *subTdb = tdbRef->val;
                if (sameString(table2, subTdb->table))
                    {
                    tdb2 = subTdb;
                    break;
                    }
                }
	    slFreeList(&tdbRefList);
            }
        cgiMakeButton(hgtaDoCorrelatePage, "calculate");
        cgiMakeButton(hgtaDoClearCorrelate, "clear");
        if (tdb2 && tdb2->shortLabel)
            hPrintf("&nbsp;(with:&nbsp;&nbsp;%s)", tdb2->shortLabel);

#ifdef NOT_YET
        /* debugging 	dbg	vvvvv	*/
        if (curTrack && curTrack->type)		/*	dbg	*/
            {
            hPrintf("<BR>&nbsp;(debug:&nbsp;'%s',&nbsp;'%s(%s)')",
                    curTrack->type, tdb2->type, table2);
            }
        /* debugging 	debug	^^^^^	*/
#endif

        }
    else
        cgiMakeButton(hgtaDoCorrelatePage, "create");

    hPrintf("</TD></TR>\n");
    }

/* Print output type line. */
showOutputTypeRow(isWig, isBedGr, isPositional, isMaf, isChromGraphCt, isPal, isArray, isHalSnake);

/* Print output destination line. */
    {
    char *compressType =
	cartUsualString(cart, hgtaCompressType, textOutCompressNone);
    char *fileName = cartUsualString(cart, hgtaOutFileName, "");
    hPrintf("<TR><TD>\n");
    hPrintf("<B>output file:</B>&nbsp;");
    cgiMakeTextVar(hgtaOutFileName, fileName, 29);
    hPrintf("&nbsp;(leave blank to keep output in browser)</TD></TR>\n");
    hPrintf("<TR><TD>\n");
    hPrintf("<B>file type returned:&nbsp;</B>");
    cgiMakeRadioButton(hgtaCompressType, textOutCompressNone,
	sameWord(textOutCompressNone, compressType));
    hPrintf("&nbsp;plain text&nbsp&nbsp");
    cgiMakeRadioButton(hgtaCompressType, textOutCompressGzip,
	sameWord(textOutCompressGzip, compressType));
    hPrintf("&nbsp;gzip compressed");
    hPrintf("</TD></TR>\n");
    }

hPrintf("</TABLE>\n");


/* Submit buttons. */
    {
    hPrintf("<BR>\n");
    if (isWig || isBam || isVcf || isLongTabix)
	{
	char *name;
	extern char *maxOutMenu[];
	char *maxOutput = maxOutMenu[0];

	if (isCustomTrack(curTable))
	    name=filterFieldVarName("ct", curTable, "_", filterMaxOutputVar);
	else
	    name=filterFieldVarName(database,curTable, "_",filterMaxOutputVar);

	maxOutput = cartUsualString(cart, name, maxOutMenu[0]);

	if (isWig)
	    hPrintf(
		"<I>Note: to return more than %s lines, change the filter setting"
		" (above). The entire data set may be available for download as"
		" a very large file that contains the original data values (not"
		" compressed into the wiggle format) -- see the Downloads page."
		"</I><BR>", maxOutput);
	else if (isBam || isVcf || isLongTabix)
	    hPrintf(
		"<I>Note: to return more than %s lines, change the filter setting"
		" (above). Please consider downloading the entire data from our Download pages."
		"</I><BR>", maxOutput);
	}
    else if (anySubtrackMerge(database, curTable) || anyIntersection())
	{
	hPrintf("<I>Note: The all fields and selected fields output formats "
		"are not available when a%s has been specified.</I><BR>",
		canSubtrackMerge ? " subtrack merge or intersection" : "n intersection");
	}
    cgiMakeButton(hgtaDoTopSubmit, "get output");
    hPrintf(" ");
    if (isPositional || isWig)
	{
	cgiMakeButton(hgtaDoSummaryStats, "summary/statistics");
	hPrintf(" ");
	}

#ifdef SOMETIMES
    hPrintf(" ");
    cgiMakeButton(hgtaDoTest, "test");
#endif /* SOMETIMES */
    }
hPrintf("<P>"
	"To reset <B>all</B> user cart settings (including custom tracks), \n"
	"<A HREF=\"/cgi-bin/cartReset?destination=%s\">click here</A>.\n",
	getScriptName());

}