This repository has been archived by the owner on Oct 9, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
909 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,9 @@ dependencies: | |
# MDAnalysis | ||
- MDAnalysis | ||
|
||
# C API | ||
- cython | ||
|
||
# Testing | ||
- pytest | ||
- pytest-cov | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
## | ||
## Makefile for Simple Interactive MD interface example program | ||
## | ||
|
||
CC = cc | ||
CXX = CC | ||
|
||
testimd : testimd.c vmdsock.c imd.h imd.c | ||
$(CC) $(CFLAGS) testimd.c vmdsock.c imd.c -o testimd -lnsl -lsocket | ||
@echo "See the README file for info on running this test code..." | ||
|
||
clean : | ||
rm -f *.o testimd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
IMD API example code | ||
-------------------- | ||
This is a simple example program that demonstrates how to write the | ||
simulation engine side of an interactive molecular dynamics system using | ||
the IMD interface in VMD. In order to test it out, follow theses steps: | ||
1) Compile the code with the "make" command, edit the compile line | ||
as needed. (some platforms don't need -lnsl or -lsocket...) | ||
|
||
2) Once compiled, run the newly compiled "testimd" program | ||
|
||
3) Start VMD, and load the "testimd.pdb" molecule, set the | ||
graphical representation to "VDW" so you can see the simulated | ||
atom. | ||
|
||
4) While the "testimd" binary is running, and the "testimd.pdb" is loaded | ||
into VMD, type the following command into your VMD text console to | ||
cause VMD to connect to the test simulation: | ||
imd connect localhost 54321 | ||
|
||
5) Go ahead and play around. | ||
|
||
6) quit VMD, or type "imd detach" to disconnect from the test program. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
|
||
|
||
#include "imd.h" | ||
#include "vmdsock.h" | ||
#include <string.h> | ||
#include <errno.h> | ||
#include <stdlib.h> | ||
|
||
typedef struct { | ||
int32 type; | ||
int32 length; | ||
} IMDheader; | ||
|
||
#define HEADERSIZE 8 | ||
#define IMDVERSION 2 | ||
|
||
static void swap4(char *data, int ndata) { | ||
int i; | ||
char *dataptr; | ||
char b0, b1; | ||
|
||
dataptr = data; | ||
for (i=0; i<ndata; i+=4) { | ||
b0 = dataptr[0]; | ||
b1 = dataptr[1]; | ||
dataptr[0] = dataptr[3]; | ||
dataptr[1] = dataptr[2]; | ||
dataptr[2] = b1; | ||
dataptr[3] = b0; | ||
dataptr += 4; | ||
} | ||
} | ||
|
||
static int32 imd_htonl(int32 h) { | ||
int32 n; | ||
((char *)&n)[0] = (h >> 24) & 0x0FF; | ||
((char *)&n)[1] = (h >> 16) & 0x0FF; | ||
((char *)&n)[2] = (h >> 8) & 0x0FF; | ||
((char *)&n)[3] = h & 0x0FF; | ||
return n; | ||
} | ||
|
||
typedef struct { | ||
unsigned int highest : 8; | ||
unsigned int high : 8; | ||
unsigned int low : 8; | ||
unsigned int lowest : 8; | ||
} netint; | ||
|
||
static int32 imd_ntohl(int32 n) { | ||
int32 h = 0; | ||
netint net; | ||
net = *((netint *)&n); | ||
h |= net.highest << 24 | net.high << 16 | net.low << 8 | net.lowest; | ||
return h; | ||
} | ||
|
||
static void fill_header(IMDheader *header, IMDType type, int32 length) { | ||
header->type = imd_htonl((int32)type); | ||
header->length = imd_htonl(length); | ||
} | ||
|
||
static void swap_header(IMDheader *header) { | ||
header->type = imd_ntohl(header->type); | ||
header->length= imd_ntohl(header->length); | ||
} | ||
|
||
static int32 imd_readn(void *s, char *ptr, int32 n) { | ||
int32 nleft; | ||
int32 nread; | ||
|
||
nleft = n; | ||
while (nleft > 0) { | ||
if ((nread = vmdsock_read(s, ptr, nleft)) < 0) { | ||
if (errno == EINTR) | ||
nread = 0; /* and call read() again */ | ||
else | ||
return -1; | ||
} else if (nread == 0) | ||
break; /* EOF */ | ||
nleft -= nread; | ||
ptr += nread; | ||
} | ||
return n-nleft; | ||
} | ||
|
||
static int32 imd_writen(void *s, const char *ptr, int32 n) { | ||
int32 nleft; | ||
int32 nwritten; | ||
|
||
nleft = n; | ||
while (nleft > 0) { | ||
if ((nwritten = vmdsock_write(s, ptr, nleft)) <= 0) { | ||
if (errno == EINTR) | ||
nwritten = 0; | ||
else | ||
return -1; | ||
} | ||
nleft -= nwritten; | ||
ptr += nwritten; | ||
} | ||
return n; | ||
} | ||
|
||
|
||
int imd_disconnect(void *s) { | ||
IMDheader header; | ||
fill_header(&header, IMD_DISCONNECT, 0); | ||
return (imd_writen(s, (char *)&header, HEADERSIZE) != HEADERSIZE); | ||
} | ||
|
||
int imd_pause(void *s) { | ||
IMDheader header; | ||
fill_header(&header, IMD_PAUSE, 0); | ||
return (imd_writen(s, (char *)&header, HEADERSIZE) != HEADERSIZE); | ||
} | ||
|
||
int imd_kill(void *s) { | ||
IMDheader header; | ||
fill_header(&header, IMD_KILL, 0); | ||
return (imd_writen(s, (char *)&header, HEADERSIZE) != HEADERSIZE); | ||
} | ||
|
||
static int imd_go(void *s) { | ||
IMDheader header; | ||
fill_header(&header, IMD_GO, 0); | ||
return (imd_writen(s, (char *)&header, HEADERSIZE) != HEADERSIZE); | ||
} | ||
|
||
|
||
int imd_handshake(void *s) { | ||
IMDheader header; | ||
fill_header(&header, IMD_HANDSHAKE, 1); | ||
header.length = IMDVERSION; /* Not byteswapped! */ | ||
return (imd_writen(s, (char *)&header, HEADERSIZE) != HEADERSIZE); | ||
} | ||
|
||
int imd_trate(void *s, int32 rate) { | ||
IMDheader header; | ||
fill_header(&header, IMD_TRATE, rate); | ||
return (imd_writen(s, (char *)&header, HEADERSIZE) != HEADERSIZE); | ||
} | ||
|
||
/* Data methods */ | ||
int imd_send_mdcomm(void *s,int32 n,const int32 *indices,const float *forces) { | ||
int rc; | ||
int32 size = HEADERSIZE+16*n; | ||
char *buf = (char *) malloc(sizeof(char) * size); | ||
fill_header((IMDheader *)buf, IMD_MDCOMM, n); | ||
memcpy(buf+HEADERSIZE, indices, 4*n); | ||
memcpy(buf+HEADERSIZE+4*n, forces, 12*n); | ||
rc = (imd_writen(s, buf, size) != size); | ||
free(buf); | ||
return rc; | ||
} | ||
|
||
int imd_send_energies(void *s, const IMDEnergies *energies) { | ||
int rc; | ||
int32 size = HEADERSIZE+sizeof(IMDEnergies); | ||
char *buf = (char *) malloc(sizeof(char) * size); | ||
fill_header((IMDheader *)buf, IMD_ENERGIES, 1); | ||
memcpy(buf+HEADERSIZE, energies, sizeof(IMDEnergies)); | ||
rc = (imd_writen(s, buf, size) != size); | ||
free(buf); | ||
return rc; | ||
} | ||
|
||
int imd_send_fcoords(void *s, int32 n, const float *coords) { | ||
int rc; | ||
int32 size = HEADERSIZE+12*n; | ||
char *buf = (char *) malloc(sizeof(char) * size); | ||
fill_header((IMDheader *)buf, IMD_FCOORDS, n); | ||
memcpy(buf+HEADERSIZE, coords, 12*n); | ||
rc = (imd_writen(s, buf, size) != size); | ||
free(buf); | ||
return rc; | ||
} | ||
|
||
/* The IMD receive functions */ | ||
IMDType imd_recv_header_nolengthswap(void *s, int32 *length) { | ||
IMDheader header; | ||
if (imd_readn(s, (char *)&header, HEADERSIZE) != HEADERSIZE) | ||
return IMD_IOERROR; | ||
*length = header.length; | ||
swap_header(&header); | ||
return (IMDType) header.type; | ||
} | ||
|
||
IMDType imd_recv_header(void *s, int32 *length) { | ||
IMDheader header; | ||
if (imd_readn(s, (char *)&header, HEADERSIZE) != HEADERSIZE) | ||
return IMD_IOERROR; | ||
swap_header(&header); | ||
*length = header.length; | ||
return (IMDType) header.type; | ||
} | ||
|
||
int imd_recv_handshake(void *s) { | ||
int32 buf; | ||
IMDType type; | ||
|
||
/* Wait up to 5 seconds for the handshake to come */ | ||
if (vmdsock_selread(s, 5) != 1) return -1; | ||
|
||
/* Check to see that a valid handshake was received */ | ||
type = imd_recv_header_nolengthswap(s, &buf); | ||
if (type != IMD_HANDSHAKE) return -1; | ||
|
||
/* Check its endianness, as well as the IMD version. */ | ||
if (buf == IMDVERSION) { | ||
if (!imd_go(s)) return 0; | ||
return -1; | ||
} | ||
swap4((char *)&buf, 4); | ||
if (buf == IMDVERSION) { | ||
if (!imd_go(s)) return 1; | ||
} | ||
|
||
/* We failed to determine endianness. */ | ||
return -1; | ||
} | ||
|
||
int imd_recv_mdcomm(void *s, int32 n, int32 *indices, float *forces) { | ||
if (imd_readn(s, (char *)indices, 4*n) != 4*n) return 1; | ||
if (imd_readn(s, (char *)forces, 12*n) != 12*n) return 1; | ||
return 0; | ||
} | ||
|
||
int imd_recv_energies(void *s, IMDEnergies *energies) { | ||
return (imd_readn(s, (char *)energies, sizeof(IMDEnergies)) | ||
!= sizeof(IMDEnergies)); | ||
} | ||
|
||
int imd_recv_fcoords(void *s, int32 n, float *coords) { | ||
return (imd_readn(s, (char *)coords, 12*n) != 12*n); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/*************************************************************************** | ||
*cr | ||
*cr (C) Copyright 1995-2003 The Board of Trustees of the | ||
*cr University of Illinois | ||
*cr All Rights Reserved | ||
*cr | ||
***************************************************************************/ | ||
|
||
/*************************************************************************** | ||
* RCS INFORMATION: | ||
* | ||
* $RCSfile: imd.h,v $ | ||
* $Author: johns $ $Locker: $ $State: Exp $ | ||
* $Revision: 1.1 $ $Date: 2003/09/12 18:30:46 $ | ||
* | ||
***************************************************************************/ | ||
|
||
#ifndef IMD_H__ | ||
#define IMD_H__ | ||
|
||
#include <limits.h> | ||
|
||
#if ( INT_MAX == 2147483647 ) | ||
typedef int int32; | ||
#else | ||
typedef short int32; | ||
#endif | ||
|
||
typedef enum IMDType_t { | ||
IMD_DISCONNECT, /**< close IMD connection, leaving sim running */ | ||
IMD_ENERGIES, /**< energy data block */ | ||
IMD_FCOORDS, /**< atom coordinates */ | ||
IMD_GO, /**< start the simulation */ | ||
IMD_HANDSHAKE, /**< endianism and version check message */ | ||
IMD_KILL, /**< kill the simulation job, shutdown IMD */ | ||
IMD_MDCOMM, /**< MDComm style force data */ | ||
IMD_PAUSE, /**< pause the running simulation */ | ||
IMD_TRATE, /**< set IMD update transmission rate */ | ||
IMD_IOERROR /**< indicate an I/O error */ | ||
} IMDType; | ||
|
||
typedef struct { | ||
int32 tstep; /**< integer timestep index */ | ||
float T; /**< Temperature in degrees Kelvin */ | ||
float Etot; /**< Total energy, in Kcal/mol */ | ||
float Epot; /**< Potential energy, in Kcal/mol */ | ||
float Evdw; /**< Van der Waals energy, in Kcal/mol */ | ||
float Eelec; /**< Electrostatic energy, in Kcal/mol */ | ||
float Ebond; /**< Bond energy, Kcal/mol */ | ||
float Eangle; /**< Angle energy, Kcal/mol */ | ||
float Edihe; /**< Dihedral energy, Kcal/mol */ | ||
float Eimpr; /**< Improper energy, Kcal/mol */ | ||
} IMDEnergies; /**< */ | ||
|
||
/* Send control messages - these consist of a header with no subsequent data */ | ||
extern int imd_disconnect(void *); /**< leave sim running but close IMD */ | ||
extern int imd_pause(void *); /**< pause simulation */ | ||
extern int imd_kill(void *); /**< kill simulation, shutdown IMD */ | ||
extern int imd_handshake(void *); /**< check endianness, version compat */ | ||
extern int imd_trate(void *, int32); /**< set IMD update transmission rate */ | ||
|
||
/* Send data update messages */ | ||
/** | ||
* Send MDComm compatible forces | ||
* Forces are in Kcal/mol/angstrom | ||
*/ | ||
extern int imd_send_mdcomm(void *, int32, const int32 *, const float *); | ||
|
||
/** | ||
* Send energies | ||
*/ | ||
extern int imd_send_energies(void *, const IMDEnergies *); | ||
|
||
/** | ||
* Send atom forces and coordinates | ||
* Forces are in Kcal/mol/angstrom | ||
*/ | ||
extern int imd_send_fcoords(void *, int32, const float *); | ||
|
||
/** | ||
* recv_handshake returns 0 if server and client have the same relative | ||
* endianism; returns 1 if they have opposite endianism, and -1 if there | ||
* was an error in the handshake process. | ||
*/ | ||
extern int imd_recv_handshake(void *); | ||
|
||
/** | ||
* Receive header and data | ||
*/ | ||
extern IMDType imd_recv_header(void *, int32 *); | ||
|
||
/** | ||
* Receive MDComm-style forces | ||
* Forces are in Kcal/mol/angstrom | ||
*/ | ||
extern int imd_recv_mdcomm(void *, int32, int32 *, float *); | ||
|
||
/** | ||
* Receive energies | ||
*/ | ||
extern int imd_recv_energies(void *, IMDEnergies *); | ||
|
||
/** | ||
* Receive atom coordinates and forces | ||
* Forces are in Kcal/mol/angstrom | ||
*/ | ||
extern int imd_recv_fcoords(void *, int32, float *); | ||
|
||
#endif | ||
|
Oops, something went wrong.