[Zooimage-commits] r172 - in pkg/zooimage/inst/imagej: . plugins
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Wed Jun 10 13:12:01 CEST 2009
Author: romain
Date: 2009-06-10 13:12:00 +0200 (Wed, 10 Jun 2009)
New Revision: 172
Added:
pkg/zooimage/inst/imagej/fitvis
pkg/zooimage/inst/imagej/plugins/FITVIS.macro
pkg/zooimage/inst/imagej/plugins/_fitvis.jar
pkg/zooimage/inst/imagej/plugins/fitvis_.cfg
Modified:
pkg/zooimage/inst/imagej/plugins/_zooimage.jar
Log:
fit vis build
Added: pkg/zooimage/inst/imagej/fitvis
===================================================================
--- pkg/zooimage/inst/imagej/fitvis (rev 0)
+++ pkg/zooimage/inst/imagej/fitvis 2009-06-10 11:12:00 UTC (rev 172)
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+java -Xmx900m -cp .:ij.jar:plugins/_fitvis.jar org.sciviews.zooimage.fitvis.FitVisMain $@
Property changes on: pkg/zooimage/inst/imagej/fitvis
___________________________________________________________________
Name: svn:executable
+ *
Added: pkg/zooimage/inst/imagej/plugins/FITVIS.macro
===================================================================
--- pkg/zooimage/inst/imagej/plugins/FITVIS.macro (rev 0)
+++ pkg/zooimage/inst/imagej/plugins/FITVIS.macro 2009-06-10 11:12:00 UTC (rev 172)
@@ -0,0 +1,810 @@
+// The calling plugin passes a single string argument which is
+// composed of a series of lines of text joined by the line separator(("\n")
+// The first line line of text holds common flags...
+// VERBOSE = boolean, output information messages
+// BATCHMODE = boolean, run in batch mode (faster)
+// DIRECTORY = string, the directory
+// PIXELSIZE = number, the pixel size in microns
+// MINSIZE = number, right now as ESD, default to 10
+// MAXSIZE = number, as ESD, default to Infinity
+// USEPIXELS = "light", "dark" or "both", default to "dark"
+// THRESHOLDDARK = number, default to 25
+// THRESHOLDLIGHT = number, default to 25
+// FILL = boolean, fill holes?
+// LARGEST = boolean, use largest or combine objects?
+// VIGNETTES = boolean, save as jpegs saved to "_" + dirname(directory)
+// ENHANCE = boolean, sharpen the vignette
+// OUTLINE = boolean, add outline to vignette
+// SCALEBAR = boolean, add scale bar where they fit
+// MASKS = boolean, save masks to _masks
+// LOG = boolean, log transform before background subtraction
+// collageID = integer
+// calibrationID = integer
+// distanceToNeighbor = integer
+// SLICE = number, set to the slice to work on in collage stack
+// (this is duplicated in the per subimage navigation info below)
+// The subsequent lines provide navigation elements per subimage
+// ID colSlice sX sY pW pH calSlice cX cY
+// 0 1 2 3 4 5 6 7 8
+
+//default values
+verbose = false;
+batchmode = false;
+dir = "";
+pixelsize = 1.0;
+minsize = 0.0;
+maxsize = parseFloat("Infinity");
+usepixels = "dark";
+thresholddark = 20;
+thresholdlight = 20;
+fillHoles = true;
+largest = true;
+vignettes = false;
+scalebar = true;
+enhance = true;
+outline = false;
+masks = false;
+dolog = false;
+distance = 45;
+
+arg = split(getArgument(),"\n");
+// get the first line of flags etc. The first line has booleans, filepaths,
+// numbers etc. in comma- or tab-delimited fields
+ //print(arg[0]);
+ s = split(arg[0], ",\t");
+ for (i=0; i<s.length; i++){
+ lowS = toLowerCase(s[i]);
+ a = split(lowS, "=");
+ b = split(s[i], "=");
+ if (startsWith(a[0],"verbose")){
+ verbose = startsWith(a[1],"true");
+ } else if (startsWith(a[0],"batchmode")){
+ batchmode = startsWith(a[1],"true");
+ } else if (startsWith(a[0],"directory")){
+ dir = b[1];
+ } else if (startsWith(a[0],"pixelsize")) {
+ pixelsize = parseFloat(b[1]);
+ } else if (startsWith(a[0],"minsize")){
+ minsize= parseFloat(b[1]);
+ } else if (startsWith(a[0],"maxsize")){
+ maxsize= parseFloat(b[1]);
+ } else if (startsWith(a[0],"usepixels")){
+ usepixels = a[1];
+ } else if (startsWith(a[0], "thresholddark")){
+ thresholddark = parseInt(a[1]);
+ } else if (startsWith(a[0], "thresholdlight")){
+ thresholdlight = parseInt(a[1]);
+ } else if (startsWith(a[0],"fill")){
+ fillholes = startsWith(a[1],"true");
+ } else if (startsWith(a[0],"largest")){
+ largest = startsWith(a[1], "true");
+ } else if (startsWith(a[0], "vignettes")){
+ vignettes = startsWith(a[1], "true");
+ } else if (startsWith(a[0], "scalebar")){
+ scalebar = startsWith(a[1], "true");
+ } else if (startsWith(a[0], "enhance")){
+ enhance = startsWith(a[1],"true");
+ } else if (startsWith(a[0], "outline")){
+ outline = startsWith(a[1], "true");
+ } else if (startsWith(a[0], "masks")){
+ masks = startsWith(a[1], "true");
+ } else if (startsWith(a[0], "slice")){
+ slice = parseInt(a[1]);
+ } else if (startsWith(a[0], "log")){
+ dolog = startsWith(a[1], "true");
+ } else if (startsWith(a[0], "collageid")) {
+ collageID = parseInt(a[1]);
+ } else if (startsWith(a[0], "calibrationid")) {
+ calibrationID = parseInt(a[1]);
+ } else if (startsWith(a[0], "distance")) {
+ distance = parseInt(a[1]);
+ } else {
+ if (verbose) {print("Unrecognized argument: " + s[i]);}
+ }
+ }
+
+//PhG: Force log treatment
+dolog = true;
+
+ //get the name of the directory - take it as the name
+ name = File.getName(dir);
+ //create the vignette directory
+ vignDir = dir + name + File.separator;
+ if (vignettes == true){
+ if (File.exists(vignDir) == false) {File.makeDirectory(vignDir);}
+ }
+
+ //create the masks directory
+ maskDir = dir + "_masks" + File.separator;
+ if (masks == true){
+ if (File.exists(maskDir)==false){File.makeDirectory(maskDir);}
+ }
+
+ outlineDir = dir + "_outlines" + File.separator;
+ if (outline == true){
+ if (File.exists(outlineDir) == false){File.makeDirectory(outlineDir);}
+ }
+
+// PhG create OD dir
+ odDir = dir + "_OD" + File.separator;
+ if (File.exists(odDir) == false){File.makeDirectory(odDir);}
+
+ //convert diameters to area of equivalent pixels
+ //2009-04-30 BT fudge factor to deal with possible rounding differences between
+ // FIT and IJ area measurments
+ minSizeScaler = 0.95;
+ minArea = pow((minsize * minSizeScaler)/2.,2) * PI;
+ maxArea= pow(maxsize/2.,2) * PI;
+ if (largest == true){
+ sizeInfo = "size=0-"+maxArea;
+ } else {
+ sizeInfo = "size=" + minArea + "-" + maxArea;
+ tempSizeInfo = "size=0-"+maxArea; //for when things go bad
+ }
+
+ n = arg.length-1;
+ data = newArray(n);
+ for (i=0;i<n;i++){data[i] = "";}
+
+ if (verbose) {
+ if (slice == 1) {
+ print(sizeInfo);
+ }
+ print("Slice = " + slice + " has " + n + " particles");
+ }
+
+ //this is where we begin to handle the segmentation scheme
+ isboth = false;
+ order = true;
+ //print("usepixels="+ usepixels);
+ if (startsWith(toLowerCase(usepixels), "both")){
+ pasteMode = "Difference";
+ isboth = true;
+ //not quite sure how to handle this as the threshold
+ //can be asymmetric like -20 < difference > 10
+ //so I'll ignore this for now - later we'll have to do some
+ // two subtractions and two thresholds then AND them. Blech.
+ } else {
+ pasteMode = "Subtract";
+ //order = true if "dark" or false if "light"
+ // true means (cal-image) > thresholddark
+ // false means (image-cal) > thresholdlight
+ order = startsWith(toLowerCase(usepixels), "dark");
+ }
+ //if (verbose) {print("order="+order);}
+ //set the scale
+ // run("Set Scale...", "distance=1 known="+pixelsize+" pixel=1 unit=um global");
+
+ //the drawing color is yellow
+ setForegroundColor(255,255,0);
+
+ // slide into batchmode so it is faster
+ setBatchMode(batchmode);
+
+// selectWindow("Collages");
+// collageID = getImageID();
+ selectImage(collageID);
+ setSlice(slice);
+
+// selectWindow("Calibrations");
+// calibrationID = getImageID();
+
+ //make the subimages
+ //cROI = from the collage
+ //bROI = from calibration (background)
+ //outline is a copy of the cROI reserved for stamping the particle outline
+ newImage("colROI", "8-bit White", 20, 20, 1);//collage subimage
+ colID = getImageID();
+ newImage("calROI", "8-bit White", 20, 20, 1);//calibration subimage
+ calID = getImageID();
+ newImage("outline","8-bit White", 20,20,1);//for outlining
+ outlineID = getImageID();
+// newImage("original", "8-bit White", 20,20,1);//for original
+// originalID = getImageID();
+// PhG: I need to keep both calID and colID intact for background division
+// However, Ben uses calID to create the mask
+// -> I create a separate maskID image for that purpose
+//newImage("mask","8-bit White", 20,20,1);//for mask
+//maskID = getImageID();
+
+ if (dolog == true){
+ newImage("colLog", "8-bit White", 20, 20, 1);//collage subimage for log
+ colLogID = getImageID();
+ newImage("calLog", "8-bit White", 20, 20, 1);//calibration subimage for log
+ calLogID = getImageID();
+ }
+
+ //set the measurements
+// run("Set Measurements...","area mean standard modal min centroid center perimeter bounding fit circularity feret's integrated median skewness kurtosis redirect=colROI decimal=3");
+ //get the header column names
+ hdr = call("org.sciviews.zooimage.fitvis.FITVIS_.getResultsHeadings");
+ colHdr = split(hdr, "\t");
+ dummy = newArray(colHdr.length);
+
+// colHdr = newArray("Area","Mean","StdDev","Mode","Min","Max","X","Y","XM","YM",
+// "Perim.","BX","BY","Width","Height","Major","Minor","Angle","Circ.","Feret",
+// "IntDen","Median","Skew","Kurt", "XStart", "YStart");
+
+ run("ROI Manager...");
+ roiManager("reset");
+ run("Clear Results");
+
+// a reminder
+// ID collageSlice, sX, sY pW pH calSlice cX cY
+// 0 1 2 3 4 5 6 7 8
+
+ for (i=0;i<n;i++){
+ //get the navigation data
+ //1 = 2 23 0 44 29 1 596 266
+ //print(i + " = " + arg[i+1]);
+ //print("Processing: " + arg[i+1]);
+ s = split(arg[i+1],",\t");
+ item = s[0];
+ colSlice = parseInt(s[1]);
+ sX = parseInt(s[2]);
+ sY = parseInt(s[3]);
+ pW = parseInt(s[4]);
+ pH = parseInt(s[5]);
+ calSlice = parseInt(s[6]);
+ cX = parseInt(s[7]);
+ cY = parseInt(s[8]);
+ //copy the calibration to the "calROI" image
+ selectImage(calibrationID);
+ setSlice(calSlice);
+
+ //function doCopy(srcID, x0, y0, w, h, dstID, resize)
+ //copy the calimage to "calROI" image
+ doCopy(calibrationID,cX,cY, pW, pH, calID, true);
+// PhG: added for the mask
+//doCopy(calibrationID,cX,cY, pW, pH, maskID, true);
+ //copy the subimage to the "colROI" image
+ selectImage(collageID);
+ doCopy(collageID, sX,sY, pW, pH, colID, true);
+// if (dolog == true){
+// doCopy(collageID, sX,sY, pW, pH, originalID, true);
+// }
+ //make a copy for the outline
+ if (outline == true){
+ selectImage(outlineID);
+ run("8-bit");
+ run("Size...", "width=" + pW + " height=" + pH);
+ run("Paste");
+ run("RGB Color");//bump up so we can "burn" the outline color in
+ }
+
+ selectImage(calID);
+ if (isboth) {
+ // this is for a two part segmentation of light and dark pixels
+ // which we ignore for now
+ } else {
+ imageCalculator(pasteMode, calID,colID);
+ selectImage(calID);
+ if (order) {
+ //if looking for dark pixels, then we want them such that
+ //(cal-col) > thresholddark
+ setThreshold(thresholddark,255);
+ } else {
+ //if looking for light pixels then we want them such that
+ // (0-cal-col) >
+ setThreshold(0,thresholdlight);
+ }
+ }
+
+ if (dolog == true){
+
+ //insert black/white points,invert, convert to float, logscale
+ // result1 = log(inverted(subimage)) - log(inverted(calibration))
+ // result2 = alog(result1)
+
+ doCopy(calID, 0,0, pW, pH, calLogID, true);
+ selectImage(calLogID);
+// PhG
+// run("Invert");
+ setPixel(0,0,0);
+ setPixel(0,1,255);
+// PhG
+run("Log");
+run("Invert");
+// run("32-bit");
+// run("Log");
+ doCopy(colID, 0,0, pW, pH, colLogID, true);
+ selectImage(colLogID);
+// PhG
+// run("Invert");
+ setPixel(0,1,0);
+ setPixel(0,0,255);
+// PhG
+// run("32-bit");
+// run("Log");
+run("Log");
+run("Invert");
+ //subtract the two, store the result in colID
+ imageCalculator("Subtract", colLogID, calLogID);
+
+// PhG: don't!
+ //delog the colID
+// selectImage(colLogID);
+// run("Exp");
+
+// PhG a dded
+ selectImage(colLogID);
+ thisFile = odDir + name + "_OD_" + s[0] + ".png";
+ //print(thisFile);
+ saveAs("PNG", thisFile);
+ rename("colLog");
+
+ redirectName = "colLog";
+ } else {
+ redirectName = "colROI";
+ }
+
+ selectImage(calID);
+ run("Convert to Mask");
+
+
+ if (masks == true) {
+ //the last image selected in the doSeg is the "bROI"
+ selectImage(calID);
+ thisFile = maskDir + name + "_mask_" + s[0] + ".png";
+ //print(thisFile);
+ saveAs("PNG", thisFile);
+ rename("calROI");
+ }
+
+
+ roiManager("reset");
+ run("Clear Results");
+ if (fillholes == true){run("Fill Holes");}
+ roiManager("reset");
+
+ //set the measurements
+ run("Set Measurements...","area mean standard modal min centroid center perimeter bounding fit circularity feret's integrated median skewness kurtosis redirect="+ redirectName+" decimal=3");
+
+ run("Analyze Particles...", sizeInfo + " circularity=0.00-1.00 show=Nothing display clear record");
+
+ nbefore = nResults;
+ // if there are NO qualifying particles, run the analysis again but with
+ // a size range of 0-maxArea. This isn't desirable but it does seem to work OK
+ // since the situation arises only occasionally
+ if (nbefore == 0){
+ selectImage(calID);
+ run("Analyze Particles...", tempSizeInfo + " circularity=0.00-1.00 show=Nothing display clear record");
+ nbefore = nResults;
+ }
+
+ selectImage(calID);
+ //print("Begin to analyze");
+
+
+ numFound = doAnalysis(outline, largest, colID, calID, outlineID, distance, pixelsize, verbose);
+// if (verbose){print("image: " + item + " has " + nResults + " candidate particles of which there are " +
+// numFound + " objects" );}
+// print("nBefore=", nbefore, " nAfter=" , nResults + " area=" + getResult("Area", nResults-1));
+
+// restore the original data to the colID if logscale filter is enabled
+// if (dolog == true){
+// selectImage(originalID);
+// run("Copy");
+// selectImage(colID);
+// run("8-bit");
+// run("Paste");
+// }
+
+ //print("numFound = " + numFound + " at " + i);
+ if(i == 0) {
+ hdr = call("org.sciviews.zooimage.fitvis.FITVIS_.getResultsHeadings");
+ colHdr = split(hdr, "\t");
+ dummy = newArray(colHdr.length);
+ }
+ str = getResultsRow(nResults-1, ",", false, colHdr, dummy);
+ data[i] = s[0] + "," + str + "," + numFound + "\n";
+
+ if (vignettes == true){
+ selectImage(colID);
+ if (enhance == true){run("Enhance Contrast", "saturated=0.5");}
+ if (scalebar == true){
+ barSize = getBarSize(pixelsize, s[4]);
+ //print("barSize("+i+")="+ barSize);
+ //set the scalebar
+ if (barSize != 0 ) {
+ text = "width="+barSize+" height=3 font=12 color=Black background=None location=[Upper Right]";
+ //run("Set Scale...", "distance=1 known="+cal+" pixel=1 unit=um");
+ run("Scale Bar...", text);
+ //run("Set Scale...", "distance=1 known=1 pixel=1 unit=pixel");
+ }
+ }
+ imgname = name + "_" + s[0] + ".jpg";
+ //if (doVerbose) {print("Saving: " + imgname );}
+ saveAs("Jpeg", vignDir+ imgname);
+ rename("colROI");
+ }
+
+ if (outline == true) {
+ thisFile = outlineDir + name + "_outline_" + s[0] + ".tif";
+ selectImage(outlineID);
+// run("Restore Selection");
+// run("Draw");
+ saveAs("Tiff", thisFile);
+ rename("outline");
+ }
+// if (masks == true) {
+// //the last image selected in the doSeg is the "bROI"
+// selectImage(calID);
+// thisFile = maskDir + name + "_mask_" + s[0] + ".png";
+// //print(thisFile);
+// saveAs("PNG", thisFile);
+// rename("calROI");
+// }
+
+ }//i-loop through n subimages
+
+ s = concat(colHdr, ",", false) ;
+ s = "!Item," + s + ",Count\n";
+ for (i=0;i<n;i++){s = s+data[i];}
+ closeWindow("colROI");
+ closeWindow("calROI");
+// PhG
+closeWindow("mask");
+ closeWindow("outline");
+ if (dolog) {
+ closeWindow("colLog");
+ closeWindow("calLog");
+ }
+// run("Clear Results");
+ showStatus("Returning from macro... please wait");
+ setBatchMode(false);
+ //run("Set Scale...", "distance=1 known=1 pixel=1 unit=pixel global");
+
+// selectWindow("Results");
+// run("Close");
+// selectWindow("ROI Manager");
+// run("Close");
+ return s;
+
+
+//------
+// copies an roi from srcID to dstID with our without a resize of dstID
+//-----
+function doCopy(srcID, x0, y0, w, h, dstID, resize){
+
+ selectImage(srcID);
+ makeRectangle(x0,y0,w,h);
+ run("Copy");
+ selectImage(dstID);
+ if (resize == true){
+ run("Size...", "width=" + w + " height=" + h);
+ }
+ setPasteMode("Copy");
+ run("Paste");
+ return dstID;
+}
+
+//-------
+// runs the analysis
+//-------
+function doAnalysis(outline, largest, colID, calID, outlineID, minDistance, pixelSize, verbose){
+
+ retval = 0;
+
+ //user wants largest single partle or there is only one
+ if ((largest == true) || (nResults == 1)) {
+ i = getBiggestIndex("Area");
+ xStart = getResult("XStart", i);
+ yStart = getResult("YStart", i);
+ doWand(xStart, yStart);
+ roiManager("Add");
+ retval = 1;
+
+ } else {
+ // ok - there are many objects
+ //
+ // (1) calculate the distances between pairs of perimeters - rather than
+ // storing in a distance matrix, store in strings of connections (i.e. "trees")
+ // (2) then collapse the trees to merge entries with overlaps
+ // (3) then compress each tree so that there is one tree per connected-blobs
+ // (4) then determine which tree represents the greatest area - this assumes
+ // that the user wants the largest connected objects
+ // (5) select that connected component and measure
+ s= newArray(nResults);
+ delim = ":";
+ eol = "\n";
+ selectImage(calID);
+ minDist = minDistance / pixelSize;
+ for (i=0 ; i<nResults ; i++) {
+ xStart = getResult("XStart", i); //get the boundary pixels for object "a"
+ yStart = getResult("YStart", i);
+ doWand(xStart,yStart);
+ getSelectionCoordinates(xa, ya);
+ conns = 0;
+ s2 = delim + (i) + delim;
+ s[i] = s2;
+ for (j = (i+1); j<nResults; j++){
+ xStart = getResult("XStart", j); //get the perimeter pixels for object "b"
+ yStart = getResult("YStart", j);
+ doWand(xStart,yStart);
+ getSelectionCoordinates(xb, yb);
+ d = shortestDistance(xa,ya, xb,yb); //compute the shortest distance
+ if (d <= minDist){s[i] = s[i] + (j) + delim;} //add this one if it is close enough
+ } //j loop through top to bottom of matrix
+ } // i loop through the left to right of matrix
+
+ //this next steps connects trees that overlap (one or more common nodes)
+ composeTrees(s, delim);
+ //this next step removes duplicate nodes and empty trees
+ r = compressTrees(s, delim);
+ // the number of entries in r indicates the number of objects
+ retval = r.length;
+
+ if (retval == 1) {
+ // if all nodes are connected then we have just one object - simple!
+ s = split(r[0], ",");
+// print("nResults=" + nResults);
+// print("r=", r[0]);
+ for (i = 0; i< s.length; i++){
+ xStart = getResult("XStart", s[i]);
+ yStart = getResult("YStart", s[i]);
+ doWand(xStart, yStart);
+ roiManager("Add");
+ }// iloop
+ } else {
+ //more than one found
+ //find the tree that represents the largest area
+ bigIndex = 0;
+ area = 0;
+ for (i = 0; i < r.length; i++){
+ s = split(r[i], ",");
+ newArea = 0;
+ for (j = 0; j< s.length; j++){
+ newArea = newArea + getResult("Area", s[j]);
+ }
+ if (newArea > area){
+ area = newArea;
+ bigIndex = i;
+ }
+ }// i-loop down through r determining the biggest area
+
+ //this one that reperesnts the largest area is the one the
+ //that we want
+ s = split(r[bigIndex], ",");
+ for (i = 0; i< s.length; i++){
+ xStart = getResult("XStart", s[i]);
+ yStart = getResult("YStart", s[i]);
+ doWand(xStart, yStart);
+ roiManager("Add");
+ }// iloop
+
+ } // more than one connected component objects
+
+ } // many objects
+
+ //now select them all (add to outline image if needed)
+ for (i = 0; i<roiManager("count"); i++){
+ setKeyDown("shift");
+ roiManager("select", i);
+ if (outline == true){
+ xStart = getResult("XStart", i);
+ yStart = getResult("YStart", i);
+ doWand(xStart, yStart);
+ selectImage(outlineID);
+ run("Restore Selection");
+ run("Draw");
+ selectImage(calID);
+ } //outline
+ } //i loop
+// PhG added
+//roiManager("Combine");
+ run("Measure"); //add the new measurement to the results table
+ return retval;
+}//doAnalysis
+
+
+// computeDistance(x0,y0,x1,y1)
+// calculate the distance between point0 and point1
+function computeDistance(x0,y0,x1,y1){
+ return sqrt(pow(x1-x0,2) + pow(y1-y0,2));
+}
+
+
+//calculates an appropriate scale bar size
+// 2006-11-29 BT changed so that anything less than 40 in length returns 0
+// 2009-04-30 BT changed to increments of 0, 100, 200, ...
+function getBarSize(cal, len) {
+ w = cal*parseInt(len);
+ if (w > 300){
+ return 250.0;
+ }
+ if (w > 200) {
+ return 150.0;
+ }
+ if (w > 100){
+ return 50.0;
+ }
+ return 0.0;
+// if (parseInt(len) < 40) {
+// x = 0.0; //no bar for small images
+// } else {
+// x = 0.5; // the 50% of the pixel width of the subimage
+// }
+// return floor(x*len*cal/10.) * 10;
+}
+
+//this function searches the results table for the biggest value in a
+// column. For example "Area"
+//returns the index of that row
+function getBiggestIndex(colname){
+ n = nResults();
+ if (n == 0) {return -1;}
+ if (n == 1) {return 0;}
+ index = 0;
+ current = getResult(colname, index);
+ for (i = 1; i<n;i++){
+ next = getResult(colname, i);
+ if ( next > current) {
+ index = i;
+ current = next;
+ }
+ }
+ return index;
+}//getBiggestIndex
+
+
+// getResults the result line at row appends a new line if requested
+function getResultsRow(row, delim, doNewLine, colHdr, dummy){
+ //empty the dummy array (fill with null) if there are no results
+ //other wise fill with each column specified by column header
+ if (nResults() == 0) {
+ for (i=0;i<dummy.length;i++){
+ dummy[i] = "null";
+ }
+ } else {
+ for (i=0; i<colHdr.length;i++){
+ str = getResult(colHdr[i], row);
+ dummy[i]= toString(str);
+ }
+ }
+ //s = getResultLabel(row) + "\t" + concat(dummy, doNewLine);
+ s = concat(dummy,delim,doNewLine);
+ return s;
+}
+
+// concats an array of strings, optional newLine
+function concat(arr, delim, appendNewLine){
+ s = "";
+ for (i = 0; i<(arr.length-1); i++){
+ s = s + toString(arr[i]) + delim;
+ }
+ s = s + toString(arr[arr.length-1]);
+ if (appendNewLine == true) {
+ s = s + "\n";
+ }
+ return s;
+}
+
+function closeWindow(title){
+ if (isOpen(title)){
+ selectWindow(title);
+ close();
+ }
+}
+
+
+// this function will compress each tree by sorting and removing duplicates
+// as in the example below. The funny delimiters have served their purpose so commas
+// are used instead.
+// before compress ...
+// s[ 0 ] = :1:2:4:2:4:4:
+// s[ 1 ] =
+// s[ 2 ] = :3:5:5:
+// s[ 3 ] =
+// s[ 4 ] =
+// s[ 5 ] = :6:
+// after compress...
+// x[ 0 ] = 1,2,4
+// x[ 1 ] = 3,5
+// x[ 2 ] = 6
+
+function compressTrees(s, delim){
+ count = 0;
+ for (i=0; i<s.length; i++){
+ x = split(s[i], ":");
+ if (x.length > 1){
+ Array.sort(x);
+ s[i] = x[0];
+ for (j=1; j<x.length; j++){
+ if (x[j] != x[j-1]) { s[i] = s[i] + "," + x[j];}
+ } //step through the x's
+ } else if (x.length == 1) {
+ s[i] = x[0];
+ }
+
+ if (lengthOf(s[i]) > 0){
+ count++;
+ }
+
+ }//i loop
+
+
+ if (count > 0) {
+ j = 0;
+ x = newArray(count);
+ for (i=0; i<s.length; i++){
+ if (lengthOf(s[i]) > 0){ x[j] = s[i]; j++;}
+ }
+ } else {
+ x = newArray(1);
+ x[0] = 0;
+ }
+ return x;
+}
+
+// this function builds the search "trees" which at this point is a series
+// of delimited identifiers (":1:5:7:13:") and combine all of those that share
+// a node in common - it will empty those which are moved to other branches.
+// nodes without neighbors are left alone. for example...
+// before compose...
+// s[ 0 ] = :1:2:4:
+// s[ 1 ] = :2:4:
+// s[ 2 ] = :3:5:
+// s[ 3 ] = :4:
+// s[ 4 ] = :5:
+// s[ 5 ] = :6:
+// move 1 to 0
+// move 3 to 0
+// move 4 to 2
+// after compose ...
+// s[ 0 ] = :1:2:4:2:4:4:
+// s[ 1 ] =
+// s[ 2 ] = :3:5:5:
+// s[ 3 ] =
+// s[ 4 ] =
+// s[ 5 ] = :6:
+//
+function composeTrees( s, delim){
+ for (i = 1; i<s.length; i++){
+ t = split(s[i], delim); //split the line
+ j = 0; //a starting index
+ while ((j >= 0) && (j < t.length)){
+ ix = topIndex(s, t[j], delim); // find the topmost location of this ID
+ if (ix >= 0) { //if it matches then move the entire line
+ if (ix != i){
+ s[ix] = s[ix] + substring(s[i],1);
+ s[i] = "";
+ }
+ j = -1; //bail out
+ } else { // otherwise keep going down the list
+ j++;
+ }
+ } // while j...
+ }// i loop
+
+ return 1;
+} // end of composeTrees
+
+// returns the lowest index into s where "num" appears
+// or -1 if num never appears
+function topIndex(s, num, delim){
+ for (i = 0; i < s.length; i++){
+ ix = indexOf(s[i], delim + num + delim);
+ if (ix >= 0) {return i;}
+ }
+ return -1;
+}
+
+
+// computes the shortest distance from p0 to p1 where p0 and p1 are perimeter vectors
+// x0 and y0 must the the same length, and x1, y1 must be the same length
+// but x1 and x2 can be different lengths
+function shortestDistance(x0,y0, x1, y1){
+ d = 1000000; // some very large number to start with
+ for (i = 0; i < x0.length; i++){
+ //print("[",x0[i],y0[i],"]");
+ for (j= 0; j < x1.length; j++){
+ dx = x0[i]-x1[j];
+ dy = y0[i]-y1[j];
+ //print(" [",x1[j],y1[j],"] => [", dx, dy, "]");
+ d2 = dx*dx + dy*dy;
+ if (d2 < d) {d = d2;}
+ }//j-loop through
+ }
+ return sqrt(d);
+}
Added: pkg/zooimage/inst/imagej/plugins/_fitvis.jar
===================================================================
(Binary files differ)
Property changes on: pkg/zooimage/inst/imagej/plugins/_fitvis.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: pkg/zooimage/inst/imagej/plugins/_zooimage.jar
===================================================================
(Binary files differ)
Added: pkg/zooimage/inst/imagej/plugins/fitvis_.cfg
===================================================================
--- pkg/zooimage/inst/imagej/plugins/fitvis_.cfg (rev 0)
+++ pkg/zooimage/inst/imagej/plugins/fitvis_.cfg 2009-06-10 11:12:00 UTC (rev 172)
@@ -0,0 +1,20 @@
+version=FITVIS_
+interval=30
+pixelSize=1.6386
+minSize=25
+maxSize=2000
+distance=45
+usePixels=Dark
+thresholdDark=15
+thresholdLight=25
+fill=false
+largest=false
+vignettes=true
+scalebar=true
+enhance=false
+outline=true
+masks=true
+log=false
+verbose=true
+batch=true
+archive=false
\ No newline at end of file
Property changes on: pkg/zooimage/inst/imagej/plugins/fitvis_.cfg
___________________________________________________________________
Name: svn:executable
+ *
More information about the Zooimage-commits
mailing list