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 9, 2009
021 * Author: Andreas Prlic
022 *
023 */
024
025package org.biojava.nbio.structure.align.xml;
026
027import org.biojava.nbio.structure.Atom;
028import org.biojava.nbio.structure.Calc;
029import org.biojava.nbio.structure.StructureException;
030import org.biojava.nbio.structure.align.model.AFPChain;
031import org.biojava.nbio.structure.jama.Matrix;
032
033public class AFPChainFlipper {
034
035
036        /** Flip the position of name1 and name2 (as well as all underlying data) in an AFPChain.
037         * This is a utility function for AFPChainXMLParser.
038         * You will have to call AFPCHainXMLParser.rebuildAFPChain in order to get twisted groups...
039         *
040         * @param o ... the original AFPCHain that should be flipped
041         * @return a cloned AFPCHain which the positions of name1 and name2 flipped.
042         */
043        public static AFPChain flipChain(AFPChain o) throws StructureException{
044
045                AFPChain n = new AFPChain(o.getAlgorithmName());
046                n.setVersion(o.getVersion());
047
048                n.setName2(o.getName1());
049                n.setName1(o.getName2());
050
051                n.setCa1Length(o.getCa2Length());
052                n.setCa2Length(o.getCa1Length());
053
054                int[] optLen = o.getOptLen();
055                n.setOptLen(optLen);
056
057                int blockNum = o.getBlockNum();
058                n.setBlockNum(blockNum);
059                n.setBlockSize(o.getBlockSize());
060                n.setBlockScore(o.getBlockScore());
061                n.setBlockRmsd(o.getBlockRmsd());
062                n.setBlockGap(o.getBlockGap());
063
064                int minLength = Math.min(n.getCa1Length(),n.getCa2Length());
065                int[][][] optAlnN                       = new int[blockNum][2][minLength];
066                int[][][] optAlnO           = o.getOptAln();
067
068
069                String[][][] pdbAlnN         = new String[blockNum][2][minLength];
070                String[][][] pdbAlnO         = o.getPdbAln();
071
072                if ( ( optAlnO == null) && ( pdbAlnO == null) ){
073                        System.err.println("Can't get either optAln or pdbAln data from original AFPChain. Not enough information to recreate alignment!");
074                }
075
076
077
078                for (int blockNr = 0 ; blockNr < blockNum ; blockNr++) {
079                        for ( int eqrNr = 0 ; eqrNr < optLen[blockNr] ; eqrNr++ ) {
080
081                                if ( optAlnO != null ){
082                                        optAlnN[blockNr][0][eqrNr] = optAlnO[blockNr][1][eqrNr];
083                                        optAlnN[blockNr][1][eqrNr] = optAlnO[blockNr][0][eqrNr];
084                                }
085                                if ( pdbAlnO != null) {
086                                        pdbAlnN[blockNr][0][eqrNr] = pdbAlnO[blockNr][1][eqrNr];
087                                        pdbAlnN[blockNr][1][eqrNr] = pdbAlnO[blockNr][0][eqrNr];
088                                }
089                        }
090                }
091
092                n.setOptAln(optAlnN);
093
094                if ( pdbAlnO != null) {
095                        n.setPdbAln(pdbAlnN);
096                }
097
098
099
100                n.setAlnLength(o.getAlnLength());
101                n.setAlignScore(o.getAlignScore());
102                n.setAlignScoreUpdate(o.getAlignScoreUpdate());
103                n.setAfpSet(o.getAfpSet());
104                n.setChainRmsd(o.getChainRmsd());
105                n.setFocusRes1(o.getFocusRes2());
106                n.setFocusRes2(o.getFocusRes1());
107                n.setFocusResn(o.getFocusResn());
108                n.setGapLen(o.getGapLen());
109                n.setIdentity(o.getIdentity());
110                n.setNormAlignScore(o.getNormAlignScore());
111                n.setOptLength(o.getOptLength());
112                n.setProbability(o.getProbability());
113                n.setSimilarity(o.getSimilarity());
114                n.setTotalLenIni(o.getTotalLenIni());
115                n.setTotalRmsdIni(o.getTotalRmsdIni());
116                n.setTotalRmsdOpt(o.getTotalRmsdOpt());
117                n.setTMScore(o.getTMScore());
118
119
120                // change direction of the Matrix and shift!
121                //
122                Matrix[] maxO  = o.getBlockRotationMatrix();
123                Matrix[] maxN = new Matrix[maxO.length];
124
125                int i = -1;
126
127                Atom[] shiftO = o.getBlockShiftVector();
128                Atom[] shiftN = new Atom[shiftO.length];
129
130                for (Matrix m : maxO){
131                        i++;
132                        if ( m == null) {
133                                // alignment too short probably
134                                continue;
135                        }
136
137                        Matrix mnew = m ;
138                        Atom a = shiftO[i];
139
140                        maxN[i] = mnew.transpose();
141
142                        shiftN[i] =  Calc.invert(a);
143
144                        Calc.rotate(shiftN[i],maxN[i]);
145
146
147                }
148
149                n.setBlockRotationMatrix(maxN);
150                n.setBlockShiftVector(shiftN);
151                return n;
152
153        }
154}