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 */
020package org.biojava.nbio.structure.ecod;
021
022import org.biojava.nbio.structure.*;
023import org.biojava.nbio.structure.align.util.AtomCache;
024
025import java.io.IOException;
026import java.io.Serializable;
027import java.util.HashSet;
028import java.util.List;
029import java.util.Set;
030
031/**
032 * An EcodDomain contains all the information of the ECOD database: id, 
033 * classification groups (from higher to lower in the tree: X,H,T,F), PDB code,
034 * chain, residue ranges and status (manual or automatic classification).
035 * <p>
036 * For detailed explanation about the ECOD information see the original article
037 * at: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4256011.
038 * <pre>
039 * Cheng H, Schaeffer RD, Liao Y, et al. 
040 * ECOD: An Evolutionary Classification of Protein Domains. 
041 * Elofsson A, ed. PLoS Computational Biology. 2014;10(12):e1003926.
042 * </pre>
043 * 
044 * @author Spencer Bliven
045 *
046 */
047public class EcodDomain implements Serializable, Cloneable, StructureIdentifier {
048
049        /*
050Column 1: ECOD uid - internal domain unique identifier
051Column 2: ECOD domain id - domain identifier
052Column 3: ECOD representative status - manual (curated) or automated nonrep
053Column 4: ECOD hierachy identifier - [X-group].[H-group].[T-group].[F-group]
054Column 5: PDB identifier
055Column 6: Chain identifier (note: case-sensitive)
056Column 7: PDB residue number range
057Column 8: seq_id number range (based on internal PDB indices)
058Column 9: Architecture name
059Column 10: X-group name
060Column 11: H-group name
061Column 12: T-group name
062Column 13: F-group name (F_UNCLASSIFIED denotes that domain has not been assigned to an F-group)
063Column 14: Domain assembly status (if domain is member of assembly, partners' ecod domain ids listed)
064Column 15: Comma-separated value list of non-polymer entities within 4 A of at least one residue of domain
065
066
067001502751       e4s1gA1 1.1.1   4s1g    A       A:68-251        beta barrels    cradle loop barrel      RIFT-related    acid protease   F_UNCLASSIFIED  NOT_DOMAIN_ASSEMBLY     NO_LIGANDS_4A
068
069         */
070
071
072        private static final long serialVersionUID = -7760082165560332048L;
073
074
075        private Long uid;
076        private String domainId;
077        private Boolean manual;
078        private Integer xGroup;
079        private Integer hGroup;
080        private Integer tGroup;
081        private Integer fGroup;
082        private String pdbId;
083        private String chainId;
084        private String range;
085        private String seqIdRange;
086        private String architectureName;
087        private String xGroupName;
088        private String hGroupName;
089        private String tGroupName;
090        private String fGroupName;
091        private Long assemblyId; //for non-assemblies, matches the uid.
092        private Set<String> ligands;
093
094        /** Default constructor with all null properties */
095        public EcodDomain() {}
096
097        public EcodDomain(Long uid, String domainId, Boolean manual,
098                        Integer xGroup, Integer hGroup, Integer tGroup, Integer fGroup, String pdbId,
099                        String chainId, String range, String architectureName,
100                        String xGroupName, String hGroupName, String tGroupName,
101                        String fGroupName, Long assemblyId, Set<String> ligands) {
102                this(uid, domainId, manual,
103                                xGroup, hGroup, tGroup, fGroup, pdbId,
104                                chainId, range, null, architectureName,
105                                xGroupName, hGroupName, tGroupName,
106                                fGroupName, assemblyId, ligands);
107        }
108        public EcodDomain(Long uid, String domainId, Boolean manual,
109                                Integer xGroup, Integer hGroup, Integer tGroup, Integer fGroup, String pdbId,
110                                String chainId, String range, String seqId, String architectureName,
111                                String xGroupName, String hGroupName, String tGroupName,
112                                String fGroupName, Long assemblyId, Set<String> ligands) {
113                this.uid = uid;
114                this.domainId = domainId;
115                this.manual = manual;
116                this.xGroup = xGroup;
117                this.hGroup = hGroup;
118                this.tGroup = tGroup;
119                this.fGroup = fGroup;
120                this.pdbId = pdbId;
121                this.chainId = chainId;
122                this.range = range;
123                this.seqIdRange = seqId;
124                this.architectureName = architectureName;
125                this.xGroupName = xGroupName;
126                this.hGroupName = hGroupName;
127                this.tGroupName = tGroupName;
128                this.fGroupName = fGroupName;
129                this.assemblyId = assemblyId;
130                this.ligands = ligands;
131        }
132        public EcodDomain(String domainId) {
133                this.domainId = domainId;
134        }
135        public EcodDomain(EcodDomain o) {
136                this.uid = o.uid;
137                this.domainId = o.domainId;
138                this.manual = o.manual;
139                this.xGroup = o.xGroup;
140                this.hGroup = o.hGroup;
141                this.tGroup = o.tGroup;
142                this.fGroup = o.fGroup;
143                this.pdbId = o.pdbId;
144                this.chainId = o.chainId;
145                this.range = o.range;
146                this.seqIdRange = o.seqIdRange;
147                this.architectureName = o.architectureName;
148                this.xGroupName = o.xGroupName;
149                this.hGroupName = o.hGroupName;
150                this.tGroupName = o.tGroupName;
151                this.fGroupName = o.fGroupName;
152                this.assemblyId = o.assemblyId;
153                this.ligands = new HashSet<String>(o.ligands);
154        }
155
156
157
158        @Override
159        protected Object clone() throws CloneNotSupportedException {
160                return new EcodDomain(this);
161        }
162
163        public Long getUid() {
164                return uid;
165        }
166        public void setUid(Long uid) {
167                this.uid = uid;
168        }
169        public String getDomainId() {
170                return domainId;
171        }
172        public void setDomainId(String domainId) {
173                this.domainId = domainId;
174        }
175        public Boolean getManual() {
176                return manual;
177        }
178        public void setManual(Boolean manual) {
179                this.manual = manual;
180        }
181        public Integer getXGroup() {
182                return xGroup;
183        }
184        public void setXGroup(Integer xGroup) {
185                this.xGroup = xGroup;
186        }
187        public Integer getHGroup() {
188                return hGroup;
189        }
190        public void setHGroup(Integer hGroup) {
191                this.hGroup = hGroup;
192        }
193        public Integer getTGroup() {
194                return tGroup;
195        }
196        public void setTGroup(Integer tGroup) {
197                this.tGroup = tGroup;
198        }
199        public Integer getFGroup() {
200                return fGroup;
201        }
202        public void setFGroup(Integer fGroup) {
203                this.fGroup = fGroup;
204        }
205        public String getPdbId() {
206                return pdbId;
207        }
208        public void setPdbId(String pdbId) {
209                this.pdbId = pdbId;
210        }
211        public String getChainId() {
212                return chainId;
213        }
214        public void setChainId(String chainId) {
215                this.chainId = chainId;
216        }
217        /**
218         * Get the range of this domain, in PDB residue numbers (mmCif's
219         * _pdbx_poly_seq_scheme.pdb_seq_num and pdb_ins_code).
220         * @return The chain and residue range, e.g. "A:1-100"
221         */
222        public String getRange() {
223                return range;
224        }
225        public void setRange(String range) {
226                this.range = range;
227        }
228        /**
229         * Get the range of this domain, in 1-based residue indices (mmCif's
230         * _pdbx_poly_seq_scheme.seq_id)
231         *
232         * Note that {@link #getRange()} is used when constructing the domain.
233         * @return The chain and residue range, e.g. "A:1-100"
234         */
235        public String getSeqIdRange() {
236                return seqIdRange;
237        }
238        public void setSeqIdRange(String seqIdRange) {
239                this.seqIdRange = seqIdRange;
240        }
241        public String getArchitectureName() {
242                return architectureName;
243        }
244        public void setArchitectureName(String architectureName) {
245                this.architectureName = architectureName;
246        }
247        public String getXGroupName() {
248                return xGroupName;
249        }
250        public void setXGroupName(String xGroupName) {
251                this.xGroupName = xGroupName;
252        }
253        public String getHGroupName() {
254                return hGroupName;
255        }
256        public void setHGroupName(String hGroupName) {
257                this.hGroupName = hGroupName;
258        }
259        public String getTGroupName() {
260                return tGroupName;
261        }
262        public void setGroupName(String tGroupName) {
263                this.tGroupName = tGroupName;
264        }
265        public String getFGroupName() {
266                return fGroupName;
267        }
268        public void setFGroupName(String fGroupName) {
269                this.fGroupName = fGroupName;
270        }
271        /**
272         * @return The assembly ID, or the DomainId if not in an assembly, or null if unknown.
273         */
274        public Long getAssemblyId() {
275                return assemblyId;
276        }
277        public void setAssemblyId(Long assemblyId) {
278                this.assemblyId = assemblyId;
279        }
280        public Set<String> getLigands() {
281                return ligands;
282        }
283        public void setLigands(Set<String> ligands) {
284                this.ligands = ligands;
285        }
286
287        /* (non-Javadoc)
288         * @see java.lang.Object#toString()
289         */
290        @Override
291        public String toString() {
292                return "EcodDomain [uid=" + uid + ", domainId=" + domainId
293                                + ", manual=" + manual + ", xGroup=" + xGroup + ", hGroup="
294                                + hGroup + ", tGroup=" + tGroup + ", fGroup="+ fGroup + ", pdbId=" + pdbId
295                                + ", chainId=" + chainId + ", range=" + range
296                                + ", architectureName=" + architectureName + ", xGroupName="
297                                + xGroupName + ", hGroupName=" + hGroupName + ", tGroupName="
298                                + tGroupName + ", fGroupName=" + fGroupName + ", assemblyId="
299                                + assemblyId + ", ligands=" + ligands + "]";
300        }
301
302        /* (non-Javadoc)
303         * @see java.lang.Object#hashCode()
304         */
305        @Override
306        public int hashCode() {
307                final int prime = 31;
308                int result = 1;
309                result = prime
310                                * result
311                                + ((architectureName == null) ? 0 : architectureName.hashCode());
312                result = prime * result + ((chainId == null) ? 0 : chainId.hashCode());
313                result = prime * result
314                                + ((domainId == null) ? 0 : domainId.hashCode());
315                result = prime * result
316                                + ((fGroupName == null) ? 0 : fGroupName.hashCode());
317                result = prime * result + ((fGroup == null) ? 0 : fGroup.hashCode());
318                result = prime * result + ((hGroup == null) ? 0 : hGroup.hashCode());
319                result = prime * result
320                                + ((hGroupName == null) ? 0 : hGroupName.hashCode());
321                result = prime * result
322                                + ((assemblyId == null) ? 0 : assemblyId.hashCode());
323                result = prime * result + ((ligands == null) ? 0 : ligands.hashCode());
324                result = prime * result + ((manual == null) ? 0 : manual.hashCode());
325                result = prime * result + ((pdbId == null) ? 0 : pdbId.hashCode());
326                result = prime * result + ((range == null) ? 0 : range.hashCode());
327                result = prime * result + ((tGroup == null) ? 0 : tGroup.hashCode());
328                result = prime * result
329                                + ((tGroupName == null) ? 0 : tGroupName.hashCode());
330                result = prime * result + ((uid == null) ? 0 : uid.hashCode());
331                result = prime * result + ((xGroup == null) ? 0 : xGroup.hashCode());
332                result = prime * result
333                                + ((xGroupName == null) ? 0 : xGroupName.hashCode());
334                return result;
335        }
336
337        /* (non-Javadoc)
338         * @see java.lang.Object#equals(java.lang.Object)
339         */
340        @Override
341        public boolean equals(Object obj) {
342                if (this == obj)
343                        return true;
344                if (obj == null)
345                        return false;
346                if (getClass() != obj.getClass())
347                        return false;
348                EcodDomain other = (EcodDomain) obj;
349                if (architectureName == null) {
350                        if (other.architectureName != null)
351                                return false;
352                } else if (!architectureName.equals(other.architectureName))
353                        return false;
354                if (chainId == null) {
355                        if (other.chainId != null)
356                                return false;
357                } else if (!chainId.equals(other.chainId))
358                        return false;
359                if (domainId == null) {
360                        if (other.domainId != null)
361                                return false;
362                } else if (!domainId.equals(other.domainId))
363                        return false;
364                if (fGroupName == null) {
365                        if (other.fGroupName != null)
366                                return false;
367                } else if (!fGroupName.equals(other.fGroupName))
368                        return false;
369                if (fGroup == null) {
370                        if (other.fGroup != null)
371                                return false;
372                } else if (!fGroup.equals(other.fGroup))
373                        return false;
374                if (hGroup == null) {
375                        if (other.hGroup != null)
376                                return false;
377                } else if (!hGroup.equals(other.hGroup))
378                        return false;
379                if (hGroupName == null) {
380                        if (other.hGroupName != null)
381                                return false;
382                } else if (!hGroupName.equals(other.hGroupName))
383                        return false;
384                if (assemblyId == null) {
385                        if (other.assemblyId != null)
386                                return false;
387                } else if (!assemblyId.equals(other.assemblyId))
388                        return false;
389                if (ligands == null) {
390                        if (other.ligands != null)
391                                return false;
392                } else if (!ligands.equals(other.ligands))
393                        return false;
394                if (manual == null) {
395                        if (other.manual != null)
396                                return false;
397                } else if (!manual.equals(other.manual))
398                        return false;
399                if (pdbId == null) {
400                        if (other.pdbId != null)
401                                return false;
402                } else if (!pdbId.equals(other.pdbId))
403                        return false;
404                if (range == null) {
405                        if (other.range != null)
406                                return false;
407                } else if (!range.equals(other.range))
408                        return false;
409                if (tGroup == null) {
410                        if (other.tGroup != null)
411                                return false;
412                } else if (!tGroup.equals(other.tGroup))
413                        return false;
414                if (tGroupName == null) {
415                        if (other.tGroupName != null)
416                                return false;
417                } else if (!tGroupName.equals(other.tGroupName))
418                        return false;
419                if (uid == null) {
420                        if (other.uid != null)
421                                return false;
422                } else if (!uid.equals(other.uid))
423                        return false;
424                if (xGroup == null) {
425                        if (other.xGroup != null)
426                                return false;
427                } else if (!xGroup.equals(other.xGroup))
428                        return false;
429                if (xGroupName == null) {
430                        if (other.xGroupName != null)
431                                return false;
432                } else if (!xGroupName.equals(other.xGroupName))
433                        return false;
434                return true;
435        }
436
437        @Override
438        public String getIdentifier() {
439                return getDomainId();
440        }
441
442        public List<ResidueRange> getResidueRanges() {
443                return ResidueRange.parseMultiple(range);
444        }
445
446        @Override
447        public SubstructureIdentifier toCanonical() {
448                return new SubstructureIdentifier(getPdbId(), ResidueRange.parseMultiple(getRange()));
449        }
450
451        @Override
452        public Structure reduce(Structure input) throws StructureException {
453                return toCanonical().reduce(input);
454        }
455
456        @Override
457        public Structure loadStructure(AtomCache cache) throws StructureException,
458                        IOException {
459                return cache.getStructureForPdbId(pdbId);
460        }
461
462}