/* * pdata.c * * Summary: Force field parameter database, associating atom names with * MD API parameter types. * * Author: David Hardy */ #include #include #include "pdata.h" #include "error.h" #define INIT_KEY_MAX 10 #define ATOM_NAME_MAX 4 int pdata_init(Pdata *p, Pbuf *pbuf) { p->status = 0; p->pbuf = pbuf; p->key_num = 0; p->key_len = 0; p->key = NULL; if (ihash_init(&(p->table), INIT_KEY_MAX) == IHASH_MEMALLOC) { mdio_error("ihash_init() failed, file %s, line %d\n", __FILE__, __LINE__); p->status |= MDIO_ERR_MEMALLOC; return -1; } p->key = (char **) calloc(INIT_KEY_MAX, sizeof(char *)); if (p->key == NULL) { mdio_error("calloc() failed, file %s, line %d\n", __FILE__, __LINE__); p->status |= MDIO_ERR_MEMALLOC; return -1; } p->key_len = INIT_KEY_MAX; return 0; } void pdata_destroy(Pdata *p) { int i; for (i = 0; i < p->key_num; i++) free(p->key[i]); free(p->key); ihash_destroy(&(p->table)); memset(p, 0, sizeof(Pdata)); } int pdata_status(Pdata *p) { return p->status; } void pdata_clear_status(Pdata *p) { p->status = 0; } static int add_string(Pdata *p, const char *name, int val) { char *buf; int retval = 0, update; if (ihash_lookup(&(p->table), name) == IHASH_FAIL) { /* string not in hash table, extend key if necessary */ if (p->key_num == p->key_len) { void *vptr; vptr = realloc(p->key, 2 * p->key_len * sizeof(char *)); if (vptr == NULL) { mdio_error("realloc() failed, file %s, line %d\n", __FILE__, __LINE__); p->status |= MDIO_ERR_MEMALLOC; retval = -1; } p->key = (char **) vptr; p->key_len *= 2; } /* place name into next key entry */ buf = (char *) malloc((strlen(name) + 1) * sizeof(char)); if (buf == NULL) { mdio_error("malloc() failed, file %s, line %d\n", __FILE__, __LINE__); p->status |= MDIO_ERR_MEMALLOC; retval = -1; } strcpy(buf, name); p->key[p->key_num++] = buf; /* insert string into hash table */ if (ihash_insert(&(p->table), buf, val) == IHASH_MEMALLOC) { mdio_error("ihash_insert() failed, file %s, line %d\n",__FILE__,__LINE__); p->status |= MDIO_ERR_MEMALLOC; retval = -1; } } else { update = ihash_update(&(p->table), name, val); MDIO_ASSERT(update != IHASH_FAIL); } return retval; } int pdata_add_atom(Pdata *p, MD_Atom_Param *x, const char *s) { Pbuf *pbuf = p->pbuf; char buf[64]; int retval = 0; /* add atom to atomp */ MDIO_ASSERT(strlen(s) <= ATOM_NAME_MAX); sprintf(buf, "atom %s", s); retval |= add_string(p, buf, pbuf->atomp_num); if (retval != 0) return retval; MDIO_ASSERT(pbuf->atomp_num < pbuf->atomp_len); pbuf->atomp[pbuf->atomp_num] = *x; pbuf->atomp_num++; /* positive return value indicates no more space in Pbuf */ if (pbuf->atomp_num == pbuf->atomp_len) { return MD_ATOM_PARAM; } return 0; } int pdata_add_bond(Pdata *p, MD_Bond_Param *x, const char *s1, const char *s2) { Pbuf *pbuf = p->pbuf; char buf[64]; int retval = 0; /* add bond to bondp */ MDIO_ASSERT(strlen(s1) <= ATOM_NAME_MAX && strlen(s2) <= ATOM_NAME_MAX); sprintf(buf, "bond %s %s", s1, s2); retval |= add_string(p, buf, pbuf->bondp_num); sprintf(buf, "bond %s %s", s2, s1); retval |= add_string(p, buf, pbuf->bondp_num); if (retval != 0) return retval; MDIO_ASSERT(pbuf->bondp_num < pbuf->bondp_len); pbuf->bondp[pbuf->bondp_num] = *x; pbuf->bondp_num++; /* nonzero return value indicates no more space in Pbuf */ if (pbuf->bondp_num == pbuf->bondp_len) { return MD_BOND_PARAM; } return 0; } int pdata_add_angle(Pdata *p, MD_Angle_Param *x, const char *s1, const char *s2, const char *s3) { Pbuf *pbuf = p->pbuf; char buf[64]; int retval = 0; /* add angle to anglep */ MDIO_ASSERT(strlen(s1) <= ATOM_NAME_MAX && strlen(s2) <= ATOM_NAME_MAX && strlen(s3) <= ATOM_NAME_MAX); sprintf(buf, "angle %s %s %s", s1, s2, s3); retval |= add_string(p, buf, pbuf->anglep_num); sprintf(buf, "angle %s %s %s", s3, s2, s1); retval |= add_string(p, buf, pbuf->anglep_num); if (retval != 0) return retval; MDIO_ASSERT(pbuf->anglep_num < pbuf->anglep_len); pbuf->anglep[pbuf->anglep_num] = *x; pbuf->anglep_num++; /* nonzero return value indicates no more space in Pbuf */ if (pbuf->anglep_num == pbuf->anglep_len) { return MD_ANGLE_PARAM; } return 0; } int pdata_add_dihed(Pdata *p, MD_Dihed_Param *x, const char *s1, const char *s2, const char *s3, const char *s4) { Pbuf *pbuf = p->pbuf; char buf[64]; int retval = 0; /* add dihed to dihedp */ MDIO_ASSERT(strlen(s1) <= ATOM_NAME_MAX && strlen(s2) <= ATOM_NAME_MAX && strlen(s3) <= ATOM_NAME_MAX && strlen(s4) <= ATOM_NAME_MAX); sprintf(buf, "dihed %s %s %s %s", s1, s2, s3, s4); retval |= add_string(p, buf, pbuf->dihedp_num); sprintf(buf, "dihed %s %s %s %s", s4, s3, s2, s1); retval |= add_string(p, buf, pbuf->dihedp_num); if (retval != 0) return retval; MDIO_ASSERT(pbuf->dihedp_num < pbuf->dihedp_len); pbuf->dihedp[pbuf->dihedp_num] = *x; pbuf->dihedp_num++; /* no higher than multiplicity m <= PARAM_MAX_MULT allowed */ /* nonzero return value indicates no more space in Pbuf */ if (pbuf->dihedp_num == pbuf->dihedp_len) { return MD_DIHED_PARAM; } return 0; } int pdata_add_impr(Pdata *p, MD_Impr_Param *x, const char *s1, const char *s2, const char *s3, const char *s4) { Pbuf *pbuf = p->pbuf; char buf[64]; int retval = 0; /* add impr to imprp */ MDIO_ASSERT(strlen(s1) <= ATOM_NAME_MAX && strlen(s2) <= ATOM_NAME_MAX && strlen(s3) <= ATOM_NAME_MAX && strlen(s4) <= ATOM_NAME_MAX); sprintf(buf, "impr %s %s %s %s", s1, s2, s3, s4); retval |= add_string(p, buf, pbuf->imprp_num); sprintf(buf, "impr %s %s %s %s", s4, s3, s2, s1); retval |= add_string(p, buf, pbuf->imprp_num); if (retval != 0) return retval; MDIO_ASSERT(pbuf->imprp_num < pbuf->imprp_len); pbuf->imprp[pbuf->imprp_num] = *x; pbuf->imprp_num++; /* no higher than multiplicity m <= PARAM_MAX_MULT allowed */ /* nonzero return value indicates no more space in Pbuf */ if (pbuf->imprp_num == pbuf->imprp_len) { return MD_IMPR_PARAM; } return 0; } int pdata_add_nbfix(Pdata *p, MD_Nbfix_Param *x, const char *s1, const char *s2) { Pbuf *pbuf = p->pbuf; char buf[64]; /* add nbfix to nbfixp */ MDIO_ASSERT(strlen(s1) <= ATOM_NAME_MAX && strlen(s2) <= ATOM_NAME_MAX); sprintf(buf, "nbfix %s %s", s1, s2); add_string(p, buf, pbuf->nbfixp_num); sprintf(buf, "nbfix %s %s", s2, s1); add_string(p, buf, pbuf->nbfixp_num); MDIO_ASSERT(pbuf->nbfixp_num < pbuf->nbfixp_len); pbuf->nbfixp[pbuf->nbfixp_num] = *x; pbuf->nbfixp_num++; /* nonzero return value indicates no more space in Pbuf */ if (pbuf->nbfixp_num == pbuf->nbfixp_len) { return MD_NBFIX_PARAM; } return 0; } int pdata_find_atom(Pdata *p, const char *s) { char buf[64]; int i; MDIO_ASSERT(strlen(s) <= ATOM_NAME_MAX); sprintf(buf, "atom %s", s); i = ihash_lookup(&(p->table), buf); return (i != IHASH_FAIL ? i : PDATA_ERR_NOTFOUND); } int pdata_find_bond(Pdata *p, const char *s1, const char *s2) { char buf[64]; int i; MDIO_ASSERT(strlen(s1) <= ATOM_NAME_MAX && strlen(s2) <= ATOM_NAME_MAX); sprintf(buf, "bond %s %s", s1, s2); i = ihash_lookup(&(p->table), buf); return (i != IHASH_FAIL ? i : PDATA_ERR_NOTFOUND); } int pdata_find_angle(Pdata *p, const char *s1, const char *s2, const char *s3) { char buf[64]; int i; MDIO_ASSERT(strlen(s1) <= ATOM_NAME_MAX && strlen(s2) <= ATOM_NAME_MAX && strlen(s3) <= ATOM_NAME_MAX); sprintf(buf, "angle %s %s %s", s1, s2, s3); i = ihash_lookup(&(p->table), buf); return (i != IHASH_FAIL ? i : PDATA_ERR_NOTFOUND); } int pdata_find_dihed(Pdata *p, const char *s1, const char *s2, const char *s3, const char *s4) { char buf[64]; int i; MDIO_ASSERT(strlen(s1) <= ATOM_NAME_MAX && strlen(s2) <= ATOM_NAME_MAX && strlen(s3) <= ATOM_NAME_MAX && strlen(s4) <= ATOM_NAME_MAX); sprintf(buf, "dihed %s %s %s %s", s1, s2, s3, s4); i = ihash_lookup(&(p->table), buf); return (i != IHASH_FAIL ? i : PDATA_ERR_NOTFOUND); } int pdata_find_impr(Pdata *p, const char *s1, const char *s2, const char *s3, const char *s4) { char buf[64]; int i; MDIO_ASSERT(strlen(s1) <= ATOM_NAME_MAX && strlen(s2) <= ATOM_NAME_MAX && strlen(s3) <= ATOM_NAME_MAX && strlen(s4) <= ATOM_NAME_MAX); sprintf(buf, "impr %s %s %s %s", s1, s2, s3, s4); i = ihash_lookup(&(p->table), buf); return (i != IHASH_FAIL ? i : PDATA_ERR_NOTFOUND); } int pdata_find_nbfix(Pdata *p, const char *s1, const char *s2) { char buf[64]; int i; MDIO_ASSERT(strlen(s1) <= ATOM_NAME_MAX && strlen(s2) <= ATOM_NAME_MAX); sprintf(buf, "nbfix %s %s", s1, s2); i = ihash_lookup(&(p->table), buf); return (i != IHASH_FAIL ? i : PDATA_ERR_NOTFOUND); }