e70152e44cc66cc599ff6b699eb8adc07f3e656a
kent
  Sat May 24 21:09:34 2014 -0700
Adding Copyright NNNN Regents of the University of California to all files I believe with reasonable certainty were developed under UCSC employ or as part of Genome Browser copyright assignment.
diff --git src/hg/lib/ispyTables.c src/hg/lib/ispyTables.c
index aafa726..98e01dd 100644
--- src/hg/lib/ispyTables.c
+++ src/hg/lib/ispyTables.c
@@ -1,2766 +1,2769 @@
 /* ispyTables.c was originally generated by the autoSql program, which also 
  * generated ispyTables.h and ispyTables.sql.  This module links the database and
  * the RAM representation of objects. */
 
+/* Copyright (C) 2014 The Regents of the University of California 
+ * See README in this or parent directory for licensing information. */
+
 #include "common.h"
 #include "linefile.h"
 #include "dystring.h"
 #include "jksql.h"
 #include "ispyTables.h"
 
 
 void patientStaticLoadWithNull(char **row, struct patient *ret)
 /* Load a row from patient table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->ispyId = row[0];
 ret->DataExtractDt = row[1];
 ret->Inst_ID = row[2];
 }
 
 struct patient *patientLoadWithNull(char **row)
 /* Load a patient from row fetched with select * from patient
  * from database.  Dispose of this with patientFree(). */
 {
 struct patient *ret;
 
 AllocVar(ret);
 ret->ispyId = cloneString(row[0]);
 ret->DataExtractDt = cloneString(row[1]);
 ret->Inst_ID = cloneString(row[2]);
 return ret;
 }
 
 struct patient *patientLoadAll(char *fileName) 
 /* Load all patient from a whitespace-separated file.
  * Dispose of this with patientFreeList(). */
 {
 struct patient *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[3];
 
 while (lineFileRow(lf, row))
     {
     el = patientLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct patient *patientLoadAllByChar(char *fileName, char chopper) 
 /* Load all patient from a chopper separated file.
  * Dispose of this with patientFreeList(). */
 {
 struct patient *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[3];
 
 while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
     {
     el = patientLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct patient *patientLoadByQuery(struct sqlConnection *conn, char *query)
 /* Load all patient 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 patientFreeList(). */
 {
 struct patient *list = NULL, *el;
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = patientLoadWithNull(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void patientSaveToDb(struct sqlConnection *conn, struct patient *el, char *tableName, int updateSize)
 /* Save patient as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
  * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */
 {
 struct dyString *update = newDyString(updateSize);
 sqlDyStringPrintf(update, "insert into %s values ( '%s','%s','%s')", 
 	tableName,  el->ispyId,  el->DataExtractDt,  el->Inst_ID);
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
 
 struct patient *patientCommaIn(char **pS, struct patient *ret)
 /* Create a patient out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new patient */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->ispyId = sqlStringComma(&s);
 ret->DataExtractDt = sqlStringComma(&s);
 ret->Inst_ID = sqlStringComma(&s);
 *pS = s;
 return ret;
 }
 
 void patientFree(struct patient **pEl)
 /* Free a single dynamically allocated patient such as created
  * with patientLoad(). */
 {
 struct patient *el;
 
 if ((el = *pEl) == NULL) return;
 freeMem(el->ispyId);
 freeMem(el->DataExtractDt);
 freeMem(el->Inst_ID);
 freez(pEl);
 }
 
 void patientFreeList(struct patient **pList)
 /* Free a list of dynamically allocated patient's */
 {
 struct patient *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     patientFree(&el);
     }
 *pList = NULL;
 }
 
 void patientOutput(struct patient *el, FILE *f, char sep, char lastSep) 
 /* Print out patient.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ispyId);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->DataExtractDt);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Inst_ID);
 if (sep == ',') fputc('"',f);
 fputc(lastSep,f);
 }
 
 void patientInfoStaticLoadWithNull(char **row, struct patientInfo *ret)
 /* Load a row from patientInfo table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->ispyId = row[0];
 ret->DataExtractDt = row[1];
 ret->Inst_ID = row[2];
 ret->AgeCat = row[3];
 if (row[4] != NULL)
     {
     ret->Age = needMem(sizeof(float));
     *(ret->Age) = sqlFloat(row[4]);
     }
 ret->Race_id = row[5];
 ret->Sstat = row[6];
 if (row[7] != NULL)
     {
     ret->SurvDtD = needMem(sizeof(*(ret->SurvDtD)));
     *(ret->SurvDtD) = sqlSigned(row[7]);
     }
 else
     {
     ret->SurvDtD = NULL;
     }
 }
 
 struct patientInfo *patientInfoLoadWithNull(char **row)
 /* Load a patientInfo from row fetched with select * from patientInfo
  * from database.  Dispose of this with patientInfoFree(). */
 {
 struct patientInfo *ret;
 
 AllocVar(ret);
 ret->ispyId = cloneString(row[0]);
 ret->DataExtractDt = cloneString(row[1]);
 ret->Inst_ID = cloneString(row[2]);
 ret->AgeCat = cloneString(row[3]);
 if (row[4] != NULL)
     {
     ret->Age = needMem(sizeof(float));
     *(ret->Age) = sqlFloat(row[4]);
     }
 ret->Race_id = cloneString(row[5]);
 ret->Sstat = cloneString(row[6]);
 if (row[7] != NULL)
     {
     ret->SurvDtD = needMem(sizeof(*(ret->SurvDtD)));
     *(ret->SurvDtD) = sqlSigned(row[7]);
     }
 else
     {
     ret->SurvDtD = NULL;
     }
 return ret;
 }
 
 struct patientInfo *patientInfoLoadAll(char *fileName) 
 /* Load all patientInfo from a whitespace-separated file.
  * Dispose of this with patientInfoFreeList(). */
 {
 struct patientInfo *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[8];
 
 while (lineFileRow(lf, row))
     {
     el = patientInfoLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct patientInfo *patientInfoLoadAllByChar(char *fileName, char chopper) 
 /* Load all patientInfo from a chopper separated file.
  * Dispose of this with patientInfoFreeList(). */
 {
 struct patientInfo *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[8];
 
 while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
     {
     el = patientInfoLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct patientInfo *patientInfoLoadByQuery(struct sqlConnection *conn, char *query)
 /* Load all patientInfo 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 patientInfoFreeList(). */
 {
 struct patientInfo *list = NULL, *el;
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = patientInfoLoadWithNull(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void patientInfoSaveToDb(struct sqlConnection *conn, struct patientInfo *el, char *tableName, int updateSize)
 /* Save patientInfo as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
  * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */
 {
 struct dyString *update = newDyString(updateSize);
 sqlDyStringPrintf(update, "insert into %s values ( '%s','%s','%s','%s',%g,'%s','%s',%d)", 
 	tableName,  el->ispyId,  el->DataExtractDt,  el->Inst_ID,  el->AgeCat,  *(el->Age),  el->Race_id,  el->Sstat,  *(el->SurvDtD));
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
 
 struct patientInfo *patientInfoCommaIn(char **pS, struct patientInfo *ret)
 /* Create a patientInfo out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new patientInfo */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->ispyId = sqlStringComma(&s);
 ret->DataExtractDt = sqlStringComma(&s);
 ret->Inst_ID = sqlStringComma(&s);
 ret->AgeCat = sqlStringComma(&s);
 ret->Age = needMem(sizeof(*(ret->Age)));
 *(ret->Age) = sqlFloatComma(&s);
 ret->Race_id = sqlStringComma(&s);
 ret->Sstat = sqlStringComma(&s);
 ret->SurvDtD = needMem(sizeof(*(ret->SurvDtD)));
 *(ret->SurvDtD) = sqlSignedComma(&s);
 *pS = s;
 return ret;
 }
 
 void patientInfoFree(struct patientInfo **pEl)
 /* Free a single dynamically allocated patientInfo such as created
  * with patientInfoLoad(). */
 {
 struct patientInfo *el;
 
 if ((el = *pEl) == NULL) return;
 freeMem(el->ispyId);
 freeMem(el->DataExtractDt);
 freeMem(el->Inst_ID);
 freeMem(el->AgeCat);
 freeMem(el->Race_id);
 freeMem(el->Sstat);
 freez(pEl);
 }
 
 void patientInfoFreeList(struct patientInfo **pList)
 /* Free a list of dynamically allocated patientInfo's */
 {
 struct patientInfo *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     patientInfoFree(&el);
     }
 *pList = NULL;
 }
 
 void patientInfoOutput(struct patientInfo *el, FILE *f, char sep, char lastSep) 
 /* Print out patientInfo.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ispyId);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->DataExtractDt);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Inst_ID);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->AgeCat);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 fprintf(f, "%g", *(el->Age));
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Race_id);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Sstat);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 fprintf(f, "%d", *(el->SurvDtD));
 fputc(lastSep,f);
 }
 
 void chemoStaticLoadWithNull(char **row, struct chemo *ret)
 /* Load a row from chemo table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->ispyId = row[0];
 ret->Chemo = row[1];
 ret->ChemoCat = row[2];
 ret->DoseDenseAnthra = row[3];
 ret->DoseDenseTaxane = row[4];
 ret->Tam = row[5];
 ret->Herceptin = row[6];
 }
 
 struct chemo *chemoLoadWithNull(char **row)
 /* Load a chemo from row fetched with select * from chemo
  * from database.  Dispose of this with chemoFree(). */
 {
 struct chemo *ret;
 
 AllocVar(ret);
 ret->ispyId = cloneString(row[0]);
 ret->Chemo = cloneString(row[1]);
 ret->ChemoCat = cloneString(row[2]);
 ret->DoseDenseAnthra = cloneString(row[3]);
 ret->DoseDenseTaxane = cloneString(row[4]);
 ret->Tam = cloneString(row[5]);
 ret->Herceptin = cloneString(row[6]);
 return ret;
 }
 
 struct chemo *chemoLoadAll(char *fileName) 
 /* Load all chemo from a whitespace-separated file.
  * Dispose of this with chemoFreeList(). */
 {
 struct chemo *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[7];
 
 while (lineFileRow(lf, row))
     {
     el = chemoLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct chemo *chemoLoadAllByChar(char *fileName, char chopper) 
 /* Load all chemo from a chopper separated file.
  * Dispose of this with chemoFreeList(). */
 {
 struct chemo *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[7];
 
 while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
     {
     el = chemoLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct chemo *chemoLoadByQuery(struct sqlConnection *conn, char *query)
 /* Load all chemo 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 chemoFreeList(). */
 {
 struct chemo *list = NULL, *el;
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = chemoLoadWithNull(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void chemoSaveToDb(struct sqlConnection *conn, struct chemo *el, char *tableName, int updateSize)
 /* Save chemo as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
  * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */
 {
 struct dyString *update = newDyString(updateSize);
 sqlDyStringPrintf(update, "insert into %s values ( '%s','%s','%s','%s','%s','%s','%s')", 
 	tableName,  el->ispyId,  el->Chemo,  el->ChemoCat,  el->DoseDenseAnthra,  el->DoseDenseTaxane,  el->Tam,  el->Herceptin);
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
 
 struct chemo *chemoCommaIn(char **pS, struct chemo *ret)
 /* Create a chemo out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new chemo */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->ispyId = sqlStringComma(&s);
 ret->Chemo = sqlStringComma(&s);
 ret->ChemoCat = sqlStringComma(&s);
 ret->DoseDenseAnthra = sqlStringComma(&s);
 ret->DoseDenseTaxane = sqlStringComma(&s);
 ret->Tam = sqlStringComma(&s);
 ret->Herceptin = sqlStringComma(&s);
 *pS = s;
 return ret;
 }
 
 void chemoFree(struct chemo **pEl)
 /* Free a single dynamically allocated chemo such as created
  * with chemoLoad(). */
 {
 struct chemo *el;
 
 if ((el = *pEl) == NULL) return;
 freeMem(el->ispyId);
 freeMem(el->Chemo);
 freeMem(el->ChemoCat);
 freeMem(el->DoseDenseAnthra);
 freeMem(el->DoseDenseTaxane);
 freeMem(el->Tam);
 freeMem(el->Herceptin);
 freez(pEl);
 }
 
 void chemoFreeList(struct chemo **pList)
 /* Free a list of dynamically allocated chemo's */
 {
 struct chemo *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     chemoFree(&el);
     }
 *pList = NULL;
 }
 
 void chemoOutput(struct chemo *el, FILE *f, char sep, char lastSep) 
 /* Print out chemo.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ispyId);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Chemo);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ChemoCat);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->DoseDenseAnthra);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->DoseDenseTaxane);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Tam);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Herceptin);
 if (sep == ',') fputc('"',f);
 fputc(lastSep,f);
 }
 
 void onStudyStaticLoadWithNull(char **row, struct onStudy *ret)
 /* Load a row from onStudy table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->ispyId = row[0];
 ret->MenoStatus = row[1];
 ret->SentinelNodeSample = row[2];
 ret->SentinelNodeResult = row[3];
 ret->HistTypeInvOS = row[4];
 ret->HistologicGradeOS = row[5];
 if (row[6] != NULL)
     {
     ret->ER_TS = needMem(sizeof(*(ret->ER_TS)));
     *(ret->ER_TS) = sqlSigned(row[6]);
     }
 else
     {
     ret->ER_TS = NULL;
     }
 if (row[7] != NULL)
     {
     ret->PgR_TS = needMem(sizeof(*(ret->PgR_TS)));
     *(ret->PgR_TS) = sqlSigned(row[7]);
     }
 else
     {
     ret->PgR_TS = NULL;
     }
 ret->ERpos = row[8];
 ret->PgRpos = row[9];
 ret->Her2CommunityPos = row[10];
 ret->Her2CommunityMethod = row[11];
 ret->pCR = row[12];
 }
 
 struct onStudy *onStudyLoadWithNull(char **row)
 /* Load a onStudy from row fetched with select * from onStudy
  * from database.  Dispose of this with onStudyFree(). */
 {
 struct onStudy *ret;
 
 AllocVar(ret);
 ret->ispyId = cloneString(row[0]);
 ret->MenoStatus = cloneString(row[1]);
 ret->SentinelNodeSample = cloneString(row[2]);
 ret->SentinelNodeResult = cloneString(row[3]);
 ret->HistTypeInvOS = cloneString(row[4]);
 ret->HistologicGradeOS = cloneString(row[5]);
 if (row[6] != NULL)
     {
     ret->ER_TS = needMem(sizeof(*(ret->ER_TS)));
     *(ret->ER_TS) = sqlSigned(row[6]);
     }
 else
     {
     ret->ER_TS = NULL;
     }
 if (row[7] != NULL)
     {
     ret->PgR_TS = needMem(sizeof(*(ret->PgR_TS)));
     *(ret->PgR_TS) = sqlSigned(row[7]);
     }
 else
     {
     ret->PgR_TS = NULL;
     }
 ret->ERpos = cloneString(row[8]);
 ret->PgRpos = cloneString(row[9]);
 ret->Her2CommunityPos = cloneString(row[10]);
 ret->Her2CommunityMethod = cloneString(row[11]);
 ret->pCR = cloneString(row[12]);
 return ret;
 }
 
 struct onStudy *onStudyLoadAll(char *fileName) 
 /* Load all onStudy from a whitespace-separated file.
  * Dispose of this with onStudyFreeList(). */
 {
 struct onStudy *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[13];
 
 while (lineFileRow(lf, row))
     {
     el = onStudyLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct onStudy *onStudyLoadAllByChar(char *fileName, char chopper) 
 /* Load all onStudy from a chopper separated file.
  * Dispose of this with onStudyFreeList(). */
 {
 struct onStudy *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[13];
 
 while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
     {
     el = onStudyLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct onStudy *onStudyLoadByQuery(struct sqlConnection *conn, char *query)
 /* Load all onStudy 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 onStudyFreeList(). */
 {
 struct onStudy *list = NULL, *el;
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = onStudyLoadWithNull(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void onStudySaveToDb(struct sqlConnection *conn, struct onStudy *el, char *tableName, int updateSize)
 /* Save onStudy as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
  * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */
 {
 struct dyString *update = newDyString(updateSize);
 sqlDyStringPrintf(update, "insert into %s values ( '%s','%s','%s','%s','%s','%s',%d,%d,'%s','%s','%s','%s','%s')", 
 	tableName,  el->ispyId,  el->MenoStatus,  el->SentinelNodeSample,  el->SentinelNodeResult,  el->HistTypeInvOS,  el->HistologicGradeOS,  *(el->ER_TS),  *(el->PgR_TS),  el->ERpos,  el->PgRpos,  el->Her2CommunityPos,  el->Her2CommunityMethod,  el->pCR);
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
 
 struct onStudy *onStudyCommaIn(char **pS, struct onStudy *ret)
 /* Create a onStudy out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new onStudy */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->ispyId = sqlStringComma(&s);
 ret->MenoStatus = sqlStringComma(&s);
 ret->SentinelNodeSample = sqlStringComma(&s);
 ret->SentinelNodeResult = sqlStringComma(&s);
 ret->HistTypeInvOS = sqlStringComma(&s);
 ret->HistologicGradeOS = sqlStringComma(&s);
 ret->ER_TS = needMem(sizeof(*(ret->ER_TS)));
 *(ret->ER_TS) = sqlSignedComma(&s);
 ret->PgR_TS = needMem(sizeof(*(ret->PgR_TS)));
 *(ret->PgR_TS) = sqlSignedComma(&s);
 ret->ERpos = sqlStringComma(&s);
 ret->PgRpos = sqlStringComma(&s);
 ret->Her2CommunityPos = sqlStringComma(&s);
 ret->Her2CommunityMethod = sqlStringComma(&s);
 ret->pCR = sqlStringComma(&s);
 *pS = s;
 return ret;
 }
 
 void onStudyFree(struct onStudy **pEl)
 /* Free a single dynamically allocated onStudy such as created
  * with onStudyLoad(). */
 {
 struct onStudy *el;
 
 if ((el = *pEl) == NULL) return;
 freeMem(el->ispyId);
 freeMem(el->MenoStatus);
 freeMem(el->SentinelNodeSample);
 freeMem(el->SentinelNodeResult);
 freeMem(el->HistTypeInvOS);
 freeMem(el->HistologicGradeOS);
 freeMem(el->ERpos);
 freeMem(el->PgRpos);
 freeMem(el->Her2CommunityPos);
 freeMem(el->Her2CommunityMethod);
 freeMem(el->pCR);
 freez(pEl);
 }
 
 void onStudyFreeList(struct onStudy **pList)
 /* Free a list of dynamically allocated onStudy's */
 {
 struct onStudy *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     onStudyFree(&el);
     }
 *pList = NULL;
 }
 
 void onStudyOutput(struct onStudy *el, FILE *f, char sep, char lastSep) 
 /* Print out onStudy.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ispyId);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->MenoStatus);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->SentinelNodeSample);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->SentinelNodeResult);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->HistTypeInvOS);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->HistologicGradeOS);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 fprintf(f, "%d", *(el->ER_TS));
 fputc(sep,f);
 fprintf(f, "%d", *(el->PgR_TS));
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ERpos);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->PgRpos);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Her2CommunityPos);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Her2CommunityMethod);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->pCR);
 if (sep == ',') fputc('"',f);
 fputc(lastSep,f);
 }
 
 void postSurgeryStaticLoadWithNull(char **row, struct postSurgery *ret)
 /* Load a row from postSurgery table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->ispyId = row[0];
 ret->SurgeryLumpectomy = row[1];
 ret->SurgeryMastectomy = row[2];
 ret->InitLump_FupMast = row[3];
 ret->Surgery = row[4];
 ret->DCISonly = row[5];
 if (row[6] != NULL)
     {
     ret->PTumor1Szcm_Micro = needMem(sizeof(float));
     *(ret->PTumor1Szcm_Micro) = sqlFloat(row[6]);
     }
 ret->HistologicTypePS = row[7];
 if (row[8] != NULL)
     {
     ret->HistologicGradePS = needMem(sizeof(*(ret->HistologicGradePS)));
     *(ret->HistologicGradePS) = sqlSigned(row[8]);
     }
 else
     {
     ret->HistologicGradePS = NULL;
     }
 if (row[9] != NULL)
     {
     ret->NumPosNodes = needMem(sizeof(*(ret->NumPosNodes)));
     *(ret->NumPosNodes) = sqlSigned(row[9]);
     }
 else
     {
     ret->NumPosNodes = NULL;
     }
 ret->NodesExamined = row[10];
 ret->PathologyStage = row[11];
 ret->ReasonNoSurg = row[12];
 }
 
 struct postSurgery *postSurgeryLoadWithNull(char **row)
 /* Load a postSurgery from row fetched with select * from postSurgery
  * from database.  Dispose of this with postSurgeryFree(). */
 {
 struct postSurgery *ret;
 
 AllocVar(ret);
 ret->ispyId = cloneString(row[0]);
 ret->SurgeryLumpectomy = cloneString(row[1]);
 ret->SurgeryMastectomy = cloneString(row[2]);
 ret->InitLump_FupMast = cloneString(row[3]);
 ret->Surgery = cloneString(row[4]);
 ret->DCISonly = cloneString(row[5]);
 if (row[6] != NULL)
     {
     ret->PTumor1Szcm_Micro = needMem(sizeof(float));
     *(ret->PTumor1Szcm_Micro) = sqlFloat(row[6]);
     }
 ret->HistologicTypePS = cloneString(row[7]);
 if (row[8] != NULL)
     {
     ret->HistologicGradePS = needMem(sizeof(*(ret->HistologicGradePS)));
     *(ret->HistologicGradePS) = sqlSigned(row[8]);
     }
 else
     {
     ret->HistologicGradePS = NULL;
     }
 if (row[9] != NULL)
     {
     ret->NumPosNodes = needMem(sizeof(*(ret->NumPosNodes)));
     *(ret->NumPosNodes) = sqlSigned(row[9]);
     }
 else
     {
     ret->NumPosNodes = NULL;
     }
 ret->NodesExamined = cloneString(row[10]);
 ret->PathologyStage = cloneString(row[11]);
 ret->ReasonNoSurg = cloneString(row[12]);
 return ret;
 }
 
 struct postSurgery *postSurgeryLoadAll(char *fileName) 
 /* Load all postSurgery from a whitespace-separated file.
  * Dispose of this with postSurgeryFreeList(). */
 {
 struct postSurgery *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[13];
 
 while (lineFileRow(lf, row))
     {
     el = postSurgeryLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct postSurgery *postSurgeryLoadAllByChar(char *fileName, char chopper) 
 /* Load all postSurgery from a chopper separated file.
  * Dispose of this with postSurgeryFreeList(). */
 {
 struct postSurgery *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[13];
 
 while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
     {
     el = postSurgeryLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct postSurgery *postSurgeryLoadByQuery(struct sqlConnection *conn, char *query)
 /* Load all postSurgery 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 postSurgeryFreeList(). */
 {
 struct postSurgery *list = NULL, *el;
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = postSurgeryLoadWithNull(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void postSurgerySaveToDb(struct sqlConnection *conn, struct postSurgery *el, char *tableName, int updateSize)
 /* Save postSurgery as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
  * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */
 {
 struct dyString *update = newDyString(updateSize);
 sqlDyStringPrintf(update, "insert into %s values ( '%s','%s','%s','%s','%s','%s',%g,'%s',%d,%d,'%s','%s','%s')", 
 	tableName,  el->ispyId,  el->SurgeryLumpectomy,  el->SurgeryMastectomy,  el->InitLump_FupMast,  el->Surgery,  el->DCISonly,  *(el->PTumor1Szcm_Micro),  el->HistologicTypePS,  *(el->HistologicGradePS),  *(el->NumPosNodes),  el->NodesExamined,  el->PathologyStage,  el->ReasonNoSurg);
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
 
 struct postSurgery *postSurgeryCommaIn(char **pS, struct postSurgery *ret)
 /* Create a postSurgery out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new postSurgery */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->ispyId = sqlStringComma(&s);
 ret->SurgeryLumpectomy = sqlStringComma(&s);
 ret->SurgeryMastectomy = sqlStringComma(&s);
 ret->InitLump_FupMast = sqlStringComma(&s);
 ret->Surgery = sqlStringComma(&s);
 ret->DCISonly = sqlStringComma(&s);
 ret->PTumor1Szcm_Micro = needMem(sizeof(*(ret->PTumor1Szcm_Micro)));
 *(ret->PTumor1Szcm_Micro) = sqlFloatComma(&s);
 ret->HistologicTypePS = sqlStringComma(&s);
 ret->HistologicGradePS = needMem(sizeof(*(ret->HistologicGradePS)));
 *(ret->HistologicGradePS) = sqlSignedComma(&s);
 ret->NumPosNodes = needMem(sizeof(*(ret->NumPosNodes)));
 *(ret->NumPosNodes) = sqlSignedComma(&s);
 ret->NodesExamined = sqlStringComma(&s);
 ret->PathologyStage = sqlStringComma(&s);
 ret->ReasonNoSurg = sqlStringComma(&s);
 *pS = s;
 return ret;
 }
 
 void postSurgeryFree(struct postSurgery **pEl)
 /* Free a single dynamically allocated postSurgery such as created
  * with postSurgeryLoad(). */
 {
 struct postSurgery *el;
 
 if ((el = *pEl) == NULL) return;
 freeMem(el->ispyId);
 freeMem(el->SurgeryLumpectomy);
 freeMem(el->SurgeryMastectomy);
 freeMem(el->InitLump_FupMast);
 freeMem(el->Surgery);
 freeMem(el->DCISonly);
 freeMem(el->HistologicTypePS);
 freeMem(el->NodesExamined);
 freeMem(el->PathologyStage);
 freeMem(el->ReasonNoSurg);
 freez(pEl);
 }
 
 void postSurgeryFreeList(struct postSurgery **pList)
 /* Free a list of dynamically allocated postSurgery's */
 {
 struct postSurgery *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     postSurgeryFree(&el);
     }
 *pList = NULL;
 }
 
 void postSurgeryOutput(struct postSurgery *el, FILE *f, char sep, char lastSep) 
 /* Print out postSurgery.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ispyId);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->SurgeryLumpectomy);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->SurgeryMastectomy);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->InitLump_FupMast);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Surgery);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->DCISonly);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 fprintf(f, "%g", *(el->PTumor1Szcm_Micro));
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->HistologicTypePS);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 fprintf(f, "%d", *(el->HistologicGradePS));
 fputc(sep,f);
 fprintf(f, "%d", *(el->NumPosNodes));
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->NodesExamined);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->PathologyStage);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ReasonNoSurg);
 if (sep == ',') fputc('"',f);
 fputc(lastSep,f);
 }
 
 void followUpStaticLoadWithNull(char **row, struct followUp *ret)
 /* Load a row from followUp table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->ispyId = row[0];
 ret->RtTherapy = row[1];
 ret->RtBreast = row[2];
 ret->RtBoost = row[3];
 ret->RtAxilla = row[4];
 ret->RtSNode = row[5];
 ret->RtIMamNode = row[6];
 ret->RTChestW = row[7];
 ret->RtOther = row[8];
 }
 
 struct followUp *followUpLoadWithNull(char **row)
 /* Load a followUp from row fetched with select * from followUp
  * from database.  Dispose of this with followUpFree(). */
 {
 struct followUp *ret;
 
 AllocVar(ret);
 ret->ispyId = cloneString(row[0]);
 ret->RtTherapy = cloneString(row[1]);
 ret->RtBreast = cloneString(row[2]);
 ret->RtBoost = cloneString(row[3]);
 ret->RtAxilla = cloneString(row[4]);
 ret->RtSNode = cloneString(row[5]);
 ret->RtIMamNode = cloneString(row[6]);
 ret->RTChestW = cloneString(row[7]);
 ret->RtOther = cloneString(row[8]);
 return ret;
 }
 
 struct followUp *followUpLoadAll(char *fileName) 
 /* Load all followUp from a whitespace-separated file.
  * Dispose of this with followUpFreeList(). */
 {
 struct followUp *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[9];
 
 while (lineFileRow(lf, row))
     {
     el = followUpLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct followUp *followUpLoadAllByChar(char *fileName, char chopper) 
 /* Load all followUp from a chopper separated file.
  * Dispose of this with followUpFreeList(). */
 {
 struct followUp *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[9];
 
 while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
     {
     el = followUpLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct followUp *followUpLoadByQuery(struct sqlConnection *conn, char *query)
 /* Load all followUp 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 followUpFreeList(). */
 {
 struct followUp *list = NULL, *el;
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = followUpLoadWithNull(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void followUpSaveToDb(struct sqlConnection *conn, struct followUp *el, char *tableName, int updateSize)
 /* Save followUp as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
  * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */
 {
 struct dyString *update = newDyString(updateSize);
 sqlDyStringPrintf(update, "insert into %s values ( '%s','%s','%s','%s','%s','%s','%s','%s','%s')", 
 	tableName,  el->ispyId,  el->RtTherapy,  el->RtBreast,  el->RtBoost,  el->RtAxilla,  el->RtSNode,  el->RtIMamNode,  el->RTChestW,  el->RtOther);
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
 
 struct followUp *followUpCommaIn(char **pS, struct followUp *ret)
 /* Create a followUp out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new followUp */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->ispyId = sqlStringComma(&s);
 ret->RtTherapy = sqlStringComma(&s);
 ret->RtBreast = sqlStringComma(&s);
 ret->RtBoost = sqlStringComma(&s);
 ret->RtAxilla = sqlStringComma(&s);
 ret->RtSNode = sqlStringComma(&s);
 ret->RtIMamNode = sqlStringComma(&s);
 ret->RTChestW = sqlStringComma(&s);
 ret->RtOther = sqlStringComma(&s);
 *pS = s;
 return ret;
 }
 
 void followUpFree(struct followUp **pEl)
 /* Free a single dynamically allocated followUp such as created
  * with followUpLoad(). */
 {
 struct followUp *el;
 
 if ((el = *pEl) == NULL) return;
 freeMem(el->ispyId);
 freeMem(el->RtTherapy);
 freeMem(el->RtBreast);
 freeMem(el->RtBoost);
 freeMem(el->RtAxilla);
 freeMem(el->RtSNode);
 freeMem(el->RtIMamNode);
 freeMem(el->RTChestW);
 freeMem(el->RtOther);
 freez(pEl);
 }
 
 void followUpFreeList(struct followUp **pList)
 /* Free a list of dynamically allocated followUp's */
 {
 struct followUp *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     followUpFree(&el);
     }
 *pList = NULL;
 }
 
 void followUpOutput(struct followUp *el, FILE *f, char sep, char lastSep) 
 /* Print out followUp.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ispyId);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->RtTherapy);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->RtBreast);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->RtBoost);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->RtAxilla);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->RtSNode);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->RtIMamNode);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->RTChestW);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->RtOther);
 if (sep == ',') fputc('"',f);
 fputc(lastSep,f);
 }
 
 void respEvalStaticLoadWithNull(char **row, struct respEval *ret)
 /* Load a row from respEval table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->ispyId = row[0];
 if (row[1] != NULL)
     {
     ret->TSizeClinical = needMem(sizeof(float));
     *(ret->TSizeClinical) = sqlFloat(row[1]);
     }
 if (row[2] != NULL)
     {
     ret->NSizeClinical = needMem(sizeof(float));
     *(ret->NSizeClinical) = sqlFloat(row[2]);
     }
 ret->StageTe = row[3];
 ret->StageNe = row[4];
 ret->StageMe = row[5];
 ret->ClinicalStage = row[6];
 ret->ClinRespT1_T2 = row[7];
 ret->ClinRespT1_T3 = row[8];
 ret->ClinRespT1_T4 = row[9];
 }
 
 struct respEval *respEvalLoadWithNull(char **row)
 /* Load a respEval from row fetched with select * from respEval
  * from database.  Dispose of this with respEvalFree(). */
 {
 struct respEval *ret;
 
 AllocVar(ret);
 ret->ispyId = cloneString(row[0]);
 if (row[1] != NULL)
     {
     ret->TSizeClinical = needMem(sizeof(float));
     *(ret->TSizeClinical) = sqlFloat(row[1]);
     }
 if (row[2] != NULL)
     {
     ret->NSizeClinical = needMem(sizeof(float));
     *(ret->NSizeClinical) = sqlFloat(row[2]);
     }
 ret->StageTe = cloneString(row[3]);
 ret->StageNe = cloneString(row[4]);
 ret->StageMe = cloneString(row[5]);
 ret->ClinicalStage = cloneString(row[6]);
 ret->ClinRespT1_T2 = cloneString(row[7]);
 ret->ClinRespT1_T3 = cloneString(row[8]);
 ret->ClinRespT1_T4 = cloneString(row[9]);
 return ret;
 }
 
 struct respEval *respEvalLoadAll(char *fileName) 
 /* Load all respEval from a whitespace-separated file.
  * Dispose of this with respEvalFreeList(). */
 {
 struct respEval *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[10];
 
 while (lineFileRow(lf, row))
     {
     el = respEvalLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct respEval *respEvalLoadAllByChar(char *fileName, char chopper) 
 /* Load all respEval from a chopper separated file.
  * Dispose of this with respEvalFreeList(). */
 {
 struct respEval *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[10];
 
 while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
     {
     el = respEvalLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct respEval *respEvalLoadByQuery(struct sqlConnection *conn, char *query)
 /* Load all respEval 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 respEvalFreeList(). */
 {
 struct respEval *list = NULL, *el;
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = respEvalLoadWithNull(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void respEvalSaveToDb(struct sqlConnection *conn, struct respEval *el, char *tableName, int updateSize)
 /* Save respEval as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
  * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */
 {
 struct dyString *update = newDyString(updateSize);
 sqlDyStringPrintf(update, "insert into %s values ( '%s',%g,%g,'%s','%s','%s','%s','%s','%s','%s')", 
 	tableName,  el->ispyId,  *(el->TSizeClinical),  *(el->NSizeClinical),  el->StageTe,  el->StageNe,  el->StageMe,  el->ClinicalStage,  el->ClinRespT1_T2,  el->ClinRespT1_T3,  el->ClinRespT1_T4);
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
 
 struct respEval *respEvalCommaIn(char **pS, struct respEval *ret)
 /* Create a respEval out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new respEval */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->ispyId = sqlStringComma(&s);
 ret->TSizeClinical = needMem(sizeof(*(ret->TSizeClinical)));
 *(ret->TSizeClinical) = sqlFloatComma(&s);
 ret->NSizeClinical = needMem(sizeof(*(ret->NSizeClinical)));
 *(ret->NSizeClinical) = sqlFloatComma(&s);
 ret->StageTe = sqlStringComma(&s);
 ret->StageNe = sqlStringComma(&s);
 ret->StageMe = sqlStringComma(&s);
 ret->ClinicalStage = sqlStringComma(&s);
 ret->ClinRespT1_T2 = sqlStringComma(&s);
 ret->ClinRespT1_T3 = sqlStringComma(&s);
 ret->ClinRespT1_T4 = sqlStringComma(&s);
 *pS = s;
 return ret;
 }
 
 void respEvalFree(struct respEval **pEl)
 /* Free a single dynamically allocated respEval such as created
  * with respEvalLoad(). */
 {
 struct respEval *el;
 
 if ((el = *pEl) == NULL) return;
 freeMem(el->ispyId);
 freeMem(el->StageTe);
 freeMem(el->StageNe);
 freeMem(el->StageMe);
 freeMem(el->ClinicalStage);
 freeMem(el->ClinRespT1_T2);
 freeMem(el->ClinRespT1_T3);
 freeMem(el->ClinRespT1_T4);
 freez(pEl);
 }
 
 void respEvalFreeList(struct respEval **pList)
 /* Free a list of dynamically allocated respEval's */
 {
 struct respEval *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     respEvalFree(&el);
     }
 *pList = NULL;
 }
 
 void respEvalOutput(struct respEval *el, FILE *f, char sep, char lastSep) 
 /* Print out respEval.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ispyId);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 fprintf(f, "%g", *(el->TSizeClinical));
 fputc(sep,f);
 fprintf(f, "%g", *(el->NSizeClinical));
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->StageTe);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->StageNe);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->StageMe);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ClinicalStage);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ClinRespT1_T2);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ClinRespT1_T3);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ClinRespT1_T4);
 if (sep == ',') fputc('"',f);
 fputc(lastSep,f);
 }
 
 void mrStaticLoadWithNull(char **row, struct mr *ret)
 /* Load a row from mr table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->ispyId = row[0];
 ret->ChemoCat = row[1];
 ret->DoseDenseAnthra = row[2];
 ret->DoseDenseTaxane = row[3];
 ret->LES_T1 = row[4];
 ret->LES_T2 = row[5];
 ret->LES_T3 = row[6];
 ret->LES_T4 = row[7];
 if (row[8] != NULL)
     {
     ret->LD_T1 = needMem(sizeof(*(ret->LD_T1)));
     *(ret->LD_T1) = sqlSigned(row[8]);
     }
 else
     {
     ret->LD_T1 = NULL;
     }
 if (row[9] != NULL)
     {
     ret->LD_T2 = needMem(sizeof(*(ret->LD_T2)));
     *(ret->LD_T2) = sqlSigned(row[9]);
     }
 else
     {
     ret->LD_T2 = NULL;
     }
 if (row[10] != NULL)
     {
     ret->LD_T3 = needMem(sizeof(*(ret->LD_T3)));
     *(ret->LD_T3) = sqlSigned(row[10]);
     }
 else
     {
     ret->LD_T3 = NULL;
     }
 if (row[11] != NULL)
     {
     ret->LD_T4 = needMem(sizeof(*(ret->LD_T4)));
     *(ret->LD_T4) = sqlSigned(row[11]);
     }
 else
     {
     ret->LD_T4 = NULL;
     }
 if (row[12] != NULL)
     {
     ret->LD_T1_T2_PERCT = needMem(sizeof(float));
     *(ret->LD_T1_T2_PERCT) = sqlFloat(row[12]);
     }
 if (row[13] != NULL)
     {
     ret->LD_T1_T3_PERCT = needMem(sizeof(float));
     *(ret->LD_T1_T3_PERCT) = sqlFloat(row[13]);
     }
 if (row[14] != NULL)
     {
     ret->LD_T1_T4_PERCT = needMem(sizeof(float));
     *(ret->LD_T1_T4_PERCT) = sqlFloat(row[14]);
     }
 if (row[15] != NULL)
     {
     ret->LD_T2_T3_PERCT = needMem(sizeof(float));
     *(ret->LD_T2_T3_PERCT) = sqlFloat(row[15]);
     }
 if (row[16] != NULL)
     {
     ret->LD_T2_T4_PERCT = needMem(sizeof(float));
     *(ret->LD_T2_T4_PERCT) = sqlFloat(row[16]);
     }
 if (row[17] != NULL)
     {
     ret->LD_T3_T4_PERCT = needMem(sizeof(float));
     *(ret->LD_T3_T4_PERCT) = sqlFloat(row[17]);
     }
 ret->Mri_Pattern_Code = row[18];
 ret->Mri_Pattern_Desc = row[19];
 }
 
 struct mr *mrLoadWithNull(char **row)
 /* Load a mr from row fetched with select * from mr
  * from database.  Dispose of this with mrFree(). */
 {
 struct mr *ret;
 
 AllocVar(ret);
 ret->ispyId = cloneString(row[0]);
 ret->ChemoCat = cloneString(row[1]);
 ret->DoseDenseAnthra = cloneString(row[2]);
 ret->DoseDenseTaxane = cloneString(row[3]);
 ret->LES_T1 = cloneString(row[4]);
 ret->LES_T2 = cloneString(row[5]);
 ret->LES_T3 = cloneString(row[6]);
 ret->LES_T4 = cloneString(row[7]);
 if (row[8] != NULL)
     {
     ret->LD_T1 = needMem(sizeof(*(ret->LD_T1)));
     *(ret->LD_T1) = sqlSigned(row[8]);
     }
 else
     {
     ret->LD_T1 = NULL;
     }
 if (row[9] != NULL)
     {
     ret->LD_T2 = needMem(sizeof(*(ret->LD_T2)));
     *(ret->LD_T2) = sqlSigned(row[9]);
     }
 else
     {
     ret->LD_T2 = NULL;
     }
 if (row[10] != NULL)
     {
     ret->LD_T3 = needMem(sizeof(*(ret->LD_T3)));
     *(ret->LD_T3) = sqlSigned(row[10]);
     }
 else
     {
     ret->LD_T3 = NULL;
     }
 if (row[11] != NULL)
     {
     ret->LD_T4 = needMem(sizeof(*(ret->LD_T4)));
     *(ret->LD_T4) = sqlSigned(row[11]);
     }
 else
     {
     ret->LD_T4 = NULL;
     }
 if (row[12] != NULL)
     {
     ret->LD_T1_T2_PERCT = needMem(sizeof(float));
     *(ret->LD_T1_T2_PERCT) = sqlFloat(row[12]);
     }
 if (row[13] != NULL)
     {
     ret->LD_T1_T3_PERCT = needMem(sizeof(float));
     *(ret->LD_T1_T3_PERCT) = sqlFloat(row[13]);
     }
 if (row[14] != NULL)
     {
     ret->LD_T1_T4_PERCT = needMem(sizeof(float));
     *(ret->LD_T1_T4_PERCT) = sqlFloat(row[14]);
     }
 if (row[15] != NULL)
     {
     ret->LD_T2_T3_PERCT = needMem(sizeof(float));
     *(ret->LD_T2_T3_PERCT) = sqlFloat(row[15]);
     }
 if (row[16] != NULL)
     {
     ret->LD_T2_T4_PERCT = needMem(sizeof(float));
     *(ret->LD_T2_T4_PERCT) = sqlFloat(row[16]);
     }
 if (row[17] != NULL)
     {
     ret->LD_T3_T4_PERCT = needMem(sizeof(float));
     *(ret->LD_T3_T4_PERCT) = sqlFloat(row[17]);
     }
 ret->Mri_Pattern_Code = cloneString(row[18]);
 ret->Mri_Pattern_Desc = cloneString(row[19]);
 return ret;
 }
 
 struct mr *mrLoadAll(char *fileName) 
 /* Load all mr from a whitespace-separated file.
  * Dispose of this with mrFreeList(). */
 {
 struct mr *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[20];
 
 while (lineFileRow(lf, row))
     {
     el = mrLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct mr *mrLoadAllByChar(char *fileName, char chopper) 
 /* Load all mr from a chopper separated file.
  * Dispose of this with mrFreeList(). */
 {
 struct mr *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[20];
 
 while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
     {
     el = mrLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct mr *mrLoadByQuery(struct sqlConnection *conn, char *query)
 /* Load all mr 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 mrFreeList(). */
 {
 struct mr *list = NULL, *el;
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = mrLoadWithNull(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void mrSaveToDb(struct sqlConnection *conn, struct mr *el, char *tableName, int updateSize)
 /* Save mr as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
  * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */
 {
 struct dyString *update = newDyString(updateSize);
 sqlDyStringPrintf(update, "insert into %s values ( '%s','%s','%s','%s','%s','%s','%s','%s',%d,%d,%d,%d,%g,%g,%g,%g,%g,%g,'%s','%s')", 
 	tableName,  el->ispyId,  el->ChemoCat,  el->DoseDenseAnthra,  el->DoseDenseTaxane,  el->LES_T1,  el->LES_T2,  el->LES_T3,  el->LES_T4,  *(el->LD_T1),  *(el->LD_T2),  *(el->LD_T3),  *(el->LD_T4),  *(el->LD_T1_T2_PERCT),  *(el->LD_T1_T3_PERCT),  *(el->LD_T1_T4_PERCT),  *(el->LD_T2_T3_PERCT),  *(el->LD_T2_T4_PERCT),  *(el->LD_T3_T4_PERCT),  el->Mri_Pattern_Code,  el->Mri_Pattern_Desc);
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
 
 struct mr *mrCommaIn(char **pS, struct mr *ret)
 /* Create a mr out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new mr */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->ispyId = sqlStringComma(&s);
 ret->ChemoCat = sqlStringComma(&s);
 ret->DoseDenseAnthra = sqlStringComma(&s);
 ret->DoseDenseTaxane = sqlStringComma(&s);
 ret->LES_T1 = sqlStringComma(&s);
 ret->LES_T2 = sqlStringComma(&s);
 ret->LES_T3 = sqlStringComma(&s);
 ret->LES_T4 = sqlStringComma(&s);
 ret->LD_T1 = needMem(sizeof(*(ret->LD_T1)));
 *(ret->LD_T1) = sqlSignedComma(&s);
 ret->LD_T2 = needMem(sizeof(*(ret->LD_T2)));
 *(ret->LD_T2) = sqlSignedComma(&s);
 ret->LD_T3 = needMem(sizeof(*(ret->LD_T3)));
 *(ret->LD_T3) = sqlSignedComma(&s);
 ret->LD_T4 = needMem(sizeof(*(ret->LD_T4)));
 *(ret->LD_T4) = sqlSignedComma(&s);
 ret->LD_T1_T2_PERCT = needMem(sizeof(*(ret->LD_T1_T2_PERCT)));
 *(ret->LD_T1_T2_PERCT) = sqlFloatComma(&s);
 ret->LD_T1_T3_PERCT = needMem(sizeof(*(ret->LD_T1_T3_PERCT)));
 *(ret->LD_T1_T3_PERCT) = sqlFloatComma(&s);
 ret->LD_T1_T4_PERCT = needMem(sizeof(*(ret->LD_T1_T4_PERCT)));
 *(ret->LD_T1_T4_PERCT) = sqlFloatComma(&s);
 ret->LD_T2_T3_PERCT = needMem(sizeof(*(ret->LD_T2_T3_PERCT)));
 *(ret->LD_T2_T3_PERCT) = sqlFloatComma(&s);
 ret->LD_T2_T4_PERCT = needMem(sizeof(*(ret->LD_T2_T4_PERCT)));
 *(ret->LD_T2_T4_PERCT) = sqlFloatComma(&s);
 ret->LD_T3_T4_PERCT = needMem(sizeof(*(ret->LD_T3_T4_PERCT)));
 *(ret->LD_T3_T4_PERCT) = sqlFloatComma(&s);
 ret->Mri_Pattern_Code = sqlStringComma(&s);
 ret->Mri_Pattern_Desc = sqlStringComma(&s);
 *pS = s;
 return ret;
 }
 
 void mrFree(struct mr **pEl)
 /* Free a single dynamically allocated mr such as created
  * with mrLoad(). */
 {
 struct mr *el;
 
 if ((el = *pEl) == NULL) return;
 freeMem(el->ispyId);
 freeMem(el->ChemoCat);
 freeMem(el->DoseDenseAnthra);
 freeMem(el->DoseDenseTaxane);
 freeMem(el->LES_T1);
 freeMem(el->LES_T2);
 freeMem(el->LES_T3);
 freeMem(el->LES_T4);
 freeMem(el->Mri_Pattern_Code);
 freeMem(el->Mri_Pattern_Desc);
 freez(pEl);
 }
 
 void mrFreeList(struct mr **pList)
 /* Free a list of dynamically allocated mr's */
 {
 struct mr *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     mrFree(&el);
     }
 *pList = NULL;
 }
 
 void mrOutput(struct mr *el, FILE *f, char sep, char lastSep) 
 /* Print out mr.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ispyId);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ChemoCat);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->DoseDenseAnthra);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->DoseDenseTaxane);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->LES_T1);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->LES_T2);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->LES_T3);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->LES_T4);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 fprintf(f, "%d", *(el->LD_T1));
 fputc(sep,f);
 fprintf(f, "%d", *(el->LD_T2));
 fputc(sep,f);
 fprintf(f, "%d", *(el->LD_T3));
 fputc(sep,f);
 fprintf(f, "%d", *(el->LD_T4));
 fputc(sep,f);
 fprintf(f, "%g", *(el->LD_T1_T2_PERCT));
 fputc(sep,f);
 fprintf(f, "%g", *(el->LD_T1_T3_PERCT));
 fputc(sep,f);
 fprintf(f, "%g", *(el->LD_T1_T4_PERCT));
 fputc(sep,f);
 fprintf(f, "%g", *(el->LD_T2_T3_PERCT));
 fputc(sep,f);
 fprintf(f, "%g", *(el->LD_T2_T4_PERCT));
 fputc(sep,f);
 fprintf(f, "%g", *(el->LD_T3_T4_PERCT));
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Mri_Pattern_Code);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Mri_Pattern_Desc);
 if (sep == ',') fputc('"',f);
 fputc(lastSep,f);
 }
 
 void cdnaStaticLoadWithNull(char **row, struct cdna *ret)
 /* Load a row from cdna table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->ispyId = row[0];
 ret->Cdna_T1 = row[1];
 ret->Cdna_T2 = row[2];
 ret->Cdna_T3 = row[3];
 ret->Cdna_T4 = row[4];
 }
 
 struct cdna *cdnaLoadWithNull(char **row)
 /* Load a cdna from row fetched with select * from cdna
  * from database.  Dispose of this with cdnaFree(). */
 {
 struct cdna *ret;
 
 AllocVar(ret);
 ret->ispyId = cloneString(row[0]);
 ret->Cdna_T1 = cloneString(row[1]);
 ret->Cdna_T2 = cloneString(row[2]);
 ret->Cdna_T3 = cloneString(row[3]);
 ret->Cdna_T4 = cloneString(row[4]);
 return ret;
 }
 
 struct cdna *cdnaLoadAll(char *fileName) 
 /* Load all cdna from a whitespace-separated file.
  * Dispose of this with cdnaFreeList(). */
 {
 struct cdna *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[5];
 
 while (lineFileRow(lf, row))
     {
     el = cdnaLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct cdna *cdnaLoadAllByChar(char *fileName, char chopper) 
 /* Load all cdna from a chopper separated file.
  * Dispose of this with cdnaFreeList(). */
 {
 struct cdna *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[5];
 
 while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
     {
     el = cdnaLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct cdna *cdnaLoadByQuery(struct sqlConnection *conn, char *query)
 /* Load all cdna 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 cdnaFreeList(). */
 {
 struct cdna *list = NULL, *el;
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = cdnaLoadWithNull(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void cdnaSaveToDb(struct sqlConnection *conn, struct cdna *el, char *tableName, int updateSize)
 /* Save cdna as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
  * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */
 {
 struct dyString *update = newDyString(updateSize);
 sqlDyStringPrintf(update, "insert into %s values ( '%s','%s','%s','%s','%s')", 
 	tableName,  el->ispyId,  el->Cdna_T1,  el->Cdna_T2,  el->Cdna_T3,  el->Cdna_T4);
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
 
 struct cdna *cdnaCommaIn(char **pS, struct cdna *ret)
 /* Create a cdna out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new cdna */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->ispyId = sqlStringComma(&s);
 ret->Cdna_T1 = sqlStringComma(&s);
 ret->Cdna_T2 = sqlStringComma(&s);
 ret->Cdna_T3 = sqlStringComma(&s);
 ret->Cdna_T4 = sqlStringComma(&s);
 *pS = s;
 return ret;
 }
 
 void cdnaFree(struct cdna **pEl)
 /* Free a single dynamically allocated cdna such as created
  * with cdnaLoad(). */
 {
 struct cdna *el;
 
 if ((el = *pEl) == NULL) return;
 freeMem(el->ispyId);
 freeMem(el->Cdna_T1);
 freeMem(el->Cdna_T2);
 freeMem(el->Cdna_T3);
 freeMem(el->Cdna_T4);
 freez(pEl);
 }
 
 void cdnaFreeList(struct cdna **pList)
 /* Free a list of dynamically allocated cdna's */
 {
 struct cdna *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     cdnaFree(&el);
     }
 *pList = NULL;
 }
 
 void cdnaOutput(struct cdna *el, FILE *f, char sep, char lastSep) 
 /* Print out cdna.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ispyId);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Cdna_T1);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Cdna_T2);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Cdna_T3);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Cdna_T4);
 if (sep == ',') fputc('"',f);
 fputc(lastSep,f);
 }
 
 void agiStaticLoadWithNull(char **row, struct agi *ret)
 /* Load a row from agi table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->ispyId = row[0];
 ret->Agi_T1 = row[1];
 ret->Agi_T2 = row[2];
 ret->Agi_T3 = row[3];
 ret->Agi_T4 = row[4];
 }
 
 struct agi *agiLoadWithNull(char **row)
 /* Load a agi from row fetched with select * from agi
  * from database.  Dispose of this with agiFree(). */
 {
 struct agi *ret;
 
 AllocVar(ret);
 ret->ispyId = cloneString(row[0]);
 ret->Agi_T1 = cloneString(row[1]);
 ret->Agi_T2 = cloneString(row[2]);
 ret->Agi_T3 = cloneString(row[3]);
 ret->Agi_T4 = cloneString(row[4]);
 return ret;
 }
 
 struct agi *agiLoadAll(char *fileName) 
 /* Load all agi from a whitespace-separated file.
  * Dispose of this with agiFreeList(). */
 {
 struct agi *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[5];
 
 while (lineFileRow(lf, row))
     {
     el = agiLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct agi *agiLoadAllByChar(char *fileName, char chopper) 
 /* Load all agi from a chopper separated file.
  * Dispose of this with agiFreeList(). */
 {
 struct agi *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[5];
 
 while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
     {
     el = agiLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct agi *agiLoadByQuery(struct sqlConnection *conn, char *query)
 /* Load all agi 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 agiFreeList(). */
 {
 struct agi *list = NULL, *el;
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = agiLoadWithNull(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void agiSaveToDb(struct sqlConnection *conn, struct agi *el, char *tableName, int updateSize)
 /* Save agi as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
  * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */
 {
 struct dyString *update = newDyString(updateSize);
 sqlDyStringPrintf(update, "insert into %s values ( '%s','%s','%s','%s','%s')", 
 	tableName,  el->ispyId,  el->Agi_T1,  el->Agi_T2,  el->Agi_T3,  el->Agi_T4);
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
 
 struct agi *agiCommaIn(char **pS, struct agi *ret)
 /* Create a agi out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new agi */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->ispyId = sqlStringComma(&s);
 ret->Agi_T1 = sqlStringComma(&s);
 ret->Agi_T2 = sqlStringComma(&s);
 ret->Agi_T3 = sqlStringComma(&s);
 ret->Agi_T4 = sqlStringComma(&s);
 *pS = s;
 return ret;
 }
 
 void agiFree(struct agi **pEl)
 /* Free a single dynamically allocated agi such as created
  * with agiLoad(). */
 {
 struct agi *el;
 
 if ((el = *pEl) == NULL) return;
 freeMem(el->ispyId);
 freeMem(el->Agi_T1);
 freeMem(el->Agi_T2);
 freeMem(el->Agi_T3);
 freeMem(el->Agi_T4);
 freez(pEl);
 }
 
 void agiFreeList(struct agi **pList)
 /* Free a list of dynamically allocated agi's */
 {
 struct agi *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     agiFree(&el);
     }
 *pList = NULL;
 }
 
 void agiOutput(struct agi *el, FILE *f, char sep, char lastSep) 
 /* Print out agi.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ispyId);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Agi_T1);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Agi_T2);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Agi_T3);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Agi_T4);
 if (sep == ',') fputc('"',f);
 fputc(lastSep,f);
 }
 
 void ihcStaticLoadWithNull(char **row, struct ihc *ret)
 /* Load a row from ihc table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->ispyId = row[0];
 ret->Ihc_T1 = row[1];
 ret->Ihc_T2 = row[2];
 ret->Ihc_T3 = row[3];
 ret->Ihc_T4 = row[4];
 }
 
 struct ihc *ihcLoadWithNull(char **row)
 /* Load a ihc from row fetched with select * from ihc
  * from database.  Dispose of this with ihcFree(). */
 {
 struct ihc *ret;
 
 AllocVar(ret);
 ret->ispyId = cloneString(row[0]);
 ret->Ihc_T1 = cloneString(row[1]);
 ret->Ihc_T2 = cloneString(row[2]);
 ret->Ihc_T3 = cloneString(row[3]);
 ret->Ihc_T4 = cloneString(row[4]);
 return ret;
 }
 
 struct ihc *ihcLoadAll(char *fileName) 
 /* Load all ihc from a whitespace-separated file.
  * Dispose of this with ihcFreeList(). */
 {
 struct ihc *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[5];
 
 while (lineFileRow(lf, row))
     {
     el = ihcLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct ihc *ihcLoadAllByChar(char *fileName, char chopper) 
 /* Load all ihc from a chopper separated file.
  * Dispose of this with ihcFreeList(). */
 {
 struct ihc *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[5];
 
 while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
     {
     el = ihcLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct ihc *ihcLoadByQuery(struct sqlConnection *conn, char *query)
 /* Load all ihc 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 ihcFreeList(). */
 {
 struct ihc *list = NULL, *el;
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = ihcLoadWithNull(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void ihcSaveToDb(struct sqlConnection *conn, struct ihc *el, char *tableName, int updateSize)
 /* Save ihc as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
  * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */
 {
 struct dyString *update = newDyString(updateSize);
 sqlDyStringPrintf(update, "insert into %s values ( '%s','%s','%s','%s','%s')", 
 	tableName,  el->ispyId,  el->Ihc_T1,  el->Ihc_T2,  el->Ihc_T3,  el->Ihc_T4);
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
 
 struct ihc *ihcCommaIn(char **pS, struct ihc *ret)
 /* Create a ihc out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new ihc */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->ispyId = sqlStringComma(&s);
 ret->Ihc_T1 = sqlStringComma(&s);
 ret->Ihc_T2 = sqlStringComma(&s);
 ret->Ihc_T3 = sqlStringComma(&s);
 ret->Ihc_T4 = sqlStringComma(&s);
 *pS = s;
 return ret;
 }
 
 void ihcFree(struct ihc **pEl)
 /* Free a single dynamically allocated ihc such as created
  * with ihcLoad(). */
 {
 struct ihc *el;
 
 if ((el = *pEl) == NULL) return;
 freeMem(el->ispyId);
 freeMem(el->Ihc_T1);
 freeMem(el->Ihc_T2);
 freeMem(el->Ihc_T3);
 freeMem(el->Ihc_T4);
 freez(pEl);
 }
 
 void ihcFreeList(struct ihc **pList)
 /* Free a list of dynamically allocated ihc's */
 {
 struct ihc *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     ihcFree(&el);
     }
 *pList = NULL;
 }
 
 void ihcOutput(struct ihc *el, FILE *f, char sep, char lastSep) 
 /* Print out ihc.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ispyId);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Ihc_T1);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Ihc_T2);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Ihc_T3);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Ihc_T4);
 if (sep == ',') fputc('"',f);
 fputc(lastSep,f);
 }
 
 void fishStaticLoadWithNull(char **row, struct fish *ret)
 /* Load a row from fish table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->ispyId = row[0];
 ret->Fish_T1 = row[1];
 ret->Fish_T2 = row[2];
 ret->Fish_T3 = row[3];
 ret->Fish_T4 = row[4];
 }
 
 struct fish *fishLoadWithNull(char **row)
 /* Load a fish from row fetched with select * from fish
  * from database.  Dispose of this with fishFree(). */
 {
 struct fish *ret;
 
 AllocVar(ret);
 ret->ispyId = cloneString(row[0]);
 ret->Fish_T1 = cloneString(row[1]);
 ret->Fish_T2 = cloneString(row[2]);
 ret->Fish_T3 = cloneString(row[3]);
 ret->Fish_T4 = cloneString(row[4]);
 return ret;
 }
 
 struct fish *fishLoadAll(char *fileName) 
 /* Load all fish from a whitespace-separated file.
  * Dispose of this with fishFreeList(). */
 {
 struct fish *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[5];
 
 while (lineFileRow(lf, row))
     {
     el = fishLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct fish *fishLoadAllByChar(char *fileName, char chopper) 
 /* Load all fish from a chopper separated file.
  * Dispose of this with fishFreeList(). */
 {
 struct fish *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[5];
 
 while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
     {
     el = fishLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct fish *fishLoadByQuery(struct sqlConnection *conn, char *query)
 /* Load all fish 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 fishFreeList(). */
 {
 struct fish *list = NULL, *el;
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = fishLoadWithNull(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void fishSaveToDb(struct sqlConnection *conn, struct fish *el, char *tableName, int updateSize)
 /* Save fish as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
  * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */
 {
 struct dyString *update = newDyString(updateSize);
 sqlDyStringPrintf(update, "insert into %s values ( '%s','%s','%s','%s','%s')", 
 	tableName,  el->ispyId,  el->Fish_T1,  el->Fish_T2,  el->Fish_T3,  el->Fish_T4);
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
 
 struct fish *fishCommaIn(char **pS, struct fish *ret)
 /* Create a fish out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new fish */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->ispyId = sqlStringComma(&s);
 ret->Fish_T1 = sqlStringComma(&s);
 ret->Fish_T2 = sqlStringComma(&s);
 ret->Fish_T3 = sqlStringComma(&s);
 ret->Fish_T4 = sqlStringComma(&s);
 *pS = s;
 return ret;
 }
 
 void fishFree(struct fish **pEl)
 /* Free a single dynamically allocated fish such as created
  * with fishLoad(). */
 {
 struct fish *el;
 
 if ((el = *pEl) == NULL) return;
 freeMem(el->ispyId);
 freeMem(el->Fish_T1);
 freeMem(el->Fish_T2);
 freeMem(el->Fish_T3);
 freeMem(el->Fish_T4);
 freez(pEl);
 }
 
 void fishFreeList(struct fish **pList)
 /* Free a list of dynamically allocated fish's */
 {
 struct fish *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     fishFree(&el);
     }
 *pList = NULL;
 }
 
 void fishOutput(struct fish *el, FILE *f, char sep, char lastSep) 
 /* Print out fish.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ispyId);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Fish_T1);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Fish_T2);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Fish_T3);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->Fish_T4);
 if (sep == ',') fputc('"',f);
 fputc(lastSep,f);
 }
 
 void labTrackStaticLoadWithNull(char **row, struct labTrack *ret)
 /* Load a row from labTrack table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->ispyId = row[0];
 ret->trackId = row[1];
 ret->coreType = row[2];
 ret->timePoint = row[3];
 ret->section = row[4];
 }
 
 struct labTrack *labTrackLoadWithNull(char **row)
 /* Load a labTrack from row fetched with select * from labTrack
  * from database.  Dispose of this with labTrackFree(). */
 {
 struct labTrack *ret;
 
 AllocVar(ret);
 ret->ispyId = cloneString(row[0]);
 ret->trackId = cloneString(row[1]);
 ret->coreType = cloneString(row[2]);
 ret->timePoint = cloneString(row[3]);
 ret->section = cloneString(row[4]);
 return ret;
 }
 
 struct labTrack *labTrackLoadAll(char *fileName) 
 /* Load all labTrack from a whitespace-separated file.
  * Dispose of this with labTrackFreeList(). */
 {
 struct labTrack *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[5];
 
 while (lineFileRow(lf, row))
     {
     el = labTrackLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct labTrack *labTrackLoadAllByChar(char *fileName, char chopper) 
 /* Load all labTrack from a chopper separated file.
  * Dispose of this with labTrackFreeList(). */
 {
 struct labTrack *list = NULL, *el;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 char *row[5];
 
 while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
     {
     el = labTrackLoadWithNull(row);
     slAddHead(&list, el);
     }
 lineFileClose(&lf);
 slReverse(&list);
 return list;
 }
 
 struct labTrack *labTrackLoadByQuery(struct sqlConnection *conn, char *query)
 /* Load all labTrack 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 labTrackFreeList(). */
 {
 struct labTrack *list = NULL, *el;
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = labTrackLoadWithNull(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void labTrackSaveToDb(struct sqlConnection *conn, struct labTrack *el, char *tableName, int updateSize)
 /* Save labTrack as a row to the table specified by tableName. 
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
  * inserted as NULL. Strings are automatically escaped to allow insertion into the database. */
 {
 struct dyString *update = newDyString(updateSize);
 sqlDyStringPrintf(update, "insert into %s values ( '%s','%s','%s','%s','%s')", 
 	tableName,  el->ispyId,  el->trackId,  el->coreType,  el->timePoint,  el->section);
 sqlUpdate(conn, update->string);
 freeDyString(&update);
 }
 
 
 struct labTrack *labTrackCommaIn(char **pS, struct labTrack *ret)
 /* Create a labTrack out of a comma separated string. 
  * This will fill in ret if non-null, otherwise will
  * return a new labTrack */
 {
 char *s = *pS;
 
 if (ret == NULL)
     AllocVar(ret);
 ret->ispyId = sqlStringComma(&s);
 ret->trackId = sqlStringComma(&s);
 ret->coreType = sqlStringComma(&s);
 ret->timePoint = sqlStringComma(&s);
 ret->section = sqlStringComma(&s);
 *pS = s;
 return ret;
 }
 
 void labTrackFree(struct labTrack **pEl)
 /* Free a single dynamically allocated labTrack such as created
  * with labTrackLoad(). */
 {
 struct labTrack *el;
 
 if ((el = *pEl) == NULL) return;
 freeMem(el->ispyId);
 freeMem(el->trackId);
 freeMem(el->coreType);
 freeMem(el->timePoint);
 freeMem(el->section);
 freez(pEl);
 }
 
 void labTrackFreeList(struct labTrack **pList)
 /* Free a list of dynamically allocated labTrack's */
 {
 struct labTrack *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     labTrackFree(&el);
     }
 *pList = NULL;
 }
 
 void labTrackOutput(struct labTrack *el, FILE *f, char sep, char lastSep) 
 /* Print out labTrack.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->ispyId);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->trackId);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->coreType);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->timePoint);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->section);
 if (sep == ',') fputc('"',f);
 fputc(lastSep,f);
 }
 
 /* -------------------------------- End autoSql Generated Code -------------------------------- */