[Zooimage-commits] r170 - in pkg/zooimage/src: . data_fitvis data_fitvis/S04.2008-03-10.300F4X3 src_fitvis src_fitvis/org src_fitvis/org/sciviews src_fitvis/org/sciviews/zooimage src_fitvis/org/sciviews/zooimage/fitvis

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Wed Jun 10 13:10:03 CEST 2009


Author: romain
Date: 2009-06-10 13:10:03 +0200 (Wed, 10 Jun 2009)
New Revision: 170

Added:
   pkg/zooimage/src/data_fitvis/
   pkg/zooimage/src/data_fitvis/FITVIS.macro
   pkg/zooimage/src/data_fitvis/FITVIS_batch.ijm
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3.ctx
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3.lst
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3.zim
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000001.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000002.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000003.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000004.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000005.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000006.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000007.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000008.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000009.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000010.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000011.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000012.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000013.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000014.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000015.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000016.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000017.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_000018.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3_notes.txt
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/cal_image_000001.tif
   pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/data_export.csv
   pkg/zooimage/src/data_fitvis/batchExampleParameters.csv
   pkg/zooimage/src/data_fitvis/fitvis_.cfg
   pkg/zooimage/src/src_fitvis/
   pkg/zooimage/src/src_fitvis/org/
   pkg/zooimage/src/src_fitvis/org/sciviews/
   pkg/zooimage/src/src_fitvis/org/sciviews/zooimage/
   pkg/zooimage/src/src_fitvis/org/sciviews/zooimage/fitvis/
   pkg/zooimage/src/src_fitvis/org/sciviews/zooimage/fitvis/FITVIS_.java
   pkg/zooimage/src/src_fitvis/org/sciviews/zooimage/fitvis/FitVisMain.java
   pkg/zooimage/src/src_fitvis/org/sciviews/zooimage/fitvis/ZPIStackPlus.java
   pkg/zooimage/src/src_fitvis/org/sciviews/zooimage/fitvis/ZPIVirtualStack.java
   pkg/zooimage/src/src_fitvis/org/sciviews/zooimage/fitvis/ZPIVirtualStackPlus.java
   pkg/zooimage/src/src_fitvis/org/sciviews/zooimage/fitvis/ZPIconfig.java
   pkg/zooimage/src/src_fitvis/org/sciviews/zooimage/fitvis/ZPItools.java
   pkg/zooimage/src/src_fitvis/org/sciviews/zooimage/fitvis/ZPIvData.java
Log:
added first version of fit vis 

Added: pkg/zooimage/src/data_fitvis/FITVIS.macro
===================================================================
--- pkg/zooimage/src/data_fitvis/FITVIS.macro	                        (rev 0)
+++ pkg/zooimage/src/data_fitvis/FITVIS.macro	2009-06-10 11:10:03 UTC (rev 170)
@@ -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("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("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);
+}


Property changes on: pkg/zooimage/src/data_fitvis/FITVIS.macro
___________________________________________________________________
Name: svn:executable
   + *

Added: pkg/zooimage/src/data_fitvis/FITVIS_batch.ijm
===================================================================
--- pkg/zooimage/src/data_fitvis/FITVIS_batch.ijm	                        (rev 0)
+++ pkg/zooimage/src/data_fitvis/FITVIS_batch.ijm	2009-06-10 11:10:03 UTC (rev 170)
@@ -0,0 +1,98 @@
+// this macro can run this from the command line
+//
+// MacOSX  assumes current directory is /Applications/ImageJ
+//  java -jar -mx256m ImageJ.app/Contents/Resources/Java/ij.jar -macro plugins/FITVIS/FITVIS_batch.ijm /Users/Shared/data/FIT_VIS_kevin/test-3/test-largest/batchExampleParameters.csv
+//
+// WIndows XP
+// ??
+
+print("FITVIS_Batch.ijm");
+
+bfile = getArgument();
+//print("argument="+bfile);
+
+if (lengthOf(bfile) == 0){
+  bfile = File.openDialog("Select the batch parameters file");
+}
+data = File.openAsString(bfile);
+data = replace(data, "\"", "");
+
+dir = File.getParent(bfile) + File.separator();
+
+arg = split(data, "\n");
+n = arg.length-1;
+names = split(arg[0], ",");
+
+for (i = 0; i<n; i++){
+	closeImages();
+	a = split(arg[i+1], ",");
+	s = assembleParameters(dir, names, a);
+	//s = assembleParameters(arg[0], arg[i+1]);
+	run("FITVIS ", s);
+}
+
+
+function assembleParameters(dir, names, s){
+	//select,interval,pixelsize,minsize,maxsize,use,thresholddark,thresholdlight,
+	//fill,largest,vignettes,scalebar,enhance,outline,masks,verbose
+	r = "";
+	//names = split(inNames,",");
+	//s = split(inS, ",");
+	for (i=0;i<names.length;i++){
+		if (names[i]=="select"){
+			if (lengthOf(s[i]) != 0){r= r + "select="+dir+s[i];}
+		} else if (names[i]=="interval"){
+      r = r + " interval=" + s[i];
+		} else if (names[i]=="pixelsize"){
+		  r = r + " pixelsize="+s[i];
+		} else if (names[i] == "minsize"){
+		  r = r + " minsize="+s[i];
+		} else if (names[i]=="maxsize"){
+		  r = r + " maxsize="+s[i];
+	  } else if (names[i]=="distance"){
+		  r = r + " distance="+s[i];
+		} else if (names[i]=="use"){
+		  r = r + " use="+s[i];
+		} else if (names[i]=="thresholddark"){
+		  r = r + " thresholddark="+s[i];
+		} else if (names[i] == "thresholdlight"){
+		  r = r + " thresholdlight=" + s[i];
+		} else if (names[i]=="fill"){
+		  if (s[i] == "TRUE") { r = r + " fill";}
+		} else if (names[i]=="largest"){
+		  if (s[i]=="TRUE") {r = r + " largest";}
+		} else if (names[i] == "vignettes"){
+		  if (s[i]=="TRUE") {r = r+ " vignettes";}
+		} else if (names[i] == "scalebar"){
+		  if (s[i]=="TRUE") {r = r + " scalebar";}
+		} else if (names[i] == "enhance"){
+		  if (s[i]=="TRUE") {r = r + " enhance";}
+		} else if (names[i] == "outline"){
+		  if (s[i]=="TRUE") {r = r + " outline";}
+		} else if (names[i] == "masks"){
+		  if (s[i]=="TRUE") {r = r + " masks";}
+		} else if (names[i] == "verbose"){
+		  if (s[i]=="TRUE") {r = r + " verbose";}
+		} else if (names[i] == "log") {
+		  if (s[i]=="TRUE") {r = r + "log";}
+		} else if (names[i] == "batch"){
+		  if (s[i]=="TRUE") {r = r + " batch";}  
+		} else {
+		  print("Parameter not recognized: " + names[i]);
+		}
+	}//i-loop
+
+  //if (indexOf(r, " ") == 0) {r = substring(r, 1);}
+    
+	return r;
+}
+
+//closes all of the image windows
+function closeImages(){
+  while (nImages()>0) {
+    selectImage(nImages());  
+    run("Close");
+  }
+  return;
+}
+


Property changes on: pkg/zooimage/src/data_fitvis/FITVIS_batch.ijm
___________________________________________________________________
Name: svn:executable
   + *

Added: pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3.ctx
===================================================================
--- pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3.ctx	                        (rev 0)
+++ pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3.ctx	2009-06-10 11:10:03 UTC (rev 170)
@@ -0,0 +1,98 @@
+[Software]
+SoftwareName=VisualSpreadsheet
+SoftwareVersion=1.5.14
+SoftwareBetaFlag=0
+[General]
+TechnicianName= 
+LocationName= 
+LocationLatitude= 
+LocationLongitude= 
+RunStartTime=2008-03-11 16:00:11
+RunEndTime=2008-03-11 16:11:21
+TimeZone= 
+[Camera]
+Gain=565
+WhiteBalanceU=1999
+WhiteBalanceV=1940
+Shutter=129
+Brightness=256
+Gamma=129
+Hue=128
+Saturation=0
+Sharpness=0
+AutoTriggerFlag=0
+[Fluorescence]
+Ch1Use=1
+Ch1Gain=820
+Ch1Threshold=4
+Ch2Use=1
+Ch2Gain=820
+Ch2Threshold=4
+Ch2IsScatter=0
+Ch3Use=0
+Ch3Gain=4
+Ch3Threshold=100
+Ch3IsScatter=0
+Ch4Use=0
+Ch4Gain=4
+Ch4Threshold=100
+[Fluid]
+FlowCellDepth=300.0000
+FlowCellWidth=3000.0000
+UseManualVolume=0
+TotalVolumeML=0.0000
+CalibrationConstant=1.7076
+[CaptureRegion]
+AcceptableLeft=1
+AcceptableRight=1022
+AcceptableTop=1
+AcceptableBottom=766
+ImagePixelBorder=30
+[CaptureParameters]
+DistanceToNeighbor=30
+Threshold=25.0000
+CloseHoles=0
+CaptureDarkOrLightPixels=0
+MinESD=25.0000
+MaxESD=2000.0000
+UseESDForCapture=1
+[RunTermination]
+MaxParticles=10000
+StopOnMaxParticles=0
+MaxRunTimeMinutes=120
+StopOnMaxRunTime=0
+MaxImageFiles=1000
+[Files]
+SaveIntervalMinutes=120
+SaveRawFilesFlag=0
+WriteLatestTifFlag=0
+[CaptureStats]
+RawImageTotal=2698
+CollageImageTotal=18
+DisplayImageTotal=2317
+ImageCaptureTotal_Seconds=575.776
+ImageCaptureAvg_Milliseconds=213.41
+ImageCalibrationTotal_Seconds=7.821
+ImageCalibrationAvg_Milliseconds=2.90
+ImageProcessingTotal_Seconds=52.823
+ImageProcessingAvg_Milliseconds=19.58
+ImageMaskingTotal_Seconds=16.259
+ImageMaskingAvg_Milliseconds=6.03
+ImageBinarizingTotal_Seconds=16.219
+ImageBinarizingAvg_Milliseconds=6.01
+ImageCloseHolesTotal_Seconds=0.000
+ImageCloseHolesAvg_Milliseconds=0.00
+ImageBlobCalculateTotal_Seconds=8.728
+ImageBlobCalculateAvg_Milliseconds=3.23
+ImageBlobFilterTotal_Seconds=0.053
+ImageBlobFilterAvg_Milliseconds=0.02
+ImageBlobExtractTotal_Seconds=0.861
+ImageBlobExtractAvg_Milliseconds=0.32
+ImageBlobGroupTotal_Seconds=0.015
+ImageBlobGroupAvg_Milliseconds=0.01
+ImageBlobColorTotal_Seconds=0.000
+ImageBlobColorAvg_Milliseconds=0.00
+ImageListSaveTotal_Seconds=0.049
+ImageListSaveAvg_Milliseconds=0.02
+ImageCollageSaveTotal_Seconds=10.639
+ImageCollageSaveAvg_Milliseconds=3.94


Property changes on: pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3.ctx
___________________________________________________________________
Name: svn:executable
   + *

Added: pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3.lst
===================================================================
--- pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3.lst	                        (rev 0)
+++ pkg/zooimage/src/data_fitvis/S04.2008-03-10.300F4X3/S04.2008-03-10.300F4X3.lst	2009-06-10 11:10:03 UTC (rev 170)
@@ -0,0 +1,1416 @@
+013
+1414           
[TRUNCATED]

To get the complete diff run:
    svnlook diff /svnroot/zooimage -r 170


More information about the Zooimage-commits mailing list