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 May 27, 2006
021 *
022 */
023package org.biojava.nbio.structure.align.helper;
024
025import org.biojava.nbio.structure.Atom;
026import org.biojava.nbio.structure.AtomImpl;
027import org.biojava.nbio.structure.Calc;
028import org.biojava.nbio.structure.jama.Matrix;
029import org.slf4j.Logger;
030import org.slf4j.LoggerFactory;
031
032/**
033 * Low level helper methods for CE and FATCAT algorithms. 
034 * 
035 * @author Andreas Prlic
036 */
037public class AlignUtils {
038        
039        private static final Logger logger = LoggerFactory.getLogger(AlignUtils.class);
040
041        /** 
042         * Get a subset of Atoms based by their positions
043         *
044         * @param caall
045         * @param idx an array where each element is a position of all the Atoms to return
046         * @return at Atom[] array
047         */
048        public static Atom[] getFragmentFromIdxList(Atom[] caall, int[] idx){
049                Atom[] subset = new Atom[idx.length];
050
051                for (int p = 0 ; p < idx.length;p++){
052
053                        int pos1 =  idx[p];
054                        subset[p] =  (Atom) caall[pos1].clone();
055                }
056                return subset;
057        }
058
059        /** 
060         * Get a continue subset of Atoms based by the starting position and the length
061         *
062         * @param caall
063         * @param pos the start position
064         * @param fragmentLength the length of the subset to extract.
065         * @return an Atom[] array
066         */
067        public static Atom[] getFragment(Atom[] caall, int pos, int fragmentLength){
068
069                if ( pos+fragmentLength > caall.length)
070                        return null;
071
072                Atom[] tmp = new Atom[fragmentLength];
073
074                for (int i=0;i< fragmentLength;i++){
075                        tmp[i] = (Atom)caall[i+pos].clone();
076                }
077                return tmp;
078
079        }
080
081
082        /** 
083         * Get a continue subset of Atoms based by the starting position and the length
084         * does not clone the original atoms.
085         *
086         * @param caall
087         * @param pos the start position
088         * @param fragmentLength the length of the subset to extract.
089         * @return an Atom[] array
090         */
091        public static Atom[] getFragmentNoClone(Atom[] caall, int pos, int fragmentLength){
092
093                if ( pos+fragmentLength > caall.length)
094                        return null;
095
096                Atom[] tmp = new Atom[fragmentLength];
097
098                for (int i=0;i< fragmentLength;i++){
099                        tmp[i] = caall[i+pos];
100                }
101                return tmp;
102
103        }
104
105        /** 
106         * Get the centroid for the set of atoms starting from position pos, length fragmentLenght
107         *
108         * @param ca
109         * @param pos
110         * @param fragmentLength
111         * @return an Atom
112         */
113        public static Atom getCenter(Atom[] ca, int pos, int fragmentLength){
114                Atom center = new AtomImpl();
115
116                if ( pos+fragmentLength > ca.length) {
117                        logger.info("pos ("+pos+"), fragL ("+fragmentLength +") > ca.length"+ca.length);
118                        return center;
119                }
120
121                Atom[] tmp = getFragmentNoClone(ca,pos,fragmentLength);
122
123                return Calc.getCentroid(tmp);
124        }
125
126
127        /**
128         * Get distances along diagonal k from coordinate array coords.
129         *
130         * @param atoms set of atoms to be used
131         * @param k number of diagonal to be used
132         */
133        public static double[] getDiagonalAtK (Atom[] atoms,int k) {
134
135                int l = atoms.length;
136
137                double[] dk = new double[(l-k)];
138
139                for ( int i = 0 ; i< (l-k); i++){
140
141                        double dist = Calc.getDistance(atoms[i],atoms[i+k]);
142                        dk[i] = dist;
143
144                }
145
146                return dk;
147        }
148
149        /**
150         * Given distance matrix diagonals dk1, dk2, get the rmsd of a fpair.
151         * i,j is the fpair start in mol1 and mol2, l is the length of the fragment
152         *
153         * @param dk1 distances of structure 1
154         * @param dk2 distance of structure 2
155         * @param i position in structure 1
156         * @param j position in structure 2
157         * @param l length of the fragments
158         * @param k diagonal used
159         * @return a double
160         */
161        public static double rms_dk_diag(double[] dk1, double[] dk2, int i, int j, int l, int k) {
162                //        dk = 0
163                //        for x in range(l-k):
164                //            dk += (dk1[x+i]-dk2[x+j])*(dk1[x+i]-dk2[x+j])
165                //        dk /= (l-k)
166                //        return math.sqrt(dk)
167
168                double dk = 0.0;
169                for (int x = 0 ; x < (l-k) ; x++)
170                        dk += (dk1[x+i]-dk2[x+j])*(dk1[x+i]-dk2[x+j]);
171
172                dk /= ( l-k);
173                return Math.sqrt(dk);
174
175        }
176
177        /**
178         * Matrix of all distances between two sets of Atoms. Does not
179         * superimpose or modify the Atoms.
180         *
181         * @param ca1
182         * @param ca2
183         * @return a Matrix
184         */
185        public static Matrix getDistanceMatrix(Atom[] ca1, Atom[] ca2){
186
187                int r = ca1.length;
188                int c = ca2.length;
189
190                Matrix out = new Matrix(r,c);
191
192                for (int i=0; i<r; i++) {
193                        Atom a1 = ca1[i];
194                        for (int j=0;j<c;j++){
195                                Atom b1 = ca2[j];
196
197                                double d = Calc.getDistance(a1,b1);
198                                out.set(i,j,d);
199                        }
200                }
201                return out;
202        }
203
204}