001package com.hfg.chem; 002 003 004import java.util.ArrayList; 005import java.util.Collections; 006import java.util.List; 007 008import com.hfg.util.CompareUtil; 009 010//------------------------------------------------------------------------------ 011/** 012 Represents an atom - an element plus coordinates. 013 014 @author J. Alex Taylor, hairyfatguy.com 015 */ 016//------------------------------------------------------------------------------ 017// com.hfg XML/HTML Coding Library 018// 019// This library is free software; you can redistribute it and/or 020// modify it under the terms of the GNU Lesser General Public 021// License as published by the Free Software Foundation; either 022// version 2.1 of the License, or (at your option) any later version. 023// 024// This library is distributed in the hope that it will be useful, 025// but WITHOUT ANY WARRANTY; without even the implied warranty of 026// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 027// Lesser General Public License for more details. 028// 029// You should have received a copy of the GNU Lesser General Public 030// License along with this library; if not, write to the Free Software 031// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 032// 033// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 034// jataylor@hairyfatguy.com 035//------------------------------------------------------------------------------ 036 037public class Atom implements Comparable 038{ 039 private Element mElement; 040 private Float mXCoordinate; 041 private Float mYCoordinate; 042 private Float mZCoordinate; 043 044 private Integer mCharge; 045 private Boolean mIsAromatic; 046 private Integer mHCount; 047 private Integer mImplicitHCount; 048 private Integer mAtomClass; 049 private ChiralityOrder mChiralityOrder; 050 private List<CovalentBond> mBonds; 051 052 private final int mId = sIdSrc++; 053 054 private static int sIdSrc = Integer.MIN_VALUE; 055 056 public enum ChiralityOrder 057 { 058 clockwise, 059 anticlockwise 060 } 061 062 //########################################################################## 063 // CONSTRUCTORS 064 //########################################################################## 065 066 //-------------------------------------------------------------------------- 067 public Atom(Element inElement) 068 { 069 mElement = inElement; 070 } 071 072 //########################################################################## 073 // PUBLIC METHODS 074 //########################################################################## 075 076 //-------------------------------------------------------------------------- 077 @Override 078 public String toString() 079 { 080 return mElement != null ? mElement.getSymbol() : "*"; 081 } 082 083 //-------------------------------------------------------------------------- 084 @Override 085 public int hashCode() 086 { 087 return mId; 088 } 089 090 //-------------------------------------------------------------------------- 091 @Override 092 public boolean equals(Object inObj) 093 { 094 boolean result = false; 095 096 if (inObj != null) 097 { 098 result = (0 == compareTo(inObj)); 099 } 100 101 return result; 102 } 103 104 //-------------------------------------------------------------------------- 105 @Override 106 public int compareTo(Object inObj) 107 { 108 int result = -1; 109 110 if (inObj instanceof Atom) 111 { 112 result = CompareUtil.compare(mId, ((Atom) inObj).mId); 113 } 114 115 return result; 116 } 117 118 //-------------------------------------------------------------------------- 119 public Element getElement() 120 { 121 return mElement; 122 } 123 124 125 //-------------------------------------------------------------------------- 126 public Float getXCoordinate() 127 { 128 return mXCoordinate; 129 } 130 131 //-------------------------------------------------------------------------- 132 public Atom setXCoordinate(Float inValue) 133 { 134 mXCoordinate = inValue; 135 return this; 136 } 137 138 139 //-------------------------------------------------------------------------- 140 public Float getYCoordinate() 141 { 142 return mYCoordinate; 143 } 144 145 //-------------------------------------------------------------------------- 146 public Atom setYCoordinate(Float inValue) 147 { 148 mYCoordinate = inValue; 149 return this; 150 } 151 152 153 //-------------------------------------------------------------------------- 154 public Float getZCoordinate() 155 { 156 return mZCoordinate; 157 } 158 159 //-------------------------------------------------------------------------- 160 public Atom setZCoordinate(Float inValue) 161 { 162 mZCoordinate = inValue; 163 return this; 164 } 165 166 167 //-------------------------------------------------------------------------- 168 public Integer getCharge() 169 { 170 return mCharge; 171 } 172 173 //-------------------------------------------------------------------------- 174 public Atom setCharge(Integer inValue) 175 { 176 mCharge = inValue != null && inValue != 0 ? inValue : null; 177 return this; 178 } 179 180 181 //-------------------------------------------------------------------------- 182 public Atom addBond(CovalentBond inValue) 183 { 184 if (inValue != null) 185 { 186 if (null == mBonds) 187 { 188 mBonds = new ArrayList<>(3); 189 } 190 else 191 { 192 // Has an equivalent bond already been added? 193 for (CovalentBond bond : mBonds) 194 { 195 if (bond.equals(inValue) 196 && inValue.getSecondAtom() != null) 197 { 198 throw new MolecularStructureException("There cannot be two bonds between one pair of Atoms!"); 199 } 200 } 201 } 202 203 // Make sure that the bond involves this Atom 204 if (inValue.getFirstAtom() != this 205 && inValue.getSecondAtom() != this) 206 { 207 throw new MolecularStructureException("Can't add a bond to an Atom that doesn't involve the Atom!"); 208 } 209 210 mBonds.add(inValue); 211 } 212 213 return this; 214 } 215 216 //-------------------------------------------------------------------------- 217 public boolean removeBond(CovalentBond inValue) 218 { 219 boolean result = false; 220 if (mBonds != null) 221 { 222 result = mBonds.remove(inValue); 223 } 224 225 return result; 226 } 227 228 //-------------------------------------------------------------------------- 229 public List<CovalentBond> getBonds() 230 { 231 return mBonds != null ? Collections.unmodifiableList(mBonds) : null; 232 } 233 234 235 //-------------------------------------------------------------------------- 236 public ChiralityOrder getChiralityOrder() 237 { 238 return mChiralityOrder; 239 } 240 241 //-------------------------------------------------------------------------- 242 public Atom setChiralityOrder(ChiralityOrder inValue) 243 { 244 mChiralityOrder = inValue; 245 return this; 246 } 247 248 249 //-------------------------------------------------------------------------- 250 public Integer getAtomClass() 251 { 252 return mAtomClass; 253 } 254 255 //-------------------------------------------------------------------------- 256 public Atom setAtomClass(Integer inValue) 257 { 258 mAtomClass = inValue; 259 return this; 260 } 261 262 263 //-------------------------------------------------------------------------- 264 public Atom setIsAromatic(boolean inValue) 265 { 266 mIsAromatic = inValue; 267 return this; 268 } 269 270 //-------------------------------------------------------------------------- 271 public boolean isAromatic() 272 { 273 return mIsAromatic != null ? mIsAromatic : false; 274 } 275 276 277 //-------------------------------------------------------------------------- 278 public Atom setHCount(Integer inValue) 279 { 280 mHCount = inValue; 281 return this; 282 } 283 284 //-------------------------------------------------------------------------- 285 public Integer getHCount() 286 { 287 return mHCount; 288 } 289 290 291 //-------------------------------------------------------------------------- 292 public Atom setImplicitHCount(Integer inValue) 293 { 294 mImplicitHCount = inValue; 295 return this; 296 } 297 298 //-------------------------------------------------------------------------- 299 public Integer getImplicitHCount() 300 { 301 return mImplicitHCount; 302 } 303 304}