Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
VamsasAppDatastore | 87 | 894 | 372 |
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.io; | |
22 | ||
23 | import jalview.bin.Console; | |
24 | import jalview.datamodel.AlignedCodonFrame; | |
25 | import jalview.datamodel.AlignmentAnnotation; | |
26 | import jalview.datamodel.GraphLine; | |
27 | import jalview.datamodel.SequenceI; | |
28 | import jalview.gui.AlignFrame; | |
29 | import jalview.gui.AlignViewport; | |
30 | import jalview.gui.Desktop; | |
31 | import jalview.gui.TreePanel; | |
32 | import jalview.io.vamsas.Datasetsequence; | |
33 | import jalview.io.vamsas.DatastoreItem; | |
34 | import jalview.io.vamsas.DatastoreRegistry; | |
35 | import jalview.io.vamsas.Rangetype; | |
36 | import jalview.project.Jalview2XML; | |
37 | import jalview.util.MessageManager; | |
38 | import jalview.viewmodel.AlignmentViewport; | |
39 | ||
40 | import java.io.IOException; | |
41 | import java.util.Enumeration; | |
42 | import java.util.HashMap; | |
43 | import java.util.Hashtable; | |
44 | import java.util.IdentityHashMap; | |
45 | import java.util.Iterator; | |
46 | import java.util.List; | |
47 | import java.util.Vector; | |
48 | import java.util.jar.JarInputStream; | |
49 | import java.util.jar.JarOutputStream; | |
50 | ||
51 | import uk.ac.vamsas.client.IClientAppdata; | |
52 | import uk.ac.vamsas.client.IClientDocument; | |
53 | import uk.ac.vamsas.client.Vobject; | |
54 | import uk.ac.vamsas.client.VorbaId; | |
55 | import uk.ac.vamsas.objects.core.Alignment; | |
56 | import uk.ac.vamsas.objects.core.AlignmentSequence; | |
57 | import uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation; | |
58 | import uk.ac.vamsas.objects.core.AnnotationElement; | |
59 | import uk.ac.vamsas.objects.core.DataSet; | |
60 | import uk.ac.vamsas.objects.core.DataSetAnnotations; | |
61 | import uk.ac.vamsas.objects.core.DbRef; | |
62 | import uk.ac.vamsas.objects.core.Entry; | |
63 | import uk.ac.vamsas.objects.core.Glyph; | |
64 | import uk.ac.vamsas.objects.core.Local; | |
65 | import uk.ac.vamsas.objects.core.MapType; | |
66 | import uk.ac.vamsas.objects.core.Mapped; | |
67 | import uk.ac.vamsas.objects.core.Property; | |
68 | import uk.ac.vamsas.objects.core.Provenance; | |
69 | import uk.ac.vamsas.objects.core.RangeAnnotation; | |
70 | import uk.ac.vamsas.objects.core.RangeType; | |
71 | import uk.ac.vamsas.objects.core.Seg; | |
72 | import uk.ac.vamsas.objects.core.Sequence; | |
73 | import uk.ac.vamsas.objects.core.SequenceType; | |
74 | import uk.ac.vamsas.objects.core.VAMSAS; | |
75 | import uk.ac.vamsas.objects.utils.Properties; | |
76 | ||
77 | /* | |
78 | * | |
79 | * static { | |
80 | * org.exolab.castor.util.LocalConfiguration.getInstance().getProperties().setProperty( | |
81 | * "org.exolab.castor.serializer", "org.apache.xml.serialize.XMLSerilazizer"); } | |
82 | * | |
83 | */ | |
84 | /* | |
85 | * TODO: check/verify consistency for vamsas sync with group associated alignment annotation | |
86 | */ | |
87 | public class VamsasAppDatastore | |
88 | { | |
89 | /** | |
90 | * Type used for general jalview generated annotation added to vamsas document | |
91 | */ | |
92 | public static final String JALVIEW_ANNOTATION_ROW = "JalviewAnnotation"; | |
93 | ||
94 | /** | |
95 | * AlignmentAnnotation property to indicate that values should not be | |
96 | * interpolated | |
97 | */ | |
98 | public static final String DISCRETE_ANNOTATION = "discrete"; | |
99 | ||
100 | /** | |
101 | * continuous property - optional to specify that annotation should be | |
102 | * represented as a continous graph line | |
103 | */ | |
104 | private static final String CONTINUOUS_ANNOTATION = "continuous"; | |
105 | ||
106 | private static final String THRESHOLD = "threshold"; | |
107 | ||
108 | /** | |
109 | * template for provenance entries written to vamsas session document | |
110 | */ | |
111 | Entry provEntry = null; | |
112 | ||
113 | /** | |
114 | * Instance of the session document being synchronized with | |
115 | */ | |
116 | IClientDocument cdoc; | |
117 | ||
118 | /** | |
119 | * map Vorba (vamsas object xml ref) IDs to live jalview object references | |
120 | */ | |
121 | Hashtable vobj2jv; | |
122 | ||
123 | /** | |
124 | * map live jalview object references to Vorba IDs | |
125 | */ | |
126 | IdentityHashMap jv2vobj; | |
127 | ||
128 | /** | |
129 | * map jalview sequence set ID (which is vorba ID for alignment) to last | |
130 | * recorded hash value for the alignment viewport (the undo/redo hash value) | |
131 | */ | |
132 | Hashtable alignRDHash; | |
133 | ||
134 | 0 | public VamsasAppDatastore(IClientDocument cdoc, Hashtable vobj2jv, |
135 | IdentityHashMap jv2vobj, Entry provEntry, Hashtable alignRDHash) | |
136 | { | |
137 | 0 | this.cdoc = cdoc; |
138 | 0 | this.vobj2jv = vobj2jv; |
139 | 0 | this.jv2vobj = jv2vobj; |
140 | 0 | this.provEntry = provEntry; |
141 | 0 | this.alignRDHash = alignRDHash; |
142 | 0 | buildSkipList(); |
143 | } | |
144 | ||
145 | /** | |
146 | * the skipList used to skip over views from Jalview Appdata's that we've | |
147 | * already syncrhonized | |
148 | */ | |
149 | Hashtable skipList; | |
150 | ||
151 | 0 | private void buildSkipList() |
152 | { | |
153 | 0 | skipList = new Hashtable(); |
154 | 0 | AlignFrame[] al = Desktop.getDesktopAlignFrames(); |
155 | 0 | for (int f = 0; al != null && f < al.length; f++) |
156 | { | |
157 | 0 | skipList.put(al[f].getViewport().getSequenceSetId(), al[f]); |
158 | } | |
159 | } | |
160 | ||
161 | /** | |
162 | * @return the Vobject bound to Jalview datamodel object | |
163 | */ | |
164 | 0 | protected Vobject getjv2vObj(Object jvobj) |
165 | { | |
166 | 0 | if (jv2vobj.containsKey(jvobj)) |
167 | { | |
168 | 0 | return cdoc.getObject((VorbaId) jv2vobj.get(jvobj)); |
169 | } | |
170 | // check if we're working with a string - then workaround | |
171 | // the use of IdentityHashTable because different strings | |
172 | // have different object IDs. | |
173 | 0 | if (jvobj instanceof String) |
174 | { | |
175 | 0 | Object seqsetidobj = null; |
176 | 0 | seqsetidobj = getVamsasObjectBinding().get(jvobj); |
177 | 0 | if (seqsetidobj != null) |
178 | { | |
179 | 0 | if (seqsetidobj instanceof String) |
180 | { | |
181 | // what is expected. object returned by av.getSequenceSetId() - | |
182 | // reverse lookup to get the 'registered' instance of this string | |
183 | 0 | Vobject obj = getjv2vObj(seqsetidobj); |
184 | 0 | if (obj != null && !(obj instanceof Alignment)) |
185 | { | |
186 | 0 | Console.warn( |
187 | "IMPLEMENTATION ERROR?: Unexpected mapping for unmapped jalview string object content:" | |
188 | + seqsetidobj + " to object " + obj); | |
189 | } | |
190 | 0 | return obj; |
191 | } | |
192 | else | |
193 | { | |
194 | 0 | Console.warn("Unexpected mapping for Jalview String Object ID " |
195 | + seqsetidobj + " to another jalview dataset object " | |
196 | + seqsetidobj); | |
197 | } | |
198 | } | |
199 | } | |
200 | ||
201 | 0 | if (Console.isDebugEnabled()) |
202 | { | |
203 | 0 | Console.debug( |
204 | "Returning null VorbaID binding for jalview object " + jvobj); | |
205 | } | |
206 | 0 | return null; |
207 | } | |
208 | ||
209 | /** | |
210 | * | |
211 | * @param vobj | |
212 | * @return Jalview datamodel object bound to the vamsas document object | |
213 | */ | |
214 | 0 | protected Object getvObj2jv(uk.ac.vamsas.client.Vobject vobj) |
215 | { | |
216 | 0 | VorbaId id = vobj.getVorbaId(); |
217 | 0 | if (id == null) |
218 | { | |
219 | 0 | id = cdoc.registerObject(vobj); |
220 | 0 | Console.debug( |
221 | "Registering new object and returning null for getvObj2jv"); | |
222 | 0 | return null; |
223 | } | |
224 | 0 | if (vobj2jv.containsKey(vobj.getVorbaId())) |
225 | { | |
226 | 0 | return vobj2jv.get(vobj.getVorbaId()); |
227 | } | |
228 | 0 | return null; |
229 | } | |
230 | ||
231 | 0 | protected void bindjvvobj(Object jvobj, uk.ac.vamsas.client.Vobject vobj) |
232 | { | |
233 | 0 | VorbaId id = vobj.getVorbaId(); |
234 | 0 | if (id == null) |
235 | { | |
236 | 0 | id = cdoc.registerObject(vobj); |
237 | 0 | if (id == null || vobj.getVorbaId() == null |
238 | || cdoc.getObject(id) != vobj) | |
239 | { | |
240 | 0 | Console.error("Failed to get id for " |
241 | 0 | + (vobj.isRegisterable() ? "registerable" |
242 | : "unregisterable") | |
243 | + " object " + vobj); | |
244 | } | |
245 | } | |
246 | ||
247 | 0 | if (vobj2jv.containsKey(vobj.getVorbaId()) |
248 | && !((VorbaId) vobj2jv.get(vobj.getVorbaId())).equals(jvobj)) | |
249 | { | |
250 | 0 | Console.debug( |
251 | "Warning? Overwriting existing vamsas id binding for " | |
252 | + vobj.getVorbaId(), | |
253 | new Exception(MessageManager.getString( | |
254 | "exception.overwriting_vamsas_id_binding"))); | |
255 | } | |
256 | 0 | else if (jv2vobj.containsKey(jvobj) |
257 | && !((VorbaId) jv2vobj.get(jvobj)).equals(vobj.getVorbaId())) | |
258 | { | |
259 | 0 | Console.debug( |
260 | "Warning? Overwriting existing jalview object binding for " | |
261 | + jvobj, | |
262 | new Exception("Overwriting jalview object binding.")); | |
263 | } | |
264 | /* | |
265 | * Cache.error("Attempt to make conflicting object binding! "+vobj+" id " | |
266 | * +vobj.getVorbaId()+" already bound to "+getvObj2jv(vobj)+" and "+jvobj+" | |
267 | * already bound to "+getjv2vObj(jvobj),new Exception("Excessive call to | |
268 | * bindjvvobj")); } | |
269 | */ | |
270 | // we just update the hash's regardless! | |
271 | 0 | Console.debug("Binding " + vobj.getVorbaId() + " to " + jvobj); |
272 | 0 | vobj2jv.put(vobj.getVorbaId(), jvobj); |
273 | // JBPNote - better implementing a hybrid invertible hash. | |
274 | 0 | jv2vobj.put(jvobj, vobj.getVorbaId()); |
275 | } | |
276 | ||
277 | /** | |
278 | * put the alignment viewed by AlignViewport into cdoc. | |
279 | * | |
280 | * @param av | |
281 | * alignViewport to be stored | |
282 | * @param aFtitle | |
283 | * title for alignment | |
284 | * @return true if alignment associated with viewport was stored/synchronized | |
285 | * to document | |
286 | */ | |
287 | 0 | public boolean storeVAMSAS(AlignViewport av, String aFtitle) |
288 | { | |
289 | 0 | try |
290 | { | |
291 | 0 | jalview.datamodel.AlignmentI jal = av.getAlignment(); |
292 | 0 | jalview.datamodel.AlignmentI jds = jal.getDataset(); |
293 | 0 | boolean nw = false; |
294 | 0 | VAMSAS root = null; // will be resolved based on Dataset Parent. |
295 | // ///////////////////////////////////////// | |
296 | // SAVE THE DATASET | |
297 | 0 | DataSet dataset = null; |
298 | 0 | if (jds == null) |
299 | { | |
300 | 0 | Console.warn("Creating new dataset for an alignment."); |
301 | 0 | jal.setDataset(null); |
302 | 0 | jds = jal.getDataset(); |
303 | } | |
304 | ||
305 | // try and get alignment and association for sequence set id | |
306 | ||
307 | 0 | Alignment alignment = (Alignment) getjv2vObj(av.getSequenceSetId()); |
308 | 0 | if (alignment != null) |
309 | { | |
310 | 0 | dataset = (DataSet) alignment.getV_parent(); |
311 | } | |
312 | else | |
313 | { | |
314 | // is the dataset already registered | |
315 | 0 | dataset = (DataSet) getjv2vObj(jds); |
316 | } | |
317 | ||
318 | 0 | if (dataset == null) |
319 | { | |
320 | // it might be that one of the dataset sequences does actually have a | |
321 | // binding, so search for it indirectly. If it does, then the local | |
322 | // jalview dataset | |
323 | // must be merged with the existing vamsas dataset. | |
324 | 0 | jalview.datamodel.SequenceI[] jdatset = jds.getSequencesArray(); |
325 | 0 | for (int i = 0; i < jdatset.length; i++) |
326 | { | |
327 | 0 | Vobject vbound = getjv2vObj(jdatset[i]); |
328 | 0 | if (vbound != null) |
329 | { | |
330 | 0 | if (vbound instanceof uk.ac.vamsas.objects.core.Sequence) |
331 | { | |
332 | 0 | if (dataset == null) |
333 | { | |
334 | 0 | dataset = (DataSet) vbound.getV_parent(); |
335 | } | |
336 | else | |
337 | { | |
338 | 0 | if (vbound.getV_parent() != null |
339 | && dataset != vbound.getV_parent()) | |
340 | { | |
341 | 0 | throw new Error( |
342 | "IMPLEMENTATION ERROR: Cannot map an alignment of sequences from different datasets into a single alignment in the vamsas document."); | |
343 | } | |
344 | } | |
345 | } | |
346 | } | |
347 | } | |
348 | } | |
349 | ||
350 | 0 | if (dataset == null) |
351 | { | |
352 | 0 | Console.warn("Creating new vamsas dataset for alignment view " |
353 | + av.getSequenceSetId()); | |
354 | // we create a new dataset on the default vamsas root. | |
355 | 0 | root = cdoc.getVamsasRoots()[0]; // default vamsas root for modifying. |
356 | 0 | dataset = new DataSet(); |
357 | 0 | root.addDataSet(dataset); |
358 | 0 | bindjvvobj(jds, dataset); |
359 | 0 | dataset.setProvenance(dummyProvenance()); |
360 | // dataset.getProvenance().addEntry(provEntry); | |
361 | 0 | nw = true; |
362 | } | |
363 | else | |
364 | { | |
365 | 0 | root = (VAMSAS) dataset.getV_parent(); |
366 | } | |
367 | // update dataset | |
368 | 0 | Sequence sequence; |
369 | // set new dataset and alignment sequences based on alignment Nucleotide | |
370 | // flag. | |
371 | // this *will* break when alignment contains both nucleotide and amino | |
372 | // acid sequences. | |
373 | 0 | String dict = jal.isNucleotide() |
374 | ? uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA | |
375 | : uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA; | |
376 | 0 | Vector dssmods = new Vector(); |
377 | 0 | for (int i = 0; i < jal.getHeight(); i++) |
378 | { | |
379 | 0 | SequenceI sq = jal.getSequenceAt(i).getDatasetSequence(); // only insert |
380 | // referenced | |
381 | // sequences | |
382 | // to dataset. | |
383 | 0 | Datasetsequence dssync = new jalview.io.vamsas.Datasetsequence(this, |
384 | sq, dict, dataset); | |
385 | 0 | sequence = (Sequence) dssync.getVobj(); |
386 | 0 | if (dssync.getModified()) |
387 | { | |
388 | 0 | dssmods.addElement(sequence); |
389 | } | |
390 | 0 | ; |
391 | } | |
392 | 0 | if (dssmods.size() > 0) |
393 | { | |
394 | 0 | if (!nw) |
395 | { | |
396 | 0 | Entry pentry = this.addProvenance(dataset.getProvenance(), |
397 | "updated sequences"); | |
398 | // pentry.addInput(vInput); could write in which sequences were | |
399 | // modified. | |
400 | 0 | dssmods.removeAllElements(); |
401 | } | |
402 | } | |
403 | // dataset.setProvenance(getVamsasProvenance(jal.getDataset().getProvenance())); | |
404 | // //////////////////////////////////////////// | |
405 | 0 | if (alignmentWillBeSkipped(av)) |
406 | { | |
407 | // TODO: trees could be written - but for the moment we just | |
408 | 0 | addToSkipList(av); |
409 | // add to the JalviewXML skipList and .. | |
410 | 0 | return false; |
411 | } | |
412 | ||
413 | 0 | if (alignment == null) |
414 | { | |
415 | 0 | alignment = new Alignment(); |
416 | 0 | bindjvvobj(av.getSequenceSetId(), alignment); |
417 | 0 | if (alignment.getProvenance() == null) |
418 | { | |
419 | 0 | alignment.setProvenance(new Provenance()); |
420 | } | |
421 | 0 | addProvenance(alignment.getProvenance(), "added"); // TODO: insert some |
422 | // sensible source | |
423 | // here | |
424 | 0 | dataset.addAlignment(alignment); |
425 | { | |
426 | 0 | Property title = new Property(); |
427 | 0 | title.setName("title"); |
428 | 0 | title.setType("string"); |
429 | 0 | title.setContent(aFtitle); |
430 | 0 | alignment.addProperty(title); |
431 | } | |
432 | 0 | alignment.setGapChar(String.valueOf(av.getGapCharacter())); |
433 | 0 | for (int i = 0; i < jal.getHeight(); i++) |
434 | { | |
435 | 0 | syncToAlignmentSequence(jal.getSequenceAt(i), alignment, null); |
436 | } | |
437 | 0 | alignRDHash.put(av.getSequenceSetId(), av.getUndoRedoHash()); |
438 | } | |
439 | else | |
440 | { | |
441 | // always prepare to clone the alignment | |
442 | 0 | boolean alismod = av.isUndoRedoHashModified( |
443 | (long[]) alignRDHash.get(av.getSequenceSetId())); | |
444 | // todo: verify and update mutable alignment props. | |
445 | // TODO: Use isLocked methods | |
446 | 0 | if (alignment.getModifiable() == null |
447 | || alignment.getModifiable().length() == 0) | |
448 | // && !alignment.isDependedOn()) | |
449 | { | |
450 | 0 | boolean modified = false; |
451 | // check existing sequences in local and in document. | |
452 | 0 | Vector docseqs = new Vector( |
453 | alignment.getAlignmentSequenceAsReference()); | |
454 | 0 | for (int i = 0; i < jal.getHeight(); i++) |
455 | { | |
456 | 0 | modified |= syncToAlignmentSequence(jal.getSequenceAt(i), |
457 | alignment, docseqs); | |
458 | } | |
459 | 0 | if (docseqs.size() > 0) |
460 | { | |
461 | // removeValignmentSequences(alignment, docseqs); | |
462 | 0 | docseqs.removeAllElements(); |
463 | 0 | jalview.bin.Console.outPrintln( |
464 | "Sequence deletion from alignment is not implemented."); | |
465 | ||
466 | } | |
467 | 0 | if (modified) |
468 | { | |
469 | 0 | if (alismod) |
470 | { | |
471 | // info in the undo | |
472 | 0 | addProvenance(alignment.getProvenance(), "Edited"); // TODO: |
473 | // insert | |
474 | // something | |
475 | // sensible | |
476 | // here again | |
477 | } | |
478 | else | |
479 | { | |
480 | // info in the undo | |
481 | 0 | addProvenance(alignment.getProvenance(), "Attributes Edited"); // TODO: |
482 | // insert | |
483 | // something | |
484 | // sensible | |
485 | // here | |
486 | // again | |
487 | } | |
488 | } | |
489 | 0 | if (alismod) |
490 | { | |
491 | 0 | jalview.bin.Console.outPrintln("update alignment in document."); |
492 | } | |
493 | else | |
494 | { | |
495 | 0 | jalview.bin.Console |
496 | .outPrintln("alignment in document left unchanged."); | |
497 | } | |
498 | } | |
499 | else | |
500 | { | |
501 | // unbind alignment from view. | |
502 | // create new binding and new alignment. | |
503 | // mark trail on new alignment as being derived from old ? | |
504 | 0 | jalview.bin.Console.outPrintln( |
505 | "update edited alignment to new alignment in document."); | |
506 | } | |
507 | } | |
508 | // //////////////////////////////////////////// | |
509 | // SAVE Alignment Sequence Features | |
510 | 0 | for (int i = 0, iSize = alignment |
511 | 0 | .getAlignmentSequenceCount(); i < iSize; i++) |
512 | { | |
513 | 0 | AlignmentSequence valseq; |
514 | 0 | SequenceI alseq = (SequenceI) getvObj2jv( |
515 | valseq = alignment.getAlignmentSequence(i)); | |
516 | 0 | if (alseq != null && alseq.getSequenceFeatures() != null) |
517 | { | |
518 | /* | |
519 | * We do not put local Alignment Sequence Features into the vamsas | |
520 | * document yet. | |
521 | * | |
522 | * | |
523 | * jalview.datamodel.SequenceFeature[] features = alseq | |
524 | * .getSequenceFeatures(); for (int f = 0; f < features.length; f++) { | |
525 | * if (features[f] != null) { AlignmentSequenceAnnotation valseqf = ( | |
526 | * AlignmentSequenceAnnotation) getjv2vObj(features[i]); if (valseqf | |
527 | * == null) { | |
528 | * | |
529 | * valseqf = (AlignmentSequenceAnnotation) getDSAnnotationFromJalview( | |
530 | * new AlignmentSequenceAnnotation(), features[i]); | |
531 | * valseqf.setGraph(false); | |
532 | * valseqf.addProperty(newProperty("jalview:feature" | |
533 | * ,"boolean","true")); if (valseqf.getProvenance() == null) { | |
534 | * valseqf.setProvenance(new Provenance()); } | |
535 | * addProvenance(valseqf.getProvenance(), "created"); // JBPNote - // | |
536 | * need to // update bindjvvobj(features[i], valseqf); | |
537 | * valseq.addAlignmentSequenceAnnotation(valseqf); } } } | |
538 | */ | |
539 | } | |
540 | } | |
541 | ||
542 | // //////////////////////////////////////////// | |
543 | // SAVE ANNOTATIONS | |
544 | 0 | if (jal.getAlignmentAnnotation() != null) |
545 | { | |
546 | 0 | jalview.datamodel.AlignmentAnnotation[] aa = jal |
547 | .getAlignmentAnnotation(); | |
548 | 0 | java.util.HashMap AlSeqMaps = new HashMap(); // stores int maps from |
549 | // alignment columns to | |
550 | // sequence positions. | |
551 | 0 | for (int i = 0; i < aa.length; i++) |
552 | { | |
553 | 0 | if (aa[i] == null || isJalviewOnly(aa[i])) |
554 | { | |
555 | 0 | continue; |
556 | } | |
557 | 0 | if (aa[i].groupRef != null) |
558 | { | |
559 | // TODO: store any group associated annotation references | |
560 | 0 | Console.warn( |
561 | "Group associated sequence annotation is not stored in VAMSAS document."); | |
562 | 0 | continue; |
563 | } | |
564 | 0 | if (aa[i].sequenceRef != null) |
565 | { | |
566 | // Deal with sequence associated annotation | |
567 | 0 | Vobject sref = getjv2vObj(aa[i].sequenceRef); |
568 | 0 | if (sref instanceof uk.ac.vamsas.objects.core.AlignmentSequence) |
569 | { | |
570 | 0 | saveAlignmentSequenceAnnotation(AlSeqMaps, |
571 | (AlignmentSequence) sref, aa[i]); | |
572 | } | |
573 | else | |
574 | { | |
575 | // first find the alignment sequence to associate this with. | |
576 | 0 | for (SequenceI jvalsq : av.getAlignment().getSequences()) |
577 | { | |
578 | // saveDatasetSequenceAnnotation(AlSeqMaps,(uk.ac.vamsas.objects.core.Sequence) | |
579 | // sref, aa[i]); | |
580 | 0 | if (jvalsq.getDatasetSequence() == aa[i].sequenceRef) |
581 | { | |
582 | 0 | Vobject alsref = getjv2vObj(jvalsq); |
583 | 0 | saveAlignmentSequenceAnnotation(AlSeqMaps, |
584 | (AlignmentSequence) alsref, aa[i]); | |
585 | 0 | break; |
586 | } | |
587 | 0 | ; |
588 | } | |
589 | } | |
590 | } | |
591 | else | |
592 | { | |
593 | // add Alignment Annotation | |
594 | 0 | uk.ac.vamsas.objects.core.AlignmentAnnotation an = (uk.ac.vamsas.objects.core.AlignmentAnnotation) getjv2vObj( |
595 | aa[i]); | |
596 | 0 | if (an == null) |
597 | { | |
598 | 0 | an = new uk.ac.vamsas.objects.core.AlignmentAnnotation(); |
599 | 0 | an.setType(JALVIEW_ANNOTATION_ROW); |
600 | 0 | an.setDescription(aa[i].description); |
601 | 0 | alignment.addAlignmentAnnotation(an); |
602 | 0 | Seg vSeg = new Seg(); // TODO: refactor to have a default |
603 | // rangeAnnotationType initer/updater that | |
604 | // takes a set of int ranges. | |
605 | 0 | vSeg.setStart(1); |
606 | 0 | vSeg.setInclusive(true); |
607 | 0 | vSeg.setEnd(jal.getWidth()); |
608 | 0 | an.addSeg(vSeg); |
609 | 0 | if (aa[i].graph > 0) |
610 | { | |
611 | 0 | an.setGraph(true); // aa[i].graph); |
612 | } | |
613 | 0 | an.setLabel(aa[i].label); |
614 | 0 | an.setProvenance(dummyProvenance()); |
615 | 0 | if (aa[i].graph != AlignmentAnnotation.NO_GRAPH) |
616 | { | |
617 | 0 | an.setGroup(Integer.toString(aa[i].graphGroup)); // // JBPNote |
618 | // - | |
619 | // originally we | |
620 | // were going to | |
621 | // store | |
622 | // graphGroup in | |
623 | // the Jalview | |
624 | // specific | |
625 | // bits. | |
626 | 0 | an.setGraph(true); |
627 | } | |
628 | else | |
629 | { | |
630 | 0 | an.setGraph(false); |
631 | } | |
632 | 0 | AnnotationElement ae; |
633 | ||
634 | 0 | for (int a = 0; a < aa[i].annotations.length; a++) |
635 | { | |
636 | 0 | if ((aa[i] == null) || (aa[i].annotations[a] == null)) |
637 | { | |
638 | 0 | continue; |
639 | } | |
640 | ||
641 | 0 | ae = new AnnotationElement(); |
642 | 0 | ae.setDescription(aa[i].annotations[a].description); |
643 | 0 | ae.addGlyph(new Glyph()); |
644 | 0 | ae.getGlyph(0) |
645 | .setContent(aa[i].annotations[a].displayCharacter); // assume | |
646 | // jax-b | |
647 | // takes | |
648 | // care | |
649 | // of | |
650 | // utf8 | |
651 | // translation | |
652 | 0 | if (an.isGraph()) |
653 | { | |
654 | 0 | ae.addValue(aa[i].annotations[a].value); |
655 | } | |
656 | 0 | ae.setPosition(a + 1); |
657 | 0 | if (aa[i].annotations[a].secondaryStructure != ' ') |
658 | { | |
659 | 0 | Glyph ss = new Glyph(); |
660 | 0 | ss.setDict( |
661 | uk.ac.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE); | |
662 | 0 | ss.setContent(String.valueOf( |
663 | aa[i].annotations[a].secondaryStructure)); | |
664 | 0 | ae.addGlyph(ss); |
665 | } | |
666 | 0 | an.addAnnotationElement(ae); |
667 | } | |
668 | 0 | if (aa[i].editable) |
669 | { | |
670 | // an.addProperty(newProperty("jalview:editable", null, | |
671 | // "true")); | |
672 | // an.setModifiable(""); // TODO: This is not the way the | |
673 | // modifiable flag is supposed to be used. | |
674 | } | |
675 | 0 | setAnnotationType(an, aa[i]); |
676 | ||
677 | 0 | if (aa[i].graph != jalview.datamodel.AlignmentAnnotation.NO_GRAPH) |
678 | { | |
679 | 0 | an.setGraph(true); |
680 | 0 | an.setGroup(Integer.toString(aa[i].graphGroup)); |
681 | 0 | if (aa[i].threshold != null && aa[i].threshold.displayed) |
682 | { | |
683 | 0 | an.addProperty(Properties.newProperty(THRESHOLD, |
684 | Properties.FLOATTYPE, | |
685 | "" + aa[i].threshold.value)); | |
686 | 0 | if (aa[i].threshold.label != null) |
687 | { | |
688 | 0 | an.addProperty(Properties.newProperty( |
689 | THRESHOLD + "Name", Properties.STRINGTYPE, | |
690 | "" + aa[i].threshold.label)); | |
691 | } | |
692 | } | |
693 | } | |
694 | ||
695 | } | |
696 | ||
697 | else | |
698 | { | |
699 | 0 | if (an.getModifiable() == null) // TODO: USE VAMSAS LIBRARY OBJECT |
700 | // LOCK METHODS) | |
701 | { | |
702 | // verify annotation - update (perhaps) | |
703 | 0 | Console.info( |
704 | "update alignment sequence annotation. not yet implemented."); | |
705 | } | |
706 | else | |
707 | { | |
708 | // verify annotation - update (perhaps) | |
709 | 0 | Console.info( |
710 | "updated alignment sequence annotation added."); | |
711 | } | |
712 | } | |
713 | } | |
714 | } | |
715 | } | |
716 | // ///////////////////////////////////////////////////// | |
717 | ||
718 | // ////////////////////////////////////////////// | |
719 | // /SAVE THE TREES | |
720 | // ///////////////////////////////// | |
721 | // FIND ANY ASSOCIATED TREES | |
722 | 0 | if (Desktop.desktop != null) |
723 | { | |
724 | 0 | javax.swing.JInternalFrame[] frames = Desktop.instance |
725 | .getAllFrames(); | |
726 | ||
727 | 0 | for (int t = 0; t < frames.length; t++) |
728 | { | |
729 | 0 | if (frames[t] instanceof TreePanel) |
730 | { | |
731 | 0 | TreePanel tp = (TreePanel) frames[t]; |
732 | ||
733 | 0 | if (tp.getViewPort().getSequenceSetId() |
734 | .equals(av.getSequenceSetId())) | |
735 | { | |
736 | 0 | DatastoreItem vtree = new jalview.io.vamsas.Tree(this, tp, |
737 | jal, alignment); | |
738 | } | |
739 | } | |
740 | } | |
741 | } | |
742 | // Store Jalview specific stuff in the Jalview appData | |
743 | // not implemented in the SimpleDoc interface. | |
744 | } | |
745 | ||
746 | catch (Exception ex) | |
747 | { | |
748 | 0 | ex.printStackTrace(); |
749 | 0 | return false; |
750 | } | |
751 | 0 | return true; |
752 | } | |
753 | ||
754 | /** | |
755 | * very quick test to see if the viewport would be stored in the vamsas | |
756 | * document. Reasons for not storing include the unaligned flag being false | |
757 | * (for all sequences, including the hidden ones!) | |
758 | * | |
759 | * @param av | |
760 | * @return true if alignment associated with this view will be stored in | |
761 | * document. | |
762 | */ | |
763 | 0 | public boolean alignmentWillBeSkipped(AlignmentViewport av) |
764 | { | |
765 | 0 | return (!av.getAlignment().isAligned()); |
766 | } | |
767 | ||
768 | 0 | private void addToSkipList(AlignmentViewport av) |
769 | { | |
770 | 0 | if (skipList == null) |
771 | { | |
772 | 0 | skipList = new Hashtable(); |
773 | } | |
774 | 0 | skipList.put(av.getSequenceSetId(), av); |
775 | } | |
776 | ||
777 | /** | |
778 | * remove docseqs from the given alignment marking provenance appropriately | |
779 | * and removing any references to the sequences. | |
780 | * | |
781 | * @param alignment | |
782 | * @param docseqs | |
783 | */ | |
784 | 0 | private void removeValignmentSequences(Alignment alignment, |
785 | Vector docseqs) | |
786 | { | |
787 | // delete these from document. This really needs to be a generic document | |
788 | // API function derived by CASTOR. | |
789 | 0 | Enumeration en = docseqs.elements(); |
790 | 0 | while (en.hasMoreElements()) |
791 | { | |
792 | 0 | alignment.removeAlignmentSequence( |
793 | (AlignmentSequence) en.nextElement()); | |
794 | } | |
795 | 0 | Entry pe = addProvenance(alignment.getProvenance(), |
796 | "Removed " + docseqs.size() + " sequences"); | |
797 | 0 | en = alignment.enumerateAlignmentAnnotation(); |
798 | 0 | Vector toremove = new Vector(); |
799 | 0 | while (en.hasMoreElements()) |
800 | { | |
801 | 0 | uk.ac.vamsas.objects.core.AlignmentAnnotation alan = (uk.ac.vamsas.objects.core.AlignmentAnnotation) en |
802 | .nextElement(); | |
803 | 0 | if (alan.getSeqrefsCount() > 0) |
804 | { | |
805 | 0 | int p = 0; |
806 | 0 | Vector storem = new Vector(); |
807 | 0 | Enumeration sr = alan.enumerateSeqrefs(); |
808 | 0 | while (sr.hasMoreElements()) |
809 | { | |
810 | 0 | Object alsr = sr.nextElement(); |
811 | 0 | if (docseqs.contains(alsr)) |
812 | { | |
813 | 0 | storem.addElement(alsr); |
814 | } | |
815 | } | |
816 | // remove references to the deleted sequences | |
817 | 0 | sr = storem.elements(); |
818 | 0 | while (sr.hasMoreElements()) |
819 | { | |
820 | 0 | alan.removeSeqrefs(sr.nextElement()); |
821 | } | |
822 | ||
823 | 0 | if (alan.getSeqrefsCount() == 0) |
824 | { | |
825 | // should then delete alan from dataset | |
826 | 0 | toremove.addElement(alan); |
827 | } | |
828 | } | |
829 | } | |
830 | // remove any annotation that used to be associated to a specific bunch of | |
831 | // sequences | |
832 | 0 | en = toremove.elements(); |
833 | 0 | while (en.hasMoreElements()) |
834 | { | |
835 | 0 | alignment.removeAlignmentAnnotation( |
836 | (uk.ac.vamsas.objects.core.AlignmentAnnotation) en | |
837 | .nextElement()); | |
838 | } | |
839 | // TODO: search through alignment annotations to remove any references to | |
840 | // this alignment sequence | |
841 | } | |
842 | ||
843 | /** | |
844 | * sync a jalview alignment seuqence into a vamsas alignment assumes all lock | |
845 | * transformation/bindings have been sorted out before hand. creates/syncs the | |
846 | * vamsas alignment sequence for jvalsq and adds it to the alignment if | |
847 | * necessary. unbounddocseq is a duplicate of the vamsas alignment sequences | |
848 | * and these are removed after being processed w.r.t a bound jvalsq | |
849 | * | |
850 | */ | |
851 | 0 | private boolean syncToAlignmentSequence(SequenceI jvalsq, |
852 | Alignment alignment, Vector unbounddocseq) | |
853 | { | |
854 | 0 | boolean modal = false; |
855 | // todo: islocked method here | |
856 | 0 | boolean up2doc = false; |
857 | 0 | AlignmentSequence alseq = (AlignmentSequence) getjv2vObj(jvalsq); |
858 | 0 | if (alseq == null) |
859 | { | |
860 | 0 | alseq = new AlignmentSequence(); |
861 | 0 | up2doc = true; |
862 | } | |
863 | else | |
864 | { | |
865 | 0 | if (unbounddocseq != null) |
866 | { | |
867 | 0 | unbounddocseq.removeElement(alseq); |
868 | } | |
869 | } | |
870 | // boolean locked = (alignment.getModifiable()==null || | |
871 | // alignment.getModifiable().length()>0); | |
872 | // TODO: VAMSAS: translate lowercase symbols to annotation ? | |
873 | 0 | if (up2doc || !alseq.getSequence().equals(jvalsq.getSequenceAsString())) |
874 | { | |
875 | 0 | alseq.setSequence(jvalsq.getSequenceAsString()); |
876 | 0 | alseq.setStart(jvalsq.getStart()); |
877 | 0 | alseq.setEnd(jvalsq.getEnd()); |
878 | 0 | modal = true; |
879 | } | |
880 | 0 | if (up2doc || !alseq.getName().equals(jvalsq.getName())) |
881 | { | |
882 | 0 | modal = true; |
883 | 0 | alseq.setName(jvalsq.getName()); |
884 | } | |
885 | 0 | if (jvalsq.getDescription() != null && (alseq.getDescription() == null |
886 | || !jvalsq.getDescription().equals(alseq.getDescription()))) | |
887 | { | |
888 | 0 | modal = true; |
889 | 0 | alseq.setDescription(jvalsq.getDescription()); |
890 | } | |
891 | 0 | if (getjv2vObj(jvalsq.getDatasetSequence()) == null) |
892 | { | |
893 | 0 | Console.warn( |
894 | "Serious Implementation error - Unbound dataset sequence in alignment: " | |
895 | + jvalsq.getDatasetSequence()); | |
896 | } | |
897 | 0 | alseq.setRefid(getjv2vObj(jvalsq.getDatasetSequence())); |
898 | 0 | if (up2doc) |
899 | { | |
900 | ||
901 | 0 | alignment.addAlignmentSequence(alseq); |
902 | 0 | bindjvvobj(jvalsq, alseq); |
903 | } | |
904 | 0 | return up2doc || modal; |
905 | } | |
906 | ||
907 | /** | |
908 | * locally sync a jalview alignment seuqence from a vamsas alignment assumes | |
909 | * all lock transformation/bindings have been sorted out before hand. | |
910 | * creates/syncs the jvalsq from the alignment sequence | |
911 | */ | |
912 | 0 | private boolean syncFromAlignmentSequence(AlignmentSequence valseq, |
913 | char valGapchar, char gapChar, List<SequenceI> dsseqs) | |
914 | ||
915 | { | |
916 | 0 | boolean modal = false; |
917 | // todo: islocked method here | |
918 | 0 | boolean upFromdoc = false; |
919 | 0 | jalview.datamodel.SequenceI alseq = (SequenceI) getvObj2jv(valseq); |
920 | 0 | if (alseq == null) |
921 | { | |
922 | 0 | upFromdoc = true; |
923 | } | |
924 | 0 | if (alseq != null) |
925 | { | |
926 | ||
927 | // boolean locked = (alignment.getModifiable()==null || | |
928 | // alignment.getModifiable().length()>0); | |
929 | // TODO: VAMSAS: translate lowercase symbols to annotation ? | |
930 | 0 | if (upFromdoc |
931 | || !valseq.getSequence().equals(alseq.getSequenceAsString())) | |
932 | { | |
933 | // this might go *horribly* wrong | |
934 | 0 | alseq.setSequence(new String(valseq.getSequence()) |
935 | .replace(valGapchar, gapChar)); | |
936 | 0 | alseq.setStart((int) valseq.getStart()); |
937 | 0 | alseq.setEnd((int) valseq.getEnd()); |
938 | 0 | modal = true; |
939 | } | |
940 | 0 | if (!valseq.getName().equals(alseq.getName())) |
941 | { | |
942 | 0 | modal = true; |
943 | 0 | alseq.setName(valseq.getName()); |
944 | } | |
945 | 0 | if (alseq.getDescription() == null || (valseq.getDescription() != null |
946 | && !alseq.getDescription().equals(valseq.getDescription()))) | |
947 | { | |
948 | 0 | alseq.setDescription(valseq.getDescription()); |
949 | 0 | modal = true; |
950 | } | |
951 | 0 | if (modal && Console.isDebugEnabled()) |
952 | { | |
953 | 0 | Console.debug( |
954 | "Updating apparently edited sequence " + alseq.getName()); | |
955 | } | |
956 | } | |
957 | else | |
958 | { | |
959 | 0 | alseq = new jalview.datamodel.Sequence(valseq.getName(), |
960 | valseq.getSequence().replace(valGapchar, gapChar), | |
961 | (int) valseq.getStart(), (int) valseq.getEnd()); | |
962 | ||
963 | 0 | Vobject datsetseq = (Vobject) valseq.getRefid(); |
964 | 0 | if (datsetseq != null) |
965 | { | |
966 | 0 | alseq.setDatasetSequence((SequenceI) getvObj2jv(datsetseq)); // exceptions |
967 | 0 | if (valseq.getDescription() != null) |
968 | { | |
969 | 0 | alseq.setDescription(valseq.getDescription()); |
970 | } | |
971 | else | |
972 | { | |
973 | // inherit description line from dataset. | |
974 | 0 | if (alseq.getDatasetSequence().getDescription() != null) |
975 | { | |
976 | 0 | alseq.setDescription( |
977 | alseq.getDatasetSequence().getDescription()); | |
978 | } | |
979 | } | |
980 | // if | |
981 | // AlignemntSequence | |
982 | // reference | |
983 | // isn't | |
984 | // a | |
985 | // simple | |
986 | // SequenceI | |
987 | } | |
988 | else | |
989 | { | |
990 | 0 | Console.error( |
991 | "Invalid dataset sequence id (null) for alignment sequence " | |
992 | + valseq.getVorbaId()); | |
993 | } | |
994 | 0 | bindjvvobj(alseq, valseq); |
995 | 0 | alseq.setVamsasId(valseq.getVorbaId().getId()); |
996 | 0 | dsseqs.add(alseq); |
997 | } | |
998 | 0 | Vobject datsetseq = (Vobject) valseq.getRefid(); |
999 | 0 | if (datsetseq != null) |
1000 | { | |
1001 | 0 | if (datsetseq != alseq.getDatasetSequence()) |
1002 | { | |
1003 | 0 | modal = true; |
1004 | } | |
1005 | 0 | alseq.setDatasetSequence((SequenceI) getvObj2jv(datsetseq)); // exceptions |
1006 | } | |
1007 | 0 | return upFromdoc || modal; |
1008 | } | |
1009 | ||
1010 | 0 | private void initRangeAnnotationType(RangeAnnotation an, |
1011 | AlignmentAnnotation alan, int[] gapMap) | |
1012 | { | |
1013 | 0 | Seg vSeg = new Seg(); |
1014 | 0 | vSeg.setStart(1); |
1015 | 0 | vSeg.setInclusive(true); |
1016 | 0 | vSeg.setEnd(gapMap.length); |
1017 | 0 | an.addSeg(vSeg); |
1018 | ||
1019 | // LATER: much of this is verbatim from the alignmentAnnotation | |
1020 | // method below. suggests refactoring to make rangeAnnotation the | |
1021 | // base class | |
1022 | 0 | an.setDescription(alan.description); |
1023 | 0 | an.setLabel(alan.label); |
1024 | 0 | an.setGroup(Integer.toString(alan.graphGroup)); |
1025 | // // JBPNote - | |
1026 | // originally we | |
1027 | // were going to | |
1028 | // store | |
1029 | // graphGroup in | |
1030 | // the Jalview | |
1031 | // specific | |
1032 | // bits. | |
1033 | 0 | AnnotationElement ae; |
1034 | 0 | for (int a = 0; a < alan.annotations.length; a++) |
1035 | { | |
1036 | 0 | if (alan.annotations[a] == null) |
1037 | { | |
1038 | 0 | continue; |
1039 | } | |
1040 | ||
1041 | 0 | ae = new AnnotationElement(); |
1042 | 0 | ae.setDescription(alan.annotations[a].description); |
1043 | 0 | ae.addGlyph(new Glyph()); |
1044 | 0 | ae.getGlyph(0).setContent(alan.annotations[a].displayCharacter); // assume |
1045 | // jax-b | |
1046 | // takes | |
1047 | // care | |
1048 | // of | |
1049 | // utf8 | |
1050 | // translation | |
1051 | 0 | if (alan.graph != jalview.datamodel.AlignmentAnnotation.NO_GRAPH) |
1052 | { | |
1053 | 0 | ae.addValue(alan.annotations[a].value); |
1054 | } | |
1055 | 0 | ae.setPosition(gapMap[a] + 1); // position w.r.t. AlignmentSequence |
1056 | // symbols | |
1057 | 0 | if (alan.annotations[a].secondaryStructure != ' ') |
1058 | { | |
1059 | // we only write an annotation where it really exists. | |
1060 | 0 | Glyph ss = new Glyph(); |
1061 | 0 | ss.setDict( |
1062 | uk.ac.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE); | |
1063 | 0 | ss.setContent( |
1064 | String.valueOf(alan.annotations[a].secondaryStructure)); | |
1065 | 0 | ae.addGlyph(ss); |
1066 | } | |
1067 | 0 | an.addAnnotationElement(ae); |
1068 | } | |
1069 | ||
1070 | } | |
1071 | ||
1072 | 0 | private void saveDatasetSequenceAnnotation(HashMap AlSeqMaps, |
1073 | uk.ac.vamsas.objects.core.Sequence sref, AlignmentAnnotation alan) | |
1074 | { | |
1075 | // { | |
1076 | // uk.ac.vamsas. | |
1077 | // objects.core.AlignmentSequence alsref = (uk.ac.vamsas. | |
1078 | // objects.core.AlignmentSequence) sref; | |
1079 | 0 | uk.ac.vamsas.objects.core.DataSetAnnotations an = (uk.ac.vamsas.objects.core.DataSetAnnotations) getjv2vObj( |
1080 | alan); | |
1081 | 0 | int[] gapMap = getGapMap(AlSeqMaps, alan); |
1082 | 0 | if (an == null) |
1083 | { | |
1084 | 0 | an = new uk.ac.vamsas.objects.core.DataSetAnnotations(); |
1085 | 0 | initRangeAnnotationType(an, alan, gapMap); |
1086 | ||
1087 | 0 | an.setProvenance(dummyProvenance()); // get provenance as user |
1088 | // created, or jnet, or | |
1089 | // something else. | |
1090 | 0 | setAnnotationType(an, alan); |
1091 | 0 | an.setGroup(Integer.toString(alan.graphGroup)); // // JBPNote - |
1092 | // originally we | |
1093 | // were going to | |
1094 | // store | |
1095 | // graphGroup in | |
1096 | // the Jalview | |
1097 | // specific | |
1098 | // bits. | |
1099 | 0 | if (alan.getThreshold() != null && alan.getThreshold().displayed) |
1100 | { | |
1101 | 0 | an.addProperty(Properties.newProperty(THRESHOLD, |
1102 | Properties.FLOATTYPE, "" + alan.getThreshold().value)); | |
1103 | 0 | if (alan.getThreshold().label != null) |
1104 | { | |
1105 | 0 | an.addProperty(Properties.newProperty(THRESHOLD + "Name", |
1106 | Properties.STRINGTYPE, "" + alan.getThreshold().label)); | |
1107 | } | |
1108 | } | |
1109 | 0 | ((DataSet) sref.getV_parent()).addDataSetAnnotations(an); |
1110 | 0 | bindjvvobj(alan, an); |
1111 | } | |
1112 | else | |
1113 | { | |
1114 | // update reference sequence Annotation | |
1115 | 0 | if (an.getModifiable() == null) // TODO: USE VAMSAS LIBRARY OBJECT LOCK |
1116 | // METHODS) | |
1117 | { | |
1118 | // verify existing alignment sequence annotation is up to date | |
1119 | 0 | jalview.bin.Console |
1120 | .outPrintln("update dataset sequence annotation."); | |
1121 | } | |
1122 | else | |
1123 | { | |
1124 | // verify existing alignment sequence annotation is up to date | |
1125 | 0 | jalview.bin.Console.outPrintln( |
1126 | "make new alignment dataset sequence annotation if modification has happened."); | |
1127 | } | |
1128 | } | |
1129 | ||
1130 | } | |
1131 | ||
1132 | 0 | private int[] getGapMap(HashMap AlSeqMaps, AlignmentAnnotation alan) |
1133 | { | |
1134 | 0 | int[] gapMap; |
1135 | 0 | if (AlSeqMaps.containsKey(alan.sequenceRef)) |
1136 | { | |
1137 | 0 | gapMap = (int[]) AlSeqMaps.get(alan.sequenceRef); |
1138 | } | |
1139 | else | |
1140 | { | |
1141 | 0 | gapMap = new int[alan.sequenceRef.getLength()]; |
1142 | // map from alignment position to sequence position. | |
1143 | 0 | int[] sgapMap = alan.sequenceRef.gapMap(); |
1144 | 0 | for (int a = 0; a < sgapMap.length; a++) |
1145 | { | |
1146 | 0 | gapMap[sgapMap[a]] = a; |
1147 | } | |
1148 | } | |
1149 | 0 | return gapMap; |
1150 | } | |
1151 | ||
1152 | 0 | private void saveAlignmentSequenceAnnotation(HashMap AlSeqMaps, |
1153 | AlignmentSequence alsref, AlignmentAnnotation alan) | |
1154 | { | |
1155 | // { | |
1156 | // uk.ac.vamsas. | |
1157 | // objects.core.AlignmentSequence alsref = (uk.ac.vamsas. | |
1158 | // objects.core.AlignmentSequence) sref; | |
1159 | 0 | uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation an = (uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation) getjv2vObj( |
1160 | alan); | |
1161 | 0 | int[] gapMap = getGapMap(AlSeqMaps, alan); |
1162 | 0 | if (an == null) |
1163 | { | |
1164 | 0 | an = new uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation(); |
1165 | 0 | initRangeAnnotationType(an, alan, gapMap); |
1166 | /** | |
1167 | * I mean here that we don't actually have a semantic 'type' for the | |
1168 | * annotation (this might be - score, intrinsic property, measurement, | |
1169 | * something extracted from another program, etc) | |
1170 | */ | |
1171 | 0 | an.setType(JALVIEW_ANNOTATION_ROW); // TODO: better fix |
1172 | // this rough guess ;) | |
1173 | 0 | alsref.addAlignmentSequenceAnnotation(an); |
1174 | 0 | bindjvvobj(alan, an); |
1175 | // These properties are directly supported by the | |
1176 | // AlignmentSequenceAnnotation type. | |
1177 | 0 | setAnnotationType(an, alan); |
1178 | 0 | an.setProvenance(dummyProvenance()); // get provenance as user |
1179 | // created, or jnet, or | |
1180 | // something else. | |
1181 | } | |
1182 | else | |
1183 | { | |
1184 | // update reference sequence Annotation | |
1185 | 0 | if (an.getModifiable() == null) // TODO: USE VAMSAS LIBRARY OBJECT LOCK |
1186 | // METHODS) | |
1187 | { | |
1188 | // verify existing alignment sequence annotation is up to date | |
1189 | 0 | jalview.bin.Console |
1190 | .outPrintln("update alignment sequence annotation."); | |
1191 | } | |
1192 | else | |
1193 | { | |
1194 | // verify existing alignment sequence annotation is up to date | |
1195 | 0 | jalview.bin.Console.outPrintln( |
1196 | "make new alignment sequence annotation if modification has happened."); | |
1197 | } | |
1198 | } | |
1199 | } | |
1200 | ||
1201 | /** | |
1202 | * set vamsas annotation object type from jalview annotation | |
1203 | * | |
1204 | * @param an | |
1205 | * @param alan | |
1206 | */ | |
1207 | 0 | private void setAnnotationType(RangeAnnotation an, |
1208 | AlignmentAnnotation alan) | |
1209 | { | |
1210 | 0 | if (an instanceof AlignmentSequenceAnnotation) |
1211 | { | |
1212 | 0 | if (alan.graph != AlignmentAnnotation.NO_GRAPH) |
1213 | { | |
1214 | 0 | ((AlignmentSequenceAnnotation) an).setGraph(true); |
1215 | } | |
1216 | else | |
1217 | { | |
1218 | 0 | ((AlignmentSequenceAnnotation) an).setGraph(false); |
1219 | } | |
1220 | } | |
1221 | 0 | if (an instanceof uk.ac.vamsas.objects.core.AlignmentAnnotation) |
1222 | { | |
1223 | 0 | if (alan.graph != AlignmentAnnotation.NO_GRAPH) |
1224 | { | |
1225 | 0 | ((uk.ac.vamsas.objects.core.AlignmentAnnotation) an).setGraph(true); |
1226 | } | |
1227 | else | |
1228 | { | |
1229 | 0 | ((uk.ac.vamsas.objects.core.AlignmentAnnotation) an) |
1230 | .setGraph(false); | |
1231 | } | |
1232 | } | |
1233 | 0 | switch (alan.graph) |
1234 | { | |
1235 | 0 | case AlignmentAnnotation.BAR_GRAPH: |
1236 | 0 | an.addProperty(Properties.newProperty(DISCRETE_ANNOTATION, |
1237 | Properties.BOOLEANTYPE, "true")); | |
1238 | 0 | break; |
1239 | 0 | case AlignmentAnnotation.LINE_GRAPH: |
1240 | 0 | an.addProperty(Properties.newProperty(CONTINUOUS_ANNOTATION, |
1241 | Properties.BOOLEANTYPE, "true")); | |
1242 | 0 | break; |
1243 | 0 | default: |
1244 | // don't add any kind of discrete or continous property info. | |
1245 | } | |
1246 | } | |
1247 | ||
1248 | /** | |
1249 | * get start<end range of segment, adjusting for inclusivity flag and | |
1250 | * polarity. | |
1251 | * | |
1252 | * @param visSeg | |
1253 | * @param ensureDirection | |
1254 | * when true - always ensure start is less than end. | |
1255 | * @return int[] { start, end, direction} where direction==1 for range running | |
1256 | * from end to start. | |
1257 | */ | |
1258 | 0 | private int[] getSegRange(Seg visSeg, boolean ensureDirection) |
1259 | { | |
1260 | 0 | boolean incl = visSeg.getInclusive(); |
1261 | // adjust for inclusive flag. | |
1262 | 0 | int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of |
1263 | // region. | |
1264 | 0 | int start = visSeg.getStart() + (incl ? 0 : pol); |
1265 | 0 | int end = visSeg.getEnd() + (incl ? 0 : -pol); |
1266 | 0 | if (ensureDirection && pol == -1) |
1267 | { | |
1268 | // jalview doesn't deal with inverted ranges, yet. | |
1269 | 0 | int t = end; |
1270 | 0 | end = start; |
1271 | 0 | start = t; |
1272 | } | |
1273 | 0 | return new int[] { start, end, pol < 0 ? 1 : 0 }; |
1274 | } | |
1275 | ||
1276 | /** | |
1277 | * | |
1278 | * @param annotation | |
1279 | * @return true if annotation is not to be stored in document | |
1280 | */ | |
1281 | 0 | private boolean isJalviewOnly(AlignmentAnnotation annotation) |
1282 | { | |
1283 | 0 | return annotation.autoCalculated || annotation.label.equals("Quality") |
1284 | || annotation.label.equals("Conservation") | |
1285 | || annotation.label.equals("Consensus"); | |
1286 | } | |
1287 | ||
1288 | boolean dojvsync = true; | |
1289 | ||
1290 | // boolean dojvsync = false; // disables Jalview AppData IO | |
1291 | /** | |
1292 | * list of alignment views created when updating Jalview from document. | |
1293 | */ | |
1294 | private final Vector newAlignmentViews = new Vector(); | |
1295 | ||
1296 | /** | |
1297 | * update local jalview view settings from the stored appdata (if any) | |
1298 | */ | |
1299 | 0 | public void updateJalviewFromAppdata() |
1300 | { | |
1301 | // recover any existing Jalview data from appdata | |
1302 | // TODO: recover any PDB files stored as attachments in the vamsas session | |
1303 | // and initialise the Jalview2XML.alreadyLoadedPDB hashtable with mappings | |
1304 | // to temp files. | |
1305 | { | |
1306 | 0 | final IClientAppdata cappdata = cdoc.getClientAppdata(); |
1307 | 0 | if (cappdata != null) |
1308 | { | |
1309 | 0 | if (cappdata.hasClientAppdata()) |
1310 | { | |
1311 | // TODO: how to check version of Jalview client app data and whether | |
1312 | // it has been modified | |
1313 | // client data is shared over all app clients | |
1314 | 0 | try |
1315 | { | |
1316 | // jalview.gui.Jalview2XML fromxml = new jalview.gui.Jalview2XML(); | |
1317 | 0 | Jalview2XML fromxml = new Jalview2XML(); |
1318 | 0 | fromxml.attemptversion1parse = false; |
1319 | 0 | fromxml.setUniqueSetSuffix(""); |
1320 | 0 | fromxml.setObjectMappingTables(vobj2jv, jv2vobj); // mapKeysToString |
1321 | // and | |
1322 | // mapValuesToString | |
1323 | 0 | fromxml.setSkipList(skipList); |
1324 | 0 | jalview.util.jarInputStreamProvider jprovider = new jalview.util.jarInputStreamProvider() |
1325 | { | |
1326 | ||
1327 | 0 | @Override |
1328 | public String getFilename() | |
1329 | { | |
1330 | ||
1331 | // TODO Get the vamsas session ID here | |
1332 | 0 | return "Jalview Vamsas Document Client Data"; |
1333 | } | |
1334 | ||
1335 | 0 | @Override |
1336 | public JarInputStream getJarInputStream() throws IOException | |
1337 | { | |
1338 | 0 | Console.debug( |
1339 | "Returning client input stream for Jalview from Vamsas Document."); | |
1340 | 0 | return new JarInputStream(cappdata.getClientInputStream()); |
1341 | } | |
1342 | }; | |
1343 | 0 | if (dojvsync) |
1344 | { | |
1345 | 0 | fromxml.loadJalviewAlign(jprovider); |
1346 | } | |
1347 | } catch (Exception e) | |
1348 | { | |
1349 | ||
1350 | } catch (OutOfMemoryError e) | |
1351 | { | |
1352 | ||
1353 | } catch (Error e) | |
1354 | { | |
1355 | ||
1356 | } | |
1357 | } | |
1358 | } | |
1359 | 0 | if (cappdata.hasUserAppdata()) |
1360 | { | |
1361 | // TODO: how to check version of Jalview user app data and whether it | |
1362 | // has been modified | |
1363 | // user data overrides data shared over all app clients ? | |
1364 | 0 | try |
1365 | { | |
1366 | 0 | Jalview2XML fromxml = new Jalview2XML(); |
1367 | 0 | fromxml.attemptversion1parse = false; |
1368 | 0 | fromxml.setUniqueSetSuffix(""); |
1369 | 0 | fromxml.setSkipList(skipList); |
1370 | 0 | fromxml.setObjectMappingTables(mapKeysToString(vobj2jv), |
1371 | mapValuesToString(jv2vobj)); | |
1372 | 0 | jalview.util.jarInputStreamProvider jarstream = new jalview.util.jarInputStreamProvider() |
1373 | { | |
1374 | ||
1375 | 0 | @Override |
1376 | public String getFilename() | |
1377 | { | |
1378 | ||
1379 | // TODO Get the vamsas session ID here | |
1380 | 0 | return "Jalview Vamsas Document User Data"; |
1381 | } | |
1382 | ||
1383 | 0 | @Override |
1384 | public JarInputStream getJarInputStream() throws IOException | |
1385 | { | |
1386 | 0 | Console.debug( |
1387 | "Returning user input stream for Jalview from Vamsas Document."); | |
1388 | 0 | return new JarInputStream(cappdata.getUserInputStream()); |
1389 | } | |
1390 | }; | |
1391 | 0 | if (dojvsync) |
1392 | { | |
1393 | 0 | fromxml.loadJalviewAlign(jarstream); |
1394 | } | |
1395 | } catch (Exception e) | |
1396 | { | |
1397 | ||
1398 | } catch (OutOfMemoryError e) | |
1399 | { | |
1400 | ||
1401 | } catch (Error e) | |
1402 | { | |
1403 | ||
1404 | } | |
1405 | } | |
1406 | ||
1407 | } | |
1408 | 0 | flushAlignViewports(); |
1409 | } | |
1410 | ||
1411 | /** | |
1412 | * remove any spurious views generated by document synchronization | |
1413 | */ | |
1414 | 0 | private void flushAlignViewports() |
1415 | { | |
1416 | // remove any additional viewports originally recovered from the vamsas | |
1417 | // document. | |
1418 | // search for all alignframes containing viewports generated from document | |
1419 | // sync, | |
1420 | // and if any contain more than one view, then remove the one generated by | |
1421 | // document update. | |
1422 | 0 | AlignmentViewport views[], av = null; |
1423 | 0 | AlignFrame af = null; |
1424 | 0 | Iterator newviews = newAlignmentViews.iterator(); |
1425 | 0 | while (newviews.hasNext()) |
1426 | { | |
1427 | 0 | av = (AlignmentViewport) newviews.next(); |
1428 | 0 | af = Desktop.getAlignFrameFor(av); |
1429 | // TODO implement this : af.getNumberOfViews | |
1430 | 0 | String seqsetidobj = av.getSequenceSetId(); |
1431 | 0 | views = Desktop.getViewports(seqsetidobj); |
1432 | 0 | Console.debug("Found " + (views == null ? " no " : "" + views.length) |
1433 | + " views for '" + av.getSequenceSetId() + "'"); | |
1434 | 0 | if (views.length > 1) |
1435 | { | |
1436 | // we need to close the original document view. | |
1437 | ||
1438 | // work out how to do this by seeing if the views are gathered. | |
1439 | // pretty clunky but the only way to do this without adding more flags | |
1440 | // to the align frames. | |
1441 | 0 | boolean gathered = false; |
1442 | 0 | String newviewid = null; |
1443 | 0 | List<AlignedCodonFrame> mappings = av.getAlignment() |
1444 | .getCodonFrames(); | |
1445 | 0 | for (int i = 0; i < views.length; i++) |
1446 | { | |
1447 | 0 | if (views[i] != av) |
1448 | { | |
1449 | 0 | AlignFrame viewframe = Desktop.getAlignFrameFor(views[i]); |
1450 | 0 | if (viewframe == af) |
1451 | { | |
1452 | 0 | gathered = true; |
1453 | } | |
1454 | 0 | newviewid = views[i].getSequenceSetId(); |
1455 | } | |
1456 | else | |
1457 | { | |
1458 | // lose the reference to the vamsas document created view | |
1459 | 0 | views[i] = null; |
1460 | } | |
1461 | } | |
1462 | // close the view generated by the vamsas document synchronization | |
1463 | 0 | if (gathered) |
1464 | { | |
1465 | 0 | af.closeView(av); |
1466 | } | |
1467 | else | |
1468 | { | |
1469 | 0 | af.closeMenuItem_actionPerformed(false); |
1470 | } | |
1471 | 0 | replaceJvObjMapping(seqsetidobj, newviewid); |
1472 | 0 | seqsetidobj = newviewid; |
1473 | // not sure if we need to do this: | |
1474 | ||
1475 | 0 | if (false) // mappings != null) |
1476 | { | |
1477 | // ensure sequence mappings from vamsas document view still | |
1478 | // active | |
1479 | 0 | if (mappings != null) |
1480 | { | |
1481 | 0 | jalview.structure.StructureSelectionManager |
1482 | .getStructureSelectionManager(Desktop.instance) | |
1483 | .registerMappings(mappings); | |
1484 | } | |
1485 | } | |
1486 | } | |
1487 | // ensure vamsas object binds to the stored views retrieved from | |
1488 | // Jalview appdata | |
1489 | // jalview.structure.StructureSelectionManager | |
1490 | // .getStructureSelectionManager() | |
1491 | // .addStructureViewerListener(viewframe.alignPanel); | |
1492 | ||
1493 | } | |
1494 | ||
1495 | 0 | newviews = null; |
1496 | 0 | newAlignmentViews.clear(); |
1497 | } | |
1498 | ||
1499 | /** | |
1500 | * replaces oldjvobject with newjvobject in the Jalview Object <> VorbaID | |
1501 | * binding tables | |
1502 | * | |
1503 | * @param oldjvobject | |
1504 | * @param newjvobject | |
1505 | * (may be null) | |
1506 | */ | |
1507 | 0 | private void replaceJvObjMapping(Object oldjvobject, Object newjvobject) |
1508 | { | |
1509 | 0 | Object vobject = jv2vobj.remove(oldjvobject); |
1510 | 0 | if (vobject == null) |
1511 | { | |
1512 | // NOTE: this happens if user deletes object in one session then updates | |
1513 | // from another client | |
1514 | 0 | throw new Error(MessageManager.formatMessage( |
1515 | "error.implementation_error_old_jalview_object_not_bound", | |
1516 | new String[] | |
1517 | { oldjvobject.toString() })); | |
1518 | } | |
1519 | 0 | if (newjvobject != null) |
1520 | { | |
1521 | 0 | jv2vobj.put(newjvobject, vobject); |
1522 | 0 | vobj2jv.put(vobject, newjvobject); |
1523 | } | |
1524 | } | |
1525 | ||
1526 | /** | |
1527 | * Update the jalview client and user appdata from the local jalview settings | |
1528 | */ | |
1529 | 0 | public void updateJalviewClientAppdata() |
1530 | { | |
1531 | 0 | final IClientAppdata cappdata = cdoc.getClientAppdata(); |
1532 | 0 | if (cappdata != null) |
1533 | { | |
1534 | 0 | try |
1535 | { | |
1536 | 0 | Jalview2XML jxml = new Jalview2XML(); |
1537 | 0 | jxml.setObjectMappingTables(mapKeysToString(vobj2jv), |
1538 | mapValuesToString(jv2vobj)); | |
1539 | 0 | jxml.setSkipList(skipList); |
1540 | 0 | if (dojvsync) |
1541 | { | |
1542 | 0 | jxml.saveState( |
1543 | new JarOutputStream(cappdata.getClientOutputStream())); | |
1544 | } | |
1545 | ||
1546 | } catch (Exception e) | |
1547 | { | |
1548 | // TODO raise GUI warning if user requests it. | |
1549 | 0 | Console.error( |
1550 | "Couldn't update jalview client application data. Giving up - local settings probably lost.", | |
1551 | e); | |
1552 | } | |
1553 | } | |
1554 | else | |
1555 | { | |
1556 | 0 | Console.error( |
1557 | "Couldn't access client application data for vamsas session. This is probably a vamsas client bug."); | |
1558 | } | |
1559 | } | |
1560 | ||
1561 | /** | |
1562 | * translate the Vobject keys to strings for use in Jalview2XML | |
1563 | * | |
1564 | * @param jv2vobj2 | |
1565 | * @return | |
1566 | */ | |
1567 | 0 | private IdentityHashMap mapValuesToString(IdentityHashMap jv2vobj2) |
1568 | { | |
1569 | 0 | IdentityHashMap mapped = new IdentityHashMap(); |
1570 | 0 | Iterator keys = jv2vobj2.keySet().iterator(); |
1571 | 0 | while (keys.hasNext()) |
1572 | { | |
1573 | 0 | Object key = keys.next(); |
1574 | 0 | mapped.put(key, jv2vobj2.get(key).toString()); |
1575 | } | |
1576 | 0 | return mapped; |
1577 | } | |
1578 | ||
1579 | /** | |
1580 | * translate the Vobject values to strings for use in Jalview2XML | |
1581 | * | |
1582 | * @param vobj2jv2 | |
1583 | * @return hashtable with string values | |
1584 | */ | |
1585 | 0 | private Hashtable mapKeysToString(Hashtable vobj2jv2) |
1586 | { | |
1587 | 0 | Hashtable mapped = new Hashtable(); |
1588 | 0 | Iterator keys = vobj2jv2.keySet().iterator(); |
1589 | 0 | while (keys.hasNext()) |
1590 | { | |
1591 | 0 | Object key = keys.next(); |
1592 | 0 | mapped.put(key.toString(), vobj2jv2.get(key)); |
1593 | } | |
1594 | 0 | return mapped; |
1595 | } | |
1596 | ||
1597 | /** | |
1598 | * synchronize Jalview from the vamsas document | |
1599 | * | |
1600 | * @return number of new views from document | |
1601 | */ | |
1602 | 0 | public int updateToJalview() |
1603 | { | |
1604 | 0 | VAMSAS _roots[] = cdoc.getVamsasRoots(); |
1605 | ||
1606 | 0 | for (int _root = 0; _root < _roots.length; _root++) |
1607 | { | |
1608 | 0 | VAMSAS root = _roots[_root]; |
1609 | 0 | boolean newds = false; |
1610 | 0 | for (int _ds = 0, _nds = root.getDataSetCount(); _ds < _nds; _ds++) |
1611 | { | |
1612 | // /////////////////////////////////// | |
1613 | // ///LOAD DATASET | |
1614 | 0 | DataSet dataset = root.getDataSet(_ds); |
1615 | 0 | int i, iSize = dataset.getSequenceCount(); |
1616 | 0 | List<SequenceI> dsseqs; |
1617 | 0 | jalview.datamodel.Alignment jdataset = (jalview.datamodel.Alignment) getvObj2jv( |
1618 | dataset); | |
1619 | 0 | int jremain = 0; |
1620 | 0 | if (jdataset == null) |
1621 | { | |
1622 | 0 | Console.debug("Initialising new jalview dataset fields"); |
1623 | 0 | newds = true; |
1624 | 0 | dsseqs = new Vector(); |
1625 | } | |
1626 | else | |
1627 | { | |
1628 | 0 | Console.debug("Update jalview dataset from vamsas."); |
1629 | 0 | jremain = jdataset.getHeight(); |
1630 | 0 | dsseqs = jdataset.getSequences(); |
1631 | } | |
1632 | ||
1633 | // TODO: test sequence merging - we preserve existing non vamsas | |
1634 | // sequences but add in any new vamsas ones, and don't yet update any | |
1635 | // sequence attributes | |
1636 | 0 | for (i = 0; i < iSize; i++) |
1637 | { | |
1638 | 0 | Sequence vdseq = dataset.getSequence(i); |
1639 | 0 | jalview.io.vamsas.Datasetsequence dssync = new Datasetsequence( |
1640 | this, vdseq); | |
1641 | ||
1642 | 0 | jalview.datamodel.SequenceI dsseq = (SequenceI) dssync.getJvobj(); |
1643 | 0 | if (dssync.isAddfromdoc()) |
1644 | { | |
1645 | 0 | dsseqs.add(dsseq); |
1646 | } | |
1647 | 0 | if (vdseq.getDbRefCount() > 0) |
1648 | { | |
1649 | 0 | DbRef[] dbref = vdseq.getDbRef(); |
1650 | 0 | for (int db = 0; db < dbref.length; db++) |
1651 | { | |
1652 | 0 | new jalview.io.vamsas.Dbref(this, dbref[db], vdseq, dsseq); |
1653 | ||
1654 | } | |
1655 | 0 | dsseq.updatePDBIds(); |
1656 | } | |
1657 | } | |
1658 | ||
1659 | 0 | if (newds) |
1660 | { | |
1661 | 0 | SequenceI[] seqs = new SequenceI[dsseqs.size()]; |
1662 | 0 | for (i = 0, iSize = dsseqs.size(); i < iSize; i++) |
1663 | { | |
1664 | 0 | seqs[i] = dsseqs.get(i); |
1665 | 0 | dsseqs.set(i, null); |
1666 | } | |
1667 | 0 | jdataset = new jalview.datamodel.Alignment(seqs); |
1668 | 0 | Console.debug("New vamsas dataset imported into jalview."); |
1669 | 0 | bindjvvobj(jdataset, dataset); |
1670 | } | |
1671 | // //////// | |
1672 | // add any new dataset sequence feature annotations | |
1673 | 0 | if (dataset.getDataSetAnnotations() != null) |
1674 | { | |
1675 | 0 | for (int dsa = 0; dsa < dataset |
1676 | .getDataSetAnnotationsCount(); dsa++) | |
1677 | { | |
1678 | 0 | DataSetAnnotations dseta = dataset.getDataSetAnnotations(dsa); |
1679 | // TODO: deal with group annotation on datset sequences. | |
1680 | 0 | if (dseta.getSeqRefCount() == 1) |
1681 | { | |
1682 | 0 | SequenceI dsSeq = (SequenceI) getvObj2jv( |
1683 | (Vobject) dseta.getSeqRef(0)); // TODO: deal with group | |
1684 | // dataset | |
1685 | // annotations | |
1686 | 0 | if (dsSeq == null) |
1687 | { | |
1688 | 0 | Console.warn( |
1689 | "Couldn't resolve jalview sequenceI for dataset object reference " | |
1690 | + ((Vobject) dataset | |
1691 | .getDataSetAnnotations(dsa) | |
1692 | .getSeqRef(0)).getVorbaId() | |
1693 | .getId()); | |
1694 | } | |
1695 | else | |
1696 | { | |
1697 | 0 | if (dseta.getAnnotationElementCount() == 0) |
1698 | { | |
1699 | 0 | new jalview.io.vamsas.Sequencefeature(this, dseta, dsSeq); |
1700 | ||
1701 | } | |
1702 | else | |
1703 | { | |
1704 | // TODO: deal with alignmentAnnotation style annotation | |
1705 | // appearing on dataset sequences. | |
1706 | // JBPNote: we could just add them to all alignments but | |
1707 | // that may complicate cross references in the jalview | |
1708 | // datamodel | |
1709 | 0 | Console.warn( |
1710 | "Ignoring dataset annotation with annotationElements. Not yet supported in jalview."); | |
1711 | } | |
1712 | } | |
1713 | } | |
1714 | else | |
1715 | { | |
1716 | 0 | Console.warn( |
1717 | "Ignoring multiply referenced dataset sequence annotation for binding to datsaet sequence features."); | |
1718 | } | |
1719 | } | |
1720 | } | |
1721 | 0 | if (dataset.getAlignmentCount() > 0) |
1722 | { | |
1723 | // LOAD ALIGNMENTS from DATASET | |
1724 | ||
1725 | 0 | for (int al = 0, nal = dataset |
1726 | 0 | .getAlignmentCount(); al < nal; al++) |
1727 | { | |
1728 | 0 | uk.ac.vamsas.objects.core.Alignment alignment = dataset |
1729 | .getAlignment(al); | |
1730 | // TODO check this handles multiple views properly | |
1731 | 0 | AlignmentViewport av = findViewport(alignment); |
1732 | ||
1733 | 0 | jalview.datamodel.AlignmentI jal = null; |
1734 | 0 | if (av != null) |
1735 | { | |
1736 | // TODO check that correct alignment object is retrieved when | |
1737 | // hidden seqs exist. | |
1738 | 0 | jal = (av.hasHiddenRows()) ? av.getAlignment() |
1739 | .getHiddenSequences().getFullAlignment() | |
1740 | : av.getAlignment(); | |
1741 | } | |
1742 | 0 | iSize = alignment.getAlignmentSequenceCount(); |
1743 | 0 | boolean refreshal = false; |
1744 | 0 | Vector newasAnnots = new Vector(); |
1745 | 0 | char gapChar = ' '; // default for new alignments read in from the |
1746 | // document | |
1747 | 0 | if (jal != null) |
1748 | { | |
1749 | 0 | dsseqs = jal.getSequences(); // for merge/update |
1750 | 0 | gapChar = jal.getGapCharacter(); |
1751 | } | |
1752 | else | |
1753 | { | |
1754 | 0 | dsseqs = new Vector(); |
1755 | } | |
1756 | 0 | char valGapchar = alignment.getGapChar().charAt(0); |
1757 | 0 | for (i = 0; i < iSize; i++) |
1758 | { | |
1759 | 0 | AlignmentSequence valseq = alignment.getAlignmentSequence(i); |
1760 | 0 | jalview.datamodel.Sequence alseq = (jalview.datamodel.Sequence) getvObj2jv( |
1761 | valseq); | |
1762 | 0 | if (syncFromAlignmentSequence(valseq, valGapchar, gapChar, |
1763 | dsseqs) && alseq != null) | |
1764 | { | |
1765 | ||
1766 | // updated to sequence from the document | |
1767 | 0 | jremain--; |
1768 | 0 | refreshal = true; |
1769 | } | |
1770 | 0 | if (valseq.getAlignmentSequenceAnnotationCount() > 0) |
1771 | { | |
1772 | 0 | AlignmentSequenceAnnotation[] vasannot = valseq |
1773 | .getAlignmentSequenceAnnotation(); | |
1774 | 0 | for (int a = 0; a < vasannot.length; a++) |
1775 | { | |
1776 | 0 | jalview.datamodel.AlignmentAnnotation asa = (jalview.datamodel.AlignmentAnnotation) getvObj2jv( |
1777 | vasannot[a]); // TODO: | |
1778 | // 1:many | |
1779 | // jalview | |
1780 | // alignment | |
1781 | // sequence | |
1782 | // annotations | |
1783 | 0 | if (asa == null) |
1784 | { | |
1785 | 0 | int se[] = getBounds(vasannot[a]); |
1786 | 0 | asa = getjAlignmentAnnotation(jal, vasannot[a]); |
1787 | 0 | asa.setSequenceRef(alseq); |
1788 | 0 | asa.createSequenceMapping(alseq, se[0], false); // TODO: |
1789 | // verify | |
1790 | // that | |
1791 | // positions | |
1792 | // in | |
1793 | // alseqAnnotation | |
1794 | // correspond | |
1795 | // to | |
1796 | // ungapped | |
1797 | // residue | |
1798 | // positions. | |
1799 | 0 | alseq.addAlignmentAnnotation(asa); |
1800 | 0 | bindjvvobj(asa, vasannot[a]); |
1801 | 0 | refreshal = true; |
1802 | 0 | newasAnnots.add(asa); |
1803 | } | |
1804 | else | |
1805 | { | |
1806 | // update existing annotation - can do this in place | |
1807 | 0 | if (vasannot[a].getModifiable() == null) // TODO: USE |
1808 | // VAMSAS LIBRARY | |
1809 | // OBJECT LOCK | |
1810 | // METHODS) | |
1811 | { | |
1812 | 0 | Console.info( |
1813 | "UNIMPLEMENTED: not recovering user modifiable sequence alignment annotation"); | |
1814 | // TODO: should at least replace with new one - otherwise | |
1815 | // things will break | |
1816 | // basically do this: | |
1817 | // int se[] = getBounds(vasannot[a]); | |
1818 | // asa.update(getjAlignmentAnnotation(jal, vasannot[a])); | |
1819 | // // update from another annotation object in place. | |
1820 | // asa.createSequenceMapping(alseq, se[0], false); | |
1821 | ||
1822 | } | |
1823 | } | |
1824 | } | |
1825 | } | |
1826 | } | |
1827 | 0 | if (jal == null) |
1828 | { | |
1829 | 0 | SequenceI[] seqs = new SequenceI[dsseqs.size()]; |
1830 | 0 | for (i = 0, iSize = dsseqs.size(); i < iSize; i++) |
1831 | { | |
1832 | 0 | seqs[i] = dsseqs.get(i); |
1833 | 0 | dsseqs.set(i, null); |
1834 | } | |
1835 | 0 | jal = new jalview.datamodel.Alignment(seqs); |
1836 | 0 | Console.debug("New vamsas alignment imported into jalview " |
1837 | + alignment.getVorbaId().getId()); | |
1838 | 0 | jal.setDataset(jdataset); |
1839 | } | |
1840 | 0 | if (newasAnnots != null && newasAnnots.size() > 0) |
1841 | { | |
1842 | // Add the new sequence annotations in to the alignment. | |
1843 | 0 | for (int an = 0, anSize = newasAnnots |
1844 | 0 | .size(); an < anSize; an++) |
1845 | { | |
1846 | 0 | jal.addAnnotation( |
1847 | (AlignmentAnnotation) newasAnnots.elementAt(an)); | |
1848 | // TODO: check if anything has to be done - like calling | |
1849 | // adjustForAlignment or something. | |
1850 | 0 | newasAnnots.setElementAt(null, an); |
1851 | } | |
1852 | 0 | newasAnnots = null; |
1853 | } | |
1854 | // ////////////////////////////////////////// | |
1855 | // //LOAD ANNOTATIONS FOR THE ALIGNMENT | |
1856 | // //////////////////////////////////// | |
1857 | 0 | if (alignment.getAlignmentAnnotationCount() > 0) |
1858 | { | |
1859 | 0 | uk.ac.vamsas.objects.core.AlignmentAnnotation[] an = alignment |
1860 | .getAlignmentAnnotation(); | |
1861 | ||
1862 | 0 | for (int j = 0; j < an.length; j++) |
1863 | { | |
1864 | 0 | jalview.datamodel.AlignmentAnnotation jan = (jalview.datamodel.AlignmentAnnotation) getvObj2jv( |
1865 | an[j]); | |
1866 | 0 | if (jan != null) |
1867 | { | |
1868 | // update or stay the same. | |
1869 | // TODO: should at least replace with a new one - otherwise | |
1870 | // things will break | |
1871 | // basically do this: | |
1872 | // jan.update(getjAlignmentAnnotation(jal, an[a])); // update | |
1873 | // from another annotation object in place. | |
1874 | ||
1875 | 0 | Console.debug( |
1876 | "update from vamsas alignment annotation to existing jalview alignment annotation."); | |
1877 | 0 | if (an[j].getModifiable() == null) // TODO: USE VAMSAS |
1878 | // LIBRARY OBJECT LOCK | |
1879 | // METHODS) | |
1880 | { | |
1881 | // TODO: user defined annotation is totally mutable... - so | |
1882 | // load it up or throw away if locally edited. | |
1883 | 0 | Console.info( |
1884 | "NOT IMPLEMENTED - Recovering user-modifiable annotation - yet..."); | |
1885 | } | |
1886 | // TODO: compare annotation element rows | |
1887 | // TODO: compare props. | |
1888 | } | |
1889 | else | |
1890 | { | |
1891 | 0 | jan = getjAlignmentAnnotation(jal, an[j]); |
1892 | // TODO: ensure we add the alignment annotation before the | |
1893 | // automatic annotation rows | |
1894 | 0 | jal.addAnnotation(jan); |
1895 | 0 | bindjvvobj(jan, an[j]); |
1896 | 0 | refreshal = true; |
1897 | } | |
1898 | } | |
1899 | } | |
1900 | 0 | AlignFrame alignFrame; |
1901 | 0 | if (av == null) |
1902 | { | |
1903 | 0 | Console.debug("New alignframe for alignment " |
1904 | + alignment.getVorbaId()); | |
1905 | // /////////////////////////////// | |
1906 | // construct alignment view | |
1907 | 0 | alignFrame = new AlignFrame(jal, AlignFrame.DEFAULT_WIDTH, |
1908 | AlignFrame.DEFAULT_HEIGHT, | |
1909 | alignment.getVorbaId().toString()); | |
1910 | 0 | av = alignFrame.getViewport(); |
1911 | 0 | newAlignmentViews.addElement(av); |
1912 | 0 | String title = alignment.getProvenance() |
1913 | .getEntry( | |
1914 | alignment.getProvenance().getEntryCount() - 1) | |
1915 | .getAction(); | |
1916 | 0 | if (alignment.getPropertyCount() > 0) |
1917 | { | |
1918 | 0 | for (int p = 0, pe = alignment |
1919 | 0 | .getPropertyCount(); p < pe; p++) |
1920 | { | |
1921 | 0 | if (alignment.getProperty(p).getName().equals("title")) |
1922 | { | |
1923 | 0 | title = alignment.getProperty(p).getContent(); |
1924 | } | |
1925 | } | |
1926 | } | |
1927 | // TODO: automatically create meaningful title for a vamsas | |
1928 | // alignment using its provenance. | |
1929 | 0 | if (Console.isDebugEnabled()) |
1930 | { | |
1931 | 0 | title = title + "(" + alignment.getVorbaId() + ")"; |
1932 | ||
1933 | } | |
1934 | 0 | jalview.gui.Desktop.addInternalFrame(alignFrame, title, |
1935 | AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); | |
1936 | 0 | bindjvvobj(av.getSequenceSetId(), alignment); |
1937 | } | |
1938 | else | |
1939 | { | |
1940 | // find the alignFrame for jal. | |
1941 | // TODO: fix this so we retrieve the alignFrame handing av | |
1942 | // *directly* (JBPNote - don't understand this now) | |
1943 | // TODO: make sure all associated views are refreshed | |
1944 | 0 | alignFrame = Desktop.getAlignFrameFor(av); |
1945 | 0 | if (refreshal) |
1946 | { | |
1947 | 0 | av.alignmentChanged(alignFrame.alignPanel); |
1948 | 0 | alignFrame.alignPanel.adjustAnnotationHeight(); |
1949 | } | |
1950 | } | |
1951 | // LOAD TREES | |
1952 | // ///////////////////////////////////// | |
1953 | 0 | if (alignment.getTreeCount() > 0) |
1954 | { | |
1955 | ||
1956 | 0 | for (int t = 0; t < alignment.getTreeCount(); t++) |
1957 | { | |
1958 | 0 | jalview.io.vamsas.Tree vstree = new jalview.io.vamsas.Tree( |
1959 | this, alignFrame, alignment.getTree(t)); | |
1960 | 0 | TreePanel tp = null; |
1961 | 0 | if (vstree.isValidTree()) |
1962 | { | |
1963 | 0 | tp = alignFrame.showNewickTree(vstree.getNewickTree(), |
1964 | vstree.getTitle(), vstree.getInputData(), 600, | |
1965 | 500, t * 20 + 50, t * 20 + 50); | |
1966 | ||
1967 | } | |
1968 | 0 | if (tp != null) |
1969 | { | |
1970 | 0 | bindjvvobj(tp, alignment.getTree(t)); |
1971 | 0 | try |
1972 | { | |
1973 | 0 | vstree.UpdateSequenceTreeMap(tp); |
1974 | } catch (RuntimeException e) | |
1975 | { | |
1976 | 0 | Console.warn("update of labels failed.", e); |
1977 | } | |
1978 | } | |
1979 | else | |
1980 | { | |
1981 | 0 | Console.warn("Cannot create tree for tree " + t |
1982 | + " in document (" | |
1983 | + alignment.getTree(t).getVorbaId()); | |
1984 | } | |
1985 | ||
1986 | } | |
1987 | } | |
1988 | } | |
1989 | } | |
1990 | } | |
1991 | // we do sequenceMappings last because they span all datasets in a vamsas | |
1992 | // root | |
1993 | 0 | for (int _ds = 0, _nds = root.getDataSetCount(); _ds < _nds; _ds++) |
1994 | { | |
1995 | 0 | DataSet dataset = root.getDataSet(_ds); |
1996 | 0 | if (dataset.getSequenceMappingCount() > 0) |
1997 | { | |
1998 | 0 | for (int sm = 0, smCount = dataset |
1999 | 0 | .getSequenceMappingCount(); sm < smCount; sm++) |
2000 | { | |
2001 | 0 | Rangetype seqmap = new jalview.io.vamsas.Sequencemapping(this, |
2002 | dataset.getSequenceMapping(sm)); | |
2003 | } | |
2004 | } | |
2005 | } | |
2006 | } | |
2007 | 0 | return newAlignmentViews.size(); |
2008 | } | |
2009 | ||
2010 | 0 | public AlignmentViewport findViewport(Alignment alignment) |
2011 | { | |
2012 | 0 | AlignmentViewport av = null; |
2013 | 0 | AlignmentViewport[] avs = Desktop |
2014 | .getViewports((String) getvObj2jv(alignment)); | |
2015 | 0 | if (avs != null) |
2016 | { | |
2017 | 0 | av = avs[0]; |
2018 | } | |
2019 | 0 | return av; |
2020 | } | |
2021 | ||
2022 | // bitfields - should be a template in j1.5 | |
2023 | private static int HASSECSTR = 0; | |
2024 | ||
2025 | private static int HASVALS = 1; | |
2026 | ||
2027 | private static int HASHPHOB = 2; | |
2028 | ||
2029 | private static int HASDC = 3; | |
2030 | ||
2031 | private static int HASDESCSTR = 4; | |
2032 | ||
2033 | private static int HASTWOSTATE = 5; // not used yet. | |
2034 | ||
2035 | /** | |
2036 | * parses the AnnotationElements - if they exist - into | |
2037 | * jalview.datamodel.Annotation[] rows Two annotation rows are made if there | |
2038 | * are distinct annotation for both at 'pos' and 'after pos' at any particular | |
2039 | * site. | |
2040 | * | |
2041 | * @param annotation | |
2042 | * @return { boolean[static int constants ], int[ae.length] - map to annotated | |
2043 | * object frame, jalview.datamodel.Annotation[], | |
2044 | * jalview.datamodel.Annotation[] (after)} | |
2045 | */ | |
2046 | 0 | private Object[] parseRangeAnnotation( |
2047 | uk.ac.vamsas.objects.core.RangeAnnotation annotation) | |
2048 | { | |
2049 | // set these attributes by looking in the annotation to decide what kind of | |
2050 | // alignment annotation rows will be made | |
2051 | // TODO: potentially we might make several annotation rows from one vamsas | |
2052 | // alignment annotation. the jv2Vobj binding mechanism | |
2053 | // may not quite cope with this (without binding an array of annotations to | |
2054 | // a vamsas alignment annotation) | |
2055 | // summary flags saying what we found over the set of annotation rows. | |
2056 | 0 | boolean[] AeContent = new boolean[] { false, false, false, false, |
2057 | false }; | |
2058 | 0 | int[] rangeMap = getMapping(annotation); |
2059 | 0 | jalview.datamodel.Annotation[][] anot = new jalview.datamodel.Annotation[][] { |
2060 | new jalview.datamodel.Annotation[rangeMap.length], | |
2061 | new jalview.datamodel.Annotation[rangeMap.length] }; | |
2062 | 0 | boolean mergeable = true; // false if 'after positions cant be placed on |
2063 | // same annotation row as positions. | |
2064 | ||
2065 | 0 | if (annotation.getAnnotationElementCount() > 0) |
2066 | { | |
2067 | 0 | AnnotationElement ae[] = annotation.getAnnotationElement(); |
2068 | 0 | for (int aa = 0; aa < ae.length; aa++) |
2069 | { | |
2070 | 0 | int pos = (int) ae[aa].getPosition() - 1; // pos counts from 1 to |
2071 | // (|seg.start-seg.end|+1) | |
2072 | 0 | if (pos >= 0 && pos < rangeMap.length) |
2073 | { | |
2074 | 0 | int row = ae[aa].getAfter() ? 1 : 0; |
2075 | 0 | if (anot[row][pos] != null) |
2076 | { | |
2077 | // only time this should happen is if the After flag is set. | |
2078 | 0 | Console.debug("Ignoring duplicate annotation site at " + pos); |
2079 | 0 | continue; |
2080 | } | |
2081 | 0 | if (anot[1 - row][pos] != null) |
2082 | { | |
2083 | 0 | mergeable = false; |
2084 | } | |
2085 | 0 | String desc = ""; |
2086 | 0 | if (ae[aa].getDescription() != null) |
2087 | { | |
2088 | 0 | desc = ae[aa].getDescription(); |
2089 | 0 | if (desc.length() > 0) |
2090 | { | |
2091 | // have imported valid description string | |
2092 | 0 | AeContent[HASDESCSTR] = true; |
2093 | } | |
2094 | } | |
2095 | 0 | String dc = null; // ae[aa].getDisplayCharacter()==null ? "dc" : |
2096 | // ae[aa].getDisplayCharacter(); | |
2097 | 0 | String ss = null; // ae[aa].getSecondaryStructure()==null ? "ss" : |
2098 | // ae[aa].getSecondaryStructure(); | |
2099 | 0 | java.awt.Color colour = null; |
2100 | 0 | if (ae[aa].getGlyphCount() > 0) |
2101 | { | |
2102 | 0 | Glyph[] glyphs = ae[aa].getGlyph(); |
2103 | 0 | for (int g = 0; g < glyphs.length; g++) |
2104 | { | |
2105 | 0 | if (glyphs[g].getDict().equals( |
2106 | uk.ac.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE)) | |
2107 | { | |
2108 | 0 | ss = glyphs[g].getContent(); |
2109 | 0 | AeContent[HASSECSTR] = true; |
2110 | } | |
2111 | 0 | else if (glyphs[g].getDict().equals( |
2112 | uk.ac.vamsas.objects.utils.GlyphDictionary.PROTEIN_HD_HYDRO)) | |
2113 | { | |
2114 | 0 | Console.debug("ignoring hydrophobicity glyph marker."); |
2115 | 0 | AeContent[HASHPHOB] = true; |
2116 | 0 | char c = (dc = glyphs[g].getContent()).charAt(0); |
2117 | // dc may get overwritten - but we still set the colour. | |
2118 | 0 | colour = new java.awt.Color(c == '+' ? 255 : 0, |
2119 | 0 | c == '.' ? 255 : 0, c == '-' ? 255 : 0); |
2120 | ||
2121 | } | |
2122 | 0 | else if (glyphs[g].getDict().equals( |
2123 | uk.ac.vamsas.objects.utils.GlyphDictionary.DEFAULT)) | |
2124 | { | |
2125 | 0 | dc = glyphs[g].getContent(); |
2126 | 0 | AeContent[HASDC] = true; |
2127 | } | |
2128 | else | |
2129 | { | |
2130 | 0 | Console.debug( |
2131 | "IMPLEMENTATION TODO: Ignoring unknown glyph type " | |
2132 | + glyphs[g].getDict()); | |
2133 | } | |
2134 | } | |
2135 | } | |
2136 | 0 | float val = 0; |
2137 | 0 | if (ae[aa].getValueCount() > 0) |
2138 | { | |
2139 | 0 | AeContent[HASVALS] = true; |
2140 | 0 | if (ae[aa].getValueCount() > 1) |
2141 | { | |
2142 | 0 | Console.warn( |
2143 | "ignoring additional " + (ae[aa].getValueCount() - 1) | |
2144 | + " values in annotation element."); | |
2145 | } | |
2146 | 0 | val = ae[aa].getValue(0); |
2147 | } | |
2148 | 0 | if (colour == null) |
2149 | { | |
2150 | 0 | anot[row][pos] = new jalview.datamodel.Annotation( |
2151 | 0 | (dc != null) ? dc : "", desc, |
2152 | 0 | (ss != null) ? ss.charAt(0) : ' ', val); |
2153 | } | |
2154 | else | |
2155 | { | |
2156 | 0 | anot[row][pos] = new jalview.datamodel.Annotation( |
2157 | 0 | (dc != null) ? dc : "", desc, |
2158 | 0 | (ss != null) ? ss.charAt(0) : ' ', val, colour); |
2159 | } | |
2160 | } | |
2161 | else | |
2162 | { | |
2163 | 0 | Console.warn("Ignoring out of bound annotation element " + aa |
2164 | + " in " + annotation.getVorbaId().getId()); | |
2165 | } | |
2166 | } | |
2167 | // decide on how many annotation rows are needed. | |
2168 | 0 | if (mergeable) |
2169 | { | |
2170 | 0 | for (int i = 0; i < anot[0].length; i++) |
2171 | { | |
2172 | 0 | if (anot[1][i] != null) |
2173 | { | |
2174 | 0 | anot[0][i] = anot[1][i]; |
2175 | 0 | anot[0][i].description = anot[0][i].description + " (after)"; |
2176 | 0 | AeContent[HASDESCSTR] = true; // we have valid description string |
2177 | // data | |
2178 | 0 | anot[1][i] = null; |
2179 | } | |
2180 | } | |
2181 | 0 | anot[1] = null; |
2182 | } | |
2183 | else | |
2184 | { | |
2185 | 0 | for (int i = 0; i < anot[0].length; i++) |
2186 | { | |
2187 | 0 | anot[1][i].description = anot[1][i].description + " (after)"; |
2188 | } | |
2189 | } | |
2190 | 0 | return new Object[] { AeContent, rangeMap, anot[0], anot[1] }; |
2191 | } | |
2192 | else | |
2193 | { | |
2194 | // no annotations to parse. Just return an empty annotationElement[] | |
2195 | // array. | |
2196 | 0 | return new Object[] { AeContent, rangeMap, anot[0], anot[1] }; |
2197 | } | |
2198 | // return null; | |
2199 | } | |
2200 | ||
2201 | /** | |
2202 | * @param jal | |
2203 | * the jalview alignment to which the annotation will be attached | |
2204 | * (ideally - freshly updated from corresponding vamsas alignment) | |
2205 | * @param annotation | |
2206 | * @return unbound jalview alignment annotation object. | |
2207 | */ | |
2208 | 0 | private jalview.datamodel.AlignmentAnnotation getjAlignmentAnnotation( |
2209 | jalview.datamodel.AlignmentI jal, | |
2210 | uk.ac.vamsas.objects.core.RangeAnnotation annotation) | |
2211 | { | |
2212 | 0 | if (annotation == null) |
2213 | { | |
2214 | 0 | return null; |
2215 | } | |
2216 | // boolean | |
2217 | // hasSequenceRef=annotation.getClass().equals(uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation.class); | |
2218 | // boolean hasProvenance=hasSequenceRef || | |
2219 | // (annotation.getClass().equals(uk.ac.vamsas.objects.core.AlignmentAnnotation.class)); | |
2220 | /* | |
2221 | * int se[] = getBounds(annotation); if (se==null) se=new int[] | |
2222 | * {0,jal.getWidth()-1}; | |
2223 | */ | |
2224 | 0 | Object[] parsedRangeAnnotation = parseRangeAnnotation(annotation); |
2225 | 0 | String a_label = annotation.getLabel(); |
2226 | 0 | String a_descr = annotation.getDescription(); |
2227 | 0 | GraphLine gl = null; |
2228 | 0 | int type = 0; |
2229 | 0 | boolean interp = true; // cleared if annotation is DISCRETE |
2230 | // set type and other attributes from properties | |
2231 | 0 | if (annotation.getPropertyCount() > 0) |
2232 | { | |
2233 | // look for special jalview properties | |
2234 | 0 | uk.ac.vamsas.objects.core.Property[] props = annotation.getProperty(); |
2235 | 0 | for (int p = 0; p < props.length; p++) |
2236 | { | |
2237 | 0 | if (props[p].getName().equalsIgnoreCase(DISCRETE_ANNOTATION)) |
2238 | { | |
2239 | 0 | type = AlignmentAnnotation.BAR_GRAPH; |
2240 | 0 | interp = false; |
2241 | } | |
2242 | 0 | else if (props[p].getName().equalsIgnoreCase(CONTINUOUS_ANNOTATION)) |
2243 | { | |
2244 | 0 | type = AlignmentAnnotation.LINE_GRAPH; |
2245 | } | |
2246 | 0 | else if (props[p].getName().equalsIgnoreCase(THRESHOLD)) |
2247 | { | |
2248 | 0 | Float val = null; |
2249 | 0 | try |
2250 | { | |
2251 | 0 | val = Float.valueOf(props[p].getContent()); |
2252 | } catch (Exception e) | |
2253 | { | |
2254 | 0 | Console.warn("Failed to parse threshold property"); |
2255 | } | |
2256 | 0 | if (val != null) |
2257 | { | |
2258 | 0 | if (gl == null) |
2259 | { | |
2260 | 0 | gl = new GraphLine(val.floatValue(), "", |
2261 | java.awt.Color.black); | |
2262 | } | |
2263 | else | |
2264 | { | |
2265 | 0 | gl.value = val.floatValue(); |
2266 | } | |
2267 | } | |
2268 | } | |
2269 | 0 | else if (props[p].getName().equalsIgnoreCase(THRESHOLD + "Name")) |
2270 | { | |
2271 | 0 | if (gl == null) |
2272 | { | |
2273 | 0 | gl = new GraphLine(0, "", java.awt.Color.black); |
2274 | } | |
2275 | 0 | gl.label = props[p].getContent(); |
2276 | } | |
2277 | } | |
2278 | } | |
2279 | 0 | jalview.datamodel.AlignmentAnnotation jan = null; |
2280 | 0 | if (a_label == null || a_label.length() == 0) |
2281 | { | |
2282 | 0 | a_label = annotation.getType(); |
2283 | 0 | if (a_label.length() == 0) |
2284 | { | |
2285 | 0 | a_label = "Unamed annotation"; |
2286 | } | |
2287 | } | |
2288 | 0 | if (a_descr == null || a_descr.length() == 0) |
2289 | { | |
2290 | 0 | a_descr = "Annotation of type '" + annotation.getType() + "'"; |
2291 | } | |
2292 | 0 | if (parsedRangeAnnotation == null) |
2293 | { | |
2294 | 0 | Console.debug( |
2295 | "Inserting empty annotation row elements for a whole-alignment annotation."); | |
2296 | } | |
2297 | else | |
2298 | { | |
2299 | 0 | if (parsedRangeAnnotation[3] != null) |
2300 | { | |
2301 | 0 | Console.warn("Ignoring 'After' annotation row in " |
2302 | + annotation.getVorbaId()); | |
2303 | } | |
2304 | 0 | jalview.datamodel.Annotation[] arow = (jalview.datamodel.Annotation[]) parsedRangeAnnotation[2]; |
2305 | 0 | boolean[] has = (boolean[]) parsedRangeAnnotation[0]; |
2306 | // VAMSAS: getGraph is only on derived annotation for alignments - in this | |
2307 | // way its 'odd' - there is already an existing TODO about removing this | |
2308 | // flag as being redundant | |
2309 | /* | |
2310 | * if((annotation.getClass().equals(uk.ac.vamsas.objects.core. | |
2311 | * AlignmentAnnotation.class) && | |
2312 | * ((uk.ac.vamsas.objects.core.AlignmentAnnotation)annotation).getGraph()) | |
2313 | * || (hasSequenceRef=true && | |
2314 | * ((uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation | |
2315 | * )annotation).getGraph())) { | |
2316 | */ | |
2317 | 0 | if (has[HASVALS]) |
2318 | { | |
2319 | 0 | if (type == 0) |
2320 | { | |
2321 | 0 | type = jalview.datamodel.AlignmentAnnotation.BAR_GRAPH; // default |
2322 | // type of | |
2323 | // value | |
2324 | // annotation | |
2325 | 0 | if (has[HASHPHOB]) |
2326 | { | |
2327 | // no hints - so we ensure HPHOB display is like this. | |
2328 | 0 | type = jalview.datamodel.AlignmentAnnotation.BAR_GRAPH; |
2329 | } | |
2330 | } | |
2331 | // make bounds and automatic description strings for jalview user's | |
2332 | // benefit (these shouldn't be written back to vamsas document) | |
2333 | 0 | boolean first = true; |
2334 | 0 | float min = 0, max = 1; |
2335 | 0 | int lastval = 0; |
2336 | 0 | for (int i = 0; i < arow.length; i++) |
2337 | { | |
2338 | 0 | if (arow[i] != null) |
2339 | { | |
2340 | 0 | if (i - lastval > 1 && interp) |
2341 | { | |
2342 | // do some interpolation *between* points | |
2343 | 0 | if (arow[lastval] != null) |
2344 | { | |
2345 | 0 | float interval = arow[i].value - arow[lastval].value; |
2346 | 0 | interval /= i - lastval; |
2347 | 0 | float base = arow[lastval].value; |
2348 | 0 | for (int ip = lastval + 1, np = 0; ip < i; np++, ip++) |
2349 | { | |
2350 | 0 | arow[ip] = new jalview.datamodel.Annotation("", "", ' ', |
2351 | interval * np + base); | |
2352 | // NB - Interpolated points don't get a tooltip and | |
2353 | // description. | |
2354 | } | |
2355 | } | |
2356 | } | |
2357 | 0 | lastval = i; |
2358 | // check range - shouldn't we have a min and max property in the | |
2359 | // annotation object ? | |
2360 | 0 | if (first) |
2361 | { | |
2362 | 0 | min = max = arow[i].value; |
2363 | 0 | first = false; |
2364 | } | |
2365 | else | |
2366 | { | |
2367 | 0 | if (arow[i].value < min) |
2368 | { | |
2369 | 0 | min = arow[i].value; |
2370 | } | |
2371 | 0 | else if (arow[i].value > max) |
2372 | { | |
2373 | 0 | max = arow[i].value; |
2374 | } | |
2375 | } | |
2376 | // make tooltip and display char value | |
2377 | 0 | if (!has[HASDESCSTR]) |
2378 | { | |
2379 | 0 | arow[i].description = arow[i].value + ""; |
2380 | } | |
2381 | 0 | if (!has[HASDC]) |
2382 | { | |
2383 | 0 | if (!interp) |
2384 | { | |
2385 | 0 | if (arow[i].description != null |
2386 | && arow[i].description.length() < 3) | |
2387 | { | |
2388 | // copy over the description as the display char. | |
2389 | 0 | arow[i].displayCharacter = new String( |
2390 | arow[i].description); | |
2391 | } | |
2392 | } | |
2393 | else | |
2394 | { | |
2395 | // mark the position as a point used for the interpolation. | |
2396 | 0 | arow[i].displayCharacter = arow[i].value + ""; |
2397 | } | |
2398 | } | |
2399 | } | |
2400 | } | |
2401 | 0 | jan = new jalview.datamodel.AlignmentAnnotation(a_label, a_descr, |
2402 | arow, min, max, type); | |
2403 | } | |
2404 | else | |
2405 | { | |
2406 | 0 | if (annotation.getAnnotationElementCount() == 0) |
2407 | { | |
2408 | // empty annotation array | |
2409 | // TODO: alignment 'features' compare rangeType spec to alignment | |
2410 | // width - if it is not complete, then mark regions on the annotation | |
2411 | // row. | |
2412 | } | |
2413 | 0 | jan = new jalview.datamodel.AlignmentAnnotation(a_label, a_descr, |
2414 | arow); | |
2415 | 0 | jan.setThreshold(null); |
2416 | 0 | jan.annotationId = annotation.getVorbaId().toString(); // keep all the |
2417 | // ids together. | |
2418 | } | |
2419 | 0 | if (annotation.getLinkCount() > 0) |
2420 | { | |
2421 | 0 | Console.warn("Ignoring " + annotation.getLinkCount() |
2422 | + "links added to AlignmentAnnotation."); | |
2423 | } | |
2424 | 0 | if (annotation.getModifiable() == null |
2425 | || annotation.getModifiable().length() == 0) // TODO: USE VAMSAS | |
2426 | // LIBRARY OBJECT | |
2427 | // LOCK METHODS) | |
2428 | { | |
2429 | 0 | jan.editable = true; |
2430 | } | |
2431 | 0 | try |
2432 | { | |
2433 | 0 | if (annotation.getGroup() != null |
2434 | && annotation.getGroup().length() > 0) | |
2435 | { | |
2436 | 0 | jan.graphGroup = Integer.parseInt(annotation.getGroup()); // TODO: |
2437 | // group | |
2438 | // similarly | |
2439 | // named | |
2440 | // annotation | |
2441 | // together | |
2442 | // ? | |
2443 | } | |
2444 | } catch (Exception e) | |
2445 | { | |
2446 | 0 | Console.info( |
2447 | "UNIMPLEMENTED : Couldn't parse non-integer group value for setting graphGroup correctly."); | |
2448 | } | |
2449 | 0 | return jan; |
2450 | ||
2451 | } | |
2452 | ||
2453 | 0 | return null; |
2454 | } | |
2455 | ||
2456 | /** | |
2457 | * get real bounds of a RangeType's specification. start and end are an | |
2458 | * inclusive range within which all segments and positions lie. TODO: refactor | |
2459 | * to vamsas utils | |
2460 | * | |
2461 | * @param dseta | |
2462 | * @return int[] { start, end} | |
2463 | */ | |
2464 | 0 | private int[] getBounds(RangeType dseta) |
2465 | { | |
2466 | 0 | if (dseta != null) |
2467 | { | |
2468 | 0 | int[] se = null; |
2469 | 0 | if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0) |
2470 | { | |
2471 | 0 | throw new Error(MessageManager.getString( |
2472 | "error.invalid_vamsas_rangetype_cannot_resolve_lists")); | |
2473 | } | |
2474 | 0 | if (dseta.getSegCount() > 0) |
2475 | { | |
2476 | 0 | se = getSegRange(dseta.getSeg(0), true); |
2477 | 0 | for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++) |
2478 | { | |
2479 | 0 | int nse[] = getSegRange(dseta.getSeg(s), true); |
2480 | 0 | if (se[0] > nse[0]) |
2481 | { | |
2482 | 0 | se[0] = nse[0]; |
2483 | } | |
2484 | 0 | if (se[1] < nse[1]) |
2485 | { | |
2486 | 0 | se[1] = nse[1]; |
2487 | } | |
2488 | } | |
2489 | } | |
2490 | 0 | if (dseta.getPosCount() > 0) |
2491 | { | |
2492 | // could do a polarity for pos range too. and pass back indication of | |
2493 | // discontinuities. | |
2494 | 0 | int pos = dseta.getPos(0).getI(); |
2495 | 0 | se = new int[] { pos, pos }; |
2496 | 0 | for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++) |
2497 | { | |
2498 | 0 | pos = dseta.getPos(p).getI(); |
2499 | 0 | if (se[0] > pos) |
2500 | { | |
2501 | 0 | se[0] = pos; |
2502 | } | |
2503 | 0 | if (se[1] < pos) |
2504 | { | |
2505 | 0 | se[1] = pos; |
2506 | } | |
2507 | } | |
2508 | } | |
2509 | 0 | return se; |
2510 | } | |
2511 | 0 | return null; |
2512 | } | |
2513 | ||
2514 | /** | |
2515 | * map from a rangeType's internal frame to the referenced object's coordinate | |
2516 | * frame. | |
2517 | * | |
2518 | * @param dseta | |
2519 | * @return int [] { ref(pos)...} for all pos in rangeType's frame. | |
2520 | */ | |
2521 | 0 | private int[] getMapping(RangeType dseta) |
2522 | { | |
2523 | 0 | Vector posList = new Vector(); |
2524 | 0 | if (dseta != null) |
2525 | { | |
2526 | 0 | int[] se = null; |
2527 | 0 | if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0) |
2528 | { | |
2529 | 0 | throw new Error(MessageManager.getString( |
2530 | "error.invalid_vamsas_rangetype_cannot_resolve_lists")); | |
2531 | } | |
2532 | 0 | if (dseta.getSegCount() > 0) |
2533 | { | |
2534 | 0 | for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++) |
2535 | { | |
2536 | 0 | se = getSegRange(dseta.getSeg(s), false); |
2537 | 0 | int se_end = se[1 - se[2]] + (se[2] == 0 ? 1 : -1); |
2538 | 0 | for (int p = se[se[2]]; p != se_end; p += se[2] == 0 ? 1 : -1) |
2539 | { | |
2540 | 0 | posList.add(Integer.valueOf(p)); |
2541 | } | |
2542 | } | |
2543 | } | |
2544 | 0 | else if (dseta.getPosCount() > 0) |
2545 | { | |
2546 | 0 | int pos = dseta.getPos(0).getI(); |
2547 | ||
2548 | 0 | for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++) |
2549 | { | |
2550 | 0 | pos = dseta.getPos(p).getI(); |
2551 | 0 | posList.add(Integer.valueOf(pos)); |
2552 | } | |
2553 | } | |
2554 | } | |
2555 | 0 | if (posList != null && posList.size() > 0) |
2556 | { | |
2557 | 0 | int[] range = new int[posList.size()]; |
2558 | 0 | for (int i = 0; i < range.length; i++) |
2559 | { | |
2560 | 0 | range[i] = ((Integer) posList.elementAt(i)).intValue(); |
2561 | } | |
2562 | 0 | posList.clear(); |
2563 | 0 | return range; |
2564 | } | |
2565 | 0 | return null; |
2566 | } | |
2567 | ||
2568 | /** | |
2569 | * | |
2570 | * @param maprange | |
2571 | * where the from range is the local mapped range, and the to range | |
2572 | * is the 'mapped' range in the MapRangeType | |
2573 | * @param default | |
2574 | * unit for local | |
2575 | * @param default | |
2576 | * unit for mapped | |
2577 | * @return MapList | |
2578 | */ | |
2579 | 0 | private jalview.util.MapList parsemapType(MapType maprange, int localu, |
2580 | int mappedu) | |
2581 | { | |
2582 | 0 | jalview.util.MapList ml = null; |
2583 | 0 | int[] localRange = getMapping(maprange.getLocal()); |
2584 | 0 | int[] mappedRange = getMapping(maprange.getMapped()); |
2585 | 0 | long lu = maprange.getLocal().hasUnit() ? maprange.getLocal().getUnit() |
2586 | : localu; | |
2587 | 0 | long mu = maprange.getMapped().hasUnit() |
2588 | ? maprange.getMapped().getUnit() | |
2589 | : mappedu; | |
2590 | 0 | ml = new jalview.util.MapList(localRange, mappedRange, (int) lu, |
2591 | (int) mu); | |
2592 | 0 | return ml; |
2593 | } | |
2594 | ||
2595 | /** | |
2596 | * initialise a range type object from a set of start/end inclusive intervals | |
2597 | * | |
2598 | * @param mrt | |
2599 | * @param ranges | |
2600 | */ | |
2601 | 0 | private void initRangeType(RangeType mrt, List<int[]> ranges) |
2602 | { | |
2603 | 0 | for (int[] range : ranges) |
2604 | { | |
2605 | 0 | Seg vSeg = new Seg(); |
2606 | 0 | vSeg.setStart(range[0]); |
2607 | 0 | vSeg.setEnd(range[1]); |
2608 | 0 | mrt.addSeg(vSeg); |
2609 | } | |
2610 | } | |
2611 | ||
2612 | /** | |
2613 | * initialise a MapType object from a MapList object. | |
2614 | * | |
2615 | * @param maprange | |
2616 | * @param ml | |
2617 | * @param setUnits | |
2618 | */ | |
2619 | 0 | private void initMapType(MapType maprange, jalview.util.MapList ml, |
2620 | boolean setUnits) | |
2621 | { | |
2622 | 0 | maprange.setLocal(new Local()); |
2623 | 0 | maprange.setMapped(new Mapped()); |
2624 | 0 | initRangeType(maprange.getLocal(), ml.getFromRanges()); |
2625 | 0 | initRangeType(maprange.getMapped(), ml.getToRanges()); |
2626 | 0 | if (setUnits) |
2627 | { | |
2628 | 0 | maprange.getLocal().setUnit(ml.getFromRatio()); |
2629 | 0 | maprange.getLocal().setUnit(ml.getToRatio()); |
2630 | } | |
2631 | } | |
2632 | ||
2633 | /* | |
2634 | * not needed now. Provenance getVamsasProvenance(jalview.datamodel.Provenance | |
2635 | * jprov) { jalview.datamodel.ProvenanceEntry[] entries = null; // TODO: fix | |
2636 | * App and Action here. Provenance prov = new Provenance(); | |
2637 | * org.exolab.castor.types.Date date = new org.exolab.castor.types.Date( new | |
2638 | * java.util.Date()); Entry provEntry; | |
2639 | * | |
2640 | * if (jprov != null) { entries = jprov.getEntries(); for (int i = 0; i < | |
2641 | * entries.length; i++) { provEntry = new Entry(); try { date = new | |
2642 | * org.exolab.castor.types.Date(entries[i].getDate()); } catch (Exception ex) | |
2643 | * { ex.printStackTrace(); | |
2644 | * | |
2645 | * date = new org.exolab.castor.types.Date(entries[i].getDate()); } | |
2646 | * provEntry.setDate(date); provEntry.setUser(entries[i].getUser()); | |
2647 | * provEntry.setAction(entries[i].getAction()); prov.addEntry(provEntry); } } | |
2648 | * else { provEntry = new Entry(); provEntry.setDate(date); | |
2649 | * provEntry.setUser(System.getProperty("user.name")); // TODO: ext string | |
2650 | * provEntry.setApp("JVAPP"); // TODO: ext string provEntry.setAction(action); | |
2651 | * prov.addEntry(provEntry); } | |
2652 | * | |
2653 | * return prov; } | |
2654 | */ | |
2655 | 0 | jalview.datamodel.Provenance getJalviewProvenance(Provenance prov) |
2656 | { | |
2657 | // TODO: fix App and Action entries and check use of provenance in jalview. | |
2658 | 0 | jalview.datamodel.Provenance jprov = new jalview.datamodel.Provenance(); |
2659 | 0 | for (int i = 0; i < prov.getEntryCount(); i++) |
2660 | { | |
2661 | 0 | jprov.addEntry(prov.getEntry(i).getUser(), |
2662 | prov.getEntry(i).getAction(), prov.getEntry(i).getDate(), | |
2663 | prov.getEntry(i).getId()); | |
2664 | } | |
2665 | ||
2666 | 0 | return jprov; |
2667 | } | |
2668 | ||
2669 | /** | |
2670 | * | |
2671 | * @return default initial provenance list for a Jalview created vamsas | |
2672 | * object. | |
2673 | */ | |
2674 | 0 | Provenance dummyProvenance() |
2675 | { | |
2676 | 0 | return dummyProvenance(null); |
2677 | } | |
2678 | ||
2679 | 0 | Entry dummyPEntry(String action) |
2680 | { | |
2681 | 0 | Entry entry = new Entry(); |
2682 | 0 | entry.setApp(this.provEntry.getApp()); |
2683 | 0 | if (action != null) |
2684 | { | |
2685 | 0 | entry.setAction(action); |
2686 | } | |
2687 | else | |
2688 | { | |
2689 | 0 | entry.setAction("created."); |
2690 | } | |
2691 | 0 | entry.setDate(new java.util.Date()); |
2692 | 0 | entry.setUser(this.provEntry.getUser()); |
2693 | 0 | return entry; |
2694 | } | |
2695 | ||
2696 | 0 | Provenance dummyProvenance(String action) |
2697 | { | |
2698 | 0 | Provenance prov = new Provenance(); |
2699 | 0 | prov.addEntry(dummyPEntry(action)); |
2700 | 0 | return prov; |
2701 | } | |
2702 | ||
2703 | 0 | Entry addProvenance(Provenance p, String action) |
2704 | { | |
2705 | 0 | Entry dentry = dummyPEntry(action); |
2706 | 0 | p.addEntry(dentry); |
2707 | 0 | return dentry; |
2708 | } | |
2709 | ||
2710 | 0 | public Entry getProvEntry() |
2711 | { | |
2712 | 0 | return provEntry; |
2713 | } | |
2714 | ||
2715 | 0 | public IClientDocument getClientDocument() |
2716 | { | |
2717 | 0 | return cdoc; |
2718 | } | |
2719 | ||
2720 | 0 | public IdentityHashMap getJvObjectBinding() |
2721 | { | |
2722 | 0 | return jv2vobj; |
2723 | } | |
2724 | ||
2725 | 0 | public Hashtable getVamsasObjectBinding() |
2726 | { | |
2727 | 0 | return vobj2jv; |
2728 | } | |
2729 | ||
2730 | 0 | public void storeSequenceMappings(AlignmentViewport viewport, |
2731 | String title) throws Exception | |
2732 | { | |
2733 | 0 | AlignmentViewport av = viewport; |
2734 | 0 | try |
2735 | { | |
2736 | 0 | jalview.datamodel.AlignmentI jal = av.getAlignment(); |
2737 | // ///////////////////////////////////////// | |
2738 | // SAVE THE DATASET | |
2739 | 0 | DataSet dataset = null; |
2740 | 0 | if (jal.getDataset() == null) |
2741 | { | |
2742 | 0 | Console.warn("Creating new dataset for an alignment."); |
2743 | 0 | jal.setDataset(null); |
2744 | } | |
2745 | 0 | dataset = (DataSet) ((Alignment) getjv2vObj( |
2746 | viewport.getSequenceSetId())).getV_parent(); // jal.getDataset()); | |
2747 | 0 | if (dataset == null) |
2748 | { | |
2749 | 0 | dataset = (DataSet) getjv2vObj(jal.getDataset()); |
2750 | 0 | Console.error( |
2751 | "Can't find the correct dataset for the alignment in this view. Creating new one."); | |
2752 | ||
2753 | } | |
2754 | // Store any sequence mappings. | |
2755 | 0 | List<AlignedCodonFrame> cframes = av.getAlignment().getCodonFrames(); |
2756 | 0 | if (cframes != null) |
2757 | { | |
2758 | 0 | for (AlignedCodonFrame acf : cframes) |
2759 | { | |
2760 | 0 | if (acf.getdnaSeqs() != null && acf.getdnaSeqs().length > 0) |
2761 | { | |
2762 | 0 | jalview.datamodel.SequenceI[] dmps = acf.getdnaSeqs(); |
2763 | 0 | jalview.datamodel.Mapping[] mps = acf.getProtMappings(); |
2764 | 0 | for (int smp = 0; smp < mps.length; smp++) |
2765 | { | |
2766 | 0 | uk.ac.vamsas.objects.core.SequenceType mfrom = (SequenceType) getjv2vObj( |
2767 | dmps[smp]); | |
2768 | 0 | if (mfrom != null) |
2769 | { | |
2770 | 0 | new jalview.io.vamsas.Sequencemapping(this, mps[smp], mfrom, |
2771 | dataset); | |
2772 | } | |
2773 | else | |
2774 | { | |
2775 | 0 | Console.warn( |
2776 | "NO Vamsas Binding for local sequence! NOT CREATING MAPPING FOR " | |
2777 | + dmps[smp].getDisplayId(true) + " to " | |
2778 | + mps[smp].getTo().getName()); | |
2779 | } | |
2780 | } | |
2781 | } | |
2782 | } | |
2783 | } | |
2784 | } catch (Exception e) | |
2785 | { | |
2786 | 0 | throw new Exception(MessageManager.formatMessage( |
2787 | "exception.couldnt_store_sequence_mappings", new String[] | |
2788 | { title }), e); | |
2789 | } | |
2790 | } | |
2791 | ||
2792 | 0 | public void clearSkipList() |
2793 | { | |
2794 | 0 | if (skipList != null) |
2795 | { | |
2796 | 0 | skipList.clear(); |
2797 | } | |
2798 | } | |
2799 | ||
2800 | /** | |
2801 | * @return the skipList | |
2802 | */ | |
2803 | 0 | public Hashtable getSkipList() |
2804 | { | |
2805 | 0 | return skipList; |
2806 | } | |
2807 | ||
2808 | /** | |
2809 | * @param skipList | |
2810 | * the skipList to set | |
2811 | */ | |
2812 | 0 | public void setSkipList(Hashtable skipList) |
2813 | { | |
2814 | 0 | this.skipList = skipList; |
2815 | } | |
2816 | ||
2817 | /** | |
2818 | * registry for datastoreItems | |
2819 | */ | |
2820 | DatastoreRegistry dsReg = new DatastoreRegistry(); | |
2821 | ||
2822 | 0 | public DatastoreRegistry getDatastoreRegisty() |
2823 | { | |
2824 | 0 | if (dsReg == null) |
2825 | { | |
2826 | 0 | dsReg = new DatastoreRegistry(); |
2827 | } | |
2828 | 0 | return dsReg; |
2829 | } | |
2830 | } |