X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fext%2Fedu%2Fucsf%2Frbvi%2Fstrucviz2%2FChimUtils.java;h=03f51f7a5ddfb12a8f3cb4732006f4193f50188b;hb=4d7f98a6dd54d9863ba449ec79dcd95d25ed863d;hp=aedf657ed8fb143db7586ad45625590ce11fa644;hpb=619cc880371f3228e6a1fb33c6bfb6e7a7e2622c;p=jalview.git diff --git a/src/ext/edu/ucsf/rbvi/strucviz2/ChimUtils.java b/src/ext/edu/ucsf/rbvi/strucviz2/ChimUtils.java index aedf657..03f51f7 100644 --- a/src/ext/edu/ucsf/rbvi/strucviz2/ChimUtils.java +++ b/src/ext/edu/ucsf/rbvi/strucviz2/ChimUtils.java @@ -11,745 +11,941 @@ import org.slf4j.LoggerFactory; import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType; - -public abstract class ChimUtils { - - private static Logger logger = LoggerFactory - .getLogger(ChimUtils.class); - - static int MAX_SUB_MODELS = 1000; - - public static final HashMap aaNames; - - public static String RESIDUE_ATTR = "ChimeraResidue"; - public static String RINALYZER_ATTR = "RINalyzerResidue"; - public static String DEFAULT_STRUCTURE_KEY = "pdbFileName"; - - /** - * Parse the model number returned by Chimera and return the int value - */ - // invoked by the ChimeraModel constructor - // line = model id #0 type Molecule name 1ert - public static int[] parseModelNumber(String inputLine) { - int hash = inputLine.indexOf('#'); - int space = inputLine.indexOf(' ', hash); - int decimal = inputLine.substring(hash + 1, space).indexOf('.'); - // model number is between hash+1 and space - int modelNumber = -1; - int subModelNumber = 0; - try { - if (decimal > 0) { - subModelNumber = Integer.parseInt(inputLine.substring(decimal + hash + 2, space)); - space = decimal + hash + 1; - } - modelNumber = Integer.parseInt(inputLine.substring(hash + 1, space)); - } catch (Exception e) { - logger.warn("Unexpected return from Chimera: " + inputLine, e); - } - return new int[] { modelNumber, subModelNumber }; - } - - /** - * Parse the model number returned by Chimera and return the int value - */ - // invoked by openModel in ChimeraManager - // line: #1, chain A: hiv-1 protease - public static int[] parseOpenedModelNumber(String inputLine) { - int hash = inputLine.indexOf('#'); - int space = inputLine.indexOf(',', hash); - int decimal = inputLine.substring(hash + 1, space).indexOf('.'); - // model number is between hash+1 and space - int modelNumber = -1; - int subModelNumber = 0; - try { - if (decimal > 0) { - subModelNumber = Integer.parseInt(inputLine.substring(decimal + hash + 2, space)); - space = decimal + hash + 1; - } - modelNumber = Integer.parseInt(inputLine.substring(hash + 1, space)); - } catch (Exception e) { - logger.warn("Unexpected return from Chimera: " + inputLine, e); - } - return new int[] { modelNumber, subModelNumber }; - } - - /** - * Parse the model identifier returned by Chimera and return the String value - */ - // invoked by the ChimeraModel constructor - // line = model id #0 type Molecule name 1ert - public static String parseModelName(String inputLine) { - int start = inputLine.indexOf("name "); - if (start < 0) - return null; - // Might get a quoted string (don't understand why, but there you have it) - if (inputLine.startsWith("\"", start + 5)) { - start += 6; // Skip over the first quote - int end = inputLine.lastIndexOf('"'); - if (end >= 1) { - return inputLine.substring(start, end); - } else - return inputLine.substring(start); - } else { - return inputLine.substring(start + 5); - } - } - - public static Color parseModelColor(String inputLine) { - try { - int colorStart = inputLine.indexOf("color "); - String colorString = inputLine.substring(colorStart + 6); - String[] rgbStrings = colorString.split(","); - float[] rgbValues = new float[4]; - for (int i = 0; i < rgbStrings.length; i++) { - Float f = new Float(rgbStrings[i]); - rgbValues[i] = f.floatValue(); - } - if (rgbStrings.length == 4) { - return new Color(rgbValues[0], rgbValues[1], rgbValues[2], rgbValues[3]); - } else { - return new Color(rgbValues[0], rgbValues[1], rgbValues[2]); - } - } catch (Exception ex) { - logger.warn("Unexpected return from Chimera: " + inputLine, ex); - } - return Color.white; - } - - /** - * Create the key to use for forming the model/submodel key into the modelHash - * - * @param model - * the model number - * @param subModel - * the submodel number - * @return the model key as an Integer - */ - public static Integer makeModelKey(int model, int subModel) { - return new Integer(model * MAX_SUB_MODELS + subModel); - } - - // invoked by the getResdiue (parseConnectivityReplies in CreateStructureNetworkTask) - // atomSpec = #0:1.A or #1:96.B@N - public static ChimeraModel getModel(String atomSpec, ChimeraManager chimeraManager) { - // System.out.println("getting model for "+atomSpec); - String[] split = atomSpec.split(":"); - // No model specified.... - if (split[0].length() == 0) { - logger.info("Unexpected return from Chimera: " + atomSpec); - return null; - } - // System.out.println("model = "+split[0].substring(1)); - int model = 0; - int submodel = 0; - try { - String[] subSplit = split[0].substring(1).split("\\."); - if (subSplit.length > 0) - model = Integer.parseInt(subSplit[0]); - else - model = Integer.parseInt(split[0].substring(1)); - - if (subSplit.length > 1) - submodel = Integer.parseInt(subSplit[1]); - } catch (Exception e) { - // ignore - logger.warn("Unexpected return from Chimera: " + atomSpec, e); - } - return chimeraManager.getChimeraModel(model, submodel); - } - - // invoked by the parseConnectivityReplies in CreateStructureNetworkTask - // atomSpec = #0:1.A or #1:96.B@N - public static ChimeraResidue getResidue(String atomSpec, ChimeraManager chimeraManager) { - // System.out.println("Getting residue from: "+atomSpec); - ChimeraModel model = getModel(atomSpec, chimeraManager); // Get the model - if (model == null) { - model = chimeraManager.getChimeraModel(); - } - return getResidue(atomSpec, model); - } - - // invoked by the getResdiue (parseConnectivityReplies in CreateStructureNetworkTask) - // atomSpec = #0:1.A or #1:96.B@N - public static ChimeraResidue getResidue(String atomSpec, ChimeraModel model) { - // System.out.println("Getting residue from: "+atomSpec); - String[] split = atomSpec.split(":|@"); - - // Split into residue and chain - String[] residueChain = split[1].split("\\."); - - if (residueChain[0].length() == 0) { - logger.info("Unexpected return from Chimera: " + atomSpec); - return null; - } - - if (residueChain.length == 2 && residueChain[1].length() > 0) { - ChimeraChain chain = model.getChain(residueChain[1]); - return chain.getResidue(residueChain[0]); - } - return model.getResidue("_", residueChain[0]); - } - - public static ChimeraChain getChain(String atomSpec, ChimeraModel model) { - String[] split = atomSpec.split(":|@"); - - // Split into residue and chain - String[] residueChain = split[1].split("\\."); - if (residueChain.length == 1) { - logger.info("Unexpected return from Chimera: " + atomSpec); - return null; - } - return model.getChain(residueChain[1]); - } - - public static String getAtomName(String atomSpec) { - String[] split = atomSpec.split("@"); - if (split.length > 1) { - return split[1]; - } - return atomSpec; - } - - public static boolean isBackbone(String atom) { - if (atom.equals("C") || atom.equals("CA") || atom.equals("N") || atom.equals("O") - || atom.equals("H")) - return true; - return false; - } - - public static String getIntSubtype(String node, String atom) { - String[] split = node.split("#| "); - String resType = ""; - if (split.length == 2) { - resType = split[0].trim().toUpperCase(); - } else if (split.length == 3) { - resType = split[1].trim().toUpperCase(); - } - if (resType.equalsIgnoreCase("HOH") || resType.equalsIgnoreCase("WAT")) { - return "water"; - } else if (aaNames.containsKey(resType)) { - if (atom.equals("C") || atom.equals("CA") || atom.equals("N") || atom.equals("O") - || atom.equals("H")) { - return "mc"; - } else { - return "sc"; - } - } else { - return "other"; - } - } - - - public static String[] getResKeyParts(String resKey) { - // [pdbID[.modelNo]#][residueID][.chainID] - // pdbID := 4-character code | "URL" | "path" - String[] resKeyParts = new String[4]; - String[] split = resKey.split("#"); - String resChain = null; - // if no "#" then it is either only a pdb id or a residue or a chain - if (split.length == 1) { - // pdb id without model - if (resKey.length() == 4 && resKey.indexOf("\\.") < 0) { - parseModelID(resKey, resKeyParts); - } - // pdb link or file - else if (resKey.startsWith("\"")) { - parseModelID(resKey, resKeyParts); - } - // chain and residue or model and number - else { - String[] splitSplit = resKey.split("\\."); - if (splitSplit.length == 1) { - // only a chain or a residue - resChain = resKey; - } else { - try { - // pdb with a model - Integer.parseInt(splitSplit[1]); - parseModelID(resKey, resKeyParts); - } catch (NumberFormatException ex) { - // residue and chain - resChain = resKey; - } - } - } - } else if (split.length == 2) { - // model and residue+chain - parseModelID(split[0], resKeyParts); - resChain = split[1]; - } else { - // model string with "#" - // TODO: [Optional] Are there more possibilities? - parseModelID(resKey.substring(0, resKey.lastIndexOf("#")), resKeyParts); - resChain = resKey.substring(resKey.lastIndexOf("#") + 1, resKey.length()); - } - if (resChain != null) { - //System.out.println(resChain); - String[] resChainSplit = resChain.split("\\."); - if (resChainSplit.length == 1) { - // TODO: [Optional] Find a better way to distinguish between chain and residue - // if only one character and not an int, probably a chain - if (resChainSplit[0].length() == 1) { - try { - Integer.parseInt(resChainSplit[0]); - resKeyParts[3] = resChainSplit[0]; - } catch (NumberFormatException ex) { - resKeyParts[2] = resChainSplit[0]; - } - } else { - resKeyParts[3] = resChainSplit[0]; - } - } else if (resChainSplit.length == 2) { - resKeyParts[2] = resChainSplit[0]; - resKeyParts[3] = resChainSplit[1]; - } else { - // too many dots? - logger.info("Could not parse residue identifier: " + resKey); - } - } - // String print = ""; - // for (int i = 0; i < resKeyParts.length; i++) { - // if (resKeyParts[i] == null) { - // print += i + ": null\t"; - // } else { - // print += i + ": " + resKeyParts[i] + ";"; - // } - // } - // System.out.println(print); - return resKeyParts; - } - - public static void parseModelID(String modelID, String[] resKeyParts) { - if (modelID.startsWith("\"")) { - if (modelID.endsWith("\"")) { - resKeyParts[0] = modelID.substring(1, modelID.length() - 1); - return; - } else { - try { - Integer.parseInt(modelID.substring(modelID.lastIndexOf("\"") + 2, - modelID.length())); - resKeyParts[0] = modelID.substring(0, modelID.lastIndexOf("\"") - 1); - resKeyParts[1] = modelID.substring(modelID.lastIndexOf("\"") + 2, - modelID.length()); - } catch (NumberFormatException ex) { - resKeyParts[0] = modelID.substring(1); - } - } - } else { - String[] modelIDNo = modelID.split("\\."); - if (modelIDNo.length == 1) { - resKeyParts[0] = modelIDNo[0]; - } else if (modelIDNo.length == 2) { - try { - Integer.parseInt(modelIDNo[1]); - resKeyParts[0] = modelIDNo[0]; - resKeyParts[1] = modelIDNo[1]; - } catch (NumberFormatException ex) { - resKeyParts[0] = modelID; - } - } else { - logger.info("Could not parse model identifier: " + modelID); - } - } - } - - /** - * This method takes a Cytoscape attribute specification ([structure#][residue][.chainID]) and - * returns the lowest-level object referenced by the spec. For example, if the spec is "1tkk", - * this method will return a ChimeraModel. If the spec is ".A", it will return a ChimeraChain, - * etc. - * - * @param attrSpec - * the specification string - * @param chimeraManager - * the Chimera object we're currently using - * @return a ChimeraStructuralObject of the lowest type - */ - public static ChimeraStructuralObject fromAttributeOld(String attrSpec, - ChimeraManager chimeraManager) { - if (attrSpec == null || attrSpec.indexOf(',') > 0 || attrSpec.indexOf('-') > 0) { - // No support for either lists or ranges - logger.warn("No support for identifier: " + attrSpec); - return null; - } - - String residue = null; - String model = null; - String chain = null; - - ChimeraModel chimeraModel = null; - ChimeraChain chimeraChain = null; - ChimeraResidue chimeraResidue = null; - - // System.out.println("Getting object from attribute: "+attrSpec); - try { - String[] split = attrSpec.split("#"); - String resChain = null; - if (split.length == 1) { - // no model - resChain = split[0]; - } else if (split.length == 2) { - // model and rest - model = split[0]; - resChain = split[1]; - } else { - // model string with "#" - model = attrSpec.substring(0, attrSpec.lastIndexOf("#")); - resChain = attrSpec.substring(attrSpec.lastIndexOf("#") + 1, attrSpec.length()); - } - if (resChain != null) { - String[] resChainSplit = resChain.split("\\."); - if (resChainSplit.length == 1) { - residue = resChainSplit[0]; - } else if (resChainSplit.length == 2) { - residue = resChainSplit[0]; - chain = resChainSplit[1]; - } else { - // too many dots? - logger.warn("No support for identifier: " + attrSpec); - } - } - - // if (split.length == 1) { - // // No model - // residue = split[0]; - // } else if (split.length == 3) { - // // We have all three - // model = split[0]; - // residue = split[1]; - // chain = split[2]; - // } else if (split.length == 2 && attrSpec.indexOf('#') > 0) { - // // Model and Residue - // model = split[0]; - // residue = split[1]; - // } else { - // // Residue and Chain - // residue = split[0]; - // chain = split[1]; - // } - - // System.out.println("model = " + model + " chain = " + chain + " residue = " + - // residue); - if (model != null) { - List models = chimeraManager.getChimeraModels(model, - ModelType.PDB_MODEL); - if (models.size() == 1) { - chimeraModel = models.get(0); - } else { - try { - chimeraModel = chimeraManager.getChimeraModel(Integer.valueOf(model), 0); - } catch (NumberFormatException ex) { - // ignore - } - } - } - if (chimeraModel == null) { - chimeraModel = chimeraManager.getChimeraModel(); - } - // System.out.println("ChimeraModel = " + chimeraModel); - - if (chain != null) { - chimeraChain = chimeraModel.getChain(chain); - // System.out.println("ChimeraChain = " + chimeraChain); - } - if (residue != null) { - if (chimeraChain != null) { - chimeraResidue = chimeraChain.getResidue(residue); - } else { - chimeraResidue = chimeraModel.getResidue("_", residue); - } - // System.out.println("ChimeraResidue = " + chimeraResidue); - } - - if (chimeraResidue != null) - return chimeraResidue; - - if (chimeraChain != null) - return chimeraChain; - - if (chimeraModel != null) - return chimeraModel; - - } catch (Exception ex) { - logger.warn("Could not parse residue identifier: " + attrSpec, ex); - } - return null; - } - - public static ChimeraStructuralObject fromAttribute(String attrSpec, - ChimeraManager chimeraManager) { - // TODO: Make sure it is OK to remove this: || attrSpec.indexOf('-') > 0 - if (attrSpec == null || attrSpec.indexOf(',') > 0) { - // No support for either lists or ranges - // System.out.println("No support for identifier: " + attrSpec); - logger.warn("No support for identifier: " + attrSpec); - return null; - } - String[] modelIDNoResChain = getResKeyParts(attrSpec); - - ChimeraModel chimeraModel = null; - ChimeraChain chimeraChain = null; - ChimeraResidue chimeraResidue = null; - - // System.out.println("Getting object from attribute: "+attrSpec); - try { - if (modelIDNoResChain[0] != null) { - String modelID = modelIDNoResChain[0]; - List models = chimeraManager.getChimeraModels(modelID, - ModelType.PDB_MODEL); - if (models.size() == 1) { // usual case with only one model - chimeraModel = models.get(0); - } else if (models.size() > 1 && modelIDNoResChain[1] != null) { - // there are several submodels - try { - int modelNo = Integer.valueOf(modelIDNoResChain[1]); - for (ChimeraModel model : models) { - if (model.getSubModelNumber() == modelNo) { - chimeraModel = model; - break; - } - } - } catch (NumberFormatException ex) { - // ignore - } - } else { - // TODO: [Optional] What is this doing? - try { - chimeraModel = chimeraManager.getChimeraModel(Integer.valueOf(modelID), 0); - } catch (NumberFormatException ex) { - // ignore - } - } - } - if (chimeraModel == null) { - // TODO: [Optional] Find a better way to handle this case - // If no model can be matched, continue - // System.out.println("No matching model could be find for " + attrSpec); - return null; - // chimeraModel = chimeraManager.getChimeraModel(); - // logger.warn("No matching model could be find for " + attrSpec + ". Trying with " - // + chimeraModel.toSpec()); - } - // System.out.println("ChimeraModel = " + chimeraModel); - - if (modelIDNoResChain[3] != null) { - chimeraChain = chimeraModel.getChain(modelIDNoResChain[3]); - // System.out.println("ChimeraChain = " + chimeraChain); - } - if (modelIDNoResChain[2] != null) { - String residue = modelIDNoResChain[2]; - if (chimeraChain != null) { - chimeraResidue = chimeraChain.getResidue(residue); - } else if (chimeraModel.getChain("_") != null) { - chimeraResidue = chimeraModel.getResidue("_", residue); - } else if (chimeraModel.getChainCount() == 1) { - chimeraResidue = chimeraModel.getResidue(chimeraModel.getChainNames() - .iterator().next(), residue); - } - // System.out.println("ChimeraResidue = " + chimeraResidue); - } - - if (chimeraResidue != null) - return chimeraResidue; - - if (chimeraChain != null) - return chimeraChain; - - if (chimeraModel != null) - return chimeraModel; - - } catch (Exception ex) { - // System.out.println("Could not parse chimera identifier: " + - // attrSpec+"("+ex.getMessage()+")"); - logger.warn("Could not parse chimera identifier: " + attrSpec, ex); - } - return null; - } - - /** - * Search for structure references in the residue list - * - * @param residueList - * the list of residues - * @return a concatenated list of structures encoded in the list - */ - public static String findStructures(String residueList) { - if (residueList == null) - return null; - String[] residues = residueList.split(","); - Map structureNameMap = new HashMap(); - for (int i = 0; i < residues.length; i++) { - String[] components = residues[i].split("#"); - if (components.length > 1) { - structureNameMap.put(components[0], components[1]); - } - } - if (structureNameMap.isEmpty()) - return null; - - String structure = null; - for (String struct : structureNameMap.keySet()) { - if (structure == null) - structure = new String(); - else - structure = structure.concat(","); - structure = structure.concat(struct); - } - return structure; - } - - // invoked by openStructures in StructureManager - public static List parseFuncRes(List residueNames, String modelName) { - List resRanges = new ArrayList(); - for (int i = 0; i < residueNames.size(); i++) { - String residue = residueNames.get(i); - // Parse out the structure, if there is one - String[] components = residue.split("#"); - if (components.length > 1 && !modelName.equals(components[0])) { - continue; - } else if (components.length > 1) { - residue = components[1]; - } else if (components.length == 1) { - residue = components[0]; - } - // Check to see if we have a range-spec - String resRange = ""; - if (residue == null || residue.equals("") || residue.length() == 0) { - continue; - } - String[] range = residue.split("-", 2); - String chain = null; - for (int res = 0; res < range.length; res++) { - if (res == 1) { - resRange = resRange.concat("-"); - if (chain != null && range[res].indexOf('.') == -1) - range[res] = range[res].concat("." + chain); - } - - if (res == 0 && range.length >= 2 && range[res].indexOf('.') > 0) { - // This is a range spec with the leading residue containing a chain spec - String[] resChain = range[res].split("\\."); - chain = resChain[1]; - range[res] = resChain[0]; - } - // Fix weird SFLD syntax... - if (range[res].indexOf('|') > 0 && Character.isDigit(range[res].charAt(0))) { - int offset = range[res].indexOf('|'); - String str = range[res].substring(offset + 1) + range[res].substring(0, offset); - range[res] = str; - } - - // Convert to legal atom-spec - if (Character.isDigit(range[res].charAt(0))) { - resRange = resRange.concat(range[res]); - } else if (Character.isDigit(range[res].charAt(1))) { - resRange = resRange.concat(range[res].substring(1)); - } else if (range[res].charAt(0) == '.') { - // Do we have a chain spec? - resRange = resRange.concat(range[res]); - } else { - resRange = resRange.concat(range[res].substring(3)); - } - } - if (!resRanges.contains(resRange)) { - resRanges.add(resRange); - } - } - return resRanges; - } - - static { - aaNames = new HashMap(); - aaNames.put("ALA", "A Ala Alanine N[C@@H](C)C(O)=O"); - aaNames.put("ARG", "R Arg Arginine N[C@@H](CCCNC(N)=N)C(O)=O"); - aaNames.put("ASN", "N Asn Asparagine N[C@@H](CC(N)=O)C(O)=O"); - aaNames.put("ASP", "D Asp Aspartic_acid N[C@@H](CC(O)=O)C(O)=O"); - aaNames.put("CYS", "C Cys Cysteine N[C@@H](CS)C(O)=O"); - aaNames.put("GLN", "Q Gln Glutamine N[C@H](C(O)=O)CCC(N)=O"); - aaNames.put("GLU", "E Glu Glumatic_acid N[C@H](C(O)=O)CCC(O)=O"); - aaNames.put("GLY", "G Gly Glycine NCC(O)=O"); - aaNames.put("HIS", "H His Histidine N[C@@H](CC1=CN=CN1)C(O)=O"); - aaNames.put("ILE", "I Ile Isoleucine N[C@]([C@H](C)CC)([H])C(O)=O"); - aaNames.put("LEU", "L Leu Leucine N[C@](CC(C)C)([H])C(O)=O"); - aaNames.put("LYS", "K Lys Lysine N[C@](CCCCN)([H])C(O)=O"); - aaNames.put("DLY", "K Dly D-Lysine NCCCC[C@@H](N)C(O)=O"); - aaNames.put("MET", "M Met Methionine N[C@](CCSC)([H])C(O)=O"); - aaNames.put("PHE", "F Phe Phenylalanine N[C@](CC1=CC=CC=C1)([H])C(O)=O"); - aaNames.put("PRO", "P Pro Proline OC([C@@]1([H])NCCC1)=O"); - aaNames.put("SER", "S Ser Serine OC[C@](C(O)=O)([H])N"); - aaNames.put("THR", "T Thr Threonine O[C@H](C)[C@](C(O)=O)([H])N"); - aaNames.put("TRP", "W Trp Tryptophan N[C@@]([H])(CC1=CN([H])C2=C1C=CC=C2)C(O)=O"); - aaNames.put("TYR", "Y Tyr Tyrosine N[C@@](C(O)=O)([H])CC1=CC=C(O)C=C1"); - aaNames.put("VAL", "V Val Valine N[C@@](C(O)=O)([H])C(C)C"); - aaNames.put("ASX", "B Asx Aspartic_acid_or_Asparagine"); - aaNames.put("GLX", "Z Glx Glutamine_or_Glutamic_acid"); - aaNames.put("XAA", "X Xaa Any_or_unknown_amino_acid"); - aaNames.put("HOH", "HOH HOH Water [H]O[H]"); - } - - /** - * Convert the amino acid type to a full name - * - * @param aaType - * the residue type to convert - * @return the full name of the residue - */ - public static String toFullName(String aaType) { - if (!aaNames.containsKey(aaType)) - return aaType; - String[] ids = ((String) aaNames.get(aaType)).split(" "); - return ids[2].replace('_', ' '); - } - - /** - * Convert the amino acid type to a single letter - * - * @param aaType - * the residue type to convert - * @return the single letter representation of the residue - */ - public static String toSingleLetter(String aaType) { - if (!aaNames.containsKey(aaType)) - return aaType; - String[] ids = ((String) aaNames.get(aaType)).split(" "); - return ids[0]; - } - - /** - * Convert the amino acid type to three letters - * - * @param aaType - * the residue type to convert - * @return the three letter representation of the residue - */ - public static String toThreeLetter(String aaType) { - if (!aaNames.containsKey(aaType)) - return aaType; - String[] ids = ((String) aaNames.get(aaType)).split(" "); - return ids[1]; - } - - /** - * Convert the amino acid type to its SMILES string - * - * @param aaType - * the residue type to convert - * @return the SMILES representation of the residue - */ - public static String toSMILES(String aaType) { - if (!aaNames.containsKey(aaType)) - return null; - String[] ids = ((String) aaNames.get(aaType)).split(" "); - if (ids.length < 4) - return null; - return ids[3]; - } - - public static String getAlignName(ChimeraStructuralObject chimObj) { - String name = chimObj.getChimeraModel().toString(); - if (chimObj instanceof ChimeraChain) { - name = ((ChimeraChain) chimObj).toString() + " [" + name + "]"; - } - return name; - } +public abstract class ChimUtils +{ + + private static Logger logger = LoggerFactory.getLogger(ChimUtils.class); + + static int MAX_SUB_MODELS = 1000; + + public static final HashMap aaNames; + + public static String RESIDUE_ATTR = "ChimeraResidue"; + + public static String RINALYZER_ATTR = "RINalyzerResidue"; + + public static String DEFAULT_STRUCTURE_KEY = "pdbFileName"; + + /** + * Parse the model number returned by Chimera and return the int value + */ + // invoked by the ChimeraModel constructor + // line = model id #0 type Molecule name 1ert + public static int[] parseModelNumber(String inputLine) + { + int hash = inputLine.indexOf('#'); + int space = inputLine.indexOf(' ', hash); + int decimal = inputLine.substring(hash + 1, space).indexOf('.'); + // model number is between hash+1 and space + int modelNumber = -1; + int subModelNumber = 0; + try + { + if (decimal > 0) + { + subModelNumber = Integer.parseInt(inputLine.substring(decimal + + hash + 2, space)); + space = decimal + hash + 1; + } + modelNumber = Integer.parseInt(inputLine.substring(hash + 1, space)); + } catch (Exception e) + { + logger.warn("Unexpected return from Chimera: " + inputLine, e); + } + return new int[] { modelNumber, subModelNumber }; + } + + /** + * Parse the model number returned by Chimera and return the int value + */ + // invoked by openModel in ChimeraManager + // line: #1, chain A: hiv-1 protease + public static int[] parseOpenedModelNumber(String inputLine) + { + int hash = inputLine.indexOf('#'); + int space = inputLine.indexOf(',', hash); + int decimal = inputLine.substring(hash + 1, space).indexOf('.'); + // model number is between hash+1 and space + int modelNumber = -1; + int subModelNumber = 0; + try + { + if (decimal > 0) + { + subModelNumber = Integer.parseInt(inputLine.substring(decimal + + hash + 2, space)); + space = decimal + hash + 1; + } + modelNumber = Integer.parseInt(inputLine.substring(hash + 1, space)); + } catch (Exception e) + { + logger.warn("Unexpected return from Chimera: " + inputLine, e); + } + return new int[] { modelNumber, subModelNumber }; + } + + /** + * Parse the model identifier returned by Chimera and return the String value + */ + // invoked by the ChimeraModel constructor + // line = model id #0 type Molecule name 1ert + public static String parseModelName(String inputLine) + { + int start = inputLine.indexOf("name "); + if (start < 0) + return null; + // Might get a quoted string (don't understand why, but there you have it) + if (inputLine.startsWith("\"", start + 5)) + { + start += 6; // Skip over the first quote + int end = inputLine.lastIndexOf('"'); + if (end >= 1) + { + return inputLine.substring(start, end); + } + else + return inputLine.substring(start); + } + else + { + return inputLine.substring(start + 5); + } + } + + public static Color parseModelColor(String inputLine) + { + try + { + int colorStart = inputLine.indexOf("color "); + String colorString = inputLine.substring(colorStart + 6); + String[] rgbStrings = colorString.split(","); + float[] rgbValues = new float[4]; + for (int i = 0; i < rgbStrings.length; i++) + { + Float f = new Float(rgbStrings[i]); + rgbValues[i] = f.floatValue(); + } + if (rgbStrings.length == 4) + { + return new Color(rgbValues[0], rgbValues[1], rgbValues[2], + rgbValues[3]); + } + else + { + return new Color(rgbValues[0], rgbValues[1], rgbValues[2]); + } + } catch (Exception ex) + { + logger.warn("Unexpected return from Chimera: " + inputLine, ex); + } + return Color.white; + } + + /** + * Create the key to use for forming the model/submodel key into the modelHash + * + * @param model + * the model number + * @param subModel + * the submodel number + * @return the model key as an Integer + */ + public static Integer makeModelKey(int model, int subModel) + { + return new Integer(model * MAX_SUB_MODELS + subModel); + } + + // invoked by the getResdiue (parseConnectivityReplies in + // CreateStructureNetworkTask) + // atomSpec = #0:1.A or #1:96.B@N + public static ChimeraModel getModel(String atomSpec, + ChimeraManager chimeraManager) + { + // System.out.println("getting model for "+atomSpec); + String[] split = atomSpec.split(":"); + // No model specified.... + if (split[0].length() == 0) + { + logger.info("Unexpected return from Chimera: " + atomSpec); + return null; + } + // System.out.println("model = "+split[0].substring(1)); + int model = 0; + int submodel = 0; + try + { + String[] subSplit = split[0].substring(1).split("\\."); + if (subSplit.length > 0) + model = Integer.parseInt(subSplit[0]); + else + model = Integer.parseInt(split[0].substring(1)); + + if (subSplit.length > 1) + submodel = Integer.parseInt(subSplit[1]); + } catch (Exception e) + { + // ignore + logger.warn("Unexpected return from Chimera: " + atomSpec, e); + } + return chimeraManager.getChimeraModel(model, submodel); + } + + // invoked by the parseConnectivityReplies in CreateStructureNetworkTask + // atomSpec = #0:1.A or #1:96.B@N + public static ChimeraResidue getResidue(String atomSpec, + ChimeraManager chimeraManager) + { + // System.out.println("Getting residue from: "+atomSpec); + ChimeraModel model = getModel(atomSpec, chimeraManager); // Get the model + if (model == null) + { + model = chimeraManager.getChimeraModel(); + } + return getResidue(atomSpec, model); + } + + // invoked by the getResdiue (parseConnectivityReplies in + // CreateStructureNetworkTask) + // atomSpec = #0:1.A or #1:96.B@N + public static ChimeraResidue getResidue(String atomSpec, + ChimeraModel model) + { + // System.out.println("Getting residue from: "+atomSpec); + String[] split = atomSpec.split(":|@"); + + // Split into residue and chain + String[] residueChain = split[1].split("\\."); + + if (residueChain[0].length() == 0) + { + logger.info("Unexpected return from Chimera: " + atomSpec); + return null; + } + + if (residueChain.length == 2 && residueChain[1].length() > 0) + { + ChimeraChain chain = model.getChain(residueChain[1]); + return chain.getResidue(residueChain[0]); + } + return model.getResidue("_", residueChain[0]); + } + + public static ChimeraChain getChain(String atomSpec, ChimeraModel model) + { + String[] split = atomSpec.split(":|@"); + + // Split into residue and chain + String[] residueChain = split[1].split("\\."); + if (residueChain.length == 1) + { + logger.info("Unexpected return from Chimera: " + atomSpec); + return null; + } + return model.getChain(residueChain[1]); + } + + public static String getAtomName(String atomSpec) + { + String[] split = atomSpec.split("@"); + if (split.length > 1) + { + return split[1]; + } + return atomSpec; + } + + public static boolean isBackbone(String atom) + { + if (atom.equals("C") || atom.equals("CA") || atom.equals("N") + || atom.equals("O") || atom.equals("H")) + return true; + return false; + } + + public static String getIntSubtype(String node, String atom) + { + String[] split = node.split("#| "); + String resType = ""; + if (split.length == 2) + { + resType = split[0].trim().toUpperCase(); + } + else if (split.length == 3) + { + resType = split[1].trim().toUpperCase(); + } + if (resType.equalsIgnoreCase("HOH") || resType.equalsIgnoreCase("WAT")) + { + return "water"; + } + else if (aaNames.containsKey(resType)) + { + if (atom.equals("C") || atom.equals("CA") || atom.equals("N") + || atom.equals("O") || atom.equals("H")) + { + return "mc"; + } + else + { + return "sc"; + } + } + else + { + return "other"; + } + } + + public static String[] getResKeyParts(String resKey) + { + // [pdbID[.modelNo]#][residueID][.chainID] + // pdbID := 4-character code | "URL" | "path" + String[] resKeyParts = new String[4]; + String[] split = resKey.split("#"); + String resChain = null; + // if no "#" then it is either only a pdb id or a residue or a chain + if (split.length == 1) + { + // pdb id without model + if (resKey.length() == 4 && resKey.indexOf("\\.") < 0) + { + parseModelID(resKey, resKeyParts); + } + // pdb link or file + else if (resKey.startsWith("\"")) + { + parseModelID(resKey, resKeyParts); + } + // chain and residue or model and number + else + { + String[] splitSplit = resKey.split("\\."); + if (splitSplit.length == 1) + { + // only a chain or a residue + resChain = resKey; + } + else + { + try + { + // pdb with a model + Integer.parseInt(splitSplit[1]); + parseModelID(resKey, resKeyParts); + } catch (NumberFormatException ex) + { + // residue and chain + resChain = resKey; + } + } + } + } + else if (split.length == 2) + { + // model and residue+chain + parseModelID(split[0], resKeyParts); + resChain = split[1]; + } + else + { + // model string with "#" + // TODO: [Optional] Are there more possibilities? + parseModelID(resKey.substring(0, resKey.lastIndexOf("#")), + resKeyParts); + resChain = resKey.substring(resKey.lastIndexOf("#") + 1, + resKey.length()); + } + if (resChain != null) + { + // System.out.println(resChain); + String[] resChainSplit = resChain.split("\\."); + if (resChainSplit.length == 1) + { + // TODO: [Optional] Find a better way to distinguish between chain and + // residue + // if only one character and not an int, probably a chain + if (resChainSplit[0].length() == 1) + { + try + { + Integer.parseInt(resChainSplit[0]); + resKeyParts[3] = resChainSplit[0]; + } catch (NumberFormatException ex) + { + resKeyParts[2] = resChainSplit[0]; + } + } + else + { + resKeyParts[3] = resChainSplit[0]; + } + } + else if (resChainSplit.length == 2) + { + resKeyParts[2] = resChainSplit[0]; + resKeyParts[3] = resChainSplit[1]; + } + else + { + // too many dots? + logger.info("Could not parse residue identifier: " + resKey); + } + } + // String print = ""; + // for (int i = 0; i < resKeyParts.length; i++) { + // if (resKeyParts[i] == null) { + // print += i + ": null\t"; + // } else { + // print += i + ": " + resKeyParts[i] + ";"; + // } + // } + // System.out.println(print); + return resKeyParts; + } + + public static void parseModelID(String modelID, String[] resKeyParts) + { + if (modelID.startsWith("\"")) + { + if (modelID.endsWith("\"")) + { + resKeyParts[0] = modelID.substring(1, modelID.length() - 1); + return; + } + else + { + try + { + Integer.parseInt(modelID.substring(modelID.lastIndexOf("\"") + 2, + modelID.length())); + resKeyParts[0] = modelID.substring(0, + modelID.lastIndexOf("\"") - 1); + resKeyParts[1] = modelID.substring(modelID.lastIndexOf("\"") + 2, + modelID.length()); + } catch (NumberFormatException ex) + { + resKeyParts[0] = modelID.substring(1); + } + } + } + else + { + String[] modelIDNo = modelID.split("\\."); + if (modelIDNo.length == 1) + { + resKeyParts[0] = modelIDNo[0]; + } + else if (modelIDNo.length == 2) + { + try + { + Integer.parseInt(modelIDNo[1]); + resKeyParts[0] = modelIDNo[0]; + resKeyParts[1] = modelIDNo[1]; + } catch (NumberFormatException ex) + { + resKeyParts[0] = modelID; + } + } + else + { + logger.info("Could not parse model identifier: " + modelID); + } + } + } + + /** + * This method takes a Cytoscape attribute specification + * ([structure#][residue][.chainID]) and returns the lowest-level object + * referenced by the spec. For example, if the spec is "1tkk", this method + * will return a ChimeraModel. If the spec is ".A", it will return a + * ChimeraChain, etc. + * + * @param attrSpec + * the specification string + * @param chimeraManager + * the Chimera object we're currently using + * @return a ChimeraStructuralObject of the lowest type + */ + public static ChimeraStructuralObject fromAttributeOld(String attrSpec, + ChimeraManager chimeraManager) + { + if (attrSpec == null || attrSpec.indexOf(',') > 0 + || attrSpec.indexOf('-') > 0) + { + // No support for either lists or ranges + logger.warn("No support for identifier: " + attrSpec); + return null; + } + + String residue = null; + String model = null; + String chain = null; + + ChimeraModel chimeraModel = null; + ChimeraChain chimeraChain = null; + ChimeraResidue chimeraResidue = null; + + // System.out.println("Getting object from attribute: "+attrSpec); + try + { + String[] split = attrSpec.split("#"); + String resChain = null; + if (split.length == 1) + { + // no model + resChain = split[0]; + } + else if (split.length == 2) + { + // model and rest + model = split[0]; + resChain = split[1]; + } + else + { + // model string with "#" + model = attrSpec.substring(0, attrSpec.lastIndexOf("#")); + resChain = attrSpec.substring(attrSpec.lastIndexOf("#") + 1, + attrSpec.length()); + } + if (resChain != null) + { + String[] resChainSplit = resChain.split("\\."); + if (resChainSplit.length == 1) + { + residue = resChainSplit[0]; + } + else if (resChainSplit.length == 2) + { + residue = resChainSplit[0]; + chain = resChainSplit[1]; + } + else + { + // too many dots? + logger.warn("No support for identifier: " + attrSpec); + } + } + + // if (split.length == 1) { + // // No model + // residue = split[0]; + // } else if (split.length == 3) { + // // We have all three + // model = split[0]; + // residue = split[1]; + // chain = split[2]; + // } else if (split.length == 2 && attrSpec.indexOf('#') > 0) { + // // Model and Residue + // model = split[0]; + // residue = split[1]; + // } else { + // // Residue and Chain + // residue = split[0]; + // chain = split[1]; + // } + + // System.out.println("model = " + model + " chain = " + chain + + // " residue = " + + // residue); + if (model != null) + { + List models = chimeraManager.getChimeraModels(model, + ModelType.PDB_MODEL); + if (models.size() == 1) + { + chimeraModel = models.get(0); + } + else + { + try + { + chimeraModel = chimeraManager.getChimeraModel( + Integer.valueOf(model), 0); + } catch (NumberFormatException ex) + { + // ignore + } + } + } + if (chimeraModel == null) + { + chimeraModel = chimeraManager.getChimeraModel(); + } + // System.out.println("ChimeraModel = " + chimeraModel); + + if (chain != null) + { + chimeraChain = chimeraModel.getChain(chain); + // System.out.println("ChimeraChain = " + chimeraChain); + } + if (residue != null) + { + if (chimeraChain != null) + { + chimeraResidue = chimeraChain.getResidue(residue); + } + else + { + chimeraResidue = chimeraModel.getResidue("_", residue); + } + // System.out.println("ChimeraResidue = " + chimeraResidue); + } + + if (chimeraResidue != null) + return chimeraResidue; + + if (chimeraChain != null) + return chimeraChain; + + if (chimeraModel != null) + return chimeraModel; + + } catch (Exception ex) + { + logger.warn("Could not parse residue identifier: " + attrSpec, ex); + } + return null; + } + + public static ChimeraStructuralObject fromAttribute(String attrSpec, + ChimeraManager chimeraManager) + { + // TODO: Make sure it is OK to remove this: || attrSpec.indexOf('-') > 0 + if (attrSpec == null || attrSpec.indexOf(',') > 0) + { + // No support for either lists or ranges + // System.out.println("No support for identifier: " + attrSpec); + logger.warn("No support for identifier: " + attrSpec); + return null; + } + String[] modelIDNoResChain = getResKeyParts(attrSpec); + + ChimeraModel chimeraModel = null; + ChimeraChain chimeraChain = null; + ChimeraResidue chimeraResidue = null; + + // System.out.println("Getting object from attribute: "+attrSpec); + try + { + if (modelIDNoResChain[0] != null) + { + String modelID = modelIDNoResChain[0]; + List models = chimeraManager.getChimeraModels( + modelID, ModelType.PDB_MODEL); + if (models.size() == 1) + { // usual case with only one model + chimeraModel = models.get(0); + } + else if (models.size() > 1 && modelIDNoResChain[1] != null) + { + // there are several submodels + try + { + int modelNo = Integer.valueOf(modelIDNoResChain[1]); + for (ChimeraModel model : models) + { + if (model.getSubModelNumber() == modelNo) + { + chimeraModel = model; + break; + } + } + } catch (NumberFormatException ex) + { + // ignore + } + } + else + { + // TODO: [Optional] What is this doing? + try + { + chimeraModel = chimeraManager.getChimeraModel( + Integer.valueOf(modelID), 0); + } catch (NumberFormatException ex) + { + // ignore + } + } + } + if (chimeraModel == null) + { + // TODO: [Optional] Find a better way to handle this case + // If no model can be matched, continue + // System.out.println("No matching model could be find for " + + // attrSpec); + return null; + // chimeraModel = chimeraManager.getChimeraModel(); + // logger.warn("No matching model could be find for " + attrSpec + + // ". Trying with " + // + chimeraModel.toSpec()); + } + // System.out.println("ChimeraModel = " + chimeraModel); + + if (modelIDNoResChain[3] != null) + { + chimeraChain = chimeraModel.getChain(modelIDNoResChain[3]); + // System.out.println("ChimeraChain = " + chimeraChain); + } + if (modelIDNoResChain[2] != null) + { + String residue = modelIDNoResChain[2]; + if (chimeraChain != null) + { + chimeraResidue = chimeraChain.getResidue(residue); + } + else if (chimeraModel.getChain("_") != null) + { + chimeraResidue = chimeraModel.getResidue("_", residue); + } + else if (chimeraModel.getChainCount() == 1) + { + chimeraResidue = chimeraModel.getResidue(chimeraModel + .getChainNames().iterator().next(), residue); + } + // System.out.println("ChimeraResidue = " + chimeraResidue); + } + + if (chimeraResidue != null) + return chimeraResidue; + + if (chimeraChain != null) + return chimeraChain; + + if (chimeraModel != null) + return chimeraModel; + + } catch (Exception ex) + { + // System.out.println("Could not parse chimera identifier: " + + // attrSpec+"("+ex.getMessage()+")"); + logger.warn("Could not parse chimera identifier: " + attrSpec, ex); + } + return null; + } + + /** + * Search for structure references in the residue list + * + * @param residueList + * the list of residues + * @return a concatenated list of structures encoded in the list + */ + public static String findStructures(String residueList) + { + if (residueList == null) + return null; + String[] residues = residueList.split(","); + Map structureNameMap = new HashMap(); + for (int i = 0; i < residues.length; i++) + { + String[] components = residues[i].split("#"); + if (components.length > 1) + { + structureNameMap.put(components[0], components[1]); + } + } + if (structureNameMap.isEmpty()) + return null; + + String structure = null; + for (String struct : structureNameMap.keySet()) + { + if (structure == null) + structure = new String(); + else + structure = structure.concat(","); + structure = structure.concat(struct); + } + return structure; + } + + // invoked by openStructures in StructureManager + public static List parseFuncRes(List residueNames, + String modelName) + { + List resRanges = new ArrayList(); + for (int i = 0; i < residueNames.size(); i++) + { + String residue = residueNames.get(i); + // Parse out the structure, if there is one + String[] components = residue.split("#"); + if (components.length > 1 && !modelName.equals(components[0])) + { + continue; + } + else if (components.length > 1) + { + residue = components[1]; + } + else if (components.length == 1) + { + residue = components[0]; + } + // Check to see if we have a range-spec + String resRange = ""; + if (residue == null || residue.equals("") || residue.length() == 0) + { + continue; + } + String[] range = residue.split("-", 2); + String chain = null; + for (int res = 0; res < range.length; res++) + { + if (res == 1) + { + resRange = resRange.concat("-"); + if (chain != null && range[res].indexOf('.') == -1) + range[res] = range[res].concat("." + chain); + } + + if (res == 0 && range.length >= 2 && range[res].indexOf('.') > 0) + { + // This is a range spec with the leading residue containing a chain + // spec + String[] resChain = range[res].split("\\."); + chain = resChain[1]; + range[res] = resChain[0]; + } + // Fix weird SFLD syntax... + if (range[res].indexOf('|') > 0 + && Character.isDigit(range[res].charAt(0))) + { + int offset = range[res].indexOf('|'); + String str = range[res].substring(offset + 1) + + range[res].substring(0, offset); + range[res] = str; + } + + // Convert to legal atom-spec + if (Character.isDigit(range[res].charAt(0))) + { + resRange = resRange.concat(range[res]); + } + else if (Character.isDigit(range[res].charAt(1))) + { + resRange = resRange.concat(range[res].substring(1)); + } + else if (range[res].charAt(0) == '.') + { + // Do we have a chain spec? + resRange = resRange.concat(range[res]); + } + else + { + resRange = resRange.concat(range[res].substring(3)); + } + } + if (!resRanges.contains(resRange)) + { + resRanges.add(resRange); + } + } + return resRanges; + } + + static + { + aaNames = new HashMap(); + aaNames.put("ALA", "A Ala Alanine N[C@@H](C)C(O)=O"); + aaNames.put("ARG", "R Arg Arginine N[C@@H](CCCNC(N)=N)C(O)=O"); + aaNames.put("ASN", "N Asn Asparagine N[C@@H](CC(N)=O)C(O)=O"); + aaNames.put("ASP", "D Asp Aspartic_acid N[C@@H](CC(O)=O)C(O)=O"); + aaNames.put("CYS", "C Cys Cysteine N[C@@H](CS)C(O)=O"); + aaNames.put("GLN", "Q Gln Glutamine N[C@H](C(O)=O)CCC(N)=O"); + aaNames.put("GLU", "E Glu Glumatic_acid N[C@H](C(O)=O)CCC(O)=O"); + aaNames.put("GLY", "G Gly Glycine NCC(O)=O"); + aaNames.put("HIS", "H His Histidine N[C@@H](CC1=CN=CN1)C(O)=O"); + aaNames.put("ILE", "I Ile Isoleucine N[C@]([C@H](C)CC)([H])C(O)=O"); + aaNames.put("LEU", "L Leu Leucine N[C@](CC(C)C)([H])C(O)=O"); + aaNames.put("LYS", "K Lys Lysine N[C@](CCCCN)([H])C(O)=O"); + aaNames.put("DLY", "K Dly D-Lysine NCCCC[C@@H](N)C(O)=O"); + aaNames.put("MET", "M Met Methionine N[C@](CCSC)([H])C(O)=O"); + aaNames.put("PHE", "F Phe Phenylalanine N[C@](CC1=CC=CC=C1)([H])C(O)=O"); + aaNames.put("PRO", "P Pro Proline OC([C@@]1([H])NCCC1)=O"); + aaNames.put("SER", "S Ser Serine OC[C@](C(O)=O)([H])N"); + aaNames.put("THR", "T Thr Threonine O[C@H](C)[C@](C(O)=O)([H])N"); + aaNames.put("TRP", + "W Trp Tryptophan N[C@@]([H])(CC1=CN([H])C2=C1C=CC=C2)C(O)=O"); + aaNames.put("TYR", "Y Tyr Tyrosine N[C@@](C(O)=O)([H])CC1=CC=C(O)C=C1"); + aaNames.put("VAL", "V Val Valine N[C@@](C(O)=O)([H])C(C)C"); + aaNames.put("ASX", "B Asx Aspartic_acid_or_Asparagine"); + aaNames.put("GLX", "Z Glx Glutamine_or_Glutamic_acid"); + aaNames.put("XAA", "X Xaa Any_or_unknown_amino_acid"); + aaNames.put("HOH", "HOH HOH Water [H]O[H]"); + } + + /** + * Convert the amino acid type to a full name + * + * @param aaType + * the residue type to convert + * @return the full name of the residue + */ + public static String toFullName(String aaType) + { + if (!aaNames.containsKey(aaType)) + return aaType; + String[] ids = ((String) aaNames.get(aaType)).split(" "); + return ids[2].replace('_', ' '); + } + + /** + * Convert the amino acid type to a single letter + * + * @param aaType + * the residue type to convert + * @return the single letter representation of the residue + */ + public static String toSingleLetter(String aaType) + { + if (!aaNames.containsKey(aaType)) + return aaType; + String[] ids = ((String) aaNames.get(aaType)).split(" "); + return ids[0]; + } + + /** + * Convert the amino acid type to three letters + * + * @param aaType + * the residue type to convert + * @return the three letter representation of the residue + */ + public static String toThreeLetter(String aaType) + { + if (!aaNames.containsKey(aaType)) + return aaType; + String[] ids = ((String) aaNames.get(aaType)).split(" "); + return ids[1]; + } + + /** + * Convert the amino acid type to its SMILES string + * + * @param aaType + * the residue type to convert + * @return the SMILES representation of the residue + */ + public static String toSMILES(String aaType) + { + if (!aaNames.containsKey(aaType)) + return null; + String[] ids = ((String) aaNames.get(aaType)).split(" "); + if (ids.length < 4) + return null; + return ids[3]; + } + + public static String getAlignName(ChimeraStructuralObject chimObj) + { + String name = chimObj.getChimeraModel().toString(); + if (chimObj instanceof ChimeraChain) + { + name = ((ChimeraChain) chimObj).toString() + " [" + name + "]"; + } + return name; + } }