package utils.nexus;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.BitSet;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.math.IntRange;
import org.apache.log4j.Logger;
import utils.RangeUtils;
public class CodonPositions{
private static final Logger logger = Logger.getLogger(CodonPositions.class);
private CodonRanges codonRanges;
private int readingFrame;
private TranslatedAminoAcidPositions translatedAminoAcidPos;
public CodonPositions(){
this(new CodonRanges(), 1);
}
public int size() {
return codonRanges.size();
}
private CodonPositions(CodonRanges positionsArray, int readingFrame) {
this.setCodonRandes(positionsArray);
this.readingFrame = readingFrame;
}
public boolean isNonCoding(int pos){
return codonRanges.getPosVal(pos) == 0;
}
public boolean isCoding(int pos) {
return codonRanges.getPosVal(pos) != 0;
}
private TranslatedAminoAcidPositions getTranslatedAminoAcidPositions() {
if(translatedAminoAcidPos == null){
translatedAminoAcidPos = new TranslatedAminoAcidPositions(this.codonRanges, this.readingFrame);
}
return translatedAminoAcidPos;
}
public int getAminoAcidPosFromNucleotidePos(int pos){
TranslatedAminoAcidPositions aaPositions = getTranslatedAminoAcidPositions();
return getTranslatedAminoAcidPositions().getAAPosAtNucleotidePos(pos);
}
public CodonPos getCodonAtNucleotidePos(int pos){
return getTranslatedAminoAcidPositions().getCodonAtNucleotidePos(pos);
}
public CodonPos getCodonInTranslatedPos(int pos) {
return getTranslatedAminoAcidPositions().getCodonAtTranslatedPos(pos);
}
public boolean isFullCodonStartingAt(int x) {
boolean isFullCodon = false;
if(getReadingFrame() == 1){
if(getCodonRanges().getPosVal(x) == 1 && getCodonRanges().getPosVal(x+1) == 2 && getCodonRanges().getPosVal(x+2) == 3){
isFullCodon = true;
}
}
if(getReadingFrame() == 2){
if(getCodonRanges().getPosVal(x) == 2 && getCodonRanges().getPosVal(x+1) == 3 && getCodonRanges().getPosVal(x+2) == 1){
isFullCodon = true;
}
}
if(getReadingFrame() == 3){
if(getCodonRanges().getPosVal(x) == 3 && getCodonRanges().getPosVal(x+1) == 1 && getCodonRanges().getPosVal(x+2) == 2){
isFullCodon = true;
}
}
return isFullCodon;
}
public boolean isPartOfFullCodon(int x){
// if full codon check x (x-1 && x -2)
if(isFullCodonStartingAt(x)){
return true;
}else if(isFullCodonStartingAt(x - 1)){
return true;
}else if(isFullCodonStartingAt(x - 2)){
return true;
}else{
return false;
}
}
public ArrayList<IntRange> getAllNonCodingPositionsAsRanges(int wanted, int startPos, int endPos) {
ArrayList<IntRange> allRanges = new ArrayList<IntRange>();
int lastPos = -1;
int firstPos = -1;
// look at uninterupted ranges of the wanted codonInteger - since this in noncoding - they should be next to each other
// loop all position three times, start in position 0 (offset) and after that start in pos 1 and pos 2
logger.info("endpos"+endPos);
// logger.info("arrayLen"+getPositionsArray().getLength());
for(int n = startPos; n < endPos; n++){
if(getCodonRanges().getPosVal(n) == wanted){
if(firstPos == -1){
firstPos = n;
}
lastPos = n;
}else{
// if there is a firstPos define range
if(firstPos != -1){
IntRange range = new IntRange(firstPos,lastPos);
allRanges.add(range);
}
// start a new range
firstPos = -1;
lastPos = -1;
}
}
// sort them
RangeUtils.sortIntRangeList(allRanges);
return allRanges;
}
public ArrayList<IntRange> getAllCodingPositionsAsIntRanges(int wanted, int startPos, int endPos) {
ArrayList<IntRange> allRanges = new ArrayList<IntRange>();
int lastPos = -1;
int firstPos = -1;
// look at uninterupted ranges of the wanted codonInteger at every third position
// loop all position three times, start in position 0 (offset) and after that start in pos 1 and pos 2
for(int offset = 0; offset <= 2; offset++){
for(int n = startPos + offset; n < endPos; n = n +3){
if(getCodonRanges().getPosVal(n) == wanted){
if(firstPos == -1){
firstPos = n;
}
lastPos = n;
}else{
// if there is a firstPos define range
if(firstPos != -1){
IntRange range = new IntRange(firstPos,lastPos);
allRanges.add(range);
}
// start a new range
firstPos = -1;
lastPos = -1;
}
}
// And at end of offset
// if there is a firstPos define range
if(firstPos != -1){
IntRange range = new IntRange(firstPos,lastPos);
allRanges.add(range);
}
// start a new range
firstPos = -1;
lastPos = -1;
}
// sort them
RangeUtils.sortIntRangeList(allRanges);
return allRanges;
}
public void setReadingFrame(int readingFrame) {
this.readingFrame = readingFrame;
positionsUpdated();
}
public int getReadingFrame() {
return readingFrame;
}
public ArrayList<Integer> getAllPositions(int wantedCodonPosInteger, int startPos, int endPosInclusive) {
ArrayList<Integer> allPos = new ArrayList<Integer>();
for(int n = startPos; n <= endPosInclusive; n++){
if(getCodonRanges().getPosVal(n) == wantedCodonPosInteger){
allPos.add(new Integer(n));
}
}
return allPos;
}
public void addRange(CodonRange range){
codonRanges.addRange(range);
}
public void addRange(int start, int end, int firstVal) {
codonRanges.addRange(new CodonRange(start, end, firstVal));
}
public void positionsUpdated() {
translatedAminoAcidPos = null;
}
public void reverse(int length) {
codonRanges.reverse(length);
positionsUpdated();
}
public CodonPositions getCopy(){
return new CodonPositions(this.codonRanges.getCopy(), this.readingFrame);
}
public CodonRanges getCodonRanges() {
return codonRanges;
}
public void setCodonRandes(CodonRanges codonRanges) {
this.codonRanges = codonRanges;
positionsUpdated();
}
public int getPosAt(int x){
return this.codonRanges.getPosVal(x);
}
public void deletePosition(int n) {
this.codonRanges.removePosition(n);
positionsUpdated();
}
public void insertPosition(int n) {
this.codonRanges.insert(n);
positionsUpdated();
}
public boolean isAnythingButDefault() {
return codonRanges.isAnythingButDefault();
}
public int[] translatePositions(int[] selection) {
if(selection == null){
return null;
}
int[] translated = new int[selection.length];
for(int n = 0; n < selection.length; n++){
translated[n] = getAminoAcidPosFromNucleotidePos(selection[n]);
}
return translated;
}
public int[] reTranslatePositions(int[] selection) {
if(selection == null){
return null;
}
ArrayList<Integer> reTranslated = new ArrayList<Integer>(selection.length * 3);
for(int n = 0; n < selection.length; n++){
CodonPos codon = getCodonInTranslatedPos(selection[n]);
for(int i = codon.startPos; i <= codon.endPos; i++){
reTranslated.add(new Integer(i));
}
}
return ArrayUtils.toPrimitive(reTranslated.toArray(new Integer[0]));
}
public Rectangle reTranslatePositions(Rectangle bounds) {
CodonPos codonX1 = getCodonInTranslatedPos(bounds.x);
CodonPos codonX2 = getCodonInTranslatedPos((int)bounds.getMaxX());
CodonPos codonY1 = getCodonInTranslatedPos(bounds.y);
CodonPos codonY2 = getCodonInTranslatedPos((int)bounds.getMaxY());
int width = codonX2.endPos - codonX1.startPos;
int height = codonY2.endPos - codonY2.startPos;
Rectangle trans = new Rectangle(codonX1.startPos, codonY1.startPos, width, height);
return trans;
}
public void addRanges(Ranges allRanges) {
codonRanges.setBackend(allRanges);
positionsUpdated();
}
}