/* * This file is part of MoleculeViewer. * * MoleculeViewer 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. * * MoleculeViewer 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 MoleculeViewer. If not, see <http://www.gnu.org/licenses/>. */ package astex; /* Copyright Astex Technology Ltd. 1999 */ /* Copyright David Hall, Boston University, 2011 */ /* * 14-08-02 mjh * isDisplayed checks to see if the parent molecule is * displayed as well. * 17-02-00 mjh * add Visited attribute. * 07-11-99 mjh * change getBond(i) so that it doesn't perform range checking. it is * better that we get out of bound exception rather than have to * handle null that could be returned. * 05-11-99 mjh * modify getAtomLabel() so that it will return a label * made of the element type followed by the atom id if there * is no label defined. * 28-10-99 mjh * created */ import astex.generic.*; import java.util.*; import java.awt.Color; /** * A class for holding information about an atom. */ public class Atom extends Point3d implements Selectable, GenericInterface { /** Default constructor. */ private Atom(){ super(); initialise(); } /** Undefined atom id. */ public static final int Undefined = -1; /** An integer for storing various attributes. */ public EnumSet<Attribute> attributes = EnumSet.noneOf(Attribute.class); /** The radius of the atom. */ private float radius = -1.0f; /** The stick radius of the atom. */ private float ballRadius = defaultBallRadius; public enum Attribute { Solvent, Labelled, Selected, Hetero, TemporarilySelected, Visited, Displayed, Wide, VDWSphere, Surface, SurfaceContext, Property, Ring, BallAndStick, Cylinder, CustomLabelled, ModellingActive, Aromatic, ModellingEnvironment, ModellingXray, ModellingFixed, NameLeftJustified } public static final EnumSet<Attribute> DisplayedMask = EnumSet.of(Attribute.Displayed, Attribute.Cylinder, Attribute.BallAndStick, Attribute.VDWSphere); /** The X coordinate attribute. */ public static final int X = 0; /** The Y coordinate attribute. */ public static final int Y = 1; /** The Z coordinate attribute. */ public static final int Z = 2; /** The B coordinate attribute. */ public static final int B = 3; /** The O coordinate attribute. */ public static final int O = 4; /** The ID attribute. */ public static final int ID = 5; /** The partial charge attribute. */ public static final int Q = 6; /** The energy. */ public static final int E = 7; /** The color of selected atoms. */ private static final int selectedColor = Color32.yellow; /** Default radius for balls in ball and stick. */ private static final float defaultBallRadius = 0.3f; /** Hybridisation states. */ public static final int sp3 = 3; public static final int sp2 = 2; public static final int sp = 1; /** Initialise an atom. */ public void initialise(){ bonds = null; firstBond = null; secondBond = null; thirdBond = null; id = Undefined; color = 0xff000000; transparency = 255; charge = 0; partialCharge = 0.0f; attributes = EnumSet.of(Attribute.Displayed); bFactor = 0.0f; occupancy = 1.0f; radius = -1.0f; ballRadius = defaultBallRadius; atomType = null; insertionCode = ' '; } /** * Dynamic array containing the list of bonds for this atom. * * Used only when we have more than three bonds. */ private List<Bond> bonds; /** Reference to first bond (or null if there are no bonds). */ private Bond firstBond; /** Reference to second bond. */ private Bond secondBond; /** Reference to third bond. */ private Bond thirdBond; /** Screen x-coordinate. */ public transient int xs; /** Screen y-coordinate. */ public transient int ys; /** Screen z-coordinate. */ public transient int zs; /** Insertion code if any. */ public char insertionCode; /** The color index for this atom. */ private int color; /** The transparency setting for spheres. */ private int transparency; /** The (usually sybyl) atom type of the atom. */ public String atomType = null; /** Set the atomType. */ public void setAtomType(String s){ atomType = s; } /** Get the atomType. */ public String getAtomType(){ return atomType; } /** Set the transparency. */ public void setTransparency(int t){ transparency = t; } /** Get the transparency. */ public int getTransparency(){ return transparency; } /** Set the insertion code. */ public void setInsertionCode(char c){ insertionCode = c; } /** Get the insertion code. */ public char getInsertionCode(){ return insertionCode; } /** Maximum number of atoms we will cache. */ private static final int MaxAtomCacheSize = 2048; /** Cache for reusing atoms. */ private static Stack<Atom> atomCache = new Stack<Atom>(); /** * Create an atom. * * This is the only public interface for creating new atoms. */ public static synchronized Atom create(){ if(!atomCache.isEmpty()){ Atom atom = atomCache.pop(); atom.initialise(); return atom; } return new Atom(); } /** Release an atom after we finished with it. */ public synchronized void release(){ if(atomCache.size() < MaxAtomCacheSize){ atomCache.push(this); } } /** The atomic number of this atom. */ private int element; /** A label for the atom. */ private String label; /** A custom label for the atom. */ private String customLabel; /** An integer id for the atom. */ private int id; /** Charge for the atom. */ private int charge; /** BFactor for the atom. */ private float bFactor; /** Occupancy for the atom. */ private float occupancy; /** Partial charge for the atom. */ private float partialCharge; /** Set the bFactor. */ public void setBFactor(double b){ bFactor = (float)b; } /** Return the bFactor. */ public double getBFactor(){ return (double)bFactor; } /** Set the occupancy. */ public void setOccupancy(double o){ occupancy = (float)o; } /** Get the occupancy. */ public double getOccupancy(){ return (double)occupancy; } /** * Get the value of partialCharge. * @return value of partialCharge. */ public float getPartialCharge() { return partialCharge; } /** * Set the value of partialCharge. * @param v Value to assign to partialCharge. */ public void setPartialCharge(double v) { this.partialCharge = (float)v; } /** Get an attribute. */ public double getAttribute(int attribute){ switch(attribute){ case X: return x; case Y: return y; case Z: return z; case B: return bFactor; case O: return occupancy; case Q: return partialCharge; case E: return 0.0; case ID: return getId(); default: System.out.println("Atom: attempt to get unknown attribute " + attribute); return 0.0; } } /** Set the id for this atom. */ public void setId(int newId){ if(newId == Undefined){ System.out.println("explicitly setting id to undefined " + this); System.out.println("(anti-desirable)"); } id = newId; } /** Get the id for this atom. */ public int getId(){ if(id == Undefined){ Molecule molecule = getMolecule(); molecule.assignAtomNumbers(); } return id; } /** Set the element of this atom. */ public void setElement(int newElement){ element = newElement; } /** Get the element type of this atom. */ public int getElement(){ return element; } /** Get the atomic symbol for this atom. */ public String getAtomSymbol(){ String symbol = PeriodicTable.getAtomSymbolFromElement(element); if(symbol == null) return "C"; return symbol; } /** Set the atom label. */ public void setAtomLabel(String newLabel){ label = newLabel; } /** Get the atom label. */ public String getAtomLabel(){ if(label != null) return label; String symbol = PeriodicTable.getAtomSymbolFromElement(element); return symbol.toUpperCase() + getId(); } /** Generate an atom label according to a format. */ public String generateLabel(String format){ // if there is no % character just return the original // or no url substitution character return as well if(format.indexOf('%') == -1 && format.indexOf('`') == -1) return format; StringBuilder s = new StringBuilder(16); int len = format.length(); for(int i = 0; i < len; i++){ char c = format.charAt(i); if(c == '%'){ if(i == len - 1){ System.out.println("Atom.generateLabel: % at end of " + "format string, just placing %"); }else{ char nc = format.charAt(i + 1); if(nc == '%'){ s.append('%'); }else if(nc == 'x'){ s.append(String.format("%.3f", x)); }else if(nc == 'y'){ s.append(String.format("%.3f", y)); }else if(nc == 'z'){ s.append(String.format("%.3f", z)); }else if(nc == 'e'){ double v = 0.0; s.append(String.format("%.2f", v)); }else if(nc == 'b'){ s.append(String.format("%.1f", getBFactor())); }else if(nc == 'B'){ s.append(String.format("%d", (int)getBFactor())); }else if(nc == 'o'){ s.append(String.format("%.2f", getOccupancy())); }else if(nc == 'q'){ s.append(String.format("%.2f", getPartialCharge())); }else if(nc == 'i'){ s.append(String.format("%-4d", getId())); }else if(nc == 'I'){ s.append(getInsertionCode()); }else if(nc == 'A'){ Residue res = getResidue(); label = getAtomLabel(); if(res != null && res.isStandardAminoAcid()){ int labelLength = label.length(); for(int l = 0; l < labelLength; l++){ char lc = label.charAt(l); // put the escape code for the // greek letter if(l == 1){ s.append('\\'); s.append(Character.toLowerCase(lc)); }else{ s.append(lc); } } }else{ s.append(label); } }else if(nc == 'a'){ s.append(getAtomLabel()); }else if(nc == 'r'){ Residue res = getResidue(); if(res != null){ s.append(String.format("%d", res.getNumber())); if(res.getInsertionCode() != 0 && res.getInsertionCode() != ' '){ s.append(res.getInsertionCode()); } } }else if(nc == 'R'){ Residue res = getResidue(); if(res != null){ s.append(res.getName()); } }else if(nc == 'f'){ // fancy residue name. Capital followed by lower case Residue res = getResidue(); if(res != null){ String name = res.getName(); s.append(name.charAt(0)); s.append(name.toLowerCase().substring(1)); } }else if(nc == 'c'){ Residue res = getResidue(); if(res != null){ Chain chain = res.getParent(); if(chain != null && !" ".equals(chain.getName())){ s.append(chain.getName()); } } }else if(nc == 'm'){ Residue res = getResidue(); if(res != null){ Chain chain = res.getParent(); if(chain != null){ Molecule mol = chain.getParent(); if(mol != null){ s.append(mol.getName()); } } } } } i++; }else{ s.append(c); } } format = s.toString(); s.setLength(0); len = format.length(); // substitue url enclosed within ` characters // done after variable substitution so that you can get atom info // into the url string for(int i = 0; i < len; i++){ char c = format.charAt(i); if(c == '`'){ // its a url to call StringBuilder url = new StringBuilder(16); ++i; for( ; i < len; i++){ c = format.charAt(i); if(c == '`') break; url.append(c); } FILE f = FILE.openURL(url.toString()); if(f == null){ s.append("invalid_url"); }else{ while(f.nextLine()){ String contents = f.getCurrentLineAsString(); s.append(contents); } } }else{ s.append(c); } } return s.toString(); } /** Get the atom symbol for the element. */ public String getSymbol(){ return PeriodicTable.getAtomSymbolFromElement(element); } /** Get the default mass for the atom. */ public double getMass(){ return PeriodicTable.elements[element].mass; } /** Get the atom charge. */ public int getCharge(){ return charge; } /** Set the atom charge. */ public void setCharge(int newCharge){ charge = newCharge; } /** Set the atom color. */ public void setColor(int newColor){ color = newColor; } /** Get the atom color. */ public int getColor(){ if(color == 0xff000000){ switch(element){ case PeriodicTable.CARBON: color = Color32.green; break; case PeriodicTable.OXYGEN: color = Color32.red; break; case PeriodicTable.NITROGEN: color = Color32.blue; break; case PeriodicTable.SULPHUR: color = Color32.yellow; break; case PeriodicTable.PHOSPHORUS: color = Color32.magenta; break; case PeriodicTable.CHLORINE: color = Color32.orange; break; case PeriodicTable.FLUORINE: color = Color32.cyan; break; case PeriodicTable.BROMINE: color = Color32.magenta; break; case PeriodicTable.HYDROGEN: default: color = Color32.white; break; } } return color; } /** Get the color or selected color if selected. */ public int getSelectedColor(){ if(isSelected()) return selectedColor; return getColor(); } /** Set color back to undefined. */ public void resetColor(){ color = 0xff000000; } /** The residue to which the atom belongs. */ private Residue parentResidue; /** Get the molecule to which the atom belongs. */ public Molecule getMolecule(){ if(parentResidue != null){ Chain parentChain = parentResidue.getParent(); if(parentChain != null){ return parentChain.getParent(); } } return null; } /** Set the residues to which the atom belongs. */ public void setParent(Residue residue){ parentResidue = residue; } /** Get the residue to which the atom belongs. */ public Residue getResidue(){ return parentResidue; } /** Add a bond to the atom. */ public void addBond(Bond bond){ if(bonds != null){ // we already have more than two bonds so just keep adding. bonds.add(bond); }else if(firstBond == null){ // no bonds yet so stick it there. firstBond = bond; }else if(secondBond == null){ // first slot full, second empty stick it here secondBond = bond; }else if(thirdBond == null){ // first slot full, second empty stick it here thirdBond = bond; }else{ // both slots are full so allocate the list bonds = new ArrayList<Bond>(6); bonds.add(firstBond); bonds.add(secondBond); bonds.add(thirdBond); bonds.add(bond); firstBond = null; secondBond = null; thirdBond = null; } } /** Return a specified bond or null if it doesn't exist. */ public Bond getBond(int index){ if(bonds != null) // have dynamic array so it should be in here return bonds.get(index); if(index == 0) return firstBond; if(index == 1) return secondBond; if(index == 2) return thirdBond; return null; } /** Return the specified bonded atom. */ public Atom getBondedAtom(int index){ Bond bond = getBond(index); if(bond != null){ return bond.getOtherAtom(this); } return null; } /** Return the total number of bonds. */ public int getBondCount(){ if(bonds != null) return bonds.size(); if(thirdBond != null) return 3; if(secondBond != null) return 2; if(firstBond != null) return 1; return 0; } /** Does this atom have a bond to the specified atom. */ public Bond getBond(Atom otherAtom){ int bondCount = getBondCount(); for(int i = 0; i < bondCount; i++){ Bond bond = getBond(i); if(bond.getOtherAtom(this) == otherAtom){ return bond; } } return null; } /** Get bonded atom with this name. */ public Atom getBondedAtom(String nm){ int bondCount = getBondCount(); for(int i = 0; i < bondCount; i++){ Atom otherAtom = getBondedAtom(i); if(otherAtom.getAtomLabel().equals(nm) && (otherAtom.getInsertionCode() == ' ' || otherAtom.getInsertionCode() == 'A')){ return otherAtom; } } return null; } /** Does this atom have a bond to the other atom. */ public boolean hasBond(Atom otherAtom){ return getBond(otherAtom) != null; } /** Does this atom have bonds that came from an explicit bond. */ public boolean hasExplicitBond(){ int bondCount = getBondCount(); for(int b = 0; b < bondCount; b++){ Bond bond = getBond(b); if(bond.isExplicitBond()){ return true; } } return false; } /** * Is this atom connected by two bonds to the specified atom. * * That is are they 1,3 connected. */ public boolean connected13(Atom targetAtom){ for(int b1 = 0; b1 < getBondCount(); b1++){ Bond bond1 = getBond(b1); Atom otherAtom = bond1.getOtherAtom(this); for(int b2 = 0; b2 < otherAtom.getBondCount(); b2++){ Bond bond2 = otherAtom.getBond(b2); Atom finalAtom = bond2.getOtherAtom(otherAtom); if(finalAtom == targetAtom){ return true; } } } return false; } /** * Is this atom connected by three bonds to the specified atom. * * That is are they 1,4 connected. */ public boolean connected14(Atom targetAtom){ int bondCount = getBondCount(); int targetBondCount = targetAtom.getBondCount(); for(int b1 = 0; b1 < bondCount; b1++){ Bond bond1 = getBond(b1); Atom bond1Other = bond1.getOtherAtom(this); for(int b2 = 0; b2 < targetBondCount; b2++){ Bond bond2 = targetAtom.getBond(b2); Atom bond2Other = bond2.getOtherAtom(targetAtom); if(bond1Other.hasBond(bond2Other)){ return true; } } } return false; } /** Are these atoms connected 1,2, 1,3 or 1,4. */ public boolean connected121314(Atom otherAtom){ if(hasBond(otherAtom)){ return true; } if(connected13(otherAtom)){ return true; } if(connected14(otherAtom)){ return true; } return false; } /** Get the bonding radius for the atom. */ public double getBondingRadius(){ if(element == PeriodicTable.CARBON || element == PeriodicTable.NITROGEN || element == PeriodicTable.FLUORINE || element == PeriodicTable.OXYGEN) return 0.9; if(element == PeriodicTable.HYDROGEN) return 0.3; if(element == PeriodicTable.WOLFRAM) return 1.0; if(element == PeriodicTable.UNKNOWN) return 0.0; if(element == PeriodicTable.IRON) return 1.25; if(element == PeriodicTable.MANGANESE) // we would prefer not to have Mn bonded to anything return 0.0; return 1.2; } /** Get the VDW radius of this atom. */ public double getVDWRadius(){ if(radius < 0.0f){ if(element == PeriodicTable.CARBON){ radius = 1.88f; }else if(element == PeriodicTable.NITROGEN){ radius = 1.64f; }else if(element == PeriodicTable.OXYGEN){ radius = 1.42f; }else if(element == PeriodicTable.HYDROGEN){ radius = 1.05f; }else if(element == PeriodicTable.SULPHUR){ radius = 1.77f; }else if(element == PeriodicTable.PHOSPHORUS){ radius = 1.7f; }else if(element == PeriodicTable.IODINE){ // www.webelements.com radius = 1.98f; }else if(element == PeriodicTable.BROMINE){ // www.webelements.com radius = 1.85f; }else if(element == PeriodicTable.CHLORINE){ // www.webelements.com radius = 1.75f; }else{ radius = 1.35f; } } return (double)radius; } /** Get the biggest radius that is displayed. */ public double getBiggestDisplayedRadius(){ double maxRadius = 0.0; if(attributes.contains(Attribute.VDWSphere)){ double r = getVDWRadius(); if(r > maxRadius){ maxRadius = r; } } if(attributes.contains(Attribute.BallAndStick)){ double r = getBallRadius(); if(r > maxRadius){ maxRadius = r; } } // can't see where that is recorded... if(attributes.contains(Attribute.Cylinder)){ double r = getBallRadius(); if(r > maxRadius){ maxRadius = r; } } return maxRadius + 0.05; } /** Set the vdw radius. */ public void setVDWRadius(double r){ radius = (float)r; } /** Set the vdw radius. */ public void setBallRadius(double r){ ballRadius = (float)r; } /** Get the vdw radius. */ public double getBallRadius(){ return ballRadius; } /** Transform this atom to screen coordinates. */ public void transformToScreen(Matrix m){ // add 0.5 to make it the nearest integer double xx = x*m.m00 + y*m.m10 + z*m.m20 + m.m30 + 0.5; double yy = x*m.m01 + y*m.m11 + z*m.m21 + m.m31 + 0.5; double zz = x*m.m02 + y*m.m12 + z*m.m22 + m.m32; xs = (int)(xx) << Renderer.FixedBits; ys = (int)(yy) << Renderer.FixedBits; zs = (int)((zz) * (1 << (Renderer.FixedBits+8))); } /* Various kinds of tests for particular atom types. */ /** Is this an aliphatic hydrogen. */ public boolean isAliphaticHydrogen(){ if(element != PeriodicTable.HYDROGEN){ return false; } if(getBondCount() == 1){ Atom atom = getBondedAtom(0); if(atom.getElement() == PeriodicTable.CARBON){ return true; } } return false; } /** * Is this atom an HBond donor. * Only suitable for standard aminoacid names. */ public boolean isHBondDonor(){ String name = label; if(isSolvent()) return true; if(!parentResidue.isStandardAminoAcid()) return false; String resname = parentResidue.getName(); if("N".equals(name)){ return !("PRO".equals(resname)); } if("NE1".equals(name) && "TRP".equals(resname)) return true; if("OG".equals(name) && "SER".equals(resname)) return true; if("OG1".equals(name) && "THR".equals(resname)) return true; if("ND2".equals(name) && "ASN".equals(resname)) return true; if("NE2".equals(name) && "GLN".equals(resname)) return true; if("OH".equals(name) && "TYR".equals(resname)) return true; if("NE1".equals(name) && "HIS".equals(resname)) return true; if(("NE2".equals(name) || "ND1".equals(name)) && "HIS".equals(resname)) return true; if("NZ".equals(name) && "LYS".equals(resname)) return true; return (("NE".equals(name) || "NH1".equals(name) || "NH2".equals(name)) && "ARG".equals(resname)); } /** * Is this atom an HBond donor. * Only suitable for standard aminoacid names. */ public boolean isHBondAcceptor(){ String name = label; if(isSolvent()) return true; if(!parentResidue.isStandardAminoAcid()) return false; if("O".equals(name)) return true; String resname = parentResidue.getName(); if("NE1".equals(name) && "TRP".equals(resname)) return true; if("OG".equals(name) && "SER".equals(resname)) return true; if("OG1".equals(name) && "THR".equals(resname)) return true; if("OD1".equals(name) && "ASN".equals(resname)) return true; if("OE1".equals(name) && "GLN".equals(resname)) return true; if("OH".equals(name) && "TYR".equals(resname)) return true; if("NE1".equals(name) && "HIS".equals(resname)) return true; if(("NE2".equals(name) || "ND1".equals(name)) && "HIS".equals(resname)) return true; if(("OD1".equals(name) || "OD2".equals(name)) && "ASP".equals(resname)) return true; return (("OE1".equals(name) || "OE2".equals(name)) && "GLU".equals(resname)); } /** Does the atom have any attributes set? */ public boolean hasAttributes(){ return attributes.size() != 0; } /** Set or clear a particular attribute. */ public void setOrClearAttribute(Attribute attribute, boolean state){ if(state){ attributes.add(attribute); }else{ attributes.remove(attribute); } } /** Set whether the atom is solvent. */ public void setSolvent(boolean state){ setOrClearAttribute(Attribute.Solvent, state); } /** Is this atom a solvent atom. */ public boolean isSolvent(){ return attributes.contains(Attribute.Solvent); } /** Set whether the atom is solvent. */ public void setCustomLabel(String l){ customLabel = l; if(customLabel == null){ setOrClearAttribute(Attribute.CustomLabelled, false); }else{ setOrClearAttribute(Attribute.CustomLabelled, true); } } /** Set whether the atom is solvent. */ public String getCustomLabel(){ return customLabel; } /** Is this atom a solvent atom. */ public boolean isLabelled(){ return attributes.contains(Attribute.Labelled); } /** Set whether the atom is solvent. */ public void setLabelled(boolean state){ setOrClearAttribute(Attribute.Labelled, state); } /** Set whether the atom is selected. */ public void setSelected(boolean state){ setOrClearAttribute(Attribute.Selected, state); } /** Is this atom selected. */ public boolean isSelected(){ return attributes.contains(Attribute.Selected); } /** Set whether the atom is a heteroatom. */ public void setHeteroAtom(boolean state){ setOrClearAttribute(Attribute.Hetero, state); } /** Is this atom a heteroatom. */ public boolean isHeteroAtom(){ return attributes.contains(Attribute.Hetero); } /** Set whether the atom is temporarily selected. */ public void setTemporarilySelected(boolean state){ setOrClearAttribute(Attribute.TemporarilySelected, state); } /** Is this atom temporarily selected. */ public boolean isTemporarilySelected(){ return attributes.contains(Attribute.TemporarilySelected); } /** Set whether the atom has been visited. */ public void setVisited(boolean state){ setOrClearAttribute(Attribute.Visited, state); } /** Has this atom been visited. */ public boolean isVisited(){ return attributes.contains(Attribute.Visited); } /** Set whether the atom has been wide. */ public void setWide(boolean state){ setOrClearAttribute(Attribute.Wide, state); } /** Has this atom been wide. Its a bond property.*/ public boolean isWide(){ return attributes.contains(Attribute.Wide); } /** Set whether the atom has been displayed. */ public void setDisplayed(boolean state){ setOrClearAttribute(Attribute.Displayed, state); } /** Has this atom been displayed. */ public boolean isSimpleDisplayed(){ return attributes.contains(Attribute.Displayed); } /** Has this atom been displayed. */ public boolean isDisplayed(){ Molecule mol = getMolecule(); if(mol.getDisplayed()) { EnumSet<Attribute> tmp = attributes.clone(); tmp.retainAll(DisplayedMask); return !tmp.isEmpty(); } return false; } /** Set the selection state. */ public int select(int state){ switch(state){ case 1: setSelected(true); break; case 2: if(!isSelected()) setSelected(true); break; case 3: setSelected(false); break; } return isSelected() ? 1 : 0; } public String selectStatement(){ Residue res = getResidue(); String resSelect = res.selectStatement(); String command = "id " + getId(); return command + " and " + resSelect; } /** Return the hybridisation state of the atom. */ public int getHybridisation(){ int bondCount = getBondCount(); for(int b = 0; b < bondCount; b++){ Bond bond = getBond(b); Bond.BondOrder bondOrder = bond.getBondOrder(); if(bondOrder == Bond.BondOrder.DoubleBond) return sp2; if(bondOrder == Bond.BondOrder.TripleBond) return sp; } return sp3; } /** Placeholder for the default format atom string. */ private static String defaultLongFormat = null; @Override public String toString(){ if(defaultLongFormat == null){ defaultLongFormat = Settings.getString("config", "atom.long.format"); if(defaultLongFormat == null){ // no config so set it here defaultLongFormat = "%a %R %c:%r ID=%i X=%x Y=%y Z=%z O=%o B=%b %m"; } } return generateLabel(defaultLongFormat); } /** Remove a bond from this atom. */ public void removeBond(Bond b){ if(bonds != null){ bonds.remove(b); }else{ if(firstBond == b){ firstBond = secondBond; secondBond = thirdBond; }else if(secondBond == b){ secondBond = thirdBond; }else if(thirdBond == b){ thirdBond = null; } } Molecule mol = getMolecule(); mol.removeBond(b); } /** Remove all bonds. */ public void removeAllBonds(){ if(bonds != null){ bonds.clear(); bonds = null; } firstBond = secondBond = thirdBond = null; } public static final String XAttribute = "x"; public static final String YAttribute = "y"; public static final String ZAttribute = "z"; public static final String BAttribute = "b"; public static final String OAttribute = "o"; public static final String QAttribute = "charge"; public static final String Color = "color"; public static final String Radius = "radius"; public static final String Opacity = "opacity"; public static final String Element = "element"; /** Arbitrary properties. */ private HashMap<Object,Object> properties = null; /** Get Object representing key. */ public Object get(Object key, Object def){ Object val = null; if(key.equals(XAttribute)) val = Double.valueOf(getAttribute(X)); else if(key.equals(YAttribute)) val = Double.valueOf(getAttribute(Y)); else if(key.equals(ZAttribute)) val = Double.valueOf(getAttribute(Z)); else if(key.equals(BAttribute)) val = Double.valueOf(getAttribute(B)); else if(key.equals(OAttribute)) val = Double.valueOf(getAttribute(O)); else if(key.equals(QAttribute)) val = Double.valueOf(getAttribute(Q)); else if(key.equals(Element)) val = Integer.valueOf(element); else if(key.equals(Color)) val = new Color(getColor()); else if(key.equals(Radius)) val = Double.valueOf(getVDWRadius()); else if(key.equals(Opacity)) val = Integer.valueOf(transparency); else { if(properties != null){ val = properties.get(key); } } return val == null ? def : val; } public void edit(String name, String value){ if("type".equals(name)){ setAtomType(value); }else{ System.err.println("Atom.edit: unknown parameter name " + name); } } /** Set an object value. */ public Object set(Object key, Object value){ if(key.equals(XAttribute)) x = ((Double)value).doubleValue(); else if(key.equals(YAttribute)) y = ((Double)value).doubleValue(); else if(key.equals(ZAttribute)) z = ((Double)value).doubleValue(); else if(key.equals(BAttribute)) bFactor = (float)((Double)value).doubleValue(); else if(key.equals(OAttribute)) occupancy = (float)((Double)value).doubleValue(); else if(key.equals(QAttribute)) partialCharge = (float)((Double)value).doubleValue(); else if(key.equals(Radius)) radius = (float)((Double)value).doubleValue(); else if(key.equals(Element)) element = ((Integer) value).intValue(); else if(key.equals(Color)) setColor(((Color)value).getRGB()); else if(key.equals(Opacity)) transparency = ((Integer)value).intValue(); else{ if(properties == null){ properties = new HashMap<Object,Object>(20); } if(value == null){ properties.remove(key); }else{ properties.put(key, value); } } return null; } /** Get an Enumeration of our parents. */ public Iterator<GenericInterface> getParents(Object type){ return null; } /** Add a parent. */ public void addParent(GenericInterface parent){ } /** Remove a parent. */ public void removeParent(GenericInterface parent){ } /** Get an enumeration of our children. */ public Iterator<GenericInterface> getChildren(Object type){ return null; } /** Add a child. */ public void addChild(GenericInterface child){ } /** Remove a child. */ public void removeChild(GenericInterface child){ } /** Add a listener. */ public void addListener(GenericEventInterface geh){ } /** Remove a listener. */ public void removeListener(GenericEventInterface geh){ } }