001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 * Created on 28.04.2004
021 * @author Andreas Prlic
022 *
023 */
024package org.biojava.nbio.structure;
025
026import org.biojava.nbio.structure.io.FileConvert;
027
028import java.util.ArrayList;
029import java.util.List;
030
031import javax.vecmath.Point3d;
032
033
034/**
035 * Implementation of an Atom of a PDB file.
036 * currently the coordinates of an atom are represented by a double[3] array.
037 * @author Andreas Prlic
038 * @since 1.4
039 * @version %I% %G%
040 */
041public class AtomImpl implements Atom {
042
043        private static final long serialVersionUID = -2258364127420562883L;
044
045        /**
046         * The inital capacity of the bonds list.
047         * Most atoms have a maximum of 3 heavy atom neighbors.
048         */
049        public static final int BONDS_INITIAL_CAPACITY = 3;
050
051        private String name;
052        private Element element;        
053        private Point3d coords;
054        private int pdbserial;
055        private short charge;
056
057        private float occupancy ;
058        private float tempfactor;
059
060        private char altLoc ;
061        private Group parent;
062
063        private List<Bond> bonds;
064
065        public AtomImpl () {
066                name       = null;
067                element    = Element.R;
068                coords     = new Point3d();
069                occupancy  = 0.0f;
070                tempfactor = 0.0f;
071                altLoc     = 0;
072                parent     = null;
073                bonds      = null; // let's save some memory and let's not initialise this until it's needed - JD 2016-03-02
074                charge     = 0;
075        }
076
077        /**
078         * {@inheritDoc}
079         */
080        @Override
081        public void   setName(String s) { name = s ;}
082
083        /**
084         * {@inheritDoc}
085         */
086        @Override
087        public String getName()         { return name ;}
088
089        /**
090         * {@inheritDoc}
091         */
092        @Override
093        public void setPDBserial(int i) { pdbserial = i    ; }
094
095        /**
096         * {@inheritDoc}
097         */
098        @Override
099        public int  getPDBserial()      { return pdbserial ; }
100
101        /**
102         * {@inheritDoc}
103         */
104        @Override
105        public void     setCoords( double[] c ) { 
106                coords = new Point3d(c); 
107        }
108
109        /**
110         * {@inheritDoc}
111         */
112        @Override
113        public double[] getCoords() { 
114                double[] c = new double[3];
115                coords.get(c);
116                return c;               
117        }
118        
119        /**
120         * {@inheritDoc}
121         */
122        @Override
123        public Point3d getCoordsAsPoint3d() {
124                return coords;
125        }
126
127        @Override
128        public void setX(double x) {
129                coords.x = x ;
130        }
131        
132        @Override
133        public void setY(double y) {
134                coords.y = y ;
135        }
136        
137        @Override
138        public void setZ(double z) {
139                coords.z = z ;
140        }
141
142        /**
143         * {@inheritDoc}
144         */
145        @Override
146        public double getX() { return coords.x; }
147
148        /**
149         * {@inheritDoc}
150         */
151        @Override
152        public double getY() { return coords.y; }
153
154        /**
155         * {@inheritDoc}
156         */
157        @Override
158        public double getZ() { return coords.z; }
159
160        /**
161         * Set alternate Location.
162         * @see #getAltLoc
163         */
164        @Override
165        public void setAltLoc(Character c) {
166                // after changing altLoc from Character to char, we do this to keep the interface the same as it used to be - JD 2016-01-27
167                if (c==null)
168                        altLoc = 0;
169                else
170                        altLoc = c ;
171        }
172
173        /**
174         * Get alternate Location.
175         * @return a Character object representing the alt loc value
176         * @see #setAltLoc
177         */
178        @Override
179        public Character getAltLoc() {
180                // after changing altLoc from Character to char, we do this to keep the interface the same as it used to be - JD 2016-01-27
181                if (altLoc==0 ) return null;
182                return altLoc ;
183        }
184
185        @Override
186        public String toString() {
187                return name + " " + element + " " + pdbserial + " " + coords.x + " " + coords.y + " " + coords.z;
188        }
189
190        @Override
191        public void   setOccupancy(float occu){
192                occupancy = occu ;
193        }
194
195        @Override
196        public float getOccupancy(){
197                return occupancy;
198        }
199
200        @Override
201        public void   setTempFactor(float temp) {
202                tempfactor = temp ;
203        }
204
205        @Override
206        public float getTempFactor() {
207                return tempfactor;
208        }
209
210        /** returns and identical copy of this  object .
211         * @return  and identical copy of this  object
212         */
213        @Override
214        public Object clone() {
215                AtomImpl n = new AtomImpl();
216                n.setOccupancy(getOccupancy());
217                n.setTempFactor(getTempFactor());
218                n.altLoc = altLoc; // since char is a primitive we can do this (to avoid going through getter/setter that check for nulls)
219                n.setCharge(getCharge());
220                double[] coords = getCoords();
221                n.setX(coords[0]);
222                n.setY(coords[1]);
223                n.setZ(coords[2]);
224                n.setPDBserial(getPDBserial());
225                n.setName(getName());
226                n.setElement(getElement());
227                // NOTE bonds can't be cloned here, they would need to be cloned at the
228                //      chain or group level (depending if they are intra or inter group bonds) -- JD 2016-03-02
229
230                return n ;
231        }
232
233        /**
234         * {@inheritDoc}
235         */
236        @Override
237        public void setGroup(Group parent){
238                this.parent = parent;
239        }
240
241        /**
242         * {@inheritDoc}
243         */
244        @Override
245        public Group getGroup(){
246                return parent;
247        }
248
249        /**
250         * {@inheritDoc}
251         */
252        @Override
253        public Element getElement() {
254                return element;
255        }
256
257        /**
258         * {@inheritDoc}
259         */
260        @Override
261        public void setElement(Element e) {
262                this.element = e;
263
264        }
265
266        @Override
267        public String toPDB() {
268
269                return FileConvert.toPDB(this);
270        }
271
272        @Override
273        public void toPDB(StringBuffer buf) {
274                FileConvert.toPDB(this,buf);
275
276        }
277
278        /**
279         * {@inheritDoc}
280         */
281        @Override
282        public List<Bond> getBonds() {
283                return bonds;
284        }
285
286        /**
287         * {@inheritDoc}
288         */
289        @Override
290        public boolean hasBond(Atom other){
291                if ( bonds == null)
292                        return false;
293
294                for (Bond b : bonds){
295                        if ( b.getAtomA().equals(other) || b.getAtomB().equals(other))
296                                return true;
297                }
298                return false;
299        }
300
301        /**
302         * {@inheritDoc}
303         */
304        @Override
305        public void setBonds(List<Bond> bonds) {
306                this.bonds = bonds;
307        }
308
309        @Override
310        public void addBond(Bond bond) {
311                if (bonds==null) {
312                        bonds = new ArrayList<Bond>(BONDS_INITIAL_CAPACITY);
313                }
314                bonds.add(bond);
315        }
316
317        @Override
318        public short getCharge() {
319                // Get the charge
320                return charge;
321        }
322
323        @Override
324        public void setCharge(short inputCharge) {
325                // Set the charge
326                charge = inputCharge;
327
328        }
329}