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 */
021
022package org.biojava.nbio.structure.symmetry.core;
023
024import javax.vecmath.AxisAngle4d;
025import javax.vecmath.Matrix4d;
026import java.util.ArrayList;
027import java.util.Iterator;
028import java.util.List;
029
030/**
031 *
032 * @author Peter
033 */
034public class Helix {
035        private QuatSymmetryScores scores = new QuatSymmetryScores();
036        private List<Integer> permutation;
037        private List<List<Integer>> repeatUnits;
038        private Matrix4d transformation;
039        private double rise;
040        private int nStart;
041        private int fold;
042        private int contacts;
043
044        /**
045         * @return the scores
046         */
047        public QuatSymmetryScores getScores() {
048                return scores;
049        }
050
051        /**
052         * @param scores the scores to set
053         */
054        public void setScores(QuatSymmetryScores scores) {
055                this.scores = scores;
056        }
057
058        /**
059         * @return the permutation
060         */
061        public List<Integer> getPermutation() {
062                return permutation;
063        }
064
065        /**
066         * @param permutation the permutation to set
067         */
068        public void setPermutation(List<Integer> permutation) {
069                this.permutation = permutation;
070        }
071
072        public List<List<Integer>> getRepeatUnits() {
073                return repeatUnits;
074        }
075
076        public void setRepeatUnits(List<List<Integer>> repeatUnits) {
077                this.repeatUnits = repeatUnits;
078        }
079
080        /**
081         * @return the transformation
082         */
083        public Matrix4d getTransformation() {
084                return transformation;
085        }
086
087        /**
088         * @param transformation the transformation to set
089         */
090        public void setTransformation(Matrix4d transformation) {
091                this.transformation = transformation;
092        }
093
094        public double getRise() {
095                return rise;
096        }
097
098        public void setRise(double rise) {
099                this.rise = rise;
100        }
101
102        /**
103         * Returns the pitch angle of the helix
104         * @param transformation helix transformation
105         * @return
106         */
107        public double getAngle() {
108                return getAxisAngle().angle;
109        }
110
111        /**
112         * Returns the AxisAngle of the helix transformation
113         * @param transformation helix transformation
114         * @return
115         */
116        public AxisAngle4d getAxisAngle() {
117                AxisAngle4d axis = new AxisAngle4d();
118                axis.set(this.transformation);
119                return axis;
120        }
121
122        public int getnStart() {
123                return nStart;
124        }
125
126        public void setnStart(int nStart) {
127                this.nStart = nStart;
128        }
129
130        /**
131         * @return the fold
132         */
133        public int getFold() {
134                return fold;
135        }
136
137        /**
138         * @param fold the fold to set
139         */
140        public void setFold(int fold) {
141                this.fold = fold;
142        }
143
144        public int getContacts() {
145                return contacts;
146        }
147
148        public void setContacts(int contacts) {
149                this.contacts = contacts;
150        }
151
152        @Override
153        public String toString() {
154                StringBuilder sb = new StringBuilder();
155                sb.append("Permutation   : " + getPermutation() + "\n");
156                sb.append("Repeat units  : " + getRepeatUnits() + "\n");
157                sb.append("Rise          : " + getRise() + "\n");
158                sb.append("Angle         : " + Math.toDegrees(getAngle()) +"\n");
159                sb.append("Fold          : " + getFold() + "\n");
160                return sb.toString();
161        }
162
163        public List<List<Integer>> getLayerLines() {
164                List<List<Integer>> layerLines = new ArrayList<List<Integer>>();
165
166                createLineSegments(permutation, layerLines);
167
168//              System.out.println("Line segments: " + layerLines.size());
169//              for (List<Integer> lineSegment: layerLines) {
170//                      System.out.println(lineSegment);
171//              }
172
173                int count = layerLines.size();
174
175                // iteratively join line segments
176                do {
177                        count = layerLines.size();
178                        joinLineSegments(layerLines);
179                        // after joining line segments, get rid of the empty line segments left behind
180                        trimEmptyLineSegments(layerLines);
181
182//                      System.out.println("Line segments: " + count);
183//                      for (List<Integer> lineSegment: layerLines) {
184//                              System.out.println(lineSegment);
185//                      }
186                } while (layerLines.size() < count);
187
188                return layerLines;
189        }
190
191        private static void createLineSegments(List<Integer> permutation,
192                        List<List<Integer>> layerLines) {
193                for (int i = 0; i < permutation.size(); i++) {
194                        if (permutation.get(i) != -1 ) {
195                                List<Integer> lineSegment = new ArrayList<Integer>();
196                                lineSegment.add(i);
197                                lineSegment.add(permutation.get(i));
198                                layerLines.add(lineSegment);
199                        }
200                }
201        }
202
203        private static void joinLineSegments(List<List<Integer>> layerLines) {
204                for (int i = 0; i < layerLines.size()-1; i++) {
205                        List<Integer> lineSegmentI = layerLines.get(i);
206                        if (! lineSegmentI.isEmpty()) {
207                                for (int j = i + 1; j < layerLines.size(); j++) {
208                                        List<Integer> lineSegmentJ = layerLines.get(j);
209                                        if (! lineSegmentJ.isEmpty()) {
210                                                if (lineSegmentI.get(lineSegmentI.size()-1).equals(lineSegmentJ.get(0))) {
211//                                                      System.out.println("join right: " + lineSegmentI + " - " + lineSegmentJ);
212                                                        lineSegmentI.addAll(lineSegmentJ.subList(1,  lineSegmentJ.size()));
213//                                                      System.out.println("joned segment: " + lineSegmentI);
214                                                        lineSegmentJ.clear();
215                                                } else if ((lineSegmentI.get(0).equals(lineSegmentJ.get(lineSegmentJ.size()-1)))) {
216                                                        lineSegmentI.addAll(0, lineSegmentJ.subList(0,  lineSegmentJ.size()-1));
217//                                                      System.out.println("join left: " + lineSegmentJ + " - " + lineSegmentI);
218//                                                      System.out.println("joned segment: " + lineSegmentI);
219                                                        lineSegmentJ.clear();
220                                                }
221                                        }
222                                }
223                        }
224                }
225        }
226
227        private static void trimEmptyLineSegments(List<List<Integer>> layerLines) {
228                for (Iterator<List<Integer>> iter = layerLines.iterator(); iter.hasNext();) {
229                        if (iter.next().isEmpty()) {
230                                iter.remove();
231                        }
232                }
233        }
234}