Commit in CDMS/src/CDMS/Partridge/FieldFlattening on MAIN
ImageQuadrant.java+104added 1.1
BlankImageFinder.java+68-491.2 -> 1.3
FieldFlattener.java+99-781.2 -> 1.3
FieldFlattenerTest.java+10-61.3 -> 1.4
+281-133
1 added + 3 modified, total 4 files
Use blank quadrants for field flattening since we aren't guaranteed to get full blank images with the new phonon/charge scans.

CDMS/src/CDMS/Partridge/FieldFlattening
ImageQuadrant.java added at 1.1
diff -N ImageQuadrant.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ImageQuadrant.java	9 Apr 2011 17:22:14 -0000	1.1
@@ -0,0 +1,104 @@
+/**
+ * ImageQuadrant.java
+ */
+
+package CDMS.Partridge.FieldFlattening;
+
+import CDMS.Partridge.ImageUtils.GeImage;
+import CDMS.Partridge.ImageUtils.PixelArray;
+
+/**
+ * Provide access to a quadrant of an image file.  The quadrants are numbered
+ * as follows:
+ * 
+ * 0: upper left quadrant
+ * 1: upper right quadrant
+ * 2: lower left quadrant
+ * 3: lower right quadrant
+ *
+ * @author Richard Partridge
+ * @date Apr 8, 2011
+ * @version $Id: ImageQuadrant.java,v 1.1 2011/04/09 17:22:14 partridge Exp $
+ */
+public class ImageQuadrant {
+
+    private String _fname;
+    private int _quad;
+    private PixelArray _pixarray;
+    private int _ncol;
+    private int _nrow;
+    private int[][] _red;
+    private int[][] _green;
+    private int[][] _blue;
+
+    public ImageQuadrant(String fname, int quad) {
+        _fname = fname;
+        _quad = quad;
+        if (_quad < 0 || _quad > 3) throw new RuntimeException("Invalid quadrant: "+_quad);
+
+        GeImage image = new GeImage(fname, 0., 0., 1., 1.);
+        _pixarray = image.getPixelArray();
+        _nrow = _pixarray.getNRow() / 2;
+        _ncol = _pixarray.getNCol() / 2;
+
+        //  Create arrays for the color intensities of each pixel
+        _red = new int[_nrow][_ncol];
+        _green = new int[_nrow][_ncol];
+        _blue = new int[_nrow][_ncol];
+
+        //  Loop over all pixels in the quadrant
+        for (int row=0; row<_nrow; row++) {
+            for (int col = 0; col<_ncol; col++) {
+
+                //  Get the image row/col coordinates
+                int irow = getIRow(row, _nrow, _quad);
+                int icol = getICol(col, _ncol, _quad);
+
+                //  Save the color intensities found for this pixel
+                int rgb = image.getRGB(irow, icol);
+                _red[row][col] = image.getRed(rgb);
+                _blue[row][col] = image.getBlue(rgb);
+                _green[row][col] = image.getGreen(rgb);
+            }
+        }
+    }
+
+    public int getQuadrant() {
+        return _quad;
+    }
+
+    public String getFileName() {
+        return _fname;
+    }
+
+    public int getNRow() {
+        return _nrow;
+    }
+
+    public int getNCol() {
+        return _ncol;
+    }
+
+    public int getRed(int row, int col) {
+        return _red[row][col];
+    }
+
+    public int getGreen(int row, int col) {
+        return _green[row][col];
+    }
+    public int getBlue(int row, int col) {
+        return _blue[row][col];
+    }
+
+    public static int getIRow(int row, int nrow, int quad) {
+        int irow = row;
+        if (quad > 1) irow += nrow;
+        return irow;
+    }
+
+    public static int getICol(int col, int ncol, int quad) {
+        int icol = col;
+        if (quad == 1 || quad == 3) icol += ncol;
+        return icol;
+    }
+}

CDMS/src/CDMS/Partridge/FieldFlattening
BlankImageFinder.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- BlankImageFinder.java	11 Oct 2010 00:25:43 -0000	1.2
+++ BlankImageFinder.java	9 Apr 2011 17:22:14 -0000	1.3
@@ -11,10 +11,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 
 /**
  * Find blank images by identifying images with small standard deviations
@@ -28,69 +25,91 @@
 
         //  Define the inputs and outputs - eventually it would be good to package
         //  this application and invoke these parameters from the command line
-        String fbase = "c:/CDMS/IZipG47_Side1_PKG/IZipG47_Side1_PKG-";
+        String fbase = "c:/CDMS/MaxScanTestL09/MaxScanTestL09-";
         int ifirst = 1;
-        int ilast = 8585;
-        String suffix = ".png";
-        String outfile = "c:/CDMS/IZipv4_side1_blanks.txt";
+        int ilast = 138;
+        int nfile = ilast - ifirst + 1;
+        String suffix = ".BMP";
+        String outfile = "c:/CDMS/MaxScanTestL09_blanks.txt";
         double imin = 100.;
-        int nblank = 100;
+        int nblank = 10;
 
-        //  Create maps to hold the mean and sd calculations
-        Map<String, Double> imean = new HashMap<String, Double>();
-        Map<String, Double> isd = new HashMap<String, Double>();
+        //  Create arrays to hold the mean and sd calculations
+        double[][] imean = new double[nfile][4];
+        double[][] isd = new double[nfile][4];
 
         //  Loop over the image files
-        for (int ifile=ifirst; ifile<=ilast; ifile++) {
+        for (int file=0; file<nfile; file++) {
             
             //  Show progress in processing the image files
-            if (ifile > 0 && (ifile % 100) == 0) System.out.println("Processing file "+ifile);
+            int ifile = ifirst + file;
+            if (file % 10 == 9) System.out.println("Processing file "+ifile);
 
             //  Open the image file with arbitrary origin and pixel size
             String fname = fbase + ifile + suffix;
             GeImage image = new GeImage(fname, 0., 0., 1., 1.);
             PixelArray pixarray = image.getPixelArray();
 
-            //  Loop over pixels and find the intensity mean and standard deviation
-            double itot = 0.;
-            double i2tot = 0.;
-            for (int row=0; row<pixarray.getNRow(); row++) {
-                for (int col=0; col<pixarray.getNCol(); col++) {
-                    double intensity = image.getIntensity(row, col);
-                    itot += intensity;
-                    i2tot += intensity*intensity;
+            //  Loop over quadrants
+            for (int quad=0; quad<4; quad++) {
+
+                //  Loop over pixels and find the intensity mean and standard deviation
+                int nrow = pixarray.getNRow() / 2;
+                int ncol = pixarray.getNCol() / 2;
+                double itot = 0.;
+                double i2tot = 0.;
+                for (int row=0; row<nrow; row++) {
+                    for (int col=0; col<ncol; col++) {
+
+                        int irow = ImageQuadrant.getIRow(row, nrow, quad);
+                        int icol = ImageQuadrant.getICol(col, ncol, quad);
+                        double intensity = image.getIntensity(irow, icol);
+                        itot += intensity;
+                        i2tot += intensity*intensity;
+                    }
                 }
-            }
-            int npixel = pixarray.getNRow() * pixarray.getNCol();
-            double mean = itot / npixel;
-            double sd = Math.sqrt(i2tot/npixel - mean*mean);
-
-            //  Save the mean and st dev in maps for later access
-            imean.put(fname, mean);
-            isd.put(fname, sd);
+                int npixel = nrow * ncol;
+                double mean = itot / npixel;
+                double sd = Math.sqrt(i2tot/npixel - mean*mean);
+
+                //  Save the mean and st dev in arrays for later access
+                imean[file][quad] = mean;
+                isd[file][quad] = sd;
+           }
         }
 
-        //  Make a list of sd for blank candidates, excluding those that have
-        //  low mean intensity (typically images outside the detector boundary)
-        List<Double> sdlist = new ArrayList<Double>();
-        for (Entry<String, Double> ent : imean.entrySet()) {
-            if (ent.getValue() > imin) sdlist.add(isd.get(ent.getKey()));
-        }
+        //  Open the output file
+        PrintWriter out = new PrintWriter(new FileWriter(outfile));
+
+        //  Loop over quadrants and find the best blank candidates
+        for (int quad = 0; quad<4; quad++) {
 
-        //  Sort the list and find the cutoff sd for our list of blank images
-        Collections.sort(sdlist);
-        double sdmax = sdlist.get(nblank-1);
-
-       //  Open the output file
-       PrintWriter out = new PrintWriter(new FileWriter(outfile));
-
-        //  Output the desired number of images choosing those with the smallest sd
-        for (String fname : imean.keySet()) {
-            double mean = imean.get(fname);
-            double sd = isd.get(fname);
-            if (sd > sdmax || mean <= imin) continue;
-            System.out.println("File "+fname+" selected - mean: "+mean+" sd: "+sd);
-            out.println(fname);
+            //  Make a list of sd for blank candidates, excluding those that have
+            //  low mean intensity (typically images outside the detector boundary)
+            List<Double> sdlist = new ArrayList<Double>();
+            for (int file=0; file<nfile; file++) {
+                if (imean[file][quad] > imin) sdlist.add(isd[file][quad]);
+            }
+
+            //  Sort the list and find the cutoff sd for our list of blank images
+            Collections.sort(sdlist);
+            double sdmax = sdlist.get(nblank-1);
+
+            //  Output the desired number of images choosing those with the smallest sd
+            for (int file=0; file<nfile; file++) {
+
+                //  Check if this is among the image files with the smallest sd
+                double mean = imean[file][quad];
+                double sd = isd[file][quad];
+                if (sd > sdmax || mean <= imin) continue;
+
+                //  Construct the file name and write it and the quadrant out
+                int ifile = ifirst + file;
+                String fname = fbase + ifile + suffix;
+                System.out.println("File "+fname+" quadrant "+quad+
+                        " selected - mean: "+mean+" sd: "+sd);
+                out.println(fname+" "+quad);
+            }
         }
 
         //  Close the output file

CDMS/src/CDMS/Partridge/FieldFlattening
FieldFlattener.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- FieldFlattener.java	11 Oct 2010 00:25:43 -0000	1.2
+++ FieldFlattener.java	9 Apr 2011 17:22:14 -0000	1.3
@@ -13,9 +13,9 @@
 import java.util.List;
 
 /**
- * Takes a set of uniform blank images and creates a 2D field flattening map that
- * eliminates variations in intensity among the different image pixels.  These
- * variations may arise from non-uniform illumination and/or camera response.
+ * Takes a set of uniform blank image quadrants and creates a 2D field flattening
+ * map that eliminates variations in intensity among the different image pixels.
+ * These variations may arise from non-uniform illumination and/or camera response.
  *
  * The BlankImageFinder class can be used to identify blank images and create
  * the blank image file used by this class.
@@ -30,7 +30,7 @@
  */
 public class FieldFlattener {
 
-    private List<String> _fnames;
+    private List<ImageQuadrant> _quads;
     private int _nrow;
     private int _ncol;
     private double[][] _rcor;
@@ -46,66 +46,55 @@
      */
     public FieldFlattener(String blankfile, double cut) {
 
-        //  Read in the list of blank images
+        //  Read in the list of blank quadrants and create the corresponding ImageQuadrants
         ReadBlankFile(blankfile);
 
         //  Initialize the arrays for the image data and pixel descriptors
-        int nfiles = _fnames.size();
-        if (nfiles == 0) throw new RuntimeException("No blank images found");
-        GeImage[] _images = new GeImage[nfiles];
-        PixelArray[] _pixarray = new PixelArray[nfiles];
-
-        //  Loop over files and retrieve the image data
-        for (int ifile=0; ifile<nfiles; ifile++) {
-
-            //  Get the image data and pixel array descriptor for this file
-            String fname = _fnames.get(ifile);
-            _images[ifile] = new GeImage(fname, 0., 0., 1., 1.);
-            _pixarray[ifile] = _images[ifile].getPixelArray();
-
-            //  If this is the first image, save the image size
-            if (ifile == 0) {
-                _nrow = _pixarray[0].getNRow();
-                _ncol = _pixarray[0].getNCol();
-            }
-
-            //  Check that all images are the same size
-            if (_pixarray[ifile].getNRow() != _nrow ||
-                _pixarray[ifile].getNCol() != _ncol)
-                throw new RuntimeException("Blank image files have different sizes");
-        }
+        if (_quads.isEmpty()) throw new RuntimeException("No blank image quadrants found");
 
         //  Create arrays for the average color intensities of each pixel
-        double ared[][] = new double[_nrow][_ncol];
-        double agreen[][] = new double[_nrow][_ncol];
-        double ablue[][] = new double[_nrow][_ncol];
-
-        //  Loop over all pixels
-        for (int row=0; row<_nrow; row++) {
-            for (int col=0; col<_ncol; col++) {
-
-                //  Arrays for the color intensities from each blank image
-                int[] red = new int[nfiles];
-                int[] blue = new int[nfiles];
-                int[] green = new int[nfiles];
-
-                //  Loop over the blank images
-                for (int ifile=0; ifile<nfiles; ifile++) {
-
-                    //  Save the color intensities found for this pixel
-                    GeImage image = _images[ifile];
-                    int rgb = image.getRGB(row, col);
-                    red[ifile] = image.getRed(rgb);
-                    blue[ifile] = image.getBlue(rgb);
-                    green[ifile] = image.getGreen(rgb);
+        double ared[][][] = new double[_nrow][_ncol][4];
+        double agreen[][][] = new double[_nrow][_ncol][4];
+        double ablue[][][] = new double[_nrow][_ncol][4];
+        int nquad[] = {0, 0, 0, 0};
+
+        //  Count the number of images for each quadrant
+        for (ImageQuadrant iquad : _quads) {
+            int quad = iquad.getQuadrant();
+            nquad[quad] += 1;
+        }
+
+        //  Loop over the quadrants
+        for (int quad=0; quad<4; quad++) {
+
+            //  Loop over all pixels in a quadrant
+            for (int row=0; row<_nrow; row++) {
+                for (int col=0; col<_ncol; col++) {
+
+                    //  Lists for the color intensities
+                    List<Integer> red = new ArrayList<Integer>();
+                    List<Integer> green = new ArrayList<Integer>();
+                    List<Integer> blue = new ArrayList<Integer>();
+
+                    //  Loop over the ImageQuadrants
+                    for (ImageQuadrant iquad : _quads) {
+
+                        //  Check that this is the quadrant we are interested in
+                        if (iquad.getQuadrant() != quad) continue;
+
+                        //  Save the color intensities found for this pixel
+                        red.add(iquad.getRed(row, col));
+                        green.add(iquad.getGreen(row, col));
+                        blue.add(iquad.getBlue(row, col));
+                    }
+
+                    //  Average the color intensities for this pixel using a
+                    //  truncated mean that discards outliers since our blank
+                    //  images may not be flawless
+                    ared[row][col][quad] = TruncatedMean(red, cut);
+                    ablue[row][col][quad] = TruncatedMean(blue, cut);
+                    agreen[row][col][quad] = TruncatedMean(green, cut);
                 }
-
-                //  Average the color intensities for this pixel using a
-                //  truncated mean that discards outliers since our blank
-                //  images may not be flawless
-                ared[row][col] = TruncatedMean(red, cut);
-                ablue[row][col] = TruncatedMean(blue, cut);
-                agreen[row][col] = TruncatedMean(green, cut);
             }
         }
 
@@ -116,25 +105,33 @@
         double bave = 0.;
         for (int row=0; row<_nrow; row++) {
             for (int col=0; col<_ncol; col++) {
-                rave += ared[row][col] / (_nrow * _ncol);
-                gave += agreen[row][col] / (_nrow * _ncol);
-                bave += ablue[row][col] / (_nrow * _ncol);
+                for (int quad=0; quad<4; quad++) {
+                    rave += ared[row][col][quad] / (4 * _nrow * _ncol);
+                    gave += agreen[row][col][quad] / (4 * _nrow * _ncol);
+                    bave += ablue[row][col][quad] / (4 * _nrow * _ncol);
+                }
             }
         }
 
         //  Create the arrays to hold the field flattening map
-        _rcor = new double[_nrow][_ncol];
-        _gcor = new double[_nrow][_ncol];
-        _bcor = new double[_nrow][_ncol];
+        _rcor = new double[2*_nrow][2*_ncol];
+        _gcor = new double[2*_nrow][2*_ncol];
+        _bcor = new double[2*_nrow][2*_ncol];
 
         //  Calculate the correction factors to be applied to the
         //  color intensities for each image pixel
         for (int row=0; row<_nrow; row++) {
             for (int col=0; col<_ncol; col++) {
+                for (int quad=0; quad<4; quad++) {
 
-                _rcor[row][col] = rave / ared[row][col];
-                _gcor[row][col] = gave / agreen[row][col];
-                _bcor[row][col] = bave / ablue[row][col];
+                    //  Get the row/col for the full 4-quadrant image
+                    int irow = ImageQuadrant.getIRow(row, _nrow, quad);
+                    int icol = ImageQuadrant.getICol(col, _ncol, quad);
+
+                    _rcor[irow][icol] = rave / ared[row][col][quad];
+                    _gcor[irow][icol] = gave / agreen[row][col][quad];
+                    _bcor[irow][icol] = bave / ablue[row][col][quad];
+                }
             }
         }
     }
@@ -181,8 +178,8 @@
      *
      * @return
      */
-    public List<String> getBlankFileNames() {
-        return _fnames;
+    public List<ImageQuadrant> getBlankImageQuadrants() {
+        return _quads;
     }
 
     /**
@@ -200,12 +197,12 @@
 
         //  Check that the dimensions of the image to be flattened are the
         //  same as the blank images used to develop the flattening correction
-        if (pixarray.getNRow() != _nrow || pixarray.getNCol() != _ncol)
+        if (pixarray.getNRow() != 2*_nrow || pixarray.getNCol() != 2*_ncol)
             throw new RuntimeException("Image sizes don't match");
 
         //  Loop over the image pixels
-        for (int row=0; row<_nrow; row++) {
-            for (int col=0; col<_ncol; col++) {
+        for (int row=0; row<2*_nrow; row++) {
+            for (int col=0; col<2*_ncol; col++) {
 
                 //  Get the packed rgb color intensities for this pixel
                 int rgb = image.getRGB(row, col);
@@ -230,8 +227,9 @@
      */
     private void ReadBlankFile(String blankfile) {
 
-        //  Initialize the list of file names
-        _fnames = new ArrayList<String>();
+        //  Initialize the list of file names and initialization flag
+        _quads = new ArrayList<ImageQuadrant>();
+        boolean first = true;
 
         //  Open the file with the list of blank images
         FileReader fr;
@@ -252,10 +250,30 @@
         //  Loop over the blank file entries
         try {
             while (tok.nextToken() != StreamTokenizer.TT_EOF) {
+
                 //  Get the next file name
                 if (tok.ttype != StreamTokenizer.TT_WORD) ParseError();
                 String fname = tok.sval;
-                _fnames.add(fname);
+
+                //  Get the quadrant
+                if (tok.nextToken() != StreamTokenizer.TT_NUMBER) ParseError();
+                int quad = (int) Math.round(tok.nval);
+
+                //  Create a new ImageQuadrant and add it to the list
+                ImageQuadrant iquad = new ImageQuadrant(fname, quad);
+                _quads.add(iquad);
+
+                //  Initialize / check the image size
+                if (first) {
+                    _nrow = iquad.getNRow();
+                    _ncol = iquad.getNCol();
+                    first = false;
+                } else {
+                    if (iquad.getNRow() != _nrow || iquad.getNCol() != _ncol)
+                        throw new RuntimeException("Blank image files have different sizes");
+                }
+
+                //  Check for the end of line token
                 if (tok.nextToken() != StreamTokenizer.TT_EOL) ParseError();
             }
         } catch (Exception ex) {
@@ -284,17 +302,20 @@
      * @param cut truncation cut in units of the standard deviation
      * @return truncated mean
      */
-    private double TruncatedMean(int[] values, double cut) {
+    private double TruncatedMean(List<Integer> valuelist, double cut) {
 
         //  Get the number of values to average
-        int nval = values.length;
+        int nval = valuelist.size();
 
-        //  Create and initialize the array of values to be excluded
+        //  Create and initialize the arrays of values and exclusion flags
+        int[] values = new int[nval];
         boolean[] exclude = new boolean[nval];
         for (int i=0; i<nval; i++) {
+            values[i] = valuelist.get(i);
             exclude[i] = false;
         }
 
+
         //  Calculate the initial mean and stddev using all values
         double mean = CalcMean(values, exclude);
         double sd = CalcStdDev(values, mean, exclude);

CDMS/src/CDMS/Partridge/FieldFlattening
FieldFlattenerTest.java 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- FieldFlattenerTest.java	12 Nov 2010 21:26:54 -0000	1.3
+++ FieldFlattenerTest.java	9 Apr 2011 17:22:14 -0000	1.4
@@ -19,11 +19,12 @@
 
     public static void main(String[] args) throws IOException {
 
-        String blankindexfile = "c:/CDMS/IZipv4_side1_blanks.txt";
+        String blankindexfile = "c:/CDMS/MaxScanTestL09_blanks.txt";
         FieldFlattener flat = new FieldFlattener(blankindexfile, 2.0);
         int ifile = 0;
         AIDA aida = AIDA.defaultInstance();
-        for (String fname : flat.getBlankFileNames()) {
+        for (ImageQuadrant iquad : flat.getBlankImageQuadrants()) {
+            String fname = iquad.getFileName();
             GeImage image = new GeImage(fname, 0., 0., 1., 1.);
             PixelArray pixarray = image.getPixelArray();
             GeImage flatimage = flat.FlattenImage(image);
@@ -31,14 +32,17 @@
             double i2sum = 0.;
             double ifsum = 0.;
             double i2fsum = 0.;
-            int nrow = pixarray.getNRow();
-            int ncol = pixarray.getNCol();
+            int nrow = iquad.getNRow();
+            int ncol = iquad.getNCol();
+            int quad = iquad.getQuadrant();
             for (int row=0; row<nrow; row++) {
                 for (int col=0; col<ncol; col++) {
-                    double fintensity = flatimage.getIntensity(row, col);
+                    int irow = ImageQuadrant.getIRow(row, nrow, quad);
+                    int icol = ImageQuadrant.getICol(col, ncol, quad);
+                    double fintensity = flatimage.getIntensity(irow, icol);
                     ifsum += fintensity;
                     i2fsum += fintensity*fintensity;
-                    double intensity = image.getIntensity(row, col);
+                    double intensity = image.getIntensity(irow, icol);
                     isum += intensity;
                     i2sum += intensity*intensity;
                     aida.histogram1D("Flattened intensity", 256, 0., 256.).fill(fintensity);
CVSspam 0.2.8