static void hgSeqDisplayOptions(struct cart *cart, boolean canDoUTR,
                                boolean canDoIntrons, boolean offerRevComp)
/* Print out HTML FORM entries for sequence display options. */
{
    char *casing, *repMasking;

    puts("\n<H3> Sequence Formatting Options: </H3>\n");

    casing = cartCgiUsualString(cart, "hgSeq.casing", "exon");
    if (canDoIntrons)
    {
        cgiMakeRadioButton("hgSeq.casing", "exon", sameString(casing, "exon"));
        if (canDoUTR)
            puts("Exons in upper case, everything else in lower case. <BR>");
        else
            puts("Blocks in upper case, everything else in lower case. <BR>");
    }
    if (canDoUTR)
    {
        if (sameString(casing, "exon") && !canDoIntrons)
            casing = "cds";
        cgiMakeRadioButton("hgSeq.casing", "cds", sameString(casing, "cds"));
        puts("CDS in upper case, UTR in lower case. <BR>");
    }
    if ((sameString(casing, "exon") && !canDoIntrons) ||
            (sameString(casing, "cds") && !canDoUTR))
        casing = "upper";
    cgiMakeRadioButton("hgSeq.casing", "upper", sameString(casing, "upper"));
    puts("All upper case. <BR>");
    cgiMakeRadioButton("hgSeq.casing", "lower", sameString(casing, "lower"));
    puts("All lower case. <BR>");

    cgiMakeCheckBox("hgSeq.maskRepeats",
                    cartCgiUsualBoolean(cart, "hgSeq.maskRepeats", FALSE));
    puts("Mask repeats: ");

    repMasking = cartCgiUsualString(cart, "hgSeq.repMasking", "lower");
    cgiMakeRadioButton("hgSeq.repMasking", "lower",
                       sameString(repMasking, "lower"));
    puts(" to lower case ");
    cgiMakeRadioButton("hgSeq.repMasking", "N", sameString(repMasking, "N"));
    puts(" to N <BR>");
    if (offerRevComp)
    {
        cgiMakeCheckBox("hgSeq.revComp",
                        cartCgiUsualBoolean(cart, "hgSeq.revComp", FALSE));
        puts("Reverse complement (get \'-\' strand sequence)");
    }
}
Beispiel #2
0
Bits *bitsForIntersectingTable(struct sqlConnection *conn, struct region *region, int chromSize,
	boolean isBpWise)
/* Get a bitmap that corresponds to the table we are intersecting with.
 * Consult CGI vars to figure out what table it is. */
{
boolean invTable2 = cartCgiUsualBoolean(cart, hgtaInvertTable2, FALSE);
char *table2 = cartString(cart, hgtaIntersectTable);
struct hTableInfo *hti2 = getHti(database, table2, conn);
struct lm *lm2 = lmInit(64*1024);
Bits *bits2 = bitAlloc(chromSize+8);
struct bed *bedList2;
if (isBigWigTable(table2))
    bedList2 = bigWigIntervalsToBed(conn, table2, region, lm2);
else
    // We should go straight to raw beds here, not through the routines that
    // do filter & intersections, because the secondary table has no filter
    // and sure shouldn't be intersected. :)
    bedList2 = getFilteredBeds(conn, table2, region, lm2, NULL);
if (!isBpWise)
    expandZeroSize(bedList2, hti2->hasBlocks, chromSize);
bedOrBits(bits2, chromSize, bedList2, hti2->hasBlocks, 0);
if (invTable2)
    bitNot(bits2, chromSize);
lmCleanup(&lm2);
return bits2;
}
Beispiel #3
0
static struct bed *bedTable2(struct sqlConnection *conn,
	struct region *region, char *table2)
/*	get a bed list, possibly complement, for table2	*/
{
/* This use of bedTable rather than a bitmap is not really working. The
 * rest of the table browser does intersection at the exon level, while
 * the wig code, which this is part of, does it at the gene level.  I
 * noticed it while working on the corresponding routines for bigWig,
 * which I'm building to work with bitmaps at the exon level.  I'm not
 * sure it's worth fixing this code since nobody has complained, and we're
 * probably going to be doing mostly bigWig rather than wig in the future.
 *    -JK */
boolean invTable2 = cartCgiUsualBoolean(cart, hgtaInvertTable2, FALSE);
char *op = cartString(cart, hgtaIntersectOp);
struct bed *bedList = NULL;
struct lm *lm1 = lmInit(64*1024);

/*	fetch table 2 as a bed list	*/
bedList = getFilteredBeds(conn, table2, region, lm1, NULL);

/*	If table 2 bed list needs to be complemented (!table2), then do so */
if (invTable2 || sameString("none", op))
    {
    unsigned chromStart = 0;		/*	start == end == 0	*/
    unsigned chromEnd = 0;		/*	means do full chrom	*/
    unsigned chromSize = hChromSize(database, region->chrom);
    struct lm *lm2 = lmInit(64*1024);
    struct bed *inverseBedList = NULL;		/*	new list	*/

    if ((region->start != 0) || (region->end != 0))
	{
	chromStart = region->start;
	chromEnd = region->end;
	}

    if ((struct bed *)NULL == bedList)
	{
	if (0 == region->end)
	    chromEnd = chromSize;
	addBedElement(&inverseBedList, region->chrom, chromStart, chromEnd,
		1, lm2);
	}
    else
	inverseBedList=invertBedList(bedList, lm2, region->chrom, chromStart,
	    chromEnd, chromSize);

    lmCleanup(&lm1);			/*	== bedFreeList(&bedList) */

    return inverseBedList;
    }
else
    return bedList;
}
Bits *bitsForIntersectingTable(struct sqlConnection *conn, struct region *region, int chromSize,
	boolean isBpWise)
/* Get a bitmap that corresponds to the table we are intersecting with.
 * Consult CGI vars to figure out what table it is. */
{
boolean invTable2 = cartCgiUsualBoolean(cart, hgtaInvertTable2, FALSE);
char *table2 = cartString(cart, hgtaIntersectTable);
struct hTableInfo *hti2 = getHti(database, table2, conn);
struct lm *lm2 = lmInit(64*1024);
Bits *bits2 = bitAlloc(chromSize+8);
struct bed *bedList2 = getFilteredBeds(conn, table2, region, lm2, NULL);
if (!isBpWise)
    expandZeroSize(bedList2, hti2->hasBlocks, chromSize);
bedOrBits(bits2, chromSize, bedList2, hti2->hasBlocks, 0);
if (invTable2)
    bitNot(bits2, chromSize);
lmCleanup(&lm2);
return bits2;
}
Beispiel #5
0
void doBedOrCtOptions(char *table, struct sqlConnection *conn,
                      boolean doCt)
/* Put up form to get options on BED or custom track output. */
/* (Taken from hgText.c/doBedCtOptions) */
{
char *table2 = NULL;	/* For now... */
struct hTableInfo *hti = getHti(database, table, conn);
char buf[256];
char *setting;
htmlOpen("Output %s as %s", table, (doCt ? "Custom Track" : "BED"));
if (doGalaxy())
    startGalaxyForm();
else if (doGreat())
    {
    verifyGreatAssemblies();
    startGreatForm();
    }
else
    hPrintf("<FORM ACTION=\"%s\" METHOD=GET>\n", getScriptName());
cartSaveSession(cart);
if (!doGreat())
{
    hPrintf("%s\n", "<TABLE><TR><TD>");
    if (doCt)
        {
        hPrintf("%s\n", "</TD><TD>"
                "<A HREF=\"../goldenPath/help/customTrack.html\" TARGET=_blank>"
                "Custom track</A> header: </B>");
        }
    else
        {
        cgiMakeCheckBox(hgtaPrintCustomTrackHeaders,
                        cartCgiUsualBoolean(cart, hgtaPrintCustomTrackHeaders, FALSE));
        hPrintf("%s\n", "</TD><TD> <B> Include "
                        "<A HREF=\"../goldenPath/help/customTrack.html\" TARGET=_blank>"
                        "custom track</A> header: </B>");
        }
    hPrintf("%s\n", "</TD></TR><TR><TD></TD><TD>name=");
    safef(buf, sizeof(buf), "tb_%s", hti->rootName);
    setting = cgiUsualString(hgtaCtName, buf);
    cgiMakeTextVar(hgtaCtName, setting, 16);
    hPrintf("%s\n", "</TD></TR><TR><TD></TD><TD>description=");
    safef(buf, sizeof(buf), "table browser query on %s%s%s",
          table, (table2 ? ", " : ""), (table2 ? table2 : ""));
    setting = cgiUsualString(hgtaCtDesc, buf);
    cgiMakeTextVar(hgtaCtDesc, setting, 50);
    hPrintf("%s\n", "</TD></TR><TR><TD></TD><TD>visibility=");
    if (isWiggle(database, table) || isBigWigTable(table))
        {
        setting = cartCgiUsualString(cart, hgtaCtVis, ctVisWigMenu[2]);
        cgiMakeDropList(hgtaCtVis, ctVisWigMenu, ctVisWigMenuSize, setting);
        }
    else
        {
        setting = cartCgiUsualString(cart, hgtaCtVis, ctVisMenu[3]);
        cgiMakeDropList(hgtaCtVis, ctVisMenu, ctVisMenuSize, setting);
        }
    hPrintf("%s\n", "</TD></TR><TR><TD></TD><TD>url=");
    setting = cartCgiUsualString(cart, hgtaCtUrl, "");
    cgiMakeTextVar(hgtaCtUrl, setting, 50);
    hPrintf("%s\n", "</TD></TR><TR><TD></TD><TD>");
    hPrintf("%s\n", "</TD></TR></TABLE>");
}
if (isWiggle(database, table) || isBedGraph(table) || isBigWigTable(table) )
    {
    char *setting = NULL;
    hPrintf("<P> <B> Select type of data output: </B> <BR>\n");
    setting = cartCgiUsualString(cart, hgtaCtWigOutType, outWigData);
    cgiMakeRadioButton(hgtaCtWigOutType, outWigBed, sameString(setting, outWigBed));
    hPrintf("BED format (no data value information, only position)<BR>\n");
    cgiMakeRadioButton(hgtaCtWigOutType, outWigData, sameString(setting, outWigData));
    hPrintf("DATA VALUE format (position and real valued data)</P>\n");
    }
else
    {
    cgiDown(0.9);
    hPrintf("<B> Create one BED record per: </B>\n");
    if ((anyIntersection() && intersectionIsBpWise()) ||
	(anySubtrackMerge(database, table) && subtrackMergeIsBpWise()))
	{
        /* The original table may have blocks/CDS, described in hti, but
         * that info will be lost after base pair-wise operations.  So make
         * a temporary copy of hti with its flags tweaked: */
	struct hTableInfo simplifiedHti;
	memcpy(&simplifiedHti, hti, sizeof(simplifiedHti));
	simplifiedHti.hasBlocks = FALSE;
	simplifiedHti.hasCDS = FALSE;
	fbOptionsHtiCart(&simplifiedHti, cart);
	}
    else
	fbOptionsHtiCart(hti, cart);
    }
if (doCt)
    {
    if (doGalaxy())
        {
        /* send the action parameter with the form as well */
        cgiMakeHiddenVar(hgtaDoGetCustomTrackFile, "get custom track in file");
        printGalaxySubmitButtons();
        }
    else
        {
        cgiMakeButton(hgtaDoGetCustomTrackTb, "get custom track in table browser");
        hPrintf(" ");
        cgiMakeButton(hgtaDoGetCustomTrackFile, "get custom track in file");
        hPrintf("<BR>\n");
        cgiMakeButton(hgtaDoGetCustomTrackGb, "get custom track in genome browser");
        }
    }
else
    {
    if (doGalaxy())
        {
        cgiMakeHiddenVar(hgtaDoGetBed, "get BED");
        printGalaxySubmitButtons();
        }
    else if (doGreat())
        {
        cgiMakeHiddenVar(hgtaDoGetBed, "get BED");
        printGreatSubmitButtons();
        }
    else
        cgiMakeButton(hgtaDoGetBed, "get BED");
    }
if (!doGalaxy() && !doGreat())
    {
    hPrintf(" ");
    cgiMakeButton(hgtaDoMainPage, "cancel");
    hPrintf("</FORM>\n");
    }
cgiDown(0.9);
htmlClose();
}
Beispiel #6
0
static struct bed *intersectOnRegion(
	struct sqlConnection *conn,	/* Open connection to database. */
	struct region *region, 		/* Region to work inside */
	char *table1,			/* Table input list is from. */
	struct bed *bedList1,	/* List before intersection, should be
	                                 * all within region. */
	struct lm *lm,	   /* Local memory pool. */
	int *retFieldCount)	   /* Field count. */
/* Intersect bed list, consulting CGI vars to figure out
 * with what table and how.  Return intersected result,
 * which is independent from input.  This potentially will
 * chew up bedList1. */
{
/* Grab parameters for intersection from cart. */
double moreThresh = cartCgiUsualDouble(cart, hgtaMoreThreshold, 0);
double lessThresh = cartCgiUsualDouble(cart, hgtaLessThreshold, 100);
boolean invTable = cartCgiUsualBoolean(cart, hgtaInvertTable, FALSE);
char *op = intersectOp();
/* --- TODO MIKE - replace bedList2, bits2 with baseMask stuff. */
/* Load up intersecting bedList2 (to intersect with) */
int chromSize = hChromSize(database, region->chrom);
boolean isBpWise = (sameString("and", op) || sameString("or", op));
Bits *bits2 = bitsForIntersectingTable(conn, region, chromSize, isBpWise);
/* Set up some other local vars. */
struct hTableInfo *hti1 = getHti(database, table1, conn);
struct bed *intersectedBedList = NULL;

/* Produce intersectedBedList. */
if (isBpWise)
    {
/* --- TODO MIKE - replace, bits1 with baseMask stuff. */
    /* Base-pair-wise operation: get bitmap  for primary table too */
    Bits *bits1 = bitAlloc(chromSize+8);
    boolean hasBlocks = hti1->hasBlocks;
    if (retFieldCount != NULL && (*retFieldCount < 12))
	hasBlocks = FALSE;
    bedOrBits(bits1, chromSize, bedList1, hasBlocks, 0);
    /* invert inputs if necessary */
    if (invTable)
	bitNot(bits1, chromSize);
    /* do the intersection/union */
    if (sameString("and", op))
	bitAnd(bits1, bits2, chromSize);
    else
	bitOr(bits1, bits2, chromSize);
    /* clip to region if necessary: */
    if (region->start > 0)
	bitClearRange(bits1, 0, region->start);
    if (region->end < chromSize)
	bitClearRange(bits1, region->end, (chromSize - region->end));
    /* translate back to bed */
    intersectedBedList = bitsToBed4List(bits1, chromSize,
    	region->chrom, 1, region->start, region->end, lm);
    if (retFieldCount != NULL)
	*retFieldCount = 4;
    bitFree(&bits1);
    }
else
    intersectedBedList = filterBedByOverlap(bedList1, hti1->hasBlocks, op,
					    moreThresh, lessThresh, bits2,
					    chromSize);
bitFree(&bits2);
return intersectedBedList;
}
Beispiel #7
0
void mafPrettyOut(FILE *f, struct mafAli *maf, int lineSize,
                  boolean onlyDiff, int blockNo)
{
int ii, ch;
int srcChars = 0;
struct mafComp *mc;
int lineStart, lineEnd;
char *summaryLine = needMem(lineSize+1);
char *referenceText;
int startChars, sizeChars, srcSizeChars;
boolean haveInserts = FALSE;
struct mafComp *masterMc = maf->components;

startChars = sizeChars = srcSizeChars = 0;

for (mc = maf->components; mc != NULL; mc = mc->next)
    {
    /* Figure out length of source (species) field. */
    /*if (mc->size != 0)*/
	{
	char dbOnly[128];
	int len;
	char *org;

	memset(dbOnly, 0, sizeof(dbOnly));
	safef(dbOnly, sizeof(dbOnly), "%s", mc->src);
	chopPrefix(dbOnly);

	if ((org = hOrganism(dbOnly)) == NULL)
	    len = strlen(dbOnly);
	else
	    len = strlen(org);
	if (srcChars < len)
	    srcChars = len;

	len = digitsBaseTen(mc->start);
	if (startChars < len)
	    startChars = len;
	len = digitsBaseTen(mc->size);
	if (sizeChars < len)
	    sizeChars = len;
	len = digitsBaseTen(mc->srcSize);
	if (srcSizeChars < len)
	    srcSizeChars = len;

	if (mc->text && (mc->rightStatus == MAF_INSERT_STATUS) && (masterMc->start + masterMc->size < winEnd))
	    haveInserts = TRUE;

#ifdef REVERSESTRAND
	/* complement bases if hgTracks is on reverse strand */
	if (mc->size && cartCgiUsualBoolean(cart, COMPLEMENT_BASES_VAR, FALSE))
	    complement(mc->text, maf->textSize);
#endif
	}
    }
/* first sequence in the alignment */
referenceText = maf->components->text;

for (lineStart = 0; lineStart < maf->textSize; lineStart = lineEnd)
    {
    int size;
    lineEnd = lineStart + lineSize;
    if (lineEnd >= maf->textSize)
        lineEnd = maf->textSize;
    size = lineEnd - lineStart;
    initSummaryLine(summaryLine, size, '*');
    for (mc = maf->components; mc != NULL; mc = mc->next)
        {
	char dbOnly[128], *chrom;
	int s = mc->start;
	int e = s + mc->size;
	char *org;
	char *revComp = "";
	char strand = mc->strand;
	struct dyString *dy = newDyString(512);
#ifdef REVERSESTRAND
	if (cartCgiUsualBoolean(cart, COMPLEMENT_BASES_VAR, FALSE))
	    strand = (strand == '+') ? '-' : '+';
#endif
	if (strand == '-') revComp = "&hgSeq.revComp=on";

	dyStringClear(dy);

	safef(dbOnly, sizeof(dbOnly), "%s", mc->src);
	chrom = chopPrefix(dbOnly);
	if ((org = hOrganism(dbOnly)) == NULL)
	    org = dbOnly;

	if (mc->strand == '-')
	    reverseIntRange(&s, &e, mc->srcSize);


	if (mc->text != NULL)
	    {
            if (lineStart == 0)
		{
		if (hDbIsActive(dbOnly))
		    {
		    dyStringPrintf(dy, "%s Browser %s:%d-%d %c %*dbps",hOrganism(dbOnly),chrom, s+1, e, mc->strand,sizeChars, mc->size);
		    linkToOtherBrowserTitle(dbOnly, chrom, s, e, dy->string);
		    dyStringClear(dy);
		    fprintf(f, "B</A> ");
		    }
		else
		    fprintf(f, "  ");

                if (hDbExists(dbOnly))
                    {
                    dyStringPrintf(dy, "Get %s DNA %s:%d-%d %c %*dbps",hOrganism(dbOnly),chrom, s+1, e, mc->strand,sizeChars, mc->size);
                    printf("<A TITLE=\"%s\" TARGET=\"_blank\" HREF=\"%s?o=%d&g=getDna&i=%s&c=%s&l=%d&r=%d&db=%s%s\">D</A> ",  dy->string,hgcName(),
                       s, cgiEncode(chrom),
                       chrom, s, e, dbOnly, revComp);
                    }
                else
                    fprintf(f, "  ");
                }
            else
                {
                fprintf(f, "    ");
                }

            dyStringClear(dy);
            dyStringPrintf(dy, "%s:%d-%d %c %*dbps",chrom, s+1, e, mc->strand,sizeChars, mc->size);
            fprintf(f, "<A TITLE=\"%s\"> %*s </A> ", dy->string, srcChars, org);

            updateSummaryLine(summaryLine, referenceText + lineStart, mc->text + lineStart, size);
            blueCapWrite(f, mc->text + lineStart, size,
			 (onlyDiff && mc != maf->components) ? referenceText + lineStart : NULL);
	    fprintf(f, "\n");
	    }
	else
	    {
	    if (((mc->leftStatus == MAF_CONTIG_STATUS) && (mc->rightStatus == MAF_CONTIG_STATUS) )
	    || ((mc->leftStatus == MAF_TANDEM_STATUS) && (mc->rightStatus == MAF_TANDEM_STATUS) )
	    || ((mc->leftStatus == MAF_INSERT_STATUS) && (mc->rightStatus == MAF_INSERT_STATUS) )
	    || ((mc->leftStatus == MAF_MISSING_STATUS) && (mc->rightStatus == MAF_MISSING_STATUS) ))
		{
                if (lineStart == 0)
		    {
		    int s = mc->start;
		    int e = s + mc->rightLen;
		    struct dyString *dy = newDyString(512);

		    if (mc->strand == '-')
			reverseIntRange(&s, &e, mc->srcSize);

		    if ( hDbIsActive(dbOnly))
			{
			dyStringPrintf(dy, "%s Browser %s:%d-%d %c %d bps Unaligned",hOrganism(dbOnly),chrom, s+1, e, mc->strand, e-s);
			linkToOtherBrowserTitle(dbOnly, chrom, s, e, dy->string);

			fprintf(f,"B</A> ");
			dyStringClear(dy);
			}
		    else
			fprintf(f,"  ");

                    if (hDbExists(dbOnly))
                        {
                        dyStringPrintf(dy, "Get %s DNA %s:%d-%d %c %d bps Unaligned",hOrganism(dbOnly),chrom, s+1, e, mc->strand, e-s);

                        printf("<A TITLE=\"%s\" TARGET=\"_blank\" HREF=\"%s?o=%d&g=getDna&i=%s&c=%s&l=%d&r=%d&db=%s%s\">D</A>  ", dy->string,  hgcName(),
                           s, cgiEncode(chrom),
                           chrom, s, e, dbOnly,revComp);
                        }
                    else
                        fprintf(f, "  ");
                    }
                else
		    fprintf(f, "     ");
		initSummaryLine(summaryLine, size, ' ');
		dyStringClear(dy);
		dyStringPrintf(dy, "%s:%d-%d %c %*dbps",chrom, s+1, e, mc->strand,sizeChars, mc->size);
		fprintf(f, "<A TITLE=\"%s\">%*s</A>  ", dy->string, srcChars, org);
		ch = '-';
		switch(mc->rightStatus)
		    {
		    case MAF_INSERT_STATUS:
			ch = '=';
			break;
		    case MAF_MISSING_STATUS:
			ch = 'N';
			break;
		    case MAF_TANDEM_STATUS:
		    case MAF_CONTIG_STATUS:
			ch = '-';
			break;
		    }
		for(ii=lineStart; ii < lineEnd ; ii++)
		    fputc(ch,f);
		fprintf(f,"\n");
		}
	    }
	}
#ifdef ADDMATCHLINE
    if (lineStart == 0)
	fprintf(f, "    %-*s %s\n", srcChars, "", summaryLine);
    else
	fprintf(f, "%-*s %s\n", srcChars, "", summaryLine);
#else
    fprintf(f, "\n");
#endif
    }

if (haveInserts)
    {
    fprintf(f, "<B>Inserts between block %d and %d in window</B>\n",blockNo, blockNo+1);
    for (mc = maf->components; mc != NULL; mc = mc->next)
	{
	char dbOnly[128], *chrom;
	int s = mc->start + mc->size;
	int e = s + mc->rightLen;
	char *org;

	if (mc->text == NULL)
	    continue;

	if (mc->strand == '-')
	    reverseIntRange(&s, &e, mc->srcSize);

	safef(dbOnly, sizeof(dbOnly), "%s", mc->src);
	chrom = chopPrefix(dbOnly);

	if ((org = hOrganism(dbOnly)) == NULL)
	    org = dbOnly;

	if (mc->rightStatus == MAF_INSERT_STATUS)
	    {
	    char *revComp = "";
	    if (hDbIsActive(dbOnly))
		{
		char strand = mc->strand;
#ifdef REVERSESTRAND
		if (cartCgiUsualBoolean(cart, COMPLEMENT_BASES_VAR, FALSE))
		    strand = (strand == '+') ? '-' : '+';
#endif
		if (strand == '-') revComp = "&hgSeq.revComp=on";

		linkToOtherBrowser(dbOnly, chrom, s, e);
		fprintf(f,"B");
		fprintf(f, "</A>");
		fprintf(f, " ");

		}
	    else
		fprintf(f, "  ");

            if (hDbExists(dbOnly))
                {
                printf("<A TARGET=\"_blank\" HREF=\"%s?o=%d&g=getDna&i=%s&c=%s&l=%d&r=%d"
                       "&db=%s%s\">D</A> ",  hgcName(), s, cgiEncode(chrom), chrom,  s,
                       e, dbOnly,revComp);
                }
            else
		fprintf(f, "  ");
            fprintf(f, "%*s %dbp\n", srcChars, org,mc->rightLen);
	    }
	}
    fprintf(f, "\n");
    }
freeMem(summaryLine);

}
Beispiel #8
0
static void mafOrAxtClick2(struct sqlConnection *conn, struct sqlConnection *conn2, struct trackDb *tdb, char *axtOtherDb, char *fileName)
/* Display details for MAF or AXT tracks. */
{
hgBotDelay();
if (winEnd - winStart > 30000)
    {
    printf("Zoom so that window is 30,000 bases or less to see alignments and conservation statistics\n");
    }
else
    {
    struct mafAli *mafList = NULL, *maf, *subList = NULL;
    int aliIx = 0, realCount = 0;
    char dbChrom[64];
    char option[128];
    char *capTrack;
    struct consWiggle *consWig, *consWiggles;
    struct hash *speciesOffHash = NULL;
    char *speciesOrder = NULL;
    char *speciesTarget = trackDbSetting(tdb, SPECIES_TARGET_VAR);
    char buffer[1024];
    int useTarg = FALSE;
    int useIrowChains = FALSE;

    safef(option, sizeof(option), "%s.%s", tdb->track, MAF_CHAIN_VAR);
    if (cartCgiUsualBoolean(cart, option, FALSE) &&
	trackDbSetting(tdb, "irows") != NULL)
	    useIrowChains = TRUE;

    safef(buffer, sizeof(buffer), "%s.vis",tdb->track);
    if (useIrowChains)
	{
	if (!cartVarExists(cart, buffer) && (speciesTarget != NULL))
	    useTarg = TRUE;
	else
	    {
	    char *val;

	    val = cartUsualString(cart, buffer, "useCheck");
            useTarg = sameString("useTarg",val);
            }
        }

    if (sameString(tdb->type, "bigMaf"))
        {
        char *fileName = trackDbSetting(tdb, "bigDataUrl");
        struct bbiFile *bbi = bigBedFileOpen(fileName);
        mafList = bigMafLoadInRegion(bbi, seqName, winStart, winEnd);
        }
    else
        mafList = mafOrAxtLoadInRegion2(conn,conn2, tdb, seqName, winStart, winEnd,
                                        axtOtherDb, fileName);
    safef(dbChrom, sizeof(dbChrom), "%s.%s", hubConnectSkipHubPrefix(database), seqName);

    safef(option, sizeof(option), "%s.speciesOrder", tdb->track);
    speciesOrder = cartUsualString(cart, option, NULL);
    if (speciesOrder == NULL)
	speciesOrder = trackDbSetting(tdb, "speciesOrder");

    for (maf = mafList; maf != NULL; maf = maf->next)
        {
        int mcCount = 0;
        struct mafComp *mc;
        struct mafAli *subset;
        struct mafComp *nextMc;

        /* remove empty components and configured off components
         * from MAF, and ignore
         * the entire MAF if all components are empty
         * (solely for gap annotation) */

        if (!useTarg)
            {
            for (mc = maf->components->next; mc != NULL; mc = nextMc)
		{
		char buf[64];
                char *organism;
		mafSrcDb(mc->src, buf, sizeof buf);
                organism = hOrganism(buf);
                if (!organism)
                    organism = buf;
		nextMc = mc->next;
		safef(option, sizeof(option), "%s.%s", tdb->track, buf);
		if (!cartUsualBoolean(cart, option, TRUE))
		    {
		    if (speciesOffHash == NULL)
			speciesOffHash = newHash(4);
		    hashStoreName(speciesOffHash, organism);
		    }
		if (!cartUsualBoolean(cart, option, TRUE))
		    slRemoveEl(&maf->components, mc);
		else
		    mcCount++;
		}
	    }
        if (mcCount == 0)
            continue;

	if (speciesOrder)
	    {
	    int speciesCt;
	    char *species[2048];
	    struct mafComp **newOrder, *mcThis;
	    int i;

	    mcCount = 0;
	    speciesCt = chopLine(cloneString(speciesOrder), species);
	    newOrder = needMem((speciesCt + 1) * sizeof (struct mafComp *));
	    newOrder[mcCount++] = maf->components;

	    for (i = 0; i < speciesCt; i++)
		{
		if ((mcThis = mafMayFindCompSpecies(maf, species[i], '.')) == NULL)
		    continue;
		newOrder[mcCount++] = mcThis;
		}

	    maf->components = NULL;
	    for (i = 0; i < mcCount; i++)
		{
		newOrder[i]->next = 0;
		slAddHead(&maf->components, newOrder[i]);
		}

	    slReverse(&maf->components);
	    }
	subset = mafSubsetE(maf, dbChrom, winStart, winEnd, TRUE);
	if (subset != NULL)
	    {
	    /* Reformat MAF if needed so that sequence from current
	     * database is the first component and on the
	     * plus strand. */
	    mafMoveComponentToTop(subset, dbChrom);
	    if (subset->components->strand == '-')
		mafFlipStrand(subset);
	    subset->score = mafScoreMultiz(subset);
	    slAddHead(&subList, subset);
	    ++realCount;
	    }
	}
    slReverse(&subList);
    mafAliFreeList(&mafList);
    if (subList != NULL)
	{
	char *showVarName = "hgc.showMultiBase";
	char *showVarVal = cartUsualString(cart, showVarName, "all");
	boolean onlyDiff = sameWord(showVarVal, "diff");
#ifdef ADDEXONCAPITAL
	char *codeVarName = "hgc.multiCapCoding";
	char *codeVarVal = cartUsualString(cart, codeVarName, "coding");
	boolean onlyCds = sameWord(codeVarVal, "coding");
#endif
        /* add links for conservation score statistics */
        consWiggles = wigMafWiggles(database, tdb);
        int wigCount = slCount(consWiggles);
        if (wigCount == 1)
            {
            conservationStatsLink(tdb, "Conservation score statistics", consWiggles->table);
            }
        else if (wigCount > 1)
            {
            /* multiple wiggles. List all that have been turned on with
             * checkboxes */

            /* Scan for cart variables -- do any exist, are any turned on ? */
            boolean wigSet = FALSE;
            boolean wigOn = FALSE;
            for (consWig = consWiggles; consWig != NULL;
                        consWig = consWig->next)
                {
                char *wigVarSuffix = NULL;
                (void)wigMafWiggleVar(tdb->track, consWig, &wigVarSuffix);
                if (cartVarExistsAnyLevel(cart, tdb, FALSE, wigVarSuffix))
                    {
                    wigSet = TRUE;
                    if (cartBooleanClosestToHome(cart, tdb, FALSE, wigVarSuffix))
                        wigOn = TRUE;
                    }
                }
            /* If there are no cart vars, turn on the first (default) wig */
            if (!wigSet)
                {
                char *prefix = tdb->track; // use when setting things to the cart
                if (tdbIsContainerChild(tdb))
                    prefix = tdbGetContainer(tdb)->track;

                cartSetBoolean(cart, wigMafWiggleVar(prefix, consWiggles, NULL), TRUE);
                wigOn = TRUE;
                }
            if (wigOn)
                {
                boolean first = TRUE;
                for (consWig = consWiggles; consWig != NULL;
                            consWig = consWig->next)
                    {
                    if (first)
                        {
                        printf("Conservation score statistics:");
                        first = FALSE;
                        }
                    char *wigVarSuffix = NULL;
                    (void)wigMafWiggleVar(tdb->track, consWig, &wigVarSuffix);
                    if (cartUsualBooleanClosestToHome(cart, tdb, FALSE, wigVarSuffix,FALSE))
                        {
                        printf("&nbsp;&nbsp;");
                        subChar(consWig->uiLabel, '_', ' ');
                        conservationStatsLink(tdb,
                            consWig->uiLabel, consWig->table);
                        }
                    }
                }
            }
        puts("</P>\n");

        /* no alignment to display when in visibilities where only wiggle is shown */
        char *vis = cartOptionalString(cart, tdb->track);
        if (vis)
            {
            enum trackVisibility tv = hTvFromStringNoAbort(vis);
            if (tv == tvSquish || tv == tvDense)
                return;
            }

#ifdef ADDEXONCAPITAL
	puts("<FORM ACTION=\"../cgi-bin/hgc\" NAME=\"gpForm\" METHOD=\"GET\">");
	cartSaveSession(cart);
	cgiContinueHiddenVar("g");
	cgiContinueHiddenVar("c");
	cgiContinueHiddenVar("i");
	printf("Capitalize ");
        cgiMakeDropListFull(codeVarName, codeAll, codeAll,
	    ArraySize(codeAll), codeVarVal, autoSubmit);
	printf("exons based on ");
        capTrack = genePredDropDown(cart, trackHash,
                                       "gpForm", "hgc.multiCapTrack");
#endif
	printf("show ");
        cgiMakeDropListFull(showVarName, showAll, showAll,
	    ArraySize(showAll), showVarVal, autoSubmit);
	printf("bases");
	printf("<BR>\n");
	printf("</FORM>\n");

#ifdef REVERSESTRAND
        /* notify if bases are complemented (hgTracks is on reverse strand) */
        if (cartCgiUsualBoolean(cart, COMPLEMENT_BASES_VAR, FALSE))
            puts("<EM>Alignment displayed on reverse strand</EM><BR>");
#endif
	puts("Place cursor over species for alignment detail. Click on 'B' to link to browser ");
	puts("for aligned species, click on 'D' to get DNA for aligned species.<BR>");

	printf("<TT><PRE>");

        /* notify if species removed from alignment */
        if (speciesOffHash) 
            {
            char *species;
            struct hashCookie hc = hashFirst(speciesOffHash);
            puts("<B>Components not displayed:</B> ");
            while ((species = hashNextName(&hc)) != NULL)
                printf("%s ", species);
            puts("<BR>");
            }


	for (maf = subList; maf != NULL; maf = maf->next)
	    {
	    mafLowerCase(maf);
#ifdef ADDEXONCAPITAL
	    if (capTrack != NULL)
                capMafOnTrack(maf, capTrack, onlyCds);
#endif
            printf("<B>Alignment block %d of %d in window, %d - %d, %d bps </B>\n",
                   ++aliIx,realCount,maf->components->start + 1,
                   maf->components->start + maf->components->size, maf->components->size);
            mafPrettyOut(stdout, maf, 70,onlyDiff, aliIx);
            }
	mafAliFreeList(&subList);
	}
    else
	{
        printf("No multiple alignment in browser window");
	}
    printf("</PRE></TT>");
    }
}
static void hgSeqFeatureRegionOptions(struct cart *cart, boolean canDoUTR,
                                      boolean canDoIntrons)
/* Print out HTML FORM entries for feature region options. */
{
    char *exonStr = canDoIntrons ? " Exons" : "";
    char *setting;

    puts("\n<H3> Sequence Retrieval Region Options: </H3>\n");

    if (canDoIntrons || canDoUTR)
    {
        cgiMakeCheckBox("hgSeq.promoter",
                        cartCgiUsualBoolean(cart, "hgSeq.promoter", FALSE));
        puts("Promoter/Upstream by ");
        setting = cartCgiUsualString(cart, "hgSeq.promoterSize", "1000");
        cgiMakeTextVar("hgSeq.promoterSize", setting, 5);
        puts("bases <BR>");
    }

    if (canDoUTR)
    {
        cgiMakeCheckBox("hgSeq.utrExon5",
                        cartCgiUsualBoolean(cart, "hgSeq.utrExon5", TRUE));
        printf("5' UTR%s <BR>\n", exonStr);
    }

    if (canDoIntrons)
    {
        cgiMakeCheckBox("hgSeq.cdsExon",
                        cartCgiUsualBoolean(cart, "hgSeq.cdsExon", TRUE));
        if (canDoUTR)
            printf("CDS Exons <BR>\n");
        else
            printf("Blocks <BR>\n");
    }
    else if (canDoUTR)
    {
        cgiMakeCheckBox("hgSeq.cdsExon",
                        cartCgiUsualBoolean(cart, "hgSeq.cdsExon", TRUE));
        printf("CDS <BR>\n");
    }
    else
    {
        cgiMakeHiddenVar("hgSeq.cdsExon", "1");
    }

    if (canDoUTR)
    {
        cgiMakeCheckBox("hgSeq.utrExon3",
                        cartCgiUsualBoolean(cart, "hgSeq.utrExon3", TRUE));
        printf("3' UTR%s <BR>\n", exonStr);
    }

    if (canDoIntrons)
    {
        cgiMakeCheckBox("hgSeq.intron",
                        cartCgiUsualBoolean(cart, "hgSeq.intron", TRUE));
        if (canDoUTR)
            puts("Introns <BR>");
        else
            puts("Regions between blocks <BR>");
    }

    if (canDoIntrons || canDoUTR)
    {
        cgiMakeCheckBox("hgSeq.downstream",
                        cartCgiUsualBoolean(cart, "hgSeq.downstream", FALSE));
        puts("Downstream by ");
        setting = cartCgiUsualString(cart, "hgSeq.downstreamSize", "1000");
        cgiMakeTextVar("hgSeq.downstreamSize", setting, 5);
        puts("bases <BR>");
    }

    if (canDoIntrons || canDoUTR)
    {
        setting = cartCgiUsualString(cart, "hgSeq.granularity", "gene");
        cgiMakeRadioButton("hgSeq.granularity", "gene",
                           sameString(setting, "gene"));
        if (canDoUTR)
            puts("One FASTA record per gene. <BR>");
        else
            puts("One FASTA record per item. <BR>");
        cgiMakeRadioButton("hgSeq.granularity", "feature",
                           sameString(setting, "feature"));
        if (canDoUTR)
            puts("One FASTA record per region (exon, intron, etc.) with ");
        else
            puts("One FASTA record per region (block/between blocks) with ");
    }
    else
    {
        puts("Add ");
    }
    setting = cartCgiUsualString(cart, "hgSeq.padding5", "0");
    cgiMakeTextVar("hgSeq.padding5", setting, 5);
    puts("extra bases upstream (5') and ");
    setting = cartCgiUsualString(cart, "hgSeq.padding3", "0");
    cgiMakeTextVar("hgSeq.padding3", setting, 5);
    puts("extra downstream (3') <BR>");
    if (canDoIntrons && canDoUTR)
    {
        puts("&nbsp;&nbsp;&nbsp;");
        cgiMakeCheckBox("hgSeq.splitCDSUTR",
                        cartCgiUsualBoolean(cart, "hgSeq.splitCDSUTR", FALSE));
        puts("Split UTR and CDS parts of an exon into separate FASTA records");
    }
    puts("<BR>\n");
    puts("Note: if a feature is close to the beginning or end of a chromosome \n"
         "and upstream/downstream bases are added, they may be truncated \n"
         "in order to avoid extending past the edge of the chromosome. <P>");
}
void doMiddle(struct cart *theCart)
/* Set up globals and make web page */
{
/* struct liftOverChain *chainList = NULL, *chain; */
char *userData;
/* char *dataFile; */
char *dataFormat;
char *organism;
char *db;
float minBlocks, minMatch;
boolean multiple, fudgeThick;
int minSizeQ, minSizeT;
boolean refreshOnly = FALSE;

/* char *err = NULL; */
struct liftOverChain *chainList = NULL, *choice;

cart = theCart;

if (cgiOptionalString(HGLFT_ERRORHELP_VAR))
    {
    puts("<PRE>");
    puts(liftOverErrHelp());
    //system("/usr/bin/cal");
    puts("</PRE>");
    return;
    }

/* Get data to convert - from userData variable, or if 
 * that is empty from a file. */

if (cartOptionalString(cart, "SubmitFile"))
    userData = cartOptionalString(cart, HGLFT_DATAFILE_VAR);
else
    userData = cartOptionalString(cart, HGLFT_USERDATA_VAR);
dataFormat = cartCgiUsualString(cart, HGLFT_DATAFORMAT_VAR, DEFAULT_FORMAT);
cartWebStart(cart, NULL, "Lift Genome Annotations");

getDbAndGenome(cart, &db, &organism, oldVars);

chainList = liftOverChainListFiltered();

choice = defaultChoices(chainList, db);
if (choice == NULL)
    errAbort("Sorry, no conversions available from this assembly\n");

minSizeQ = cartCgiUsualInt(cart, HGLFT_MINSIZEQ, choice->minSizeQ);
minSizeT = cartCgiUsualInt(cart, HGLFT_MINSIZET, choice->minSizeT);
minBlocks = cartCgiUsualDouble(cart, HGLFT_MINBLOCKS, choice->minBlocks);
minMatch = cartCgiUsualDouble(cart, HGLFT_MINMATCH, choice->minMatch);
fudgeThick = cartCgiUsualBoolean(cart, HGLFT_FUDGETHICK, (choice->fudgeThick[0]=='Y') ? TRUE : FALSE);
multiple = cartCgiUsualBoolean(cart, HGLFT_MULTIPLE, (choice->multiple[0]=='Y') ? TRUE : FALSE);
refreshOnly = cartCgiUsualInt(cart, HGLFT_REFRESHONLY_VAR, 0);

webMain(choice, dataFormat, multiple);
liftOverChainFreeList(&chainList);

if (!refreshOnly && userData != NULL && userData[0] != '\0')
    {
    struct hash *chainHash = newHash(0);
    char *chainFile;
    struct tempName oldTn, mappedTn, unmappedTn;
    FILE *old, *mapped, *unmapped;
    char *line;
    int lineSize;
    char *fromDb, *toDb;
    int ct = 0, errCt = 0;

    /* read in user data and save to file */
    makeTempName(&oldTn, HGLFT, ".user");
    old = mustOpen(oldTn.forCgi, "w");
    fputs(userData, old);
    fputs("\n", old);           /* in case user doesn't end last line */
    carefulClose(&old);
    chmod(oldTn.forCgi, 0666);

    /* setup output files -- one for converted lines, the other
     * for lines that could not be mapped */
    makeTempName(&mappedTn, HGLFT, ".bed");
    makeTempName(&unmappedTn, HGLFT, ".err");
    mapped = mustOpen(mappedTn.forCgi, "w");
    chmod(mappedTn.forCgi, 0666);
    unmapped = mustOpen(unmappedTn.forCgi, "w");
    chmod(unmappedTn.forCgi, 0666);

    fromDb = cgiString(HGLFT_FROMDB_VAR);
    toDb = cgiString(HGLFT_TODB_VAR);
    chainFile = liftOverChainFile(fromDb, toDb);
    if (chainFile == NULL)
        errAbort("ERROR: Can't convert from %s to %s: no chain file loaded",
                                fromDb, toDb);
    readLiftOverMap(chainFile, chainHash);
    if (sameString(dataFormat, WIGGLE_FORMAT))
        /* TODO: implement Wiggle */
	{}
    else if (sameString(dataFormat, POSITION_FORMAT))
	{
	/* minSizeT here and in liftOverChain.c/h has been renamed minChainT in liftOver.c */
	/* ignore multiple, it must be false when position is used */
	ct = liftOverPositions(oldTn.forCgi, chainHash, 
			minMatch, minBlocks, 0, minSizeQ,
			minSizeT, 0, 
			fudgeThick, mapped, unmapped, FALSE, NULL, &errCt);

	
        }
    else if (sameString(dataFormat, BED_FORMAT))
        {
	/* minSizeT here and in liftOverChain.c/h has been renamed minChainT in liftOver.c */
        ct = liftOverBed(oldTn.forCgi, chainHash, 
			minMatch, minBlocks, 0, minSizeQ,
			minSizeT, 0,
			fudgeThick, mapped, unmapped, multiple, NULL, &errCt);
        }
    else
        /* programming error */
        errAbort("ERROR: Unsupported data format: %s\n", dataFormat);

    webNewSection("Results");
    if (ct)
        {
        /* some records succesfully converted */
        cgiParagraph("");
        printf("Successfully converted %d record", ct);
        printf("%s: ", ct > 1 ? "s" : "");
        printf("<A HREF=%s TARGET=_blank>View Conversions</A>\n", mappedTn.forCgi);
        }
    if (errCt)
        {
        /* some records not converted */
        cgiParagraph("");
        printf("Conversion failed on %d record", errCt);
        printf("%s. &nbsp;&nbsp;&nbsp;", errCt > 1 ? "s" : "");
        printf("<A HREF=%s TARGET=_blank>Display failure file</A>&nbsp; &nbsp;\n",
                         unmappedTn.forCgi);
        printf("<A HREF=\"../cgi-bin/hgLiftOver?%s=1\" TARGET=_blank>Explain failure messages</A>\n", HGLFT_ERRORHELP_VAR);
        puts("<P>Failed input regions:\n");
        struct lineFile *errFile = lineFileOpen(unmappedTn.forCgi, TRUE);
        puts("<BLOCKQUOTE><PRE>\n");
        while (lineFileNext(errFile, &line, &lineSize))
            puts(line);
        lineFileClose(&errFile);
        puts("</PRE></BLOCKQUOTE>\n");
        }
    if (sameString(dataFormat, POSITION_FORMAT) && multiple)
	{
        puts("<BLOCKQUOTE><PRE>\n");
        puts("Note: multiple checkbox ignored since it is not supported for position format.");
        puts("</PRE></BLOCKQUOTE>\n");
	}
    carefulClose(&unmapped);
    }
webDataFormats();
webDownloads();
cartWebEnd();
}