Commit in CDMS/src/CDMS/Partridge on MAIN
Cluster/Cluster.java+7-71.2 -> 1.3
       /VanillaNNClustering.java+1-11.2 -> 1.3
FeatureFinder/FeatureFinderTest.java+1-11.2 -> 1.3
FieldFlattening/FieldFlattenerTest.java+15-31.2 -> 1.3
ImageAlignment/AlignImages.java+47-201.1 -> 1.2
              /AlignImagesTest.java+29-301.2 -> 1.3
              /ImageMatch.java+6-31.1 -> 1.2
ImageComparison/CompareImages.java+41-731.4 -> 1.5
               /CompareImagesTest.java+36-81.1 -> 1.2
ImageUtils/GeImage.java+1-11.1 -> 1.2
          /InterpolatePixelIntensity.java+18-181.2 -> 1.3
          /TransformedPixelArray.java+25-191.2 -> 1.3
+227-184
12 modified files
Updated code

CDMS/src/CDMS/Partridge/Cluster
Cluster.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- Cluster.java	15 Oct 2010 21:34:46 -0000	1.2
+++ Cluster.java	12 Nov 2010 21:26:54 -0000	1.3
@@ -18,7 +18,7 @@
  */
 public class Cluster {
 
-    private Map<Long, Integer> _pixmap;
+    private Map<Long, Double> _pixmap;
     private PixelArray _pixarray;
 
     /**
@@ -29,17 +29,17 @@
      */
     public Cluster(PixelArray pixarray) {
         _pixarray = pixarray;
-        _pixmap = new HashMap<Long, Integer>();
+        _pixmap = new HashMap<Long, Double>();
     }
 
     /**
      * Add a pixel to the cluster.
      *
      * @param pixel pixel to be added
-     * @param RGB pixel data (typically RGB color info)
+     * @param data pixel data value
      */
-    public void addPixel(Long pixel, int RGB) {
-        _pixmap.put(pixel, RGB);
+    public void addPixel(Long pixel, double data) {
+        _pixmap.put(pixel, data);
     }
 
     /**
@@ -56,7 +56,7 @@
      *
      * @return map of pixels to pixel data
      */
-    public Map<Long, Integer> getPixelMap() {
+    public Map<Long, Double> getPixelMap() {
         return _pixmap;
     }
 
@@ -82,7 +82,7 @@
         int npix = _pixmap.size();
 
         //  Loop over all pixels and calculate the average x,y coordinates
-        for (Entry<Long, Integer> entry : _pixmap.entrySet()) {
+        for (Entry<Long, Double> entry : _pixmap.entrySet()) {
             long pixel = entry.getKey();
             double x = _pixarray.getX(pixel);
             double y = _pixarray.getY(pixel);

CDMS/src/CDMS/Partridge/Cluster
VanillaNNClustering.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- VanillaNNClustering.java	11 Oct 2010 00:34:01 -0000	1.2
+++ VanillaNNClustering.java	12 Nov 2010 21:26:54 -0000	1.3
@@ -72,7 +72,7 @@
 
                 //  Pull the next pixel off the queue and add it to the cluster
                 long clustered_pixel = unchecked.removeFirst();
-                cluster.addPixel(clustered_pixel, pixmap.get(clustered_pixel));
+                cluster.addPixel(clustered_pixel, (double) pixmap.get(clustered_pixel));
 
                 //  Get the neigbor channels
                 Set<Long> neighbor_pixels = pixarray.getNeighbors(clustered_pixel);

CDMS/src/CDMS/Partridge/FeatureFinder
FeatureFinderTest.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- FeatureFinderTest.java	11 Oct 2010 00:34:01 -0000	1.2
+++ FeatureFinderTest.java	12 Nov 2010 21:26:54 -0000	1.3
@@ -32,7 +32,7 @@
 
         FeatureDef ge = new FeatureDef("Ge", 130, 170, 10);
         FeatureDef al = new FeatureDef("Al", 170, 255, 10);
-        FeatureDef dark = new FeatureDef("dark", 0, 120, 10);
+        FeatureDef dark = new FeatureDef("dark", 0, 130, 10);
 //        FeatureDef mid = new FeatureDef("mid", 164, 170, 10);
 //        FeatureDef light = new FeatureDef("light", 206, 255, 10);
         List<FeatureDef> fdeflist = new ArrayList<FeatureDef>();

CDMS/src/CDMS/Partridge/FieldFlattening
FieldFlattenerTest.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- FieldFlattenerTest.java	11 Oct 2010 00:25:43 -0000	1.2
+++ FieldFlattenerTest.java	12 Nov 2010 21:26:54 -0000	1.3
@@ -9,6 +9,7 @@
 import java.io.File;
 import java.io.IOException;
 import javax.imageio.ImageIO;
+import org.lcsim.util.aida.AIDA;
 
 /**
  *
@@ -21,32 +22,43 @@
         String blankindexfile = "c:/CDMS/IZipv4_side1_blanks.txt";
         FieldFlattener flat = new FieldFlattener(blankindexfile, 2.0);
         int ifile = 0;
+        AIDA aida = AIDA.defaultInstance();
         for (String fname : flat.getBlankFileNames()) {
             GeImage image = new GeImage(fname, 0., 0., 1., 1.);
             PixelArray pixarray = image.getPixelArray();
             GeImage flatimage = flat.FlattenImage(image);
             double isum = 0.;
             double i2sum = 0.;
+            double ifsum = 0.;
+            double i2fsum = 0.;
             int nrow = pixarray.getNRow();
             int ncol = pixarray.getNCol();
             for (int row=0; row<nrow; row++) {
                 for (int col=0; col<ncol; col++) {
-                    double intensity = flatimage.getIntensity(row, col);
+                    double fintensity = flatimage.getIntensity(row, col);
+                    ifsum += fintensity;
+                    i2fsum += fintensity*fintensity;
+                    double intensity = image.getIntensity(row, col);
                     isum += intensity;
                     i2sum += intensity*intensity;
+                    aida.histogram1D("Flattened intensity", 256, 0., 256.).fill(fintensity);
+                    aida.histogram1D("Original intensity", 256, 0., 256.).fill(intensity);
                 }
             }
             int npixel = nrow * ncol;
+            double fmean = ifsum / npixel;
+            double fsd = Math.sqrt(i2fsum/npixel - fmean*fmean);
+            System.out.println("Flattened file: "+fname+" mean: "+fmean+" sd: "+fsd);
             double mean = isum / npixel;
             double sd = Math.sqrt(i2sum/npixel - mean*mean);
-            System.out.println("Flattened file: "+fname+" mean: "+mean+" sd: "+sd);
+            System.out.println("Original file: "+fname+" mean: "+mean+" sd: "+sd);
             String otype = "png";
             File outfile = new File("c:/CDMS/flattened"+ifile+"."+otype);
             ifile++;
             ImageIO.write(flatimage.getBufferedImage(), otype, outfile);
 
         }
-
+        aida.saveAs("c:/CDMS/flattenhists.aida");
     }
 
 }

CDMS/src/CDMS/Partridge/ImageAlignment
AlignImages.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- AlignImages.java	11 Oct 2010 00:25:44 -0000	1.1
+++ AlignImages.java	12 Nov 2010 21:26:54 -0000	1.2
@@ -28,7 +28,7 @@
  */
 public class AlignImages {
 
-    private FeatureFinder _finder;
+    private List<FeatureDef> _fdefs;
     private int _border = 20;
     private int _minpix = 100;
 
@@ -40,22 +40,24 @@
      */
     public AlignImages(List<FeatureDef> fdefs) {
 
-        //  Instantiate the feature finder
-        _finder = new FeatureFinder(fdefs);
+        //  Save the list of alignment feature definitions
+        _fdefs = fdefs;
     }
 
     /**
      * Fit for the x,y offsets that best align a test image with a
      * reference image.  Offsets are to be applied to the test image.
-     *
+     * This method should be used if the relevant feature finding has already
+     * been performed.  Note that only features found with a FeatureDef
+     * matching one of those specified when AlignImages was instantiated
+     * will be used for alignment.
      * @param testimage test image
      * @param refimage reference image
+     * @param flist list of features that have been found
+     * @param rotate true if rotations are to be included in the alignment fit
      * @return fit results
      */
-    public AlignParameters doFit(GeImage testimage, GeImage refimage, boolean rotate) {
-
-        //  Find the specified features in the reference image
-        List<Feature> flist = _finder.FindFeatures(refimage);
+    public AlignParameters doFit(GeImage testimage, GeImage refimage, List<Feature> flist, boolean rotate) {
 
         //  Initialize the list of pixels to use in the fit
         List<Long> pixels = new ArrayList<Long>();
@@ -65,10 +67,13 @@
         int nrow = pixarray.getNRow();
         int ncol = pixarray.getNCol();
 
-        //  Loop over the features found
+        //  Loop over the features
         for (Feature feature : flist) {
 
-            //  Get the pixel cluster associated with this feature
+            //  Skip this feature if it isn't in our list of alignment features
+            if (!_fdefs.contains(feature.getFeatureDef())) continue;
+
+            //  Get the cluster for this feature
             Cluster cluster = feature.getCluster();
 
             //  Add pixels in the cluster to the list of pixels to use in the
@@ -93,25 +98,28 @@
         double maxoff;
         double maxang;
         if (rotate) {
-            maxoff = _border / 2.;
-            maxang = Math.asin(_border / Math.min(nrow, ncol));
+            maxoff = 0.5 * _border;
+            maxang = Math.asin(((double) _border) / Math.min(nrow, ncol));
         } else {
             maxoff = _border;
             maxang = 1.e-6;
         }
 
+        double dx = pixarray.getXSize();
+        double dy = pixarray.getYSize();
+
         //  Set the starting parameters, step size, and bounds on the starting parameters
         MnUserParameters pars = new MnUserParameters();
-        pars.add("xoff", 0., 0.5, -maxoff, maxoff);
-        pars.add("yoff", 0., 0.5, -maxoff, maxoff);
-        pars.add("angle", 0.0, 0.0, -maxang, maxang);
+        pars.add("xoff", 0., 0.5, -maxoff * dx, maxoff * dx);
+        pars.add("yoff", 0., 0.5, -maxoff * dy, maxoff * dy);
+        pars.add("angle", 0.0, 0.001, -maxang, maxang);
         pars.add("border", _border, 0.);
         if (!rotate) pars.fix(2);
         pars.fix(3);
 
         //  Instantiate the minimization class
         MnMinimize minimize = new MnMinimize(comp, pars);
-        
+
         //  Define the function change corresponding to "1 sigma".  Tis is not
         //  well defined for our problem since the interpolation function is
         //  a bit ad hoc with discontinuous derivatives.  This parameter also
@@ -130,23 +138,23 @@
             double yoff = finalpars.value(1);
             double rotang = finalpars.value(2);
             double chisq = fcnmin.fval();
-//          System.out.println("Pixels for fitting: "+pixels.size()+" xoff: "+xoff+" yoff: "+yoff);
             return new AlignParameters(xoff, yoff, rotang, chisq, npix, FitStatus.MinuitFit);
         }
 
         //  Minuit failed - do a simply search with integer pixel offsets
+        System.out.println("Minuit faile - doing step fit");
         double chibest = 1.e99;
         double xoff = 0.;
         double yoff = 0.;
-        for (int hoff=-_border; hoff<=_border; hoff++) {
-            for (int voff=-_border; voff<_border+1; voff++) {
+        int imaxoff = (int) Math.floor(maxoff);
+        for (int hoff=-imaxoff; hoff<=imaxoff; hoff++) {
+            for (int voff=-imaxoff; voff<=imaxoff; voff++) {
                 double[] args = {hoff, voff, 0., _border};
                 double chitest = comp.valueOf(args);
                 if (chitest < chibest) {
                     xoff = hoff;
                     yoff = voff;
                     chibest = chitest;
-//                  System.out.println("x: "+hoff+" y: "+voff+" chisq: "+chitest);
                 }
             }
         }
@@ -155,6 +163,25 @@
     }
 
     /**
+     * Fit for the x,y offsets that best align a test image with a
+     * reference image.  Offsets are to be applied to the test image.
+     *
+     * @param testimage test image
+     * @param refimage reference image
+     * @param rotate true if rotations are to be included in the alignment fit
+     * @return fit results
+     */
+    public AlignParameters doFit(GeImage testimage, GeImage refimage, boolean rotate) {
+
+        //  Find the specified features in the reference image
+        FeatureFinder finder = new FeatureFinder(_fdefs);
+        List<Feature> flist = finder.FindFeatures(refimage);
+        return doFit(testimage, refimage, flist, rotate);
+    }
+
+
+
+    /**
      * Get the size of the border region in units of pixels.
      *
      * @return number of border pixels

CDMS/src/CDMS/Partridge/ImageAlignment
AlignImagesTest.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- AlignImagesTest.java	15 Oct 2010 21:34:46 -0000	1.2
+++ AlignImagesTest.java	12 Nov 2010 21:26:54 -0000	1.3
@@ -5,12 +5,14 @@
 
 package CDMS.Partridge.ImageAlignment;
 
-import CDMS.Partridge.FieldFlattening.FieldFlattener;
 import CDMS.Partridge.ImageAlignment.AlignParameters.FitStatus;
 import CDMS.Partridge.FeatureFinder.FeatureDef;
 import CDMS.Partridge.ImageUtils.ParseAutorunFile;
 import CDMS.Partridge.ImageUtils.GeImage;
+import java.io.File;
+import java.io.FileWriter;
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 import org.lcsim.util.aida.AIDA;
@@ -28,59 +30,55 @@
         String refbase = "c:/CDMS/IZipG47_Side1_PKG/IZipG47_Side1_PKG-";
         String testbase = "c:/CDMS/IZipG16K_Side1/IZipG16K_Side1-";
 
-        FieldFlattener flat = new FieldFlattener(blankindexfile, 2.0);
-
         AIDA aida = AIDA.defaultInstance();
 
+        PrintWriter pw = new PrintWriter(new FileWriter("c:/CDMS/alignment_offsets.txt", false));
+
         ParseAutorunFile parser = new ParseAutorunFile(autorunfile);
         List<Double[]> coordinatelist = parser.getImageCoordinates();
-        int ifirst = 1000;
-        int ilast = 1200;
-//        int ifirst = 1;
-//        int ilast = 8585;
+        int ifirst = 1;
+        int ilast = 8585;
         double rmax = 35.;
 
         int nrow = 480;
         int ncol = 640;
-        double dx = 0.0001396;
+        double dx = 0.001396;
         double dy = dx;
 
-        for (String refname : flat.getBlankFileNames()) {
-//        for (int i = ifirst ; i <= ilast; i++) {
+        for (int i = ifirst ; i <= ilast; i++) {
 
-//            if (i % 100 == 0) System.out.println("Processing image "+i);
+            if (i % 100 == 0) System.out.println("Processing image "+i);
             
-//            Double[] pos = coordinatelist.get(i-1);
-//            double xc = pos[0];
-//            double yc = pos[1];
-//            System.out.println("Image: "+i+" xc: "+xc+" yc: "+yc);
-//            double r = Math.sqrt(xc*xc + yc*yc);
-//            if (r > rmax) continue;
-
-            double xc = 0.;
-            double yc = 0.;
-            String testname = refname.replaceAll("G47_Side1_PKG", "G16K_Side1");
-//            String refname = refbase+i+".png";
-//            String testname = testbase + i +".png";
+            Double[] pos = coordinatelist.get(i-1);
+            double xc = pos[0];
+            double yc = pos[1];
+            double r = Math.sqrt(xc*xc + yc*yc);
+            if (r > rmax) {
+                pw.println(i+" NoFit-OutsideFiducialArea 0 0");
+                continue;
+            }
+
+            String refname = refbase+i+".png";
+            String testname = testbase + i +".png";
             GeImage refimage = new GeImage(refname, xc, yc, dx, dy);
             GeImage testimage = new GeImage(testname, xc, yc, dx, dy);
 
             List<FeatureDef> fdefs = new ArrayList<FeatureDef>();
             FeatureDef fdblack = new FeatureDef("Black", 0, 130, 10);
-            FeatureDef fdall = new FeatureDef("All", 0, 256, 1);
-//            fdefs.add(fdblack);
-            fdefs.add(fdall);
+            fdefs.add(fdblack);
 
             AlignImages align = new AlignImages(fdefs);
             align.setBorder(10);
             align.setMinPixels(100);
             AlignParameters pars = align.doFit(testimage, refimage, false);
             String minstat = "Undefined";
-            if (pars.getFitStatus() == FitStatus.NoFit) minstat = "No Fit";
-            if (pars.getFitStatus() == FitStatus.MinuitFit) minstat = "Minuit Fit";
-            if (pars.getFitStatus() == FitStatus.StepFit) minstat = "Step Fit";
+            if (pars.getFitStatus() == FitStatus.NoFit) minstat = "NoFit-TooFewEdgePixels";
+            if (pars.getFitStatus() == FitStatus.MinuitFit) minstat = "MinuitFit";
+            if (pars.getFitStatus() == FitStatus.StepFit) minstat = "StepFit";
+
+            pw.println(i+" "+minstat+" "+pars.getXOffset()+" "+pars.getYOffset());
 
-            System.out.println("xoffset: "+pars.getXOffset()+" yoffset: "+pars.getYOffset());
+//            System.out.println("xoffset: "+pars.getXOffset()+" yoffset: "+pars.getYOffset());
             
             aida.cloud1D("Vertical offset - "+minstat).fill(pars.getYOffset());
             aida.cloud1D("Horizontal offset - "+minstat).fill(pars.getXOffset());
@@ -90,5 +88,6 @@
         }
 
         aida.saveAs("c:/CDMS/newnudge_allpixels.aida");
+        pw.close();
     }
 }

CDMS/src/CDMS/Partridge/ImageAlignment
ImageMatch.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- ImageMatch.java	11 Oct 2010 00:25:44 -0000	1.1
+++ ImageMatch.java	12 Nov 2010 21:26:54 -0000	1.2
@@ -63,10 +63,12 @@
         PixelArray pixarray = _ref.getPixelArray();
         double xc = pixarray.getXC();
         double yc = pixarray.getYC();
+        double dx = pixarray.getXSize();
+        double dy = pixarray.getYSize();
         int ncol = pixarray.getNCol();
         int nrow = pixarray.getNRow();
-        TransformedPixelArray refpix = new TransformedPixelArray(xc, yc, 0., 1, nrow, ncol);
-        TransformedPixelArray testpix = new TransformedPixelArray(xc + xoff, yc + yoff, rotang, 1, nrow, ncol);
+        TransformedPixelArray refpix = new TransformedPixelArray(xc, yc, 0., dx, dy, nrow, ncol);
+        TransformedPixelArray testpix = new TransformedPixelArray(xc + xoff, yc + yoff, rotang, dx, dy, nrow, ncol);
 
         //  Setup the pixel interpolation
         InterpolatePixelIntensity interpolate = new InterpolatePixelIntensity(_ref, refpix, testpix);
@@ -77,13 +79,14 @@
         //  image.  A pseudo chi square is formed that will be minimized by
         //  the alignment fit.
         double chisq = 0.;
+//        System.out.println("xoff: " + xoff + " yoff: " + yoff + " rotang: " + rotang);
         for (Long pixel : _pixels) {
 
             //  Find the interpolated reference intensity for this test pixel
             double ipred = interpolate.Interpolate(pixel);
 
             //  Compare with the intensity of the test pixel
-            double itest = _test.getIntensity(_test.getRGB(pixel));
+            double itest = _test.getIntensity(pixel);
             chisq += (itest - ipred) * (itest - ipred);
  
         }

CDMS/src/CDMS/Partridge/ImageComparison
CompareImages.java 1.4 -> 1.5
diff -u -r1.4 -r1.5
--- CompareImages.java	15 Oct 2010 21:34:46 -0000	1.4
+++ CompareImages.java	12 Nov 2010 21:26:55 -0000	1.5
@@ -7,12 +7,13 @@
 import CDMS.Partridge.Cluster.SeededNNClustering;
 import CDMS.Partridge.Cluster.Cluster;
 import CDMS.Partridge.ImageUtils.GeImage;
+import CDMS.Partridge.ImageUtils.InterpolatePixelIntensity;
 import CDMS.Partridge.ImageUtils.PixelArray;
+import CDMS.Partridge.ImageUtils.TransformedPixelArray;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 
 /**
  * Compare two sets of images by finding significant deviations in the image and
@@ -41,101 +42,68 @@
     }
 
     /**
-     * Finds clusters of significant intensity deviations between two sets
-     * of images.  The user provides a map relating pairs of images.  The image
-     * serving as the key is the image being examined, while the image serving
-     * as the value is the image for the reference image.
+     * Finds clusters of significant intensity deviations between two images.
      *
      * @param imagemap map giving set of image pairs to be compared
      * @return list of clusters found
      */
-    public List<Cluster> FindClusters(Map<GeImage, GeImage> imagemap) {
+    public List<Cluster> FindClusters(GeImage test, GeImage ref, double xoff, double yoff, double rotang) {
 
         //  Create the list of clusters
         List<Cluster> clusterlist = new ArrayList<Cluster>();
 
-        //  If no images to check, we are done
-        if (imagemap.size() == 0) return clusterlist;
+        //  Check that the pixel arrays for the reference and test images are identical
+        PixelArray testarray = test.getPixelArray();
+        PixelArray refarray = ref.getPixelArray();
+        if (!testarray.equals(refarray))
+            throw new RuntimeException("Test and Reference pixel arrays are not consistent");
+
+         //  Setup pixel arrays for the reference image and the test image
+        PixelArray pixarray = ref.getPixelArray();
+        double xc = pixarray.getXC();
+        double yc = pixarray.getYC();
+        double dx = pixarray.getXSize();
+        double dy = pixarray.getYSize();
+        int ncol = pixarray.getNCol();
+        int nrow = pixarray.getNRow();
 
-        //  Initialize the image bounds and minimum pixel size
-        double xmin = 9999.;
-        double xmax = -9999.;
-        double ymin = 99999.;
-        double ymax = -9999.;
-        double dxmin = 9999.;
-        double dymin = 9999.;
-
-        //  Loop over all pairs of test and reference image descriptors
-        for (Entry<GeImage, GeImage> entry : imagemap.entrySet()) {
-     
-            //  Check that the pixel arrays for the reference and test images are identical
-            PixelArray testpix = entry.getKey().getPixelArray();
-            PixelArray refpix = entry.getValue().getPixelArray();
-            if (!testpix.equals(refpix))
-                throw new RuntimeException("Test and Reference pixel arrays are not consistent");
-
-            //  Accumulate bounds on the images and the smallest pixel size
-            xmin = Math.min(xmin, refpix.getXMin());
-            xmax = Math.max(xmax, refpix.getXMax());
-            ymin = Math.min(ymin, refpix.getYMin());
-            ymax = Math.max(ymax, refpix.getYMax());
-            dxmin = Math.min(dxmin, refpix.getXSize());
-            dymin = Math.min(dymin, refpix.getYSize());
-        }
+        TransformedPixelArray refpix = new TransformedPixelArray(xc, yc, 0., dx, dy, nrow, ncol);
+        TransformedPixelArray testpix = new TransformedPixelArray(xc + xoff, yc + yoff, rotang, dx, dy, nrow, ncol);
 
-        //  Create a mother pixelarray to cover the extent given of the images
-        int ncol = (int) Math.floor(2. * Math.max(xmax, -xmin) / dxmin + 0.5);
-        int nrow = (int) Math.floor(2. * Math.max(ymax, -ymin) / dymin + 0.5);
-        PixelArray mother = new PixelArray(nrow, ncol, 0., 0., dxmin, dymin);
-
-        //  Add subarrays to the mother array for each image
-        int id = 1;
-        for (GeImage image : imagemap.keySet()) {
-
-            //  Get the pixel array for this image
-            PixelArray pixarray = image.getPixelArray();
-            
-            //  Create a subarray in the mother array for this image
-            mother.addSubArray(id, pixarray);
-            id++;
-        }
+        //  Setup the pixel interpolation
+        InterpolatePixelIntensity interpolate = new InterpolatePixelIntensity(ref, refpix, testpix);
 
-        //  Create a map relating mother pixels to deviations above the neighbor cut
+        //  Create a map relating pixels to deviations above the neighbor cut
         Map<Long, Double> devmap = new HashMap<Long, Double>();
 
-        //  Loop over images and find significant deviations
-        for (Entry<GeImage, GeImage> entry : imagemap.entrySet()) {
-            GeImage testimage = entry.getKey();
-            GeImage refimage = entry.getValue();
-            PixelArray pixarray = testimage.getPixelArray();
-            for (int row=20; row<pixarray.getNRow()-20; row++) {
-                for (int col=20; col<pixarray.getNCol()-20; col++) {
-//                    int refrgb = refimage.getRGB(row, col);
-//                    int testrgb = testimage.getRGB(row, col);
-//                    int dblue = refimage.getBlue(refrgb) - testimage.getBlue(testrgb);
-//                    int dgreen = refimage.getGreen(refrgb) - testimage.getGreen(testrgb);
-//                    int dred = refimage.getRed(refrgb) - testimage.getGreen(testrgb);
-//                    double deviation = Math.sqrt((dblue*dblue + dgreen*dgreen + dred*dred) / 3.);
-                    double deviation = refimage.getIntensity(row+2, col+1) - testimage.getIntensity(row, col);
-                    if (Math.abs(deviation) > _neighbor_threshold) {
-                        long pixel = pixarray.getPixel(row, col);
-                        double x = pixarray.getX(pixel);
-                        double y = pixarray.getY(pixel);
-                        long mpixel = mother.getPixel(x, y);
-                        devmap.put(pixel, deviation);
-                    }
+        //  Loop over the images and find significant deviations
+         for (int row=20; row<nrow-20; row++) {
+            for (int col=20; col<ncol-20; col++) {
+
+                //  Find the pixel associated with this row, col
+                long pixel = pixarray.getPixel(row, col);
+
+                //  Find the interpolated reference intensity for this test pixel
+                double ipred = interpolate.Interpolate(pixel);
+
+                //  Find the intensity of the test pixel
+                double itest = test.getIntensity(pixel);
+
+                double deviation = ipred - itest;
+                if (Math.abs(deviation) > _neighbor_threshold) {
+                    devmap.put(pixel, deviation);
                 }
             }
         }
 
+
         //  Cluster the deviations
         SeededNNClustering clusterer = new SeededNNClustering();
         clusterer.setNeighborThreshold(_neighbor_threshold);
         clusterer.setSeedThreshold(_seed_threshold);
-        List<Cluster> clusters = clusterer.findClusters(mother, devmap);
+        List<Cluster> clusters = clusterer.findClusters(pixarray, devmap);
 
         return clusters;
-        return null;
     }
 
     /**

CDMS/src/CDMS/Partridge/ImageComparison
CompareImagesTest.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- CompareImagesTest.java	11 Oct 2010 00:25:43 -0000	1.1
+++ CompareImagesTest.java	12 Nov 2010 21:26:55 -0000	1.2
@@ -5,11 +5,17 @@
 package CDMS.Partridge.ImageComparison;
 
 import CDMS.Partridge.Cluster.Cluster;
+import CDMS.Partridge.FeatureFinder.FeatureDef;
+import CDMS.Partridge.FieldFlattening.FieldFlattener;
+import CDMS.Partridge.ImageAlignment.AlignImages;
+import CDMS.Partridge.ImageAlignment.AlignParameters;
+import CDMS.Partridge.ImageAlignment.AlignParameters.FitStatus;
 import CDMS.Partridge.ImageUtils.GeImage;
 import CDMS.Partridge.ImageUtils.PixelArray;
 import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -26,23 +32,45 @@
 
     public static void main(String[] args) throws IOException {
 
-        String fname1 = "c:/CDMS/IZipG47_Side1_PKG/IZipG47_Side1_PKG-4293.png";
-        String fname2 = "c:/CDMS/IZipG16K_Side1/IZipG16K_Side1-4293.png";
+        String blankindexfile = "c:/CDMS/IZipv4_side1_blanks.txt";
+        String fname1 = "c:/CDMS/IZipG47_Side1_PKG/IZipG47_Side1_PKG-4300.png";
+        String fname2 = "c:/CDMS/IZipG16K_Side1/IZipG16K_Side1-4300.png";
+
+        FieldFlattener flat = new FieldFlattener(blankindexfile, 2.0);
+
         double xc = 0.;
         double yc = 0.;
-        double dx = 0.0014;
-        double dy = 0.0014;
-        GeImage image1 = new GeImage(fname1, xc, yc, dx, dy);
-        GeImage image2 = new GeImage(fname2, xc, yc, dx, dy);
+        double dx = 0.001396;
+        double dy = dx;
+        GeImage image1 = flat.FlattenImage(new GeImage(fname1, xc, yc, dx, dy));
+        GeImage image2 = flat.FlattenImage(new GeImage(fname2, xc, yc, dx, dy));
 
         Map<GeImage, GeImage> imagemap = new HashMap<GeImage, GeImage>();
         imagemap.put(image1, image2);
 
-        int seed_threshold = 20;
+        List<FeatureDef> fdefs = new ArrayList<FeatureDef>();
+        FeatureDef fdblack = new FeatureDef("Black", 0, 130, 10);
+        fdefs.add(fdblack);
+
+        AlignImages align = new AlignImages(fdefs);
+        align.setBorder(10);
+        align.setMinPixels(100);
+        AlignParameters pars = align.doFit(image1, image2, false);
+        String minstat = "Undefined";
+        if (pars.getFitStatus() == FitStatus.NoFit) minstat = "No Fit";
+        if (pars.getFitStatus() == FitStatus.MinuitFit) minstat = "Minuit Fit";
+        if (pars.getFitStatus() == FitStatus.StepFit) minstat = "Step Fit";
+
+        double xoff = pars.getXOffset();
+        double yoff = pars.getYOffset();
+        double rotang = pars.getRotation();
+        System.out.println("xoffset: "+xoff+" yoffset: "+yoff+" rotation: "+rotang);
+
+        int seed_threshold = 25;
         int nbr_threshold = 10;
         CompareImages compare = new CompareImages((double) seed_threshold, (double) nbr_threshold);
 
-        List<Cluster> clusters = compare.FindClusters(imagemap);
+        List<Cluster> clusters = compare.FindClusters(image1, image2, xoff, yoff, rotang);
 
         BufferedImage buf = new BufferedImage(640, 480, BufferedImage.TYPE_3BYTE_BGR);
 

CDMS/src/CDMS/Partridge/ImageUtils
GeImage.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- GeImage.java	11 Oct 2010 00:25:43 -0000	1.1
+++ GeImage.java	12 Nov 2010 21:26:55 -0000	1.2
@@ -236,7 +236,7 @@
      * @param RGB packed color data
      */
     public void setRGB(int row, int col, int RGB) {
-        _image.setRGB(RGB, col, row);
+        _image.setRGB(col, row, RGB);
     }
 
     /**

CDMS/src/CDMS/Partridge/ImageUtils
InterpolatePixelIntensity.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- InterpolatePixelIntensity.java	11 Oct 2010 00:25:43 -0000	1.2
+++ InterpolatePixelIntensity.java	12 Nov 2010 21:26:55 -0000	1.3
@@ -29,25 +29,24 @@
         _testpix = testpix;
         _rotated = refpix.isRotated() || testpix.isRotated();
         if (!_rotated) {
-            double dx = (testpix.getXC() - refpix.getXC()) / testpix.getSize();
-            double dy = (testpix.getYC() - refpix.getYC()) / testpix.getSize();
-            int dcol = (int) Math.round(dx);
-            int drow = (int) Math.round(dy);
-//            System.out.println("dx: " + dx + " dy: " + dy + " dcol: " + dcol + " drow: " + drow);
-            dx -= dcol;
-            dy -= drow;
-            if (dx < 0.) {
-                _wcol[0] = -dx;
+            double delx = (testpix.getXC() - refpix.getXC()) / testpix.getXSize();
+            double dely = (testpix.getYC() - refpix.getYC()) / testpix.getYSize();
+            int dcol = (int) Math.round(delx);
+            int drow = (int) Math.round(dely);
+            delx -= dcol;
+            dely -= drow;
+            if (delx < 0.) {
+                _wcol[0] = -delx;
             }
-            if (dx > 0.) {
-                _wcol[2] = dx;
+            if (delx > 0.) {
+                _wcol[2] = delx;
             }
             _wcol[1] = 1. - _wcol[0] - _wcol[2];
-            if (dy < 0.) {
-                _wrow[0] = -dy;
+            if (dely < 0.) {
+                _wrow[0] = -dely;
             }
-            if (dy > 0.) {
-                _wrow[2] = dy;
+            if (dely > 0.) {
+                _wrow[2] = dely;
             }
             _wrow[1] = 1. - _wrow[0] - _wrow[2];
 //            System.out.println("wrow: " + _wrow[0] + " , " + _wrow[1] + " , " + _wrow[2]);
@@ -157,9 +156,10 @@
             intensity += area * _ref.getIntensity(refrow, refcol);
         }
 
-        //  Check to make sure the total pixel area is unity
-        if (Math.abs(totarea - 1.) > Math.sqrt(_eps)) {
-            System.out.println(" ***** Grand total area: " + totarea + " *****");
+        //  Check to make sure the total pixel area is OK
+        double pixarea = _refpix.getXSize() * _refpix.getYSize();
+        if (Math.abs(totarea - pixarea) > Math.sqrt(_eps) * pixarea) {
+            System.out.println(" ***** Grand total area: " + totarea + " expected: "+pixarea+" *****");
             throw new RuntimeException("area sum error");
         }
 

CDMS/src/CDMS/Partridge/ImageUtils
TransformedPixelArray.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- TransformedPixelArray.java	11 Oct 2010 00:25:43 -0000	1.2
+++ TransformedPixelArray.java	12 Nov 2010 21:26:55 -0000	1.3
@@ -16,7 +16,8 @@
     private double _x0;
     private double _y0;
     private double _rotang;
-    private double _size;
+    private double _dx;
+    private double _dy;
     private int _nrow;
     private int _ncol;
     private double _xc;
@@ -27,13 +28,14 @@
     private double[] _yv = new double[4];
     private double _eps = 1.e-6;
 
-    public TransformedPixelArray(double x0, double y0, double rotang, double size, int nrow, int ncol) {
+    public TransformedPixelArray(double x0, double y0, double rotang, double dx, double dy, int nrow, int ncol) {
 
         //  Save the parameters that define the pixel array
         _x0 = x0;
         _y0 = y0;
         _rotang = rotang;
-        _size = size;
+        _dx = dx;
+        _dy = dy;
         _nrow = nrow;
         _ncol = ncol;
 
@@ -47,19 +49,19 @@
 
         //  Find the coordinates of the LL pixel given offsets x0, y0 specified for
         //  the center pixel
-        double xll = _x0 + 0.5 * _size * (_ncol * (1 - _u[0]) - _nrow * _v[0]);
-        double yll = _y0 + 0.5 * _size * (_nrow * (1 - _v[1]) - _ncol * _u[1]);
+        double xll = _x0 + 0.5 * _dx * (_ncol * (1 - _u[0]) - _nrow * _v[0]);
+        double yll = _y0 + 0.5 * _dy * (_nrow * (1 - _v[1]) - _ncol * _u[1]);
 
         //  Find the vertices of pixel 0 whose LL corner is at the origin
         //  Vertices are stored in a clockwise direction
         _xv[0] = xll;
         _yv[0] = yll;
-        _xv[1] = xll + _size * _v[0];
-        _yv[1] = yll + _size * _v[1];
-        _xv[2] = xll + _size * (_u[0] + _v[0]);
-        _yv[2] = yll + _size * (_u[1] + _v[1]);
-        _xv[3] = xll + _size * _u[0];
-        _yv[3] = yll + _size * _u[1];
+        _xv[1] = xll + _dy * _v[0];
+        _yv[1] = yll + _dy * _v[1];
+        _xv[2] = xll + _dx * _u[0] + _dy * _v[0];
+        _yv[2] = yll + _dx * _u[1] + _dy * _v[1];
+        _xv[3] = xll + _dx * _u[0];
+        _yv[3] = yll + _dx * _u[1];
 
         //  Find the center
         _xc = (_xv[0] + _xv[2]) / 2.;
@@ -70,8 +72,8 @@
         int row = getRow(pixel);
         int col = getCol(pixel);
         double[] center = new double[2];
-        center[0] = _xc + _size * (col * _u[0] + row * _v[0]);
-        center[1] = _yc + _size * (col * _u[1] + row * _v[1]);
+        center[0] = _xc + _dx * col * _u[0] + _dy * row * _v[0];
+        center[1] = _yc + _dx * col * _u[1] + _dy * row * _v[1];
         return center;
     }
 
@@ -89,8 +91,8 @@
         int row = getRow(pixel);
         int col = getCol(pixel);
         double[] vtx = new double[2];
-        vtx[0] = _xv[ivtx] + _size * (col * _u[0] + row * _v[0]);
-        vtx[1] = _yv[ivtx] + _size * (col * _u[1] + row * _v[1]);
+        vtx[0] = _xv[ivtx] + _dx * col * _u[0] + _dy * row * _v[0];
+        vtx[1] = _yv[ivtx] + _dx * col * _u[1] + _dy * row * _v[1];
         return vtx;
     }
 
@@ -115,8 +117,8 @@
     }
 
     public long getPixel(double x, double y) {
-        int col = (int) Math.round(((x-_xc)*_u[0] + (y-_yc)*_u[1]) / _size);
-        int row = (int) Math.round(((x-_xc)*_v[0] + (y-_yc)*_v[1]) / _size);
+        int col = (int) Math.round(((x-_xc)*_u[0] + (y-_yc)*_u[1]) / _dx);
+        int row = (int) Math.round(((x-_xc)*_v[0] + (y-_yc)*_v[1]) / _dy);
         return getPixel(row, col);
     }
 
@@ -154,8 +156,12 @@
         return _yc;
     }
 
-    public double getSize() {
-        return _size;
+    public double getXSize() {
+        return _dx;
+    }
+
+    public double getYSize() {
+        return _dy;
     }
 
     private double twicearea(double x1, double y1, double x2, double y2, double x3, double y3) {
CVSspam 0.2.8