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.secstruc;
022
023import java.util.ArrayList;
024import java.util.List;
025import java.util.Map;
026import java.util.TreeMap;
027
028import org.biojava.nbio.structure.Group;
029import org.biojava.nbio.structure.GroupIterator;
030import org.biojava.nbio.structure.ResidueNumber;
031import org.biojava.nbio.structure.Structure;
032
033/**
034 * This class contains methods for obtaining and converting secondary structure
035 * information from BioJava {@link Structure}s.
036 *
037 * @author Aleix Lafita
038 * @since 4.1.1
039 *
040 */
041public class SecStrucTools {
042
043        /**
044         * Obtain the List of secondary structure information (SecStrucInfo) of a
045         * Structure.
046         *
047         * @param s
048         *            Structure with SS assignments
049         * @return List of SecStrucInfo objects
050         */
051        public static List<SecStrucInfo> getSecStrucInfo(Structure s) {
052
053                List<SecStrucInfo> listSSI = new ArrayList<SecStrucInfo>();
054                GroupIterator iter = new GroupIterator(s);
055
056                while (iter.hasNext()) {
057                        Group g = iter.next();
058                        if (g.hasAminoAtoms()) {
059                                Object p = g.getProperty(Group.SEC_STRUC);
060                                if (!(p == null)) {
061                                        SecStrucInfo ss = (SecStrucInfo) p;
062                                        listSSI.add(ss);
063                                }
064                        }
065                }
066
067                return listSSI;
068        }
069
070        /**
071         * Obtain the List of secondary structure elements (SecStrucElement) of a
072         * Structure.
073         *
074         * @param s
075         *            Structure with SS assignments
076         * @return List of SecStrucElement objects
077         */
078        public static List<SecStrucElement> getSecStrucElements(Structure s) {
079
080                List<SecStrucElement> listSSE = new ArrayList<SecStrucElement>();
081                GroupIterator iter = new GroupIterator(s);
082
083                // SecStruc information - initialize
084                SecStrucType type = SecStrucType.coil;
085                ResidueNumber previous = new ResidueNumber();
086                ResidueNumber start = new ResidueNumber();
087                String chainId = "";
088                int count = 0; // counts the number of residues in SSE
089
090                // Create a map for the IDs of the SSE in the structure
091                Map<SecStrucType, Integer> ids = new TreeMap<SecStrucType, Integer>();
092                for (SecStrucType t : SecStrucType.values())
093                        ids.put(t, 1);
094
095                while (iter.hasNext()) {
096                        Group g = iter.next();
097
098                        if (g.hasAminoAtoms()) {
099                                Object p = g.getProperty(Group.SEC_STRUC);
100                                if (p == null)
101                                        continue;
102                                SecStrucInfo ss = (SecStrucInfo) p;
103
104                                if (count > 0) {
105                                        // If chain and type are equal increment counter
106                                        if (ss.type == type && chainId == g.getChainId()) {
107                                                previous = g.getResidueNumber();
108                                                count++;
109                                                continue;
110                                        } else {
111                                                // Save the current SSE if chain or type change
112                                                SecStrucElement sse = new SecStrucElement(type, start,
113                                                                previous, count, ids.get(type), chainId);
114                                                listSSE.add(sse);
115                                                ids.put(type, ids.get(type) + 1);
116                                                count = 0;
117
118                                                // Initialize a new SSE one
119                                                if (ss.type != SecStrucType.coil) {
120                                                        type = ss.type;
121                                                        start = g.getResidueNumber();
122                                                        previous = start;
123                                                        chainId = g.getChainId();
124                                                        count = 1;
125                                                }
126                                        }
127                                } else {
128                                        // This is for the first residue only
129                                        if (ss.type != SecStrucType.coil) {
130                                                type = ss.type;
131                                                start = g.getResidueNumber();
132                                                previous = start;
133                                                chainId = g.getChainId();
134                                                count = 1;
135                                        }
136                                }
137                        }
138                }
139                return listSSE;
140        }
141
142        /**
143         * Obtain the List of secondary structure elements (SecStrucElement) of a
144         * List of Groups (assumed to be sequential, this is, connected in the
145         * original Structure).
146         *
147         * @param groups
148         *            Structure with SS assignments
149         * @return List of SecStrucElement objects
150         */
151        public static List<SecStrucElement> getSecStrucElements(List<Group> groups) {
152
153                List<SecStrucElement> listSSE = new ArrayList<SecStrucElement>();
154
155                // SecStruc information - initialize
156                SecStrucType type = SecStrucType.coil;
157                ResidueNumber previous = new ResidueNumber();
158                ResidueNumber start = new ResidueNumber();
159                String chainId = "";
160                int count = 0; // counts the number of residues in SSE
161
162                // Create a map for the IDs of the SSE in the structure
163                Map<SecStrucType, Integer> ids = new TreeMap<SecStrucType, Integer>();
164                for (SecStrucType t : SecStrucType.values())
165                        ids.put(t, 1);
166
167                for (Group g : groups) {
168
169                        if (g.hasAminoAtoms()) {
170                                Object p = g.getProperty(Group.SEC_STRUC);
171                                if (p == null)
172                                        continue;
173                                SecStrucInfo ss = (SecStrucInfo) p;
174
175                                if (count > 0) {
176                                        // If chain and type are equal increment counter
177                                        if (ss.type == type && chainId == g.getChainId()) {
178                                                previous = g.getResidueNumber();
179                                                count++;
180                                                continue;
181                                        } else {
182                                                // Save the current SSE if chain or type change
183                                                SecStrucElement sse = new SecStrucElement(type, start,
184                                                                previous, count, ids.get(type), chainId);
185                                                listSSE.add(sse);
186                                                ids.put(type, ids.get(type) + 1);
187                                                count = 0;
188
189                                                // Initialize a new SSE one
190                                                if (ss.type != SecStrucType.coil) {
191                                                        type = ss.type;
192                                                        start = g.getResidueNumber();
193                                                        previous = start;
194                                                        chainId = g.getChainId();
195                                                        count = 1;
196                                                }
197                                        }
198                                } else {
199                                        // This is for the first residue only
200                                        if (ss.type != SecStrucType.coil) {
201                                                type = ss.type;
202                                                start = g.getResidueNumber();
203                                                previous = start;
204                                                chainId = g.getChainId();
205                                                count = 1;
206                                        }
207                                }
208                        }
209                }
210                return listSSE;
211        }
212}