JAL-629 improvements to argparser toString. Improvements to cli paeFile structure...
[jalview.git] / src / jalview / datamodel / ContactMatrix.java
1 package jalview.datamodel;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.StringTokenizer;
6
7 import jalview.bin.Console;
8
9 public abstract class ContactMatrix implements ContactMatrixI
10 {
11   /**
12    * are contacts reflexive ?
13    */
14   boolean symmetric = true;
15
16   public ContactMatrix(boolean symmetric)
17   {
18     this.symmetric = symmetric;
19   }
20
21   List<List<Float>> contacts = null;
22
23   int width = 0, numcontacts = 0;
24
25   float min = 0f, max = 0f;
26
27   public void addContact(int left, int right, float strength)
28   {
29     if (left < 0 || right < 0)
30     {
31       throw new Error(new RuntimeException(
32               "Cannot have negative indices for contact left=" + left
33                       + " right=" + right + " strength=" + strength));
34     }
35     if (symmetric)
36     {
37       if (left > right)
38       {
39         // swap
40         int r = right;
41         right = left;
42         left = r;
43       }
44     }
45     if (contacts == null)
46     {
47       // TODO: use sparse list for efficiency ?
48       contacts = new ArrayList<List<Float>>();
49     }
50     List<Float> clist = contacts.get(left);
51     if (clist == null)
52     {
53       clist = new ArrayList<Float>();
54       contacts.set(left, clist);
55     }
56     Float last = clist.set(right, strength);
57     // TODO: if last is non null, may need to recompute range
58     checkBounds(strength);
59     if (last == null)
60     {
61       numcontacts++;
62     }
63   }
64
65   private void checkBounds(float strength)
66   {
67     if (min > strength)
68     {
69       min = strength;
70     }
71     if (max < strength)
72     {
73       max = strength;
74     }
75   }
76
77   @Override
78   public ContactListI getContactList(final int column)
79   {
80     if (column < 0 || column >= width)
81     {
82       return null;
83     }
84
85     return new ContactListImpl(new ContactListProviderI()
86     {
87       int p = column;
88
89       @Override
90       public int getPosition()
91       {
92         return p;
93       }
94
95       @Override
96       public int getContactHeight()
97       {
98         return width;
99
100       }
101
102       @Override
103       public double getContactAt(int column)
104       {
105         List<Float> clist;
106         Float cl = null;
107         if (symmetric)
108         {
109           if (p < column)
110           {
111             clist = contacts.get(p);
112             cl = clist.get(column);
113           }
114           else
115           {
116             clist = contacts.get(column);
117             cl = clist.get(p);
118           }
119         }
120         else
121         {
122           clist = contacts.get(p);
123           cl = clist.get(column);
124         }
125         if (cl == null)
126         {
127           // return 0 not NaN ?
128           return Double.NaN;
129         }
130         return cl.doubleValue();
131       }
132     });
133   }
134
135   @Override
136   public float getMin()
137   {
138     return min;
139   }
140
141   @Override
142   public float getMax()
143   {
144     return max;
145   }
146
147   @Override
148   public boolean hasReferenceSeq()
149   {
150     // TODO Auto-generated method stub
151     return false;
152   }
153
154   @Override
155   public SequenceI getReferenceSeq()
156   {
157     // TODO Auto-generated method stub
158     return null;
159   }
160
161   @Override
162   public String getAnnotLabel()
163   {
164     return "Contact Matrix";
165   }
166
167   @Override
168   public String getAnnotDescr()
169   {
170     return "Contact Matrix";
171   }
172
173   public static String contactToFloatString(ContactMatrixI cm)
174   {
175     StringBuilder sb = new StringBuilder();
176     for (int c = 0; c < cm.getWidth(); c++)
177     {
178       ContactListI cl = cm.getContactList(c);
179       if (cl != null)
180       {
181         for (int h = 0; h <= cl.getContactHeight(); h++)
182         {
183           if (sb.length() > 0)
184           {
185             sb.append('\t');
186           }
187           sb.append(cl.getContactAt(h));
188         }
189       }
190     }
191     return sb.toString();
192   }
193
194   public static float[][] fromFloatStringToContacts(String values, int cols,
195           int rows)
196   {
197     float[][] vals = new float[cols][rows];
198     StringTokenizer tabsep = new StringTokenizer(values, "" + '\t');
199     int c = 0, r = 0;
200
201     while (tabsep.hasMoreTokens())
202     {
203       double elem = Double.valueOf(tabsep.nextToken());
204       vals[c][r++] = (float) elem;
205       if (r >= vals[c].length)
206       {
207         r = 0;
208         c++;
209       }
210       if (c >= vals.length)
211       {
212
213         break;
214       }
215     }
216     if (tabsep.hasMoreElements())
217     {
218       Console.warn(
219               "Ignoring additional elements for Float string to contact matrix parsing.");
220     }
221
222     return vals;
223   }
224 }