src/hg/lib/lsSnpPdbChimera.c 1.4

1.4 2009/05/13 19:05:17 markd
added prototype support for launching 3D structure browser on H1N1 predicted structures
Index: src/hg/lib/lsSnpPdbChimera.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/lib/lsSnpPdbChimera.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -b -B -U 1000000 -r1.3 -r1.4
--- src/hg/lib/lsSnpPdbChimera.c	5 Feb 2009 08:05:16 -0000	1.3
+++ src/hg/lib/lsSnpPdbChimera.c	13 May 2009 19:05:17 -0000	1.4
@@ -1,162 +1,195 @@
 /* lsSnpPdbChimera - Code for interfacing to LS-SNP and Chimera.  Generates
  * Chimera scripts to visualize proteins with SNPs annotated.  Takes an
  * external python script that defines methods used in the rendering.  The
  * generates a .chimerax file that contains the script as well as the code to
  * initialize Chimera for the specific PDB and SNP set.  This also includes
  * interfacing to LS-SNP/PDB, which is used to label Chimera images.
  */
 #include "common.h"
 #include "lsSnpPdbChimera.h"
 #include "obscure.h"
 #include "jksql.h"
 #include "lsSnpPdb.h"
 #include "trashDir.h"
 
 /* Chimerax XML wrapper around python code in .chimerax files */
 static char *chimeraxHead =
     "<?xml version=\"1.0\"?>\n"
     "<ChimeraPuppet type=\"std_webdata\">\n"
     "  <commands>\n"
     "    <py_cmd>\n"
     "<![CDATA[\n";
 static char *chimeraxTail =
     "]]>\n"
     "    </py_cmd>\n"
     "  </commands>\n"
     "</ChimeraPuppet>\n";
 
 /* location of python code relative to CGI dir */
 static char *chimeraxPythonFile = "lsSnpPdbChimera.py";
 
 
 static void getOutFile(char *pdbId, char *other,
                        struct tempName *outName)
 /* generate output file names, other can be NULL*/
 {
 char baseName[PATH_LEN];
 if (other != NULL)
     safef(baseName, sizeof(baseName), "%s.%s", pdbId, other);
 else 
     safecpy(baseName, sizeof(baseName), pdbId);
 trashDirFile(outName, "lssnp", baseName, ".chimerax");
 }
 
 static void prSnp(FILE *xfh, struct lsSnpPdb *pdbSnp, char *primarySnpId)
 /* output one SNP tuple entry in list passed to displayPdb function */
 {
 boolean isPrimary = (primarySnpId != NULL) && sameString(pdbSnp->snpId, primarySnpId);
 fprintf(xfh, "(\"%s\", \"%c\", %d,%s), ", pdbSnp->snpId, pdbSnp->chain,
         pdbSnp->snpPdbLoc, (isPrimary ? " True" : ""));
 }
 
+static FILE *chimeraxBegin(char *outName)
+/* open chimerax file and write XML and python function definitions */
+{
+FILE *xfh = mustOpen(outName, "w");
+fputs(chimeraxHead, xfh);
+
+FILE *pxf = mustOpen(chimeraxPythonFile, "r");
+copyOpenFile(pxf, xfh);
+carefulClose(&pxf);
+return xfh;
+}
+
+static void chimeraxEnd(FILE **xfhPtr)
+/* finish writing XML and close chimerax function */
+{
+fputs(chimeraxTail, *xfhPtr);
+carefulClose(xfhPtr);
+}
+
 static void chimeraxGen(struct sqlConnection *conn,
                         char *pdbId, char *where,
                         char *primarySnpId,
                         char *outName)
 /* Generate a chimerax file for the given PDB, optionally coloring
  * primarySnpId differently.  The where arguments specifies which entries to
  * obtain from the lsSnpPdb table.
  */
 {
-FILE *xfh = mustOpen(outName, "w");
-fputs(chimeraxHead, xfh);
-
-FILE *pxf = mustOpen(chimeraxPythonFile, "r");
-copyOpenFile(pxf, xfh);
-carefulClose(&pxf);
+FILE *xfh = chimeraxBegin(outName);
 
 fprintf(xfh, "\ndisplayPdb(\"%s\", (", pdbId);
 
 struct lsSnpPdb *pdbSnp, *pdbSnps = NULL;
 if (sqlTableExists(conn, "lsSnpPdb"))
     pdbSnps = sqlQueryObjs(conn, (sqlLoadFunc)lsSnpPdbLoad, sqlQueryMulti,
                            "SELECT * FROM lsSnpPdb WHERE %s", where);
 for (pdbSnp = pdbSnps; pdbSnp != NULL; pdbSnp = pdbSnp->next)
     prSnp(xfh, pdbSnp, primarySnpId);
 if (pdbSnps == NULL)
     fprintf(xfh, ",");  // no table or none selected
 lsSnpPdbFreeList(&pdbSnps);
 
 fprintf(xfh, "))\n");
 
-fputs(chimeraxTail, xfh);
-carefulClose(&xfh);
+chimeraxEnd(&xfh);
 }
 
 void lsSnpPdbChimeraSnpAnn(struct sqlConnection *conn,
                            char *pdbId, char *primarySnpId,
                            struct tempName *outName)
 /* Generate a chimerax file for the given pdb with all non-synonymous SNPs
  * that have been mapped to this protein.  If primarySnpId is not NULL, it is
  * colored differently than the other SNPs.  Fills in outName structure. */
 {
 getOutFile(pdbId, primarySnpId, outName);
 char where[512];
 safef(where, sizeof(where), "(pdbId=\"%s\")", pdbId);
 chimeraxGen(conn, pdbId, where, primarySnpId, outName->forCgi);
 }
 
 struct slName *lsSnpPdbChimeraGetSnpPdbs(struct sqlConnection *conn,
                                          char *snpId)
 /* get list of PDBs to which snpId is mapped.  */
 {
 if (!sqlTableExists(conn, "lsSnpPdb"))
     return NULL;
 char query[256];
 safef(query, sizeof(query), "SELECT distinct pdbId FROM lsSnpPdb WHERE (snpId = \"%s\")",
       snpId);
 struct slName *pdbIds = sqlQuickList(conn, query);
 slNameSort(&pdbIds);
 return pdbIds;
 }
 
 char *lsSnpPdbChimeraGetStructType(struct sqlConnection *conn, char *pdbId)
 /* Determine structure type of a PDB (NMR or X-Ray).  Constant result, don't
  * free. */
 {
 
 char query[256], buf[32];
 safef(query, sizeof(query), "SELECT structType FROM lsSnpPdb WHERE (pdbId = \"%s\")",
       pdbId);
 char *structType = sqlNeedQuickQuery(conn, query, buf, sizeof(buf));
 if (sameString(structType, "XRay"))
     return "X-Ray";
 else if (sameString(structType, "NMR"))
     return "NMR";
 else
     return NULL;
 }
 
 boolean lsSnpPdbHasPdb(struct sqlConnection *conn, char *pdbId)
 /* determine if the specified PDB has any entries in LS-SNP */
 {
 if (!sqlTableExists(conn, "lsSnpPdb"))
     return FALSE;
 char query[256], buf[64];
 safef(query, sizeof(query), "SELECT chain FROM lsSnpPdb WHERE (pdbId = \"%s\")", pdbId);
 return (sqlQuickQuery(conn, query, buf, sizeof(buf)) != NULL);
 }
 
 static char *fmtParam(char sep, char *name, char *val)
 /* format a parameter to the URL; WARNING: static return */
 {
 static char param[64];
 safef(param, sizeof(param), "%c%s=%s", sep, name, val);
 return param;
 }
 
 char *lsSnpPdbGetUrlPdbSnp(char *pdbId, char *snpId)
 /* get LS-SNP/PDB URL for a particular PDB and/or SNP.  One or the two
  * ids maybe null */
 {
 char url[256], sep='?';
 safecpy(url, sizeof(url), "http://ls-snp.icm.jhu.edu/ls-snp-pdb/inquire");
 if (pdbId != NULL)
     {
     safecat(url, sizeof(url), fmtParam(sep, "pdbId", pdbId));
     sep = '&';
     }
 if (snpId != NULL)
     safecat(url, sizeof(url), fmtParam(sep, "snpId", snpId));
 return cloneString(url);
 }
+
+void lsSnpPdbChimeraGenericLink(char *pdbSpec, char *script,
+                                char *trashDirName, char *trashBaseName,
+                                struct tempName *chimerax)
+/* Generate a chimerax file for the given pdbSpec, which can be a PDB id or a
+ * URL.  Copies in the lsSnpPdbChimera.py file and then adds optional script python code.
+ * Fills in chimerax structure.
+ * FIXME: This is an experiment for H1N1 flu browser, this function has
+ * nothing to do with LS/SNP.  If we decide to keep this, this should be
+ * split into a generic chimera module.
+ */
+{
+trashDirFile(chimerax, trashDirName, trashBaseName, ".chimerax");
+FILE *xfh = chimeraxBegin(chimerax->forCgi);
+fprintf(xfh, "\ndisplayPdb(\"%s\", ())\n", pdbSpec);
+if (script != NULL)
+    fputs(script, xfh);
+chimeraxEnd(&xfh);
+}
+