protected void jvxlReadSurfaceInfo() throws Exception {
    String s;
    String data = xr.getXmlData("jvxlSurfaceInfo", null, true, true);
    isXLowToHigh = XmlReader.getXmlAttrib(data, "isXLowToHigh").equals("true");
    jvxlCutoff = parseFloatStr(XmlReader.getXmlAttrib(data, "cutoff"));
    if (!Float.isNaN(jvxlCutoff)) Logger.info("JVXL read: cutoff " + jvxlCutoff);
    int nContourData = parseIntStr(XmlReader.getXmlAttrib(data, "nContourData"));
    haveContourData = (nContourData > 0);
    params.isContoured = XmlReader.getXmlAttrib(data, "contoured").equals("true");
    if (params.isContoured) {
      int nContoursRead = parseIntStr(XmlReader.getXmlAttrib(data, "nContours"));
      if (nContoursRead <= 0) {
        nContoursRead = 0;
      } else {
        s = XmlReader.getXmlAttrib(data, "contourValues");
        if (s.length() > 0) {
          jvxlData.contourValues = params.contoursDiscrete = parseFloatArrayStr(s);
          Logger.info("JVXL read: contourValues " + Escape.eAF(jvxlData.contourValues));
        }
        s = XmlReader.getXmlAttrib(data, "contourColors");
        if (s.length() > 0) {
          jvxlData.contourColixes = params.contourColixes = C.getColixArray(s);
          jvxlData.contourColors = C.getHexCodes(jvxlData.contourColixes);
          Logger.info("JVXL read: contourColixes " + C.getHexCodes(jvxlData.contourColixes));
        }
        params.contourFromZero = XmlReader.getXmlAttrib(data, "contourFromZero").equals("true");
      }
      params.nContours = (haveContourData ? nContourData : nContoursRead);
      // TODO ? params.contourFromZero = false; // MEP data to complete the plane
    }
    jvxlData.nVertexColors = parseIntStr(XmlReader.getXmlAttrib(data, "nVertexColors"));
    params.isBicolorMap = XmlReader.getXmlAttrib(data, "bicolorMap").equals("true");
    if (params.isBicolorMap) {
      // TODO -- not quite right, because
      s = XmlReader.getXmlAttrib(data, "colorPositive");
      if (s.length() > 0
          && params.colorRgb == Integer.MIN_VALUE
          && params.colorPos == Parameters.defaultColorPositive)
        params.colorPos = CU.getArgbFromString(s);
      s = XmlReader.getXmlAttrib(data, "colorNegative");
      if (s.length() > 0
          && params.colorRgb == Integer.MIN_VALUE
          && params.colorNeg == Parameters.defaultColorNegative)
        params.colorNeg = CU.getArgbFromString(s);
    }
    if (params.isBicolorMap || params.colorBySign) jvxlCutoff = 0;
    jvxlDataIsColorMapped =
        ((params.colorRgb == Integer.MIN_VALUE || params.colorRgb == Integer.MAX_VALUE)
            && (params.isBicolorMap || XmlReader.getXmlAttrib(data, "colorMapped").equals("true")));
    // isJvxlPrecisionColor is for information only -- will be superceded by encoding attribute of
    // jvxlColorData
    jvxlData.isJvxlPrecisionColor = XmlReader.getXmlAttrib(data, "precisionColor").equals("true");
    jvxlData.jvxlDataIsColorDensity =
        params.colorDensity =
            (params.colorRgb == Integer.MIN_VALUE
                && XmlReader.getXmlAttrib(data, "colorDensity").equals("true"));
    if (jvxlData.jvxlDataIsColorDensity && Float.isNaN(params.pointSize)) {
      s = XmlReader.getXmlAttrib(data, "pointSize");
      if (s.length() > 0) jvxlData.pointSize = params.pointSize = parseFloatStr(s);
    }
    s = XmlReader.getXmlAttrib(data, "allowVolumeRender");
    jvxlData.allowVolumeRender =
        params.allowVolumeRender = (s.length() == 0 || s.equalsIgnoreCase("true"));
    s = XmlReader.getXmlAttrib(data, "plane");
    if (s.indexOf("{") >= 0) {
      params.thePlane = null;
      params.mapLattice = null;
      try {
        params.thePlane = (P4) Escape.uP(s);
        s = XmlReader.getXmlAttrib(data, "maplattice");
        Logger.info("JVXL read: plane " + params.thePlane);
        if (s.indexOf("{") >= 0) {
          params.mapLattice = (P3) Escape.uP(s);
          Logger.info("JVXL read: mapLattice " + params.mapLattice);
        }
        if (params.scale3d == 0)
          params.scale3d = parseFloatStr(XmlReader.getXmlAttrib(data, "scale3d"));
        if (Float.isNaN(params.scale3d)) params.scale3d = 0;
      } catch (Exception e) {
        if (params.thePlane == null) {
          Logger.error("JVXL Error reading plane definition -- setting to 0 0 1 0  (z=0)");
          params.thePlane = P4.new4(0, 0, 1, 0);
        } else {
          Logger.error("JVXL Error reading mapLattice definition -- ignored");
        }
      }
      surfaceDataCount = 0;
      edgeDataCount = 0;
    } else {
      params.thePlane = null;
      surfaceDataCount = parseIntStr(XmlReader.getXmlAttrib(data, "nSurfaceInts"));
      edgeDataCount = parseIntStr(XmlReader.getXmlAttrib(data, "nBytesUncompressedEdgeData"));
    }
    excludedVertexCount = parseIntStr(XmlReader.getXmlAttrib(data, "nExcludedVertexes"));
    excludedTriangleCount = parseIntStr(XmlReader.getXmlAttrib(data, "nExcludedTriangles"));
    invalidatedVertexCount = parseIntStr(XmlReader.getXmlAttrib(data, "nInvalidatedVertexes"));
    s = XmlReader.getXmlAttrib(data, "slabInfo");
    if (s.length() > 0) jvxlData.slabInfo = s;
    colorDataCount =
        Math.max(0, parseIntStr(XmlReader.getXmlAttrib(data, "nBytesUncompressedColorData")));
    jvxlDataIs2dContour = (params.thePlane != null && jvxlDataIsColorMapped);

    // new Jmol 12.1.50
    jvxlData.color = XmlReader.getXmlAttrib(data, "color");
    if (jvxlData.color.length() == 0 || jvxlData.color.indexOf("null") >= 0)
      jvxlData.color = "orange";
    jvxlData.translucency = parseFloatStr(XmlReader.getXmlAttrib(data, "translucency"));
    if (Float.isNaN(jvxlData.translucency)) jvxlData.translucency = 0;
    s = XmlReader.getXmlAttrib(data, "meshColor");
    if (s.length() > 0) jvxlData.meshColor = s;
    s = XmlReader.getXmlAttrib(data, "rendering");
    if (s.length() > 0) jvxlData.rendering = s;
    jvxlData.colorScheme = XmlReader.getXmlAttrib(data, "colorScheme");
    if (jvxlData.colorScheme.length() == 0) jvxlData.colorScheme = null;
    if (jvxlData.thisSet < 0) {
      int n = parseIntStr(XmlReader.getXmlAttrib(data, "set"));
      if (n > 0) jvxlData.thisSet = n - 1;
    }
    jvxlData.slabValue = parseIntStr(XmlReader.getXmlAttrib(data, "slabValue"));
    jvxlData.isSlabbable = (XmlReader.getXmlAttrib(data, "slabbable").equalsIgnoreCase("true"));
    jvxlData.diameter = parseIntStr(XmlReader.getXmlAttrib(data, "diameter"));
    if (jvxlData.diameter == Integer.MIN_VALUE) jvxlData.diameter = 0;

    if (jvxlDataIs2dContour) params.isContoured = true;

    if (params.colorBySign) params.isBicolorMap = true;
    boolean insideOut = XmlReader.getXmlAttrib(data, "insideOut").equals("true");
    float dataMin = Float.NaN;
    float dataMax = Float.NaN;
    float red = Float.NaN;
    float blue = Float.NaN;
    if (jvxlDataIsColorMapped) {
      dataMin = parseFloatStr(XmlReader.getXmlAttrib(data, "dataMinimum"));
      dataMax = parseFloatStr(XmlReader.getXmlAttrib(data, "dataMaximum"));
      red = parseFloatStr(XmlReader.getXmlAttrib(data, "valueMappedToRed"));
      blue = parseFloatStr(XmlReader.getXmlAttrib(data, "valueMappedToBlue"));
      if (Float.isNaN(dataMin)) {
        dataMin = red = -1f;
        dataMax = blue = 1f;
      }
    }
    jvxlSetColorRanges(dataMin, dataMax, red, blue, insideOut);
  }