69538d553cdc08612e96967b779badb10c09c750
[jalview.git] / src / jalview / analysis / scoremodels / FeatureScoreModel.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.analysis.scoremodels;
22
23 import jalview.api.analysis.ScoreModelI;
24 import jalview.api.analysis.ViewBasedAnalysisI;
25 import jalview.datamodel.AlignmentView;
26 import jalview.datamodel.SequenceFeature;
27 import jalview.datamodel.SequenceI;
28 import jalview.util.Comparison;
29
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Hashtable;
33 import java.util.List;
34
35 public class FeatureScoreModel implements ScoreModelI, ViewBasedAnalysisI
36 {
37   jalview.api.FeatureRenderer fr;
38
39   @Override
40   public boolean configureFromAlignmentView(
41           jalview.api.AlignmentViewPanel view)
42   {
43     fr = view.cloneFeatureRenderer();
44     return true;
45   }
46
47   @Override
48   public float[][] findDistances(AlignmentView seqData)
49   {
50     int nofeats = 0;
51     List<String> dft = Arrays.asList(fr.getDisplayedFeatureTypes());
52
53     if (dft != null)
54     {
55       nofeats = dft.size();
56     }
57
58     SequenceI[] sequenceString = seqData.getVisibleAlignment(
59             Comparison.GapChars.charAt(0)).getSequencesArray();
60     int noseqs = sequenceString.length;
61     int cpwidth = seqData.getWidth();
62     float[][] distance = new float[noseqs][noseqs];
63     if (nofeats == 0)
64     {
65       for (float[] d : distance)
66       {
67         for (int i = 0; i < d.length; d[i++] = 0f)
68         {
69           ;
70         }
71       }
72       return distance;
73     }
74     float max = 0;
75     for (int cpos = 0; cpos < cpwidth; cpos++)
76     {
77       // get visible features at cpos under view's display settings and compare
78       // them
79       List<Hashtable<String, SequenceFeature>> sfap = new ArrayList<Hashtable<String, SequenceFeature>>();
80       for (int i = 0; i < noseqs; i++)
81       {
82         Hashtable<String, SequenceFeature> types = new Hashtable<String, SequenceFeature>();
83         List<SequenceFeature> sfs = fr.findFeaturesAtRes(sequenceString[i],
84                 sequenceString[i].findPosition(cpos));
85         for (SequenceFeature sf : sfs)
86         {
87           types.put(sf.getType(), sf);
88         }
89         sfap.add(types);
90       }
91       for (int i = 0; i < (noseqs - 1); i++)
92       {
93         if (cpos == 0)
94         {
95           distance[i][i] = 0f;
96         }
97         for (int j = i + 1; j < noseqs; j++)
98         {
99           int sfcommon = 0;
100           // compare the two lists of features...
101           Hashtable<String, SequenceFeature> fi = sfap.get(i), fk, fj = sfap
102                   .get(j);
103           if (fi.size() > fj.size())
104           {
105             fk = fj;
106           }
107           else
108           {
109             fk = fi;
110             fi = fj;
111           }
112           for (String k : fi.keySet())
113           {
114             SequenceFeature sfj = fk.get(k);
115             if (sfj != null)
116             {
117               sfcommon++;
118             }
119           }
120           distance[i][j] += (fi.size() + fk.size() - 2f * sfcommon);
121           distance[j][i] += distance[i][j];
122         }
123       }
124     }
125     for (int i = 0; i < noseqs; i++)
126     {
127       for (int j = i + 1; j < noseqs; j++)
128       {
129         distance[i][j] /= cpwidth;
130         distance[j][i] = distance[i][j];
131       }
132     }
133     return distance;
134   }
135
136   @Override
137   public String getName()
138   {
139     return "Sequence Feature Similarity";
140   }
141
142   @Override
143   public boolean isDNA()
144   {
145     return true;
146   }
147
148   @Override
149   public boolean isProtein()
150   {
151     return true;
152   }
153
154   public String toString()
155   {
156     return "Score between sequences based on hamming distance between binary vectors marking features displayed at each column";
157   }
158 }