2 * Jalview - A Sequence Alignment Editor and Viewer
\r
3 * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
\r
5 * This program is free software; you can redistribute it and/or
\r
6 * modify it under the terms of the GNU General Public License
\r
7 * as published by the Free Software Foundation; either version 2
\r
8 * of the License, or (at your option) any later version.
\r
10 * This program is distributed in the hope that it will be useful,
\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 * GNU General Public License for more details.
\r
15 * You should have received a copy of the GNU General Public License
\r
16 * along with this program; if not, write to the Free Software
\r
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
\r
22 import org.vamsas.client.Vobject;
\r
23 import org.vamsas.client.VorbaId;
\r
24 import org.vamsas.objects.core.*;
\r
25 import org.vamsas.objects.utils.DocumentStuff;
\r
26 import org.vamsas.test.simpleclient.ClientDoc;
\r
28 import jalview.bin.Cache;
\r
29 import jalview.datamodel.AlignmentAnnotation;
\r
30 import jalview.datamodel.AlignmentI;
\r
31 import jalview.datamodel.AlignmentView;
\r
32 import jalview.datamodel.DBRefEntry;
\r
33 import jalview.datamodel.SequenceFeature;
\r
34 import jalview.datamodel.SequenceI;
\r
35 import jalview.gui.*;
\r
38 import java.util.HashMap;
\r
39 import java.util.HashSet;
\r
40 import java.util.Hashtable;
\r
41 import java.util.IdentityHashMap;
\r
42 import java.util.Vector;
\r
43 import java.util.jar.*;
\r
44 import org.exolab.castor.xml.*;
\r
45 import org.exolab.castor.mapping.Mapping;
\r
50 * org.exolab.castor.util.LocalConfiguration.getInstance().getProperties().setProperty(
\r
51 * "org.exolab.castor.serializer", "org.apache.xml.serialize.XMLSerilazizer"); }
\r
55 public class VamsasDatastore {
\r
56 Entry provEntry = null;
\r
58 // AlignViewport av;
\r
60 org.exolab.castor.types.Date date = new org.exolab.castor.types.Date(
\r
61 new java.util.Date());
\r
67 IdentityHashMap jv2vobj;
\r
69 public VamsasDatastore(ClientDoc cdoc, Hashtable vobj2jv,
\r
70 IdentityHashMap jv2vobj, Entry provEntry) {
\r
72 this.vobj2jv = vobj2jv;
\r
73 this.jv2vobj = jv2vobj;
\r
74 this.provEntry = provEntry;
\r
78 * public void storeJalview(String file, AlignFrame af) { try { // 1. Load the
\r
79 * mapping information from the file Mapping map = new
\r
80 * Mapping(getClass().getClassLoader()); java.net.URL url =
\r
81 * getClass().getResource("/jalview_mapping.xml"); map.loadMapping(url); // 2.
\r
82 * Unmarshal the data // Unmarshaller unmar = new Unmarshaller();
\r
83 * //unmar.setIgnoreExtraElements(true); //unmar.setMapping(map); // uni =
\r
84 * (UniprotFile) unmar.unmarshal(new FileReader(file)); // 3. marshal the data
\r
85 * with the total price back and print the XML in the console Marshaller
\r
86 * marshaller = new Marshaller( new FileWriter(file) );
\r
88 * marshaller.setMapping(map); marshaller.marshal(af); } catch (Exception e) {
\r
89 * e.printStackTrace(); } }
\r
94 * @return the Vobject bound to Jalview datamodel object
\r
96 protected Vobject getjv2vObj(Object jvobj) {
\r
97 if (jv2vobj.containsKey(jvobj))
\r
98 return cdoc.getObject((VorbaId) jv2vobj.get(jvobj));
\r
105 * @return Jalview datamodel object bound to the vamsas document object
\r
107 protected Object getvObj2jv(org.vamsas.client.Vobject vobj) {
\r
108 VorbaId id = vobj.getVorbaId();
\r
111 id = cdoc.registerObject(vobj);
\r
113 .debug("Registering new object and returning null for getvObj2jv");
\r
116 if (vobj2jv.containsKey(vobj.getVorbaId()))
\r
117 return vobj2jv.get(vobj.getVorbaId());
\r
121 protected void bindjvvobj(Object jvobj, org.vamsas.client.Vobject vobj) {
\r
122 VorbaId id = vobj.getVorbaId();
\r
125 id = cdoc.registerObject(vobj);
\r
126 if (id==null || vobj.getVorbaId()==null)
\r
127 Cache.log.error("Failed to get id for "+(vobj.isRegisterable() ? "registerable" : "unregisterable") +" object "+vobj);
\r
130 if (vobj2jv.containsKey(vobj.getVorbaId()) && !((VorbaId)vobj2jv.get(vobj.getVorbaId())).equals(jvobj)) {
\r
131 Cache.log.debug("Warning? Overwriting existing vamsas id binding for "+vobj.getVorbaId(), new Exception("Overwriting vamsas id binding."));
\r
133 else if (jv2vobj.containsKey(jvobj) && !((VorbaId)jv2vobj.get(jvobj)).equals(vobj.getVorbaId()))
\r
135 Cache.log.debug("Warning? Overwriting existing jalview object binding for "+jvobj, new Exception("Overwriting jalview object binding."));
\r
137 /* Cache.log.error("Attempt to make conflicting object binding! "+vobj+" id " +vobj.getVorbaId()+" already bound to "+getvObj2jv(vobj)+" and "+jvobj+" already bound to "+getjv2vObj(jvobj),new Exception("Excessive call to bindjvvobj"));
\r
139 // we just update the hash's regardless!
\r
140 vobj2jv.put(vobj.getVorbaId(), jvobj);
\r
141 // JBPNote - better implementing a hybrid invertible hash.
\r
142 jv2vobj.put(jvobj, vobj.getVorbaId());
\r
146 * put the alignment viewed by AlignViewport into cdoc.
\r
148 * @param av alignViewport to be stored
\r
149 * @param aFtitle title for alignment
\r
151 public void storeVAMSAS(AlignViewport av, String aFtitle) {
\r
154 jalview.datamodel.AlignmentI jal = av.getAlignment();
\r
155 boolean nw = false;
\r
156 VAMSAS root = null; // will be resolved based on Dataset Parent.
\r
157 // /////////////////////////////////////////
\r
158 // SAVE THE DATASET
\r
159 if (jal.getDataset() == null)
\r
161 Cache.log.warn("Creating new dataset for an alignment.");
\r
162 jal.setDataset(null);
\r
164 DataSet dataset = (DataSet) getjv2vObj(jal.getDataset());
\r
165 if (dataset == null)
\r
167 root = cdoc.getVamsasRoots()[0]; // default vamsas root for modifying.
\r
168 dataset = new DataSet();
\r
169 root.addDataSet(dataset);
\r
170 bindjvvobj(jal.getDataset(), dataset);
\r
171 dataset.setProvenance(dummyProvenance());
\r
172 dataset.getProvenance().addEntry(provEntry);
\r
177 root = (VAMSAS) dataset.getV_parent();
\r
182 // set new dataset and alignment sequences based on alignment Nucleotide
\r
184 // this *will* break when alignment contains both nucleotide and amino
\r
186 String dict = jal.isNucleotide() ? org.vamsas.objects.utils.SymbolDictionary.STANDARD_NA
\r
187 : org.vamsas.objects.utils.SymbolDictionary.STANDARD_AA;
\r
188 for (int i = 0; i < jal.getHeight(); i++)
\r
190 SequenceI sq = jal.getSequenceAt(i).getDatasetSequence(); // only insert
\r
194 sequence = (Sequence) getjv2vObj(sq);
\r
195 if (sequence == null)
\r
197 sequence = new Sequence();
\r
198 bindjvvobj(sq, sequence);
\r
199 sq.setVamsasId(sequence.getVorbaId().getId());
\r
200 sequence.setSequence(sq.getSequence());
\r
201 sequence.setDictionary(dict);
\r
202 sequence.setName(jal.getDataset().getSequenceAt(i).getName());
\r
203 sequence.setStart(jal.getDataset().getSequenceAt(i).getStart());
\r
204 sequence.setEnd(jal.getDataset().getSequenceAt(i).getEnd());
\r
205 dataset.addSequence(sequence);
\r
209 // verify principal attributes. and update any new
\r
210 // features/references.
\r
211 System.out.println("update dataset sequence object.");
\r
213 if (sq.getSequenceFeatures() != null)
\r
215 int sfSize = sq.getSequenceFeatures().length;
\r
217 for (int sf = 0; sf < sfSize; sf++)
\r
219 jalview.datamodel.SequenceFeature feature = (jalview.datamodel.SequenceFeature) sq
\r
220 .getSequenceFeatures()[sf];
\r
222 DataSetAnnotations dsa = (DataSetAnnotations) getjv2vObj(feature);
\r
225 dsa = (DataSetAnnotations) getDSAnnotationFromJalview(
\r
226 new DataSetAnnotations(), feature);
\r
227 if (dsa.getProvenance() == null)
\r
229 dsa.setProvenance(new Provenance());
\r
231 addProvenance(dsa.getProvenance(), "created"); // JBPNote - need
\r
233 dsa.setSeqRef(sequence);
\r
234 bindjvvobj(feature, dsa);
\r
235 dataset.addDataSetAnnotations(dsa);
\r
239 // todo: verify and update dataset annotations for sequence
\r
240 System.out.println("update dataset sequence annotations.");
\r
245 if (sq.getDBRef() != null)
\r
247 DBRefEntry[] entries = sq.getDBRef();
\r
248 jalview.datamodel.DBRefEntry dbentry;
\r
249 for (int db = 0; db < entries.length; db++)
\r
251 dbentry = entries[db];
\r
252 dbref = (DbRef) getjv2vObj(dbentry);
\r
255 dbref = new DbRef();
\r
256 bindjvvobj(dbentry, dbref);
\r
257 dbref.setAccessionId(dbentry.getAccessionId());
\r
258 dbref.setSource(dbentry.getSource());
\r
259 dbref.setVersion(dbentry.getVersion());
\r
261 * TODO: Maps are not yet supported by Jalview. Map vMap = new
\r
262 * Map(); vMap.set dbref.addMap(vMap);
\r
264 sequence.addDbRef(dbref);
\r
268 // TODO: verify and update dbrefs in vamsas document
\r
269 // there will be trouble when a dataset sequence is modified to
\r
270 // contain more residues than were originally referenced - we must
\r
271 // then make a number of dataset sequence entries
\r
273 .println("update dataset sequence database references.");
\r
279 // dataset.setProvenance(getVamsasProvenance(jal.getDataset().getProvenance()));
\r
280 // ////////////////////////////////////////////
\r
282 // ////////////////////////////////////////////
\r
283 // Save the Alignments
\r
285 Alignment alignment = (Alignment) getjv2vObj(av); // this is so we can get the alignviewport back
\r
286 if (alignment == null)
\r
288 alignment = new Alignment();
\r
289 bindjvvobj(av, alignment);
\r
290 if (alignment.getProvenance() == null)
\r
291 alignment.setProvenance(new Provenance());
\r
292 addProvenance(alignment.getProvenance(), "added"); // TODO: insert some
\r
295 dataset.addAlignment(alignment);
\r
297 Property title = new Property();
\r
298 title.setName("jalview:AlTitle");
\r
299 title.setType("string");
\r
300 title.setContent(aFtitle);
\r
301 alignment.addProperty(title);
\r
303 alignment.setGapChar(String.valueOf(av.getGapCharacter()));
\r
304 AlignmentSequence alseq = null;
\r
305 for (int i = 0; i < jal.getHeight(); i++)
\r
307 alseq = new AlignmentSequence();
\r
308 // TODO: VAMSAS: translate lowercase symbols to annotation ?
\r
309 alseq.setSequence(jal.getSequenceAt(i).getSequence());
\r
310 alseq.setName(jal.getSequenceAt(i).getName());
\r
311 alseq.setStart(jal.getSequenceAt(i).getStart());
\r
312 alseq.setEnd(jal.getSequenceAt(i).getEnd());
\r
313 alseq.setRefid(getjv2vObj(jal.getSequenceAt(i).getDatasetSequence()));
\r
314 alignment.addAlignmentSequence(alseq);
\r
315 bindjvvobj(jal.getSequenceAt(i), alseq);
\r
320 // todo: verify and update mutable alignment props.
\r
321 if (alignment.getModifiable())
\r
323 System.out.println("update alignment in document.");
\r
328 .println("update edited alignment to new alignment in document.");
\r
331 // ////////////////////////////////////////////
\r
332 // SAVE Alignment Sequence Features
\r
333 for (int i = 0, iSize = alignment.getAlignmentSequenceCount(); i < iSize; i++)
\r
335 AlignmentSequence valseq;
\r
336 SequenceI alseq = (SequenceI) getvObj2jv(valseq = alignment
\r
337 .getAlignmentSequence(i));
\r
338 if (alseq != null && alseq.getSequenceFeatures() != null)
\r
340 jalview.datamodel.SequenceFeature[] features = alseq
\r
341 .getSequenceFeatures();
\r
342 for (int f = 0; f < features.length; f++)
\r
344 if (features[f] != null)
\r
346 AlignmentSequenceAnnotation valseqf = (AlignmentSequenceAnnotation) getjv2vObj(features[i]);
\r
347 if (valseqf == null)
\r
350 valseqf = (AlignmentSequenceAnnotation) getDSAnnotationFromJalview(
\r
351 new AlignmentSequenceAnnotation(), features[i]);
\r
352 if (valseqf.getProvenance() == null)
\r
354 valseqf.setProvenance(new Provenance());
\r
356 addProvenance(valseqf.getProvenance(), "created"); // JBPNote -
\r
359 bindjvvobj(features[i], valseqf);
\r
360 valseq.addAlignmentSequenceAnnotation(valseqf);
\r
368 // ////////////////////////////////////////////
\r
369 // SAVE ANNOTATIONS
\r
370 if (jal.getAlignmentAnnotation() != null)
\r
372 jalview.datamodel.AlignmentAnnotation[] aa = jal
\r
373 .getAlignmentAnnotation();
\r
374 java.util.HashMap AlSeqMaps = new HashMap(); // stores int maps from
\r
375 // alignment columns to
\r
376 // sequence positions.
\r
377 for (int i = 0; i < aa.length; i++)
\r
379 if (aa[i] == null || isJalviewOnly(aa[i]))
\r
383 if (aa[i].sequenceRef != null)
\r
385 org.vamsas.objects.core.AlignmentSequence alsref = (org.vamsas.objects.core.AlignmentSequence) getjv2vObj(aa[i].sequenceRef);
\r
386 org.vamsas.objects.core.AlignmentSequenceAnnotation an = (org.vamsas.objects.core.AlignmentSequenceAnnotation) getjv2vObj(aa[i]);
\r
387 int[] gapMap = null;
\r
388 if (AlSeqMaps.containsKey(aa[i].sequenceRef))
\r
390 gapMap = (int[]) AlSeqMaps.get(aa[i].sequenceRef);
\r
394 gapMap = new int[aa[i].sequenceRef.getLength()];
\r
395 // map from alignment position to sequence position.
\r
396 int[] sgapMap = aa[i].sequenceRef.gapMap();
\r
397 for (int a = 0; a < sgapMap.length; a++)
\r
398 gapMap[sgapMap[a]] = a;
\r
402 an = new org.vamsas.objects.core.AlignmentSequenceAnnotation();
\r
403 Seg vSeg = new Seg();
\r
405 vSeg.setInclusive(true);
\r
406 vSeg.setEnd(gapMap.length);
\r
408 an.setType("jalview:SecondaryStructurePrediction");// TODO: better fix this rough guess ;)
\r
409 alsref.addAlignmentSequenceAnnotation(an);
\r
410 bindjvvobj(aa[i],an);
\r
411 // LATER: much of this is verbatim from the alignmentAnnotation
\r
412 // method below. suggests refactoring to make rangeAnnotation the
\r
414 an.setDescription(aa[i].description);
\r
415 if (aa[i].graph > 0)
\r
416 an.setGraph(true); // aa[i].graph);
\r
418 an.setGraph(false);
\r
419 an.setLabel(aa[i].label);
\r
420 an.setProvenance(dummyProvenance()); // get provenance as user
\r
421 // created, or jnet, or
\r
423 an.setGroup(Integer.toString(aa[i].graphGroup)); // // JBPNote -
\r
431 AnnotationElement ae;
\r
432 for (int a = 0; a < aa[i].annotations.length; a++)
\r
434 if (aa[i].annotations[a] == null)
\r
439 ae = new AnnotationElement();
\r
440 ae.setDescription(aa[i].annotations[a].description);
\r
441 ae.addGlyph(new Glyph());
\r
443 .setContent(aa[i].annotations[a].displayCharacter); // assume
\r
450 if (aa[i].graph!=jalview.datamodel.AlignmentAnnotation.NO_GRAPH)
\r
451 ae.addValue(aa[i].annotations[a].value);
\r
452 ae.setPosition(gapMap[a]+1); // position w.r.t. AlignmentSequence
\r
454 if (aa[i].annotations[a].secondaryStructure != ' ')
\r
456 // we only write an annotation where it really exists.
\r
457 Glyph ss = new Glyph();
\r
459 .setDict(org.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE);
\r
460 ss.setContent(String
\r
461 .valueOf(aa[i].annotations[a].secondaryStructure));
\r
464 an.addAnnotationElement(ae);
\r
469 // update reference sequence Annotation
\r
470 if (an.getModifiable())
\r
472 // verify existing alignment sequence annotation is up to date
\r
473 System.out.println("update alignment sequence annotation.");
\r
477 // verify existing alignment sequence annotation is up to date
\r
479 .println("make new alignment sequence annotation if modification has happened.");
\r
485 // add Alignment Annotation
\r
486 org.vamsas.objects.core.AlignmentAnnotation an = (org.vamsas.objects.core.AlignmentAnnotation) getjv2vObj(aa[i]);
\r
489 an = new org.vamsas.objects.core.AlignmentAnnotation();
\r
490 an.setType("jalview:AnnotationRow");
\r
491 an.setDescription(aa[i].description);
\r
492 alignment.addAlignmentAnnotation(an);
\r
493 Seg vSeg = new Seg();
\r
495 vSeg.setInclusive(true);
\r
496 vSeg.setEnd(jal.getWidth());
\r
498 if (aa[i].graph > 0)
\r
499 an.setGraph(true); // aa[i].graph);
\r
500 an.setLabel(aa[i].label);
\r
501 an.setProvenance(dummyProvenance());
\r
502 if (aa[i].graph!=aa[i].NO_GRAPH) {
\r
503 an.setGroup(Integer.toString(aa[i].graphGroup)); // // JBPNote -
\r
513 an.setGraph(false);
\r
515 AnnotationElement ae;
\r
517 for (int a = 0; a < aa[i].annotations.length; a++)
\r
519 if ((aa[i] == null) || (aa[i].annotations[a] == null))
\r
524 ae = new AnnotationElement();
\r
525 ae.setDescription(aa[i].annotations[a].description);
\r
526 ae.addGlyph(new Glyph());
\r
528 .setContent(aa[i].annotations[a].displayCharacter); // assume
\r
535 ae.addValue(aa[i].annotations[a].value);
\r
536 ae.setPosition(a+1);
\r
537 if (aa[i].annotations[a].secondaryStructure != ' ')
\r
539 Glyph ss = new Glyph();
\r
541 .setDict(org.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE);
\r
542 ss.setContent(String
\r
543 .valueOf(aa[i].annotations[a].secondaryStructure));
\r
546 an.addAnnotationElement(ae);
\r
548 if (aa[i].editable) {
\r
549 //an.addProperty(newProperty("jalview:editable", null, "true"));
\r
550 an.setModifiable(true);
\r
552 if (aa[i].graph!=jalview.datamodel.AlignmentAnnotation.NO_GRAPH) {
\r
554 an.setGroup(Integer.toString(aa[i].graphGroup));
\r
555 an.addProperty(newProperty("jalview:graphType",null,
\r
556 ((aa[i].graph==jalview.datamodel.AlignmentAnnotation.BAR_GRAPH) ? "BAR_GRAPH" : "LINE_GRAPH")));
\r
558 /** and on and on..
\r
559 vProperty=new Property();
\r
560 vProperty.setName("jalview:graphThreshhold");
\r
561 vProperty.setContent(aa[i].threshold);
\r
568 if (an.getModifiable())
\r
570 // verify annotation - update (perhaps)
\r
571 Cache.log.info("update alignment sequence annotation. not yet implemented.");
\r
575 // verify annotation - update (perhaps)
\r
576 Cache.log.info("updated alignment sequence annotation added.");
\r
582 // /////////////////////////////////////////////////////
\r
584 // //////////////////////////////////////////////
\r
586 // /////////////////////////////////
\r
587 // FIND ANY ASSOCIATED TREES
\r
588 if (Desktop.desktop != null)
\r
590 javax.swing.JInternalFrame[] frames = Desktop.desktop.getAllFrames();
\r
592 for (int t = 0; t < frames.length; t++)
\r
594 if (frames[t] instanceof TreePanel)
\r
596 TreePanel tp = (TreePanel) frames[t];
\r
598 if (tp.getAlignment() == jal)
\r
600 Tree tree = (Tree) getjv2vObj(tp);
\r
604 bindjvvobj(tp, tree);
\r
605 tree.setTitle(tp.getTitle());
\r
606 Newick newick = new Newick();
\r
607 // TODO: translate sequenceI to leaf mappings to vamsas
\r
608 // references - see tree specification in schema.
\r
609 newick.setContent(tp.getTree().toString());
\r
610 newick.setTitle(tp.getTitle());
\r
611 tree.addNewick(newick);
\r
612 tree.setProvenance(makeTreeProvenance(jal, tp));
\r
613 alignment.addTree(tree);
\r
617 if (tree.getModifiable())
\r
619 // verify any changes.
\r
620 System.out.println("Update tree in document.");
\r
625 .println("Add modified tree as new tree in document.");
\r
632 // Store Jalview specific stuff in the Jalview appData
\r
633 // not implemented in the SimpleDoc interface.
\r
636 catch (Exception ex)
\r
638 ex.printStackTrace();
\r
643 private Property newProperty(String name, String type, String content) {
\r
644 Property vProperty=new Property();
\r
645 vProperty.setName(name);
\r
647 vProperty.setType(type);
\r
649 vProperty.setType("String");
\r
650 vProperty.setContent(content);
\r
655 * correctly create a RangeAnnotation from a jalview sequence feature
\r
658 * (typically DataSetAnnotations or AlignmentSequenceAnnotation)
\r
660 * (the feature to be mapped from)
\r
663 private RangeAnnotation getDSAnnotationFromJalview(RangeAnnotation dsa,
\r
664 SequenceFeature feature) {
\r
665 dsa.setType(feature.getType());
\r
666 Seg vSeg = new Seg();
\r
667 vSeg.setStart(feature.getBegin());
\r
668 vSeg.setEnd(feature.getEnd());
\r
669 vSeg.setInclusive(true);
\r
671 dsa.setDescription(feature.getDescription());
\r
672 dsa.setStatus(feature.getStatus());
\r
673 if (feature.links != null && feature.links.size() > 0)
\r
675 for (int i = 0, iSize = feature.links.size(); i < iSize; i++)
\r
677 String link = (String) feature.links.elementAt(i);
\r
678 int sep = link.indexOf('|');
\r
681 Link vLink = new Link();
\r
683 vLink.setContent(link.substring(0, sep - 1));
\r
685 vLink.setContent("");
\r
686 vLink.setHref(link.substring(sep + 1)); // TODO: validate href.
\r
687 dsa.addLink(vLink);
\r
691 dsa.setGroup(feature.getFeatureGroup());
\r
696 * correctly creates provenance for trees calculated on an alignment by
\r
703 private Provenance makeTreeProvenance(AlignmentI jal, TreePanel tp) {
\r
704 Provenance prov = new Provenance();
\r
705 prov.addEntry(new Entry());
\r
706 prov.getEntry(0).setAction("imported "+tp.getTitle());
\r
707 prov.getEntry(0).setUser(provEntry.getUser());
\r
708 prov.getEntry(0).setApp(provEntry.getApp());
\r
709 prov.getEntry(0).setDate(provEntry.getDate());
\r
710 if (tp.getTree().hasOriginalSequenceData())
\r
712 Input vInput = new Input();
\r
713 // LATER: check to see if tree input data is contained in this alignment -
\r
714 // or just correctly resolve the tree's seqData to the correct alignment in
\r
716 // vInput.setObjRef(getjv2vObj(jal));
\r
717 vInput.setObjRef(getjv2vObj(tp.getViewPort()));
\r
718 prov.getEntry(0).setAction("created "+tp.getTitle());
\r
719 prov.getEntry(0).addInput(vInput);
\r
720 vInput.setName("jalview:seqdist");
\r
721 prov.getEntry(0).addParam(new Param());
\r
722 prov.getEntry(0).getParam(0).setName("treeType");
\r
723 prov.getEntry(0).getParam(0).setType("utf8");
\r
724 prov.getEntry(0).getParam(0).setContent("NJ");
\r
726 int ranges[] = tp.getTree().seqData.getVisibleContigs();
\r
727 // VisibleContigs are with respect to alignment coordinates. Still need offsets
\r
728 int start= tp.getTree().seqData.getAlignmentOrigin();
\r
729 for (int r = 0; r < ranges.length; r += 2)
\r
731 Seg visSeg = new Seg();
\r
732 visSeg.setStart(1+start+ranges[r]);
\r
733 visSeg.setEnd(start+ranges[r + 1]);
\r
734 visSeg.setInclusive(true);
\r
735 vInput.addSeg(visSeg);
\r
744 * @return Object[] { AlignmentView, AlignmentI - reference alignment for
\r
747 private Object[] recoverInputData(Provenance tp) {
\r
748 for (int pe = 0; pe < tp.getEntryCount(); pe++)
\r
750 if (tp.getEntry(pe).getInputCount() > 0)
\r
752 if (tp.getEntry(pe).getInputCount() > 1)
\r
753 Cache.log.warn("Ignoring additional input spec in provenance entry "
\r
754 + tp.getEntry(pe).toString());
\r
755 // LATER: deal sensibly with multiple inputs.
\r
756 Input vInput = tp.getEntry(pe).getInput(0);
\r
757 if (vInput.getObjRef() instanceof org.vamsas.objects.core.Alignment)
\r
759 // recover an AlignmentView for the input data
\r
760 AlignViewport javport = (AlignViewport) getvObj2jv((org.vamsas.client.Vobject) vInput
\r
762 jalview.datamodel.AlignmentI jal = javport.getAlignment();
\r
763 jalview.datamodel.CigarArray view = javport.getAlignment().getCompactAlignment();
\r
764 int from = 1, to = jal.getWidth();
\r
765 int offset=0; // deleteRange modifies its frame of reference
\r
766 for (int r = 0, s = vInput.getSegCount(); r < s; r++)
\r
768 Seg visSeg = vInput.getSeg(r);
\r
769 int se[] = getSegRange(visSeg,true); // jalview doesn't do bidirection alignments yet.
\r
771 Cache.log.warn("Ignoring invalid segment in InputData spec.");
\r
776 view.deleteRange(offset+from-1, offset+se[0] - 2);
\r
777 offset-=se[0]-from;
\r
784 view.deleteRange(offset+from-1, offset+to-1); // final deletion - TODO: check off by
\r
787 return new Object[] { new AlignmentView(view), jal };
\r
791 Cache.log.debug("Returning null for input data recovery from provenance.");
\r
796 * get start<end range of segment, adjusting for inclusivity flag and
\r
800 * @param ensureDirection when true - always ensure start is less than end.
\r
801 * @return int[] { start, end, direction} where direction==1 for range running from end to start.
\r
803 private int[] getSegRange(Seg visSeg, boolean ensureDirection) {
\r
804 boolean incl = visSeg.getInclusive();
\r
805 // adjust for inclusive flag.
\r
806 int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of
\r
808 int start = visSeg.getStart() + (incl ? 0 : pol);
\r
809 int end = visSeg.getEnd() + (incl ? 0 : -pol);
\r
810 if (ensureDirection && pol==-1)
\r
812 // jalview doesn't deal with inverted ranges, yet.
\r
817 return new int[] { start, end, pol<0 ? 1 : 0 };
\r
822 * @param annotation
\r
823 * @return true if annotation is not to be stored in document
\r
825 private boolean isJalviewOnly(AlignmentAnnotation annotation) {
\r
826 return annotation.label.equals("Quality")
\r
827 || annotation.label.equals("Conservation")
\r
828 || annotation.label.equals("Consensus");
\r
831 * This will return the first AlignFrame viewing AlignViewport av.
\r
832 * It will break if there are more than one AlignFrames viewing a particular av.
\r
833 * This also shouldn't be in the io package.
\r
835 * @return alignFrame for av
\r
837 public AlignFrame getAlignFrameFor(AlignViewport av) {
\r
838 if (Desktop.desktop != null)
\r
840 javax.swing.JInternalFrame[] frames = Desktop.desktop.getAllFrames();
\r
842 for (int t = 0; t < frames.length; t++)
\r
844 if (frames[t] instanceof AlignFrame) {
\r
845 if (((AlignFrame) frames[t]).getViewport()==av)
\r
846 return (AlignFrame) frames[t];
\r
852 public void updateToJalview() {
\r
853 VAMSAS _roots[] = cdoc.getVamsasRoots();
\r
855 for (int _root = 0; _root<_roots.length; _root++) {
\r
856 VAMSAS root = _roots[_root];
\r
857 boolean newds=false;
\r
858 for (int _ds=0,_nds=root.getDataSetCount(); _ds<_nds; _ds++) {
\r
859 // ///////////////////////////////////
\r
861 DataSet dataset = root.getDataSet(_ds);
\r
862 int i, iSize = dataset.getSequenceCount();
\r
864 jalview.datamodel.Alignment jdataset = (jalview.datamodel.Alignment) getvObj2jv(dataset);
\r
866 if (jdataset==null) {
\r
867 Cache.log.debug("Initialising new jalview dataset fields");
\r
869 dsseqs=new Vector();
\r
871 Cache.log.debug("Update jalview dataset from vamsas.");
\r
872 jremain=jdataset.getHeight();
\r
873 dsseqs=jdataset.getSequences();
\r
876 // TODO: test sequence merging - we preserve existing non vamsas
\r
877 // sequences but add in any new vamsas ones, and don't yet update any
\r
878 // sequence attributes
\r
879 for (i = 0; i < iSize ; i++)
\r
881 Sequence vdseq = dataset.getSequence(i);
\r
882 jalview.datamodel.SequenceI dsseq = (SequenceI) getvObj2jv(vdseq);
\r
884 if (!dsseq.getSequence().equals(vdseq.getSequence()))
\r
885 throw new Error("Broken! - mismatch of dataset sequence and jalview internal dataset sequence.");
\r
888 dsseq = new jalview.datamodel.Sequence(
\r
889 dataset.getSequence(i).getName(),
\r
890 dataset.getSequence(i).getSequence(),
\r
891 dataset.getSequence(i).getStart(),
\r
892 dataset.getSequence(i).getEnd() );
\r
893 bindjvvobj(dsseq, dataset.getSequence(i));
\r
894 dsseq.setVamsasId(dataset.getSequence(i).getVorbaId().getId());
\r
897 if (vdseq.getDbRefCount()>0) {
\r
898 DbRef [] dbref = vdseq.getDbRef();
\r
899 for(int db=0; db<dbref.length; db++)
\r
901 jalview.datamodel.DBRefEntry dbr=(jalview.datamodel.DBRefEntry) getvObj2jv(dbref[db]);
\r
904 dsseq.addDBRef(dbr= new jalview.datamodel.DBRefEntry
\r
906 dbref[db].getSource().toString(),
\r
907 dbref[db].getVersion().toString(),
\r
908 dbref[db].getAccessionId().toString()));
\r
909 bindjvvobj(dbr, dbref[db]);
\r
916 SequenceI[] seqs = new SequenceI[dsseqs.size()];
\r
917 for (i=0,iSize=dsseqs.size(); i<iSize; i++) {
\r
918 seqs[i]=(SequenceI) dsseqs.elementAt(i);
\r
919 dsseqs.setElementAt(null, i);
\r
921 jdataset = new jalview.datamodel.Alignment(seqs);
\r
922 Cache.log.debug("New vamsas dataset imported into jalview.");
\r
923 bindjvvobj(jdataset, dataset);
\r
926 // add any new dataset sequence feature annotations
\r
927 if (dataset.getDataSetAnnotations() != null) {
\r
928 for (int dsa = 0; dsa < dataset.getDataSetAnnotationsCount(); dsa++) {
\r
929 DataSetAnnotations dseta=dataset.getDataSetAnnotations(dsa);
\r
930 SequenceI dsSeq=(SequenceI) getvObj2jv((Vobject) dseta.getSeqRef());
\r
932 jalview.bin.Cache.log.warn("Couldn't resolve jalview sequenceI for dataset object reference "+((Vobject)dataset.getDataSetAnnotations(dsa).getSeqRef()).getVorbaId().getId());
\r
934 if (dseta.getAnnotationElementCount()==0) {
\r
935 jalview.datamodel.SequenceFeature sf=(jalview.datamodel.SequenceFeature) getvObj2jv(dseta);
\r
937 dsSeq.addSequenceFeature(sf=getJalviewSeqFeature(dseta));
\r
938 bindjvvobj(sf, dseta);
\r
941 // TODO: deal with alignmentAnnotation style annotation
\r
942 // appearing on dataset sequences.
\r
943 // JBPNote: we could just add them to all alignments but
\r
944 // that may complicate cross references in the jalview
\r
946 Cache.log.warn("Ignoring dataset annotation with annotationElements. Not yet supported in jalview.");
\r
952 if (dataset.getAlignmentCount()>0) {
\r
953 // LOAD ALIGNMENTS from DATASET
\r
955 for (int al=0,nal=dataset.getAlignmentCount(); al<nal; al++) {
\r
956 org.vamsas.objects.core.Alignment alignment = dataset.getAlignment(al);
\r
957 AlignViewport av = (AlignViewport) getvObj2jv(alignment);
\r
958 jalview.datamodel.AlignmentI jal=null;
\r
960 jal = av.getAlignment();
\r
961 iSize = alignment.getAlignmentSequenceCount();
\r
962 boolean newal=(jal==null) ? true : false;
\r
963 Vector newasAnnots=new Vector();
\r
964 char gapChar=' '; // default for new alignments read in from the document
\r
966 dsseqs=jal.getSequences(); // for merge/update
\r
967 gapChar=jal.getGapCharacter();
\r
969 dsseqs=new Vector();
\r
971 char valGapchar=alignment.getGapChar().charAt(0);
\r
972 for (i = 0; i < iSize; i++)
\r
974 AlignmentSequence valseq = alignment.getAlignmentSequence(i);
\r
975 jalview.datamodel.SequenceI alseq = (SequenceI) getvObj2jv(valseq);
\r
977 //TODO: upperCase/LowerCase situation here ? do we allow it ?
\r
978 //if (!alseq.getSequence().equals(valseq.getSequence())) {
\r
979 // throw new Error("Broken! - mismatch of dataset sequence and jalview internal dataset sequence.");
\r
980 if (Cache.log.isDebugEnabled())
\r
981 Cache.log.debug("Updating apparently edited sequence "+alseq.getName());
\r
982 // this might go *horribly* wrong
\r
983 alseq.setSequence(new String(valseq.getSequence()).replace(valGapchar, gapChar));
\r
986 alseq = new jalview.datamodel.Sequence(
\r
988 valseq.getSequence().replace(valGapchar, gapChar),
\r
992 Vobject datsetseq = (Vobject)valseq.getRefid();
\r
993 if (datsetseq!=null) {
\r
994 alseq.setDatasetSequence((SequenceI)getvObj2jv(datsetseq)); // exceptions if AlignemntSequence reference isn't a simple SequenceI
\r
996 Cache.log.error("Invalid dataset sequence id (null) for alignment sequence "+valseq.getVorbaId());
\r
998 bindjvvobj(alseq, valseq);
\r
999 alseq.setVamsasId(valseq.getVorbaId().getId());
\r
1000 dsseqs.add(alseq);
\r
1002 if (valseq.getAlignmentSequenceAnnotationCount()>0) {
\r
1003 AlignmentSequenceAnnotation[] vasannot=valseq.getAlignmentSequenceAnnotation();
\r
1004 for (int a=0; a<vasannot.length; a++) {
\r
1005 jalview.datamodel.AlignmentAnnotation asa = (jalview.datamodel.AlignmentAnnotation) getvObj2jv(vasannot[a]); // TODO: 1:many jalview alignment sequence annotations
\r
1007 int se[] = getBounds(vasannot[a]);
\r
1008 asa = getjAlignmentAnnotation(jal, vasannot[a]);
\r
1009 asa.sequenceRef=alseq;
\r
1010 asa.createSequenceMapping(alseq, alseq.getStart()+se[0], false); // TODO: verify that positions in alseqAnnotation correspond to ungapped residue positions.
\r
1011 bindjvvobj(asa, vasannot[a]);
\r
1012 newasAnnots.add(asa);
\r
1014 // update existing annotation - can do this in place
\r
1015 if (vasannot[a].getModifiable()) {
\r
1016 Cache.log.info("UNIMPLEMENTED: not recovering user modifiable sequence alignment annotation");
\r
1017 // TODO: should at least replace with new one - otherwise things will break
\r
1018 // basically do this:
\r
1019 // int se[] = getBounds(vasannot[a]);
\r
1020 // asa.update(getjAlignmentAnnotation(jal, vasannot[a])); // update from another annotation object in place.
\r
1021 // asa.createSequenceMapping(alseq, se[0], false);
\r
1029 SequenceI[] seqs = new SequenceI[dsseqs.size()];
\r
1030 for (i=0,iSize=dsseqs.size(); i<iSize; i++) {
\r
1031 seqs[i]=(SequenceI) dsseqs.elementAt(i);
\r
1032 dsseqs.setElementAt(null, i);
\r
1034 jal = new jalview.datamodel.Alignment(seqs);
\r
1035 Cache.log.debug("New vamsas alignment imported into jalview "+alignment.getVorbaId().getId());
\r
1036 jal.setDataset(jdataset);
\r
1038 if (newasAnnots!=null && newasAnnots.size()>0) {
\r
1039 // Add the new sequence annotations in to the alignment.
\r
1040 for (int an=0,anSize=newasAnnots.size(); an<anSize; an++) {
\r
1041 jal.addAnnotation((AlignmentAnnotation) newasAnnots.elementAt(an));
\r
1042 // TODO: check if anything has to be done - like calling adjustForAlignment or something.
\r
1043 newasAnnots.setElementAt(null, an);
\r
1047 // //////////////////////////////////////////
\r
1048 // //LOAD ANNOTATIONS FOR THE ALIGNMENT
\r
1049 // ////////////////////////////////////
\r
1050 if (alignment.getAlignmentAnnotationCount()>0)
\r
1052 org.vamsas.objects.core.AlignmentAnnotation[] an = alignment.getAlignmentAnnotation();
\r
1054 for (int j = 0; j < an.length; j++)
\r
1056 jalview.datamodel.AlignmentAnnotation jan=(jalview.datamodel.AlignmentAnnotation) getvObj2jv(an[j]);
\r
1058 // update or stay the same.
\r
1059 // TODO: should at least replace with a new one - otherwise things will break
\r
1060 // basically do this:
\r
1061 // jan.update(getjAlignmentAnnotation(jal, an[a])); // update from another annotation object in place.
\r
1063 Cache.log.debug("update from vamsas alignment annotation to existing jalview alignment annotation.");
\r
1064 if (an[j].getModifiable()) {
\r
1065 // TODO: user defined annotation is totally mutable... - so load it up or throw away if locally edited.
\r
1066 Cache.log.info("NOT IMPLEMENTED - Recovering user-modifiable annotation - yet...");
\r
1068 // TODO: compare annotation element rows
\r
1069 // TODO: compare props.
\r
1071 jan = getjAlignmentAnnotation(jal, an[j]);
\r
1072 jal.addAnnotation(jan);
\r
1073 bindjvvobj(jan, an[j]);
\r
1077 AlignFrame alignFrame;
\r
1079 Cache.log.debug("New alignframe for alignment "+alignment.getVorbaId());
\r
1080 // ///////////////////////////////
\r
1081 // construct alignment view
\r
1082 alignFrame = new AlignFrame(jal, AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
\r
1083 av=alignFrame.getViewport();
\r
1084 String title = alignment.getProvenance().getEntry(alignment.getProvenance().getEntryCount()-1).getAction();
\r
1085 if (alignment.getPropertyCount()>0) {
\r
1086 for (int p=0,pe=alignment.getPropertyCount(); p<pe; p++) {
\r
1087 if (alignment.getProperty(p).getName().equals("jalview:AlTitle")) {
\r
1088 title = alignment.getProperty(p).getContent();
\r
1092 // TODO: automatically create meaningful title for a vamsas alignment using its provenance.
\r
1093 jalview.gui.Desktop.addInternalFrame(alignFrame, title + "("+alignment.getVorbaId()+")",
\r
1094 AlignFrame.DEFAULT_WIDTH,
\r
1095 AlignFrame.DEFAULT_HEIGHT);
\r
1096 bindjvvobj(av, alignment);
\r
1098 // find the alignFrame for jal.
\r
1099 // TODO: fix this so we retrieve the alignFrame handing av *directly*
\r
1100 alignFrame=getAlignFrameFor(av);
\r
1103 // /////////////////////////////////////
\r
1104 if (alignment.getTreeCount() > 0)
\r
1107 for (int t = 0; t < alignment.getTreeCount(); t++)
\r
1109 Tree tree = alignment.getTree(t);
\r
1110 TreePanel tp=(TreePanel) getvObj2jv(tree);
\r
1112 Cache.log.info("Update from vamsas document to alignment associated tree not implemented yet.");
\r
1114 // make a new tree
\r
1115 Object[] idata = this.recoverInputData(tree.getProvenance());
\r
1117 AlignmentView inputData=null;
\r
1118 if (idata!=null && idata[0]!=null)
\r
1119 inputData = (AlignmentView) idata[0];
\r
1120 tp = alignFrame.ShowNewickTree(
\r
1121 new jalview.io.NewickFile(tree.getNewick(0).getContent()),
\r
1122 tree.getNewick(0).getTitle()+" ("+tree.getVorbaId()+")",inputData,
\r
1124 t * 20 + 50, t * 20 + 50);
\r
1125 bindjvvobj(tp, tree);
\r
1126 } catch (Exception e) {
\r
1127 Cache.log.warn("Problems parsing treefile '"+tree.getNewick(0).getContent()+"'",e);
\r
1138 // bitfields - should be a template in j1.5
\r
1139 private static int HASSECSTR=0;
\r
1140 private static int HASVALS=1;
\r
1141 private static int HASHPHOB=2;
\r
1142 private static int HASDC=3;
\r
1143 private static int HASDESCSTR=4;
\r
1144 private static int HASTWOSTATE=5; // not used yet.
\r
1146 * parses the AnnotationElements - if they exist - into jalview.datamodel.Annotation[] rows
\r
1147 * Two annotation rows are made if there are distinct annotation for both at 'pos' and 'after pos' at any particular site.
\r
1148 * @param annotation
\r
1149 * @return { boolean[static int constants ], int[ae.length] - map to annotated object frame, jalview.datamodel.Annotation[], jalview.datamodel.Annotation[] (after)}
\r
1151 private Object[] parseRangeAnnotation(org.vamsas.objects.core.RangeAnnotation annotation) {
\r
1152 // set these attributes by looking in the annotation to decide what kind of alignment annotation rows will be made
\r
1153 // TODO: potentially we might make several annotation rows from one vamsas alignment annotation. the jv2Vobj binding mechanism
\r
1154 // may not quite cope with this (without binding an array of annotations to a vamsas alignment annotation)
\r
1155 // summary flags saying what we found over the set of annotation rows.
\r
1156 boolean[] AeContent = new boolean[] { false, false, false, false, false};
\r
1157 int[] rangeMap = getMapping(annotation);
\r
1158 jalview.datamodel.Annotation[][] anot=new jalview.datamodel.Annotation[][] {
\r
1159 new jalview.datamodel.Annotation[rangeMap.length],
\r
1160 new jalview.datamodel.Annotation[rangeMap.length]
\r
1162 boolean mergeable=true; //false if 'after positions cant be placed on same annotation row as positions.
\r
1164 if (annotation.getAnnotationElementCount()>0) {
\r
1165 AnnotationElement ae[] = annotation.getAnnotationElement();
\r
1166 for (int aa = 0; aa < ae.length; aa++)
\r
1168 int pos = ae[aa].getPosition()-1;// pos counts from 1 to (|seg.start-seg.end|+1)
\r
1169 if (pos>=0 && pos<rangeMap.length) {
\r
1170 int row=ae[aa].getAfter()?1:0;
\r
1171 if (anot[row][pos]!=null) {
\r
1172 // only time this should happen is if the After flag is set.
\r
1173 Cache.log.debug("Ignoring duplicate annotation site at "+pos);
\r
1176 if (anot[1-row][pos]!=null)
\r
1179 if (ae[aa].getDescription()!=null) {
\r
1180 desc = ae[aa].getDescription();
\r
1181 if (desc.length()>0) {
\r
1182 // have imported valid description string
\r
1183 AeContent[HASDESCSTR]=true;
\r
1186 String dc = null;//ae[aa].getDisplayCharacter()==null ? "dc" : ae[aa].getDisplayCharacter();
\r
1187 String ss = null;//ae[aa].getSecondaryStructure()==null ? "ss" : ae[aa].getSecondaryStructure();
\r
1188 java.awt.Color colour = null;
\r
1189 if (ae[aa].getGlyphCount()>0) {
\r
1190 Glyph[] glyphs = ae[aa].getGlyph();
\r
1191 for (int g=0; g<glyphs.length; g++) {
\r
1192 if (glyphs[g].getDict().equals(org.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE)) {
\r
1193 ss=glyphs[g].getContent();
\r
1194 AeContent[HASSECSTR]=true;
\r
1195 } else if (glyphs[g].getDict().equals(org.vamsas.objects.utils.GlyphDictionary.PROTEIN_HD_HYDRO)) {
\r
1196 Cache.log.debug("ignoring hydrophobicity glyph marker.");
\r
1197 AeContent[HASHPHOB]=true;
\r
1198 char c=(dc=glyphs[g].getContent()).charAt(0);
\r
1199 // dc may get overwritten - but we still set the colour.
\r
1200 colour = new java.awt.Color(c=='+'?255:0,c=='.'?255:0,c=='-'?255:0);
\r
1202 } else if (glyphs[g].getDict().equals(org.vamsas.objects.utils.GlyphDictionary.DEFAULT)) {
\r
1203 dc = glyphs[g].getContent();
\r
1204 AeContent[HASDC]=true;
\r
1206 Cache.log.debug("Ignoring unknown glyph type "+glyphs[g].getDict());
\r
1211 if (ae[aa].getValueCount()>0) {
\r
1212 AeContent[HASVALS]=true;
\r
1213 if (ae[aa].getValueCount()>1) {
\r
1214 Cache.log.warn("ignoring additional "+(ae[aa].getValueCount()-1)+"values in annotation element.");
\r
1216 val = ae[aa].getValue(0);
\r
1218 if (colour==null) {
\r
1219 anot[row][pos]=new jalview.datamodel.Annotation((dc!=null) ? dc : "", desc, (ss!=null)?ss.charAt(0):' ', val);
\r
1221 anot[row][pos]=new jalview.datamodel.Annotation((dc!=null) ? dc : "", desc, (ss!=null)?ss.charAt(0):' ', val, colour);
\r
1224 Cache.log.warn("Ignoring out of bound annotation element "+aa+" in "+annotation.getVorbaId().getId());
\r
1227 // decide on how many annotation rows are needed.
\r
1229 for (int i=0; i<anot[0].length;i++) {
\r
1230 if (anot[1][i]!=null) {
\r
1231 anot[0][i] = anot[1][i];
\r
1232 anot[0][i].description = anot[0][i].description+" (after)";
\r
1233 AeContent[HASDESCSTR]=true; // we have valid description string data
\r
1234 anot[1][i] = null;
\r
1239 for (int i=0; i<anot[0].length;i++) {
\r
1240 anot[1][i].description = anot[1][i].description+" (after)";
\r
1243 return new Object[] { AeContent, rangeMap, anot[0], anot[1] };
\r
1245 // no annotations to parse. Just return an empty annotationElement[] array.
\r
1246 return new Object[] { AeContent, rangeMap, anot[0], anot[1] };
\r
1251 * @param jal the jalview alignment to which the annotation will be attached (ideally - freshly updated from corresponding vamsas alignment)
\r
1252 * @param annotation
\r
1253 * @return unbound jalview alignment annotation object.
\r
1255 private jalview.datamodel.AlignmentAnnotation getjAlignmentAnnotation(jalview.datamodel.AlignmentI jal, org.vamsas.objects.core.RangeAnnotation annotation) {
\r
1256 jalview.datamodel.AlignmentAnnotation jan =null;
\r
1257 if (annotation==null)
\r
1259 // boolean hasSequenceRef=annotation.getClass().equals(org.vamsas.objects.core.AlignmentSequenceAnnotation.class);
\r
1260 //boolean hasProvenance=hasSequenceRef || (annotation.getClass().equals(org.vamsas.objects.core.AlignmentAnnotation.class));
\r
1261 /*int se[] = getBounds(annotation);
\r
1263 se=new int[] {0,jal.getWidth()-1};
\r
1265 Object[] parsedRangeAnnotation = parseRangeAnnotation(annotation);
\r
1266 String a_label=annotation.getLabel();
\r
1267 String a_descr=annotation.getDescription();
\r
1268 if (a_label==null || a_label.length()==0) {
\r
1269 a_label = annotation.getType();
\r
1270 if (a_label.length()==0)
\r
1271 a_label = "Unamed annotation";
\r
1273 if (a_descr==null || a_descr.length()==0) {
\r
1274 a_descr = "Annotation of type '"+annotation.getType()+"'";
\r
1276 if (parsedRangeAnnotation==null) {
\r
1277 Cache.log.debug("Inserting empty annotation row elements for a whole-alignment annotation.");
\r
1281 if (parsedRangeAnnotation[3]!=null) {
\r
1282 Cache.log.warn("Ignoring 'After' annotation row in "+annotation.getVorbaId());
\r
1284 jalview.datamodel.Annotation[] arow = (jalview.datamodel.Annotation[]) parsedRangeAnnotation[2];
\r
1285 boolean[] has=(boolean[])parsedRangeAnnotation[0];
\r
1286 // VAMSAS: getGraph is only on derived annotation for alignments - in this way its 'odd' - there is already an existing TODO about removing this flag as being redundant
\r
1287 /*if ((annotation.getClass().equals(org.vamsas.objects.core.AlignmentAnnotation.class) && ((org.vamsas.objects.core.AlignmentAnnotation)annotation).getGraph())
\r
1288 || (hasSequenceRef=true && ((org.vamsas.objects.core.AlignmentSequenceAnnotation)annotation).getGraph())) {
\r
1290 if (has[HASVALS]) {
\r
1291 // make bounds and automatic description strings for jalview user's benefit (these shouldn't be written back to vamsas document)
\r
1292 boolean first=true;
\r
1293 float min=0,max=1;
\r
1295 for (int i=0;i<arow.length; i++) {
\r
1296 if (arow[i]!=null) {
\r
1297 if (i-lastval>1) {
\r
1298 // do some interpolation *between* points
\r
1299 if (arow[lastval]!=null) {
\r
1300 float interval = arow[i].value-arow[lastval].value;
\r
1301 interval/=i-lastval;
\r
1302 float base = arow[lastval].value;
\r
1303 for (int ip=lastval+1,np=0; ip<i; np++,ip++) {
\r
1304 arow[ip] = new jalview.datamodel.Annotation("","",' ', interval*np+base);
\r
1305 // NB - Interpolated points don't get a tooltip and description.
\r
1310 // check range - shouldn't we have a min and max property in the annotation object ?
\r
1311 if (first) { min=max=arow[i].value; first=false;}
\r
1312 else { if (arow[i].value<min) { min=arow[i].value; }
\r
1313 else if (arow[i].value>max) { max=arow[i].value; }
\r
1315 // make tooltip and display char value
\r
1316 if (!has[HASDESCSTR]) arow[i].description = arow[i].value + "";
\r
1317 if (!has[HASDC]) arow[i].displayCharacter=arow[i].value+"";
\r
1320 int type=jalview.datamodel.AlignmentAnnotation.LINE_GRAPH;
\r
1321 if (has[HASHPHOB]) {
\r
1322 type = jalview.datamodel.AlignmentAnnotation.BAR_GRAPH;
\r
1324 jan = new jalview.datamodel.AlignmentAnnotation(a_label, a_descr, arow, min, max, type);
\r
1326 jan = new jalview.datamodel.AlignmentAnnotation(a_label, a_descr, arow);
\r
1327 jan.setThreshold(null);
\r
1329 if (annotation.getLinkCount()>0) {
\r
1330 Cache.log.warn("Ignoring "+annotation.getLinkCount()+"links added to AlignmentAnnotation.");
\r
1332 if (annotation.getModifiable()) {
\r
1333 jan.editable=true;
\r
1336 if (annotation.getPropertyCount()>0) {
\r
1337 // look for special jalview properties
\r
1338 org.vamsas.objects.core.Property[] props=annotation.getProperty();
\r
1339 for (int p=0;p<props.length; p++) {
\r
1340 if (props[p].getName().equalsIgnoreCase("jalview:graphType")) {
\r
1342 // probably a jalview annotation graph so recover the visualization hints.
\r
1343 jan.graph = jalview.datamodel.AlignmentAnnotation.getGraphValueFromString(props[p].getContent());
\r
1344 } catch (Exception e) {
\r
1345 Cache.log.debug("Invalid graph type value in jalview:graphType property.");
\r
1348 if (annotation.getGroup()!=null && annotation.getGroup().length()>0)
\r
1349 jan.graphGroup = Integer.parseInt(annotation.getGroup());
\r
1350 } catch (Exception e) {
\r
1351 Cache.log.info("UNIMPLEMENTED : Couldn't parse non-integer group value for setting graphGroup correctly.");
\r
1364 private SequenceFeature getJalviewSeqFeature(RangeAnnotation dseta) {
\r
1365 int[] se = getBounds(dseta);
\r
1366 SequenceFeature sf = new jalview.datamodel.SequenceFeature(dseta.getType(),
\r
1367 dseta.getDescription(), dseta.getStatus(), se[0], se[1], dseta
\r
1369 if (dseta.getLinkCount() > 0)
\r
1371 Link[] links = dseta.getLink();
\r
1372 for (int i = 0; i < links.length; i++)
\r
1374 sf.addLink(links[i].getContent() + "|" + links[i].getHref());
\r
1381 * get real bounds of a RangeType's specification. start and end are an
\r
1382 * inclusive range within which all segments and positions lie.
\r
1383 * TODO: refactor to vamsas utils
\r
1385 * @return int[] { start, end}
\r
1387 private int[] getBounds(RangeType dseta) {
\r
1388 if (dseta != null)
\r
1391 if (dseta.getSegCount()>0 && dseta.getPosCount()>0)
\r
1392 throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
\r
1393 if (dseta.getSegCount() > 0)
\r
1395 se = getSegRange(dseta.getSeg(0),true);
\r
1396 for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++)
\r
1398 int nse[] = getSegRange(dseta.getSeg(s), true);
\r
1399 if (se[0] > nse[0])
\r
1401 if (se[1] < nse[1])
\r
1405 if (dseta.getPosCount() > 0)
\r
1407 // could do a polarity for pos range too. and pass back indication of discontinuities.
\r
1408 int pos = dseta.getPos(0).getI();
\r
1409 se = new int[] { pos, pos };
\r
1410 for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)
\r
1412 pos = dseta.getPos(p).getI();
\r
1424 * map from a rangeType's internal frame to the referenced object's coordinate frame.
\r
1426 * @return int [] { ref(pos)...} for all pos in rangeType's frame.
\r
1428 private int[] getMapping(RangeType dseta) {
\r
1429 Vector posList=new Vector();
\r
1430 if (dseta != null)
\r
1433 if (dseta.getSegCount()>0 && dseta.getPosCount()>0)
\r
1434 throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
\r
1435 if (dseta.getSegCount() > 0)
\r
1437 for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++)
\r
1439 se = getSegRange(dseta.getSeg(s), false);
\r
1440 int se_end=se[1-se[2]]+(se[2]==0 ? 1 : -1);
\r
1441 for (int p=se[se[2]]; p!=se_end; p+=se[2]==0 ? 1 : -1 ) {
\r
1442 posList.add(new Integer(p));
\r
1446 else if (dseta.getPosCount() > 0)
\r
1448 int pos = dseta.getPos(0).getI();
\r
1450 for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)
\r
1452 pos = dseta.getPos(p).getI();
\r
1453 posList.add(new Integer(pos));
\r
1457 if (posList!=null && posList.size()>0) {
\r
1458 int[] range=new int[posList.size()];
\r
1459 for (int i=0; i<range.length; i++)
\r
1460 range[i] = ((Integer)posList.elementAt(i)).intValue();
\r
1466 /* not needed now.
\r
1467 * Provenance getVamsasProvenance(jalview.datamodel.Provenance jprov) {
\r
1468 jalview.datamodel.ProvenanceEntry[] entries = null;
\r
1469 // TODO: fix App and Action here.
\r
1470 Provenance prov = new Provenance();
\r
1471 org.exolab.castor.types.Date date = new org.exolab.castor.types.Date(
\r
1472 new java.util.Date());
\r
1475 if (jprov != null)
\r
1477 entries = jprov.getEntries();
\r
1478 for (int i = 0; i < entries.length; i++)
\r
1480 provEntry = new Entry();
\r
1483 date = new org.exolab.castor.types.Date(entries[i].getDate());
\r
1484 } catch (Exception ex)
\r
1486 ex.printStackTrace();
\r
1488 date = new org.exolab.castor.types.Date(entries[i].getDate());
\r
1490 provEntry.setDate(date);
\r
1491 provEntry.setUser(entries[i].getUser());
\r
1492 provEntry.setAction(entries[i].getAction());
\r
1493 prov.addEntry(provEntry);
\r
1498 provEntry = new Entry();
\r
1499 provEntry.setDate(date);
\r
1500 provEntry.setUser(System.getProperty("user.name")); // TODO: ext string
\r
1501 provEntry.setApp("JVAPP"); // TODO: ext string
\r
1502 provEntry.setAction(action);
\r
1503 prov.addEntry(provEntry);
\r
1509 jalview.datamodel.Provenance getJalviewProvenance(Provenance prov) {
\r
1510 // TODO: fix App and Action entries and check use of provenance in jalview.
\r
1511 jalview.datamodel.Provenance jprov = new jalview.datamodel.Provenance();
\r
1512 for (int i = 0; i < prov.getEntryCount(); i++)
\r
1514 jprov.addEntry(prov.getEntry(i).getUser(), prov.getEntry(i).getAction(),
\r
1515 prov.getEntry(i).getDate().toDate(), prov.getEntry(i).getId());
\r
1523 * @return default initial provenance list for a Jalview created vamsas
\r
1526 Provenance dummyProvenance() {
\r
1527 return dummyProvenance(null);
\r
1530 Entry dummyPEntry(String action) {
\r
1531 Entry entry = new Entry();
\r
1532 entry.setApp(this.provEntry.getApp());
\r
1533 if (action != null)
\r
1534 entry.setAction(action);
\r
1536 entry.setAction("created.");
\r
1537 entry.setDate(new org.exolab.castor.types.Date(new java.util.Date()));
\r
1538 entry.setUser(this.provEntry.getUser());
\r
1542 Provenance dummyProvenance(String action) {
\r
1543 Provenance prov = new Provenance();
\r
1544 prov.addEntry(dummyPEntry(action));
\r
1548 void addProvenance(Provenance p, String action) {
\r
1549 p.addEntry(dummyPEntry(action));
\r