eb709217581384bfb7348fe687edfe5a7db0c5a0 ceisenhart Tue Dec 29 10:55:43 2015 -0800 fixing up the javascript that is printed, added some options to the visualization. refs #16216 diff --git src/hg/expMatrixToJson/expMatrixToJson.c src/hg/expMatrixToJson/expMatrixToJson.c index 7054467..0bed5b1 100644 --- src/hg/expMatrixToJson/expMatrixToJson.c +++ src/hg/expMatrixToJson/expMatrixToJson.c @@ -172,48 +172,66 @@ { struct bioExpVector *bio = (struct bioExpVector *)tree->itemOrCluster; char *tissue = bio->name; struct rgbColor colors = bio->color; if (tree->childDistance > clLongest) /* In practice the first distance will be the longest, and is used for normalization. */ clLongest = tree->childDistance; int i; for (i = 0; i < level; i++) fputc(' ', f); // correct spacing for .json format if (tree->left == NULL && tree->right == NULL) // Print the leaf nodes { if (bio->desc) - fprintf(f, "{\"name\":\"%s\",\"kids\":\"%i\",\"distance\":\"%s\",\"colorGroup\":\"rgb(%i,%i,%i)\"}", tissue, 0, bio->desc, colors.r, colors.g, colors.b); + fprintf(f, "{\"name\":\"%s\",\"length\":%f,\"distance\":\"%s\",\"colorGroup\":\"rgb(%i,%i,%i)\"}", tissue, (tree->parent->childDistance*tree->parent->childDistance) /1000, bio->desc, colors.r, colors.g, colors.b); else - fprintf(f, "{\"name\":\"%s\",\"kids\":\"%i\",\"distance\":\"%s\",\"colorGroup\":\"rgb(%i,%i,%i)\"}", tissue, 0, " ", colors.r, colors.g, colors.b); + fprintf(f, "{\"name\":\"%s\",\"length\":%f,\"distance\":\"%s\",\"colorGroup\":\"rgb(%i,%i,%i)\"}", tissue, tree->parent->childDistance, " ", colors.r, colors.g, colors.b); return; } else if (tree->left == NULL || tree->right == NULL) errAbort("\nHow did we get a node with one NULL kid??"); // Prints out the node object and opens a new children block. -fprintf(f, "{\"name\": \" \", \"longestDistance\":\"%f\", \"tpmDistance\": \"%f\", \"kids\": \"%f\", \"colorGroup\": \"rgb(%i," - "%i,%i)\",",clLongest,tree->childDistance,sqrt(bio->children), colors.r,colors.g,colors.b); +for (i = 0; i < level + 1; i++) + fputc(' ', f); distance = tree->childDistance/clLongest; +double temp = 0; +if (tree->parent != NULL) + { + temp = tree->parent->childDistance; + } +fprintf(f, "{\"name\": \" \", \"longestDistance\":\"%f\", \"tpmDistance\": \"%f\", \"length\": %f, \"colorGroup\": \"rgb(%i," + "%i,%i)\",",clLongest,tree->childDistance, temp*temp/1000, colors.r,colors.g,colors.b); if (distance != distance) distance = 0; //fprintf(f, "\"%s\"%s \"%f\"%s\n", "distance", ":", 100*distance, ","); struct rgbColor wTB; -if (distance == 0) {wTB = whiteToBlackRainbowAtPos(.95);} -else {wTB = whiteToBlackRainbowAtPos(.95-(sqrt(distance)*.95));} -fprintf(f, "\"distance\": \"%f\", \"whiteToBlack\":\"rgb(%i,%i,%i)\",\n", 100*distance, wTB.r, wTB.g, wTB.b); +struct rgbColor wTBsqrt; +struct rgbColor wTBquad; +if (distance == 0) { + wTB = whiteToBlackRainbowAtPos(0); + wTBsqrt = whiteToBlackRainbowAtPos(0); + wTBquad = whiteToBlackRainbowAtPos(0); + } +else { + wTB = whiteToBlackRainbowAtPos(distance*.95); + wTBsqrt = whiteToBlackRainbowAtPos(sqrt(distance*.95)); + wTBquad = whiteToBlackRainbowAtPos(sqrt(sqrt(distance*.95))); + } +fprintf(f, "\"distance\": \"%f\", \"whiteToBlack\":\"rgb(%i,%i,%i)\", \"whiteTo", distance, wTB.r, wTB.g, wTB.b); +fprintf(f, "BlackSqrt\":\"rgb(%i,%i,%i)\", \"whiteToBlackQuad\":\"rgb(%i,%i,%i)\",\n", wTBsqrt.r, wTBsqrt.g, wTBsqrt.b, wTBquad.r, wTBquad.g, wTBquad.b); for (i = 0; i < level + 1; i++) fputc(' ', f); fprintf(f, "\"children\":[\n"); rPrintHierarchicalJson(f, tree->left, level+1, distance); fputs(",\n", f); rPrintHierarchicalJson(f, tree->right, level+1, distance); fputc('\n', f); // Closes the children block for node objects for (i=0; i < level + 1; i++) fputc(' ', f); fputs("]\n", f); for (i = 0; i < level; i++) fputc(' ', f); fputs("}", f); } @@ -269,67 +287,77 @@ el->count = kid1->count; el->name = catTwoStrings(kid1->name, kid2->name); int i; for (i = 0; i < el->count; ++i) { el->vector[i] = (kid1Weight*kid1->vector[i] + kid2Weight*kid2->vector[i]); } el->children = kid1->children + kid2->children; return (struct slList *)(el); } void colorLeaves(struct slRef *leafList) /* Assign colors of rainbow to leaves. */ { float total = 0.0; -double purplePos = 0.80; +//double purplePos = 0.80; struct slRef *el, *nextEl; /* Loop through list once to figure out total, since we need to normalize */ for (el = leafList; el != NULL; el = nextEl) { nextEl = el->next; if (nextEl == NULL) break; struct bioExpVector *bio1 = el->val; struct bioExpVector *bio2 = nextEl->val; double distance = slBioExpVectorDistance((struct slList *)bio1, (struct slList *)bio2, NULL); if (distance != distance ) distance = 0; total += distance; } if (total == 0) errAbort("There doesn't seem to be any difference between these matrix columns. Aborting."); - double soFar = 0; /* Loop through list a second time to generate actual colors. */ +bool firstLine = TRUE; for (el = leafList; el != NULL; el = nextEl) { nextEl = el->next; if (nextEl == NULL) break; struct bioExpVector *bio1 = el->val; struct bioExpVector *bio2 = nextEl->val; double distance = slBioExpVectorDistance((struct slList *)bio1, (struct slList *)bio2, NULL); - if (distance != distance ) distance = 0 ; - soFar += distance; - double normalized = soFar/total; - bio2->color = saturatedRainbowAtPos(normalized*purplePos); + if (firstLine) + { + double normalized = distance/total; + bio1->color = whiteToBlackRainbowAtPos(normalized); + firstLine = FALSE; + } + //if (distance != distance ) distance = 0 ; + //soFar += distance; + //double normalized = soFar/total; + double normalized = distance/total; + if (normalized * 100 >= .95) bio2->color = whiteToBlackRainbowAtPos(.95); + else bio2->color = whiteToBlackRainbowAtPos(normalized*100); + //bio2->color = saturatedRainbowAtPos(distance); + soFar += normalized; } - /* Set first color to correspond to 0, since not set in above loop */ -struct bioExpVector *bio = leafList->val; -bio->color = saturatedRainbowAtPos(0); +//struct bioExpVector *bio = leafList->val; +//bio->color = saturatedRainbowAtPos(0); +//bio->color = whiteToBlackRainbowAtPos(0.0); } void convertInput(char *expMatrix, char *descFile, bool csv) /* Takes in a expression matrix and makes the inputs that this program will use. * Namely a transposed table with the first column removed. Makes use of system calls * to use cut, sed, kent utility rowsToCols, and paste (for descFile option). */ { char cmd1[1024], cmd2[1024]; if (csv) /* A sed one liner will convert comma separated values into a tab separated values*/ { char cmd3[1024]; safef(cmd3, 1024, "sed -i 's/,/\\t/g' %s ",expMatrix); verbose(2,"%s\n", cmd3); mustSystem(cmd3); @@ -360,63 +388,239 @@ mustSystem(cmd2); } } void generateHtml(FILE *outputFile, int nameSize, char* jsonFile) // Generates a new .html file for the dendrogram. Will do some size calculations as well. { char *pageName = cloneString(jsonFile); chopSuffix(pageName); int textSize = 12 - log(nodeCount); int radius = 540 + 270*log10(nodeCount); int labelLength = 10+nameSize*(15-textSize); if (labelLength > 100) labelLength = 100; -fprintf(outputFile,"