001/*
002 *
003 * This code may be freely distributed and modified under the
004 * terms of the GNU Lesser General Public Licence.  This should
005 * be distributed with the code.  If you do not have a copy,
006 * see:
007 *
008 *      http://www.gnu.org/copyleft/lesser.html
009 *
010 * Copyright for this code is held jointly by the individual
011 * authors.  These should be listed in @author doc comments.
012 *
013 * For more information on the BioJava project and its aims,
014 * or to join the biojava-l mailing list, visit the home page
015 * at:
016 *
017 *      http://www.biojava.org/
018 *
019 */
020
021package org.biojava.nbio.structure;
022
023import java.io.Serializable;
024import java.util.ArrayList;
025import java.util.List;
026import java.util.Locale;
027
028/**
029 * Holds the data of sites presented in PDB files. <br/>
030 * Example from the PDB flatfile:
031 * <pre>
032        SITE     1 AC1  3 GLY A  65  CYS A  67  HOH A 180
033        SITE     1 AC2 10 HIS C  37  ALA C  39  THR C 152  LEU C 153
034        SITE     2 AC2 10 HIS D  37  ALA D  39  THR D 152  LEU D 153
035        SITE     3 AC2 10 SER D 154  GOL D 172
036        </pre>
037 * @author Amr AL-Hossary
038 * @author Jules Jacobsen
039 */
040public class Site implements PDBRecord, Serializable, Comparable<Site> {
041
042        private static final long serialVersionUID = -4577047072916341237L;
043        private static final String lineEnd = System.getProperty("line.separator");
044
045        private String siteID = "";
046        private List<Group> groups = new ArrayList<Group>();
047        //variables for REMARK 800
048        private String evCode = "";
049        private String description = "";
050
051        public Site() {
052        }
053
054        public Site(String siteID, List<Group> groups) {
055                this.siteID = siteID;
056                this.groups = groups;
057        }
058
059
060        @Override
061        public String toString() {
062                StringBuilder stringBuilder = new StringBuilder("SITE ");
063                stringBuilder.append(siteID).append(" ").append(groups.size()).append(" ");
064                for (Group group : groups) {
065                        // 012345678910
066                        //'ARG H 221A '
067                        String groupString = String.format("%s %s",
068                                                group.getPDBName(),
069                                                group.getResidueNumber().toPDB());
070                        stringBuilder.append(groupString);
071                }
072                stringBuilder.append(lineEnd);
073                return stringBuilder.toString();
074        }
075
076
077        @Override
078        public String toPDB() {
079                StringBuffer buffer = new StringBuffer();
080                toPDB(buffer);
081                return buffer.toString();
082        }
083
084
085        @Override
086        public void toPDB(StringBuffer buf) {
087                if (groups == null || groups.size() < 1) {
088                        return;
089                }
090
091                //SITE     1 CAT  3 HIS H  57  ASP H 102  SER H 195
092                //SITE     1 AC1  6 ARG H 221A LYS H 224  HOH H 403  HOH H 460
093                //SITE     2 AC1  6 HOH H 464  HOH H 497
094                //         ^  ^   ^
095                //     cont# id  group size
096                //max 4 groups per line
097
098                //counters for tracking where we are
099                int seqNum = 0;
100                int groupsWritten = 0;
101                int groupNum = 0;
102                //new StringBuilder for adding the groups to
103                StringBuilder stringBuilder = new StringBuilder();
104
105                while (groupsWritten < groups.size()) {
106                        StringBuilder groupsString = new StringBuilder();
107                        for (int i = 0; i < 4 && groupsWritten < groups.size(); i++) {
108                                Group group = groups.get(groupNum);
109                                // Make sure the pdbName is formatted as 3 width string.
110                                String groupString = String.format(Locale.UK, "%3s %s",
111                                                group.getPDBName(), group.getResidueNumber().toPDB());
112                                groupsWritten++;
113                                groupNum++;
114                                if (i == 3 || groupsWritten == groups.size()) {
115                                        // groupString = groupString.trim();
116                                        groupString.replaceFirst("\\s+$", ""); // remove only trailing whitespace.
117                                }
118                                groupsString.append(groupString);
119                        }
120                        stringBuilder.append(String.format(Locale.UK, "SITE   %3d %3s %2d %-62s", seqNum + 1, siteID, groups.size(), groupsString.toString()));
121                        //iterate the line counter, add the end of line character
122                        seqNum++;
123                        stringBuilder.append(lineEnd);
124                }
125
126                buf.append(stringBuilder);
127        }
128
129        /**
130         * Appends the REMARK 800 section pertaining to the site onto the end of the
131         * StringBuffer provided.
132         *
133         * For example in pdb 1a4w:
134         * REMARK 800 SITE_IDENTIFIER: CAT
135         * REMARK 800 EVIDENCE_CODE: UNKNOWN
136         * REMARK 800 SITE_DESCRIPTION: ACTIVE SITE
137         *
138         * @param stringBuffer
139         */
140        public void remark800toPDB(StringBuffer stringBuffer) {
141                //REMARK 800 SITE_IDENTIFIER: CAT
142                //REMARK 800 EVIDENCE_CODE: UNKNOWN
143                //REMARK 800 SITE_DESCRIPTION: ACTIVE SITE
144
145                stringBuffer.append(String.format(Locale.UK, "REMARK 800 SITE_IDENTIFIER: %-52s%s", siteID, lineEnd));
146                stringBuffer.append(String.format(Locale.UK, "REMARK 800 EVIDENCE_CODE: %-54s%s", evCode, lineEnd));
147                stringBuffer.append(String.format(Locale.UK, "REMARK 800 SITE_DESCRIPTION: %-51s%s", description, lineEnd));
148
149        }
150
151        /**
152         * Provides REMARK 800 section pertaining to the site as a string.
153         *
154         * For example in pdb 1a4w:
155         * REMARK 800 SITE_IDENTIFIER: CAT
156         * REMARK 800 EVIDENCE_CODE: UNKNOWN
157         * REMARK 800 SITE_DESCRIPTION: ACTIVE SITE
158         *
159         *
160         */
161        public String remark800toPDB() {
162                StringBuffer stringBuffer = new StringBuffer();
163                remark800toPDB(stringBuffer);
164                return stringBuffer.toString();
165        }
166
167        /**
168         * @param siteID the siteID to set
169         * e.g. CAT, AC1, AC2...
170         */
171        public void setSiteID(String siteID) {
172                this.siteID = siteID;
173        }
174
175        /**
176         * @return the siteID
177         * e.g. CAT, AC1, AC2...
178         */
179        public String getSiteID() {
180                return siteID;
181        }
182
183        /**
184         * @return the groups
185         */
186        public List<Group> getGroups() {
187                return groups;
188        }
189
190        /**
191         * @param residues the groups to set
192         */
193        public void setGroups(List<Group> residues) {
194                this.groups = residues;
195        }
196
197
198        /**
199         * gets the REMARK 800 description of the site
200         * @return description
201         */
202        public String getDescription() {
203                return description;
204        }
205
206        /**
207         * sets the REMARK 800 description of the site
208         */
209        public void setDescription(String description) {
210                this.description = description;
211        }
212
213        /**
214         * gets the REMARK 800 EVIDENCE CODE for the site.
215         * @return evidence code
216         */
217        public String getEvCode() {
218                return evCode;
219        }
220
221        /**
222         * sets the REMARK 800 EVIDENCE CODE for the site.
223         */
224        public void setEvCode(String evCode) {
225                this.evCode = evCode;
226        }
227
228        @Override
229        public boolean equals(Object obj) {
230                if (obj == null) {
231                        return false;
232                }
233                if (getClass() != obj.getClass()) {
234                        return false;
235                }
236                final Site other = (Site) obj;
237                if ((this.siteID == null) ? (other.siteID != null) : !this.siteID.equals(other.siteID)) {
238                        return false;
239                }
240                if (this.groups != other.groups && (this.groups == null || !this.groups.equals(other.groups))) {
241                        return false;
242                }
243                if ((this.evCode == null) ? (other.evCode != null) : !this.evCode.equals(other.evCode)) {
244                        return false;
245                }
246                if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
247                        return false;
248                }
249                return true;
250        }
251
252        @Override
253        public int hashCode() {
254                int hash = 5;
255                hash = 37 * hash + (this.siteID != null ? this.siteID.hashCode() : 0);
256                hash = 37 * hash + (this.groups != null ? this.groups.hashCode() : 0);
257                hash = 37 * hash + (this.evCode != null ? this.evCode.hashCode() : 0);
258                hash = 37 * hash + (this.description != null ? this.description.hashCode() : 0);
259                return hash;
260        }
261
262
263
264        @Override
265        public int compareTo(Site other) {
266                return this.toString().compareTo(other.toString());
267        }
268}