TVModel.java :  » Development » TreeView-1.1.4r5 » edu » stanford » genetics » treeview » model » Java Open Source

Java Open Source » Development » TreeView 1.1.4r5 
TreeView 1.1.4r5 » edu » stanford » genetics » treeview » model » TVModel.java
/* BEGIN_HEADER                                              Java TreeView
 *
 * $Author: alokito $
 * $RCSfile: TVModel.java,v $f
 * $Revision: 1.37 $
 * $Date: 2008/04/23 23:29:19 $
 * $Name:  $
 *
 * This file is part of Java TreeView
 * Copyright (C) 2001-2003 Alok Saldanha, All Rights Reserved. Modified by Alex Segal 2004/08/13. Modifications Copyright (C) Lawrence Berkeley Lab.
 *
 * This software is provided under the GNU GPL Version 2. In particular, 
 *
 * 1) If you modify a source file, make a comment in it containing your name and the date.
 * 2) If you distribute a modified version, you must do it under the GPL 2.
 * 3) Developers are encouraged but not required to notify the Java TreeView maintainers at alok@genome.stanford.edu when they make a useful addition. It would be nice if significant contributions could be merged into the main distribution.
 *
 * A full copy of the license can be found in gpl.txt or online at
 * http://www.gnu.org/licenses/gpl.txt
 *
 * END_HEADER 
 */
package edu.stanford.genetics.treeview.model;
import java.awt.Frame;
import java.util.*;

import edu.stanford.genetics.treeview.*;

public class TVModel extends Observable implements DataModel {
  /*
   * This not-so-object-oriented hack is in those rare instances
   * where it is not enough to know that we've got a DataModel.
   */
  public String getType() {
    return "TVModel";
  }
  /** has model been successfully loaded? */
  boolean loaded = false;
  /*
   * For cases where we are comparing two models (this needs to be changed).
   */
  TVModel compareModel = null;
  int extraCompareExpr = 0;
  
    public void setModelForCompare(DataModel m)
    {
      if(m == null)
      {
        compareModel = null;
        extraCompareExpr = 0;
      }
      else
      {
        compareModel = (TVModel)m;
        extraCompareExpr = compareModel.nExpr() + 2;
      }
      hasChanged();
    }
    // accessor methods  
  public HeaderInfo getGeneHeaderInfo() {
    return geneHeaderInfo;
  }
  public HeaderInfo getArrayHeaderInfo() {
    return arrayHeaderInfo;
  }
  public DataMatrix getDataMatrix() {
    
    if(compareModel != null)
    {
      
    }
    return dataMatrix;
  }
  public HeaderInfo getAtrHeaderInfo() {
    return atrHeaderInfo;
  }
  public HeaderInfo getGtrHeaderInfo() {
    return gtrHeaderInfo;
  }
    public boolean gweightFound() {
  return gweightFound;
    }

    public int nGene() {return geneHeaderInfo.getNumHeaders();}
    public int nExpr() {return arrayHeaderInfo.getNumHeaders() + extraCompareExpr;}

  public void setExprData(double [] newData) {
    dataMatrix.setExprData(newData);
  }
    
  public double getValue(int x, int y) {
    int nexpr = nExpr();
    int ngene = nGene();
    if(x >= nexpr + 2)
    {
      if (compareModel != null)
        return compareModel.getValue(x - (nexpr + 2), y); // check offsets
    }
    else if(x >= nexpr && y < ngene)
    {
      return 0; // gray border
    }
    if ((x < nexpr && y < ngene) &&  (x >= 0    && y >= 0))
    {
      return dataMatrix.getValue(x, y);
    }
    return NODATA;
    }
    public boolean aidFound() {
  //  System.out.println("aid found called, value " + aidFound);
  return aidFound;
    };
  void aidFound(boolean newVal) {aidFound = newVal;}
    public boolean gidFound() {return gidFound;};
  void gidFound(boolean newVal) {gidFound = newVal;}

  public void setSource(FileSet source) {
    this.source = source;
    setChanged();
  }
  public String getSource() {
    if (source == null) {
    return "No Data Loaded";
    } else {
    return source.getCdt();
    }
  }
  public String getName() {
    return getFileSet().getRoot();
  }
  public FileSet getFileSet() {
    return source;
  }
    public ConfigNode getDocumentConfig() {return documentConfig.getRoot();}
    public void setDocumentConfig(XmlConfig newVal) { documentConfig = newVal;}
    public TVModel() {
    super();
    /* build TVModel, initially empty... */  
    geneHeaderInfo = new GeneHeaderInfo();
    arrayHeaderInfo = new IntHeaderInfo();
    atrHeaderInfo = new IntHeaderInfo();
    gtrHeaderInfo = new IntHeaderInfo();
    dataMatrix = new TVDataMatrix();
    }
    public void setFrame(Frame f) {
  frame = f;
    }
  public Frame getFrame() {
    return frame;
  }

  protected void hashAIDs() {
    arrayHeaderInfo.hashIDs("AID");
  }
   
  protected void hashGIDs() {
    geneHeaderInfo.hashIDs("GID");
  }
   
  protected void hashATRs() {
    atrHeaderInfo.hashIDs("NODEID");
  }
  
  protected void hashGTRs() {
    gtrHeaderInfo.hashIDs("NODEID");
  }
  
  protected Hashtable populateHash(HeaderInfo source, String headerName, Hashtable target) {
    int indexCol = source.getIndex(headerName);
    return populateHash(source, indexCol, target);
  }
   protected Hashtable populateHash(HeaderInfo source, int indexCol, Hashtable target) {
     if (target == null) {
       target = new Hashtable((source.getNumHeaders() * 4) /3, .75f);
     } else {
       target.clear();
     }

     if (indexCol <0) indexCol = 0;
     for( int i = 0; i < source.getNumHeaders(); i++) {
       target.put(source.getHeader(i)[indexCol], new Integer(i));
     }
     
     return target;
   }   
   /**
    * Reorders all the arrays in the new ordering.
    * @param ordering the new ordering of arrays, must have size equal to number of arrays
    */
  public void reorderArrays(int [] ordering)
  {
    if(ordering == null || 
        ordering.length != dataMatrix.getNumUnappendedCol()) // make sure input to function makes sense
    {
      return;
    }
  
  
    DataMatrix data = getDataMatrix();
  
    for(int j = 0; j < data.getNumRow(); j++)
    {
      double [] temp = new double[data.getNumUnappendedCol()];
      for(int i = 0; i < ordering.length; i++)
      {
        temp[i] = data.getValue(ordering[i], j);
      }
      for(int i = 0; i < ordering.length; i++)
      {
        data.setValue(temp[i], i, j);
      }
    }
    String [][]aHeaders = arrayHeaderInfo.headerArray;
    String [][] temp2 = new String[aHeaders.length][];
  
    for(int i = 0; i < aHeaders.length; i++)
    {
      if(i < ordering.length)
      {
        temp2[i] = aHeaders[ordering[i]];
      }
      else
      {
        temp2[i] = aHeaders[i];
      }
    }
    setArrayHeaders(temp2);
    hashAIDs();
    
          
    setChanged();
  }

   /**
    * Reorders all the arrays in the new ordering.
    * @param ordering the new ordering of arrays, must have size equal to number of arrays
    */
  public void reorderGenes(int [] ordering)
  {
    if(ordering == null || 
        ordering.length != dataMatrix.getNumRow()) // make sure input to function makes sense
    {
      return;
    }
    
    DataMatrix data = getDataMatrix();
    double [] temp = new double[data.getNumRow()];  
    for(int j = 0; j < data.getNumUnappendedCol(); j++)
    {
      for(int i = 0; i < ordering.length; i++)
      {
        temp[i] = data.getValue(j, ordering[i] );
      }
      for(int i = 0; i < ordering.length; i++)
      {
        data.setValue(temp[i], j, i);
      }
    }
    geneHeaderInfo.reorderHeaders(ordering);
    hashGIDs();
    setChanged();
  }

  /**
   * Reset order in config file to the identity ordering.
   */
  public void clearOrder()
  {
    ConfigNode order = documentConfig.getNode("ArrayOrder");

    for(int i = 0; i < arrayHeaderInfo.getNumHeaders(); i++)
    {
      order.setAttribute("Position" + i, i, i);
    }    
  }
  
  
  /**
   * Save a reordering to the config node.
   * @param ordering the ordering to save
   */
  public void saveOrder(int [] ordering)
  {
    ConfigNode order = documentConfig.getNode("ArrayOrder");
      
    int prevVal = 0;
    int [] temp = new int[arrayHeaderInfo.getNumHeaders()];
    
    for(int i = 0; i < dataMatrix.getNumUnappendedCol(); i++)
    {
      prevVal = order.getAttribute("Position" + ordering[i], -1);
      if(prevVal == -1)
      {
        temp[i] = ordering[i];
      }
      else
      {
        temp[i] = prevVal;
      }
    }
    
    //System.out.print("Saved ordering:  ");
    for(int i = 0; i < dataMatrix.getNumUnappendedCol(); i++)
    {
      order.setAttribute("Position" + i, temp[i], -1);
    //  System.out.print(order.getAttribute("Position" + i, -1) + " ");
    }
    //System.out.println();
    
  }
  
  /**
   * Load array order from the config node.
   */
  public void loadOrder()
  {
    if(documentConfig == null)
    {
      return;
    }
    
    ConfigNode order = documentConfig.getNode("ArrayOrder");
    
    int [] ordering = new int[dataMatrix.getNumUnappendedCol()];
    
    int prevVal = 0;
    
    
    //System.out.print("Loaded ordering:  ");
    for(int i = 0; i < ordering.length; i++)
    {
      ordering[i] = order.getAttribute("Position" + i, i);
    //  System.out.print(ordering[i] + " ");
    }
    //System.out.println();
    
    reorderArrays(ordering);
  }

   public void resetState () {
     // reset some state stuff.
     //  if (documentConfig != null)
     //          documentConfig.store();
     documentConfig = null;
     setLoaded(false);
     aidFound = false;
     gidFound = false;
     source = null;
     
     eweightFound = false;
     gweightFound = false;
     
     geneHeaderInfo.clear();
     arrayHeaderInfo.clear();
     atrHeaderInfo.clear();
     gtrHeaderInfo.clear();
     dataMatrix.clear();
   }
   
   public String toString() {
     String [] strings = toStrings();
     String msg = "";
     for (int i = 0; i < strings.length; i++) {
       msg += strings[i] + "\n";
     }
     return msg;
   }
    public String[] toStrings() {
  String[] msg = {"Selected TVModel Stats",
      "Source = " + getSource(),
      "Nexpr   = " + nExpr(),
      "NGeneHeader = " + getGeneHeaderInfo().getNumNames(),
      "Ngene   = " + nGene(),
      "eweight  = " + eweightFound,
      "gweight  = " + gweightFound,
      "aid  = " + aidFound,
      "gid  = " + gidFound};

  /*
  Enumeration e = genePrefix.elements();
  msg += "GPREFIX: " + e.nextElement();
  for (; e.hasMoreElements() ;) {
      msg += " " + e.nextElement();
  }

  e = aHeaders.elements();
  msg += "\naHeaders: " + e.nextElement();
  for (; e.hasMoreElements() ;) {
      msg += ":" + e.nextElement();
  }
  */

  return msg;
    }
    /*
    // debug functions
    private String commonEscapes() {
  String err = "Common escapes\n";
  err += "ttype TT_EOL = " + FlatFileStreamTokenizer.TT_EOL;
  err += " ttype TT_EOF = " + FlatFileStreamTokenizer.TT_EOF;
  err += " ttype TT_NUMBER = " + FlatFileStreamTokenizer.TT_NUMBER;
  err += " ttype TT_WORD = " + FlatFileStreamTokenizer.TT_WORD;
  err += " '\t' = " + '\t';
  err += " '\n' = " + '\n';
  err += " '\r' = " + '\r';

  return err;
    }
    
    private void printStream(FlatFileStreamTokenizer st) throws IOException {
  int tt = st.nextToken();
  while (tt != st.TT_EOF) {
      String msg;
      switch(tt) {
      case FlatFileStreamTokenizer.TT_WORD:
    msg = "Word: " + st.sval; break;
      case FlatFileStreamTokenizer.TT_NUMBER:
    msg = "Number: " + st.nval; break;
      case FlatFileStreamTokenizer.TT_EOL:
    msg = "EOL:"; break;
      case FlatFileStreamTokenizer.TT_NULL:
    msg = "NULL:"; break;
      default:
    msg = "INVALID TOKEN, tt=" + tt; break;
      }
      System.out.println(msg);
      tt = st.nextToken();        
  }
    }
    */
    
    public void removeAppended()
  {
    if(appendIndex == -1)
    {
      return;
    }
    int ngene = nGene();
    int nexpr = nExpr();
    double [] temp = new double[ngene*appendIndex];
    
    int i = 0;
    
    for(int g = 0; g < this.dataMatrix.getNumRow(); g++)
    {
      for(int e = 0; e < nexpr; e++)
      {
        if(e < appendIndex)
        {
          temp[i++] = getValue(e, g);
        }          
      }
    }
    dataMatrix.setExprData(temp);
    
    String [][] tempS = new String[appendIndex][];
    
    for(int j = 0; j < appendIndex; j++)
    {
      tempS[j] = arrayHeaderInfo.getHeader(j);
    }
    
    arrayHeaderInfo.setHeaderArray(tempS);
    nexpr = appendIndex;
    appendIndex = -1;
    setChanged();
  }
  
  /**
   * Appends a second matrix to this one provided they have the same height. Used for comparison of two data sets where the data is displayed side by side.
   * 
   */
  public void append(DataModel m)
  {
    int ngene = nGene();
    int nexpr = nExpr();
    if(m == null || m.getDataMatrix().getNumRow() != ngene || appendIndex != -1)
    {
      System.out.println("Could not compare.");
      return;
    }
    
    double [] temp = new double[getDataMatrix().getNumRow()* getDataMatrix().getNumCol() + 
                                m.getDataMatrix().getNumRow()*(m.getDataMatrix().getNumCol() + 1)];
    
    int i = 0;
        
    for(int g = 0; g < m.getDataMatrix().getNumRow(); g++)
    {
      for(int e = 0; e < nexpr + m.getDataMatrix().getNumCol() + 1; e++)
      {
        if(e < nexpr)
        {
          temp[i++] = getValue(e, g);
        }
        else if(e < nexpr + 1)
        {
          temp[i++] = DataModel.NODATA;
        }
        else
        {
          temp[i++] = m.getDataMatrix().getValue(e - nexpr - 1, g);
        }
        
      }
    }
    
    String [][] tempS = new String[getArrayHeaderInfo().getNumHeaders() + m.getArrayHeaderInfo().getNumHeaders() + 1][];
    
    i = 0;
    for(int j = 0; j < getArrayHeaderInfo().getNumHeaders(); j++)
    {
      tempS[i++] = getArrayHeaderInfo().getHeader(j);
    }
    
    tempS[i] = new String[getArrayHeaderInfo().getNumNames()];
    
    for(int j = 0; j < tempS[i].length; j++)
    {
      tempS[i][j] = "-----------------------";
    }
    i++;
    
    for(int j = 0; j < getArrayHeaderInfo().getNumHeaders(); j++)
    {
      tempS[i++] = getArrayHeaderInfo().getHeader(j);
    }
    
    
    arrayHeaderInfo.setHeaderArray(tempS);
    appendIndex = nexpr;
    nexpr += m.getDataMatrix().getNumCol() + 1;
    dataMatrix.setExprData(temp);
    setChanged();
  }

  int appendIndex = -1;
  
    protected Frame frame;
    protected FileSet source = null;
    protected String  dir = null;
    protected String  root;

  
  protected TVDataMatrix dataMatrix;
    
    
    protected IntHeaderInfo arrayHeaderInfo;
    protected GeneHeaderInfo geneHeaderInfo;
  protected IntHeaderInfo atrHeaderInfo;
  protected IntHeaderInfo gtrHeaderInfo;
  
  protected boolean aidFound = false;
  protected boolean gidFound = false;
    
    protected boolean eweightFound = false;
    protected boolean gweightFound = false;
    protected XmlConfig documentConfig; // holds document config
  /**
   * Really just a thin wrapper around exprData array.
   * @author aloksaldanha
   *
   */
  class TVDataMatrix implements DataMatrix {
    
      private double [] exprData = null;

    public void clear() {
      exprData = null;
    }

      public double getValue(int x, int y) {
      int nexpr = nExpr();
      int ngene = nGene();
      if ((x < nexpr) && (y < ngene) && (x >= 0) && (y >= 0)) {
        return exprData[x + y * nexpr];
      } else {
        return DataModel.NODATA;
      }
    }
    
    public void setExprData(double[] newData) {
      exprData = newData;
    }

    public void setValue(double value, int x, int y)
    {
      exprData[x + y*getNumCol()] = value;
      setChanged();
    }
    public int getNumRow() {
      return nGene();
    }
    public int getNumCol() {
      return nExpr();
    }
    
    public int getNumUnappendedCol()
    {
      return appendIndex == -1?getNumCol():appendIndex;
    }
  }

  /** holds actual node information for array tree */
  public void setAtrHeaders(String [][]atrHeaders) {
    atrHeaderInfo.setHeaderArray(atrHeaders);
  }
  /** holds header row from atr file */
  public void setAtrPrefix(String [] atrPrefix) {
    atrHeaderInfo.setPrefixArray(atrPrefix);
  }

  /** holds actual node information for gene tree */
  public void setGtrHeaders(String [][] gtrHeaders) {
    gtrHeaderInfo.setHeaderArray(gtrHeaders);
  }

  public void setGtrPrefix(String [] gtrPrefix) {
    gtrHeaderInfo.setPrefixArray(gtrPrefix);
  }

  public void setArrayHeaders(String [] [] newHeaders) {
    arrayHeaderInfo.setHeaderArray(newHeaders);
  }
  public void setArrayPrefix(String [] newPrefix) {
    arrayHeaderInfo.setPrefixArray(newPrefix);
  }
  
  
  
  class GeneHeaderInfo extends IntHeaderInfo {
    
    public int getAIDIndex() {
    return 1;
    }
  public int getGIDIndex() {
    return 0;
    }
    public int getYorfIndex() {
    if (getIndex("GID") == -1) {
      return 0;
    } else {
      return 1;
    }
    }
    public int getNameIndex() {
    if (getIndex("GID") == -1) {
      return 1;
    } else {
      return 2;
    }
    }
    
    
    /**
    * There are two special indexes, YORF and NAME.
    */
    public int getIndex(String header) {
      int retval = super.getIndex(header);
      if (retval != -1) {
        return retval;
      }
      if (header.equals("YORF")) {
        return getYorfIndex();
      }  

      if(header.equals("NAME")) {
        return getNameIndex();
      }  
      return -1;
    }
    
  }

  /**
   * A generic headerinfo, backed by private arrays.
   * 
   * @author aloksaldanha
   *
   */
  class IntHeaderInfo extends Observable implements HeaderInfo {
    private String [] prefixArray = new String[0];
    private String [][] headerArray = new String[0][];
    private Hashtable id2row = new Hashtable();
    public void hashIDs(String header) {
      int index = getIndex(header);
      id2row = populateHash(this, index , id2row);
    }
    public void clear() {
      prefixArray = new String[0];
      headerArray = new String[0][];
      id2row.clear();
    }
    public void setPrefixArray(String[] newVal) {
      prefixArray = newVal;
    }
    public void setHeaderArray(String[][] newVal) {
      headerArray = newVal;
    }
    public String [] getNames() { 
      return prefixArray;
      }
      public int getNumNames() {
        return prefixArray.length;
      }
      
      public int getNumHeaders() {
        return headerArray.length;
      }
      
      /**
      * Returns the header for a given gene and column heading.
      */
      public String [] getHeader(int gene) {
        try{
          if (headerArray[gene] == null) {
            return new String[0];
          } else {
            return headerArray[gene];
          }
        } catch (java.lang.ArrayIndexOutOfBoundsException e) {
          System.out.println("error: tried to retrieve header for  index " +
              gene + " but max is "+ headerArray.length);
          e.printStackTrace();
          return new String[0];
        }
      }

      /**
      * Returns the header for a given gene and column heading,
      * or null if not present.
      */
      public String getHeader(int gene, String col) {
      int index = getIndex(col);
      if (index == -1) {
        return null;
      }
      return getHeader(gene, index);
      }
      public String getHeader(int rowIndex, int columnIndex) {
          return (getHeader(rowIndex))[columnIndex];
      }
        public int getIndex(String header) {
          for (int i = 0 ; i < prefixArray.length; i++) {
            if (header.equalsIgnoreCase(prefixArray[i]))
            return i;
          }
          return -1;
          }
      
      public int getHeaderIndex(String id) {
        Object ind = id2row.get(id);
        if (ind == null) {
          return -1;
        } else {
          return ((Integer) ind).intValue();
        }
      }

      /**
       * adds new header column of specified name at specified index.
       * @param name
       * @param index
       * @return
       */
      public boolean addName(String name, int index) {
        int existing = getIndex(name);
        //already have this header
        if (existing != -1) return false;
        int newNumNames = getNumNames()+1;
        for (int row = 0; row < getNumHeaders(); row++) {
          String [] from = headerArray[row];
          String [] to = new String[newNumNames];
          for (int col = 0; col < index; col++)
            to[col] = from[col];
          for (int col = index+1; col < newNumNames; col++)
            to[col] = from[col-1];
          headerArray[row] = to;
        }
        String [] newPrefix = new String[newNumNames];
        for (int col = 0; col < index; col++)
          newPrefix [col] = prefixArray[col];
        newPrefix[index] = name;
        for (int col = index+1; col < newNumNames; col++)
          newPrefix [col] = prefixArray[col-1];
        prefixArray = newPrefix;
        setModified(true);
        return true;
      }
      public boolean reorderHeaders(int [] ordering) {
        if (ordering.length == headerArray.length) {          
          String [][] temp2 = new String[headerArray.length][];
          
          for(int i = 0; i < headerArray.length; i++)
          {
            if(i < ordering.length)
            {
              temp2[i] = headerArray[ordering[i]];
            }
            else
            {
              temp2[i] = headerArray[i];
            }
          }
          setHeaderArray(temp2);
          return true;
        } else {
          return false;
        }
      }
      
      public boolean setHeader(int i, String name, String value) {
        if (headerArray.length < i) return false;
        int nameIndex = getIndex(name);
        if (nameIndex == -1) return false;
        if (headerArray[i][nameIndex] == value) return false;
        headerArray[i][nameIndex] = value;
        setModified(true);
        return true;
      }
      public boolean getModified() {return modified;}
      public void setModified(boolean mod) {
        setChanged();
        notifyObservers();
        modified = mod;
      }
      private boolean modified = false;
      /*
      public void printHashKeys() {
        Enumeration e = id2row.keys();
        while (e.hasMoreElements()) {
          System.err.println(e.nextElement());
        }
      }
      */
    }
  

    void setGenePrefix(String [] newVal) {
      geneHeaderInfo.setPrefixArray(newVal);
    }
    void setGeneHeaders(String [][] newVal) {
      geneHeaderInfo.setHeaderArray(newVal);
    }
  // loading stuff follows...

    /**
     *
     *
     * @param fileSet fileset to load
     *
     */
   public void loadNew(FileSet fileSet) throws LoadException {
     resetState();
     setSource(fileSet);
     final TVModelLoader2 loader = new TVModelLoader2(this);
     loader.loadInto();
     if (!isLoaded())
       throw new LoadException("Loading Cancelled", LoadException.INTPARSE);
   }
   /**
   * Don't open a loading window...
   */
   public void loadNewNW(FileSet fileSet) throws LoadException {
     resetState();
     setSource(fileSet);
     final TVModelLoader2 loader = new TVModelLoader2(this);
     loader.loadIntoNW(); 
     if (!isLoaded())
       throw new LoadException("Loading Cancelled", LoadException.INTPARSE);
   }

  /**
   * @param b
   */
  public void setEweightFound(boolean b) {
    eweightFound = b;
  }
  /**
   * @param b
   */
  public void setGweightFound(boolean b) {
    gweightFound = b;
    
  }
  public boolean getModified() {
    return  getGtrHeaderInfo().getModified() ||
//    getGeneHeaderInfo().getModified() ||
//    getArrayHeaderInfo().getModified() ||
    getAtrHeaderInfo().getModified();
  }
  public boolean isLoaded() {
    return loaded;
  }
  public void setLoaded(boolean loaded) {
    this.loaded = loaded;
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.