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