ongoign vamsas session debugging
[jalview.git] / src / jalview / io / VamsasDatastore.java
index a9735be..279a4c4 100755 (executable)
@@ -64,26 +64,13 @@ public class VamsasDatastore {
 
   Hashtable vobj2jv;
 
-  Hashtable root2jv;
-
   IdentityHashMap jv2vobj;
 
-  IdentityHashMap jv2root;
-
   public VamsasDatastore(ClientDoc cdoc, Hashtable vobj2jv,
       IdentityHashMap jv2vobj, Entry provEntry) {
-    this(cdoc, vobj2jv, jv2vobj, provEntry, new Hashtable(),
-        new IdentityHashMap());
-  }
-
-  public VamsasDatastore(ClientDoc cdoc, Hashtable vobj2jv,
-      IdentityHashMap jv2vobj, Entry provEntry, Hashtable root2jv,
-      IdentityHashMap jv2root) {
-    this.cdoc = cdoc;
+      this.cdoc = cdoc;
     this.vobj2jv = vobj2jv;
     this.jv2vobj = jv2vobj;
-    this.root2jv = root2jv;
-    this.jv2root = jv2root;
     this.provEntry = provEntry;
   }
 
@@ -108,7 +95,7 @@ public class VamsasDatastore {
    */
   protected Vobject getjv2vObj(Object jvobj) {
     if (jv2vobj.containsKey(jvobj))
-      return cdoc.getObject(((VorbaId) jv2vobj.get(jvobj)));
+      return cdoc.getObject((VorbaId) jv2vobj.get(jvobj));
     return null;
   }
 
@@ -127,7 +114,7 @@ public class VamsasDatastore {
       return null;
     }
     if (vobj2jv.containsKey(vobj.getVorbaId()))
-      return vobj2jv.get(id);
+      return vobj2jv.get(vobj.getVorbaId());
     return null;
   }
 
@@ -136,10 +123,12 @@ public class VamsasDatastore {
     if (id == null)
     {
       id = cdoc.registerObject(vobj);
+      if (id==null || vobj.getVorbaId()==null)
+        Cache.log.error("Failed to get id for "+(vobj.isRegisterable() ? "registerable" : "unregisterable") +" object "+vobj);
     }
     if (vobj2jv.containsKey(vobj.getVorbaId()) || jv2vobj.containsKey(jvobj))
     {
-      Cache.log.error("Duplicate object binding!");
+      Cache.log.error("Duplicate object binding! "+vobj+" id " +vobj.getVorbaId().getId()+" to "+jvobj);
     }
     else
     {
@@ -292,7 +281,7 @@ public class VamsasDatastore {
       if (alignment == null)
       {
         alignment = new Alignment();
-        bindjvvobj(jal, alignment);
+        bindjvvobj(av, alignment);
         if (alignment.getProvenance() == null)
           alignment.setProvenance(new Provenance());
         addProvenance(alignment.getProvenance(), "added"); // TODO: insert some
@@ -399,13 +388,22 @@ public class VamsasDatastore {
             if (an == null)
             {
               an = new org.vamsas.objects.core.AlignmentSequenceAnnotation();
+              Seg vSeg = new Seg();
+              vSeg.setStart(1);
+              vSeg.setInclusive(true);
+              vSeg.setEnd(gapMap.length);
+              an.addSeg(vSeg);
+              an.setType("jalview:SecondaryStructurePrediction");// TODO: better fix this rough guess ;)
               alsref.addAlignmentSequenceAnnotation(an);
+              bindjvvobj(aa[i],an);
               // LATER: much of this is verbatim from the alignmentAnnotation
               // method below. suggests refactoring to make rangeAnnotation the
               // base class
               an.setDescription(aa[i].description);
               if (aa[i].graph > 0)
                 an.setGraph(true); // aa[i].graph);
+              else
+                an.setGraph(false);
               an.setLabel(aa[i].label);
               an.setProvenance(dummyProvenance()); // get provenance as user
               // created, or jnet, or
@@ -438,7 +436,7 @@ public class VamsasDatastore {
                 // utf8
                 // translation
                 ae.addValue(aa[i].annotations[a].value);
-                ae.setPosition(gapMap[a]); // position w.r.t. AlignmentSequence
+                ae.setPosition(gapMap[a]+1); // position w.r.t. AlignmentSequence
                 // symbols
                 if (aa[i].annotations[a].secondaryStructure != ' ')
                 {
@@ -476,21 +474,31 @@ public class VamsasDatastore {
             if (an == null)
             {
               an = new org.vamsas.objects.core.AlignmentAnnotation();
+              an.setType("jalview:AnnotationRow");
               an.setDescription(aa[i].description);
               alignment.addAlignmentAnnotation(an);
+              Seg vSeg = new Seg();
+              vSeg.setStart(1);
+              vSeg.setInclusive(true);
+              vSeg.setEnd(jal.getWidth());
+              an.addSeg(vSeg);
               if (aa[i].graph > 0)
                 an.setGraph(true); // aa[i].graph);
               an.setLabel(aa[i].label);
               an.setProvenance(dummyProvenance());
-              an.setGroup(Integer.toString(aa[i].graphGroup)); // // JBPNote -
-              // originally we
+              if (aa[i].graph!=aa[i].NO_GRAPH) {
+                an.setGroup(Integer.toString(aa[i].graphGroup)); // // JBPNote -
+                // originally we
               // were going to
               // store
               // graphGroup in
               // the Jalview
               // specific
               // bits.
-
+                an.setGraph(true);
+              } else {
+                an.setGraph(false);
+              }
               AnnotationElement ae;
 
               for (int a = 0; a < aa[i].annotations.length; a++)
@@ -512,7 +520,7 @@ public class VamsasDatastore {
                 // utf8
                 // translation
                 ae.addValue(aa[i].annotations[a].value);
-                ae.setPosition(a);
+                ae.setPosition(a+1);
                 if (aa[i].annotations[a].secondaryStructure != ' ')
                 {
                   Glyph ss = new Glyph();
@@ -576,10 +584,6 @@ public class VamsasDatastore {
 
             if (tp.getAlignment() == jal)
             {
-              // LATER: can recover alignment and Vamsas Alignment for an
-              // associated tree using the getjv2vObj() so we could pass through
-              // the tree list just once rather than many times
-
               Tree tree = (Tree) getjv2vObj(tp);
               if (tree == null)
               {
@@ -647,6 +651,7 @@ public class VamsasDatastore {
     Seg vSeg = new Seg();
     vSeg.setStart(feature.getBegin());
     vSeg.setEnd(feature.getEnd());
+    vSeg.setInclusive(true);
     dsa.addSeg(vSeg);
     dsa.setDescription(feature.getDescription());
     dsa.setStatus(feature.getStatus());
@@ -681,15 +686,27 @@ public class VamsasDatastore {
    * @return
    */
   private Provenance makeTreeProvenance(AlignmentI jal, TreePanel tp) {
-    Input vInput = new Input();
-    // LATER: check to see if tree input data is contained in this alignment -
-    // or just correctly resolve the tree's seqData to the correct alignment in
-    // the document.
-    vInput.setObjRef(getjv2vObj(jal));
-    Provenance prov = dummyProvenance();
+    Provenance prov = new Provenance();
+    prov.addEntry(new Entry());
+    prov.getEntry(0).setAction("imported "+tp.getTitle());
+    prov.getEntry(0).setUser(provEntry.getUser());
+    prov.getEntry(0).setApp(provEntry.getApp());
+    prov.getEntry(0).setDate(provEntry.getDate());
     if (tp.getTree().hasOriginalSequenceData())
     {
+      Input vInput = new Input();
+      // LATER: check to see if tree input data is contained in this alignment -
+      // or just correctly resolve the tree's seqData to the correct alignment in
+      // the document.
+      vInput.setObjRef(getjv2vObj(jal));
+      prov.getEntry(0).setAction("created "+tp.getTitle());
       prov.getEntry(0).addInput(vInput);
+      vInput.setName("jalview:seqdist");
+      prov.getEntry(0).addParam(new Param());
+      prov.getEntry(0).getParam(0).setName("treeType");
+      prov.getEntry(0).getParam(0).setType("utf8");
+      prov.getEntry(0).getParam(0).setContent("NJ");
+      
       int ranges[] = tp.getTree().seqData.getVisibleContigs();
       for (int r = 0; r < ranges.length; r += 2)
       {
@@ -700,7 +717,7 @@ public class VamsasDatastore {
         vInput.addSeg(visSeg);
       }
     }
-    return null;
+    return prov;
   }
 
   /**
@@ -768,7 +785,7 @@ public class VamsasDatastore {
     int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of
     // region.
     int start = visSeg.getStart() + (incl ? 0 : pol);
-    int end = visSeg.getEnd() + (incl ? -pol : 0);
+    int end = visSeg.getEnd() + (incl ? 0 : -pol);
     if (ensureDirection && pol==-1)
     {
       // jalview doesn't deal with inverted ranges, yet.
@@ -805,7 +822,7 @@ public class VamsasDatastore {
       {
         if (frames[t] instanceof AlignFrame) {
           if (((AlignFrame) frames[t]).getViewport()==av)
-          return (AlignFrame) frames[t];
+            return (AlignFrame) frames[t];
         }
       }
     }
@@ -962,7 +979,8 @@ public class VamsasDatastore {
                   if (asa==null) {
                     int se[] = getBounds(vasannot[a]);
                     asa = getjAlignmentAnnotation(jal, vasannot[a]);
-                    asa.createSequenceMapping(alseq, se[0], false); // TODO: verify that positions in alseqAnnotation correspond to ungapped residue positions.
+                    asa.sequenceRef=alseq;
+                    asa.createSequenceMapping(alseq, alseq.getStart()+se[0], false); // TODO: verify that positions in alseqAnnotation correspond to ungapped residue positions.
                     bindjvvobj(asa, vasannot[a]);
                     newasAnnots.add(asa);
                   } else {
@@ -974,7 +992,7 @@ public class VamsasDatastore {
                       // int se[] = getBounds(vasannot[a]);
                       // asa.update(getjAlignmentAnnotation(jal, vasannot[a])); //  update from another annotation object in place.
                       // asa.createSequenceMapping(alseq, se[0], false); 
-                      
+
                     }
                   }
                 }
@@ -988,7 +1006,6 @@ public class VamsasDatastore {
               }
               jal = new jalview.datamodel.Alignment(seqs);
               Cache.log.debug("New vamsas alignment imported into jalview "+alignment.getVorbaId().getId());
-              bindjvvobj(jal, alignment);
               jal.setDataset(jdataset);
             }
             if (newasAnnots!=null && newasAnnots.size()>0) {
@@ -1015,7 +1032,7 @@ public class VamsasDatastore {
                   // TODO: should at least replace with a new one - otherwise things will break
                   // basically do this:
                   // jan.update(getjAlignmentAnnotation(jal, an[a])); //  update from another annotation object in place.
-                  
+
                   Cache.log.debug("update from vamsas alignment annotation to existing jalview alignment annotation.");
                   if (an[i].getModifiable()) {
                     // TODO: user defined annotation is totally mutable... - so load it up or throw away if locally edited.
@@ -1032,14 +1049,16 @@ public class VamsasDatastore {
             }
             AlignFrame alignFrame;
             if (av==null) {
-                // ///////////////////////////////
+              Cache.log.debug("New alignframe for alignment "+alignment.getVorbaId());
+              // ///////////////////////////////
               // construct alignment view
               alignFrame = new AlignFrame(jal);
               av=alignFrame.getViewport();
               // TODO: automatically create meaningful title for a vamsas alignment using its provenance.
-              jalview.gui.Desktop.addInternalFrame(alignFrame, alignment.getProvenance().getEntry(alignment.getProvenance().getEntryCount()-1).toString(),
+              jalview.gui.Desktop.addInternalFrame(alignFrame, alignment.getProvenance().getEntry(alignment.getProvenance().getEntryCount()-1).getAction(),
                   AlignFrame.NEW_WINDOW_WIDTH,
                   AlignFrame.NEW_WINDOW_HEIGHT);
+              bindjvvobj(av, alignment);
             } else {
               // find the alignFrame for jal.
               // TODO: fix this so we retrieve the alignFrame handing av *directly*
@@ -1049,7 +1068,7 @@ public class VamsasDatastore {
             // /////////////////////////////////////
             if (alignment.getTreeCount() > 0)
             {
-              
+
               for (int t = 0; t < alignment.getTreeCount(); t++)
               {
                 Tree tree = alignment.getTree(t);
@@ -1060,18 +1079,15 @@ public class VamsasDatastore {
                   // make a new tree
                   Object[] idata = this.recoverInputData(tree.getProvenance());
                   try {
-                    
+                    AlignmentView inputData=null;
+                    if (idata!=null && idata[0]!=null)
+                      inputData = (AlignmentView) idata[0];
                     tp = alignFrame.ShowNewickTree(
                         new jalview.io.NewickFile(tree.getNewick(0).getContent()),
-                        tree.getNewick(0).getTitle(),
+                        tree.getNewick(0).getTitle(),inputData,
                         600, 500,
                         t * 20 + 50, t * 20 + 50);
                     bindjvvobj(tp, tree);
-                    if (idata!=null) {
-                      // add it to tp.
-                      check jalview_2xml that it isn't an out of date version.
-                    }
-                        
                   } catch (Exception e) {
                     Cache.log.warn("Problems parsing treefile '"+tree.getNewick(0).getContent()+"'",e);
                   }
@@ -1109,13 +1125,13 @@ public class VamsasDatastore {
         new jalview.datamodel.Annotation[rangeMap.length]
     };
     boolean mergeable=true; //false  if 'after positions cant be placed on same annotation row as positions. 
-
+    
     if (annotation.getAnnotationElementCount()>0) {
       AnnotationElement ae[] = annotation.getAnnotationElement();
       for (int aa = 0; aa < ae.length; aa++)
       {
-        int pos = ae[aa].getPosition();
-        if (pos>=0 && pos<anot.length) {
+        int pos = ae[aa].getPosition()-1;// pos counts from 1 to (|seg.start-seg.end|+1)
+        if (pos>=0 && pos<rangeMap.length) { 
           int row=ae[aa].getAfter()?1:0;
           if (anot[row][pos]!=null) {
             // only time this should happen is if the After flag is set.
@@ -1138,17 +1154,17 @@ public class VamsasDatastore {
           if (ae[aa].getGlyphCount()>0) {
             Glyph[] glyphs = ae[aa].getGlyph();
             for (int g=0; g<glyphs.length; g++) {
-              if (glyphs[g].getDict()==org.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE) {
+              if (glyphs[g].getDict().equals(org.vamsas.objects.utils.GlyphDictionary.PROTEIN_SS_3STATE)) {
                 ss=glyphs[g].getContent();
                 AeContent[HASSECSTR]=true;
-              } else if (glyphs[g].getDict()==org.vamsas.objects.utils.GlyphDictionary.PROTEIN_HD_HYDRO) {
+              } else if (glyphs[g].getDict().equals(org.vamsas.objects.utils.GlyphDictionary.PROTEIN_HD_HYDRO)) {
                 Cache.log.debug("ignoring hydrophobicity glyph marker.");
                 AeContent[HASHPHOB]=true;
                 char c=(dc=glyphs[g].getContent()).charAt(0);
                 // dc may get overwritten - but we still set the colour.
                 colour = new java.awt.Color(c=='+'?255:0,c=='.'?255:0,c=='-'?255:0);
 
-              } else if (glyphs[g].getDict()==org.vamsas.objects.utils.GlyphDictionary.DEFAULT) {
+              } else if (glyphs[g].getDict().equals(org.vamsas.objects.utils.GlyphDictionary.DEFAULT)) {
                 dc = glyphs[g].getContent();
                 AeContent[HASDC]=true;
               } else {
@@ -1164,10 +1180,10 @@ public class VamsasDatastore {
             }
             val = ae[aa].getValue(0);
           }
-          if (colour!=null) {
-            anot[row][pos]=new jalview.datamodel.Annotation(desc, (dc!=null) ? dc : "", (ss!=null)?ss.charAt(0):' ', val);
+          if (colour==null) {
+            anot[row][pos]=new jalview.datamodel.Annotation((dc!=null) ? dc : "", desc, (ss!=null)?ss.charAt(0):' ', val);
           } else {
-            anot[row][pos]=new jalview.datamodel.Annotation(desc, (dc!=null) ? dc : "", (ss!=null)?ss.charAt(0):' ', val, colour);
+            anot[row][pos]=new jalview.datamodel.Annotation((dc!=null) ? dc : "", desc, (ss!=null)?ss.charAt(0):' ', val, colour);
           }
         } else {
           Cache.log.warn("Ignoring out of bound annotation element "+aa+" in "+annotation.getVorbaId().getId());
@@ -1204,12 +1220,23 @@ public class VamsasDatastore {
     jalview.datamodel.AlignmentAnnotation jan =null;
     if (annotation==null)
       return null;
+    // boolean hasSequenceRef=annotation.getClass().equals(org.vamsas.objects.core.AlignmentSequenceAnnotation.class);
+    //boolean hasProvenance=hasSequenceRef || (annotation.getClass().equals(org.vamsas.objects.core.AlignmentAnnotation.class));
     /*int se[] = getBounds(annotation);
     if (se==null)
       se=new int[] {0,jal.getWidth()-1};
      */
     Object[] parsedRangeAnnotation = parseRangeAnnotation(annotation);
-
+    String a_label=annotation.getLabel();
+    String a_descr=annotation.getDescription();
+    if (a_label==null || a_label.length()==0) {
+      a_label = annotation.getType();
+      if (a_label.length()==0)
+        a_label = "Unamed annotation";
+    }
+    if (a_descr==null || a_descr.length()==0) {
+      a_descr = "Annotation of type '"+annotation.getType()+"'";
+    }
     if (parsedRangeAnnotation!=null) {
       if (parsedRangeAnnotation[3]!=null) {
         Cache.log.warn("Ignoring 'After' annotation row in "+annotation.getVorbaId());
@@ -1217,12 +1244,13 @@ public class VamsasDatastore {
       jalview.datamodel.Annotation[] arow = (jalview.datamodel.Annotation[]) parsedRangeAnnotation[2];
       boolean[] has=(boolean[])parsedRangeAnnotation[0];
       // 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
-      if ((annotation.getClass().equals(org.vamsas.objects.core.AlignmentAnnotation.class) && ((org.vamsas.objects.core.AlignmentAnnotation)annotation).getGraph())
-          || (annotation.getClass().equals(AlignmentSequenceAnnotation.class) && ((org.vamsas.objects.core.AlignmentAnnotation)annotation).getGraph())) {
+      /*if ((annotation.getClass().equals(org.vamsas.objects.core.AlignmentAnnotation.class) && ((org.vamsas.objects.core.AlignmentAnnotation)annotation).getGraph())
+          || (hasSequenceRef=true && ((org.vamsas.objects.core.AlignmentSequenceAnnotation)annotation).getGraph())) {
+      */
+      if (has[HASVALS]) {
         // make bounds and automatic description strings for jalview user's benefit (these shouldn't be written back to vamsas document)
         boolean first=true;
         float min=0,max=1;
-
         for (int i=0;i<arow.length; i++) {
           if (arow[i]!=null) {
             // check range - shouldn't we have a min and max property in the annotation object ?
@@ -1239,9 +1267,9 @@ public class VamsasDatastore {
         if (has[HASHPHOB]) {
           type = jalview.datamodel.AlignmentAnnotation.BAR_GRAPH;
         }
-        jan = new jalview.datamodel.AlignmentAnnotation(annotation.getLabel(), annotation.getDescription(), arow, min, max, type);
+        jan = new jalview.datamodel.AlignmentAnnotation(a_label, a_descr, arow, min, max, type);
       } else {
-        jan = new jalview.datamodel.AlignmentAnnotation(annotation.getLabel(), annotation.getDescription(), arow);
+        jan = new jalview.datamodel.AlignmentAnnotation(a_label, a_descr, arow);
       }
       if (annotation.getLinkCount()>0) {
         Cache.log.warn("Ignoring "+annotation.getLinkCount()+"links added to AlignmentAnnotation.");
@@ -1356,7 +1384,8 @@ public class VamsasDatastore {
         for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++)
         {
           se = getSegRange(dseta.getSeg(s), false);
-          for (int p=se[se[2]]; p!=se[1-se[2]]; p+=se[2]==0 ? 1 : -1 ) {
+          int se_end=se[1-se[2]]+(se[2]==0 ? 1 : -1);
+          for (int p=se[se[2]]; p!=se_end; p+=se[2]==0 ? 1 : -1 ) {
             posList.add(Integer.valueOf(p));
           }
         }
@@ -1381,8 +1410,8 @@ public class VamsasDatastore {
     }
     return null;
   }
-/* not needed now. 
- * Provenance getVamsasProvenance(jalview.datamodel.Provenance jprov) {
+  /* not needed now. 
+   * Provenance getVamsasProvenance(jalview.datamodel.Provenance jprov) {
     jalview.datamodel.ProvenanceEntry[] entries = null;
     // TODO: fix App and Action here.
     Provenance prov = new Provenance();
@@ -1423,7 +1452,7 @@ public class VamsasDatastore {
 
     return prov;
   }
-  */
+   */
   jalview.datamodel.Provenance getJalviewProvenance(Provenance prov) {
     // TODO: fix App and Action entries and check use of provenance in jalview.
     jalview.datamodel.Provenance jprov = new jalview.datamodel.Provenance();
@@ -1447,13 +1476,13 @@ public class VamsasDatastore {
 
   Entry dummyPEntry(String action) {
     Entry entry = new Entry();
-    entry.setApp("Jalview");
+    entry.setApp(this.provEntry.getApp());
     if (action != null)
       entry.setAction(action);
     else
       entry.setAction("created.");
     entry.setDate(new org.exolab.castor.types.Date(new java.util.Date()));
-    entry.setUser(System.getProperty("user.name"));
+    entry.setUser(this.provEntry.getUser());
     return entry;
   }