00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "largefiles.h"
00019
00020 #include <stdlib.h>
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <limits.h>
00024
00025 #include "molfile_plugin.h"
00026
00027 #if INT_MAX == 2147483647
00028 typedef int binpos_int32;
00029 #elif SHRT_MAX == 2147483647
00030 typedef short binpos_int32;
00031 #elif LONG_MAX == 2147483647
00032 typedef long binpos_int32;
00033 #endif
00034
00035 typedef struct {
00036 FILE *fd;
00037 int numatoms;
00038 int wrongendian;
00039 float *xyz;
00040 } binposhandle;
00041
00042 static void *open_binpos_read(const char *path, const char *filetype,
00043 int *natoms) {
00044 binposhandle *binpos;
00045 FILE *fd;
00046 int er=0,point,igarb;
00047 char lenbuf[4];
00048 char tmpc;
00049 char magicchar[5];
00050
00051 fd = fopen(path, "rb");
00052 if (!fd)
00053 {
00054 fprintf(stderr, "Could not open file '%s' for reading.\n", path);
00055 return NULL;
00056 }
00057 binpos = (binposhandle *)malloc(sizeof(binposhandle));
00058 memset(binpos, 0, sizeof(binposhandle));
00059 fread(magicchar,sizeof(char),4,fd);
00060 magicchar[4]= '\0' ;
00061 if(strcmp(magicchar,"fxyz")!=0)
00062 {
00063 fprintf(stderr,"not a binpos amber coordinate file\n");
00064 return NULL;
00065 }
00066 fprintf(stderr,"Proceeding to open amber7 binpos coordinate file\n");
00067 fread(&igarb,sizeof(int),1,fd);
00068 point=ftell(fd);
00069
00070
00071 if(igarb>1000000000)
00072 {
00073 fprintf(stderr, "File '%s' appears to be other-endian.\n", path);
00074 binpos->wrongendian = 1;
00075 memcpy(lenbuf, (const char *)&igarb, 4);
00076 tmpc = lenbuf[0]; lenbuf[0] = lenbuf[3]; lenbuf[3] = tmpc;
00077 tmpc = lenbuf[1]; lenbuf[1] = lenbuf[2]; lenbuf[2] = tmpc;
00078 memcpy((char *)&igarb, lenbuf, 4);
00079
00080 if((fseek(fd, point, SEEK_SET))!=0)
00081 {
00082 fprintf(stderr,"Endian correction failed. er=%d\n",er);
00083 return NULL;
00084 }
00085 fseek(fd, point, SEEK_SET);
00086 }
00087 binpos->fd = fd;
00088 binpos->numatoms = igarb;
00089 binpos->xyz = (float *)malloc(3 * binpos->numatoms * sizeof(float));
00090
00091 if (!binpos->xyz) {
00092 fprintf(stderr, "Unable to allocate space for %d atoms.\n", binpos->numatoms);
00093 fclose(fd);
00094 free(binpos);
00095 return NULL;
00096 }
00097 *natoms = binpos->numatoms;
00098 return binpos;
00099 }
00100
00101 static int read_next_timestep(void *v, int natoms, molfile_timestep_t *ts)
00102 {
00103 binposhandle *binpos;
00104 int i, numatoms,igarb;
00105 char *cdata;
00106 char tmpc;
00107
00108 binpos = (binposhandle *)v;
00109 if (!binpos->fd)
00110 return MOLFILE_ERROR;
00111
00112 numatoms = binpos->numatoms;
00113
00114 if (fread(binpos->xyz, sizeof(float), 3 * numatoms, binpos->fd)
00115 != (size_t)(3 * numatoms)) {
00116 fprintf(stderr, "Failure reading data from amber7 binary file.\n");
00117 return MOLFILE_ERROR;
00118 }
00119
00120 if (binpos->wrongendian) {
00121
00122
00123
00124 cdata = (char *) binpos->xyz;
00125 for ( i=0; i<3*numatoms; ++i, cdata+=4 ) {
00126 tmpc = cdata[0]; cdata[0] = cdata[3]; cdata[3] = tmpc;
00127 tmpc = cdata[1]; cdata[1] = cdata[2]; cdata[2] = tmpc;
00128 }
00129 }
00130
00131 if (ts) {
00132 for ( i=0; i<numatoms; ++i) {
00133 ts->coords[3*i] = binpos->xyz[3*i];
00134 ts->coords[3*i+1] = binpos->xyz[3*i+1];
00135 ts->coords[3*i+2] = binpos->xyz[3*i+2];
00136 }
00137 }
00138
00139
00140
00141
00142
00143 if((fread(&igarb,sizeof(int),1,binpos->fd))!=1)
00144 {
00145 fclose(binpos->fd);
00146 binpos->fd = NULL;
00147 }
00148 return MOLFILE_SUCCESS;
00149 }
00150
00151 static void close_file_read(void *v) {
00152 binposhandle *binpos = (binposhandle *)v;
00153 if (binpos->fd)
00154 fclose(binpos->fd);
00155 free(binpos->xyz);
00156 free(binpos);
00157 }
00158
00159 static void *open_binpos_write(const char *path, const char *filetype,
00160 int natoms) {
00161 binposhandle *binpos;
00162 FILE *fd;
00163
00164 fd = fopen(path, "wb");
00165 if (!fd) {
00166 fprintf(stderr, "Could not open file %s for writing\n", path);
00167 return NULL;
00168 }
00169 fprintf(stderr,"Writing file in current machine endian-ism\n");
00170 binpos = (binposhandle *)malloc(sizeof(binposhandle));
00171 binpos->fd = fd;
00172 binpos->numatoms = natoms;
00173 fwrite( "fxyz", 4, 1, binpos->fd);
00174 return binpos;
00175 }
00176
00177 static int write_timestep(void *v, const molfile_timestep_t *ts) {
00178
00179 int i,numatoms;
00180
00181 binposhandle *binpos = (binposhandle *)v;
00182
00183 if (!binpos->fd)
00184 return MOLFILE_ERROR;
00185
00186
00187
00188 numatoms = binpos->numatoms;
00189
00190 fwrite(&numatoms, 4, 1, binpos->fd);
00191
00192 for (i=0; i<3*numatoms; i++)
00193 {
00194 float tmp = ts->coords[i];
00195 if (fwrite(&tmp, sizeof(float), 1, binpos->fd) != 1) {
00196 fprintf(stderr, "Error writing amber7 binary file\n");
00197 return MOLFILE_ERROR;
00198 }
00199 }
00200
00201
00202
00203
00204
00205
00206
00207 return MOLFILE_SUCCESS;
00208 }
00209
00210 static void close_file_write(void *v) {
00211 binposhandle *binpos = (binposhandle *)v;
00212 if (binpos->fd)
00213 fclose(binpos->fd);
00214 free(binpos);
00215 }
00216
00217
00218
00219
00220
00221 static molfile_plugin_t plugin;
00222
00223 VMDPLUGIN_API int VMDPLUGIN_init() {
00224 memset(&plugin, 0, sizeof(molfile_plugin_t));
00225 plugin.abiversion = vmdplugin_ABIVERSION;
00226 plugin.type = MOLFILE_PLUGIN_TYPE;
00227 plugin.name = "binpos";
00228 plugin.prettyname = "Scripps Binpos";
00229 plugin.author = "Brian Bennion";
00230 plugin.majorv = 0;
00231 plugin.minorv = 4;
00232 plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00233 plugin.filename_extension = "binpos";
00234 plugin.open_file_read = open_binpos_read;
00235 plugin.read_next_timestep = read_next_timestep;
00236 plugin.close_file_read = close_file_read;
00237 plugin.open_file_write = open_binpos_write;
00238 plugin.write_timestep = write_timestep;
00239 plugin.close_file_write = close_file_write;
00240 return VMDPLUGIN_SUCCESS;
00241 }
00242
00243 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00244 (*cb)(v, (vmdplugin_t *)&plugin);
00245 return VMDPLUGIN_SUCCESS;
00246 }
00247
00248 VMDPLUGIN_API int VMDPLUGIN_fini() {
00249 return VMDPLUGIN_SUCCESS;
00250 }
00251