Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
Analyzer.java
1 package ij.plugin.filter;
2 import java.awt.*;
3 import java.util.Vector;
4 import java.util.Properties;
5 import ij.*;
6 import ij.gui.*;
7 import ij.process.*;
8 import ij.measure.*;
9 import ij.text.*;
10 import ij.plugin.MeasurementsWriter;
11 
13 public class Analyzer implements PlugInFilter, Measurements {
14 
15  private String arg;
16  private ImagePlus imp;
17  private ResultsTable rt;
18  private int measurements;
19  private StringBuffer min,max,mean,sd;
20 
21  // Order must agree with order of checkboxes in Set Measurements dialog box
22  private static final int[] list = {AREA,MEAN,STD_DEV,MODE,MIN_MAX,
23  CENTROID,CENTER_OF_MASS,PERIMETER,RECT,ELLIPSE,CIRCULARITY, FERET,
24  LIMIT,LABELS,INVERT_Y};
25 
26  private static final int UNDEFINED=0,AREAS=1,LENGTHS=2,ANGLES=3,MARK_AND_COUNT=4;
27  private static int mode = AREAS;
28  private static final String MEASUREMENTS = "measurements";
29  private static final String MARK_WIDTH = "mark.width";
30  private static final String PRECISION = "precision";
31  //private static int counter;
32  private static boolean unsavedMeasurements;
33  public static Color darkBlue = new Color(0,0,160);
34  private static int systemMeasurements = Prefs.getInt(MEASUREMENTS,AREA+MEAN+MIN_MAX);
35  public static int markWidth = Prefs.getInt(MARK_WIDTH,3);
36  public static int precision = Prefs.getInt(PRECISION,3);
37  private static float[] umeans = new float[MAX_STANDARDS];
38  private static ResultsTable systemRT = new ResultsTable();
39  private static int redirectTarget;
40  private static String redirectTitle = "";
41  static int firstParticle, lastParticle;
42 
43  public Analyzer() {
44  rt = systemRT;
45  rt.setPrecision(precision);
46  measurements = systemMeasurements;
47  }
48 
51  public Analyzer(ImagePlus imp) {
52  this();
53  this.imp = imp;
54  }
55 
58  public Analyzer(ImagePlus imp, int measurements, ResultsTable rt) {
59  this.imp = imp;
60  this.measurements = measurements;
61  this.rt = rt;
62  }
63 
64  public int setup(String arg, ImagePlus imp) {
65  this.arg = arg;
66  this.imp = imp;
67  IJ.register(Analyzer.class);
68  if (arg.equals("sum"))
69  {summarize(); return DONE;}
70  else if (arg.equals("clear"))
71  {clearWorksheet(); return DONE;}
72  else
73  return DOES_ALL+NO_CHANGES;
74  }
75 
76  public void run(ij.process.ImageProcessor ip) {}
77 
78  void clearWorksheet() {
79  resetCounter();
80  }
81 
82  void setOptions(GenericDialog gd) {
83  int oldMeasurements = systemMeasurements;
84  int previous = 0;
85  boolean b = false;
86  for (int i=0; i<list.length; i++) {
87  //if (list[i]!=previous)
88  b = gd.getNextBoolean();
89  previous = list[i];
90  if (b)
91  systemMeasurements |= list[i];
92  else
93  systemMeasurements &= ~list[i];
94  }
95  if ((oldMeasurements&(~LIMIT))!=(systemMeasurements&(~LIMIT))) {
96  if (IJ.macroRunning()) {
97  resetCounter();
98  mode = AREAS;
99  } else
100  mode = UNDEFINED;
101  }
102  if ((systemMeasurements&LABELS)==0)
103  systemRT.disableRowLabels();
104  }
105 
106 
107  // Update centroid and center of mass y-coordinate
108  // based on value "Invert Y Coordinates" flag
109  double updateY(double y) {
110  if (imp==null)
111  return y;
112  else {
113  if ((systemMeasurements&INVERT_Y)!=0) {
114  Calibration cal = imp.getCalibration();
115  y = imp.getHeight()*cal.pixelHeight-y;
116  }
117  return y;
118  }
119  }
120 
121  // Update bounding rectangle y-coordinate based
122  // on value "Invert Y Coordinates" flag
123  double updateY2(double y) {
124  if (imp==null)
125  return y;
126  else {
127  if ((systemMeasurements&INVERT_Y)!=0) {
128  Calibration cal = imp.getCalibration();
129  y = imp.getHeight()*cal.pixelHeight-y-cal.pixelHeight;
130  }
131  return y;
132  }
133  }
134 
136  public void displayResults() {
137  int counter = rt.getCounter();
138  if (counter==1)
139  IJ.setColumnHeadings(rt.getColumnHeadings());
140  IJ.write(rt.getRowAsString(counter-1));
141  }
142 
147  public void updateHeadings() {
148  TextPanel tp = IJ.getTextPanel();
149  if (tp==null)
150  return;
151  String worksheetHeadings = tp.getColumnHeadings();
152  String tableHeadings = rt.getColumnHeadings();
153  if (worksheetHeadings.equals(tableHeadings))
154  return;
155  IJ.setColumnHeadings(tableHeadings);
156  int n = rt.getCounter();
157  if (n>0) {
158  StringBuffer sb = new StringBuffer(n*tableHeadings.length());
159  for (int i=0; i<n; i++)
160  sb.append(rt.getRowAsString(i)+"\n");
161  tp.append(new String(sb));
162  }
163  }
164 
166  public String n(double n) {
167  String s;
168  if (Math.round(n)==n)
169  s = IJ.d2s(n,0);
170  else
171  s = IJ.d2s(n,precision);
172  return s+"\t";
173  }
174 
175  void incrementCounter() {
176  //counter++;
177  if (rt==null) rt = systemRT;
178  rt.incrementCounter();
179  unsavedMeasurements = true;
180  }
181 
182  public void summarize() {
183  rt = systemRT;
184  if (rt.getCounter()==0)
185  return;
186  measurements = systemMeasurements;
187  min = new StringBuffer(100);
188  max = new StringBuffer(100);
189  mean = new StringBuffer(100);
190  sd = new StringBuffer(100);
191  min.append("Min\t");
192  max.append("Max\t");
193  mean.append("Mean\t");
194  sd.append("SD\t");
195  if ((measurements&LABELS)!=0) {
196  min.append("\t");
197  max.append("\t");
198  mean.append("\t");
199  sd.append("\t");
200  }
201  if (mode==MARK_AND_COUNT)
202  summarizePoints(rt);
203  else if (mode==LENGTHS)
204  add2(rt.getColumnIndex("Length"));
205  else if (mode==ANGLES)
206  add2(rt.getColumnIndex("Angle"));
207  else
208  summarizeAreas();
209  TextPanel tp = IJ.getTextPanel();
210  if (tp!=null) {
211  String worksheetHeadings = tp.getColumnHeadings();
212  if (worksheetHeadings.equals(""))
213  IJ.setColumnHeadings(rt.getColumnHeadings());
214  }
215  IJ.write("");
216  IJ.write(new String(mean));
217  IJ.write(new String(sd));
218  IJ.write(new String(min));
219  IJ.write(new String(max));
220  IJ.write("");
221  mean = null;
222  sd = null;
223  min = null;
224  max = null;
225  }
226 
227  void summarizePoints(ResultsTable rt) {
228  add2(rt.getColumnIndex("X"));
229  add2(rt.getColumnIndex("Y"));
230  add2(rt.getColumnIndex("Value"));
231  }
232 
233  void summarizeAreas() {
234  if ((measurements&AREA)!=0) add2(ResultsTable.AREA);
235  if ((measurements&MEAN)!=0) add2(ResultsTable.MEAN);
236  if ((measurements&STD_DEV)!=0) add2(ResultsTable.STD_DEV);
237  if ((measurements&MODE)!=0) add2(ResultsTable.MODE);
238  if ((measurements&MIN_MAX)!=0) {
239  add2(ResultsTable.MIN);
240  add2(ResultsTable.MAX);
241  }
242  if ((measurements&CENTROID)!=0) {
243  add2(ResultsTable.X_CENTROID);
244  add2(ResultsTable.Y_CENTROID);
245  }
246  if ((measurements&CENTER_OF_MASS)!=0) {
247  add2(ResultsTable.X_CENTER_OF_MASS);
248  add2(ResultsTable.Y_CENTER_OF_MASS);
249  }
250  if ((measurements&PERIMETER)!=0)
251  add2(ResultsTable.PERIMETER);
252  if ((measurements&RECT)!=0) {
253  add2(ResultsTable.ROI_X);
254  add2(ResultsTable.ROI_Y);
255  add2(ResultsTable.ROI_WIDTH);
256  add2(ResultsTable.ROI_HEIGHT);
257  }
258  if ((measurements&ELLIPSE)!=0) {
259  add2(ResultsTable.MAJOR);
260  add2(ResultsTable.MINOR);
261  add2(ResultsTable.ANGLE);
262  }
263  if ((measurements&CIRCULARITY)!=0)
264  add2(ResultsTable.CIRCULARITY);
265  if ((measurements&FERET)!=0)
266  add2(ResultsTable.FERET);
267  }
268 
269  private void add2(int column) {
270  float[] c = column>=0?rt.getColumn(column):null;
271  if (c!=null) {
272  ImageProcessor ip = new FloatProcessor(c.length, 1, c, null);
273  if (ip==null)
274  return;
275  ImageStatistics stats = new FloatStatistics(ip);
276  if (stats==null)
277  return;
278  mean.append(n(stats.mean));
279  min.append(n(stats.min));
280  max.append(n(stats.max));
281  sd.append(n(stats.stdDev));
282  } else {
283  mean.append("-\t");
284  min.append("-\t");
285  max.append("-\t");
286  sd.append("-\t");
287  }
288  }
289 
291  public static int getCounter() {
292  return systemRT.getCounter();
293  }
294 
299  public synchronized static boolean resetCounter() {
301  int counter = systemRT.getCounter();
302  int lineCount = tp!=null?IJ.getTextPanel().getLineCount():0;
303  ImageJ ij = IJ.getInstance();
304  if (counter>0 && lineCount>0 && unsavedMeasurements && !IJ.macroRunning() && ij!=null) {
305  SaveChangesDialog d = new SaveChangesDialog(ij, "Save "+counter+" measurements?");
306  if (d.cancelPressed())
307  return false;
308  else if (d.savePressed())
309  new MeasurementsWriter().run("");
310  }
311  umeans = null;
312  systemRT.reset();
313  unsavedMeasurements = false;
314  if (tp!=null) {
315  tp.selectAll();
316  tp.clearSelection();
317  }
318  return true;
319  }
320 
321  public static void setSaved() {
322  unsavedMeasurements = false;
323  }
324 
325  // Returns the measurements defined in the Set Measurements dialog. */
326  public static int getMeasurements() {
327  return systemMeasurements;
328  }
329 
330  // Sets the system-wide measurements. */
331  public static void setMeasurements(int measurements) {
332  systemMeasurements = measurements;
333  }
334 
336  public static void savePreferences(Properties prefs) {
337  prefs.put(MEASUREMENTS, Integer.toString(systemMeasurements));
338  prefs.put(MARK_WIDTH, Integer.toString(markWidth));
339  prefs.put(PRECISION, Integer.toString(precision)); }
340 
342  public static float[] getUMeans() {
343  return umeans;
344  }
345 
347  public static ResultsTable getResultsTable() {
348  return systemRT;
349  }
350 
352  public static int getPrecision() {
353  return precision;
354  }
355 
358  public static int updateY(int y, int imageHeight) {
359  if ((systemMeasurements&INVERT_Y)!=0)
360  y = imageHeight-y-1;
361  return y;
362  }
363 
364 }
365