JAL-2089 patch broken merge to master for Release 2.10.0b1
[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.SeqCigar;
27 import jalview.datamodel.SequenceFeature;
28
29 import java.util.ArrayList;
30 import java.util.Hashtable;
31 import java.util.List;
32
33 public class FeatureScoreModel implements ScoreModelI, ViewBasedAnalysisI
34 {
35   jalview.api.FeatureRenderer fr;
36
37   @Override
38   public boolean configureFromAlignmentView(
39           jalview.api.AlignmentViewPanel view)
40   {
41     fr = view.cloneFeatureRenderer();
42     return true;
43   }
44
45   @Override
46   public float[][] findDistances(AlignmentView seqData)
47   {
48     int nofeats = 0;
49     List<String> dft = fr.getDisplayedFeatureTypes();
50     nofeats = dft.size();
51     SeqCigar[] seqs = seqData.getSequences();
52     int noseqs = seqs.length;
53     int cpwidth = 0;// = seqData.getWidth();
54     float[][] distance = new float[noseqs][noseqs];
55     if (nofeats == 0)
56     {
57       for (float[] d : distance)
58       {
59         for (int i = 0; i < d.length; d[i++] = 0f)
60         {
61           ;
62         }
63       }
64       return distance;
65     }
66     // need to get real position for view position
67     int[] viscont = seqData.getVisibleContigs();
68     for (int vc = 0; vc < viscont.length; vc += 2)
69     {
70
71       for (int cpos = viscont[vc]; cpos <= viscont[vc + 1]; cpos++)
72       {
73         cpwidth++;
74         // get visible features at cpos under view's display settings and
75         // compare them
76         List<Hashtable<String, SequenceFeature>> sfap = new ArrayList<Hashtable<String, SequenceFeature>>();
77         for (int i = 0; i < noseqs; i++)
78         {
79           Hashtable<String, SequenceFeature> types = new Hashtable<String, SequenceFeature>();
80           int spos = seqs[i].findPosition(cpos);
81           if (spos != -1)
82           {
83             List<SequenceFeature> sfs = fr.findFeaturesAtRes(
84                     seqs[i].getRefSeq(), spos);
85             for (SequenceFeature sf : sfs)
86             {
87               types.put(sf.getType(), sf);
88             }
89           }
90           sfap.add(types);
91         }
92         for (int i = 0; i < (noseqs - 1); i++)
93         {
94           if (cpos == 0)
95           {
96             distance[i][i] = 0f;
97           }
98           for (int j = i + 1; j < noseqs; j++)
99           {
100             int sfcommon = 0;
101             // compare the two lists of features...
102             Hashtable<String, SequenceFeature> fi = sfap.get(i), fk, fj = sfap
103                     .get(j);
104             if (fi.size() > fj.size())
105             {
106               fk = fj;
107             }
108             else
109             {
110               fk = fi;
111               fi = fj;
112             }
113             for (String k : fi.keySet())
114             {
115               SequenceFeature sfj = fk.get(k);
116               if (sfj != null)
117               {
118                 sfcommon++;
119               }
120             }
121             distance[i][j] += (fi.size() + fk.size() - 2f * sfcommon);
122             distance[j][i] += distance[i][j];
123           }
124         }
125       }
126     }
127     for (int i = 0; i < noseqs; i++)
128     {
129       for (int j = i + 1; j < noseqs; j++)
130       {
131         distance[i][j] /= cpwidth;
132         distance[j][i] = distance[i][j];
133       }
134     }
135     return distance;
136   }
137
138   @Override
139   public String getName()
140   {
141     return "Sequence Feature Similarity";
142   }
143
144   @Override
145   public boolean isDNA()
146   {
147     return true;
148   }
149
150   @Override
151   public boolean isProtein()
152   {
153     return true;
154   }
155
156   @Override
157   public String toString()
158   {
159     return "Score between sequences based on hamming distance between binary vectors marking features displayed at each column";
160   }
161 }