6419fc05af66878081e2b7d4d944900ec42d7cb1 tdreszer Fri Jun 22 15:29:37 2012 -0700 First of many checkins as dictated by Jim's OCD. Formatting space after if and limiting lines to 100 chars. Changes limited to lines last touched by tdreszer (git blame) so as not to ruin history. None of these changes should affect executables in any way. Only affect is to my sanity and Jim's. diff --git src/hg/hgGeneRing/hgGeneRing.c src/hg/hgGeneRing/hgGeneRing.c index 7bb8fb0..34821b2 100644 --- src/hg/hgGeneRing/hgGeneRing.c +++ src/hg/hgGeneRing/hgGeneRing.c @@ -1,970 +1,946 @@ /* hgGeneRing - Gene Network Browser. */ #include "common.h" #include "linefile.h" #include "hash.h" #include "cheapcgi.h" #include "htmshell.h" #include "obscure.h" #include "web.h" #include "cart.h" #include "hdb.h" #include "dbDb.h" #include "hgFind.h" #include "hCommon.h" #include "hui.h" #include "interaction.h" #include "bdgpGeneInfo.h" #include "portable.h" char *errMsg = NULL; char *geneList = NULL; struct slName *geneNames = NULL; struct hash *aliasHash = NULL; struct interaction *interactions = NULL; struct node { char *name; /* name or id - use also as hash key */ char *alias; /* if used */ struct nodelist *xrays; /* out-going rays in directed graph */ struct nodelist *nrays; /* in-coming rays in directed graph */ boolean ring; /* member of gene-ring? */ int ringRank; /* number of ring members connected to by x or n rays */ int xpos; /* x position */ int ypos; /* y position */ }; struct nodelist { struct nodelist *next; /* next in list */ struct node *node; }; struct nodelist* allNodes = NULL; struct hash *nodeHash = NULL; int ringCount = 0; int insideCount = 0; int outsideCount = 0; struct cart *cart = NULL; struct hash *oldVars = NULL; char *clade = NULL; char *organism = NULL; char *db = NULL; /* ------ old junk cloned from hgGateway --------- */ void hgGateway() /* hgGateway - Human Genome Browser Gateway. */ { char *defaultPosition = hDefaultPos(db); char *position = cloneString(cartUsualString(cart, "position", defaultPosition)); boolean gotClade = hGotClade(); /* JavaScript to copy input data on the change genome button to a hidden form This was done in order to be able to flexibly arrange the UI HTML */ char *onChangeDB = "onchange=\"document.orgForm.db.value = document.mainForm.db.options[document.mainForm.db.selectedIndex].value; document.orgForm.submit();\""; char *onChangeOrg = "onchange=\"document.orgForm.org.value = document.mainForm.org.options[document.mainForm.org.selectedIndex].value; document.orgForm.db.value = 0; document.orgForm.submit();\""; char *onChangeClade = "onchange=\"document.orgForm.clade.value = document.mainForm.clade.options[document.mainForm.clade.selectedIndex].value; document.orgForm.org.value = 0; document.orgForm.db.value = 0; document.orgForm.submit();\""; if (sameString(position, "genome") || sameString(position, "hgBatch")) position = defaultPosition; -puts( -"
\n" +puts("\n" "
" "\n" "
\n" "The UCSC Genome Browser was created by the \n" "Genome Bioinformatics Group of UC Santa Cruz.\n" "
" "Software Copyright (c) The Regents of the University of California.\n" "All rights reserved.\n" -"
\n" -); + "\n"); -puts( -"\n" +puts("\n" "
\n" "\n" "
\n" "\n" "
\n" "\n" "\n" "
\n" ""); if (gotClade) puts(""); -puts( -"\n" +puts("\n" "\n" "\n" "\n" "\n" -"\n" -); + "\n"); if (gotClade) { puts("\n"); } puts("\n"); puts("\n"); puts("\n"); #ifdef SORRY_GILL_I_HIT_INSTEAD_OF_SUBMIT_TOO_MANY_TIMES puts("\n"); #endif /* SORRY_GILL_I_HIT_INSTEAD_OF_SUBMIT_TOO_MANY_TIMES */ cartSetString(cart, "position", position); cartSetString(cart, "db", db); cartSetString(cart, "org", organism); if (gotClade) cartSetString(cart, "clade", clade); freez(&defaultPosition); position = NULL; puts("\n"); printf("\n"); -puts( -"
cladegenomegenomeassemblypositionimage width  
\n"); printCladeListHtml(organism, onChangeClade); puts("\n"); if (gotClade) printGenomeListForCladeHtml(db, onChangeOrg); else printGenomeListHtml(db, onChangeOrg); puts("\n"); /* HACK ALERT - Zoo needs to have different pulldown behavior - Hiram */ if ( startsWith( "Zoo", organism ) ) { puts(""); } else { printAssemblyListHtml(db, onChangeDB); } puts("\n"); cgiMakeTextVar("position", addCommasToPos(position), 30); printf("\n"); cgiMakeOnClickButton("document.mainForm.position.value=''","clear"); printf("\n"); cgiMakeIntVar("pix", cartUsualInt(cart, "pix", hgDefaultPixWidth), 4); cartSaveSession(cart); printf(""); cgiMakeButton("Submit", "Submit"); printf("
\n" +puts("
\n" "
\n" "Click here to reset the browser user interface settings to their defaults.
\n" "
\n" -"
\n" -); + "
\n"); cgiMakeButton("customTrackPage", "Add Your Own Custom Tracks"); puts("
\n" "
\n" "
\n" -"\n" -); + "\n"); puts("
"); hgPositionsHelpHtml(organism, db); puts("
\n" ); puts("
"); if (gotClade) printf("\n", clade); printf("\n", organism); printf("\n", db); cartSaveSession(cart); puts("

"); } /* end of hgGateway junk that this code was cloned from */ /* ----------------------------------------------------------------------- */ boolean getGenesAsList() /* create name-list from geneString, so that we don't have to keep re-parsing the cart string in different places */ { char* ss = cloneString(geneList); char* s = ss; char* w = NULL; int c=0; char emsg[256]; /* clean up unwanted characters if any */ subChar(ss, ',' ,' '); subChar(ss, '\t',' '); subChar(ss, '\n',' '); subChar(ss, '\r',' '); while (1) { if (!(w = nextWord(&s))) break; if(slNameInList(geneNames, w)) /* could be optimized, but not expecting large lists for ring */ { safef(emsg,sizeof(emsg), "Duplicate gene id (%s) found in list.",w); errMsg = cloneString(emsg); freez(&ss); return FALSE; } slNameAddHead(&geneNames, w); c++; } slReverse(&geneNames); if (c==0) { errMsg = "No genes in list. Please specify genes for ring."; return FALSE; } freez(&ss); return TRUE; } void updateGeneList() /* update the cart list of genes */ { char *sep = ""; struct slName *sn = geneNames; struct dyString *geneList=newDyString(512); while(sn) { dyStringPrintf(geneList,"%s%s",sep,sn->name); sep=" "; sn=sn->next; } cartSetString(cart, "ring_geneList", geneList->string); freeDyString(&geneList); } struct bdgpGeneInfo *bdgpGeneInfoLoadByQuery(struct sqlConnection *conn, char *query) /* Load all interaction from table that satisfy the query given. * Where query is of the form 'select * from example where something=something' * or 'select example.* from example, anotherTable where example.something = * anotherTable.something'. * Dispose of this with bdgpGeneInfoFreeList(). */ { struct bdgpGeneInfo *list = NULL, *el; struct sqlResult *sr; char **row; sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { el = bdgpGeneInfoLoad(row); slAddHead(&list, el); } slReverse(&list); sqlFreeResult(&sr); return list; } void getGeneAliasesFromTable(char* table) /* read all the gene aliases from database, return bdgpGeneInfo-list */ { struct bdgpGeneInfo *result = NULL, *this=NULL; struct dyString *query=newDyString(512); char *sep = "where"; struct slName *sn = geneNames; dyStringPrintf(query,"select * from %s",table); while(sn) { char * nm = sn->name; if (startsWith("CG",nm)) { dyStringPrintf(query," %s bdgpName='%s'",sep,nm); sep = "or"; } else if (!startsWith("FBgn",nm)) { dyStringPrintf(query," %s symbol='%s'",sep,nm); sep = "or"; } sn = sn->next; } //uglyf("
SQL=%s

\n",query->string); struct sqlConnection* conn = hAllocConn(); result = bdgpGeneInfoLoadByQuery(conn, query->string); for(this=result;this;this=this->next) { //uglyf("
adding %s=%s
\n",this->bdgpName,this->flyBaseId); // debug hashAdd(aliasHash,this->bdgpName,cloneString(this->flyBaseId)); //uglyf("
adding %s=%s
\n",this->symbol,this->flyBaseId); // debug hashAdd(aliasHash,this->symbol,cloneString(this->flyBaseId)); } // Mysterious crashes if I free this list: //bdgpGeneInfoFreeList(&result); hFreeConn(&conn); freeDyString(&query); } struct interaction *getGenesFromTable(char* table) /* read all the gene interactions from database, returns interaction-list */ { struct interaction *result = NULL; struct dyString *query=newDyString(512); char *sep = "where"; struct slName *sn = geneNames; getGeneAliasesFromTable("bdgpGeneInfo"); /* load aliases into hash */ dyStringPrintf(query,"select * from %s",table); while(sn) { struct hashEl *hel = NULL, *hf=NULL; char * nm = sn->name; char * alias = NULL; if (!startsWith("FBgn",nm)) { if (hf = hashLookup(aliasHash,nm)) { alias = sn->name; //uglyf("
aliasing %s with %s
\n",nm,(char *)hf->val); // debug nm = (char *)hf->val; } } hel = hashStore(nodeHash,nm); if (!hel->val) /* add geneList elements to the hash */ { struct node *n; struct nodelist *nl; AllocVar(n); AllocVar(nl); n->name = cloneString(nm); n->alias = cloneString(alias); n->ring = TRUE; /* this is a special ring member */ nl->node = n; slAddHead(&allNodes,nl); /* all nodes going in hash are added to all-nodes list */ hel->val = n; } dyStringPrintf(query," %s fromX='%s' or toY='%s'",sep,nm,nm); sep = "or"; sn = sn->next; } //uglyf("
SQL=%s

\n",query->string); struct sqlConnection* conn = hAllocConn(); result = interactionLoadByQuery(conn, query->string); hFreeConn(&conn); freeDyString(&query); return result; } void getGeneList() /* hgGeneRing - Gene Network Browser. */ { /* not much point in this, though called old it's the same as current at this point. It is not the old value from before the last submit. char *oldGeneList = hashFindVal(oldVars, "ring_geneList"); */ if (!sameString(errMsg,"")) { printf("
%s
\n",errMsg); } -puts( -"
\n" +puts("\n" "
" "\n" "
\n" "Enter gene list for gene network ring.\n" -"
\n" -); + "\n"); -puts( -"
" +puts("
" "\n" -"\n" -); + "\n"); puts("\n"); -puts( -"\n" -); +puts("\n"); printf("\n"); -puts( -"
\n"); cgiMakeTextArea("ring_geneList", geneList, 25, 30); printf("
"); cgiMakeButton("Submit", "Submit"); printf("
\n" -); +puts("
\n"); puts("
\n"); cartSetString(cart, "ring_action", "saveGeneList"); cartSetString(cart, "ring_errMsg", ""); } int compareNodes(const void *va, const void *vb) { const struct nodelist *a = *((struct nodelist **)va); const struct nodelist *b = *((struct nodelist **)vb); if (a->node->ring && !b->node->ring) return -1; if (!a->node->ring && b->node->ring) return 1; if (a->node->ring && b->node->ring) { return differentWord(a->node->name,b->node->name)*-1; } if (a->node->ringRank == b->node->ringRank) { return differentWord(a->node->name,b->node->name)*-1; } else { return (b->node->ringRank - a->node->ringRank); } } boolean saveGeneList(boolean showAll) /* Check for valid gene-list: parse and save. If list not ok, return to getGeneList page. Otherwise, show user's list and offer some links. */ { struct interaction* intr; struct nodelist *nl; if (!getGenesAsList()) { getGeneList(); return FALSE; } if (showAll) { - puts( - "
" + puts("
" "\n" - "
\n" - ); - printf("geneList: %s
\n", - geneList - ); - puts( - "
" + "
\n"); + printf("geneList: %s
\n", geneList ); + puts("
" "gene-list\n" "
" - "screen\n" - ); - puts( - "
\n" - ); + "screen\n"); + puts("
\n"); } interactions = getGenesFromTable("intrP2P"); /* adds geneList elements to hash */ if (showAll) { uglyf("slCount = %d for result list for %s.

\n",slCount(interactions),geneList); } /* this might get moved later */ /* add to hash the remaining interactions members */ for(intr=interactions;intr;intr=intr->next) { //uglyf("%s %s %f.
\n",intr->fromX,intr->toY,intr->score); struct hashEl *helX = hashStore(nodeHash,intr->fromX); struct hashEl *helY = hashStore(nodeHash,intr->toY); struct node *x, *y; struct nodelist *nl; if (!helX->val) /* add X to hash for 1st time */ { AllocVar(x); AllocVar(nl); x->name = cloneString(intr->fromX); nl->node = x; slAddHead(&allNodes,nl); /* add X to list of all nodes */ helX->val = x; } if (!helY->val) /* do same stuff for Y */ { AllocVar(y); AllocVar(nl); y->name = cloneString(intr->toY); nl->node = y; slAddHead(&allNodes,nl); helY->val = y; } x = helX->val; /* get X,Y from hash */ y = helY->val; if (x->ring) y->ringRank++; /* increment ringRank counts */ if (y->ring) x->ringRank++; AllocVar(nl); nl->node = y; slAddHead(&x->xrays,nl); /* add Y to X's list of x-rays */ AllocVar(nl); nl->node = x; slAddHead(&y->nrays,nl); /* likewise */ } interactionFreeList(&interactions); slReverse(&allNodes); slSort(&allNodes, compareNodes); /* sum counts and if showAll, display our structure */ if (showAll) { uglyf("
\n");
     uglyf("name        xrays nrays  ring? ringRank \n");
     uglyf("-------------------------------------- \n");
     }
 for(nl=allNodes;nl;nl=nl->next)
     {
 
     if (nl->node->ring)
 	{
 	ringCount++;
 	}
     else
 	{
 	if (nl->node->ringRank > 1)
 	    {
 	    insideCount++;
 	    }
 	else
 	    {
 	    outsideCount++;
 	    }
 	}
 
     if (showAll)
 	{
 	uglyf("%11s %4d %4d     %4s %3d \n",
 	    nl->node->name,
 	    slCount(nl->node->xrays),
 	    slCount(nl->node->nrays),
 	    nl->node->ring ? "ring":"not!",
 	    nl->node->ringRank
 	    );
 	}
     }
 
 if (showAll)
     {
     uglyf("
\n"); } // TODO: add some real code for freeing these things properly // e.g. for xrays and nrays lists, free up the nodelist list itself, // but not the *node values themselves, which are allocated // in the main nodelist/hash. If the nodelist is freed up // properly then hash freeing should be easy enough. // Do we use valgrind or some other util to verify mem-release? return TRUE; } /* Count up elements in list that are outside ring. */ int slCountOutside(void *list) { struct slList *pt = (struct slList *)list; int len = 0; while (pt != NULL) { struct node *n = ((struct nodelist *)pt)->node; if ((!n->ring) && (n->ringRank==1)) len += 1; pt = pt->next; } return len; } #define NODE_SIZE 10 void addMap(struct nodelist *nl) { struct node *node = nl->node; int x=node->xpos; int y=node->ypos; int r=NODE_SIZE; char *name = node->name; if (node->alias) { name = node->alias; } printf( "\"%s\""", x,y,r, name, node->name, name, name ); } void drawScreen() /* Draw Gene Ring using given genes and interactions and display it in a page as a .gif */ { #define SCREEN_SIZE 800 #define RING_SIZE 200 #define INRING_SIZE 140 #define OUTRING_SIZE 340 struct tempName filename; int width,height; char *mapName="ring_map"; ZeroVar(&filename); makeTempName(&filename, "hgGeneRing_screen", ".gif"); printf("\n", mapName); struct memGfx *mg = mgNew(SCREEN_SIZE,SCREEN_SIZE); int i; double angle=0; int xCen = SCREEN_SIZE/2, yCen = SCREEN_SIZE/2; int x=0,y=0; struct nodelist *nl, *saveNl; /* draw the main RING */ mgCircle(mg, xCen, yCen, SCREEN_SIZE/4, MG_BLACK, FALSE); /* draw the RING genes and assign position */ angle=(M_PI*2)/ringCount; nl=allNodes; for(i=0;inode->xpos = x; nl->node->ypos = y; mgCircle(mg, x, y, NODE_SIZE, MG_BLACK, FALSE); addMap(nl); nl=nl->next; } /* draw the Inside genes, assign position, and draw rays */ angle=(M_PI*2)/insideCount; for(i=0;inode->xpos = x; nl->node->ypos = y; mgCircle(mg, x, y, NODE_SIZE, MG_BLACK, FALSE); addMap(nl); /* draw connections to ring */ { /*local*/ struct nodelist *l; for(l=nl->node->xrays;l;l=l->next) { /* blue = inward = to-ring */ mgDrawLine(mg, x, y, l->node->xpos, l->node->ypos, MG_BLUE); } for(l=nl->node->nrays;l;l=l->next) { /* red = outward = from-ring */ mgDrawLine(mg, x, y, l->node->xpos, l->node->ypos, MG_RED); } } nl=nl->next; } /* draw the Outside genes, assign position, draw rays do 1 ring member at a time. */ angle=(M_PI*2)/ringCount; nl=allNodes; for(i=0;inode->nrays); numOutside += slCountOutside(nl->node->xrays); subAngle = angle / (numOutside+1); /* add 1 to give a little space between ring groups */ /* draw connections to ring */ { /*local*/ struct nodelist *l; int j = 0; struct nodelist *rays; Color color; for (j=0;j<2;j++) { if (j==0) { color = MG_BLUE; rays = nl->node->xrays; } else { color = MG_RED; rays = nl->node->nrays; } for(l=rays;l;l=l->next) { if (l->node->ring) { /* this ring-ring line gets draw twice but that's ok */ x = l->node->xpos; y = l->node->ypos; mgDrawLine(mg, x, y, nl->node->xpos, nl->node->ypos, MG_BLACK); } else if (l->node->ringRank==1) { doneOutside++; x = xCen + (int) OUTRING_SIZE*cos((i-.5)*angle+(doneOutside*subAngle)); y = yCen + (int) OUTRING_SIZE*sin((i-.5)*angle+(doneOutside*subAngle)); l->node->xpos = x; l->node->ypos = y; mgCircle(mg, x, y, NODE_SIZE, MG_BLACK, FALSE); addMap(l); mgDrawLine(mg, x, y, nl->node->xpos, nl->node->ypos, color); } } } } nl=nl->next; } printf("\n"); mgSaveGif(mg, filename.forCgi, FALSE); width=height=SCREEN_SIZE; printf("
"); printf(""); printf(""); printf(""); printf( ""); printf("
", filename.forHtml, width, height, mapName); printf("
" "back " "gene-list " "refresh " "
"); } char *unAlias(char *gene) /* deal with alias mapping for gene names, return FBgn */ { struct hashEl *hf=NULL; if (!startsWith("FBgn",gene)) { if (hf=hashLookup(aliasHash,gene)) { gene=(char *)hf->val; } } return gene; } void drawDetails() { char *gene = cartUsualString(cart, "ring_gene", ""); char *targ = unAlias(gene); struct hashEl *hel = NULL; struct node *n; hel = hashLookup(nodeHash,targ); if (hel) { n = hel->val; printf( "Details page for gene %s " "" "%s Ring " " (rank=%d) " " return " "\n", gene, n->ring?"removeFromRing":"addToRing", gene, n->ring?"Remove From ":"Add To ", n->ringRank ); } else { printf("Unknown gene %s",gene); } } void hgGeneRing() /* hgGeneRing - Gene Network Browser. */ { char *action = cartUsualString(cart, "ring_action", ""); if (sameWord(action,"")) { action = "getGeneList"; } if (sameWord(action,"getGeneList")) { getGeneList(); } else if (sameWord(action,"saveGeneList")) { saveGeneList(TRUE); } else if (sameWord(action,"drawScreen")) { if (saveGeneList(FALSE)) drawScreen(); } else if (sameWord(action,"drawDetails")) { if (saveGeneList(FALSE)) drawDetails(); } else if (sameWord(action,"addToRing")) { char *gene = cartUsualString(cart, "ring_gene", ""); getGenesAsList(); slNameAddTail(&geneNames, gene); updateGeneList(); /* in lieue of actually just redirecting the browser */ cartSaveSession(cart); geneList = cloneString(cartUsualString(cart, "ring_geneList", "")); slFreeList(&geneNames); /* just reset everything */ if (saveGeneList(FALSE)) drawScreen(); } else if (sameWord(action,"removeFromRing")) { char *gene = cartUsualString(cart, "ring_gene", ""); struct slName **psn = &geneNames; getGenesAsList(); while(*psn) { if (sameString((*psn)->name,gene)) { *psn = (*psn)->next; break; } psn=&((*psn)->next); } updateGeneList(); /* in lieue of actually just redirecting the browser */ cartSaveSession(cart); geneList = cloneString(cartUsualString(cart, "ring_geneList", "")); slFreeList(&geneNames); /* just reset everything */ if (saveGeneList(FALSE)) drawScreen(); } else { getGeneList(); } } void doMiddle(struct cart *theCart) /* Set up pretty web display and save cart in global. */ { char *action = cgiUsualString("ring_action", ""); cart = theCart; getDbGenomeClade(cart, &db, &organism, &clade, oldVars); if (! hDbIsActive(db)) { db = hDefaultDb(); organism = hGenome(db); clade = hClade(organism); } /* temporary hack, set db to dm1 fly */ db = "dm1"; organism = "D. melanogaster"; clade = "insect"; cartSetString(cart, "db", db); cartSetString(cart, "org", organism); cartSetString(cart, "clade", clade); hSetDb(db); if (sameWord(action,"geneFrame")) { /* special handling for frameset - can't use cartWebStart etc. */ char *gene = cartUsualString(cart, "ring_gene", ""); char *position = cartUsualString(cart, "ring_position", ""); printf( "" " " " " "", gene, position, db ); } else { cartWebStart(theCart, database, "%s Gene Network Browser \n", organism); geneList = cloneString(cartUsualString(cart, "ring_geneList", "")); errMsg = cartUsualString(cart, "ring_errMsg", ""); /* any error from last time */ hgGeneRing(); cartSaveSession(cart); cartWebEnd(); } freez(&geneList); } char *excludeVars[] = {NULL}; int main(int argc, char *argv[]) /* Process command line. */ { oldVars = hashNew(10); cgiSpoof(&argc, argv); nodeHash = newHash(8); aliasHash = newHash(8); cartEmptyShell(doMiddle, hUserCookie(), excludeVars, oldVars); freeHashAndVals(&nodeHash); return 0; }