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 Oct 2, 2009
021 * Author: Andreas Prlic
022 *
023 */
024
025package org.biojava.nbio.structure.align;
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.StructureTools;
032import org.biojava.nbio.structure.align.ce.ConfigStrucAligParams;
033import org.biojava.nbio.structure.align.helper.IndexPair;
034import org.biojava.nbio.structure.align.model.AFPChain;
035import org.biojava.nbio.structure.align.pairwise.AlternativeAlignment;
036import org.biojava.nbio.structure.jama.Matrix;
037
038
039/**
040 * Wrapper for the BioJava Structure Alignment Implementation
041 *
042 * @author Andreas Prlic
043 */
044public class BioJavaStructureAlignment implements StructureAlignment  {
045
046        public static final String algorithmName = "BioJava_structure";
047        private static final float versionNr = 0.1f;
048        private StrucAligParameters params;
049
050        public BioJavaStructureAlignment(){
051                params = new StrucAligParameters();
052        }
053
054        @Override
055        public String getAlgorithmName() {
056                return algorithmName;
057        }
058
059        @Override
060        public ConfigStrucAligParams getParameters() {
061                return null;//TODO shall we update it?
062        }
063
064        @Override
065        public void setParameters(ConfigStrucAligParams o){
066                //TODO what is the relation between StrucAligParameters and ConfigStrucAligParams?
067                if ( ! (o instanceof StrucAligParameters)){
068                        throw new IllegalArgumentException("Provided parameters are not of type StrucAligParameters!");
069                }
070                params = (StrucAligParameters) o;
071        }
072
073        @Override
074        public String getVersion() {
075                return String.valueOf(versionNr);
076        }
077
078        public String printHelp() {
079                return "not implemented yet. Algorithm still under development.";
080        }
081
082        @Override
083        public AFPChain align(Atom[] ca1, Atom[] ca2) throws StructureException {
084                StrucAligParameters params = StrucAligParameters.getDefaultParameters();
085                return align(ca1,ca2,params);
086
087        }
088
089        @Override
090        public AFPChain align(Atom[] ca1, Atom[] ca2, Object params)
091                        throws StructureException {
092                if ( ! (params instanceof StrucAligParameters)){
093                        throw new IllegalArgumentException("BioJava structure alignment requires a StrucAligParameters class for the arguments.");
094                }
095                this.params = (StrucAligParameters) params;
096
097                AFPChain afpChain = new AFPChain(algorithmName);
098                StructurePairAligner aligner = new StructurePairAligner();
099                aligner.align(ca1,ca2,this.params);
100
101                // copy the results over into the AFPChain...
102                AlternativeAlignment[] aligs = aligner.getAlignments();
103                if ( aligs.length > 0){
104
105                        AlternativeAlignment altAlig = aligs[0];
106                        // copy the results over!
107                        copyResults(afpChain,altAlig,ca1,ca2);
108                }
109
110                return afpChain;
111
112        }
113
114        private void copyResults(AFPChain afpChain, AlternativeAlignment altAlig, Atom[] ca1, Atom[] ca2) {
115                afpChain.setAlgorithmName(getAlgorithmName());
116                afpChain.setVersion(getVersion());
117                afpChain.setAlignScore(altAlig.getScore());
118                afpChain.setOptLength(altAlig.getEqr());
119                afpChain.setBlockRotationMatrix(new Matrix[]{altAlig.getRotationMatrix()});
120                afpChain.setBlockShiftVector(new Atom[]{altAlig.getShift() });
121                afpChain.setBlockNum(1);
122
123                double rmsd = altAlig.getRmsd();
124                afpChain.setBlockRmsd(new double[]{rmsd});
125
126
127                int nAtom = altAlig.getEqr();
128                int lcmp = altAlig.getPath().length;
129                int[] optLen = new int[]{nAtom};
130                afpChain.setOptLen(optLen);
131                afpChain.setOptLength(nAtom);
132                afpChain.setAlnLength(lcmp);
133
134                int[][][] optAln = new int[1][2][lcmp];
135                afpChain.setOptAln(optAln);
136
137                afpChain.setOptRmsd(new double[]{rmsd});
138                afpChain.setTotalRmsdOpt(rmsd);
139                afpChain.setChainRmsd(rmsd);
140                //afpChain.setProbability(-1);
141                int nse1 = ca1.length;
142                int nse2 = ca2.length;
143
144                char[] alnseq1 = new char[nse1+nse2+1];
145                char[] alnseq2 = new char[nse1+nse2+1] ;
146                char[] alnsymb = new char[nse1+nse2+1];
147
148                IndexPair[] path = altAlig.getPath();
149
150                int pos = 0;
151                for(int ia=0; ia<lcmp; ia++) {
152
153                        IndexPair align_se = path[ia];
154                        // no gap
155                        if(align_se.getRow() !=-1 && align_se.getCol()!=-1) {
156
157                                optAln[0][0][pos] = align_se.getRow();
158                                optAln[0][1][pos] = align_se.getCol();
159
160                                char l1 = getOneLetter(ca1[align_se.getRow()].getGroup());
161                                char l2 = getOneLetter(ca2[align_se.getCol()].getGroup());
162
163                                alnseq1[ia] = Character.toUpperCase(l1);
164                                alnseq2[ia] = Character.toUpperCase(l2);
165                                alnsymb[ia] = '1';
166                                pos++;
167
168                        } else {
169                                // there is a gap on this position
170                                alnsymb[ia] = ' ';
171                                if (align_se.getRow() == -1 ) {
172                                        alnseq1[ia] = '-';
173                                } else {
174                                        char l1 = getOneLetter(ca1[align_se.getRow()].getGroup());
175                                        alnseq1[ia] = Character.toLowerCase(l1);
176                                }
177                                if ( align_se.getCol() == -1 ) {
178                                        alnseq2[ia] = '-';
179                                } else {
180                                        char l2 = getOneLetter(ca2[align_se.getCol()].getGroup());
181                                        alnseq2[ia] = Character.toLowerCase(l2);
182                                }
183
184                        }
185                }
186                afpChain.setAlnseq1(alnseq1);
187                afpChain.setAlnseq2(alnseq2);
188                afpChain.setAlnsymb(alnsymb);
189
190        }
191
192        private static char getOneLetter(Group g){
193
194                if (g==null) return StructureTools.UNKNOWN_GROUP_LABEL;
195
196                return StructureTools.get1LetterCode(g.getPDBName());
197
198        }
199
200}