38b9ede07fb3bfb98c74f611c62146b820747e4a
braney
  Sat Dec 11 08:32:34 2021 -0800
check in custom hgc code for support of TOGA gene annotation from
Michael Hiller's group

diff --git src/hg/hgc/togaClick.c src/hg/hgc/togaClick.c
new file mode 100644
index 0000000..86b49db
--- /dev/null
+++ src/hg/hgc/togaClick.c
@@ -0,0 +1,371 @@
+/* togaClick - click handling for TOGA tracks */

+#include "common.h"

+#include "hgc.h"

+#include "togaClick.h"

+#include "string.h"

+#include "htmshell.h"

+

+

+struct togaData *togaDataLoad(char **row)

+/* Load a togaData from row fetched with select * from togaData

+ * from database.  Dispose of this with togaDataFree(). */

+{

+    struct togaData *ret;

+    AllocVar(ret);

+    ret->projection = cloneString(row[0]);

+    ret->ref_trans_id = cloneString(row[1]);

+    ret->ref_region = cloneString(row[2]);

+    ret->query_region = cloneString(row[3]);

+    ret->chain_score = cloneString(row[4]);

+

+    ret->chain_synteny = cloneString(row[5]);

+    ret->chain_flank = cloneString(row[6]);

+    ret->chain_gl_cds_fract = cloneString(row[7]);

+    ret->chain_loc_cds_fract = cloneString(row[8]);

+    ret->chain_exon_cov = cloneString(row[9]);

+

+    ret->chain_intron_cov = cloneString(row[10]);

+    ret->status = cloneString(row[11]);

+    ret->perc_intact_ign_M = cloneString(row[12]);

+    ret->perc_intact_int_M = cloneString(row[13]);

+    ret->intact_codon_prop = cloneString(row[14]);

+

+    ret->ouf_prop = cloneString(row[15]);

+    ret->mid_intact = cloneString(row[16]);

+    ret->mid_pres = cloneString(row[17]);

+    ret->prot_alignment = cloneString(row[18]);

+    ret->svg_line = cloneString(row[19]);

+    return ret;

+}

+

+

+void togaDataFree(struct togaData **pEl)

+/* Free a single dynamically allocated togaDatasuch as created

+ * with togaDataLoad(). */

+{

+    struct togaData *el;

+

+    if ((el = *pEl) == NULL) return;

+    freeMem(el->projection);

+    freeMem(el->ref_trans_id);

+    freeMem(el->ref_region);

+    freeMem(el->query_region);

+    freeMem(el->chain_score);

+

+    freeMem(el->chain_synteny);

+    freeMem(el->chain_flank);

+    freeMem(el->chain_gl_cds_fract);

+    freeMem(el->chain_loc_cds_fract);

+    freeMem(el->chain_exon_cov);

+

+    freeMem(el->chain_intron_cov);

+    freeMem(el->status);

+    freeMem(el->perc_intact_ign_M);

+    freeMem(el->perc_intact_int_M);

+    freeMem(el->intact_codon_prop);

+

+    freeMem(el->ouf_prop);

+    freeMem(el->mid_intact);

+    freeMem(el->mid_pres);

+    freeMem(el->prot_alignment);

+    freeMem(el->svg_line);

+    freez(pEl);

+}

+

+struct togaNucl *togaNuclLoad(char **row)

+/* Load a togaNucl from row fetched with select * from togaNucl

+ * from database.  Dispose of this with togaNuclFree(). */

+{

+    struct togaNucl *ret;

+    AllocVar(ret);

+    ret->transcript = cloneString(row[0]);

+    ret->exon_num = cloneString(row[1]);

+    ret->exon_region = cloneString(row[2]);

+    ret->pid = cloneString(row[3]);

+    ret->blosum = cloneString(row[4]);

+

+    ret->gaps = cloneString(row[5]);

+    ret->ali_class = cloneString(row[6]);

+    ret->exp_region = cloneString(row[7]);

+    ret->in_exp_region = cloneString(row[8]);

+    ret->alignment = cloneString(row[9]);

+    return ret;

+}

+

+

+void togaNuclFree(struct togaNucl **pEl)

+/* Free a single dynamically allocated togaNucl such as created

+ * with togaNuclLoad(). */

+{

+    struct togaNucl *el;

+

+    if ((el = *pEl) == NULL) return;

+    freeMem(el->transcript);

+    freeMem(el->exon_num);

+    freeMem(el->exon_region);

+    freeMem(el->pid);

+    freeMem(el->blosum);

+

+    freeMem(el->gaps);

+    freeMem(el->ali_class);

+    freeMem(el->exp_region);

+    freeMem(el->in_exp_region);

+    freeMem(el->alignment);

+    freez(pEl);

+}

+

+

+struct togaInactMut *togaInactMutLoad(char **row)

+/* Load a togaInactMut from row fetched with select * from togaInactMut

+ * from database.  Dispose of this with togaInactMutFree(). */

+{

+    struct togaInactMut *ret;

+    AllocVar(ret);

+    ret->transcript = cloneString(row[0]);

+    ret->exon_num = cloneString(row[1]);

+    ret->position = cloneString(row[2]);

+    ret->mut_class = cloneString(row[3]);

+    ret->mutation = cloneString(row[4]);

+

+    ret->is_inact = cloneString(row[5]);

+    ret->mut_id = cloneString(row[6]);

+    return ret;

+}

+

+

+void togaInactMutFree(struct togaInactMut **pEl)

+/* Free a single dynamically allocated togaInactMut such as created

+ * with togaInactMutLoad(). */

+{

+    struct togaInactMut *el;

+    if ((el = *pEl) == NULL) return;

+    freeMem(el->transcript);

+    freeMem(el->exon_num);

+    freeMem(el->position);

+    freeMem(el->mut_class);

+    freeMem(el->mutation);

+

+    freeMem(el->is_inact);

+    freeMem(el->mut_id);

+    freez(pEl);

+}

+

+

+void extractHLTOGAsuffix(char *suffix)

+/* Extract suffix from TOGA table name.

+Prefix must be HLTOGAannot */

+{

+    int suff_len = strlen(suffix);

+    if (suff_len <= HLTOGA_BED_PREFIX_LEN)

+    // we cannot chop first PREFIX_LEN characters

+    {

+        // TODO: NOT SURE IF IT WORKS; but this must not happen

+        char empty[5] = { '\0' };

+        strcpy(suffix, empty);

+    } else {

+        // just start the string 11 characters upstream

+        memmove(suffix, suffix + HLTOGA_BED_PREFIX_LEN, suff_len - HLTOGA_BED_PREFIX_LEN + 1);

+    }

+}

+

+

+void doHillerLabTOGAGene(struct trackDb *tdb, char *item, char *table_name)

+/* Put up TOGA Gene track info. */

+{

+    //int start = cartInt(cart, "o");

+    char headerTitle[512];

+    char suffix[512];

+    strcpy(suffix, table_name);

+    extractHLTOGAsuffix(suffix);

+    safef(headerTitle, sizeof(headerTitle), "%s", item);

+    genericHeader(tdb, headerTitle);

+    printf("<h2>TOGA gene annotation</h2>\n");

+    // htmlHorizontalLine();

+    struct sqlConnection *conn = hAllocConn(database);

+    

+    // define TOGA table names: initate with pre-defined prefixes

+    char togaDataTableName[256];

+    char togaNuclTableName[256];

+    char togaInactMutTableName[256];

+    strcpy(togaDataTableName, HLTOGA_DATA_PREFIX);

+    strcpy(togaNuclTableName, HLTOGA_NUCL_PREFIX);

+    strcpy(togaInactMutTableName, HLTOGA_INACT_PREFIX);

+    // add suffix

+    strcat(togaDataTableName, suffix);

+    strcat(togaNuclTableName, suffix);

+    strcat(togaInactMutTableName, suffix);

+

+

+    if (hTableExists(database, togaDataTableName)) 

+    {

+        printf("<h3>Projection %s</h3><BR>\n", item);

+        char query[256];

+        struct sqlResult *sr = NULL;

+        char **row;

+        struct togaData *info = NULL;

+

+        sqlSafef(query, sizeof(query), "select * from %s where transcript='%s'", togaDataTableName, item);

+        sr = sqlGetResult(conn, query);

+

+        if ((row = sqlNextRow(sr)) != NULL) {

+            info = togaDataLoad(row);  // parse sql output

+            // fill HTML template:

+            printf("<B>Projected via: </B><A HREF=\"http://www.ensembl.org/Homo_sapiens/transview?transcript=%s\" target=_blank>%s</A><BR>",

+                   info->ref_trans_id, info->ref_trans_id);

+            printf("<B>Region in reference: </B>%s<BR>\n", info->ref_region);

+            printf("<B>Region in query: </B>%s<BR>\n", info->query_region);

+

+            printf("<B>Projection class: </B>%s<BR>\n", info->status);

+            printf("<B>Chain score: </B>%s<BR>\n", info->chain_score);

+            // list of chain features (for orthology classification)

+            printf("<a data-toggle=\"collapse\" href=\"#collapseChain\">Show chain features for classification</a>\n");

+            printf("<div id=\"collapseChain\" class=\"panel-collapse collapse\">\n");

+            printf("<ul>\n");

+            printf("<li>Synteny: %s</li>\n", info->chain_synteny);

+            printf("<li>Global CDS fraction: %s</li>\n", info->chain_gl_cds_fract);

+            printf("<li>Local CDS fraction: %s</li>\n", info->chain_loc_cds_fract);

+            printf("<li>Local intron fraction: %s</li>\n", info->chain_intron_cov);

+            printf("<li>Local CDS coverage: %s</li>\n", info->chain_exon_cov);

+            printf("<li>Flank fraction: %s</li>\n", info->chain_flank);

+            printf("</ul>\n</div>\n<BR>\n");

+            htmlHorizontalLine();

+

+            // show inact mut plot

+            printf("<h4>Inactivating mutations plot</h4>\n");

+            printf("%s<BR>\n", info->svg_line);

+

+            // GLP features

+            printf("<a data-toggle=\"collapse\" href=\"#collapseGLP\">Show GLP features</a>\n");

+            printf("<div id=\"collapseGLP\" class=\"panel-collapse collapse\">\n");

+            printf("<ul>\n");

+            printf("<li>Percent intact ignoring missing seq: %s</li>\n", info->perc_intact_ign_M);

+            printf("<li>Percent intact (miss == intact): %s</li>\n", info->perc_intact_int_M);

+            printf("<li>Intact codon proportion %s</li>\n", info->intact_codon_prop);

+            printf("<li>Out of chain proportion: %s</li>\n", info->ouf_prop);

+            if (sameWord(info->mid_intact, ONE_))

+            {

+                printf("<li>Middle 80 percent intact: %s</li>\n", YES_);

+            } else {

+                printf("<li>Middle 80 percent intact: %s</li>\n", NO_);

+            }

+            if (sameWord(info->mid_pres, ONE_))

+            {

+                printf("<li>Middle 80 percent present: %s</li>\n", YES_);

+            } else {

+                printf("<li>Middle 80 percent present: %s</li>\n", NO_);

+            }

+            printf("</ul>\n</div>\n<BR>\n");

+

+            // and show protein sequence

+            htmlHorizontalLine();

+            printf("<h4>Protein sequence</h4><BR>\n");

+            printf("<a data-toggle=\"collapse\" href=\"#collapseProt\">Show protein alignment</a>\n");

+            printf("<div id=\"collapseProt\" class=\"panel-collapse collapse\">\n");

+            printf("<TT>%s</TT><BR>\n", info->prot_alignment);

+            printf("</div>\n<BR><BR>\n");

+

+            // do not forget to free toga data struct

+            togaDataFree(&info);

+        } else {

+            // no data found, need to report this

+            printf("Not found data for %s\n", item);

+        }

+        sqlFreeResult(&sr);

+    }

+

+    // show inactivating mutations if required

+    printf("<h4>Inactivating mutations</h4><BR>\n");

+

+    if (hTableExists(database, togaInactMutTableName))

+    {

+        char query[256];

+        struct sqlResult *sr = NULL;

+        char **row;

+        sqlSafef(query, sizeof(query), "select * from %s where transcript='%s'", togaInactMutTableName, item);

+        sr = sqlGetResult(conn, query);

+        printf("<a data-toggle=\"collapse\" href=\"#collapseMuts\">Show inactivating mutations</a>\n");

+        printf("<div id=\"collapseMuts\" class=\"panel-collapse collapse\">\n");

+        printf("<table border = \"1\" width = \"640\">\n");  // init table

+        printf("<tr><th>exon</th><th>pos</th><th>m_class</th><th>mut</th><th>is_inact</th><th>mut_id</th>\n");

+        printf("</tr>\n");

+        while ((row = sqlNextRow(sr)) != NULL)

+        {

+            struct togaInactMut *info = NULL;

+            info = togaInactMutLoad(row);

+            printf("<tr>\n");

+            printf("<td>%s</td>\n", info->exon_num);

+            printf("<td>%s</td>\n", info->position);

+            printf("<td>%s</td>\n", info->mut_class);

+            printf("<td>%s</td>\n", info->mutation);

+            if (sameWord(info->is_inact, ONE_)){

+                printf("<td>%s</td>\n", YES_);

+            } else {

+                printf("<td>%s</td>\n", NO_);

+            }

+            printf("<td>%s</td>\n", info->mut_id);

+            printf("</tr>\n");

+            togaInactMutFree(&info);

+        }

+        sqlFreeResult(&sr);

+        printf("</table>\n");

+        printf("</div>\n<BR>\n");

+    } else {

+        printf("<B>Sorry, cannot find TOGAInactMut table.</B><BR>\n");

+    }

+

+    // show exons data

+    htmlHorizontalLine();

+    printf("<h4>Exons data</h4><BR>\n");

+

+    if (hTableExists(database, togaNuclTableName))

+    {

+        char query[256];

+        struct sqlResult *sr = NULL;

+        char **row;

+        printf("<a data-toggle=\"collapse\" href=\"#collapseExons\">Show exon sequences and features</a>\n");

+        printf("<div id=\"collapseExons\" class=\"panel-collapse collapse\">\n");

+        sqlSafef(query, sizeof(query), "select * from %s where transcript='%s'", togaNuclTableName, item);

+        sr = sqlGetResult(conn, query);

+

+        while ((row = sqlNextRow(sr)) != NULL)

+        {

+            struct togaNucl *info = NULL;

+            info = togaNuclLoad(row);

+            printf("<h5>Exon number: %s</h5><BR>\n", info->exon_num);

+            printf("<B>Exon region:</B> %s<BR>\n", info->exon_region);

+            printf("<B>Nucleotide percent identity:</B> %s | <B>BLOSUM:</B> %s <BR>\n", info->pid, info->blosum);

+            if (sameWord(info->gaps, ONE_)){

+                printf("<B>Intersects assembly gaps:</B> %s<BR>\n", YES_);

+            } else {

+                printf("<B>Intersects assembly gaps:</B> %s<BR>\n", NO_);

+            }

+            printf("<B>Exon alignment class:</B> %s<BR>\n", info->ali_class);

+            if (sameWord(info->in_exp_region, ONE_)){

+                printf("<B>Detected within expected region:</B> %s<BR>\n", YES_);

+            } else {

+                printf("<B>Detected within expected region:</B> %s<BR>\n", NO_);

+            }

+            printf("<B>Expected region:</B> %s<BR>\n", info->exp_region);

+            printf("<BR>\n");

+            printf("<B>Sequence alignment:</B><BR>\n");

+            printf("%s<BR>\n", info->alignment);

+            togaNuclFree(&info);

+        }

+        sqlFreeResult(&sr);

+        printf("</div>\n<BR><BR>\n");

+    } else {

+        printf("<B>Sorry, cannot find TOGANucl table.</B><BR>\n");

+    }

+

+    htmlHorizontalLine();

+

+    // TODO: check whether I need this

+    printf("%s", hgTracksPathAndSettings());

+    hPrintf("<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css\">");

+    hPrintf("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js\"></script>");

+    hPrintf("<script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js\"></script>");

+

+

+    printTrackHtml(tdb);  // and do I need this?

+    hFreeConn(&conn);

+}