Changeset 7216 for branches/maven/projects/slimplugin
 Timestamp:
 11/16/10 20:32:10 (9 years ago)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

branches/maven/projects/slimplugin/src/main/java/loci/slim/analysis/plugins/Display.java
r7209 r7216 35 35 package loci.slim.analysis.plugins; 36 36 37 import ij.IJ;38 37 import ij.ImagePlus; 39 import ij.gui.GenericDialog;40 38 import ij.gui.MessageDialog; 41 import ij.gui.Roi;42 import ij.plugin.frame.RoiManager;43 39 import ij.process.ColorProcessor; 44 40 import java.awt.Color; 45 41 46 import java. io.FileWriter;47 import java. io.IOException;48 import java. util.prefs.*;42 import java.math.BigDecimal; 43 import java.math.MathContext; 44 import java.math.RoundingMode; 49 45 50 46 import loci.slim.SLIMProcessor.FitFunction; … … 55 51 import loci.slim.colorizer.IColorize; 56 52 57 import mpicbg.imglib.image.Image;58 import mpicbg.imglib.type.numeric.real.DoubleType;59 import mpicbg.imglib.container.planar.PlanarContainerFactory;60 import mpicbg.imglib.cursor.Cursor;61 53 import mpicbg.imglib.cursor.LocalizableByDimCursor; 62 54 import mpicbg.imglib.image.Image; 63 import mpicbg.imglib.image.ImageFactory;64 55 import mpicbg.imglib.type.numeric.RealType; 65 56 import mpicbg.imglib.type.numeric.real.DoubleType; … … 73 64 public class Display implements ISLIMAnalyzer { 74 65 private static final Character TAU = 'T'; //TODO IJ doesn't handle Unicode, was: = '\u03c4'; 66 private static final String T = "" + TAU; 75 67 private static final String T1 = "" + TAU + '1'; 76 68 private static final String T2 = "" + TAU + '2'; … … 82 74 private static final String T2_T3 = "" + TAU + "2/" + TAU + '3'; 83 75 private static final String T3_T2 = "" + TAU + "3/" + TAU + '2'; 76 private static final String A = "A"; 84 77 private static final String A1 = "A1"; 85 78 private static final String A2 = "A2"; … … 93 86 private static final String C = "C"; 94 87 95 private static int TOP_OFFSET = 20; 96 private static int SIDE_OFFSET = 10; 97 private static int BOTTOM_OFFSET = 20; 98 private static int TEXT_OFFSET = 10; 88 private static final boolean MIN = true; 89 private static final boolean MAX = false; 90 91 private static final int TOP_OFFSET = 20; 92 private static final int SIDE_OFFSET = 10; 93 private static final int BOTTOM_OFFSET = 20; 94 private static final int TEXT_OFFSET = 18; 95 private static final int BAR_HEIGHT = 3; 96 97 private Color m_bar[]; 98 String m_minText; 99 String m_maxText; 99 100 100 101 /** … … 102 103 */ 103 104 private static enum Formula { 105 T_FORMULA(T, 2), 104 106 T1_FORMULA(T1, 2), 105 107 T2_FORMULA(T2, 4), … … 111 113 T2_T3_FORMULA(T2_T3, 4, 6), 112 114 T3_T2_FORMULA(T3_T2, 6, 4), 115 A_FORMULA(A, 1), 113 116 A1_FORMULA(A1, 1), 114 117 A2_FORMULA(A2, 3), … … 129 132 130 133 /** 131 * Simple formula, just use a given parameter. 134 * Constructor. Simple formula, just use a given parameter, specified 135 * by index. 132 136 * 133 137 * @param index … … 140 144 141 145 /** 142 * Divisor formula, divide first parameter specified by index by second. 146 * Constructor. Divisor formula, divide first parameter specified by 147 * index by second parameter specified by index. 143 148 * 144 149 * @param dividendIndex … … 152 157 } 153 158 159 /** 160 * Returns the displayable String name. 161 * 162 * @return 163 */ 154 164 private String getName() { 155 165 return m_name; 156 166 } 157 167 168 /** 169 * Returns an array of indices to be used in the formula. An array 170 * of one index specifies a parameter to be used as is. An array with 171 * two indices means the first parameter is divided by the second. 172 * 173 * @return 174 */ 158 175 private int[] getIndices() { 159 176 return m_indices; … … 161 178 } 162 179 163 public Display() { 164 } 165 180 /** 181 * Main method of ISLIMAnalyzer. 182 * 183 * @param image 184 * @param region 185 * @param function 186 */ 166 187 public void analyze(Image<DoubleType> image, FitRegion region, FitFunction function) { 167 boolean combineMinMax = true; 188 boolean combineMinMax = true; //false; //TODO needs to be set from UI. 168 189 169 190 // is this plugin appropriate for current data? … … 173 194 return; 174 195 } 196 197 // look at image dimensions 175 198 int dimensions[] = image.getDimensions(); 199 //TODO for debugging only 176 200 for (int i = 0; i < dimensions.length; ++i) { 177 201 System.out.println("dim " + i + " " + dimensions[i]); … … 186 210 int params = dimensions[pIndex]; 187 211 212 // get appropriate formula for image dimensions 188 213 Formula formulas[] = null; 189 214 switch (function) { 190 215 case SINGLE_EXPONENTIAL: 191 formulas = new Formula[] { Formula.A 1_FORMULA, Formula.T1_FORMULA, Formula.C_FORMULA }; //TODO these three formulas are just for testing.216 formulas = new Formula[] { Formula.A_FORMULA, Formula.T_FORMULA, Formula.C_FORMULA }; //TODO these three formulas are just for testing. 192 217 break; 193 218 case DOUBLE_EXPONENTIAL: … … 200 225 break; 201 226 } 227 228 // build display cells 202 229 DisplayCell cells[][] = new DisplayCell[channels][formulas.length]; 203 204 230 int cellX = 0, cellY = 0; 205 231 int cellWidth = width + 2 * SIDE_OFFSET; … … 208 234 cellY = 0; 209 235 for (int f = 0; f < formulas.length; ++f) { 210 cells[c][f] = new DisplayCell( formulas[f], cellX, cellY, width, height);236 cells[c][f] = new DisplayCell("" + (c + 1), formulas[f], cellX, cellY, width, height); 211 237 cellY += cellHeight; 212 238 } … … 216 242 int totalHeight = cellY; 217 243 218 int dim[] = new int[4]; 244 // traverse the image 245 final LocalizableByDimCursor<?> cursor = image.createLocalizableByDimCursor(); 246 int dimForCursor[] = new int[4]; 219 247 double paramArray[] = new double[params]; 220 double minValue, maxValue; 221 final LocalizableByDimCursor<?> cursor = image.createLocalizableByDimCursor(); 248 249 // keep track of minimum and maximum values per formula 250 double minValue[] = new double[formulas.length]; 251 double maxValue[] = new double[formulas.length]; 252 initMinMax(minValue, maxValue); 253 254 // get the parameters for each pixel, 222 255 for (int c = 0; c < channels; ++c) { 223 dim[cIndex] = c; 256 dimForCursor[cIndex] = c; 257 224 258 for (int y = 0; y < height; ++y) { 225 dim[yIndex] = y; 259 dimForCursor[yIndex] = y; 260 226 261 for (int x = 0; x < width; ++x) { 227 dim[xIndex] = x; 262 dimForCursor[xIndex] = x; 263 264 // get the fitted parameters for c, y, x 228 265 for (int p = 0; p < params; ++p) { 229 dim[pIndex] = p; 230 cursor.moveTo(dim); 266 dimForCursor[pIndex] = p; 267 268 // get the fitted parameter 269 cursor.moveTo(dimForCursor); 231 270 paramArray[p] = ((RealType) cursor.getType()).getRealFloat(); 232 271 } 233 minValue = Double.MAX_VALUE; 234 maxValue = 0.0;272 273 // calculate for this c, y, x pixel 235 274 for (int f = 0; f < formulas.length; ++f) { 275 // accumulate minimum and maximum results for all pixels 276 cells[c][f].setMin(minValue[f]); 277 cells[c][f].setMax(maxValue[f]); 278 279 // do the calculation 236 280 cells[c][f].calculate(x, y, paramArray); 237 if (combineMinMax) { 238 if (cells[c][f].getMin() < minValue) { 239 minValue = cells[c][f].getMin(); 240 } 241 if (cells[c][f].getMax() > maxValue) { 242 maxValue = cells[c][f].getMax(); 243 } 244 } 245 } 246 if (combineMinMax) { 247 for (int f = 0; f < formulas.length; ++f) { 248 cells[c][f].setMin(minValue); 249 cells[c][f].setMax(maxValue); 250 } 251 } 281 282 minValue[f] = cells[c][f].getMin(); 283 maxValue[f] = cells[c][f].getMax(); 284 285 } // f loop 286 287 } // x loop 288 289 } // y loop 290 291 if (!combineMinMax) { 292 // save minimum and maximum results for each formula for each channel 293 for (int f = 0; f < formulas.length; ++f) { 294 Converter minConverter = new Converter(MIN, minValue[f]); 295 Converter maxConverter = new Converter(MAX, maxValue[f]); 296 double minimumValue = minConverter.getValue(); 297 double maximumValue = maxConverter.getValue(); 298 String minimumText = minConverter.getText(); 299 String maximumText = maxConverter.getText(); 300 301 cells[c][f].setMin(minimumValue); 302 cells[c][f].setMax(maximumValue); 303 cells[c][f].setMinText(minimumText); 304 cells[c][f].setMaxText(maximumText); 252 305 } 253 } 254 } 255 306 // reset minimum and maximum for each formula 307 initMinMax(minValue, maxValue); 308 } 309 } 310 311 // display cell data 256 312 ColorProcessor outputProcessor = new ColorProcessor(totalWidth, totalHeight); 257 313 outputProcessor.setAntialiasedText(true); … … 261 317 262 318 IColorize colorizer = new FiveColorColorize(Color.BLUE, Color.CYAN, Color.GREEN, Color.YELLOW, Color.RED); 263 for (int c = 0; c < channels; ++c) { 264 for (int f = 0; f < formulas.length; ++f) { 265 cells[c][f].display(outputProcessor, colorizer); 319 for (int f = 0; f < formulas.length; ++f) { 320 if (combineMinMax) { 321 // save minimum and maximum results for all channels 322 Converter minConverter = new Converter(MIN, minValue[f]); 323 Converter maxConverter = new Converter(MAX, maxValue[f]); 324 double minimumValue = minConverter.getValue(); 325 double maximumValue = maxConverter.getValue(); 326 String minimumText = minConverter.getText(); 327 String maximumText = maxConverter.getText(); 328 for (int c = 0; c < channels; ++c) { 329 cells[c][f].setMin(minimumValue); 330 cells[c][f].setMax(maximumValue); 331 cells[c][f].setMinText(minimumText); 332 cells[c][f].setMaxText(maximumText); 333 cells[c][f].display(outputProcessor, colorizer); 334 } 335 336 } 337 else { 338 // minimum and maximum results already saved 339 for (int c = 0; c < channels; ++c) { 340 cells[c][f].display(outputProcessor, colorizer); 341 } 266 342 } 267 343 } … … 269 345 } 270 346 347 private void initMinMax(double minValue[], double maxValue[]) { 348 for (int i = 0; i < minValue.length; ++i) { 349 minValue[i] = Double.MAX_VALUE; 350 maxValue[i] = 0.0; 351 } 352 } 353 354 /** 355 * Inner class. Builds a maximum or minimum value, rounding and 356 * formatting appropriately. 357 */ 358 private class Converter { 359 double m_value; 360 String m_text; 361 362 private Converter(boolean min, double value) { 363 MathContext context = new MathContext(2, min ? RoundingMode.FLOOR : RoundingMode.CEILING); 364 BigDecimal bigDecimalValue = BigDecimal.valueOf(value).round(context); 365 m_value = bigDecimalValue.doubleValue(); 366 m_text = bigDecimalValue.toEngineeringString(); 367 } 368 369 /** 370 * Gets the rounded value. 371 * 372 * @return rounded value 373 */ 374 private double getValue() { 375 return m_value; 376 } 377 378 /** 379 * Gets the formatted string representation of value. 380 * 381 * @return formatted string 382 */ 383 private String getText() { 384 return m_text; 385 } 386 } 387 388 389 /** 390 * Inner class. Calculates and accumulates data for a given cell of the display. 391 */ 271 392 private class DisplayCell { 272 Formula m_formula; 273 int m_x; 274 int m_y; 275 int m_width; 276 int m_height; 277 double m_value[][]; 278 double m_max = 0.0; 279 double m_min = Double.MAX_VALUE; 280 281 private DisplayCell(Formula formula, int x, int y, int width, int height) { 393 private String m_label; 394 private Formula m_formula; 395 private int m_x; 396 private int m_y; 397 private int m_width; 398 private int m_height; 399 private double m_value[][]; 400 private double m_max = 0.0; 401 private double m_min = Double.MAX_VALUE; 402 403 /** 404 * Creates a display cell. 405 * 406 * @param label for this channel 407 * @param formula to use for calculations 408 * @param x leftmost coordinate of the cell 409 * @param y uppermost coordinate of the cell 410 * @param width of the colorized data image 411 * @param height of the colorized data image 412 */ 413 private DisplayCell(String label, Formula formula, int x, int y, int width, int height) { 414 m_label = label; 282 415 m_formula = formula; 283 m_x = x;284 m_y = y;285 m_width = width;286 m_height = height;416 m_x = x; 417 m_y = y; 418 m_width = width; 419 m_height = height; 287 420 m_value = new double[width][height]; 288 421 } 289 422 423 /** 424 * Applies the cell's formula to a set of parameters for a given pixel. 425 * 426 * @param x of current colorized data image pixel 427 * @param y of current colorized data image pixel 428 * @param parameters data for this pixel 429 */ 290 430 private void calculate(int x, int y, double[] parameters) { 291 431 double result = 0.0; … … 306 446 } 307 447 448 /** 449 * Gets minimum calculated value. 450 * 451 * @return 452 */ 308 453 private double getMin() { 309 454 return m_min; 310 455 } 311 456 457 /** 458 * Sets minimum value. Used to initialize the minimum value and to 459 * set the final minimum value. 460 * 461 * @param min 462 */ 312 463 private void setMin(double min) { 313 464 m_min = min; 314 465 } 315 466 467 /** 468 * Sets the formatted String representation of the final minimum value. 469 * 470 * @param minText 471 */ 472 private void setMinText(String minText) { 473 m_minText = minText; 474 } 475 476 /** 477 * Gets maximum calculated value. 478 * 479 * @return 480 */ 316 481 private double getMax() { 317 482 return m_max; 318 483 } 319 484 485 /** 486 * Sets maximum value. Used to initialize the maximum value and to 487 * set the final maximum value. 488 * 489 * @param max 490 */ 320 491 private void setMax(double max) { 321 492 m_max = max; 322 493 } 323 494 495 /** 496 * Sets the formatted String representation of the final maximum value. 497 * 498 * @param maxText 499 */ 500 private void setMaxText(String maxText) { 501 m_maxText = maxText; 502 } 503 504 /** 505 * Displays the colorized data image, color bar, and labelling. 506 * 507 * @param processor 508 * @param colorize 509 */ 324 510 private void display(ColorProcessor processor, IColorize colorize) { 511 // set up color bar one time 512 if (null == m_bar) { 513 m_bar = colorize.bar(m_width); //TODO each cell makes it's own bar; that doesn't make sense 514 } 515 516 // label at top 325 517 processor.setColor(Color.WHITE); 326 518 processor.moveTo(m_x + SIDE_OFFSET, m_y + TEXT_OFFSET); 327 519 processor.drawString(m_formula.getName()); 328 String channelName = "440nm"; 329 int width = processor.getStringWidth(channelName); 330 processor.moveTo(m_x + m_width  width, m_y + TEXT_OFFSET); 331 processor.drawString(channelName); 520 int width = processor.getStringWidth(m_label); 521 processor.moveTo(m_x + SIDE_OFFSET + m_width  width, m_y + TEXT_OFFSET); 522 processor.drawString(m_label); 523 524 // draw image 332 525 for (int x = 0; x < m_width; ++x) { 333 526 for (int y = 0; y < m_height; ++y) { … … 336 529 } 337 530 } 531 532 // draw color bar 533 int barX = m_x + SIDE_OFFSET; 534 int barY = m_y + TOP_OFFSET + m_height; 535 for (int x = barX; x < barX + m_width; ++x) { 536 processor.setColor(m_bar[x  barX]); 537 for (int y = barY; y < barY + BAR_HEIGHT; ++y) { 538 processor.drawPixel(x, y); 539 } 540 } 541 542 // label color bar 543 processor.setColor(Color.WHITE); 544 processor.moveTo(barX, barY + TEXT_OFFSET); 545 processor.drawString(m_minText); 546 width = processor.getStringWidth(m_maxText); 547 processor.moveTo(barX + m_width  width, barY + TEXT_OFFSET); 548 processor.drawString(m_maxText); 338 549 } 339 550 }
Note: See TracChangeset
for help on using the changeset viewer.