92193f2966b260f188af93d57587404685e1fb48
[jalview.git] / src / ext / edu / ucsf / rbvi / strucviz2 / ChimeraChain.java
1 /* vim: set ts=2: */
2 /**
3  * Copyright (c) 2006 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *   1. Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions, and the following disclaimer.
11  *   2. Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions, and the following
13  *      disclaimer in the documentation and/or other materials provided
14  *      with the distribution.
15  *   3. Redistributions must acknowledge that this software was
16  *      originally developed by the UCSF Computer Graphics Laboratory
17  *      under support by the NIH National Center for Research Resources,
18  *      grant P41-RR01081.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
33 package ext.edu.ucsf.rbvi.strucviz2;
34
35 import java.util.ArrayList;
36 import java.util.Collection;
37 import java.util.List;
38 import java.util.TreeMap;
39
40 /**
41  * This class provides the implementation for the ChimeraChain object
42  * 
43  * @author scooter
44  * 
45  */
46 // TODO: [Optional] Implement toAttr() method
47 public class ChimeraChain implements ChimeraStructuralObject {
48
49         /**
50          * The model/subModel number this chain is a part of
51          */
52         private int modelNumber;
53         private int subModelNumber;
54
55         /**
56          * A pointer to the model this chain is a part of
57          */
58         private ChimeraModel chimeraModel;
59
60         /**
61          * The chainID (from the PDB record)
62          */
63         private String chainId;
64
65         /**
66          * The residues that are part of this chain
67          */
68         private TreeMap<String, ChimeraResidue> residueMap;
69
70         /**
71          * userData to associate with this chain
72          */
73         private Object userData;
74
75         /**
76          * Flag to indicate the selection state
77          */
78         private boolean selected = false;
79
80         /**
81          * Constructor to create a new ChimeraChain
82          * 
83          * @param model
84          *          the model number this chain is part of
85          * @param subModel
86          *          the subModel number this chain is part of
87          * @param chainId
88          *          the chain ID for this chain
89          */
90         public ChimeraChain(int model, int subModel, String chainId) {
91                 this.modelNumber = model;
92                 this.subModelNumber = subModel;
93                 this.chainId = chainId;
94                 residueMap = new TreeMap<String, ChimeraResidue>();
95         }
96
97         /**
98          * set the selected state of this chain
99          * 
100          * @param selected
101          *          a boolean to set the selected state to
102          */
103         public void setSelected(boolean selected) {
104                 this.selected = selected;
105         }
106
107         /**
108          * return the selected state of this chain
109          * 
110          * @return the selected state
111          */
112         public boolean isSelected() {
113                 return selected;
114         }
115
116         public boolean hasSelectedChildren() {
117                 if (selected) {
118                         return true;
119                 } else {
120                         for (ChimeraResidue residue : getResidues()) {
121                                 if (residue.isSelected())
122                                         return true;
123                         }
124                 }
125                 return false;
126         }
127
128         /**
129          * Return the list of selected residues
130          * 
131          * @return all selected residues
132          */
133         public List<ChimeraResidue> getSelectedResidues() {
134                 List<ChimeraResidue> residueList = new ArrayList<ChimeraResidue>();
135                 if (selected) {
136                         residueList.addAll(getResidues());
137                 } else {
138                         for (ChimeraResidue residue : getResidues()) {
139                                 if (residue.isSelected())
140                                         residueList.add(residue);
141                         }
142                 }
143                 return residueList;
144         }
145
146         /**
147          * Add a residue to the chain.
148          * 
149          * @param residue
150          *          the ChimeraResidue to add to the chain.
151          */
152         public void addResidue(ChimeraResidue residue) {
153                 String index = residue.getIndex();
154                 // Put it in our map so that we can return it in order
155                 residueMap.put(index, residue);
156         }
157
158         /**
159          * Return the list of residues in this chain in pdb residue order
160          * 
161          * @return a Collection of residues in residue order
162          */
163         public Collection<ChimeraResidue> getResidues() {
164                 return residueMap.values();
165         }
166
167         /**
168          * Return the list of residues in this chain as a list
169          * 
170          * @return List of residues
171          */
172         public List<ChimeraStructuralObject> getChildren() {
173                 return new ArrayList<ChimeraStructuralObject>(residueMap.values());
174         }
175
176         /**
177          * Get a specific residue
178          * 
179          * @param residueIndex
180          *          String representation of the residue index
181          * @return the ChimeraResidue represented by the residueIndex
182          */
183         public ChimeraResidue getResidue(String index) {
184                 // Integer index = new Integer(residueIndex);
185                 if (residueMap.containsKey(index))
186                         return residueMap.get(index);
187                 return null;
188         }
189
190         /**
191          * Get a list of residues as a residue range
192          * 
193          * @param residueRange
194          *          String representation of the residue range
195          * @return the List of ChimeraResidues represented by the range
196          */
197         public List<ChimeraResidue> getResidueRange(String residueRange) {
198                 String[] range = residueRange.split("-", 2);
199                 if (range[1] == null || range[1].length() == 0) {
200                         range[1] = range[0];
201                 }
202                 List<ChimeraResidue> resultRange = new ArrayList<ChimeraResidue>();
203                 int start = Integer.parseInt(range[0]);
204                 int end = Integer.parseInt(range[1]);
205                 for (int i = start; i <= end; i++) {
206                         String index = String.valueOf(i);
207                         if (residueMap.containsKey(index))
208                                 resultRange.add(residueMap.get(index));
209                 }
210                 return resultRange;
211         }
212
213         /**
214          * Get the ID for this chain
215          * 
216          * @return String value of the chainId
217          */
218         public String getChainId() {
219                 return chainId;
220         }
221
222         /**
223          * Get the model number for this chain
224          * 
225          * @return the model number
226          */
227         public int getModelNumber() {
228                 return modelNumber;
229         }
230
231         /**
232          * Get the sub-model number for this chain
233          * 
234          * @return the sub-model number
235          */
236         public int getSubModelNumber() {
237                 return subModelNumber;
238         }
239
240         /**
241          * Return a string representation of this chain as follows: Chain <i>chainId</i>
242          * (<i>residue_count</i> residues)
243          * 
244          * @return String representation of chain
245          */
246         public String displayName() {
247                 if (chainId.equals("_")) {
248                         return ("Chain (no ID) (" + getResidueCount() + " residues)");
249                 } else {
250                         return ("Chain " + chainId + " (" + getResidueCount() + " residues)");
251                 }
252         }
253
254         /**
255          * Return a string representation of this chain as follows: Node xxx [Model yyyy Chain
256          * <i>chainId</i>]
257          * 
258          * @return String representation of chain
259          */
260         public String toString() {
261                 String displayName = chimeraModel.getModelName();
262                 if (displayName.length() > 14)
263                         displayName = displayName.substring(0, 13) + "...";
264                 if (chainId.equals("_")) {
265                         return (displayName + " Chain (no ID) (" + getResidueCount() + " residues)");
266                 } else {
267                         return (displayName + " Chain " + chainId + " (" + getResidueCount() + " residues)");
268                 }
269         }
270
271         /**
272          * Return the Chimera specification for this chain
273          * 
274          * @return Chimera specification
275          */
276         public String toSpec() {
277                 if (chainId.equals("_")) {
278                         return ("#" + modelNumber + "." + subModelNumber + ":.");
279                 } else {
280                         return ("#" + modelNumber + "." + subModelNumber + ":." + chainId);
281                 }
282         }
283
284         /**
285          * Return the number of residues in this chain
286          * 
287          * @return integer number of residues
288          */
289         public int getResidueCount() {
290                 return residueMap.size();
291         }
292
293         /**
294          * Set the ChimeraModel for this chain
295          * 
296          * @param model
297          *          ChimeraModel to associate with this chain
298          */
299         public void setChimeraModel(ChimeraModel model) {
300                 this.chimeraModel = model;
301         }
302
303         /**
304          * Get the ChimeraModel for this chain
305          * 
306          * @return ChimeraModel associated with this chain
307          */
308         public ChimeraModel getChimeraModel() {
309                 return chimeraModel;
310         }
311
312         /**
313          * Get the user data for this Chain
314          * 
315          * @return user data
316          */
317         public Object getUserData() {
318                 return userData;
319         }
320
321         /**
322          * Set the user data for this Chain
323          * 
324          * @param data
325          *          the user data to associate with this chain
326          */
327         public void setUserData(Object data) {
328                 this.userData = data;
329         }
330 }