JAL-3748 simple test for SeqCigar preservation of start/end and name for different...
[jalview.git] / test / jalview / datamodel / SeqCigarTest.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.datamodel;
22
23 import static org.testng.Assert.assertTrue;
24 import static org.testng.AssertJUnit.assertEquals;
25 import static org.testng.AssertJUnit.assertFalse;
26
27 import jalview.gui.JvOptionPane;
28 import jalview.util.Comparison;
29
30 import org.testng.annotations.BeforeClass;
31 import org.testng.annotations.Test;
32
33 /**
34  * Unit tests for SeqCigar
35  */
36 public class SeqCigarTest
37 {
38
39   @BeforeClass(alwaysRun = true)
40   public void setUpJvOptionPane()
41   {
42     JvOptionPane.setInteractiveMode(false);
43     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
44   }
45
46   @Test(groups = { "Functional" })
47   public void testFindPosition()
48   {
49     SequenceI oseq = new Sequence("MySeq", "ASD---ASD---ASD", 37, 45);
50     oseq.createDatasetSequence();
51     SeqCigar cs = new SeqCigar(oseq);
52     assertEquals(oseq.getSequenceAsString(), cs.getSequenceString('-'));
53     for (int c = 0, cLen = oseq.getLength(); c < cLen; c++)
54     {
55       int os_p = oseq.findPosition(c);
56       int cigar_p = cs.findPosition(c);
57       if (Comparison.isGap(oseq.getCharAt(c)))
58       {
59         assertEquals("Expected gap at position " + os_p + " column " + c,
60                 -1, cigar_p);
61       }
62       else
63       {
64         assertEquals("Positions don't match for at column " + c, os_p,
65                 cigar_p);
66       }
67     }
68   }
69
70   @Test(groups= {"Functional"})
71   public void testReconstructSeq()
72   {
73     String o_seq = "asdfktryasdtqwrtsaslldddptyipqqwaslchvhttt";
74     SequenceI s = new Sequence("MySeq", o_seq, 39, 80);
75     String orig_gapped = "----asdf------ktryas---dtqwrtsasll----dddptyipqqwa----slchvhttt";
76     // name of sequence in a particular alignment should be recovered
77     SequenceI s_gapped = new Sequence("MySeqAlign", orig_gapped, 39, 80);
78     s_gapped.setDatasetSequence(s);
79     SeqCigar cg_sgapped = new SeqCigar(s_gapped);
80     assertTrue(testSeqRecovery(cg_sgapped,s_gapped,true));
81     SequenceI subseq_gapped = s_gapped.getSubSequence(44, 60);
82     SeqCigar subseq_cg_range=new SeqCigar(s_gapped,44,59);
83     assertTrue(testSeqRecovery(subseq_cg_range, subseq_gapped, true),"SeqCigar created on range of sequence failed");
84
85     // test another way of reconstructing a sequence from seqCigar
86     SequenceI[] sqs=SeqCigar.createAlignmentSequences(new SeqCigar[] {subseq_cg_range}, '-', new HiddenColumns(), null);
87     assertTrue(testSeqRecovery(subseq_cg_range, sqs[0], true),"createAlignmentSequences didn't reconstruct same sequence as for SeqCigar created on range of sequence failed (used by AlignmentView for selections)");
88
89     subseq_gapped.setName("SubSeqMySeqAlign"); // name of sequence in a particular alignment should be recovered
90     SeqCigar subseq_cg = new SeqCigar(subseq_gapped);
91     assertTrue(testSeqRecovery(subseq_cg,subseq_gapped,true));
92   }
93   /*
94    * refactored 'as is' from main method
95    * 
96    * TODO: split into separate tests
97    */
98   @Test(groups = { "Functional" })
99   public void testSomething() throws Exception
100   {
101     String o_seq = "asdfktryasdtqwrtsaslldddptyipqqwaslchvhttt";
102     Sequence s = new Sequence("MySeq", o_seq, 39, 80);
103     String orig_gapped = "----asdf------ktryas---dtqwrtsasll----dddptyipqqwa----slchvhttt";
104     Sequence s_gapped = new Sequence("MySeq", orig_gapped, 39, 80);
105     String ex_cs_gapped = "4I4M6I6M3I11M4I12M4I9M";
106     s_gapped.setDatasetSequence(s);
107     String sub_gapped_s = "------ktryas---dtqwrtsasll----dddptyipqqwa----slchvh";
108     Sequence s_subsequence_gapped = new Sequence("MySeq", sub_gapped_s, 43,
109             77);
110     s_subsequence_gapped.setDatasetSequence(s);
111
112     SeqCigar c_null = new SeqCigar(s);
113     String cs_null = c_null.getCigarstring();
114     assertEquals("Failed to recover ungapped sequence cigar operations",
115             "42M", cs_null);
116     testCigar_string(s_gapped, ex_cs_gapped);
117     SeqCigar gen_sgapped = SeqCigar.parseCigar(s, ex_cs_gapped);
118     assertEquals("Failed parseCigar", ex_cs_gapped,
119             gen_sgapped.getCigarstring());
120
121     assertTrue(testSeqRecovery(gen_sgapped, s_gapped,true));
122
123     /*
124      * Test dataset resolution
125      */
126     SeqCigar sub_gapped = new SeqCigar(s_subsequence_gapped);
127     assertTrue(testSeqRecovery(sub_gapped, s_subsequence_gapped,true));
128
129     /*
130      * Test width functions
131      */
132     assertEquals("Failed getWidth", sub_gapped_s.length(),
133             sub_gapped.getWidth());
134
135     sub_gapped.getFullWidth();
136     assertFalse("hasDeletedRegions is incorrect",
137             sub_gapped.hasDeletedRegions());
138
139     // Test start-end region SeqCigar
140     SeqCigar sub_se_gp = new SeqCigar(s_subsequence_gapped, 8, 48);
141     assertEquals(
142             "SeqCigar(seq, start, end) not properly clipped alignsequence",
143             41, sub_se_gp.getWidth());
144
145     /*
146      * TODO: can we add assertions to the sysouts that follow?
147      */
148     System.out.println("\nOriginal sequence align:\n" + sub_gapped_s
149             + "\nReconstructed window from 8 to 48\n" + "XXXXXXXX"
150             + sub_se_gp.getSequenceString('-') + "..." + "\nCigar String:"
151             + sub_se_gp.getCigarstring() + "\n");
152     SequenceI ssgp = sub_se_gp.getSeq('-');
153     System.out.println("\t " + ssgp.getSequenceAsString());
154     for (int r = 0; r < 10; r++)
155     {
156       sub_se_gp = new SeqCigar(s_subsequence_gapped, 8, 48);
157       int sl = sub_se_gp.getWidth();
158       int st = sl - 1 - r;
159       for (int rs = 0; rs < 10; rs++)
160       {
161         int e = st + rs;
162         sub_se_gp.deleteRange(st, e);
163         String ssgapedseq = sub_se_gp.getSeq('-').getSequenceAsString();
164         System.out.println(st + "," + e + "\t:" + ssgapedseq);
165         st -= 3;
166       }
167     }
168
169     SeqCigar[] set = new SeqCigar[] { new SeqCigar(s),
170         new SeqCigar(s_subsequence_gapped, 8, 48), new SeqCigar(s_gapped) };
171     Alignment al = new Alignment(set);
172     for (int i = 0; i < al.getHeight(); i++)
173     {
174       System.out.println("" + al.getSequenceAt(i).getName() + "\t"
175               + al.getSequenceAt(i).getStart() + "\t"
176               + al.getSequenceAt(i).getEnd() + "\t"
177               + al.getSequenceAt(i).getSequenceAsString());
178     }
179
180     System.out.println("Gapped.");
181     set = new SeqCigar[] { new SeqCigar(s),
182         new SeqCigar(s_subsequence_gapped, 8, 48), new SeqCigar(s_gapped) };
183     set[0].deleteRange(20, 25);
184     al = new Alignment(set);
185     for (int i = 0; i < al.getHeight(); i++)
186     {
187       System.out.println("" + al.getSequenceAt(i).getName() + "\t"
188               + al.getSequenceAt(i).getStart() + "\t"
189               + al.getSequenceAt(i).getEnd() + "\t"
190               + al.getSequenceAt(i).getSequenceAsString());
191     }
192
193     // if (!ssgapedseq.equals("ryas---dtqqwa----slchvh"))
194     // System.err.println("Subseqgaped\n------ktryas---dtqwrtsasll----dddptyipqqwa----slchvhryas---dtqwrtsasll--qwa----slchvh\n"+ssgapedseq+"\n"+sub_se_gp.getCigarstring());
195   }
196
197   /**
198    * non rigorous testing
199    * 
200    * @param seq
201    *          Sequence
202    * @param ex_cs_gapped
203    *          String
204    * @return String
205    */
206
207   protected void testCigar_string(Sequence seq, String ex_cs_gapped)
208   {
209     SeqCigar c_sgapped = new SeqCigar(seq);
210     String cs_gapped = c_sgapped.getCigarstring();
211     assertEquals("Failed getCigarstring", ex_cs_gapped, cs_gapped);
212   }
213
214   protected boolean testSeqRecovery(SeqCigar gen_sgapped, SequenceI s_gapped,boolean startEndCheck)
215   {
216     // this is non-rigorous - start and end recovery is not tested.
217     SequenceI gen_sgapped_s = gen_sgapped.getSeq('-');
218     // assertEquals("Couldn't reconstruct sequence", s_gapped.getSequence(),
219     // gen_sgapped_s);
220     if (!gen_sgapped_s.getSequenceAsString().equals(
221             s_gapped.getSequenceAsString()))
222     {
223       // TODO: investigate errors reported here, to allow full conversion to
224       // passing JUnit assertion form
225       System.err.println("Couldn't reconstruct sequence.\n"
226               + gen_sgapped_s.getSequenceAsString() + "\n"
227               + s_gapped.getSequenceAsString());
228       return false;
229     }
230     if (startEndCheck)
231     {
232       assertEquals("Start not conserved in reconstructed sequence",s_gapped.getStart(),gen_sgapped_s.getStart());
233       assertEquals("End not conserved in reconstructed sequence",s_gapped.getEnd(),gen_sgapped_s.getEnd());
234     }
235     return true;
236   }
237
238 }