Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

qcschemaplugin.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2016 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /* This is a plugin that will read input from a JSON file
00010 ** generated from QCSchema MolSSI efforts
00011 ** some more details will go here soon 
00012 */
00013 
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <ctype.h>
00017 #include <string.h>
00018 
00019 #include <sys/stat.h>
00020 #include "qcschema_json.c"
00021 
00022 #if defined(_AIX)
00023 #include <strings.h>
00024 #endif
00025 
00026 #if defined(WIN32) || defined(WIN64)
00027 #define strcasecmp stricmp
00028 #endif
00029 
00030 #include "molfile_plugin.h"
00031 #include "unit_conversion.h"
00032 #include "periodic_table.h"
00033 #include "qmplugin.h"
00034 
00035 
00036 #define ALLOCATE(array, type, size) \
00037   array = (type *)calloc(size, sizeof(type)); \
00038   if (array == NULL) { \
00039     fprintf(stderr, "qcschemaplugin) Memory allocation for %s failed!\n", #array); \
00040     return FALSE; \
00041   }
00042 
00043 #define GET_LINE(x,y) if (!fgets(x, sizeof(x), y)) return FALSE
00044 
00045 /* Read the basis set data */
00046 static int get_basis (qmdata_t *);
00047 static int shelltype_int(char *type);
00048 static int fill_basis_arrays(qmdata_t *data);
00049 
00050 /*static int read_geom_block(qmdata_t *data);*/
00051 static int read_molecular_orbitals(qmdata_t *data);
00052 static int read_wave_coeffs(FILE *file, qm_wavefunction_t *wave);
00053 static int count_orbitals(qmdata_t *data);
00054 
00055 typedef struct {
00056   json_value* geom_array;   /* store geometry array */
00057   json_value* symbol_array; /* store symbol array */
00058   json_value* model;        /* store method, basis, etc */
00059   json_value* keywords;     /* store keywords */
00060   json_value* extras;       /* store extras */
00061   json_value* provenance;   /* store creator program, version, routine, etc */
00062   json_value* properties;   /* store properties */
00063   json_value* return_result;   /* store result */
00064   int coordsonly;
00065 } jsondata_t;
00066 
00067 /*********************************************************
00068  *
00069  * Open file and fill corresponding json_values.
00070  * After, file is not used. Returns natoms.
00071  *
00072  *********************************************************/
00073 static void *open_qcschema_read(const char *filename,
00074                               const char *filetype,
00075                               int *natoms) {
00076   FILE *fd;
00077   qmdata_t *data = NULL;
00078   char buffer[1024];
00079   char keystring[20];
00080   json_char* json;
00081   json_value* value;
00082   json_value* aux_value;
00083   char* file_contents;
00084   struct stat filestatus;
00085   int file_size;
00086 
00087   if ( stat(filename, &filestatus) != 0) {
00088     fprintf(stderr, "File %s not found\n", filename);
00089     return NULL;
00090   }
00091   file_size = filestatus.st_size;
00092   file_contents = (char*)malloc(filestatus.st_size);
00093   if ( file_contents == NULL) {
00094     fprintf(stderr, "Memory error: unable to allocate %d bytes\n", file_size);
00095     return NULL;
00096   }
00097 
00098   fd = fopen(filename, "rb");
00099   if (!fd) return NULL;
00100   
00101   /* allocate memory for main QM data structure */
00102   data = init_qmdata();
00103   if (!data) return NULL;
00104 
00105   data->file = fd;
00106 
00107   /* allocate JSON specific data */
00108   jsondata_t * jsondata = (jsondata_t *)calloc(1, sizeof(jsondata_t));
00109   if (!jsondata) return NULL;
00110   
00111   if ( fread(file_contents, file_size, 1, fd) != 1 ) {
00112     fprintf(stderr, "Unable to read content of %s\n", filename);
00113     fclose(fd);
00114     free(file_contents);
00115     return NULL;
00116   }
00117 
00118   fclose(fd);
00119   json = (json_char*)file_contents;
00120   
00121   value = json_parse(json,file_size);
00122 
00123   int i, j;
00124   if (value == NULL) {
00125     return NULL;
00126   }
00127   
00128   _Bool check_schema_done = FALSE;
00129   _Bool molecule_done = FALSE;
00130   _Bool driver_done = FALSE;
00131   _Bool model_done = FALSE;
00132   _Bool extras_done = FALSE;
00133   _Bool properties_done = FALSE;
00134   _Bool return_result_done = FALSE;
00135 
00136   /* loop over main objects */
00137   for (i = 0; i < value->u.object.length; i++) {
00138     /*printf("object[%d].name = %s\n", i, value->u.object.values[i].name);*/
00139     
00140     /* Check if the file is QCSCHEMA format */
00141     if (!check_schema_done && !strcmp(value->u.object.values[i].name, "schema_name")) {
00142       /* we have a QCSchema file */
00143       check_schema_done = TRUE;
00144     }
00145 
00146     else if (!molecule_done && !strcmp(value->u.object.values[i].name, "molecule")) {
00147       /* read molecule part */
00148       aux_value = value->u.object.values[i].value;
00149       /* in molecule, the order of 'geometry' and 'symbols' is not fixed */
00150       for (j = 0; j < aux_value->u.object.length; j++) {
00151         if (!strcmp(aux_value->u.object.values[j].name, "geometry")) {
00152           /* number of atoms must be array size / 3 */
00153           data->numatoms = aux_value->u.object.values[j].value->u.array.length / 3;
00154           jsondata->geom_array = aux_value->u.object.values[j].value;
00155         } 
00156         else if (!strcmp(aux_value->u.object.values[j].name, "symbols")) {  
00157           /* get numatoms from size */
00158           data->numatoms = aux_value->u.object.values[j].value->u.array.length;
00159           jsondata->symbol_array = aux_value->u.object.values[j].value;
00160         }
00161         else if (!strcmp(aux_value->u.object.values[j].name, "molecular_charge")) {  
00162           data->totalcharge = aux_value->u.object.values[j].value;
00163         }
00164         else if (!strcmp(aux_value->u.object.values[j].name, "molecular_multiplicity")) {  
00165           data->multiplicity = aux_value->u.object.values[j].value;
00166         }
00167       }
00168       molecule_done = TRUE;
00169     }
00170 
00171     else if (!driver_done && !strcmp(value->u.object.values[i].name, "driver")) {
00172       aux_value = value->u.object.values[i].value;
00173       /* there are only 4 types supported: energy, gradient, hessian, properties */
00174       if (!strcmp(aux_value->u.string.ptr, "energy")) {
00175         data->runtype = MOLFILE_RUNTYPE_ENERGY;
00176       }
00177       else if (!strcmp(aux_value->u.string.ptr, "gradient")) {
00178         data->runtype = MOLFILE_RUNTYPE_GRADIENT;
00179       }
00180       else if (!strcmp(aux_value->u.string.ptr, "hessian")) {
00181         data->runtype = MOLFILE_RUNTYPE_HESSIAN;
00182       }
00183       driver_done = TRUE;
00184     }
00185 
00186     else if (!model_done && !strcmp(value->u.object.values[i].name, "model")) {
00187       jsondata->model = value->u.object.values[i].value;
00188       model_done = TRUE;
00189     }
00190 
00191     else if (!extras_done && !strcmp(value->u.object.values[i].name, "extras")) {
00192       jsondata->extras = value->u.object.values[i].value;
00193       extras_done = TRUE;
00194     }
00195 
00196     else if (!properties_done && !strcmp(value->u.object.values[i].name, "properties")) {
00197       jsondata->properties = value->u.object.values[i].value;
00198       properties_done = TRUE;
00199     }
00200 
00201     else if (!return_result_done && !strcmp(value->u.object.values[i].name, "return_result")) {
00202       jsondata->return_result = value->u.object.values[i].value;
00203       return_result_done = TRUE;
00204     }
00205   }
00206 
00207   if (!check_schema_done) {
00208     printf("qcschemaplugin) The file is not in JSON/QCSCHEMA format!\n");
00209     return NULL;
00210   }
00211   
00212 
00213   /* allocate JSON specific data */
00214   data->format_specific_data = jsondata;
00215   *natoms = data->numatoms;
00216   data->num_frames = 1;
00217   return data;
00218 }
00219 
00220 
00221 /**********************************************************
00222  *
00223  * Read geometry from json_value object
00224  *
00225  *********************************************************/
00226 static int read_qcschema_structure(void *mydata, int *optflags, 
00227                                  molfile_atom_t *atoms) 
00228 {
00229   int i;
00230   char buffer[1024];
00231   char atname[1024];
00232   int num, atomicnum;
00233   molfile_atom_t *atom;
00234   qmdata_t *data = (qmdata_t *)mydata;
00235   jsondata_t* jsondata = (jsondata_t*)data->format_specific_data;
00236 
00237   ALLOCATE(data->atoms, qm_atom_t, data->numatoms);
00238 
00239   /* atomic number is provided by plugin.
00240    * (This is required for QM plugins!) */
00241   *optflags = MOLFILE_ATOMICNUMBER;
00242 
00243   float unitfac = 1.f; /* to use in case of bohr units */
00244 
00245   for (i=0; i<data->numatoms; i++) {
00246     atom = atoms+i;
00247 
00248     strncpy(atname,jsondata->symbol_array->u.array.values[i]->u.string.ptr,sizeof(atname));
00249 
00250     strncpy(atom->name, atname, sizeof(atom->name)); 
00251     strncpy(atom->type, atom->name, sizeof(atom->type));
00252     atom->atomicnumber = get_pte_idx_from_string(atname);
00253     strncpy(atom->resname,"MOL", sizeof(atom->resname));
00254     atom->resid = 1;
00255     atom->chain[0] = '\0';
00256     atom->segid[0] = '\0';
00257     data->atoms[i].atomicnum = atom->atomicnumber;
00258     data->num_frames_read = 0;
00259 
00260     /* keep local copy */
00261     strncpy(data->atoms[i].type, atname, sizeof(data->atoms[i].type));
00262     data->atoms[i].atomicnum = atomicnum;
00263     data->atoms[i].x = jsondata->geom_array->u.array.values[i*3]->u.dbl*unitfac;
00264     data->atoms[i].y = jsondata->geom_array->u.array.values[i*3+1]->u.dbl*unitfac;
00265     data->atoms[i].z = jsondata->geom_array->u.array.values[i*3+2]->u.dbl*unitfac;
00266     
00267   }
00268 
00269   return MOLFILE_SUCCESS;
00270 
00271 }
00272 
00273 
00274 /***********************************************************
00275  *
00276  * Provide non-QM metadata for next timestep. 
00277  * Required by the plugin interface.
00278  *
00279  ***********************************************************/
00280 static int read_timestep_metadata(void *mydata,
00281                                   molfile_timestep_metadata_t *meta) {
00282   
00283   meta->count = -1;
00284   meta->has_velocities = 0;
00285 
00286   return MOLFILE_SUCCESS;
00287 }
00288 
00289 
00290 /***********************************************************
00291  *
00292  * We are not reading the coefficients themselves,
00293  * because that could require a large amount of memory.
00294  *
00295  ***********************************************************/
00296 static int read_qm_timestep_metadata(void *mydata,
00297                                     molfile_qm_timestep_metadata_t *meta) {
00298   qmdata_t *data = (qmdata_t *)mydata;
00299   jsondata_t* jsondata = (jsondata_t *)data->format_specific_data;
00300  
00301   if (data->num_frames_sent >= data->num_frames) {
00302     /* All frames were sent. */
00303     return MOLFILE_ERROR;
00304   }
00305 
00306   /* Count the number of cartesian basis functions in 
00307      the basis set */
00308   if (data->num_frames_sent == data->num_frames-1) {
00309     int i;
00310     qm_timestep_t *cur_ts;
00311 
00312     if (!count_orbitals(data)) return MOLFILE_ERROR;
00313 
00314     /* get a pointer to the current qm timestep */
00315     cur_ts = data->qm_timestep;
00316     
00317     for (i=0; (i<MOLFILE_MAXWAVEPERTS && i<cur_ts->numwave); i++) {
00318       meta->num_orbitals_per_wavef[i] = cur_ts->wave[i].num_orbitals;
00319       meta->has_occup_per_wavef[i]    = cur_ts->wave[i].has_occup;
00320       meta->has_orben_per_wavef[i]    = cur_ts->wave[i].has_orben;
00321     }
00322     meta->wavef_size   = data->wavef_size;
00323     meta->num_wavef    = cur_ts->numwave;
00324     meta->num_scfiter  = cur_ts->num_scfiter;
00325     meta->has_gradient = FALSE;
00326     meta->num_charge_sets = 0;
00327   }
00328   return MOLFILE_SUCCESS;
00329 }
00330 
00331 
00332 
00333 /***********************************************************
00334  *
00335  * Provides VMD with the data of the next timestep.
00336  *
00337  ***********************************************************/
00338 static int read_timestep(void *mydata, int natoms, 
00339        molfile_timestep_t *ts, molfile_qm_metadata_t *qm_metadata,
00340                          molfile_qm_timestep_t *qm_ts) {
00341   int i;
00342   qmdata_t *data = (qmdata_t *)mydata;
00343   qm_timestep_t *cur_ts;
00344 
00345   if (data->num_frames_sent >= data->num_frames) {
00346     /* All frames were sent. */
00347     return MOLFILE_ERROR;
00348   }
00349 
00350   if (data->num_frames_sent == data->num_frames_read) {
00351     /* Read next coordinate block from file */
00352     /*fseek(data->file, data->filepos_array[data->num_frames_read], SEEK_SET);*/
00353     /*read_geom_block(data);*/
00354 
00355     printf("qcschemaplugin) Read frame %d\n", data->num_frames_read);
00356     data->num_frames_read++;
00357   }
00358 
00359 
00360   /* Copy the coordinates */
00361   for (i=0; i<natoms; i++) {
00362     ts->coords[3*i  ] = data->atoms[i].x;
00363     ts->coords[3*i+1] = data->atoms[i].y;
00364     ts->coords[3*i+2] = data->atoms[i].z; 
00365   }
00366   
00367   /*printf("qcschemaplugin) Sent frame %d\n", data->num_frames_sent); */
00368   data->num_frames_sent++;
00369 
00370   /* In MOLDEN the MOs are listed only for the last frame */
00371   if (data->num_frames_sent == data->num_frames) {
00372     
00373     /* get a convenient pointer to the current qm timestep */
00374     cur_ts = data->qm_timestep;
00375 
00376     read_molecular_orbitals(data);
00377 
00378     /* store the wave function and orbital energies */
00379     if (cur_ts != NULL && cur_ts->wave != NULL) {
00380       for (i=0; i<cur_ts->numwave; i++) {
00381         qm_wavefunction_t *wave = &cur_ts->wave[i];
00382         qm_ts->wave[i].type         = wave->type;
00383         qm_ts->wave[i].spin         = wave->spin;
00384         qm_ts->wave[i].excitation   = wave->exci;
00385         qm_ts->wave[i].multiplicity = wave->mult;
00386         qm_ts->wave[i].energy       = wave->energy;
00387         strncpy(qm_ts->wave[i].info, wave->info, MOLFILE_BUFSIZ);
00388         
00389         if (wave->wave_coeffs) {
00390           memcpy(qm_ts->wave[i].wave_coeffs, wave->wave_coeffs,
00391                  wave->num_orbitals*data->wavef_size*sizeof(float));
00392         }
00393         if (wave->orb_energies) {
00394           memcpy(qm_ts->wave[i].orbital_energies, wave->orb_energies,
00395                  wave->num_orbitals*sizeof(float));
00396         }
00397         if (wave->has_occup) {
00398           memcpy(qm_ts->wave[i].occupancies, wave->orb_occupancies,
00399                  wave->num_orbitals*sizeof(float));
00400         }
00401       }
00402     }
00403 
00404   }
00405   
00406   return MOLFILE_SUCCESS;
00407 }
00408   
00409 
00410 /*****************************************************
00411  *
00412  * Provide VMD with the sizes of the QM related
00413  * data structure arrays that need to be made
00414  * available.
00415  * Since we cannot determine the basis set meta data
00416  * without parsing the whole basis set section, we
00417  * read all basis set data here. The data is stored
00418  * in the qmdata_t structure for later use in
00419  * read_molden_rundata().
00420  *
00421  *****************************************************/
00422 static int read_qcschema_metadata(void *mydata, 
00423     molfile_qm_metadata_t *metadata) {
00424 
00425   qmdata_t *data;
00426   jsondata_t* jsondata = (jsondata_t *)data->format_specific_data;
00427   data = (qmdata_t *)mydata;
00428   
00429   metadata->ncart = 0;
00430   metadata->nimag = 0;
00431   metadata->nintcoords = 0;
00432 
00433   metadata->have_sysinfo = 0;
00434   metadata->have_carthessian = 0;
00435   metadata->have_inthessian = 0;
00436   metadata->have_normalmodes = 0;
00437 
00438   metadata->num_basis_funcs = 0;
00439   metadata->num_basis_atoms = 0;
00440   metadata->num_shells = 0;
00441   metadata->wavef_size = 0;
00442 
00443   jsondata->coordsonly = 1;
00444 
00445   if (!jsondata->coordsonly) {
00446     /* Read the basis set */
00447     if (!get_basis(data)) return MOLFILE_ERROR; 
00448 
00449     /* orbital + basis set data */
00450     metadata->num_basis_funcs = data->num_basis_funcs;
00451     metadata->num_basis_atoms = data->num_basis_atoms;
00452     metadata->num_shells      = data->num_shells;
00453     metadata->wavef_size      = data->wavef_size;  
00454   }
00455 
00456   return MOLFILE_SUCCESS;
00457 }
00458 
00459 
00460 /******************************************************
00461  * 
00462  * Provide VMD with the static (i.e. non-trajectory)
00463  * data. That means we are filling the molfile_plugin
00464  * data structures.
00465  *
00466  ******************************************************/
00467 static int read_qcschema_rundata(void *mydata, 
00468                                molfile_qm_t *qm_data) {
00469   qmdata_t *data = (qmdata_t *)mydata;
00470   int i;
00471   molfile_qm_hessian_t *hessian_data;
00472   molfile_qm_basis_t   *basis_data;
00473   molfile_qm_sysinfo_t *sys_data;
00474 
00475   if (!qm_data) return MOLFILE_ERROR;
00476 
00477 
00478   hessian_data = &qm_data->hess;
00479   basis_data   = &qm_data->basis;
00480   sys_data     = &qm_data->run;
00481 
00482   sys_data->num_electrons = data->num_electrons;
00483   sys_data->totalcharge = data->totalcharge;
00484   sys_data->runtype = data->runtype;
00485 
00486 
00487   /* Populate basis set data */
00488   if (data->num_basis_funcs) {
00489     for (i=0; i<data->num_basis_atoms; i++) {
00490       basis_data->num_shells_per_atom[i] = data->num_shells_per_atom[i];
00491       basis_data->atomic_number[i] = data->atomicnum_per_basisatom[i];
00492     }
00493     
00494     for (i=0; i<data->num_shells; i++) {
00495       basis_data->num_prim_per_shell[i] = data->num_prim_per_shell[i];
00496       basis_data->shell_types[i] = data->shell_types[i];
00497     }
00498     
00499     for (i=0; i<2*data->num_basis_funcs; i++) {
00500       basis_data->basis[i] = data->basis[i];
00501     }
00502 
00503     /* If we have MOs in the file we must provide the 
00504      * angular momentum exponents */
00505     if (data->angular_momentum) {
00506       for (i=0; i<3*data->wavef_size; i++) {
00507         basis_data->angular_momentum[i] = data->angular_momentum[i];
00508       }
00509     }
00510   }
00511 
00512   /* fill in molfile_qm_sysinfo_t */
00513   /*sys_data->runtype = data->runtype;
00514   sys_data->scftype = data->scftype;
00515   sys_data->nproc   = data->nproc;
00516   sys_data->num_electrons  = data->num_electrons;
00517   sys_data->totalcharge    = data->totalcharge;
00518   sys_data->num_occupied_A = data->num_occupied_A;
00519   sys_data->num_occupied_B = data->num_occupied_B;
00520   sys_data->status         = data->opt_status;
00521   */
00522   return MOLFILE_SUCCESS;
00523 }
00524 
00525 
00526 /**********************************************************
00527  *
00528  * close file and free memory
00529  *
00530  **********************************************************/
00531 static void close_qcschema_read(void *mydata) {
00532   int i, j;
00533   qmdata_t *data = (qmdata_t *)mydata;
00534    
00535   /*fclose(data->file);*/
00536   free(data->atoms);
00537   free(data->basis);
00538   free(data->shell_types);
00539   free(data->atomicnum_per_basisatom);
00540   free(data->num_shells_per_atom);
00541   free(data->num_prim_per_shell);
00542   free(data->angular_momentum);
00543 
00544   if (data->basis_set) {
00545     for(i=0; i<data->num_basis_atoms; i++) {
00546       for (j=0; j<data->basis_set[i].numshells; j++) {
00547         free(data->basis_set[i].shell[j].prim);
00548       }
00549       free(data->basis_set[i].shell);
00550     } 
00551     free(data->basis_set);
00552   }
00553 
00554   free(data->format_specific_data);
00555   free(data->filepos_array);
00556 
00557   if (data->qm_timestep != NULL) {
00558     for (j=0; j<data->qm_timestep[0].numwave; j++) {
00559       free(data->qm_timestep[0].wave[j].wave_coeffs);
00560       free(data->qm_timestep[0].wave[j].orb_energies);
00561       free(data->qm_timestep[0].wave[j].orb_occupancies);
00562     }
00563     free(data->qm_timestep[0].wave);
00564     free(data->qm_timestep);
00565   } else {
00566     printf("close_qcschema_read(): NULL qm_timestep!\n");
00567   }
00568 
00569   free(data);
00570 }
00571 
00572 
00573 /* ####################################################### */
00574 /*             End of API functions                        */
00575 /* The following functions actually do the file parsing.   */
00576 /* ####################################################### */
00577 
00578 
00579 static int get_basis(qmdata_t *data) {
00580 
00581   return TRUE;
00582 }
00583 
00584 
00585 /******************************************************
00586  *
00587  * Populate the flat arrays containing the basis
00588  * set data.
00589  *
00590  ******************************************************/
00591 static int fill_basis_arrays(qmdata_t *data) {
00592   int i, j, k;
00593   int shellcount = 0;
00594   int primcount = 0;
00595 
00596   float *basis;
00597   int *num_shells_per_atom;
00598   int *num_prim_per_shell;
00599   int *shell_types;
00600   int *atomicnum_per_basisatom;
00601 
00602   /* Count the total number of primitives which
00603    * determines the size of the basis array. */
00604   for(i=0; i<data->num_basis_atoms; i++) {
00605     for (j=0; j<data->basis_set[i].numshells; j++) {
00606       primcount += data->basis_set[i].shell[j].numprims;
00607     }
00608   }
00609   data->num_basis_funcs = primcount;
00610 
00611   /* reserve space for pointer to array containing basis
00612    * info, i.e. contraction coeficients and expansion 
00613    * coefficients; need 2 entries per basis function, i.e.
00614    * exponent and contraction coefficient; also,
00615    * allocate space for the array holding the orbital symmetry
00616    * information per primitive Gaussian.
00617    * Finally, initialize the arrays holding the number of 
00618    * shells per atom and the number of primitives per shell*/
00619   ALLOCATE(basis,                   float, 2*primcount);
00620   ALLOCATE(shell_types,             int,   data->num_shells);
00621   ALLOCATE(num_shells_per_atom,     int,   data->num_basis_atoms);
00622   ALLOCATE(num_prim_per_shell,      int,   data->num_shells);
00623   ALLOCATE(atomicnum_per_basisatom, int,   data->num_basis_atoms);
00624 
00625 
00626 
00627   /* store pointers in struct qmdata_t */
00628   data->basis = basis;
00629   data->shell_types = shell_types;
00630   data->num_shells_per_atom = num_shells_per_atom;
00631   data->num_prim_per_shell  = num_prim_per_shell;
00632   data->atomicnum_per_basisatom = atomicnum_per_basisatom;
00633 
00634   primcount = 0;
00635   for (i=0; i<data->num_basis_atoms; i++) {
00636     /* assign atomic number */
00637     data->basis_set[i].atomicnum = data->atoms[i].atomicnum;
00638     atomicnum_per_basisatom[i]   = data->atoms[i].atomicnum;
00639 
00640     num_shells_per_atom[i] = data->basis_set[i].numshells;
00641 
00642     for (j=0; j<data->basis_set[i].numshells; j++) {
00643       shell_types[shellcount]        = data->basis_set[i].shell[j].type;
00644       num_prim_per_shell[shellcount] = data->basis_set[i].shell[j].numprims;
00645 
00646       for (k=0; k<data->basis_set[i].shell[j].numprims; k++) {
00647         basis[2*primcount  ] = data->basis_set[i].shell[j].prim[k].exponent;
00648         basis[2*primcount+1] = data->basis_set[i].shell[j].prim[k].contraction_coeff;
00649         primcount++;
00650       }
00651       shellcount++;
00652     }
00653   } 
00654 
00655   return TRUE;
00656 }
00657 
00658 
00659 /**************************************************
00660  *
00661  * Convert shell type from char to int.
00662  * Note that SP_P shells are assigned in get_basis()
00663  *
00664  ************************************************ */
00665 static int shelltype_int(char *type) {
00666   int shelltype;
00667   if      (!strcasecmp(type, "sp")) shelltype = SP_SHELL;
00668   else if (!strcasecmp(type, "s"))  shelltype = S_SHELL;
00669   else if (!strcasecmp(type, "p"))  shelltype = P_SHELL;
00670   else if (!strcasecmp(type, "d"))  shelltype = D_SHELL;
00671   else if (!strcasecmp(type, "f"))  shelltype = F_SHELL;
00672   else if (!strcasecmp(type, "g"))  shelltype = G_SHELL;
00673   else shelltype = UNK_SHELL;
00674   
00675   return shelltype;
00676 }
00677 
00678 static int count_orbitals(qmdata_t *data) {
00679   int nr;
00680   int num_wave_coeff=0;
00681   float orbenergy, occu;
00682   char spin[1024];
00683   qm_wavefunction_t *wave;
00684   jsondata_t *jsondata = (jsondata_t *)data->format_specific_data;
00685   int dummy1;
00686   float dummy2;
00687 
00688   /* Allocate memory for the qm_timestep frame */
00689   data->qm_timestep = (qm_timestep_t *)calloc(1, sizeof(qm_timestep_t));
00690 
00691   return TRUE;
00692 }
00693 
00694 static int read_molecular_orbitals(qmdata_t *data) {
00695   jsondata_t *jsondata = (jsondata_t *)data->format_specific_data;
00696   qm_wavefunction_t *wave;
00697   if (!data->qm_timestep || jsondata->coordsonly) return FALSE;
00698   return TRUE;
00699 }
00700 
00701 static int read_wave_coeffs(FILE *file, qm_wavefunction_t *wave) {
00702   return TRUE;
00703 }
00704 
00705 /*************************************************************
00706  *
00707  * plugin registration 
00708  *
00709  **************************************************************/
00710 static molfile_plugin_t plugin;
00711 
00712 VMDPLUGIN_API int VMDPLUGIN_init() {
00713   memset(&plugin, 0, sizeof(molfile_plugin_t));
00714   plugin.abiversion = vmdplugin_ABIVERSION;
00715   plugin.type = MOLFILE_PLUGIN_TYPE;
00716   plugin.name = "qcschema";
00717   plugin.prettyname = "QCSchema";
00718   plugin.author = "Mariano Spivak";
00719   plugin.majorv = 0;
00720   plugin.minorv = 1;
00721   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00722   plugin.filename_extension = "json,qcs";
00723   plugin.open_file_read = open_qcschema_read;
00724   plugin.read_structure = read_qcschema_structure;
00725 
00726   plugin.read_timestep_metadata    = read_timestep_metadata;
00727   plugin.read_timestep             = read_timestep;
00728   plugin.read_qm_timestep_metadata = read_qm_timestep_metadata;
00729 
00730   plugin.read_qm_metadata = read_qcschema_metadata;
00731   plugin.read_qm_rundata  = read_qcschema_rundata;
00732 
00733   plugin.close_file_read = close_qcschema_read;
00734   return VMDPLUGIN_SUCCESS;
00735 }
00736 
00737 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00738   (*cb)(v, (vmdplugin_t *)&plugin);
00739   return VMDPLUGIN_SUCCESS;
00740 }
00741 
00742 VMDPLUGIN_API int VMDPLUGIN_fini() {
00743   return VMDPLUGIN_SUCCESS;
00744 }
00745 

Generated on Wed Nov 11 03:06:33 2020 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002