Revision: 18528 http://sourceforge.net/p/jmol/code/18528 Author: hansonr Date: 2013-08-08 14:09:49 +0000 (Thu, 08 Aug 2013) Log Message: ----------- ___JmolVersion="13.3.4_dev_2013.08.08"
code: incommensurate crystal work Modified Paths: -------------- trunk/Jmol/src/org/jmol/adapter/readers/cif/ModulationReader.java trunk/Jmol/src/org/jmol/adapter/readers/xtal/JanaReader.java trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java trunk/Jmol/src/org/jmol/api/SymmetryInterface.java trunk/Jmol/src/org/jmol/util/Measure.java trunk/Jmol/src/org/jmol/util/Modulation.java trunk/Jmol/src/org/jmol/util/Tuple3f.java trunk/Jmol/src/org/jmol/util/V3.java trunk/Jmol/src/org/jmol/viewer/Jmol.properties Modified: trunk/Jmol/src/org/jmol/adapter/readers/cif/ModulationReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/cif/ModulationReader.java 2013-08-08 11:06:19 UTC (rev 18527) +++ trunk/Jmol/src/org/jmol/adapter/readers/cif/ModulationReader.java 2013-08-08 14:09:49 UTC (rev 18528) @@ -32,7 +32,6 @@ import org.jmol.util.Logger; import org.jmol.util.Matrix3f; -import org.jmol.util.Matrix4f; import org.jmol.util.Modulation; import org.jmol.util.P3; import org.jmol.util.SB; @@ -42,6 +41,11 @@ /** * abstract modulation class for CIF and Jana + * + * Current status: + * + * -- d=1 only + * -- only simple atom displacement, no occupation crenel, no sawtooth * * @author Bob Hanson hans...@stolaf.edu 8/7/13 * @@ -54,12 +58,15 @@ protected boolean modAverage; protected boolean checkSpecial = true; protected int modDim; - //protected boolean modCentered; - //protected boolean modOffset; protected boolean incommensurate; - private Map<String, P3> htModulation; protected Atom[] atoms; + private JmolList<float[]> lattvecs; + private V3 modT; + private Matrix3f rot; + private Map<String, P3> htModulation; + private Map<String, JmolList<Modulation>> htAtomMods; + protected void initializeMod() throws Exception { modAxes = getFilter("MODAXES="); modVib = checkFilterKey("MODVIB"); @@ -67,16 +74,8 @@ checkSpecial = !checkFilterKey("NOSPECIAL"); atomSetCollection.setCheckSpecial(checkSpecial); allowRotations = !checkFilterKey("NOSYM"); - //modOffset = !checkFilterKey("NOMODOFFSET"); - //modCentered = !checkFilterKey("NOMODCENT"); - //if (!modCentered) { - // if (doCentralize && filter.indexOf("CENTER") == filter.lastIndexOf("CENTER")) - // doCentralize = false; - // appendLoadNote("CIF reader not using delta to recenter modulation."); - // } } - private JmolList<float[]> lattvecs; protected void addLatticeVector(String data) { if (lattvecs == null) @@ -124,8 +123,13 @@ map = htModulation; map.put(id, pt); Logger.info("Adding " + id + " " + pt); - if (id.charAt(0) == 'W' || id.charAt(0) == 'F') - appendLoadNote("Wave vector " + id +" = " + pt); + if (id.charAt(0) == 'W' || id.charAt(0) == 'F') { + appendLoadNote("Wave vector " + id +" = " + pt); + if (id.equals("W_1")) { + modT = V3.newV(pt); + modT.normalize(); + } + } } /** @@ -185,12 +189,19 @@ if (key.charAt(2) == 'S') { // TODO -- sawtooth, so now what? } else { + if (htAtomMods == null) + htAtomMods = new Hashtable<String, JmolList<Modulation>>(); P3 coefs = e.getValue(); String label = key.substring(key.indexOf(";") + 1); int n = key.charAt(2) - '0'; key = "F_" + n; - P3 q = htModulation.get(key); - addAtomModulation(label, q, axis, coefs, n); + //TODO -- THIS IS WRONG. n is just a label. It will break in 2D + // but I don't know to determine "n" any other way in a CIF file. + P3 nq = htModulation.get(key); + JmolList<Modulation> list = htAtomMods.get(label); + if (list == null) + htAtomMods.put(label, list = new JmolList<Modulation>()); + list.addLast(new Modulation(nq, n, axis, coefs)); haveAtomMods = true; } break; @@ -200,94 +211,53 @@ return; atoms = atomSetCollection.getAtoms(); symmetry = atomSetCollection.getSymmetry(); - mtemp3 = new Matrix3f(); - //mtemp3i = new Matrix3f(); - ptemp = new P3(); - offset = new V3(); - //opTrans = new V3(); - // step one: All base atoms. - int n = atomSetCollection.baseSymmetryAtomCount; - P3[] pts = new P3[n]; + rot = new Matrix3f(); SB sb = new SB(); - for (int i = 0; i < n; i++) { - pts[i] = P3.newP(atoms[i]); - modulateAtom(i, modVib, null, sb); - } - // step two: All other atoms. - int n1 = atomSetCollection.getAtomCount(); - for (int i = n1; --i >= n;) - modulateAtom(i, modVib, pts[atoms[i].atomSite], sb); + int n = atomSetCollection.getAtomCount(); + for (int i = 0; i < n; i++) + modulateAtom(atoms[i], sb); atomSetCollection.setAtomSetAtomProperty("modt", sb.toString(), -1); } - private Matrix3f mtemp3; - private P3 ptemp; - private V3 offset; - private Map<String, JmolList<Modulation>> htAtomMods; - - public void addAtomModulation(String label, P3 q, char axis, P3 coefs, int n) { - if (htAtomMods == null) - htAtomMods = new Hashtable<String, JmolList<Modulation>>(); - JmolList<Modulation> list = htAtomMods.get(label); - if (list == null) - htAtomMods.put(label, list = new JmolList<Modulation>()); - list.addLast(new Modulation(q, n, axis, coefs)); - } - - private V3 qNorm; - /** - * Modulation generally involves u(x4) = u(q.r + t). Here we arbitrarily set t - * = 0, making this u(x4) = u(q.r). For symmetry- related atoms, including - * lattice shifts, we need to apply this as: - * - * u'(x4') = R'u(q.r + q.s') - * - * where s' is the sum of all shifts, and R' is the product of all rotations. - * We already track symmetry, so we should be able to figure this out. - * - * @param i - * @param modvib - * @param pt0 + * Modulation generally involves x4 = q.r + t. Here we arbitrarily set t = 0, + * but t could be a FILTER option MODT=n. There would need to be one t per dimension. + * The displacement will be set as the atom vibration vector. + * + * @param a * @param sb */ - public void modulateAtom(int i, boolean modvib, P3 pt0, SB sb) { - Atom a = atoms[i]; - a.vib = new V3(); + public void modulateAtom(Atom a, SB sb) { JmolList<Modulation> list = htAtomMods.get(a.atomName); - if (list == null || symmetry == null) + if (list == null || symmetry == null || a.bsSymmetry == null) return; - // if (pt0 != null) { int iop = a.bsSymmetry.nextSetBit(0); if (iop < 0) iop = 0; - Matrix4f m = symmetry.getSpaceGroupOperation(iop); - m.getRotationScale(mtemp3); - //mtemp3i.invertM(mtemp3); - //opTrans = symmetry.getOriginalTranslation(iop); - //m.get(opTrans); float epsilon = symmetry.getModParam(iop, 0); float delta = symmetry.getModParam(iop, 1); - ptemp.setT(a); - symmetry.unitize(ptemp); - offset.sub2(a, ptemp); - //System.out.println("=========CIF i=" + i + " " + a.atomName + " " + a); - //System.out.println("op=" + (iop + 1) + " " - // + symmetry.getSpaceGroupXyz(iop, false) + " ep=" + epsilon + " de=" - //+ delta + " a=" + a); - qNorm = V3.newV(list.get(0).getWaveVector()); - qNorm.normalize(); - Modulation.modulateAtom(ptemp, offset, list, epsilon, delta, a.vib); - System.out.println("a.vib(abc)=" + a.vib); - mtemp3.transform(a.vib); - sb.append((int) (qNorm.dot(offset) * 1.01f) + "\n"); - if (!modvib) { + symmetry.getSpaceGroupOperation(iop).getRotationScale(rot); + a.vib = new V3(); + Modulation.modulateAtom(list, a, epsilon, delta, rot, a.vib); + //System.out.println("=========MR i=" + i + " " + a.atomName + " " + a); + //System.out.println("op=" + (iop + 1) + " " + symmetry.getSpaceGroupXyz(iop, false) + " ep=" + epsilon + " de=" + delta); + //System.out.println("a.vib(abc)=" + a.vib); + + // set property_modT to be Math.floor (q.r/|q|) -- really only for d=1 + + float t = modT.dot(a); + if (Math.abs(t - (int) t) > 0.001f) + t = (int) Math.floor(t); + sb.append(((int) t) + "\n"); + + // displace the atom if not filter "MODVIB" + if (!modVib) { a.add(a.vib); a.vib.scale(-1); } symmetry.toCartesian(a.vib, true); //System.out.println("a.vib(xyz)=" + a.vib); - //if (i == 98 || i == 99) - //System.out.println("CIFTEST"); + } + } Modified: trunk/Jmol/src/org/jmol/adapter/readers/xtal/JanaReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/xtal/JanaReader.java 2013-08-08 11:06:19 UTC (rev 18527) +++ trunk/Jmol/src/org/jmol/adapter/readers/xtal/JanaReader.java 2013-08-08 14:09:49 UTC (rev 18528) @@ -197,8 +197,10 @@ private int qicount; private void qi() { - addModulation(null, "F_" + (++qicount), P3.new3(parseFloat(), - parseFloat(), parseFloat())); + P3 pt = P3.new3(parseFloat(), parseFloat(), parseFloat()); + if (qicount == 0) + addModulation(null, "W_1", pt); + addModulation(null, "F_" + (++qicount), pt); } private void ndim() { Modified: trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java 2013-08-08 11:06:19 UTC (rev 18527) +++ trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java 2013-08-08 14:09:49 UTC (rev 18528) @@ -473,7 +473,6 @@ atomSetNumbers = new int[16]; atomSymbolicMap = new Hashtable<Object, Integer>(); bonds = null; - cartesians = null; connectLast = null; currentAtomSetIndex = -1; latticeCells = null; @@ -1139,7 +1138,7 @@ : symmetryRange < 0 ? 1 // checking against symop=1555 set; just a box : 1 // not checking ); - cartesians = new P3[cartesianCount]; + P3[] cartesians = new P3[cartesianCount]; for (int i = 0; i < noSymmetryCount; i++) atoms[i + iAtomFirst].bsSymmetry = BSUtil.newBitSet(operationCount * (nCells + 1)); @@ -1197,7 +1196,7 @@ rmaxz += absRange; } cell555Count = pt = symmetryAddAtoms(iAtomFirst, noSymmetryCount, 0, - 0, 0, 0, pt, iCell * operationCount); + 0, 0, 0, pt, iCell * operationCount, cartesians); } if (checkRange111) { rminx -= absRange; @@ -1217,7 +1216,7 @@ iCell++; if (tx != 0 || ty != 0 || tz != 0) pt = symmetryAddAtoms(iAtomFirst, noSymmetryCount, tx, ty, tz, - cell555Count, pt, iCell * operationCount); + cell555Count, pt, iCell * operationCount, cartesians); } if (iCell * noSymmetryCount == atomCount - iAtomFirst) appendAtomProperties(iCell); @@ -1256,7 +1255,6 @@ setAtomSetAuxiliaryInfo("symmetryCount", Integer.valueOf(operationCount)); } - private P3[] cartesians; private int bondCount0; private int bondIndex0; private boolean applySymmetryToBonds = false; @@ -1272,7 +1270,7 @@ private int symmetryAddAtoms(int iAtomFirst, int noSymmetryCount, int transX, int transY, int transZ, int baseCount, int pt, - int iCellOpPt) throws Exception { + int iCellOpPt, P3[] cartesians) throws Exception { boolean isBaseCell = (baseCount == 0); boolean addBonds = (bondCount0 > bondIndex0 && applySymmetryToBonds); int[] atomMap = (addBonds ? new int[noSymmetryCount] : null); Modified: trunk/Jmol/src/org/jmol/api/SymmetryInterface.java =================================================================== --- trunk/Jmol/src/org/jmol/api/SymmetryInterface.java 2013-08-08 11:06:19 UTC (rev 18527) +++ trunk/Jmol/src/org/jmol/api/SymmetryInterface.java 2013-08-08 14:09:49 UTC (rev 18528) @@ -11,7 +11,6 @@ import org.jmol.util.Matrix4f; import org.jmol.util.P3; import org.jmol.util.P3i; -import org.jmol.util.P4; import org.jmol.util.Tensor; import org.jmol.util.Tuple3f; import org.jmol.util.V3; Modified: trunk/Jmol/src/org/jmol/util/Measure.java =================================================================== --- trunk/Jmol/src/org/jmol/util/Measure.java 2013-08-08 11:06:19 UTC (rev 18527) +++ trunk/Jmol/src/org/jmol/util/Measure.java 2013-08-08 14:09:49 UTC (rev 18528) @@ -199,7 +199,7 @@ } public static void getPlaneThroughPoint(P3 pt, V3 normal, P4 plane) { - plane.set(normal.x, normal.y, normal.z, -normal.dot(V3.newV(pt))); + plane.set(normal.x, normal.y, normal.z, -normal.dot(pt)); } public static float distanceToPlane(P4 plane, P3 pt) { Modified: trunk/Jmol/src/org/jmol/util/Modulation.java =================================================================== --- trunk/Jmol/src/org/jmol/util/Modulation.java 2013-08-08 11:06:19 UTC (rev 18527) +++ trunk/Jmol/src/org/jmol/util/Modulation.java 2013-08-08 14:09:49 UTC (rev 18528) @@ -14,25 +14,28 @@ private double ccos; private double csin; - private V3 q; // wave vector + private V3 nq; // wave vector private int n; // power + private char axis; + public V3 getWaveVector() { - return q; + return nq; } - private char axis; - + /** - * Each atomic modulation involves a fractional coordinate wave vector q, - * a modulation axis (x, y, or, z), and specified coefficients for cos and sin. + * Each atomic modulation involves a fractional coordinate wave vector q, a + * Fourier power n, a modulation axis (x, y, or, z), and specified + * coefficients for cos and sin. * - * @param q + * + * @param nq * @param n * @param axis * @param coefs */ - public Modulation(P3 q, int n, char axis, P3 coefs) { - this.q = V3.newV(q); + public Modulation(P3 nq, int n, char axis, P3 coefs) { + this.nq = V3.newV(nq); //this.q.scale(1f/n); leave this nq. this.n = n; this.axis = axis; @@ -41,34 +44,62 @@ } /** - * Starting with fractional coordinates, determine the overall modulation vector. + * Starting with fractional coordinates, determine the overall modulation displacement. * - * @param pt fractional xyz - * @param offset - * @param mods a given atom's modulations - * @param epsilon TODO - * @param delta TODO - * @param vecMod will be filled; + * @param mods a given atom's modulations + * @param r fractional xyz + * @param epsilon as in x4´ = epsilon x4 + delta + * @param delta as in x4´ = epsilon x4 + delta + * @param rot symmetry rotation to be applied + * @param d displacement return */ - public static void modulateAtom(P3 pt, V3 offset, JmolList<Modulation> mods, float epsilon, float delta, V3 vecMod) { - V3 r = V3.newV(pt); - if (offset != null && offset.length() > 0.0001f) - r.add(offset); - vecMod.set(0, 0, 0); + public static void modulateAtom(JmolList<Modulation> mods, Tuple3f r, float epsilon, float delta, Matrix3f rot, V3 d) { + d.set(0, 0, 0); for (int i = mods.size(); --i >= 0;) - mods.get(i).addTo(r, epsilon, delta, vecMod); + mods.get(i).apply(r, epsilon, delta, d); + rot.transform(d); } /** + * + * In general, we have: + * + * u_axis(x) = sum[A1 cos(theta) + B1 sin(theta)] + * + * where axis is x, y, or z, and theta = 2n pi x + * + * However, 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): + * + * 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 = epsilon (x4' - delta) + * + * More generally, we might have something like: + * + * x4' = x5 + 1/2; x5' = x4 - 1/2 + * + * Will have to work on that later! + * + * * @param r * @param epsilon * @param delta * @param vecMod * */ - private void addTo(V3 r, float epsilon, float delta, V3 vecMod) { - // pt[axis]' = pt[axis] + A1 cos(2pi * q.r) + B1 sin(2pi * q.r) - double theta = TWOPI * (epsilon * q.dot(r) + n * delta); + private void apply(Tuple3f r, float epsilon, float delta, V3 vecMod) { + + // TODO: must be adapted for d > 1 modulation + + double theta = TWOPI * (epsilon * (nq.dot(r) + n * delta)); double v = 0; if (ccos != 0) v += ccos * Math.cos(theta); @@ -85,6 +116,7 @@ vecMod.z += v; break; } - System.out.println("MOD q=" + q + " r=" + r + " axis=" + axis + " theta=" + theta + " ccos=" + ccos + " csin=" + csin + " delta=" + delta + " v=" + v); + //System.out.println("MOD q=" + nq + " r=" + r + " axis=" + axis + " theta=" + theta + " ccos=" + ccos + " csin=" + csin + " delta=" + delta + " v=" + v); } + } Modified: trunk/Jmol/src/org/jmol/util/Tuple3f.java =================================================================== --- trunk/Jmol/src/org/jmol/util/Tuple3f.java 2013-08-08 11:06:19 UTC (rev 18527) +++ trunk/Jmol/src/org/jmol/util/Tuple3f.java 2013-08-08 14:09:49 UTC (rev 18528) @@ -188,6 +188,17 @@ y = s * y + t1.y; z = s * z + t1.z; } + + /** + * Was in Vector3f; more useful here, though. + * + * @param v + * the other vector + * @return this.dot.v + */ + public final float dot(Tuple3f v) { + return x * v.x + y * v.y + z * v.z; + } /** * Returns a hash number based on the data values in this object. Two Modified: trunk/Jmol/src/org/jmol/util/V3.java =================================================================== --- trunk/Jmol/src/org/jmol/util/V3.java 2013-08-08 11:06:19 UTC (rev 18527) +++ trunk/Jmol/src/org/jmol/util/V3.java 2013-08-08 14:09:49 UTC (rev 18528) @@ -80,17 +80,6 @@ } /** - * Computes the dot product of the this vector and vector v. - * - * @param v - * the other vector - * @return this.dot.v - */ - public final float dot(V3 v) { - return x * v.x + y * v.y + z * v.z; - } - - /** * Normalizes this vector in place. */ public final void normalize() { Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2013-08-08 11:06:19 UTC (rev 18527) +++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2013-08-08 14:09:49 UTC (rev 18528) @@ -11,8 +11,10 @@ # 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.07" +___JmolVersion="13.3.4_dev_2013.08.08" +code: incommensurate crystal work + bug fix: shapeInfo not reporting visibility of isosurface code: pdb, cif readers separated into separate packages; p2n, pqr readers with pdb now This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Get 100% visibility into Java/.NET code with AppDynamics Lite! It's a free troubleshooting tool designed for production. Get down to code-level detail for bottlenecks, with <2% overhead. Download for free and get started troubleshooting in minutes. http://pubads.g.doubleclick.net/gampad/clk?id=48897031&iu=/4140/ostg.clktrk _______________________________________________ Jmol-commits mailing list Jmol-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jmol-commits