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 PdbId 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 = new 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
206        public void setPdbId(String pdbId) {
207                if (pdbId == null)
208                        this.pdbId = null;
209                else
210                        setPdbId(new PdbId(pdbId));
211        }
212
213        /**
214         * Gets the {@link PdbId} object.<br>
215         * Before 6.0.0, this method used to return a {@link String}.
216         * @return the {@link PdbId} object associated with this domain.
217         * @since 6.0.0
218         */
219        public PdbId getPdbId() {
220                return pdbId;
221        }
222        
223        /**
224         * @param pdbId
225         * @since 6.0.0
226         */
227        public void setPdbId(PdbId pdbId) {
228                this.pdbId = pdbId;
229        }
230
231        public String getChainId() {
232                return chainId;
233        }
234        public void setChainId(String chainId) {
235                this.chainId = chainId;
236        }
237        /**
238         * Get the range of this domain, in PDB residue numbers (mmCif's
239         * _pdbx_poly_seq_scheme.pdb_seq_num and pdb_ins_code).
240         * @return The chain and residue range, e.g. "A:1-100"
241         */
242        public String getRange() {
243                return range;
244        }
245        public void setRange(String range) {
246                this.range = range;
247        }
248        /**
249         * Get the range of this domain, in 1-based residue indices (mmCif's
250         * _pdbx_poly_seq_scheme.seq_id)
251         *
252         * Note that {@link #getRange()} is used when constructing the domain.
253         * @return The chain and residue range, e.g. "A:1-100"
254         */
255        public String getSeqIdRange() {
256                return seqIdRange;
257        }
258        public void setSeqIdRange(String seqIdRange) {
259                this.seqIdRange = seqIdRange;
260        }
261        public String getArchitectureName() {
262                return architectureName;
263        }
264        public void setArchitectureName(String architectureName) {
265                this.architectureName = architectureName;
266        }
267        public String getXGroupName() {
268                return xGroupName;
269        }
270        public void setXGroupName(String xGroupName) {
271                this.xGroupName = xGroupName;
272        }
273        public String getHGroupName() {
274                return hGroupName;
275        }
276        public void setHGroupName(String hGroupName) {
277                this.hGroupName = hGroupName;
278        }
279        public String getTGroupName() {
280                return tGroupName;
281        }
282        public void setGroupName(String tGroupName) {
283                this.tGroupName = tGroupName;
284        }
285        public String getFGroupName() {
286                return fGroupName;
287        }
288        public void setFGroupName(String fGroupName) {
289                this.fGroupName = fGroupName;
290        }
291        /**
292         * @return The assembly ID, or the DomainId if not in an assembly, or null if unknown.
293         */
294        public Long getAssemblyId() {
295                return assemblyId;
296        }
297        public void setAssemblyId(Long assemblyId) {
298                this.assemblyId = assemblyId;
299        }
300        public Set<String> getLigands() {
301                return ligands;
302        }
303        public void setLigands(Set<String> ligands) {
304                this.ligands = ligands;
305        }
306
307        /* (non-Javadoc)
308         * @see java.lang.Object#toString()
309         */
310        @Override
311        public String toString() {
312                return "EcodDomain [uid=" + uid + ", domainId=" + domainId
313                                + ", manual=" + manual + ", xGroup=" + xGroup + ", hGroup="
314                                + hGroup + ", tGroup=" + tGroup + ", fGroup="+ fGroup + ", pdbId=" + pdbId
315                                + ", chainName=" + chainId + ", range=" + range
316                                + ", architectureName=" + architectureName + ", xGroupName="
317                                + xGroupName + ", hGroupName=" + hGroupName + ", tGroupName="
318                                + tGroupName + ", fGroupName=" + fGroupName + ", assemblyId="
319                                + assemblyId + ", ligands=" + ligands + "]";
320        }
321
322        /* (non-Javadoc)
323         * @see java.lang.Object#hashCode()
324         */
325        @Override
326        public int hashCode() {
327                final int prime = 31;
328                int result = 1;
329                result = prime
330                                * result
331                                + ((architectureName == null) ? 0 : architectureName.hashCode());
332                result = prime * result + ((chainId == null) ? 0 : chainId.hashCode());
333                result = prime * result
334                                + ((domainId == null) ? 0 : domainId.hashCode());
335                result = prime * result
336                                + ((fGroupName == null) ? 0 : fGroupName.hashCode());
337                result = prime * result + ((fGroup == null) ? 0 : fGroup.hashCode());
338                result = prime * result + ((hGroup == null) ? 0 : hGroup.hashCode());
339                result = prime * result
340                                + ((hGroupName == null) ? 0 : hGroupName.hashCode());
341                result = prime * result
342                                + ((assemblyId == null) ? 0 : assemblyId.hashCode());
343                result = prime * result + ((ligands == null) ? 0 : ligands.hashCode());
344                result = prime * result + ((manual == null) ? 0 : manual.hashCode());
345                result = prime * result + ((pdbId == null) ? 0 : pdbId.hashCode());
346                result = prime * result + ((range == null) ? 0 : range.hashCode());
347                result = prime * result + ((tGroup == null) ? 0 : tGroup.hashCode());
348                result = prime * result
349                                + ((tGroupName == null) ? 0 : tGroupName.hashCode());
350                result = prime * result + ((uid == null) ? 0 : uid.hashCode());
351                result = prime * result + ((xGroup == null) ? 0 : xGroup.hashCode());
352                result = prime * result
353                                + ((xGroupName == null) ? 0 : xGroupName.hashCode());
354                return result;
355        }
356
357        /* (non-Javadoc)
358         * @see java.lang.Object#equals(java.lang.Object)
359         */
360        @Override
361        public boolean equals(Object obj) {
362                if (this == obj)
363                        return true;
364                if (obj == null)
365                        return false;
366                if (getClass() != obj.getClass())
367                        return false;
368                EcodDomain other = (EcodDomain) obj;
369                if (architectureName == null) {
370                        if (other.architectureName != null)
371                                return false;
372                } else if (!architectureName.equals(other.architectureName))
373                        return false;
374                if (chainId == null) {
375                        if (other.chainId != null)
376                                return false;
377                } else if (!chainId.equals(other.chainId))
378                        return false;
379                if (domainId == null) {
380                        if (other.domainId != null)
381                                return false;
382                } else if (!domainId.equals(other.domainId))
383                        return false;
384                if (fGroupName == null) {
385                        if (other.fGroupName != null)
386                                return false;
387                } else if (!fGroupName.equals(other.fGroupName))
388                        return false;
389                if (fGroup == null) {
390                        if (other.fGroup != null)
391                                return false;
392                } else if (!fGroup.equals(other.fGroup))
393                        return false;
394                if (hGroup == null) {
395                        if (other.hGroup != null)
396                                return false;
397                } else if (!hGroup.equals(other.hGroup))
398                        return false;
399                if (hGroupName == null) {
400                        if (other.hGroupName != null)
401                                return false;
402                } else if (!hGroupName.equals(other.hGroupName))
403                        return false;
404                if (assemblyId == null) {
405                        if (other.assemblyId != null)
406                                return false;
407                } else if (!assemblyId.equals(other.assemblyId))
408                        return false;
409                if (ligands == null) {
410                        if (other.ligands != null)
411                                return false;
412                } else if (!ligands.equals(other.ligands))
413                        return false;
414                if (manual == null) {
415                        if (other.manual != null)
416                                return false;
417                } else if (!manual.equals(other.manual))
418                        return false;
419                if (pdbId == null) {
420                        if (other.pdbId != null)
421                                return false;
422                } else if (!pdbId.equals(other.pdbId))
423                        return false;
424                if (range == null) {
425                        if (other.range != null)
426                                return false;
427                } else if (!range.equals(other.range))
428                        return false;
429                if (tGroup == null) {
430                        if (other.tGroup != null)
431                                return false;
432                } else if (!tGroup.equals(other.tGroup))
433                        return false;
434                if (tGroupName == null) {
435                        if (other.tGroupName != null)
436                                return false;
437                } else if (!tGroupName.equals(other.tGroupName))
438                        return false;
439                if (uid == null) {
440                        if (other.uid != null)
441                                return false;
442                } else if (!uid.equals(other.uid))
443                        return false;
444                if (xGroup == null) {
445                        if (other.xGroup != null)
446                                return false;
447                } else if (!xGroup.equals(other.xGroup))
448                        return false;
449                if (xGroupName == null) {
450                        if (other.xGroupName != null)
451                                return false;
452                } else if (!xGroupName.equals(other.xGroupName))
453                        return false;
454                return true;
455        }
456
457        @Override
458        public String getIdentifier() {
459                return getDomainId();
460        }
461
462        public List<ResidueRange> getResidueRanges() {
463                return ResidueRange.parseMultiple(range);
464        }
465
466        @Override
467        public SubstructureIdentifier toCanonical() {
468                return new SubstructureIdentifier(getPdbId(), ResidueRange.parseMultiple(getRange()));
469        }
470
471        @Override
472        public Structure reduce(Structure input) throws StructureException {
473                return toCanonical().reduce(input);
474        }
475
476        @Override
477        public Structure loadStructure(AtomCache cache) throws StructureException,
478                        IOException {
479                return cache.getStructureForPdbId(pdbId);
480        }
481
482}