533112afe2a2005e80cdb1f82904ea65032d4302
braney
  Sat Oct 2 11:37:34 2021 -0700
split hg/lib into two separate libaries, one only used by the cgis

diff --git src/hg/cgilib/hgExp.c src/hg/cgilib/hgExp.c
new file mode 100644
index 0000000..863463c
--- /dev/null
+++ src/hg/cgilib/hgExp.c
@@ -0,0 +1,328 @@
+/* hgExp - help browse expression data. */
+
+/* Copyright (C) 2014 The Regents of the University of California 
+ * See README in this or parent directory for licensing information. */
+
+#include "common.h"
+#include "hash.h"
+#include "jksql.h"
+#include "hdb.h"
+#include "gifLabel.h"
+#include "cart.h"
+#include "cheapcgi.h"
+#include "hgExp.h"
+#include "portable.h"
+
+
+static int expSubcellWidth = 21;
+
+static char *colorSchemeVals[] = {
+/* Menu option for color scheme. */
+   "red high/green low",
+   "yellow high/blue low",
+};
+
+void hgExpColorDropDown(struct cart *cart, char *varName)
+/* Make color drop-down. */
+{
+char *checked = cartUsualString(cart, varName, colorSchemeVals[0]);
+cgiMakeDropList(varName, 
+	colorSchemeVals, ArraySize(colorSchemeVals), checked);
+}
+
+boolean hgExpRatioUseBlue(struct cart *cart, char *varName)
+/* Return TRUE if should use blue instead of red
+ * in the expression ratios. */
+{
+char *val = cartUsualString(cart, varName, colorSchemeVals[0]);
+return !sameString(val, colorSchemeVals[0]);
+}
+
+char **hgExpGetNames(char *database, char *table, 
+	int expCount, int *expIds, int skipSize)
+/* Create array filled with experiment names. */
+{
+char **names, *name;
+int i;
+char *db = database;
+struct sqlConnection *conn;
+char query[256], nameBuf[128];
+int maxLen = 0, len;
+
+if (!hTableExists(database, table))
+    db = "hgFixed";
+conn = sqlConnect(db);
+/* Read into array and figure out longest name. */
+AllocArray(names, expCount);
+for (i=0; i<expCount; ++i)
+    {
+    int ix = expIds[i];
+    if (ix == -1)
+        names[i] = NULL;
+    else
+	{
+	sqlSafef(query, sizeof(query), "select name from %s where id = %d", 
+	    table, expIds[i]);
+	if ((name = sqlQuickQuery(conn, query, nameBuf, sizeof(nameBuf))) == NULL)
+	    name = "unknown";
+	else
+	    name += skipSize;
+	names[i] = cloneString(name);
+	len = strlen(name);
+	if (len > maxLen) maxLen = len;
+	}
+    }
+sqlDisconnect(&conn);
+
+/* Right justify names. */
+for (i=0; i<expCount; ++i)
+    {
+    char *name = names[i];
+    if (name != NULL)
+        {
+	safef(nameBuf, sizeof(nameBuf), "%*s", maxLen, name);
+	freeMem(name);
+	names[i] = cloneString(nameBuf);
+	}
+    }
+return names;
+}
+
+static int countNonNull(char **row, int maxCount)
+/* Count number of non-null rows. */
+{
+int i;
+for (i=0; i<maxCount; ++i)
+    {
+    if (row[i] == NULL)
+        break;
+    }
+return i;
+}
+
+void hgExpLabelPrint(char *database, char *colName, char *subName, int skipName,
+	char *url, int representativeCount, int *representatives,
+	char *expTable, int gifStart)
+/* Print out labels of various experiments. */
+{
+int i;
+int groupSize;
+char gifName[128];
+char **experiments = hgExpGetNames(database,
+	expTable, representativeCount, representatives, skipName);
+int height = gifLabelMaxWidth(experiments, representativeCount);
+
+for (i=0; i<representativeCount; i += groupSize+1)
+    {
+    printf("<TD VALIGN='BOTTOM' WIDTH=%d>", expSubcellWidth);
+    groupSize = countNonNull(experiments+i, representativeCount-i);
+    safef(gifName, sizeof(gifName), "../trash/nea_%s_%s%d.png", 
+    	colName, subName, ++gifStart);
+    gifLabelVerticalText(gifName, experiments+i, groupSize, height);
+    if (url != NULL)
+       printf("<A HREF=\"%s\">", url); 
+    printf("<IMG BORDER=0 SRC=\"%s\">", gifName);
+    if (url != NULL)
+	printf("</A>");
+    printf("</TD>");
+    }
+
+/* Clean up */
+for (i=0; i<representativeCount; ++i)
+   freeMem(experiments[i]);
+freeMem(experiments);
+}
+
+
+boolean hgExpLoadVals(struct sqlConnection *lookupConn,
+	struct sqlConnection *dataConn,
+	char *lookupTable, char *name, char *dataTable,
+	int *retValCount, float **retVals)
+/* Load up and return expression bed record.  Return NULL
+ * if none of given name exist. */
+{
+char query[256];
+char expName[64];
+struct sqlResult *sr;
+char **row;
+boolean ok = FALSE;
+if (lookupTable != NULL && !sameWord(lookupTable, "null"))
+    {
+    sqlSafef(query, sizeof(query), "select value from %s where name = '%s'", 
+	  lookupTable, name);
+    if (sqlQuickQuery(lookupConn, query, expName, sizeof(expName)) == NULL)
+	return FALSE;
+    sqlSafef(query, sizeof(query), "select expScores from %s where name = '%s'",
+	  dataTable, expName);
+    }
+else
+    sqlSafef(query, sizeof(query), "select expScores from %s where name = '%s'",
+	  dataTable, name);    
+sr = sqlGetResult(dataConn, query);
+if ((row = sqlNextRow(sr)) != NULL)
+    {
+    sqlFloatDynamicArray(row[0], retVals, retValCount);
+    ok = TRUE;
+    }
+sqlFreeResult(&sr);
+return ok;
+}
+
+
+static void hexOne(double val)
+/* Convert val 0.0-1.0 to hex 00 to FF */
+{
+int hex = val * 0xFF;
+if (hex > 0xFF) hex = 0xFF;
+printf("%02X", hex);
+}
+
+static void colorVal(double val, double scale, boolean useBlue, boolean useGrays, boolean logGrays)
+/* Val is -1.0 to 1.0.  Print color in form #FF0000, normally
+ * using green for minus values, red for plus values, but
+ * optionally using blue for minus values and yellow for plus values. */
+{
+if (useGrays)
+    {
+    if (val < 1)
+        printf("000000");
+    else
+	{
+	val = (logGrays) ? log(val) * scale : val * scale;
+	hexOne(val);
+	hexOne(val);
+	hexOne(val);
+	}
+    }
+else 
+    {
+    val *= scale;
+    if (useBlue)
+	{
+	if (val < 0)
+	    {
+	    val = -val;
+	    printf("00");
+	    printf("00");
+	    hexOne(val);
+	    }
+	else
+	    {
+	    val *= 0.7;
+	    hexOne(val);    /* Red */
+	    hexOne(val);     /* Green */
+	    printf("00");   /* Blue */
+	    }
+	}
+    else 
+	{
+	if (val < 0)
+	    {
+	    printf("00");	    /* Red */
+	    hexOne(-val*0.8);    /* Green - brighter than red*/
+	    printf("00");      /* Blue */
+	    }
+	else
+	    {
+	    hexOne(val);
+	    printf("00");
+	    printf("00");
+	    }
+	}
+    }
+}
+
+static void startExpCell()
+/* Print out start of expression cell, which contains a table. */
+{
+printf("<TD><TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0><TR>");
+}
+
+static void endExpCell()
+/* Print out end of expression cell, closing up internal table. */
+{
+printf("</TR></TABLE></TD>");
+}
+
+static void restartExpCell()
+/* End expression cell and begin a new one. */
+{
+endExpCell();
+startExpCell();
+}
+
+static void printRatioShades(char *colName, int repCount, 
+	int *reps, int valCount, float *vals, 
+	boolean colorBlindColors,
+	boolean useGrays, boolean logGrays, float scale)
+/* Print out representatives in shades of color in table background. */
+{
+int i;
+float val;
+startExpCell();
+for (i=0; i<repCount; ++i)
+    {
+    int ix = reps[i];
+    if (ix > valCount)
+        errAbort("Representative larger than biggest experiment in %s", colName);
+    if (ix == -1)
+        {
+	restartExpCell();
+	}
+    else
+	{
+	val = vals[ix];
+	if (val <= -9999)
+	    printf("<TD WIDTH=%d>&nbsp;</TD>", expSubcellWidth);
+	else
+	    {
+	    printf("<TD WIDTH=%d BGCOLOR='#", expSubcellWidth);
+	    colorVal(val, scale, colorBlindColors, useGrays, logGrays);
+	    printf("'>&nbsp;</TD>");
+	    }
+	}
+    }
+endExpCell();
+}
+
+static void replicate(char *s, int repCount, int *reps)
+/* Replicate s in cells of table */
+{
+int i;
+startExpCell();
+printf("%s", s);
+for (i=0; i<repCount; ++i)
+    {
+    int ix = reps[i];
+    if (ix == -1)
+        {
+	restartExpCell();
+	printf("%s", s);
+	}
+    }
+endExpCell();
+}
+
+void hgExpCellPrint(char *colName, char *geneId, 
+	struct sqlConnection *lookupConn, char *lookupTable,
+	struct sqlConnection *dataConn, char *dataTable,
+	int representativeCount, int *representatives,
+	boolean useBlue, boolean useGrays, boolean logGrays, float scale)
+/* Print out html for expression cell in table. */
+{
+int valCount;
+float *vals = NULL;
+
+if (hgExpLoadVals(lookupConn, dataConn, lookupTable, geneId, dataTable, 
+	&valCount, &vals))
+    {
+    printRatioShades(colName, representativeCount, representatives, 
+    	valCount, vals, useBlue, useGrays, logGrays, scale);
+    freez(&vals);
+    }
+else
+    {
+    replicate("<TD>n/a</TD>", representativeCount, representatives);
+    }
+}
+