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 */
021package org.biojava.nbio.structure.cluster;
022
023import org.biojava.nbio.core.exceptions.CompoundNotFoundException;
024import org.biojava.nbio.core.sequence.ProteinSequence;
025import org.biojava.nbio.structure.Atom;
026import org.biojava.nbio.structure.Structure;
027import org.biojava.nbio.structure.StructureIdentifier;
028import org.biojava.nbio.structure.StructureTools;
029
030/**
031 * A Subunit consists of a set of residues from a Structure, which may
032 * correspond to an entire Chain, a Domain, or any subset or combination of
033 * residues from them. All the residues of a Subunit are of the same type.
034 * <p>
035 * The Subunit object can contain additional fields for identification and
036 * annotation.
037 * 
038 * @author Aleix Lafita
039 * @since 5.0.0
040 *
041 */
042public class Subunit {
043
044        // Optional fields for Subunit annotation
045        private String name;
046        private Structure structure;
047        private StructureIdentifier identifier;
048
049        // Required fields for Subunit definition
050        private Atom[] reprAtoms;
051        private ProteinSequence sequence = null;
052
053        /**
054         * A Subunit is solely defined by the coordinates of the representative
055         * Atoms of its residues. It can be identified with a StructureIdentifier
056         * and/or a name and stores a reference to the Structure from which the
057         * Atoms were obtained.
058         * 
059         * @param reprAtoms
060         *            representative Atoms. It cannot be null or empty
061         * @param name
062         *            String field that identifies the Subunit. It can be null
063         * @param identifier
064         *            StructureIdentifier. It can be null
065         * @param structure
066         *            parent Structure object. It can be null
067         */
068        public Subunit(Atom[] reprAtoms, String name,
069                        StructureIdentifier identifier, Structure structure) {
070
071                if (reprAtoms == null)
072                        throw new IllegalArgumentException(
073                                        "Representative Atom Array of the Subunit is null");
074                if (reprAtoms.length==0)
075                        throw new IllegalArgumentException(
076                                        "Representative Atom Array of the Subunit has 0 length");
077
078                this.reprAtoms = reprAtoms;
079                this.name = name;
080                this.identifier = identifier;
081                this.structure = structure;
082        }
083
084        /**
085         * Get all the representative Atoms of the Subunit. These Atoms are used for
086         * clustering and displaying the Subunit.
087         * 
088         * @return representative Atom[]
089         */
090        public Atom[] getRepresentativeAtoms() {
091                return reprAtoms;
092        }
093
094        /**
095         * The size of a Subunit is the number of residues it contains.
096         * 
097         * @return the size of the Subunit
098         */
099        public int size() {
100                return reprAtoms.length;
101        }
102
103        /**
104         * Get the protein sequence of the Subunit as String.
105         * 
106         * @return protein sequence String
107         */
108        public String getProteinSequenceString() {
109
110                if (sequence != null)
111                        return sequence.toString();
112
113                StringBuilder builder = new StringBuilder();
114                for (Atom a : reprAtoms)
115                        // This method preferred over getChemComp.getOneLetterCode because
116                        // it returns always X for Unknown residues
117                        builder.append(StructureTools.get1LetterCode(a.getGroup()
118                                        .getPDBName()));
119
120                return builder.toString();
121        }
122
123        /**
124         * Get the protein sequence of the Subunit.
125         * 
126         * @return sequence ProteinSequence
127         * @throws CompoundNotFoundException
128         */
129        public ProteinSequence getProteinSequence()
130                        throws CompoundNotFoundException {
131
132                if (sequence == null)
133                        sequence = new ProteinSequence(getProteinSequenceString());
134
135                return sequence;
136        }
137
138        /**
139         * The Name of a Subunit is a free-text field, user defined.
140         * 
141         * @return the Subunit name
142         */
143        public String getName() {
144                return name;
145        }
146
147        /**
148         * The Name of a Subunit is a free-text field, user defined.
149         * 
150         * @param name
151         *            of the Subunit
152         */
153        public void setName(String name) {
154                this.name = name;
155        }
156
157        /**
158         * The parent Structure from which the Subunit atoms were obtained.
159         * 
160         * @return Structure object
161         */
162        public Structure getStructure() {
163                return structure;
164        }
165
166        /**
167         * The standard identifier of the Subunit.
168         * 
169         * @return StructureIdentifier object
170         */
171        public StructureIdentifier getIdentifier() {
172                return identifier;
173        }
174
175        @Override
176        public String toString() {
177                return "Subunit [Name: " + name + ", Identifier: " + identifier
178                                + ", Size:" + size() + ", Sequence:" + sequence + "]";
179        }
180
181}