struct slName *subtractFiles(struct slName *fileList)
/* Subtract two files using subtractLists */
{
struct slName *initialList = slNameLoadReal(fileList->name);
struct slName *subtractMe = slNameLoadReal(fileList->next->name);
struct slName *diffList = subtractLists(initialList, subtractMe);
slNameFreeList(&initialList);
slNameFreeList(&subtractMe);
return diffList;
}
예제 #2
0
static void showTableFieldsCt(char *db, char *table, boolean withGetButton)
/* Put up html table with a check box for each field of custom
 * track. */
{
struct customTrack *ct = ctLookupName(table);
char *type = ct->dbTrackType;
if (type == NULL)
    type = ct->tdb->type;
struct sqlConnection *conn = hAllocConn(CUSTOM_TRASH);
struct asObject *asObj = asForTdb(conn, ct->tdb);
if (asObj)
    {
    struct slName *fieldList = NULL;
    if (ct->dbTableName != NULL)
	{
	if (isVcfTable(table, NULL))
	    fieldList = vcfGetFields();
	else
	    fieldList = sqlListFields(conn, ct->dbTableName);
	}
    if (fieldList == NULL)
        fieldList = asColNames(asObj);
    showTableFieldsOnList(db, table, asObj, fieldList, FALSE, withGetButton);
    asObjectFree(&asObj);
    slNameFreeList(&fieldList);
    }
else
    showBedTableFields(db, table, ct->fieldCount, withGetButton);
hFreeConn(&conn);
}
예제 #3
0
static struct slName *setup_labels(char *long_form, struct slName *bw_list, struct slName **labels_from_bw_list)
{
    struct slName *lf_labels = NULL;
    if (long_form && !sameString(long_form, "on"))
    /* first check labels from CL */
    {
	lf_labels = slNameListFromComma(long_form);
	int num_labels = slCount(lf_labels);
	if (num_labels != slCount(bw_list))
	    errAbort("number of labels provided should equal the number of bigWigs given");
    }
    /* from file */
    else
    {
	if (*labels_from_bw_list)
	{
	    if (slCount(*labels_from_bw_list) == slCount(bw_list))
		lf_labels = *labels_from_bw_list;
	    else
		slNameFreeList(labels_from_bw_list);
	}
	if (!lf_labels)
	    lf_labels = slNameCloneList(bw_list);
    }
    return lf_labels;
}
예제 #4
0
void doMiddle(struct cart *theCart)
/* Set up globals and make web page */
{
char *database = cgiOptionalString("db");
char *rtdbServer = cfgOption("rtdb.server");
char *rtdbPort = cfgOption("rtdb.port");
char *rtdbChoices = cfgOption("rtdb.databases");
struct slName *dbs = slNameListFromComma(rtdbChoices);
cart = theCart;
cartWebStart(cart, database, "MGC RTDB Update");
if (!rtdbServer)
    errAbort("rtdb.update not defined in the hg.conf file. "
	     "Chances are this CGI isn't meant for this machine.");
if (!rtdbPort)
    errAbort("rtdb.update not defined in the hg.conf file. "
	     "Chances are this CGI isn't meant for this machine.");
/* create HMTL form if button wasn't pressed.  Otherwise, run the update */
if (!cgiVarExists("RTDBSubmit"))
    makeForm(dbs);
else if ((database == NULL) || (!slNameInList(dbs, database)))
    {
    makeForm(dbs);
    printf("<br>Error: Select one of databases listed.");
    }
else
    updateServer(rtdbServer, rtdbPort, database);
cartWebEnd();
slNameFreeList(&dbs);
}
void testDb(struct htmlPage *orgPage, char *org, char *db)
/* Test on one database. */
{
struct hash *genomeRa = hgReadRa(org, db, dataDir, "genome.ra", NULL);
char *canonicalTable = hashMustFindVal(genomeRa, "canonicalTable");
char *accColumn = hashMustFindVal(genomeRa, "idColumn");

struct slName *geneList = sqlRandomSampleWithSeed(db, canonicalTable, "transcript", clRepeat, seed);
struct htmlPage *dbPage;
struct slName *ptr;

verbose(1, "genelist:\n");
for (ptr = geneList; ptr != NULL; ptr = ptr->next)
    verbose(1, "%s\n", ptr->name);

htmlPageSetVar(orgPage, NULL, "db", db);
htmlPageSetVar(orgPage, NULL, searchVarName, "");

dbPage = quickSubmit(orgPage, NULL, org, db, NULL, NULL, "dbEmptyPage", "submit", "go");

quickErrReport();
if (dbPage != NULL)
    {
    testDbColumns(dbPage, org, db, geneList);
    testDbSorts(dbPage, org, db, accColumn, geneList);
    testDbFilters(dbPage, org, db, accColumn, geneList);
    }

htmlPageFree(&dbPage);
hashFree(&genomeRa);
slNameFreeList(&geneList);
}
예제 #6
0
static void returnPreview(struct customPp *cpp, struct slName **pList)
/* Return list of lines back to cpp for reuse. */
{
struct slName *el;
slReverse(pList);
for (el = *pList; el != NULL; el = el->next)
    customPpReuse(cpp, el->name);
slNameFreeList(pList);
}
struct slName *intersectFiles(struct slName *fileList)
/* Successively intersect files. */
{
struct slName *isectList = slNameLoadReal(fileList->name);
struct slName *curFile = fileList->next;
struct slName *cur;
while (curFile != NULL)
    {
    struct hash *isectHash = hashList(isectList);
    struct slName *someWords = slNameLoadReal(curFile->name);
    struct slName *bothWords = thoseInHash(isectHash, someWords, FALSE);
    slNameFreeList(&someWords);
    slNameFreeList(&isectList);
    isectList = bothWords;
    freeHashAndVals(&isectHash);
    curFile = curFile->next;
    }
return isectList;
}
예제 #8
0
파일: cgapSageUi.c 프로젝트: bowhan/kent
void cgapSageUi(struct trackDb *tdb)
/* CGAP SAGE UI options. Highlight certain libs/tissues and filter by score. */
{
struct sqlConnection *conn = hAllocConn(database);
struct slName *tissueList = getListFromCgapSageLibs(conn, "tissue", FALSE, TRUE);
char *tissueHl = cartUsualString(cart, "cgapSage.tissueHl", "All");
puts("<BR><B>Tissue:</B>");
cgapSageDropList(tissueList, NULL, "cgapSage.tissueHl", tissueHl);
hFreeConn(&conn);
slNameFreeList(&tissueList);
}
struct slName *unionFiles(struct slName *fileList)
/* Successively union files. */
{
struct slName *initialList = slNameLoadReal(fileList->name);
struct hash *theHash = hashList(initialList);
struct slName *nextFile = fileList->next;
struct slName *unionList = NULL;
struct slName *cur;
while (nextFile != NULL)
    {
    struct slName *someWords = slNameLoadReal(nextFile->name);
    addMoreToHash(theHash, someWords);
    slNameFreeList(&someWords);
    nextFile = nextFile->next;
    }
unionList = hashToList(theHash);
hashFree(&theHash);
slNameFreeList(&initialList);
return unionList;
}
예제 #10
0
파일: pa.c 프로젝트: davidhoover/kent
void parseAli(char *orderFileName, char *fastaFile, 
    alignFunc afunc, columnFunc cfunc, void *closure)
/* Parse a file of alignments. */
{
struct hash *seqHash = newHash(5);
struct slName *list = getOrderList(orderFileName);
int numSpecies = fillSeqHash(list, seqHash);
struct lineFile *lf = lineFileOpen(fastaFile, TRUE);

parseFasta(lf, numSpecies, list, seqHash, afunc, cfunc,  closure);
slNameFreeList(&list);
}
예제 #11
0
void metaBigSetRgList(struct metaBig* mb, char* commaSep, boolean isBlackList)
/* sets the whitelist (or blacklist) */
{
    struct slName* commas = slNameListFromComma(commaSep);
    struct slName* rgName;
    struct hash* rgHash = newHash(10);
    for (rgName = commas; rgName != NULL; rgName = rgName->next)
        hashAdd(rgHash, rgName->name, rgName->name);
    slNameFreeList(&commas);
    mb->rgList = rgHash;
    mb->rgListIsBlack = isBlackList;
}
예제 #12
0
void submitToDir(struct sqlConnection *conn, struct sqlConnection *conn2, struct sqlConnection *connSp,
    char *outDir, char *inJax)
/* Create directory full of visiGeneLoad .ra/.tab files from
 * jackson database connection.  Creates a pair of files for
 * each submission set.   Returns outDir. */
{
struct dyString *query = dyStringNew(0);
struct slName *ref, *refList = sqlQuickList(conn, NOSQLINJ "select distinct(_Refs_key) from GXD_Assay");
int refCount = 0;

makeDir(outDir);

for (ref = refList; ref != NULL; ref = ref->next)
    {
    char path[PATH_LEN];
    char *pub=NULL;
    boolean skip;

    /* Check that it isn't on our skip list - one that we
     * have already in the database from a higher resolution
     * source. */
    dyStringClear(query);
    sqlDyStringPrintf(query, "select title from BIB_Refs where _Refs_key = %s", 
    	ref->name);

    pub = sqlQuickString(conn, query->string);

    if (!pub)
	{
	verbose(1,"ref %s: missing title from BIB_Refs, ref skipped\n",ref->name);
	continue;
	}

    skip = oneSubmissionSet ?  oneSubmissionSet != sqlSigned(ref->name) : FALSE;

    if (!skip)
	{
	safef(path, sizeof(path), "%s/%s", outDir, ref->name);
	submitRefToFiles(conn, conn2, connSp, ref->name, path, inJax);
	refCount += 1;
	if (testMax != 0 && refCount >= testMax)
	     errAbort("Reached testMax %d output dirs [%s]\n", testMax, path);
	}
    freeMem(pub);
    }

    verbose(1,"refCount=%d\n",refCount);

slNameFreeList(&refList);
dyStringFree(&query);

}
예제 #13
0
/* free species info list */
void freeSpeciesInfo(struct speciesInfo *list)
{
struct speciesInfo *siNext;

for(; list ; list = siNext)
    {
    siNext = list->next;

    freez(&list->nucSequence);
    freez(&list->aaSequence);
    slNameFreeList(&list->posStrings);
    }
}
void sets(char *operation, struct slName *fileList)
/* sets - Do set operations on one-word-per-line files.. */
{
struct slName *finalList = NULL, *cur;
if (sameWord(operation, "intersect"))
    finalList = intersectFiles(fileList);
else if (sameWord(operation, "union"))
    finalList = unionFiles(fileList);
else if (sameWord(operation, "subtract") && (slCount(fileList) == 2))
    finalList = subtractFiles(fileList);
else if (sameWord(operation, "symetricDiff"))
    {
    struct slName *theUnion = unionFiles(fileList);
    struct slName *theIntersect = intersectFiles(fileList);
    finalList = subtractLists(theUnion, theIntersect);
    slNameFreeList(&theUnion);
    slNameFreeList(&theIntersect);
    }
else
    usage();
/* Output here */
for (cur = finalList; cur != NULL; cur = cur->next)
    printf("%s\n", cur->name);
}
예제 #15
0
void checkTableForFields(struct sqlConnection *conn, char *tableName)
/* Do basic checks on the table to make sure it's kosher. i.e. */
/* chrom, chromStart, name all exist along with the table itself. */
{
    struct slName *fieldList;
    if (!sqlTableExists(conn, tableName))
        errAbort("table %s not found.", tableName);
    fieldList = sqlListFields(conn, tableName);
    if (!slNameInList(fieldList, "chrom"))
        errAbort("table %s doesn't have a chrom field. It must have chrom, chromStart, and name at the minimum.", tableName);
    if (!slNameInList(fieldList, "chromStart"))
        errAbort("table %s doesn't have a chrom field. It must have chrom, chromStart, and name at the minimum.", tableName);
    if (!slNameInList(fieldList, "name"))
        errAbort("table %s doesn't have a chrom field. It must have chrom, chromStart, and name at the minimum.", tableName);
    slNameFreeList(&fieldList);
}
int main(int argc, char *argv[])
/* Process command line. */
{
struct slName *fileList = NULL;
int i;
optionInit(&argc, argv, options);
if (argc < 4)
    usage();
/* make a list out of the filenames. */
for (i = 2; i < argc; i++)
    slNameAddHead(&fileList, argv[i]);
slReverse(&fileList);
sets(argv[1], fileList);
slNameFreeList(&fileList);
return 0;
}
예제 #17
0
void annoOptionFreeList(struct annoOption **pList)
/* Free the same things that we clone above. */
{
if (pList == NULL)
    return;
struct annoOption *afo, *nextAfo;
for (afo = *pList;  afo != NULL;  afo = nextAfo)
    {
    nextAfo = afo->next;
    freeMem(afo->spec.name);
    unsigned opFlags = opFlags;
    if (opFlags & OPTION_MULTI)
	{
	switch (opFlags & OPTION_TYPE_MASK)
	    {
	    case OPTION_STRING:
		slNameFreeList(&(afo->value));
		break;
	    default:
		errAbort("annoOptionFreeList: OPTION_MULTI implemented only for "
			 "OPTION_STRING (not 0x%x)", opFlags);
	    }
	}
    else
	{
	switch (opFlags & OPTION_TYPE_MASK)
	    {
	    // No need to free overloaded numeric values
	    case OPTION_DOUBLE:
	    case OPTION_FLOAT:
	    case OPTION_LONG_LONG:
	    case OPTION_INT:
	    case OPTION_BOOLEAN:
		break;
	    case OPTION_STRING:
		freeMem(afo->value);
		break;
	    default:
		errAbort("annoOptionFreeList: unrecognized op type 0x%x", opFlags);
	    }
	}
    freeMem(afo);
    }
*pList = NULL;
}
예제 #18
0
struct grp *groupsFilterForTdbList(struct grp **grps,struct trackDb *tdbList)
{
struct grp *grpList = *grps;
*grps = NULL;
struct slName *tdbGroups = tdbListGetGroups(tdbList);
if (tdbList == NULL)
    return *grps;

while (grpList != NULL)
    {
    struct grp *grp = slPopHead(&grpList);
    if (slNameInList(tdbGroups,grp->name))
        slAddHead(grps,grp);
    }
slNameFreeList(&tdbGroups);
slReverse(grps);
return *grps;
}
void findCutters(char *gcgFile, char *genome, char *outputFile)
/* findCutters - Find REBASE restriction enzymes using their GCG file. */
{
struct cutter *cutters = readGcg(gcgFile);
struct dnaSeq *seqs = dnaLoadAll(genome);
struct slName *whiteList = NULL;
if (justThis)
    whiteList = newSlName(justThis);
if (justThese)
    {
    struct slName *listFromJustThese = getWhiteListFromFile();
    whiteList = slCat(whiteList, listFromJustThese);
    }
if (justThese || justThis)
    cullCutters(&cutters, TRUE, whiteList, 0);
if (countsOnly)
    findCounts(cutters, seqs, outputFile);
else
    findBeds(cutters, seqs, outputFile);
cutterFreeList(&cutters);
freeDnaSeqList(&seqs);
slNameFreeList(&whiteList);
}
예제 #20
0
struct slName *randomVcfIds(char *table, struct sqlConnection *conn, int count, boolean isTabix)
/* Return some semi-random IDs from a VCF file. */
{
/* Read 10000 items from vcf file,  or if they ask for a big list, then 4x what they ask for. */
struct trackDb *tdb = hashFindVal(fullTableToTdbHash, table);
char *fileName = vcfFileName(tdb, conn, table, hDefaultChrom(database));
struct lineFile *lf = isTabix ? lineFileTabixMayOpen(fileName, TRUE) :
				lineFileMayOpen(fileName, TRUE);
if (lf == NULL)
    noWarnAbort();
int orderedCount = count * 4;
if (orderedCount < 100)
    orderedCount = 100;
struct slName *idList = NULL;
char *words[4];
int i;
for (i = 0;  i < orderedCount && lineFileChop(lf, words); i++)
    {
    // compress runs of identical ID, in case most are placeholder
    if (i == 0 || !sameString(words[2], idList->name))
	slAddHead(&idList, slNameNew(words[2]));
    }
lineFileClose(&lf);
/* Shuffle list and trim it to count if necessary. */
shuffleList(&idList);
struct slName *sl;
for (sl = idList, i = 0; sl != NULL; sl = sl->next, i++)
    {
    if (i+1 >= count)
	{
	slNameFreeList(&(sl->next));
	break;
	}
    }
freez(&fileName);
return idList;
}
예제 #21
0
파일: search.c 프로젝트: davidhoover/kent
struct slPair *mdbSelectPairs(struct cart *cart, struct slPair *mdbVars)
// Returns the current mdb  vars and vals in the table of drop down selects
{
// figure out how many metadata selects are visible.
int numMetadataSelects = 0;

struct slPair *mdbSelectPairs = NULL;
if (mdbVars == NULL)
    return 0;

// Get the current number of rows in the table of mdb selects
for (;;)
    {
    char buf[256];
    safef(buf, sizeof(buf), "%s%d", METADATA_NAME_PREFIX, numMetadataSelects + 1);
    char *str = cartOptionalString(cart, buf);
    if (isEmpty(str))
        break;
    else
        numMetadataSelects++;
    }

// Requesting to add or delete any?
int delSearchSelect = cartUsualInt(cart, TRACK_SEARCH_DEL_ROW, 0);   // 1-based row to delete
int addSearchSelect = cartUsualInt(cart, TRACK_SEARCH_ADD_ROW, 0);   // 1-based row to insert after
if (delSearchSelect)
    numMetadataSelects--;
if (addSearchSelect)
    numMetadataSelects++;

if (numMetadataSelects)
    {
    int ix;
    char buf[256];
    for (ix = 0; ix < numMetadataSelects; ix++)
        {
        int offset;   // used to handle additions/deletions
        if (addSearchSelect > 0 && ix >= addSearchSelect)
            offset = 0; // do nothing to offset (i.e. copy data from previous row)
        else if (delSearchSelect > 0 && ix + 1 >= delSearchSelect)
            offset = 2;
        else
            offset = 1;
        safef(buf, sizeof(buf), "%s%d", METADATA_NAME_PREFIX, ix + offset);
        char *var = cartOptionalString(cart, buf);
        char *val = NULL;

        // We need to make sure var is valid in this assembly; if it isn't, reset it to "cell".
        if (slPairFindVal(mdbVars,var) == NULL)
            var = "cell";
        else
            {
            safef(buf, sizeof(buf), "%s%d", METADATA_VALUE_PREFIX, ix + offset);
            enum cvSearchable searchBy = cvSearchMethod(var);
            if (searchBy == cvSearchByMultiSelect)
                {
                // Multi-selects as comma delimited list of values
                struct slName *vals = cartOptionalSlNameList(cart,buf);
                if (vals)
                    {
                    val = slNameListToString(vals,','); // A comma delimited list of values
                    slNameFreeList(&vals);
                    }
                }
            else if (searchBy == cvSearchBySingleSelect
                 ||  searchBy == cvSearchByFreeText
                 ||  searchBy == cvSearchByWildList)
                val = cloneString(cartUsualString(cart, buf,ANYLABEL));
            //else if (searchBy == cvSearchByDateRange || searchBy == cvSearchByIntegerRange)
            //    {
            //    // TO BE IMPLEMENTED
            //    }

            if (val != NULL && sameString(val, ANYLABEL))
                val = NULL;
            }
        slPairAdd(&mdbSelectPairs,var,val); // val already cloned
        }
    if (delSearchSelect > 0)
        {
        safef(buf, sizeof(buf), "%s%d", METADATA_NAME_PREFIX, numMetadataSelects + 1);
        cartRemove(cart, buf);
        safef(buf, sizeof(buf), "%s%d", METADATA_VALUE_PREFIX, numMetadataSelects + 1);
        cartRemove(cart, buf);
        }
    }
else
    {
    // create defaults
    slPairAdd(&mdbSelectPairs,"cell",    NULL);
    slPairAdd(&mdbSelectPairs,"antibody",NULL);
    }

slReverse(&mdbSelectPairs);
return mdbSelectPairs;
}
예제 #22
0
void verifyGreatAssemblies()
{
// First read in the assembly name and description information into name lists
struct slName* supportedAssemblies = NULL;
struct lineFile *lf = lineFileOpen(greatData, TRUE);
int fieldCount = 1;
char* row[fieldCount];
int wordCount;
while ((wordCount = lineFileChopTab(lf, row)) != 0)
	{
	if (wordCount != fieldCount)
		errAbort("The %s file is not properly formatted.\n", greatData);
	slNameAddHead(&supportedAssemblies, row[0]);
	}
lineFileClose(&lf);

boolean invalidAssembly = TRUE;
struct slName* currAssembly;
for (currAssembly = supportedAssemblies; currAssembly != NULL; currAssembly = currAssembly->next)
	{
	if (!hDbIsActive(currAssembly->name))
		{
		errAbort("Assembly %s in supported assembly file is not an active assembly.\n", currAssembly->name);
		}
	if (sameOk(database, currAssembly->name))
		{
		invalidAssembly = FALSE;
		break;
		}
	}

if (invalidAssembly)
    {
	slReverse(&supportedAssemblies);
	currAssembly = supportedAssemblies;
	struct dyString* dy = dyStringNew(0);
	addAssemblyToSupportedList(dy, currAssembly->name);

	currAssembly = currAssembly->next;
	while (currAssembly != NULL)
		{
		dyStringAppend(dy, ", ");
		if (currAssembly->next == NULL)
			dyStringAppend(dy, "and ");
		addAssemblyToSupportedList(dy, currAssembly->name);
		currAssembly = currAssembly->next;
		}

    hPrintf("<script type='text/javascript'>\n");
    hPrintf("function logSpecies() {\n");
    hPrintf("try {\n");
    hPrintf("var r = new XMLHttpRequest();\n");
    hPrintf("r.open('GET', 'http://great.stanford.edu/public/cgi-bin/logSpecies.php?species=%s');\n", database);
    hPrintf("r.send(null);\n");
    hPrintf("} catch (err) { }\n");
    hPrintf("}\n");
    hPrintf("window.onload = logSpecies;\n");
    hPrintf("</script>\n");
    errAbort("GREAT only supports the %s assemblies."
    "\nPlease go back and ensure that one of those assemblies is chosen.",
	dyStringContents(dy));
    htmlClose();
	dyStringFree(&dy);
    }

slNameFreeList(&supportedAssemblies);
}
예제 #23
0
void submitRefToFiles(struct sqlConnection *conn, struct sqlConnection *conn2, struct sqlConnection *connSp,
    char *ref, char *fileRoot, char *inJax)
/* Create a .ra and a .tab file for given reference. */
{
/* Initially the tab file will have some duplicate lines, so
 * write to temp file, and then filter. */
char raName[PATH_LEN], tabName[PATH_LEN], capName[PATH_LEN];
FILE *ra = NULL, *tab = NULL, *cap = NULL;
struct dyString *query = dyStringNew(0);
struct sqlResult *sr;
char **row;
char *pubMed;
struct slName *list, *el;
boolean gotAny = FALSE;
struct hash *uniqImageHash = newHash(0);
struct hash *captionHash = newHash(0);
int imageWidth = 0, imageHeight = 0;
char path[PATH_LEN];
struct dyString *caption = dyStringNew(0);
struct dyString *copyright = dyStringNew(0);
struct dyString *probeNotes = dyStringNew(0);
boolean lookedForCopyright = FALSE;
	
safef(raName, sizeof(raName), "%s.ra", fileRoot);
safef(tabName, sizeof(tabName), "%s.tab", fileRoot);
safef(capName, sizeof(capName), "%s.txt", fileRoot);
tab = mustOpen(tabName, "w");
cap = mustOpen(capName, "w");


sqlDyStringPrintf(query, "select authors,journal,title,year from BIB_Refs where ");
sqlDyStringPrintf(query, "_Refs_key = '%s'", ref);
sr = sqlGetResultVerbose(conn, query->string);
row = sqlNextRow(sr);
if (row == NULL)
    errAbort("Can't find _Refs_key %s in BIB_Refs", ref);

/* Make ra file with stuff common to whole submission set. */
ra = mustOpen(raName, "w");
fprintf(ra, "submissionSource MGI\n");
fprintf(ra, "acknowledgement Thanks to the Gene Expression Database group at "
            "Mouse Genome Informatics (MGI) for collecting, annotating and sharing "
	    "this image. The MGI images were last updated in VisiGene on March 28, 2006. "
	    "Additional and more up to date annotations and images may be available "
	    "directly at <A HREF='http://www.informatics.jax.org' target='_blank'>MGI.</A>\n");
fprintf(ra, "submitSet jax%s\n", ref);
fprintf(ra, "taxon 10090\n");	/* Mus musculus taxon */
fprintf(ra, "fullDir http://hgwdev.gi.ucsc.edu/visiGene/full/inSitu/Mouse/jax\n");
fprintf(ra, "thumbDir http://hgwdev.gi.ucsc.edu/visiGene/200/inSitu/Mouse/jax\n");
fprintf(ra, "setUrl http://www.informatics.jax.org/\n");
fprintf(ra, "itemUrl http://www.informatics.jax.org/searches/image.cgi?%%s\n");
fprintf(ra, "abUrl http://www.informatics.jax.org/searches/antibody.cgi?%%s\n");
fprintf(ra, "journal %s\n", row[1]);
fprintf(ra, "publication %s\n", row[2]);
fprintf(ra, "year %s\n", row[3]);

/* The contributor (author) list is in format Kent WJ; Haussler DH; format in
 * Jackson.  We convert it to Kent W.J.,Haussler D.H., format for visiGene. */
fprintf(ra, "contributor ");
list = charSepToSlNames(row[0], ';');
for (el = list; el != NULL; el = el->next)
    {
    char *lastName = skipLeadingSpaces(el->name);
    char *initials = strrchr(lastName, ' ');
    if (initials == NULL)
	initials = "";
    else
	*initials++ = 0;
    fprintf(ra, "%s", lastName);
    if (initials[0] != 0)
	{
	char c;
	fprintf(ra, " ");
	while ((c = *initials++) != 0)
	    fprintf(ra, "%c.", c);
	}
    fprintf(ra, ",");
    }
fprintf(ra, "\n");
slNameFreeList(&list);
sqlFreeResult(&sr);

/* Add in link to PubMed record on publication. */
dyStringClear(query);
sqlDyStringPrintf(query,
   "select ACC_Accession.accID from ACC_Accession,ACC_LogicalDB "
   "where ACC_Accession._Object_key = %s "
   "and ACC_Accession._LogicalDB_key = ACC_LogicalDB._LogicalDB_key "
   "and ACC_LogicalDB.name = 'PubMed'", ref);
pubMed = sqlQuickStringVerbose(conn, query->string);
if (pubMed != NULL)
    fprintf(ra, "pubUrl https://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=pubmed&dopt=Abstract&list_uids=%s\n", pubMed);
freez(&pubMed);

dyStringClear(query);
sqlDyStringPrintf(query, 
	"select distinct MRK_Marker.symbol as gene,"
               "GXD_Specimen.sex as sex,"
	       "GXD_Specimen.age as age,"
	       "GXD_Specimen.ageMin as ageMin,"
	       "GXD_Specimen.ageMax as ageMax,"
	       "IMG_ImagePane.paneLabel as paneLabel,"
	       "ACC_Accession.numericPart as fileKey,"
	       "IMG_Image._Image_key as imageKey,"
	       "GXD_Assay._ProbePrep_key as probePrepKey,"
	       "GXD_Assay._AntibodyPrep_key as antibodyPrepKey,"
	       "GXD_Assay._ReporterGene_key as reporterGeneKey,"
	       "GXD_FixationMethod.fixation as fixation,"
	       "GXD_EmbeddingMethod.embeddingMethod as embedding,"
	       "GXD_Assay._Assay_key as assayKey,"
	       "GXD_Specimen.hybridization as sliceType,"
	       "GXD_Specimen._Genotype_key as genotypeKey,"
	       "IMG_ImagePane._ImagePane_key as imagePaneKey\n"
	"from MRK_Marker,"
	     "GXD_Assay,"
	     "GXD_Specimen,"
	     "GXD_InSituResult,"
	     "GXD_InSituResultImage,"
	     "GXD_FixationMethod,"
	     "GXD_EmbeddingMethod,"
	     "IMG_ImagePane,"
	     "IMG_Image,"
	     "ACC_Accession\n"
	"where MRK_Marker._Marker_key = GXD_Assay._Marker_key "
	  "and GXD_Assay._Assay_key = GXD_Specimen._Assay_key "
	  "and GXD_Specimen._Specimen_key = GXD_InSituResult._Specimen_key "
	  "and GXD_InSituResult._Result_key = GXD_InSituResultImage._Result_key "
	  "and GXD_InSituResultImage._ImagePane_key = IMG_ImagePane._ImagePane_key "
	  "and GXD_FixationMethod._Fixation_key = GXD_Specimen._Fixation_key "
	  "and GXD_EmbeddingMethod._Embedding_key = GXD_Specimen._Embedding_key "
	  "and IMG_ImagePane._Image_key = IMG_Image._Image_key "
	  "and IMG_Image._Image_key = ACC_Accession._Object_key "
	  "and ACC_Accession.prefixPart = 'PIX:' "
	  "and GXD_Assay._ImagePane_key is NULL "
	);
sqlDyStringPrintf(query, "and GXD_Assay._Refs_key = '%s'", ref);
sr = sqlGetResultVerbose(conn, query->string);

fprintf(tab, "#");
fprintf(tab, "gene\t");
fprintf(tab, "probeColor\t");
fprintf(tab, "sex\t");
fprintf(tab, "age\t");
fprintf(tab, "ageMin\t");
fprintf(tab, "ageMax\t");
fprintf(tab, "paneLabel\t");
fprintf(tab, "fileName\t");
fprintf(tab, "submitId\t");
fprintf(tab, "fPrimer\t");
fprintf(tab, "rPrimer\t");
fprintf(tab, "abName\t");
fprintf(tab, "abTaxon\t");
fprintf(tab, "abSubmitId\t");
fprintf(tab, "fixation\t");
fprintf(tab, "embedding\t");
fprintf(tab, "bodyPart\t");
fprintf(tab, "sliceType\t");
fprintf(tab, "genotype\t");
fprintf(tab, "strain\t");
fprintf(tab, "priority\t");
fprintf(tab, "captionId\t");
fprintf(tab, "imageWidth\t");
fprintf(tab, "imageHeight\n");

while ((row = sqlNextRow(sr)) != NULL)
    {
    char *gene = row[0];
    char *sex = row[1];
    char *age = row[2];
    char *ageMin = row[3];
    char *ageMax = row[4];
    char *paneLabel = row[5];
    char *fileKey = row[6];
    char *imageKey = row[7];
    char *probePrepKey = row[8];
    char *antibodyPrepKey = row[9];
    char *reporterGeneKey = row[10];
    char *fixation = row[11];
    char *embedding = row[12];
    char *assayKey = row[13];
    char *sliceType = row[14];
    char *genotypeKey = row[15];
    char *imagePaneKey = row[16];
    double calcAge = -1;
    char *probeColor = "";
    char *bodyPart = "";
    char *abName = NULL;
    char *rPrimer = NULL, *fPrimer = NULL;
    char *genotype = NULL;
    char *strain = NULL;
    char *priority = NULL;
    char abTaxon[32];
    char *captionId = "";
    char *abSubmitId = NULL;

    verbose(3, "   "); dumpRow(row, 16);

    if (age == NULL)
        continue;

    if (!lookedForCopyright)
	{
	struct sqlResult *sr = NULL;
	char **row;
	lookedForCopyright = TRUE;

	dyStringClear(query);
	sqlDyStringPrintf(query, 
	     "select note from MGI_NoteChunk,MGI_Note,MGI_NoteType,ACC_MGIType "
	     "where MGI_Note._Object_key = %s "
	     "and ACC_MGIType.name = 'Image' "
	     "and ACC_MGIType._MGIType_key = MGI_Note._MGIType_key "
	     "and MGI_NoteType.noteType='Copyright' "
	     "and MGI_Note._NoteType_key = MGI_NoteType._NoteType_key "
	     "and MGI_Note._Note_key = MGI_NoteChunk._Note_key "
	     "order by sequenceNum"
	     , imageKey);
	sr = sqlGetResultVerbose(conn2, query->string);
	while ((row = sqlNextRow(sr)) != NULL)
	   dyStringAppend(copyright, row[0]);
	sqlFreeResult(&sr);

	verbose(2,"imageKey=%s\n",imageKey);

	if (copyright->stringSize != 0)
	    {
	    fprintf(ra, "copyright %s\n", copyright->string);
	    }
	}

    /* Massage sex */
        {
	if (sameString(sex, "Male"))
	    sex = "male";
	else if (sameString(sex, "Female"))
	    sex = "female";
	else
	    sex = "";
	}

    /* Massage age */
	{
	char *embryoPat = "embryonic day ";
	char *newbornPat = "postnatal newborn";
	char *dayPat = "postnatal day ";
	char *weekPat = "postnatal week ";
	char *adultPat = "postnatal adult";
	double calcMinAge = atof(ageMin);
	double calcMaxAge = atof(ageMax);
	double mouseBirthAge = 21.0;
	//double mouseAdultAge = 63.0;	/* Relative to conception, not birth */

	if (age[0] == 0)
	    {
	    warn("age null, ageMin %s, ageMax %s\n", ageMin, ageMax);
	    calcAge = (calcMinAge + calcMaxAge) * 0.5;
	    }
	else if (startsWith(embryoPat, age))
	    calcAge = atof(age+strlen(embryoPat));
	else if (sameString(newbornPat, age))
	    calcAge = mouseBirthAge;
	else if (startsWith(dayPat, age))
	    calcAge = atof(age+strlen(dayPat)) + mouseBirthAge;
        else if (startsWith(weekPat, age))
	    calcAge = 7.0 * atof(age+strlen(weekPat)) + mouseBirthAge;
	else if (sameString(adultPat, age) && calcMaxAge - calcMinAge > 1000 
		&& calcMinAge < 365)
	    calcAge = 365;	/* Most adult mice are relatively young */
	else
	    {
	    warn("Calculating age from %s", age);
	    calcAge = (calcMinAge + calcMaxAge) * 0.5;
	    }
	if (calcAge < calcMinAge)
	    calcAge = calcMinAge;
	if (calcAge > calcMaxAge)
	    calcAge = calcMaxAge;
	}
    
    /* Massage probeColor */
        {
	if (!isStrNull(reporterGeneKey))
	    {
	    /* Fixme: make sure that reporterGene's end up in probeType table. */
	    char *name = NULL;
	    dyStringClear(query);
	    sqlDyStringPrintf(query, 
	    	"select term from VOC_Term where _Term_key = %s", 
	    	reporterGeneKey);
	    name = sqlQuickStringVerbose(conn2, query->string);
	    if (name == NULL)
	        warn("Can't find _ReporterGene_key %s in VOC_Term", 
			reporterGeneKey);
	    else if (sameString(name, "GFP"))
	        probeColor = "green";
	    else if (sameString(name, "lacZ"))
	        probeColor = "blue";
	    else 
	        warn("Don't know color of reporter gene %s", name);
	    freez(&name);
	    }
	if (!isStrNull(probePrepKey))
	    {
	    char *name = NULL;
	    dyStringClear(query);
	    sqlDyStringPrintf(query, 
	      "select GXD_VisualizationMethod.visualization "
	      "from GXD_VisualizationMethod,GXD_ProbePrep "
	      "where GXD_ProbePrep._ProbePrep_key = %s "
	      "and GXD_ProbePrep._Visualization_key = GXD_VisualizationMethod._Visualization_key"
	      , probePrepKey);
	    name = sqlQuickStringVerbose(conn2, query->string);
	    if (name == NULL)
	        warn("Can't find visualization from _ProbePrep_key %s", probePrepKey);
	    probeColor = colorFromLabel(name, gene);
	    freez(&name);
	    if (probeColor[0] == 0)
	        {
		dyStringClear(query);
		sqlDyStringPrintf(query, 
			"select GXD_Label.label from GXD_Label,GXD_ProbePrep "
		        "where GXD_ProbePrep._ProbePrep_key = %s " 
			"and GXD_ProbePrep._Label_key = GXD_Label._Label_key"
		        , probePrepKey);
		name = sqlQuickStringVerbose(conn2, query->string);
		if (name == NULL)
		    warn("Can't find label from _ProbePrep_key %s", 
		    	probePrepKey);
		probeColor = colorFromLabel(name, gene);
		}
	    freez(&name);
	    }
	if (!isStrNull(antibodyPrepKey) && probeColor[0] == 0 )
	    {
	    char *name = NULL;
	    dyStringClear(query);
	    sqlDyStringPrintf(query, 
		  "select GXD_Label.label from GXD_Label,GXD_AntibodyPrep "
		  "where GXD_AntibodyPrep._AntibodyPrep_key = %s "
		  "and GXD_AntibodyPrep._Label_key = GXD_Label._Label_key"
		  , antibodyPrepKey);
	    name = sqlQuickStringVerbose(conn2, query->string);
	    if (name == NULL)
		warn("Can't find label from _AntibodyPrep_key %s", antibodyPrepKey);
	    probeColor = colorFromLabel(name, gene);
	    freez(&name);
	    }
	}

    /* Get abName, abTaxon, abSubmitId */
    abTaxon[0] = 0;
    if (!isStrNull(antibodyPrepKey))
        {
	struct sqlResult *sr = NULL;
	int orgKey = 0;
	char **row;
	dyStringClear(query);
	sqlDyStringPrintf(query, 
		"select antibodyName,_Organism_key,GXD_Antibody._Antibody_key "
		"from GXD_AntibodyPrep,GXD_Antibody "
		"where GXD_AntibodyPrep._AntibodyPrep_key = %s "
		"and GXD_AntibodyPrep._Antibody_key = GXD_Antibody._Antibody_key"
		, antibodyPrepKey);
	sr = sqlGetResultVerbose(conn2, query->string);
	row = sqlNextRow(sr);
	if (row != NULL)
	    {
	    abName = cloneString(row[0]);
	    orgKey = atoi(row[1]);
	    abSubmitId = cloneString(row[2]);
	    }
	sqlFreeResult(&sr);

	if (orgKey > 0)
	    {
	    char *latinName = NULL, *commonName = NULL;
	    int spTaxon = 0;
	    dyStringClear(query);
	    sqlDyStringPrintf(query, "select latinName from MGI_Organism "
	                          "where _Organism_key = %d", orgKey);
	    latinName = sqlQuickStringVerbose(conn2, query->string);
	    if (latinName != NULL 
		&& !sameString(latinName, "Not Specified")
		&& !sameString(latinName, "Not Applicable"))
		{
		char *e = strchr(latinName, '/');
		if (e != NULL) 
		   *e = 0;	/* Chop off / and after. */
		spTaxon = spBinomialToTaxon(connSp, latinName);
		}
	    else
	        {
		dyStringClear(query);
		sqlDyStringPrintf(query, "select commonName from MGI_Organism "
	                          "where _Organism_key = %d", orgKey);
		commonName = sqlQuickStringVerbose(conn2, query->string);
		if (commonName != NULL 
		    && !sameString(commonName, "Not Applicable")
		    && !sameString(commonName, "Not Specified"))
		    {
		    spTaxon = spCommonToTaxon(connSp, commonName);
		    }
		}
	    if (spTaxon != 0)
	        safef(abTaxon, sizeof(abTaxon), "%d", spTaxon);
	    freez(&latinName);
	    freez(&commonName);
	    }
	}
    if (abName == NULL)
        abName = cloneString("");
    if (abSubmitId == NULL)
        abSubmitId = cloneString("");

    /* Get rPrimer, lPrimer */
    if (!isStrNull(probePrepKey))
        {
	struct sqlResult *sr = NULL;
	char **row;
	dyStringClear(query);
	sqlDyStringPrintf(query,
	    "select primer1sequence,primer2sequence "
	    "from PRB_Probe,GXD_ProbePrep "
	    "where PRB_Probe._Probe_key = GXD_ProbePrep._Probe_key "
	    "and GXD_ProbePrep._ProbePrep_key = %s"
	    , probePrepKey);
	sr = sqlGetResultVerbose(conn2, query->string);
	row = sqlNextRow(sr);
	if (row != NULL)
	    {
	    fPrimer = cloneString(row[0]);
	    rPrimer = cloneString(row[1]);
	    }
	sqlFreeResult(&sr);
	}

    /* Note Jackson database actually stores the primers very
     * erratically.  In all the cases I can find for in situs
     * the primers are actually stored in free text in the PRB_Notes
     * e.g.  ... primers CGCGGATCCAGGGGAAACAGAAGGGCTGCG and CCCAAGCTTAGACTGTACAGGCTGAGCC ...
     */
    if (fPrimer == NULL || fPrimer[0]==0)
        {
	struct sqlResult *sr = NULL;
	char **row;
	dyStringClear(query);
	sqlDyStringPrintf(query,
	    "select PRB_Notes.note from GXD_ProbePrep, PRB_Notes"
	    " where GXD_ProbePrep._ProbePrep_key = %s"
	    "  and GXD_ProbePrep._Probe_key = PRB_Notes._Probe_key"
	    " order by PRB_Notes.sequenceNum"
	    , probePrepKey);
	sr = sqlGetResultVerbose(conn2, query->string);
	dyStringClear(probeNotes);
	while ((row = sqlNextRow(sr)) != NULL)
	   dyStringAppend(probeNotes, row[0]);
	sqlFreeResult(&sr);

	if (probeNotes->stringSize > 0)
	    {
	    char f[256];
	    char r[256];
	    int i = 0;
	    char *s = strstr(probeNotes->string," primers ");
	    if (s)
		{
		s += strlen(" primers ");
		i = 0;
		while (strchr("ACGT",*s) && (i<sizeof(f)))
		    f[i++] = *s++;
		f[i]=0;
		if (strstr(s," and ")==s)
		    {
		    s += strlen(" and ");
		    i = 0;
    		    while (strchr("ACGT",*s) && (i<sizeof(r)))
    			r[i++] = *s++;
    		    r[i]=0;
		    if (strlen(f) >= 10 && strlen(r) >= 10)
			{
			fPrimer = cloneString(f);
			rPrimer = cloneString(r);
			}
		    else
			{
			verbose(1, "bad primer parse:_ProbePrep_key=%s fPrimer=[%s], rPrimer=[%s]\n",
			    probePrepKey,f,r);
			}
		    }
		}
	    }
	}
	
    if (fPrimer == NULL)
        fPrimer = cloneString("");
    if (rPrimer == NULL)
        rPrimer = cloneString("");

    fixation = blankOutUnknown(fixation);
    embedding = blankOutUnknown(embedding);

    /* Massage body part and slice type.  We only handle whole mounts. */
    if (sameString(sliceType, "whole mount"))
	{
	bodyPart = "whole";
	priority = "100";
	}
    else
	{
        sliceType = "";
	priority = "1000";
	}

    genotypeAndStrainFromKey(genotypeKey, conn2, &genotype, &strain);

    if (isStrNull(paneLabel))
	paneLabel = cloneString("");	  /* trying to suppress nulls in output */
    stripChar(paneLabel, '"');	/* Get rid of a difficult quote to process. */
    
    /* Fetch image dimensions from file. */
    imageWidth=0;
    imageHeight=0;
    safef(path, sizeof(path), "%s/%s.jpg", inJax, fileKey);
    if (fileExists(path))
    	jpegSize(path,&imageWidth,&imageHeight);  /* will errAbort if no valid .jpeg exists */
    else
	warn("Picture Missing! %s ",path);
    
    /* Deal caption if any.  Most of the work only happens the
     * first time see the image. */
    if (!hashLookup(uniqImageHash, imageKey))
        {
	struct sqlResult *sr = NULL;
	char **row;
	hashAdd(uniqImageHash, imageKey, NULL);
	dyStringClear(caption);
	dyStringClear(query);
	sqlDyStringPrintf(query, 
	     "select note from MGI_NoteChunk,MGI_Note,MGI_NoteType,ACC_MGIType "
	     "where MGI_Note._Object_key = %s "
	     "and ACC_MGIType.name = 'Image' "
	     "and ACC_MGIType._MGIType_key = MGI_Note._MGIType_key "
	     "and MGI_NoteType.noteType='Caption' "
	     "and MGI_Note._NoteType_key = MGI_NoteType._NoteType_key "
	     "and MGI_Note._Note_key = MGI_NoteChunk._Note_key "
	     "order by sequenceNum"
	     , imageKey);
	sr = sqlGetResultVerbose(conn2, query->string);
	while ((row = sqlNextRow(sr)) != NULL)
	   dyStringAppend(caption, row[0]);
	sqlFreeResult(&sr);

	if (caption->stringSize > 0)
	    {
	    subChar(caption->string, '\t', ' ');
	    subChar(caption->string, '\n', ' ');
	    fprintf(cap, "%s\t%s\n", imageKey, caption->string);
	    hashAdd(captionHash, imageKey, imageKey);
	    }
	}
    if (hashLookup(captionHash, imageKey))
        captionId = imageKey;
    else
        captionId = "";

    fprintf(tab, "%s\t", gene);
    fprintf(tab, "%s\t", probeColor);
    fprintf(tab, "%s\t", sex);
    fprintf(tab, "%3.2f\t", calcAge);
    fprintf(tab, "%s\t", ageMin);
    fprintf(tab, "%s\t", ageMax);
    fprintf(tab, "%s\t", paneLabel);   /* may have to change NULL to empty string or "0" ? */
    fprintf(tab, "%s.jpg\t", fileKey);
    fprintf(tab, "%s\t", imageKey);
    fprintf(tab, "%s\t", fPrimer);
    fprintf(tab, "%s\t", rPrimer);
    fprintf(tab, "%s\t", abName);
    fprintf(tab, "%s\t", abTaxon);
    fprintf(tab, "%s\t", abSubmitId);
    fprintf(tab, "%s\t", fixation);
    fprintf(tab, "%s\t", embedding);
    fprintf(tab, "%s\t", bodyPart);
    fprintf(tab, "%s\t", sliceType);
    fprintf(tab, "%s\t", genotype);
    fprintf(tab, "%s\t", strain);
    fprintf(tab, "%s\t", priority);
    fprintf(tab, "%s\t", captionId);
    fprintf(tab, "%d\t", imageWidth);
    fprintf(tab, "%d\n", imageHeight);

    printExpression(tab,  conn2,  imagePaneKey, assayKey);
    gotAny = TRUE;
    freez(&genotype);
    freez(&abName);
    freez(&abSubmitId);
    freez(&rPrimer);
    freez(&fPrimer);
    }
sqlFreeResult(&sr);

carefulClose(&ra);
carefulClose(&tab);
carefulClose(&cap);

if (!gotAny)
    {
    remove(raName);
    remove(capName);
    remove(tabName);
    }
dyStringFree(&probeNotes);
dyStringFree(&copyright);
dyStringFree(&caption);
dyStringFree(&query);
hashFree(&uniqImageHash);
hashFree(&captionHash);

}
예제 #24
0
파일: pal.c 프로젝트: blumroy/kentUtils
int palOutPredList(struct sqlConnection *conn, struct cart *cart,
    struct genePred *list)
/* output a list of genePreds in pal format */
{
if (list == NULL)
    return 0;

char *mafTable = cartString(cart, hgtaCGIGeneMafTable);
char *database = sqlGetDatabase(conn);
struct trackDb *maftdb = hTrackDbForTrack(database, mafTable);
struct wigMafSpecies *wmSpecies;
int groupCnt;

/* get maf parent (if any) */
maftdb->parent = hCompositeTrackDbForSubtrack(database,maftdb);

/* this queries the state of the getSpecies dialog */
wigMafGetSpecies(cart, maftdb, maftdb->track, database, &wmSpecies, &groupCnt);

/* since the species selection dialog doesn't list
 * the reference species, we just automatically include
 * it */
struct slName *includeList = slNameNew(database);

/* now make a list of all species that are on */
for(; wmSpecies; wmSpecies = wmSpecies->next)
    {
    if (wmSpecies->on)
	{
	struct slName *newName = slNameNew(wmSpecies->name);
	slAddHead(&includeList, newName);
	}
    }
slReverse(&includeList);

boolean inExons = cartUsualBoolean(cart, hgtaCGIGeneExons , FALSE);
boolean noTrans = cartUsualBoolean(cart, hgtaCGIGeneNoTrans, FALSE);
boolean outBlank = cartUsualBoolean(cart, hgtaCGIGeneOutBlank, FALSE);
boolean outTable = cartUsualBoolean(cart, hgtaCGIOutTable, FALSE);
boolean truncHeader = cartUsualBoolean(cart, hgtaCGITruncHeader, FALSE);
int numCols = cartUsualInt(cart, hgtaCGINumColumns, 20);
unsigned options = 0;

if (inExons)  options |= MAFGENE_EXONS;
if (noTrans)  options |= MAFGENE_NOTRANS;
if (outBlank) options |= MAFGENE_OUTBLANK;
if (outTable) options |= MAFGENE_OUTTABLE;

if (!truncHeader)
    numCols = -1;

/* send out the alignments */
int outCount = 0;
for( ; list ; list = list->next)
    {
    if (list->cdsStart != list->cdsEnd)
	{
	outCount++;
	mafGeneOutPred(stdout, list, database, mafTable,
	    includeList, options, numCols);
	}
    }

slNameFreeList(&includeList);
return outCount;
}
void bedListExpRecordAverage(struct bed **pBedList, struct expRecord **pERList, int extrasIndex)
/* This is a mildy complicated function to make the details page have the */
/* same data as the track when the UI option "Tissue averages" is selected. */
/* This is done by hacking the bed and expRecord lists in place and keeping */
/* the original code for the most part. */
{
struct bed *bed = NULL;
struct expRecord *er, *newERList = NULL;
struct slName *extras = NULL, *oneSlName;
int M, N, i, columns;
int *mapping;
if (!pBedList || !pERList || !*pBedList || !*pERList)
    return;
er = *pERList;
if ((extrasIndex < 0) || (extrasIndex >= er->numExtras))
    return;
/* Build up a unique list of words from the specific "extras" column. */
for (er = *pERList; er != NULL; er = er->next)
    slNameStore(&extras, er->extras[extrasIndex]);
slReverse(&extras);
M = slCount(extras);
N = slCount(*pERList);
columns = N + 1;
/* M rows, reserve first column for counts. */
mapping = needMem(sizeof(int) * M * columns);
/* Create the mapping array: */
/*   each row corresponds to one of the groupings.  The first column is the number of */
/*   things in the original list in the group (k things), and the next k elements  on */
/*   that row are indeces. */
for (er = *pERList, i = 0; er != NULL && i < N; er = er->next, i++)
    {    
    int ix = slNameFindIx(extras, er->extras[extrasIndex]) * columns;
    mapping[ix + ++mapping[ix]] = er->id; 
    }
/* Make a new expRecord list. */
for (oneSlName = extras, i = 0; oneSlName != NULL && i < M; oneSlName = oneSlName->next, i++)
    {
    struct expRecord *newER = basicExpRecord(oneSlName->name, i, extrasIndex);
    slAddHead(&newERList, newER);
    }
slReverse(&newERList);
expRecordFreeList(pERList);
*pERList = newERList;
/* Go through each bed and change it. */
for (bed = *pBedList; bed != NULL; bed = bed->next)
    {
    float *newExpScores = needMem(sizeof(float) * M);
    int *newExpIds = needMem(sizeof(int) * M);
    /* Calculate averages. */
    for (i = 0; i < M; i++)
	{
	int ix = i * columns;
	int size = mapping[ix];
	int j;
	double sum = 0;
	for (j = 1; j < size + 1; j++)
	    sum += (double)bed->expScores[mapping[ix + j]];
	newExpScores[i] = (float)(sum/size);
	newExpIds[i] = i;
	}
    bed->expCount = M;
    freeMem(bed->expIds);
    bed->expIds = newExpIds;
    freeMem(bed->expScores);
    bed->expScores = newExpScores;    
    }
/* Free stuff. */
slNameFreeList(&extras);
freez(&mapping);
}