Example #1
0
void cgapSageLoadItems(struct track *tg)
/* This function loads the beds in the current window into a linkedFeatures list. */
/* Each bed entry may turn into multiple linkedFeatures because one is made for */
/* each library at a given tag (bed). */
{
struct linkedFeatures *itemList = NULL;
struct sqlConnection *conn = hAllocConn(database);
struct hash *libHash = libTissueHash(conn);
struct hash *libTotHash = getTotTagsHashFromTable(conn);
struct sqlResult *sr = NULL;
char **row;
int rowOffset;
sr = hOrderedRangeQuery(conn, tg->table, chromName, winStart, winEnd,
			NULL, &rowOffset);
if ((winEnd - winStart) > CGAP_SAGE_DENSE_GOVERNOR)
    tg->visibility = tvDense;
while ((row = sqlNextRow(sr)) != NULL)
    {
    struct cgapSage *tag = cgapSageLoad(row+rowOffset);
    struct linkedFeatures *oneLfList = cgapSageToLinkedFeatures(tag, libHash, libTotHash, tg->visibility);
    itemList = slCat(oneLfList, itemList);
    }
slReverse(&itemList);
sqlFreeResult(&sr);
hFreeConn(&conn);
tg->items = itemList;
}
/*
 *	there are a variety of conditions that affect how FetchData is
 *	going to work.  This is an attempt to allow it to do as much
 *	as possible, but not get overloaded.
 *	summaryOnly is done when whole chrom summaries are requested
 *	for statistic purposes.  In those cases we do not need to go all
 *	the way to the data to get the averages, the SQL rows are good
 *	enough.  Although even on this level there is quite a bit of
 *	work to do on tracks such as Quality that have 180,000 rows on
 *	just chr1.
 *	a wiggleStats wsList is given when doing statistics, if it is
 *	purely a data fetch operation, there is no need to do
 *	wiggleStats and it will be a NULL pointer.
 *	a bedList pointer is given when a returned bed list is desired.
 *	In the case of processing a bedList, we honor the return limit
 *	of number of bed elements via the maxBedElements.
 *	If we are not returning a bedList and we are not doing a stats
 *	summary, then we have an honest data fetch operation, and in
 *	this case we honor the stated line limit of maxBedElements.
 *	When the caller is doing this data fetch operation and states
 *	that maxBedElements is zero, then we do all data that can be found.
 *	This would be the case for a stats operation when only one chrom
 *	is being worked on.
 */
struct wiggleData *wigFetchData(char *db, char *table, char *chromName,
    int winStart, int winEnd, boolean summaryOnly, boolean freeData,
	int tableId, boolean (*wiggleCompare)(int tableId, double value,
	    boolean summaryOnly, struct wiggle *wiggle),
		char *constraints, struct bed **bedList,
		    unsigned maxBedElements, struct wiggleStats **wsList)
/*  return linked list of wiggle data between winStart, winEnd */
{
struct sqlConnection *conn = hAllocConn(db);
struct sqlResult *sr;
char **row;
int rowOffset;
int rowCount = 0;
struct wiggle *wiggle;
struct hash *spans = NULL;      /* List of spans encountered during load */
char spanName[128];
char whereSpan[128];
char query[256];
struct hashEl *el;
int leastSpan = BIGNUM;
int mostSpan = 0;
int spanCount = 0;
int span = 0;
struct hashCookie cookie;
struct wiggleData *wigData = (struct wiggleData *) NULL;
struct wiggleData *wdList = (struct wiggleData *) NULL;
boolean bewareConstraints = FALSE;
boolean createBedList = FALSE;
boolean firstSpanDone = FALSE;
unsigned dataLimit = 0;
unsigned dataDone = 0;
boolean reachedDataLimit = FALSE;

/*	make sure table exists before we try to talk to it
 *	If it does not exist, we return a null result
 */
if (! sqlTableExists(conn, table))
    {
    hFreeConn(&conn);
    return((struct wiggleData *)NULL);
    }

if ((struct bed **)NULL != bedList)
    createBedList = TRUE;

/*	if we are not doing a summary (== return all data) and
 *	we are not creating a bed list, then obey the limit requested
 *	It will be zero if they really want everything.
 */
if (!summaryOnly && !createBedList)
    dataLimit = maxBedElements;

spans = newHash(0);	/*	a listing of all spans found here	*/

resetStats(&wigStatsAcc);	/*	zero everything	*/


/*	Are the constraints going to interfere with our span search ? */
if (constraints)
    {
    char *c = cloneString(constraints);
    tolowers(c);
    if (stringIn("span",c))
	bewareConstraints = TRUE;
    }

if (bewareConstraints)
    snprintf(query, sizeof(query),
	"SELECT span from %s where chrom = '%s' AND %s group by span",
	table, chromName, constraints );
else
    snprintf(query, sizeof(query),
	"SELECT span from %s where chrom = '%s' group by span",
	table, chromName );

/*	Survey the spans to see what the story is here */

sr = sqlMustGetResult(conn,query);
while ((row = sqlNextRow(sr)) != NULL)
{
    unsigned span = sqlUnsigned(row[0]);

    ++rowCount;

    snprintf(spanName, sizeof(spanName), "%u", span);
    el = hashLookup(spans, spanName);
    if ( el == NULL)
	{
	if (span > mostSpan) mostSpan = span;
	if (span < leastSpan) leastSpan = span;
	++spanCount;
	hashAddInt(spans, spanName, span);
	}

    }
sqlFreeResult(&sr);

/*	Now, using that span list, go through each span, fetching data	*/
cookie = hashFirst(spans);
while ((! reachedDataLimit) && (el = hashNext(&cookie)) != NULL)
    {
    if ((struct wiggleStats **)NULL != wsList)
	returnStats(&wigStatsAcc,wsList,chromName,winStart,winEnd,span);

    resetStats(&wigStatsAcc);

    if (bewareConstraints)
	{
	snprintf(whereSpan, sizeof(whereSpan), "((span = %s) AND %s)", el->name,
	    constraints);
	}
    else
	snprintf(whereSpan, sizeof(whereSpan), "span = %s", el->name);

    span = atoi(el->name);

    sr = hOrderedRangeQuery(conn, table, chromName, winStart, winEnd,
        whereSpan, &rowOffset);

    rowCount = 0;
    while ((! reachedDataLimit) && (row = sqlNextRow(sr)) != NULL)
	{
	++rowCount;
	wiggle = wiggleLoad(row + rowOffset);
	if (wiggle->count > 0 && (! reachedDataLimit))
	    {
	    wigData = wigReadDataRow(wiggle, winStart, winEnd,
		    tableId, summaryOnly, wiggleCompare );
	    if (wigData)
		{
		if (firstSpanDone)
		    accumStats(&wigStatsAcc, wigData, (struct bed **)NULL,
			maxBedElements, table);
		else
		    accumStats(&wigStatsAcc, wigData, bedList,
			maxBedElements, table);
		dataDone += wigData->count;
		if (freeData)
		    {
		    freeMem(wigData->data); /* and mark it gone */
		    wigData->data = (struct wiggleDatum *)NULL;
		    }
		slAddHead(&wdList,wigData);
		if (!createBedList && dataLimit)
		    if (dataLimit < dataDone)
			reachedDataLimit = TRUE;
		if (createBedList && (wigStatsAcc.bedElCount > maxBedElements))
		    reachedDataLimit = TRUE;
		}
	    }
	}
	/*	perhaps last bed line	*/
    if (!firstSpanDone && createBedList &&
	(wigStatsAcc.bedElEnd > wigStatsAcc.bedElStart) && wigData)
	{
	struct bed *bedEl;
	bedEl = bedElement(wigData->chrom, wigStatsAcc.bedElStart,
	    wigStatsAcc.bedElEnd, table, ++wigStatsAcc.bedElCount);
	slAddHead(bedList, bedEl);
	}
    sqlFreeResult(&sr);
    firstSpanDone = TRUE;
    }
closeWibFile();

if (createBedList)
    slReverse(bedList);

/*	last stats calculation	*/
if ((struct wiggleStats **)NULL != wsList)
    returnStats(&wigStatsAcc,wsList,chromName,winStart,winEnd,span);

hFreeConn(&conn);

if (wdList != (struct wiggleData *)NULL)
	slReverse(&wdList);
/*	this wdList can be freed by wigFreeData */
return(wdList);
}	/*	struct wiggleData *wigFetchData()	*/