JAL-860 fixed grammar for one structure vs many structures associated with selection
[jalview.git] / src / jalview / gui / Jalview2XML.java
old mode 100755 (executable)
new mode 100644 (file)
index 1fe6bf4..b899ae9
@@ -32,6 +32,7 @@ import org.exolab.castor.xml.*;
 import uk.ac.vamsas.objects.utils.MapList;
 import jalview.bin.Cache;
 import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
 import jalview.schemabinding.version2.*;
@@ -47,7 +48,7 @@ import jalview.util.jarInputStreamProvider;
  * will be :)
  * 
  * @author $author$
- * @version $Revision$
+ * @version $Revision: 1.134 $
  */
 public class Jalview2XML
 {
@@ -623,6 +624,7 @@ public class Jalview2XML
                     state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
                     state.setColourwithAlignPanel(jmol
                             .isUsedforcolourby(ap));
+                    state.setColourByJmol(jmol.isColouredByJmol());
                     if (!jmolViewIds.contains(state.getViewId()))
                     {
                       // Make sure we only store a Jmol state once in each XML
@@ -834,18 +836,12 @@ public class Jalview2XML
           }
           an.setGroupRef(groupIdr.toString());
         }
-        if (aa[i] == av.quality || aa[i] == av.conservation
-                || aa[i] == av.consensus || aa[i].autoCalculated)
-        {
-          // new way of indicating autocalculated annotation -
-          an.setAutoCalculated(aa[i].autoCalculated);
-          // write a stub for this annotation - indicate presence of autocalc
-          // rows
-          an.setLabel(aa[i].label);
-          an.setGraph(true);
-          vamsasSet.addAnnotation(an);
-          continue;
-        }
+
+        // store all visualization attributes for annotation
+        an.setGraphHeight(aa[i].graphHeight);
+        an.setCentreColLabels(aa[i].centreColLabels);
+        an.setScaleColLabels(aa[i].scaleColLabel);
+        an.setShowAllColLabels(aa[i].showAllColLabels);
 
         if (aa[i].graph > 0)
         {
@@ -867,6 +863,13 @@ public class Jalview2XML
         }
 
         an.setLabel(aa[i].label);
+
+        if (aa[i] == av.quality || aa[i] == av.conservation
+                || aa[i] == av.consensus || aa[i].autoCalculated)
+        {
+          // new way of indicating autocalculated annotation -
+          an.setAutoCalculated(aa[i].autoCalculated);
+        }
         if (aa[i].hasScore())
         {
           an.setScore(aa[i].getScore());
@@ -904,6 +907,13 @@ public class Jalview2XML
             }
 
             an.addAnnotationElement(ae);
+            if (aa[i].autoCalculated)
+            {
+              // only write one non-null entry into the annotation row -
+              // sufficient to get the visualization attributes necessary to
+              // display data
+              continue;
+            }
           }
         }
         else
@@ -1109,40 +1119,43 @@ public class Jalview2XML
       Vector settingsAdded = new Vector();
       Object gstyle = null;
       GraduatedColor gcol = null;
-      for (int ro = 0; ro < renderOrder.length; ro++)
+      if (renderOrder != null)
       {
-        gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
-                .getFeatureStyle(renderOrder[ro]);
-        Setting setting = new Setting();
-        setting.setType(renderOrder[ro]);
-        if (gstyle instanceof GraduatedColor)
-        {
-          gcol = (GraduatedColor) gstyle;
-          setting.setColour(gcol.getMaxColor().getRGB());
-          setting.setMincolour(gcol.getMinColor().getRGB());
-          setting.setMin(gcol.getMin());
-          setting.setMax(gcol.getMax());
-          setting.setColourByLabel(gcol.isColourByLabel());
-          setting.setAutoScale(gcol.isAutoScale());
-          setting.setThreshold(gcol.getThresh());
-          setting.setThreshstate(gcol.getThreshType());
-        }
-        else
+        for (int ro = 0; ro < renderOrder.length; ro++)
         {
-          setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
-                  .getColour(renderOrder[ro]).getRGB());
-        }
+          gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
+                  .getFeatureStyle(renderOrder[ro]);
+          Setting setting = new Setting();
+          setting.setType(renderOrder[ro]);
+          if (gstyle instanceof GraduatedColor)
+          {
+            gcol = (GraduatedColor) gstyle;
+            setting.setColour(gcol.getMaxColor().getRGB());
+            setting.setMincolour(gcol.getMinColor().getRGB());
+            setting.setMin(gcol.getMin());
+            setting.setMax(gcol.getMax());
+            setting.setColourByLabel(gcol.isColourByLabel());
+            setting.setAutoScale(gcol.isAutoScale());
+            setting.setThreshold(gcol.getThresh());
+            setting.setThreshstate(gcol.getThreshType());
+          }
+          else
+          {
+            setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
+                    .getColour(renderOrder[ro]).getRGB());
+          }
 
-        setting.setDisplay(av.featuresDisplayed
-                .containsKey(renderOrder[ro]));
-        float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
-                renderOrder[ro]);
-        if (rorder > -1)
-        {
-          setting.setOrder(rorder);
+          setting.setDisplay(av.featuresDisplayed
+                  .containsKey(renderOrder[ro]));
+          float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
+                  .getOrder(renderOrder[ro]);
+          if (rorder > -1)
+          {
+            setting.setOrder(rorder);
+          }
+          fs.addSetting(setting);
+          settingsAdded.addElement(renderOrder[ro]);
         }
-        fs.addSetting(setting);
-        settingsAdded.addElement(renderOrder[ro]);
       }
 
       // Make sure we save none displayed feature settings
@@ -1825,6 +1838,25 @@ public class Jalview2XML
     return null;
   }
 
+  private class JvAnnotRow
+  {
+    public JvAnnotRow(int i, AlignmentAnnotation jaa)
+    {
+      order = i;
+      template = jaa;
+    }
+
+    /**
+     * persisted version of annotation row from which to take vis properties
+     */
+    public jalview.datamodel.AlignmentAnnotation template;
+
+    /**
+     * original position of the annotation row in the alignment
+     */
+    public int order;
+  }
+
   /**
    * Load alignment frame from jalview XML DOM object
    * 
@@ -2057,11 +2089,11 @@ public class Jalview2XML
 
     // ////////////////////////////////
     // LOAD ANNOTATIONS
-    boolean hideQuality = true, hideConservation = true, hideConsensus = true;
+    ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
     /**
      * store any annotations which forward reference a group's ID
      */
-    Hashtable groupAnnotRefs = new Hashtable();
+    Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
 
     if (vamsasSet.getAnnotationCount() > 0)
     {
@@ -2069,22 +2101,29 @@ public class Jalview2XML
 
       for (int i = 0; i < an.length; i++)
       {
-        // set visibility for automatic annotation for this view
-        if (an[i].getLabel().equals("Quality"))
-        {
-          hideQuality = false;
-          continue;
-        }
-        else if (an[i].getLabel().equals("Conservation"))
-        {
-          hideConservation = false;
-          continue;
+        /**
+         * test if annotation is automatically calculated for this view only
+         */
+        boolean autoForView = false;
+        if (an[i].getLabel().equals("Quality")
+                || an[i].getLabel().equals("Conservation")
+                || an[i].getLabel().equals("Consensus"))
+        {
+          // Kludge for pre 2.5 projects which lacked the autocalculated flag
+          autoForView = true;
+          if (!an[i].hasAutoCalculated())
+          {
+            an[i].setAutoCalculated(true);
+          }
         }
-        else if (an[i].getLabel().equals("Consensus"))
+        if (autoForView
+                || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
         {
-          hideConsensus = false;
-          continue;
+          // remove ID - we don't recover annotation from other views for
+          // view-specific annotation
+          an[i].setId(null);
         }
+
         // set visiblity for other annotation in this view
         if (an[i].getId() != null
                 && annotationIds.containsKey(an[i].getId()))
@@ -2107,7 +2146,6 @@ public class Jalview2XML
         if (!an[i].getScoreOnly())
         {
           anot = new jalview.datamodel.Annotation[al.getWidth()];
-
           for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
           {
             if (ae[aa].getPosition() >= anot.length)
@@ -2137,8 +2175,13 @@ public class Jalview2XML
 
         if (an[i].getGraph())
         {
+          float llim = 0, hlim = 0;
+          // if (autoForView || an[i].isAutoCalculated()) {
+          // hlim=11f;
+          // }
           jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
-                  an[i].getDescription(), anot, 0, 0, an[i].getGraphType());
+                  an[i].getDescription(), anot, llim, hlim,
+                  an[i].getGraphType());
 
           jaa.graphGroup = an[i].getGraphGroup();
 
@@ -2150,33 +2193,49 @@ public class Jalview2XML
                     an[i].getThresholdLine().getColour())));
 
           }
-
+          if (autoForView || an[i].isAutoCalculated())
+          {
+            // Hardwire the symbol display line to ensure that labels for
+            // histograms are displayed
+            jaa.hasText = true;
+          }
         }
         else
         {
           jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
                   an[i].getDescription(), anot);
         }
-        // register new annotation
-        if (an[i].getId() != null)
-        {
-          annotationIds.put(an[i].getId(), jaa);
-          jaa.annotationId = an[i].getId();
-        }
-        // recover sequence association
-        if (an[i].getSequenceRef() != null)
+        if (autoForView)
         {
-          if (al.findName(an[i].getSequenceRef()) != null)
+          // register new annotation
+          if (an[i].getId() != null)
+          {
+            annotationIds.put(an[i].getId(), jaa);
+            jaa.annotationId = an[i].getId();
+          }
+          // recover sequence association
+          if (an[i].getSequenceRef() != null)
           {
-            jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
-                    1, true);
-            al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
+            if (al.findName(an[i].getSequenceRef()) != null)
+            {
+              jaa.createSequenceMapping(
+                      al.findName(an[i].getSequenceRef()), 1, true);
+              al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(
+                      jaa);
+            }
           }
         }
         // and make a note of any group association
         if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
         {
-          groupAnnotRefs.put(an[i].getGroupRef(), jaa);
+          ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
+                  .get(an[i].getGroupRef());
+          if (aal == null)
+          {
+            aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
+            groupAnnotRefs.put(an[i].getGroupRef(), aal);
+          }
+          aal.add(jaa);
         }
 
         if (an[i].hasScore())
@@ -2200,7 +2259,21 @@ public class Jalview2XML
           jaa.autoCalculated = true; // means annotation will be marked for
           // update at end of load.
         }
-        al.addAnnotation(jaa);
+        if (an[i].hasGraphHeight())
+        {
+          jaa.graphHeight = an[i].getGraphHeight();
+        }
+        if (jaa.autoCalculated)
+        {
+          autoAlan.add(new JvAnnotRow(i, jaa));
+        }
+        else
+        // if (!autoForView)
+        {
+          // add autocalculated group annotation and any user created annotation
+          // for the view
+          al.addAnnotation(jaa);
+        }
       }
     }
 
@@ -2289,11 +2362,29 @@ public class Jalview2XML
         if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
         {
           // re-instate unique group/annotation row reference
-          jalview.datamodel.AlignmentAnnotation jaa = (jalview.datamodel.AlignmentAnnotation) groupAnnotRefs
+          ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
                   .get(groups[i].getId());
-          if (jaa != null)
+          if (jaal != null)
           {
-            jaa.groupRef = sg;
+            for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
+            {
+              jaa.groupRef = sg;
+              if (jaa.autoCalculated)
+              {
+                // match up and try to set group autocalc alignment row for this
+                // annotation
+                if (jaa.label.startsWith("Consensus for "))
+                {
+                  sg.setConsensus(jaa);
+                }
+                // match up and try to set group autocalc alignment row for this
+                // annotation
+                if (jaa.label.startsWith("Conservation for "))
+                {
+                  sg.setConservationRow(jaa);
+                }
+              }
+            }
           }
         }
         al.addGroup(sg);
@@ -2371,9 +2462,8 @@ public class Jalview2XML
 
     if (isnewview)
     {
-      af = loadViewport(file, JSEQ, hiddenSeqs, al, hideConsensus,
-              hideQuality, hideConservation, jms, view, uniqueSeqSetId,
-              viewId);
+      af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
+              uniqueSeqSetId, viewId, autoAlan);
       av = af.viewport;
       ap = af.alignPanel;
     }
@@ -2500,20 +2590,16 @@ public class Jalview2XML
               if (!jmolViewIds.containsKey(sviewid))
               {
                 jmolViewIds.put(sviewid, new Object[]
-                {
-                    new int[]
-                    { x, y, width, height },
-                    "",
-                    new Hashtable<String, Object[]>(),
-                    new boolean[]
-                    {
-                        false,false} });
-                // Legacy->2.7 conversion: if there is no attribute for
-                // colouring with the alignPanel then by default we set the
-                // first encountered view to be the default source of colour
-                // information.
+                { new int[]
+                { x, y, width, height }, "",
+                    new Hashtable<String, Object[]>(), new boolean[]
+                    { false, false, true } });
+                // Legacy pre-2.7 conversion JAL-823 :
+                // do not assume any view has to be linked for colour by
+                // sequence
               }
-              // TODO: assemble String[] { pdb files }, String[] { id for each
+
+              // assemble String[] { pdb files }, String[] { id for each
               // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
               // seqs_file 2}, boolean[] {
               // linkAlignPanel,superposeWithAlignpanel}} from hash
@@ -2521,11 +2607,15 @@ public class Jalview2XML
               ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
                       .hasAlignwithAlignPanel() ? ids[p].getStructureState(
                       s).getAlignwithAlignPanel() : false;
-              // always colour by linked panel if not specified
+              // never colour by linked panel if not specified
               ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
                       .hasColourwithAlignPanel() ? ids[p]
                       .getStructureState(s).getColourwithAlignPanel()
                       : false;
+              // default for pre-2.7 projects is that Jmol colouring is enabled
+              ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
+                      .hasColourByJmol() ? ids[p].getStructureState(s)
+                      .getColourByJmol() : true;
 
               if (((String) jmoldat[1]).length() < ids[p]
                       .getStructureState(s).getContent().length())
@@ -2534,22 +2624,32 @@ public class Jalview2XML
                   jmoldat[1] = ids[p].getStructureState(s).getContent();
                 }
               }
-              Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
-                      .get(ids[p].getFile());
-              if (seqstrmaps == null)
+              if (ids[p].getFile() != null)
               {
-                ((Hashtable) jmoldat[2]).put(
-                        new File(ids[p].getFile()).toString(),
-                        seqstrmaps = new Object[]
-                        { pdbFile, ids[p].getId(), new Vector(),
-                            new Vector() });
+                Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
+                        .get(ids[p].getFile());
+                if (seqstrmaps == null)
+                {
+                  ((Hashtable) jmoldat[2]).put(
+                          new File(ids[p].getFile()).toString(),
+                          seqstrmaps = new Object[]
+                          { pdbFile, ids[p].getId(), new Vector(),
+                              new Vector() });
+                }
+                if (!((Vector) seqstrmaps[2]).contains(seq))
+                {
+                  ((Vector) seqstrmaps[2]).addElement(seq);
+                  // ((Vector)seqstrmaps[3]).addElement(n) :
+                  // in principle, chains
+                  // should be stored here : do we need to
+                  // TODO: store and recover seq/pdb_id :
+                  // chain mappings
+                }
               }
-              if (!((Vector) seqstrmaps[2]).contains(seq))
+              else
               {
-                ((Vector) seqstrmaps[2]).addElement(seq);
-                // ((Vector)seqstrmaps[3]).addElement(n) : in principle, chains
-                // should be stored here : do we need to
-                // TODO: store and recover seq/pdb_id : chain mappings
+                errorMessage = ("The Jmol views in the Jalview 2 project may\nnot be correctly bound to sequences in the alignment.\nIn the case of problems, see note at\nhttp://issues.jalview.org/browse/JAL-747");
+                warn(errorMessage);
               }
             }
           }
@@ -2565,7 +2665,7 @@ public class Jalview2XML
           int[] geom = (int[]) svattrib[0];
           String state = (String) svattrib[1];
           Hashtable<String, Object[]> oldFiles = (Hashtable<String, Object[]>) svattrib[2];
-          final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1];
+          final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
           int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
           // collate the pdbfile -> sequence mappings from this view
           Vector<String> pdbfilenames = new Vector<String>();
@@ -2722,8 +2822,7 @@ public class Jalview2XML
                     {
                       sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
                               useinJmolsuperpos, usetoColourbyseq,
-                              fileloc,
-                              rect, vid);
+                              jmolColouring, fileloc, rect, vid);
                     } catch (OutOfMemoryError ex)
                     {
                       new OOMWarning("restoring structure view for PDB id "
@@ -2764,9 +2863,8 @@ public class Jalview2XML
               String pdbFile = (String) filedat[0];
               SequenceI[] seq = (SequenceI[]) ((Vector<SequenceI>) filedat[2])
                       .toArray(new SequenceI[0]);
-              StructureSelectionManager.getStructureSelectionManager()
-                      .setMapping(seq, null, pdbFile,
-                              jalview.io.AppletFormatAdapter.FILE);
+              ((AppJmol) comp).jmb.ssm.setMapping(seq, null, pdbFile,
+                      jalview.io.AppletFormatAdapter.FILE);
               ((AppJmol) comp).jmb.addSequenceForStructFile(pdbFile, seq);
             }
             // and add the AlignmentPanel's reference to the Jmol view
@@ -2781,7 +2879,8 @@ public class Jalview2XML
             }
             if (usetoColourbyseq)
             {
-              ((AppJmol) comp).useAlignmentPanelForColourbyseq(ap);
+              ((AppJmol) comp).useAlignmentPanelForColourbyseq(ap,
+                      !jmolColouring);
             }
             else
             {
@@ -2796,9 +2895,9 @@ public class Jalview2XML
   }
 
   AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
-          Alignment al, boolean hideConsensus, boolean hideQuality,
-          boolean hideConservation, JalviewModelSequence jms,
-          Viewport view, String uniqueSeqSetId, String viewId)
+          Alignment al, JalviewModelSequence jms, Viewport view,
+          String uniqueSeqSetId, String viewId,
+          ArrayList<JvAnnotRow> autoAlan)
   {
     AlignFrame af = null;
     af = new AlignFrame(al, view.getWidth(), view.getHeight(),
@@ -2860,27 +2959,6 @@ public class Jalview2XML
       af.viewport.hideSequence(hseqs);
 
     }
-    // set visibility of annotation in view
-    if ((hideConsensus || hideQuality || hideConservation)
-            && al.getAlignmentAnnotation() != null)
-    {
-      int hSize = al.getAlignmentAnnotation().length;
-      for (int h = 0; h < hSize; h++)
-      {
-        if ((hideConsensus && al.getAlignmentAnnotation()[h].label
-                .equals("Consensus"))
-                || (hideQuality && al.getAlignmentAnnotation()[h].label
-                        .equals("Quality"))
-                || (hideConservation && al.getAlignmentAnnotation()[h].label
-                        .equals("Conservation")))
-        {
-          al.deleteAnnotation(al.getAlignmentAnnotation()[h]);
-          hSize--;
-          h--;
-        }
-      }
-      af.alignPanel.adjustAnnotationHeight();
-    }
     // recover view properties and display parameters
     if (view.getViewName() != null)
     {
@@ -3184,9 +3262,84 @@ public class Jalview2XML
     Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
             view.getHeight());
     af.alignPanel.updateAnnotation(false); // recompute any autoannotation
+    reorderAutoannotation(af, al, autoAlan);
     return af;
   }
 
+  private void reorderAutoannotation(AlignFrame af, Alignment al,
+          ArrayList<JvAnnotRow> autoAlan)
+  {
+    // copy over visualization settings for autocalculated annotation in the
+    // view
+    if (al.getAlignmentAnnotation() != null)
+    {
+      /**
+       * Kludge for magic autoannotation names (see JAL-811)
+       */
+      String[] magicNames = new String[]
+      { "Consensus", "Quality", "Conservation" };
+      JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
+      Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
+      for (String nm : magicNames)
+      {
+        visan.put(nm, nullAnnot);
+      }
+      for (JvAnnotRow auan : autoAlan)
+      {
+        visan.put(auan.template.label, auan);
+      }
+      int hSize = al.getAlignmentAnnotation().length;
+      ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
+      for (int h = 0; h < hSize; h++)
+      {
+        jalview.datamodel.AlignmentAnnotation jalan = al
+                .getAlignmentAnnotation()[h];
+        if (jalan.autoCalculated)
+        {
+          JvAnnotRow valan = visan.get(jalan.label);
+          if (valan != null)
+          {
+            // delete the auto calculated row from the alignment
+            al.deleteAnnotation(al.getAlignmentAnnotation()[h], false);
+            hSize--;
+            h--;
+            if (valan != nullAnnot)
+            {
+              if (jalan != valan.template)
+              {
+                // newly created autoannotation row instance
+                // so keep a reference to the visible annotation row
+                // and copy over all relevant attributes
+                if (valan.template.graphHeight >= 0)
+
+                {
+                  jalan.graphHeight = valan.template.graphHeight;
+                }
+                jalan.visible = valan.template.visible;
+              }
+              reorder.add(new JvAnnotRow(valan.order, jalan));
+            }
+          }
+        }
+      }
+      int s = 0, srt[] = new int[reorder.size()];
+      JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
+      for (JvAnnotRow jvar : reorder)
+      {
+        rws[s] = jvar;
+        srt[s++] = jvar.order;
+      }
+      reorder.clear();
+      jalview.util.QuickSort.sort(srt, rws);
+      // and re-insert the annotation at its correct position
+      for (JvAnnotRow jvar : rws)
+      {
+        al.addAnnotation(jvar.template, jvar.order);
+      }
+      af.alignPanel.adjustAnnotationHeight();
+    }
+  }
+
   Hashtable skipList = null;
 
   /**