Revision: 21293
          http://sourceforge.net/p/jmol/code/21293
Author:   hansonr
Date:     2016-12-01 23:10:35 +0000 (Thu, 01 Dec 2016)
Log Message:
-----------
Jmol.___JmolVersion="14.7.4_2016.12.01"

new feature: fully implemented CIF 2.0 reader

new feature: x = getProperty("cifInfo", "c:/temp/test.cif")
 -- reads CIF file data in structured format
 -- automatically uses CIF 1.0 or CIF 2.0, as needed.

new feature: CIF reader allows for nonstandard [ .... ] array notation in CIF 
1.0 files
 -- returned as an unaltered string for CIF 1.x; JSON string in CIF 2.x 
 

Modified Paths:
--------------
    trunk/Jmol/src/javajs/api/GenericCifDataParser.java
    trunk/Jmol/src/javajs/util/CifDataParser.java
    trunk/Jmol/src/javajs/util/Rdr.java
    trunk/Jmol/src/org/jmol/adapter/readers/cif/Cif2DataParser.java
    trunk/Jmol/src/org/jmol/adapter/readers/cif/Cif2Reader.java
    trunk/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java
    trunk/Jmol/src/org/jmol/adapter/readers/cif/MSCifRdr.java
    trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java
    trunk/Jmol/src/org/jmol/adapter/smarter/SmarterJmolAdapter.java
    trunk/Jmol/src/org/jmol/viewer/Jmol.properties
    trunk/Jmol/src/org/jmol/viewer/PropertyManager.java
    trunk/Jmol/src/org/jmol/viewer/Viewer.java

Modified: trunk/Jmol/src/javajs/api/GenericCifDataParser.java
===================================================================
--- trunk/Jmol/src/javajs/api/GenericCifDataParser.java 2016-12-01 15:04:17 UTC 
(rev 21292)
+++ trunk/Jmol/src/javajs/api/GenericCifDataParser.java 2016-12-01 23:10:35 UTC 
(rev 21293)
@@ -3,7 +3,9 @@
 import java.io.BufferedReader;
 import java.util.Map;
 
+import javajs.util.CifDataParser;
 
+
 public interface GenericCifDataParser {
 
   static final int NONE = -1;
@@ -20,21 +22,21 @@
 
   String getFileHeader();
 
-  String getColumnData(int i);
+  Object peekToken() throws Exception;
 
-  String getNextDataToken() throws Exception;
+  Object getTokenPeeked();
 
+  Object getColumnData(int i);
+
+  Object getNextDataToken() throws Exception;
+
   String getNextToken() throws Exception;
 
-  String getTokenPeeked();
-
   void parseDataBlockParameters(String[] fields, String key, String data, 
int[] key2col, int[] col2key) throws Exception;
 
-  String peekToken() throws Exception;
-
   String readLine();
 
-  GenericCifDataParser set(GenericLineReader reader, BufferedReader br);
+  GenericCifDataParser set(GenericLineReader reader, BufferedReader br, 
boolean debugging);
 
   String toUnicode(String data);
 

Modified: trunk/Jmol/src/javajs/util/CifDataParser.java
===================================================================
--- trunk/Jmol/src/javajs/util/CifDataParser.java       2016-12-01 15:04:17 UTC 
(rev 21292)
+++ trunk/Jmol/src/javajs/util/CifDataParser.java       2016-12-01 23:10:35 UTC 
(rev 21293)
@@ -87,20 +87,24 @@
   protected int ich;
   protected int cch;
   protected boolean wasUnquoted;
-  private String strPeeked;
+  protected char cterm = '\0';
+  protected String nullString = "\0";
+  protected boolean debugging;
+
+
+  private Object strPeeked;
   private int ichPeeked;
   private int columnCount;
   private String[] columnNames;
-  private String[] columnData = new String[KEY_MAX];
+  private Object[] columnData = new Object[KEY_MAX];
   private boolean isLoop;
   private boolean haveData;
-  protected String nullString = "\0";
-
   private SB fileHeader = new SB();
   private boolean isHeader = true;
 
-  protected char cterm = '\0';
+  protected boolean asObject;
 
+
   /**
    * Set the string value of what is returned for "." and "?"
    * 
@@ -127,7 +131,7 @@
   }
     
   @Override
-  public String getColumnData(int i) {
+  public Object getColumnData(int i) {
     return columnData[i];
   }
 
@@ -151,15 +155,22 @@
    * 
    * @param reader  Anything that can deliver a line of text or null
    * @param br      A standard BufferedReader.
+   * @param debugging 
    *  
    */
   @Override
-  public CifDataParser set(GenericLineReader reader, BufferedReader br) {
+  public CifDataParser set(GenericLineReader reader, BufferedReader br, 
boolean debugging) {
     this.reader = reader;
     this.br = br;
+    this.debugging = debugging;
     return this;
   }
 
+  protected int getVersion() {
+    return 1;
+  }
+
+
   /**
    * 
    * @return commented-out section at the start of a CIF file.
@@ -182,14 +193,17 @@
   public Map<String, Object> getAllCifData() {
     line = "";
     String key;
-    Map<String, Object> data = null;
+    Map<String, Object> data = null, data0 = null;
     Map<String, Object> allData = new Hashtable<String, Object>();
     Lst<Map<String, Object>> models = new  Lst<Map<String,Object>>();
     allData.put("models", models);
+    asObject = (getVersion() >= 2);
+    nullString = null;
+    Lst<Map<String, Object>> saveFrames = new Lst<Map<String, Object>>();
     try {
       while ((key = getNextToken()) != null) {
         if (key.startsWith("global_") || key.startsWith("data_")) {
-          models.addLast(data = new Hashtable<String, Object>());
+          models.addLast(data0 = data = new Hashtable<String, Object>());
           data.put("name", key);
           continue;
         }
@@ -198,13 +212,26 @@
           continue;
         }
         if (key.startsWith("save_")) {
-          System.out.println("CIF reader ignoring save_");
+          if (key.equals("save_")) {
+            int n = saveFrames.size();
+            if (n == 0) {
+              System.out.println("CIF ERROR ? save_ without corresponding 
save_xxxx");
+              data = data0;
+            } else {
+              data = saveFrames.removeItemAt(n - 1);
+            }
+          } else {
+            saveFrames.addLast(data);
+            Map<String, Object> d = data;
+            data = new Hashtable<String, Object>();
+            d.put(key, data);
+          }
           continue;
         }
         if (key.charAt(0) != '_') {
           System.out.println("CIF ERROR ? should be an underscore: " + key);
         } else {
-          String value = getNextToken();
+          Object value = (asObject ? getNextTokenObject() : getNextToken());
           if (value == null) {
             System.out.println("CIF ERROR ? end of file; data missing: " + 
key);
           } else {
@@ -215,12 +242,14 @@
     } catch (Exception e) {
       // ?
     }
+    asObject = false;
     try {
       if (br != null)
         br.close();
     } catch (Exception e) {
       // ?
     }
+    nullString = "\0";
     return allData;
   }
 
@@ -236,17 +265,23 @@
   private void getAllCifLoopData(Map<String, Object> data) throws Exception {
     String key;
     Lst<String> keyWords = new  Lst<String>();
-    while ((key = peekToken()) != null && key.charAt(0) == '_') {
-      key = fixKey(getTokenPeeked());
+    Object o;
+    while ((o = peekToken()) != null && o instanceof String &&  ((String) 
o).charAt(0) == '_') {
+      key = fixKey((String) getTokenPeeked());
       keyWords.addLast(key);
       data.put(key, new  Lst<String>());
     }
     columnCount = keyWords.size();
     if (columnCount == 0)
       return;
-    while (getData())
+    isLoop = true;
+    int n = 0;
+    while (getData()) {
       for (int i = 0; i < columnCount; i++)
-        ((Lst<String>)data.get(keyWords.get(i))).addLast(columnData[i]);
+        ((Lst<Object>)data.get(keyWords.get(i))).addLast(columnData[i]);
+      n++;
+    }
+    isLoop = false;
   }
 
   @Override
@@ -300,7 +335,7 @@
     String str;
     SB ret = (doReport ? new SB() : null);
     int n = 0;
-    while ((str = peekToken()) != null && str.charAt(0) == '_') {
+    while ((str = (String) peekToken()) != null && str.charAt(0) == '_') {
       if (ret != null)
         ret.append(str).append("\n");
       getTokenPeeked();
@@ -309,7 +344,7 @@
     if (n == 0)
       n = columnCount; // end-of-label-section skip 
     int m = 0;
-    while ((str = getNextDataToken()) != null) {
+    while ((str = (String) getNextDataToken()) != null) {
       if (ret == null)
         continue; 
       ret.append(str).append(" ");
@@ -327,10 +362,20 @@
   @Override
   public String getNextToken() throws Exception {
     wasUnquoted = true;
+    return (String) getNextTokenProtected();
+  }
+
+  /**
+   * 
+   * @return the next token of any kind, or null
+   * @throws Exception
+   */
+  public Object getNextTokenObject() throws Exception {
+    wasUnquoted = true;
     return getNextTokenProtected();
   }
 
-  protected String getNextTokenProtected() throws Exception {
+  protected Object getNextTokenProtected() throws Exception {
     return (getNextLine() ? nextStrToken() : null);
   }
 
@@ -343,16 +388,19 @@
    * @throws Exception
    */
   @Override
-  public String getNextDataToken() throws Exception { 
-    String str = peekToken();
-    if (str == null)
+  public Object getNextDataToken() throws Exception { 
+    Object o = peekToken();
+    if (o == null)
       return null;
-    if (wasUnquoted)
+    if (wasUnquoted && o instanceof String) {
+      String str = (String) o;
       if (str.charAt(0) == '_' || str.startsWith("loop_")
           || str.startsWith("data_")
+          || str.startsWith("save_")
           || str.startsWith("stop_")
           || str.startsWith("global_"))
         return null;
+    }
     return getTokenPeeked();
   }
   
@@ -364,7 +412,7 @@
    * @throws Exception
    */
   @Override
-  public String peekToken() throws Exception {
+  public Object peekToken() throws Exception {
     if (!getNextLine())
       return null;
     int ich = this.ich;
@@ -386,7 +434,7 @@
    * @return the token last acquired; may be null
    */
   @Override
-  public String getTokenPeeked() {
+  public Object getTokenPeeked() {
     ich = ichPeeked;
     return strPeeked;
   }
@@ -486,6 +534,7 @@
   public void parseDataBlockParameters(String[] fields, String key,
                                  String data, int[] key2col, int[] col2key) 
throws Exception {
     isLoop = (key == null);
+    Object o;
     String s;
     if (fields == null) {
       // for reading full list of keys, as for matrices
@@ -501,18 +550,18 @@
     int pt, i;
     if (isLoop) {
       while (true) {
-        s = peekToken();
-        if (s == null) {
+        o = peekToken();
+        if (o == null) {
           // we are PREMATURELY done; reset
           columnCount = 0;
           break;
         }
         // end of the loop is a new token not starting with underscore
-        if (s.charAt(0) != '_')
+        if (!(o instanceof String) || ((String) o).charAt(0) != '_')
           break;
 
         pt = columnCount++;
-        s = fixKey(getTokenPeeked());
+        s = fixKey((String) getTokenPeeked());
         if (fields == null) {
           // just make a linear model, saving the list
           columnNames[col2key[pt] = key2col[pt] = pt] = s;
@@ -530,14 +579,14 @@
         // end of the loop is a new token not starting with underscore
         pt = columnCount++;
         if (key == null) {
-          key = getTokenPeeked();
+          key = (String) getTokenPeeked();
           data = getNextToken();
         }
         Integer iField = htFields.get(fixKey(key));
         i = (iField == null ? NONE : iField.intValue());
         if ((col2key[pt] = i) != NONE) 
           columnData[key2col[i] = pt] = data;
-        if ((s = peekToken()) == null || !s.startsWith(str0))
+        if ((o = peekToken()) == null || !(o instanceof String) ||  !((String) 
o).startsWith(str0))
           break;
         key = null;
       }
@@ -700,13 +749,13 @@
    * 
    * @return null if no more tokens, "\0" if '.' or '?', or next token
    */
-  protected String nextStrToken() {
+  private Object nextStrToken() {
     if (ich == cch)
       return null;
     char ch = str.charAt(ich);
     if (isQuote(ch)) {
       wasUnquoted = false;
-      return (String) getQuotedStringOrObject(ch);
+      return getQuotedStringOrObject(ch);
     }
     int ichStart = ich;
     wasUnquoted = true;
@@ -720,7 +769,7 @@
     return unquoted(s);
   }
 
-  protected String unquoted(String s) {
+  protected Object unquoted(String s) {
     return s;
   }
 

Modified: trunk/Jmol/src/javajs/util/Rdr.java
===================================================================
--- trunk/Jmol/src/javajs/util/Rdr.java 2016-12-01 15:04:17 UTC (rev 21292)
+++ trunk/Jmol/src/javajs/util/Rdr.java 2016-12-01 23:10:35 UTC (rev 21293)
@@ -67,7 +67,7 @@
   }
 
   public static Map<String, Object> readCifData(GenericCifDataParser parser, 
BufferedReader br) {
-    return parser.set(null, br).getAllCifData();
+    return parser.set(null, br, false).getAllCifData();
   }
   
   

Modified: trunk/Jmol/src/org/jmol/adapter/readers/cif/Cif2DataParser.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/readers/cif/Cif2DataParser.java     
2016-12-01 15:04:17 UTC (rev 21292)
+++ trunk/Jmol/src/org/jmol/adapter/readers/cif/Cif2DataParser.java     
2016-12-01 23:10:35 UTC (rev 21293)
@@ -1,6 +1,12 @@
 package org.jmol.adapter.readers.cif;
 
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.jmol.util.Logger;
+
 import javajs.util.CifDataParser;
+import javajs.util.Lst;
 import javajs.util.PT;
 
 /**
@@ -9,10 +15,25 @@
  * 
  * see http://journals.iucr.org/j/issues/2016/01/00/aj5269/index.html
  * 
+ * Will deliver JSON versions of the data while file reading and Java List/Map 
structures when 
+ * called by 
+ * 
+ *    x = getProperty("cifInfo", filename)
+ *    
+ * Validated using the test-data suite by John Bollinger 
(john.bollin...@stjude.org)
+ * found at https://github.com/COMCIFS/cif_api  
+ * 
  * @author Bob Hanson hans...@stolaf.edu 
  */
 public class Cif2DataParser extends CifDataParser {
 
+  
+  @Override
+  protected int getVersion() {
+    return 2;
+  }
+
+
 //  3.1. Character set and encoding
 //
 //       - UTF-8
@@ -144,7 +165,7 @@
   @Override
   protected boolean isQuote(char ch) {
     switch (ch) {
-    case '\1': // CIF 1.1 encoded multi-line semicolon-encoded string
+    case '\1': // preprocessed CIF 1.1 encoded multi-line semicolon-encoded 
string
     case '\'':
     case '\"':
     case '[':
@@ -158,7 +179,7 @@
   }
 
   /**
-   * preprocess all operators
+   * preprocess operators
    * 
    */
   @Override
@@ -177,7 +198,7 @@
    */
   @Override
   protected Object getQuotedStringOrObject(char ch) {
-    return processQuotedString(false);
+    return processQuotedString();
   }
 
   /**
@@ -185,10 +206,10 @@
    */
   @Override
   protected String preprocessString() {
-    return processQuotedString(true);
+    return (String) processQuotedString();
   }
   
-  private String processQuotedString(boolean isPreprocessing) {
+  private Object processQuotedString() {
     String str = null;
     char quoteChar = this.str.charAt(ich);
     String tripleChar = null;
@@ -196,50 +217,47 @@
       switch (quoteChar) {
       case '\1':
         str = this.str.substring(1, (ich = this.str.indexOf("\1", ich + 1)));
+        ich++;
         if (cterm != '\0')
-          str = PT.esc(str);
-        ich++;
+          return (asObject ? str : PT.esc(str));
         break;
       case ';':
         line = (ich == 0 ? this.str : this.str.substring(ich));
         str = processSemiString();
         return setString(str);
       case '[':
-        str = readListAsJSON(ich + 1);
-        break;
+        return readList(ich + 1);
       case ']':
         str = "]";
         ich++;
         break;
       case '{':
-        str = readTableAsJSON(ich + 1);
-        break;
+        return readTable(ich + 1);
       case '}':
         str = "}";
         ich++;
         break;
       case '\'':
       case '"':
-        line = this.str.substring(ich);
-        if (line.indexOf("'''") == 0)
+        //line = this.str.substring(ich);
+        if (this.str.indexOf("'''") == ich)
           tripleChar = "'''";
-        else if (line.indexOf("\"\"\"") == 0)
+        else if (this.str.indexOf("\"\"\"") == ich)
           tripleChar = "\"\"\"";
         int nchar = (tripleChar == null ? 1 : 3);
-        int pt = nchar;
+        int pt = ich + nchar;
         int pt1 = 0;
-        str = "";
-        while (line != null
-            && (pt1 = (tripleChar == null ? line.indexOf(quoteChar, pt) : line
-                .indexOf(tripleChar, pt))) < 0) {
-          str += "\n" + line.substring(pt);
-          readLine();
-          pt = 0;
+        while ((pt1 = (tripleChar == null ? this.str.indexOf(quoteChar, pt) : 
+              this.str.indexOf(tripleChar, pt))) < 0) {
+          if (readLine() == null)
+            break;
+          this.str += line;
         }
-        str += (line == null ? "" : line.substring(pt, pt1));
-        setString(line.substring(pt1 + nchar));
+        ich = pt1 + nchar;
+        cch  = this.str.length();
+        str = this.str.substring(pt, pt1);
         if (cterm != '\0')
-          str = PT.esc(str);
+          return (asObject ? str : PT.esc(str));
         break;
       }
     } catch (Exception e) {
@@ -281,53 +299,66 @@
     return fixLineFolding(str);
   }
 
-  public String readListAsJSON(int ichStart) throws Exception {
+  public Object readList(int ichStart) throws Exception {
     String str = "";
-    ich = ichStart;
+    ich = ichStart; 
     int n = 0;
     char cterm0 = cterm;
     cterm = ']';
+    Lst<Object> lst = (asObject ? new Lst<Object>() : null);
+    String ns = nullString;
     nullString = null;
     while (true) {
-      String s = getNextToken();
+      Object s = (asObject ? getNextTokenObject() : getNextToken());
       if (s == null || s.equals("]"))
         break;
+      if (asObject) {
+        lst.addLast(s);
+        continue;
+      }
       if (n++ > 0)
         str += ",";
       str += s;
     }
     cterm = cterm0;
     str = "[" + str + "]";
-//    if (cterm == '\0')
-//      System.out.println("CIF2 list: " + str);
-    nullString = "\0";
-    return str;
+    if (cterm == '\0' && debugging) 
+      Logger.debug("CIF2 list: " + str);
+    nullString = ns;
+    return (asObject ? lst : str);
   }
 
-  public String readTableAsJSON(int ichStart) throws Exception {
+  public Object readTable(int ichStart) throws Exception {
     String str = "";
     int n = 0;
     ich = ichStart;
     char cterm0 = cterm;
     cterm = '}';
+    String ns = nullString;
     nullString = null;
+    Map<String, Object> map = (asObject ? new Hashtable<String, Object>()
+        : null);
     while (true) {
       String key = getNextToken();
-      if (key == null || key.equals("}")) 
+      if (key == null || key.equals("}"))
         break;
       while (isSpaceOrColon(ich))
         ich++;
-      String value = getNextToken();
-      if (n++ > 0)
-        str += ",";
-      str += key + ":" + value;
+      if (asObject) {
+        map.put(key, getNextTokenObject());
+      } else {
+        String value = getNextToken();
+        if (n++ > 0)
+          str += ",";
+        str += key + ":" + value;
+      }
     }
     cterm = cterm0;
     str = "{" + str + "}";
-    nullString = "\0";
-//    if (cterm == '\0')
-//      System.out.println("CIF2 table: " + str);
-    return str;
+    nullString = ns;
+    if (cterm == '\0' && debugging)
+      Logger.debug("CIF2 table: " + str);
+    return (asObject ? map : str);
   }
     
 
@@ -344,8 +375,8 @@
   }
 
   @Override
-  protected String unquoted(String s) {
-    if (cterm == '\0')
+  protected Object unquoted(String s) {
+    if (cterm == '\0' && !asObject)
       return s;
     int n = s.length();
     if (n > 0) {
@@ -358,18 +389,22 @@
           s = s.substring(0, pt);
         try {
           if (isFloat) {
-            s = "" + Float.parseFloat(s);
+            float f = Float.parseFloat(s);
+            if (asObject)
+              return Float.valueOf(f);
+            s = "" + f;
             if (s.indexOf(".") < 0 && s.indexOf("E") < 0)
               s += ".0";
             return s;
           }
-          return "" + Integer.parseInt(s);
+          int i = Integer.parseInt(s);
+          return (asObject ? Integer.valueOf(i) : "" + i);
         } catch (Throwable e) {
           // ignore
         }
       }
     }
-    return PT.esc(s);
+    return (asObject ? s : PT.esc(s));
   }
 
 
@@ -403,7 +438,8 @@
       if (pt < eol)
         str = str.substring(0, pt) + str.substring(eol + 1);
     }
-    //System.out.println("fixed: >>" + str + "<<");
+    if (debugging) 
+      Logger.debug("CIF2 folded: " + str.replace("\1", "~~"));
     return str;
   }
 

Modified: trunk/Jmol/src/org/jmol/adapter/readers/cif/Cif2Reader.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/readers/cif/Cif2Reader.java 2016-12-01 
15:04:17 UTC (rev 21292)
+++ trunk/Jmol/src/org/jmol/adapter/readers/cif/Cif2Reader.java 2016-12-01 
23:10:35 UTC (rev 21293)
@@ -40,7 +40,7 @@
   
   @Override
   protected GenericCifDataParser getCifDataParser() {
-    return new Cif2DataParser().set(this, null);
+    return new Cif2DataParser().set(this, null, debugging);
   }
 
 

Modified: trunk/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java  2016-12-01 
15:04:17 UTC (rev 21292)
+++ trunk/Jmol/src/org/jmol/adapter/readers/cif/CifReader.java  2016-12-01 
23:10:35 UTC (rev 21293)
@@ -170,13 +170,13 @@
      */
     parser = getCifDataParser();
     line = "";
-    while ((key = parser.peekToken()) != null)
+    while ((key = (String) parser.peekToken()) != null)
       if (!readAllData())
         break;
     if (appendedData != null) {
       parser = ((GenericCifDataParser) 
getInterface("javajs.util.CifDataParser"))
-          .set(null, Rdr.getBR(appendedData));
-      while ((key = parser.peekToken()) != null)
+          .set(null, Rdr.getBR(appendedData), debugging);
+      while ((key = (String) parser.peekToken()) != null)
         if (!readAllData())
           break;
     }
@@ -184,13 +184,13 @@
 
   protected GenericCifDataParser getCifDataParser() {
     // overridden in Cif2Reader
-    return new CifDataParser().set(this, null);
+    return new CifDataParser().set(this, null, debugging);
   }
 
   private boolean readAllData() throws Exception {
     if (key.startsWith("data_")) {
       isLigand = false;
-      if (asc.atomSetCount == 0)
+      if (asc.atomSetCount == 0)  
         iHaveDesiredModel = false;
       if (iHaveDesiredModel)
         return false;
@@ -731,10 +731,10 @@
    * @throws Exception
    */
   private boolean getData() throws Exception {
-    key = parser.getTokenPeeked();
+    key = (String) parser.getTokenPeeked();
     data = parser.getNextToken();
-    //if (debugging && data != null && data.charAt(0) != '\0')
-    Logger.debug(">> " + key  + " " + data);
+    if (debugging && data != null && data.length() > 0 && data.charAt(0) != 
'\0')
+      Logger.debug(">> " + key  + " " + data);
     if (data == null) {
       Logger.warn("CIF ERROR ? end of file; data missing: " + key);
       return false;
@@ -753,7 +753,7 @@
    */
   protected void processLoopBlock() throws Exception {
     parser.getTokenPeeked(); //loop_
-    key = parser.peekToken();
+    key = (String) parser.peekToken();
     if (key == null)
       return;
     key = parser.fixKey(key0 = key);
@@ -822,13 +822,13 @@
     String str;
     int n = 0;
     try {
-      while ((str = parser.peekToken()) != null && str.charAt(0) == '_') {
+      while ((str = (String) parser.peekToken()) != null && str.charAt(0) == 
'_') {
         parser.getTokenPeeked();
         n++;
       }
       int m = 0;
       String s = "";
-      while ((str = parser.getNextDataToken()) != null) {
+      while ((str = (String) parser.getNextDataToken()) != null) {
         s += str + (m % n == 0 ? "=" : " ");
         if (++m % n == 0) {
           appendUunitCellInfo(s.trim());
@@ -840,7 +840,7 @@
   }
 
   protected int fieldProperty(int i) {
-    return (i >= 0 && (field = parser.getColumnData(i)).length() > 0
+    return (i >= 0 && (field = (String) parser.getColumnData(i)).length() > 0
         && (firstChar = field.charAt(0)) != '\0' ? col2key[i] : NONE);
   }
 
@@ -1251,7 +1251,7 @@
           if (field.equalsIgnoreCase("Uiso")) {
             int j = key2col[U_ISO_OR_EQUIV];
             if (j != NONE)
-              asc.setU(atom, 7, parseFloatStr(parser.getColumnData(j)));
+              asc.setU(atom, 7, parseFloatStr((String) 
parser.getColumnData(j)));
           }
           break;
         case ANISO_U11:
@@ -1964,7 +1964,7 @@
 
   protected String getField(byte type) {
     int i = key2col[type];
-    return (i == NONE ? "\0" : parser.getColumnData(i));
+    return (i == NONE ? "\0" : (String) parser.getColumnData(i));
   }
 
   protected boolean isNull(String key) {

Modified: trunk/Jmol/src/org/jmol/adapter/readers/cif/MSCifRdr.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/readers/cif/MSCifRdr.java   2016-12-01 
15:04:17 UTC (rev 21292)
+++ trunk/Jmol/src/org/jmol/adapter/readers/cif/MSCifRdr.java   2016-12-01 
23:10:35 UTC (rev 21293)
@@ -603,7 +603,7 @@
   }
 
   private int fieldProperty(CifReader cr, int i) {
-    return ((field = cr.parser.getColumnData(i)).length() > 0 
+    return ((field = (String) cr.parser.getColumnData(i)).length() > 0 
         && field.charAt(0) != '\0' ? 
             cr.col2key[i] : NONE);
   }

Modified: trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java      
2016-12-01 15:04:17 UTC (rev 21292)
+++ trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollection.java      
2016-12-01 23:10:35 UTC (rev 21293)
@@ -131,8 +131,8 @@
       int n = 0;
       readerList = new Lst<AtomSetCollectionReader>();
       for (int i = 0; i < array.length; i++)
-        if (array[i].ac > 0 || array[i].reader != null
-            && array[i].reader.mustFinalizeModelSet)
+        if (array[i] != null && (array[i].ac > 0 || array[i].reader != null
+            && array[i].reader.mustFinalizeModelSet))
           appendAtomSetCollection(n++, array[i]);
       if (n > 1)
         setInfo("isMultiFile", Boolean.TRUE);

Modified: trunk/Jmol/src/org/jmol/adapter/smarter/SmarterJmolAdapter.java
===================================================================
--- trunk/Jmol/src/org/jmol/adapter/smarter/SmarterJmolAdapter.java     
2016-12-01 15:04:17 UTC (rev 21292)
+++ trunk/Jmol/src/org/jmol/adapter/smarter/SmarterJmolAdapter.java     
2016-12-01 23:10:35 UTC (rev 21293)
@@ -194,8 +194,6 @@
     //FilesOpenThread
     Viewer vwr = (Viewer) htParams.get("vwr"); // don't pass this on to user
     int size = names.length;
-    AtomSetCollectionReader[] readers = (getReadersOnly ? new 
AtomSetCollectionReader[size]
-        : null);
     Object reader = null;
     if (htParams.containsKey("concatenate")) {
       String s = "";
@@ -231,6 +229,8 @@
       size = 1;
       reader = Rdr.getBR(s);
     }
+    AtomSetCollectionReader[] readers = (getReadersOnly ? new 
AtomSetCollectionReader[size]
+        : null);
     AtomSetCollection[] atomsets = (getReadersOnly ? null
         : new AtomSetCollection[size]);
     AtomSetCollectionReader r = null;
@@ -299,6 +299,7 @@
         : (AtomSetCollection[]) atomsets);
     if (atomsets == null) {
       for (int i = 0; i < readers.length; i++) {
+        if (readers[i] != null)
         try {
           Object ret = readers[i].readData();
           if (!(ret instanceof AtomSetCollection))

Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties
===================================================================
--- trunk/Jmol/src/org/jmol/viewer/Jmol.properties      2016-12-01 15:04:17 UTC 
(rev 21292)
+++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties      2016-12-01 23:10:35 UTC 
(rev 21293)
@@ -51,8 +51,12 @@
 
 new feature: fully implemented CIF 2.0 reader
 
-new feature: CIF reader allows for [ .... ] array notation
- -- returned as an unaltered string for CIF 1.x 
+new feature: x = getProperty("cifInfo", "c:/temp/test.cif")
+ -- reads CIF file data in structured format
+ -- automatically uses CIF 1.0 or CIF 2.0, as needed.
+
+new feature: CIF reader allows for nonstandard [ .... ] array notation in CIF 
1.0 files
+ -- returned as an unaltered string for CIF 1.x; JSON string in CIF 2.x 
  
 JmolVersion="14.7.4_2016.11.28"
 

Modified: trunk/Jmol/src/org/jmol/viewer/PropertyManager.java
===================================================================
--- trunk/Jmol/src/org/jmol/viewer/PropertyManager.java 2016-12-01 15:04:17 UTC 
(rev 21292)
+++ trunk/Jmol/src/org/jmol/viewer/PropertyManager.java 2016-12-01 23:10:35 UTC 
(rev 21293)
@@ -174,6 +174,7 @@
     "domainInfo"  , atomExpression, "{visible}",
     "validationInfo"  , atomExpression, "{visible}",
     "service"    , "<hashTable>", "",
+    "CIFInfo"        , "<filename>", "_modelFile",
 
   };
 
@@ -228,7 +229,8 @@
   private final static int PROP_DOM_INFO = 42;
   private final static int PROP_VAL_INFO = 43;
   private final static int PROP_SERVICE = 44;
-  private final static int PROP_COUNT = 45;
+  private final static int PROP_CIF_INFO = 45;
+  private final static int PROP_COUNT = 46;
 
   //// static methods used by Eval and Viewer ////
 
@@ -766,6 +768,8 @@
       return vwr.getModelExtract(myParam, true, false, "MOL");
     case PROP_FILE_INFO:
       return getFileInfo(vwr.getFileData(), myParam.toString());
+    case PROP_CIF_INFO:
+      return vwr.readCifData(myParam.toString(), null);
     case PROP_FILENAME:
       return vwr.fm.getFullPathName(false);
     case PROP_FILEHEADER:

Modified: trunk/Jmol/src/org/jmol/viewer/Viewer.java
===================================================================
--- trunk/Jmol/src/org/jmol/viewer/Viewer.java  2016-12-01 15:04:17 UTC (rev 
21292)
+++ trunk/Jmol/src/org/jmol/viewer/Viewer.java  2016-12-01 23:10:35 UTC (rev 
21293)
@@ -2108,9 +2108,8 @@
                                              Map<String, Object> htParams,
                                              boolean isAppend) {
     // loadInline, openStringInline
-
-    BufferedReader br = Rdr.getBR(strModel);
-    String type = getModelAdapter().getFileTypeName(br);
+    
+    String type = getModelAdapter().getFileTypeName(Rdr.getBR(strModel));
     if (type == null)
       return "unknown file type";
     if (type.equals("spt")) {
@@ -2860,10 +2859,20 @@
   }
 
   public Map<String, Object> getCifData(int modelIndex) {
-    String data = getFileAsString3(ms.getModelFileName(modelIndex), false, 
null);
-    return (data == null ? null : Rdr.readCifData(
+    return readCifData(ms.getModelFileName(modelIndex), 
ms.getModelFileType(modelIndex));
+  }
+
+  public Map<String, Object> readCifData(String fileName, String type) {
+    String data = getFileAsString3(
+        (fileName == null || fileName.length() == 0 ? 
getCurrentFileAsString("script"): fileName), false, null);
+    if (data == null)
+      return null;
+    BufferedReader rdr = Rdr.getBR(data);
+    if (type == null)
+      type = getModelAdapter().getFileTypeName(rdr);
+    return (type == null ? null : Rdr.readCifData(
         (GenericCifDataParser) Interface.getInterface(
-            "javajs.util.CifDataParser", this, "script"), Rdr.getBR(data)));
+            ("cif2".equals(type.toLowerCase()) ? 
"org.jmol.adapter.readers.cif.Cif2DataParser" : "javajs.util.CifDataParser"), 
this, "script"), rdr));
   }
 
   JmolStateCreator jsc;

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


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Jmol-commits mailing list
Jmol-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jmol-commits

Reply via email to