db0ea49ecbe7fa3b5539fbe9ddc5ab6c509f98d3
[jalview.git] / test / jalview / structure / Mapping.java
1 package jalview.structure;
2
3 import static org.testng.AssertJUnit.assertEquals;
4 import static org.testng.AssertJUnit.assertTrue;
5
6 import jalview.datamodel.AlignmentAnnotation;
7 import jalview.datamodel.Annotation;
8 import jalview.datamodel.Sequence;
9 import jalview.datamodel.SequenceI;
10 import jalview.gui.AlignFrame;
11 import jalview.io.FileLoader;
12 import jalview.io.FormatAdapter;
13
14 import org.testng.Assert;
15 import org.testng.AssertJUnit;
16 import org.testng.annotations.Test;
17
18 import MCview.PDBfile;
19
20 public class Mapping
21 {
22
23   /*
24    * more test data
25    * 
26    * 1QCF|A/101-121 SFQKGDQMVVLEESGEWWKAR Ser 114 jumps to Gly 116 at position
27    * 115 in PDB Res Numbering secondary structure numbers in jmol seem to be in
28    * msd numbering, not pdb res numbering.
29    */
30   @Test(enabled = false)
31   public void pdbEntryPositionMap() throws Exception
32   {
33     Assert.fail("This test intentionally left to fail");
34     for (int offset = 0; offset < 20; offset += 6)
35     {
36       // check we put the secondary structure in the right position
37       Sequence uprot = new Sequence("TheProtSeq",
38               "DAWEIPRESLKLEKKLGAGQFGEVWMATYNKHTKVAVKTMKPGSMSVEAFLAEANVMKTL");
39       uprot.setStart(offset + 258); // make it harder - create a fake
40                                     // relocation problem for jalview to
41                                     // deal with
42       uprot.setEnd(uprot.getStart() + uprot.getLength() - 1);
43       // original numbers taken from
44       // http://www.ebi.ac.uk/pdbe-srv/view/entry/1qcf/secondary.html
45       // these are in numbering relative to the subsequence above
46       int coils[] =
47       { 266, 275, 278, 287, 289, 298, 302, 316 }, helices[] = new int[]
48       { 303, 315 }, sheets[] = new int[]
49       { 267, 268, 269, 270 };
50
51       StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
52       PDBfile pmap = ssm.setMapping(true, new SequenceI[]
53       { uprot }, new String[]
54       { "A" }, "test/jalview/ext/jmol/1QCF.pdb",
55               jalview.io.FormatAdapter.FILE);
56       assertTrue(pmap != null);
57       SequenceI protseq = pmap.getSeqsAsArray()[0];
58       AlignmentAnnotation pstra = protseq
59               .getAnnotation("Secondary Structure")[0];
60       int pinds, pinde;
61       pstra.restrict((pinds = protseq.findIndex(258) - 1),
62               pinde = (protseq.findIndex(317) - 1));
63       int op;
64       System.out.println("PDB Annot");
65       for (char c : protseq.getSubSequence(pinds, pinde).getSequence())
66       {
67         System.out.print(c + ", ");
68       }
69       System.out.println("\n" + pstra + "\n\nsubsequence\n");
70       for (char c : uprot.getSequence())
71       {
72         System.out.print(c + ", ");
73       }
74       System.out.println("");
75       for (AlignmentAnnotation ss : uprot
76               .getAnnotation("Secondary Structure"))
77       {
78         ss.adjustForAlignment();
79         System.out.println("Uniprot Annot\n" + ss);
80         assertTrue(ss.hasIcons);
81         char expected = 'H';
82         for (int p : helices)
83         {
84           Annotation a = ss.annotations[op = (uprot.findIndex(offset + p) - 1)];
85           assertTrue(
86                   "Expected a helix at position " + p + uprot.getCharAt(op)
87                           + " but got coil", a != null);
88           assertEquals("Expected a helix at position " + p,
89                   a.secondaryStructure, expected);
90         }
91         expected = 'E';
92         for (int p : sheets)
93         {
94           Annotation a = ss.annotations[uprot.findIndex(offset + p) - 1];
95           assertTrue(
96                   "Expected a strand at position " + p + " but got coil",
97                   a != null);
98           assertEquals("Expected a strand at position " + p,
99                   a.secondaryStructure, expected);
100         }
101         expected = ' ';
102         for (int p : coils)
103         {
104           Annotation a = ss.annotations[uprot.findIndex(offset + p) - 1];
105           assertTrue("Expected coil at position " + p + " but got "
106                   + a.secondaryStructure, a == null);
107         }
108       }
109     }
110   }
111
112   @Test(enabled = false)
113   public void testPDBentryMapping() throws Exception
114   {
115     Assert.fail("This test intentionally left to fail");
116     Sequence sq = new Sequence(
117             "1GAQ A subseq 126 to 219",
118             "EIVKGVCSNFLCDLQPGDNVQITGPVGKEMLMPKDPNATIIMLATGTGIAPFRSFLWKMFFEKHDDYKFNGLGWLFLGVPTSSSLLYKEEFGKM");
119     Sequence sq1 = new Sequence(sq);
120     String inFile;
121     StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
122     // Associate the 1GAQ pdb file with the subsequence 'imported' from another
123     // source
124     PDBfile pde = ssm.setMapping(true, new SequenceI[]
125     { sq }, new String[]
126     { "A" }, inFile = "examples/1gaq.txt", jalview.io.FormatAdapter.FILE);
127     assertTrue("PDB File couldn't be found", pde != null);
128     StructureMapping[] mp = ssm.getMapping(inFile);
129     assertTrue("No mappings made.", mp != null && mp.length > 0);
130     int nsecStr = 0, nsTemp = 0;
131     // test for presence of transferred annotation on sequence
132     for (AlignmentAnnotation alan : sq.getAnnotation())
133     {
134       if (alan.hasIcons)
135       {
136         nsecStr++;
137       }
138       if (alan.graph == alan.LINE_GRAPH)
139       {
140         nsTemp++;
141       }
142     }
143     assertEquals(
144             "Only one secondary structure should be transferred to associated sequence.",
145             1, nsecStr);
146     assertEquals(
147             "Only two line graphs should be transferred to associated sequence.",
148             2, nsTemp);
149     // Now test the transfer function and compare annotated positions
150     for (StructureMapping origMap : mp)
151     {
152       if (origMap.getSequence() == sq)
153       {
154         assertEquals("Mapping was incomplete.", sq.getLength() - 1,
155                 (origMap.getPDBResNum(sq.getEnd()) - origMap
156                         .getPDBResNum(sq.getStart())));
157         // sanity check - if this fails, mapping from first position in sequence
158         // we want to transfer to is not where we expect
159         assertEquals(1, origMap.getSeqPos(126));
160         SequenceI firstChain = pde.getSeqs().get(0);
161         // Compare the annotated positions on the PDB chain sequence with the
162         // annotation on the associated sequence
163         for (AlignmentAnnotation alan : firstChain.getAnnotation())
164         {
165           AlignmentAnnotation transfer = origMap.transfer(alan);
166           System.out.println("pdb:" + firstChain.getSequenceAsString());
167           System.out.println("ann:" + alan.toString());
168           System.out.println("pdb:" + sq.getSequenceAsString());
169           System.out.println("ann:" + transfer.toString());
170
171           for (int p = 0, pSize = firstChain.getLength(); p < pSize; p++)
172           {
173             // walk along the pdb chain's jalview sequence
174             int rseqpos;
175             int fpos = origMap.getSeqPos(rseqpos = firstChain
176                     .findPosition(p));
177             // only look at positions where there is a corresponding position in
178             // mapping
179             if (fpos < 1)
180             {
181               continue;
182             }
183             // p is index into PDB residue entries
184             // rseqpos is pdb sequence position for position p
185             // fpos is sequence position for associated position for rseqpos
186             // tanpos is the column for the mapped sequence position
187             int tanpos = sq.findIndex(fpos) - 1;
188             if (tanpos < 0 || transfer.annotations.length <= tanpos)
189             {
190               // gone beyond mapping to the sequence
191               break;
192             }
193
194             Annotation a = transfer.annotations[tanpos], b = alan.annotations[p];
195             assertEquals("Non-equivalent annotation element at " + p + "("
196                     + rseqpos + ")" + " expected at " + fpos + " (alIndex "
197                     + tanpos + ")",
198                     a == null ? a : a.toString(),
199                     b == null ? b : b.toString());
200             System.out.print("(" + a + "|" + b + ")");
201           }
202
203         }
204       }
205     }
206   }
207
208   /**
209    * corner case for pdb mapping - revealed a problem with the AlignSeq->Mapping
210    * transform
211    * 
212    */
213   @Test
214   public void mapFer1From3W5V() throws Exception
215   {
216     AlignFrame seqf = new FileLoader(false)
217             .LoadFileWaitTillLoaded(
218                     ">FER1_MAIZE/1-150 Ferredoxin-1, chloroplast precursor\nMATVLGSPRAPAFFFSSSSLRAAPAPTAVALPAAKVGIMGRSASSRRRLRAQATYNVKLITPEGEVELQVPD\nDVYILDQAEEDGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSYLDDGQIADGWVLTCHAYPTSDVVIETHKE\nEELTGA",
219                     FormatAdapter.PASTE, "FASTA");
220     SequenceI newseq = seqf.getViewport().getAlignment().getSequenceAt(0);
221     StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
222     PDBfile pmap = ssm.setMapping(true, new SequenceI[]
223     { newseq }, new String[]
224     { null }, "examples/3W5V.pdb",
225             jalview.io.FormatAdapter.FILE);
226     if (pmap == null)
227     {
228       AssertJUnit.fail("Couldn't make a mapping for 3W5V to FER1_MAIZE");
229     }
230   }
231
232   /**
233    * compare reference annotation for imported pdb sequence to identical
234    * seuqence with transferred annotation from mapped pdb file
235    */
236   @Test
237   public void compareTransferredToRefPDBAnnot() throws Exception
238   {
239     AlignFrame ref = new FileLoader(false)
240             .LoadFileWaitTillLoaded("test/jalview/ext/jmol/1QCF.pdb",
241                     jalview.io.FormatAdapter.FILE);
242     SequenceI refseq = ref.getViewport().getAlignment().getSequenceAt(0);
243     SequenceI newseq = new Sequence(refseq.getName() + "Copy",
244             refseq.getSequenceAsString());
245     // make it harder by shifting the copy vs the reference
246     newseq.setStart(refseq.getStart() + 25);
247     newseq.setEnd(refseq.getLength() + 25 + refseq.getStart());
248     StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
249     ssm.setProcessSecondaryStructure(true);
250     ssm.setAddTempFacAnnot(true);
251     PDBfile pmap = ssm.setMapping(true, new SequenceI[]
252     { newseq }, new String[]
253     { null }, "test/jalview/ext/jmol/1QCF.pdb",
254             jalview.io.FormatAdapter.FILE);
255     assertTrue(pmap != null);
256     assertEquals("Original and copied sequence of different lengths.",
257             refseq.getLength(), newseq.getLength());
258     assertTrue(refseq.getAnnotation() != null
259             && refseq.getAnnotation().length > 0);
260     assertTrue(newseq.getAnnotation() != null
261             && newseq.getAnnotation().length > 0);
262     for (AlignmentAnnotation oannot : refseq.getAnnotation())
263     {
264       for (AlignmentAnnotation tannot : newseq.getAnnotation(oannot.label))
265       {
266         for (int p = 0, pSize = refseq.getLength(); p < pSize; p++)
267         {
268           Annotation orig = oannot.annotations[p], tran = tannot.annotations[p];
269           assertTrue("Mismatch: coil and non coil site " + p, orig == tran
270                   || orig != null && tran != null);
271           if (tran != null)
272           {
273             assertEquals("Mismatch in secondary structure at site " + p,
274                     tran.secondaryStructure, orig.secondaryStructure);
275           }
276         }
277       }
278     }
279   }
280 }