6db4d4f2dcc485622fe4b22f33c796d708c6fdea kate Mon Mar 26 16:28:35 2018 -0700 Fixes to click handling. refs #17512 diff --git src/hg/lib/interact.c src/hg/lib/interact.c index 214adac..3590cc0 100644 --- src/hg/lib/interact.c +++ src/hg/lib/interact.c @@ -1,289 +1,327 @@ /* interact.c was originally generated by the autoSql program, which also * generated interact.h and interact.sql. This module links the database and * the RAM representation of objects. */ #include "common.h" #include "linefile.h" #include "dystring.h" #include "asParse.h" #include "jksql.h" #include "interact.h" char *interactCommaSepFieldNames = "chrom,chromStart,chromEnd,name,score,value,exp,color,sourceChrom,sourceStart,sourceEnd,sourceName,targetChrom,targetStart,targetEnd,targetName"; void interactStaticLoad(char **row, struct interact *ret) /* Load a row from interact table into ret. The contents of ret will * be replaced at the next call to this function. */ { ret->chrom = row[0]; ret->chromStart = sqlUnsigned(row[1]); ret->chromEnd = sqlUnsigned(row[2]); ret->name = row[3]; ret->score = sqlUnsigned(row[4]); ret->value = sqlDouble(row[5]); ret->exp = row[6]; ret->color = sqlUnsigned(row[7]); ret->sourceChrom = row[8]; ret->sourceStart = sqlUnsigned(row[9]); ret->sourceEnd = sqlUnsigned(row[10]); ret->sourceName = row[11]; ret->targetChrom = row[12]; ret->targetStart = sqlUnsigned(row[13]); ret->targetEnd = sqlUnsigned(row[14]); ret->targetName = row[15]; } struct interact *interactLoadByQuery(struct sqlConnection *conn, char *query) /* Load all interact 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 interactFreeList(). */ { struct interact *list = NULL, *el; struct sqlResult *sr; char **row; sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { el = interactLoad(row); slAddHead(&list, el); } slReverse(&list); sqlFreeResult(&sr); return list; } void interactSaveToDb(struct sqlConnection *conn, struct interact *el, char *tableName, int updateSize) /* Save interact 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. This function automatically escapes quoted strings for mysql. */ { struct dyString *update = newDyString(updateSize); sqlDyStringPrintf(update, "insert into %s values ( '%s',%u,%u,'%s',%u,%g,'%s',%u,'%s',%u,%u,'%s','%s',%u,%u,'%s')", tableName, el->chrom, el->chromStart, el->chromEnd, el->name, el->score, el->value, el->exp, el->color, el->sourceChrom, el->sourceStart, el->sourceEnd, el->sourceName, el->targetChrom, el->targetStart, el->targetEnd, el->targetName); sqlUpdate(conn, update->string); freeDyString(&update); } struct interact *interactLoad(char **row) /* Load a interact from row fetched with select * from interact * from database. Dispose of this with interactFree(). */ { struct interact *ret; AllocVar(ret); ret->chrom = cloneString(row[0]); ret->chromStart = sqlUnsigned(row[1]); ret->chromEnd = sqlUnsigned(row[2]); ret->name = cloneString(row[3]); ret->score = sqlUnsigned(row[4]); ret->value = sqlDouble(row[5]); ret->exp = cloneString(row[6]); ret->color = sqlUnsigned(row[7]); ret->sourceChrom = cloneString(row[8]); ret->sourceStart = sqlUnsigned(row[9]); ret->sourceEnd = sqlUnsigned(row[10]); ret->sourceName = cloneString(row[11]); ret->targetChrom = cloneString(row[12]); ret->targetStart = sqlUnsigned(row[13]); ret->targetEnd = sqlUnsigned(row[14]); ret->targetName = cloneString(row[15]); return ret; } struct interact *interactLoadAll(char *fileName) /* Load all interact from a whitespace-separated file. * Dispose of this with interactFreeList(). */ { struct interact *list = NULL, *el; struct lineFile *lf = lineFileOpen(fileName, TRUE); char *row[16]; while (lineFileRow(lf, row)) { el = interactLoad(row); slAddHead(&list, el); } lineFileClose(&lf); slReverse(&list); return list; } struct interact *interactLoadAllByChar(char *fileName, char chopper) /* Load all interact from a chopper separated file. * Dispose of this with interactFreeList(). */ { struct interact *list = NULL, *el; struct lineFile *lf = lineFileOpen(fileName, TRUE); char *row[16]; while (lineFileNextCharRow(lf, chopper, row, ArraySize(row))) { el = interactLoad(row); slAddHead(&list, el); } lineFileClose(&lf); slReverse(&list); return list; } struct interact *interactCommaIn(char **pS, struct interact *ret) /* Create a interact out of a comma separated string. * This will fill in ret if non-null, otherwise will * return a new interact */ { char *s = *pS; if (ret == NULL) AllocVar(ret); ret->chrom = sqlStringComma(&s); ret->chromStart = sqlUnsignedComma(&s); ret->chromEnd = sqlUnsignedComma(&s); ret->name = sqlStringComma(&s); ret->score = sqlUnsignedComma(&s); ret->value = sqlDoubleComma(&s); ret->exp = sqlStringComma(&s); ret->color = sqlUnsignedComma(&s); ret->sourceChrom = sqlStringComma(&s); ret->sourceStart = sqlUnsignedComma(&s); ret->sourceEnd = sqlUnsignedComma(&s); ret->sourceName = sqlStringComma(&s); ret->targetChrom = sqlStringComma(&s); ret->targetStart = sqlUnsignedComma(&s); ret->targetEnd = sqlUnsignedComma(&s); ret->targetName = sqlStringComma(&s); *pS = s; return ret; } void interactFree(struct interact **pEl) /* Free a single dynamically allocated interact such as created * with interactLoad(). */ { struct interact *el; if ((el = *pEl) == NULL) return; freeMem(el->chrom); freeMem(el->name); freeMem(el->exp); freeMem(el->sourceChrom); freeMem(el->sourceName); freeMem(el->targetChrom); freeMem(el->targetName); freez(pEl); } void interactFreeList(struct interact **pList) /* Free a list of dynamically allocated interact's */ { struct interact *el, *next; for (el = *pList; el != NULL; el = next) { next = el->next; interactFree(&el); } *pList = NULL; } void interactOutput(struct interact *el, FILE *f, char sep, char lastSep) /* Print out interact. Separate fields with sep. Follow last field with lastSep. */ { if (sep == ',') fputc('"',f); fprintf(f, "%s", el->chrom); if (sep == ',') fputc('"',f); fputc(sep,f); fprintf(f, "%u", el->chromStart); fputc(sep,f); fprintf(f, "%u", el->chromEnd); fputc(sep,f); if (sep == ',') fputc('"',f); fprintf(f, "%s", el->name); if (sep == ',') fputc('"',f); fputc(sep,f); fprintf(f, "%u", el->score); fputc(sep,f); fprintf(f, "%g", el->value); fputc(sep,f); if (sep == ',') fputc('"',f); fprintf(f, "%s", el->exp); if (sep == ',') fputc('"',f); fputc(sep,f); fprintf(f, "%u", el->color); fputc(sep,f); if (sep == ',') fputc('"',f); fprintf(f, "%s", el->sourceChrom); if (sep == ',') fputc('"',f); fputc(sep,f); fprintf(f, "%u", el->sourceStart); fputc(sep,f); fprintf(f, "%u", el->sourceEnd); fputc(sep,f); if (sep == ',') fputc('"',f); fprintf(f, "%s", el->sourceName); if (sep == ',') fputc('"',f); fputc(sep,f); if (sep == ',') fputc('"',f); fprintf(f, "%s", el->targetChrom); if (sep == ',') fputc('"',f); fputc(sep,f); fprintf(f, "%u", el->targetStart); fputc(sep,f); fprintf(f, "%u", el->targetEnd); fputc(sep,f); if (sep == ',') fputc('"',f); fprintf(f, "%s", el->targetName); if (sep == ',') fputc('"',f); fputc(lastSep,f); } /* -------------------------------- End autoSql Generated Code -------------------------------- */ static char *interactAutoSqlString = "table interact" "\"BED5+11 interaction between two regions\"" " (" " string chrom; \"Reference sequence chromosome or scaffold\"" " uint chromStart; \"Start position of lower region\"" " uint chromEnd; \"End position of upper region. For interchromsomal, set to chromStart+1.\"" " string name; \"Name or ID of item. Usually name1/name2 or name1/name2/exp or empty\"" " uint score; \"Score from 0-1000, typically derived from value\"" " double value; \"Strength of interaction or other data value\"" " string exp; \"Experiment name for filtering, or empty\"" " uint color; \"Item color, as itemRgb in bed9. Typically based on value or exp\"" " string sourceChrom; \"Chromosome of source region (directional) or lower region\"" " uint sourceStart; \"Start position of source/lower region\"" " uint sourceEnd; \"End position of source/lower region\"" " string sourceName; \"Identifier of source/lower region. Can be used as link to related table.\"" " string targetChrom; \"Chromosome of target region (directional) or lower region\"" " uint targetStart; \"Start position of target/lower region\"" " uint targetEnd; \"End position of target/lower region\"" " string targetName; \"Identifier of target/lower region. Can be used as link to related table.\"" " )" ; struct asObject *interactAsObj() /* Return asObject describing fields of interact object */ { return asParseText(interactAutoSqlString); } char *interactOtherChrom(struct interact *inter) /* Get other chromosome from an interaaction. Return NULL if same chromosome */ { if (sameString(inter->sourceChrom, inter->targetChrom)) return NULL; if (inter->chromStart == inter->sourceStart) return cloneString(inter->targetChrom); return cloneString(inter->sourceChrom); } + +int interactRegionCenter(int start, int end) +/* Return genomic location of center of region */ +{ +return ((double)(end - start + .5) / 2) + start; +} + +int interactRegionDistance(struct interact *inter) +/* Return distance between region midpoints. Return -1 for other chromosome */ +{ +if (interactOtherChrom(inter)) + return -1; +return abs(interactRegionCenter(inter->sourceStart, inter->sourceEnd) - + interactRegionCenter(inter->targetStart, inter->targetEnd)); +} + +int interactDistanceCmp(const void *va, const void *vb) +/* Compare based on distance between region midpoints */ +{ +struct interact *a = *((struct interact **)va); +struct interact *b = *((struct interact **)vb); + +int aDist = interactRegionDistance(a); +int bDist = interactRegionDistance(b); + +// cross chromosome; always larger than same chrom +if (aDist < 0) + { + if (bDist < 0) + return 0; + return 1; + } +if (bDist < 0) + return -1; + +// same chromosome +return aDist - bDist; +}