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 * @return 105 */ 106 public double getAngle() { 107 return getAxisAngle().angle; 108 } 109 110 /** 111 * Returns the AxisAngle of the helix transformation 112 * @return 113 */ 114 public AxisAngle4d getAxisAngle() { 115 AxisAngle4d axis = new AxisAngle4d(); 116 axis.set(this.transformation); 117 return axis; 118 } 119 120 public int getnStart() { 121 return nStart; 122 } 123 124 public void setnStart(int nStart) { 125 this.nStart = nStart; 126 } 127 128 /** 129 * @return the fold 130 */ 131 public int getFold() { 132 return fold; 133 } 134 135 /** 136 * @param fold the fold to set 137 */ 138 public void setFold(int fold) { 139 this.fold = fold; 140 } 141 142 public int getContacts() { 143 return contacts; 144 } 145 146 public void setContacts(int contacts) { 147 this.contacts = contacts; 148 } 149 150 @Override 151 public String toString() { 152 StringBuilder sb = new StringBuilder(); 153 sb.append("Permutation : " + getPermutation() + "\n"); 154 sb.append("Repeat units : " + getRepeatUnits() + "\n"); 155 sb.append("Rise : " + getRise() + "\n"); 156 sb.append("Angle : " + Math.toDegrees(getAngle()) +"\n"); 157 sb.append("Fold : " + getFold() + "\n"); 158 return sb.toString(); 159 } 160 161 public List<List<Integer>> getLayerLines() { 162 List<List<Integer>> layerLines = new ArrayList<>(); 163 164 createLineSegments(permutation, layerLines); 165 166// System.out.println("Line segments: " + layerLines.size()); 167// for (List<Integer> lineSegment: layerLines) { 168// System.out.println(lineSegment); 169// } 170 171 int count = layerLines.size(); 172 173 // iteratively join line segments 174 do { 175 count = layerLines.size(); 176 joinLineSegments(layerLines); 177 // after joining line segments, get rid of the empty line segments left behind 178 trimEmptyLineSegments(layerLines); 179 180// System.out.println("Line segments: " + count); 181// for (List<Integer> lineSegment: layerLines) { 182// System.out.println(lineSegment); 183// } 184 } while (layerLines.size() < count); 185 186 return layerLines; 187 } 188 189 private static void createLineSegments(List<Integer> permutation, 190 List<List<Integer>> layerLines) { 191 for (int i = 0; i < permutation.size(); i++) { 192 if (permutation.get(i) != -1 ) { 193 List<Integer> lineSegment = new ArrayList<>(); 194 lineSegment.add(i); 195 lineSegment.add(permutation.get(i)); 196 layerLines.add(lineSegment); 197 } 198 } 199 } 200 201 private static void joinLineSegments(List<List<Integer>> layerLines) { 202 for (int i = 0; i < layerLines.size()-1; i++) { 203 List<Integer> lineSegmentI = layerLines.get(i); 204 if (! lineSegmentI.isEmpty()) { 205 for (int j = i + 1; j < layerLines.size(); j++) { 206 List<Integer> lineSegmentJ = layerLines.get(j); 207 if (! lineSegmentJ.isEmpty()) { 208 if (lineSegmentI.get(lineSegmentI.size()-1).equals(lineSegmentJ.get(0))) { 209// System.out.println("join right: " + lineSegmentI + " - " + lineSegmentJ); 210 lineSegmentI.addAll(lineSegmentJ.subList(1, lineSegmentJ.size())); 211// System.out.println("joned segment: " + lineSegmentI); 212 lineSegmentJ.clear(); 213 } else if ((lineSegmentI.get(0).equals(lineSegmentJ.get(lineSegmentJ.size()-1)))) { 214 lineSegmentI.addAll(0, lineSegmentJ.subList(0, lineSegmentJ.size()-1)); 215// System.out.println("join left: " + lineSegmentJ + " - " + lineSegmentI); 216// System.out.println("joned segment: " + lineSegmentI); 217 lineSegmentJ.clear(); 218 } 219 } 220 } 221 } 222 } 223 } 224 225 private static void trimEmptyLineSegments(List<List<Integer>> layerLines) { 226 for (Iterator<List<Integer>> iter = layerLines.iterator(); iter.hasNext();) { 227 if (iter.next().isEmpty()) { 228 iter.remove(); 229 } 230 } 231 } 232}