1 package ext.edu.ucsf.rbvi.strucviz2;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.HashSet;
9 import java.util.TreeMap;
11 import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
14 * This class provides the implementation for the ChimeraModel, ChimeraChain,
15 * and ChimeraResidue objects
20 public class ChimeraModel implements ChimeraStructuralObject
23 private String name; // The name of this model
25 private ModelType type; // The type of the model
27 private int modelNumber; // The model number
29 private int subModelNumber; // The sub-model number
31 private Color modelColor = null; // The color of this model (from Chimera)
33 private Object userData = null; // User data associated with this model
35 private boolean selected = false; // The selected state of this model
37 private TreeMap<String, ChimeraChain> chainMap; // The list of chains
39 // private TreeMap<String, ChimeraResidue> residueMap; // The list of residues
40 private HashSet<ChimeraResidue> funcResidues; // List of functional residues
43 * Constructor to create a model
46 * the name of this model
51 * @param subModelNumber
52 * the sub-model number
54 public ChimeraModel(String name, ModelType type, int modelNumber,
59 this.modelNumber = modelNumber;
60 this.subModelNumber = subModelNumber;
62 this.chainMap = new TreeMap<String, ChimeraChain>();
63 this.funcResidues = new HashSet<ChimeraResidue>();
67 * Constructor to create a model from the Chimera input line
70 * Chimera input line from which to construct this model
72 // TODO: [Optional] How to distinguish between PDB and MODBASE?
73 // invoked when listing models: listm type molecule; lists level molecule
74 // line = model id #0 type Molecule name 1ert
75 public ChimeraModel(String inputLine)
77 this.name = ChimUtils.parseModelName(inputLine);
78 // TODO: [Optional] Write a separate method to get model type
79 if (name.startsWith("smiles"))
81 this.type = ModelType.SMILES;
85 this.type = ModelType.PDB_MODEL;
87 this.modelNumber = ChimUtils.parseModelNumber(inputLine)[0];
88 this.subModelNumber = ChimUtils.parseModelNumber(inputLine)[1];
90 this.chainMap = new TreeMap<String, ChimeraChain>();
91 this.funcResidues = new HashSet<ChimeraResidue>();
95 * Add a residue to this model
100 public void addResidue(ChimeraResidue residue)
102 residue.setChimeraModel(this);
103 // residueMap.put(residue.getIndex(), residue);
104 String chainId = residue.getChainId();
107 addResidue(chainId, residue);
111 addResidue("_", residue);
113 // Put it in our map so that we can return it in order
114 // residueMap.put(residue.getIndex(), residue);
118 * Add a residue to a chain in this model. If the chain associated with
119 * chainId doesn't exist, it will be created.
122 * to add the residue to
124 * to add to the chain
126 public void addResidue(String chainId, ChimeraResidue residue)
128 ChimeraChain chain = null;
129 if (!chainMap.containsKey(chainId))
131 chain = new ChimeraChain(this.modelNumber, this.subModelNumber,
133 chain.setChimeraModel(this);
134 chainMap.put(chainId, chain);
138 chain = chainMap.get(chainId);
140 chain.addResidue(residue);
144 * Get the ChimeraModel (required for ChimeraStructuralObject interface)
146 * @return ChimeraModel
149 public ChimeraModel getChimeraModel()
155 * Get the model color of this model
157 * @return model color of this model
159 public Color getModelColor()
161 return this.modelColor;
165 * Set the color of this model
168 * Color of this model
170 public void setModelColor(Color color)
172 this.modelColor = color;
176 * Return the name of this model
180 public String getModelName()
186 * Set the name of this model
191 public void setModelName(String name)
197 * Get the model number of this model
199 * @return integer model number
201 public int getModelNumber()
207 * Set the model number of this model
210 * integer model number
212 public void setModelNumber(int modelNumber)
214 this.modelNumber = modelNumber;
218 * Get the sub-model number of this model
220 * @return integer sub-model number
222 public int getSubModelNumber()
224 return subModelNumber;
228 * Set the sub-model number of this model
230 * @param subModelNumber
231 * integer model number
233 public void setSubModelNumber(int subModelNumber)
235 this.subModelNumber = subModelNumber;
238 public ModelType getModelType()
243 public void setModelType(ModelType type)
248 public HashSet<ChimeraResidue> getFuncResidues()
253 public void setFuncResidues(List<String> residues)
255 for (String residue : residues)
257 for (ChimeraChain chain : getChains())
259 if (residue.indexOf("-") > 0)
261 funcResidues.addAll(chain.getResidueRange(residue));
265 funcResidues.add(chain.getResidue(residue));
272 * Get the user data for this model
277 public Object getUserData()
283 * Set the user data for this model
286 * user data to associate with this model
289 public void setUserData(Object data)
291 this.userData = data;
295 * Return the selected state of this model
297 * @return the selected state
300 public boolean isSelected()
306 * Set the selected state of this model
309 * a boolean to set the selected state to
312 public void setSelected(boolean selected)
314 this.selected = selected;
318 * Return the chains in this model as a List
320 * @return the chains in this model as a list
323 public List<ChimeraStructuralObject> getChildren()
325 return new ArrayList<ChimeraStructuralObject>(chainMap.values());
329 * Return the chains in this model as a colleciton
331 * @return the chains in this model
333 public Collection<ChimeraChain> getChains()
335 return chainMap.values();
339 * Get the number of chains in this model
341 * @return integer chain count
343 public int getChainCount()
345 return chainMap.size();
349 * Get the list of chain names associated with this model
351 * @return return the list of chain names for this model
353 public Collection<String> getChainNames()
355 return chainMap.keySet();
359 * Get the residues associated with this model
361 * @return the list of residues in this model
363 public Collection<ChimeraResidue> getResidues()
365 Collection<ChimeraResidue> residues = new ArrayList<ChimeraResidue>();
366 for (ChimeraChain chain : getChains())
368 residues.addAll(chain.getResidues());
374 * Get the number of residues in this model
376 * @return integer residues count
378 public int getResidueCount()
381 for (ChimeraChain chain : getChains())
383 count += chain.getResidueCount();
389 * Get a specific chain from the model
392 * the ID of the chain to return
393 * @return ChimeraChain associated with the chain
395 public ChimeraChain getChain(String chain)
397 if (chainMap.containsKey(chain))
399 return chainMap.get(chain);
405 * Return a specific residue based on its index
408 * of the residue to return
409 * @return the residue associated with that index
411 public ChimeraResidue getResidue(String chainId, String index)
413 if (chainMap.containsKey(chainId))
415 return chainMap.get(chainId).getResidue(index);
421 * Checks if this model has selected children.
424 public boolean hasSelectedChildren()
432 for (ChimeraChain chain : getChains())
434 if (chain.hasSelectedChildren())
444 * Return the list of selected residues
446 * @return all selected residues
448 public List<ChimeraResidue> getSelectedResidues()
450 List<ChimeraResidue> residueList = new ArrayList<ChimeraResidue>();
451 for (ChimeraChain chain : getChains())
455 residueList.addAll(chain.getSelectedResidues());
459 residueList.addAll(getResidues());
466 * Return the Chimera specification for this model.
469 public String toSpec()
471 if (subModelNumber == 0)
473 return ("#" + modelNumber);
475 return ("#" + modelNumber + "." + subModelNumber);
479 * Return a string representation for the model. Shorten if longer than 100
483 public String toString()
485 String modelName = "";
486 // TODO: [Optional] Change cutoff for shortening model names in the
487 // structure naviagator dialog
488 if (getChainCount() > 0)
490 modelName = "Model " + toSpec() + " " + name + " (" + getChainCount()
491 + " chains, " + getResidueCount() + " residues)";
493 else if (getResidueCount() > 0)
495 modelName = "Model " + toSpec() + " " + name + " ("
496 + getResidueCount() + " residues)";
500 modelName = "Model " + toSpec() + " " + name + "";
503 Set<String> networkNames = new HashSet<String>();
504 Set<String> nodeNames = new HashSet<String>();
505 Set<String> edgeNames = new HashSet<String>();
507 String cytoName = " [";
508 if (networkNames.size() > 0)
510 if (networkNames.size() == 1)
512 cytoName += "Network {";
514 else if (networkNames.size() > 1)
516 cytoName += "Networks {";
518 for (String cName : networkNames)
520 cytoName += cName + ",";
522 cytoName = cytoName.substring(0, cytoName.length() - 1) + "}, ";
524 if (nodeNames.size() > 0)
526 if (nodeNames.size() == 1)
528 cytoName += "Node {";
530 else if (nodeNames.size() > 1)
532 cytoName += "Nodes {";
534 for (String cName : nodeNames)
536 cytoName += cName + ",";
538 cytoName = cytoName.substring(0, cytoName.length() - 1) + "}, ";
540 if (edgeNames.size() > 0)
542 if (edgeNames.size() == 1)
544 cytoName += "Edge {";
546 else if (edgeNames.size() > 1)
548 cytoName += "Edges {";
550 for (String cName : edgeNames)
552 cytoName += cName + ",";
554 cytoName = cytoName.substring(0, cytoName.length() - 1) + "}, ";
556 if (cytoName.endsWith(", "))
558 cytoName = cytoName.substring(0, cytoName.length() - 2);
561 String nodeName = modelName + cytoName;
562 if (nodeName.length() > 100)
564 nodeName = nodeName.substring(0, 100) + "...";
570 public boolean equals(Object otherChimeraModel)
572 if (!(otherChimeraModel instanceof ChimeraModel))
576 ChimeraModel otherCM = ((ChimeraModel) otherChimeraModel);
577 return this.name.equals(otherCM.name)
578 && this.modelNumber == otherCM.modelNumber
579 && this.type == otherCM.type;
583 public int hashCode()
586 hashCode = hashCode * 37 + this.name.hashCode();
587 hashCode = hashCode * 37 + this.type.hashCode();
588 hashCode = (hashCode * 37) + modelNumber;