updated jalview version of dasobert 1.53e client and added Das Sequence Source discov...
[jalview.git] / src / org / biojava / dasobert / feature / FeatureTrackConverter.java
diff --git a/src/org/biojava/dasobert/feature/FeatureTrackConverter.java b/src/org/biojava/dasobert/feature/FeatureTrackConverter.java
new file mode 100644 (file)
index 0000000..d7dee86
--- /dev/null
@@ -0,0 +1,490 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Dec 5, 2007
+ * 
+ */
+
+package org.biojava.dasobert.feature;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+
+
+/** converts the features from their "raw" representation as a Map
+ * into a Feature class
+ * @author Andreas Prlic
+ *
+ */
+public class FeatureTrackConverter {
+
+       public static final Color HELIX_COLOR  = new Color(255,51,51);
+       public static final Color STRAND_COLOR = new Color(255,204,51);
+       public static final Color TURN_COLOR   = new Color(204,204,204); 
+
+
+       // some  annotation types, for which there is a special treatment
+       public static final String DISULFID_TYPE = "DISULFID";
+       public static final String SECSTRUC_TYPE = "SECSTRUC";
+       public static final String METAL_TYPE    = "METAL";
+       public static final String MSD_SITE_TYPE = "MSD_SITE";
+
+       String type;
+       public static final String TYPE_HISTOGRAM = "histogram";
+       public static final String TYPE_DEFAULT   = "default";
+
+
+       // rotate between these colors
+       public static final  Color[] entColors = new Color []{
+               new Color(51,51,255), // blue
+               new Color(102,255,255),    // cyan
+               new Color(153,255,153), // green
+               new Color(153,255,153), // green
+               new Color(255,153,153), // pink
+               new Color(255,51,51),   // red
+               new Color(255,51,255)    // pink 
+       };
+
+       public static final String[] txtColors = new String[] { 
+               "blue",
+               "pink",
+               "green",
+               "yellow",
+               "red",
+               "cyan",
+       "pink"};
+
+       Map[] stylesheet;
+
+       boolean isHistogram = false;
+
+
+       public FeatureTrackConverter(){
+               type = TYPE_DEFAULT;    
+               stylesheet = new Map[0];
+       }
+
+       public FeatureTrackConverter(Map[] stylesheet){
+
+               if (stylesheet == null)
+                       stylesheet = new Map[0];
+
+               this.stylesheet = stylesheet;
+
+       }
+
+
+       public FeatureTrackConverter(Map[] stylesheet, boolean isHistogram){
+               this(stylesheet);
+               this.isHistogram = isHistogram;
+               if ( isHistogram)
+                       type = TYPE_HISTOGRAM;
+       }
+       public String getType() {
+               return type;
+       }
+
+       public void setType(String type) {
+               if ( type.equals(TYPE_HISTOGRAM))
+                       isHistogram = true;
+               this.type = type;
+       }
+
+       public boolean isHistogram() {
+               return isHistogram;
+       }
+
+
+       public void setHistogram(boolean isHistogram) {
+               this.isHistogram = isHistogram;
+       }
+
+       
+
+       
+
+       public  FeatureTrack[] convertMap2Features(Map[] mapfeatures){
+               List features = new ArrayList();
+
+               boolean first = true ;
+               boolean secstruc = false ;
+               boolean isGroup  = false;
+
+               FeatureTrack feat = null ;
+               Segment segment   = null ;
+
+               int featuresCounter = 0;
+               String prevGroup = null;
+
+               for (int i = 0 ; i< mapfeatures.length;i++) {
+
+                       Map currentFeatureMap = mapfeatures[i];
+                       String type = (String) currentFeatureMap.get("TYPE") ;
+
+                       
+                       
+                       String group = (String) currentFeatureMap.get("GROUP");
+                       if ( group != null){
+                               if ( prevGroup != null) {
+                                       if ( group.equals(prevGroup)){
+                                               feat.setName(group);
+                                               isGroup = true;
+                                       } else {
+                                               isGroup = false;
+                                       }
+                               } else {
+                                       isGroup = false;
+                               }
+                       } else {
+                               isGroup = false;
+                       }                       
+
+                       // we are skipping literature references for the moment 
+                       // TODO: add a display to spice for non-positional features
+                       //
+                       if ( type.equals("reference") || type.equals("GOA")){
+                               continue ;
+                       }
+
+                       if (! first) 
+                       {
+                               // if not first feature
+
+                               if ( (! secstruc ) && (! isGroup) )  {             
+
+                                       // if not secondary structure and not in a group ...
+                                       features = testAddFeatures(features,feat);
+
+
+                               } else if ( ! 
+                                               (
+                                                               type.equals("HELIX")  || 
+                                                               type.equals("STRAND") || 
+                                                               type.equals("TURN")  
+                                               ) 
+                               )
+                               {
+                                       // end of secondary structure
+                                       secstruc = false ;
+                                       if ( feat != null && (! isGroup)) {                                             
+                                               features = testAddFeatures(features,feat);                        
+                                       }
+
+                               }
+                       } // end of not first
+
+                       first = false ;             
+                       if ( (! secstruc) && (! isGroup)) {                             
+                               featuresCounter +=1;
+                               feat = getNewFeat(currentFeatureMap);       
+                       }
+
+
+
+
+                       if (type.equals("STRAND")){
+                               secstruc = true ;                               
+                               currentFeatureMap.put("colorTxt","yellow");
+                               feat.setName("SECSTRUC");       
+                               feat.setType("SECSTRUC");
+                       }
+
+                       else if (type.equals("HELIX")) {
+                               secstruc = true ;                               
+                               currentFeatureMap.put("colorTxt","red");
+                               feat.setName("SECSTRUC");
+                               feat.setType("SECSTRUC");
+                       }   
+
+                       else if (type.equals("TURN")) {
+                               secstruc = true ;                               
+                               currentFeatureMap.put("colorTxt","white");
+
+                               feat.setName("SECSTRUC");
+                               feat.setType("SECSTRUC");
+                       }     
+                       else {
+                               secstruc = false ;                              
+                               currentFeatureMap.put("colorTxt",txtColors[featuresCounter%txtColors.length]);
+                               if ( ! isGroup) {
+                                       try {
+                                               feat.setName(type);
+                                       
+                                       } catch ( NullPointerException e) {
+                                               //e.printStackTrace();
+                                               feat.setName("null");
+                                       }
+                               }
+                       }
+
+                       segment = getNewSegment(currentFeatureMap);
+
+                       feat.addSegment(segment);       
+                       prevGroup = group;
+               }   
+
+               if ( feat != null)  
+                       features =testAddFeatures(features,feat);
+
+
+               return (FeatureTrack[]) features.toArray(new FeatureTrack[features.size()]);
+       }
+
+       /**      test if this features is added as a new feature to the features list, 
+        * or if it is joint with an already existing one...
+        * 
+        * @param features
+        * @param newFeature
+        * @return a List of FeatureTrack objects
+        */
+       protected  List testAddFeatures(List features,FeatureTrack newFeature){
+               
+               //System.out.println("testing " + newFeature + " " + newFeature.getScore());   
+               Iterator iter = features.iterator();
+
+
+               if ( isHistogramFeatureType(newFeature)) {  
+                       
+                       // return histogram type features
+                       type = TYPE_HISTOGRAM;
+
+                       Segment seg = getHistogramSegmentFromFeature(newFeature);
+
+                       while (iter.hasNext()){
+                               FeatureTrack knownFeature = (FeatureTrack) iter.next() ;
+                               String knownType = knownFeature.getType();
+
+                               //System.out.println("found histogram style " + feat);
+                               // set type of this DAS source to being HISTOGRAM style
+
+
+                               if ( knownType.equals(newFeature.getType())){
+                                       // convert the feature into a HistogramSegment and add to the already known feature
+
+                                       knownFeature.addSegment(seg);
+                                       // we can return now
+                                       return features;
+                               }
+
+
+                       }
+                       // we could not link this to any existing feature
+                       // convert it to a new HistogramFeature
+                       HistogramFeature hfeat = new HistogramFeature();
+
+                       hfeat.setLink(newFeature.getLink());
+                       hfeat.setMethod(newFeature.getMethod());
+                       hfeat.setName(newFeature.getName());
+                       hfeat.setNote(newFeature.getNote());
+                       hfeat.setScore("0");
+                       hfeat.setSource(newFeature.getSource());
+                       hfeat.addSegment(seg);
+                       hfeat.setType(newFeature.getType());
+
+                       newFeature = hfeat;
+                       features.add(newFeature);
+                       return features;
+               } 
+
+
+
+               while (iter.hasNext()){
+                       FeatureTrack knownFeature = (FeatureTrack) iter.next() ;
+                       // this only compares method source and type ...
+                       boolean sameFeat = false;
+                       if ( knownFeature.equals(newFeature))
+                               sameFeat = true;
+
+                       if ( ( knownFeature.getSource().equals(newFeature.getSource() )) &&
+                                       ( knownFeature.getMethod().equals(newFeature.getMethod())) &&
+                                       ( knownFeature.getNote().equals(newFeature.getNote())) &&
+                                       isSecondaryStructureFeat(knownFeature) && 
+                                       isSecondaryStructureFeat(newFeature))
+                               sameFeat =true;
+
+                       if ( sameFeat) {
+
+                               // seems to be of same type, method and source, so check if the segments can be joined
+
+                               List tmpsegs = knownFeature.getSegments();
+                               Iterator segiter = tmpsegs.iterator();
+                               List newsegs = newFeature.getSegments();
+                               Iterator newsegsiter = newsegs.iterator();
+                               boolean overlap = false;
+                               while (newsegsiter.hasNext()){
+                                       Segment newseg = (Segment)newsegsiter.next();
+
+
+                                       while (segiter.hasNext()){
+                                               Segment tmpseg = (Segment) segiter.next();
+
+                                               if (  tmpseg.overlaps(newseg))
+                                                       overlap = true;
+                                       }
+                               }
+
+                               if ( ! overlap){
+                                       // add all new segments to old features...
+                                       newsegsiter = newsegs.iterator();
+                                       while (newsegsiter.hasNext()){
+                                               Segment newseg = (Segment)newsegsiter.next();
+                                               knownFeature.addSegment(newseg);
+                                       }
+
+                                       return features;
+                               } 
+                       }
+
+               }
+
+               //      if we get here, the  features could not be joint with any other one, so there is always some overlap
+               // add to the list of known features
+               features.add(newFeature);
+               return features;
+       }
+
+       private FeatureTrack getNewFeat(Map currentFeatureMap) {
+               FeatureTrack feat = new FeatureTrackImpl();
+               //logger.finest(currentFeatureMap);
+               //System.out.println("DrawableDasSource " + currentFeatureMap);
+               feat.setSource((String)currentFeatureMap.get("dassource"));
+               feat.setName(  (String)currentFeatureMap.get("NAME"));
+               feat.setType(  (String)currentFeatureMap.get("TYPE"));
+               feat.setLink(  (String)currentFeatureMap.get("LINK"));
+               feat.setNote(  (String)currentFeatureMap.get("NOTE"));
+               
+               String typeID       = (String) currentFeatureMap.get("TYPE_ID");
+               String typeCategory = (String) currentFeatureMap.get("TYPE_CATEGORY");
+               feat.setTypeID(typeID);
+               feat.setTypeCategory(typeCategory);
+               
+               String method = (String)currentFeatureMap.get("METHOD");
+               if ( method == null) { method = "";}
+               feat.setMethod(method);
+               feat.setScore( (String)currentFeatureMap.get("SCORE"));
+               return feat ;
+       }
+
+       private Segment getNewSegment(Map featureMap) {
+               Segment s = new SegmentImpl();
+               String sstart = (String)featureMap.get("START") ;
+               String send   = (String)featureMap.get("END")   ;
+               int start = Integer.parseInt(sstart) ;
+               int end   = Integer.parseInt(send)   ;
+               s.setStart(start);
+               s.setEnd(end);
+               s.setName((String)featureMap.get("TYPE"));
+               s.setTxtColor((String)featureMap.get("colorTxt"));  
+               s.setColor((Color)featureMap.get("color"));
+               s.setNote((String) featureMap.get("NOTE"));
+               return s ;
+
+       }
+
+       private boolean isSecondaryStructureFeat(FeatureTrack feat){
+               String type = feat.getType();
+               if (
+                               type.equals("HELIX")  || 
+                               type.equals("STRAND") || 
+                               type.equals("TURN")
+               ) return true;
+               return false;
+       }
+
+       private boolean isHistogramFeatureType(FeatureTrack feat){
+               String ftype = feat.getType();
+
+               Map[] style = stylesheet;
+
+               //System.out.println("is HistogramFeature type " + ftype + " " + style );
+
+
+               // todo : move this info into a config file...
+
+               if ( ftype.equals("hydrophobicity")){
+                       return true;
+               }
+               if ( getType().equals(TYPE_HISTOGRAM) )
+                       return true;
+
+
+
+               if (style != null ) {
+
+                       for ( int i =0; i< style.length ; i++){
+                               Map m = style[i];
+
+                               // make sure the stylesheet is for this feature type
+                               String styleType = (String) m.get("type");
+                               if ( styleType != null) {
+                                       if ( ! styleType.equals(ftype)){
+                                               continue;
+                                       }
+                               } else {
+                                       continue;
+                               }
+
+                               String type = (String) m.get("style");
+                               if ( type != null) {
+                                       //System.out.println("stylesheet type " + type);
+                                       if ( type.equals("gradient") || ( type.equals("lineplot")) || ( type.equals("histogram"))){
+
+                                               return true;
+                                       }
+                               }
+                       }
+               }
+
+               return false;
+       }
+
+
+       private HistogramSegment getHistogramSegmentFromFeature(FeatureTrack feat){
+               HistogramSegment s = new HistogramSegment();
+
+               double score = 0.0;
+
+               try {
+                       score = Double.parseDouble(feat.getScore());
+
+               } catch (Exception e){
+                       //e.printStackTrace();
+               }
+               s.setScore(score);              
+               List segments = feat.getSegments();
+               if (segments.size() > 0){
+                       Segment seg = (Segment) segments.get(0);
+                       s.setName(seg.getName());
+                       s.setStart(seg.getStart());
+                       s.setEnd(seg.getEnd());
+                       s.setNote(seg.getNote());
+                       s.setColor(seg.getColor());
+                       s.setTxtColor(seg.getTxtColor());
+               }
+
+
+               return s;
+       }
+
+
+}