Ejemplo n.º 1
0
void addVersion(boolean strict, char *database, char *dirName, char *raName,
                struct hash *uniqHash,
                struct hash *htmlHash,
                struct hgFindSpec **pSpecList)
/* Read in specs from raName and add them to list/database if new. */
{
    struct hgFindSpec *hfsList = NULL, *hfs = NULL;
    struct hgFindSpec *hfsNext = NULL;

    hfsList = hgFindSpecFromRa(database, raName, NULL);

    /* prune records of the incorrect release */
    hfsList = pruneRelease(hfsList);

    if (strict)
    {
        for (hfs = hfsList; hfs != NULL; hfs = hfsNext)
        {
            hfsNext = hfs->next;
            if (! hTableOrSplitExists(database, hfs->searchTable))
            {
                if (verboseLevel() > 1)
                    printf("%s missing\n", hfs->searchTable);
                slRemoveEl(&hfsList, hfs);
            }
            else if (hfs->xrefTable[0] != 0)
            {
                // Use sqlTableExists because xrefTable might be $db.$table,
                // not supported by hTableExists / hTableOrSplitExists
                // NOTE hfs->xrefTable can sometimes contain a comma-separated table list,
                // rather than just a single table.
                struct sqlConnection *conn = hAllocConn(database);
                char *tables = replaceChars(hfs->xrefTable, ",", " ");
                boolean exists = sqlTablesExist(conn, tables);
                hFreeConn(&conn);
                freeMem(tables);
                if (! exists)
                {
                    if (verboseLevel() > 1)
                        printf("%s (xref) missing\n", hfs->xrefTable);
                    slRemoveEl(&hfsList, hfs);
                }
            }
        }
    }

    for (hfs = hfsList; hfs != NULL; hfs = hfsNext)
    {
        hfsNext = hfs->next;
        if (! hashLookup(uniqHash, hfs->searchName))
        {
            hashAdd(uniqHash, hfs->searchName, hfs);
            slAddHead(pSpecList, hfs);
        }
    }
}
Ejemplo n.º 2
0
void checkAllBeds(struct bed **bedList, int expCount)
/** check to make sure that all the beds have the same
    number of experiments associated with them */
{
struct bed *bed = NULL;
for(bed = *bedList; bed != NULL; )
    {
    if(bed->expCount != expCount)
	{
	struct bed *tmp = NULL;
	if(bed->expCount != 0)
	    {
	    warn("Bed %s at %d has only %d exps, mark is %d", bed->name, slIxFromElement(*bedList, bed), bed->expCount, expCount);
	    missingExpsCount++;
	    }
	else
	    noExpCount++;
	tmp = bed->next;
	slRemoveEl(bedList, bed);
	bed = tmp;
	}
    else
	bed = bed->next;
    }
}
Ejemplo n.º 3
0
void mafMoveComponentToTop(struct mafAli *maf, char *componentSource)
/* Move given component to head of component list. */
{
struct mafComp *mcMaster = mafFindComponent(maf, componentSource);
slRemoveEl(&maf->components, mcMaster);
slAddHead(&maf->components, mcMaster);
}
void mafMeFirst(char *inMaf, char *meFile, char *outMaf)
/* mafMeFirst - Move component to top if it is one of the named ones.  Useful 
 * in conjunction with mafFrags when you don't want the one with the gene name 
 * to be in the middle.. */
{
struct hash *meHash = hashWordsInFile(meFile, 18);
struct mafFile *mf = mafOpen(inMaf);
FILE *f = mustOpen(outMaf, "w");
mafWriteStart(f, mf->scoring);
struct mafAli *maf;
while ((maf = mafNext(mf)) != NULL)
    {
    struct mafComp *comp = compInHash(maf, meHash);
    if (comp == NULL)
        errAbort("No components in %s in maf ending line %d of %s",
		meFile, mf->lf->lineIx, mf->lf->fileName);
    slRemoveEl(&maf->components, comp);
    slAddHead(&maf->components, comp);
    mafWrite(f, maf);
    mafAliFree(&maf);
    }

mafWriteEnd(f);
carefulClose(&f);
}
Ejemplo n.º 5
0
static void moveMeToFirst(struct mafAli *maf, char *myName)
/* Find component matching myName, and move it to first. */
{
struct mafComp *comp = mafMayFindCompPrefix(maf, myName, ".");
if (NULL == comp)
    comp = mafFindCompPrefix(maf, myName, NULL);
slRemoveEl(&maf->components, comp);
slAddHead(&maf->components, comp);
}
Ejemplo n.º 6
0
struct vFile *moveToHead(struct vFile *newHead, struct vFile *list)
/* Move newHead to head of list */
{
if (newHead != list)
     {
     slRemoveEl(&list, newHead);
     newHead->next = list;
     }
return newHead;
}
void moveMeToFirst(struct mafAli *maf, char *myName)
/* Find component matching myName, and move it to first. */
{
struct mafComp *comp;
for (comp = maf->components; comp != NULL; comp = comp->next)
    if (sameString(comp->src, myName))
        break;
assert(comp != NULL);
slRemoveEl(&maf->components, comp);
slAddHead(&maf->components, comp);
}
Ejemplo n.º 8
0
static void mafFrags(char *database, char *track, char *bedFile, char *mafFile)
/* mafFrags - Collect MAFs from regions specified in a 6 column bed file. */
{
struct slName *orgList = NULL;
struct lineFile *lf = lineFileOpen(bedFile, TRUE);
FILE *f = mustOpen(mafFile, "w");

if (optionExists("orgs"))
    {
    char *orgFile = optionVal("orgs", NULL);
    char *buf;
    readInGulp(orgFile, &buf, NULL);
    orgList = stringToSlNames(buf);

    /* Ensure that org list starts with database. */
    struct slName *me = slNameFind(orgList, database);
    if (me == NULL)
        errAbort("Need to have reference database '%s' in %s", database, orgFile);
    if (me != orgList)
        {
	slRemoveEl(&orgList, me);
	slAddHead(&orgList, me);
	}
    }
mafWriteStart(f, "zero");

if (bed12)
    {
    char *row[12];
    while (lineFileRow(lf, row))
	{
	struct bed *bed = bedLoadN(row, ArraySize(row));
	struct mafAli *maf = mafFromBed12(database, track, bed, orgList);
	if (meFirst)
	    moveMeToFirst(maf, bed->name);
	mafWrite(f, maf);
	mafAliFree(&maf);
	bedFree(&bed);
	}
    }
else
    {
    char *row[6];
    while (lineFileRow(lf, row))
	{
	struct bed *bed = bedLoadN(row, ArraySize(row));
        processBed6(database, track, f, bed, orgList);
	bedFree(&bed);
	}
    }
mafWriteEnd(f);
carefulClose(&f);
}
void cullCutters(struct cutter **enzList, boolean semicolon, struct slName *justThese, int matchSize)
/* Reduce the list of enzymes based on different options. */
{
struct cutter *enz = *enzList, *next;
while (enz != NULL)
    {
    next = enz->next;
    if ((justThese && !slNameInList(justThese, enz->name)) ||  
	(enz->matchSize < matchSize) || (!semicolon && enz->semicolon))
	{	
	slRemoveEl(enzList, enz);
	cutterFree(&enz);
	}
    enz = next;
    }
}
void orderTables(struct tableJoiner **pTfList, char *primaryDb, char *primaryTable)
/* Order table list so that primary table is first and the rest are
 * alphabetical.  This is the order they are listed in the UI.
 * (However we get them scrambled since the CGI variables are not
 * ordered.)*/
{
    struct tableJoiner *tjList = *pTfList;
    struct tableJoiner *primaryTf = findTable(tjList, primaryDb, primaryTable);
    if (primaryTf != NULL)
        slRemoveEl(&tjList, primaryTf);
    slSort(&tjList, tableFieldsCmp);
    if (primaryTf != NULL)
    {
        slAddHead(&tjList, primaryTf);
    }
    *pTfList = tjList;
}
Ejemplo n.º 11
0
void scrambleFa(char *inName, char *outName)
/* scrambleFa - scramble the order of records in an fa file. */
{
struct dnaSeq *seqList, *seq;
int seqCount;
int seqIx;
FILE *out;

seqList = faReadAllDna(inName);
out = mustOpen(outName, "w");
seqCount = slCount(seqList);
while (seqCount > 0)
    {
    seqIx = rand()%seqCount;
    seq = slElementFromIx(seqList, seqIx);
    faWriteNext(out, seq->name, seq->dna, seq->size);
    slRemoveEl(&seqList, seq);
    --seqCount;
    }
fclose(out);
}
Ejemplo n.º 12
0
void *hashRemove(struct hash *hash, char *name)
/* Remove item of the given name from hash table. 
 * Returns value of removed item, or NULL if not in the table.
 * If their are multiple entries for name, the last one added
 * is removed (LIFO behavior).
 */
{
struct hashEl *hel;
void *ret;
struct hashEl **pBucket = &hash->table[hashString(name)&hash->mask];
for (hel = *pBucket; hel != NULL; hel = hel->next)
    if (sameString(hel->name, name))
        break;
if (hel == NULL)
    return NULL;
ret = hel->val;
if (slRemoveEl(pBucket, hel))
    {
    hash->elCount -= 1;
    if (!hash->lm)
	freeHashEl(hel);
    }
return ret;
}
Ejemplo n.º 13
0
struct locus *readSs(char *pbFile, char *strandFile)
/* determine which allele matches assembly and store in details file */
{
struct hash *strandHash = readStrand(strandFile);
struct strand *strand = NULL;
struct hash *missingHugoIdHash = newHash(16);
struct hashCookie hashPtr;
char *missingName;
struct locus     *l  = NULL, *lPtr = NULL;
struct alleleInfo *aPtr = NULL;
struct lineFile  *lf = lineFileOpen(pbFile, TRUE); /* input file */
char             *row[4], *row2[3]; /* number of fields in input file */
char  *pbName;
char   chrom[32];
int    chromStart;
int    chromEnd;
char   name[32];
char  *allele;

while (lineFileRow(lf, row)) /* process one snp at a time */
    {
    struct alleleInfo *ai1 = NULL, *ai2 = NULL, *aiPtr;
    struct locus *m        = NULL;

    chopString(row[0], "-", row2, 3);
    chromStart = sqlUnsigned(row2[0]);
    chromEnd   = chromStart+1;
    safef(chrom, sizeof(chrom), "chr%s", row2[2]);

    if(l==NULL||l->chrom==NULL||l->chromStart!=chromStart||!(sameString(l->chrom,chrom)))
	{
	AllocVar(m);
	safef(name, sizeof(name), "%s_%d", row2[1], ++ssnpId);
	m->chrom       = cloneString(chrom);
	m->chromStart  = chromStart;
	m->chromEnd    = chromEnd;
	m->name        = cloneString(name);
	m->hugoId      = cloneString(row2[1]);
	m->strictSnp   = TRUE;
	slAddHead(&l, m);
	}

    allele=cloneString(row[2]);
    convertToUppercase(allele);
    if ( sameString(allele,"A") || sameString(allele,"C") || 
	 sameString(allele,"G") || sameString(allele,"T") )
	{
	for (aiPtr=l->alleles; aiPtr!=NULL; aiPtr=aiPtr->next)
	    if (sameString(aiPtr->allele, allele))
		break;
	if (aiPtr==NULL)
	    {
	    AllocVar(ai1);
	    ai1->allele=cloneString(allele);
	    slAddHead(&(l->alleles), ai1);
	    l->alleleCount++;
	    aiPtr=l->alleles;
	    }
	aiPtr->count++;
	l->sampleSize++;
	}

    allele=cloneString(row[3]);
    convertToUppercase(allele);
    if ( sameString(allele,"A") || sameString(allele,"C") || 
	 sameString(allele,"G") || sameString(allele,"T") )
	{
	for (aiPtr=l->alleles; aiPtr!=NULL; aiPtr=aiPtr->next)
	    if (sameString(aiPtr->allele, allele))
		break;
	if (aiPtr==NULL)
	    {
	    AllocVar(ai2);
	    ai2->allele=cloneString(allele);
	    slAddHead(&(l->alleles), ai2);
	    l->alleleCount++;
	    aiPtr=l->alleles;
	    }
	aiPtr->count++;
	l->sampleSize++;
	}
    }
slReverse(&l);
for(lPtr=l; lPtr!=NULL; lPtr=lPtr->next)
    {
    strand = hashFindVal(strandHash, lPtr->hugoId);
    if (strand == NULL)
	{
	hashStore(missingHugoIdHash, lPtr->hugoId);
	slRemoveEl(l, lPtr);
	continue;
	}
    lPtr->strand = cloneString(strand->strand);
    }
freeHash(&strandHash);
hashPtr = hashFirst(missingHugoIdHash);
while ( (missingName=hashNextName(&hashPtr)) != NULL )
    printf("HUGO ID was not found in strand.txt (usually from proteome.hgncXref): %s\n", missingName);
freeHash(&missingHugoIdHash);
return l;
}
Ejemplo n.º 14
0
void liftOverMerge(char *oldFile, char *newFile)
/* liftOverMerge - Merge regions in BED5  generated by liftOver -multiple */
{
    struct bed *bedList = NULL, *bed = NULL, *otherBed = NULL, *nextBed = NULL;
    struct bedList *bedListHeaders = NULL, *bedListHeader = NULL;
    FILE *f = mustOpen(newFile, "w");

    bedList = bedLoadNAll(oldFile, 5);

    /* break down bed list into a list of lists, one per "region", where region
     * is the name field in the bed */
    for (bed = bedList; bed != NULL; bed = nextBed)
    {
        verbose(3, "%s:%d-%d %s %d\n", bed->chrom, bed->chromStart, bed->chromEnd,
                bed->name, bed->score);
        if (bedListHeader == NULL ||
                differentString(bed->name, bedListHeader->name))
        {
            verbose(2, "region %s\n", bed->name);
            AllocVar(bedListHeader);
            bedListHeader->name = cloneString(bed->name);
            slAddHead(&bedListHeaders, bedListHeader);
        }
        nextBed = bed->next;
        slAddHead(&bedListHeader->bed, bed);
    }
    slReverse(&bedListHeaders);

    for (bedListHeader = bedListHeaders; bedListHeader != NULL;
            bedListHeader = bedListHeader->next)
    {
        int ix = 1;
        verbose(3, "region %s\n", bedListHeader->name);
        slReverse(&bedListHeader->bed);

        /* traverse list of bed lists, merging overlapping entries
         * for each region */
        for (bed = bedListHeader->bed; bed != NULL; bed = bed->next)
        {
            for (otherBed = bed->next; otherBed != NULL; otherBed = nextBed)
            {
                nextBed = otherBed->next;
                if (sameString(bed->chrom, otherBed->chrom) &&
                        (max(bed->chromStart, otherBed->chromStart) <=
                         min(bed->chromEnd, otherBed->chromEnd) + mergeGap))
                {
                    /* these regions overlap (or are within the merge gap),
                     * so create one that is a merge, and drop the other */
                    verbose(2,"merging %s:%d-%d, %s:%d-%d (overlap=%d)",
                            otherBed->chrom, otherBed->chromStart, otherBed->chromEnd,
                            bed->chrom, bed->chromStart, bed->chromEnd,
                            min(bed->chromEnd, otherBed->chromEnd) -
                            max(bed->chromStart, otherBed->chromStart));
                    bed->chromStart = min(otherBed->chromStart, bed->chromStart);
                    bed->chromEnd = max(otherBed->chromEnd, bed->chromEnd);
                    verbose(2," to %s:%d-%d\n",
                            bed->chrom, bed->chromStart, bed->chromEnd);
                    slRemoveEl(&bedListHeader->bed, otherBed);
                }
            }
        }
        for (otherBed = bedListHeader->bed; otherBed != NULL;
                otherBed = otherBed->next)
        {
            otherBed->score = ix++;
            bedOutputN(otherBed, 5, f, '\t', '\n');
        }
    }
}
Ejemplo n.º 15
0
struct altGraphX *mapAltGraphX(struct altGraphX *ag, struct sqlConnection *conn,
			       char *db, char *netTable )
/* Map one altGraphX record. Return NULL if can't find. This function
 is getting a bit long but it isn't easy to do...*/
{
struct altGraphX *agNew = NULL;
struct chain *chain = NULL;
struct chain *workingChain = NULL, *workingChainFree = NULL;
struct chain *subChain = NULL, *toFree = NULL;
int i,j,k;
int edgeCountNew =0;
int vCountNew=0;
bool reverse = FALSE;
int *starts = NULL, *sizes = NULL;
int blockCount =0;

/* Find the best chain (one that overlaps the most exons. */
AllocArray(starts, ag->edgeCount);
AllocArray(sizes, ag->edgeCount);
for(i=0; i<ag->edgeCount; i++)
    {
    if(getSpliceEdgeType(ag, i) == ggExon)
	{
	starts[blockCount] = ag->vPositions[ag->edgeStarts[i]];
	sizes[blockCount] = ag->vPositions[ag->edgeEnds[i]] - ag->vPositions[ag->edgeStarts[i]];
	blockCount++;
	}
    }
chain = chainForBlocks(conn, db, netTable, ag->tName, ag->tStart, ag->tEnd,
		       starts, sizes, blockCount);
freez(&starts);
freez(&sizes);

if(chain == NULL)
    return NULL;
/* Make a smaller chain to work on... */
chainSubSetForRegion(chain, ag->tStart-1, ag->tEnd+1, &workingChain, &workingChainFree);
if(workingChain == NULL)
    return NULL;
if (chain->qStrand == '-')
    reverse = TRUE;
agNew = altGraphXClone(ag);
freez(&agNew->tName);
agNew->tName = cloneString(chain->qName);
/* Map vertex positions using chain. */
for(i = 0; i < agNew->vertexCount; i++)
    {
    struct cBlock *bi = NULL;
    int targetPos = agNew->vPositions[i];
    struct chain *subChain=NULL, *toFree=NULL;
    agNew->vPositions[i] = -1;
    chainSubSetForRegion(workingChain, targetPos , targetPos, &subChain, &toFree);    
    if(subChain != NULL)
	{
	int qs, qe;
	qChainRangePlusStrand(subChain, &qs, &qe);
	agNew->vPositions[i] = qs;
	}
    chainFree(&toFree);
    }
/* Prune out edges not found. */

/* Set up to remember how many edges we have and our start and stop. */
edgeCountNew = agNew->edgeCount;
vCountNew = agNew->vertexCount;
agNew->tStart = BIGNUM;
agNew->tEnd = 0;
for(i=0; i<agNew->vertexCount && i>= 0; i++)
    {
    struct evidence *ev = NULL;
    if(agNew->vPositions[i] == -1)
	{
	/* Adjust positions, overwriting one that isn't found. */
	vCountNew--;
	for(j=i; j<agNew->vertexCount-1; j++)
	    {
	    agNew->vPositions[j] = agNew->vPositions[j+1];
	    agNew->vTypes[j] = agNew->vTypes[j+1];
	    }
	/* Remove edges associated with this vertex. */
	for(j=0; j<agNew->edgeCount && j>=0; j++)
	    {
	    if(agNew->edgeStarts[j] == i || agNew->edgeEnds[j] == i)
		{
		edgeCountNew--;
		/* Remove evidence. */
		ev = slElementFromIx(agNew->evidence, j);
		slRemoveEl(&agNew->evidence, ev);
		for(k=j; k<agNew->edgeCount -1; k++)
		    {
		    agNew->edgeStarts[k] = agNew->edgeStarts[k+1];
		    agNew->edgeEnds[k] = agNew->edgeEnds[k+1];
		    agNew->edgeTypes[k] = agNew->edgeTypes[k+1];
		    }
		j--;
		agNew->edgeCount--;
		}
	    }
	/* Subtract off one vertex from all the others. */
	for(j=0; j<agNew->edgeCount; j++)
	    {
	    if(agNew->edgeStarts[j] > i)
		agNew->edgeStarts[j]--; 
	    if(agNew->edgeEnds[j] > i)
		agNew->edgeEnds[j]--; 
	    }
	i--;
	agNew->vertexCount--;
	}
    /* Else if vertex found set agNew start and ends. */
    else
	{
	agNew->tStart = min(agNew->vPositions[i], agNew->tStart);
	agNew->tEnd = max(agNew->vPositions[i], agNew->tEnd);
	}
    }
/* Not going to worry about mRNAs that aren't used anymore. Leave them in
   for now. */
agNew->vertexCount = vCountNew;
agNew->edgeCount = edgeCountNew;
if(agNew->vertexCount == 0 || agNew->edgeCount == 0)
    {
    altGraphXFree(&agNew);
    return NULL;
    }
for(i=0; i<agNew->edgeCount; i++)
    {
    if(agNew->edgeStarts[i] >= agNew->vertexCount ||
       agNew->edgeEnds[i] >= agNew->vertexCount)
	{
	warn("For %s vertexes occur at %d when in reality there are only %d vertices.",
	     agNew->name, max(agNew->edgeStarts[i], agNew->edgeEnds[i]), agNew->vertexCount);
	}
    }
/* If it is on the other strand reverse it. */
if(reverse)
    {
    altGraphXReverse(agNew);
    }
chainFree(&workingChainFree);
return agNew;
}
Ejemplo n.º 16
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>");
    }
}