Revision: 18596 http://sourceforge.net/p/jmol/code/18596 Author: hansonr Date: 2013-08-19 21:13:46 +0000 (Mon, 19 Aug 2013) Log Message: ----------- ___JmolVersion="13.3.4_dev_2013.08.19"
code: Incommensurate modulated structure CIF and M50/40 file loading validation -- includes d=1 and d=2 -- Fourier, sawtooth, crenel Modified Paths: -------------- trunk/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java trunk/Jmol/src/org/jmol/adapter/readers/cif/ModulationReader.java trunk/Jmol/src/org/jmol/adapter/readers/pdb/PdbReader.java trunk/Jmol/src/org/jmol/adapter/readers/xtal/JanaReader.java trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java trunk/Jmol/src/org/jmol/api/SymmetryInterface.java trunk/Jmol/src/org/jmol/modelset/LabelToken.java trunk/Jmol/src/org/jmol/symmetry/Symmetry.java trunk/Jmol/src/org/jmol/symmetry/SymmetryOperation.java trunk/Jmol/src/org/jmol/thread/MoveToThread.java trunk/Jmol/src/org/jmol/util/Modulation.java trunk/Jmol/src/org/jmol/util/ModulationSet.java trunk/Jmol/src/org/jmol/viewer/Jmol.properties trunk/Jmol/src/org/jmol/viewer/StateCreator.java trunk/Jmol/src/org/jmol/viewer/TransformManager.java Modified: trunk/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java 2013-08-19 21:13:46 UTC (rev 18596) @@ -2356,12 +2356,12 @@ /** * creates entries in htModulation with a key of the form: * - * type_id_axis;atomLabel + * type_id_axis;atomLabel * - * where type = W|F|D|O (wave vector, Fourier index, - * displacement, occupancy); id = 1|2|3|0|S (Fourier index, Crenel(0), - * sawtooth); axis (optional) = 0|x|y|z (0 indicates irrelevant -- occupancy); - * and ;atomLabel is only for D and O. + * where type = W|F|D|O (wave vector, Fourier index, displacement, occupancy); + * id = 1|2|3|0|S (Fourier index, Crenel(0), sawtooth); axis (optional) = + * 0|x|y|z (0 indicates irrelevant -- occupancy); and ;atomLabel is only for D + * and O. * * @throws Exception */ @@ -2384,7 +2384,8 @@ case FA_ID: case FO_ID: case FU_ID: - fid = "#=P" + Character.toUpperCase(modulationFields[tok].charAt(11)) + "_" + field; + fid = "#=P" + Character.toUpperCase(modulationFields[tok].charAt(11)) + + "_" + field; pt.x = pt.y = pt.z = 0; break; case WV_ID: @@ -2407,28 +2408,27 @@ case FWV_DISP_ID: case FWV_OCC_ID: case FWV_U_ID: - id = "" + Character.toUpperCase(modulationFields[tok].charAt(11)) + "_"; + id = "" + Character.toUpperCase(modulationFields[tok].charAt(11)) + + "_"; break; case FP_DISP_ID: case FP_OCC_ID: case FP_U_ID: - id = "P" + Character.toUpperCase(modulationFields[tok].charAt(11)) + "_"; + id = "P" + Character.toUpperCase(modulationFields[tok].charAt(11)) + + "_"; } id += field; break; case DISP_SPEC_LABEL: id = "D_S"; - atomLabel = field; - axis = "0"; - break; + //$FALL-THROUGH$ case OCC_SPECIAL_LABEL: - id = "O_0"; + if (id == null) + id = "O_0"; axis = "0"; //$FALL-THROUGH$ case FWV_DISP_LABEL: case FWV_OCC_LABEL: - atomLabel = field; - break; case FWV_U_LABEL: atomLabel = field; break; @@ -2497,7 +2497,9 @@ w = parseFloatStr(field); break; } - if (ignore || Float.isNaN(pt.x + pt.y + pt.z) || pt.x == 0 && pt.y == 0 && pt.z == 0 || id == null) + if (ignore || Float.isNaN(pt.x + pt.y + pt.z) || pt.x == 0 && pt.y == 0 + && pt.z == 0 || id == null || atomLabel != null + && rejectAtomName(atomLabel)) continue; switch (id.charAt(0)) { case 'W': @@ -2527,8 +2529,7 @@ } } } - - + private void addMod(String id, String fid, P3 params) { if (fid != null) id += fid; Modified: trunk/Jmol/src/org/jmol/adapter/readers/cif/ModulationReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/cif/ModulationReader.java 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/adapter/readers/cif/ModulationReader.java 2013-08-19 21:13:46 UTC (rev 18596) @@ -41,7 +41,6 @@ import org.jmol.util.P3; import org.jmol.util.SB; import org.jmol.util.Tensor; -import org.jmol.util.TextFormat; import org.jmol.util.V3; @@ -82,7 +81,6 @@ private V3 q1Norm; private Map<String, P3> htModulation; private Map<String, JmolList<Modulation>> htAtomMods; - private int modT; protected Map<String, Object> htSubsystems; @@ -110,7 +108,7 @@ modDim = 0; modAverage = true; } else { - appendLoadNote("Modulation dimension = " + modDim + (modDim > 1 ? " NOT IMPLEMENTED YET " : "")); + appendLoadNote("Modulation dimension = " + modDim); htModulation = new Hashtable<String, P3>(); } incommensurate = (modDim > 0); @@ -143,6 +141,8 @@ pt.x = pt.y = 0; break; } + if (pt.x == 0 && pt.y == 0 && pt.z == 0) + return; if (map == null) map = htModulation; id += "@" @@ -179,7 +179,7 @@ if (htModulation.containsKey("X_" + suffix)) return; htModulation.put("X_" +suffix, new P3()); - q123 = new P3[modDim]; + q123 = new P3[3]; qlen = new double[modDim]; for (int i = 0; i < modDim; i++) { q123[i] = getMod("W_" + (i + 1)); @@ -189,8 +189,11 @@ } qlen[i] = q123[i].length(); } + for (int i = modDim; i < 3; i++) + q123[i] = new P3(); q1 = q123[0]; q1Norm = V3.new3(q1.x == 0 ? 0 : 1, q1.y == 0 ? 0 : 1, q1.z == 0 ? 0 : 1); + P3 qlist100 = P3.new3(1, 0, 0); P3 pt; int n = atomSetCollection.getAtomCount(); Map<String, P3> map = new Hashtable<String, P3>(); @@ -225,23 +228,13 @@ // convert JAVA Fourier descriptions to standard descriptions if (key.indexOf("_q_") >= 0) { // d > 1 -- already set - appendLoadNote("Wave vector " + key + "(n=" + (modDim == 1 ? Integer.valueOf((int)pt.x) : pt)+")"); - P3 pf = new P3(); - if (pt.x != 0) - pf.scaleAdd2(pt.x, getMod("W_1"), pf); - if (pt.y != 0) - pf.scaleAdd2(pt.y, getMod("W_2"), pf); - if (pt.z != 0) - pf.scaleAdd2(pt.z, getMod("W_3"), pf); - key = TextFormat.simpleReplace(key, "_q_", ""); - addModulation(map, key, pf, iModel); - appendLoadNote("Wave vector " + key + "(n=" + (modDim == 1 ? Integer.valueOf((int)pt.x) : pt)+") = " + pf); + appendLoadNote("Wave vector " + key + "=" + pt); } else { int fn = (int) (pt.dot(q1) / q1.dot(q1) * 1.01f); String k2 = key + "_q_"; if (!htModulation.containsKey(k2 + suffix)) { addModulation(map, k2, P3.new3(fn, 0, 0), iModel); - appendLoadNote("Wave vector " + key + " = " + pt + " n = " + fn); + //appendLoadNote("Wave vector " + key + " = " + pt + " n = " + fn); } } break; @@ -282,10 +275,13 @@ htAtomMods = new Hashtable<String, JmolList<Modulation>>(); int fn = (id == 'S' ? 0 : parseIntStr(key.substring(2))); if (fn == 0) { - addAtomModulation(atomName, axis, type, 1, params, utens, new int[] {1}); + addAtomModulation(atomName, axis, type, params, utens, qlist100); } else { - P3 qlist = getMod("F_" + fn + "_q_"); - addAtomModulation(atomName, axis, type, 1, params, utens, new int[] { (int) qlist.x, (int) qlist.y, (int) qlist.z } ); + P3 qlist = getMod("F_" + fn + "_q_"); + if (qlist == null) { + Logger.error("Missing qlist for F_" + fn); + } + addAtomModulation(atomName, axis, type, params, utens, qlist); } haveAtomMods = true; break; @@ -296,7 +292,6 @@ atoms = atomSetCollection.getAtoms(); symmetry = atomSetCollection.getSymmetry(); iopLast = -1; - f4 = new float[4]; SB sb = new SB(); for (int i = atomSetCollection.getLastAtomSetAtomIndex(); i < n; i++) modulateAtom(atoms[i], sb); @@ -305,11 +300,11 @@ } private void addAtomModulation(String atomName, char axis, int type, - int fn, P3 params, String utens, int[] qcoefs) { + P3 params, String utens, P3 qcoefs) { JmolList<Modulation> list = htAtomMods.get(atomName); if (list == null) htAtomMods.put(atomName, list = new JmolList<Modulation>()); - list.addLast(new Modulation(axis, type, fn, params, utens, qcoefs)); + list.addLast(new Modulation(axis, type, params, utens, qcoefs)); } private String checkKey(String key) { @@ -318,10 +313,8 @@ } private int iopLast = -1; - private Matrix3f rot; - private float[] f4; - float[] epsilon = new float[3]; - float[] delta = new float[3]; + private Matrix3f gammaE; + private Matrix4f gammaIS; /** * The displacement will be set as the atom vibration vector; the string @@ -352,37 +345,23 @@ if (iop != iopLast) { //System.out.println("mdim=" + mdim + " op=" + (iop + 1) + " " + symmetry.getSpaceGroupOperation(iop) + " " + symmetry.getSpaceGroupXyz(iop, false)); iopLast = iop; - rot = new Matrix3f(); - for (int i = 0; i < modDim; i++) { - symmetry.getMod456Row(iop, i, f4); - epsilon[i] = 0; - if (modSelected > 0) { - if (i == modSelected - 1) - epsilon[i] = f4[i] * modSelected; - continue; - } - for (int j = 0; j < modDim; j++) - epsilon[i] += f4[j] * (j + 1); - delta[i] = f4[3] - modT; - } + gammaE = new Matrix3f(); + symmetry.getSpaceGroupOperation(iop).getRotationScale(gammaE); + gammaIS = symmetry.getOperationGammaIS(iop); } - symmetry.getSpaceGroupOperation(iop).getRotationScale(rot); if (Logger.debugging) { Logger.debug("setModulation iop = " + iop + " " + symmetry.getSpaceGroupXyz(iop, false) + " " + a.bsSymmetry); } - ModulationSet ms = new ModulationSet(a.index + " " + a.atomName, list, - modDim, q123, qlen); + + float vocc0 = a.occupancy / 100f; + ModulationSet ms = new ModulationSet(a.index + " " + a.atomName, + P3.newP(a), vocc0, modDim, list, gammaE, gammaIS, q123, qlen); a.vib = ms; - ms.epsilon = epsilon; - ms.delta = delta; - ms.r = P3.newP(a); - ms.vocc0 = a.occupancy / 100f; - ms.rot = rot; ms.calculate(); if (!Float.isNaN(ms.vocc)) { - if (modVib && !Float.isNaN(ms.vocc0)) { - a.occupancy = (int) ((ms.vocc0 + ms.vocc) * 100); + if (modVib && !Float.isNaN(vocc0)) { + a.occupancy = (int) ((vocc0 + ms.vocc) * 100); } else if (ms.vocc < 0.5f) { a.occupancy = 0; if (bsAtoms != null) @@ -391,7 +370,7 @@ a.occupancy = 100; } } - if (ms.htValues != null) { + if (ms.htUij != null) { // Uiso or Uij. We add the displacements, create the tensor, then rotate it, // replacing the tensor already present for that atom. if (Logger.debuggingHigh) { @@ -399,7 +378,7 @@ Logger.debug("setModulation tensor=" + Escape.e(a.tensors.get(0).getInfo("all"))); } - for (Entry<String, Float> e : ms.htValues.entrySet()) + for (Entry<String, Float> e : ms.htUij.entrySet()) addUStr(a, e.getKey(), e.getValue().floatValue()); if (a.tensors != null) Modified: trunk/Jmol/src/org/jmol/adapter/readers/pdb/PdbReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/pdb/PdbReader.java 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/adapter/readers/pdb/PdbReader.java 2013-08-19 21:13:46 UTC (rev 18596) @@ -201,7 +201,7 @@ atomTypePt0 = Integer.parseInt(tokens[0]) - 1; int pt = tokens[1].indexOf("="); if (pt >= 0) { - filterAtomTypeStr = tokens[1].substring(pt + 1).toUpperCase(); + setFilterAtomTypeStr(tokens[1].substring(pt + 1).toUpperCase()); } else { pt = tokens[1].length(); } Modified: trunk/Jmol/src/org/jmol/adapter/readers/xtal/JanaReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/xtal/JanaReader.java 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/adapter/readers/xtal/JanaReader.java 2013-08-19 21:13:46 UTC (rev 18596) @@ -139,9 +139,20 @@ private void qi() { P3 pt = P3.new3(parseFloat(), parseFloat(), parseFloat()); - if (qicount == 0) - addModulation(null, "W_1", pt, -1); - addModulation(null, "F_" + (++qicount), pt, -1); + addModulation(null, "W_" + (++qicount), pt, -1); + pt = new P3(); + switch (qicount) { + case 1: + pt.x = 1; + break; + case 2: + pt.y = 1; + break; + case 3: + pt.z = 1; + break; + } + addModulation(null, "F_" + qicount + "_q_", pt, -1); } private void lattvec(String data) throws Exception { float[] a; @@ -211,18 +222,21 @@ ipt = id.lastIndexOf("/"); id = id.substring(ipt + 1); BufferedReader r = JmolBinary.getBufferedReaderForString((String) viewer.getLigandModel(id, name, "_file", "----")); - if (readM40Floats(r).startsWith("command")) { - discardLinesUntilContains("end"); - readM40Floats(r); - } + if (readM40Floats(r).startsWith("command")) + readM40WaveVectors(r); int nAtoms = (int) floats[0]; for (int i = 0; i < nAtoms; i++) { while (readM40Floats(r).length() == 0 || line.charAt(0) == ' ' || line.charAt(0) == '-') { } - Atom atom = atomSetCollection.addNewAtom(); + + + Atom atom = new Atom(); atom.atomName = line.substring(0, 9).trim(); + if (!filterAtom(atom, 0)) + continue; setAtomCoordXYZ(atom, floats[3], floats[4], floats[5]); + atomSetCollection.addAtom(atom); if (!incommensurate) continue; String label = ";" + atom.atomName; @@ -305,6 +319,26 @@ r.close(); } + private void readM40WaveVectors(BufferedReader r) throws Exception { + while (!readM40Floats(r).contains("end")) + if (line.startsWith("wave")) { + String[] tokens = getTokens(); + P3 pt = new P3(); + switch (modDim) { + case 3: + pt.z = parseFloatStr(tokens[4]); + //$FALL-THROUGH$ + case 2: + pt.y = parseFloatStr(tokens[3]); + //$FALL-THROUGH$ + case 1: + pt.x = parseFloatStr(tokens[2]); + } + addModulation(null, "F_" + parseIntStr(tokens[1]) + "_q_", pt, -1); + } + readM40Floats(r); + } + private void addSinCos(int j, String key, String label, BufferedReader r) throws Exception { checkFourier(j); readM40Floats(r); @@ -323,10 +357,11 @@ } private void checkFourier(int j) { - if (j > 0 && getModulationVector("F_" + (j + 1)) == null) { - P3 pt = P3.newP(getModulationVector("F_1")); + P3 pt; + if (j > 0 && getModulationVector("F_" + (j + 1) + "_q_") == null && (pt = getModulationVector("F_1_q_")) != null) { + pt = P3.newP(pt); pt.scale(j + 1); - addModulation(null, "F_" + (j + 1), pt, -1); + addModulation(null, "F_" + (j + 1) + "_q_", pt, -1); } } @@ -339,7 +374,8 @@ private String readM40Floats(BufferedReader r) throws Exception { line = r.readLine(); - System.out.println(line); + if (Logger.debugging) + Logger.debug(line); int ptLast = line.length() - 10; for (int i = 0, pt = 0; i < 6 && pt <= ptLast; i++, pt += 9) floats[i] = parseFloatStr(line.substring(pt, pt + 9)); Modified: trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java 2013-08-19 21:13:46 UTC (rev 18596) @@ -790,7 +790,8 @@ private boolean filterChain; private boolean filterAtomName; private boolean filterAtomType; - protected String filterAtomTypeStr; + private String filterAtomTypeStr; + private String filterAtomNameTerminator = ";"; private boolean filterElement; protected boolean filterHetero; private boolean filterEveryNth; @@ -823,6 +824,12 @@ // Spartan: "INPUT", "ESPCHARGES" // + protected void setFilterAtomTypeStr(String s) { + // PDB reader TYPE=... + filterAtomTypeStr = s; + filterAtomNameTerminator = "\0"; + } + protected void setFilter(String filter0) { if (filter0 == null) { filter0 = (String) htParams.get("filter"); @@ -922,8 +929,7 @@ private boolean checkFilter(Atom atom, String f) { return (!filterGroup3 || atom.group3 == null || !filterReject(f, "[", atom.group3.toUpperCase() + "]")) - && (!filterAtomName || atom.atomName == null || !filterReject(f, ".", - atom.atomName.toUpperCase() + (filterAtomTypeStr == null ? ";" : "\0"))) + && (!filterAtomName || allowAtomName(atom.atomName, f)) && (filterAtomTypeStr == null || atom.atomName == null || atom.atomName.toUpperCase().indexOf("\0" + filterAtomTypeStr) >= 0) && (!filterElement || atom.elementSymbol == null || !filterReject(f, "_", @@ -936,6 +942,15 @@ atom.isHetero ? "HETATM" : "ATOM")); } + protected boolean rejectAtomName(String name) { + return filterAtomName && !allowAtomName(name, filter); + } + + private boolean allowAtomName(String atomName, String f) { + return (atomName == null || !filterReject(f, ".", + atomName.toUpperCase() + filterAtomNameTerminator)); + } + protected boolean filterReject(String f, String code, String atomCode) { return (f.indexOf(code) >= 0 && (f.indexOf("!" + code) >= 0 ? f .indexOf(code + atomCode) >= 0 : f.indexOf(code + atomCode) < 0)); Modified: trunk/Jmol/src/org/jmol/api/SymmetryInterface.java =================================================================== --- trunk/Jmol/src/org/jmol/api/SymmetryInterface.java 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/api/SymmetryInterface.java 2013-08-19 21:13:46 UTC (rev 18596) @@ -66,8 +66,6 @@ public Matrix4f getSpaceGroupOperation(int i); - public void getMod456Row(int iop, int irow, float[] f4); - public String getSpaceGroupXyz(int i, boolean doNormalize); public void newSpaceGroupPoint(int i, P3 atom1, P3 atom2, @@ -178,5 +176,7 @@ public void addLatticeVectors(JmolList<float[]> lattvecs); public boolean hasLatticeCentering(); + + public Matrix4f getOperationGammaIS(int iop); } Modified: trunk/Jmol/src/org/jmol/modelset/LabelToken.java =================================================================== --- trunk/Jmol/src/org/jmol/modelset/LabelToken.java 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/modelset/LabelToken.java 2013-08-19 21:13:46 UTC (rev 18596) @@ -342,6 +342,8 @@ private static int setToken(Viewer viewer, String strFormat, LabelToken lt, int cch, int chAtom, Map<String, Object> htValues) { int ich = lt.pt + 1; + if (ich >= cch) + return ich; char ch; if (strFormat.charAt(ich) == '-') { lt.alignLeft = true; Modified: trunk/Jmol/src/org/jmol/symmetry/Symmetry.java =================================================================== --- trunk/Jmol/src/org/jmol/symmetry/Symmetry.java 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/symmetry/Symmetry.java 2013-08-19 21:13:46 UTC (rev 18596) @@ -180,13 +180,6 @@ } - public void getMod456Row(int iop, int rowPt, float[] f4) { - spaceGroup.finalOperations[iop].getMod456Row(rowPt, f4); - } - - - - public String getSpaceGroupXyz(int i, boolean doNormalize) { return spaceGroup.finalOperations[i].getXyz(doNormalize); } @@ -656,4 +649,11 @@ return spaceGroup.hasLatticeCentering; } + public Matrix4f getOperationGammaIS(int iop) { + return spaceGroup.finalOperations[iop].gammaIS; + } + + + + } Modified: trunk/Jmol/src/org/jmol/symmetry/SymmetryOperation.java =================================================================== --- trunk/Jmol/src/org/jmol/symmetry/SymmetryOperation.java 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/symmetry/SymmetryOperation.java 2013-08-19 21:13:46 UTC (rev 18596) @@ -73,7 +73,7 @@ private String[] myLabels; int modDim; float[] rotTransMatrix; - public Matrix4f mod456; + Matrix4f gammaIS; /** @@ -113,7 +113,7 @@ } private void setMod456() { - (mod456 = new Matrix4f()).setA(rotTransMatrix, 16); + (gammaIS = new Matrix4f()).setA(rotTransMatrix, 16); } void doFinalize() { @@ -121,9 +121,9 @@ m13 /= 12; m23 /= 12; if (modDim > 0) { - mod456.m03 /= 12; - mod456.m13 /= 12; - mod456.m23 /= 12; + gammaIS.m03 /= 12; + gammaIS.m13 /= 12; + gammaIS.m23 /= 12; } isFinalized = true; } @@ -266,7 +266,7 @@ setA(rotTransMatrix, 0); if (rotTransMatrix.length == 32) { rotTransMatrix[31] = 1; - (mod456 = new Matrix4f()).setA(rotTransMatrix, 16); + (gammaIS = new Matrix4f()).setA(rotTransMatrix, 16); } isFinalized = true; if (isReverse) @@ -1315,8 +1315,4 @@ operation.m23 = ((int)operation.m23 + 12) % 12; } - public void getMod456Row(int rowPt, float[] f4) { - mod456.getRow(rowPt, f4); - } - } Modified: trunk/Jmol/src/org/jmol/thread/MoveToThread.java =================================================================== --- trunk/Jmol/src/org/jmol/thread/MoveToThread.java 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/thread/MoveToThread.java 2013-08-19 21:13:46 UTC (rev 18596) @@ -233,7 +233,7 @@ } private float getVal(Slider s) { - return (s == null ? Float.MAX_VALUE : s.getVal(fStep)); + return (s == null ? Float.NaN : s.getVal(fStep)); } @Override Modified: trunk/Jmol/src/org/jmol/util/Modulation.java =================================================================== --- trunk/Jmol/src/org/jmol/util/Modulation.java 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/util/Modulation.java 2013-08-19 21:13:46 UTC (rev 18596) @@ -13,14 +13,13 @@ private static final double TWOPI = 2 * Math.PI; - private int[] qCoefs; + private P3 qCoefs; private double a1; private double a2; private double center; private double left, right; - private int fn; // power private char axis; private final int type; @@ -40,17 +39,15 @@ * * @param axis * @param type - * @param fn * @param params * @param utens TODO * @param qCoefs */ - public Modulation(char axis, int type, int fn, P3 params, String utens, int[] qCoefs) { + public Modulation(char axis, int type, P3 params, String utens, P3 qCoefs) { if (Logger.debuggingHigh) - Logger.debug("MOD create " + Escape.eAI(qCoefs) + " axis=" + axis + " type=" + type + " fn=" + fn + " params=" + params + " utens=" + utens); + Logger.debug("MOD create " + Escape.eP(qCoefs) + " axis=" + axis + " type=" + type + " params=" + params + " utens=" + utens); this.axis = axis; this.type = type; - this.fn = fn; this.utens = utens; this.qCoefs = qCoefs; switch (type) { @@ -75,7 +72,7 @@ right -= 1; if (left >= right && left - right < 0.01f) left = right + 0.01f; - a1 = 2 * params.z / width; + a1 = 2 * params.z / params.y; break; } } @@ -88,28 +85,64 @@ * * where axis is x, y, or z, and theta = 2n pi x * - * @param i + * More generally, we have for a given rotation that is characterized by + * + * X {x4 x5 x6 ...} + * + * Gamma_E (R3 rotation) + * + * Gamma_I (X rotation) + * + * S_I (X translation) + * + * We allow here only up to x6, simply because we are using standard R3 + * rotation objects Matrix3f, P3, V3. + * + * We desire: + * + * u'(X') = Gamma_E u(X) + * + * which is defined as [private communication, Vaclav Petricek]: + * + * u'(X') = Gamma_E sum[ U_c cos(2 pi (n m).Gamma_I^-1{X - S_I}) + U_s sin(2 + * pi (n m).Gamma_I^-1{X - S_I}) ] + * + * where + * + * U_c and U_s are coefficients for cos and sin, respectively (will be a1 and + * a2 here) + * + * (n m) is an array of Fourier number coefficients, such as (1 0), (1 -1), or + * (0 2) + * + * Offset here is only for d=1 case. + * + * + * * @param ms - * @param x4 + * @param offset * + * */ - void apply(int i, ModulationSet ms, double x4) { + void apply(ModulationSet ms, double offset) { + double x = qCoefs.dot(ms.x456) + qCoefs.x * offset; double v = 0; //if (type == TYPE_OCC_CRENEL) //delta = 0; - + switch (type) { case TYPE_DISP_FOURIER: case TYPE_OCC_FOURIER: case TYPE_U_FOURIER: - double theta = TWOPI * fn * x4; + double theta = TWOPI * x; if (a1 != 0) v += a1 * Math.cos(theta); if (a2 != 0) v += a2 * Math.sin(theta); if (Logger.debuggingHigh) - Logger.debug("MOD " + i + ":" + ms.id + " fn=" + fn + " " + " axis=" + axis + " v=" + v + " ccos,csin=" + a1 + "," + a2 + " / theta=" + theta); + Logger.debug("MOD " + ms.id + " " + Escape.eP(qCoefs) + " axis=" + axis + + " v=" + v + " ccos,csin=" + a1 + "," + a2 + " / theta=" + theta); break; case TYPE_OCC_CRENEL: @@ -119,8 +152,8 @@ // p(x4)=1 if x4 belongs to the interval [c-w/2,c+w/2] // p(x4)=0 if x4 is outside the interval [c-w/2,c+w/2], - x4 -= Math.floor(x4); - ms.vocc = (range(x4) ? 1 : 0); + x -= Math.floor(x); + ms.vocc = (range(x) ? 1 : 0); ms.vocc0 = Float.NaN; // don't add this in //System.out.println("MOD " + ms.r + " " + ms.delta + " " + ms.epsilon + " " + ms.id + " " + ms.v + " l=" + left + " x=" + x4 + " r=" + right); return; @@ -140,8 +173,8 @@ // here we have set a1 = 2a_xyz/w - x4 -= Math.floor(x4); - if (!range(x4)) + x -= Math.floor(x); + if (!range(x)) return; // x < L < c @@ -193,12 +226,12 @@ // |/ if (left > right) { - if (x4 < left && left < center) - x4 += 1; - else if (x4 > right && right > center) - x4 -= 1; + if (x < left && left < center) + x += 1; + else if (x > right && right > center) + x -= 1; } - v = a1 * (x4 - center); + v = a1 * (x - center); break; } @@ -213,7 +246,7 @@ ms.z += v; break; case 'U': - ms.addUTens(utens, (float) v, fn); + ms.addUTens(utens, (float) v); break; default: if (Float.isNaN(ms.vocc)) @@ -234,25 +267,4 @@ || x4 <= right); } - /** just guessing here.... - * - * @param aq - * @param q - * @return pointer to last-used index - */ - int getQ(P3[] aq, P3 q) { - q.set(0, 0, 0); - int eq = 0; - fn = 0; - for (int i = 0; i < aq.length; i++) { - q.scaleAdd2(qCoefs[i], aq[i], q); - if (qCoefs[i] != 0) { - eq = i; - fn+= Math.abs(qCoefs[i]); - } - } - q.scale(1f/fn); - return eq; - } - } Modified: trunk/Jmol/src/org/jmol/util/ModulationSet.java =================================================================== --- trunk/Jmol/src/org/jmol/util/ModulationSet.java 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/util/ModulationSet.java 2013-08-19 21:13:46 UTC (rev 18596) @@ -13,149 +13,92 @@ public class ModulationSet extends Vibration { - public JmolList<Modulation> mods; - public float[] epsilon; - public float[] delta; - public int[] t = new int[3]; - - public P3[] q123; - public double[] qlen; - private int modDim; - public P3 r; - public Matrix3f rot; - public float vdisp = Float.NaN; public float vocc = Float.NaN; - public float vocc0 = Float.NaN; - public Map<String, Float> htValues; + public Map<String, Float> htUij; public boolean enabled = false; public String id; - public V3 prevSetting; - public ModulationSet(String id, JmolList<Modulation> list, int modDim, P3[] q123, double[] qlen) { - this.id = id; - mods = list; - this.modDim = modDim; - this.q123 = q123; - this.qlen = qlen; - } + float vocc0 = Float.NaN; + private JmolList<Modulation> mods; + private Matrix3f gammaE; + private int t = Integer.MAX_VALUE; + private double[] qlen; + + int modDim; + V3 x456; + /** - * Determine the overall modulation. + * A collection of modulations for a specific atom. * - * For symmetry-related atoms, we need to do a 4D transformation, not just a - * 3D one. We need to operate on x first BEFORE applying u(x): + * @param id + * @param r + * @param vocc0 + * @param modDim + * @param mods + * @param gammaE + * @param gammaIS + * @param q123 + * @param qlen * - * u(x4') = Ru(x4) * - * where we need to express x4 in terms of a "transformed" x4', because x4' is - * for our rotated point. - * - * x4' = epsilon x4 + delta - * - * where epsilon = +/-1, so - * - * x4 = (x4' - delta) / epsilon = epsilon (x4' - delta) - * - * More generally, we might have something like: - * - * x4' = x5 + 1/2; x5' = x4 - 1/2 - * - * so in those cases, we have to use the proper q. - * - * */ - public void calculate() { - // Q: What about x4,x5 exchange? - set(0, 0, 0); - htValues = null; - vdisp = vocc = Float.NaN; - P3[] aq = new P3[modDim]; + + public ModulationSet(String id, P3 r, float vocc0, int modDim, + JmolList<Modulation> mods, Matrix3f gammaE, Matrix4f gammaIS, P3[] q123, double[] qlen) { + this.id = id; + this.vocc0 = vocc0; + this.modDim = modDim; + this.mods = mods; - for (int iq = 0; iq < modDim; iq++) { - int eps = (int) epsilon[iq]; - if (eps == 0) - continue; - int qpt = (Math.abs(eps) - 1); - aq[iq] = q123[qpt]; - } - P3 q = new P3(); - int jmax = 1; - for (int j = 0;j < modDim; j++) { - // testing hypothesis that either one should work... - // checks out for (0,1) (1,0), but not (1,1) - if (j == jmax)continue; - - for (int i = mods.size(); --i >= 0;) { + // set up x456 + + this.gammaE = gammaE; + Matrix3f gammaIinv = new Matrix3f(); + gammaIS.getRotationScale(gammaIinv); + V3 sI = new V3(); + + gammaIS.get(sI); + gammaIinv.invert(); + x456 = V3.new3(q123[0].dot(r), q123[1].dot(r), q123[2].dot(r)); + x456.sub(sI); + gammaIinv.transform(x456); + if (Logger.debuggingHigh) + Logger.debug("MODSET create r=" + Escape.eP(r) + " q0=" + Escape.eP(q123[0]) + + " si=" + Escape.eP(sI) + " ginv=" + gammaIinv.toString().replace('\n',' ') + " x4=" + x456.x); - int iq = mods.get(i).getQ(aq, q); - int eps = (int) epsilon[iq]; - eps = (eps > 0 ? 1 : -1); - //int qpt = (Math.abs(eps) - 1); + // temporary only - only for d=1: + this.qlen = qlen; + + } - - double x4 = eps * (q.dot(r) - delta[iq] + qlen[iq] * t[iq]); - System.out.println("MODSET q=" + q + " r=" + r - + " epsilon=" + eps + " delta=" + delta[iq] + " t=" + t[iq] - + " x4=" + x4); - - // here we are using the original specification for the function. - // F2 = "(0)q1 + (1)q2" - // even though we have switched q1 and q2 - mods.get(i).apply(i, this, x4); - } - } - rot.transform(this); + public void calculate() { + x = y = z = 0; + htUij = null; + vocc = Float.NaN; + double offset = (t == Integer.MAX_VALUE ? 0 : qlen[0] * t); + for (int i = mods.size(); --i >= 0;) + mods.get(i).apply(this, offset); + gammaE.transform(this); } -// http://nanocrystallography.research.pdx.edu/static/mcodcif/4/33/14/4331458.cif - -// _space_group_ssg_name_WJJ P-42_1m(a,a,0)00s(-a,a,0)000 -// loop_ -// _space_group_symop_ssg_id -// _space_group_symop_ssg_operation_algebraic -// 1 x1,x2,x3,x4,x5 -// 2 -x1,-x2,x3,-x4,-x5 -// 3 x2,-x1,-x3,x5,-x4 -// 4 -x2,x1,-x3,-x5,x4 -// 5 -x1+1/2,x2+1/2,-x3,x5+1/2,x4+1/2 -// 6 x1+1/2,-x2+1/2,-x3,-x5+1/2,-x4+1/2 -// 7 -x2+1/2,-x1+1/2,x3,-x4+1/2,x5+1/2 -// 8 x2+1/2,x1+1/2,x3,x4+1/2,-x5+1/2 - -// _cell_wave_vector_seq_id -// _cell_wave_vector_x -// _cell_wave_vector_y -// _cell_wave_vector_z -// 1 0.216050 0.216050 0.000000 -// 2 -0.216050 0.216050 0.000000 - -// loop_ -// _atom_site_Fourier_wave_vector_seq_id -// _jana_atom_site_fourier_wave_vector_q1_coeff -// _jana_atom_site_fourier_wave_vector_q2_coeff -// 1 1 0 -// 2 0 1 -// 3 1 1 -// 4 -1 1 -// 5 2 0 -// 6 0 2 - - public void addUTens(String utens, float v, int n) { - if (htValues == null) - htValues = new Hashtable<String, Float>(); - Float f = htValues.get(utens); + public void addUTens(String utens, float v) { + if (htUij == null) + htUij = new Hashtable<String, Float>(); + Float f = htUij.get(utens); if (Logger.debuggingHigh) - Logger.debug("MODSET " + id + " n=" + n + " utens=" + utens + " f=" + f + " v="+ v); + Logger.debug("MODSET " + id + " utens=" + utens + " f=" + f + " v="+ v); if(f != null) v += f.floatValue(); - htValues.put(utens, Float.valueOf(v)); + htUij.put(utens, Float.valueOf(v)); } /** - * Set modulation "t" value, which sets which unit cell in sequence we are looking at. + * Set modulation "t" value, which sets which unit cell + * in sequence we are looking at; d=1 only. * * @param isOn * @param t @@ -170,15 +113,19 @@ scale(-1); return (enabled ? 2 : 1); } - if (t == this.t[0]) + if (modDim > 1 || t == this.t) return 4; if (prevSetting == null) prevSetting = new V3(); prevSetting.setT(this); - this.t[0] = t; + this.t = t; calculate(); enabled = false; return 3; } + public String getState() { + return "modulation " + (!enabled ? "OFF" : t == Integer.MAX_VALUE ? "ON" : "" + t); + } + } Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2013-08-19 21:13:46 UTC (rev 18596) @@ -11,8 +11,12 @@ # The quotes above look odd for a parameter file, but they are # important for the JavaScript version of Jmol. -___JmolVersion="13.3.4_dev_2013.08.18" +___JmolVersion="13.3.4_dev_2013.08.19" +code: Incommensurate modulated structure CIF and M50/40 file loading validation + -- includes d=1 and d=2 + -- Fourier, sawtooth, crenel + bug fix: translation not read from state new feature: set platformSpeed [0 to 10] Modified: trunk/Jmol/src/org/jmol/viewer/StateCreator.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/StateCreator.java 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/viewer/StateCreator.java 2013-08-19 21:13:46 UTC (rev 18596) @@ -365,8 +365,9 @@ if ((ivib = viewer.modelGetLastVibrationIndex(i, T.modulation)) >= 0) for (int j = models[i].firstAtomIndex; j <= ivib; j++) { ModulationSet mset = (ModulationSet) viewer.getVibration(j); - if (mset != null && mset.enabled) - BSUtil.setMapBitSet(temp, j, j, "modulation " + mset.t[0]); + if (mset != null && mset.enabled) { + BSUtil.setMapBitSet(temp, j, j, mset.getState()); + } } } String s = getCommands(temp, null, "select"); Modified: trunk/Jmol/src/org/jmol/viewer/TransformManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/TransformManager.java 2013-08-19 04:39:18 UTC (rev 18595) +++ trunk/Jmol/src/org/jmol/viewer/TransformManager.java 2013-08-19 21:13:46 UTC (rev 18596) @@ -1708,15 +1708,15 @@ matrixEnd.setAA(aaMoveTo); } } - if (Float.isNaN(cameraX) || cameraX == cameraSetting.x) - cameraX = Float.MAX_VALUE; - if (Float.isNaN(cameraY) || cameraY == cameraSetting.y) - cameraY = Float.MAX_VALUE; + if (cameraX == cameraSetting.x) + cameraX = Float.NaN; + if (cameraY == cameraSetting.y) + cameraY = Float.NaN; if (cameraDepth == this.cameraDepth) - cameraDepth = Float.MAX_VALUE; - if (cameraX != Float.MAX_VALUE) + cameraDepth = Float.NaN; + if (!Float.isNaN(cameraX)) xTrans = cameraX * 50 / newRotationRadius / width * screenPixelCount; - if (cameraY != Float.MAX_VALUE) + if (!Float.isNaN(cameraY)) yTrans = cameraY * 50 / newRotationRadius / height * screenPixelCount; float pixelScale = (center == null ? scaleDefaultPixelsPerAngstrom : defaultScaleToScreen(newRotationRadius)); @@ -2760,21 +2760,23 @@ moveRotationCenter(center, !windowCentered); if (navCenter != null && mode == MODE_NAVIGATION) navigationCenter.setT(navCenter); - if (cameraDepth != Float.MAX_VALUE) + if (!Float.isNaN(cameraDepth)) setCameraDepthPercent(cameraDepth, false); - if (cameraX != Float.MAX_VALUE && cameraY != Float.MAX_VALUE) + if (!Float.isNaN(cameraX) && !Float.isNaN(cameraY)) setCamera(cameraX, cameraY); - if (zoom != Float.MAX_VALUE) + if (!Float.isNaN(zoom)) zoomToPercent(zoom); - modelRadius = rotationRadius; - scaleDefaultPixelsPerAngstrom = pixelScale; - if (xTrans != Float.MAX_VALUE && yTrans != Float.MAX_VALUE) { + if (!Float.isNaN(rotationRadius)) + modelRadius = rotationRadius; + if (!Float.isNaN(pixelScale)) + scaleDefaultPixelsPerAngstrom = pixelScale; + if (!Float.isNaN(xTrans) && !Float.isNaN(yTrans)) { translateToPercent('x', xTrans); translateToPercent('y', yTrans); } - if (xNav != Float.MAX_VALUE && yNav != Float.MAX_VALUE) + if (!Float.isNaN(xNav) && !Float.isNaN(yNav)) navTranslatePercentOrTo(0, xNav, yNav); - if (navDepth != Float.MAX_VALUE) + if (!Float.isNaN(navDepth)) setNavigationDepthPercent(navDepth); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Introducing Performance Central, a new site from SourceForge and AppDynamics. Performance Central is your source for news, insights, analysis and resources for efficient Application Performance Management. Visit us today! http://pubads.g.doubleclick.net/gampad/clk?id=48897511&iu=/4140/ostg.clktrk _______________________________________________ Jmol-commits mailing list Jmol-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jmol-commits