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 Nov 14, 2007
021 *
022 */
023
024package org.biojava.nbio.structure.io;
025
026import java.io.Serializable;
027import java.util.ArrayList;
028import java.util.List;
029
030import org.biojava.nbio.structure.Bond;
031import org.biojava.nbio.structure.PDBRecord;
032
033/**
034 * A simple bean to store disulfide bridge information, the SSBOND records in the PDB files.
035 *
036 * The two residues specified here are CYS residues that form a Disulfide bridge.
037 *
038 *
039 *
040 * @author Andreas Prlic
041 *
042 */
043public class SSBondImpl implements PDBRecord, Serializable, Cloneable {
044
045        private static final long serialVersionUID = -8663681100691188647L;
046
047        private int serNum;
048
049        private String chainID1;
050        private String chainID2;
051        private String resnum1;
052        private String resnum2;
053        private String insCode1;
054        private String insCode2;
055
056        public SSBondImpl(){
057                serNum = 0;
058        }
059
060        @Override
061        public String toPDB(){
062
063
064                StringBuffer buf = new StringBuffer();
065                toPDB(buf);
066                return buf.toString();
067        }
068
069        /**
070         * Append the PDB representation of this SSBOND to the provided StringBuffer
071         *
072         * @param buf a StringBuffer to print the PDB representation to
073         */
074        @Override
075        public void toPDB(StringBuffer buf){
076
077                /*12 - 14        LString(3)      "CYS"        Residue name.
078                16             Character       chainID1     Chain identifier.
079                18 - 21        Integer         seqNum1      Residue sequence number.
080                22             AChar           icode1       Insertion code.
081                26 - 28        LString(3)      "CYS"        Residue name.
082                30             Character       chainID2     Chain identifier.
083                32 - 35        Integer         seqNum2      Residue sequence number.
084                36             AChar           icode2       Insertion code.
085                60 - 65        SymOP           sym1         Symmetry oper for 1st resid
086                67 - 72        SymOP           sym2         Symmetry oper for 2nd resid
087                */
088                //01234567890123456789012345678901234567890123456789012345678901234567890123456789
089                //SSBOND   1 CYS      5    CYS     55                                     5PTI  67
090                //SSBOND   2 CYS     14    CYS     38
091                //SSBOND   3 CYS     30    CYS     51
092
093
094                buf.append("SSBOND ");
095                buf.append(String.format("%3d", serNum));
096                buf.append(String.format(" CYS %s %4s%1s  ", chainID1, resnum1, insCode1));
097                buf.append(String.format(" CYS %s %4s%1s  ", chainID2, resnum2, insCode2));
098
099        }
100
101
102        public String getInsCode1() {
103                return insCode1;
104        }
105
106        public void setInsCode1(String insCode1) {
107                this.insCode1 = insCode1;
108        }
109
110        public String getInsCode2() {
111                return insCode2;
112        }
113
114        public void setInsCode2(String insCode2) {
115                this.insCode2 = insCode2;
116        }
117
118
119        public int getSerNum() {
120                return serNum;
121        }
122
123        /** get serial number of this SSBOND in PDB file
124         *
125         * @param serNum
126         */
127        public void setSerNum(int serNum) {
128                this.serNum = serNum;
129        }
130
131        @Override
132        public SSBondImpl clone() {
133                SSBondImpl nbond = new SSBondImpl();
134                nbond.setChainID1(chainID1);
135                nbond.setChainID2(chainID2);
136                nbond.setResnum1(resnum1);
137                nbond.setResnum2(resnum2);
138                return nbond;
139        }
140
141        public String getChainID1() {
142                return chainID1;
143        }
144        public void setChainID1(String chainID1) {
145                this.chainID1 = chainID1;
146        }
147        public String getChainID2() {
148                return chainID2;
149        }
150        public void setChainID2(String chainID2) {
151                this.chainID2 = chainID2;
152        }
153
154
155        public String getResnum1() {
156                return resnum1;
157        }
158
159        public void setResnum1(String resnum1) {
160                this.resnum1 = resnum1;
161        }
162
163
164        public String getResnum2() {
165                return resnum2;
166        }
167        public void setResnum2(String resnum2) {
168                this.resnum2 = resnum2;
169        }
170
171        @Override
172        public String toString() {
173                String s = "[SSBOND:\n";
174
175                s += "Atom 1:\n";
176                s += "\tChain: " + chainID1 + "\n";
177                s += "\tResidue #: " + resnum1 + "\n";
178                s += "\tIns. Code: " + insCode1 + "\n";
179
180                s += "Atom 2:\n";
181                s += "\tChain: " + chainID2 + "\n";
182                s += "\tResidue #: " + resnum2 + "\n";
183                s += "\tIns. Code: " + insCode2 + "\n";
184
185                s += "]";
186
187                return s;
188        }
189
190        /* (non-Javadoc)
191         * @see java.lang.Object#hashCode()
192         */
193        @Override
194        public int hashCode() {
195                final int prime = 31;
196                int result = 1;
197                result = prime * result + ((chainID1 == null) ? 0 : chainID1.hashCode());
198                result = prime * result + ((chainID2 == null) ? 0 : chainID2.hashCode());
199                result = prime * result + ((insCode1 == null) ? 0 : insCode1.hashCode());
200                result = prime * result + ((insCode2 == null) ? 0 : insCode2.hashCode());
201                result = prime * result + ((resnum1 == null) ? 0 : resnum1.hashCode());
202                result = prime * result + ((resnum2 == null) ? 0 : resnum2.hashCode());
203                return result;
204        }
205
206        /* (non-Javadoc)
207         * @see java.lang.Object#equals(java.lang.Object)
208         */
209        @Override
210        public boolean equals(Object obj) {
211                if (this == obj)
212                        return true;
213                if (obj == null)
214                        return false;
215                if (getClass() != obj.getClass())
216                        return false;
217                SSBondImpl other = (SSBondImpl) obj;
218                if (chainID1 == null) {
219                        if (other.chainID1 != null)
220                                return false;
221                } else if (!chainID1.equals(other.chainID1))
222                        return false;
223                if (chainID2 == null) {
224                        if (other.chainID2 != null)
225                                return false;
226                } else if (!chainID2.equals(other.chainID2))
227                        return false;
228                if (insCode1 == null) {
229                        if (other.insCode1 != null)
230                                return false;
231                } else if (!insCode1.equals(other.insCode1))
232                        return false;
233                if (insCode2 == null) {
234                        if (other.insCode2 != null)
235                                return false;
236                } else if (!insCode2.equals(other.insCode2))
237                        return false;
238                if (resnum1 == null) {
239                        if (other.resnum1 != null)
240                                return false;
241                } else if (!resnum1.equals(other.resnum1))
242                        return false;
243                if (resnum2 == null) {
244                        if (other.resnum2 != null)
245                                return false;
246                } else if (!resnum2.equals(other.resnum2))
247                        return false;
248                return true;
249        }
250
251        public static List<SSBondImpl> getSsBondListFromBondList(List<Bond> bonds) {
252                List<SSBondImpl> l = new ArrayList<>();
253                for (int i=0; i<bonds.size(); i++) {
254                        SSBondImpl ssbond = toSsBond(bonds.get(i));
255                        ssbond.setSerNum(i + 1);
256                        l.add(ssbond);
257                }
258                return l;
259        }
260
261        /**
262         * Converts the given {@link Bond} object into a {@link SSBondImpl}.
263         *
264         * @return
265         * @throws IllegalArgumentException if this Bond is not between two CYS residues
266         */
267        public static SSBondImpl toSsBond(Bond bond) {
268
269                if (!bond.getAtomA().getGroup().getPDBName().equals("CYS") ||
270                        !bond.getAtomB().getGroup().getPDBName().equals("CYS")    ) {
271
272                        throw new IllegalArgumentException("Trying to create a SSBond from a Bond between 2 groups that are not CYS");
273                }
274
275                SSBondImpl ssbond = new SSBondImpl();
276                ssbond.setChainID1(bond.getAtomA().getGroup().getChainId());
277                ssbond.setChainID2(bond.getAtomB().getGroup().getChainId());
278                ssbond.setResnum1(String.valueOf(bond.getAtomA().getGroup().getResidueNumber().getSeqNum()));
279                ssbond.setResnum2(String.valueOf(bond.getAtomB().getGroup().getResidueNumber().getSeqNum()));
280
281                Character iCode1 = bond.getAtomA().getGroup().getResidueNumber().getInsCode();
282                if (iCode1 == null) iCode1 = ' ';
283                Character iCode2 = bond.getAtomB().getGroup().getResidueNumber().getInsCode();
284                if (iCode2 == null) iCode2 = ' ';
285
286                ssbond.setInsCode1(String.valueOf(iCode1));
287                ssbond.setInsCode2(String.valueOf(iCode2));
288
289                return ssbond;
290        }
291}