/* * 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.application.glycanbuilder; import java.util.*; /** Objects of this class are used to compute and store the position of a residue around its parent during the rendering process. @see GlycanRenderer @author Alessio Ceroni (a.ceroni@imperial.ac.uk) */ public class PositionManager { protected static final ResAngle[] static_positions = new ResAngle[5]; static { try { static_positions[0] = new ResAngle(-90); static_positions[1] = new ResAngle(-45); static_positions[2] = new ResAngle(0); static_positions[3] = new ResAngle(45); static_positions[4] = new ResAngle(90); //static_positions[5] = new ResAngle(-135); //static_positions[6] = new ResAngle(135); } catch(Exception e) { LogUtils.report(e); } } protected HashMap<Residue,ResAngle> orientations; protected HashMap<Residue,ResAngle> rotations; protected HashMap<Residue,ResAngle> relative_positions; protected HashMap<Residue,ResAngle> absolute_positions; protected HashMap<Residue,Boolean> onborder_flags; protected HashMap<Residue,Boolean> sticky_flags; /** Default constructor. */ public PositionManager() { orientations = new HashMap<Residue,ResAngle>(); rotations = new HashMap<Residue,ResAngle>(); relative_positions = new HashMap<Residue,ResAngle>(); absolute_positions = new HashMap<Residue,ResAngle>(); onborder_flags = new HashMap<Residue,Boolean>(); sticky_flags = new HashMap<Residue,Boolean>(); } /** Clear all fields. */ public void reset() { orientations.clear(); rotations.clear(); relative_positions.clear(); absolute_positions.clear(); onborder_flags.clear(); sticky_flags.clear(); } /** Store the information about the position of a residue around its parent. @param node the residue @param parent_orientation the absolute orientation of the parent @param relative_position the position of the residue relative to its parent @param on_border <code>true</code> if the residue is rendered on the border of the parent @param sticky <code>true</code> if all the children of the current residue should be placed in position 0 */ public void add(Residue node, ResAngle parent_orientation, ResAngle relative_position, boolean on_border, boolean sticky) { if( node!=null ) { ResAngle absolute_position = parent_orientation.combine(relative_position); ResAngle rotation = (sticky) ?relative_position : new ResAngle(); ResAngle orientation = parent_orientation; if( sticky && !relative_position.equals(-45) && !relative_position.equals(45) && !on_border) //if( !relative_position.equals(-45) && !relative_position.equals(45) ) orientation = absolute_position; orientations.put(node,orientation); rotations.put(node,rotation); relative_positions.put(node,relative_position); absolute_positions.put(node,absolute_position); onborder_flags.put(node,on_border); sticky_flags.put(node,sticky); } } /** Return the absolute orientation of the parent residue */ public ResAngle getOrientation(Residue node) { return orientations.get(node); } public ResAngle getRotation(Residue node) { return rotations.get(node); } /** Return the orientation of the residue relative to its parent */ public ResAngle getRelativePosition(Residue node) { return relative_positions.get(node); } /** Return the absolute orientation of the residue */ public ResAngle getAbsolutePosition(Residue node) { return absolute_positions.get(node); } /** Return <code>true</code> if the residue is rendered on the border of its parent. */ public boolean isOnBorder(Residue node) { Boolean b = onborder_flags.get(node); if( b==null ) return false; return b; } /** Return <code>true</code> if the children of the residue should be placed all in position 0. */ public boolean isSticky(Residue node) { Boolean b = sticky_flags.get(node); if( b==null ) return false; return b; } /** Return all the possible positions of a residue around its parent. */ static public ResAngle[] getPossiblePositions() { return static_positions; } /** Return the possible positions of the residue around its parent given the current orientation. */ public ResAngle[] getAvailablePositions(Residue current, ResAngle orientation) { ResAngle[] positions = getPossiblePositions(); if( current==null ) return positions; Residue parent = current.getParent(); if( parent==null ) return positions; ResAngle cur_abs_pos = getAbsolutePosition(current); if( cur_abs_pos==null ) return positions; // check for conflicting position (e.g: +90/-90) Vector<ResAngle> vec_available_positions = new Vector<ResAngle>(); for( int i=0; i<positions.length; i++ ) { ResAngle pos = positions[i]; ResAngle abs_pos = orientation.combine(pos); if( !cur_abs_pos.isOpposite(abs_pos) ) vec_available_positions.add(pos); } // transform into array ResAngle[] available_positions = new ResAngle[vec_available_positions.size()]; vec_available_positions.copyInto(available_positions); return available_positions; } /** Return the children of the residue that have been placed in a specific position. */ public Vector<Residue> getChildrenAtPosition(Residue parent, ResAngle position) { Vector<Residue> nodes = new Vector<Residue>(); for(Iterator<Linkage> i=parent.iterator(); i.hasNext(); ) { Residue child = i.next().getChildResidue(); if( getRelativePosition(child).equals(position) ) nodes.add(child); } return nodes; } /** Return the children of the residue that have been placed in a specific position. @param on_border if <code>true</code> look at the children residues on the border of the parent */ public Vector<Residue> getChildrenAtPosition(Residue parent, ResAngle position, boolean on_border) { Vector<Residue> nodes = new Vector<Residue>(); for(Iterator<Linkage> i=parent.iterator(); i.hasNext(); ) { Residue child = i.next().getChildResidue(); if( getRelativePosition(child).equals(position) && isOnBorder(child)==on_border ) nodes.add(child); } return nodes; } /* public Vector<Residue> getChildrenCompatibleWith(Residue parent, Linkage link, Residue child) { Vector<Residue> nodes = new Vector<Residue>(); ResAngle[] child_positions = ResiduePlacementDictionary.getPlacement(parent,link,child).getPositions(); for( int i=0; i<child_positions.length; i++ ) nodes.addAll(getChildrenAtPosition(parent,child_positions[i])); return nodes; }*/ }