JAL-3438 spotless for 2.11.2.0
[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   /**
51    * The model/subModel number this chain is a part of
52    */
53   private int modelNumber;
54
55   private int subModelNumber;
56
57   /**
58    * A pointer to the model this chain is a part of
59    */
60   private ChimeraModel chimeraModel;
61
62   /**
63    * The chainID (from the PDB record)
64    */
65   private String chainId;
66
67   /**
68    * The residues that are part of this chain
69    */
70   private TreeMap<String, ChimeraResidue> residueMap;
71
72   /**
73    * userData to associate with this chain
74    */
75   private Object userData;
76
77   /**
78    * Flag to indicate the selection state
79    */
80   private boolean selected = false;
81
82   /**
83    * Constructor to create a new ChimeraChain
84    * 
85    * @param model
86    *          the model number this chain is part of
87    * @param subModel
88    *          the subModel number this chain is part of
89    * @param chainId
90    *          the chain ID for this chain
91    */
92   public ChimeraChain(int model, int subModel, String chainId)
93   {
94     this.modelNumber = model;
95     this.subModelNumber = subModel;
96     this.chainId = chainId;
97     residueMap = new TreeMap<String, ChimeraResidue>();
98   }
99
100   /**
101    * set the selected state of this chain
102    * 
103    * @param selected
104    *          a boolean to set the selected state to
105    */
106   public void setSelected(boolean selected)
107   {
108     this.selected = selected;
109   }
110
111   /**
112    * return the selected state of this chain
113    * 
114    * @return the selected state
115    */
116   public boolean isSelected()
117   {
118     return selected;
119   }
120
121   public boolean hasSelectedChildren()
122   {
123     if (selected)
124     {
125       return true;
126     }
127     else
128     {
129       for (ChimeraResidue residue : getResidues())
130       {
131         if (residue.isSelected())
132           return true;
133       }
134     }
135     return false;
136   }
137
138   /**
139    * Return the list of selected residues
140    * 
141    * @return all selected residues
142    */
143   public List<ChimeraResidue> getSelectedResidues()
144   {
145     List<ChimeraResidue> residueList = new ArrayList<ChimeraResidue>();
146     if (selected)
147     {
148       residueList.addAll(getResidues());
149     }
150     else
151     {
152       for (ChimeraResidue residue : getResidues())
153       {
154         if (residue.isSelected())
155           residueList.add(residue);
156       }
157     }
158     return residueList;
159   }
160
161   /**
162    * Add a residue to the chain.
163    * 
164    * @param residue
165    *          the ChimeraResidue to add to the chain.
166    */
167   public void addResidue(ChimeraResidue residue)
168   {
169     String index = residue.getIndex();
170     // Put it in our map so that we can return it in order
171     residueMap.put(index, residue);
172   }
173
174   /**
175    * Return the list of residues in this chain in pdb residue order
176    * 
177    * @return a Collection of residues in residue order
178    */
179   public Collection<ChimeraResidue> getResidues()
180   {
181     return residueMap.values();
182   }
183
184   /**
185    * Return the list of residues in this chain as a list
186    * 
187    * @return List of residues
188    */
189   public List<ChimeraStructuralObject> getChildren()
190   {
191     return new ArrayList<ChimeraStructuralObject>(residueMap.values());
192   }
193
194   /**
195    * Get a specific residue
196    * 
197    * @param residueIndex
198    *          String representation of the residue index
199    * @return the ChimeraResidue represented by the residueIndex
200    */
201   public ChimeraResidue getResidue(String index)
202   {
203     // Integer index = Integer.valueOf(residueIndex);
204     if (residueMap.containsKey(index))
205       return residueMap.get(index);
206     return null;
207   }
208
209   /**
210    * Get a list of residues as a residue range
211    * 
212    * @param residueRange
213    *          String representation of the residue range
214    * @return the List of ChimeraResidues represented by the range
215    */
216   public List<ChimeraResidue> getResidueRange(String residueRange)
217   {
218     String[] range = residueRange.split("-", 2);
219     if (range[1] == null || range[1].length() == 0)
220     {
221       range[1] = range[0];
222     }
223     List<ChimeraResidue> resultRange = new ArrayList<ChimeraResidue>();
224     int start = Integer.parseInt(range[0]);
225     int end = Integer.parseInt(range[1]);
226     for (int i = start; i <= end; i++)
227     {
228       String index = String.valueOf(i);
229       if (residueMap.containsKey(index))
230         resultRange.add(residueMap.get(index));
231     }
232     return resultRange;
233   }
234
235   /**
236    * Get the ID for this chain
237    * 
238    * @return String value of the chainId
239    */
240   public String getChainId()
241   {
242     return chainId;
243   }
244
245   /**
246    * Get the model number for this chain
247    * 
248    * @return the model number
249    */
250   public int getModelNumber()
251   {
252     return modelNumber;
253   }
254
255   /**
256    * Get the sub-model number for this chain
257    * 
258    * @return the sub-model number
259    */
260   public int getSubModelNumber()
261   {
262     return subModelNumber;
263   }
264
265   /**
266    * Return a string representation of this chain as follows: Chain
267    * <i>chainId</i> (<i>residue_count</i> residues)
268    * 
269    * @return String representation of chain
270    */
271   public String displayName()
272   {
273     if (chainId.equals("_"))
274     {
275       return ("Chain (no ID) (" + getResidueCount() + " residues)");
276     }
277     else
278     {
279       return ("Chain " + chainId + " (" + getResidueCount() + " residues)");
280     }
281   }
282
283   /**
284    * Return a string representation of this chain as follows: Node xxx [Model
285    * yyyy Chain <i>chainId</i>]
286    * 
287    * @return String representation of chain
288    */
289   public String toString()
290   {
291     String displayName = chimeraModel.getModelName();
292     if (displayName.length() > 14)
293       displayName = displayName.substring(0, 13) + "...";
294     if (chainId.equals("_"))
295     {
296       return (displayName + " Chain (no ID) (" + getResidueCount()
297               + " residues)");
298     }
299     else
300     {
301       return (displayName + " Chain " + chainId + " (" + getResidueCount()
302               + " residues)");
303     }
304   }
305
306   /**
307    * Return the Chimera specification for this chain
308    * 
309    * @return Chimera specification
310    */
311   public String toSpec()
312   {
313     if (chainId.equals("_"))
314     {
315       return ("#" + modelNumber + "." + subModelNumber + ":.");
316     }
317     else
318     {
319       return ("#" + modelNumber + "." + subModelNumber + ":." + chainId);
320     }
321   }
322
323   /**
324    * Return the number of residues in this chain
325    * 
326    * @return integer number of residues
327    */
328   public int getResidueCount()
329   {
330     return residueMap.size();
331   }
332
333   /**
334    * Set the ChimeraModel for this chain
335    * 
336    * @param model
337    *          ChimeraModel to associate with this chain
338    */
339   public void setChimeraModel(ChimeraModel model)
340   {
341     this.chimeraModel = model;
342   }
343
344   /**
345    * Get the ChimeraModel for this chain
346    * 
347    * @return ChimeraModel associated with this chain
348    */
349   public ChimeraModel getChimeraModel()
350   {
351     return chimeraModel;
352   }
353
354   /**
355    * Get the user data for this Chain
356    * 
357    * @return user data
358    */
359   public Object getUserData()
360   {
361     return userData;
362   }
363
364   /**
365    * Set the user data for this Chain
366    * 
367    * @param data
368    *          the user data to associate with this chain
369    */
370   public void setUserData(Object data)
371   {
372     this.userData = data;
373   }
374 }