Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package ext.edu.ucsf.rbvi.strucviz2

File ChimUtils.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart0.png
56% of files have more coverage

Code metrics

180
356
24
1
1,043
774
149
0.42
14.83
24
6.21

Classes

Class Line # Actions
ChimUtils 46 356 149 560
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

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.awt.Color;
36    import java.util.ArrayList;
37    import java.util.HashMap;
38    import java.util.List;
39    import java.util.Map;
40   
41    import org.slf4j.Logger;
42    import org.slf4j.LoggerFactory;
43   
44    import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
45   
 
46    public abstract class ChimUtils
47    {
48   
49    private static Logger logger = LoggerFactory.getLogger(ChimUtils.class);
50   
51    static int MAX_SUB_MODELS = 1000;
52   
53    public static final HashMap<String, String> aaNames;
54   
55    public static String RESIDUE_ATTR = "ChimeraResidue";
56   
57    public static String RINALYZER_ATTR = "RINalyzerResidue";
58   
59    public static String DEFAULT_STRUCTURE_KEY = "pdbFileName";
60   
61    /**
62    * Parse the model number returned by Chimera and return the int value
63    */
64    // invoked by the ChimeraModel constructor
65    // line = model id #0 type Molecule name 1ert
 
66  0 toggle public static int[] parseModelNumber(String inputLine)
67    {
68  0 int hash = inputLine.indexOf('#');
69  0 int space = inputLine.indexOf(' ', hash);
70  0 int decimal = inputLine.substring(hash + 1, space).indexOf('.');
71    // model number is between hash+1 and space
72  0 int modelNumber = -1;
73  0 int subModelNumber = 0;
74  0 try
75    {
76  0 if (decimal > 0)
77    {
78  0 subModelNumber = Integer.parseInt(inputLine.substring(decimal
79    + hash + 2, space));
80  0 space = decimal + hash + 1;
81    }
82  0 modelNumber = Integer.parseInt(inputLine.substring(hash + 1, space));
83    } catch (Exception e)
84    {
85  0 logger.warn("Unexpected return from Chimera: " + inputLine, e);
86    }
87  0 return new int[] { modelNumber, subModelNumber };
88    }
89   
90    /**
91    * Parse the model number returned by Chimera and return the int value
92    */
93    // invoked by openModel in ChimeraManager
94    // line: #1, chain A: hiv-1 protease
95    // line: Model 0 (filename)
 
96  0 toggle public static int[] parseOpenedModelNumber(String inputLine)
97    {
98  0 int hash = inputLine.indexOf('#');
99  0 int space = -1;
100  0 if (hash == (-1))
101    {
102  0 hash = inputLine.indexOf("Model");
103  0 if (hash >= 0)
104    {
105  0 hash = hash + 5;
106    }
107  0 space = inputLine.indexOf(' ', hash + 1);
108    }
109    else
110    {
111  0 space = inputLine.indexOf(',', hash);
112    }
113   
114  0 int decimal = inputLine.substring(hash + 1, space).indexOf('.');
115    // model number is between hash+1 and space
116  0 int modelNumber = -1;
117  0 int subModelNumber = 0;
118  0 try
119    {
120  0 if (decimal > 0)
121    {
122  0 subModelNumber = Integer.parseInt(inputLine.substring(decimal
123    + hash + 2, space));
124  0 space = decimal + hash + 1;
125    }
126  0 modelNumber = Integer.parseInt(inputLine.substring(hash + 1, space));
127    } catch (Exception e)
128    {
129  0 logger.warn("Unexpected return from Chimera: " + inputLine, e);
130    }
131  0 return new int[] { modelNumber, subModelNumber };
132    }
133   
134    /**
135    * Parse the model identifier returned by Chimera and return the String value
136    */
137    // invoked by the ChimeraModel constructor
138    // line = model id #0 type Molecule name 1ert
 
139  0 toggle public static String parseModelName(String inputLine)
140    {
141  0 int start = inputLine.indexOf("name ");
142  0 if (start < 0)
143    {
144  0 return null;
145    }
146    // Might get a quoted string (don't understand why, but there you have it)
147  0 if (inputLine.startsWith("\"", start + 5))
148    {
149  0 start += 6; // Skip over the first quote
150  0 int end = inputLine.lastIndexOf('"');
151  0 if (end >= 1)
152    {
153  0 return inputLine.substring(start, end);
154    }
155    else
156    {
157  0 return inputLine.substring(start);
158    }
159    }
160    else
161    {
162  0 return inputLine.substring(start + 5);
163    }
164    }
165   
 
166  0 toggle public static Color parseModelColor(String inputLine)
167    {
168  0 try
169    {
170  0 int colorStart = inputLine.indexOf("color ");
171  0 String colorString = inputLine.substring(colorStart + 6);
172  0 String[] rgbStrings = colorString.split(",");
173  0 float[] rgbValues = new float[4];
174  0 for (int i = 0; i < rgbStrings.length; i++)
175    {
176  0 Float f = new Float(rgbStrings[i]);
177  0 rgbValues[i] = f.floatValue();
178    }
179  0 if (rgbStrings.length == 4)
180    {
181  0 return new Color(rgbValues[0], rgbValues[1], rgbValues[2],
182    rgbValues[3]);
183    }
184    else
185    {
186  0 return new Color(rgbValues[0], rgbValues[1], rgbValues[2]);
187    }
188    } catch (Exception ex)
189    {
190  0 logger.warn("Unexpected return from Chimera: " + inputLine, ex);
191    }
192  0 return Color.white;
193    }
194   
195    /**
196    * Create the key to use for forming the model/submodel key into the modelHash
197    *
198    * @param model
199    * the model number
200    * @param subModel
201    * the submodel number
202    * @return the model key as an Integer
203    */
 
204  0 toggle public static Integer makeModelKey(int model, int subModel)
205    {
206  0 return new Integer(model * MAX_SUB_MODELS + subModel);
207    }
208   
209    // invoked by the getResdiue (parseConnectivityReplies in
210    // CreateStructureNetworkTask)
211    // atomSpec = #0:1.A or #1:96.B@N
 
212  0 toggle public static ChimeraModel getModel(String atomSpec,
213    ChimeraManager chimeraManager)
214    {
215    // System.out.println("getting model for "+atomSpec);
216  0 String[] split = atomSpec.split(":");
217    // No model specified....
218  0 if (split[0].length() == 0)
219    {
220  0 logger.info("Unexpected return from Chimera: " + atomSpec);
221  0 return null;
222    }
223    // System.out.println("model = "+split[0].substring(1));
224  0 int model = 0;
225  0 int submodel = 0;
226  0 try
227    {
228  0 String[] subSplit = split[0].substring(1).split("\\.");
229  0 if (subSplit.length > 0)
230    {
231  0 model = Integer.parseInt(subSplit[0]);
232    }
233    else
234    {
235  0 model = Integer.parseInt(split[0].substring(1));
236    }
237   
238  0 if (subSplit.length > 1)
239    {
240  0 submodel = Integer.parseInt(subSplit[1]);
241    }
242    } catch (Exception e)
243    {
244    // ignore
245  0 logger.warn("Unexpected return from Chimera: " + atomSpec, e);
246    }
247  0 return chimeraManager.getChimeraModel(model, submodel);
248    }
249   
250    // invoked by the parseConnectivityReplies in CreateStructureNetworkTask
251    // atomSpec = #0:1.A or #1:96.B@N
 
252  0 toggle public static ChimeraResidue getResidue(String atomSpec,
253    ChimeraManager chimeraManager)
254    {
255    // System.out.println("Getting residue from: "+atomSpec);
256  0 ChimeraModel model = getModel(atomSpec, chimeraManager); // Get the model
257  0 if (model == null)
258    {
259  0 model = chimeraManager.getChimeraModel();
260    }
261  0 return getResidue(atomSpec, model);
262    }
263   
264    // invoked by the getResdiue (parseConnectivityReplies in
265    // CreateStructureNetworkTask)
266    // atomSpec = #0:1.A or #1:96.B@N
 
267  0 toggle public static ChimeraResidue getResidue(String atomSpec,
268    ChimeraModel model)
269    {
270    // System.out.println("Getting residue from: "+atomSpec);
271  0 String[] split = atomSpec.split(":|@");
272   
273    // Split into residue and chain
274  0 String[] residueChain = split[1].split("\\.");
275   
276  0 if (residueChain[0].length() == 0)
277    {
278  0 logger.info("Unexpected return from Chimera: " + atomSpec);
279  0 return null;
280    }
281   
282  0 if (residueChain.length == 2 && residueChain[1].length() > 0)
283    {
284  0 ChimeraChain chain = model.getChain(residueChain[1]);
285  0 return chain.getResidue(residueChain[0]);
286    }
287  0 return model.getResidue("_", residueChain[0]);
288    }
289   
 
290  0 toggle public static ChimeraChain getChain(String atomSpec, ChimeraModel model)
291    {
292  0 String[] split = atomSpec.split(":|@");
293   
294    // Split into residue and chain
295  0 String[] residueChain = split[1].split("\\.");
296  0 if (residueChain.length == 1)
297    {
298  0 logger.info("Unexpected return from Chimera: " + atomSpec);
299  0 return null;
300    }
301  0 return model.getChain(residueChain[1]);
302    }
303   
 
304  0 toggle public static String getAtomName(String atomSpec)
305    {
306  0 String[] split = atomSpec.split("@");
307  0 if (split.length > 1)
308    {
309  0 return split[1];
310    }
311  0 return atomSpec;
312    }
313   
 
314  0 toggle public static boolean isBackbone(String atom)
315    {
316  0 if (atom.equals("C") || atom.equals("CA") || atom.equals("N")
317    || atom.equals("O") || atom.equals("H"))
318    {
319  0 return true;
320    }
321  0 return false;
322    }
323   
 
324  0 toggle public static String getIntSubtype(String node, String atom)
325    {
326  0 String[] split = node.split("#| ");
327  0 String resType = "";
328  0 if (split.length == 2)
329    {
330  0 resType = split[0].trim().toUpperCase();
331    }
332  0 else if (split.length == 3)
333    {
334  0 resType = split[1].trim().toUpperCase();
335    }
336  0 if (resType.equalsIgnoreCase("HOH") || resType.equalsIgnoreCase("WAT"))
337    {
338  0 return "water";
339    }
340  0 else if (aaNames.containsKey(resType))
341    {
342  0 if (atom.equals("C") || atom.equals("CA") || atom.equals("N")
343    || atom.equals("O") || atom.equals("H"))
344    {
345  0 return "mc";
346    }
347    else
348    {
349  0 return "sc";
350    }
351    }
352    else
353    {
354  0 return "other";
355    }
356    }
357   
 
358  0 toggle public static String[] getResKeyParts(String resKey)
359    {
360    // [pdbID[.modelNo]#][residueID][.chainID]
361    // pdbID := 4-character code | "URL" | "path"
362  0 String[] resKeyParts = new String[4];
363  0 String[] split = resKey.split("#");
364  0 String resChain = null;
365    // if no "#" then it is either only a pdb id or a residue or a chain
366  0 if (split.length == 1)
367    {
368    // pdb id without model
369  0 if (resKey.length() == 4 && resKey.indexOf("\\.") < 0)
370    {
371  0 parseModelID(resKey, resKeyParts);
372    }
373    // pdb link or file
374  0 else if (resKey.startsWith("\""))
375    {
376  0 parseModelID(resKey, resKeyParts);
377    }
378    // chain and residue or model and number
379    else
380    {
381  0 String[] splitSplit = resKey.split("\\.");
382  0 if (splitSplit.length == 1)
383    {
384    // only a chain or a residue
385  0 resChain = resKey;
386    }
387    else
388    {
389  0 try
390    {
391    // pdb with a model
392  0 Integer.parseInt(splitSplit[1]);
393  0 parseModelID(resKey, resKeyParts);
394    } catch (NumberFormatException ex)
395    {
396    // residue and chain
397  0 resChain = resKey;
398    }
399    }
400    }
401    }
402  0 else if (split.length == 2)
403    {
404    // model and residue+chain
405  0 parseModelID(split[0], resKeyParts);
406  0 resChain = split[1];
407    }
408    else
409    {
410    // model string with "#"
411    // TODO: [Optional] Are there more possibilities?
412  0 parseModelID(resKey.substring(0, resKey.lastIndexOf("#")),
413    resKeyParts);
414  0 resChain = resKey.substring(resKey.lastIndexOf("#") + 1,
415    resKey.length());
416    }
417  0 if (resChain != null)
418    {
419    // System.out.println(resChain);
420  0 String[] resChainSplit = resChain.split("\\.");
421  0 if (resChainSplit.length == 1)
422    {
423    // TODO: [Optional] Find a better way to distinguish between chain and
424    // residue
425    // if only one character and not an int, probably a chain
426  0 if (resChainSplit[0].length() == 1)
427    {
428  0 try
429    {
430  0 Integer.parseInt(resChainSplit[0]);
431  0 resKeyParts[3] = resChainSplit[0];
432    } catch (NumberFormatException ex)
433    {
434  0 resKeyParts[2] = resChainSplit[0];
435    }
436    }
437    else
438    {
439  0 resKeyParts[3] = resChainSplit[0];
440    }
441    }
442  0 else if (resChainSplit.length == 2)
443    {
444  0 resKeyParts[2] = resChainSplit[0];
445  0 resKeyParts[3] = resChainSplit[1];
446    }
447    else
448    {
449    // too many dots?
450  0 logger.info("Could not parse residue identifier: " + resKey);
451    }
452    }
453    // String print = "";
454    // for (int i = 0; i < resKeyParts.length; i++) {
455    // if (resKeyParts[i] == null) {
456    // print += i + ": null\t";
457    // } else {
458    // print += i + ": " + resKeyParts[i] + ";";
459    // }
460    // }
461    // System.out.println(print);
462  0 return resKeyParts;
463    }
464   
 
465  0 toggle public static void parseModelID(String modelID, String[] resKeyParts)
466    {
467  0 if (modelID.startsWith("\""))
468    {
469  0 if (modelID.endsWith("\""))
470    {
471  0 resKeyParts[0] = modelID.substring(1, modelID.length() - 1);
472  0 return;
473    }
474    else
475    {
476  0 try
477    {
478  0 Integer.parseInt(modelID.substring(modelID.lastIndexOf("\"") + 2,
479    modelID.length()));
480  0 resKeyParts[0] = modelID.substring(0,
481    modelID.lastIndexOf("\"") - 1);
482  0 resKeyParts[1] = modelID.substring(modelID.lastIndexOf("\"") + 2,
483    modelID.length());
484    } catch (NumberFormatException ex)
485    {
486  0 resKeyParts[0] = modelID.substring(1);
487    }
488    }
489    }
490    else
491    {
492  0 String[] modelIDNo = modelID.split("\\.");
493  0 if (modelIDNo.length == 1)
494    {
495  0 resKeyParts[0] = modelIDNo[0];
496    }
497  0 else if (modelIDNo.length == 2)
498    {
499  0 try
500    {
501  0 Integer.parseInt(modelIDNo[1]);
502  0 resKeyParts[0] = modelIDNo[0];
503  0 resKeyParts[1] = modelIDNo[1];
504    } catch (NumberFormatException ex)
505    {
506  0 resKeyParts[0] = modelID;
507    }
508    }
509    else
510    {
511    // length > 1, so we probably have a file name with "." in it
512  0 logger.info("Could not parse model identifier: " + modelID);
513  0 resKeyParts[0] = modelID;
514    }
515    }
516    }
517   
518    /**
519    * This method takes a Cytoscape attribute specification
520    * ([structure#][residue][.chainID]) and returns the lowest-level object
521    * referenced by the spec. For example, if the spec is "1tkk", this method
522    * will return a ChimeraModel. If the spec is ".A", it will return a
523    * ChimeraChain, etc.
524    *
525    * @param attrSpec
526    * the specification string
527    * @param chimeraManager
528    * the Chimera object we're currently using
529    * @return a ChimeraStructuralObject of the lowest type
530    */
 
531  0 toggle public static ChimeraStructuralObject fromAttributeOld(String attrSpec,
532    ChimeraManager chimeraManager)
533    {
534  0 if (attrSpec == null || attrSpec.indexOf(',') > 0
535    || attrSpec.indexOf('-') > 0)
536    {
537    // No support for either lists or ranges
538  0 logger.warn("No support for identifier: " + attrSpec);
539  0 return null;
540    }
541   
542  0 String residue = null;
543  0 String model = null;
544  0 String chain = null;
545   
546  0 ChimeraModel chimeraModel = null;
547  0 ChimeraChain chimeraChain = null;
548  0 ChimeraResidue chimeraResidue = null;
549   
550    // System.out.println("Getting object from attribute: "+attrSpec);
551  0 try
552    {
553  0 String[] split = attrSpec.split("#");
554  0 String resChain = null;
555  0 if (split.length == 1)
556    {
557    // no model
558  0 resChain = split[0];
559    }
560  0 else if (split.length == 2)
561    {
562    // model and rest
563  0 model = split[0];
564  0 resChain = split[1];
565    }
566    else
567    {
568    // model string with "#"
569  0 model = attrSpec.substring(0, attrSpec.lastIndexOf("#"));
570  0 resChain = attrSpec.substring(attrSpec.lastIndexOf("#") + 1,
571    attrSpec.length());
572    }
573  0 if (resChain != null)
574    {
575  0 String[] resChainSplit = resChain.split("\\.");
576  0 if (resChainSplit.length == 1)
577    {
578  0 residue = resChainSplit[0];
579    }
580  0 else if (resChainSplit.length == 2)
581    {
582  0 residue = resChainSplit[0];
583  0 chain = resChainSplit[1];
584    }
585    else
586    {
587    // too many dots?
588  0 logger.warn("No support for identifier: " + attrSpec);
589    }
590    }
591   
592    // if (split.length == 1) {
593    // // No model
594    // residue = split[0];
595    // } else if (split.length == 3) {
596    // // We have all three
597    // model = split[0];
598    // residue = split[1];
599    // chain = split[2];
600    // } else if (split.length == 2 && attrSpec.indexOf('#') > 0) {
601    // // Model and Residue
602    // model = split[0];
603    // residue = split[1];
604    // } else {
605    // // Residue and Chain
606    // residue = split[0];
607    // chain = split[1];
608    // }
609   
610    // System.out.println("model = " + model + " chain = " + chain +
611    // " residue = " + residue);
612  0 if (model != null)
613    {
614  0 List<ChimeraModel> models = chimeraManager.getChimeraModels(model,
615    ModelType.PDB_MODEL);
616  0 if (models.size() == 1)
617    {
618  0 chimeraModel = models.get(0);
619    }
620    else
621    {
622  0 try
623    {
624  0 chimeraModel = chimeraManager.getChimeraModel(
625    Integer.valueOf(model), 0);
626    } catch (NumberFormatException ex)
627    {
628    // ignore
629    }
630    }
631    }
632  0 if (chimeraModel == null)
633    {
634  0 chimeraModel = chimeraManager.getChimeraModel();
635    }
636    // System.out.println("ChimeraModel = " + chimeraModel);
637   
638  0 if (chain != null)
639    {
640  0 chimeraChain = chimeraModel.getChain(chain);
641    // System.out.println("ChimeraChain = " + chimeraChain);
642    }
643  0 if (residue != null)
644    {
645  0 if (chimeraChain != null)
646    {
647  0 chimeraResidue = chimeraChain.getResidue(residue);
648    }
649    else
650    {
651  0 chimeraResidue = chimeraModel.getResidue("_", residue);
652    }
653    // System.out.println("ChimeraResidue = " + chimeraResidue);
654    }
655   
656  0 if (chimeraResidue != null)
657    {
658  0 return chimeraResidue;
659    }
660   
661  0 if (chimeraChain != null)
662    {
663  0 return chimeraChain;
664    }
665   
666  0 if (chimeraModel != null)
667    {
668  0 return chimeraModel;
669    }
670   
671    } catch (Exception ex)
672    {
673  0 logger.warn("Could not parse residue identifier: " + attrSpec, ex);
674    }
675  0 return null;
676    }
677   
 
678  0 toggle public static ChimeraStructuralObject fromAttribute(String attrSpec,
679    ChimeraManager chimeraManager)
680    {
681    // TODO: Make sure it is OK to remove this: || attrSpec.indexOf('-') > 0
682  0 if (attrSpec == null || attrSpec.indexOf(',') > 0)
683    {
684    // No support for either lists or ranges
685    // System.out.println("No support for identifier: " + attrSpec);
686  0 logger.warn("No support for identifier: " + attrSpec);
687  0 return null;
688    }
689  0 String[] modelIDNoResChain = getResKeyParts(attrSpec);
690   
691  0 ChimeraModel chimeraModel = null;
692  0 ChimeraChain chimeraChain = null;
693  0 ChimeraResidue chimeraResidue = null;
694   
695    // System.out.println("Getting object from attribute: "+attrSpec);
696  0 try
697    {
698  0 if (modelIDNoResChain[0] != null)
699    {
700  0 String modelID = modelIDNoResChain[0];
701  0 List<ChimeraModel> models = chimeraManager.getChimeraModels(
702    modelID, ModelType.PDB_MODEL);
703  0 if (models.size() == 1)
704    { // usual case with only one model
705  0 chimeraModel = models.get(0);
706    }
707  0 else if (models.size() > 1 && modelIDNoResChain[1] != null)
708    {
709    // there are several submodels
710  0 try
711    {
712  0 int modelNo = Integer.valueOf(modelIDNoResChain[1]);
713  0 for (ChimeraModel model : models)
714    {
715  0 if (model.getSubModelNumber() == modelNo)
716    {
717  0 chimeraModel = model;
718  0 break;
719    }
720    }
721    } catch (NumberFormatException ex)
722    {
723    // ignore
724    }
725    }
726    else
727    {
728    // TODO: [Optional] What is this doing?
729  0 try
730    {
731  0 chimeraModel = chimeraManager.getChimeraModel(
732    Integer.valueOf(modelID), 0);
733    } catch (NumberFormatException ex)
734    {
735    // ignore
736    }
737    }
738    }
739  0 if (chimeraModel == null)
740    {
741    // TODO: [Optional] Find a better way to handle this case
742    // If no model can be matched, continue
743    // System.out.println("No matching model could be find for " +
744    // attrSpec);
745  0 return null;
746    // chimeraModel = chimeraManager.getChimeraModel();
747    // logger.warn("No matching model could be find for " + attrSpec +
748    // ". Trying with "
749    // + chimeraModel.toSpec());
750    }
751    // System.out.println("ChimeraModel = " + chimeraModel);
752   
753  0 if (modelIDNoResChain[3] != null)
754    {
755  0 chimeraChain = chimeraModel.getChain(modelIDNoResChain[3]);
756    // System.out.println("ChimeraChain = " + chimeraChain);
757    }
758  0 if (modelIDNoResChain[2] != null)
759    {
760  0 String residue = modelIDNoResChain[2];
761  0 if (chimeraChain != null)
762    {
763  0 chimeraResidue = chimeraChain.getResidue(residue);
764    }
765  0 else if (chimeraModel.getChain("_") != null)
766    {
767  0 chimeraResidue = chimeraModel.getResidue("_", residue);
768    }
769  0 else if (chimeraModel.getChainCount() == 1)
770    {
771  0 chimeraResidue = chimeraModel.getResidue(chimeraModel
772    .getChainNames().iterator().next(), residue);
773    }
774    // System.out.println("ChimeraResidue = " + chimeraResidue);
775    }
776   
777  0 if (chimeraResidue != null)
778    {
779  0 return chimeraResidue;
780    }
781   
782  0 if (chimeraChain != null)
783    {
784  0 return chimeraChain;
785    }
786   
787  0 if (chimeraModel != null)
788    {
789  0 return chimeraModel;
790    }
791   
792    } catch (Exception ex)
793    {
794    // System.out.println("Could not parse chimera identifier: " +
795    // attrSpec+"("+ex.getMessage()+")");
796  0 logger.warn("Could not parse chimera identifier: " + attrSpec, ex);
797    }
798  0 return null;
799    }
800   
801    /**
802    * Search for structure references in the residue list
803    *
804    * @param residueList
805    * the list of residues
806    * @return a concatenated list of structures encoded in the list
807    */
 
808  0 toggle public static String findStructures(String residueList)
809    {
810  0 if (residueList == null)
811    {
812  0 return null;
813    }
814  0 String[] residues = residueList.split(",");
815  0 Map<String, String> structureNameMap = new HashMap<String, String>();
816  0 for (int i = 0; i < residues.length; i++)
817    {
818  0 String[] components = residues[i].split("#");
819  0 if (components.length > 1)
820    {
821  0 structureNameMap.put(components[0], components[1]);
822    }
823    }
824  0 if (structureNameMap.isEmpty())
825    {
826  0 return null;
827    }
828   
829  0 String structure = null;
830  0 for (String struct : structureNameMap.keySet())
831    {
832  0 if (structure == null)
833    {
834  0 structure = new String();
835    }
836    else
837    {
838  0 structure = structure.concat(",");
839    }
840  0 structure = structure.concat(struct);
841    }
842  0 return structure;
843    }
844   
845    // invoked by openStructures in StructureManager
 
846  0 toggle public static List<String> parseFuncRes(List<String> residueNames,
847    String modelName)
848    {
849  0 List<String> resRanges = new ArrayList<String>();
850  0 for (int i = 0; i < residueNames.size(); i++)
851    {
852  0 String residue = residueNames.get(i);
853    // Parse out the structure, if there is one
854  0 String[] components = residue.split("#");
855  0 if (components.length > 1 && !modelName.equals(components[0]))
856    {
857  0 continue;
858    }
859  0 else if (components.length > 1)
860    {
861  0 residue = components[1];
862    }
863  0 else if (components.length == 1)
864    {
865  0 residue = components[0];
866    }
867    // Check to see if we have a range-spec
868  0 String resRange = "";
869  0 if (residue == null || residue.equals("") || residue.length() == 0)
870    {
871  0 continue;
872    }
873  0 String[] range = residue.split("-", 2);
874  0 String chain = null;
875  0 for (int res = 0; res < range.length; res++)
876    {
877  0 if (res == 1)
878    {
879  0 resRange = resRange.concat("-");
880  0 if (chain != null && range[res].indexOf('.') == -1)
881    {
882  0 range[res] = range[res].concat("." + chain);
883    }
884    }
885   
886  0 if (res == 0 && range.length >= 2 && range[res].indexOf('.') > 0)
887    {
888    // This is a range spec with the leading residue containing a chain
889    // spec
890  0 String[] resChain = range[res].split("\\.");
891  0 chain = resChain[1];
892  0 range[res] = resChain[0];
893    }
894    // Fix weird SFLD syntax...
895  0 if (range[res].indexOf('|') > 0
896    && Character.isDigit(range[res].charAt(0)))
897    {
898  0 int offset = range[res].indexOf('|');
899  0 String str = range[res].substring(offset + 1)
900    + range[res].substring(0, offset);
901  0 range[res] = str;
902    }
903   
904    // Convert to legal atom-spec
905  0 if (Character.isDigit(range[res].charAt(0)))
906    {
907  0 resRange = resRange.concat(range[res]);
908    }
909  0 else if (Character.isDigit(range[res].charAt(1)))
910    {
911  0 resRange = resRange.concat(range[res].substring(1));
912    }
913  0 else if (range[res].charAt(0) == '.')
914    {
915    // Do we have a chain spec?
916  0 resRange = resRange.concat(range[res]);
917    }
918    else
919    {
920  0 resRange = resRange.concat(range[res].substring(3));
921    }
922    }
923  0 if (!resRanges.contains(resRange))
924    {
925  0 resRanges.add(resRange);
926    }
927    }
928  0 return resRanges;
929    }
930   
 
931  0 toggle static
932    {
933  0 aaNames = new HashMap<String, String>();
934  0 aaNames.put("ALA", "A Ala Alanine N[C@@H](C)C(O)=O");
935  0 aaNames.put("ARG", "R Arg Arginine N[C@@H](CCCNC(N)=N)C(O)=O");
936  0 aaNames.put("ASN", "N Asn Asparagine N[C@@H](CC(N)=O)C(O)=O");
937  0 aaNames.put("ASP", "D Asp Aspartic_acid N[C@@H](CC(O)=O)C(O)=O");
938  0 aaNames.put("CYS", "C Cys Cysteine N[C@@H](CS)C(O)=O");
939  0 aaNames.put("GLN", "Q Gln Glutamine N[C@H](C(O)=O)CCC(N)=O");
940  0 aaNames.put("GLU", "E Glu Glumatic_acid N[C@H](C(O)=O)CCC(O)=O");
941  0 aaNames.put("GLY", "G Gly Glycine NCC(O)=O");
942  0 aaNames.put("HIS", "H His Histidine N[C@@H](CC1=CN=CN1)C(O)=O");
943  0 aaNames.put("ILE", "I Ile Isoleucine N[C@]([C@H](C)CC)([H])C(O)=O");
944  0 aaNames.put("LEU", "L Leu Leucine N[C@](CC(C)C)([H])C(O)=O");
945  0 aaNames.put("LYS", "K Lys Lysine N[C@](CCCCN)([H])C(O)=O");
946  0 aaNames.put("DLY", "K Dly D-Lysine NCCCC[C@@H](N)C(O)=O");
947  0 aaNames.put("MET", "M Met Methionine N[C@](CCSC)([H])C(O)=O");
948  0 aaNames.put("PHE", "F Phe Phenylalanine N[C@](CC1=CC=CC=C1)([H])C(O)=O");
949  0 aaNames.put("PRO", "P Pro Proline OC([C@@]1([H])NCCC1)=O");
950  0 aaNames.put("SER", "S Ser Serine OC[C@](C(O)=O)([H])N");
951  0 aaNames.put("THR", "T Thr Threonine O[C@H](C)[C@](C(O)=O)([H])N");
952  0 aaNames.put("TRP",
953    "W Trp Tryptophan N[C@@]([H])(CC1=CN([H])C2=C1C=CC=C2)C(O)=O");
954  0 aaNames.put("TYR", "Y Tyr Tyrosine N[C@@](C(O)=O)([H])CC1=CC=C(O)C=C1");
955  0 aaNames.put("VAL", "V Val Valine N[C@@](C(O)=O)([H])C(C)C");
956  0 aaNames.put("ASX", "B Asx Aspartic_acid_or_Asparagine");
957  0 aaNames.put("GLX", "Z Glx Glutamine_or_Glutamic_acid");
958  0 aaNames.put("XAA", "X Xaa Any_or_unknown_amino_acid");
959  0 aaNames.put("HOH", "HOH HOH Water [H]O[H]");
960    }
961   
962    /**
963    * Convert the amino acid type to a full name
964    *
965    * @param aaType
966    * the residue type to convert
967    * @return the full name of the residue
968    */
 
969  0 toggle public static String toFullName(String aaType)
970    {
971  0 if (!aaNames.containsKey(aaType))
972    {
973  0 return aaType;
974    }
975  0 String[] ids = aaNames.get(aaType).split(" ");
976  0 return ids[2].replace('_', ' ');
977    }
978   
979    /**
980    * Convert the amino acid type to a single letter
981    *
982    * @param aaType
983    * the residue type to convert
984    * @return the single letter representation of the residue
985    */
 
986  0 toggle public static String toSingleLetter(String aaType)
987    {
988  0 if (!aaNames.containsKey(aaType))
989    {
990  0 return aaType;
991    }
992  0 String[] ids = aaNames.get(aaType).split(" ");
993  0 return ids[0];
994    }
995   
996    /**
997    * Convert the amino acid type to three letters
998    *
999    * @param aaType
1000    * the residue type to convert
1001    * @return the three letter representation of the residue
1002    */
 
1003  0 toggle public static String toThreeLetter(String aaType)
1004    {
1005  0 if (!aaNames.containsKey(aaType))
1006    {
1007  0 return aaType;
1008    }
1009  0 String[] ids = aaNames.get(aaType).split(" ");
1010  0 return ids[1];
1011    }
1012   
1013    /**
1014    * Convert the amino acid type to its SMILES string
1015    *
1016    * @param aaType
1017    * the residue type to convert
1018    * @return the SMILES representation of the residue
1019    */
 
1020  0 toggle public static String toSMILES(String aaType)
1021    {
1022  0 if (!aaNames.containsKey(aaType))
1023    {
1024  0 return null;
1025    }
1026  0 String[] ids = aaNames.get(aaType).split(" ");
1027  0 if (ids.length < 4)
1028    {
1029  0 return null;
1030    }
1031  0 return ids[3];
1032    }
1033   
 
1034  0 toggle public static String getAlignName(ChimeraStructuralObject chimObj)
1035    {
1036  0 String name = chimObj.getChimeraModel().toString();
1037  0 if (chimObj instanceof ChimeraChain)
1038    {
1039  0 name = ((ChimeraChain) chimObj).toString() + " [" + name + "]";
1040    }
1041  0 return name;
1042    }
1043    }