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