Something went wrong on our end
DcdWriter.h 9.94 KiB
///////////////////////////////////////////////////////////////////////
// Modified dcd reader from NAMD.
// Author: Jeff Comer <jcomer2@illinois.edu>
/**
*** Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000 by
*** The Board of Trustees of the University of Illinois.
*** All rights reserved.
**/
/*
dcdlib contains C routines for reading and writing binary DCD
files. The output format of these files is based on binary FORTRAN
output, so its pretty ugly. If you are squeamish, don't look!
*/
#pragma once
#include <unistd.h>
#include <cstring>
#include <fstream>
#include <fcntl.h>
#include <sys/stat.h>
// using namespace std;
#define NFILE_POS (off_t) 8
#define NPRIV_POS (off_t) 12
#define NSAVC_POS (off_t) 16
#define NSTEP_POS (off_t) 20
#ifndef O_LARGEFILE
#define O_LARGEFILE 0x0
#endif
/* DEFINE ERROR CODES THAT MAY BE RETURNED BY DCD ROUTINES */
#define DCD_DNE -2 /* DCD file does not exist */
#define DCD_OPENFAILED -3 /* Open of DCD file failed */
#define DCD_BADREAD -4 /* read call on DCD file failed */
#define DCD_BADEOF -5 /* premature EOF found in DCD file */
#define DCD_BADFORMAT -6 /* format of DCD file is wrong */
#define DCD_FILEEXISTS -7 /* output file already exists */
#define DCD_BADMALLOC -8 /* malloc failed */
// Just use write instead of NAMD_write --JRC
#define NAMD_write write
class DcdWriter {
public:
DcdWriter(const char* fileName) {
fd = openDcd(fileName);
if (fd == DCD_OPENFAILED) {
printf("DcdWriter::DcdWriter Failed to open dcd file %s.", fileName);
exit(-1);
}
}
~DcdWriter() {
closeDcd();
}
private:
int fd;
private:
void pad(char *s, int len)
{
int curlen;
int i;
curlen=strlen(s);
if (curlen>len)
{
s[len]='\0';
return;
}
for (i=curlen; i<len; i++)
{
s[i]=' ';
}
s[i]='\0';
}
/*********************************************************************/
/* */
/* FUNCTION open_dcd_write */
/* */
/* INPUTS: */
/* dcdfile - Name of the dcd file */
/* */
/* OUTPUTS: */
/* returns an open file descriptor for writing */
/* */
/* This function will open a dcd file for writing. It takes */
/* the filename to open as its only argument. It will return a */
/* valid file descriptor if successful or DCD_OPENFAILED if the */
/* open fails for some reason. If the file specifed already */
/* exists, it is renamed by appending .BAK to it. */
/* */
/*********************************************************************/
int openDcd(const char* dcdname)
{
struct stat sbuf;
int dcdfd;
char *newdcdname = 0;
if (stat(dcdname, &sbuf) == 0)
{
newdcdname = new char[strlen(dcdname)+5];
if(newdcdname == (char *) 0)
return DCD_OPENFAILED;
strcpy(newdcdname, dcdname);
strcat(newdcdname, ".BAK");
if(rename(dcdname, newdcdname))
return(DCD_OPENFAILED);
delete [] newdcdname;
}
if ( (dcdfd = open(dcdname, O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE,
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
{
return(DCD_OPENFAILED);
}
return dcdfd;
}
/****************************************************************/
/* */
/* FUNCTION close_dcd_write */
/* */
/* INPUTS: */
/* fd - file descriptor to close */
/* */
/* OUTPUTS: */
/* the file pointed to by fd */
/* */
/* close_dcd_write close a dcd file that was opened for */
/* writing */
/* */
/****************************************************************/
void closeDcd()
{
close(fd);
}
public:
/*****************************************************************************/
/* */
/* FUNCTION write_dcdheader */
/* */
/* INPUTS: */
/* fd - file descriptor for the dcd file */
/* filename - filename for output */
/* N - Number of atoms */
/* NFILE - Number of sets of coordinates */
/* NPRIV - Starting timestep of DCD file - NOT ZERO */
/* NSAVC - Timesteps between DCD saves */
/* NSTEP - Number of timesteps */
/* DELTA - length of a timestep */
/* */
/* OUTPUTS: */
/* none */
/* */
/* This function prints the "header" information to the DCD file. Since*/
/* this is duplicating an unformatted binary output from FORTRAN, its ugly.*/
/* So if you're squeamish, don't look. */
/* */
/*****************************************************************************/
int writeHeader(const char *filename, int N, int NFILE, int NPRIV,
int NSAVC, int NSTEP, float DELTA, int with_unitcell)
{
int out_integer;
float out_float;
char title_string[200];
//int user_id;
time_t cur_time;
struct tm *tmbuf;
char time_str[11];
out_integer = 84;
NAMD_write(fd, (char *) & out_integer, sizeof(int));
strcpy(title_string, "CORD");
NAMD_write(fd, title_string, 4);
out_integer = NFILE; /* located at fpos 8 */
out_integer = 0; /* ignore the lies */
NAMD_write(fd, (char *) & out_integer, sizeof(int));
out_integer = NPRIV; /* located at fpos 12 */
NAMD_write(fd, (char *) & out_integer, sizeof(int));
out_integer = NSAVC; /* located at fpos 16 */
NAMD_write(fd, (char *) & out_integer, sizeof(int));
out_integer = NSTEP; /* located at fpos 20 */
out_integer = NPRIV - NSAVC; /* ignore the lies */
NAMD_write(fd, (char *) &out_integer, sizeof(int));
out_integer=0;
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) &out_integer, sizeof(int));
out_float = DELTA;
NAMD_write(fd, (char *) &out_float, sizeof(float));
out_integer = with_unitcell ? 1 : 0;
NAMD_write(fd, (char *) &out_integer, sizeof(int));
out_integer = 0;
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) &out_integer, sizeof(int));
out_integer = 24; // PRETEND TO BE CHARMM24 -JCP
NAMD_write(fd, (char *) &out_integer, sizeof(int));
out_integer = 84;
NAMD_write(fd, (char *) & out_integer, sizeof(int));
out_integer = 164;
NAMD_write(fd, (char *) & out_integer, sizeof(int));
out_integer = 2;
NAMD_write(fd, (char *) & out_integer, sizeof(int));
sprintf(title_string, "REMARKS FILENAME=%s CREATED BY NAMD", filename);
pad(title_string, 80);
NAMD_write(fd, title_string, 80);
char username[100];
//user_id= (int) getuid();
//pwbuf=getpwuid(user_id);
//if ( pwbuf ) sprintf(username,"%s",pwbuf->pw_name);
//else sprintf(username,"%d",user_id);
sprintf(username,"%s", "BrownTown");
cur_time=time(NULL);
tmbuf=localtime(&cur_time);
strftime(time_str, 10, "%m/%d/%y", tmbuf);
sprintf(title_string, "REMARKS DATE: %s CREATED BY USER: %s",
time_str, username);
pad(title_string, 80);
NAMD_write(fd, title_string, 80);
out_integer = 164;
NAMD_write(fd, (char *) & out_integer, sizeof(int));
out_integer = 4;
NAMD_write(fd, (char *) & out_integer, sizeof(int));
out_integer = N;
NAMD_write(fd, (char *) & out_integer, sizeof(int));
out_integer = 4;
NAMD_write(fd, (char *) & out_integer, sizeof(int));
return(0);
}
/************************************************************************/
/* */
/* FUNCTION write_dcdstep */
/* */
/* INPUTS: */
/* fd - file descriptor for the DCD file to write to */
/* N - Number of atoms */
/* X - X coordinates */
/* Y - Y coordinates */
/* Z - Z coordinates */
/* unitcell - a, b, c, alpha, beta, gamma of unit cell */
/* */
/* OUTPUTS: */
/* none */
/* */
/* write_dcdstep writes the coordinates out for a given timestep */
/* to the specified DCD file. */
/* */
/************************************************************************/
int writeStep(int N, const float *X, const float *Y, const float *Z, const double *cell)
{
int NSAVC,NSTEP,NFILE;
int out_integer;
/* Unit cell */
if (cell) {
out_integer = 6*8;
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) cell, out_integer);
NAMD_write(fd, (char *) &out_integer, sizeof(int));
}
/* Coordinates */
out_integer = N*4;
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) X, out_integer);
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) Y, out_integer);
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) &out_integer, sizeof(int));
NAMD_write(fd, (char *) Z, out_integer);
NAMD_write(fd, (char *) &out_integer, sizeof(int));
/* don't update header until after write succeeds */
lseek(fd,NSAVC_POS,SEEK_SET);
read(fd,(void*) &NSAVC,sizeof(int));
lseek(fd,NSTEP_POS,SEEK_SET);
read(fd,(void*) &NSTEP,sizeof(int));
lseek(fd,NFILE_POS,SEEK_SET);
read(fd,(void*) &NFILE,sizeof(int));
NSTEP += NSAVC;
NFILE += 1;
lseek(fd,NSTEP_POS,SEEK_SET);
NAMD_write(fd,(char*) &NSTEP,sizeof(int));
lseek(fd,NFILE_POS,SEEK_SET);
NAMD_write(fd,(char*) &NFILE,sizeof(int));
lseek(fd,0,SEEK_END);
return(0);
}
};