Revision: 18382
          http://sourceforge.net/p/jmol/code/18382
Author:   hansonr
Date:     2013-06-30 07:21:27 +0000 (Sun, 30 Jun 2013)
Log Message:
-----------
Tensor Javadoc and code clean-up

Modified Paths:
--------------
    trunk/Jmol/src/org/jmol/adapter/readers/cifpdb/PdbReader.java
    trunk/Jmol/src/org/jmol/modelset/AtomCollection.java
    trunk/Jmol/src/org/jmol/shapespecial/Ellipsoids.java
    trunk/Jmol/src/org/jmol/symmetry/UnitCell.java
    trunk/Jmol/src/org/jmol/util/Tensor.java

Modified: trunk/Jmol/src/org/jmol/adapter/readers/cifpdb/PdbReader.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/readers/cifpdb/PdbReader.java       
2013-06-29 23:32:44 UTC (rev 18381)
+++ trunk/Jmol/src/org/jmol/adapter/readers/cifpdb/PdbReader.java       
2013-06-30 07:21:27 UTC (rev 18382)
@@ -59,6 +59,11 @@
  * see http://repo.or.cz/w/gromacs.git/blob/HEAD:/src/gmxlib/pdbio.c line 244
  * see http://repo.or.cz/w/gromacs.git/blob/HEAD:/src/gmxlib/pdbio.c line 323
  * 
+ * TLS Motion Determination:
+ *  
+ *    J Painter & E A Merritt (2006) Acta Cryst. D62, 439-450 
+ *    http://skuld.bmsc.washington.edu/~tlsmd
+ *    
  * symmetry added by Bob Hanson:
  * 
  *  setFractionalCoordinates()
@@ -1602,21 +1607,19 @@
                   tensorType, ' ').replace(':', ' ');
           //System.out.println("Tensor data = " + s);
           tokens = getTokensStr(s);
-          float[][] tensor = new float[3][3];
-          tlsGroup.put("t" + tensorType, tensor);
+          float[][] data = new float[3][3];
+          tlsGroup.put("t" + tensorType, data);
           for (int i = 0; i < tokens.length; i++) {
             int ti = tokens[i].charAt(0) - '1';
             int tj = tokens[i].charAt(1) - '1';
-            tensor[ti][tj] = parseFloatStr(tokens[++i]);
+            data[ti][tj] = parseFloatStr(tokens[++i]);
             if (ti < tj)
-              tensor[tj][ti] = tensor[ti][tj];
+              data[tj][ti] = data[ti][tj];
           }
           for (int i = 0; i < 3; i++)
             for (int j = 0; j < 3; j++)
-              if (Float.isNaN(tensor[i][j])) {
-                tlsAddError("invalid tensor: " + Escape.escapeFloatAA(tensor, 
false));
-
-              }
+              if (Float.isNaN(data[i][j]))
+                tlsAddError("invalid tensor: " + Escape.escapeFloatAA(data, 
false));
           //System.out.println("Tensor t" + tensorType + " = " + 
Escape.escape(tensor));
           if (tensorType == 'S' && ++iGroup == nGroups) {
             Logger.info(nGroups + " TLS groups read");
@@ -1632,10 +1635,10 @@
       }
     }
     if (tlsGroups != null) {
-      Hashtable<String, Object> groups = new Hashtable<String, Object>();
-      groups.put("groupCount", Integer.valueOf(nGroups));
-      groups.put("groups", tlsGroups);
-      vTlsModels.addLast(groups);
+      Hashtable<String, Object> tlsModel = new Hashtable<String, Object>();
+      tlsModel.put("groupCount", Integer.valueOf(nGroups));
+      tlsModel.put("groups", tlsGroups);
+      vTlsModels.addLast(tlsModel);
     }
     return (nGroups < 1);
   }
@@ -1648,7 +1651,8 @@
   }
 
   /**
-   * sets the atom property property_tlsGroup based on TLS group ranges
+   * Sets the atom property property_tlsGroup based on TLS group ranges
+   * and adds "TLS" key to model's auxiliaryInfo.
    * 
    * @param iGroup
    * @param iModel
@@ -1656,6 +1660,26 @@
    */
   @SuppressWarnings("unchecked")
   private void setTlsGroups(int iGroup, int iModel, SymmetryInterface 
symmetry) {
+
+    // TLS.groupCount   Integer
+    // TLS.groups       JmolList of Map
+    //   .id            String
+    //   .ranges        JmolList of Map
+    //      .chains     String
+    //      .residues   int[2]
+    //   .origin        P3
+    //   .tT            float[3][3]
+    //   .tL            float[3][3]
+    //   .tS            float[3][3]
+    //
+    // ultimately, each atom gets an associated TLS-U and TLS-R 
org.jmol.util.Tensor
+    // that can be visualized using 
+    //
+    //  ellipsoid set "TLS-R"
+    //  ellipsoids ON
+    //
+    //
+    
     Logger.info("TLS model " + (iModel + 1) + " set " + (iGroup + 1));
     Map<String, Object> tlsGroupInfo = vTlsModels.get(iGroup);
     JmolList<Map<String, Object>> groups = ( JmolList<Map<String, Object>>) 
tlsGroupInfo

Modified: trunk/Jmol/src/org/jmol/modelset/AtomCollection.java
===================================================================
--- trunk/Jmol/src/org/jmol/modelset/AtomCollection.java        2013-06-29 
23:32:44 UTC (rev 18381)
+++ trunk/Jmol/src/org/jmol/modelset/AtomCollection.java        2013-06-30 
07:21:27 UTC (rev 18382)
@@ -168,7 +168,6 @@
     return atomTypes;
   }
 
-  
   public float[] getPartialCharges() {
     return partialCharges;
   }
@@ -266,20 +265,13 @@
       t.atomIndex2 = -1;
       t.modelIndex = atoms[atomIndex].modelIndex;
       addTensor(t, t.type);
-      int pt = "charge temp   TLS-R  TLS-U".indexOf(t.type + " ");
-      //        0      7      14     21
-      // "1" is assigned for Born Effective Charges and temperature
-      // "2" is TLS-R
-      // "3" is TLS-U
-      // and no more of that!
-      if (pt >= 0) {
-        addTensor(t, t.altType = "" + (pt >= 14 ? pt / 7: 1));        
-      }
+      if (t.altType != null)
+        addTensor(t, t.altType); 
     }
   }
 
   public JmolList<Tensor> getAllAtomTensors(String type) {
-    return atomTensors.get(type);
+    return atomTensors.get(type.toLowerCase());
   }
   
   private Tensor[] getTensorList(JmolList<Tensor> list) {
@@ -290,7 +282,7 @@
       Tensor t = list.get(i);
       if (t.forThermalEllipsoid)
         pt = i;
-      else if (t.type.equals("TLS-U"))
+      else if (t.iType == Tensor.TYPE_TLS_U)
         haveTLS = true;
     }
     Tensor[] a = new Tensor[(pt >= 0 || !haveTLS ? 0 : 1) + n];
@@ -317,6 +309,7 @@
  }
 
   private void addTensor(Tensor t, String type) {
+    type = type.toLowerCase();
     JmolList<Tensor> tensors = atomTensors.get(type);
     if (tensors == null)
       atomTensors.put(type, tensors = new JmolList<Tensor>()); 

Modified: trunk/Jmol/src/org/jmol/shapespecial/Ellipsoids.java
===================================================================
--- trunk/Jmol/src/org/jmol/shapespecial/Ellipsoids.java        2013-06-29 
23:32:44 UTC (rev 18381)
+++ trunk/Jmol/src/org/jmol/shapespecial/Ellipsoids.java        2013-06-30 
07:21:27 UTC (rev 18382)
@@ -194,7 +194,7 @@
     }
 
     if ("select" == propertyName) {
-      typeSelected = (String) value;
+      typeSelected = ((String) value).toLowerCase();
       return;
     }
 
@@ -210,7 +210,7 @@
       short colix = C.getColixO(value);
       byte pid = EnumPalette.pidOf(value);
       for (Ellipsoid e : atomEllipsoids.values())
-        if (e.tensor.type.equals(typeSelected)) {
+        if (e.tensor.type.equalsIgnoreCase(typeSelected)) {
           e.colix = getColixI(colix, pid, e.tensor.atomIndex1);
           e.pid = pid;
         }
@@ -220,7 +220,7 @@
     if ("translucency" == propertyName) {
       boolean isTranslucent = (value.equals("translucent"));
       for (Ellipsoid e : atomEllipsoids.values())
-        if (e.tensor.type.equals(typeSelected))
+        if (e.tensor.type.equalsIgnoreCase(typeSelected))
           e.colix = C.getColixTranslucent3(e.colix, isTranslucent,
               translucentLevel);
       return;

Modified: trunk/Jmol/src/org/jmol/symmetry/UnitCell.java
===================================================================
--- trunk/Jmol/src/org/jmol/symmetry/UnitCell.java      2013-06-29 23:32:44 UTC 
(rev 18381)
+++ trunk/Jmol/src/org/jmol/symmetry/UnitCell.java      2013-06-30 07:21:27 UTC 
(rev 18382)
@@ -263,8 +263,10 @@
      * The coefficients bij (i,j = 1,2,3) of the various types are defined with
      * the following constant settings.
      * 
-     * Type 0: Base = e, c = 2, D = 1 Type 1: Base = e, c = 1, D = l Type 2:
-     * Base = 2, c = 2, D = l Type 3: Base = 2, c = 1, D = l
+     * Type 0: Base = e, c = 2, D = 1 
+     * Type 1: Base = e, c = 1, D = l 
+     * Type 2: Base = 2, c = 2, D = l 
+     * Type 3: Base = 2, c = 1, D = l
      * 
      * Anisotropic temperature factor Types 4, 5, 8, and 9 use the following
      * formula for the complete temperature factor, in which a1* , a2*, a3* are
@@ -276,7 +278,9 @@
      * The coefficients Uij (i,j = 1,2,3) of the various types are defined with
      * the following constant settings.
      * 
-     * Type 4: C = 2, D = 1/4 Type 5: C = 1, D = 1/4 Type 8: C = 2, D = 2pi2
+     * Type 4: C = 2, D = 1/4 
+     * Type 5: C = 1, D = 1/4 
+     * Type 8: C = 2, D = 2pi2
      * Type 9: C = 1, D = 2pi2
      * 
      * 

Modified: trunk/Jmol/src/org/jmol/util/Tensor.java
===================================================================
--- trunk/Jmol/src/org/jmol/util/Tensor.java    2013-06-29 23:32:44 UTC (rev 
18381)
+++ trunk/Jmol/src/org/jmol/util/Tensor.java    2013-06-30 07:21:27 UTC (rev 
18382)
@@ -27,55 +27,110 @@
 import java.util.Arrays;
 import java.util.Comparator;
 
+/**
+ * @author Bob Hanson hans...@stolaf.edu 6/30/2013
+ * 
+ */
 public class Tensor {
 
-  private static float TEMPERATURE_FACTOR = (float) (Math.sqrt(0.5) / Math.PI);
+  // factors that give reasonable first views of ellipsoids.
+  
+  private static final float TEMPERATURE_FACTOR = (float) (Math.sqrt(0.5) / 
Math.PI);
   private static final float MAGNETIC_SUSCEPTIBILITY_FACTOR = 0.01f;
+  private static final float ELECTRIC_FIELD_GRADIENT_FACTOR = 1f;
   private static final float BORN_EFFECTIVE_CHARGE_FACTOR = 1f;
   private static final float INTERACTION_FACTOR = 0.04f;
+  
+  private static TensorSort tSort; // used for sorting eigenvector/values
 
-  private static TensorSort tSort;
+  // base data:
+  
+  public String type;
+  public int iType = TYPE_OTHER;
+  
+  // type is an identifier that the reader/creator delivers:
+  //
+  // temp   -- crystallographic displacement parameters 
+  //           - "temperature factors"; t.forThermalEllipsoid = true
+  //           - either anisotropic (ADP) or isotropic (IDP)
+  // iso      -- isotropic displacement parameters; from 
org.jmol.symmetry.UnitCell 
+  //           - changed to "temp" after setting t.isIsotropic = true
+  // ms       -- magnetic susceptibility
+  // isc      -- NMR interaction tensors
+  //           - will have both atomIndex1 and atomIndex2 defined when
+  //           - incorporated into a model
+  // charge   -- Born Effective Charge tensor
+  // TLS-U    -- Translation/Libration/Skew tensor (anisotropic)
+  // TLS-R    -- Translation/Libration/Skew tensor (residual)
+  
+  private static final String KNOWN_TYPES = 
";iso....;temp...;tls-u..;tls-r..;ms.....;efg....;isc....;charge.;";
+  private static int getType(String type) {
+    int pt = KNOWN_TYPES.indexOf(";" + type.toLowerCase() + ".");
+    return (pt < 0 ? TYPE_OTHER : pt / 8); 
+  }
 
-  private double[][] asymmetricTensor;
-    
+  // these may be augmented, but the order should be kept the same within this 
list 
 
-  public String type; // iso temp ms isc charge TLS-R TLS-U...
+  public static final int TYPE_OTHER  = -1;
+  public static final int TYPE_ISO    = 0;
+  public static final int TYPE_TEMP   = 1;
+  public static final int TYPE_TLS_U  = 2;
+  public static final int TYPE_TLS_R  = 3;
+  public static final int TYPE_MS     = 4;
+  public static final int TYPE_EFG    = 5;
+  public static final int TYPE_ISC    = 6;
+  public static final int TYPE_CHARGE = 7;
+
+  public double[][] asymTensor;
+  public double[][] symTensor;    
+  public V3[] eigenVectors;
+  public float[] eigenValues;
+
+  // derived type-based information, Jmol-centric, for rendering:
+  
   public String altType; // "0" "1" "2"
-  public float typeFactor = 1;
 
+  // altType is somewhat of a legacy - just lets you use 
+  
+  //  ellipsoid SET 1
+  //  ellipsoid SET 2
+  //   etc...
+  
+  public boolean isIsotropic; // just rendered as balls, not special features
+  public boolean forThermalEllipsoid;
+  public int eigenSignMask = 7; // signs of eigenvalues; bits 2,1,0 set to 1 
if > 0
+  private float typeFactor = 1; // an ellipsoid scaling factor depending upon 
type
+
+  // added only after passing
+  // the tensor to ModelLoader:
+  
   public int modelIndex;
   public int atomIndex1 = -1;
   public int atomIndex2 = -1;
 
-  public V3[] eigenVectors; // possibly null (isotropic)
-  public float[] eigenValues;
-
-  public boolean forThermalEllipsoid = true;
-  public int eigenSignMask = 7;
-  public boolean isIsotropic;
-
   public static Tensor copyTensor(Tensor t0) {
     Tensor t = new Tensor();
+    t.setType(t0.type);
     t.eigenValues = t0.eigenValues;
     t.eigenVectors = t0.eigenVectors;
-    t.asymmetricTensor = t0.asymmetricTensor;
-    t.type = t0.type;
-    t.typeFactor = t0.typeFactor;
+    t.asymTensor = t0.asymTensor;
+    t.symTensor = t0.symTensor;
+    t.eigenSignMask = t0.eigenSignMask;
+    t.modelIndex = t0.modelIndex;
+    t.atomIndex1 = t0.atomIndex1;
+    t.atomIndex2 = t0.atomIndex2;
     return t;
   }
 
-
-  public double[][] getAsymmetricTensor() {
-    return asymmetricTensor;
-  }
-
   /**
-   * all instantiation must go through one of the static getTensor... methods
+   * private constructor so that all instantiation must go through one 
+   * of the static getTensor... methods to set fields properly.
    * 
    */
   private Tensor() {}
   
   /**
+   * Standard constructor for QM tensors
    * 
    * @param asymmetricTensor
    * @param type
@@ -127,10 +182,19 @@
     float[] values = new float[3];
     eigen.fillArrays(vectors, values);
     Tensor t = newTensorType(vectors, values, type);
-    t.asymmetricTensor = asymmetricTensor;
+    t.asymTensor = asymmetricTensor;
+    t.symTensor = a;
     return t;
   }
 
+  /**
+   * Standard constructor for charge and iso 
+   * 
+   * @param eigenVectors
+   * @param eigenValues
+   * @param type
+   * @return Tensor
+   */
   public static Tensor getTensorFromEigenVectors(V3[] eigenVectors,
                                             float[] eigenValues, String type) {
     float[] values = new float[3];
@@ -139,11 +203,15 @@
       vectors[i] = V3.newV(eigenVectors[i]);
       values[i] = eigenValues[i];
     }    
-    Tensor t = newTensorType(vectors, values, type);
-    t.isIsotropic = "iso".equals(type);
-    return t;
+    return newTensorType(vectors, values, type);
   }
 
+  /**
+   * Standard constructor for ellipsoids based on axes 
+   * 
+   * @param axes
+   * @return Tensor
+   */
   public static Tensor getTensorFromAxes(V3[] axes) {
     Tensor t = new Tensor();
     t.eigenValues = new float[3];
@@ -160,30 +228,76 @@
         || Math.abs(t.eigenVectors[2].dot(t.eigenVectors[0])) > 0.0001f)
       return null;
     sort(t.eigenVectors, t.eigenValues);
-    return t;
+    return t.setType("other");
   }
 
-  public static Tensor getTensorFromThermalEquation(double[] coef) {
+  /**
+   * standard constructor for thermal ellipsoids convention beta
+   * (see http://www.iucr.org/iucr-top/comm/cnom/adp/finrepone/finrepone.html)
+   * 
+   * @param coefs
+   * @return Tensor
+   */
+  public static Tensor getTensorFromThermalEquation(double[] coefs) {
     Tensor t = new Tensor();
     t.eigenValues = new float[3];
     t.eigenVectors = new V3[3];
     // assumes an ellipsoid centered on 0,0,0
-    // called by UnitCell for the initial creation of Object[] ellipsoid    
+    // called by UnitCell for the initial creation from PDB/CIF ADP data    
     double[][] mat = new double[3][3];
-    mat[0][0] = coef[0]; //XX
-    mat[1][1] = coef[1]; //YY
-    mat[2][2] = coef[2]; //ZZ
-    mat[0][1] = mat[1][0] = coef[3] / 2; //XY
-    mat[0][2] = mat[2][0] = coef[4] / 2; //XZ
-    mat[1][2] = mat[2][1] = coef[5] / 2; //YZ
+    mat[0][0] = coefs[0]; //XX
+    mat[1][1] = coefs[1]; //YY
+    mat[2][2] = coefs[2]; //ZZ
+    mat[0][1] = mat[1][0] = coefs[3] / 2; //XY
+    mat[0][2] = mat[2][0] = coefs[4] / 2; //XZ
+    mat[1][2] = mat[2][1] = coefs[5] / 2; //YZ
     Eigen.getUnitVectors(mat, t.eigenVectors, t.eigenValues);
     sort(t.eigenVectors, t.eigenValues);
     t.typeFactor = TEMPERATURE_FACTOR;
-    t.type = "temp";
-    t.setTypeFactor();
-    return t;
+    return t.setType("temp");
   }
 
+  /**
+   * Note that type may be null here to skip type initialization
+   * and allow later setting of type; this should be used with care.
+   * 
+   * @param type
+   * @return "this" for convenience only
+   */
+  public Tensor setType(String type) {
+    if (this.type == null || type == null)
+      this.type = type;
+    if (type != null)
+      processType();
+    return this;
+  }
+
+  /**
+   * Returns a factored eigenvalue; thermal ellipsoids use 
sqrt(abs(eigenvalue)) for
+   * ellipsoid axes; others use just use abs(eigenvalue); all cases get 
factored by
+   * typeFactor
+   * 
+   * @param i
+   * @return factored eigenvalue
+   */
+  public float getFactoredValue(int i) {
+    float f = Math.abs(eigenValues[i]);
+    return (forThermalEllipsoid ? (float) Math.sqrt(f) : f) * typeFactor;
+  }
+
+  public void setAtomIndexes(int index1, int index2) {
+    atomIndex1 = index1;
+    atomIndex2 = index2;
+  }
+
+  /**
+   * common processing of eigenvectors.
+   * 
+   * @param vectors
+   * @param values
+   * @param type
+   * @return Tensor
+   */
   private static Tensor newTensorType(V3[] vectors, float[] values, String 
type) {
     Tensor t = new Tensor();
     t.eigenValues = values;
@@ -197,62 +311,64 @@
     return t;
   }
 
-  private void setTypeFactor() {
+  /**
+   * Sets typeFactor, altType, isIsotropic, forThermalEllipsoid;
+   * type "iso" changed to "temp" here.
+   * 
+   */
+  private void processType() {
+    
     forThermalEllipsoid = false;
-    switch ("iso  temp ms   isc  chargeTLS-UTLS-R".indexOf(type)) {
-    //       0    5    10   15   20    25   30
-    default: // TLS, other
-      typeFactor = 1;
-      break;
-    case 0: // iso
+    isIsotropic = false;
+    altType = null;
+    typeFactor = 1;
+    
+    switch (iType = getType(type)) {
+    case TYPE_ISO:
       forThermalEllipsoid = true;
-      typeFactor = 1;
+      isIsotropic = true;
+      altType = "1";
+      type = "temp";
       break;
-    case 5: // temp
+    case TYPE_TEMP:
       forThermalEllipsoid = true;
       typeFactor = TEMPERATURE_FACTOR;
+      altType = "1";
       break;
-    case 10: // ms
+    case TYPE_MS:
       typeFactor = MAGNETIC_SUSCEPTIBILITY_FACTOR;
       break;
-    case 15: // isc
+    case TYPE_EFG:
+      typeFactor = ELECTRIC_FIELD_GRADIENT_FACTOR;
+      break;
+    case TYPE_ISC:
       typeFactor = INTERACTION_FACTOR;
       break;
-    case 20: // charge
+    case TYPE_CHARGE:
       typeFactor = BORN_EFFECTIVE_CHARGE_FACTOR;
       break;
+    case TYPE_TLS_R:
+      altType = "2";
+      break;
+    case TYPE_TLS_U:
+      altType = "3";
+      break;
     }
   }
 
-  public Tensor setType(String type) {
-    if (this.type == null || type == null)
-      this.type = type;
-    setTypeFactor();
-    return this;
-  }
-
-  public float getFactoredValue(int i) {
-    float f = Math.abs(eigenValues[i]);
-    return (forThermalEllipsoid ? (float) Math.sqrt(f) : f) * typeFactor;
-  }
-
-  public void setAtomIndexes(int index1, int index2) {
-    atomIndex1 = index1;
-    atomIndex2 = index2;
-  }
-
   private static int[] sortOrder = { 1, 0, 2 };
 
   /**
-   * sorts EigenVectors by
+   * sorts EigenVectors by 
    * 
+   * |sigma_3 - sigma_iso| >= |sigma_1 - sigma_iso| >= |sigma_2 - sigma_iso|
+   * 
    * and normalize the eigenVectors
    * 
    * @param eigenVectors
    * @param eigenValues
    */
   private static void sort(V3[] eigenVectors, float[] eigenValues) {
-    // |sigma_3 - sigma_iso| >= |sigma_1 - sigma_iso| >= |sigma_2 - sigma_iso|
     // first sorted 3 2 1, then 1 and 2 are switched using the sortOrder above.
     Object[][] o = new Object[][] {
         new Object[] { eigenVectors[0], Float.valueOf(eigenValues[0]) },

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


------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Jmol-commits mailing list
Jmol-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jmol-commits

Reply via email to