1 /***************************************************************************
2  *cr
3  *cr            (C) Copyright 1995-2006 The Board of Trustees of the
4  *cr                        University of Illinois
5  *cr                         All Rights Reserved
6  *cr
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * RCS INFORMATION:
11  *
12  *      $RCSfile: molfile_plugin.h,v $
13  *      $Author: johns $       $Locker:  $             $State: Exp $
14  *      $Revision: 1.112 $       $Date: 2019/10/17 06:12:24 $
15  *
16  ***************************************************************************/
17 
18 /** @file
19  * API for C extensions to define a way to load structure, coordinate,
20  * trajectory, and volumetric data files
21  */
22 
23 #ifndef MOL_FILE_PLUGIN_H
24 #define MOL_FILE_PLUGIN_H
25 
26 #include "vmdplugin.h"
27 
28 #if defined(DESRES_READ_TIMESTEP2)
29 /* includes needed for large integer types used for frame counts */
30 #include <sys/types.h>
31 typedef ssize_t molfile_ssize_t;      /**< for frame counts */
32 #endif
33 
34 /**
35  * Define a common plugin type to be used when registering the plugin.
36  */
37 #define MOLFILE_PLUGIN_TYPE "mol file reader"
38 
39 /**
40  * File converter plugins use the same API  but register under a different
41  * type so that regular file readers can have priority.
42  */
43 #define MOLFILE_CONVERTER_PLUGIN_TYPE "mol file converter"
44 
45 /* File plugin symbolic constants for better code readability */
46 #define MOLFILE_SUCCESS           0   /**< succeeded in reading file      */
47 #define MOLFILE_EOF              -1   /**< end of file                    */
48 #define MOLFILE_ERROR            -1   /**< error reading/opening a file   */
49 #define MOLFILE_NOSTRUCTUREDATA  -2   /**< no structure data in this file */
50 
51 #define MOLFILE_NUMATOMS_UNKNOWN -1   /**< unknown number of atoms       */
52 #define MOLFILE_NUMATOMS_NONE     0   /**< no atoms in this file type    */
53 
54 /**
55  * Maximum string size macro
56  */
57 #define MOLFILE_BUFSIZ           81   /**< maximum chars in string data  */
58 #define MOLFILE_BIGBUFSIZ        4096 /**< maximum chars in long strings */
59 
60 #define MOLFILE_MAXWAVEPERTS     25   /**< maximum number of wavefunctions
61                                        *   per timestep */
62 
63 /**
64  * Hard-coded direct-I/O page size constants for use by both VMD
65  * and the plugins that want to use direct, unbuffered I/O for high
66  * performance with SSDs etc.  We use two constants to define the
67  * range of hardware page sizes that we can support, so that we can
68  * add support for larger 8KB or 16KB page sizes in the future
69  * as they become more prevalent in high-end storage systems.
70  *
71  * At present, VMD uses a hard-coded 4KB page size to reduce memory
72  * fragmentation, but these constants will make it easier to enable the
73  * use of larger page sizes in the future if it becomes necessary.
74  */
75 #define MOLFILE_DIRECTIO_MIN_BLOCK_SIZE 4096
76 #define MOLFILE_DIRECTIO_MAX_BLOCK_SIZE 4096
77 
78 
79 /**
80  * File level comments, origin information, and annotations.
81  */
82 typedef struct {
83   char database[81];   /**< database of origin, if any        */
84   char accession[81];  /**< database accession code, if any   */
85   char date[81];       /**< date/time stamp for this data     */
86   char title[81];      /**< brief title for this data         */
87   int remarklen;       /**< length of remarks string          */
88   char *remarks;       /**< free-form remarks about data      */
89 } molfile_metadata_t;
90 
91 
92 /*
93  * Struct for specifying atoms in a molecular structure.  The first
94  * six components are required, the rest are optional and their presence is
95  * indicating by setting the corresponding bit in optsflag.  When omitted,
96  * the application (for read_structure) or plugin (for write_structure)
97  * must be able to supply default values if the missing parameters are
98  * part of its internal data structure.
99  * Note that it is not possible to specify coordinates with this structure.
100  * This is intentional; all coordinate I/O is done with the read_timestep and
101  * write_timestep functions.
102  */
103 
104 /**
105  * Per-atom attributes and information.
106  */
107 typedef struct {
108   /* these fields absolutely must be set or initialized to empty */
109   char name[16];      /**< required atom name string             */
110   char type[16];      /**< required atom type string             */
111   char resname[8];    /**< required residue name string          */
112   int resid;          /**< required integer residue ID           */
113   char segid[8];      /**< required segment name string, or ""   */
114 #if 0 && vmdplugin_ABIVERSION > 10000
115   /* The new PDB file formats allows for much larger structures, */
116   /* which can therefore require longer chain ID strings.  The   */
117   /* new PDBx/mmCIF file formats do not have length limits on    */
118   /* fields, so PDB chains could be arbitrarily long strings     */
119   /* in such files.  At present, we know we need at least 3-char */
120   /* chains for existing PDBx/mmCIF files.                       */
121   char chain[4];      /**< required chain name, or ""            */
122 #else
123   char chain[2];      /**< required chain name, or ""            */
124 #endif
125   /* rest are optional; use optflags to specify what's present   */
126   char altloc[2];     /**< optional PDB alternate location code  */
127   char insertion[2];  /**< optional PDB insertion code           */
128   float occupancy;    /**< optional occupancy value              */
129   float bfactor;      /**< optional B-factor value               */
130   float mass;         /**< optional mass value                   */
131   float charge;       /**< optional charge value                 */
132   float radius;       /**< optional radius value                 */
133   int atomicnumber;   /**< optional element atomic number        */
134 
135 #if 0
136   char complex[16];
137   char assembly[16];
138   int qmregion;
139   int qmregionlink;
140   int qmlayer;
141   int qmlayerlink;
142   int qmfrag;
143   int qmfraglink;
144   string qmecp;
145   int qmadapt;
146   int qmect;          /**< boolean */
147   int qmparam;
148   int autoparam;
149 #endif
150 
151 #if defined(DESRES_CTNUMBER)
152   int ctnumber;       /**< mae ct block, 0-based, including meta */
153 #endif
154 } molfile_atom_t;
155 
156 /*@{*/
157 /** Plugin optional data field availability flag */
158 #define MOLFILE_NOOPTIONS     0x0000 /**< no optional data                 */
159 #define MOLFILE_INSERTION     0x0001 /**< insertion codes provided         */
160 #define MOLFILE_OCCUPANCY     0x0002 /**< occupancy data provided          */
161 #define MOLFILE_BFACTOR       0x0004 /**< B-factor data provided           */
162 #define MOLFILE_MASS          0x0008 /**< Atomic mass provided             */
163 #define MOLFILE_CHARGE        0x0010 /**< Atomic charge provided           */
164 #define MOLFILE_RADIUS        0x0020 /**< Atomic VDW radius provided       */
165 #define MOLFILE_ALTLOC        0x0040 /**< Multiple conformations present   */
166 #define MOLFILE_ATOMICNUMBER  0x0080 /**< Atomic element number provided   */
167 #define MOLFILE_BONDSSPECIAL  0x0100 /**< Only non-standard bonds provided */
168 #if defined(DESRES_CTNUMBER)
169 #define MOLFILE_CTNUMBER      0x0200 /**< ctnumber provided */
170 #endif
171 #define MOLFILE_BADOPTIONS    0xFFFFFFFF /**< Detect badly behaved plugins */
172 
173 /*@}*/
174 
175 /*@{*/
176 /** Flags indicating availability of optional data fields
177  *  for QM timesteps
178  */
179 #define MOLFILE_QMTS_NOOPTIONS     0x0000 /**< no optional data               */
180 #define MOLFILE_QMTS_GRADIENT      0x0001 /**< energy gradients provided      */
181 #define MOLFILE_QMTS_SCFITER       0x0002
182 /*@}*/
183 
184 typedef struct molfile_timestep_metadata {
185   unsigned int count;                  /**< total # timesteps; -1 if unknown */
186   unsigned int avg_bytes_per_timestep; /** bytes per timestep                */
187   int has_velocities;                  /**< if timesteps have velocities     */
188 } molfile_timestep_metadata_t;
189 
190 
191 /*
192  *
193  * Per-timestep atom coordinates, velocities, forces, energies,
194  * and periodic cell information
195  *
196  */
197 
198 #if 0
199 /**
200  * Periodically stored energies of various kinds
201  */
202 typedef struct {
203   int energyflags;         // XXX indicate use and semantics of data fields
204 
205   double total_energy;     // XXX these copied from DESRES_READ_TIMESTEP2 case
206   double potential_energy;
207   double kinetic_energy;
208   double extended_energy;
209   double force_energy;
210   double total_pressure;
211 
212   // Alchemical free energy methods need to store individual energy samples.
213   // We don't really want pre-averaged quantities, they lead to problems later.
214   double lambda;       // data gen sim parm: + aux scheduling + soft core parm
215   double temperature;  // temp set by thermostat
216   // either we use deltaU, or we store U and Uprime...
217   double deltaU;       // Ulambda - Ulambdaprime
218   double Ulambda;      // U for lambda
219   double Ulambdaprime; // U for lambdaprime
220 
221   // IDWS methods
222   // XXX both values of lambdaprime and required de-interleaving information
223 
224   // Replica exchange methods
225   // XXX rectangle sample params?
226 
227   // REST2 method
228   // XXX
229 
230 } molfile_energies_t;
231 #endif
232 
233 
234 /**
235  * Per-timestep atom coordinates, velocities, time, energies
236  * and periodic cell info
237  */
238 typedef struct {
239   float *coords;        /**< coordinates of all atoms, arranged xyzxyzxyz   */
240   float *velocities;    /**< space for velocities of all atoms; same layout */
241                         /**< NULL unless has_velocities is set              */
242 
243   /*@{*/
244   /**
245    * Unit cell specification of the form A, B, C, alpha, beta, gamma.
246    * notes: A, B, C are side lengths of the unit cell
247    * alpha = angle between b and c
248    *  beta = angle between a and c
249    * gamma = angle between a and b
250    */
251   float A, B, C, alpha, beta, gamma;
252   /*@}*/
253 
254   double physical_time; /**< physical time point associated with this frame */
255 
256 #if defined(DESRES_READ_TIMESTEP2)
257   /* HACK to support generic trajectory information */
258   double total_energy;
259   double potential_energy;
260   double kinetic_energy;
261   double extended_energy;
262   double force_energy;
263   double total_pressure;
264 #endif
265 
266 } molfile_timestep_t;
267 
268 
269 /**
270  * Metadata for volumetric datasets, read initially and used for subsequent
271  * memory allocations and file loading.
272  */
273 typedef struct {
274   char dataname[256];   /**< name of volumetric data set                    */
275   float origin[3];      /**< origin: origin of volume (x=0, y=0, z=0 corner */
276 
277   /*
278    * x/y/z axis:
279    * These the three cell sides, providing both direction and length
280    * (not unit vectors) for the x, y, and z axes.  In the simplest
281    * case, these would be <size,0,0> <0,size,0> and <0,0,size) for
282    * an orthogonal cubic volume set.  For other cell shapes these
283    * axes can be oriented non-orthogonally, and the parallelpiped
284    * may have different side lengths, not just a cube/rhombus.
285    */
286   float xaxis[3];       /**< direction (and length) for X axis              */
287   float yaxis[3];       /**< direction (and length) for Y axis              */
288   float zaxis[3];       /**< direction (and length) for Z axis              */
289 
290   /*
291    * x/y/z size:
292    * Number of grid cells along each axis.  This is _not_ the
293    * physical size of the box, this is the number of voxels in each
294    * direction, independent of the shape of the volume set.
295    */
296   int xsize;            /**< number of grid cells along the X axis           */
297   int ysize;            /**< number of grid cells along the Y axis           */
298   int zsize;            /**< number of grid cells along the Z axis           */
299 
300 #if vmdplugin_ABIVERSION > 16
301   int has_scalar;       /**< flag indicating presence of scalar volume       */
302   int has_gradient;     /**< flag indicating presence of vector volume       */
303   int has_variance;     /**< flag indicating presence of variance map        */
304 #endif
305   int has_color;        /**< flag indicating presence of voxel color data    */
306 } molfile_volumetric_t;
307 
308 
309 #if vmdplugin_ABIVERSION > 16
310 /**
311  * Volumetric dataset read/write structure with both flag/parameter sets
312  * and VMD-allocated pointers for fields to be used by the plugin.
313  */
314 typedef struct {
315   int setidx;           /**< volumetric dataset index to load/save */
316   float *scalar;        /**< scalar density/potential field data   */
317   float *gradient;      /**< gradient vector field                 */
318   float *variance;      /**< variance map indicating signal/noise  */
319   float *rgb3f;         /**< RGB floating point color texture map  */
320   unsigned char *rgb3u; /**< RGB unsigned byte color texture map   */
321 } molfile_volumetric_readwrite_t;
322 #endif
323 
324 
325 /**************************************************************
326  **************************************************************
327  ****                                                      ****
328  ****          Data structures for QM files                ****
329  ****                                                      ****
330  **************************************************************
331  **************************************************************/
332 
333 /* macros for the convergence status of a QM calculation. */
334 #define MOLFILE_QMSTATUS_UNKNOWN       -1 /* don't know yet */
335 #define MOLFILE_QMSTATUS_OPT_CONV       0 /* optimization converged */
336 #define MOLFILE_QMSTATUS_SCF_NOT_CONV   1 /* SCF convergence failed */
337 #define MOLFILE_QMSTATUS_OPT_NOT_CONV   2 /* optimization not converged */
338 #define MOLFILE_QMSTATUS_FILE_TRUNCATED 3 /* file was truncated */
339 
340 /* macros describing the SCF method (SCFTYP in GAMESS) */
341 #define MOLFILE_SCFTYPE_UNKNOWN -1 /* no info about the method  */
342 #define MOLFILE_SCFTYPE_NONE     0 /* calculation didn't make use of SCF */
343 #define MOLFILE_SCFTYPE_RHF      1 /* restricted Hartree-Fock   */
344 #define MOLFILE_SCFTYPE_UHF      2 /* unrestricted Hartree-Fock */
345 #define MOLFILE_SCFTYPE_ROHF     3 /* restricted open-shell Hartree-Fock */
346 #define MOLFILE_SCFTYPE_GVB      4 /* generalized valence bond orbitals  */
347 #define MOLFILE_SCFTYPE_MCSCF    5 /* multi-configuration SCF   */
348 #define MOLFILE_SCFTYPE_FF       6 /* classical force-field based sim.   */
349 
350 /* macros describing the type of calculation (RUNTYP in GAMESS) */
351 #define MOLFILE_RUNTYPE_UNKNOWN    0  /* single point run */
352 #define MOLFILE_RUNTYPE_ENERGY     1  /* single point run */
353 #define MOLFILE_RUNTYPE_OPTIMIZE   2  /* geometry optimization */
354 #define MOLFILE_RUNTYPE_SADPOINT   3  /* saddle point search */
355 #define MOLFILE_RUNTYPE_HESSIAN    4  /* Hessian/frequency calculation */
356 #define MOLFILE_RUNTYPE_SURFACE    5  /* potential surface scan */
357 #define MOLFILE_RUNTYPE_GRADIENT   6  /* energy gradient calculation */
358 #define MOLFILE_RUNTYPE_MEX        7  /* minimum energy crossing */
359 #define MOLFILE_RUNTYPE_DYNAMICS   8  /* Any type of molecular dynamics
360                                        * e.g. Born-Oppenheimer, Car-Parinello,
361                                        * or classical MD */
362 #define MOLFILE_RUNTYPE_PROPERTIES 9  /* Properties were calculated from a
363                                        * wavefunction that was read from file */
364 
365 
366 /**
367  * Sizes of various QM-related, timestep independent data arrays
368  * which must be allocated by the caller (VMD) so that the plugin
369  * can fill in the arrays with data.
370  */
371 typedef struct {
372   /* hessian data */
373   int nimag;                    /**< number of imaginary modes */
374   int nintcoords;               /**< number internal coordinates */
375   int ncart;                    /**< number cartesian coordinates */
376 
377   /* orbital/basisset data */
378   int num_basis_funcs;          /**< number of uncontracted basis functions in basis array */
379   int num_basis_atoms;          /**< number of atoms in basis set */
380   int num_shells;               /**< total number of atomic shells */
381   int wavef_size;               /**< size of the wavefunction
382                                  *   i.e. size of secular eq. or
383                                  *   # of cartesian contracted
384                                  *   gaussian basis functions */
385 
386   /* everything else */
387   int have_sysinfo;
388   int have_carthessian;         /**< hessian in cartesian coords available  */
389   int have_inthessian;          /**< hessian in internal coords available  */
390   int have_normalmodes;         /**< normal modes available  */
391 } molfile_qm_metadata_t;
392 
393 
394 /**
395  * QM run info. Parameters that stay unchanged during a single file.
396  */
397 typedef struct {
398   int nproc;             /**< number of processors used. */
399   int memory;            /**< amount of memory used in Mbyte. */
400   int runtype;           /**< flag indicating the calculation method. */
401   int scftype;           /**< SCF type: RHF, UHF, ROHF, GVB or MCSCF wfn. */
402   int status;            /**< indicates wether SCF and geometry optimization
403                           *   have converged properly. */
404   int num_electrons;     /**< number of electrons.    XXX: can be fractional in some DFT codes */
405   int totalcharge;       /**< total charge of system. XXX: can be fractional in some DFT codes */
406   int num_occupied_A;    /**< number of occupied alpha orbitals */
407   int num_occupied_B;    /**< number of occupied beta orbitals */
408 
409   double *nuc_charge;    /**< array(natom) containing the nuclear charge of atom i */
410 
411   char basis_string[MOLFILE_BUFSIZ];    /**< basis name as "nice" string. */
412   char runtitle[MOLFILE_BIGBUFSIZ];     /**< title of run.                */
413   char geometry[MOLFILE_BUFSIZ];        /**< type of provided geometry,   XXX: remove?
414                                          * e.g. UNIQUE, ZMT, CART, ...    */
415   char version_string[MOLFILE_BUFSIZ];  /**< QM code version information. */
416 } molfile_qm_sysinfo_t;
417 
418 
419 /**
420  * Data for QM basis set
421  */
422 typedef struct {
423   int *num_shells_per_atom; /**< number of shells per atom */
424   int *num_prim_per_shell;  /**< number of shell primitives shell */
425 
426   float *basis;             /**< contraction coeffients and exponents for
427                              *   the basis functions in the form
428                              *   {exp(1), c-coeff(1), exp(2), c-coeff(2), ...};
429                              *   array size = 2*num_basis_funcs
430                              *   The basis must NOT be normalized. */
431   int *atomic_number;       /**< atomic numbers (chem. element) of atoms in basis set */
432   int *angular_momentum;    /**< 3 ints per wave function coefficient do describe the
433                              *   cartesian components of the angular momentum.
434                              *   E.g. S={0 0 0}, Px={1 0 0}, Dxy={1 1 0}, or Fyyz={0 2 1}.
435                              */
436   int *shell_types;         /**< type for each shell in basis */
437 } molfile_qm_basis_t;
438 
439 
440 /**
441  * Data from QM Hessian/normal mode runs
442  *
443  * A noteworthy comment from one of Axel's emails:
444  * The molfile_qm_hessian_t, I'd rename to molfile_hessian_t (one
445  * can do vibrational analysis without QM) and would make this a
446  * completely separate entity. This could then be also used to
447  * read in data from, say, principal component analysis or normal
448  * mode analysis and VMD could contain code to either project a
449  * trajectory on the contained eigenvectors or animate them and
450  * so on. There is a bunch of possible applications...
451  */
452 typedef struct {
453   double *carthessian;  /**< hessian matrix in cartesian coordinates (ncart)*(ncart)
454                          *   as a single array of doubles (row(1), ...,row(natoms)) */
455   int    *imag_modes;   /**< list(nimag) of imaginary modes */
456   double *inthessian;   /**< hessian matrix in internal coordinates
457                          *   (nintcoords*nintcoords) as a single array of
458                          *   doubles (row(1), ...,row(nintcoords)) */
459   float *wavenumbers;   /**< array(ncart) of wavenumbers of normal modes */
460   float *intensities;   /**< array(ncart) of intensities of normal modes */
461   float *normalmodes;   /**< matrix(ncart*ncart) of normal modes  */
462 } molfile_qm_hessian_t;
463 
464 
465 /**
466  * QM related information that is timestep independent
467  */
468 typedef struct {
469   molfile_qm_sysinfo_t run;             /* system info  */
470   molfile_qm_basis_t   basis;           /* basis set info */
471   molfile_qm_hessian_t hess;            /* hessian info */
472 } molfile_qm_t;
473 
474 
475 
476 /**
477  *  Enumeration of all of the wavefunction types that can be read
478  *  from QM file reader plugins.
479  *
480  *  CANON    = canonical (i.e diagonalized) wavefunction
481  *  GEMINAL  = GVB-ROHF geminal pairs
482  *  MCSCFNAT = Multi-Configuration SCF natural orbitals
483  *  MCSCFOPT = Multi-Configuration SCF optimized orbitals
484  *  CINATUR  = Configuration-Interaction natural orbitals
485  *  BOYS     = Boys localization
486  *  RUEDEN   = Ruedenberg localization
487  *  PIPEK    = Pipek-Mezey population localization
488  *
489  *  NBO related localizations:
490  *  --------------------------
491  *  NAO      = Natural Atomic Orbitals
492  *  PNAO     = pre-orthogonal NAOs
493  *  NBO      = Natural Bond Orbitals
494  *  PNBO     = pre-orthogonal NBOs
495  *  NHO      = Natural Hybrid Orbitals
496  *  PNHO     = pre-orthogonal NHOs
497  *  NLMO     = Natural Localized Molecular Orbitals
498  *  PNLMO    = pre-orthogonal NLMOs
499  *
500  *  UNKNOWN  = Use this for any type not listed here
501  *             You can use the string field for description
502  */
503 enum molfile_qm_wavefunc_type {
504   MOLFILE_WAVE_CANON,    MOLFILE_WAVE_GEMINAL,
505   MOLFILE_WAVE_MCSCFNAT, MOLFILE_WAVE_MCSCFOPT,
506   MOLFILE_WAVE_CINATUR,
507   MOLFILE_WAVE_PIPEK,  MOLFILE_WAVE_BOYS, MOLFILE_WAVE_RUEDEN,
508   MOLFILE_WAVE_NAO,    MOLFILE_WAVE_PNAO, MOLFILE_WAVE_NHO,
509   MOLFILE_WAVE_PNHO,   MOLFILE_WAVE_NBO,  MOLFILE_WAVE_PNBO,
510   MOLFILE_WAVE_PNLMO,  MOLFILE_WAVE_NLMO, MOLFILE_WAVE_MOAO,
511   MOLFILE_WAVE_NATO,   MOLFILE_WAVE_UNKNOWN
512 };
513 
514 
515 /**
516  *  Enumeration of all of the supported QM related charge
517  *  types
518  */
519 enum molfile_qm_charge_type {
520   MOLFILE_QMCHARGE_UNKNOWN,
521   MOLFILE_QMCHARGE_MULLIKEN, MOLFILE_QMCHARGE_LOWDIN,
522   MOLFILE_QMCHARGE_ESP, MOLFILE_QMCHARGE_NPA
523 };
524 
525 
526 
527 /**
528  * Sizes of various QM-related, per-timestep data arrays
529  * which must be allocated by the caller (VMD) so that the plugin
530  * can fill in the arrays with data.
531  */
532 typedef struct molfile_qm_timestep_metadata {
533   unsigned int count;                  /**< total # timesteps; -1 if unknown */
534   unsigned int avg_bytes_per_timestep; /**< bytes per timestep                */
535   int has_gradient;                    /**< if timestep contains gradient    */
536   int num_scfiter;                     /**< # scf iterations for this ts     */
537   int num_orbitals_per_wavef[MOLFILE_MAXWAVEPERTS]; /**< # orbitals for each wavefunction */
538   int has_orben_per_wavef[MOLFILE_MAXWAVEPERTS]; /**< orbital energy flags */
539   int has_occup_per_wavef[MOLFILE_MAXWAVEPERTS]; /**< orbital occupancy flags */
540   int num_wavef ;                      /**< # wavefunctions in this ts     */
541   int wavef_size;                      /**< size of one wavefunction
542                                         *   (# of gaussian basis fctns)    */
543   int num_charge_sets;                 /**< # of charge values per atom */
544 } molfile_qm_timestep_metadata_t;
545 
546 
547 /**
548  * QM wavefunction
549  */
550 typedef struct {
551   int   type;               /**< MOLFILE_WAVE_CANON, MOLFILE_WAVE_MCSCFNAT, ... */
552   int   spin;               /**< 1 for alpha, -1 for beta */
553   int   excitation;         /**< 0 for ground state, 1,2,3,... for excited states */
554   int   multiplicity;       /**< spin multiplicity of the state, zero if unknown */
555   char info[MOLFILE_BUFSIZ]; /**< string for additional type info */
556 
557   double energy;            /**< energy of the electronic state.
558                              *   i.e. HF-SCF energy, CI state energy,
559                              *   MCSCF energy, etc. */
560 
561   float *wave_coeffs;       /**< expansion coefficients for wavefunction in the
562                              *   form {orbital1(c1),orbital1(c2),.....,orbitalM(cN)} */
563   float *orbital_energies;  /**< list of orbital energies for wavefunction */
564   float *occupancies;       /**< orbital occupancies */
565   int   *orbital_ids;       /**< orbital ID numbers; If NULL then VMD will
566                              *   assume 1,2,3,...num_orbs.     */
567 } molfile_qm_wavefunction_t;
568 
569 
570 /**
571  * QM per trajectory timestep info
572  * Note that each timestep can contain multiple wavefunctions.
573  */
574 typedef struct {
575   molfile_qm_wavefunction_t *wave; /**< array of wavefunction objects */
576   float  *gradient;         /**< force on each atom (=gradient of energy) */
577 
578   double *scfenergies;      /**< energies from the SCF cycles */
579   double *charges;          /**< per-atom charges */
580   int    *charge_types;     /**< type of each charge set */
581 } molfile_qm_timestep_t;
582 
583 
584 /**************************************************************
585  **************************************************************/
586 
587 
588 
589 
590 /**
591  *  Enumeration of all of the supported graphics objects that can be read
592  *  from graphics file reader plugins.
593  */
594 enum molfile_graphics_type {
595   MOLFILE_POINT,  MOLFILE_TRIANGLE, MOLFILE_TRINORM, MOLFILE_NORMS,
596   MOLFILE_LINE,   MOLFILE_CYLINDER, MOLFILE_CAPCYL,  MOLFILE_CONE,
597   MOLFILE_SPHERE, MOLFILE_TEXT,     MOLFILE_COLOR,   MOLFILE_TRICOLOR
598 };
599 
600 /**
601  *  Individual graphics object/element data
602  */
603 typedef struct {
604   int type;             /* One of molfile_graphics_type */
605   int style;            /* A general style parameter    */
606   float size;           /* A general size parameter     */
607   float data[9];        /* All data for the element     */
608 } molfile_graphics_t;
609 
610 
611 /*
612  * Types for raw graphics elements stored in files.  Data for each type
613  * should be stored by the plugin as follows:
614 
615 type        data                                     style       size
616 ----        ----                                     -----       ----
617 point       x, y, z                                              pixel size
618 triangle    x1,y1,z1,x2,y2,z2,x3,y3,z3
619 trinorm     x1,y1,z1,x2,y2,z2,x3,y3,z3
620             the next array element must be NORMS
621 tricolor    x1,y1,z1,x2,y2,z2,x3,y3,z3
622             the next array elements must be NORMS
623             the following element must be COLOR, with three RGB triples
624 norms       x1,y1,z1,x2,y2,z2,x3,y3,z3
625 line        x1,y1,z1,x2,y2,z2                        0=solid     pixel width
626                                                      1=stippled
627 cylinder    x1,y1,z1,x2,y2,z2                        resolution  radius
628 capcyl      x1,y1,z1,x2,y2,z2                        resolution  radius
629 sphere      x1,y1,z1                                 resolution  radius
630 text        x, y, z, up to 24 bytes of text                      pixel size
631 color       r, g, b
632 */
633 
634 
635 /**
636  * Main file reader API.  Any function in this struct may be NULL
637  * if not implemented by the plugin; the application checks this to determine
638  * what functionality is present in the plugin.
639  */
640 typedef struct {
641   /**
642    * Required header
643    */
644   vmdplugin_HEAD
645 
646   /**
647    * Filename extension for this file type.  May be NULL if no filename
648    * extension exists and/or is known.  For file types that match several
649    * common extensions, list them in a comma separated list such as:
650    *  "pdb,ent,foo,bar,baz,ban"
651    * The comma separated list will be expanded when filename extension matching
652    * is performed.  If multiple plugins solicit the same filename extensions,
653    * the one that lists the extension earliest in its list is selected. In the
654    * case of a "tie", the first one tried/checked "wins".
655    */
656   const char *filename_extension;
657 
658   /**
659    * Try to open the file for reading.  Return an opaque handle, or NULL on
660    * failure. Set the number of atoms; if the number of atoms cannot be
661    * determined, set natoms to MOLFILE_NUMATOMS_UNKNOWN.
662    * Filetype should be the name under which this plugin was registered;
663    * this is provided so that plugins can provide the same function pointer
664    * to handle multiple file types.
665    */
666   void *(* open_file_read)(const char *filepath, const char *filetype,
667       int *natoms);
668 
669   /**
670    * Read molecular structure from the given file handle.  atoms is allocated
671    * by the caller and points to space for natoms.
672    * On success, place atom information in the passed-in pointer.
673    * optflags specifies which optional fields in the atoms will be set by
674    * the plugin.
675    */
676   int (*read_structure)(void *, int *optflags, molfile_atom_t *atoms);
677 
678   /**
679    * Read bond information for the molecule.  On success the arrays from
680    * and to should point to the (one-based) indices of bonded atoms.
681    * Each unique bond should be specified only once, so file formats that list
682    * bonds twice will need post-processing before the results are returned to
683    * the caller.
684    * If the plugin provides bond information, but the file loaded doesn't
685    * actually contain any bond info, the nbonds parameter should be
686    * set to 0 and from/to should be set to NULL to indicate that no bond
687    * information was actually present, and automatic bond search should be
688    * performed.
689    *
690    * If the plugin provides bond order information, the bondorder array
691    * will contain the bond order for each from/to pair.  If not, the bondorder
692    * pointer should be set to NULL, in which case the caller will provide a
693    * default bond order value of 1.0.
694    *
695    * If the plugin provides bond type information, the bondtype array
696    * will contain the bond type index for each from/to pair. These numbers
697    * are consecutive integers starting from 0.
698    * the bondtypenames list, contains the corresponding names, if available,
699    * as a NULL string terminated list. nbondtypes is provided for convenience
700    * and consistency checking.
701    *
702    * These arrays must be freed by the plugin in the close_file_read function.
703    * This function can be called only after read_structure().
704    * Return MOLFILE_SUCCESS if no errors occur.
705    */
706   int (*read_bonds)(void *, int *nbonds, int **from, int **to, float **bondorder,
707                     int **bondtype, int *nbondtypes, char ***bondtypename);
708 
709   /**
710    * XXX this function will be augmented and possibly superceded by a
711    *     new QM-capable version named read_timestep(), when finished.
712    *
713    * Read the next timestep from the file.  Return MOLFILE_SUCCESS, or
714    * MOLFILE_EOF on EOF.  If the molfile_timestep_t argument is NULL, then
715    * the frame should be skipped.  Otherwise, the application must prepare
716    * molfile_timestep_t by allocating space in coords for the corresponding
717    * number of coordinates.
718    * The natoms parameter exists because some coordinate file formats
719    * (like CRD) cannot determine for themselves how many atoms are in a
720    * timestep; the app must therefore obtain this information elsewhere
721    * and provide it to the plugin.
722    */
723   int (* read_next_timestep)(void *, int natoms, molfile_timestep_t *);
724 
725   /**
726    * Close the file and release all data.  The handle cannot be reused.
727    */
728   void (* close_file_read)(void *);
729 
730   /**
731    * Open a coordinate file for writing using the given header information.
732    * Return an opaque handle, or NULL on failure.  The application must
733    * specify the number of atoms to be written.
734    * filetype should be the name under which this plugin was registered.
735    */
736   void *(* open_file_write)(const char *filepath, const char *filetype,
737       int natoms);
738 
739   /**
740    * Write structure information.  Return success.
741    */
742   int (* write_structure)(void *, int optflags, const molfile_atom_t *atoms);
743 
744   /**
745    * Write a timestep to the coordinate file.  Return MOLFILE_SUCCESS if no
746    * errors occur.  If the file contains structure information in each
747    * timestep (like a multi-entry PDB), it will have to cache the information
748    * from the initial calls from write_structure.
749    */
750   int (* write_timestep)(void *, const molfile_timestep_t *);
751 
752   /**
753    * Close the file and release all data.  The handle cannot be reused.
754    */
755   void (* close_file_write)(void *);
756 
757   /**
758    * Retrieve metadata pertaining to volumetric datasets in this file.
759    * Set nsets to the number of volumetric data sets, and set *metadata
760    * to point to an array of molfile_volumetric_t.  The array is owned by
761    * the plugin and should be freed by close_file_read().  The application
762    * may call this function any number of times.
763    */
764   int (* read_volumetric_metadata)(void *, int *nsets,
765         molfile_volumetric_t **metadata);
766 
767   /**
768    * Read the specified volumetric data set into the space pointed to by
769    * datablock.  The set is specified with a zero-based index.  The space
770    * allocated for the datablock must be equal to
771    * xsize * ysize * zsize.  No space will be allocated for colorblock
772    * unless has_color is nonzero; in that case, colorblock should be
773    * filled in with three RGB floats per datapoint.
774    */
775   int (* read_volumetric_data)(void *, int set, float *datablock,
776         float *colorblock);
777 #if vmdplugin_ABIVERSION > 16
778   int (* read_volumetric_data_ex)(void *, molfile_volumetric_readwrite_t *v);
779 #endif
780 
781   /**
782    * Read raw graphics data stored in this file.   Return the number of data
783    * elements and the data itself as an array of molfile_graphics_t in the
784    * pointer provided by the application.  The plugin is responsible for
785    * freeing the data when the file is closed.
786    */
787   int (* read_rawgraphics)(void *, int *nelem, const molfile_graphics_t **data);
788 
789   /**
790    * Read molecule metadata such as what database (if any) this file/data
791    * came from, what the accession code for the database is, textual remarks
792    * and other notes pertaining to the contained structure/trajectory/volume
793    * and anything else that's informative at the whole file level.
794    */
795   int (* read_molecule_metadata)(void *, molfile_metadata_t **metadata);
796 
797   /**
798    * Write bond information for the molecule.  The arrays from
799    * and to point to the (one-based) indices of bonded atoms.
800    * Each unique bond will be specified only once by the caller.
801    * File formats that list bonds twice will need to emit both the
802    * from/to and to/from versions of each.
803    * This function must be called before write_structure().
804    *
805    * Like the read_bonds() routine, the bondorder pointer is set to NULL
806    * if the caller doesn't have such information, in which case the
807    * plugin should assume a bond order of 1.0 if the file format requires
808    * bond order information.
809    *
810    * Support for bond types follows the bondorder rules. bondtype is
811    * an integer array of the size nbonds that contains the bond type
812    * index (consecutive integers starting from 0) and bondtypenames
813    * contain the corresponding strings, in case the naming/numbering
814    * scheme is different from the index numbers.
815    * if the pointers are set to NULL, then this information is not available.
816    * bondtypenames can only be used of bondtypes is also given.
817    * Return MOLFILE_SUCCESS if no errors occur.
818    */
819   int (* write_bonds)(void *, int nbonds, int *from, int *to, float *bondorder,
820                      int *bondtype, int nbondtypes, char **bondtypename);
821 
822   /**
823    * Write the specified volumetric data set into the space pointed to by
824    * datablock.  The * allocated for the datablock must be equal to
825    * xsize * ysize * zsize.  No space will be allocated for colorblock
826    * unless has_color is nonzero; in that case, colorblock should be
827    * filled in with three RGB floats per datapoint.
828    */
829   int (* write_volumetric_data)(void *, molfile_volumetric_t *metadata,
830                                 float *datablock, float *colorblock);
831 #if vmdplugin_ABIVERSION > 16
832   int (* write_volumetric_data_ex)(void *, molfile_volumetric_t *metadata,
833                                    molfile_volumetric_readwrite_t *v);
834 #endif
835 
836   /**
837    * Read in Angles, Dihedrals, Impropers, and Cross Terms and optionally types.
838    * (Cross terms pertain to the CHARMM/NAMD CMAP feature)
839    */
840   int (* read_angles)(void *handle, int *numangles, int **angles, int **angletypes,
841                       int *numangletypes, char ***angletypenames, int *numdihedrals,
842                       int **dihedrals, int **dihedraltypes, int *numdihedraltypes,
843                       char ***dihedraltypenames, int *numimpropers, int **impropers,
844                       int **impropertypes, int *numimpropertypes, char ***impropertypenames,
845                       int *numcterms, int **cterms, int *ctermcols, int *ctermrows);
846 
847   /**
848    * Write out Angles, Dihedrals, Impropers, and Cross Terms
849    * (Cross terms pertain to the CHARMM/NAMD CMAP feature)
850    */
851   int (* write_angles)(void *handle, int numangles, const int *angles, const int *angletypes,
852                        int numangletypes, const char **angletypenames, int numdihedrals,
853                        const int *dihedrals, const int *dihedraltypes, int numdihedraltypes,
854                        const char **dihedraltypenames, int numimpropers,
855                        const int *impropers, const int *impropertypes, int numimpropertypes,
856                        const char **impropertypenames, int numcterms,  const int *cterms,
857                        int ctermcols, int ctermrows);
858 
859 
860   /**
861    * Retrieve metadata pertaining to timestep independent
862    * QM datasets in this file.
863    *
864    * The metadata are the sizes of the QM related data structure
865    * arrays that will be populated by the plugin when
866    * read_qm_rundata() is called. Since the allocation of these
867    * arrays is done by VMD rather than the plugin, VMD needs to
868    * know the sizes beforehand. Consequently read_qm_metadata()
869    * has to be called before read_qm_rundata().
870    */
871   int (* read_qm_metadata)(void *, molfile_qm_metadata_t *metadata);
872 
873 
874   /**
875    * Read timestep independent QM data.
876    *
877    * Typical data that are defined only once per trajectory are
878    * general info about the calculation (such as the used method),
879    * the basis set and normal modes.
880    * The data structures to be populated must have been allocated
881    * before by VMD according to sizes obtained through
882    * read_qm_metadata().
883    */
884   int (* read_qm_rundata)(void *, molfile_qm_t *qmdata);
885 
886 
887   /**
888    * Query the molfile plugin to determine whether or not memory
889    * allocations used for atomic coordinates and PBC unit cell information
890    * need to be aligned to a particular virtual memory or filesystem
891    * page size boundary to facilitate kernel-bypass unbuffered I/O,
892    * e.g., as used by jsplugin.  This API should be called prior to the
893    * first call to read a timestep.  The required page alignment size
894    * (in bytes) is returned to the caller.  If this API has not been
895    * called, then the molfile plugin should revert to standard
896    * kernel-buffered I/O and suffer the associated performance loss.
897    * The caller can be assured that the plugin will not request any
898    * page alignment size that is greater than the value of
899    * MOLFILE_DIRECTIO_MAX_BLOCK_SIZE, both as a runtime sanity check,
900    * and to ensure that a caller that is unable to perform the max
901    * aligned allocation doesn't call the API in the first place.
902    * If a page-aligned allocation is not required for the file being read,
903    * the plugin will return an alignment size of 1.
904    */
905 #if vmdplugin_ABIVERSION > 17
906   int (* read_timestep_pagealign_size)(void *, int *pagealignsize);
907 #endif
908 
909 
910   /**
911    * Read the next timestep from the file.  Return MOLFILE_SUCCESS, or
912    * MOLFILE_EOF on EOF.  If the molfile_timestep_t or molfile_qm_metadata_t
913    * arguments are NULL, then the coordinate or qm data should be skipped.
914    * Otherwise, the application must prepare molfile_timestep_t and
915    * molfile_qm_timestep_t by allocating space for the corresponding
916    * number of coordinates, orbital wavefunction coefficients, etc.
917    * Since it is common for users to want to load only the final timestep
918    * data from a QM run, the application may provide any combination of
919    * valid, or NULL pointers for the molfile_timestep_t and
920    * molfile_qm_timestep_t parameters, depending on what information the
921    * user is interested in.
922    * The natoms and qm metadata parameters exist because some file formats
923    * cannot determine for themselves how many atoms etc are in a
924    * timestep; the app must therefore obtain this information elsewhere
925    * and provide it to the plugin.
926    */
927   int (* read_timestep)(void *, int natoms, molfile_timestep_t *,
928                         molfile_qm_metadata_t *, molfile_qm_timestep_t *);
929 
930   int (* read_timestep_metadata)(void *, molfile_timestep_metadata_t *);
931   int (* read_qm_timestep_metadata)(void *, molfile_qm_timestep_metadata_t *);
932 
933 
934 #if defined(EXPERIMENTAL_DIRECTIO_APIS)
935   /**
936     * Calculate file offsets and I/O lengths for performing
937     * kernel-bypass direct I/O or using GPU-Direct Storage APIs,
938     * thereby enabling peak I/O rates to be achieved for analysis
939     * worksloads like clustering of trajectories.
940     */
941   int (* calc_fileoffsets_timestep)(void *,
942                                     molfile_ssize_t frameindex,
943                                     int firstatom,
944                                     int lastatom,
945                                     int *firstatom,
946                                     int *pageoffset,
947                                     molfile_ssize_t *startoffset,
948                                     molfile_ssize_t *readlen);
949 #endif
950 
951 
952 #if defined(DESRES_READ_TIMESTEP2)
953   /**
954     * Read a specified timestep!
955     */
956   int (* read_timestep2)(void *, molfile_ssize_t index, molfile_timestep_t *);
957 
958   /**
959     * write up to count times beginning at index start into the given
960     * space.  Return the number read, or -1 on error.
961     */
962   molfile_ssize_t (* read_times)( void *,
963                                   molfile_ssize_t start,
964                                   molfile_ssize_t count,
965                                   double * times );
966 #endif
967 
968   /**
969    *  Console output, READ-ONLY function pointer.
970    *  Function pointer that plugins can use for printing to the host
971    *  application's text console.  This provides a clean way for plugins
972    *  to send message strings back to the calling application, giving the
973    *  caller the ability to prioritize, buffer, and redirect console messages
974    *  to an appropriate output channel, window, etc.  This enables the use of
975    *  graphical consoles like TkCon without losing console output from plugins.
976    *  If the function pointer is NULL, no console output service is provided
977    *  by the calling application, and the output should default to stdout
978    *  stream.  If the function pointer is non-NULL, all output will be
979    *  subsequently dealt with by the calling application.
980    *
981    *  XXX this should really be put into a separate block of
982    *      application-provided read-only function pointers for any
983    *      application-provided services
984    */
985   int (* cons_fputs)(const int, const char*);
986 
987 } molfile_plugin_t;
988 
989 #endif
990 
991