Merge branch 'Jalview-JS/jim/JAL-3253-JAL-3418' into Jalview-JS/JAL-3253-applet
[jalview.git] / srcjar / fr / orsay / lri / varna / models / rna / Mapping.java
1 /*
2  VARNA is a tool for the automated drawing, visualization and annotation of the secondary structure of RNA, designed as a companion software for web servers and databases.
3  Copyright (C) 2008  Kevin Darty, Alain Denise and Yann Ponty.
4  electronic mail : Yann.Ponty@lri.fr
5  paper mail : LRI, bat 490 Université Paris-Sud 91405 Orsay Cedex France
6
7  This file is part of VARNA version 3.1.
8  VARNA version 3.1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
9  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
10
11  VARNA version 3.1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  See the GNU General Public License for more details.
14
15  You should have received a copy of the GNU General Public License along with VARNA version 3.1.
16  If not, see http://www.gnu.org/licenses.
17  */
18 package fr.orsay.lri.varna.models.rna;
19
20 import java.io.Serializable;
21 import java.util.Enumeration;
22 import java.util.Hashtable;
23
24 import fr.orsay.lri.varna.exceptions.MappingException;
25
26 public class Mapping implements Serializable {
27
28         /**
29          * 
30          */
31         private static final long serialVersionUID = -3031358968555310380L;
32
33         public static final int UNKNOWN = -1;
34
35         Hashtable<Integer, Integer> _mapping = new Hashtable<Integer, Integer>();
36         Hashtable<Integer, Integer> _invMapping = new Hashtable<Integer, Integer>();
37
38         public Mapping() {
39
40         }
41
42         public void addCouple(int i, int j) throws MappingException {
43                 if (_mapping.containsKey(i) || _invMapping.containsKey(j)) {
44                         throw new MappingException(
45                                         MappingException.MULTIPLE_PARTNERS_DEFINITION_ATTEMPT);
46                 }
47
48                 _mapping.put(new Integer(i), new Integer(j));
49                 _invMapping.put(new Integer(j), new Integer(i));
50         }
51
52         public int getPartner(int i) {
53                 if (!_mapping.containsKey(i))
54                         return UNKNOWN;
55                 else
56                         return _mapping.get(i);
57         }
58
59         public int getAncestor(int j) {
60                 if (!_invMapping.containsKey(j))
61                         return UNKNOWN;
62                 else
63                         return _invMapping.get(j);
64         }
65
66         public int[] getSourceElems() {
67                 int[] elems = new int[_mapping.size()];
68                 Enumeration<Integer> en = _mapping.keys();
69                 int i = 0;
70                 while (en.hasMoreElements()) {
71                         int a = en.nextElement();
72                         elems[i] = a;
73                         i++;
74                 }
75                 return elems;
76         }
77
78         public int[] getTargetElems() {
79                 int[] elems = new int[_invMapping.size()];
80                 Enumeration<Integer> en = _invMapping.keys();
81                 int i = 0;
82                 while (en.hasMoreElements()) {
83                         int a = en.nextElement();
84                         elems[i] = a;
85                         i++;
86                 }
87                 return elems;
88         }
89
90         public static Mapping readMappingFromAlignment(String m, String n)
91                         throws MappingException {
92                 Mapping map = new Mapping();
93                 if (m.length() != n.length()) {
94                         throw new MappingException(MappingException.BAD_ALIGNMENT_INPUT);
95                 }
96                 int i = 0;
97                 int j = 0;
98                 for (int k = 0; k < m.length(); k++) {
99                         char a = m.charAt(k);
100                         char b = n.charAt(k);
101                         if ((a != '-') && (a != ':') && (b != '-') && (b != ':')) {
102                                 map.addCouple(i, j);
103                         }
104
105                         if ((a != '-') && (a != ':')) {
106                                 j++;
107                         }
108                         if ((b != '-') && (b != ':')) {
109                                 i++;
110                         }
111                 }
112                 return map;
113         }
114
115         public static Mapping DefaultMapping(int n, int m) {
116                 Mapping map = new Mapping();
117                 try {
118                         for (int i = 0; i < Math.min(n, m); i++) {
119                                 map.addCouple(i, i);
120                         }
121                 } catch (MappingException e) {
122                         e.printStackTrace();
123                 }
124                 return map;
125         }
126
127         public static Mapping DefaultOutermostMapping(int n, int m) {
128                 Mapping map = new Mapping();
129                 try {
130                         int k = Math.min(n, m);
131                         int i = 0;
132                         int j = 0;
133                         boolean pile = true;
134                         while (i <= (k - 1) - j) {
135                                 if (pile) {
136                                         map.addCouple(i, i);
137                                         i++;
138                                 } else {
139                                         map.addCouple(n - 1 - j, m - 1 - j);
140                                         j++;
141                                 }
142                                 pile = !pile;
143                         }
144                 } catch (MappingException e) {
145                         e.printStackTrace();
146                 }
147                 // System.println(map);
148                 return map;
149         }
150
151         public String toString() {
152                 Enumeration<Integer> en = _mapping.keys();
153                 String tmp = "";
154                 int l1 = 0;
155                 int l2 = 0;
156                 int maxIndex = 0;
157                 while (en.hasMoreElements()) {
158                         Integer i = en.nextElement();
159                         Integer j = _mapping.get(i);
160                         l1 = Math.max(l1,i);
161                         l2 = Math.max(l2,j);
162                         tmp += "("+i+","+j+")";
163                 }
164                 maxIndex = Math.max(maxIndex,Math.max(l1,l2));
165                 String tmp1 = ""; 
166                 String tmp2 = ""; 
167                 en = _mapping.keys();
168                 
169                 int i = l1;
170                 int j = l2;
171                 while (en.hasMoreElements()) {
172                         Integer a = en.nextElement();
173                         Integer b = _mapping.get(a);
174                         while(a<i)
175                         {
176                                 tmp1 = 'x'+tmp1;
177                                 tmp2 = '-'+tmp2;
178                                 i--;
179                         }
180                         while(b<j)
181                         {
182                                 tmp1 = '-'+tmp1;
183                                 tmp2 = 'x'+tmp2;
184                                 j--;
185                         }
186                         tmp1 = '|'+tmp1;
187                         tmp2 = '|'+tmp2;
188                         i--;j--;
189                 }
190                 return tmp+"\n"+tmp1+"\n"+tmp2;
191         }
192 }