Guest User

Untitled

a guest
Jun 21st, 2018
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.15 KB | None | 0 0
  1. package calhoun.bean;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.List;
  6.  
  7. import calhoun.bean.impl.SequenceStringGenerator;
  8. import calhoun.mapping.castor.CastorClass;
  9. import calhoun.mapping.castor.CastorCollection;
  10. import calhoun.mapping.castor.CastorEnums;
  11. import calhoun.mapping.castor.CastorField;
  12. import calhoun.mapping.castor.CastorEnums.CollectionType;
  13. import calhoun.mapping.hibernate.HibernateClass;
  14. import calhoun.mapping.hibernate.HibernateCollection;
  15. import calhoun.mapping.hibernate.HibernateEnums;
  16. import calhoun.mapping.hibernate.HibernateId;
  17. import calhoun.mapping.hibernate.HibernateManyToMany;
  18. import calhoun.mapping.hibernate.HibernateProperty;
  19. import calhoun.mapping.hibernate.HibernateEnums.CascadeType;
  20. import calhoun.util.Assert;
  21. import calhoun.util.CheckException;
  22. import calhoun.util.Checkable;
  23. import calhoun.util.StringUtil;
  24.  
  25. /**
  26. * A MultipleAlignment is a collection of HalfAlignments all aligned to a single
  27. * reference frame.
  28. *
  29. * TODO: more documentation
  30. *
  31. * @author aroberts
  32. *
  33. */
  34.  
  35. @CastorClass(isAutoComplete = false, idProperty = "ref")
  36. @HibernateClass(table = "ap_multiple_alignment")
  37. public class MultipleAlignment extends AbstractEntity implements Checkable {
  38.  
  39. public static interface FeatureLabeler {
  40. public String label(Feature f);
  41. }
  42.  
  43. public static class OutputOptions {
  44. private boolean includePositionIndexes;
  45. private FeatureLabeler labeler;
  46. private int width;
  47.  
  48. public OutputOptions() {
  49. this.width = 60;
  50. this.labeler = new FeatureLabeler() {
  51. public String label(Feature f) {
  52. return f.getName();
  53. }
  54. };
  55.  
  56. this.includePositionIndexes = false;
  57. }
  58.  
  59. public FeatureLabeler getLabeler() {
  60. return labeler;
  61. }
  62.  
  63. public int getWidth() {
  64. return width;
  65. }
  66.  
  67. public boolean isIncludePositionIndexes() {
  68. return includePositionIndexes;
  69. }
  70.  
  71. public OutputOptions setIncludePositionIndexes(
  72. boolean includePositionIndexes) {
  73. this.includePositionIndexes = includePositionIndexes;
  74. return this;
  75. }
  76.  
  77. public OutputOptions setLabeler(FeatureLabeler labeler) {
  78. this.labeler = labeler;
  79. return this;
  80. }
  81.  
  82. public OutputOptions setWidth(int width) {
  83. this.width = width;
  84. return this;
  85. }
  86.  
  87. }
  88.  
  89. private List<? extends HalfAlignment> alignments;
  90. private String consensus;
  91. private String id;
  92.  
  93. private Integer length = null;
  94.  
  95. public MultipleAlignment() {
  96. }
  97.  
  98. public MultipleAlignment(List<? extends HalfAlignment> alignments) {
  99. this(alignments, null);
  100. }
  101.  
  102. /**
  103. * Construct a new MultipleAlignment from a list of HalfAlignments and a
  104. * consensus sequence. The consensus sequence is meant to be passed in from an
  105. * aligner, which should do a better job of generating it than we would here
  106. * in the code. The consensus may be null.
  107. *
  108. * @param alignments
  109. * the component HalfAlignments of this MultipleAlignment
  110. * @param consensus
  111. * a sequence to use as the consensus string
  112. */
  113. public MultipleAlignment(List<? extends HalfAlignment> alignments,
  114. String consensus) {
  115. this.alignments = Collections.unmodifiableList(alignments);
  116. length = calculateLength();
  117. this.consensus = consensus;
  118. }
  119.  
  120. private Integer calculateLength() {
  121. return alignments.iterator().next().getLength();
  122. }
  123.  
  124. public void check() {
  125. validate();
  126. for (HalfAlignment a : alignments) {
  127. a.check();
  128. }
  129. }
  130.  
  131. @CastorField(xmlName = "half-alignment")
  132. @CastorCollection(elementType = HalfAlignment.class, collectionType = CollectionType.ARRAYLIST)
  133. @HibernateCollection(elementType = HalfAlignment.class, cascade = CascadeType.SAVE_UPDATE, collectionType = HibernateEnums.CollectionType.LIST)
  134. @HibernateManyToMany(joinTable = "ap_multiple_alignment_member", ownerColumn = "ap_multiple_alignment_id", referenceColumn = "ap_half_alignment_id", indexColumn = "ap_index")
  135. public List<? extends HalfAlignment> getAlignments() {
  136. return alignments;
  137. }
  138.  
  139. @HibernateProperty(column = "ap_consensus")
  140. public String getConsensus() {
  141. return consensus;
  142. }
  143.  
  144. @Override
  145. @CastorField(nodeType = CastorEnums.NodeType.ATTRIBUTE)
  146. @HibernateId(column = "ap_id", generator = SequenceStringGenerator.class, sequence = "ap_multiple_alignment_seq")
  147. public String getId() {
  148. return id;
  149. }
  150.  
  151. @Override
  152. public Class<? extends Object> getIdType() {
  153. return MultipleAlignment.class;
  154. }
  155.  
  156. /**
  157. * Returns the length of the alignment coordinate frame for this alignment. In
  158. * a visual sense, this is the width of the 'rectangle' of sequence formed by
  159. * this multiple alignment.
  160. *
  161. * @return the length of the alignment
  162. */
  163. public int getLength() {
  164. if (length == null) {
  165. length = calculateLength();
  166. }
  167. return length;
  168. }
  169.  
  170. /**
  171. * This method is required by castor and not designed for programmer use.
  172. *
  173. * @param alignments
  174. */
  175. public void setAlignments(List<? extends HalfAlignment> alignments) {
  176. this.alignments = alignments;
  177. }
  178.  
  179. public void setConsensus(String consensus) {
  180. this.consensus = consensus;
  181. }
  182.  
  183. public void setId(String id) {
  184. this.id = id;
  185. }
  186.  
  187. /**
  188. * Creates a new MultipleAlignment object as a partition of this
  189. * MultipleAlignment. The new MultipleAlignment will contain slices of all of
  190. * the contained HalfAlignments at the specified coordinates.
  191. *
  192. * Given a multiple Alignment <code>m</code>:
  193. *
  194. * <pre>
  195. * 12345678901
  196. * AATACGCGGGC
  197. * AAGA-GGCGGC
  198. * AAT----CGGG
  199. * </pre>
  200. *
  201. * Calling <code>m.slice(3,7)</code> gives us this MultipleAlignment:
  202. *
  203. * <pre>
  204. * 12345
  205. * TACGC
  206. * GA-GG
  207. * T----
  208. * </pre>
  209. *
  210. * @param start
  211. * 1-based start coordinate
  212. * @param stop
  213. * 1-based stop coordinate
  214. * @return a new MultipleAlignment, cut from the old MultipleAlignment at the
  215. * specified coordinates
  216. */
  217. public MultipleAlignment slice(int start, int stop) {
  218. List<HalfAlignment> newSet = new ArrayList<HalfAlignment>();
  219. for (HalfAlignment h : getAlignments()) {
  220. HalfAlignment newHalf = h.slice(start, stop);
  221. newSet.add(newHalf);
  222. }
  223. String newConsensus = getConsensus().substring(start - 1, stop);
  224. return new MultipleAlignment(newSet, newConsensus);
  225. }
  226.  
  227. @Override
  228. public String toString() {
  229. return toString(new OutputOptions());
  230. }
  231.  
  232. public String toString(OutputOptions options) {
  233. String separator = " ";
  234. int start = 0;
  235. int maxLabelLength = 0;
  236. FeatureLabeler labeler = options.getLabeler();
  237. int width = options.getWidth();
  238.  
  239. StringBuilder sb = new StringBuilder();
  240. // find max label length
  241. for (HalfAlignment h : alignments) {
  242. Assert.a(labeler.label(h) != null,
  243. "Labeler produced a null label for feature " + h.getId());
  244. maxLabelLength = Math.max(maxLabelLength, labeler.label(h).length());
  245. }
  246.  
  247. while (start < getLength()) {
  248. int end = Math.min(start + width, getLength());
  249.  
  250. // optionally, include a '1234567890...' count above the alignment to make
  251. // it easy to find specific positions
  252. if (options.isIncludePositionIndexes()) {
  253. sb.append(StringUtil.repeatChars(maxLabelLength, ' '));
  254. sb.append(separator);
  255. for (int i = 1; i <= end - start; i++) {
  256. sb.append(i % 10);
  257. }
  258. sb.append("\n");
  259. }
  260.  
  261. for (HalfAlignment h : alignments) {
  262. String label = labeler.label(h);
  263. sb.append(label);
  264. sb.append(StringUtil.repeatChars(maxLabelLength - label.length(), ' '));
  265. sb.append(separator);
  266. sb.append(h.getTransformedSequence().substring(start, end));
  267. sb.append("\n");
  268. }
  269. sb.append("\n");
  270. start = end;
  271. }
  272.  
  273. return sb.toString();
  274. }
  275.  
  276. public void validate() {
  277. for (HalfAlignment a : alignments) {
  278. Assert.a(a.getLength() == getLength(), String.format(
  279. "HalfAlignment %s is not the same length as this multiple alignment",
  280. a.getId()));
  281. }
  282. Assert
  283. .a(
  284. consensus.length() == getLength(),
  285. String
  286. .format(
  287. "Consensus is not the same length as the half alignments - %d instead of %d",
  288. consensus.length(), getLength()));
  289. }
  290.  
  291. public boolean valid() {
  292. try {
  293. validate();
  294. return true;
  295. } catch (CheckException e) {
  296. return false;
  297. }
  298. }
  299. }
Add Comment
Please, Sign In to add comment