Revision: 20296
          http://sourceforge.net/p/jmol/code/20296
Author:   hansonr
Date:     2015-02-15 18:32:52 +0000 (Sun, 15 Feb 2015)
Log Message:
-----------
Jmol.___JmolVersion="14.3.12_2015.02.14"

new feature:  x.dot(y) for planes and points -- was present but undocumented 
and not working correctly
new feature: (undocumented) x.distance.all(y)

new feature: load MUTATE "==LYS"
 -- loads using set appendNew false
 -- bypasses regeneration of secondary structure
 -- not to be documented
 -- issued by MUTATE command only

bug fix: MUTATE command adjustments for saving state
bug fix: MUTATE command should not force recreation of shapes
bug fix: MUTATE command should not change backbone atoms
bug fix: x = measure(a,b) where b is {none} crashes Jmol
bug fix: compare({atomA},{atomsB}) should return standard 4x4 matrix, not one 
involving a rotation
         about an atom center 
  -- (not adjusted when ROTATESELECTED was fixed in 14.3.11_2014.12.17; Angel 
Herraez)

code: org.jmol.modelsetbio.BioExt 
 -- extracts struts, quaternion plots, polymerInfo, mutate into optional module
 -- saves 15K in corebio.js

Modified Paths:
--------------
    trunk/Jmol/src/javajs/util/A4.java
    trunk/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java
    trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java
    trunk/Jmol/src/org/jmol/jvxl/calc/MarchingCubes.java
    trunk/Jmol/src/org/jmol/jvxl/data/MeshData.java
    trunk/Jmol/src/org/jmol/minimize/Minimizer.java
    trunk/Jmol/src/org/jmol/minimize/forcefield/ForceFieldUFF.java
    trunk/Jmol/src/org/jmol/modelset/ModelLoader.java
    trunk/Jmol/src/org/jmol/modelsetbio/BioExt.java
    trunk/Jmol/src/org/jmol/modelsetbio/BioModel.java
    trunk/Jmol/src/org/jmol/script/ScriptCompiler.java
    trunk/Jmol/src/org/jmol/script/ScriptEval.java
    trunk/Jmol/src/org/jmol/script/ScriptMathProcessor.java
    trunk/Jmol/src/org/jmol/scriptext/MathExt.java
    trunk/Jmol/src/org/jmol/viewer/Jmol.properties
    trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/console/AppConsole.java

Modified: trunk/Jmol/src/javajs/util/A4.java
===================================================================
--- trunk/Jmol/src/javajs/util/A4.java  2015-02-15 00:51:11 UTC (rev 20295)
+++ trunk/Jmol/src/javajs/util/A4.java  2015-02-15 18:32:52 UTC (rev 20296)
@@ -190,7 +190,12 @@
     y = (float) (m02 - m20);
     z = (float) (m10 - m01);
     double sin = 0.5 * Math.sqrt(x * x + y * y + z * z);
-    angle = (float) Math.atan2(sin, cos);
+    if (sin == 0 && cos == 1) {
+      x = y = 0;
+      z = 1;
+    } else {
+      angle = (float) Math.atan2(sin, cos);
+    }
 
     // no need to normalize
     // x /= n;

Modified: trunk/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java        
2015-02-15 00:51:11 UTC (rev 20295)
+++ trunk/Jmol/src/org/jmol/adapter/readers/cif/MMCifReader.java        
2015-02-15 18:32:52 UTC (rev 20296)
@@ -71,6 +71,8 @@
   protected void initSubclass() {
     setIsPDB();
     isMMCIF = true;
+    if (htParams.containsKey("isMutate"))
+      asc.setInfo("isMutate",Boolean.TRUE);      
     byChain = checkFilterKey("BYCHAIN");
     bySymop = checkFilterKey("BYSYMOP");
     isCourseGrained = byChain || bySymop;

Modified: trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java        
2015-02-15 00:51:11 UTC (rev 20295)
+++ trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java        
2015-02-15 18:32:52 UTC (rev 20296)
@@ -467,7 +467,7 @@
       return asc.errorMessage + "\nfor file " + filePath
           + "\ntype " + name;
     if ((asc.bsAtoms == null ? asc.ac
-        : asc.bsAtoms.cardinality()) == 0
+        : asc.bsAtoms.nextSetBit(0)) <= 0
         && fileType.indexOf("DataOnly") < 0 && asc.atomSetInfo.get("dataOnly") 
== null)
       return "No atoms found\nfor file " + filePath + "\ntype " + name;
     fixBaseIndices();

Modified: trunk/Jmol/src/org/jmol/jvxl/calc/MarchingCubes.java
===================================================================
--- trunk/Jmol/src/org/jmol/jvxl/calc/MarchingCubes.java        2015-02-15 
00:51:11 UTC (rev 20295)
+++ trunk/Jmol/src/org/jmol/jvxl/calc/MarchingCubes.java        2015-02-15 
18:32:52 UTC (rev 20296)
@@ -277,7 +277,7 @@
       break;
     }
     allInside = (colorDensity && (cutoff == 0 
-        || mode == MODE_JVXL && bsVoxels.cardinality() == 0));
+        || mode == MODE_JVXL && bsVoxels.nextSetBit(0) < 0));
     boolean colorDensityAll = (colorDensity && cutoff == 0);
     float v = 0;
     for (int x = x0; x != x1; x += xStep, ptX += ptStep, pt = ptX) {

Modified: trunk/Jmol/src/org/jmol/jvxl/data/MeshData.java
===================================================================
--- trunk/Jmol/src/org/jmol/jvxl/data/MeshData.java     2015-02-15 00:51:11 UTC 
(rev 20295)
+++ trunk/Jmol/src/org/jmol/jvxl/data/MeshData.java     2015-02-15 18:32:52 UTC 
(rev 20296)
@@ -236,7 +236,7 @@
       return;
     int nNull = 0;
     for (int i = 0; i < nSets; i++) {
-      if (surfaceSet[i] != null && surfaceSet[i].cardinality() == 0)
+      if (surfaceSet[i] != null && surfaceSet[i].nextSetBit(0) < 0)
         surfaceSet[i] = null;
       if (surfaceSet[i] == null)
         nNull++;

Modified: trunk/Jmol/src/org/jmol/minimize/Minimizer.java
===================================================================
--- trunk/Jmol/src/org/jmol/minimize/Minimizer.java     2015-02-15 00:51:11 UTC 
(rev 20295)
+++ trunk/Jmol/src/org/jmol/minimize/Minimizer.java     2015-02-15 18:32:52 UTC 
(rev 20296)
@@ -223,7 +223,7 @@
     }
     Logger.info("minimize: initializing " + pFF.name + " (steps = " + steps + 
" criterion = "
         + crit + ") ...");
-    if (bsSelected.cardinality() == 0) {
+    if (bsSelected.nextSetBit(0) < 0) {
       Logger.error(GT._("No atoms selected -- nothing to do!"));
       return false;
     }

Modified: trunk/Jmol/src/org/jmol/minimize/forcefield/ForceFieldUFF.java
===================================================================
--- trunk/Jmol/src/org/jmol/minimize/forcefield/ForceFieldUFF.java      
2015-02-15 00:51:11 UTC (rev 20295)
+++ trunk/Jmol/src/org/jmol/minimize/forcefield/ForceFieldUFF.java      
2015-02-15 18:32:52 UTC (rev 20296)
@@ -171,12 +171,12 @@
     if (!(v instanceof BS))
       return null;
     BS bs = (BS) v;
-    if (isAromatic && bs.cardinality() > 0) {
+    if (isAromatic && bs.nextSetBit(0) >= 0) {
       if (bsAromatic == null)
         bsAromatic = (BS) 
minimizer.vwr.evaluateExpression(tokenTypes[TOKEN_AROMATIC]);
       bs.and(bsAromatic);
     }
-    if (Logger.debugging && bs.cardinality() > 0)
+    if (Logger.debugging && bs.nextSetBit(0) >= 0)
       Logger.debug(smarts + " minimize atoms=" + bs);
     return bs;
   }

Modified: trunk/Jmol/src/org/jmol/modelset/ModelLoader.java
===================================================================
--- trunk/Jmol/src/org/jmol/modelset/ModelLoader.java   2015-02-15 00:51:11 UTC 
(rev 20295)
+++ trunk/Jmol/src/org/jmol/modelset/ModelLoader.java   2015-02-15 18:32:52 UTC 
(rev 20296)
@@ -144,7 +144,7 @@
 
   private boolean someModelsHaveUnitcells;
   private boolean someModelsAreModulated;
-  private boolean is2D;
+  private boolean is2D, isMutate;
   public boolean isTrajectory; 
   private boolean isPyMOLsession;
   private boolean doMinimize;
@@ -167,6 +167,7 @@
     ms.modelSetProperties = (Properties) ms.getInfoM("properties");
     //isMultiFile = getModelSetAuxiliaryInfoBoolean("isMultiFile"); -- no 
longer necessary
     ms.haveBioModels = ms.getMSInfoB("isPDB");
+    isMutate = ms.getMSInfoB("isMutate");
     if (ms.haveBioModels)
       jbr = vwr.getJBR().setLoader(this);
     jmolData = (String) ms.getInfoM("jmolData");
@@ -285,7 +286,7 @@
     adapterModelCount = (adapter == null ? 1 : adapter
         .getAtomSetCount(asc));
     // cannot append a trajectory into a previous model
-    appendNew = (!merging || adapter == null || adapterModelCount > 1
+    appendNew = !isMutate && (!merging || adapter == null || adapterModelCount 
> 1
         || isTrajectory || vwr.getBoolean(T.appendnew));
     htAtomMap.clear();
     chainOf = new Chain[defaultGroupCount];
@@ -574,7 +575,6 @@
       if (loadScript.indexOf("load append ") >= 0)
         loadScript.append("; set appendNew true");
       m.loadScript.append("  ").appendSB(loadScript).append(";\n");
-      
     }
     if (isTrajectory) {
       // fill in the rest of the data
@@ -1299,7 +1299,7 @@
 
     // finalize all structures
 
-    if (!ms.haveBioModels || isPyMOLsession) {
+    if (!ms.haveBioModels || isPyMOLsession || isMutate) {
       ms.freezeModels();
       return;
     }

Modified: trunk/Jmol/src/org/jmol/modelsetbio/BioExt.java
===================================================================
--- trunk/Jmol/src/org/jmol/modelsetbio/BioExt.java     2015-02-15 00:51:11 UTC 
(rev 20295)
+++ trunk/Jmol/src/org/jmol/modelsetbio/BioExt.java     2015-02-15 18:32:52 UTC 
(rev 20296)
@@ -955,7 +955,6 @@
       return false; 
     
     String[] info = vwr.fm.getFileInfo();
-    boolean b = vwr.getBoolean(T.appendnew);
     Group g = ms.at[iatom].group;
     //try {
       // get the initial group -- protein for now
@@ -975,9 +974,7 @@
             "try{\n"
           + "  var atoms0 = {*}\n"
           + "  var res0 = " + BS.escape(bsRes0,'(',')')  + "\n"
-          + "  set appendNew false\n"
-          + "  load append "+fileName+"\n"
-          + "  set appendNew " + b + "\n"
+          + "  load mutate "+fileName+"\n"
           + "  var res1 = {!atoms0};var r1 = res1[1];var r0 = res1[0]\n"
           + "  if ({r1 & within(group, r0)}){\n" 
           + "    var haveHs = ({_H & connected(res0)} != 0)\n"
@@ -999,13 +996,20 @@
           + "        connect {N2} {keyatoms & *.C}\n"
           + "      }\n"
           + "      if (C0) {\n" // not terminal
-          + "        if ({res1 and _H & connected(*.N)} == 1) {\n" // proline 
or proline-like
-          + "          delete *.H and res1\n"
-          + "        } else {\n"
-          + "          var x = angle({*.C and res1},{*.CA and res1},{*.N and 
res1},{*.H and res1})\n"
+          + "        var h1 = {*.H and res1}\n"
+          + "        var n = (h1 ? 0 + {res1 and _H & connected(*.N)} : 0)\n"
+          + "        switch (n) {\n" 
+          + "        case 0:\n" // no hydrogens
+          + "          break\n" 
+          + "        case 1:\n" // proline or proline-like
+          + "          delete h1\n"
+          + "          break\n"
+          + "        default:\n"
+          + "          var x = angle({*.C and res1},{*.CA and res1},{*.N and 
res1},h1)\n"
           + "          rotate branch {*.CA and res1} {*.N and res1} 
@{angleH-x}\n"
           + "          delete *.H2 and res1\n"
           + "          delete *.H3 and res1\n"
+          + "          break\n"
           + "        }\n"
           + "        connect {C0} {keyatoms & *.N}\n"
           + "      }\n"
@@ -1017,13 +1021,16 @@
           Logger.debug(script);
         vwr.eval.runScript(script);
       } catch (Exception e) {
-        // TODO
+        // serious Jmol bug here!
+        if (!vwr.isJS)
+          e.printStackTrace();
+        System.out.println(e);
       }
       ms = vwr.ms;
       if (ms.ac == ac)
         return false;
       SB sb = ms.am[iModel].loadScript;
-      String s = PT.rep(sb.toString(), "load append", "mutate ({" + iatom + 
"})");
+      String s = PT.rep(sb.toString(), "load mutate ", "mutate ({" + iatom + 
"})");
       sb.setLength(0);
       sb.append(s);
       // check for protein monomer
@@ -1048,7 +1055,6 @@
     //} catch (Exception e) {
      // System.out.println("" + e);
    // }
-    vwr.setBooleanProperty("appendNew", b);
     vwr.fm.setFileInfo(info);
     return true;
 

Modified: trunk/Jmol/src/org/jmol/modelsetbio/BioModel.java
===================================================================
--- trunk/Jmol/src/org/jmol/modelsetbio/BioModel.java   2015-02-15 00:51:11 UTC 
(rev 20295)
+++ trunk/Jmol/src/org/jmol/modelsetbio/BioModel.java   2015-02-15 18:32:52 UTC 
(rev 20296)
@@ -589,10 +589,10 @@
     } else {
       for (int i = 0; i < specInfo.length();) {
         bsA = ms.getSequenceBits(specInfo.substring(i, ++i), null);
-        if (bsA.cardinality() == 0)
+        if (bsA.nextSetBit(0) < 0)
           continue;
         bsB = ms.getSequenceBits(specInfo.substring(i, ++i), null);
-        if (bsB.cardinality() == 0)
+        if (bsB.nextSetBit(0) < 0)
           continue;
         calcAllRasmolHydrogenBonds(bsA, bsB, vHBonds, true, 1, false, null);
       }

Modified: trunk/Jmol/src/org/jmol/script/ScriptCompiler.java
===================================================================
--- trunk/Jmol/src/org/jmol/script/ScriptCompiler.java  2015-02-15 00:51:11 UTC 
(rev 20295)
+++ trunk/Jmol/src/org/jmol/script/ScriptCompiler.java  2015-02-15 18:32:52 UTC 
(rev 20296)
@@ -1069,7 +1069,7 @@
         return OK;
       }
       if (tokCommand == T.load) {
-        if (nTokens == 1 || nTokens == 2 && tokAt(1) == T.append) {
+        if (nTokens == 1 || nTokens == 2 && (tokAt(1) == T.append)) {
           boolean isDataBase = Viewer.isDatabaseCode(charAt(ichToken));
           if (lookingAtLoadFormat(isDataBase)) {
             String strFormat = script.substring(ichToken, ichToken + cchToken);
@@ -1079,6 +1079,7 @@
             case T.orientation:
             case T.append:
             case T.history:
+            case T.mutate:
             case T.nbo:
               if (nTokens != 1)
                 return ERROR;

Modified: trunk/Jmol/src/org/jmol/script/ScriptEval.java
===================================================================
--- trunk/Jmol/src/org/jmol/script/ScriptEval.java      2015-02-15 00:51:11 UTC 
(rev 20295)
+++ trunk/Jmol/src/org/jmol/script/ScriptEval.java      2015-02-15 18:32:52 UTC 
(rev 20296)
@@ -2184,7 +2184,7 @@
         continue;
       }
       thisCommand = getCommand(pc, false, true);
-      if (debugScript)
+      if (debugHigh || debugScript)
         Logger.info(thisCommand);
       String nextCommand = getCommand(pc + 1, false, true);
       fullCommand = thisCommand
@@ -4037,6 +4037,7 @@
     boolean isAppend = false;
     boolean isInline = false;
     boolean isSmiles = false;
+    boolean isMutate = false;
     boolean isData = false;
     boolean isAsync = vwr.async;
     boolean isConcat = false;
@@ -4145,6 +4146,13 @@
           i += 2; // skip END "key"
         }
         break;
+      case T.mutate:
+        isMutate = isAppend = true;
+        appendNew = false;
+        loadScript.append(" mutate");
+        modelName = optParameterAsString(++i);
+        tok = T.getTokFromName(modelName);
+        break;
       case T.append:
         isAppend = true;
         loadScript.append(" append");
@@ -4503,6 +4511,8 @@
       Logger.startTimer("load");
     if (!isStateScript && !isAppend)
       vwr.setBooleanProperty("legacyJavaFloat", false);
+    if (isMutate)
+      htParams.put("isMutate", Boolean.TRUE);
     errMsg = vwr.loadModelFromFile(null, filename, filenames, null, isAppend,
         htParams, loadScript, sOptions, tokType, isConcat);
     if (timeMsg)

Modified: trunk/Jmol/src/org/jmol/script/ScriptMathProcessor.java
===================================================================
--- trunk/Jmol/src/org/jmol/script/ScriptMathProcessor.java     2015-02-15 
00:51:11 UTC (rev 20295)
+++ trunk/Jmol/src/org/jmol/script/ScriptMathProcessor.java     2015-02-15 
18:32:52 UTC (rev 20296)
@@ -900,10 +900,8 @@
         m4.transpose();
         return addXM4(m4);
       case T.bitset:
-        return addXBs(BSUtil.copyInvert(
-            SV.bsSelectVar(x2),
-            (x2.value instanceof BondSet ? vwr.ms.bondCount : vwr
-                .ms.ac)));
+        return addXBs(BSUtil.copyInvert(SV.bsSelectVar(x2),
+            (x2.value instanceof BondSet ? vwr.ms.bondCount : vwr.ms.ac)));
       }
       return addXFloat(-x2.asFloat());
     case T.opNot:
@@ -919,10 +917,8 @@
       case T.matrix4f:
         return addXM4(M4.newM4((M4) x2.value).invert());
       case T.bitset:
-        return addXBs(BSUtil.copyInvert(
-            SV.bsSelectVar(x2),
-            (x2.value instanceof BondSet ? vwr.ms.bondCount : vwr
-                .ms.ac)));
+        return addXBs(BSUtil.copyInvert(SV.bsSelectVar(x2),
+            (x2.value instanceof BondSet ? vwr.ms.bondCount : vwr.ms.ac)));
       default:
         return addXBool(!x2.asBoolean());
       }
@@ -949,12 +945,8 @@
       switch (iv) {
       case T.identifier:
         // special flag to get all properties.
-        return (x2.tok == T.bitset && getAllProperties(x2, (String) op.value));
-      case T.type:
-        return addXStr(typeOf(x2));
-      case T.keys:
-        return getKeys(x2, (op.intValue & T.minmaxmask) == T.minmaxmask);
-      case T.length:
+        return (x2.tok == T.bitset && (chk ? addXStr("") : getAllProperties(x2,
+            (String) op.value)));
       case T.count:
       case T.size:
         if (iv == T.length && x2.value instanceof BondSet)
@@ -1246,16 +1238,14 @@
     case T.times:
       switch (x1.tok) {
       case T.integer:
-        return (isDecimal(x2) ?
-            addXFloat(x1.intValue * x2.asFloat())
-                : addXInt(x1.intValue * x2.asInt()));
+        return (isDecimal(x2) ? addXFloat(x1.intValue * x2.asFloat())
+            : addXInt(x1.intValue * x2.asInt()));
       case T.string:
-        return (isDecimal(x2) || isDecimal(x1) ?
-            addXFloat(x1.asFloat() * x2.asFloat()) : 
-              addXInt(x1.asInt() * x2.asInt()));
-      }      
-      pt = (x1.tok == T.matrix3f ? ptValue(x2, false)
-          : x2.tok == T.matrix3f ? ptValue(x1, false) : null);
+        return (isDecimal(x2) || isDecimal(x1) ? addXFloat(x1.asFloat()
+            * x2.asFloat()) : addXInt(x1.asInt() * x2.asInt()));
+      }
+      pt = (x1.tok == T.matrix3f ? ptValue(x2)
+          : x2.tok == T.matrix3f ? ptValue(x1) : null);
       pt4 = (x1.tok == T.matrix4f ? planeValue(x2)
           : x2.tok == T.matrix4f ? planeValue(x1) : null);
       // checking here to make sure arrays remain arrays and
@@ -1268,15 +1258,14 @@
           M3 m3b = M3.newM3((M3) x2.value);
           m3b.transpose();
           m3b.rotate(pt);
-          if (x1.tok == T.varray)
-            return addX(SV.getVariableAF(new float[] { pt.x, pt.y, pt.z }));
-          return addXPt(pt);
+          return (x1.tok == T.varray ? addX(SV.getVariableAF(new float[] {
+              pt.x, pt.y, pt.z })) : addXPt(pt));
         }
         if (pt4 != null)
           // q * m --> q
-          return addXPt4((Quat.newP4(pt4).mulQ(Quat
-              .newM((M3) x2.value))).toPoint4f());
-          break;
+          return addXPt4((Quat.newP4(pt4).mulQ(Quat.newM((M3) x2.value)))
+              .toPoint4f());
+        break;
       case T.matrix4f:
         // pt4 * m4
         // [a b c d] * m4
@@ -1284,10 +1273,8 @@
           M4 m4b = M4.newM4((M4) x2.value);
           m4b.transpose();
           m4b.transform(pt4);
-          if (x1.tok == T.varray)
-            return addX(SV.getVariableAF(new float[] { pt4.x, pt4.y, pt4.z,
-                pt4.w }));
-          return addXPt4(pt4);
+          return (x1.tok == T.varray ? addX(SV.getVariableAF(new float[] {
+              pt4.x, pt4.y, pt4.z, pt4.w })) : addXPt4(pt4));
         }
         break;
       }
@@ -1296,9 +1283,8 @@
         M3 m3 = (M3) x1.value;
         if (pt != null) {
           m3.rotate(pt);
-          if (x2.tok == T.varray)
-            return addX(SV.getVariableAF(new float[] { pt.x, pt.y, pt.z }));
-          return addXPt(pt);
+          return (x2.tok == T.varray ? addX(SV.getVariableAF(new float[] {
+              pt.x, pt.y, pt.z })) : addXPt(pt));
         }
         switch (x2.tok) {
         case T.matrix3f:
@@ -1307,8 +1293,8 @@
           return addXM3(m);
         case T.point4f:
           // m * q
-          return addXM3(Quat.newM(m3)
-              .mulQ(Quat.newP4((P4) x2.value)).getMatrix());
+          return addXM3(Quat.newM(m3).mulQ(Quat.newP4((P4) x2.value))
+              .getMatrix());
         }
         f = x2.asFloat();
         A4 aa = new A4();
@@ -1319,16 +1305,13 @@
         M4 m4 = (M4) x1.value;
         if (pt != null) {
           m4.rotTrans(pt);
-          if (x2.tok == T.varray)
-            return addX(SV.getVariableAF(new float[] { pt.x, pt.y, pt.z }));
-          return addXPt(pt);
+          return (x2.tok == T.varray ? addX(SV.getVariableAF(new float[] {
+              pt.x, pt.y, pt.z })) : addXPt(pt));
         }
         if (pt4 != null) {
           m4.transform(pt4);
-          if (x2.tok == T.varray)
-            return addX(SV.getVariableAF(new float[] { pt4.x, pt4.y, pt4.z,
-                pt4.w }));
-          return addXPt4(pt4);
+          return (x2.tok == T.varray ? addX(SV.getVariableAF(new float[] {
+              pt4.x, pt4.y, pt4.z, pt4.w })) : addXPt4(pt4));
         }
         if (x2.tok == T.matrix4f) {
           M4 m4b = M4.newM4((M4) x2.value);
@@ -1352,8 +1335,7 @@
           // quaternion notation as well here.
           return addXPt4(Quat.newP4((P4) x1.value)
               .mulQ(Quat.newP4((P4) x2.value)).toPoint4f());
-        return addXPt4(Quat.newP4((P4) x1.value).mul(x2.asFloat())
-            .toPoint4f());
+        return addXPt4(Quat.newP4((P4) 
x1.value).mul(x2.asFloat()).toPoint4f());
       }
       return addXFloat(x1.asFloat() * x2.asFloat());
     case T.divide:
@@ -1377,21 +1359,20 @@
             Float.NaN) : P3.new3(pt.x / f2, pt.y / f2, pt.z / f2));
       case T.point4f:
         return addXPt4(x2.tok == T.point4f ? Quat.newP4((P4) x1.value)
-            .div(Quat.newP4((P4) x2.value)).toPoint4f() : (f2 = x2
-            .asFloat()) == 0 ? P4.new4(Float.NaN, Float.NaN, Float.NaN,
-            Float.NaN) : Quat.newP4((P4) x1.value).mul(1 / f2)
-            .toPoint4f());
+            .div(Quat.newP4((P4) x2.value)).toPoint4f()
+            : (f2 = x2.asFloat()) == 0 ? P4.new4(Float.NaN, Float.NaN,
+                Float.NaN, Float.NaN) : Quat.newP4((P4) x1.value).mul(1 / f2)
+                .toPoint4f());
       }
       return addXFloat(x1.asFloat() / x2.asFloat());
     case T.leftdivide:
       f = x2.asFloat();
       if (x1.tok == T.point4f) {
-        if (f == 0)
-          return addXPt4(P4.new4(Float.NaN, Float.NaN, Float.NaN, Float.NaN));
-        if (x2.tok == T.point4f)
-          return addXPt4(Quat.newP4((P4) x1.value)
-              .divLeft(Quat.newP4((P4) x2.value)).toPoint4f());
-        return addXPt4(Quat.newP4((P4) x1.value).mul(1 / f).toPoint4f());
+        return (f == 0 ? addXPt4(P4.new4(Float.NaN, Float.NaN, Float.NaN,
+            Float.NaN)) : x2.tok == T.point4f ? addXPt4(Quat
+            .newP4((P4) x1.value).divLeft(Quat.newP4((P4) x2.value))
+            .toPoint4f()) : addXPt4(Quat.newP4((P4) x1.value).mul(1 / f)
+            .toPoint4f()));
       }
       return addXInt(f == 0 ? 0 : (int) Math.floor(x1.asFloat() / 
x2.asFloat()));
     case T.timestimes:
@@ -1428,15 +1409,9 @@
         return addXStr(s);
       case T.string:
         s = (String) x1.value;
-        if (n == 0)
-          return addXStr(PT.trim(s, "\n\t "));
-        if (n == 9999)
-          return addXStr(s.toUpperCase());
-        if (n == -9999)
-          return addXStr(s.toLowerCase());
-        if (n > 0)
-          return addXStr(PT.formatS(s, n, n, false, false));
-        return addXStr(PT.formatS(s, n, n - 1, true, false));
+        return addXStr(n == 0 ? PT.trim(s, "\n\t ") : n == 9999 ? s
+            .toUpperCase() : n == -9999 ? s.toLowerCase() : n > 0 ? PT.formatS(
+            s, n, n, false, false) : PT.formatS(s, n, n - 1, true, false));
       case T.varray:
         String[] list = SV.strListValue(x1);
         for (int i = 0; i < list.length; i++) {
@@ -1455,7 +1430,8 @@
       case T.point4f:
         pt4 = (P4) x1.value;
         if (x2.tok == T.point3f)
-          return addXPt((P3) (Quat.newP4(pt4)).transform2((P3) x2.value, new 
P3()));
+          return addXPt((P3) (Quat.newP4(pt4)).transform2((P3) x2.value,
+              new P3()));
         if (x2.tok == T.point4f) {
           P4 v4 = P4.newPt((P4) x2.value);
           (Quat.newP4(pt4)).getThetaDirected(v4);
@@ -1546,15 +1522,16 @@
             .lastIndexOf("-") > 0));
   }
 
-  public P3 ptValue(SV x, boolean allowFloat) throws ScriptException {
+  public P3 ptValue(SV x) throws ScriptException {
     Object pt;
-    if (chk)
-      return new P3();
     switch (x.tok) {
     case T.point3f:
       return (P3) x.value;
     case T.bitset:
-      return (P3) eval.getBitsetProperty(SV.bsSelectVar(x), T.xyz, null, null,
+      BS bs = SV.bsSelectVar(x);
+      if (bs.nextSetBit(0) < 0)
+        break;
+      return (P3) eval.getBitsetProperty(bs, T.xyz, null, null,
           x.value, null, false, Integer.MAX_VALUE, false);
     case T.string:
       pt = Escape.uP(SV.sValue(x));
@@ -1562,21 +1539,15 @@
         return (P3) pt;
       break;
     case T.varray:
-      
       pt = Escape.uP("{" + SV.sValue(x).replace(']',' ').replace('[',' ') + 
"}");
       if (pt instanceof P3)
         return (P3) pt;
       break;
     }
-    if (!allowFloat)
-      return null;
-    float f = SV.fValue(x);
-    return P3.new3(f, f, f);
+    return null;
   }
 
   public P4 planeValue(T x) {
-    if (chk)
-      return new P4();
     switch (x.tok) {
     case T.point4f:
       return (P4) x.value;
@@ -1617,8 +1588,6 @@
 
   private boolean getAllProperties(SV x2, String abbr)
       throws ScriptException {
-    if (chk)
-      return addXStr("");
     BS bs = SV.bsSelectVar(x2);
     Lst<T> tokens;
     int n = bs.cardinality();
@@ -1652,8 +1621,6 @@
   private boolean getBoundBox(SV x2) {
     if (x2.tok != T.bitset)
       return false;
-    if (chk)
-      return addXStr("");
     BoxInfo b = vwr.ms.getBoxInfo(SV.bsSelectVar(x2), 1);
     P3[] pts = b.getBoundBoxPoints(true);
     Lst<P3> list = new  Lst<P3>();

Modified: trunk/Jmol/src/org/jmol/scriptext/MathExt.java
===================================================================
--- trunk/Jmol/src/org/jmol/scriptext/MathExt.java      2015-02-15 00:51:11 UTC 
(rev 20295)
+++ trunk/Jmol/src/org/jmol/scriptext/MathExt.java      2015-02-15 18:32:52 UTC 
(rev 20296)
@@ -138,10 +138,11 @@
       return evaluateCross(mp, args);
     case T.data:
       return evaluateData(mp, args);
+    case T.dot:
+      return evaluateDotDist(mp, args, 0);
     case T.distance:
-    case T.dot:
       if (op.tok == T.propselector)
-        return evaluateDot(mp, args, tok, op.intValue);
+        return evaluateDotDist(mp, args, op.intValue);
       //$FALL-THROUGH$
     case T.angle:
     case T.measure:
@@ -744,24 +745,67 @@
    // }
   }
 
-  private boolean evaluateDot(ScriptMathProcessor mp, SV[] args, int tok,
-                              int intValue) throws ScriptException {
+  /**
+   * x = y.distance({atoms}) the average distance from elements of y to the
+   * CENTER of {atoms}
+   * 
+   * x = {atomset1}.distance.min({atomset2}, asAtomSet) If asAtomSet is true,
+   * returns the closest atom in atomset1 to any atom of atomset2; if false or
+   * omitted, returns an array listing the distance of each atom in atomset1 to
+   * the closest atom in atomset2. This array can be used to assign properties
+   * to atomset1: {1.1}.property_d = {1.1}.distance.min({2.1}); color {1.1}
+   * property_d.
+   * 
+   * x = {atomset1}.distance.min({point}, asAtomSet) If asAtomSet is true,
+   * returns the atom in atomset1 closest to the specified point;if false or
+   * omitted, returns the closest distance to the specified point from any atom
+   * in atomset1.
+   * 
+   * x = {atomset1}.distance.min({atomset2}).min returns the shortest distance
+   * from any atom in atomset1 to any atom in atomset2.
+   * 
+   * x = {atomset1}.distance.max({atomset2}, asAtomSet) If asAtomSet is true,
+   * returns the furthest atom in atomset1 to any atom of atomset2; if false or
+   * omitted, returns an array listing the distance of each atom in atomset1 to
+   * the furthest atom in atomset2.
+   * 
+   * x = {atomset1}.distance.max({point}, asAtomSet) If asAtomSet is true,
+   * returns the atom in atomset1 furthest from the specified point;if false or
+   * omitted, returns the furthest distance to the specified point from any 
atom
+   * in atomset1.
+   * 
+   * x = {atomset1}.distance.max({atomset2}).max returns the furthest distance
+   * from any atom in atomset1 to any atom in atomset2.
+   * 
+   * x = {atomset1}.distance.all({atomset2}) returns an array or array of 
arrays of values
+   * 
+   * @param mp 
+   * @param args 
+   * @param intValue optional .min .max
+   * @return true if successful
+   * @throws ScriptException 
+   */
+
+  private boolean evaluateDotDist(ScriptMathProcessor mp, SV[] args,
+                                  int intValue) throws ScriptException {
     // distance and dot
+
+    boolean isDist = (intValue != 0);
     switch (args.length) {
     case 1:
-      if (tok == T.dot)
-        return false;
+      break;
+    case 2:
+      if (isDist)
+        break;
       //$FALL-THROUGH$
-    case 2:
-      break;
     default:
       return false;
     }
     SV x1 = mp.getX();
     SV x2 = args[0];
-    P3 pt2 = (x2.tok == T.varray ? null : mp.ptValue(x2, false));
+    P3 pt2 = (x2.tok == T.varray ? null : mp.ptValue(x2));
     P4 plane2 = mp.planeValue(x2);
-    if (tok == T.distance) {
+    if (isDist) {
       int minMax = intValue & T.minmaxmask;
       boolean isMinMax = (minMax == T.min || minMax == T.max);
       boolean isAll = minMax == T.minmaxmask;
@@ -813,9 +857,8 @@
             float[] data = new float[bs.cardinality()];
             for (int i = bs.nextSetBit(0), p = 0; i >= 0; i = bs
                 .nextSetBit(i + 1))
-              data[p++] = ((Float) e.getBitsetProperty(bs2, intValue,
-                  atoms[i], plane2, x1.value, null, false, x1.index, false))
-                  .floatValue();
+              data[p++] = ((Float) e.getBitsetProperty(bs2, intValue, atoms[i],
+                  plane2, x1.value, null, false, x1.index, 
false)).floatValue();
             return mp.addXAF(data);
           }
           return mp.addXObj(e.getBitsetProperty(bs, intValue, pt2, plane2,
@@ -823,7 +866,32 @@
         }
       }
     }
-    return mp.addXFloat(getDistance(mp, x1, x2, tok));
+    P3 pt1 = mp.ptValue(x1);
+    P4 plane1 = mp.planeValue(x1);
+    float f = Float.NaN;
+    try {
+      if (isDist) {
+        f = (plane1 == null ? (plane2 == null ? pt2.distance(pt1) : Measure
+            .distanceToPlane(plane2, pt1)) : Measure.distanceToPlane(plane1,
+            pt2));
+      } else {
+        if (plane1 != null && plane2 != null) {
+          // q1.dot(q2) assume quaternions
+          f = plane1.x * plane2.x + plane1.y * plane2.y + plane1.z * plane2.z
+              + plane1.w * plane2.w;
+          // plane.dot(point) =
+        } else {
+          if (plane1 != null)
+            pt1 = P3.new3(plane1.x, plane1.y, plane1.z);
+          // point.dot(plane)
+          else if (plane2 != null)
+            pt2 = P3.new3(plane2.x, plane2.y, plane2.z);
+          f = pt1.dot(pt2);
+        }
+      }
+    } catch (Exception e) {
+    }
+    return mp.addXFloat(f);
   }
 
   private boolean evaluateHelix(ScriptMathProcessor mp, SV[] args)
@@ -841,9 +909,9 @@
     int tok = T.getTokFromName(type);
     if (args.length > 2) {
       // helix(pt1, pt2, dq ...)
-      P3 pta = mp.ptValue(args[0], true);
-      P3 ptb = mp.ptValue(args[1], true);
-      if (tok == T.nada || args[2].tok != T.point4f)
+      P3 pta = mp.ptValue(args[0]);
+      P3 ptb = mp.ptValue(args[1]);
+      if (tok == T.nada || args[2].tok != T.point4f || pta == null || ptb == 
null)
         return false;
       Quat dq = Quat.newP4((P4) args[2].value);
       T3[] data = Measure.computeHelicalAxis(pta, ptb, dq);
@@ -1556,8 +1624,10 @@
         return false;
     }
     P3[] pts = new P3[nPoints];
-    for (int i = 0; i < nPoints; i++)
-      pts[i] = mp.ptValue(args[i], true);
+    for (int i = 0; i < nPoints; i++) {
+      if ((pts[i] = mp.ptValue(args[i])) == null)
+        return false;
+    }
     switch (nPoints) {
     case 2:
       return mp.addXFloat(pts[0].distance(pts[1]));
@@ -1647,7 +1717,7 @@
             return mp.addXStr("");
           return mp.addXList(list);
         }
-        pt2 = mp.ptValue(args[0], false);
+        pt2 = mp.ptValue(args[0]);
         if (pt2 == null)
           return mp.addXStr("");
         return mp.addXPt(Measure.getIntersection(pt2, null, plane, pt3, norm,
@@ -1662,8 +1732,8 @@
         return mp.addXPt4(e.getHklPlane(P3.new3(SV.fValue(args[0]),
             SV.fValue(args[1]), SV.fValue(args[2]))));
       case T.intersection:
-        pt1 = mp.ptValue(args[0], false);
-        pt2 = mp.ptValue(args[1], false);
+        pt1 = mp.ptValue(args[0]);
+        pt2 = mp.ptValue(args[1]);
         if (pt1 == null || pt2 == null)
           return mp.addXStr("");
         V3 vLine = V3.newV(pt2);
@@ -1679,7 +1749,7 @@
             return mp.addXStr("");
           return mp.addXPt(pt1);
         }
-        pt3 = mp.ptValue(args[2], false);
+        pt3 = mp.ptValue(args[2]);
         if (pt3 == null)
           return mp.addXStr("");
         // intersection(ptLine, vLine, pt2); 
@@ -1714,13 +1784,13 @@
         break;
       case T.bitset:
       case T.point3f:
-        pt1 = mp.ptValue(args[0], false);
-        pt2 = mp.ptValue(args[1], false);
+        pt1 = mp.ptValue(args[0]);
+        pt2 = mp.ptValue(args[1]);
         if (pt2 == null)
           return false;
         pt3 = (args.length > 2
             && (args[2].tok == T.bitset || args[2].tok == T.point3f) ? mp
-            .ptValue(args[2], false) : null);
+            .ptValue(args[2]) : null);
         norm = V3.newV(pt2);
         if (pt3 == null) {
           plane = new P4();
@@ -1747,8 +1817,11 @@
         // plane(<point1>,<point2>,<point3>)
         // plane(<point1>,<point2>,<point3>,<pointref>)
         V3 vAB = new V3();
+        P3 ptref = (args.length == 4 ? mp.ptValue(args[3]) : null);
+        if (ptref == null)
+          return false;
         float nd = Measure.getDirectedNormalThroughPoints(pt1, pt2, pt3,
-            (args.length == 4 ? mp.ptValue(args[3], true) : null), norm, vAB);
+            ptref, norm, vAB);
         return mp.addXPt4(P4.new4(norm.x, norm.y, norm.z, nd));
       }
     }
@@ -1868,7 +1941,7 @@
             && (args[1].tok == T.integer || args[1].tok == T.bitset))
           break;
       }
-      if ((pt0 = mp.ptValue(args[0], false)) == null || tok != T.quaternion
+      if ((pt0 = mp.ptValue(args[0])) == null || tok != T.quaternion
           && args[1].tok == T.point3f)
         return false;
       break;
@@ -1940,7 +2013,7 @@
           break;
         }
       }
-      P3 pt1 = mp.ptValue(args[1], false);
+      P3 pt1 = mp.ptValue(args[1]);
       p4 = mp.planeValue(args[0]);
       if (pt1 != null)
         q = Quat.getQuaternionFrame(P3.new3(0, 0, 0), pt0, pt1);
@@ -2280,8 +2353,26 @@
 
   private boolean evaluateSymop(ScriptMathProcessor mp, SV[] args,
                                 boolean haveBitSet) throws ScriptException {
-    // {xxx}.symop()
-    // symop({xxx}    
+    
+    // x = y.symop(op,atomOrPoint) 
+    // Returns the point that is the result of the transformation of 
atomOrPoint 
+    // via a crystallographic symmetry operation. The atom set y selects the 
unit 
+    // cell and spacegroup to be used. If only one model is present, this can 
simply be all. 
+    // Otherwise, it could be any atom or group of atoms from any model, for 
example 
+    // {*/1.2} or {atomno=1}. The first parameter, op, is a symmetry 
operation. 
+    // This can be the 1-based index of a symmetry operation in a file (use 
show spacegroup to get this listing) 
+    // or a specific Jones-Faithful expression in quotes such as "x,1/2-y,z".
+    //
+    // x = y.symop(op,"label")
+    // This form of the .symop() function returns a set of draw commands that 
describe 
+    // the symmetry operation in terms of rotation axes, inversion centers, 
planes, and 
+    // translational vectors. The draw objects will all have IDs starting with 
whatever 
+    // is given for the label. 
+    //
+    // x = symop("x,y,-z")
+    // x = symop(3)
+    
+    
     if (args.length == 0)
       return false;
     SV x1 = (haveBitSet ? mp.getX() : null);
@@ -2301,14 +2392,14 @@
       xyz = null;
     }
     int iOp = (xyz == null ? args[0].asInt() : 0);
-    P3 pt = (args.length > 1 ? mp.ptValue(args[1], true) : null);
-    if (args.length == 2 && !Float.isNaN(pt.x))
+    P3 pt = (args.length > 1 ?  mp.ptValue(args[1]) : null);
+    if (args.length == 2 && pt != null)
       return mp.addXObj(vwr.ms.getSymTemp(false).getSymmetryInfoAtom(vwr.ms, 
bs, xyz, iOp, pt, null, null,
           T.point));
-    String desc = (args.length == 1 ? "" : SV.sValue(args[args.length - 1]))
+    String desc = (args.length == 1 ? "matrix" : SV.sValue(args[args.length - 
1]))
         .toLowerCase();
     int tok = T.draw;
-    if (args.length == 1 || desc.equalsIgnoreCase("matrix")) {
+    if (desc.equalsIgnoreCase("matrix")) {
       tok = T.matrix4f;
     } else if (desc.equalsIgnoreCase("array") || 
desc.equalsIgnoreCase("list")) {
       tok = T.list;
@@ -2596,32 +2687,6 @@
   }
 
 
-  private float getDistance(ScriptMathProcessor mp, SV x1, SV x2, int tok)
-      throws ScriptException {
-    P3 pt1 = mp.ptValue(x1, true);
-    P4 plane1 = mp.planeValue(x1);
-    P3 pt2 = mp.ptValue(x2, true);
-    P4 plane2 = mp.planeValue(x2);
-    if (tok == T.dot) {
-      if (plane1 != null && plane2 != null)
-        // q1.dot(q2) assume quaternions
-        return plane1.x * plane2.x + plane1.y * plane2.y + plane1.z * plane2.z
-            + plane1.w * plane2.w;
-      // plane.dot(point) =
-      if (plane1 != null)
-        pt1 = P3.new3(plane1.x, plane1.y, plane1.z);
-      // point.dot(plane)
-      if (plane2 != null)
-        pt2 = P3.new3(plane2.x, plane2.y, plane2.z);
-      return pt1.x * pt2.x + pt1.y * pt2.y + pt1.z * pt2.z;
-    }
-
-    if (plane1 == null)
-      return (plane2 == null ? pt2.distance(pt1) : Measure.distanceToPlane(
-          plane2, pt1));
-    return Measure.distanceToPlane(plane1, pt2);
-  }
-
   @Override
   @SuppressWarnings("unchecked")
   public Object getMinMax(Object floatOrSVArray, int tok) {

Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties
===================================================================
--- trunk/Jmol/src/org/jmol/viewer/Jmol.properties      2015-02-15 00:51:11 UTC 
(rev 20295)
+++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties      2015-02-15 18:32:52 UTC 
(rev 20296)
@@ -17,12 +17,26 @@
 
 Jmol.___JmolVersion="14.3.12_2015.02.14"
 
+new feature:  x.dot(y) for planes and points -- was present but undocumented 
and not working correctly
+new feature: (undocumented) x.distance.all(y)
+
+new feature: load MUTATE "==LYS"
+ -- loads using set appendNew false
+ -- bypasses regeneration of secondary structure
+ -- not to be documented
+ -- issued by MUTATE command only
+
+bug fix: MUTATE command adjustments for saving state
+bug fix: MUTATE command should not force recreation of shapes
+bug fix: MUTATE command should not change backbone atoms
+bug fix: x = measure(a,b) where b is {none} crashes Jmol
 bug fix: compare({atomA},{atomsB}) should return standard 4x4 matrix, not one 
involving a rotation
-         about an atom center (follow-up ROTATESELECTED was broken in 
14.3.11_2014.12.17)
-bug fix: mutation should not force recreation of shapes
+         about an atom center 
+  -- (not adjusted when ROTATESELECTED was fixed in 14.3.11_2014.12.17; Angel 
Herraez)
 
 code: org.jmol.modelsetbio.BioExt 
  -- extracts struts, quaternion plots, polymerInfo, mutate into optional module
+ -- saves 15K in corebio.js
  
 JmolVersion="14.3.12_2015.02.11"
 

Modified: 
trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/console/AppConsole.java
===================================================================
--- trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/console/AppConsole.java   
2015-02-15 00:51:11 UTC (rev 20295)
+++ trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/console/AppConsole.java   
2015-02-15 18:32:52 UTC (rev 20296)
@@ -878,8 +878,8 @@
         pt = caretPosition.getOffset();
         consoleTextPane.setCaretPosition(pt);
         try {
-          vBar.setValue(Integer.MAX_VALUE);
-        } catch (Exception e) {
+          vBar.setValue(vBar.getMaximum());
+        } catch (Throwable e) {
           //
         }
         

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


------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Jmol-commits mailing list
Jmol-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jmol-commits

Reply via email to