001package org.biojava.nbio.structure.chem; 002 003import java.io.Serializable; 004import java.util.HashMap; 005import java.util.Map; 006 007/** 008 * Enumerates the possible classifications of residues. These are generally more specific than PolymerTypes 009 * This information is derived from the mmcif dictionary. 010 * @author mulvaney 011 * @author Andreas Prlic 012 * @see <a href="http://mmcif.rcsb.org/dictionaries/mmcif_pdbx.dic/Items/_chem_comp.type.html">link into mmCIF dictionary</a> 013 * @since 1.7 014 */ 015public enum ResidueType implements Serializable { 016 atomn(null, "null"), // present in db for _chem_comp.id_ = 'CFL' but not enumerated in dictionary 017 // Peptides 018 dPeptideLinking(PolymerType.dpeptide, "D-peptide linking"), 019 lPeptideLinking(PolymerType.peptide, "L-peptide linking"), 020 glycine(PolymerType.peptide,"PEPTIDE LINKING"), 021 peptideLike(PolymerType.otherPolymer, "peptide-like"), 022 dPeptideAminoTerminus(PolymerType.dpeptide, "D-peptide NH3 amino terminus"), 023 lPeptideAminoTerminus(PolymerType.peptide, "L-peptide NH3 amino terminus"), 024 dPeptideCarboxyTerminus(PolymerType.dpeptide, "D-peptide COOH carboxy terminus"), 025 lPeptideCarboxyTerminus(PolymerType.peptide, "L-peptide COOH carboxy terminus"), 026 // Nucleotides 027 dnaLinking(PolymerType.dna, "DNA linking"), 028 rnaLinking(PolymerType.rna, "RNA linking"), 029 dna3PrimeTerminus(PolymerType.dna, "DNA OH 3 prime terminus"), 030 rna3PrimeTerminus(PolymerType.rna, "RNA OH 3 prime terminus"), 031 dna5PrimeTerminus(PolymerType.dna, "DNA OH 5 prime terminus"), 032 rna5PrimeTerminus(PolymerType.rna, "RNA OH 5 prime terminus"), 033 // Sugars 034 dSaccharide(PolymerType.polysaccharide, "D-saccharide"), 035 dSaccharide14and14linking(PolymerType.polysaccharide, "D-saccharide 1,4 and 1,4 linking"), 036 dSaccharide14and16linking(PolymerType.polysaccharide, "D-saccharide 1,4 and 1,6 linking"), 037 lSaccharide(PolymerType.lpolysaccharide, "L-saccharide"), 038 lSaccharide14and14linking(PolymerType.lpolysaccharide, "L-saccharide 1,4 and 1,4 linking"), 039 lSaccharide14and16linking(PolymerType.lpolysaccharide, "L-saccharide 1,4 and 1,6 linking"), 040 saccharide(PolymerType.polysaccharide, "saccharide"), 041 // Iso-peptides 042 dBetaPeptideCGammaLinking(PolymerType.dpeptide,"D-beta-peptide, C-gamma linking"), 043 dGammaPeptideCDeltaLinking(PolymerType.dpeptide,"D-gamma-peptide, C-delta linking"), 044 lBetaPeptideCGammaLinking(PolymerType.peptide,"L-beta-peptide, C-gamma linking"), 045 lGammaPeptideCDeltaLinking(PolymerType.peptide,"L-gamma-peptide, C-delta linking"), 046 // L nucleotides. As of 2015-04, these are only found in D-DNA hybrids, so they don't have their own PolymerType 047 lDNALinking(PolymerType.dna,"L-DNA linking"), 048 lRNALinking(PolymerType.dna,"L-RNA linking"), 049 // Other 050 nonPolymer(null, "non-polymer"), 051 otherChemComp(null, "other"); 052 053 static Map<String, ResidueType> lookupTable = new HashMap<>(); 054 055 static { 056 for (ResidueType residueType : ResidueType.values() ) { 057 lookupTable.put(residueType.chem_comp_type, residueType); 058 lookupTable.put(residueType.chem_comp_type.toLowerCase(), residueType); 059 } 060 } 061 062 ResidueType(PolymerType polymerType, String chem_comp_type) { 063 this.polymerType = polymerType; 064 this.chem_comp_type = chem_comp_type; 065 } 066 067 /** 068 * The associated {@link PolymerType} 069 */ 070 public final PolymerType polymerType; 071 072 /** 073 * Gets the associated PolymerType, which are less specific 074 * @return 075 */ 076 public PolymerType getPolymerType() { 077 return polymerType; 078 } 079 080 /** 081 * String value of the type 082 */ 083 public final String chem_comp_type; 084 085 /** Get ResidueType by chem_comp_type 086 * 087 * @param chem_comp_type e.g. L-peptide linking 088 * @return 089 */ 090 public static ResidueType getResidueTypeFromString(String chem_comp_type) { 091 if (chem_comp_type == null) { 092 return null; 093 } 094 095 // Almost all calls to this method are for L-peptide linking. Use this knowledge for a shortcut. 096 if (chem_comp_type.equalsIgnoreCase(lPeptideLinking.chem_comp_type)) { 097 return lPeptideLinking; 098 } 099 100 ResidueType lookedUpResidueType = lookupTable.get(chem_comp_type); 101 if (lookedUpResidueType != null) { 102 return lookedUpResidueType; 103 } 104 105 /* 106 * Unfortunately it can be guaranteed that chem_comp_type case sensitivity is preserved. 107 * E.g. mmtf has it all upper-case. As such we need to do a second check 108 */ 109 lookedUpResidueType = lookupTable.get(chem_comp_type.toLowerCase()); 110 if (lookedUpResidueType != null) { 111 return lookedUpResidueType; 112 } 113 114 // preserving previous behaviour. Not sure if this is really necessary? 115 for (ResidueType residueType : ResidueType.values()) { 116 if(residueType.chem_comp_type.equalsIgnoreCase(chem_comp_type)) { 117 return residueType; 118 } 119 120 if (residueType.chem_comp_type.toLowerCase().startsWith(chem_comp_type.toLowerCase())) { 121 return residueType; 122 } 123 if (chem_comp_type.toLowerCase().startsWith(residueType.chem_comp_type.toLowerCase())) { 124 return residueType; 125 } 126 } 127 return null; 128 } 129}