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