#include "largefiles.h" /* platform dependent 64-bit file I/O defines */ #include #include #include #include #include "molfile_plugin.h" #include "gemmi/cif.hpp" #include "gemmi/smcif.hpp" typedef struct { int numatoms; int step; const char *filename; gemmi::cif::Document *doc; } cifdata; static void *open_cif_read(const char *filename, const char *filetype, int *natoms) { cifdata *data = (cifdata *) malloc(sizeof(cifdata)); printf("cif) trying to open file '%s'\n", filename); data->doc = new gemmi::cif::Document(gemmi::cif::read_file(filename)); printf("cif) read %zd blocks\n", data->doc->blocks.size()); // Find the number of atoms in the first block gemmi::SmallStructure s = gemmi::make_small_structure_from_block(data->doc->blocks[0]); *natoms = s.get_all_unit_cell_sites().size(); printf("cif) number of atoms: %d\n", *natoms); printf("cif) space group: %s\n", s.spacegroup_hm.c_str()); printf("cif) cell parameters: %g %g %g %g %g %g\n", s.cell.a, s.cell.b, s.cell.c, s.cell.alpha, s.cell.beta, s.cell.gamma); data->filename = filename; data->numatoms = *natoms; data->step = 0; return data; } static int read_cif_structure(void *mydata, int *optflags, molfile_atom_t *atoms) { int i; cifdata *data = (cifdata *) mydata; gemmi::SmallStructure s = gemmi::make_small_structure_from_block(data->doc->blocks[0]); auto sites = s.get_all_unit_cell_sites(); for (i=0; istep >= data->doc->blocks.size()) return MOLFILE_ERROR; gemmi::SmallStructure s = gemmi::make_small_structure_from_block(data->doc->blocks[data->step]); auto sites = s.get_all_unit_cell_sites(); n = sites.size(); if (n != natoms) { printf("cif) Number of atoms in block %d is %d, not %d as expected", data->step, n, natoms); return MOLFILE_ERROR; } printf("cif) reading block #%d\n", data->step); printf("cif) space group: %s\n", s.spacegroup_hm.c_str()); printf("cif) cell parameters: %g %g %g %g %g %g\n", s.cell.a, s.cell.b, s.cell.c, s.cell.alpha, s.cell.beta, s.cell.gamma); /* Cell parameters */ ts->A = s.cell.a; ts->B = s.cell.b; ts->C = s.cell.c; ts->alpha = s.cell.alpha; ts->beta = s.cell.beta; ts->gamma = s.cell.gamma; /* read the coordinates */ for (i=0; icoords[3*i ] = p.x; ts->coords[3*i+1] = p.y; ts->coords[3*i+2] = p.z; printf("cif) %g %g %g\n", p.x, p.y, p.z); } data->step += 1; return MOLFILE_SUCCESS; } static void close_cif_read(void *mydata) { cifdata *data = (cifdata *) mydata; delete data->doc; free(mydata); } static molfile_plugin_t plugin; VMDPLUGIN_API int VMDPLUGIN_init() { memset(&plugin, 0, sizeof(molfile_plugin_t)); plugin.abiversion = vmdplugin_ABIVERSION; plugin.type = MOLFILE_PLUGIN_TYPE; plugin.name = "cif"; plugin.prettyname = "CIF"; plugin.author = "Francois-Xavier Coudert"; plugin.majorv = 0; plugin.minorv = 1; plugin.is_reentrant = VMDPLUGIN_THREADSAFE; plugin.filename_extension = "cif"; plugin.open_file_read = open_cif_read; plugin.read_structure = read_cif_structure; plugin.read_next_timestep = read_cif_timestep; plugin.close_file_read = close_cif_read; return VMDPLUGIN_SUCCESS; } VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) { (*cb)(v, (vmdplugin_t *)&plugin); return VMDPLUGIN_SUCCESS; } VMDPLUGIN_API int VMDPLUGIN_fini() { return VMDPLUGIN_SUCCESS; }