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 * Created on Sep 15, 2009
021 * Author: Andreas Prlic
022 *
023 */
024
025package org.biojava.nbio.structure.align.ce;
026
027
028import org.biojava.nbio.structure.Atom;
029import org.biojava.nbio.structure.Group;
030import org.biojava.nbio.structure.StructureException;
031import org.biojava.nbio.structure.align.AbstractStructureAlignment;
032import org.biojava.nbio.structure.align.StructureAlignment;
033import org.biojava.nbio.structure.align.model.AFPChain;
034import org.biojava.nbio.structure.jama.Matrix;
035
036/**
037 * The main class of the Java implementation of the Combinatorial Extension Algorithm (CE),
038 * as has been originally developed by I. Shindyalov and P.Bourne (1998).
039 * The original CE paper is available from here: <a href="http://peds.oxfordjournals.org/cgi/content/short/11/9/739">http://peds.oxfordjournals.org/cgi/content/short/11/9/739</a>
040 *
041 * For a demo of how to use this algorithm, visit the BioJava web site:
042 * <a href="">CE usage example</a>.
043 *
044 * The BioJava CE version is based on CE version 2.3 (2003 or 2004).
045 *
046 * @author Andreas Prlic.
047 *
048 */
049public class CeMain extends AbstractStructureAlignment implements StructureAlignment {
050
051        public static final String algorithmName = "jCE";
052
053        /**
054         *  version history:
055         *  1.2 - Added more parameters to the command line, including -maxOptRMSD
056         *  1.1 - Additional parameters
057         *  1.0 - Initial port from C code
058         */
059        public static final String version = "1.2";
060
061        protected CeParameters params;
062        protected CECalculator calculator;
063        private Atom[] ca2clone;
064
065        public CeMain(){
066                super();
067                params = new CeParameters();
068                calculator = new CECalculator(params);
069        }
070
071
072        /**
073         * Example Parameters:
074         *
075         * -pdbFilePath /tmp -autoFetch -printCE -pdb1 1cnv -pdb2 3cna
076         *
077         */
078        public static void main(String[] args) throws Exception {
079                CeUserArgumentProcessor processor = new CeUserArgumentProcessor(); //Responsible for creating a CeMain instance
080                processor.process(args);
081        }
082
083        /**
084         * Align ca2 onto ca1.
085         */
086        @Override
087        public AFPChain align(Atom[] ca1, Atom[] ca2, Object param) throws StructureException{
088                if ( ! (param instanceof CeParameters))
089                        throw new IllegalArgumentException("CE algorithm needs an object of call CeParameters as argument.");
090
091                params = (CeParameters) param;
092
093                // we don't want to rotate input atoms, do we?
094                ca2clone = new Atom[ca2.length];
095
096                int pos = 0;
097                for (Atom a : ca2){
098                        Group g = (Group)a.getGroup().clone(); // works because each group has only a CA atom
099
100                        ca2clone[pos] = g.getAtom(a.getName());
101
102                        pos++;
103                }
104
105                calculator = new CECalculator(params);
106
107                //Build alignment ca1 to ca2-ca2
108                AFPChain afpChain = new AFPChain(algorithmName);
109                afpChain = calculator.extractFragments(afpChain, ca1, ca2clone);
110                calculator.traceFragmentMatrix( afpChain,ca1, ca2clone);
111                calculator.nextStep( afpChain,ca1, ca2clone);
112
113                afpChain.setAlgorithmName(getAlgorithmName());
114                afpChain.setVersion(version);
115
116                // Try to guess names
117
118                if (ca1.length!=0 && ca1[0].getGroup().getChain()!=null && ca1[0].getGroup().getChain().getStructure()!=null)
119                        afpChain.setName1(ca1[0].getGroup().getChain().getStructure().getName());
120
121                if (ca2.length!=0 && ca2[0].getGroup().getChain()!=null && ca2[0].getGroup().getChain().getStructure()!=null)
122                        afpChain.setName2(ca2[0].getGroup().getChain().getStructure().getName());
123
124                if ( afpChain.getNrEQR() == 0)
125                   return afpChain;
126
127                // Set the distance matrix
128
129                int winSize = params.getWinSize();
130                int winSizeComb1 = (winSize-1)*(winSize-2)/2;
131                double[][] m = calculator.initSumOfDistances(ca1.length, ca2.length, winSize, winSizeComb1, ca1, ca2clone);
132                afpChain.setDistanceMatrix(new Matrix(m));
133                afpChain.setSequentialAlignment(true);
134
135                return afpChain;
136        }
137
138
139
140
141        @Override
142        public AFPChain align(Atom[] ca1, Atom[] ca2) throws StructureException {
143
144                if (params == null)
145                        params = new CeParameters();
146
147                return align(ca1,ca2,params);
148        }
149
150        @Override
151        public String getAlgorithmName() {
152
153                return CeMain.algorithmName;
154        }
155
156        @Override
157        public ConfigStrucAligParams getParameters() {
158
159                return params;
160        }
161
162        @Override
163        public void setParameters(ConfigStrucAligParams params){
164                if (! (params instanceof CeParameters )){
165                        throw new IllegalArgumentException("provided parameter object is not of type CeParameter");
166                }
167                this.params = (CeParameters) params;
168        }
169
170        @Override
171        public String getVersion() {
172                return CeMain.version;
173        }
174
175        public CECalculator getCECalculator() {
176                return calculator;
177        }
178}