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