/* $RCSfile$
* $Author$
* $Date$
* $Revision$
*
* Copyright (C) 2005-2007 The Chemistry Development Kit (CDK) Project
*
* Contact: cdk-devel@lists.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
* All we ask is that proper credit is given for our work, which includes
* - but is not limited to - adding the above copyright notice to the beginning
* of your source code files, and to any copyright notice that you may distribute
* with programs based on this work.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
package org.openscience.cdk.tools;
import org.openscience.cdk.*;
import org.openscience.cdk.exception.CDKException;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.templates.AminoAcids;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Class that facilitates building protein structures. Building DNA and RNA
* is done by a complementary class <code>NucleicAcidBuilderTool</code> (to be
* written).
*
* @cdk.module pdb
* @cdk.githash
*/
public class ProteinBuilderTool {
private static ILoggingTool logger =
LoggingToolFactory.createLoggingTool(ProteinBuilderTool.class);
/**
* Builds a protein by connecting a new amino acid at the N-terminus of the
* given strand.
*
* @param protein protein to which the strand belongs
* @param aaToAdd amino acid to add to the strand of the protein
* @param strand strand to which the protein is added
*/
public static BioPolymer addAminoAcidAtNTerminus(
BioPolymer protein, AminoAcid aaToAdd, Strand strand, AminoAcid aaToAddTo)
{
// then add the amino acid
addAminoAcid(protein, aaToAdd, strand);
// Now think about the protein back bone connection
if (protein.getMonomerCount() == 0) {
// make the connection between that aminoAcid's C-terminus and the
// protein's N-terminus
protein.addBond(
new Bond(aaToAddTo.getNTerminus(), aaToAdd.getCTerminus(), IBond.Order.SINGLE)
);
} // else : no current N-terminus, so nothing special to do
return protein;
}
/**
* Builds a protein by connecting a new amino acid at the C-terminus of the
* given strand. The acidic oxygen of the added amino acid is removed so that
* additional amino acids can be added savely. But this also means that you
* might want to add an oxygen at the end of the protein building!
*
* @param protein protein to which the strand belongs
* @param aaToAdd amino acid to add to the strand of the protein
* @param strand strand to which the protein is added
*/
public static BioPolymer addAminoAcidAtCTerminus(
BioPolymer protein, AminoAcid aaToAdd, Strand strand, AminoAcid aaToAddTo)
{
// then add the amino acid
addAminoAcid(protein, aaToAdd, strand);
// Now think about the protein back bone connection
if ((protein.getMonomerCount() != 0) && (aaToAddTo != null)) {
// make the connection between that aminoAcid's N-terminus and the
// protein's C-terminus
protein.addBond(
new Bond(aaToAddTo.getCTerminus(), aaToAdd.getNTerminus(), IBond.Order.SINGLE)
);
} // else : no current C-terminus, so nothing special to do
return protein;
}
/**
* Creates a BioPolymer from a sequence of amino acid as identified by a
* the sequence of there one letter codes.
*
* <p>For example:
* <pre>
* BioPolymer protein = ProteinBuilderTool.createProtein("GAGA");
* </pre>
*/
public static BioPolymer createProtein(String sequence) throws CDKException {
Map<String,AminoAcid> templates = AminoAcids.getHashMapBySingleCharCode();
BioPolymer protein = new BioPolymer();
Strand strand = new Strand();
AminoAcid previousAA = null;
for (int i=0; i<sequence.length(); i++) {
String aminoAcidCode = "" + sequence.charAt(i);
logger.debug("Adding AA: " + aminoAcidCode);
if (aminoAcidCode.equals(" ")) {
// fine, just skip spaces
} else {
AminoAcid aminoAcid = (AminoAcid)templates.get(aminoAcidCode);
if (aminoAcid == null) {
throw new CDKException("Cannot build sequence! Unknown amino acid: " + aminoAcidCode);
}
try {
aminoAcid = (AminoAcid)aminoAcid.clone();
} catch (CloneNotSupportedException e) {
throw new CDKException("Cannot build sequence! Clone exception: " + e.getMessage(), e);
}
aminoAcid.setMonomerName(aminoAcidCode + i);
logger.debug("protein: ", protein);
logger.debug("strand: ", strand);
addAminoAcidAtCTerminus(protein, aminoAcid, strand, previousAA);
previousAA = aminoAcid;
}
}
// add the last oxygen of the protein
Atom oxygen = new Atom("O");
// ... to amino acid
previousAA.addAtom(oxygen);
Bond bond = new Bond(oxygen, previousAA.getCTerminus(), IBond.Order.SINGLE);
previousAA.addBond(bond);
// ... and to protein
protein.addAtom(oxygen, previousAA, strand);
protein.addBond(bond);
return protein;
}
private static BioPolymer addAminoAcid(BioPolymer protein, AminoAcid aaToAdd, Strand strand) {
for (IAtom atom : aaToAdd.atoms()) protein.addAtom(atom, aaToAdd, strand);
for (IBond bond : aaToAdd.bonds()) protein.addBond(bond);
return protein;
}
}