mev-4.0.01/source/org/tigr/microarray/mev/cluster/gui/impl/lem/LinearExpressionMapViewer.java

Code
Comments
Other
Rev Date Author Line
2 26 Feb 07 jari 1 /*
2 26 Feb 07 jari 2 Copyright @ 1999-2006, The Institute for Genomic Research (TIGR).
2 26 Feb 07 jari 3 All rights reserved.
2 26 Feb 07 jari 4 */
2 26 Feb 07 jari 5
2 26 Feb 07 jari 6 package org.tigr.microarray.mev.cluster.gui.impl.lem;
2 26 Feb 07 jari 7
2 26 Feb 07 jari 8 import java.awt.AlphaComposite;
2 26 Feb 07 jari 9 import java.awt.Color;
2 26 Feb 07 jari 10 import java.awt.Composite;
2 26 Feb 07 jari 11 import java.awt.Dimension;
2 26 Feb 07 jari 12 import java.awt.Font;
2 26 Feb 07 jari 13 import java.awt.FontMetrics;
2 26 Feb 07 jari 14 import java.awt.GradientPaint;
2 26 Feb 07 jari 15 import java.awt.Graphics;
2 26 Feb 07 jari 16 import java.awt.Graphics2D;
2 26 Feb 07 jari 17 import java.awt.Rectangle;
2 26 Feb 07 jari 18 import java.awt.event.ActionEvent;
2 26 Feb 07 jari 19 import java.awt.event.ActionListener;
2 26 Feb 07 jari 20 import java.awt.event.MouseAdapter;
2 26 Feb 07 jari 21 import java.awt.event.MouseEvent;
2 26 Feb 07 jari 22 import java.awt.event.MouseMotionListener;
2 26 Feb 07 jari 23 import java.awt.image.BufferedImage;
2 26 Feb 07 jari 24 import java.beans.Expression;
2 26 Feb 07 jari 25 import java.io.BufferedWriter;
2 26 Feb 07 jari 26 import java.io.File;
2 26 Feb 07 jari 27 import java.io.FileWriter;
2 26 Feb 07 jari 28 import java.io.IOException;
2 26 Feb 07 jari 29 import java.util.Properties;
2 26 Feb 07 jari 30 import java.util.Vector;
2 26 Feb 07 jari 31
2 26 Feb 07 jari 32 import javax.swing.ButtonGroup;
2 26 Feb 07 jari 33 import javax.swing.JCheckBoxMenuItem;
2 26 Feb 07 jari 34 import javax.swing.JComponent;
2 26 Feb 07 jari 35 import javax.swing.JFileChooser;
2 26 Feb 07 jari 36 import javax.swing.JFrame;
2 26 Feb 07 jari 37 import javax.swing.JMenu;
2 26 Feb 07 jari 38 import javax.swing.JMenuItem;
2 26 Feb 07 jari 39 import javax.swing.JOptionPane;
2 26 Feb 07 jari 40 import javax.swing.JPanel;
2 26 Feb 07 jari 41 import javax.swing.JPopupMenu;
2 26 Feb 07 jari 42 import javax.swing.JViewport;
2 26 Feb 07 jari 43
2 26 Feb 07 jari 44 import org.tigr.microarray.mev.TMEV;
2 26 Feb 07 jari 45 import org.tigr.microarray.mev.cluster.clusterUtil.Cluster;
2 26 Feb 07 jari 46 import org.tigr.microarray.mev.cluster.gui.Experiment;
2 26 Feb 07 jari 47 import org.tigr.microarray.mev.cluster.gui.IData;
2 26 Feb 07 jari 48 import org.tigr.microarray.mev.cluster.gui.IDisplayMenu;
2 26 Feb 07 jari 49 import org.tigr.microarray.mev.cluster.gui.IFramework;
2 26 Feb 07 jari 50 import org.tigr.microarray.mev.cluster.gui.IViewer;
2 26 Feb 07 jari 51 import org.tigr.microarray.mev.cluster.gui.helpers.ExperimentUtil;
2 26 Feb 07 jari 52 import org.tigr.util.FloatMatrix;
2 26 Feb 07 jari 53
2 26 Feb 07 jari 54 /**
2 26 Feb 07 jari 55  * @author braisted
2 26 Feb 07 jari 56  *    
2 26 Feb 07 jari 57  *  LinearExpressionMapViewer Description: Provides a multiple sample
2 26 Feb 07 jari 58  * expression view that is organized by chromosomal coordinates Each
2 26 Feb 07 jari 59  * chromosome, if there is more than one, will have a dedicated LEM in which
2 26 Feb 07 jari 60  * Loci are arranged based on coordinate information in a linear,
2 26 Feb 07 jari 61  * top-to-bottom fashion in the viewer. Samples are displayed in parallel
2 26 Feb 07 jari 62  * lines in the viewer.
2 26 Feb 07 jari 63  * 
2 26 Feb 07 jari 64  * Fixed arrow length indicates a more compressed view where sequence
2 26 Feb 07 jari 65  * lengths are not rendered based on length. In this mode all overlapping
2 26 Feb 07 jari 66  * sequences will be on the same line rather than offset and intergenic
2 26 Feb 07 jari 67  * spaces will be of uniform length.
2 26 Feb 07 jari 68  */
2 26 Feb 07 jari 69 public class LinearExpressionMapViewer extends JPanel implements IViewer {
2 26 Feb 07 jari 70
2 26 Feb 07 jari 71   /**
2 26 Feb 07 jari 72    * Holds the reduced and sorted Experiment
2 26 Feb 07 jari 73    */
2 26 Feb 07 jari 74   private Experiment experiment;
2 26 Feb 07 jari 75
2 26 Feb 07 jari 76   /**
2 26 Feb 07 jari 77    * Holds the full experiment (from IData, doesn't include trimmed elements)
2 26 Feb 07 jari 78    */
2 26 Feb 07 jari 79   private Experiment fullExperiment;
2 26 Feb 07 jari 80
2 26 Feb 07 jari 81   /**
2 26 Feb 07 jari 82    * Holds Locus IDs, sorted by min. coord.
2 26 Feb 07 jari 83    */
2 26 Feb 07 jari 84   private String[] sortedLocusIDs;
2 26 Feb 07 jari 85
2 26 Feb 07 jari 86   /**
2 26 Feb 07 jari 87    * Holds starting or lower coord. (the smaller of 5' or 3' coordinate)
2 26 Feb 07 jari 88    */
2 26 Feb 07 jari 89   private int[] start;
2 26 Feb 07 jari 90
2 26 Feb 07 jari 91   /**
2 26 Feb 07 jari 92    * Holds ending or greater coord. (the greater of 5' or 3' coordinate)
2 26 Feb 07 jari 93    */
2 26 Feb 07 jari 94   private int[] end;
2 26 Feb 07 jari 95
2 26 Feb 07 jari 96   /**
2 26 Feb 07 jari 97    * Holds replicate Experiment indices
2 26 Feb 07 jari 98    */
2 26 Feb 07 jari 99   private int [][] replicates;
2 26 Feb 07 jari 100   
2 26 Feb 07 jari 101   /**
2 26 Feb 07 jari 102    * Indicates direction of transcription relative to chr. coordinate system
2 26 Feb 07 jari 103    */
2 26 Feb 07 jari 104   private boolean[] isForward;
2 26 Feb 07 jari 105
2 26 Feb 07 jari 106   /**
2 26 Feb 07 jari 107    * Holds information for rendering orfs that overlap
2 26 Feb 07 jari 108    */
2 26 Feb 07 jari 109   private int[] strata;
2 26 Feb 07 jari 110   private String locusIDFieldName;
2 26 Feb 07 jari 111   
2 26 Feb 07 jari 112   private int maxStrata;
2 26 Feb 07 jari 113
2 26 Feb 07 jari 114   private LEMHeader header;
2 26 Feb 07 jari 115     
2 26 Feb 07 jari 116   private int numberOfSamples;
2 26 Feb 07 jari 117   private int locusCount;
2 26 Feb 07 jari 118
2 26 Feb 07 jari 119   private int bpPerPixel = 50;
2 26 Feb 07 jari 120
2 26 Feb 07 jari 121   private IFramework framework;
2 26 Feb 07 jari 122   private IData data;
2 26 Feb 07 jari 123   
2 26 Feb 07 jari 124   //scaling options
2 26 Feb 07 jari 125   private boolean fixedLengthArrows = true;
2 26 Feb 07 jari 126   private boolean showOpenAreas = false;
2 26 Feb 07 jari 127
2 26 Feb 07 jari 128   //arrow coordinate arrays for rendering
2 26 Feb 07 jari 129   private int[] x = new int[8];
2 26 Feb 07 jari 130   private int[] y = new int[8];
2 26 Feb 07 jari 131
2 26 Feb 07 jari 132   private int minArrowLength = 15;
2 26 Feb 07 jari 133   private int maxArrowLength = 100;
2 26 Feb 07 jari 134   private int currArrowLength = 25;
2 26 Feb 07 jari 135   private int minArrowHead = 10;
2 26 Feb 07 jari 136   private int arrowWidth = 10;  
2 26 Feb 07 jari 137   private int currArrowHead;
2 26 Feb 07 jari 138   private int currArrowShank;
2 26 Feb 07 jari 139   private int wingWidth = 5;  
2 26 Feb 07 jari 140   private int maxIntergenicLength = 100;
2 26 Feb 07 jari 141
2 26 Feb 07 jari 142   //column spacing is a function of maxStrata, fixedLengthArrows
2 26 Feb 07 jari 143   private int columnSpacing = 40;
2 26 Feb 07 jari 144
2 26 Feb 07 jari 145   //pixel coordinate information, updated during scaling
2 26 Feb 07 jari 146   private int maxPixelCoord = 0;
2 26 Feb 07 jari 147   private int[] coordStarts;
2 26 Feb 07 jari 148   private int[] coordEnds;
2 26 Feb 07 jari 149   private int[] annYPos;
2 26 Feb 07 jari 150
2 26 Feb 07 jari 151   private int currX;
2 26 Feb 07 jari 152   private int currY;
2 26 Feb 07 jari 153   
2 26 Feb 07 jari 154   private int X_ORIGIN = 20;
2 26 Feb 07 jari 155   private int Y_ORIGIN = 7;
2 26 Feb 07 jari 156
2 26 Feb 07 jari 157   private int DEFAULT_COLUMN_SPACING = 30;
2 26 Feb 07 jari 158   private int DEFAULT_STRATA_SPACING = 20;
2 26 Feb 07 jari 159
2 26 Feb 07 jari 160   //arrow spacing in y axis
2 26 Feb 07 jari 161   private int INTERGENIC_ESTIMATE = 5;
2 26 Feb 07 jari 162   private int CONTIG_ARROW_Y_SPACING = 2;
2 26 Feb 07 jari 163   private int NONCONTIG_ARROW_Y_SPACING = 10;
2 26 Feb 07 jari 164
2 26 Feb 07 jari 165   private int COORD_LEFT_MARGIN = 25;
2 26 Feb 07 jari 166   private int COORD_SEPARATOR_MARGIN = 10;
2 26 Feb 07 jari 167   private int LEFT_LOCUS_MARGIN = 20;
2 26 Feb 07 jari 168   private int RIGHT_LOCUS_MARGIN = 30;
2 26 Feb 07 jari 169   private int RIGHT_MARGIN = 10;
2 26 Feb 07 jari 170   
2 26 Feb 07 jari 171   //annotation width (for X offset determination)
2 26 Feb 07 jari 172   private int fullAnnotationWidth;
2 26 Feb 07 jari 173   private int locusMaxWidth;
2 26 Feb 07 jari 174   private int startMaxWidth;
2 26 Feb 07 jari 175   private int endMaxWidth;
2 26 Feb 07 jari 176   private int annotationWidth;
2 26 Feb 07 jari 177   private int viewerWidth;
2 26 Feb 07 jari 178   private int fieldIndex = 0;
2 26 Feb 07 jari 179
2 26 Feb 07 jari 180   //current color mode option
2 26 Feb 07 jari 181   private int colorMode;
2 26 Feb 07 jari 182
2 26 Feb 07 jari 183   //color mode constants
2 26 Feb 07 jari 184   public static final int COLOR_MODE_GRADIENT = 0;
2 26 Feb 07 jari 185   public static final int COLOR_MODE_2_BIN = 1;
2 26 Feb 07 jari 186   public static final int COLOR_MODE_4_BIN = 2;
2 26 Feb 07 jari 187
2 26 Feb 07 jari 188   //gradient images, grad. type flag, limits
2 26 Feb 07 jari 189   private BufferedImage posColorImage;
2 26 Feb 07 jari 190   private BufferedImage negColorImage;
2 26 Feb 07 jari 191   private boolean useDoubleGradient = true;
2 26 Feb 07 jari 192
2 26 Feb 07 jari 193   //min and max for gradient option, set from main menu
2 26 Feb 07 jari 194   private float minValue = -3f;
2 26 Feb 07 jari 195   private float maxValue = 3f;
2 26 Feb 07 jari 196   private float midValue = 0f;  
2 26 Feb 07 jari 197
2 26 Feb 07 jari 198   //bin colors
2 26 Feb 07 jari 199   private Color lowestColor = new Color(10, 159, 1);
2 26 Feb 07 jari 200   private Color lowerColor = new Color(187, 240, 181);
2 26 Feb 07 jari 201   private Color midPointColor = Color.white;
2 26 Feb 07 jari 202   private Color higherColor = new Color(243, 169, 160);
2 26 Feb 07 jari 203   private Color highestColor = Color.red;
2 26 Feb 07 jari 204   private Color missingColor = new Color(128, 128, 128);
2 26 Feb 07 jari 205   
2 26 Feb 07 jari 206   //bin cutoffs
2 26 Feb 07 jari 207   private float cutoff1 = -3f;
2 26 Feb 07 jari 208   private float cutoff2 = -1f;
2 26 Feb 07 jari 209   private float midBinValue = 0f;
2 26 Feb 07 jari 210   private float cutoff3 = 1f;
2 26 Feb 07 jari 211   private float cutoff4 = 3f;
2 26 Feb 07 jari 212   
2 26 Feb 07 jari 213   //highlight rendering fields
2 26 Feb 07 jari 214   private boolean highlighted = false;
2 26 Feb 07 jari 215   private int highlightStart;
2 26 Feb 07 jari 216   private int highlightEnd;
2 26 Feb 07 jari 217   private int highlightedIndex;
2 26 Feb 07 jari 218       
2 26 Feb 07 jari 219   //clip bound determination fields
2 26 Feb 07 jari 220   private int [][] boundingRanges;
2 26 Feb 07 jari 221   private int boundryCount = 20;
2 26 Feb 07 jari 222   private int clipY1;
2 26 Feb 07 jari 223   private int clipY2;
2 26 Feb 07 jari 224
2 26 Feb 07 jari 225   private Vector activeInfoDialogs;
2 26 Feb 07 jari 226   
2 26 Feb 07 jari 227   //thumbnail and navigation aid
2 26 Feb 07 jari 228   private LEMThumbNail thumbnail;
2 26 Feb 07 jari 229   
2 26 Feb 07 jari 230   //Locus selection
2 26 Feb 07 jari 231   private Vector selectedIndicesVector;
2 26 Feb 07 jari 232   private LEMSelectionEditor selectionEditor;
2 26 Feb 07 jari 233   private boolean [] selected;
2 26 Feb 07 jari 234
2 26 Feb 07 jari 235   private JPopupMenu menu;
2 26 Feb 07 jari 236
2 26 Feb 07 jari 237   private boolean showAllReplicates = false;
2 26 Feb 07 jari 238   private int maxNumReps;
2 26 Feb 07 jari 239   private int maxEndBaseLocation;
2 26 Feb 07 jari 240   private int replicateSpacing = 22;
2 26 Feb 07 jari 241   private float replicateLengthFraction = 0.6f;
2 26 Feb 07 jari 242   
2 26 Feb 07 jari 243   //EH state-saving
2 26 Feb 07 jari 244   private int exptID;
2 26 Feb 07 jari 245   
2 26 Feb 07 jari 246   /* (non-Javadoc)
2 26 Feb 07 jari 247    * @see org.tigr.microarray.mev.cluster.gui.IViewer#getExpression()
2 26 Feb 07 jari 248    */
2 26 Feb 07 jari 249   public Expression getExpression(){
2 26 Feb 07 jari 250     return new Expression(this, this.getClass(), "new", 
2 26 Feb 07 jari 251         new Object[]{new Integer(exptID), fullExperiment.getMatrix(), experiment.getMatrix(), 
2 26 Feb 07 jari 252         fullExperiment.getColumns(), fullExperiment.getRows(), experiment.getColumns(), experiment.getRows(),
2 26 Feb 07 jari 253         this.sortedLocusIDs, this.start, this.end, this.replicates, this.isForward,
2 26 Feb 07 jari 254         this.strata, new String(""), this.locusIDFieldName});
2 26 Feb 07 jari 255   }
2 26 Feb 07 jari 256   
2 26 Feb 07 jari 257   public LinearExpressionMapViewer(Integer exptID, FloatMatrix fullExptFloatMatrix, FloatMatrix redExptFloatMatrix, 
2 26 Feb 07 jari 258       int[] fullCols, int[] fullRows, int[] redCols, int[] redRows,
2 26 Feb 07 jari 259       String[] sortedLocusIDs,
2 26 Feb 07 jari 260       int[] sortedStartArray, int[] sortedEndArray, int [][] replicates, boolean[] isForward,
2 26 Feb 07 jari 261       int[] strata, String chrID, String locusIDFieldName){
2 26 Feb 07 jari 262     this(new Experiment(fullCols, fullRows, exptID.intValue(), fullExptFloatMatrix), new Experiment(redCols, redRows, 0, redExptFloatMatrix), sortedLocusIDs,
2 26 Feb 07 jari 263         sortedStartArray, sortedEndArray, replicates, isForward,
2 26 Feb 07 jari 264         strata, chrID, locusIDFieldName);
2 26 Feb 07 jari 265   }
2 26 Feb 07 jari 266   /**
2 26 Feb 07 jari 267    * LinearExpressionMapViewer Description: Provides a multiple sample
2 26 Feb 07 jari 268    * expression view that is organized by chromosomal coordinates Each
2 26 Feb 07 jari 269    * chromosome, if there is more than one, will have a dedicated LEM in which
2 26 Feb 07 jari 270    * Loci are arranged based on coordinate information in a linear,
2 26 Feb 07 jari 271    * top-to-bottom fashion in the viewer. Samples are displayed in parallel
2 26 Feb 07 jari 272    * lines in the viewer.
2 26 Feb 07 jari 273    * 
2 26 Feb 07 jari 274    * Fixed arrow length indicates a more compressed view where sequence
2 26 Feb 07 jari 275    * lengths are not rendered based on length. In this mode all overlapping
2 26 Feb 07 jari 276    * sequences will be on the same line rather than offset and intergenic
2 26 Feb 07 jari 277    * spaces will be of uniform length.
2 26 Feb 07 jari 278    * 
2 26 Feb 07 jari 279    * @param fullExperiment
2 26 Feb 07 jari 280    *            The current Experiment from IFramwork
2 26 Feb 07 jari 281    * @param reducedExperiment
2 26 Feb 07 jari 282    *            The reduced and sorted (by min coord.) Experiment
2 26 Feb 07 jari 283    * @param sortedLocusIDs
2 26 Feb 07 jari 284    *            Sorted Locus IDs
2 26 Feb 07 jari 285    * @param sortedStartArray
2 26 Feb 07 jari 286    *            Sorted min coordinates for each loci.
2 26 Feb 07 jari 287    * @param sortedEndArray
2 26 Feb 07 jari 288    *            Sorted max coordinates for each loci.
2 26 Feb 07 jari 289    * @param isForward
2 26 Feb 07 jari 290    *            Indicates if a loci is transcribe forward or reverse (rel. to
2 26 Feb 07 jari 291    *            coord. system)
2 26 Feb 07 jari 292    * @param strata
2 26 Feb 07 jari 293    *            renders loci that overlap as an offset from the main linear
2 26 Feb 07 jari 294    *            map.
2 26 Feb 07 jari 295    * @param chrID
2 26 Feb 07 jari 296    *            Identifies the chromosome in view.
2 26 Feb 07 jari 297    */
2 26 Feb 07 jari 298   public LinearExpressionMapViewer(Experiment fullExperiment,
2 26 Feb 07 jari 299       Experiment reducedExperiment, String[] sortedLocusIDs,
2 26 Feb 07 jari 300       int[] sortedStartArray, int[] sortedEndArray, int [][] replicates, boolean[] isForward,
2 26 Feb 07 jari 301       int[] strata, String chrID, String locusIDFieldName) {
2 26 Feb 07 jari 302     
2 26 Feb 07 jari 303     this.fullExperiment = fullExperiment;
2 26 Feb 07 jari 304     this.experiment = reducedExperiment;
2 26 Feb 07 jari 305     this.numberOfSamples = experiment.getNumberOfSamples();
2 26 Feb 07 jari 306     this.sortedLocusIDs = sortedLocusIDs;
2 26 Feb 07 jari 307     this.start = sortedStartArray;
2 26 Feb 07 jari 308     this.end = sortedEndArray;
2 26 Feb 07 jari 309     this.replicates = replicates;
2 26 Feb 07 jari 310     this.isForward = isForward;
2 26 Feb 07 jari 311     this.strata = strata;
2 26 Feb 07 jari 312     this.locusIDFieldName = locusIDFieldName;
2 26 Feb 07 jari 313     this.locusCount = sortedLocusIDs.length;
2 26 Feb 07 jari 314
2 26 Feb 07 jari 315     //constrain bin size to 50 loci
2 26 Feb 07 jari 316     boundryCount = locusCount/50;
2 26 Feb 07 jari 317     
2 26 Feb 07 jari 318     this.activeInfoDialogs = new Vector();
2 26 Feb 07 jari 319     this.selectedIndicesVector = new Vector();
2 26 Feb 07 jari 320     this.selected = new boolean[locusCount];
2 26 Feb 07 jari 321     
2 26 Feb 07 jari 322     this.maxNumReps = 0;
2 26 Feb 07 jari 323     for(int i = 0; i < replicates.length; i++) {
2 26 Feb 07 jari 324       this.maxNumReps = Math.max(this.maxNumReps, replicates[i].length);
2 26 Feb 07 jari 325     }
2 26 Feb 07 jari 326       
2 26 Feb 07 jari 327     //constrain initial size of *scaled* map to 500-10000 pixels high.
2 26 Feb 07 jari 328     if ((int) (sortedEndArray[sortedEndArray.length - 1] / bpPerPixel) > 10000)
2 26 Feb 07 jari 329       bpPerPixel = (int) (sortedEndArray[sortedEndArray.length - 1] / 10000);
2 26 Feb 07 jari 330     else if ((int) (sortedEndArray[sortedEndArray.length - 1] / bpPerPixel) < 500)
2 26 Feb 07 jari 331       bpPerPixel = (int) (sortedEndArray[sortedEndArray.length - 1] / 500);
2 26 Feb 07 jari 332     if (bpPerPixel == 0)
2 26 Feb 07 jari 333       bpPerPixel = 1;
2 26 Feb 07 jari 334
2 26 Feb 07 jari 335     //initializes for scaled representation
2 26 Feb 07 jari 336     coordStarts = new int[start.length];
2 26 Feb 07 jari 337     coordEnds = new int[end.length];
2 26 Feb 07 jari 338     annYPos = new int[sortedLocusIDs.length];
2 26 Feb 07 jari 339
2 26 Feb 07 jari 340     this.boundingRanges = new int[boundryCount][4];
2 26 Feb 07 jari 341     
2 26 Feb 07 jari 342     updateCoords();
2 26 Feb 07 jari 343
2 26 Feb 07 jari 344     maxStrata = 0;
2 26 Feb 07 jari 345     maxEndBaseLocation = 0;
2 26 Feb 07 jari 346     for (int i = 0; i < strata.length; i++) {
2 26 Feb 07 jari 347       if (strata[i] > maxStrata) {
2 26 Feb 07 jari 348         maxStrata = strata[i];        
2 26 Feb 07 jari 349       }
2 26 Feb 07 jari 350       //reverse search for largest end location
2 26 Feb 07 jari 351       if(maxEndBaseLocation < end[end.length-i-1])
2 26 Feb 07 jari 352         maxEndBaseLocation = end[end.length-i-1];
2 26 Feb 07 jari 353     }
2 26 Feb 07 jari 354
2 26 Feb 07 jari 355     updateColumnSpacing();
2 26 Feb 07 jari 356     setBackground(Color.white);
2 26 Feb 07 jari 357
2 26 Feb 07 jari 358     negColorImage = createGradient(lowestColor, midPointColor);
2 26 Feb 07 jari 359     posColorImage = createGradient(midPointColor, highestColor);
2 26 Feb 07 jari 360
2 26 Feb 07 jari 361     updateLocusAnnotationWidth();
2 26 Feb 07 jari 362
2 26 Feb 07 jari 363     colorMode = COLOR_MODE_GRADIENT;
2 26 Feb 07 jari 364     
2 26 Feb 07 jari 365     header = new LEMHeader(experiment);
2 26 Feb 07 jari 366     header.setLeftInset(this.X_ORIGIN); // -arrowWidth/2-wingWidth);
2 26 Feb 07 jari 367     header.setArrowWingWidth(wingWidth);
2 26 Feb 07 jari 368     header.setArrowWidth(arrowWidth);
2 26 Feb 07 jari 369
2 26 Feb 07 jari 370     LEMListener listener = new LEMListener();
2 26 Feb 07 jari 371     createPopupMenu(listener);
2 26 Feb 07 jari 372     this.addMouseListener(listener);
2 26 Feb 07 jari 373     this.addMouseMotionListener(listener);
2 26 Feb 07 jari 374   }
2 26 Feb 07 jari 375   /**
2 26 Feb 07 jari 376    * EH - State-saving constructor
2 26 Feb 07 jari 377    */
2 26 Feb 07 jari 378   public LinearExpressionMapViewer(Integer exptID, Integer numberOfSamples, String[] sortedLocusIDs,
2 26 Feb 07 jari 379       int[] sortedStartArray, int[] sortedEndArray, int [][] replicates, boolean[] isForward,
2 26 Feb 07 jari 380       int[] strata, String chrID, String locusIDFieldName) {
2 26 Feb 07 jari 381     this.exptID = exptID.intValue();
2 26 Feb 07 jari 382     this.numberOfSamples = numberOfSamples.intValue();
2 26 Feb 07 jari 383     this.sortedLocusIDs = sortedLocusIDs;
2 26 Feb 07 jari 384     this.start = sortedStartArray;
2 26 Feb 07 jari 385     this.end = sortedEndArray;
2 26 Feb 07 jari 386     this.replicates = replicates;
2 26 Feb 07 jari 387     this.isForward = isForward;
2 26 Feb 07 jari 388     this.strata = strata;
2 26 Feb 07 jari 389     this.locusIDFieldName = locusIDFieldName;
2 26 Feb 07 jari 390     this.locusCount = sortedLocusIDs.length;
2 26 Feb 07 jari 391
2 26 Feb 07 jari 392     //constrain bin size to 50 loci
2 26 Feb 07 jari 393     boundryCount = locusCount/50;
2 26 Feb 07 jari 394     
2 26 Feb 07 jari 395     this.activeInfoDialogs = new Vector();
2 26 Feb 07 jari 396     this.selectedIndicesVector = new Vector();
2 26 Feb 07 jari 397     this.selected = new boolean[locusCount];
2 26 Feb 07 jari 398     
2 26 Feb 07 jari 399     this.maxNumReps = 0;
2 26 Feb 07 jari 400     for(int i = 0; i < replicates.length; i++) {
2 26 Feb 07 jari 401       this.maxNumReps = Math.max(this.maxNumReps, replicates[i].length);
2 26 Feb 07 jari 402     }
2 26 Feb 07 jari 403       
2 26 Feb 07 jari 404     //constrain initial size of *scaled* map to 500-10000 pixels high.
2 26 Feb 07 jari 405     if ((int) (sortedEndArray[sortedEndArray.length - 1] / bpPerPixel) > 10000)
2 26 Feb 07 jari 406       bpPerPixel = (int) (sortedEndArray[sortedEndArray.length - 1] / 10000);
2 26 Feb 07 jari 407     else if ((int) (sortedEndArray[sortedEndArray.length - 1] / bpPerPixel) < 500)
2 26 Feb 07 jari 408       bpPerPixel = (int) (sortedEndArray[sortedEndArray.length - 1] / 500);
2 26 Feb 07 jari 409     if (bpPerPixel == 0)
2 26 Feb 07 jari 410       bpPerPixel = 1;
2 26 Feb 07 jari 411
2 26 Feb 07 jari 412     //initializes for scaled representation
2 26 Feb 07 jari 413     coordStarts = new int[start.length];
2 26 Feb 07 jari 414     coordEnds = new int[end.length];
2 26 Feb 07 jari 415     annYPos = new int[sortedLocusIDs.length];
2 26 Feb 07 jari 416
2 26 Feb 07 jari 417     this.boundingRanges = new int[boundryCount][4];
2 26 Feb 07 jari 418     
2 26 Feb 07 jari 419     updateCoords();
2 26 Feb 07 jari 420
2 26 Feb 07 jari 421     maxStrata = 0;
2 26 Feb 07 jari 422     maxEndBaseLocation = 0;
2 26 Feb 07 jari 423     for (int i = 0; i < strata.length; i++) {
2 26 Feb 07 jari 424       if (strata[i] > maxStrata) {
2 26 Feb 07 jari 425         maxStrata = strata[i];        
2 26 Feb 07 jari 426       }
2 26 Feb 07 jari 427       //reverse search for largest end location
2 26 Feb 07 jari 428       if(maxEndBaseLocation < end[end.length-i-1])
2 26 Feb 07 jari 429         maxEndBaseLocation = end[end.length-i-1];
2 26 Feb 07 jari 430     }
2 26 Feb 07 jari 431
2 26 Feb 07 jari 432     updateColumnSpacing();
2 26 Feb 07 jari 433     setBackground(Color.white);
2 26 Feb 07 jari 434
2 26 Feb 07 jari 435     negColorImage = createGradient(lowestColor, midPointColor);
2 26 Feb 07 jari 436     posColorImage = createGradient(midPointColor, highestColor);
2 26 Feb 07 jari 437
2 26 Feb 07 jari 438     updateLocusAnnotationWidth();
2 26 Feb 07 jari 439
2 26 Feb 07 jari 440     colorMode = COLOR_MODE_GRADIENT;
2 26 Feb 07 jari 441     
2 26 Feb 07 jari 442
2 26 Feb 07 jari 443   }
2 26 Feb 07 jari 444   
2 26 Feb 07 jari 445   public Experiment getExperiment(){
2 26 Feb 07 jari 446     return experiment;
2 26 Feb 07 jari 447   }
2 26 Feb 07 jari 448   
2 26 Feb 07 jari 449   /**
2 26 Feb 07 jari 450    * @see org.tigr.microarray.mev.cluster.gui.IViewer#setExperiment(org.tigr.microarray.mev.cluster.gui.Experiment)
2 26 Feb 07 jari 451    */
2 26 Feb 07 jari 452   public void setExperiment(Experiment e) {
2 26 Feb 07 jari 453   }
2 26 Feb 07 jari 454
2 26 Feb 07 jari 455
2 26 Feb 07 jari 456
2 26 Feb 07 jari 457   
2 26 Feb 07 jari 458   /**
2 26 Feb 07 jari 459    * Paints the graphics context of the viewer
2 26 Feb 07 jari 460    */
2 26 Feb 07 jari 461   public void paint(Graphics g) {
2 26 Feb 07 jari 462     super.paint(g);
2 26 Feb 07 jari 463     
2 26 Feb 07 jari 464     Font font = g.getFont();
2 26 Feb 07 jari 465     Font boldFont = new Font(font.getFontName(), Font.BOLD, font.getSize());
2 26 Feb 07 jari 466     FontMetrics fm = g.getFontMetrics();
2 26 Feb 07 jari 467     
2 26 Feb 07 jari 468     Graphics2D g2 = (Graphics2D) g;
2 26 Feb 07 jari 469     
2 26 Feb 07 jari 470     Object obj = this.getParent();
2 26 Feb 07 jari 471     Rectangle visRect = ((JViewport)obj).getViewRect();
2 26 Feb 07 jari 472     
2 26 Feb 07 jari 473     //obtain the visible rectangle to get clip bounds
2 26 Feb 07 jari 474     if(visRect != null) {
2 26 Feb 07 jari 475       clipY1 = visRect.y;
2 26 Feb 07 jari 476       clipY2 = clipY1+visRect.height;
2 26 Feb 07 jari 477     } else {
2 26 Feb 07 jari 478       visRect = g.getClipBounds();
2 26 Feb 07 jari 479       if(visRect != null) {
2 26 Feb 07 jari 480         clipY1 = visRect.y;
2 26 Feb 07 jari 481         clipY2 = clipY1+visRect.height;      
2 26 Feb 07 jari 482       } else {
2 26 Feb 07 jari 483         clipY1 = 0; 
2 26 Feb 07 jari 484         clipY2 = getHeight();
2 26 Feb 07 jari 485       }      
2 26 Feb 07 jari 486     }
2 26 Feb 07 jari 487     
2 26 Feb 07 jari 488     //clip boundry sections
2 26 Feb 07 jari 489     int [] bounds = getBoundingIndices(visRect.y, visRect.y+visRect.height);
2 26 Feb 07 jari 490     
2 26 Feb 07 jari 491     g.setColor(Color.blue);
2 26 Feb 07 jari 492     
2 26 Feb 07 jari 493     //hiding replicates    
2 26 Feb 07 jari 494     if(!this.showAllReplicates) {      
2 26 Feb 07 jari 495       
2 26 Feb 07 jari 496       currX = X_ORIGIN + this.arrowWidth/2 + this.wingWidth;
2 26 Feb 07 jari 497       currY = Y_ORIGIN;
2 26 Feb 07 jari 498       
2 26 Feb 07 jari 499       //highlighter
2 26 Feb 07 jari 500       if(highlighted) {
2 26 Feb 07 jari 501         Composite composite = g2.getComposite();                  
2 26 Feb 07 jari 502         g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f));
2 26 Feb 07 jari 503         
2 26 Feb 07 jari 504         if(fixedLengthArrows)
2 26 Feb 07 jari 505           g2.fillRect(0, highlightStart, visRect.width, highlightEnd - highlightStart);
2 26 Feb 07 jari 506         else {
2 26 Feb 07 jari 507           g2.setColor(Color.blue);
2 26 Feb 07 jari 508           g2.fillRect(0, highlightStart, columnSpacing*numberOfSamples+wingWidth+arrowWidth/2+COORD_LEFT_MARGIN/2, highlightEnd - highlightStart);
2 26 Feb 07 jari 509           g2.setColor(Color.black);
2 26 Feb 07 jari 510           g2.fillRect(columnSpacing*numberOfSamples+wingWidth+arrowWidth/2+COORD_LEFT_MARGIN/2, annYPos[highlightedIndex]- fm.getHeight(), this.viewerWidth-columnSpacing*numberOfSamples, 20);//visRect.width-columnSpacing*numberOfSamples, fm.getHeight()+fm.getDescent());      
2 26 Feb 07 jari 511         }
2 26 Feb 07 jari 512         g2.setComposite(composite);
2 26 Feb 07 jari 513       }
2 26 Feb 07 jari 514       
2 26 Feb 07 jari 515       //lines 
2 26 Feb 07 jari 516       for (int j = 0; j < this.numberOfSamples; j++) {
2 26 Feb 07 jari 517         if (visRect.y < 10)
2 26 Feb 07 jari 518           g2.fillRoundRect(currX - 5, 0, 10, 5, 3, 3);        
2 26 Feb 07 jari 519         
2 26 Feb 07 jari 520         g.drawLine(currX, visRect.y, currX, visRect.y + visRect.height);
2 26 Feb 07 jari 521         currX += columnSpacing;
2 26 Feb 07 jari 522       }
2 26 Feb 07 jari 523       
2 26 Feb 07 jari 524       for (int i = bounds[0]; i <= bounds[1]; i++) {
2 26 Feb 07 jari 525         
2 26 Feb 07 jari 526         //render selection markers
2 26 Feb 07 jari 527         if(selected[i]) {
2 26 Feb 07 jari 528           Color color = g.getColor();
2 26 Feb 07 jari 529           g.setColor(Color.red);
2 26 Feb 07 jari 530           g.fillRoundRect(4, coordStarts[i] + 2, 8, coordEnds[i] - coordStarts[i] - 4, 2, 1);
2 26 Feb 07 jari 531           g.setColor(Color.black);        
2 26 Feb 07 jari 532           g.drawRoundRect(4, coordStarts[i] + 2, 8, coordEnds[i] - coordStarts[i] - 4, 2, 2);
2 26 Feb 07 jari 533           g.setColor(color);
2 26 Feb 07 jari 534         }
2 26 Feb 07 jari 535         
2 26 Feb 07 jari 536         currX = X_ORIGIN + this.arrowWidth/2 + this.wingWidth;
2 26 Feb 07 jari 537         
2 26 Feb 07 jari 538         if(!fixedLengthArrows)
2 26 Feb 07 jari 539           currX += strata[i] * DEFAULT_STRATA_SPACING;
2 26 Feb 07 jari 540         
2 26 Feb 07 jari 541         //render arrows
2 26 Feb 07 jari 542         for (int j = 0; j < this.numberOfSamples; j++) {
2 26 Feb 07 jari 543           renderArrow(g2, this.experiment.get(i, j), currX,
2 26 Feb 07 jari 544               this.coordStarts[i], this.coordEnds[i], isForward[i], (highlighted && i == highlightedIndex));
2 26 Feb 07 jari 545           currX += columnSpacing;
2 26 Feb 07 jari 546         }
2 26 Feb 07 jari 547         
2 26 Feb 07 jari 548         //if strata is shifted, then offset the annotaiton
2 26 Feb 07 jari 549         if(!fixedLengthArrows)
2 26 Feb 07 jari 550           currX += (this.maxStrata - strata[i]) * DEFAULT_STRATA_SPACING;
2 26 Feb 07 jari 551         
2 26 Feb 07 jari 552         //render locus id and annotation field
2 26 Feb 07 jari 553         if(!selected[i])
2 26 Feb 07 jari 554           g.setColor(Color.black);      
2 26 Feb 07 jari 555         else
2 26 Feb 07 jari 556           g.setColor(Color.red);
2 26 Feb 07 jari 557         
2 26 Feb 07 jari 558         //render annotation
2 26 Feb 07 jari 559         renderAnnotation(g, i, currX, font, boldFont);        
2 26 Feb 07 jari 560       }
2 26 Feb 07 jari 561       
2 26 Feb 07 jari 562       //untangle overlap issues by rendering highlighted text on top
2 26 Feb 07 jari 563       if(!fixedLengthArrows && highlighted) {
2 26 Feb 07 jari 564         blockSelectedTextArea(g2, currX, font);
2 26 Feb 07 jari 565         
2 26 Feb 07 jari 566         if(!selected[highlightedIndex])
2 26 Feb 07 jari 567           g.setColor(Color.black);      
2 26 Feb 07 jari 568         else
2 26 Feb 07 jari 569           g.setColor(Color.red);
2 26 Feb 07 jari 570         
2 26 Feb 07 jari 571         renderAnnotation(g, this.highlightedIndex, currX, font, boldFont);
2 26 Feb 07 jari 572       }
2 26 Feb 07 jari 573       
2 26 Feb 07 jari 574     } else {
2 26 Feb 07 jari 575       
2 26 Feb 07 jari 576       currX = X_ORIGIN + this.arrowWidth/2 + this.wingWidth;
2 26 Feb 07 jari 577       currY = Y_ORIGIN;
2 26 Feb 07 jari 578       
2 26 Feb 07 jari 579       int repYIndent = (currArrowLength - (int)(this.currArrowLength * replicateLengthFraction))/2;
2 26 Feb 07 jari 580       
2 26 Feb 07 jari 581       //background shading
2 26 Feb 07 jari 582       Composite composite = g2.getComposite();                  
2 26 Feb 07 jari 583       g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f));
2 26 Feb 07 jari 584       Color color = g.getColor();
2 26 Feb 07 jari 585       g.setColor(Color.yellow);
2 26 Feb 07 jari 586       for(int j = 0; j < this.numberOfSamples; j++) {
2 26 Feb 07 jari 587         if(j%2 == 0) {
2 26 Feb 07 jari 588           g.fillRect(currX-this.wingWidth-this.arrowWidth/2-5, visRect.y, columnSpacing, visRect.y + visRect.height);
2 26 Feb 07 jari 589         }
2 26 Feb 07 jari 590         currX += columnSpacing;
2 26 Feb 07 jari 591       }
2 26 Feb 07 jari 592       g.setColor(color);
2 26 Feb 07 jari 593       g2.setComposite(composite);
2 26 Feb 07 jari 594             
2 26 Feb 07 jari 595       //reset currX
2 26 Feb 07 jari 596       currX = X_ORIGIN + this.arrowWidth/2 + this.wingWidth;
2 26 Feb 07 jari 597       
2 26 Feb 07 jari 598       //lines 
2 26 Feb 07 jari 599       for (int j = 0; j < this.numberOfSamples; j++) {
2 26 Feb 07 jari 600         if (visRect.y < 10)
2 26 Feb 07 jari 601           g2.fillRoundRect(currX - 5, 0, 10, 5, 3, 3);                
2 26 Feb 07 jari 602         g.drawLine(currX, visRect.y, currX, visRect.y + visRect.height);        
2 26 Feb 07 jari 603         currX += columnSpacing;        
2 26 Feb 07 jari 604       }      
2 26 Feb 07 jari 605       
2 26 Feb 07 jari 606       //highlighter
2 26 Feb 07 jari 607       if(highlighted) {
2 26 Feb 07 jari 608         composite = g2.getComposite();                  
2 26 Feb 07 jari 609         g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f));
2 26 Feb 07 jari 610         if(fixedLengthArrows)
2 26 Feb 07 jari 611           g2.fillRect(0, highlightStart, visRect.width, highlightEnd - highlightStart);
2 26 Feb 07 jari 612         else {
2 26 Feb 07 jari 613           g2.fillRect(0, highlightStart, columnSpacing*numberOfSamples, highlightEnd - highlightStart);
2 26 Feb 07 jari 614           g2.fillRect(columnSpacing*numberOfSamples, annYPos[highlightedIndex]- fm.getHeight(), visRect.width-columnSpacing*numberOfSamples, fm.getHeight()+fm.getDescent());      
2 26 Feb 07 jari 615         }
2 26 Feb 07 jari 616         g2.setComposite(composite);
2 26 Feb 07 jari 617       }
2 26 Feb 07 jari 618       
2 26 Feb 07 jari 619       for (int i = bounds[0]; i <= bounds[1]; i++) {
2 26 Feb 07 jari 620         
2 26 Feb 07 jari 621         currX = X_ORIGIN + this.arrowWidth/2 + this.wingWidth;
2 26 Feb 07 jari 622         
2 26 Feb 07 jari 623         for (int j = 0; j < this.numberOfSamples; j++) {
2 26 Feb 07 jari 624           renderArrow(g2, this.experiment.get(i, j), currX,
2 26 Feb 07 jari 625               this.coordStarts[i], this.coordEnds[i], isForward[i], false);
2 26 Feb 07 jari 626           
2 26 Feb 07 jari 627           for(int k = 0; k < replicates[i].length; k++) {
2 26 Feb 07 jari 628             renderArrow(g2, this.fullExperiment.get(replicates[i][k], j), 
2 26 Feb 07 jari 629                 currX + ((k+1) * replicateSpacing), coordStarts[i]+repYIndent, coordEnds[i]-repYIndent, isForward[i], false);
2 26 Feb 07 jari 630           }          
2 26 Feb 07 jari 631           currX += columnSpacing;
2 26 Feb 07 jari 632         }        
2 26 Feb 07 jari 633         currX += maxNumReps * replicateSpacing;
2 26 Feb 07 jari 634         
2 26 Feb 07 jari 635         //render locus id and annotation field
2 26 Feb 07 jari 636         g.setColor(Color.black);                      
2 26 Feb 07 jari 637         renderAnnotation(g, i, currX, font, boldFont);
2 26 Feb 07 jari 638         
2 26 Feb 07 jari 639         if(selected[i]) {
2 26 Feb 07 jari 640           color = g.getColor();
2 26 Feb 07 jari 641           g.setColor(Color.red);
2 26 Feb 07 jari 642           g.fillRoundRect(4, coordStarts[i] + 2, 8, coordEnds[i] - coordStarts[i] - 4, 2, 1);
2 26 Feb 07 jari 643           g.setColor(Color.black);        
2 26 Feb 07 jari 644           g.drawRoundRect(4, coordStarts[i] + 2, 8, coordEnds[i] - coordStarts[i] - 4, 2, 2);
2 26 Feb 07 jari 645           g.setColor(color);
2 26 Feb 07 jari 646         }
2 26 Feb 07 jari 647       }            
2 26 Feb 07 jari 648     }
2 26 Feb 07 jari 649   }
2 26 Feb 07 jari 650
2 26 Feb 07 jari 651   /**
2 26 Feb 07 jari 652    * Renders annotatation for the locus index (i).
2 26 Feb 07 jari 653    * @param g Graphics object
2 26 Feb 07 jari 654    * @param i Locus index
2 26 Feb 07 jari 655    * @param currX x pixel location to start annoation
2 26 Feb 07 jari 656    * @param font current font
2 26 Feb 07 jari 657    * @param boldFont bold font
2 26 Feb 07 jari 658    */
2 26 Feb 07 jari 659   private void renderAnnotation(Graphics g, int i, int currX, Font font, Font boldFont) {
2 26 Feb 07 jari 660     if (isForward[i]) {
2 26 Feb 07 jari 661       g.drawString(String.valueOf(start[i]), currX - columnSpacing
2 26 Feb 07 jari 662           + COORD_LEFT_MARGIN, annYPos[i]);
2 26 Feb 07 jari 663       g.drawString(String.valueOf(end[i]), currX - columnSpacing + this.COORD_LEFT_MARGIN
2 26 Feb 07 jari 664           + startMaxWidth + this.COORD_SEPARATOR_MARGIN, annYPos[i]);
2 26 Feb 07 jari 665     } else {
2 26 Feb 07 jari 666       g.drawString(String.valueOf(end[i]),
2 26 Feb 07 jari 667           currX - columnSpacing + this.COORD_LEFT_MARGIN, annYPos[i]);
2 26 Feb 07 jari 668       g.drawString(String.valueOf(start[i]), currX - columnSpacing
2 26 Feb 07 jari 669           + this.COORD_LEFT_MARGIN + startMaxWidth + this.COORD_SEPARATOR_MARGIN, annYPos[i]);
2 26 Feb 07 jari 670     }
2 26 Feb 07 jari 671     
2 26 Feb 07 jari 672     g.setFont(boldFont);
2 26 Feb 07 jari 673     g.drawString(sortedLocusIDs[i],
2 26 Feb 07 jari 674         currX - columnSpacing + this.COORD_LEFT_MARGIN + startMaxWidth + this.COORD_SEPARATOR_MARGIN
2 26 Feb 07 jari 675         + endMaxWidth + this.LEFT_LOCUS_MARGIN, annYPos[i]);
2 26 Feb 07 jari 676     g.setFont(font);
2 26 Feb 07 jari 677     
2 26 Feb 07 jari 678     
2 26 Feb 07 jari 679     g.drawString(data.getElementAttribute(fullExperiment.getGeneIndexMappedToData(replicates[i][0]), fieldIndex),
2 26 Feb 07 jari 680         currX - columnSpacing + this.COORD_LEFT_MARGIN + startMaxWidth 
2 26 Feb 07 jari 681         + this.COORD_SEPARATOR_MARGIN + endMaxWidth + this.LEFT_LOCUS_MARGIN + this.locusMaxWidth + this.RIGHT_LOCUS_MARGIN
2 26 Feb 07 jari 682         ,annYPos[i]);
2 26 Feb 07 jari 683
2 26 Feb 07 jari 684   }
2 26 Feb 07 jari 685
2 26 Feb 07 jari 686   /**
2 26 Feb 07 jari 687    * Used to bring hightlighted text to foreground when loci are scaled and overlap can occur
2 26 Feb 07 jari 688    * @param g2 Graphics2D object
2 26 Feb 07 jari 689    * @param currX current x cooridnate for rendering
2 26 Feb 07 jari 690    * @param font current font
2 26 Feb 07 jari 691    */
2 26 Feb 07 jari 692   private void blockSelectedTextArea(Graphics2D g2, int currX, Font font) {
2 26 Feb 07 jari 693     FontMetrics fm = g2.getFontMetrics();
2 26 Feb 07 jari 694     Color color = g2.getColor();
2 26 Feb 07 jari 695
2 26 Feb 07 jari 696     //set background to white
2 26 Feb 07 jari 697     g2.setColor(Color.white);
2 26 Feb 07 jari 698     g2.fillRect(columnSpacing*numberOfSamples+wingWidth+arrowWidth/2+COORD_LEFT_MARGIN/2, annYPos[highlightedIndex]- fm.getHeight(), this.viewerWidth-columnSpacing*numberOfSamples, 20);//visRect.width-columnSpacing*numberOfSamples, fm.getHeight()+fm.getDescent());          
2 26 Feb 07 jari 699     
2 26 Feb 07 jari 700     Composite composite = g2.getComposite();                  
2 26 Feb 07 jari 701     g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f));
2 26 Feb 07 jari 702
2 26 Feb 07 jari 703     g2.setColor(Color.black);
2 26 Feb 07 jari 704     g2.fillRect(columnSpacing*numberOfSamples+wingWidth+arrowWidth/2+COORD_LEFT_MARGIN/2, annYPos[highlightedIndex]- fm.getHeight(), this.viewerWidth-columnSpacing*numberOfSamples, 20);//visRect.width-columnSpacing*numberOfSamples, fm.getHeight()+fm.getDescent());          
2 26 Feb 07 jari 705       
2 26 Feb 07 jari 706     g2.setComposite(composite);
2 26 Feb 07 jari 707
2 26 Feb 07 jari 708     //diagnostic test
2 26 Feb 07 jari 709     g2.drawRect(columnSpacing*numberOfSamples+wingWidth+arrowWidth/2+COORD_LEFT_MARGIN/2, annYPos[highlightedIndex]- fm.getHeight(), this.viewerWidth-columnSpacing*numberOfSamples, 20);//visRect.width-columnSpacing*numberOfSamples, fm.getHeight()+fm.getDescent());          
2 26 Feb 07 jari 710     
2 26 Feb 07 jari 711     g2.setColor(color);
2 26 Feb 07 jari 712   }
2 26 Feb 07 jari 713
2 26 Feb 07 jari 714   
2 26 Feb 07 jari 715   /**
2 26 Feb 07 jari 716    * Updates the spacing between sample columns.  This is updated when rendering
2 26 Feb 07 jari 717    * and scaling options change.
2 26 Feb 07 jari 718    */
2 26 Feb 07 jari 719   private void updateColumnSpacing() {
2 26 Feb 07 jari 720     if(this.fixedLengthArrows && !this.showAllReplicates)
2 26 Feb 07 jari 721       columnSpacing = DEFAULT_COLUMN_SPACING;
2 26 Feb 07 jari 722     else
2 26 Feb 07 jari 723       columnSpacing = DEFAULT_STRATA_SPACING * maxStrata + DEFAULT_COLUMN_SPACING;    
2 26 Feb 07 jari 724
2 26 Feb 07 jari 725     if(this.showAllReplicates)
2 26 Feb 07 jari 726       columnSpacing = DEFAULT_COLUMN_SPACING + this.maxNumReps * this.replicateSpacing;
2 26 Feb 07 jari 727   }
2 26 Feb 07 jari 728
2 26 Feb 07 jari 729   /**
2 26 Feb 07 jari 730    * Renders a locus arrow
2 26 Feb 07 jari 731    * @param g graphics 2D object
2 26 Feb 07 jari 732    * @param value locus expression value
2 26 Feb 07 jari 733    * @param xCenter x coordinate for center of arrow
2 26 Feb 07 jari 734    * @param yStart y coordinate for arrow start
2 26 Feb 07 jari 735    * @param yEnd y coordinate for arrow end
2 26 Feb 07 jari 736    * @param forward indicates arrow is forward (down), or reverse (up)
2 26 Feb 07 jari 737    * @param highlighted Indicates if the arrow is highlighted
2 26 Feb 07 jari 738    */
2 26 Feb 07 jari 739   public void renderArrow(Graphics2D g, float value, int xCenter, int yStart,
2 26 Feb 07 jari 740       int yEnd, boolean forward, boolean highlighted) {
2 26 Feb 07 jari 741     Color startColor = g.getColor();
2 26 Feb 07 jari 742     currArrowHead = minArrowHead;
2 26 Feb 07 jari 743     currArrowShank = yEnd - yStart - currArrowHead;
2 26 Feb 07 jari 744     g.setColor(getColor(value));
2 26 Feb 07 jari 745
2 26 Feb 07 jari 746     if (forward) {
2 26 Feb 07 jari 747       x[0] = xCenter;
2 26 Feb 07 jari 748       y[0] = yStart;
2 26 Feb 07 jari 749       x[1] = xCenter + arrowWidth / 2;
2 26 Feb 07 jari 750       y[1] = yStart;
2 26 Feb 07 jari 751       x[2] = xCenter + arrowWidth / 2;
2 26 Feb 07 jari 752       y[2] = yStart + currArrowShank;
2 26 Feb 07 jari 753
2 26 Feb 07 jari 754       x[3] = xCenter + arrowWidth / 2 + wingWidth;
2 26 Feb 07 jari 755       y[3] = yStart + currArrowShank;
2 26 Feb 07 jari 756       x[4] = xCenter;
2 26 Feb 07 jari 757       y[4] = yStart + currArrowShank + currArrowHead;
2 26 Feb 07 jari 758       x[5] = xCenter - arrowWidth / 2 - wingWidth;
2 26 Feb 07 jari 759       y[5] = yStart + currArrowShank;
2 26 Feb 07 jari 760       x[6] = xCenter - arrowWidth / 2;
2 26 Feb 07 jari 761       y[6] = yStart + currArrowShank;
2 26 Feb 07 jari 762       x[7] = xCenter - arrowWidth / 2;
2 26 Feb 07 jari 763       y[7] = yStart;
2 26 Feb 07 jari 764     } else {
2 26 Feb 07 jari 765       x[0] = xCenter;
2 26 Feb 07 jari 766       y[0] = yEnd;
2 26 Feb 07 jari 767       x[1] = xCenter + arrowWidth / 2;
2 26 Feb 07 jari 768       y[1] = yEnd;
2 26 Feb 07 jari 769       x[2] = xCenter + arrowWidth / 2;
2 26 Feb 07 jari 770       y[2] = yEnd - currArrowShank;
2 26 Feb 07 jari 771
2 26 Feb 07 jari 772       x[3] = xCenter + arrowWidth / 2 + wingWidth;
2 26 Feb 07 jari 773       y[3] = yEnd - currArrowShank;
2 26 Feb 07 jari 774       x[4] = xCenter;
2 26 Feb 07 jari 775       y[4] = yEnd - currArrowShank - currArrowHead;
2 26 Feb 07 jari 776       x[5] = xCenter - arrowWidth / 2 - wingWidth;
2 26 Feb 07 jari 777       y[5] = yEnd - currArrowShank;
2 26 Feb 07 jari 778       x[6] = xCenter - arrowWidth / 2;
2 26 Feb 07 jari 779       y[6] = yEnd - currArrowShank;
2 26 Feb 07 jari 780       x[7] = xCenter - arrowWidth / 2;
2 26 Feb 07 jari 781       y[7] = yEnd;
2 26 Feb 07 jari 782     }
2 26 Feb 07 jari 783     g.fillPolygon(x, y, 8);
2 26 Feb 07 jari 784     g.setColor(Color.BLACK);
2 26 Feb 07 jari 785     g.drawPolygon(x, y, 8);
2 26 Feb 07 jari 786     
2 26 Feb 07 jari 787     
2 26 Feb 07 jari 788     //render anchors if posible over lap
2 26 Feb 07 jari 789     if(!fixedLengthArrows) { 
2 26 Feb 07 jari 790       if(highlighted)
2 26 Feb 07 jari 791         g.setColor(Color.red);
2 26 Feb 07 jari 792       else
2 26 Feb 07 jari 793         g.setColor(Color.white);
2 26 Feb 07 jari 794       g.fillOval(xCenter-1, (yStart+yEnd)/2-1, 4, 4);
2 26 Feb 07 jari 795       g.setColor(Color.black);
2 26 Feb 07 jari 796       g.drawOval(xCenter-2, (yStart+yEnd)/2-2, 4, 4);
2 26 Feb 07 jari 797     }
2 26 Feb 07 jari 798     
2 26 Feb 07 jari 799     g.setColor(startColor);
2 26 Feb 07 jari 800   }
2 26 Feb 07 jari 801
2 26 Feb 07 jari 802
2 26 Feb 07 jari 803   /**
2 26 Feb 07 jari 804    * Updates the pixel coordinates and the boundry array for cliping rendering support
2 26 Feb 07 jari 805    * These coordinates are used to define locus arrow positions for rendering and are updated
2 26 Feb 07 jari 806    * when scaling or rendering options are changed
2 26 Feb 07 jari 807    */
2 26 Feb 07 jari 808   private void updateCoords() {
2 26 Feb 07 jari 809
2 26 Feb 07 jari 810     int currY = Y_ORIGIN;
2 26 Feb 07 jari 811     int fontAscent = 0;
2 26 Feb 07 jari 812
2 26 Feb 07 jari 813     Graphics g = getGraphics();
2 26 Feb 07 jari 814     if (g != null) {
2 26 Feb 07 jari 815       FontMetrics fm = g.getFontMetrics();
2 26 Feb 07 jari 816       fontAscent = fm.getAscent();
2 26 Feb 07 jari 817     }
2 26 Feb 07 jari 818     
2 26 Feb 07 jari 819     maxPixelCoord = 0;
2 26 Feb 07 jari 820
2 26 Feb 07 jari 821     if (this.fixedLengthArrows && !showOpenAreas) {
2 26 Feb 07 jari 822       for (int i = 0; i < this.coordStarts.length; i++) {
2 26 Feb 07 jari 823         coordStarts[i] = currY;
2 26 Feb 07 jari 824         coordEnds[i] = currY + currArrowLength;
2 26 Feb 07 jari 825         currY = coordEnds[i] + CONTIG_ARROW_Y_SPACING;
2 26 Feb 07 jari 826         annYPos[i] = coordStarts[i] + (coordEnds[i] - coordStarts[i])/2 + fontAscent/2;
2 26 Feb 07 jari 827         maxPixelCoord = Math.max(maxPixelCoord, coordEnds[i]);
2 26 Feb 07 jari 828       }
2 26 Feb 07 jari 829     } else if (this.fixedLengthArrows && showOpenAreas) {
2 26 Feb 07 jari 830       coordStarts[0] = currY;
2 26 Feb 07 jari 831       coordEnds[0] = currY + currArrowLength;
2 26 Feb 07 jari 832       annYPos[0] = coordStarts[0] + (coordEnds[0] - coordStarts[0]) / 2;
2 26 Feb 07 jari 833       currY = coordEnds[0];
2 26 Feb 07 jari 834
2 26 Feb 07 jari 835       for (int i = 1; i < this.coordStarts.length; i++) {
2 26 Feb 07 jari 836         if (start[i] - end[i - 1] > INTERGENIC_ESTIMATE) {
2 26 Feb 07 jari 837           coordStarts[i] = currY + NONCONTIG_ARROW_Y_SPACING;
2 26 Feb 07 jari 838           currY = coordStarts[i];
2 26 Feb 07 jari 839         } else
2 26 Feb 07 jari 840           coordStarts[i] = currY;
2 26 Feb 07 jari 841
2 26 Feb 07 jari 842         coordEnds[i] = currY + currArrowLength;
2 26 Feb 07 jari 843         currY = coordEnds[i] + CONTIG_ARROW_Y_SPACING;
2 26 Feb 07 jari 844         annYPos[i] = coordStarts[i] + (coordEnds[i] - coordStarts[i])
2 26 Feb 07 jari 845             / 2 + fontAscent / 2;
2 26 Feb 07 jari 846
2 26 Feb 07 jari 847         maxPixelCoord = Math.max(maxPixelCoord, coordEnds[i]);
2 26 Feb 07 jari 848       }
2 26 Feb 07 jari 849     } else if (!this.fixedLengthArrows && showOpenAreas) {
2 26 Feb 07 jari 850       int offSet = 0;
2 26 Feb 07 jari 851       int oldEnd;
2 26 Feb 07 jari 852       int intergenicLength, diff;
2 26 Feb 07 jari 853       
2 26 Feb 07 jari 854       for (int i = 0; i < this.coordStarts.length; i++) {
2 26 Feb 07 jari 855
2 26 Feb 07 jari 856         coordStarts[i] = offSet + start[i] / this.bpPerPixel + Y_ORIGIN;
2 26 Feb 07 jari 857         coordEnds[i] = offSet + end[i] / this.bpPerPixel + Y_ORIGIN;
2 26 Feb 07 jari 858
2 26 Feb 07 jari 859         if (coordEnds[i] - coordStarts[i] < minArrowLength) {
2 26 Feb 07 jari 860           oldEnd = coordEnds[i];
2 26 Feb 07 jari 861           coordEnds[i] = coordStarts[i] + minArrowLength;
2 26 Feb 07 jari 862
2 26 Feb 07 jari 863           //offset subtracts old length and adds in minArrowLength
2 26 Feb 07 jari 864           offSet += minArrowLength - (oldEnd - coordStarts[i]);
2 26 Feb 07 jari 865         }
2 26 Feb 07 jari 866         
2 26 Feb 07 jari 867         //consider intergenic length max when showing open areas
2 26 Feb 07 jari 868         //if not at i == 0 check coordStarts[i] vs coordEnds[i-1]
2 26 Feb 07 jari 869         //relative to the max intergenic length
2 26 Feb 07 jari 870         //if greater then subtract a constant from start and end
2 26 Feb 07 jari 871         //(sub. amount that exceedes intergenic max)
2 26 Feb 07 jari 872         //should only occur on strata == 0
2 26 Feb 07 jari 873         
2 26 Feb 07 jari 874         if(i > 0) {
2 26 Feb 07 jari 875           intergenicLength = coordStarts[i]-coordEnds[i-1];
2 26 Feb 07 jari 876           if( intergenicLength > this.maxIntergenicLength) {
2 26 Feb 07 jari 877             coordStarts[i] -= (intergenicLength - maxIntergenicLength);
2 26 Feb 07 jari 878             coordEnds[i] -= (intergenicLength - maxIntergenicLength);                        
2 26 Feb 07 jari 879             offSet -= (intergenicLength-maxIntergenicLength);            
2 26 Feb 07 jari 880           }
2 26 Feb 07 jari 881         }
2 26 Feb 07 jari 882         
2 26 Feb 07 jari 883         annYPos[i] = coordStarts[i] + (coordEnds[i] - coordStarts[i])
2 26 Feb 07 jari 884             / 2 + fontAscent / 2;
2 26 Feb 07 jari 885         
2 26 Feb 07 jari 886         maxPixelCoord = Math.max(maxPixelCoord, coordEnds[i]);  
2 26 Feb 07 jari 887       }
2 26 Feb 07 jari 888             
2 26 Feb 07 jari 889     } else if (!this.fixedLengthArrows && !showOpenAreas) {
2 26 Feb 07 jari 890
2 26 Feb 07 jari 891       int oldEnd;
2 26 Feb 07 jari 892       
2 26 Feb 07 jari 893       for (int i = 0; i < this.coordStarts.length; i++) {
2 26 Feb 07 jari 894         coordStarts[i] = currY;// + start[i] / this.bpPerPixel;
2 26 Feb 07 jari 895         coordEnds[i] = currY + (end[i]-start[i]) / this.bpPerPixel;        
2 26 Feb 07 jari 896         if (coordEnds[i] - coordStarts[i] < minArrowLength) {
2 26 Feb 07 jari 897           coordEnds[i] = coordStarts[i] + minArrowLength;
2 26 Feb 07 jari 898           currY += minArrowLength+CONTIG_ARROW_Y_SPACING;
2 26 Feb 07 jari 899         } else {
2 26 Feb 07 jari 900           currY += coordEnds[i]-coordStarts[i] + CONTIG_ARROW_Y_SPACING;          
2 26 Feb 07 jari 901         }        
2 26 Feb 07 jari 902         annYPos[i] = coordStarts[i] + (coordEnds[i] - coordStarts[i])/ 2 + fontAscent / 2;                
2 26 Feb 07 jari 903         maxPixelCoord = Math.max(maxPixelCoord, coordEnds[i]);      
2 26 Feb 07 jari 904       }
2 26 Feb 07 jari 905     }
2 26 Feb 07 jari 906     
2 26 Feb 07 jari 907     //set viewer width
2 26 Feb 07 jari 908     viewerWidth = X_ORIGIN+columnSpacing*numberOfSamples-arrowWidth/2-wingWidth+fullAnnotationWidth;
2 26 Feb 07 jari 909       
2 26 Feb 07 jari 910     setPreferredSize(new Dimension(viewerWidth, maxPixelCoord + 5));
2 26 Feb 07 jari 911     setSize(viewerWidth, maxPixelCoord + 5);    
2 26 Feb 07 jari 912   
2 26 Feb 07 jari 913     setBoundingRanges();
2 26 Feb 07 jari 914
2 26 Feb 07 jari 915     if(this.thumbnail != null) {
2 26 Feb 07 jari 916       this.thumbnail.updateCoords(coordStarts, coordEnds, maxPixelCoord);
2 26 Feb 07 jari 917     }
2 26 Feb 07 jari 918   }
2 26 Feb 07 jari 919
2 26 Feb 07 jari 920   /**
2 26 Feb 07 jari 921    * Sets the boundry ranges based on number of boundaries and the range of pixel coordinates
2 26 Feb 07 jari 922    * These boundaries indicate locus indices that fall within the bounds of bins within the LEM
2 26 Feb 07 jari 923    * Using these bins can speed the search for specific loci index ranges that bound a y coordinate
2 26 Feb 07 jari 924    */
2 26 Feb 07 jari 925   private void setBoundingRanges() {    
2 26 Feb 07 jari 926     int chunkSize = (int)Math.ceil((this.maxPixelCoord+5)/(float)this.boundryCount);
2 26 Feb 07 jari 927     int [] range;
2 26 Feb 07 jari 928     for(int boundry = 0; boundry < boundingRanges.length; boundry++) {
2 26 Feb 07 jari 929       boundingRanges[boundry][0] = chunkSize*boundry;
2 26 Feb 07 jari 930       boundingRanges[boundry][1] = chunkSize*(boundry+1);
2 26 Feb 07 jari 931       range = getLociCoverage(chunkSize*boundry, chunkSize*(boundry+1));
2 26 Feb 07 jari 932       boundingRanges[boundry][2] = range[0];
2 26 Feb 07 jari 933       boundingRanges[boundry][3] = range[1];
2 26 Feb 07 jari 934     }
2 26 Feb 07 jari 935   }
2 26 Feb 07 jari 936
2 26 Feb 07 jari 937   /**
2 26 Feb 07 jari 938    * Returns the array of loci thata cover the [y2,y1] pixel range
2 26 Feb 07 jari 939    * @param y1 upper y coord
2 26 Feb 07 jari 940    * @param y2 lower y coord
2 26 Feb 07 jari 941    * @return
2 26 Feb 07 jari 942    */
2 26 Feb 07 jari 943   private int [] getLociCoverage(int y1, int y2) {
2 26 Feb 07 jari 944     int [] lowHigh = new int[2];
2 26 Feb 07 jari 945     lowHigh[0] = findNextLowestStart(y1);
2 26 Feb 07 jari 946     lowHigh[1] = findNextHighestStart(y2);    
2 26 Feb 07 jari 947     return lowHigh;    
2 26 Feb 07 jari 948   }
2 26 Feb 07 jari 949
2 26 Feb 07 jari 950   /**
2 26 Feb 07 jari 951    * recursive search for loci that contains the passed coord
2 26 Feb 07 jari 952    * @param coord y coordinate
2 26 Feb 07 jari 953    * @param index locus index
2 26 Feb 07 jari 954    * @param start start index
2 26 Feb 07 jari 955    * @param end end index
2 26 Feb 07 jari 956    * @return
2 26 Feb 07 jari 957    */
2 26 Feb 07 jari 958   public int findIndex(int coord, int index, int start, int end) {
2 26 Feb 07 jari 959     if(start == end)
2 26 Feb 07 jari 960       return start;
2 26 Feb 07 jari 961     if(coordStarts[index] > coord)    
2 26 Feb 07 jari 962       return findIndex(coord, start, (index-start)/2+start, index);
2 26 Feb 07 jari 963     else
2 26 Feb 07 jari 964       return findIndex(coord, index, (end-index)/2+start, end);
2 26 Feb 07 jari 965   }
2 26 Feb 07 jari 966
2 26 Feb 07 jari 967   /**
2 26 Feb 07 jari 968    * Returns the array of locus start values (low end values, sorted)
2 26 Feb 07 jari 969    * @return
2 26 Feb 07 jari 970    */
2 26 Feb 07 jari 971   public int [] getStartValues() {
2 26 Feb 07 jari 972     return this.start;
2 26 Feb 07 jari 973   }
2 26 Feb 07 jari 974   
2 26 Feb 07 jari 975   /**
2 26 Feb 07 jari 976    * Returns the mean float matrix ordered by loci location
2 26 Feb 07 jari 977    * @return
2 26 Feb 07 jari 978    */
2 26 Feb 07 jari 979   public FloatMatrix getLocusMeanMatrix() {
2 26 Feb 07 jari 980     return this.experiment.getMatrix();
2 26 Feb 07 jari 981   }
2 26 Feb 07 jari 982   
2 26 Feb 07 jari 983   /**
2 26 Feb 07 jari 984    * Returns the array of locus end values (higher end values)
2 26 Feb 07 jari 985    * @return
2 26 Feb 07 jari 986    */
2 26 Feb 07 jari 987   public int [] getEndValues() {
2 26 Feb 07 jari 988     return this.end;
2 26 Feb 07 jari 989   }
2 26 Feb 07 jari 990   
2 26 Feb 07 jari 991   /**
2 26 Feb 07 jari 992    * Returns the array that indicates locus direction
2 26 Feb 07 jari 993    * true == foward (down in LEM), false == reverse (up in LEM)
2 26 Feb 07 jari 994    * @return
2 26 Feb 07 jari 995    */
2 26 Feb 07 jari 996   public boolean [] getDirectionArray() {
2 26 Feb 07 jari 997     return this.isForward;
2 26 Feb 07 jari 998   }
2 26 Feb 07 jari 999
2 26 Feb 07 jari 1000   /**
2 26 Feb 07 jari 1001    * Return the array of locus ids
2 26 Feb 07 jari 1002    * @return
2 26 Feb 07 jari 1003    */
2 26 Feb 07 jari 1004   public String [] getLocusIDArray() {
2 26 Feb 07 jari 1005     return this.sortedLocusIDs;
2 26 Feb 07 jari 1006   }
2 26 Feb 07 jari 1007   
2 26 Feb 07 jari 1008   /**
2 26 Feb 07 jari 1009    * Returns the strata array, each entry cooresponds to the strata of the loci
2 26 Feb 07 jari 1010    * @return
2 26 Feb 07 jari 1011    */
2 26 Feb 07 jari 1012   public int [] getStrata() {
2 26 Feb 07 jari 1013     return this.strata;
2 26 Feb 07 jari 1014   }
2 26 Feb 07 jari 1015   
2 26 Feb 07 jari 1016   /**
2 26 Feb 07 jari 1017    * Returns the maximum locus strata in the viewer
2 26 Feb 07 jari 1018    * Strata are offset levels when loci overlap
2 26 Feb 07 jari 1019    * @return
2 26 Feb 07 jari 1020    */
2 26 Feb 07 jari 1021   public int getMaxStrata() {
2 26 Feb 07 jari 1022     return this.maxStrata;
2 26 Feb 07 jari 1023   }
2 26 Feb 07 jari 1024   
2 26 Feb 07 jari 1025   /**
2 26 Feb 07 jari 1026    * Returns true if the given locus index is selected
2 26 Feb 07 jari 1027    * @param locusIndex
2 26 Feb 07 jari 1028    * @return
2 26 Feb 07 jari 1029    */
2 26 Feb 07 jari 1030   public boolean isLocusSelected(int locusIndex) {
2 26 Feb 07 jari 1031     return selected[locusIndex];
2 26 Feb 07 jari 1032   }
2 26 Feb 07 jari 1033   
2 26 Feb 07 jari 1034   /**
2 26 Feb 07 jari 1035    * Returns true if arrow lengths are fixed
2 26 Feb 07 jari 1036    * @return
2 26 Feb 07 jari 1037    */
2 26 Feb 07 jari 1038   public boolean areArrowLengthsFixed() {
2 26 Feb 07 jari 1039     return this.fixedLengthArrows;
2 26 Feb 07 jari 1040   }
2 26 Feb 07 jari 1041   
2 26 Feb 07 jari 1042   /**
2 26 Feb 07 jari 1043    * returns the locus id related to the locus index
2 26 Feb 07 jari 1044    * @param index locus Index
2 26 Feb 07 jari 1045    * @return
2 26 Feb 07 jari 1046    */
2 26 Feb 07 jari 1047   public String getLocusID(int index) {
2 26 Feb 07 jari 1048     return sortedLocusIDs[index];
2 26 Feb 07 jari 1049   }
2 26 Feb 07 jari 1050
2 26 Feb 07 jari 1051   /**
2 26 Feb 07 jari 1052    *  Returns the 5' end of the slocus (referenced by the locus index)
2 26 Feb 07 jari 1053    * @param index locus index
2 26 Feb 07 jari 1054    * @return
2 26 Feb 07 jari 1055    */
2 26 Feb 07 jari 1056   public int getStart(int index) {
2 26 Feb 07 jari 1057     return start[index];
2 26 Feb 07 jari 1058   }
2 26 Feb 07 jari 1059
2 26 Feb 07 jari 1060   /**
2 26 Feb 07 jari 1061    *  Returns the 5' end of the locus (referenced by the locus index)
2 26 Feb 07 jari 1062    * @param index locus index
2 26 Feb 07 jari 1063    * @return
2 26 Feb 07 jari 1064    */
2 26 Feb 07 jari 1065   public int getEnd(int index) {
2 26 Feb 07 jari 1066     return end[index];
2 26 Feb 07 jari 1067   }
2 26 Feb 07 jari 1068
2 26 Feb 07 jari 1069   /**
2 26 Feb 07 jari 1070    * Returns the number of spots that map to a locus index
2 26 Feb 07 jari 1071    * @param index locus index
2 26 Feb 07 jari 1072    * @return
2 26 Feb 07 jari 1073    */
2 26 Feb 07 jari 1074   public int getNumReplicates(int index) {
2 26 Feb 07 jari 1075     return replicates[index].length;
2 26 Feb 07 jari 1076   }
2 26 Feb 07 jari 1077
2 26 Feb 07 jari 1078   /**
2 26 Feb 07 jari 1079    * returns selected indices
2 26 Feb 07 jari 1080    * @return selected selected locus indices
2 26 Feb 07 jari 1081    */
2 26 Feb 07 jari 1082   public int [] getSelectedIndices() {
2 26 Feb 07 jari 1083     if(this.selectedIndicesVector.size() == 0) {
2 26 Feb 07 jari 1084       return new int[0];
2 26 Feb 07 jari 1085     }
2 26 Feb 07 jari 1086     
2 26 Feb 07 jari 1087     int [] indices = new int[selectedIndicesVector.size()];
2 26 Feb 07 jari 1088     
2 26 Feb 07 jari 1089     for(int i  = 0; i < indices.length; i++) {
2 26 Feb 07 jari 1090       indices[i] = ((Integer)(this.selectedIndicesVector.get(i))).intValue();
2 26 Feb 07 jari 1091     }
2 26 Feb 07 jari 1092     return indices;
2 26 Feb 07 jari 1093   }
2 26 Feb 07 jari 1094   
2 26 Feb 07 jari 1095   /**
2 26 Feb 07 jari 1096    * Stores spots that map to selected loci to the cluster manager
2 26 Feb 07 jari 1097    */
2 26 Feb 07 jari 1098   private void storeSelectedLociSpotsToCluster() {
2 26 Feb 07 jari 1099     int [] locusIndices = getSelectedIndices();
2 26 Feb 07 jari 1100     
2 26 Feb 07 jari 1101     if(locusIndices.length == 0) {
2 26 Feb 07 jari 1102       JOptionPane.showMessageDialog(framework.getFrame(), "There are no loci selected.  Shift+Left Click to select.", "Empty Locus Selection List", JOptionPane.INFORMATION_MESSAGE);
2 26 Feb 07 jari 1103       return;
2 26 Feb 07 jari 1104     }
2 26 Feb 07 jari 1105     
2 26 Feb 07 jari 1106     int spotCount = 0;
2 26 Feb 07 jari 1107     for(int i = 0; i < locusIndices.length; i++) {
2 26 Feb 07 jari 1108       spotCount += replicates[locusIndices[i]].length;
2 26 Feb 07 jari 1109     }
2 26 Feb 07 jari 1110     int [] spotIndices = new int[spotCount];
2 26 Feb 07 jari 1111     int cnt = 0;
2 26 Feb 07 jari 1112     for(int i = 0; i < locusIndices.length; i++) {
2 26 Feb 07 jari 1113       for(int j = 0; j < replicates[locusIndices[i]].length; j++) {
2 26 Feb 07 jari 1114         spotIndices[cnt] = replicates[locusIndices[i]][j];
2 26 Feb 07 jari 1115         cnt++;
2 26 Feb 07 jari 1116       }
2 26 Feb 07 jari 1117     }    
2 26 Feb 07 jari 1118     framework.storeSubCluster(spotIndices, fullExperiment, Cluster.GENE_CLUSTER);
2 26 Feb 07 jari 1119   }
2 26 Feb 07 jari 1120   
2 26 Feb 07 jari 1121   /**
2 26 Feb 07 jari 1122    * saves spots that map to selected loci
2 26 Feb 07 jari 1123    */
2 26 Feb 07 jari 1124   private void saveSelectedLociSpots() {
2 26 Feb 07 jari 1125     int [] indices = getSelectedIndices();
2 26 Feb 07 jari 1126     
2 26 Feb 07 jari 1127     if(indices.length == 0) {
2 26 Feb 07 jari 1128       JOptionPane.showMessageDialog(framework.getFrame(), "There are no loci selected.  Shift+Left Click to select.", "Empty Locus Selection List", JOptionPane.INFORMATION_MESSAGE);
2 26 Feb 07 jari 1129       return;
2 26 Feb 07 jari 1130     }
2 26 Feb 07 jari 1131     
2 26 Feb 07 jari 1132     saveSpotsForLocusList(indices);
2 26 Feb 07 jari 1133   }
2 26 Feb 07 jari 1134
2 26 Feb 07 jari 1135   
2 26 Feb 07 jari 1136   /**
2 26 Feb 07 jari 1137    * Saves the spots related to loci in the selected list to file (spot detial)
2 26 Feb 07 jari 1138    * @param locusIndices array of locus indices to save
2 26 Feb 07 jari 1139    */
2 26 Feb 07 jari 1140   public void saveSpotsForLocusList(int locusIndices[]) {
2 26 Feb 07 jari 1141     int spotCount = 0;
2 26 Feb 07 jari 1142     for(int i = 0; i < locusIndices.length; i++) {
2 26 Feb 07 jari 1143       spotCount += replicates[locusIndices[i]].length;
2 26 Feb 07 jari 1144     }
2 26 Feb 07 jari 1145     int [] spotIndices = new int[spotCount];
2 26 Feb 07 jari 1146     int cnt = 0;
2 26 Feb 07 jari 1147     for(int i = 0; i < locusIndices.length; i++) {
2 26 Feb 07 jari 1148       for(int j = 0; j < replicates[locusIndices[i]].length; j++) {
2 26 Feb 07 jari 1149         spotIndices[cnt] = replicates[locusIndices[i]][j];
2 26 Feb 07 jari 1150         cnt++;
2 26 Feb 07 jari 1151       }
2 26 Feb 07 jari 1152     }
2 26 Feb 07 jari 1153     
2 26 Feb 07 jari 1154     try {
2 26 Feb 07 jari 1155       ExperimentUtil.saveExperiment(framework.getFrame(), fullExperiment, data, spotIndices);
2 26 Feb 07 jari 1156     } catch (Exception e) {
2 26 Feb 07 jari 1157             JOptionPane.showMessageDialog(framework.getFrame(), "Cannot save cluster!", e.toString(), JOptionPane.ERROR_MESSAGE);
2 26 Feb 07 jari 1158             e.printStackTrace();
2 26 Feb 07 jari 1159         }    
2 26 Feb 07 jari 1160   }
2 26 Feb 07 jari 1161   
2 26 Feb 07 jari 1162   /**
2 26 Feb 07 jari 1163    * Saves all loci to a matrix file.
2 26 Feb 07 jari 1164    */
2 26 Feb 07 jari 1165   private void saveLocusMatrix() {     
2 26 Feb 07 jari 1166     JFileChooser chooser = new JFileChooser(TMEV.getFile("data"));
2 26 Feb 07 jari 1167
2 26 Feb 07 jari 1168     if(chooser.showSaveDialog(framework.getFrame()) == JFileChooser.APPROVE_OPTION) {
2 26 Feb 07 jari 1169       try {
2 26 Feb 07 jari 1170         File file = chooser.getSelectedFile();
2 26 Feb 07 jari 1171         BufferedWriter bw = new BufferedWriter(new FileWriter(file));
2 26 Feb 07 jari 1172         
2 26 Feb 07 jari 1173         Vector sampleFieldNames = data.getSampleAnnotationFieldNames();
2 26 Feb 07 jari 1174
2 26 Feb 07 jari 1175         String headerLine = this.locusIDFieldName + "\tSpots/Locus\t" + "5' End\t" + "3' End\t";
2 26 Feb 07 jari 1176         String fieldName;
2 26 Feb 07 jari 1177         
2 26 Feb 07 jari 1178         
2 26 Feb 07 jari 1179         for(int i = 0; i < this.numberOfSamples; i++) {
2 26 Feb 07 jari 1180           headerLine += data.getSampleAnnotation(i, (String)(sampleFieldNames.get(0)));
2 26 Feb 07 jari 1181           if(i < numberOfSamples-1)
2 26 Feb 07 jari 1182             headerLine += "\t";
2 26 Feb 07 jari 1183           else
2 26 Feb 07 jari 1184             headerLine += "\n";
2 26 Feb 07 jari 1185         }
2 26 Feb 07 jari 1186         
2 26 Feb 07 jari 1187         bw.write(headerLine);
2 26 Feb 07 jari 1188         
2 26 Feb 07 jari 1189         if(sampleFieldNames.size() > 0) {
2 26 Feb 07 jari 1190           
2 26 Feb 07 jari 1191           //add addional headers
2 26 Feb 07 jari 1192           for(int i = 1; i < sampleFieldNames.size(); i++) {
2 26 Feb 07 jari 1193             fieldName = (String)(sampleFieldNames.get(i));
2 26 Feb 07 jari 1194             headerLine = "\t\t\t"+fieldName+"\t";
2 26 Feb 07 jari 1195             
2 26 Feb 07 jari 1196             for(int j = 0; j < numberOfSamples; j++) {
2 26 Feb 07 jari 1197               headerLine += data.getSampleAnnotation(j, fieldName);
2 26 Feb 07 jari 1198
2 26 Feb 07 jari 1199               if(j < numberOfSamples-1)
2 26 Feb 07 jari 1200                 headerLine += "\t";
2 26 Feb 07 jari 1201               else
2 26 Feb 07 jari 1202                 headerLine += "\n";              
2 26 Feb 07 jari 1203             }
2 26 Feb 07 jari 1204             bw.write(headerLine);
2 26 Feb 07 jari 1205           }          
2 26 Feb 07 jari 1206         }
2 26 Feb 07 jari 1207         
2 26 Feb 07 jari 1208         String line;
2 26 Feb 07 jari 1209         int fivePrime, threePrime;
2 26 Feb 07 jari 1210         
2 26 Feb 07 jari 1211         for(int i = 0; i < sortedLocusIDs.length; i++) {
2 26 Feb 07 jari 1212
2 26 Feb 07 jari 1213           //locus name
2 26 Feb 07 jari 1214           line = sortedLocusIDs[i] + "\t" + String.valueOf(replicates[i].length) + "\t";
2 26 Feb 07 jari 1215
2 26 Feb 07 jari 1216           //5' and 3' info
2 26 Feb 07 jari 1217           if(this.isForward[i]) {
2 26 Feb 07 jari 1218             fivePrime = this.start[i];
2 26 Feb 07 jari 1219             threePrime = this.end[i];
2 26 Feb 07 jari 1220           } else {
2 26 Feb 07 jari 1221             fivePrime = this.end[i];
2 26 Feb 07 jari 1222             threePrime = this.start[i];            
2 26 Feb 07 jari 1223           }
2 26 Feb 07 jari 1224
2 26 Feb 07 jari 1225           line += String.valueOf(fivePrime) + "\t" + String.valueOf(threePrime) + "\t";
2 26 Feb 07 jari 1226
2 26 Feb 07 jari 1227           for(int j = 0; j < numberOfSamples; j++) {
2 26 Feb 07 jari 1228             //add locus means
2 26 Feb 07 jari 1229             line += String.valueOf(experiment.get(i,j));
2 26 Feb 07 jari 1230             if(j < numberOfSamples-1)
2 26 Feb 07 jari 1231               line += "\t";
2 26 Feb 07 jari 1232             else
2 26 Feb 07 jari 1233               line += "\n";              
2 26 Feb 07 jari 1234           }
2 26 Feb 07 jari 1235           bw.write(line);
2 26 Feb 07 jari 1236         }
2 26 Feb 07 jari 1237         bw.flush();
2 26 Feb 07 jari 1238         bw.close();
2 26 Feb 07 jari 1239       } catch (IOException ioe) {
2 26 Feb 07 jari 1240               JOptionPane.showMessageDialog(framework.getFrame(), "Cannot save loci!", ioe.toString(), JOptionPane.ERROR_MESSAGE);
2 26 Feb 07 jari 1241               ioe.printStackTrace();        
2 26 Feb 07 jari 1242       } 
2 26 Feb 07 jari 1243       
2 26 Feb 07 jari 1244     }
2 26 Feb 07 jari 1245     
2 26 Feb 07 jari 1246   }
2 26 Feb 07 jari 1247   
2 26 Feb 07 jari 1248   
2 26 Feb 07 jari 1249   /**
2 26 Feb 07 jari 1250    * Saves selecte loci to file
2 26 Feb 07 jari 1251    **/
2 26 Feb 07 jari 1252   public void saveSelectedLoci() {
2 26 Feb 07 jari 1253         
2 26 Feb 07 jari 1254     int [] indices = getSelectedIndices();
2 26 Feb 07 jari 1255     
2 26 Feb 07 jari 1256     if(indices.length == 0) {
2 26 Feb 07 jari 1257       JOptionPane.showMessageDialog(framework.getFrame(), "There are no loci selected.  Shift+Left Click to select.", "Empty Locus Selection List", JOptionPane.INFORMATION_MESSAGE);
2 26 Feb 07 jari 1258       return;
2 26 Feb 07 jari 1259     }
2 26 Feb 07 jari 1260     
2 26 Feb 07 jari 1261     for(int i  = 0; i < indices.length; i++) {
2 26 Feb 07 jari 1262       indices[i] = ((Integer)(this.selectedIndicesVector.get(i))).intValue();
2 26 Feb 07 jari 1263     }    
2 26 Feb 07 jari 1264     saveLocusList(indices);    
2 26 Feb 07 jari 1265   }
2 26 Feb 07 jari 1266   
2 26 Feb 07 jari 1267   
2 26 Feb 07 jari 1268   /**
2 26 Feb 07 jari 1269    * Saves the list of loci to file
2 26 Feb 07 jari 1270    * @param locusIndices array of locus indices
2 26 Feb 07 jari 1271    */
2 26 Feb 07 jari 1272   public void saveLocusList(int locusIndices[]) {
2 26 Feb 07 jari 1273     JFileChooser chooser = new JFileChooser(TMEV.getFile("data"));
2 26 Feb 07 jari 1274     
2 26 Feb 07 jari 1275     if(chooser.showSaveDialog(framework.getFrame()) == JFileChooser.APPROVE_OPTION) {
2 26 Feb 07 jari 1276       try {
2 26 Feb 07 jari 1277         File file = chooser.getSelectedFile();
2 26 Feb 07 jari 1278         BufferedWriter bw = new BufferedWriter(new FileWriter(file));
2 26 Feb 07 jari 1279         
2 26 Feb 07 jari 1280         Vector sampleFieldNames = data.getSampleAnnotationFieldNames();
2 26 Feb 07 jari 1281         
2 26 Feb 07 jari 1282         String headerLine = this.locusIDFieldName + "\tSpots/Locus\t" + "5' End\t" + "3' End\t";
2 26 Feb 07 jari 1283         
2 26 Feb 07 jari 1284         String fieldName;
2 26 Feb 07 jari 1285         
2 26 Feb 07 jari 1286         
2 26 Feb 07 jari 1287         for(int i = 0; i < this.numberOfSamples; i++) {
2 26 Feb 07 jari 1288           headerLine += data.getSampleAnnotation(i, (String)(sampleFieldNames.get(0)));
2 26 Feb 07 jari 1289           if(i < numberOfSamples-1)
2 26 Feb 07 jari 1290             headerLine += "\t";
2 26 Feb 07 jari 1291           else
2 26 Feb 07 jari 1292             headerLine += "\n";
2 26 Feb 07 jari 1293         }
2 26 Feb 07 jari 1294         
2 26 Feb 07 jari 1295         bw.write(headerLine);
2 26 Feb 07 jari 1296         
2 26 Feb 07 jari 1297         if(sampleFieldNames.size() > 0) {
2 26 Feb 07 jari 1298           
2 26 Feb 07 jari 1299           //add addional headers
2 26 Feb 07 jari 1300           for(int i = 1; i < sampleFieldNames.size(); i++) {
2 26 Feb 07 jari 1301             fieldName = (String)(sampleFieldNames.get(i));
2 26 Feb 07 jari 1302             headerLine = "\t\t\t"+fieldName+"\t";
2 26 Feb 07 jari 1303             
2 26 Feb 07 jari 1304             for(int j = 0; j < numberOfSamples; j++) {
2 26 Feb 07 jari 1305               headerLine += data.getSampleAnnotation(j, fieldName);
2 26 Feb 07 jari 1306               
2 26 Feb 07 jari 1307               if(j < numberOfSamples-1)
2 26 Feb 07 jari 1308                 headerLine += "\t";
2 26 Feb 07 jari 1309               else
2 26 Feb 07 jari 1310                 headerLine += "\n";              
2 26 Feb 07 jari 1311             }
2 26 Feb 07 jari 1312             bw.write(headerLine);
2 26 Feb 07 jari 1313           }          
2 26 Feb 07 jari 1314         }
2 26 Feb 07 jari 1315         
2 26 Feb 07 jari 1316         String line;
2 26 Feb 07 jari 1317         
2 26 Feb 07 jari 1318         for(int i = 0; i < locusIndices.length; i++) {
2 26 Feb 07 jari 1319           
2 26 Feb 07 jari 1320           //locus name
2 26 Feb 07 jari 1321           line = sortedLocusIDs[locusIndices[i]] + "\t" + String.valueOf(replicates[locusIndices[i]].length) + "\t";
2 26 Feb 07 jari 1322           
2 26 Feb 07 jari 1323           int fivePrime, threePrime;
2 26 Feb 07 jari 1324           
2 26 Feb 07 jari 1325           //5' and 3' info
2 26 Feb 07 jari 1326           if(this.isForward[i]) {
2 26 Feb 07 jari 1327             fivePrime = this.start[i];
2 26 Feb 07 jari 1328             threePrime = this.end[i];
2 26 Feb 07 jari 1329           } else {
2 26 Feb 07 jari 1330             fivePrime = this.end[i];
2 26 Feb 07 jari 1331             threePrime = this.start[i];            
2 26 Feb 07 jari 1332           }
2 26 Feb 07 jari 1333           
2 26 Feb 07 jari 1334           line += String.valueOf(fivePrime) + "\t" + String.valueOf(threePrime) + "\t";
2 26 Feb 07 jari 1335           
2 26 Feb 07 jari 1336           
2 26 Feb 07 jari 1337           for(int j = 0; j < numberOfSamples; j++) {
2 26 Feb 07 jari 1338             //add locus means
2 26 Feb 07 jari 1339             line += String.valueOf(experiment.get(locusIndices[i],j));
2 26 Feb 07 jari 1340             if(j < numberOfSamples-1)
2 26 Feb 07 jari 1341               line += "\t";
2 26 Feb 07 jari 1342             else
2 26 Feb 07 jari 1343               line += "\n";              
2 26 Feb 07 jari 1344           }
2 26 Feb 07 jari 1345           bw.write(line);
2 26 Feb 07 jari 1346         }
2 26 Feb 07 jari 1347         bw.flush();
2 26 Feb 07 jari 1348         bw.close();
2 26 Feb 07 jari 1349       } catch (IOException ioe) {
2 26 Feb 07 jari 1350         JOptionPane.showMessageDialog(framework.getFrame(), "Cannot save loci!", ioe.toString(), JOptionPane.ERROR_MESSAGE);
2 26 Feb 07 jari 1351         ioe.printStackTrace();        
2 26 Feb 07 jari 1352       }       
2 26 Feb 07 jari 1353     }    
2 26 Feb 07 jari 1354   }
2 26 Feb 07 jari 1355
2 26 Feb 07 jari 1356   
2 26 Feb 07 jari 1357   /**
2 26 Feb 07 jari 1358    * opens a url related to the passed locus index
2 26 Feb 07 jari 1359    * @param index locus index
2 26 Feb 07 jari 1360    */
2 26 Feb 07 jari 1361   public void linkToURL(int index) {      
2 26 Feb 07 jari 1362     JFrame frame = (JFrame)(JOptionPane.getFrameForComponent(this));                
2 26 Feb 07 jari 1363     ExperimentUtil.linkToURL(frame, fullExperiment, data, this.replicates[index][0], locusIDFieldName, ExperimentUtil.lastSelectedAnnotationIndices);            
2 26 Feb 07 jari 1364   }
2 26 Feb 07 jari 1365
2 26 Feb 07 jari 1366   /**
2 26 Feb 07 jari 1367    * Returns the locus name for the give locus index
2 26 Feb 07 jari 1368    * @param index locus index
2 26 Feb 07 jari 1369    * @return
2 26 Feb 07 jari 1370    */
2 26 Feb 07 jari 1371   public String getLocusName(int index) {
2 26 Feb 07 jari 1372     if(index > this.sortedLocusIDs.length-1)
2 26 Feb 07 jari 1373       return sortedLocusIDs[0];
2 26 Feb 07 jari 1374     if(index < 0)
2 26 Feb 07 jari 1375       return sortedLocusIDs[sortedLocusIDs.length-1];
2 26 Feb 07 jari 1376
2 26 Feb 07 jari 1377     return sortedLocusIDs[index];
2 26 Feb 07 jari 1378   }
2 26 Feb 07 jari 1379
2 26 Feb 07 jari 1380   /**
2 26 Feb 07 jari 1381    * Returns the array of indices for spots that map to the provided locus index
2 26 Feb 07 jari 1382    * @param index locus index
2 26 Feb 07 jari 1383    * @return array of spots that map to the locus (indices map to full experiment)
2 26 Feb 07 jari 1384    */
2 26 Feb 07 jari 1385   public int [] getReplicatesArray(int index) {
2 26 Feb 07 jari 1386     if(index > this.replicates.length-1)
2 26 Feb 07 jari 1387       return replicates[0];
2 26 Feb 07 jari 1388     if(index < 0)
2 26 Feb 07 jari 1389       return replicates[replicates.length-1];
2 26 Feb 07 jari 1390     return replicates[index];
2 26 Feb 07 jari 1391   }
2 26 Feb 07 jari 1392   
2 26 Feb 07 jari 1393   /** Updates viewer configuration
2 26 Feb 07 jari 1394    *  Updated fields are interdependent so that the minimum number
2 26 Feb 07 jari 1395    *  of fields is altered depending on selections.
2 26 Feb 07 jari 1396    * @param props
2 26 Feb 07 jari 1397    */
2 26 Feb 07 jari 1398   public void setViewerSettings(Properties props) {    
2 26 Feb 07 jari 1399     this.fixedLengthArrows = Boolean.valueOf(props.getProperty("fixed-arrows")).booleanValue();
2 26 Feb 07 jari 1400
2 26 Feb 07 jari 1401     if(fixedLengthArrows) {
2 26 Feb 07 jari 1402       this.currArrowLength = Integer.parseInt(props.getProperty("fixed-arrow-length"));
2 26 Feb 07 jari 1403     } else {
2 26 Feb 07 jari 1404       this.bpPerPixel = Integer.parseInt(props.getProperty("scaling-factor"));    
2 26 Feb 07 jari 1405       this.minArrowLength = Integer.parseInt(props.getProperty("min-arrow-length"));
2 26 Feb 07 jari 1406       this.maxArrowLength = Integer.parseInt(props.getProperty("max-arrow-length"));
2 26 Feb 07 jari 1407     }    
2 26 Feb 07 jari 1408     this.showOpenAreas = ! (Boolean.valueOf(props.getProperty("fixed-open")).booleanValue());
2 26 Feb 07 jari 1409     if(this.showOpenAreas)
2 26 Feb 07 jari 1410       this.maxIntergenicLength = Integer.parseInt(props.getProperty("max-open-length"));
2 26 Feb 07 jari 1411     this.showAllReplicates = Boolean.valueOf(props.getProperty("show-replicates")).booleanValue();    
2 26 Feb 07 jari 1412     updateViewer();
2 26 Feb 07 jari 1413   }
2 26 Feb 07 jari 1414
2 26 Feb 07 jari 1415   
2 26 Feb 07 jari 1416   /**
2 26 Feb 07 jari 1417    *  Returns true if base coordinates is in a locus
2 26 Feb 07 jari 1418    * @param coord base location
2 26 Feb 07 jari 1419    * @return
2 26 Feb 07 jari 1420    */
2 26 Feb 07 jari 1421   private boolean isOpen(int coord) {
2 26 Feb 07 jari 1422     int index = 0;
2 26 Feb 07 jari 1423     while (index < start.length && start[index] < coord) {
2 26 Feb 07 jari 1424       if (start[index] < coord && end[index] > coord)
2 26 Feb 07 jari 1425         return true;
2 26 Feb 07 jari 1426     }
2 26 Feb 07 jari 1427     return false;
2 26 Feb 07 jari 1428   }
2 26 Feb 07 jari 1429   
2 26 Feb 07 jari 1430   /**
2 26 Feb 07 jari 1431    * sets the bin policy, informs header, repaints LEM and navigator
2 26 Feb 07 jari 1432    * @param mode
2 26 Feb 07 jari 1433    */
2 26 Feb 07 jari 1434   private void setColorBinPolicy(int mode) {
2 26 Feb 07 jari 1435     this.colorMode = mode;
2 26 Feb 07 jari 1436     this.header.setColorBinPolicy(mode);
2 26 Feb 07 jari 1437     header.repaint();
2 26 Feb 07 jari 1438     repaint();
2 26 Feb 07 jari 1439     if(thumbnail != null && thumbnail.isVisible()) {
2 26 Feb 07 jari 1440       thumbnail.repaint();
2 26 Feb 07 jari 1441     }    
2 26 Feb 07 jari 1442   }
2 26 Feb 07 jari 1443
2 26 Feb 07 jari 1444
2 26 Feb 07 jari 1445   /** Returns the content of the viewer
2 26 Feb 07 jari 1446    * 
2 26 Feb 07 jari 1447    */  
2 26 Feb 07 jari 1448   public JComponent getContentComponent() {
2 26 Feb 07 jari 1449     return this;
2 26 Feb 07 jari 1450   }
2 26 Feb 07 jari 1451
2 26 Feb 07 jari 1452  
2 26 Feb 07 jari 1453   /**
2 26 Feb 07 jari 1454    * Returns the header
2 26 Feb 07 jari 1455    */
2 26 Feb 07 jari 1456   public JComponent getHeaderComponent() {
2 26 Feb 07 jari 1457     return header;
2 26 Feb 07 jari 1458   }
2 26 Feb 07 jari 1459
2 26 Feb 07 jari 1460  
2 26 Feb 07 jari 1461   /**
2 26 Feb 07 jari 1462    * Returns a the row header, null for this viewer
2 26 Feb 07 jari 1463    */
2 26 Feb 07 jari 1464   public JComponent getRowHeaderComponent() {
2 26 Feb 07 jari 1465     return null;
2 26 Feb 07 jari 1466   }
2 26 Feb 07 jari 1467
2 26 Feb 07 jari 1468   /**
2 26 Feb 07 jari 1469    * Returns the corner component, null for this viewer
2 26 Feb 07 jari 1470    */
2 26 Feb 07 jari 1471   public JComponent getCornerComponent(int cornerIndex) {
2 26 Feb 07 jari 1472     return null;
2 26 Feb 07 jari 1473   }
2 26 Feb 07 jari 1474
2 26 Feb 07 jari 1475   /**
2 26 Feb 07 jari 1476    * Prepares the viewer for viewing when selected 
2 26 Feb 07 jari 1477    */
2 26 Feb 07 jari 1478   public void onSelected(IFramework framework) {
2 26 Feb 07 jari 1479     this.framework = framework;
2 26 Feb 07 jari 1480     
2 26 Feb 07 jari 1481     data = framework.getData();
2 26 Feb 07 jari 1482     IDisplayMenu menu = framework.getDisplayMenu();
2 26 Feb 07 jari 1483     
2 26 Feb 07 jari 1484     updateLocusAnnotationWidth();
2 26 Feb 07 jari 1485     updateCoords();
2 26 Feb 07 jari 1486     
2 26 Feb 07 jari 1487     this.maxValue = menu.getMaxRatioScale();
2 26 Feb 07 jari 1488     this.minValue = menu.getMinRatioScale();
2 26 Feb 07 jari 1489     this.midValue = menu.getMidRatioValue();
2 26 Feb 07 jari 1490     this.posColorImage = menu.getPositiveGradientImage();
2 26 Feb 07 jari 1491     this.negColorImage = menu.getNegativeGradientImage();
2 26 Feb 07 jari 1492     this.useDoubleGradient = menu.getUseDoubleGradient();
2 26 Feb 07 jari 1493     this.header.setNegAndPosColorImages(this.negColorImage, this.posColorImage);
2 26 Feb 07 jari 1494     this.header.setUseDoubleGradient(useDoubleGradient);
2 26 Feb 07 jari 1495     this.header.setValues(minValue, midValue, maxValue);
2 26 Feb 07 jari 1496     
2 26 Feb 07 jari 1497     int index = this.fieldIndex;
2 26 Feb 07 jari 1498     this.fieldIndex = menu.getLabelIndex();
2 26 Feb 07 jari 1499     
2 26 Feb 07 jari 1500     if(index != fieldIndex) //change ann
2 26 Feb 07 jari 1501       this.updateLocusAnnotationWidth();
2 26 Feb 07 jari 1502     
2 26 Feb 07 jari 1503     header.setData(data);
2 26 Feb 07 jari 1504     header.setColumnSpacing(columnSpacing);    
2 26 Feb 07 jari 1505     header.updateSizes(viewerWidth, columnSpacing);    
2 26 Feb 07 jari 1506     
2 26 Feb 07 jari 1507     if(this.selectionEditor == null)
2 26 Feb 07 jari 1508       this.selectionEditor = new LEMSelectionEditor((JFrame)framework.getFrame(), this, selectedIndicesVector);    
2 26 Feb 07 jari 1509   }
2 26 Feb 07 jari 1510
2 26 Feb 07 jari 1511   /**
2 26 Feb 07 jari 1512    * Updates the header with current <code>IData</code>
2 26 Feb 07 jari 1513    */
2 26 Feb 07 jari 1514   public void onDataChanged(IData data) {
2 26 Feb 07 jari 1515     header.setData(data);    
2 26 Feb 07 jari 1516   }
2 26 Feb 07 jari 1517   
2 26 Feb 07 jari 1518   /**
2 26 Feb 07 jari 1519    * Updates the viewer, header, and thumbnail (if visible), during a menu change.
2 26 Feb 07 jari 1520    */
2 26 Feb 07 jari 1521   public void onMenuChanged(IDisplayMenu menu) {
2 26 Feb 07 jari 1522         this.maxValue = menu.getMaxRatioScale();
2 26 Feb 07 jari 1523         this.minValue = menu.getMinRatioScale();
2 26 Feb 07 jari 1524         this.midValue = menu.getMidRatioValue();
2 26 Feb 07 jari 1525         this.posColorImage = menu.getPositiveGradientImage();
2 26 Feb 07 jari 1526         this.negColorImage = menu.getNegativeGradientImage();
2 26 Feb 07 jari 1527         this.useDoubleGradient = menu.getUseDoubleGradient();
2 26 Feb 07 jari 1528         int index = fieldIndex;
2 26 Feb 07 jari 1529         this.fieldIndex = menu.getLabelIndex();
2 26 Feb 07 jari 1530         if(index != fieldIndex) //change ann
2 26 Feb 07 jari 1531           this.updateLocusAnnotationWidth();
2 26 Feb 07 jari 1532
2 26 Feb 07 jari 1533         this.header.setNegAndPosColorImages(this.negColorImage, this.posColorImage);
2 26 Feb 07 jari 1534         this.header.setUseDoubleGradient(useDoubleGradient);
2 26 Feb 07 jari 1535         this.header.setValues(minValue, midValue, maxValue);
2 26 Feb 07 jari 1536         this.repaint();
2 26 Feb 07 jari 1537     
2 26 Feb 07 jari 1538         if(thumbnail != null && thumbnail.isVisible()) {
2 26 Feb 07 jari 1539       thumbnail.repaint();
2 26 Feb 07 jari 1540     }
2 26 Feb 07 jari 1541   }
2 26 Feb 07 jari 1542
2 26 Feb 07 jari 1543   public void onDeselected() {
2 26 Feb 07 jari 1544
2 26 Feb 07 jari 1545   }
2 26 Feb 07 jari 1546
2 26 Feb 07 jari 1547   public void onClosed() {
2 26 Feb 07 jari 1548   }
2 26 Feb 07 jari 1549
2 26 Feb 07 jari 1550   public BufferedImage getImage() {
2 26 Feb 07 jari 1551     return null;
2 26 Feb 07 jari 1552   }
2 26 Feb 07 jari 1553
2 26 Feb 07 jari 1554   /**
2 26 Feb 07 jari 1555    * Returns null for this viewer, clusters do not apply
2 26 Feb 07 jari 1556    */
2 26 Feb 07 jari 1557   public int[][] getClusters() {
2 26 Feb 07 jari 1558     return null;
2 26 Feb 07 jari 1559   }
2 26 Feb 07 jari 1560
2 26 Feb 07 jari 1561   /**
2 26 Feb 07 jari 1562    * Returns the viewer type, gene or sample 
2 26 Feb 07 jari 1563    */  
2 26 Feb 07 jari 1564   public int getViewerType() {
2 26 Feb 07 jari 1565     return 0;
2 26 Feb 07 jari 1566   }
2 26 Feb 07 jari 1567
2 26 Feb 07 jari 1568   /**
2 26 Feb 07 jari 1569    * Computes annoation width and sets global variables related to component width
2 26 Feb 07 jari 1570    *
2 26 Feb 07 jari 1571    */
2 26 Feb 07 jari 1572   private void updateLocusAnnotationWidth() {
2 26 Feb 07 jari 1573     Graphics g = getGraphics();
2 26 Feb 07 jari 1574     if (g == null)
2 26 Feb 07 jari 1575       return;
2 26 Feb 07 jari 1576     FontMetrics fm = g.getFontMetrics();
2 26 Feb 07 jari 1577     if (fm == null)
2 26 Feb 07 jari 1578       return;
2 26 Feb 07 jari 1579     
2 26 Feb 07 jari 1580     int currLocusWidth = 0;
2 26 Feb 07 jari 1581     int currStartWidth = 0;
2 26 Feb 07 jari 1582     int currEndWidth = 0;
2 26 Feb 07 jari 1583     int currAnnWidth = 0;
2 26 Feb 07 jari 1584     
2 26 Feb 07 jari 1585     int maxLocusWidth = 0;
2 26 Feb 07 jari 1586     int maxStartWidth = 0;
2 26 Feb 07 jari 1587     int maxEndWidth = 0;
2 26 Feb 07 jari 1588     int maxAnnWidth = 0;
2 26 Feb 07 jari 1589         
2 26 Feb 07 jari 1590     for (int i = 0; i < this.locusCount; i++) {
2 26 Feb 07 jari 1591
2 26 Feb 07 jari 1592       //locus name width
2 26 Feb 07 jari 1593       currLocusWidth = fm.stringWidth(this.sortedLocusIDs[i]);
2 26 Feb 07 jari 1594       if (currLocusWidth > maxLocusWidth)
2 26 Feb 07 jari 1595         maxLocusWidth = currLocusWidth;
2 26 Feb 07 jari 1596     
2 26 Feb 07 jari 1597       //start width
2 26 Feb 07 jari 1598       currStartWidth = fm.stringWidth(this.isForward[i] ? String
2 26 Feb 07 jari 1599           .valueOf(this.start[i]) : String.valueOf(this.end[i]));
2 26 Feb 07 jari 1600       if (currStartWidth > maxStartWidth)
2 26 Feb 07 jari 1601         maxStartWidth = currStartWidth;
2 26 Feb 07 jari 1602     
2 26 Feb 07 jari 1603       //end width
2 26 Feb 07 jari 1604       currEndWidth = fm.stringWidth(this.isForward[i] ? String
2 26 Feb 07 jari 1605           .valueOf(this.end[i]) : String.valueOf(this.start[i]));
2 26 Feb 07 jari 1606       if (currEndWidth > maxEndWidth)
2 26 Feb 07 jari 1607         maxEndWidth = currEndWidth;
2 26 Feb 07 jari 1608       
2 26 Feb 07 jari 1609       currAnnWidth = fm.stringWidth(data.getElementAttribute(fullExperiment.getGeneIndexMappedToData(replicates[i][0]), fieldIndex));
2 26 Feb 07 jari 1610       if(currAnnWidth > maxAnnWidth)
2 26 Feb 07 jari 1611         maxAnnWidth = currAnnWidth;
2 26 Feb 07 jari 1612     }
2 26 Feb 07 jari 1613     
2 26 Feb 07 jari 1614     startMaxWidth = maxStartWidth;
2 26 Feb 07 jari 1615     endMaxWidth = maxEndWidth;
2 26 Feb 07 jari 1616     locusMaxWidth = maxLocusWidth;
2 26 Feb 07 jari 1617     annotationWidth = maxAnnWidth;
2 26 Feb 07 jari 1618
2 26 Feb 07 jari 1619     //add in factor for margins and for second field
2 26 Feb 07 jari 1620     this.fullAnnotationWidth = this.COORD_LEFT_MARGIN + startMaxWidth + this.COORD_SEPARATOR_MARGIN + endMaxWidth 
2 26 Feb 07 jari 1621       + LEFT_LOCUS_MARGIN + locusMaxWidth + RIGHT_LOCUS_MARGIN + annotationWidth;
2 26 Feb 07 jari 1622   }
2 26 Feb 07 jari 1623
2 26 Feb 07 jari 1624   /**
2 26 Feb 07 jari 1625    * Returns a color that cooresponds the expression value.  this depends on colorMode status
2 26 Feb 07 jari 1626    * @param value expression value
2 26 Feb 07 jari 1627    * @return
2 26 Feb 07 jari 1628    */
2 26 Feb 07 jari 1629   public Color getColor(float value) {
2 26 Feb 07 jari 1630     if (Float.isNaN(value)) {
2 26 Feb 07 jari 1631       return missingColor;
2 26 Feb 07 jari 1632     }
2 26 Feb 07 jari 1633     Color color;
2 26 Feb 07 jari 1634     float maximum;
2 26 Feb 07 jari 1635     int colorIndex, rgb = 0;
2 26 Feb 07 jari 1636     
2 26 Feb 07 jari 1637     if (colorMode == COLOR_MODE_GRADIENT) {
2 26 Feb 07 jari 1638       if (useDoubleGradient) {
2 26 Feb 07 jari 1639         maximum = value < midValue ? this.minValue : this.maxValue;
2 26 Feb 07 jari 1640         colorIndex = (int) (255 * (value - midValue) / (maximum - midValue));
2 26 Feb 07 jari 1641         colorIndex = colorIndex > 255 ? 255 : colorIndex;
2 26 Feb 07 jari 1642         rgb = value < midValue ? negColorImage.getRGB(255 - colorIndex,
2 26 Feb 07 jari 1643             0) : posColorImage.getRGB(colorIndex, 0);
2 26 Feb 07 jari 1644       } else {
2 26 Feb 07 jari 1645         float span = this.maxValue - this.minValue;
2 26 Feb 07 jari 1646         if (value <= this.minValue)
2 26 Feb 07 jari 1647           colorIndex = 0;
2 26 Feb 07 jari 1648         else if (value >= maxValue)
2 26 Feb 07 jari 1649           colorIndex = 255;
2 26 Feb 07 jari 1650         else
2 26 Feb 07 jari 1651           colorIndex = (int) (((value - this.minValue) / span) * 255);
2 26 Feb 07 jari 1652
2 26 Feb 07 jari 1653         rgb = posColorImage.getRGB(colorIndex, 0);
2 26 Feb 07 jari 1654       }
2 26 Feb 07 jari 1655       color = new Color(rgb);
2 26 Feb 07 jari 1656     } else if (colorMode == COLOR_MODE_2_BIN) {
2 26 Feb 07 jari 1657       if(value <= cutoff1)
2 26 Feb 07 jari 1658         color = lowestColor;
2 26 Feb 07 jari 1659       else if(value >= cutoff4)
2 26 Feb 07 jari 1660         color = highestColor;
2 26 Feb 07 jari 1661       else
2 26 Feb 07 jari 1662         color = midPointColor;      
2 26 Feb 07 jari 1663     } else { //four bin system
2 26 Feb 07 jari 1664       if(value < cutoff1)
2 26 Feb 07 jari 1665         color = lowestColor;
2 26 Feb 07 jari 1666       else if(value >= cutoff4)
2 26 Feb 07 jari 1667         color = highestColor;
2 26 Feb 07 jari 1668       else if(value >= cutoff3)
2 26 Feb 07 jari 1669         color = higherColor;
2 26 Feb 07 jari 1670       else if(value < cutoff2)
2 26 Feb 07 jari 1671         color = lowerColor;
2 26 Feb 07 jari 1672       else
2 26 Feb 07 jari 1673         color = midPointColor;            
2 26 Feb 07 jari 1674     }
2 26 Feb 07 jari 1675     return color;
2 26 Feb 07 jari 1676   }
2 26 Feb 07 jari 1677
2 26 Feb 07 jari 1678   /**
2 26 Feb 07 jari 1679    * Creates gradient images
2 26 Feb 07 jari 1680    * @param c1 Low end color
2 26 Feb 07 jari 1681    * @param c2 High end color
2 26 Feb 07 jari 1682    * @return
2 26 Feb 07 jari 1683    */
2 26 Feb 07 jari 1684   protected BufferedImage createGradient(Color c1, Color c2) {
2 26 Feb 07 jari 1685     BufferedImage image = (BufferedImage) java.awt.GraphicsEnvironment
2 26 Feb 07 jari 1686         .getLocalGraphicsEnvironment().getDefaultScreenDevice()
2 26 Feb 07 jari 1687         .getDefaultConfiguration().createCompatibleImage(256, 1);
2 26 Feb 07 jari 1688     Graphics2D graphics = image.createGraphics();
2 26 Feb 07 jari 1689     GradientPaint gp = new GradientPaint(0, 0, c1, 255, 0, c2);
2 26 Feb 07 jari 1690     graphics.setPaint(gp);
2 26 Feb 07 jari 1691     graphics.drawRect(0, 0, 255, 1);
2 26 Feb 07 jari 1692     return image;
2 26 Feb 07 jari 1693   }
2 26 Feb 07 jari 1694   
2 26 Feb 07 jari 1695   /**
2 26 Feb 07 jari 1696    * Updates viewer settings following option changes
2 26 Feb 07 jari 1697    * -updates: column spacing, loci pixel coordinates, header column spacing
2 26 Feb 07 jari 1698    * header size, updates thumbnail/navigator, fires repaintng.
2 26 Feb 07 jari 1699    */
2 26 Feb 07 jari 1700   private void updateViewer() {
2 26 Feb 07 jari 1701     updateColumnSpacing();
2 26 Feb 07 jari 1702     updateCoords();
2 26 Feb 07 jari 1703     header.setColumnSpacing(columnSpacing);
2 26 Feb 07 jari 1704     header.updateSizes(this.getWidth(), columnSpacing);
2 26 Feb 07 jari 1705     repaint();
2 26 Feb 07 jari 1706     header.repaint();
2 26 Feb 07 jari 1707     if(thumbnail != null && thumbnail.isVisible()) {
2 26 Feb 07 jari 1708       thumbnail.setIsFixedLength(this.fixedLengthArrows);
2 26 Feb 07 jari 1709       thumbnail.repaint();
2 26 Feb 07 jari 1710     }    
2 26 Feb 07 jari 1711   }
2 26 Feb 07 jari 1712
2 26 Feb 07 jari 1713   /**
2 26 Feb 07 jari 1714    * Toggles the optino to scale loci
2 26 Feb 07 jari 1715    */
2 26 Feb 07 jari 1716   private void setScaleLoci() {
2 26 Feb 07 jari 1717     this.fixedLengthArrows = !this.fixedLengthArrows;
2 26 Feb 07 jari 1718     updateViewer();
2 26 Feb 07 jari 1719   }
2 26 Feb 07 jari 1720   
2 26 Feb 07 jari 1721   /**
2 26 Feb 07 jari 1722    * Toggles the option to scale intergenic (open) regions   *
2 26 Feb 07 jari 1723    */
2 26 Feb 07 jari 1724   private void setScaleIntergenic() {
2 26 Feb 07 jari 1725     this.showOpenAreas = !this.showOpenAreas;    
2 26 Feb 07 jari 1726     updateViewer();
2 26 Feb 07 jari 1727   }
2 26 Feb 07 jari 1728
2 26 Feb 07 jari 1729   /**
2 26 Feb 07 jari 1730    * Checks location and shades the locus (highlights) if appropriate.
2 26 Feb 07 jari 1731    * Sets highlighted index and end an start coordinates
2 26 Feb 07 jari 1732    * @param x
2 26 Feb 07 jari 1733    * @param y
2 26 Feb 07 jari 1734    */
2 26 Feb 07 jari 1735   private void shadeLoci(int x, int y) {
2 26 Feb 07 jari 1736     if(x > X_ORIGIN && x < columnSpacing*numberOfSamples+this.wingWidth+this.arrowWidth/2) { 
2 26 Feb 07 jari 1737       highlightedIndex = this.findNearestArrowMidPoint(y);
2 26 Feb 07 jari 1738       if( highlightedIndex != -1) {
2 26 Feb 07 jari 1739         setStatusText(highlightedIndex);
2 26 Feb 07 jari 1740         highlightStart = coordStarts[highlightedIndex];
2 26 Feb 07 jari 1741         highlightEnd = coordEnds[highlightedIndex];        
2 26 Feb 07 jari 1742         highlighted = true;
2 26 Feb 07 jari 1743         repaint();
2 26 Feb 07 jari 1744       } else {
2 26 Feb 07 jari 1745         //on lem but off locus
2 26 Feb 07 jari 1746         setStatusText(-1);
2 26 Feb 07 jari 1747         highlighted = false;
2 26 Feb 07 jari 1748         repaint();
2 26 Feb 07 jari 1749       }
2 26 Feb 07 jari 1750     } else {
2 26 Feb 07 jari 1751       setStatusText(-1);
2 26 Feb 07 jari 1752       highlighted = false;
2 26 Feb 07 jari 1753       repaint();
2 26 Feb 07 jari 1754     }
2 26 Feb 07 jari 1755   }
2 26 Feb 07 jari 1756
2 26 Feb 07 jari 1757   /**
2 26 Feb 07 jari 1758    * Sets the highlighted locus name in the status bar, or default string in no locus is highlighted
2 26 Feb 07 jari 1759    * @param index locus index
2 26 Feb 07 jari 1760    */
2 26 Feb 07 jari 1761   private void setStatusText(int index) {
2 26 Feb 07 jari 1762     if(index == -1)
2 26 Feb 07 jari 1763       framework.setStatusText(" TIGR MultiExperiment Viewer");
2 26 Feb 07 jari 1764     else
2 26 Feb 07 jari 1765       framework.setStatusText(" "+this.locusIDFieldName+": "+this.sortedLocusIDs[highlightedIndex]);
2 26 Feb 07 jari 1766   }
2 26 Feb 07 jari 1767   
2 26 Feb 07 jari 1768   /**
2 26 Feb 07 jari 1769    * Finds teh closest locus anchor
2 26 Feb 07 jari 1770    * @param yCoord mouse y pixel coordinate
2 26 Feb 07 jari 1771    * @return
2 26 Feb 07 jari 1772    */
2 26 Feb 07 jari 1773   private int findNearestArrowMidPoint(int yCoord) {    
2 26 Feb 07 jari 1774     int minDeltaIndex = -1;
2 26 Feb 07 jari 1775     int delta = Integer.MAX_VALUE;
2 26 Feb 07 jari 1776     
2 26 Feb 07 jari 1777     //get a collection of loci to interrogate        
2 26 Feb 07 jari 1778     int [] bounds = this.getBoundingIndices(yCoord, yCoord);
2 26 Feb 07 jari 1779     
2 26 Feb 07 jari 1780     if(bounds[1]-bounds[0] <= 0)
2 26 Feb 07 jari 1781       return minDeltaIndex;
2 26 Feb 07 jari 1782         
2 26 Feb 07 jari 1783     for(int i = bounds[0]; i <= bounds[1]; i++) {
2 26 Feb 07 jari 1784       if((coordStarts[i] <= yCoord && coordEnds[i] >= yCoord)) {
2 26 Feb 07 jari 1785         if(delta > Math.abs(yCoord - (coordEnds[i] + coordStarts[i])/2)) {
2 26 Feb 07 jari 1786           minDeltaIndex = i;
2 26 Feb 07 jari 1787           delta = Math.abs(yCoord - (coordEnds[i] + coordStarts[i])/2);
2 26 Feb 07 jari 1788         }
2 26 Feb 07 jari 1789       }
2 26 Feb 07 jari 1790     }            
2 26 Feb 07 jari 1791     return minDeltaIndex;
2 26 Feb 07 jari 1792   }
2 26 Feb 07 jari 1793
2 26 Feb 07 jari 1794   /** Launches a <code>LEMColorRangeSelector</code> to collect range and color information   * 
2 26 Feb 07 jari 1795    */
2 26 Feb 07 jari 1796   private void setBinColorRanges() {
2 26 Feb 07 jari 1797     
2 26 Feb 07 jari 1798     LEMColorRangeSelector selector = new LEMColorRangeSelector((JFrame)framework.getFrame(), this,
2 26 Feb 07 jari 1799         this.lowestColor, this.lowerColor, this.higherColor,
2 26 Feb 07 jari 1800         this.highestColor, this.cutoff1, this.cutoff2, this.midBinValue, this.cutoff3,
2 26 Feb 07 jari 1801         this.cutoff4);
2 26 Feb 07 jari 1802
2 26 Feb 07 jari 1803     selector.showModal();    
2 26 Feb 07 jari 1804   }
2 26 Feb 07 jari 1805   
2 26 Feb 07 jari 1806   /**
2 26 Feb 07 jari 1807    * Public method to apply bin limits and colors
2 26 Feb 07 jari 1808    * @param c1
2 26 Feb 07 jari 1809    * @param c2
2 26 Feb 07 jari 1810    * @param mid
2 26 Feb 07 jari 1811    * @param c3
2 26 Feb 07 jari 1812    * @param c4
2 26 Feb 07 jari 1813    * @param color1
2 26 Feb 07 jari 1814    * @param color2
2 26 Feb 07 jari 1815    * @param color3
2 26 Feb 07 jari 1816    * @param color4
2 26 Feb 07 jari 1817    */
2 26 Feb 07 jari 1818   public void setBinLimitsAndColors(float c1, float c2, float mid, float c3, float c4,
2 26 Feb 07 jari 1819       Color color1, Color color2, Color color3, Color color4) {
2 26 Feb 07 jari 1820
2 26 Feb 07 jari 1821     this.cutoff1 = c1;
2 26 Feb 07 jari 1822     this.cutoff2 = c2;
2 26 Feb 07 jari 1823     this.midBinValue = mid;
2 26 Feb 07 jari 1824     this.cutoff3 = c3;
2 26 Feb 07 jari 1825     this.cutoff4 = c4;
2 26 Feb 07 jari 1826
2 26 Feb 07 jari 1827     this.lowestColor = color1;
2 26 Feb 07 jari 1828     this.lowerColor = color2;
2 26 Feb 07 jari 1829     this.midPointColor = Color.white;
2 26 Feb 07 jari 1830     this.higherColor = color3;
2 26 Feb 07 jari 1831     this.highestColor = color4;      
2 26 Feb 07 jari 1832
2 26 Feb 07 jari 1833     header.setBinColors(lowestColor, lowerColor, higherColor, highestColor);
2 26 Feb 07 jari 1834     header.setBinCutoffs(cutoff1, cutoff2, midBinValue, cutoff3, cutoff4);
2 26 Feb 07 jari 1835     
2 26 Feb 07 jari 1836     header.repaint();
2 26 Feb 07 jari 1837     repaint();
2 26 Feb 07 jari 1838     if(thumbnail != null && thumbnail.isVisible()) {
2 26 Feb 07 jari 1839       thumbnail.repaint();
2 26 Feb 07 jari 1840     }    
2 26 Feb 07 jari 1841   }
2 26 Feb 07 jari 1842
2 26 Feb 07 jari 1843   /**
2 26 Feb 07 jari 1844    * Shows locus information for the highlighted locus
2 26 Feb 07 jari 1845    * @param x x mouse coordinate
2 26 Feb 07 jari 1846    * @param y y mouse coordinate
2 26 Feb 07 jari 1847    */
2 26 Feb 07 jari 1848   private void showInfo(int x, int y) {
2 26 Feb 07 jari 1849     if(x > X_ORIGIN && x < columnSpacing*numberOfSamples) {
2 26 Feb 07 jari 1850       int index = this.findNearestArrowMidPoint(y);
2 26 Feb 07 jari 1851       
2 26 Feb 07 jari 1852       if(index != -1) {
2 26 Feb 07 jari 1853         launchInfo(index);
2 26 Feb 07 jari 1854       }
2 26 Feb 07 jari 1855     }      
2 26 Feb 07 jari 1856   }
2 26 Feb 07 jari 1857
2 26 Feb 07 jari 1858   
2 26 Feb 07 jari 1859   /**
2 26 Feb 07 jari 1860    * Launches a <code>LocusInfoDialog</code> for the specified locus index
2 26 Feb 07 jari 1861    * @param index
2 26 Feb 07 jari 1862    */
2 26 Feb 07 jari 1863   private void launchInfo(int index) {    
2 26 Feb 07 jari 1864     LocusInfoDialog info = new LocusInfoDialog( (JFrame)(framework.getFrame()), this, sortedLocusIDs[index], index, experiment, fullExperiment, framework.getData(), replicates[index]); 
2 26 Feb 07 jari 1865     this.activeInfoDialogs.add(info);
2 26 Feb 07 jari 1866     info.showInfo();    
2 26 Feb 07 jari 1867   }
2 26 Feb 07 jari 1868   
2 26 Feb 07 jari 1869   
2 26 Feb 07 jari 1870   /**
2 26 Feb 07 jari 1871    * Removes the locus info dialog from the active dialog list
2 26 Feb 07 jari 1872    * @param info <code>LocusInfoDialog</code> object to remove
2 26 Feb 07 jari 1873    */
2 26 Feb 07 jari 1874   public void removeInfoViewer(LocusInfoDialog info) {
2 26 Feb 07 jari 1875     this.activeInfoDialogs.remove(info);
2 26 Feb 07 jari 1876   }
2 26 Feb 07 jari 1877   
2 26 Feb 07 jari 1878
2 26 Feb 07 jari 1879   /**
2 26 Feb 07 jari 1880    * Displays the thumbnail navigation controller
2 26 Feb 07 jari 1881    *
2 26 Feb 07 jari 1882    */
2 26 Feb 07 jari 1883   private void showThumbnail() {    
2 26 Feb 07 jari 1884     //dispose of a current thumbnail and show new
2 26 Feb 07 jari 1885     if(thumbnail != null) {
2 26 Feb 07 jari 1886       thumbnail.dispose();
2 26 Feb 07 jari 1887       thumbnail = null;
2 26 Feb 07 jari 1888     }  
2 26 Feb 07 jari 1889     thumbnail = new LEMThumbNail(framework, this, coordStarts, coordEnds, experiment.getMatrix(), cutoff4, cutoff1, highestColor, lowestColor, midPointColor, maxPixelCoord, clipY1, clipY2, this.locusIDFieldName);
2 26 Feb 07 jari 1890     thumbnail.showThumbnail();
2 26 Feb 07 jari 1891   }
2 26 Feb 07 jari 1892   
2 26 Feb 07 jari 1893   
2 26 Feb 07 jari 1894   /**
2 26 Feb 07 jari 1895    * Returns the y-clip bounds as a two member int array, low and high clip bounds
2 26 Feb 07 jari 1896    * @return
2 26 Feb 07 jari 1897    */
2 26 Feb 07 jari 1898   public int [] getYClipBounds(){
2 26 Feb 07 jari 1899     int [] yBounds = new int[2];
2 26 Feb 07 jari 1900     yBounds[0] = clipY1;
2 26 Feb 07 jari 1901     yBounds[1] = clipY2;
2 26 Feb 07 jari 1902     return yBounds;
2 26 Feb 07 jari 1903   }
2 26 Feb 07 jari 1904     
2 26 Feb 07 jari 1905     
2 26 Feb 07 jari 1906   /**
2 26 Feb 07 jari 1907    * Find s the next start relative to the y coordinate
2 26 Feb 07 jari 1908    * @param y y pixel location
2 26 Feb 07 jari 1909    * @return
2 26 Feb 07 jari 1910    */
2 26 Feb 07 jari 1911   private int findNextLowestStart(int y) {
2 26 Feb 07 jari 1912     int index = 0, i;
2 26 Feb 07 jari 1913     for(i = 0; i < this.coordStarts.length; i++) {
2 26 Feb 07 jari 1914       if(coordStarts[i] <= y && coordEnds[i] >= y)
2 26 Feb 07 jari 1915         return i;
2 26 Feb 07 jari 1916       if(coordStarts[i] > y) {
2 26 Feb 07 jari 1917         if(i > 0)
2 26 Feb 07 jari 1918           return i-1;
2 26 Feb 07 jari 1919         else
2 26 Feb 07 jari 1920           return 0;
2 26 Feb 07 jari 1921       }
2 26 Feb 07 jari 1922     }
2 26 Feb 07 jari 1923     
2 26 Feb 07 jari 1924     if(i >= this.coordStarts.length)
2 26 Feb 07 jari 1925       return coordStarts.length-1;
2 26 Feb 07 jari 1926     
2 26 Feb 07 jari 1927     return index;
2 26 Feb 07 jari 1928   }
2 26 Feb 07 jari 1929
2 26 Feb 07 jari 1930   /**
2 26 Feb 07 jari 1931    * returns the loci that starts after location y
2 26 Feb 07 jari 1932    * @param y y location value to start the search.
2 26 Feb 07 jari 1933    * @return
2 26 Feb 07 jari 1934    */
2 26 Feb 07 jari 1935   private int findNextHighestStart(int y) {
2 26 Feb 07 jari 1936     int index = 0, i;
2 26 Feb 07 jari 1937     for(i = this.coordStarts.length-1; i >= 0; i--) {
2 26 Feb 07 jari 1938       if(coordStarts[i] <= y && coordEnds[i] >= y)
2 26 Feb 07 jari 1939         return i;
2 26 Feb 07 jari 1940       if(coordStarts[i] < y) {
2 26 Feb 07 jari 1941         if(i < coordStarts.length-1)
2 26 Feb 07 jari 1942           return i+1;
2 26 Feb 07 jari 1943         else
2 26 Feb 07 jari 1944           return coordStarts.length-1;
2 26 Feb 07 jari 1945       }
2 26 Feb 07 jari 1946     }    
2 26 Feb 07 jari 1947     if(i < 0)
2 26 Feb 07 jari 1948       return 1;
2 26 Feb 07 jari 1949     
2 26 Feb 07 jari 1950     return index;
2 26 Feb 07 jari 1951   }
2 26 Feb 07 jari 1952
2 26 Feb 07 jari 1953   
2 26 Feb 07 jari 1954   /**
2 26 Feb 07 jari 1955    * Returns the locus indices that bound the specified y range
2 26 Feb 07 jari 1956    * @param y1 lower range limit
2 26 Feb 07 jari 1957    * @param y2 upper range limit
2 26 Feb 07 jari 1958    * @return returns two (2) indices that bound the specified y range
2 26 Feb 07 jari 1959    */
2 26 Feb 07 jari 1960   private int [] getBoundingIndices(int y1, int y2) {
2 26 Feb 07 jari 1961     int [] bounds = new int[2];
2 26 Feb 07 jari 1962     bounds[0] = 0;
2 26 Feb 07 jari 1963     bounds[1] = coordStarts.length-1;
2 26 Feb 07 jari 1964
2 26 Feb 07 jari 1965     boolean setHigh = false, setLow = false;
2 26 Feb 07 jari 1966     
2 26 Feb 07 jari 1967     for(int i = 0; i < boundingRanges.length; i++) {
2 26 Feb 07 jari 1968       if(!setLow && y1 >= boundingRanges[i][0] && y1 < boundingRanges[i][1]) {
2 26 Feb 07 jari 1969         bounds[0] = boundingRanges[i][2];
2 26 Feb 07 jari 1970         setLow = true;
2 26 Feb 07 jari 1971       }
2 26 Feb 07 jari 1972       if(!setHigh && y2 >= boundingRanges[i][0] && y2 < boundingRanges[i][1]) {
2 26 Feb 07 jari 1973         bounds[1] = boundingRanges[i][3];        
2 26 Feb 07 jari 1974         setHigh = true;
2 26 Feb 07 jari 1975       }
2 26 Feb 07 jari 1976       if(setHigh && setLow)
2 26 Feb 07 jari 1977         return bounds;      
2 26 Feb 07 jari 1978     }
2 26 Feb 07 jari 1979     return bounds;
2 26 Feb 07 jari 1980   }
2 26 Feb 07 jari 1981
2 26 Feb 07 jari 1982
2 26 Feb 07 jari 1983   /**
2 26 Feb 07 jari 1984    * Moves viewer to specified locus ID
2 26 Feb 07 jari 1985    * @param locus locus name
2 26 Feb 07 jari 1986    * @return returns the locus index or -1 if not found
2 26 Feb 07 jari 1987    */
2 26 Feb 07 jari 1988   public int jumpToLocus(String locus) {
2 26 Feb 07 jari 1989     int loc = -1;
2 26 Feb 07 jari 1990     for(int i = 0; i < this.sortedLocusIDs.length; i++) {
2 26 Feb 07 jari 1991       if(locus.equals(sortedLocusIDs[i])) {
2 26 Feb 07 jari 1992         loc = annYPos[i]-15;
2 26 Feb 07 jari 1993         if(loc < 0)
2 26 Feb 07 jari 1994           loc = 0;
2 26 Feb 07 jari 1995           
2 26 Feb 07 jari 1996         shadeLoci(X_ORIGIN,loc);
2 26 Feb 07 jari 1997         framework.setContentLocation(0, loc);        
2 26 Feb 07 jari 1998         return loc;
2 26 Feb 07 jari 1999       }
2 26 Feb 07 jari 2000     }
2 26 Feb 07 jari 2001     //if not found return -1
2 26 Feb 07 jari 2002     return loc;
2 26 Feb 07 jari 2003   }
2 26 Feb 07 jari 2004   
2 26 Feb 07 jari 2005
2 26 Feb 07 jari 2006   /**
2 26 Feb 07 jari 2007    * Moves viewer to indicated base location
2 26 Feb 07 jari 2008    * @param bp base location
2 26 Feb 07 jari 2009    * @return returns the locus index or -1 if none found
2 26 Feb 07 jari 2010    */
2 26 Feb 07 jari 2011   public int jumpToLocation(int bp) {
2 26 Feb 07 jari 2012     int loc = -1;
2 26 Feb 07 jari 2013     for(int i = 0; i < this.start.length-1; i++) {
2 26 Feb 07 jari 2014       if(bp >= start[i] && bp <= start[i+1]) {
2 26 Feb 07 jari 2015
2 26 Feb 07 jari 2016         //if it's in a gene
2 26 Feb 07 jari 2017         if(bp >= start[i] && bp <= end[i]) {
2 26 Feb 07 jari 2018           loc = annYPos[i]-15;
2 26 Feb 07 jari 2019           if(loc < 0)
2 26 Feb 07 jari 2020             loc = 0;
2 26 Feb 07 jari 2021             
2 26 Feb 07 jari 2022           shadeLoci(X_ORIGIN, annYPos[i]);
2 26 Feb 07 jari 2023           framework.setContentLocation(0, loc);        
2 26 Feb 07 jari 2024           return loc;            
2 26 Feb 07 jari 2025         } else {
2 26 Feb 07 jari 2026           loc = annYPos[i]-15;
2 26 Feb 07 jari 2027           if(loc < 0)
2 26 Feb 07 jari 2028             loc = 0;
2 26 Feb 07 jari 2029             
2 26 Feb 07 jari 2030           shadeLoci(X_ORIGIN, annYPos[i]);
2 26 Feb 07 jari 2031           shadeLoci(X_ORIGIN, annYPos[i+1]);
2 26 Feb 07 jari 2032           framework.setContentLocation(0, loc);        
2 26 Feb 07 jari 2033           return loc;                      
2 26 Feb 07 jari 2034         }
2 26 Feb 07 jari 2035       }
2 26 Feb 07 jari 2036     }
2 26 Feb 07 jari 2037     //if not found return -1
2 26 Feb 07 jari 2038     return loc;
2 26 Feb 07 jari 2039   }
2 26 Feb 07 jari 2040   
2 26 Feb 07 jari 2041   /**
2 26 Feb 07 jari 2042    * Launches the selection editor (list) or if already visible it centers the dialog
2 26 Feb 07 jari 2043    */
2 26 Feb 07 jari 2044   private void showSelectionList() {    
2 26 Feb 07 jari 2045     if(!selectionEditor.isVisible())
2 26 Feb 07 jari 2046       selectionEditor.showDialog();
2 26 Feb 07 jari 2047     else
2 26 Feb 07 jari 2048       selectionEditor.centerDialog();
2 26 Feb 07 jari 2049   }
2 26 Feb 07 jari 2050   
2 26 Feb 07 jari 2051
2 26 Feb 07 jari 2052   /**
2 26 Feb 07 jari 2053    * selects the locus closes to the mouse y coordinate
2 26 Feb 07 jari 2054    * @param x
2 26 Feb 07 jari 2055    * @param yCoord
2 26 Feb 07 jari 2056    */
2 26 Feb 07 jari 2057   public void selectLocus(int x, int yCoord) {    
2 26 Feb 07 jari 2058     if(x > X_ORIGIN - wingWidth - this.arrowWidth/2 && x < columnSpacing*numberOfSamples + wingWidth + arrowWidth/2) {
2 26 Feb 07 jari 2059       
2 26 Feb 07 jari 2060       int index = this.findNearestArrowMidPoint(yCoord);
2 26 Feb 07 jari 2061
2 26 Feb 07 jari 2062       if(index == -1)
2 26 Feb 07 jari 2063         return;
2 26 Feb 07 jari 2064       
2 26 Feb 07 jari 2065       selected[index] = !selected[index];
2 26 Feb 07 jari 2066       if(selected[index]) {            
2 26 Feb 07 jari 2067         this.selectedIndicesVector.add(new Integer(index));
2 26 Feb 07 jari 2068         this.selectionEditor.fireLocusAdded();
2 26 Feb 07 jari 2069       } else {
2 26 Feb 07 jari 2070         this.selectedIndicesVector.remove(new Integer(index));          
2 26 Feb 07 jari 2071         this.selectionEditor.fireLocusRemoved();
2 26 Feb 07 jari 2072       }      
2 26 Feb 07 jari 2073       updateInfoViewers();      
2 26 Feb 07 jari 2074       repaint();
2 26 Feb 07 jari 2075     }
2 26 Feb 07 jari 2076   }
2 26 Feb 07 jari 2077   
2 26 Feb 07 jari 2078   
2 26 Feb 07 jari 2079   /**
2 26 Feb 07 jari 2080    * Launches a dialog to select a base range.  Selects all loci that overlap the range
2 26 Feb 07 jari 2081    */
2 26 Feb 07 jari 2082   public boolean selectBaseRange() {    
2 26 Feb 07 jari 2083     int startBase, endBase;
2 26 Feb 07 jari 2084     boolean selectionMade = false;
2 26 Feb 07 jari 2085     
2 26 Feb 07 jari 2086     LEMRangeSelectionDialog dialog = new LEMRangeSelectionDialog((JFrame)framework.getFrame(), start[0], maxEndBaseLocation);
2 26 Feb 07 jari 2087     
2 26 Feb 07 jari 2088     if(dialog.showModal() == JOptionPane.OK_OPTION) {
2 26 Feb 07 jari 2089       
2 26 Feb 07 jari 2090       startBase = dialog.getLowerLimit();
2 26 Feb 07 jari 2091       endBase = dialog.getUpperLimit();
2 26 Feb 07 jari 2092       
2 26 Feb 07 jari 2093       int loc = 0;
2 26 Feb 07 jari 2094       Vector indices = new Vector();
2 26 Feb 07 jari 2095       
2 26 Feb 07 jari 2096       for(loc = 0; loc < start.length; loc++) {
2 26 Feb 07 jari 2097         if(haveOverLap(loc, startBase, endBase)) {        
2 26 Feb 07 jari 2098           indices.add(new Integer(loc));      
2 26 Feb 07 jari 2099         }
2 26 Feb 07 jari 2100       }
2 26 Feb 07 jari 2101       
2 26 Feb 07 jari 2102       for(int i = 0; i < indices.size(); i++) {
2 26 Feb 07 jari 2103         loc = ((Integer)indices.get(i)).intValue();
2 26 Feb 07 jari 2104         
2 26 Feb 07 jari 2105         if(!selected[loc]) {
2 26 Feb 07 jari 2106           selected[loc] = true;
2 26 Feb 07 jari 2107           this.selectedIndicesVector.add(indices.get(i));
2 26 Feb 07 jari 2108           this.selectionEditor.fireLocusAdded();        
2 26 Feb 07 jari 2109         }      
2 26 Feb 07 jari 2110       }    
2 26 Feb 07 jari 2111             
2 26 Feb 07 jari 2112       if(indices.size()>0)
2 26 Feb 07 jari 2113         selectionMade = true;
2 26 Feb 07 jari 2114         
2 26 Feb 07 jari 2115       updateInfoViewers();
2 26 Feb 07 jari 2116       repaint();                
2 26 Feb 07 jari 2117     }
2 26 Feb 07 jari 2118     return selectionMade;
2 26 Feb 07 jari 2119   }
2 26 Feb 07 jari 2120   
2 26 Feb 07 jari 2121   /**
2 26 Feb 07 jari 2122    * Checks to see if the locus indicated by locusIndex overlaps the coordinate range
2 26 Feb 07 jari 2123    * @param locusIndex locus index to check
2 26 Feb 07 jari 2124    * @param startBase start base location
2 26 Feb 07 jari 2125    * @param endBase end base location
2 26 Feb 07 jari 2126    * @return
2 26 Feb 07 jari 2127    */
2 26 Feb 07 jari 2128   private boolean haveOverLap(int locusIndex, int startBase, int endBase) {    
2 26 Feb 07 jari 2129     return ( (start[locusIndex] >= startBase && start[locusIndex] <= endBase)
2 26 Feb 07 jari 2130         || (end[locusIndex] >= startBase && end[locusIndex] <= endBase)
2 26 Feb 07 jari 2131         || (startBase >= start[locusIndex] && startBase <= end[locusIndex]));                
2 26 Feb 07 jari 2132   }
2 26 Feb 07 jari 2133   
2 26 Feb 07 jari 2134   /**
2 26 Feb 07 jari 2135    * Updates all information viewers that are present.  Each checks the selection
2 26 Feb 07 jari 2136    * status of it's displayed locus.
2 26 Feb 07 jari 2137    */
2 26 Feb 07 jari 2138   private void updateInfoViewers() {
2 26 Feb 07 jari 2139     for(int i = 0; i < this.activeInfoDialogs.size(); i++)
2 26 Feb 07 jari 2140       ((LocusInfoDialog)(this.activeInfoDialogs.get(i))).checkSelection();
2 26 Feb 07 jari 2141   }
2 26 Feb 07 jari 2142
2 26 Feb 07 jari 2143   /**
2 26 Feb 07 jari 2144    * Toggles selection status of a locus given a locus index
2 26 Feb 07 jari 2145    * @param locusIndex locus index to toggle status
2 26 Feb 07 jari 2146    */
2 26 Feb 07 jari 2147   public void toggleSelectedLocus(int locusIndex) {
2 26 Feb 07 jari 2148     selected[locusIndex] = !selected[locusIndex];
2 26 Feb 07 jari 2149     if(!selected[locusIndex]) {
2 26 Feb 07 jari 2150       selectedIndicesVector.remove(new Integer(locusIndex));
2 26 Feb 07 jari 2151       this.selectionEditor.fireLocusRemoved();
2 26 Feb 07 jari 2152     } else {
2 26 Feb 07 jari 2153       selectedIndicesVector.add(new Integer(locusIndex));      
2 26 Feb 07 jari 2154       this.selectionEditor.fireLocusAdded();
2 26 Feb 07 jari 2155     }
2 26 Feb 07 jari 2156     updateInfoViewers();
2 26 Feb 07 jari 2157     repaint();
2 26 Feb 07 jari 2158   }  
2 26 Feb 07 jari 2159   
2 26 Feb 07 jari 2160   /**
2 26 Feb 07 jari 2161    * Launches the dialog to customize viewer scaling constraints
2 26 Feb 07 jari 2162    */
2 26 Feb 07 jari 2163   private void customizeSettings() {      
2 26 Feb 07 jari 2164     LEMViewerAttributeDialog dialog = new LEMViewerAttributeDialog(framework.getFrame(), this,
2 26 Feb 07 jari 2165         this.fixedLengthArrows, !this.showOpenAreas, this.currArrowLength,
2 26 Feb 07 jari 2166         this.minArrowLength, this.maxArrowLength, this.maxIntergenicLength, 
2 26 Feb 07 jari 2167         this.bpPerPixel, this.showAllReplicates);
2 26 Feb 07 jari 2168
2 26 Feb 07 jari 2169     dialog.showModal();    
2 26 Feb 07 jari 2170   }
2 26 Feb 07 jari 2171
2 26 Feb 07 jari 2172
2 26 Feb 07 jari 2173   /**
2 26 Feb 07 jari 2174    * Creates popup menu and adds lem listener to menu items
2 26 Feb 07 jari 2175    * @param listener event handler
2 26 Feb 07 jari 2176    */
2 26 Feb 07 jari 2177   private void createPopupMenu(LEMListener listener) {
2 26 Feb 07 jari 2178     menu = new JPopupMenu();
2 26 Feb 07 jari 2179     ButtonGroup bg = new ButtonGroup();
2 26 Feb 07 jari 2180     
2 26 Feb 07 jari 2181     JMenuItem customizeItem = new JMenuItem("Customize Viewer");
2 26 Feb 07 jari 2182     customizeItem.setActionCommand("customize-viewer-command");
2 26 Feb 07 jari 2183     customizeItem.addActionListener(listener);
2 26 Feb 07 jari 2184
2 26 Feb 07 jari 2185     JMenu colorMenu = new JMenu("Color Scale Options");
2 26 Feb 07 jari 2186
2 26 Feb 07 jari 2187     JCheckBoxMenuItem item = new JCheckBoxMenuItem("Gradient Mode", true);
2 26 Feb 07 jari 2188     item.setActionCommand("gradient-color-mode");
2 26 Feb 07 jari 2189     item.addActionListener(listener);
2 26 Feb 07 jari 2190     bg.add(item);
2 26 Feb 07 jari 2191     colorMenu.add(item);
2 26 Feb 07 jari 2192
2 26 Feb 07 jari 2193     item = new JCheckBoxMenuItem("3 Bin Mode", false);
2 26 Feb 07 jari 2194     item.setActionCommand("3-bin-mode");
2 26 Feb 07 jari 2195     item.addActionListener(listener);
2 26 Feb 07 jari 2196     bg.add(item);
2 26 Feb 07 jari 2197     colorMenu.add(item);
2 26 Feb 07 jari 2198
2 26 Feb 07 jari 2199     item = new JCheckBoxMenuItem("5 Bin Mode", false);
2 26 Feb 07 jari 2200     item.setActionCommand("5-bin-mode");
2 26 Feb 07 jari 2201     item.addActionListener(listener);
2 26 Feb 07 jari 2202     bg.add(item);
2 26 Feb 07 jari 2203     colorMenu.add(item);
2 26 Feb 07 jari 2204     
2 26 Feb 07 jari 2205     colorMenu.addSeparator();
2 26 Feb 07 jari 2206     
2 26 Feb 07 jari 2207     JMenuItem colorItem = new JMenuItem("Bin Colors and Limits");
2 26 Feb 07 jari 2208     colorItem.setActionCommand("bin-color-range-command");
2 26 Feb 07 jari 2209     colorItem.addActionListener(listener);
2 26 Feb 07 jari 2210     colorMenu.add(colorItem);    
2 26 Feb 07 jari 2211         
2 26 Feb 07 jari 2212     JMenuItem navItem = new JMenuItem("LEM Navigation");
2 26 Feb 07 jari 2213     navItem.setActionCommand("show-thumbnail-command");     
2 26 Feb 07 jari 2214     navItem.addActionListener(listener);
2 26 Feb 07 jari 2215     
2 26 Feb 07 jari 2216     JMenuItem showSelectionListItem = new JMenuItem("Locus Selection Manager");
2 26 Feb 07 jari 2217     showSelectionListItem.setActionCommand("show-selection-list-command");
2 26 Feb 07 jari 2218     showSelectionListItem.addActionListener(listener);
2 26 Feb 07 jari 2219
2 26 Feb 07 jari 2220     JMenuItem storeMenuItem = new JMenuItem("Store Selected Loci (as cluster)");  
2 26 Feb 07 jari 2221     storeMenuItem.setActionCommand("store-cluster-command");
2 26 Feb 07 jari 2222     storeMenuItem.addActionListener(listener);
2 26 Feb 07 jari 2223             
2 26 Feb 07 jari 2224     JMenuItem saveSelectedLociItem = new JMenuItem("Save Selected Loci (Locus Detail)");
2 26 Feb 07 jari 2225     saveSelectedLociItem.setActionCommand("save-selected-loci-command");
2 26 Feb 07 jari 2226     saveSelectedLociItem.addActionListener(listener);    
2 26 Feb 07 jari 2227     
2 26 Feb 07 jari 2228     JMenuItem saveSelectedLociSpotsItem = new JMenuItem("Save Selected Loci (Spot Detail)");    
2 26 Feb 07 jari 2229     saveSelectedLociSpotsItem.setActionCommand("save-selected-loci-spots-command");
2 26 Feb 07 jari 2230     saveSelectedLociSpotsItem.addActionListener(listener);    
2 26 Feb 07 jari 2231     
2 26 Feb 07 jari 2232   /*  JMenu selectionMenu = new JMenu("Locus Selection Operations");
2 26 Feb 07 jari 2233     selectionMenu.add(showSelectionListItem);
2 26 Feb 07 jari 2234     selectionMenu.addSeparator();
2 26 Feb 07 jari 2235     selectionMenu.add(storeMenuItem);
2 26 Feb 07 jari 2236     selectionMenu.addSeparator();
2 26 Feb 07 jari 2237     selectionMenu.add(saveSelectedLociItem);
2 26 Feb 07 jari 2238     selectionMenu.add(saveSelectedLociSpotsItem);
2 26 Feb 07 jari 2239     */    
2 26 Feb 07 jari 2240     
2 26 Feb 07 jari 2241     JMenuItem saveMatrixItem = new JMenuItem("Save All Loci");
2 26 Feb 07 jari 2242     saveMatrixItem.setActionCommand("save-matrix-command");
2 26 Feb 07 jari 2243     saveMatrixItem.addActionListener(listener);
2 26 Feb 07 jari 2244
2 26 Feb 07 jari 2245     menu.add(navItem);
2 26 Feb 07 jari 2246     menu.addSeparator();
2 26 Feb 07 jari 2247     menu.add(customizeItem);
2 26 Feb 07 jari 2248     menu.add(colorMenu);
2 26 Feb 07 jari 2249     menu.addSeparator();        
2 26 Feb 07 jari 2250     menu.add(showSelectionListItem);
2 26 Feb 07 jari 2251     menu.addSeparator();    
2 26 Feb 07 jari 2252     menu.add(storeMenuItem);
2 26 Feb 07 jari 2253     menu.addSeparator();    
2 26 Feb 07 jari 2254     menu.add(saveSelectedLociItem);
2 26 Feb 07 jari 2255     menu.add(saveSelectedLociSpotsItem);
2 26 Feb 07 jari 2256     menu.add(saveMatrixItem);
2 26 Feb 07 jari 2257   }
2 26 Feb 07 jari 2258
2 26 Feb 07 jari 2259   private void showPopup(int x, int y) {
2 26 Feb 07 jari 2260     menu.show(this, x, y);
2 26 Feb 07 jari 2261   }
2 26 Feb 07 jari 2262
2 26 Feb 07 jari 2263   /**
2 26 Feb 07 jari 2264    * Handles LEM mouse and action events
2 26 Feb 07 jari 2265    * @author braisted
2 26 Feb 07 jari 2266    */
2 26 Feb 07 jari 2267   public class LEMListener extends MouseAdapter implements ActionListener, MouseMotionListener {
2 26 Feb 07 jari 2268   
2 26 Feb 07 jari 2269     public void actionPerformed(ActionEvent ae) {
2 26 Feb 07 jari 2270       String command = ae.getActionCommand();
2 26 Feb 07 jari 2271       
2 26 Feb 07 jari 2272       if(command.equals("gradient-color-mode")) {
2 26 Feb 07 jari 2273         setColorBinPolicy(LinearExpressionMapViewer.COLOR_MODE_GRADIENT);
2 26 Feb 07 jari 2274       } else if(command.equals("3-bin-mode")) {
2 26 Feb 07 jari 2275         setColorBinPolicy(LinearExpressionMapViewer.COLOR_MODE_2_BIN);        
2 26 Feb 07 jari 2276       } else if(command.equals("5-bin-mode")) {
2 26 Feb 07 jari 2277         setColorBinPolicy(LinearExpressionMapViewer.COLOR_MODE_4_BIN);        
2 26 Feb 07 jari 2278       } else if(command.equals("scale-loci-command")) {
2 26 Feb 07 jari 2279         setScaleLoci();
2 26 Feb 07 jari 2280       } else if(command.equals("scale-open-command")) {
2 26 Feb 07 jari 2281         setScaleIntergenic();
2 26 Feb 07 jari 2282       } else if(command.equals("show-thumbnail-command")) {
2 26 Feb 07 jari 2283         showThumbnail();
2 26 Feb 07 jari 2284       } else if(command.equals("bin-color-range-command")) {
2 26 Feb 07 jari 2285         setBinColorRanges();
2 26 Feb 07 jari 2286       } else if(command.equals("show-selection-list-command")) {      
2 26 Feb 07 jari 2287         showSelectionList();        
2 26 Feb 07 jari 2288       } else if(command.equals("customize-viewer-command")) {
2 26 Feb 07 jari 2289         customizeSettings();
2 26 Feb 07 jari 2290       } else if(command.equals("save-matrix-command")) {
2 26 Feb 07 jari 2291         saveLocusMatrix();
2 26 Feb 07 jari 2292       } else if(command.equals("store-cluster-command")) {
2 26 Feb 07 jari 2293         storeSelectedLociSpotsToCluster();
2 26 Feb 07 jari 2294       } else if(command.equals("save-selected-loci-command")) {
2 26 Feb 07 jari 2295         saveSelectedLoci();
2 26 Feb 07 jari 2296       } else if(command.equals("save-selected-loci-spots-command")) {
2 26 Feb 07 jari 2297         saveSelectedLociSpots();
2 26 Feb 07 jari 2298       }
2 26 Feb 07 jari 2299     }
2 26 Feb 07 jari 2300     
2 26 Feb 07 jari 2301     public void mousePressed(MouseEvent me) {
2 26 Feb 07 jari 2302       if(me.isPopupTrigger()) {
2 26 Feb 07 jari 2303         showPopup(me.getX(), me.getY());
2 26 Feb 07 jari 2304       } 
2 26 Feb 07 jari 2305     }
2 26 Feb 07 jari 2306
2 26 Feb 07 jari 2307     public void mouseReleased(MouseEvent me) {
2 26 Feb 07 jari 2308       if(me.isPopupTrigger()) {
2 26 Feb 07 jari 2309         showPopup(me.getX(), me.getY());
2 26 Feb 07 jari 2310       } else {
2 26 Feb 07 jari 2311         if(MouseEvent.getModifiersExText(me.getModifiersEx()).equalsIgnoreCase("Shift")) {
2 26 Feb 07 jari 2312           selectLocus(me.getX(), me.getY());        
2 26 Feb 07 jari 2313         } else 
2 26 Feb 07 jari 2314           showInfo(me.getX(), me.getY());
2 26 Feb 07 jari 2315       }      
2 26 Feb 07 jari 2316     }
2 26 Feb 07 jari 2317     
2 26 Feb 07 jari 2318     public void mouseExited(MouseEvent me) {
2 26 Feb 07 jari 2319       if(!menu.isVisible() || ( thumbnail != null && !thumbnail.isVisible())) {      
2 26 Feb 07 jari 2320         highlighted = false;
2 26 Feb 07 jari 2321         repaint();
2 26 Feb 07 jari 2322       }
2 26 Feb 07 jari 2323       setStatusText(-1);
2 26 Feb 07 jari 2324     }
2 26 Feb 07 jari 2325
2 26 Feb 07 jari 2326     public void mouseMoved(MouseEvent me) {            
2 26 Feb 07 jari 2327       shadeLoci(me.getX(), me.getY());
2 26 Feb 07 jari 2328     }
2 26 Feb 07 jari 2329     
2 26 Feb 07 jari 2330     public void mouseDragged(MouseEvent me) {
2 26 Feb 07 jari 2331     }    
2 26 Feb 07 jari 2332   }
2 26 Feb 07 jari 2333
2 26 Feb 07 jari 2334
2 26 Feb 07 jari 2335   /**
2 26 Feb 07 jari 2336    * @see org.tigr.microarray.mev.cluster.gui.IViewer#getExperimentID()
2 26 Feb 07 jari 2337    */
2 26 Feb 07 jari 2338   public int getExperimentID() {
2 26 Feb 07 jari 2339     return this.exptID;
2 26 Feb 07 jari 2340   }
2 26 Feb 07 jari 2341
2 26 Feb 07 jari 2342   /**
2 26 Feb 07 jari 2343    * @see org.tigr.microarray.mev.cluster.gui.IViewer#setExperimentID(int)
2 26 Feb 07 jari 2344    */
2 26 Feb 07 jari 2345   public void setExperimentID(int id) {
2 26 Feb 07 jari 2346     this.exptID = id;
2 26 Feb 07 jari 2347   }
2 26 Feb 07 jari 2348
2 26 Feb 07 jari 2349     
2 26 Feb 07 jari 2350 }