1 /* $RCSfile$
2  * $Author: hansonr $
3  * $Date: 2021-09-03 09:05:34 -0500 (Fri, 03 Sep 2021) $
4  * $Revision: 22225 $
5 
6  *
7  * Copyright (C) 2003-2005  Miguel, Jmol Development, www.jmol.org
8  *
9  * Contact: jmol-developers@lists.sf.net
10  *
11  *  This library is free software; you can redistribute it and/or
12  *  modify it under the terms of the GNU Lesser General Public
13  *  License as published by the Free Software Foundation; either
14  *  version 2.1 of the License, or (at your option) any later version.
15  *
16  *  This library is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  *  Lesser General Public License for more details.
20  *
21  *  You should have received a copy of the GNU Lesser General Public
22  *  License along with this library; if not, write to the Free Software
23  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 package org.jmol.viewer;
26 
27 import java.io.BufferedInputStream;
28 import java.io.InputStream;
29 import java.util.Hashtable;
30 import java.util.Map;
31 import java.util.Properties;
32 
33 import org.jmol.script.T;
34 import org.jmol.util.Elements;
35 import org.jmol.util.Logger;
36 
37 import javajs.util.PT;
38 import javajs.util.V3;
39 
40 import javajs.J2SIgnoreImport;
41 import javajs.J2SRequireImport;
42 
43 @J2SIgnoreImport({ java.util.Properties.class,
44     java.io.BufferedInputStream.class })
45 @J2SRequireImport({ javajs.util.SB.class })
46 public final class JC {
47 
48   public static final String NBO_TYPES = ";" + "AO;;;;" // 31
49       + "PNAO;;" // 32
50       + "NAO;;;" // 33
51       + "PNHO;;" // 34
52       + "NHO;;;" // 35
53       + "PNBO;;" // 36
54       + "NBO;;;" // 37
55       + "PNLMO;" // 38
56       + "NLMO;;" // 39
57       + "MO;;;;" // 40
58       + "NO;;;;" // 41
59       + ";;;;;;" // 42
60       + "PRNBO;" // 43
61       + "RNBO;;" // 44
62       + ";;;;;;" // 45
63       + "";
64 
getNBOTypeFromName(String nboType)65   public static int getNBOTypeFromName(String nboType) {
66     int pt = NBO_TYPES.indexOf(";" + nboType + ";");
67     return (pt < 0 ? pt : pt / 6 + 31);
68   }
69 
70   // requires 8 bits for rule and type:        rrrba*SR
71   public final static int CIP_CHIRALITY_UNKNOWN = 0;
72   public final static int CIP_CHIRALITY_R_FLAG = 1;
73   public final static int CIP_CHIRALITY_S_FLAG = 2;
74   public final static int CIP_CHIRALITY_CANTDETERMINE = 7;
75 
76   public final static int CIP_CHIRALITY_NONE = CIP_CHIRALITY_R_FLAG
77       | CIP_CHIRALITY_S_FLAG;
78   public final static int CIP_CHIRALITY_EZ_FLAG = 1 << 2; //  100
79   public final static int CIP_CHIRALITY_PSEUDO_FLAG = 1 << 3; //  1000
80   public final static int CIP_CHIRALITY_AXIAL_FLAG = 1 << 4; //  10000
81   public final static int CIP_CHIRALITY_NAME_MASK = 7 << 5; //11100000
82   public final static int CIP_CHIRALITY_NAME_OFFSET = 5;
83 
84   public final static int CIP_CHIRALITY_seqCis_FLAG = CIP_CHIRALITY_R_FLAG
85       | CIP_CHIRALITY_EZ_FLAG;
86   public final static int CIP_CHIRALITY_seqTrans_FLAG = CIP_CHIRALITY_S_FLAG
87       | CIP_CHIRALITY_EZ_FLAG;
88 
89   public final static int CIP_CHIRALITY_seqcis_FLAG = CIP_CHIRALITY_seqCis_FLAG
90       | CIP_CHIRALITY_PSEUDO_FLAG;
91   public final static int CIP_CHIRALITY_seqtrans_FLAG = CIP_CHIRALITY_seqTrans_FLAG
92       | CIP_CHIRALITY_PSEUDO_FLAG;
93 
94   public final static int CIP_CHIRALITY_M_FLAG = CIP_CHIRALITY_R_FLAG
95       | CIP_CHIRALITY_AXIAL_FLAG;
96   public final static int CIP_CHIRALITY_P_FLAG = CIP_CHIRALITY_S_FLAG
97       | CIP_CHIRALITY_AXIAL_FLAG;
98 
99   public final static int CIP_CHIRALITY_r_FLAG = CIP_CHIRALITY_R_FLAG
100       | CIP_CHIRALITY_PSEUDO_FLAG;
101   public final static int CIP_CHIRALITY_s_FLAG = CIP_CHIRALITY_S_FLAG
102       | CIP_CHIRALITY_PSEUDO_FLAG;
103   public final static int CIP_CHIRALITY_m_FLAG = CIP_CHIRALITY_M_FLAG
104       | CIP_CHIRALITY_PSEUDO_FLAG;
105   public final static int CIP_CHIRALITY_p_FLAG = CIP_CHIRALITY_P_FLAG
106       | CIP_CHIRALITY_PSEUDO_FLAG;
107 
getCIPChiralityName(int flags)108   public static String getCIPChiralityName(int flags) {
109     switch (flags) {
110     // going with ACD Labs idea E/Z and e/z, where e/z is the special case -- NOT pseudochiral
111     case CIP_CHIRALITY_seqcis_FLAG:
112       return "Z";
113     case CIP_CHIRALITY_seqCis_FLAG:
114       return "z";
115     case CIP_CHIRALITY_seqtrans_FLAG:
116       return "E";
117     case CIP_CHIRALITY_seqTrans_FLAG:
118       return "e";
119     case CIP_CHIRALITY_M_FLAG:
120       return "M";
121     case CIP_CHIRALITY_P_FLAG:
122       return "P";
123     case CIP_CHIRALITY_R_FLAG:
124       return "R";
125     case CIP_CHIRALITY_S_FLAG:
126       return "S";
127     case CIP_CHIRALITY_r_FLAG:
128       return "r";
129     case CIP_CHIRALITY_s_FLAG:
130       return "s";
131     case CIP_CHIRALITY_m_FLAG:
132       return "m";
133     case CIP_CHIRALITY_p_FLAG:
134       return "p";
135     case CIP_CHIRALITY_CANTDETERMINE:
136       return "?";
137     case CIP_CHIRALITY_NONE:
138     case CIP_CHIRALITY_UNKNOWN:
139     default:
140       return "";
141     }
142   }
143 
144   private static final String[] ruleNames = { "", "1a", "1b", "2", "3", "4a",
145       "4b", "4c", "5", "6" };
146 
getCIPRuleName(int i)147   public static String getCIPRuleName(int i) {
148     return ruleNames[i];
149   }
150 
getCIPChiralityCode(char c)151   public static int getCIPChiralityCode(char c) {
152     switch (c) {
153     case 'Z':
154       return CIP_CHIRALITY_seqcis_FLAG;
155     case 'z':
156       return CIP_CHIRALITY_seqCis_FLAG;
157     case 'E':
158       return CIP_CHIRALITY_seqtrans_FLAG;
159     case 'e':
160       return CIP_CHIRALITY_seqTrans_FLAG;
161     case 'R':
162       return CIP_CHIRALITY_R_FLAG;
163     case 'S':
164       return CIP_CHIRALITY_S_FLAG;
165     case 'r':
166       return CIP_CHIRALITY_r_FLAG;
167     case 's':
168       return CIP_CHIRALITY_s_FLAG;
169     case '?':
170       return CIP_CHIRALITY_CANTDETERMINE;
171     default:
172       return CIP_CHIRALITY_UNKNOWN;
173     }
174   }
175 
176   // axes mode constants --> org.jmol.constant.EnumAxesMode
177   // callback constants --> org.jmol.constant.EnumCallback
178   // draw constants --> org.jmol.shapespecial.draw.EnumCallback
179 
180   public static final String PDB_ANNOTATIONS = ";dssr;rna3d;dom;val;";
181 
182   public static final String CACTUS_FILE_TYPES = ";alc;cdxml;cerius;charmm;cif;cml;ctx;gjf;gromacs;hyperchem;jme;maestro;mol;mol2;sybyl2;mrv;pdb;sdf;sdf3000;sln;smiles;xyz";
183 
184   // note list of RCSB access points: http://www.rcsb.org/pdb/static.do?p=download/http/index.html
185 
186   public static final String defaultMacroDirectory = "https://chemapps.stolaf.edu/jmol/macros";
187 
188   private final static String[] databaseArray = {
189       // still http:
190       "aflowbin",
191       "http://aflowlib.mems.duke.edu/users/jmolers/binary_new/%FILE.aflow_binary",
192       "aflow",
193       "http://aflowlib.mems.duke.edu/users/jmolers/binary_new/%FILE.aflow_binary",
194       // _#DOCACHE_ flag indicates that the loaded file should be saved in any state in full
195       // ' at start indicates a Jmol script evaluation
196       "ams",
197       "'http://rruff.geo.arizona.edu/AMS/viewJmol.php?'+(0+'%file'==0? 'mineral':('%file'.length==7? 'amcsd':'id'))+'=%file&action=showcif#_DOCACHE_'",
198       "dssr", "http://dssr-jmol.x3dna.org/report.php?id=%FILE&opts=--json=ebi", //for debugging: -blocks",
199       "dssrModel",
200       "http://dssr-jmol.x3dna.org/report.php?POST?opts=--json=ebi&model=", // called in DSSR1.java
201       "iucr", "http://scripts.iucr.org/cgi-bin/sendcif_yard?%FILE", // e.g. wf5113sup1
202       "cod",
203       "http://www.crystallography.net/cod/cif/%c1/%c2%c3/%c4%c5/%FILE.cif",
204       "nmr", "https://www.nmrdb.org/new_predictor?POST?molfile=", "nmrdb",
205       "https://www.nmrdb.org/service/predictor?POST?molfile=", "nmrdb13",
206       "https://www.nmrdb.org/service/jsmol13c?POST?molfile=",
207       //"pdb", "http://ftp.wwpdb.org/pub/pdb/data/structures/divided/pdb/%c2%c3/pdb%file.ent.gz", // new Jmol 14.5.0 10/28/2015
208       "magndata", "http://webbdcrista1.ehu.es/magndata/mcif/%FILE.mcif",
209       "rna3d", "http://rna.bgsu.edu/rna3dhub/%TYPE/download/%FILE",
210       // now https:
211       "mmtf", "https://mmtf.rcsb.org/v1.0/full/%FILE", // new Jmol 14.5.4 4/2016
212       "chebi",
213       "https://www.ebi.ac.uk/chebi/saveStructure.do?defaultImage=true&chebiId=%file%2D%",
214       "ligand", "https://files.rcsb.org/ligands/download/%FILE.cif", "mp",
215       "https://www.materialsproject.org/materials/mp-%FILE/cif#_DOCACHE_", // e.g. https://materialsproject.org/rest/v1/materials/mp-24972/cif
216       "nci", "https://cactus.nci.nih.gov/chemical/structure",
217       "pdb", "https://files.rcsb.org/download/%FILE.pdb", // new Jmol 14.4.4 3/2016
218       "pdb0", "https://files.rcsb.org/download/%FILE.pdb", // used in JSmol
219       "pdbe", "https://www.ebi.ac.uk/pdbe/entry-files/download/%FILE.cif",
220       "pdbe2", "https://www.ebi.ac.uk/pdbe/static/entry/%FILE_updated.cif",
221       "pubchem", "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/%FILE/SDF?record_type=3d",
222       "map", "https://www.ebi.ac.uk/pdbe/api/%TYPE/%FILE?pretty=false&metadata=true",
223       "pdbemap", "https://www.ebi.ac.uk/pdbe/coordinates/files/%file.ccp4",
224       "pdbemapdiff", "https://www.ebi.ac.uk/pdbe/coordinates/files/%file_diff.ccp4",
225       "pdbemapserver", "https://www.ebi.ac.uk/pdbe/densities/x-ray/%file/box/0,0,0/0,0,0?detail=6&space=cartesian&encoding=bcif",
226       "pdbemapdiffserver", "https://www.ebi.ac.uk/pdbe/densities/x-ray/%file/box/0,0,0/0,0,0?detail=6&space=cartesian&encoding=bcif&diff=1", // last bit is just mine
227       //"emdbmap", "https://ftp.ebi.ac.uk/pub/databases/emdb/structures/EMD-%file/map/emd_%file.map.gz", // https did not work in Java due to certificate issues
228       // was considerably slower
229       "emdbmap", "https://www.ebi.ac.uk/pdbe/densities/emd/emd-%file/cell?detail=6&space=cartesian&encoding=bcif",
230       "emdbquery", "https://www.ebi.ac.uk/emdb/api/search/fitted_pdbs:%file?fl=emdb_id,map_contour_level_value&wt=csv", // to get the EMDB id from the PDB id
231       "emdbmapserver", "https://www.ebi.ac.uk/pdbe/densities/emd/emd-%file/box/0,0,0/0,0,0?detail=6&space=cartesian&encoding=bcif",
232       "resolverResolver", "https://chemapps.stolaf.edu/resolver",
233   };
234 
235   final static String legacyResolver = "cactus.nci.nih.gov/chemical/structure";
236 
237   final static Map<String, String> databases = new Hashtable<String, String>();
238 
239   static {
240     for (int i = 0; i < databaseArray.length; i += 2)
databases.put(databaseArray[i].toLowerCase(), databaseArray[i + 1])241       databases.put(databaseArray[i].toLowerCase(), databaseArray[i + 1]);
242   }
243 
resolveDataBase(String database, String id, String format)244   static String resolveDataBase(String database, String id, String format) {
245     if (format == null) {
246       if ((format = databases.get(database.toLowerCase())) == null)
247         return null;
248       int pt = id.indexOf("/");
249       if (pt < 0) {
250         if (database.equals("pubchem"))
251           id = "name/" + id;
252         else if (database.equals("nci"))
253           id += "/file?format=sdf&get3d=true";
254       }
255       if (format.startsWith("'")) {
256         // needs evaluation
257         // xxxx.n means "the nth item"
258         pt = id.indexOf(".");
259         int n = (pt > 0 ? PT.parseInt(id.substring(pt + 1)) : 0);
260         if (pt > 0)
261           id = id.substring(0, pt);
262         format = PT.rep(format, "%n", "" + n);
263       }
264     } else if (id.indexOf(".") >= 0 && format.indexOf("%FILE.") >= 0) {
265       // replace RCSB format extension when a file extension is made explicit
266       format = format.substring(0, format.indexOf("%FILE"));
267     }
268     if (format.indexOf("%c") >= 0)
269       for (int i = 1, n = id.length(); i <= n; i++)
270         if (format.indexOf("%c" + i) >= 0)
271           format = PT.rep(format, "%c" + i,
272               id.substring(i - 1, i).toLowerCase());
273     return (format.indexOf("%FILE") >= 0 ? PT.rep(format, "%FILE", id)
274         : format.indexOf("%file") >= 0
275             ? PT.rep(format, "%file", id.toLowerCase())
276             : format + id);
277   }
278 
279   /**
280    * Check for databases that have changed from http:// to https:// over time.
281    * We substitute https here in case this is from an old reference.
282    *
283    * @param name
284    * @return https protocol if necessary
285    */
fixProtocol(String name)286   static String fixProtocol(String name) {
287     String newname = (name == null ? null
288         : name.indexOf("http://www.rcsb.org/pdb/files/") == 0
289             ? resolveDataBase(name.indexOf("/ligand/") >= 0 ? "ligand" : "pdb",
290                 name.substring(name.lastIndexOf("/") + 1), null)
291             : name.indexOf("http://www.ebi") == 0
292                 || name.indexOf("http://pubchem") == 0
293                 || name.indexOf("http://cactus") == 0
294                 || name.indexOf("http://www.materialsproject") == 0
295                     ? "https://" + name.substring(7)
296                     : name);
297     if (newname != name)
298       Logger.info("JC.fixProtocol " + name + " --> " + newname);
299     return newname;
300   }
301 
302   public static String[] macros = { "aflow",
303       "https://chemapps.stolaf.edu/jmol/macros/AFLOW.spt", "AFLOW macros", "bz",
304       "https://chemapps.stolaf.edu/jmol/macros/bz.spt",
305       "Brillouin Zone/Wigner-Seitz macros", "topology",
306       "https://chemapps.stolaf.edu/jmol/macros/topology.spt",
307       "Topology CIF macros", "topond",
308       "https://chemapps.stolaf.edu/jmol/macros/topond.spt",
309       "CRYSTAL/TOPOND macros", "crystal",
310       "https://chemapps.stolaf.edu/jmol/macros/crystal.spt", "CRYSTAL macros" };
311 
312   // unused
313 
314   //  public static String[] macros = {
315   //    "aflow",       "https://chemapps.stolaf.edu/jmol/macros/AFLOW.spt", "AFLOW macros",
316   //    "bz",          "https://chemapps.stolaf.edu/jmol/macros/bz.spt", "Brillouin Zone/Wigner-Seitz macros",
317   //    "topology",    "https://chemapps.stolaf.edu/jmol/macros/topology.spt", "Topology CIF macros",
318   //    "topond",      "https://chemapps.stolaf.edu/jmol/macros/topond.spt", "CRYSTAL/TOPOND macros",
319   //    "crystal",     "https://chemapps.stolaf.edu/jmol/macros/crystal.spt", "CRYSTAL macros"
320   //  };
321   //
322   //  public static String getMacroList() {
323   //    SB s = new SB();
324   //    for (int i = 0; i < macros.length; i += 3)
325   //      s.append(macros[i]).append("\t").append(macros[i + 1]).append("\t").append(macros[i + 1]).append("\n");
326   //    return s.toString();
327   //  }
328   //
329   //
330   //  public static String getMacro(String key) {
331   //    for (int i = 0; i < macros.length; i += 3)
332   //      if (macros[i].equals(key))
333   //        return macros[i + 1];
334   //    return null;
335   //  }
336 
337   public final static String copyright = "(C) 2015 Jmol Development";
338 
339   public final static String version;
340   public static String majorVersion;
341   public final static String date;
342   public final static int versionInt;
343 
344   static {
345     String tmpVersion = null;
346     String tmpDate = null;
347 
348     /**
349      * definitions are incorporated into j2s/java/core.z.js by buildtojs.xml
350      *
351      * @j2sNative
352      *
353      *            tmpVersion = Jmol.___JmolVersion; tmpDate = Jmol.___JmolDate;
354      */
355     {
356       BufferedInputStream bis = null;
357       InputStream is = null;
358       try {
359         // Reading version from resource   inside jar
360         is = JC.class.getClassLoader()
361             .getResourceAsStream("org/jmol/viewer/Jmol.properties");
362         bis = new BufferedInputStream(is);
363         Properties props = new Properties();
364         props.load(bis);
365         String s = props.getProperty("Jmol.___JmolVersion", tmpVersion);
366         if (s != null && s.lastIndexOf("\"") > 0)
367           s = s.substring(0, s.lastIndexOf("\"") + 1);
368         tmpVersion = PT.trimQuotes(s);
369         tmpDate = PT.trimQuotes(props.getProperty("Jmol.___JmolDate", tmpDate));
370       } catch (Exception e) {
371         // Nothing to do
372       } finally {
373         if (bis != null) {
374           try {
bis.close()375             bis.close();
376           } catch (Exception e) {
377             // Nothing to do
378           }
379         }
380         if (is != null) {
381           try {
is.close()382             is.close();
383           } catch (Exception e) {
384             // Nothing to do
385           }
386         }
387       }
388     }
389     if (tmpDate != null) {
390       tmpDate = tmpDate.substring(7, 23);
391       // NOTE : date is updated in the properties by SVN, and is in the format
392       // "$Date: 2021-09-03 09:05:34 -0500 (Fri, 03 Sep 2021) $"
393       //  0         1         2
394       //  012345678901234567890123456789
395     }
396     version = (tmpVersion != null ? tmpVersion : "(Unknown_version)");
397     majorVersion = (tmpVersion != null ? tmpVersion : "(Unknown_version)");
398     date = (tmpDate != null ? tmpDate : "(Unknown_date)");
399     // 11.9.999 --> 1109999
400     int v = -1;
401     try {
402       String s = version;
403       String major = "";
404       // Major number
405       int i = s.indexOf(".");
406       if (i < 0) {
407         v = 100000 * Integer.parseInt(s);
408         s = null;
409       }
410       if (s != null) {
411         v = 100000 * Integer.parseInt(major = s.substring(0, i));
412 
413         // Minor number
414         s = s.substring(i + 1);
415         i = s.indexOf(".");
416         if (i < 0) {
417           v += 1000 * Integer.parseInt(s);
418           s = null;
419         }
420         if (s != null) {
421           String m = s.substring(0, i);
422           major += "." + m;
423           majorVersion = major;
424           v += 1000 * Integer.parseInt(m);
425 
426           // Revision number
427           s = s.substring(i + 1);
428           i = s.indexOf("_");
429           if (i >= 0)
430             s = s.substring(0, i);
431           i = s.indexOf(" ");
432           if (i >= 0)
433             s = s.substring(0, i);
434           v += Integer.parseInt(s);
435         }
436       }
437     } catch (NumberFormatException e) {
438       // We simply keep the version currently found
439     }
440     versionInt = v;
441   }
442 
443   public final static boolean officialRelease = false;
444 
445   public final static String DEFAULT_HELP_PATH = "https://chemapps.stolaf.edu/jmol/docs/index.htm";
446 
447   public final static String STATE_VERSION_STAMP = "# Jmol state version ";
448 
449   public final static String EMBEDDED_SCRIPT_TAG = "**** Jmol Embedded Script ****";
450 
embedScript(String s)451   public static String embedScript(String s) {
452     return "\n/**" + EMBEDDED_SCRIPT_TAG + " \n" + s + "\n**/";
453   }
454 
455   public final static String NOTE_SCRIPT_FILE = "NOTE: file recognized as a script file: ";
456 
457   public final static String SCRIPT_EDITOR_IGNORE = "\1## EDITOR_IGNORE ##";
458   public final static String REPAINT_IGNORE = "\1## REPAINT_IGNORE ##";
459 
460   public final static String LOAD_ATOM_DATA_TYPES = ";xyz;vxyz;vibration;temperature;occupancy;partialcharge;";
461 
462   public final static float radiansPerDegree = (float) (Math.PI / 180);
463 
464   public final static String allowedQuaternionFrames = "RC;RP;a;b;c;n;p;q;x;";
465 
466   //note: Eval.write() processing requires drivers to be first-letter-capitalized.
467   //do not capitalize any other letter in the word. Separate by semicolon.
468   public final static String EXPORT_DRIVER_LIST = "Idtf;Maya;Povray;Vrml;X3d;Stl;Tachyon;Obj";
469 
470   public final static V3 center = V3.new3(0, 0, 0);
471   public final static V3 axisX = V3.new3(1, 0, 0);
472   public final static V3 axisY = V3.new3(0, 1, 0);
473   public final static V3 axisZ = V3.new3(0, 0, 1);
474   public final static V3 axisNX = V3.new3(-1, 0, 0);
475   public final static V3 axisNY = V3.new3(0, -1, 0);
476   public final static V3 axisNZ = V3.new3(0, 0, -1);
477   public final static V3[] unitAxisVectors = { axisX, axisY, axisZ, axisNX,
478       axisNY, axisNZ };
479 
480   public final static int XY_ZTOP = 100; // Z value for [x y] positioned echos and axis origin
481   public final static int DEFAULT_PERCENT_VDW_ATOM = 23; // matches C sizes of AUTO with 20 for Jmol set
482   public final static float DEFAULT_BOND_RADIUS = 0.15f;
483   public final static short DEFAULT_BOND_MILLIANGSTROM_RADIUS = (short) (DEFAULT_BOND_RADIUS
484       * 1000);
485   public final static float DEFAULT_STRUT_RADIUS = 0.3f;
486   //angstroms of slop ... from OpenBabel ... mth 2003 05 26
487   public final static float DEFAULT_BOND_TOLERANCE = 0.45f;
488   //minimum acceptable bonding distance ... from OpenBabel ... mth 2003 05 26
489   public final static float DEFAULT_MIN_BOND_DISTANCE = 0.4f;
490   public final static float DEFAULT_MAX_CONNECT_DISTANCE = 100000000f;
491   public final static float DEFAULT_MIN_CONNECT_DISTANCE = 0.1f;
492   public final static float MINIMIZE_FIXED_RANGE = 5.0f;
493 
494   public final static float ENC_CALC_MAX_DIST = 3f;
495   public final static int ENV_CALC_MAX_LEVEL = 3;//Geodesic.standardLevel;
496 
497   public final static int MOUSE_NONE = -1;
498 
499   public final static byte MULTIBOND_NEVER = 0;
500   public final static byte MULTIBOND_WIREFRAME = 1;
501   public final static byte MULTIBOND_NOTSMALL = 2;
502   public final static byte MULTIBOND_ALWAYS = 3;
503 
504   // maximum number of bonds that an atom can have when
505   // autoBonding
506   // All bonding is done by distances
507   // this is only here for truly pathological cases
508   public final static int MAXIMUM_AUTO_BOND_COUNT = 20;
509 
510   public final static short madMultipleBondSmallMaximum = 500;
511 
512   /* .cube files need this */
513   public final static float ANGSTROMS_PER_BOHR = 0.5291772f;
514 
515   public final static int[] altArgbsCpk = { 0xFFFF1493, // Xx 0
516       0xFFBFA6A6, // Al 13
517       0xFFFFFF30, // S  16
518       0xFF57178F, // Cs 55
519       0xFFFFFFC0, // D 2H
520       0xFFFFFFA0, // T 3H
521       0xFFD8D8D8, // 11C  6 - lighter
522       0xFF505050, // 13C  6 - darker
523       0xFF404040, // 14C  6 - darker still
524       0xFF105050, // 15N  7 - darker
525   };
526 
527   // hmmm ... what is shapely backbone? seems interesting
528   //public final static int argbShapelyBackbone = 0xFFB8B8B8;
529   //public final static int argbShapelySpecial =  0xFF5E005E;
530   //public final static int argbShapelyDefault =  0xFFFF00FF;
531 
532   public final static int[] argbsFormalCharge = { 0xFFFF0000, // -4
533       0xFFFF4040, // -3
534       0xFFFF8080, // -2
535       0xFFFFC0C0, // -1
536       0xFFFFFFFF, // 0
537       0xFFD8D8FF, // 1
538       0xFFB4B4FF, // 2
539       0xFF9090FF, // 3
540       0xFF6C6CFF, // 4
541       0xFF4848FF, // 5
542       0xFF2424FF, // 6
543       0xFF0000FF, // 7
544   };
545 
546   public final static int[] argbsRwbScale = { 0xFFFF0000, // red
547       0xFFFF1010, //
548       0xFFFF2020, //
549       0xFFFF3030, //
550       0xFFFF4040, //
551       0xFFFF5050, //
552       0xFFFF6060, //
553       0xFFFF7070, //
554       0xFFFF8080, //
555       0xFFFF9090, //
556       0xFFFFA0A0, //
557       0xFFFFB0B0, //
558       0xFFFFC0C0, //
559       0xFFFFD0D0, //
560       0xFFFFE0E0, //
561       0xFFFFFFFF, // white
562       0xFFE0E0FF, //
563       0xFFD0D0FF, //
564       0xFFC0C0FF, //
565       0xFFB0B0FF, //
566       0xFFA0A0FF, //
567       0xFF9090FF, //
568       0xFF8080FF, //
569       0xFF7070FF, //
570       0xFF6060FF, //
571       0xFF5050FF, //
572       0xFF4040FF, //
573       0xFF3030FF, //
574       0xFF2020FF, //
575       0xFF1010FF, //
576       0xFF0000FF, // blue
577   };
578 
579   public final static int FORMAL_CHARGE_COLIX_RED = Elements.elementSymbols.length
580       + altArgbsCpk.length;
581   public final static int PARTIAL_CHARGE_COLIX_RED = FORMAL_CHARGE_COLIX_RED
582       + argbsFormalCharge.length;
583   public final static int PARTIAL_CHARGE_RANGE_SIZE = argbsRwbScale.length;
584 
585   //  $ print  color("red","blue", 33,true)
586   //  [xff0000][xff2000][xff4000]
587   //[xff6000][xff8000][xff9f00]
588 
589   //[xffbf00][xffdf00] -------
590   //[xffff00] ------- [xdfff00]
591 
592   //[xbfff00][x9fff00][x7fff00]
593   //[x60ff00][x40ff00][x20ff00]
594   //[x00ff00][x00ff20][x00ff40]
595   //[x00ff60][x00ff7f][x00ff9f]
596   //[x00ffbf][x00ffdf][x00ffff]
597   //[x00dfff][x00bfff][x009fff]
598   //[x0080ff][x0060ff][x0040ff]
599   //[x0020ff][x0000ff]
600 
601   public final static int[] argbsRoygbScale = {
602       // 35 in all //why this comment?: must be multiple of THREE for high/low
603       0xFFFF0000, 0xFFFF2000, 0xFFFF4000, 0xFFFF6000, 0xFFFF8000, 0xFFFFA000,
604 
605       // yellow gets compressed, so give it an extra boost
606 
607       0xFFFFC000, 0xFFFFE000, 0xFFFFF000, 0xFFFFFF00, 0xFFF0F000, 0xFFE0FF00,
608 
609       0xFFC0FF00, 0xFFA0FF00, 0xFF80FF00, 0xFF60FF00, 0xFF40FF00, 0xFF20FF00,
610       0xFF00FF00, 0xFF00FF20, 0xFF00FF40, 0xFF00FF60, 0xFF00FF80, 0xFF00FFA0,
611       0xFF00FFC0, 0xFF00FFE0, 0xFF00FFFF, 0xFF00E0FF, 0xFF00C0FF, 0xFF00A0FF,
612       0xFF0080FF, 0xFF0060FF, 0xFF0040FF, 0xFF0020FF, 0xFF0000FF, };
613 
614   // positive and negative default colors used for
615   // isosurface rendering of .cube files
616   // multiple colors removed -- RMH 3/2008 11.1.28
617 
618   public final static int argbsIsosurfacePositive = 0xFF5020A0;
619   public final static int argbsIsosurfaceNegative = 0xFFA02050;
620 
621   ////////////////////////////////////////////////////////////////
622   // currently, ATOMIDs must be >= 0 && <= 127
623   // if we need more then we can go to 255 by:
624   //  1. applying 0xFF mask ... as in atom.specialAtomID & 0xFF;
625   //  2. change the interesting atoms table to be shorts
626   //     so that we can store negative numbers
627   ////////////////////////////////////////////////////////////////
628 
629   ////////////////////////////////////////////////////////////////
630   // keep this table in order to make it easier to maintain
631   ////////////////////////////////////////////////////////////////
632 
633   // the following refer to jmol.biomodelset.Resolver.specialAtomNames
634 
635   // atomID 0 => nothing special, just an ordinary atom
636   public final static byte ATOMID_AMINO_NITROGEN = 1;
637   public final static byte ATOMID_ALPHA_CARBON = 2;
638   public final static byte ATOMID_CARBONYL_CARBON = 3;
639   public final static byte ATOMID_CARBONYL_OXYGEN = 4;
640   public final static byte ATOMID_O1 = 5;
641 
642   // this is for groups that only contain an alpha carbon
643   public final static int ATOMID_ALPHA_ONLY_MASK = 1 << ATOMID_ALPHA_CARBON;
644 
645   //this is entries 1 through 3 ... 3 bits ... N, CA, C
646   public final static int ATOMID_PROTEIN_MASK = 0x7 << ATOMID_AMINO_NITROGEN;
647 
648   public final static byte ATOMID_O5_PRIME = 6;
649   public final static byte ATOMID_C5_PRIME = 7;
650   public final static byte ATOMID_C4_PRIME = 8;
651   public final static byte ATOMID_C3_PRIME = 9;
652   public final static byte ATOMID_O3_PRIME = 10;
653   public final static byte ATOMID_C2_PRIME = 11;
654   public final static byte ATOMID_C1_PRIME = 12;
655   public final static byte ATOMID_O4_PRIME = 78;
656 
657   // this is entries 6 through through 12 ... 7 bits
658   public final static int ATOMID_NUCLEIC_MASK = 0x7F << ATOMID_O5_PRIME;
659 
660   public final static byte ATOMID_NUCLEIC_PHOSPHORUS = 13;
661 
662   // this is for nucleic groups that only contain a phosphorus
663   public final static int ATOMID_PHOSPHORUS_ONLY_MASK = 1 << ATOMID_NUCLEIC_PHOSPHORUS;
664 
665   // this can be increased as far as 32, but not higher.
666   public final static int ATOMID_DISTINGUISHING_ATOM_MAX = 14;
667 
668   public final static byte ATOMID_CARBONYL_OD1 = 14;
669   public final static byte ATOMID_CARBONYL_OD2 = 15;
670   public final static byte ATOMID_CARBONYL_OE1 = 16;
671   public final static byte ATOMID_CARBONYL_OE2 = 17;
672   //public final static byte ATOMID_SG = 18;
673 
674   public final static byte ATOMID_N1 = 32;
675   public final static byte ATOMID_C2 = 33;
676   public final static byte ATOMID_N3 = 34;
677   public final static byte ATOMID_C4 = 35;
678   public final static byte ATOMID_C5 = 36;
679   public final static byte ATOMID_C6 = 37; // wing
680   public final static byte ATOMID_O2 = 38;
681   public final static byte ATOMID_N7 = 39;
682   public final static byte ATOMID_C8 = 40;
683   public final static byte ATOMID_N9 = 41;
684   public final static byte ATOMID_N4 = 42;
685   public final static byte ATOMID_N2 = 43;
686   public final static byte ATOMID_N6 = 44;
687   public final static byte ATOMID_C5M = 45;
688   public final static byte ATOMID_O6 = 46;
689   public final static byte ATOMID_O4 = 47;
690   public final static byte ATOMID_S4 = 48;
691   public final static byte ATOMID_C7 = 49;
692 
693   public final static byte ATOMID_TERMINATING_OXT = 64;
694 
695   public final static byte ATOMID_H5T_TERMINUS = 72;
696   public final static byte ATOMID_O5T_TERMINUS = 73;
697   public final static byte ATOMID_O1P = 74;
698   public final static byte ATOMID_OP1 = 75;
699   public final static byte ATOMID_O2P = 76;
700   public final static byte ATOMID_OP2 = 77;
701   public final static byte ATOMID_O2_PRIME = 79;
702   public final static byte ATOMID_H3T_TERMINUS = 88;
703   public final static byte ATOMID_HO3_PRIME = 89;
704   public final static byte ATOMID_HO5_PRIME = 90;
705 
706   // These masks are only used for P-only and N-only polymers
707   // or cases where there are so few atoms that a monomer's type
708   // cannot be determined by checking actual atoms and connections.
709   // They are not used for NucleicMonomer or AminoMonomer classes.
710   //
711   //             I  A G
712   //   purine:   100101 = 0x25
713   //
714   //              UT C
715   // pyrimidine: 011010 = 0x1A
716   //
717   //            +IUTACGDIUTACG IUTACG
718   //        dna: 001111 111111 001000 = 0x0FFC8
719   //
720   //            +IUTACGDIUTACG IUTACG
721   //        rna: 110??? 000000 110111 = 0x30037
722 
723   public static final int PURINE_MASK = 0x25 | (0x25 << 6) | (0x25 << 12);
724   public static final int PYRIMIDINE_MASK = 0x1A | (0x1A << 6) | (0x1A << 12);
725   public static final int DNA_MASK = 0x0FFC8;
726   public static final int RNA_MASK = 0x30037;
727 
728   ////////////////////////////////////////////////////////////////
729   // GROUP_ID related stuff for special groupIDs
730   ////////////////////////////////////////////////////////////////
731 
732   public final static int GROUPID_ARGININE = 2;
733   public final static int GROUPID_ASPARAGINE = 3;
734   public final static int GROUPID_ASPARTATE = 4;
735   public final static int GROUPID_CYSTEINE = 5;
736   public final static int GROUPID_GLUTAMINE = 6;
737   public final static int GROUPID_GLUTAMATE = 7;
738   public final static int GROUPID_HISTIDINE = 9;
739   public final static int GROUPID_LYSINE = 12;
740   public final static int GROUPID_PROLINE = 15;
741   public final static int GROUPID_TRYPTOPHAN = 19;
742   public final static int GROUPID_AMINO_MAX = 24;
743   public final static int GROUPID_NUCLEIC_MAX = 42;
744   public final static int GROUPID_WATER = 42;
745   public final static int GROUPID_SOLVENT_MIN = 45; // urea only
746   private final static int GROUPID_ION_MIN = 46;
747   private final static int GROUPID_ION_MAX = 48;
748 
749   ////////////////////////////////////////////////////////////////
750   // predefined sets
751   ////////////////////////////////////////////////////////////////
752 
753   // these must be removed after various script commands so that they stay current
754 
755   public static String[] predefinedVariable = {
756       //
757       // main isotope (variable because we can do {xxx}.element = n;
758       //
759       "@_1H _H & !(_2H,_3H)", "@_12C _C & !(_13C,_14C)", "@_14N _N & !(_15N)",
760 
761       //
762       // solvent
763       //
764       // @water is specially defined, avoiding the CONNECTED() function
765       //"@water _g>=" + GROUPID_WATER + " & _g<" + GROUPID_SOLVENT_MIN
766       //+ ", oxygen & connected(2) & connected(2, hydrogen), (hydrogen) & connected(oxygen & connected(2) & connected(2, hydrogen))",
767 
768       "@solvent water, (_g>=" + GROUPID_SOLVENT_MIN + " & _g<" + GROUPID_ION_MAX
769           + ")", // water, other solvent or ions
770       "@ligand _g=0|!(_g<" + GROUPID_ION_MIN + ",protein,nucleic,water)", // includes UNL
771 
772       // protein structure
773       "@turn structure=1", "@sheet structure=2", "@helix structure=3",
774       "@helix310 substructure=7", "@helixalpha substructure=8",
775       "@helixpi substructure=9",
776 
777       // nucleic acid structures
778       "@bulges within(dssr,'bulges')", "@coaxStacks within(dssr,'coaxStacks')",
779       "@hairpins within(dssr,'hairpins')", "@hbonds within(dssr,'hbonds')",
780       "@helices within(dssr,'helices')", "@iloops within(dssr,'iloops')",
781       "@isoCanonPairs within(dssr,'isoCanonPairs')",
782       "@junctions within(dssr,'junctions')",
783       "@kissingLoops within(dssr,'kissingLoops')",
784       "@multiplets within(dssr,'multiplets')",
785       "@nonStack within(dssr,'nonStack')", "@nts within(dssr,'nts')",
786       "@pairs within(dssr,'pairs')", "@ssSegments within(dssr,'ssSegments')",
787       "@stacks within(dssr,'stacks')", "@stems within(dssr,'stems')",
788 
789   };
790 
791   // these are only updated once per file load or file append
792 
793   public static String[] predefinedStatic = {
794       //
795       // protein related
796       //
797       // protein is hardwired
798       "@amino _g>0 & _g<=23", "@acidic asp,glu", "@basic arg,his,lys",
799       "@charged acidic,basic", "@negative acidic", "@positive basic",
800       "@neutral amino&!(acidic,basic)", "@polar amino&!hydrophobic",
801       "@peptide protein&within(chain,monomer>1)&!within(chain,monomer>12)", // Jmol 14.29.1
802       "@cyclic his,phe,pro,trp,tyr", "@acyclic amino&!cyclic",
803       "@aliphatic ala,gly,ile,leu,val", "@aromatic his,phe,trp,tyr",
804       "@cystine within(group,(cys,cyx)&atomname=sg&connected((cys,cyx)&atomname=sg))",
805 
806       "@buried ala,cys,ile,leu,met,phe,trp,val", "@surface amino&!buried",
807 
808       // doc on hydrophobic is inconsistent
809       // text description of hydrophobic says this
810       //    "@hydrophobic ala,leu,val,ile,pro,phe,met,trp",
811       // table says this
812       "@hydrophobic ala,gly,ile,leu,met,phe,pro,trp,tyr,val",
813       "@mainchain backbone", "@small ala,gly,ser",
814       "@medium asn,asp,cys,pro,thr,val",
815       "@large arg,glu,gln,his,ile,leu,lys,met,phe,trp,tyr",
816 
817       //
818       // nucleic acid related
819 
820       // nucleic, dna, rna, purine, pyrimidine are hard-wired
821       //
822       "@c nucleic & ([C] or [DC] or within(group,_a=" + ATOMID_N4 + "))",
823       "@g nucleic & ([G] or [DG] or within(group,_a=" + ATOMID_N2 + "))",
824       "@cg c,g",
825       "@a nucleic & ([A] or [DA] or within(group,_a=" + ATOMID_N6 + "))",
826       "@t nucleic & ([T] or [DT] or within(group,_a=" + ATOMID_C5M + " | _a="
827           + ATOMID_C7 + "))",
828       "@at a,t",
829       "@i nucleic & ([I] or [DI] or within(group,_a=" + ATOMID_O6 + ") & !g)",
830       "@u nucleic & ([U] or [DU] or within(group,_a=" + ATOMID_O4 + ") & !t)",
831       "@tu nucleic & within(group,_a=" + ATOMID_S4 + ")",
832 
833       //
834       // ions
835       //
836       "@ions _g>=" + GROUPID_ION_MIN + "&_g<" + GROUPID_ION_MAX,
837 
838       //
839       // structure related
840       //
841       "@alpha _a=2", // rasmol doc says "approximately *.CA" - whatever?
842       "@_bb protein&(_a>=1&_a<6|_a=64) | nucleic&(_a>=6&_a<14|_a>=73&&_a<=79||_a==99||_a=100)", // no H atoms
843       "@backbone _bb | _H && connected(single, _bb)",
844       "@spine protein&_a>=1&_a<4|nucleic&(_a>=6&_a<11|_a=13)",
845       "@sidechain (protein,nucleic) & !backbone", "@base nucleic & !backbone",
846       "@dynamic_flatring search('[a]')",
847 
848       //periodic table
849       "@nonmetal _H,_He,_B,_C,_N,_O,_F,_Ne,_Si,_P,_S,_Cl,_Ar,_As,_Se,_Br,_Kr,_Te,_I,_Xe,_At,_Rn",
850       "@metal !nonmetal && !_Xx",
851       "@alkaliMetal _Li,_Na,_K,_Rb,_Cs,_Fr",
852       "@alkalineEarth _Be,_Mg,_Ca,_Sr,_Ba,_Ra",
853       "@nobleGas _He,_Ne,_Ar,_Kr,_Xe,_Rn", "@metalloid _B,_Si,_Ge,_As,_Sb,_Te",
854       // added La, Ac as per Frank Weinhold - these two are not f-block
855       "@transitionMetal elemno>=21&elemno<=30|elemno=57|elemno=89|elemno>=39&elemno<=48|elemno>=72&elemno<=80|elemno>=104&elemno<=112",
856       // removed La
857       "@lanthanide elemno>57&elemno<=71",
858       // removed Ac
859       "@actinide elemno>89&elemno<=103",
860 
861       //    "@hetero", handled specially
862 
863   };
864 
865   public final static String MODELKIT_ZAP_STRING = "5\n\nC 0 0 0\nH .63 .63 .63\nH -.63 -.63 .63\nH -.63 .63 -.63\nH .63 -.63 -.63";
866   public final static String MODELKIT_ZAP_TITLE = "Jmol Model Kit";//do not ever change this -- it is in the state
867   public final static String ZAP_TITLE = "zapped";//do not ever change this -- it is in the state
868   public final static String ADD_HYDROGEN_TITLE = "Viewer.AddHydrogens"; //do not ever change this -- it is in the state
869 
870   ////////////////////////////////////////////////////////////////
871   // font-related
872   ////////////////////////////////////////////////////////////////
873 
874   public final static String DEFAULT_FONTFACE = "SansSerif";
875   public final static String DEFAULT_FONTSTYLE = "Plain";
876 
877   public final static int MEASURE_DEFAULT_FONTSIZE = 18;
878   public final static int AXES_DEFAULT_FONTSIZE = 16;
879 
880   ////////////////////////////////////////////////////////////////
881   // do not rearrange/modify these shapes without
882   // updating the String[] shapeBaseClasses below &&
883   // also creating a token for this shape in Token.java &&
884   // also updating shapeToks to confirm consistent
885   // conversion from tokens to shapes
886   ////////////////////////////////////////////////////////////////
887 
888   public final static int SHAPE_BALLS = 0;
889   public final static int SHAPE_STICKS = 1;
890   public final static int SHAPE_HSTICKS = 2; //placeholder only; handled by SHAPE_STICKS
891   public final static int SHAPE_SSSTICKS = 3; //placeholder only; handled by SHAPE_STICKS
892   public final static int SHAPE_STRUTS = 4; //placeholder only; handled by SHAPE_STICKS
893   public final static int SHAPE_LABELS = 5;
894   public final static int SHAPE_MEASURES = 6;
895   public final static int SHAPE_STARS = 7;
896 
897   public final static int SHAPE_MIN_HAS_SETVIS = 8;
898 
899   public final static int SHAPE_HALOS = 8;
900 
901   public final static int SHAPE_MIN_SECONDARY = 9; //////////
902 
903   public final static int SHAPE_BACKBONE = 9;
904   public final static int SHAPE_TRACE = 10;
905   public final static int SHAPE_CARTOON = 11;
906   public final static int SHAPE_STRANDS = 12;
907   public final static int SHAPE_MESHRIBBON = 13;
908   public final static int SHAPE_RIBBONS = 14;
909   public final static int SHAPE_ROCKETS = 15;
910 
911   public final static int SHAPE_MAX_SECONDARY = 16; //////////
912   public final static int SHAPE_MIN_SPECIAL = 16; //////////
913 
914   public final static int SHAPE_DOTS = 16;
915   public final static int SHAPE_DIPOLES = 17;
916   public final static int SHAPE_VECTORS = 18;
917   public final static int SHAPE_GEOSURFACE = 19;
918   public final static int SHAPE_ELLIPSOIDS = 20;
919 
920   public final static int SHAPE_MAX_SIZE_ZERO_ON_RESTRICT = 21; //////////
921 
922   public final static int SHAPE_MIN_HAS_ID = 21; //////////
923 
924   public final static int SHAPE_POLYHEDRA = 21; // for restrict, uses setProperty(), not setSize()
925 
926   public final static int SHAPE_DRAW = 22;
927 
928   public final static int SHAPE_MAX_SPECIAL = 23; //////////
929 
930   public final static int SHAPE_CGO = 23;
931 
932   public final static int SHAPE_MIN_SURFACE = 24; //////////
933 
934   public final static int SHAPE_ISOSURFACE = 24;
935   public final static int SHAPE_CONTACT = 25;
936 
937   public final static int SHAPE_LCAOCARTOON = 26;
938 
939   private final static int SHAPE_LAST_ATOM_VIS_FLAG = 26; // LCAO
940   // no setting of atom.shapeVisibilityFlags after this point
941 
942   public final static int SHAPE_MO = 27; //but no ID for MO
943   public final static int SHAPE_NBO = 28; //but no ID for MO
944 
945   public final static int SHAPE_PMESH = 29;
946   public final static int SHAPE_PLOT3D = 30;
947 
948   public final static int SHAPE_MAX_SURFACE = 30; //////////
949   public final static int SHAPE_MAX_MESH_COLLECTION = 30; //////////
950 
951   public final static int SHAPE_ECHO = 31;
952 
953   public final static int SHAPE_MAX_HAS_ID = 32;
954 
955   public final static int SHAPE_BBCAGE = 32;
956 
957   public final static int SHAPE_MAX_HAS_SETVIS = 33;
958 
959   public final static int SHAPE_UCCAGE = 33;
960   public final static int SHAPE_AXES = 34;
961   public final static int SHAPE_HOVER = 35;
962   public final static int SHAPE_FRANK = 36;
963   public final static int SHAPE_MAX = SHAPE_FRANK + 1;
964 
getShapeVisibilityFlag(int shapeID)965   public final static int getShapeVisibilityFlag(int shapeID) {
966     return 16 << Math.min(shapeID, SHAPE_LAST_ATOM_VIS_FLAG);
967   }
968 
969   public static final int VIS_BOND_FLAG = 16 << SHAPE_STICKS;
970   public static final int VIS_BALLS_FLAG = 16 << SHAPE_BALLS;
971   public static final int VIS_LABEL_FLAG = 16 << SHAPE_LABELS;
972   public static final int VIS_BACKBONE_FLAG = 16 << SHAPE_BACKBONE;
973   public final static int VIS_CARTOON_FLAG = 16 << SHAPE_CARTOON;
974 
975   public final static int ALPHA_CARBON_VISIBILITY_FLAG = (16 << SHAPE_ROCKETS)
976       | (16 << SHAPE_TRACE) | (16 << SHAPE_STRANDS) | (16 << SHAPE_MESHRIBBON)
977       | (16 << SHAPE_RIBBONS) | VIS_CARTOON_FLAG | VIS_BACKBONE_FLAG;
978 
979   // note that these next two arrays *MUST* be in the same sequence
980   // given in SHAPE_* and they must be capitalized exactly as in their class name
981 
982   public final static String[] shapeClassBases = { "Balls", "Sticks", "Hsticks",
983       "Sssticks", "Struts",
984       //Hsticks, Sssticks, and Struts classes do not exist, but this returns Token for them
985       "Labels", "Measures", "Stars", "Halos", "Backbone", "Trace", "Cartoon",
986       "Strands", "MeshRibbon", "Ribbons", "Rockets", "Dots", "Dipoles",
987       "Vectors", "GeoSurface", "Ellipsoids", "Polyhedra", "Draw", "CGO",
988       "Isosurface", "Contact", "LcaoCartoon", "MolecularOrbital", "NBO",
989       "Pmesh", "Plot3D", "Echo", "Bbcage", "Uccage", "Axes", "Hover", "Frank" };
990   // .hbond and .ssbonds will return a class,
991   // but the class is never loaded, so it is skipped in each case.
992   // coloring and sizing of hydrogen bonds and S-S bonds is now
993   // done by Sticks.
994 
shapeTokenIndex(int tok)995   public final static int shapeTokenIndex(int tok) {
996     switch (tok) {
997     case T.atoms:
998     case T.balls:
999       return SHAPE_BALLS;
1000     case T.bonds:
1001     case T.wireframe:
1002       return SHAPE_STICKS;
1003     case T.hbond:
1004       return SHAPE_HSTICKS;
1005     case T.ssbond:
1006       return SHAPE_SSSTICKS;
1007     case T.struts:
1008       return SHAPE_STRUTS;
1009     case T.label:
1010       return SHAPE_LABELS;
1011     case T.measure:
1012     case T.measurements:
1013       return SHAPE_MEASURES;
1014     case T.star:
1015       return SHAPE_STARS;
1016     case T.halo:
1017       return SHAPE_HALOS;
1018     case T.backbone:
1019       return SHAPE_BACKBONE;
1020     case T.trace:
1021       return SHAPE_TRACE;
1022     case T.cartoon:
1023       return SHAPE_CARTOON;
1024     case T.strands:
1025       return SHAPE_STRANDS;
1026     case T.meshRibbon:
1027       return SHAPE_MESHRIBBON;
1028     case T.ribbon:
1029       return SHAPE_RIBBONS;
1030     case T.rocket:
1031       return SHAPE_ROCKETS;
1032     case T.dots:
1033       return SHAPE_DOTS;
1034     case T.dipole:
1035       return SHAPE_DIPOLES;
1036     case T.vector:
1037       return SHAPE_VECTORS;
1038     case T.geosurface:
1039       return SHAPE_GEOSURFACE;
1040     case T.ellipsoid:
1041       return SHAPE_ELLIPSOIDS;
1042     case T.polyhedra:
1043       return SHAPE_POLYHEDRA;
1044     case T.cgo:
1045       return SHAPE_CGO;
1046     case T.draw:
1047       return SHAPE_DRAW;
1048     case T.isosurface:
1049       return SHAPE_ISOSURFACE;
1050     case T.contact:
1051       return SHAPE_CONTACT;
1052     case T.lcaocartoon:
1053       return SHAPE_LCAOCARTOON;
1054     case T.mo:
1055       return SHAPE_MO;
1056     case T.nbo:
1057       return SHAPE_NBO;
1058     case T.pmesh:
1059       return SHAPE_PMESH;
1060     case T.plot3d:
1061       return SHAPE_PLOT3D;
1062     case T.echo:
1063       return SHAPE_ECHO;
1064     case T.axes:
1065       return SHAPE_AXES;
1066     case T.boundbox:
1067       return SHAPE_BBCAGE;
1068     case T.unitcell:
1069       return SHAPE_UCCAGE;
1070     case T.hover:
1071       return SHAPE_HOVER;
1072     case T.frank:
1073       return SHAPE_FRANK;
1074     }
1075     return -1;
1076   }
1077 
getShapeClassName(int shapeID, boolean isRenderer)1078   public final static String getShapeClassName(int shapeID,
1079                                                boolean isRenderer) {
1080     if (shapeID < 0)
1081       return shapeClassBases[~shapeID];
1082     return "org.jmol." + (isRenderer ? "render" : "shape")
1083         + (shapeID >= SHAPE_MIN_SECONDARY && shapeID < SHAPE_MAX_SECONDARY
1084             ? "bio."
1085             : shapeID >= SHAPE_MIN_SPECIAL && shapeID < SHAPE_MAX_SPECIAL
1086                 ? "special."
1087                 : shapeID >= SHAPE_MIN_SURFACE && shapeID < SHAPE_MAX_SURFACE
1088                     ? "surface."
1089                     : shapeID == SHAPE_CGO ? "cgo." : ".")
1090         + shapeClassBases[shapeID];
1091   }
1092 
1093   //  public final static String binaryExtensions = ";pse=PyMOL;";// PyMOL
1094 
1095   public static final String SCRIPT_COMPLETED = "Script completed";
1096   public static final String JPEG_EXTENSIONS = ";jpg;jpeg;jpg64;jpeg64;";
1097   public final static String IMAGE_TYPES = JPEG_EXTENSIONS
1098       + "gif;gift;pdf;ppm;png;pngj;pngt;";
1099   public static final String IMAGE_OR_SCENE = IMAGE_TYPES + "scene;";
1100 
1101   static {
1102     /**
1103      * @j2sNative
1104      */
1105     {
1106       if (argbsFormalCharge.length != Elements.FORMAL_CHARGE_MAX
1107           - Elements.FORMAL_CHARGE_MIN + 1) {
1108         Logger.error("formal charge color table length");
NullPointerException()1109         throw new NullPointerException();
1110       }
1111       if (shapeClassBases.length != SHAPE_MAX) {
1112         Logger.error("shapeClassBases wrong length");
NullPointerException()1113         throw new NullPointerException();
1114       }
1115       if (shapeClassBases.length != SHAPE_MAX) {
1116         Logger.error("the shapeClassBases array has the wrong length");
NullPointerException()1117         throw new NullPointerException();
1118       }
1119     }
1120   }
1121 
1122   ///////////////// LABEL and ECHO ///////////////////////
1123 
1124   // note that the y offset is positive upward
1125 
1126   //  3         2         1
1127   // 10987654321098765432109876543210
1128   //  -x-offset--y-offset-___cafgaabp
1129   //                      |||||||| ||_pointer on
1130   //                      |||||||| |_background pointer color
1131   //                      ||||||||_text alignment 0xC
1132   //                      |||||||_labels group 0x10
1133   //                      ||||||_labels front  0x20
1134   //                      |||||_absolute
1135   //                      ||||_centered
1136   //                      |||_reserved
1137   //                      ||_reserved
1138   //                      |_reserved
1139 
1140   public final static int LABEL_MINIMUM_FONTSIZE = 6;
1141   public final static int LABEL_MAXIMUM_FONTSIZE = 63;
1142   public final static int LABEL_DEFAULT_FONTSIZE = 13;
1143   public final static int LABEL_DEFAULT_X_OFFSET = 4;
1144   public final static int LABEL_DEFAULT_Y_OFFSET = 4;
1145   public final static int LABEL_OFFSET_MAX = 500; // 0x1F4;
1146 
1147   private final static int LABEL_OFFSET_MASK = 0x3FF; // 10 bits for each offset (-500 to 500)
1148   private final static int LABEL_FLAGY_OFFSET_SHIFT = 11; // 11-20 is Y offset
1149   private final static int LABEL_FLAGX_OFFSET_SHIFT = 21; // 21-30 is X offset
1150 
1151   public final static int LABEL_FLAGS = 0x03F; // does not include absolute or centered
1152   private final static int LABEL_POINTER_FLAGS = 0x003;
1153   public final static int LABEL_POINTER_NONE = 0x000;
1154   public final static int LABEL_POINTER_ON = 0x001; // add label pointer
1155   public final static int LABEL_POINTER_BACKGROUND = 0x002; // add label pointer to background
1156 
1157   private final static int TEXT_ALIGN_SHIFT = 0x002;
1158   private final static int TEXT_ALIGN_FLAGS = 0x00C;
1159   public final static int TEXT_ALIGN_NONE = 0x000;
1160   public final static int TEXT_ALIGN_LEFT = 0x004;
1161   public final static int TEXT_ALIGN_CENTER = 0x008;
1162   public final static int TEXT_ALIGN_RIGHT = 0x00C;
1163 
1164   private final static int LABEL_ZPOS_FLAGS = 0x030;
1165   public final static int LABEL_ZPOS_GROUP = 0x010;
1166   public final static int LABEL_ZPOS_FRONT = 0x020;
1167 
1168   private final static int LABEL_EXPLICIT = 0x040;
1169 
1170   private final static int LABEL_CENTERED = 0x100;
1171 
1172   public static int LABEL_DEFAULT_OFFSET = (LABEL_DEFAULT_X_OFFSET << LABEL_FLAGX_OFFSET_SHIFT)
1173       | (LABEL_DEFAULT_Y_OFFSET << LABEL_FLAGY_OFFSET_SHIFT);
1174 
1175   public final static int ECHO_TOP = 0;
1176   public final static int ECHO_BOTTOM = 1;
1177   public final static int ECHO_MIDDLE = 2;
1178   public final static int ECHO_XY = 3;
1179   public final static int ECHO_XYZ = 4;
1180 
1181   private final static String[] echoNames = { "top", "bottom", "middle", "xy",
1182       "xyz" };
1183 
getEchoName(int type)1184   public static String getEchoName(int type) {
1185     return echoNames[type];
1186   }
1187 
setZPosition(int offset, int pos)1188   public static int setZPosition(int offset, int pos) {
1189     return (offset & ~LABEL_ZPOS_FLAGS) | pos;
1190   }
1191 
setPointer(int offset, int pointer)1192   public static int setPointer(int offset, int pointer) {
1193     return (offset & ~LABEL_POINTER_FLAGS) | pointer;
1194   }
1195 
getPointer(int offset)1196   public static int getPointer(int offset) {
1197     return offset & LABEL_POINTER_FLAGS;
1198   }
1199 
getPointerName(int pointer)1200   public static String getPointerName(int pointer) {
1201     return ((pointer & LABEL_POINTER_ON) == 0 ? ""
1202         : (pointer & LABEL_POINTER_BACKGROUND) > 0 ? "background" : "on");
1203   }
1204 
isOffsetAbsolute(int offset)1205   public static boolean isOffsetAbsolute(int offset) {
1206     return ((offset & LABEL_EXPLICIT) != 0);
1207   }
1208 
1209   /**
1210    * Construct an 32-bit integer packed with 10-byte x and y offsets (-500 to
1211    * 500) along with flags to indicate if exact and, if not, a flag to indicate
1212    * that the 0 in x or y indicates "centered". The non-exact default offset of
1213    * [4,4] is represented as 0 so that new array elements do not have to be
1214    * initialized.
1215    *
1216    * @param xOffset
1217    * @param yOffset
1218    * @param isAbsolute
1219    * @return packed offset x and y with positioning flags
1220    */
getOffset(int xOffset, int yOffset, boolean isAbsolute)1221   public static int getOffset(int xOffset, int yOffset, boolean isAbsolute) {
1222     xOffset = Math.min(Math.max(xOffset, -LABEL_OFFSET_MAX), LABEL_OFFSET_MAX);
1223     yOffset = (Math.min(Math.max(yOffset, -LABEL_OFFSET_MAX),
1224         LABEL_OFFSET_MAX));
1225     int offset = ((xOffset & LABEL_OFFSET_MASK) << LABEL_FLAGX_OFFSET_SHIFT)
1226         | ((yOffset & LABEL_OFFSET_MASK) << LABEL_FLAGY_OFFSET_SHIFT)
1227         | (isAbsolute ? LABEL_EXPLICIT : 0);
1228     if (offset == LABEL_DEFAULT_OFFSET)
1229       offset = 0;
1230     else if (!isAbsolute && (xOffset == 0 || yOffset == 0))
1231       offset |= LABEL_CENTERED;
1232     return offset;
1233   }
1234 
1235   /**
1236    * X offset in pixels.
1237    *
1238    * negative of this is the actual screen offset
1239    *
1240    * @param offset
1241    *        0 for an offset indicates "not set" and delivers the default offset
1242    * @return screen offset from left
1243    */
getXOffset(int offset)1244   public static int getXOffset(int offset) {
1245     if (offset == 0)
1246       return LABEL_DEFAULT_X_OFFSET;
1247     int x = (offset >> LABEL_FLAGX_OFFSET_SHIFT) & LABEL_OFFSET_MASK;
1248     x = (x > LABEL_OFFSET_MAX ? x - LABEL_OFFSET_MASK - 1 : x);
1249     return x;
1250   }
1251 
1252   /**
1253    * Y offset in pixels; negative of this is the actual screen offset
1254    *
1255    * @param offset
1256    *        0 for an offset indicates "not set" and delivers the default offset
1257    * @return screen offset from bottom
1258    */
getYOffset(int offset)1259   public static int getYOffset(int offset) {
1260     if (offset == 0)
1261       return LABEL_DEFAULT_Y_OFFSET;
1262     int y = (offset >> LABEL_FLAGY_OFFSET_SHIFT) & LABEL_OFFSET_MASK;
1263     return (y > LABEL_OFFSET_MAX ? y - LABEL_OFFSET_MASK - 1 : y);
1264   }
1265 
getAlignment(int offset)1266   public static int getAlignment(int offset) {
1267     return (offset & TEXT_ALIGN_FLAGS);
1268   }
1269 
setHorizAlignment(int offset, int hAlign)1270   public static int setHorizAlignment(int offset, int hAlign) {
1271     return (offset & ~TEXT_ALIGN_FLAGS) | hAlign;
1272   }
1273 
1274   private final static String[] hAlignNames = { "", "left", "center", "right" };
1275 
getHorizAlignmentName(int align)1276   public static String getHorizAlignmentName(int align) {
1277     return hAlignNames[(align >> TEXT_ALIGN_SHIFT) & 3];
1278   }
1279 
isSmilesCanonical(String options)1280   public static boolean isSmilesCanonical(String options) {
1281     return (options != null && PT.isOneOf(options.toLowerCase(),
1282         ";/cactvs///;/cactus///;/nci///;/canonical///;"));
1283   }
1284 
1285   public static final int SMILES_TYPE_SMILES = 0x1; // placeholder -- DO NOT TEST FOR THIS as it is also in openSMARTS
1286   public static final int SMILES_TYPE_SMARTS = 0x2; // CmdExt -> matcher
1287   public static final int SMILES_TYPE_OPENSMILES = 0x5; // includes aromatic normalization of pattern; tests true when openSMARTS as well
1288   public static final int SMILES_TYPE_OPENSMARTS = 0x7; //
1289 
1290   public static final int SMILES_FIRST_MATCH_ONLY = 0x8; // 0xFF0 reserved for SmilesMatcher mflag
1291 
1292   public final static int SMILES_NO_AROMATIC = 0x010; //SmilesParser -> SmilesSearch
1293 
1294   public final static int SMILES_IGNORE_STEREOCHEMISTRY = 0x020; //SmilesParser -> SmilesSearch
1295 
1296   public final static int SMILES_INVERT_STEREOCHEMISTRY = 0x040; //SmilesParser -> SmilesSearch
1297 
1298   public static final int SMILES_MAP_UNIQUE = 0x080; //SmilesMatcher return only unique mappings
1299 
1300   /**
1301    * AROMATIC_DEFINED draws all aromatic bonds from connection definitions It is
1302    * deprecated, because a=a will set it by itself.
1303    */
1304   public final static int SMILES_AROMATIC_DEFINED = 0x080; //SmilesParser -> SmilesSearch
1305 
1306   /**
1307    * AROMATIC_STRICT enforces Hueckel 4+2 rule, not allowing acyclic double
1308    * bonds
1309    *
1310    */
1311   public final static int SMILES_AROMATIC_STRICT = 0x100; //SmilesParser -> SmilesSearch
1312 
1313   /**
1314    * AROMATIC_DOUBLE allows a distinction between single and double, as for
1315    * example is necessary to distinguish between n=cNH2 and ncNH2 (necessary for
1316    * MMFF94 atom typing)
1317    */
1318   public final static int SMILES_AROMATIC_DOUBLE = 0x200; //SmilesParser -> SmilesSearch
1319 
1320   /**
1321    * AROMATIC_MMFF94 also raises the strictness level to force all 6- and
1322    * 7-membered rings to have exactly three double bonds.
1323    */
1324   public static final int SMILES_AROMATIC_MMFF94 = 0x300; // includes AROMATIC_STRICT and AROMATIC_DOUBLE;
1325 
1326   //  /**
1327   //   * AROMATIC_JSME_NONCANONICAL matches the JSME noncanonical option.
1328   //  *
1329   //   */
1330   //  final static int AROMATIC_JSME_NONCANONICAL = 0x800; //SmilesParser -> SmilesSearch
1331 
1332   /**
1333    * AROMATIC_PLANAR only invokes planarity (Jmol default through 14.5)
1334    *
1335    */
1336   public final static int SMILES_AROMATIC_PLANAR = 0x400; //SmilesParser -> SmilesSearch
1337 
1338   public static final int SMILES_IGNORE_ATOM_CLASS = 0x800;
1339 
1340   public static final int SMILES_GEN_EXPLICIT_H_ALL = 0x00001000; // SmilesExt -> generator
1341   public static final int SMILES_GEN_EXPLICIT_H2_ONLY = 0x00002000; // SmilesExt -> generator
1342   public static final int SMILES_GEN_TOPOLOGY = 0x00004000; // SmilesExt -> generator
1343   public static final int SMILES_GEN_POLYHEDRAL = 0x00010000; // polyhedron -> generator
1344   public static final int SMILES_GEN_ATOM_COMMENT = 0x00020000; // polyhedron,Viewer -> generator
1345 
1346   public static final int SMILES_GEN_BIO = 0x00100000; // MathExt -> generator
1347   public static final int SMILES_GEN_BIO_ALLOW_UNMATCHED_RINGS = 0x00300000; // MathExt -> generator
1348   public static final int SMILES_GEN_BIO_COV_CROSSLINK = 0x00500000; // MathExt -> generator
1349   public static final int SMILES_GEN_BIO_HH_CROSSLINK = 0x00900000; // MathExt -> generator
1350   public static final int SMILES_GEN_BIO_COMMENT = 0x01100000; // MathExt -> Viewer
1351   public static final int SMILES_GEN_BIO_NOCOMMENTS = 0x02100000; // MathExt -> Generator
1352 
1353   public static final int SMILES_GROUP_BY_MODEL = 0x04000000; // MathExt -> search
1354   public static final int SMILES_2D = 0x08000000; // Viewer -> generator
1355 
1356   // SYNC types
1357 
1358   public static final int JSV_NOT = -1;
1359   public static final int JSV_SEND_JDXMOL = 0;
1360   public static final int JSV_SETPEAKS = 7;
1361   public static final int JSV_SELECT = 14;
1362   public static final int JSV_STRUCTURE = 21;
1363   public static final int JSV_SEND_H1SIMULATE = 28;
1364   public static final int JSV_SEND_C13SIMULATE = 35;
1365   public static final int NBO_MODEL = 42;
1366   public static final int NBO_RUN = 49;
1367   public static final int NBO_VIEW = 56;
1368   public static final int NBO_SEARCH = 63;
1369   public static final int NBO_CONFIG = 70;
1370   public static final int JSV_CLOSE = 77;
1371 
getServiceCommand(String script)1372   public static int getServiceCommand(String script) {
1373     return (script.length() < 7 ? -1
1374         : ("" + "JSPECVI" + "PEAKS: " + "SELECT:" + "JSVSTR:" + "H1SIMUL"
1375             + "C13SIMU" + "NBO:MOD" + "NBO:RUN" + "NBO:VIE" + "NBO:SEA"
1376             + "NBO:CON" + "NONESIM")
1377                 .indexOf(script.substring(0, 7).toUpperCase()));
1378   }
1379 
1380   public static String READER_NOT_FOUND = "File reader was not found:";
1381 
1382   public final static int UNITID_MODEL = 1;
1383   public final static int UNITID_RESIDUE = 2;
1384   public final static int UNITID_ATOM = 4;
1385   public final static int UNITID_INSCODE = 8;
1386   public final static int UNITID_TRIM = 16;
1387 
1388   public static final String DEFAULT_DRAG_DROP_SCRIPT = "zap; load SYNC \"%FILE\";if (%ALLOWCARTOONS && _loadScript == '' && defaultLoadScript == '' && _filetype == 'Pdb') {if ({(protein or nucleic)&*/1.1} && {*/1.1}[1].groupindex != {*/1.1}[0].groupindex){select protein or nucleic;cartoons only;}if ({visible && cartoons > 0}){color structure}else{wireframe -0.1};if (!{visible}){spacefill 23%};select *}";
1389 
1390   /**
1391    * Get a unitID type
1392    *
1393    * @param type
1394    *        -mra (model name, residue, atom, and ins code), -mr (model and
1395    *        residue; no atom) -ra default - or -r just residue -t right-trim
1396    *
1397    * @return coded type
1398    */
getUnitIDFlags(String type)1399   public static int getUnitIDFlags(String type) {
1400     int i = UNITID_RESIDUE | UNITID_ATOM | UNITID_INSCODE;
1401     if (type.indexOf("-") == 0) {
1402       if (type.indexOf("m") > 0)
1403         i |= UNITID_MODEL;
1404       if (type.indexOf("a") < 0)
1405         i ^= UNITID_ATOM;
1406       if (type.indexOf("t") > 0)
1407         i |= UNITID_TRIM;
1408     }
1409     return i;
1410   }
1411 
1412 }
1413