/* wikiPlot - Quick plots of maps vs. each other. */ #include "common.h" #include "linefile.h" #include "hash.h" #include "cheapcgi.h" #include "htmshell.h" #include "portable.h" #include "memgfx.h" /* Variables that can be overridden by CGI. */ char *contigDir = "/projects/hg3/gs.7/oo.29/19/ctg18433"; char *mapX = "info.noNt"; char *mapY = "gold.99"; int pix = 500; double xOff = -0.05, yOff = -0.05, zoom = 0.9; /* Span range of values in x and y. */ int xStart, xEnd, yStart, yEnd; boolean plotName = TRUE; MgFont *font; struct clonePos { struct clonePos *next; char *name; /* Name of clone. */ int pos; /* Position in map. */ double totSize; /* Total fragment size (just for gold) */ double weightedPos; /* Total weighted position (just for gold) */ }; double scaleOne(double raw, double rangeStart, double rangeEnd, int pix, double offset, double zoom) /* Scale one coordinate. */ { double range = rangeEnd - rangeStart + 1; double pos = ((raw - rangeStart) / range - offset) * zoom; return pix*pos; } void zoomScale(double x, double y, int *retX, int *retY) /* Scale both coordinates. */ { *retX = round(scaleOne(x, xStart, xEnd, pix, xOff, zoom)); *retY = round(scaleOne(y, yStart, yEnd, pix, yOff, zoom)); } void readInfo(char *fileName, struct clonePos **retList, struct hash **retHash) /* Read info formatted files */ { struct lineFile *lf = lineFileOpen(fileName, TRUE); char *line, *row[3]; struct clonePos *cpList = NULL, *cp; struct hash *hash = newHash(0); if (!lineFileNext(lf, &line, NULL)) errAbort("%s is empty", fileName); while (lineFileRow(lf, row)) { if (hashLookup(hash, row[0])) warn("%s duplicated in %s, ignoring all but first", row[0], fileName); else { AllocVar(cp); hashAddSaveName(hash, row[0], cp, &cp->name); cp->pos = lineFileNeedNum(lf, row, 1); slAddHead(&cpList, cp); } } lineFileClose(&lf); slReverse(&cpList); *retList = cpList; *retHash = hash; } void readGold(char *fileName, struct clonePos **retList, struct hash **retHash) /* Read .agp/gold formatted file */ { struct lineFile *lf = lineFileOpen(fileName, TRUE); char *words[12]; struct clonePos *cpList = NULL, *cp; struct hash *hash = newHash(0); int wordCount; while ((wordCount = lineFileChop(lf, words)) != 0) { char *type = words[4]; char *clone = words[5]; int fragStart, fragEnd; double fragSize; if (type[0] == 'N') continue; lineFileExpectWords(lf, 9, wordCount); chopSuffix(clone); fragStart = lineFileNeedNum(lf, words, 1)-1; fragEnd = lineFileNeedNum(lf, words, 2); fragSize = fragEnd - fragStart; if ((cp = hashFindVal(hash, clone)) == NULL) { AllocVar(cp); hashAddSaveName(hash, clone, cp, &cp->name); slAddHead(&cpList, cp); } cp->weightedPos += fragSize * fragStart; cp->totSize += fragSize; } lineFileClose(&lf); slReverse(&cpList); for (cp = cpList; cp != NULL; cp = cp->next) cp->pos = cp->weightedPos/cp->totSize; *retList = cpList; *retHash = hash; } void readGl(char *fileName, struct clonePos **retList, struct hash **retHash) /* Read gl formatted files. */ { struct lineFile *lf = lineFileOpen(fileName, TRUE); char *row[3]; struct clonePos *cpList = NULL, *cp; struct hash *hash = newHash(0); while (lineFileRow(lf, row)) { char *clone = row[0]; int fragStart, fragEnd; double fragSize; chopSuffix(clone); fragStart = lineFileNeedNum(lf, row, 1); fragEnd = lineFileNeedNum(lf, row, 2); fragSize = fragEnd - fragStart; if ((cp = hashFindVal(hash, clone)) == NULL) { AllocVar(cp); hashAddSaveName(hash, clone, cp, &cp->name); slAddHead(&cpList, cp); } cp->weightedPos += fragSize * fragStart; cp->totSize += fragSize; } lineFileClose(&lf); slReverse(&cpList); for (cp = cpList; cp != NULL; cp = cp->next) cp->pos = cp->weightedPos/cp->totSize; *retList = cpList; *retHash = hash; } void readMmBarge(char *fileName, struct clonePos **retList, struct hash **retHash) /* Read mmBarge formatted files. */ { struct lineFile *lf = lineFileOpen(fileName, TRUE); char *line, *row[3]; struct clonePos *cpList = NULL, *cp; struct hash *hash = newHash(0); /* Open file and verify header. */ if (!lineFileNext(lf, &line, NULL)) errAbort("%s is empty", fileName); if (!startsWith("Barge", line)) errAbort("%s is not an mmBarge file", fileName); lineFileNext(lf, &line, NULL); lineFileNext(lf, &line, NULL); lineFileNext(lf, &line, NULL); if (!startsWith("-----", line)) errAbort("%s is not an mmBarge file", fileName); while (lineFileRow(lf, row)) { char *offset = row[0]; if (startsWith("-----", offset)) continue; if (hashLookup(hash, row[1])) warn("%s duplicated in %s, ignoring all but first", row[0], fileName); else { AllocVar(cp); hashAddSaveName(hash, row[1], cp, &cp->name); if (offset[0] == '(') ++offset; if (!isdigit(offset[0])) errAbort("Expecting number first field of line %d of %s", lf->lineIx, lf->fileName); cp->pos = atoi(offset); slAddHead(&cpList, cp); } } lineFileClose(&lf); slReverse(&cpList); *retList = cpList; *retHash = hash; } void readDat(char *fileName, struct clonePos **retList, struct hash **retHash, int column) /* Read in one of Terry Furey's dat files. */ { struct lineFile *lf = lineFileOpen(fileName, TRUE); char *row[3]; struct clonePos *cpList = NULL, *cp; struct hash *hash = newHash(0); while (lineFileRow(lf, row)) { AllocVar(cp); hashAddSaveName(hash, row[2], cp, &cp->name); cp->pos = lineFileNeedNum(lf, row, column); slAddHead(&cpList, cp); } lineFileClose(&lf); slReverse(&cpList); *retList = cpList; *retHash = hash; } void loadMap(char *fileName, struct clonePos **retList, struct hash **retHash) /* Figure out file type and load it. */ { char file[128], ext[64]; splitPath(fileName, NULL, file, ext); if (startsWith("info", file)) return readInfo(fileName, retList, retHash); else if (startsWith("mmBarge", file)) return readMmBarge(fileName, retList, retHash); else if (startsWith("gold", file) || sameString(".agp", ext)) return readGold(fileName, retList, retHash); else if (sameString(".gl", ext) || sameString("gl", file)) return readGl(fileName, retList, retHash); else errAbort("Unrecognized file type %s%s", file, ext); } void loadMaps(char *mapA, char *mapB, struct clonePos **retListA, struct clonePos **retListB, struct hash **retHashA, struct hash **retHashB) /* Load some maps. */ { char file[128], ext[64]; splitPath(mapA, NULL, file, ext); if (sameString(".dat", ext)) { readDat(mapA, retListA, retHashA, 0); readDat(mapA, retListB, retHashB, 1); } else { loadMap(mapA, retListA, retHashA); loadMap(mapB, retListB, retHashB); } } void posSpan(struct clonePos *cpList, int *retStart, int *retEnd) /* Figure out min/max span of clone list. */ { struct clonePos *cp; int start, end; start = end = cpList->pos; for (cp = cpList->next; cp != NULL; cp = cp->next) { if (start > cp->pos) start = cp->pos; if (end < cp->pos) end = cp->pos; } *retStart = start; *retEnd = end; } void mapZoomIn(int x, int y, int width, int height, double zx, double zy, double zScale) /* Print out image map rectangle that calls self with zoom info. */ { printf("\n"); } void plot(struct memGfx *mg, int x, int y, char *name, Color color) /* Plot a point. */ { // y = mg->height - 1 - y; if (plotName) { mgTextCentered(mg, x-1, y-1, 3, 3, color, font, name); } else mgDrawBox(mg, x-1, y-1, 3, 3, color); } void makePlot(struct clonePos *xList, struct clonePos *yList, struct hash *yHash) /* Write out graphics for plot. */ { struct memGfx *mg = NULL; struct tempName gifTn; char *mapName = "map"; struct clonePos *xp, *yp; int i, j, x, y, nextX, nextY; int divisions = 10; double invZoom = 1.0/zoom; double magnify = 2.0; double newZoom = zoom*magnify; double invNewZoom = 1.0/newZoom; int xCount = slCount(xList); plotName = (xCount/zoom < 50); if (xList == NULL || yList == NULL) return; font = mgSmallFont(); posSpan(xList, &xStart, &xEnd); posSpan(yList, &yStart, &yEnd); if (pix < 50 || pix > 5000) errAbort("Pixels out of range - must be between 50 an 5000"); mg = mgNew(pix, pix); mgClearPixels(mg); /* Plot dots. */ for (xp = xList; xp != NULL; xp = xp->next) { if ((yp = hashFindVal(yHash, xp->name)) != NULL) { zoomScale(xp->pos, yp->pos, &x, &y); plot(mg, x, y, xp->name, MG_BLACK); } } /* Make zooming image map. */ printf("\n", mapName); for (i=0; i\n"); /* Save image in temp dir. */ makeTempName(&gifTn, "wikPic", ".gif"); mgSaveGif(mg, gifTn.forCgi, FALSE); printf( "


\n", gifTn.forHtml, pix, pix, mapName); mgFree(&mg); /* Print some extra info. */ printf("X has %d elements ranging from %d to %d
\n", slCount(xList), xStart, xEnd); printf("Y has %d elements ranging from %d to %d
\n", slCount(yList), yStart, yEnd); } void printBox() /* Make little navigation box. */ { puts( "\n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "
\">
\n" "\n"); cgiMakeButton("unzoom", "unzoom"); } void wikiPlot() /* wikiPlot - Quick plots of maps vs. each other. */ { boolean gotDir = cgiVarExists("contigDir"); double step; contigDir = cgiUsualString("contigDir", contigDir); mapX = cgiUsualString("mapX", mapX); mapY = cgiUsualString("mapY", mapY); pix = cgiUsualInt("pix", pix); xOff = cgiUsualDouble("xOff", xOff); yOff = cgiUsualDouble("yOff", yOff); zoom = cgiUsualDouble("zoom", zoom); step = 0.1 * 1/zoom; if (cgiVarExists("boxOut")) { double invZoom = 1.0/zoom; double xCen = xOff + invZoom*0.5; double yCen = yOff + invZoom*0.5; zoom /= 2; invZoom = 1.0/zoom; xOff = xCen - invZoom*0.5; yOff = yCen - invZoom*0.5; } else if (cgiVarExists("boxUp")) yOff -= step; else if (cgiVarExists("boxDown")) yOff += step; else if (cgiVarExists("boxLeft")) xOff -= step; else if (cgiVarExists("boxRight")) xOff += step; else if (cgiVarExists("boxUpLeft")) { yOff -= step; xOff -= step; } else if (cgiVarExists("boxUpRight")) { yOff -= step; xOff += step; } else if (cgiVarExists("boxDownLeft")) { yOff += step; xOff -= step; } else if (cgiVarExists("boxDownRight")) { yOff += step; xOff += step; } else if (cgiVarExists("unzoom")) { xOff = yOff = -0.05; zoom = 0.9; } printf("

\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
\n"); printf("Wiki Plotter
\n"); printf("Contig: "); cgiMakeTextVar("contigDir", contigDir, 0); if (gotDir) { cgiMakeButton("refresh", "refresh"); } else cgiMakeButton("submit", "submit"); printf("
\n"); printf("Map X: "); cgiMakeTextVar("mapX", mapX, 12); printf("Map Y: "); cgiMakeTextVar("mapY", mapY, 12); printf("Pixels: "); cgiMakeIntVar("pix", pix, 4); printf("
\n"); if (gotDir) printBox(); printf("
\n"); if (gotDir) { char xFile[512], yFile[512]; struct hash *xHash = NULL, *yHash = NULL; struct clonePos *xList = NULL, *yList = NULL; sprintf(xFile, "%s/%s", contigDir, mapX); sprintf(yFile, "%s/%s", contigDir, mapY); loadMaps(xFile, yFile, &xList, &yList, &xHash, &yHash); makePlot(xList, yList, yHash); } /* Save hidden vars. */ { char buf[256]; sprintf(buf, "%f", zoom); cgiMakeHiddenVar("zoom", buf); sprintf(buf, "%f", xOff); cgiMakeHiddenVar("xOff", buf); sprintf(buf, "%f", yOff); cgiMakeHiddenVar("yOff", buf); } printf("
\n"); } int main(int argc, char *argv[]) /* Process command line. */ { cgiSpoof(&argc, argv); htmShell("wikiPlot", wikiPlot, NULL); return 0; }