/* * 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; } }