ccbd240668585b6eb8eec4f244a56f5d4660288b
tdreszer
Tue Oct 19 13:39:25 2010 -0700
Fixed number 18 on Katrina's list. Supertrack childen were showing as visibile when their parent was hide
diff --git src/hg/hgTracks/searchTracks.c src/hg/hgTracks/searchTracks.c
index 57b6e16..e812f90 100644
--- src/hg/hgTracks/searchTracks.c
+++ src/hg/hgTracks/searchTracks.c
@@ -1,874 +1,873 @@
/* Track search code used by hgTracks CGI */
#include "common.h"
#include "searchTracks.h"
#include "hCommon.h"
#include "memalloc.h"
#include "obscure.h"
#include "dystring.h"
#include "hash.h"
#include "cheapcgi.h"
#include "hPrint.h"
#include "htmshell.h"
#include "cart.h"
#include "hgTracks.h"
#include "web.h"
#include "jksql.h"
#include "hdb.h"
#include "mdb.h"
#include "trix.h"
#include "jsHelper.h"
#include "imageV2.h"
static char const rcsid[] = "$Id: searchTracks.c,v 1.11 2010/06/11 18:21:40 larrym Exp $";
#define ANYLABEL "Any"
#define METADATA_NAME_PREFIX "hgt.metadataName"
#define METADATA_VALUE_PREFIX "hgt.metadataValue"
static int gCmpGroup(const void *va, const void *vb)
/* Compare groups based on label. */
{
const struct group *a = *((struct group **)va);
const struct group *b = *((struct group **)vb);
return strcmp(a->label, b->label);
}
// Would like to do a radio button choice ofsorts
#define SORT_BY_VAR "hgt_sortFound"
enum sortBy
{
sbRelevance=0,
sbAbc =1,
sbHierarchy=2,
};
static int gCmpTrackHierarchy(const void *va, const void *vb)
/* Compare tracks based on longLabel. */
{
const struct slRef *aa = *((struct slRef **)va);
const struct slRef *bb = *((struct slRef **)vb);
const struct track *a = ((struct track *) aa->val);
const struct track *b = ((struct track *) bb->val);
if ( tdbIsFolder(a->tdb) && !tdbIsFolder(b->tdb))
return -1;
else if (!tdbIsFolder(a->tdb) && tdbIsFolder(b->tdb))
return 1;
if ( tdbIsContainer(a->tdb) && !tdbIsContainer(b->tdb))
return -1;
else if (!tdbIsContainer(a->tdb) && tdbIsContainer(b->tdb))
return 1;
if (!tdbIsContainerChild(a->tdb) && tdbIsContainerChild(b->tdb))
return -1;
else if ( tdbIsContainerChild(a->tdb) && !tdbIsContainerChild(b->tdb))
return 1;
return strcasecmp(a->longLabel, b->longLabel);
}
static int gCmpTrack(const void *va, const void *vb)
/* Compare tracks based on longLabel. */
{
const struct slRef *aa = *((struct slRef **)va);
const struct slRef *bb = *((struct slRef **)vb);
const struct track *a = ((struct track *) aa->val);
const struct track *b = ((struct track *) bb->val);
return strcasecmp(a->longLabel, b->longLabel);
}
static void findTracksSort(struct slRef **pTrack, boolean simpleSearch, enum sortBy sortBy)
{
if (sortBy == sbHierarchy)
slSort(pTrack, gCmpTrackHierarchy);
else if (sortBy == sbAbc)
slSort(pTrack, gCmpTrack);
else
slReverse(pTrack);
}
// XXXX make a matchString function to support "contains", "is" etc. and wildcards in contains
// ((sameString(op, "is") && !strcasecmp(track->shortLabel, str)) ||
static boolean isNameMatch(struct track *track, char *str, char *op)
{
return str && strlen(str) &&
((sameString(op, "is") && !strcasecmp(track->shortLabel, str)) ||
(sameString(op, "is") && !strcasecmp(track->longLabel, str)) ||
(sameString(op, "contains") && containsStringNoCase(track->shortLabel, str) != NULL) ||
(sameString(op, "contains") && containsStringNoCase(track->longLabel, str) != NULL));
}
static boolean isDescriptionMatch(struct track *track, char **words, int wordCount)
// We parse str and look for every word at the start of any word in track description (i.e. google style).
{
if(words)
{
// We do NOT lookup up parent hierarchy for html descriptions.
char *html = track->tdb->html;
if(!isEmpty(html))
{
/* This probably could be made more efficient by parsing the html into some kind of b-tree, but I am assuming
that the inner html loop while only happen for 1-2 words for vast majority of the tracks. */
int i, numMatches = 0;
html = stripRegEx(html, "<[^>]*>", REG_ICASE);
for(i = 0; i < wordCount; i++)
{
char *needle = words[i];
char *haystack, *tmp = cloneString(html);
boolean found = FALSE;
while((haystack = nextWord(&tmp)))
{
char *ptr = strstrNoCase(haystack, needle);
if(ptr != NULL && ptr == haystack)
{
found = TRUE;
break;
}
}
if(found)
numMatches++;
else
break;
}
if(numMatches == wordCount)
return TRUE;
}
}
return FALSE;
}
static int getTermArray(struct sqlConnection *conn, char ***pLabels, char ***pTerms, char *type)
// Pull out all term fields from ra entries with given type
// Returns count of items found and items via the terms argument.
{
int ix = 0, count = 0;
char **labels;
char **values;
struct slPair *pairs = mdbValLabelSearch(conn, type, MDB_VAL_STD_TRUNCATION, TRUE, FALSE); // Tables not files
count = slCount(pairs) + 1; // make room for "Any"
AllocArray(labels, count);
AllocArray(values, count);
labels[ix] = cloneString(ANYLABEL);
values[ix] = cloneString(ANYLABEL);
struct slPair *pair = NULL;
while((pair = slPopHead(&pairs)) != NULL)
{
ix++;
labels[ix] = pair->name;
values[ix] = pair->val;
freeMem(pair);
}
*pLabels = labels;
*pTerms = values;
return count;
}
static int metaDbVars(struct sqlConnection *conn, char *** metaVars, char *** metaLabels)
// Search the assemblies metaDb table; If name == NULL, we search every metadata field.
{
char query[256];
#define WHITE_LIST_COUNT 35
#ifdef WHITE_LIST_COUNT
#define WHITE_LIST_VAR 0
#define WHITE_LIST_LABEL 1
char *whiteList[WHITE_LIST_COUNT][2] = {
{"age", "Age of experimental organism"},
{"antibody", "Antibody or target protein"},
{"origAssembly", "Assembly originally mapped to"},
{"cell", "Cell, tissue or DNA sample"},
{"localization", "Cell compartment"},
{"control", "Control or Input for ChIPseq"},
//{"controlId", "ControlId - explicit relationship"},
{"dataType", "Experiment type"},
{"dataVersion", "ENCODE release"},
//{"fragLength", "Fragment Length for ChIPseq"},
//{"freezeDate", "Gencode freeze date"},
//{"level", "Gencode level"},
//{"annotation", "Gencode annotation"},
{"geoSample", "GEO accession"},
{"growthProtocol", "Growth Protocol"},
{"lab", "Lab producing data"},
{"labVersion", "Lab specific details"},
{"labExpId", "Lab specific identifier"},
{"softwareVersion", "Lab specific informatics"},
{"protocol", "Library Protocol"},
{"mapAlgorithm", "Mapping algorithm"},
{"readType", "Paired/Single reads lengths"},
{"grant", "Principal Investigator"},
{"replicate", "Replicate number"},
//{"restrictionEnzyme","Restriction Enzyme used"},
//{"ripAntibody", "RIP Antibody"},
//{"ripTgtProtein", "RIP Target Protein"},
{"rnaExtract", "RNA Extract"},
{"seqPlatform", "Sequencing Platform"},
{"setType", "Experiment or Input"},
{"sex", "Sex of organism"},
{"strain", "Strain of organism"},
{"subId", "Submission Id"},
{"treatment", "Treatment"},
{"view", "View - Peaks or Signals"},
};
// FIXME: The whitelist should be a table or ra
// FIXME: The whitelist should be in list order
// FIXME: Should read in list, then verify that an mdb val exists.
char **retVar = needMem(sizeof(char *) * WHITE_LIST_COUNT);
char **retLab = needMem(sizeof(char *) * WHITE_LIST_COUNT);
int ix,count;
for(ix=0,count=0;ix
Search for terms in track descriptions, groups, and names. " "If multiple terms are entered, only tracks with all terms " "will be part of the results.
"); hPrintf("\n"); webEndSectionTables(); }