Revision: 20103
          http://sourceforge.net/p/jmol/code/20103
Author:   hansonr
Date:     2014-11-11 13:00:10 +0000 (Tue, 11 Nov 2014)
Log Message:
-----------
code comments; clearer code in GifEncoder

Modified Paths:
--------------
    trunk/Jmol/src/javajs/img/GifEncoder.java
    trunk/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java

Modified: trunk/Jmol/src/javajs/img/GifEncoder.java
===================================================================
--- trunk/Jmol/src/javajs/img/GifEncoder.java   2014-11-10 22:58:19 UTC (rev 
20102)
+++ trunk/Jmol/src/javajs/img/GifEncoder.java   2014-11-11 13:00:10 UTC (rev 
20103)
@@ -78,11 +78,11 @@
  * GifEncoder extensively adapted for Jmol by Bob Hanson
  * 
  * Color quantization roughly follows the GIMP method
- * "dither Floyd-Steinberg (normal)" but with some twists.
- * (For example, we exclude the background color.)
+ * "dither Floyd-Steinberg (normal)" but with some twists. (For example, we
+ * exclude the background color.)
  * 
- * Note that although GIMP code annotation refers to "median-cut", 
- * it is really using MEAN-cut. That is what I use here as well.
+ * Note that although GIMP code annotation refers to "median-cut", it is really
+ * using MEAN-cut. That is what I use here as well.
  * 
  * -- commented code allows visualization of the color space using Jmol. Very
  * enlightening!
@@ -207,47 +207,43 @@
 
   //////////////  256-color quantization  //////////////
 
-  private class ColorItem {
+  /**
+   * a color point in normalized L*a*b space with a flag indicating whether it
+   * is the background color
+   */
+  private class ColorItem extends P3 {
+    protected boolean isBackground;
 
-    int rgb;
-    P3 lab;
-
-    ColorItem(int rgb) {
-      this.rgb = rgb;
-      lab = toLAB(rgb);
+    ColorItem(int rgb, boolean isBackground) {
+      this.isBackground = isBackground;
+      setT(toLABnorm(rgb));
     }
-
-    @Override
-    public String toString() {
-      return Integer.toHexString(rgb) + " " + lab;
-    }
   }
 
-  private class ColorCell {
+  /**
+   * A list of normalized L*a*b points with an index and a center and volume
+   * 
+   */
+  private class ColorCell extends Lst<P3> {
+
     protected int index;
-    // counts here are counts of color occurances for this grouped set.
-    // ints here allow for 2147483647/0x100 = count of 8388607 for THIS 
average color, which should be fine.
-    protected P3 lab;
-    // min and max based on 0 0 0 for this rgb
-//    private float maxr = Integer.MAX_VALUE, minr = -Integer.MAX_VALUE,
-//        maxg = Integer.MAX_VALUE, ming = -Integer.MAX_VALUE,
-//        maxb = Integer.MAX_VALUE, minb = -Integer.MAX_VALUE;
-//    private float rmaxr = -Integer.MAX_VALUE, rminr = Integer.MAX_VALUE,
-//        rmaxg = -Integer.MAX_VALUE, rming = Integer.MAX_VALUE,
-//        rmaxb = -Integer.MAX_VALUE, rminb = Integer.MAX_VALUE;
-    int rgb;
-    Lst<ColorItem> lst;
+    protected P3 center;
+
     private float volume;
 
     ColorCell(int index) {
       this.index = index;
-      lst = new Lst<ColorItem>();
     }
 
-    public float getVolume() {
+    /**
+     * @param doVisualize
+     *        debugging only
+     * @return volume in normalized L*a*b space
+     */
+    public float getVolume(boolean doVisualize) {
       if (volume != 0)
         return volume;
-      if (lst.size() < 2)
+      if (size() < 2)
         return -1;
       //if (true)
       //return lst.size();
@@ -258,9 +254,9 @@
       float miny = Integer.MAX_VALUE;
       float maxz = -Integer.MAX_VALUE;
       float minz = Integer.MAX_VALUE;
-      int n = lst.size();
+      int n = size();
       for (int i = n; --i >= 0;) {
-        P3 xyz = lst.get(i).lab;
+        P3 xyz = get(i);
         if (xyz.x < minx)
           minx = xyz.x;
         if (xyz.y < miny)
@@ -277,70 +273,80 @@
       float dx = (maxx - minx);
       float dy = (maxy - miny);
       float dz = (maxz - minz);
+      // Jmol visualization only
+      //      if (doVisualize) {
+      //        P3 ptRGB = toRGB(center);
+      //        drawPt(index, -size(), ptRGB);
+      //        //for (int i = n; --i >= 0;)
+      //        //drawPt(index, i, toRGB(get(i)));
+      //        P3 pt0 = toRGB(P3.new3(Math.max(minx, 0), Math.max(miny, 0),
+      //            Math.max(minz, 0)));
+      //        P3 pt1 = toRGB(P3.new3(Math.min(maxx, 100), Math.min(maxy, 
100),
+      //            Math.min(maxz, 100)));
+      //        rgbToXyz(pt0, pt0);
+      //        xyzToLab(pt0, pt0);
+      //        rgbToXyz(pt1, pt1);
+      //        xyzToLab(pt1, pt1);
+      //        System.out.println("boundbox corners " + pt0 + " " + pt1);
+      //        System.out.println("draw d" + index + " boundbox color " + 
ptRGB
+      //            + " mesh nofill");
+      //      }
       return volume = dx * dx + dy * dy + dz * dz;
     }
 
-    void addItem(ColorItem c) {
-      lst.addLast(c);
-    }
+    //    // Jmol visualization only
+    //      private void drawPt(int index, int i, P3 rgb) {
+    //        boolean isMain = (i < 0);
+    //      P3 lab = rgbToXyz(rgb, null);
+    //      xyzToLab(lab, lab);
+    //      System.out.println("draw d" + index + (isMain ? "_" : "_" + i) + " 
width "
+    //          + (isMain ? 1.0 : 0.2) + " " + lab
+    //          + " color " + rgb + (isMain ? " '" + -i + "'" : ""));
+    //      }
 
     /**
-     * Set the average L*a*b value for this box
+     * Set the average normalized L*a*b value for this cell and return its RGB 
point
      * 
      * @return RGB point
      * 
      */
     protected P3 setColor() {
-      int count = lst.size();
-      lab = new P3();
-      for (int i = count; --i >= 0;) {
-        lab.add(lst.get(i).lab);
-      }
-      lab.scale(1f / count);
-      P3 ptrgb = toRGB(lab);
-      rgb = CU.colorPtToFFRGB(ptrgb);
-
-      //for (int i = 0; i < count; i++) {
-      // drawPt(index, i+1, lst.get(i).rgb, false);
-      // }
-
-      //      drawPt(index, 0, rgb, true);
-      //      System.out.println("boundbox corners { " + Math.max(minr, 0) + " 
"
-      //          + Math.max(ming, 0) + " " + Math.max(minb, 0) + "}{ "
-      //          + Math.min(maxr, 100) + " " + Math.min(maxg, 100) + " "
-      //          + Math.min(maxb, 100) + "}");
-      //      System.out.println("draw d" + index + " boundbox color "
-      //          + CU.colorPtFromInt(rgb, null) + " mesh nofill");
-      //      System.out.println("//" + index + " " + volume);
-
-      //System.out.println(index + " " + Integer.toHexString(rgb) + " " + 
ptrgb + " " + xyz + " " + (maxr - minr)+ " " + (maxg - ming) + " " + 
(maxb-minb));
-      return ptrgb;
+      int count = size();
+      center = new P3();
+      for (int i = count; --i >= 0;)
+        center.add(get(i));
+      center.scale(1f / count);
+      // Jmol visualization only
+      //volume = 0;
+      //getVolume(true); 
+      return toRGB(center);
     }
 
     /**
-     * use median_cut algorithm to split the box, creating a doubly linked 
list.
+     * use median_cut algorithm to split the cell, creating a doubly linked
+     * list.
      * 
      * Paul Heckbert, MIT thesis COLOR IMAGE QUANTIZATION FOR FRAME BUFFER
      * DISPLAY https://www.cs.cmu.edu/~ph/ciq_thesis
      * 
-     * except, as in GIMP, we use mean, not median here.
+     * except, as in GIMP, we use center (not median) here.
      * 
-     * @param boxes
+     * @param cells
      * @return true if split
      */
-    protected boolean splitBox(Lst<ColorCell> boxes) {
-      int n = lst.size();
+    protected boolean splitCell(Lst<ColorCell> cells) {
+      int n = size();
       if (n < 2)
         return false;
-      int newIndex = boxes.size();
-      ColorCell newBox = new ColorCell(newIndex);
-      boxes.addLast(newBox);
+      int newIndex = cells.size();
+      ColorCell newCell = new ColorCell(newIndex);
+      cells.addLast(newCell);
       float[][] ranges = new float[3][3];
       for (int ic = 0; ic < 3; ic++) {
         float low = Float.MAX_VALUE;
         float high = -Float.MAX_VALUE;
-        for (int i = lst.size(); --i >= 0;) {
-          P3 lab = lst.get(i).lab;
+        for (int i = n; --i >= 0;) {
+          P3 lab = get(i);
           float v = (ic == 0 ? lab.x : ic == 1 ? lab.y : lab.z);
           if (low > v)
             low = v;
@@ -352,132 +358,123 @@
         ranges[2][ic] = high - low;
       }
       float[] r = ranges[2];
-      int mode = (r[0] >= r[1] ? (r[0] >= r[2] ? 0 : 2)
-          : r[1] >= r[2] ? 1 : 2);
-      // NOTE: GIMP does not use median! uses mean instead;
-
-      //      int median = n / 2;
-      //      float val = a[median];
-      //      int dir = (val == a[0] ? 1 : -1);
-      //      while (median >= 0 && median < n && a[median] == val) {
-      //        median += dir;
-      //      }
-      //      if (dir == -1)
-      //        median++;
-      //      val = a[median];
-
+      int mode = (r[0] >= r[1] ? (r[0] >= r[2] ? 0 : 2) : r[1] >= r[2] ? 1 : 
2);
       float val = ranges[0][mode] + ranges[2][mode] / 2;
-      
-//      newBox.minr = minr;
-//      newBox.ming = ming;
-//      newBox.minb = minb;
-//      newBox.maxr = maxr;
-//      newBox.maxg = maxg;
-//      newBox.maxb = maxb;
-      volume = 0;
-      
+      volume = 0; // recalculate volume if needed
       switch (mode) {
       case 0:
-        for (int i = lst.size(); --i >= 0;)
-          if (lst.get(i).lab.x >= val)
-            newBox.addItem(lst.remove(i));
-//        maxr = val - 0.001f;
-//        newBox.minr = val;
+        for (int i = n; --i >= 0;)
+          if (get(i).x >= val)
+            newCell.addLast(remove(i));
         break;
       case 1:
-        for (int i = lst.size(); --i >= 0;)
-          if (lst.get(i).lab.y >= val)
-            newBox.addItem(lst.remove(i));
-//        maxg = val - 0.001f;
-//        newBox.ming = val;
+        for (int i = n; --i >= 0;)
+          if (get(i).y >= val)
+            newCell.addLast(remove(i));
         break;
       case 2:
-        for (int i = lst.size(); --i >= 0;)
-          if (lst.get(i).lab.z >= val)
-            newBox.addItem(lst.remove(i));
-//        maxb = val - 0.001f;
-//        newBox.minb = val;
+        for (int i = size(); --i >= 0;)
+          if (get(i).z >= val)
+            newCell.addLast(remove(i));
         break;
       }
       return true;
     }
-
-    @Override
-    public String toString() {
-      return index + " " + Integer.toHexString(rgb);
-    }
   }
 
   /**
-   * Generate a palette and quantize all colors into it. 
+   * Quantize all colors and create the final palette
    * 
    */
   private void createPalette() {
-    Lst<ColorItem> colors = new Lst<ColorItem>();
+
+    // catalog all pixel colors
+
+    Lst<ColorItem> tempColors = new Lst<ColorItem>();
     Map<Integer, ColorItem> ciHash = new Hashtable<Integer, ColorItem>();
     for (int i = 0, n = pixels.length; i < n; i++) {
       int rgb = pixels[i];
       Integer key = Integer.valueOf(rgb);
       ColorItem item = ciHash.get(key);
       if (item == null) {
-        item = new ColorItem(rgb);
+        item = new ColorItem(rgb, rgb == backgroundColor);
         ciHash.put(key, item);
-        colors.addLast(item);
+        tempColors.addLast(item);
       }
     }
+    int nColors = tempColors.size();
+    System.out.println("GIF total image colors: " + nColors);
     ciHash = null;
-    int nTotal = colors.size();
-    System.out.println("GIF total image colors: " + nTotal);
-    bitsPerPixel = (nTotal <= 2 ? 1 : nTotal <= 4 ? 2 : nTotal <= 16 ? 4 : 8);
+
+    // create a set of <= 256 color cells
+
+    Lst<ColorCell> cells = quantizeColors(tempColors);
+    nColors = cells.size();
+    System.out.println("GIF final color count: " + nColors);
+
+    // generate the palette and map each cell's rgb color to itself
+
+    Map<Integer, ColorCell> colorMap = new Hashtable<Integer, ColorCell>();
+    bitsPerPixel = (nColors <= 2 ? 1 : nColors <= 4 ? 2 : nColors <= 16 ? 4 : 
8);
     palette = new P3[1 << bitsPerPixel];
-    quantizeColors(colors);
+    for (int i = 0; i < nColors; i++) {
+      ColorCell c = cells.get(i);
+      colorMap.put(
+          Integer.valueOf(CU.colorPtToFFRGB(palette[i] = c.setColor())), c);
+    }
+
+    // index all pixels to a pallete color
+
+    pixels = indexPixels(cells, colorMap);
   }
 
   /**
-   *  Quantize colors by generating a set of boxes containing all colors.
-   *  Start with just two boxes -- fixed background color and all others.
-   *  Keep splitting boxes while there are fewer than 256 and some with
-   *  multiple colors in them. 
-   *  
-   *  It is possible that we will end up with fewer than 256 colors.
-   *  
-   * @param colors
+   * Quantize colors by generating a set of cells in normalized L*a*b space
+   * containing all colors. Start with just two cells -- fixed background color
+   * and all others. Keep splitting cells while there are fewer than 256 and
+   * some with multiple colors in them.
+   * 
+   * It is possible that we will end up with fewer than 256 colors.
+   * 
+   * @param tempColors
+   * @return final list of colors
    */
-  private void quantizeColors(Lst<ColorItem> colors) {
-    Map<Integer, ColorCell> colorMap = new Hashtable<Integer, ColorCell>();
-    Lst<ColorCell> boxes = new Lst<ColorCell>();
+  private Lst<ColorCell> quantizeColors(Lst<ColorItem> tempColors) {
+    int n = tempColors.size();
+    Lst<ColorCell> cells = new Lst<ColorCell>();
     ColorCell cc = new ColorCell(0);
-    cc.addItem(new ColorItem(backgroundColor));
-    boxes.addLast(cc);
-    boxes.addLast(cc = new ColorCell(1));
-    for (int i = colors.size(); --i >= 0;) {
-      ColorItem c = colors.get(i);
-      if (c.rgb != backgroundColor)
-        cc.addItem(c);
+    cc.addLast(new ColorItem(backgroundColor, true));
+    cells.addLast(cc);
+    cc = new ColorCell(1);
+    if (n > 256)
+      cells.addLast(cc);
+    for (int i = 0; i < n; i++) {
+      ColorItem c = tempColors.get(i);
+      if (c.isBackground)
+        continue;
+      cc.addLast(c);
+      if (n <= 256) {
+        cells.addLast(cc);
+        cc = new ColorCell(cells.size());
+      }
     }
-    colors.clear();
-    int n;
-    while ((n = boxes.size()) < 256) {
-      float maxVol = 0;
-      ColorCell maxCell = null;
-      for (int i = n; --i >= 1;) {
-        ColorCell b = boxes.get(i);
-        float v = b.getVolume();
-        if (v > maxVol) {
-          maxVol = v;
-          maxCell = b;
+    tempColors.clear();
+    if (n > 256)
+      while ((n = cells.size()) < 256) {
+        float maxVol = 0;
+        ColorCell maxCell = null;
+        for (int i = n; --i >= 1;) {
+          ColorCell c = cells.get(i);
+          float v = c.getVolume(false);
+          if (v > maxVol) {
+            maxVol = v;
+            maxCell = c;
+          }
         }
+        if (maxCell == null || !maxCell.splitCell(cells))
+          break;
       }
-      if (maxCell == null || !maxCell.splitBox(boxes))
-        break;
-    }
-    for (int i = 0; i < n; i++) {
-      ColorCell b = boxes.get(i);
-      palette[i] = b.setColor();
-      colorMap.put(Integer.valueOf(b.rgb), b);
-    }
-    System.out.println("GIF final color count: " + boxes.size());
-    quantizePixels(colorMap, boxes);
+    return cells;
   }
 
   /**
@@ -488,13 +485,27 @@
    * Floyd-Steinberg dithering, with error limiting to 75%. Finds the closest
    * known color and then spreads out the error over four leading pixels.
    * 
+   * @param cells
+   *        quantized color cells
    * @param colorMap
-   * @param boxes
+   *        map of quantized rgb to its cell
+   * @return array of color indexes, one for each pixel
    * 
    */
-  private void quantizePixels(Map<Integer, ColorCell> colorMap,
-                              Lst<ColorCell> boxes) {
-    P3[] pixelErr = new P3[pixels.length];
+  private int[] indexPixels(Lst<ColorCell> cells,
+                            Map<Integer, ColorCell> colorMap) {
+    // We need a strip only width+2 wide to process all the errors.
+    // Errors are added to the next pixel and the next row's pixels 
+    // only through p + width + 1:
+    //         p  +1
+    //   +w-1 +w  +w+1
+    // so including p as well, we need a total of width + 2 errors.
+    //
+    // as p moves through the pixels, we just use mod to cycle through
+    // this strip.
+    //
+    int w2 = width + 2;
+    P3[] errors = new P3[w2];
     // We should replace, not overwrite, pixels 
     // as this may be the raw canvas.buf32.
     int[] newPixels = new int[pixels.length];
@@ -505,13 +516,13 @@
     for (int i = 0, p = 0; i < height; ++i) {
       boolean notLastRow = (i != height - 1);
       for (int j = 0; j < width; ++j, p++) {
-        if (pixelErr[p] == null) {
+        P3 pe = errors[p % w2];
+        if (pe == null || pe.x == Float.MAX_VALUE) {
           lab = null;
           rgb = pixels[p];
         } else {
-          lab = toLAB(pixels[p]);
-          err = pixelErr[p]; 
-          // it does not matter that we repurpose errors[p] here.
+          lab = toLABnorm(pixels[p]);
+          err = pe;
           // important not to round the clamp here -- full floating precision
           err.x = clamp(err.x, -75, 75);
           err.y = clamp(err.y, -75, 75);
@@ -522,68 +533,65 @@
         Integer key = Integer.valueOf(rgb);
         ColorCell cell = colorMap.get(key);
         if (cell == null) {
-          // critical to generate lab from rgb here for nearestCell mapping.
-          lab = toLAB(rgb);
+          // critical to generate normalized L*a*b from RGB here for 
nearestCell mapping.
+          // otherwise future RGB keys may match the wrong cell
+          lab = toLABnorm(rgb);
           cell = nearestCell.get(key);
           if (cell == null) {
             // find nearest cell
             float maxerr = Float.MAX_VALUE;
             // skip 0 0 0
-            for (int ib = boxes.size(); --ib >= 1;) {
-              ColorCell b = boxes.get(ib);
-              err.sub2(lab, b.lab);
+            for (int ib = cells.size(); --ib >= 1;) {
+              ColorCell c = cells.get(ib);
+              err.sub2(lab, c.center);
               float d = err.lengthSquared();
               if (d < maxerr) {
                 maxerr = d;
-                cell = b;
+                cell = c;
               }
             }
             nearestCell.put(key, cell);
           }
           if (floydSteinberg) {
             // dither
-            err.sub2(lab, cell.lab);
+            err.sub2(lab, cell.center);
             boolean notLastCol = (j < width - 1);
             if (notLastCol)
-              addError(err, 7, pixelErr, p + 1);
+              addError(err, 7, errors, p + 1, w2);
             if (notLastRow) {
               if (j > 0)
-                addError(err, 3, pixelErr, p + width - 1);
-              addError(err, 5, pixelErr, p + width);
+                addError(err, 3, errors, p + width - 1, w2);
+              addError(err, 5, errors, p + width, w2);
               if (notLastCol)
-                addError(err, 1, pixelErr, p + width + 1);
+                addError(err, 1, errors, p + width + 1, w2);
             }
           }
+          err.x = Float.MAX_VALUE; // used; flag for resetting to 0
         }
         newPixels[p] = cell.index;
       }
     }
-    pixels = newPixels;
+    return newPixels;
   }
 
-  private void addError(P3 err, int f, P3[] pixelErr, int p) {
+  private void addError(P3 err, int f, P3[] errors, int p, int w2) {
     // GIMP will allow changing the background color.
     if (pixels[p] == backgroundColor)
       return;
-    P3 errp = pixelErr[p];
+    p %= w2;
+    P3 errp = errors[p];
     if (errp == null)
-      errp = pixelErr[p] = new P3();
+      errp = errors[p] = new P3();
+    else if (errp.x == Float.MAX_VALUE) // reuse
+      errp.set(0, 0, 0);
     errp.scaleAdd2(f / 16f, err, errp);
   }
 
-  //  protected void drawPt(int index, int i, int rgb, boolean isMain) {
-  //    P3 pt = toLAB(rgb);
-  //    System.out.println("draw id 'd" + index + "_" + i + "' width "
-  //        + (isMain ? 1.0 : 0.2) + " " + pt + " color "
-  //        + CU.colorPtFromInt(rgb, null) + " '" + index + "'");
-  //  }
-
   ///////////////////////// CIE L*a*b / XYZ / sRGB conversion methods /////////
 
+  // these could be static, but that just makes for more JavaScript code
 
-  // these could be static, but that just makes for more JavaScript code
-  
-  protected P3 toLAB(int rgb) {
+  protected P3 toLABnorm(int rgb) {
     P3 lab = CU.colorPtFromInt(rgb, null);
     rgbToXyz(lab, lab);
     xyzToLab(lab, lab);
@@ -613,7 +621,7 @@
         1.8758f, 0.0415f, 0.0557f, -0.2040f, 1.0570f });
   }
 
-  private P3 rgbToXyz(P3 rgb, P3 xyz) {
+  public P3 rgbToXyz(P3 rgb, P3 xyz) {
     // http://en.wikipedia.org/wiki/CIE_1931_color_space
     // http://rsb.info.nih.gov/ij/plugins/download/Color_Space_Converter.java
     if (xyz == null)
@@ -631,7 +639,7 @@
         2.4)) * 100;
   }
 
-  private P3 xyzToRgb(P3 xyz, P3 rgb) {
+  public P3 xyzToRgb(P3 xyz, P3 rgb) {
     // http://en.wikipedia.org/wiki/CIE_1931_color_space
     // http://rsb.info.nih.gov/ij/plugins/download/Color_Space_Converter.java
     if (rgb == null)
@@ -650,7 +658,7 @@
         : x * 12.92) * 255;
   }
 
-  private P3 xyzToLab(P3 xyz, P3 lab) {
+  public P3 xyzToLab(P3 xyz, P3 lab) {
     // http://en.wikipedia.org/wiki/Lab_color_space
     // http://rsb.info.nih.gov/ij/plugins/download/Color_Space_Converter.java
     // Lab([0..100], [-86.185..98.254], [-107.863..94.482])
@@ -672,7 +680,7 @@
     );
   }
 
-  private P3 labToXyz(P3 lab, P3 xyz) {
+  public P3 labToXyz(P3 lab, P3 xyz) {
     // http://en.wikipedia.org/wiki/Lab_color_space
     // http://rsb.info.nih.gov/ij/plugins/download/Color_Space_Converter.java
     // XYZn = D65 = {95.0429, 100.0, 108.8900};
@@ -700,29 +708,6 @@
     return (min == 0 ? Math.round(c) : c);
   }
 
-  //static {
-  //  P3 x;
-  //  x = rgbToXyz(P3.new3(0,0,0), null);
-  //  System.out.println("xyz="+x);
-  //  x = xyzToLab(x, x);
-  //  System.out.println("lab="+x);
-  //  x = labToXyz(x, x);
-  //  System.out.println(x);
-  //  x = xyzToRgb(x, x);
-  //  System.out.println(x);
-  //  
-  //  x = rgbToXyz(P3.new3(254,1,253), null);
-  //  System.out.println("xyz="+x);
-  //  x = xyzToLab(x, x);
-  //  System.out.println("lab="+x);
-  //  x = labToXyz(x, x);
-  //  System.out.println(x);
-  //  x = xyzToRgb(x, x);
-  //  System.out.println(x);
-  //  
-  //  System.out.println(toRGB(toLAB(CU.colorPtToFFRGB(P3.new3(200,100,50)))));
-  //}
-
   ///////////////////////// GifEncoder writing methods ////////////////////////
 
   /**

Modified: trunk/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java        
2014-11-10 22:58:19 UTC (rev 20102)
+++ trunk/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java        
2014-11-11 13:00:10 UTC (rev 20103)
@@ -65,7 +65,7 @@
   
   private boolean isLigandBondBug; 
   // Jmol-14.3.3_2014.07.27 broke mmCIF bond reading for ligands
-  // Jmol-1
+  // Jmol-14.3.9_2014.11.11 fixes this. 
 
   @Override
   protected void initSubclass() {
@@ -82,6 +82,10 @@
       filter = PT.rep(filter, "BIOMOLECULE", "ASSEMBLY");
     isBiomolecule = checkFilterKey("ASSEMBLY");
     
+    // When this reader was split off from CifReader, a bug was introduced
+    // into the Resolver that made it so that ligand files were read by 
+    // CifReader and not MMCifReader. This caused CHEM_COMP_BOND records to be 
+    // skipped and so in the case of pdbAddHydrogen no hydrogens added.
     isLigandBondBug = (stateScriptVersionInt >= 140204 && 
stateScriptVersionInt <= 140208
         || stateScriptVersionInt >= 140304 && stateScriptVersionInt <= 140308);
 

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Comprehensive Server Monitoring with Site24x7.
Monitor 10 servers for $9/Month.
Get alerted through email, SMS, voice calls or mobile push notifications.
Take corrective actions from your mobile device.
http://pubads.g.doubleclick.net/gampad/clk?id=154624111&iu=/4140/ostg.clktrk
_______________________________________________
Jmol-commits mailing list
Jmol-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jmol-commits

Reply via email to