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