/*
* This file is part of the Vamsas Client version 0.1.
* Copyright 2009 by Jim Procter, Iain Milne, Pierre Marguerite,
* Andrew Waterhouse and Dominik Lindner.
*
* Earlier versions have also been incorporated into Jalview version 2.4
* since 2008, and TOPALi version 2 since 2007.
*
* The Vamsas Client is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Vamsas Client 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Vamsas Client. If not, see .
*/
package uk.ac.vamsas.objects.utils;
import java.util.Vector;
import uk.ac.vamsas.objects.core.Local;
import uk.ac.vamsas.objects.core.MapType;
import uk.ac.vamsas.objects.core.Mapped;
import uk.ac.vamsas.objects.core.RangeType;
import uk.ac.vamsas.objects.core.Seg;
/**
* Utilities for working with RangeType and MapType objects. Derived from bitter
* experience.
*
* @author JimP
*
*/
public class Range {
static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
.getFactory().getLog(Range.class);
/**
* get start 0 && dseta.getPosCount() > 0) {
throw new Error(
"Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
}
if (dseta.getSegCount() > 0) {
se = getSegRange(dseta.getSeg(0), true);
for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++) {
int nse[] = getSegRange(dseta.getSeg(s), true);
if (se[0] > nse[0]) {
se[0] = nse[0];
}
if (se[1] < nse[1]) {
se[1] = nse[1];
}
}
}
if (dseta.getPosCount() > 0) {
// could do a polarity for pos range too. and pass back indication of
// discontinuities.
int pos = dseta.getPos(0).getI();
se = new int[] { pos, pos };
for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++) {
pos = dseta.getPos(p).getI();
if (se[0] > pos) {
se[0] = pos;
}
if (se[1] < pos) {
se[1] = pos;
}
}
}
return se;
}
return null;
}
/**
* map from a rangeType's internal frame to the referenced object's coordinate
* frame.
*
* @param dseta
* @return int [] { ref(pos)...} for all pos in rangeType's frame.
*/
public static int[] getMapping(RangeType dseta) {
Vector posList = new Vector();
if (dseta != null) {
int[] se = null;
if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0) {
throw new Error(
"Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
}
if (dseta.getSegCount() > 0) {
for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++) {
se = getSegRange(dseta.getSeg(s), false);
int se_end = se[1 - se[2]] + (se[2] == 0 ? 1 : -1);
for (int p = se[se[2]]; p != se_end; p += se[2] == 0 ? 1 : -1) {
posList.add(new Integer(p));
}
}
} else if (dseta.getPosCount() > 0) {
int pos = dseta.getPos(0).getI();
for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++) {
pos = dseta.getPos(p).getI();
posList.add(new Integer(pos));
}
}
}
if (posList != null && posList.size() > 0) {
int[] range = new int[posList.size()];
for (int i = 0; i < range.length; i++) {
range[i] = ((Integer) posList.elementAt(i)).intValue();
}
posList.clear();
return range;
}
return null;
}
public static int[] getIntervals(RangeType range) {
int[] intervals = null;
Vector posList = new Vector();
if (range != null) {
int[] se = null;
if (range.getSegCount() > 0 && range.getPosCount() > 0) {
throw new Error(
"Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
}
if (range.getSegCount() > 0) {
for (int s = 0, sSize = range.getSegCount(); s < sSize; s++) {
se = getSegRange(range.getSeg(s), false);
posList.addElement(new Integer(se[0]));
posList.addElement(new Integer(se[1]));
}
} else if (range.getPosCount() > 0) {
int pos = range.getPos(0).getI();
for (int p = 0, pSize = range.getPosCount(); p < pSize; p++) {
pos = range.getPos(p).getI();
posList.add(new Integer(pos));
posList.add(new Integer(pos));
}
}
}
if (posList != null && posList.size() > 0) {
intervals = new int[posList.size()];
java.util.Enumeration e = posList.elements();
int i = 0;
while (e.hasMoreElements()) {
intervals[i++] = ((Integer) e.nextElement()).intValue();
}
}
return intervals;
}
/**
* initialise a range type object from a set of start/end inclusive intervals
*
* @param mrt
* @param range
*/
public static void initRangeType(RangeType mrt, int[] range) {
for (int i = 0; i < range.length; i += 2) {
Seg vSeg = new Seg();
vSeg.setStart(range[i]);
vSeg.setEnd(range[i + 1]);
vSeg.setInclusive(true);
mrt.addSeg(vSeg);
}
}
/**
*
* @param maprange
* where the from range is the local mapped range, and the to range
* is the 'mapped' range in the MapRangeType
* @param default unit for local
* @param default unit for mapped
* @return MapList
*/
public static MapList parsemapType(MapType maprange, int localu, int mappedu) {
MapList ml = null;
int[] localRange = getIntervals(maprange.getLocal());
int[] mappedRange = getIntervals(maprange.getMapped());
long lu = maprange.getLocal().hasUnit() ? maprange.getLocal().getUnit()
: localu;
long mu = maprange.getMapped().hasUnit() ? maprange.getMapped().getUnit()
: mappedu;
ml = new MapList(localRange, mappedRange, (int) lu, (int) mu);
return ml;
}
/**
* Parse map with default units of 1,1
*
* @param map
* @return MapList representing map
*/
public static MapList parsemapType(MapType map) {
if (!map.getLocal().hasUnit() || !map.getMapped().hasUnit()) {
if (log.isDebugEnabled()) {
log.debug("using default mapping length of 1:1 for map "
+ (map.isRegistered() ? map.getVorbaId().toString()
: (" " + map.toString())));
}
}
return parsemapType(map, 1, 1);
}
/**
* initialise a MapType object from a MapList object.
*
* @param maprange
* @param ml
* @param setUnits
*/
public static void initMapType(MapType maprange, MapList ml, boolean setUnits) {
initMapType(maprange, ml, setUnits, false);
}
/**
*
* @param maprange
* @param ml
* @param setUnits
* @param reverse
* - reverse MapList mapping for Local and Mapped ranges and units
*/
public static void initMapType(MapType maprange, MapList ml,
boolean setUnits, boolean reverse) {
maprange.setLocal(new Local());
maprange.setMapped(new Mapped());
if (!reverse) {
initRangeType(maprange.getLocal(), ml.getFromRanges());
initRangeType(maprange.getMapped(), ml.getToRanges());
} else {
initRangeType(maprange.getLocal(), ml.getToRanges());
initRangeType(maprange.getMapped(), ml.getFromRanges());
}
if (setUnits) {
if (!reverse) {
maprange.getLocal().setUnit(ml.getFromRatio());
maprange.getMapped().setUnit(ml.getToRatio());
} else {
maprange.getLocal().setUnit(ml.getToRatio());
maprange.getMapped().setUnit(ml.getFromRatio());
}
}
}
}