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