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
021package org.biojava.nbio.structure;
022
023import org.biojava.nbio.structure.io.PDBParseException;
024
025import java.util.ArrayList;
026import java.util.List;
027
028
029/** A class that can change one amino acid to another. Side chain atoms are neglected, only the Cb atom is kept.
030 *
031 *
032 * example usage:
033 * <pre>
034String outputfile =  "/Users/ap3/WORK/PDB/mutated.pdb" ;
035
036Structure struc = StructureIO.getStructure("5pti");
037System.out.println(struc);
038
039String chainName = "A";
040String pdbResnum = "3";
041String newType = "ARG";
042
043// mutate the original structure and create a new one.
044Mutator m = new Mutator();
045Structure newstruc = m.mutate(struc,chainName,pdbResnum,newType);
046
047FileOutputStream out= new FileOutputStream(outputfile);
048PrintStream p =  new PrintStream( out );
049
050p.println (newstruc.toPDB());
051
052p.close();
053</pre>
054 * @author Andreas Prlic
055 * @since 1.5
056 * @version %I% %G%
057 */
058public class Mutator{
059        List<String> supportedAtoms;
060
061        public Mutator(){
062                supportedAtoms = new ArrayList<String>();
063                supportedAtoms.add("N");
064                supportedAtoms.add("CA");
065                supportedAtoms.add("C");
066                supportedAtoms.add("O");
067                supportedAtoms.add("CB");
068        }
069
070        /** creates a new structure which is identical with the original one.
071         * only one amino acid will be different.
072         *
073         *
074         *
075         *
076         * @param struc the structure object that is the container for the residue to be mutated
077         * @param chainId the id (name) of the chain to be mutated. @see Chain.getName()
078         * @param pdbResnum the PDB residue number of the residue
079         * @param newType the new residue type (3 characters)
080         * @return a structure object where one residue has been modified
081         * @throws PDBParseException
082         */
083        public Structure  mutate(Structure struc, String chainId, String pdbResnum, String newType)
084        throws PDBParseException{
085
086
087                // create a  container for the new structure
088                Structure newstruc = new StructureImpl();
089
090                // first we need to find our corresponding chain
091
092                // get the chains for model nr. 0
093                // if structure is xray there will be only one "model".
094                List<Chain> chains = struc.getChains(0);
095
096                // iterate over all chains.
097                for (Chain c : chains) {
098                        if (c.getName().equals(chainId)) {
099                                // here is our chain!
100
101                                Chain newchain = new ChainImpl();
102                                newchain.setName(c.getName());
103
104                                List<Group> groups = c.getAtomGroups();
105
106                                // now iterate over all groups in this chain.
107                                // in order to find the amino acid that has this pdbRenum.
108
109                                for (Group g : groups) {
110                                        String rnum = g.getResidueNumber().toString();
111
112                                        // we only mutate amino acids
113                                        // and ignore hetatoms and nucleotides in this case
114                                        if (rnum.equals(pdbResnum) && (g.getType() == GroupType.AMINOACID)) {
115
116                                                // create the mutated amino acid and add it to our new chain
117                                                AminoAcid newgroup = mutateResidue((AminoAcid) g, newType);
118                                                newchain.addGroup(newgroup);
119                                        } else {
120                                                // add the group  to the new chain unmodified.
121                                                newchain.addGroup(g);
122                                        }
123                                }
124
125                                // add the newly constructed chain to the structure;
126                                newstruc.addChain(newchain);
127                        } else {
128                                // this chain is not requested, add it to the new structure unmodified.
129                                newstruc.addChain(c);
130                        }
131
132                }
133                return newstruc;
134        }
135
136        /** create a new residue which is of the new type.
137         * Only the atoms N, Ca, C, O, Cb will be considered.
138         * @param oldAmino
139         * @param newType
140         * @return a new, mutated, residue
141         * @throws PDBParseException
142         */
143        public AminoAcid mutateResidue(AminoAcid oldAmino, String newType)
144        throws PDBParseException {
145
146                AminoAcid newgroup = new AminoAcidImpl();
147
148                newgroup.setResidueNumber(oldAmino.getResidueNumber());
149                newgroup.setPDBName(newType);
150
151
152                AtomIterator aiter =new AtomIterator(oldAmino);
153                while (aiter.hasNext()){
154                        Atom a = aiter.next();
155                        if ( supportedAtoms.contains(a.getName())){
156                                newgroup.addAtom(a);
157                        }
158                }
159
160                return newgroup;
161
162        }
163
164}