/*************************************************************************** *cr *cr (C) Copyright 1995 The Board of Trustees of the *cr University of Illinois *cr All Rights Reserved *cr ***************************************************************************/ /*************************************************************************** * RCS INFORMATION: * * $RCSfile: ReadDCD.c,v $ * $Author: keith $ $Locker: $ $State: Exp $ * $Revision: 1.7 $ $Date: 1997/11/27 15:58:19 $ * *************************************************************************** * DESCRIPTION: * * C routines to read and write binary DCD files (which use the goofy * FORTRAN UNFORMATTED format). These routines are courtesy of * Mark Nelson (autographs available upon request and $1 tip). * * Converted to ANSI C for use with Moldy - Keith Refson, Nov 1997 ***************************************************************************/ #include #include "ReadDCD.h" /************************************************************************/ /* */ /* MACRO CHECK_FREAD */ /* */ /* CHECK_FREAD is used to check the status of a file read. It */ /* is passed the return code from read and a string to print out if */ /* an error is detected. If an error is found, an error message is */ /* printed out and the program terminates. This was made into a */ /* macro because it had to be done over and over and over . . . */ /* */ /************************************************************************/ #define CHECK_FREAD(X, msg) if (X<=0 && ferror(fp)) \ { \ return(DCD_BADREAD); \ } /************************************************************************/ /* */ /* MACRO CHECK_FEOF */ /* */ /* CHECK_FEOF checks for an abnormal EOF on a file read. It is */ /* passed the return status from read and a message to print on error.*/ /* if an EOF is detected, the error message is printed and the program*/ /* terminates. This is used for reads that should find something in */ /* the file. */ /* */ /************************************************************************/ #define CHECK_FEOF(X, msg) if (X<=0 && feof(fp)) \ { \ return(DCD_BADEOF); \ } /* GLOBAL VARIABLES */ extern int errno; void pad(s, len) char *s; int len; { int curlen; int i; curlen=strlen(s); if (curlen>len) { s[len]=0; return; } for (i=curlen; ifirst time called */ /* indexes - indexes for free atoms */ /* */ /* OUTPUTS: */ /* read step populates the arrays X, Y, Z and returns a 0 if the */ /* read is successful. If the read fails, a negative error code is */ /* returned. */ /* */ /* read_step reads in the coordinates from one step. It places */ /* these coordinates into the arrays X, Y, and Z. */ /* */ /************************************************************************/ int read_dcdstep(fp, N, X, Y, Z, num_fixed, first, indexes) FILE *fp; int N; float *X; float *Y; float *Z; int num_fixed; int first; int *indexes; { int ret_val; /* Return value from read */ int input_integer; /* Integer buffer space */ int i; /* Loop counter */ static float *tmpX; if (first && num_fixed) { tmpX = (float *) calloc(N-num_fixed, sizeof(float)); if (tmpX==NULL) { return(DCD_BADMALLOC); } } /* Get the first size from the file */ ret_val = fread(&input_integer, sizeof(int), 1, fp); CHECK_FREAD(ret_val, "reading number of atoms at begining of step"); /* See if we've reached the end of the file */ if (ret_val == 0) { free(tmpX); return(-1); } if ( (num_fixed==0) || first) { if (input_integer != 4*N) { return(DCD_BADFORMAT); } ret_val = fread(X, N, 4, fp); CHECK_FREAD(ret_val, "reading X array"); CHECK_FEOF(ret_val, "reading X array"); ret_val = fread(&input_integer, sizeof(int), 1, fp); CHECK_FREAD(ret_val, "reading number of atoms after X array"); CHECK_FEOF(ret_val, "reading number of atoms after X array"); if (input_integer != 4*N) { return(DCD_BADFORMAT); } ret_val = fread(&input_integer, sizeof(int), 1, fp); CHECK_FREAD(ret_val, "reading number of atoms after X array"); CHECK_FEOF(ret_val, "reading number of atoms after X array"); if (input_integer != 4*N) { return(DCD_BADFORMAT); } ret_val = fread(Y, N, 4, fp); CHECK_FREAD(ret_val, "reading Y array"); CHECK_FEOF(ret_val, "reading Y array"); ret_val = fread(&input_integer, sizeof(int), 1, fp); CHECK_FREAD(ret_val, "reading number of atoms after Y array"); CHECK_FEOF(ret_val, "reading number of atoms after Y array"); if (input_integer != 4*N) { return(DCD_BADFORMAT); } ret_val = fread(&input_integer, sizeof(int), 1, fp); CHECK_FREAD(ret_val, "reading number of atoms after Y array"); CHECK_FEOF(ret_val, "reading number of atoms after Y array"); if (input_integer != 4*N) { return(DCD_BADFORMAT); } ret_val = fread(Z, N, 4, fp); CHECK_FREAD(ret_val, "reading Z array"); CHECK_FEOF(ret_val, "reading Z array"); ret_val = fread(&input_integer, sizeof(int), 1, fp); CHECK_FREAD(ret_val, "reading number of atoms after Z array"); CHECK_FEOF(ret_val, "reading number of atoms after Z array"); if (input_integer != 4*N) { return(DCD_BADFORMAT); } } else { if (input_integer != 4*(N-num_fixed)) { return(DCD_BADFORMAT); } ret_val = fread(tmpX, N-num_fixed, 4, fp); CHECK_FREAD(ret_val, "reading Xtmp array"); CHECK_FEOF(ret_val, "reading Xtmp array"); for (i=0; i