void copy_t_restp(t_restp *s, t_restp *d) { int i; *d = *s; d->resname = safe_strdup(s->resname); snew(d->atom, s->natom); for (i = 0; i < s->natom; i++) { d->atom[i] = s->atom[i]; } snew(d->atomname, s->natom); for (i = 0; i < s->natom; i++) { snew(d->atomname[i], 1); *d->atomname[i] = safe_strdup(*s->atomname[i]); } snew(d->cgnr, s->natom); for (i = 0; i < s->natom; i++) { d->cgnr[i] = s->cgnr[i]; } for (i = 0; i < ebtsNR; i++) { d->rb[i].type = s->rb[i].type; d->rb[i].nb = 0; d->rb[i].b = NULL; } merge_t_bondeds(s->rb, d->rb, FALSE, FALSE); }
void get_hackblocks_rtp(t_hackblock **hb, t_restp **restp, int nrtp, t_restp rtp[], int nres, t_resinfo *resinfo, int nterpairs, t_hackblock **ntdb, t_hackblock **ctdb, int *rn, int *rc) { int i, j, k, l; char *key; t_restp *res; char buf[STRLEN]; const char *Hnum="123456"; int tern,terc; gmx_bool bN,bC,bRM; snew(*hb,nres); snew(*restp,nres); /* first the termini */ for(i=0; i<nterpairs; i++) { if (rn[i] >= 0 && ntdb[i] != NULL) { copy_t_hackblock(ntdb[i], &(*hb)[rn[i]]); } if (rc[i] >= 0 && ctdb[i] != NULL) { merge_t_hackblock(ctdb[i], &(*hb)[rc[i]]); } } /* then the whole rtp */ for(i=0; i < nres; i++) { /* Here we allow a mismatch of one character when looking for the rtp entry. * For such a mismatch there should be only one mismatching name. * This is mainly useful for small molecules such as ions. * Note that this will usually not work for protein, DNA and RNA, * since there the residue names should be listed in residuetypes.dat * and an error will have been generated earlier in the process. */ key = *resinfo[i].rtp; snew(resinfo[i].rtp,1); *resinfo[i].rtp = search_rtp(key,nrtp,rtp); res = get_restp(*resinfo[i].rtp,nrtp,rtp); copy_t_restp(res, &(*restp)[i]); /* Check that we do not have different bonded types in one molecule */ check_restp_types(&(*restp)[0],&(*restp)[i]); tern = -1; for(j=0; j<nterpairs && tern==-1; j++) { if (i == rn[j]) { tern = j; } } terc = -1; for(j=0; j<nterpairs && terc == -1; j++) { if (i == rc[j]) { terc = j; } } bRM = merge_t_bondeds(res->rb, (*hb)[i].rb,tern>=0,terc>=0); if (bRM && ((tern >= 0 && ntdb[tern] == NULL) || (terc >= 0 && ctdb[terc] == NULL))) { gmx_fatal(FARGS,"There is a dangling bond at at least one of the terminal ends and the force field does not provide terminal entries or files. Edit a .n.tdb and/or .c.tdb file."); } if (bRM && ((tern >= 0 && ntdb[tern]->nhack == 0) || (terc >= 0 && ctdb[terc]->nhack == 0))) { gmx_fatal(FARGS,"There is a dangling bond at at least one of the terminal ends. Select a proper terminal entry."); } } /* now perform t_hack's on t_restp's, i.e. add's and deletes from termini database will be added to/removed from residue topology we'll do this on one big dirty loop, so it won't make easy reading! */ for(i=0; i < nres; i++) { for(j=0; j < (*hb)[i].nhack; j++) { if ( (*hb)[i].hack[j].nr ) { /* find atom in restp */ for(l=0; l < (*restp)[i].natom; l++) if ( ( (*hb)[i].hack[j].oname==NULL && strcmp((*hb)[i].hack[j].AI, *(*restp)[i].atomname[l])==0 ) || ( (*hb)[i].hack[j].oname!=NULL && strcmp((*hb)[i].hack[j].oname,*(*restp)[i].atomname[l])==0 ) ) break; if (l == (*restp)[i].natom) { /* If we are doing an atom rename only, we don't need * to generate a fatal error if the old name is not found * in the rtp. */ /* Deleting can happen also only on the input atoms, * not necessarily always on the rtp entry. */ if (!((*hb)[i].hack[j].oname != NULL && (*hb)[i].hack[j].nname != NULL) && !((*hb)[i].hack[j].oname != NULL && (*hb)[i].hack[j].nname == NULL)) { gmx_fatal(FARGS, "atom %s not found in buiding block %d%s " "while combining tdb and rtp", (*hb)[i].hack[j].oname!=NULL ? (*hb)[i].hack[j].oname : (*hb)[i].hack[j].AI, i+1,*resinfo[i].rtp); } } else { if ( (*hb)[i].hack[j].oname==NULL ) { /* we're adding: */ add_atom_to_restp(&(*restp)[i],resinfo[i].nr,l, &(*hb)[i].hack[j]); } else { /* oname != NULL */ if ( (*hb)[i].hack[j].nname==NULL ) { /* we're deleting */ if (debug) fprintf(debug, "deleting atom %s from res %d%s in rtp\n", *(*restp)[i].atomname[l], i+1,(*restp)[i].resname); /* shift the rest */ (*restp)[i].natom--; for(k=l; k < (*restp)[i].natom; k++) { (*restp)[i].atom [k] = (*restp)[i].atom [k+1]; (*restp)[i].atomname[k] = (*restp)[i].atomname[k+1]; (*restp)[i].cgnr [k] = (*restp)[i].cgnr [k+1]; } /* give back space */ srenew((*restp)[i].atom, (*restp)[i].natom); srenew((*restp)[i].atomname, (*restp)[i].natom); srenew((*restp)[i].cgnr, (*restp)[i].natom); } else { /* nname != NULL */ /* we're replacing */ if (debug) fprintf(debug, "replacing atom %s by %s in res %d%s in rtp\n", *(*restp)[i].atomname[l], (*hb)[i].hack[j].nname, i+1,(*restp)[i].resname); snew( (*restp)[i].atomname[l], 1); (*restp)[i].atom[l] = *(*hb)[i].hack[j].atom; *(*restp)[i].atomname[l] = strdup((*hb)[i].hack[j].nname); if ( (*hb)[i].hack[j].cgnr != NOTSET ) (*restp)[i].cgnr [l] = (*hb)[i].hack[j].cgnr; } } } } } } }
void merge_t_hackblock(t_hackblock *s, t_hackblock *d) { merge_hacks(s, d); merge_t_bondeds(s->rb, d->rb, FALSE, FALSE); }