/* * EuroCarbDB, a framework for carbohydrate bioinformatics * * Copyright (c) 2006-2009, Eurocarb project, or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * A copy of this license accompanies this distribution in the file LICENSE.txt. * * This program 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. * * Last commit: $Rev: 1210 $ by $Author: glycoslave $ on $Date:: 2009-06-12 #$ */ package org.eurocarbdb.resourcesdb.monosaccharide; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import org.eurocarbdb.resourcesdb.ResourcesDbObject; import org.eurocarbdb.resourcesdb.util.Utils; /** * The Modification class is the basis for both the Substitution and the CoreModification classes. * It contains the fields and methods that are common to both types of modifications, esp. the methods for handling the positions of the monosaccharide at which the modification is present. * * @author Thomas Luetteke */ public class Modification extends ResourcesDbObject implements Comparator<Object>, Cloneable { private String name; private int valence; private ArrayList<Integer> position1; private ArrayList<Integer> position2; private String sourceName; private int modificationId = 0; public static final int EMPTYPOSITIONVALUE = -1; //***************************************************************************** //*** constructors: *********************************************************** //***************************************************************************** public Modification() { this.init(); } //***************************************************************************** //*** getters/setters: ******************************************************** //***************************************************************************** public String getName() { return name; } public void setName(String name) { this.name = name; } public int getValence() { return valence; } public void setValence(int valence) { this.valence = valence; } /** * Get the original modification name as used in the parsed source residue * @return */ public String getSourceName() { return sourceName; } /** * Set the original modification name as used in the parsed source residue * @param sourceName */ public void setSourceName(String sourceName) { this.sourceName = sourceName; } /** * @return the modificationId */ public int getModificationId() { return modificationId; } /** * @param modificationId the modificationId to set */ public void setModificationId(int modificationId) { this.modificationId = modificationId; } //***************************************************************************** //*** position related methods: *********************************************** //***************************************************************************** public ArrayList<Integer> getPosition1() { if(this.position1 == null) { this.position1 = new ArrayList<Integer>(); } return this.position1; } public String getPosition1Str(String delimiter, String unknownPositionLabel) { return Utils.formatPositionsString(this.getPosition1(), delimiter, unknownPositionLabel); } public ArrayList<Integer> getPosition1Clone() { return(Utils.cloneIntegerList(this.getPosition1())); } public int getIntValuePosition1() { if(getPosition1().size() == 0) { return(Modification.EMPTYPOSITIONVALUE); } else if(getPosition1().size() == 1) { return(getPosition1().get(0).intValue()); } else { return(0); } } public void setIntValuePosition1(int position) throws MonosaccharideException { setPosition1(position); } public void setPosition1(ArrayList<Integer> positions) { this.position1 = positions; } public void setPosition1(int position) throws MonosaccharideException { if(getPosition1() == null) { setPosition1(new ArrayList<Integer>()); } else { getPosition1().clear(); } if(position != Modification.EMPTYPOSITIONVALUE) { addPosition1(position); } } public void addPosition1(int position) throws MonosaccharideException { if(position < 0) { throw new MonosaccharideException("Modification position must not be negative."); } if(!containsPosition1(position)) { getPosition1().add(new Integer(position)); Collections.sort(getPosition1()); } } public boolean containsPosition1(int position) { for(int i = 0; i < getPosition1().size(); i++) { int usedPosition = getPosition1().get(i).intValue(); if(usedPosition == position) { return(true); } } return(false); } /** * Check, if the modification position 1 is identical with a given position * @param position: the position to be checked * @return true, if position1 contains exactly one value, which equals the position parameter */ public boolean position1equals(int position) { return(getPosition1().size() == 1 && getIntValuePosition1() == position); } public ArrayList<Integer> getPosition2() { if(this.position2 == null) { this.position2 = new ArrayList<Integer>(); } return this.position2; } public String getPosition2Str(String delimiter, String unknownPositionLabel) { return Utils.formatPositionsString(this.getPosition2(), delimiter, unknownPositionLabel); } public ArrayList<Integer> getPosition2Clone() { return(Utils.cloneIntegerList(this.getPosition2())); } public int getIntValuePosition2() { if(getPosition2().size() == 0) { return(Modification.EMPTYPOSITIONVALUE); } else if(getPosition2().size() == 1) { return(getPosition2().get(0).intValue()); } else { return(0); } } public void setIntValuePosition2(int position) throws MonosaccharideException { setPosition2(position); } public void setPosition2(ArrayList<Integer> positions) { this.position2 = positions; } public void setPosition2(int position) throws MonosaccharideException { if(getPosition2() == null) { setPosition2(new ArrayList<Integer>()); } else { getPosition2().clear(); } if(position != Modification.EMPTYPOSITIONVALUE) { addPosition2(position); } } public void addPosition2(int position) throws MonosaccharideException { if(position < 0) { throw new MonosaccharideException("Modification position must not be negative."); } if(!containsPosition2(position)) { getPosition2().add(new Integer(position)); Collections.sort(getPosition2()); } } public boolean containsPosition2(int position) { for(int i = 0; i < getPosition2().size(); i++) { int usedPosition = getPosition2().get(i).intValue(); if(usedPosition == position) { return(true); } } return(false); } /** * Check, if the modification position 2 is identical with a given position * @param position: the position to be checked * @return true, if position2 contains exactly one value, which equals the position parameter */ public boolean position2equals(int position) { return(getPosition2().size() == 1 && getIntValuePosition2() == position); } /** * Check, if a given position is contained in the positions of the modification * @param position: the position to be checked * @return true, if the given position is present, otherwise false */ public boolean containsPosition(int position) { return(containsPosition1(position) || containsPosition2(position)); } /** * Check, if the modification is divalent, i.e. if a position2 is set for the modification. * @return true, if the modification is divalent, otherwise false */ public boolean hasPosition2() { if(getPosition2().size() > 0) { return(true); } return(false); } /** * Get a list of all positions the modification is involved in. * @return */ public ArrayList<Integer> getPositions() { ArrayList<Integer> posList = this.getPosition1Clone(); if(this.hasPosition2()) { //posList.addAll(this.getPosition2()); for(Integer pos2value : this.getPosition2()) { if(!this.containsPosition1(pos2value.intValue())) { //*** avoid adding double values, in case both position1 and position2 contain the same value (due to uncertain positions or a substituent which is twice linked to the same backbone atom like pyruvate) *** posList.add(pos2value); } } } return(posList); } /** * Check, if this modification has an uncertain linkage position, i.e. if it has a linkage position for which more than one value or the value "0" is set * @return */ public boolean hasUncertainLinkagePosition() { if(getPosition1().size() > 1) { return(true); } if(containsPosition1(0)) { return(true); } if(hasPosition2()) { if(getPosition2().size() > 1) { return(true); } if(containsPosition2(0)) { return(true); } } return(false); } public void sortPositions() { Collections.sort(this.getPosition1()); if(this.hasPosition2()) { Collections.sort(this.getPosition2()); String pos1Str = Utils.formatPositionsString(this.getPosition1(), ",", "X"); String pos2Str = Utils.formatPositionsString(this.getPosition2(), ",", "X"); if(pos1Str.compareTo(pos2Str) > 0) { ArrayList<Integer> tmpPosList = this.getPosition1(); this.setPosition1(this.getPosition2()); this.setPosition2(tmpPosList); } } } /** * Check, if the positions of this modification equal those of another modification. * The check is independant of the order of uncertain positions. * @param otherMod the Modification to compare to this one * @return true, if position1 and position2 of both modifications contain the same values */ public boolean positionsEqual(Modification otherMod) { if(otherMod == null) { return false; } if(this.getPosition1().size() != otherMod.getPosition1().size()) { return false; } for(Integer posInt : this.getPosition1()) { if(!otherMod.containsPosition1(posInt.intValue())) { return false; } } if(this.getPosition2().size() != otherMod.getPosition2().size()) { return false; } for(Integer posInt : this.getPosition2()) { if(!otherMod.containsPosition2(posInt.intValue())) { return false; } } return true; } //***************************************************************************** //*** other methods: ********************************************************** //***************************************************************************** public Modification clone() { Modification modClone = new Modification(); modClone.setName(this.getName()); modClone.setValence(this.getValence()); modClone.setPosition1(this.getPosition1Clone()); modClone.setPosition2(this.getPosition2Clone()); return(modClone); } public int compare(Object o1, Object o2) { ArrayList<Integer> positions1 = ((Modification) o1).getPosition1(); ArrayList<Integer> positions2 = ((Modification) o2).getPosition1(); for(int i = 0; i < Math.min(positions1.size(), positions2.size()); i++) { if(positions1.get(i).intValue() < positions2.get(i).intValue() && positions1.get(i).intValue() != 0) { return(-1); } if(positions1.get(i).intValue() > positions2.get(i).intValue()) { return(1); } } if(positions1.size() > positions2.size()) { return(-1); } if(positions1.size() < positions2.size()) { return(1); } positions1 = ((Modification) o1).getPosition2(); positions2 = ((Modification) o2).getPosition2(); for(int i = 0; i < Math.min(positions1.size(), positions2.size()); i++) { if(positions1.get(i).intValue() < positions2.get(i).intValue()) { return(-1); } if(positions1.get(i).intValue() > positions2.get(i).intValue()) { return(1); } } if(positions1.size() > positions2.size()) { return(-1); } if(positions1.size() < positions2.size()) { return(1); } return(((Modification) o1).getName().compareTo(((Modification) o2).getName())); } public boolean equals(Modification mod2) { return(compare(this, mod2) == 0); } public void init() { this.setName(null); this.setPosition1(new ArrayList<Integer>()); this.setPosition2(new ArrayList<Integer>()); this.setValence(0); this.setSourceName(null); this.setModificationId(0); } public String makeCmpString() { String cmpStr; cmpStr = Utils.formatPositionsString(this.getPosition1(), "/", "0"); if(this.hasPosition2()) { cmpStr += "|" + Utils.formatPositionsString(this.getPosition2(), "/", "0"); } cmpStr += "|" + this.getName(); return cmpStr; } public String toString() { String str = "["; str += "name: " + this.getName() + "; "; str += "position: " + this.getPosition1().toString(); if(getPosition2() != null && getPosition2().size() > 0) { str += "/" + getPosition2().toString(); } //str += ";"; str += "]"; return(str); } }