/*
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.
Copyright (C) 2008 Kevin Darty, Alain Denise and Yann Ponty.
electronic mail : Yann.Ponty@lri.fr
paper mail : LRI, bat 490 University Paris-Sud 91405 Orsay Cedex France
This file is part of VARNA version 3.1.
VARNA version 3.1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
VARNA version 3.1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with VARNA version 3.1.
If not, see http://www.gnu.org/licenses.
*/
package fr.orsay.lri.varna.models.rna;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;
import fr.orsay.lri.varna.exceptions.MappingException;
public class Mapping implements Serializable {
/**
*
*/
private static final long serialVersionUID = -3031358968555310380L;
public static final int UNKNOWN = -1;
Hashtable<Integer, Integer> _mapping = new Hashtable<Integer, Integer>();
Hashtable<Integer, Integer> _invMapping = new Hashtable<Integer, Integer>();
public Mapping() {
}
public void addCouple(int i, int j) throws MappingException {
if (_mapping.containsKey(i) || _invMapping.containsKey(j)) {
throw new MappingException(
MappingException.MULTIPLE_PARTNERS_DEFINITION_ATTEMPT);
}
_mapping.put(new Integer(i), new Integer(j));
_invMapping.put(new Integer(j), new Integer(i));
}
public int getPartner(int i) {
if (!_mapping.containsKey(i))
return UNKNOWN;
else
return _mapping.get(i);
}
public int getAncestor(int j) {
if (!_invMapping.containsKey(j))
return UNKNOWN;
else
return _invMapping.get(j);
}
public int[] getSourceElems() {
int[] elems = new int[_mapping.size()];
Enumeration<Integer> en = _mapping.keys();
int i = 0;
while (en.hasMoreElements()) {
int a = en.nextElement();
elems[i] = a;
i++;
}
return elems;
}
public int[] getTargetElems() {
int[] elems = new int[_invMapping.size()];
Enumeration<Integer> en = _invMapping.keys();
int i = 0;
while (en.hasMoreElements()) {
int a = en.nextElement();
elems[i] = a;
i++;
}
return elems;
}
public static Mapping readMappingFromAlignment(String m, String n)
throws MappingException {
Mapping map = new Mapping();
if (m.length() != n.length()) {
throw new MappingException(MappingException.BAD_ALIGNMENT_INPUT);
}
int i = 0;
int j = 0;
for (int k = 0; k < m.length(); k++) {
char a = m.charAt(k);
char b = n.charAt(k);
if ((a != '-') && (a != ':') && (b != '-') && (b != ':')) {
map.addCouple(i, j);
}
if ((a != '-') && (a != ':')) {
j++;
}
if ((b != '-') && (b != ':')) {
i++;
}
}
return map;
}
public static Mapping DefaultMapping(int n, int m) {
Mapping map = new Mapping();
try {
for (int i = 0; i < Math.min(n, m); i++) {
map.addCouple(i, i);
}
} catch (MappingException e) {
e.printStackTrace();
}
return map;
}
public static Mapping DefaultOutermostMapping(int n, int m) {
Mapping map = new Mapping();
try {
int k = Math.min(n, m);
int i = 0;
int j = 0;
boolean pile = true;
while (i <= (k - 1) - j) {
if (pile) {
map.addCouple(i, i);
i++;
} else {
map.addCouple(n - 1 - j, m - 1 - j);
j++;
}
pile = !pile;
}
} catch (MappingException e) {
e.printStackTrace();
}
// System.println(map);
return map;
}
public String toString() {
Enumeration<Integer> en = _mapping.keys();
String tmp = "";
int l1 = 0;
int l2 = 0;
int maxIndex = 0;
while (en.hasMoreElements()) {
Integer i = en.nextElement();
Integer j = _mapping.get(i);
l1 = Math.max(l1,i);
l2 = Math.max(l2,j);
tmp += "("+i+","+j+")";
}
maxIndex = Math.max(maxIndex,Math.max(l1,l2));
String tmp1 = "";
String tmp2 = "";
en = _mapping.keys();
int i = l1;
int j = l2;
while (en.hasMoreElements()) {
Integer a = en.nextElement();
Integer b = _mapping.get(a);
while(a<i)
{
tmp1 = 'x'+tmp1;
tmp2 = '-'+tmp2;
i--;
}
while(b<j)
{
tmp1 = '-'+tmp1;
tmp2 = 'x'+tmp2;
j--;
}
tmp1 = '|'+tmp1;
tmp2 = '|'+tmp2;
i--;j--;
}
return tmp+"\n"+tmp1+"\n"+tmp2;
}
}