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