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

Reply via email to