struct axisset* read_axisset (const char* path) { FILE* fp = myfopen (path, "r"); // open parms file char* line = NULL; size_t len = 0; int naxes = 0; // number of sets of rots while (getline (&line, &len, fp) != -1) { if (! iswhiteline (line)) { naxes++; } } rewind (fp); // reset the file pointer struct axisset* axisset = (struct axisset*) _mol_malloc (sizeof (struct axisset)); axisset->naxes = naxes; // save the value axisset->axes = (struct axis*) _mol_malloc (axisset->naxes * sizeof (struct axis)); int i = 0; while (getline (&line, &len, fp) != -1) { int tmpi; // tmp roti if (iswhiteline (line)) { continue; } if (sscanf (line, "%d %f %f %f", &tmpi, &axisset->axes[i].a, &axisset->axes[i].b, &axisset->axes[i].c ) < 4) { fprintf (stderr, "read error on file %s\n", path); fprintf (stderr, "expecting one index and 3 floats per line %d\n", i); exit (EXIT_FAILURE); } if (tmpi != i) { fprintf (stderr, "read error on file %s\n", path); fprintf (stderr, "expecting index %d, found index %d\n", i, tmpi); exit (EXIT_FAILURE); } i++; } if (line) free (line); myfclose (fp); return axisset; }
struct rotset* read_rotset (const char* path) { FILE* fp = myfopen (path, "r"); // open parms file char* line = NULL; size_t len = 0; int nrots = 0; // number of sets of rots while (getline (&line, &len, fp) != -1) { if (! iswhiteline (line)) { nrots++; } } rewind (fp); // reset the file pointer struct rotset* rotset = (struct rotset*) _mol_malloc (sizeof (struct rotset)); rotset->nrots = nrots; // save the value rotset->rmats = (struct rmatrix*) _mol_malloc (rotset->nrots * sizeof (struct rmatrix)); int i = 0; while (getline (&line, &len, fp) != -1) { int tmpi; // tmp roti if (iswhiteline (line)) { continue; } if (sscanf (line, "%d %f %f %f %f %f %f %f %f %f", &tmpi, &rotset->rmats[i].a11, &rotset->rmats[i].a12, &rotset->rmats[i].a13, &rotset->rmats[i].a21, &rotset->rmats[i].a22, &rotset->rmats[i].a23, &rotset->rmats[i].a31, &rotset->rmats[i].a32, &rotset->rmats[i].a33 ) < 10) { fprintf (stderr, "read error on file %s\n", path); fprintf (stderr, "expecting one index and 9 floats per line %d\n", i); exit (EXIT_FAILURE); } if (tmpi != i) { fprintf (stderr, "read error on file %s\n", path); fprintf (stderr, "expecting index %d, found index %d\n", i, tmpi); exit (EXIT_FAILURE); } i++; } if (line) free (line); myfclose (fp); return rotset; }
struct atomgrp *around(int nlist, int *list, struct atomgrp* ag, double distup) { int i, j; int natoms=ag->natoms; double x1,y1,z1,x2,y2,z2,d2; double du2=distup*distup; int *tmplist; int nout; struct atomgrp *destag; if(natoms==0) { fprintf (stderr, "around> ERROR: no atoms initially"); exit (EXIT_FAILURE); } tmplist=_mol_malloc(natoms*sizeof(int)); for(i=0; i<natoms; i++)tmplist[i]=1; for(i=0; i<nlist; i++)tmplist[list[i]]=0; nout=0; for(i=0; i<nlist; i++) { x1=ag->atoms[list[i]].X; y1=ag->atoms[list[i]].Y; z1=ag->atoms[list[i]].Z; for(j=0; j<natoms; j++) { if(tmplist[j]!=1)continue; x2=ag->atoms[j].X-x1; y2=ag->atoms[j].Y-y1; z2=ag->atoms[j].Z-z1; d2=x2*x2+y2*y2+z2*z2; if(d2<=du2) { tmplist[j]=2; nout++; } } } destag = (struct atomgrp*) _mol_calloc (1, sizeof (struct atomgrp)); destag->natoms = nout; destag->atoms = (struct atom*) _mol_malloc (sizeof (struct atom) * destag->natoms); j=0; for (i = 0; i < natoms; i++) { if(tmplist[i]==2)copy_atom (&ag->atoms[i], &destag->atoms[j++]); } free(tmplist); return destag; }
char *atom_prm_file(const char *atom_prm) { _PRINT_DEPRECATED_ size_t slen; // string length char *pdir = prms_dir(); char *atom_pfile = (char *)_mol_malloc(MAXSLEN * sizeof(char)); slen = strlen(pdir); if (slen > MAXSLEN - 20) { fprintf(stderr, "string %s is too long\n", pdir); exit(EXIT_FAILURE); } slen = strlen(pdir) + strlen(atom_prm); if (slen > MAXSLEN - 20) { fprintf(stderr, "string %s is too long\n", atom_prm); exit(EXIT_FAILURE); } atom_pfile = strcpy(atom_pfile, pdir); free(pdir); atom_pfile = strcat(atom_pfile, "/"); atom_pfile = strcat(atom_pfile, atom_prm); return atom_pfile; }
struct atomgrp* join_atomgrps (struct atomgrp** ags) { struct atomgrp* ag = (struct atomgrp*) _mol_calloc (1, sizeof (struct atomgrp)); ag->natoms = 100; // just a guess, realloc as necessary ag->atoms = (struct atom*) _mol_malloc (sizeof (struct atom) * ag->natoms); int agai = 0; // ag atom index int agi = 0; // index into ags while (ags[agi] != NULL) { int agsai; // ags atom index for (agsai = 0; agsai < ags[agi]->natoms; agsai++, agai++) { if (agai+1 > ag->natoms) { ag->natoms *= 2; ag->atoms = (struct atom*) _mol_realloc (ag->atoms, sizeof (struct atom) * ag->natoms); } copy_atom (&ags[agi]->atoms[agsai], &ag->atoms[agai]); } agi++; } // final realloc of the arrays to make them tight ag->natoms = agai; ag->atoms = (struct atom*) _mol_realloc (ag->atoms, sizeof (struct atom) * ag->natoms); return ag; }
static int *compute_0123_list(struct atomgrp *ag, int *n0123, int *list03, int n03, int *list02, int n02, int *na01, int **pna01) { int i, j, n2, ind; int *p; int *list0123; *n0123 = (ag->nbonds + n03 + n02); list0123 = (int *)_mol_malloc(*n0123 * 2 * sizeof(int)); ind = 0; //list03 goes first for (i = 0; i < n03; i++) { list0123[ind++] = list03[2 * i]; list0123[ind++] = list03[2 * i + 1]; } for (i = 0; i < ag->natoms; i++) { n2 = na01[i]; p = pna01[i]; for (j = 0; j < n2; j++) { if (p[j] > i) { list0123[ind++] = i; list0123[ind++] = p[j]; } } } for (i = 0; i < n02; i++) { list0123[ind++] = list02[2 * i]; list0123[ind++] = list02[2 * i + 1]; } return list0123; }
struct tvector* negative_tvector (struct tvector* tv) { struct tvector* neg_tv = (struct tvector*) _mol_malloc (sizeof (struct tvector)); neg_tv->X = -tv->X; neg_tv->Y = -tv->Y; neg_tv->Z = -tv->Z; return neg_tv; }
void baccs2(struct atomgrp* ag, float r_solv ) { int n_at=ag->natoms; int i; float* as=_mol_malloc(n_at*sizeof(float)); accs2(ag, r_solv, 1, as); for(i=0; i<n_at; i++)ag->atoms[i].sa=as[i]>0.0?1:0; free(as); }
struct atomgrp* join_2atomgrps (struct atomgrp* ag1, struct atomgrp* ag2) { struct atomgrp** ags = (struct atomgrp**) _mol_malloc (3 * sizeof (struct atomgrp*)); ags[0] = ag1; ags[1] = ag2; ags[2] = NULL; struct atomgrp* ag = join_atomgrps (ags); free (ags); return ag; }
/* sthresh if as > sthresh sa=1 if as<= sthresh sa=0 */ void baccs(struct atomgrp* ag, struct prm* prm, float r_solv, short cont_acc, short rpr, float sthresh) { int n_at=ag->natoms; int i; float* as= (float*)_mol_malloc(n_at*sizeof(float)); accs(ag, prm, r_solv, cont_acc, rpr, as); for(i=0; i<n_at; i++)ag->atoms[i].sa=as[i]>sthresh?1:0; free(as); }
/*This function does the same thing as baccs except it call accs1 (the traditional surface area accesibility algorith) instead of accs (in-house protein-protein concerned algorithm).*/ void baccs1(struct atomgrp* ag, int n_at, int* restat, double r_solv, short cont_acc, float sthresh) { int i; double* as=(double*)_mol_malloc(n_at*sizeof(double)); accs1(ag, n_at, restat, r_solv, cont_acc, as); for(i=0; i<n_at; i++)ag->atoms[i].sa=as[i]>sthresh?1:0; free(as); }
// warning: this function does not handle all of mol_atom_group void mol_atom_group_create_from_template ( mol_atom_group* ag, mol_atom_group* agtmplt) { int i; //nulls out any unset pointers, zeroes out counts memset(ag, 0, sizeof(mol_atom_group)); assert (ag != NULL); assert (agtmplt != NULL); // create atoms ag->natoms = agtmplt->natoms; if (ag->natoms > 0) { ag->atoms = _mol_malloc (ag->natoms * sizeof (mol_atom)); for (i=0; i < ag->natoms; i++) mol_atom_create (&ag->atoms[i], agtmplt->atoms[i].nbondis); } else ag->atoms = NULL; // create bonds ag->nbonds = agtmplt->nbonds; if (ag->nbonds > 0) { ag->bonds = _mol_malloc (ag->nbonds * sizeof (mol_bond)); for (i=0; i < ag->nbonds; i++) mol_bond_create (&ag->bonds[i]); } else ag->bonds = NULL; ag->nres = 0; ag->nangs = 0; ag->ntors = 0; ag->nimps = 0; return; }
void _mol_atom_create_bond_indices(mol_atom * a, int nbondis) { assert(a != NULL); a->nbondis = nbondis; if (a->nbondis > 0) a->bondis = _mol_malloc(a->nbondis * sizeof(int)); else a->bondis = NULL; return; }
struct atomgrp* copy_atomgrp (struct atomgrp* srcag) { struct atomgrp* destag = (struct atomgrp*) _mol_calloc (1, sizeof (struct atomgrp)); destag->natoms = srcag->natoms; destag->atoms = (struct atom*) _mol_malloc (sizeof (struct atom) * destag->natoms); int atomn; for (atomn = 0; atomn < destag->natoms; atomn++) { copy_atom (&srcag->atoms[atomn], &destag->atoms[atomn]); } return destag; }
void check_epeng_grads(struct atomgrp *ag, struct grid* pot, double d, void (*efun)(double, struct atomgrp *, double*, struct grid*)) { int n=ag->natoms, i; double en, en1, t; double *fs=(double*)_mol_malloc(3*n*sizeof(double)); //en0 en=0; // (*efun)(ag, &en); (*efun)(1.0,ag, &en, pot); for(i=0; i<n; i++) { //x en1=0; t=ag->atoms[i].X; ag->atoms[i].X=d+t; // (*efun)(ag, &en1); (*efun)(1.0,ag, &en1, pot); ag->atoms[i].X=t; fs[3*i]=(en-en1)/d; //y en1=0; t=ag->atoms[i].Y; ag->atoms[i].Y=d+t; // (*efun)(ag, &en1); (*efun)(1.0,ag, &en1, pot); ag->atoms[i].Y=t; fs[3*i+1]=(en-en1)/d; //z en1=0; t=ag->atoms[i].Z; ag->atoms[i].Z=d+t; // (*efun)(ag, &en1); (*efun)(1.0,ag, &en1, pot); ag->atoms[i].Z=t; fs[3*i+2]=(en-en1)/d; } en=0; zero_grads(ag); // (*efun)(ag, &en); (*efun)(1.0,ag, &en, pot); for(i=0; i<n; i++) { printf("%d calculated: %lf %lf %lf\n", i,ag->atoms[i].GX,ag->atoms[i].GY,ag->atoms[i].GZ); printf("%d numerical : %lf %lf %lf\n", i,fs[3*i],fs[3*i+1],fs[3*i+2]); } free(fs); }
struct atomgrp* exrm_type (struct atomgrp* ag, const char* type, struct prm* prm, int direction) { int atomn; // loop var int natoms; // type atom number struct atomgrp* exag = (struct atomgrp*) _mol_calloc (1, sizeof (struct atomgrp)); // resultant extracted atomgrp exag->atoms = (struct atom*) _mol_malloc (sizeof (struct atom) * ag->natoms); // allocate memory for the array of atoms, realloc later to make it tight natoms = 0; for (atomn = 0; atomn < ag->natoms; atomn++) { if ( (direction == 0 && strcmp (type, prm->atoms[ag->atoms[atomn].atom_typen].typemin) == 0) // extract type || (direction == 1 && ! (strcmp (type, prm->atoms[ag->atoms[atomn].atom_typen].typemin) == 0)) // rm type ) { exag->atoms[natoms].atom_typen = ag->atoms[atomn].atom_typen; exag->atoms[natoms].sa = ag->atoms[atomn].sa; exag->atoms[natoms].X = ag->atoms[atomn].X; exag->atoms[natoms].Y = ag->atoms[atomn].Y; exag->atoms[natoms].Z = ag->atoms[atomn].Z; /* exag->atoms[natoms].bonds[0] = ag->atoms[atomn].bonds[0]; exag->atoms[natoms].bonds[1] = ag->atoms[atomn].bonds[1]; exag->atoms[natoms].bonds[2] = ag->atoms[atomn].bonds[2]; exag->atoms[natoms].bonds[3] = ag->atoms[atomn].bonds[3]; */ natoms++; } } if (natoms == 0) { if (direction == 0) { fprintf (stderr, "there are no atoms of type %s to extract\n", type); } if (direction == 1) { fprintf (stderr, "removing atoms of type %s leaves no remaining atoms\n", type); } exit (EXIT_FAILURE); } exag->atoms = (struct atom*) _mol_realloc (exag->atoms, sizeof (struct atom) * natoms); // realloc exag->atoms to make it tight exag->natoms = natoms; // attach number of atoms return exag; }
struct rotset* create_sym_rotset (int nmonomers) { struct rotset* rotset = (struct rotset*) _mol_malloc (sizeof (struct rotset)); rotset->nrots = 2; // 2 rotations: 1 for cyclical symmetry and 1 for dihedral symmetry rotset->rmats = (struct rmatrix*) _mol_malloc (rotset->nrots * sizeof (struct rmatrix)); float angle = 2.0 * 3.14159 / (float) nmonomers; // for cyclic symmetry: rotset->rmats[0].a11 = cos (angle); rotset->rmats[0].a12 = sin (angle); rotset->rmats[0].a13 = 0.0; rotset->rmats[0].a21 = -sin (angle); rotset->rmats[0].a22 = cos (angle); rotset->rmats[0].a23 = 0.0; rotset->rmats[0].a31 = 0.0; rotset->rmats[0].a32 = 0.0; rotset->rmats[0].a33 = 1.0; // for dihedral symmetry: return rotset; }
void mol_svn_version (char** lineptr, size_t *n) { size_t length = strlen(_SVN_VERSION_); if (*lineptr == NULL) { *lineptr = (char*)_mol_malloc( sizeof(char) * length ); *n = length; } else if( *n < length) { *lineptr = (char*)_mol_realloc(*lineptr, sizeof(char) * length ); *n = length; } sprintf(*lineptr, "%s", _SVN_VERSION_); }
float* moment_of_inertia (struct atomgrp* ag) { struct tvector* com = center_of_mass (ag); float sq_x_com = powf (com->X, 2.0); float sq_y_com = powf (com->Y, 2.0); float sq_z_com = powf (com->Z, 2.0); float sum_sq_x = 0; float sum_sq_y = 0; float sum_sq_z = 0; float sum_mult_xy = 0; float sum_mult_xz = 0; float sum_mult_yz = 0; int i; for (i = 0; i < ag->natoms; i++) { sum_sq_x += powf (ag->atoms[i].X, 2.0); sum_sq_y += powf (ag->atoms[i].Y, 2.0); sum_sq_z += powf (ag->atoms[i].Z, 2.0); sum_mult_xy += ag->atoms[i].X * ag->atoms[i].Y; sum_mult_xz += ag->atoms[i].X * ag->atoms[i].Z; sum_mult_yz += ag->atoms[i].Y * ag->atoms[i].Z; } float* moi_matrix = (float*) _mol_malloc (sizeof (float) * 9); moi_matrix[0] = sum_sq_y + sum_sq_z - (sq_y_com + sq_z_com) * ag->natoms; moi_matrix[1] = -sum_mult_xy + com->X * com->Y * ag->natoms; moi_matrix[2] = -sum_mult_xz + com->X * com->Z * ag->natoms; moi_matrix[3] = -sum_mult_xy + com->X * com->Y * ag->natoms; moi_matrix[4] = sum_sq_x + sum_sq_z - (sq_x_com + sq_z_com) * ag->natoms; moi_matrix[5] = -sum_mult_yz + com->Y * com->Z * ag->natoms; moi_matrix[6] = -sum_mult_xz + com->X * com->Z * ag->natoms; moi_matrix[7] = -sum_mult_yz + com->Y * com->Z * ag->natoms; moi_matrix[8] = sum_sq_x + sum_sq_y - (sq_x_com + sq_y_com) * ag->natoms; free (com); return moi_matrix; }
int* read_sasa (const char* path) { FILE* fp = myfopen (path, "r"); int nsasas = 100; // just a guess, realloc as necessary int* sasas = (int*) _mol_malloc (sizeof (int) * nsasas); char* line = NULL; size_t len = 0; int i = 0; while (getline (&line, &len, fp) != -1) { if (i+1 > nsasas) { nsasas *= 2; sasas = (int*) _mol_realloc (sasas, sizeof (int) * nsasas); } if (sscanf (line, "%d", &sasas[i]) < 1) { fprintf (stderr, "error: in file %s line %s: incorrect sasa line\n", path, line); exit (EXIT_FAILURE); } if (sasas[i] != 0 && sasas[i] != 1) { fprintf (stderr, "error: in file %s line %s integer should be 0 or 1\n", path, line); exit (EXIT_FAILURE); } i++; } if (line) free (line); myfclose (fp); // final realloc of the arrays to make them tight nsasas = i; sasas = (int*) _mol_realloc (sasas, sizeof (int) * (nsasas+1)); // one extra for -1 sasas[nsasas] = -1; return sasas; }
char *prms_dir() { _PRINT_DEPRECATED_ size_t slen; // string length char *mdir = main_dir(); char *pdir = (char *)_mol_malloc(MAXSLEN * sizeof(char)); slen = strlen(mdir); if (slen > MAXSLEN - 20) { fprintf(stderr, "string %s is too long\n", mdir); exit(EXIT_FAILURE); } pdir = strcpy(pdir, mdir); free(mdir); pdir = strcat(pdir, "/prm"); return pdir; }
char *main_dir() { _PRINT_DEPRECATED_ size_t slen; // string length char here[] = "."; char *mdir = (char *)_mol_malloc(MAXSLEN * sizeof(char)); slen = strlen(here); if (slen > MAXSLEN - 20) { fprintf(stderr, "string %s is too long\n", here); exit(EXIT_FAILURE); } mdir = strcpy(mdir, here); //mdir = strcat (mdir, "/.mol"); mdir = strcat(mdir, ""); return mdir; }
void replace_coordinates(struct atomgrp *ag, const char *pdb_path) { int i; int *list = _mol_malloc(sizeof(int) * ag->natoms); struct atomgrp *ag_new = read_pdb_nopar(pdb_path); if (ag_new->natoms != ag->natoms) { _mol_error("new atomgroup has %d atoms, old has %d atoms", ag_new->natoms, ag->natoms); exit(EXIT_FAILURE); } for (i = 0; i < ag->natoms; i++) { list[i] = i; } setup_subag(ag, ag_new, ag->natoms, list); free(list); free_atomgrp(ag_new); }
struct tvector* center_of_mass (struct atomgrp* ag) { // sums of atom positions float sumX = 0; float sumY = 0; float sumZ = 0; int i; for (i = 0; i < ag->natoms; i++) // sum the atoms { sumX += ag->atoms[i].X; sumY += ag->atoms[i].Y; sumZ += ag->atoms[i].Z; } struct tvector* tvec = (struct tvector*) _mol_malloc (sizeof (struct tvector)); tvec->X = (sumX / ag->natoms); tvec->Y = (sumY / ag->natoms); tvec->Z = (sumZ / ag->natoms); return tvec; }
struct tvector* center_of_extrema (struct atomgrp* ag) { if (ag->natoms == 0) return NULL; // extrema of atom positions float minX = ag->atoms[0].X, maxX = ag->atoms[0].X; float minY = ag->atoms[0].Y, maxY = ag->atoms[0].Y; float minZ = ag->atoms[0].Z, maxZ = ag->atoms[0].Z; int i; for (i = 1; i < ag->natoms; i++) { if (ag->atoms[i].X < minX) minX = ag->atoms[i].X; if (ag->atoms[i].X > maxX) maxX = ag->atoms[i].X; if (ag->atoms[i].Y < minY) minY = ag->atoms[i].Y; if (ag->atoms[i].Y > maxY) maxY = ag->atoms[i].Y; if (ag->atoms[i].Z < minZ) minZ = ag->atoms[i].Z; if (ag->atoms[i].Z > maxZ) maxZ = ag->atoms[i].Z; } struct tvector* tvec = (struct tvector*) _mol_malloc (sizeof (struct tvector)); tvec->X = ((maxX - minX) / 2) + minX; tvec->Y = ((maxY - minY) / 2) + minY; tvec->Z = ((maxZ - minZ) / 2) + minZ; return tvec; }
mol_tvector * mol_tvector_create () { mol_tvector *v = (mol_tvector*)_mol_malloc (sizeof (mol_tvector)); return v; }
struct atomgrp *read_json_ag(const char *json_file) { struct atomgrp *ag = (struct atomgrp *)_mol_calloc(1, sizeof(struct atomgrp)); json_error_t json_file_error; json_t *base = json_load_file(json_file, 0, &json_file_error); if (!base) { fprintf(stderr, "error reading json file %s on line %d column %d: %s\n", json_file, json_file_error.line, json_file_error.column, json_file_error.text); } if (!json_is_object(base)) { fprintf(stderr, "json file not an object %s\n", json_file); } json_t *atoms, *bonds, *angles, *torsions, *impropers; atoms = json_object_get(base, "atoms"); if (!json_is_array(atoms)) { fprintf(stderr, "json atoms are not an array %s\n", json_file); } size_t natoms = json_array_size(atoms); ag->natoms = natoms; ag->atoms = (struct atom *)_mol_calloc(ag->natoms, sizeof(struct atom)); ag->num_atom_types = 0; char *prev_segment = _mol_calloc(1, sizeof(char)); char *prev_residue = _mol_calloc(1, sizeof(char)); int prev_residue_seq = -107; ag->nres = 0; int alloc_res = 250; ag->iares = _mol_malloc(alloc_res*sizeof(int)); for (size_t i = 0; i < natoms; i++) { json_t *atom = json_array_get(atoms, i); if (!json_is_object(atom)) { fprintf(stderr, "Atom %zd not an object in json file %s\n", i, json_file); } json_t *ace_volume, *ftype_index, *ftype_name, *eps03; json_t *name, *radius03, *eps, *acp_type, *residue_name; json_t *charge, *radius, *element; json_t *x, *y, *z; json_t *yeti_type, *sybyl_type; json_t *backbone, *hb_acceptor, *hb_donor, *hb_weight; json_t *segment, *residue; segment = json_object_get(atom, "segment"); residue = json_object_get(atom, "residue"); if ((segment != NULL) && (residue != NULL)) { if (!json_is_string(segment)) { fprintf(stderr, "json segment is not string for atom %zd in json_file %s\n", i, json_file); } if (!json_is_string(residue)) { fprintf(stderr, "json residue is not string for atom %zd in json_file %s\n", i, json_file); } const char *cur_segment = json_string_value(segment); const char *cur_residue = json_string_value(residue); if (strcmp(cur_segment, prev_segment) != 0) { prev_residue_seq += 100; free(prev_segment); prev_segment = strdup(cur_segment); } if (strcmp(cur_residue, prev_residue) != 0) { int cur_residue_int = atoi(cur_residue); int prev_residue_int = atoi(prev_residue); if ((cur_residue_int - prev_residue_int) > 1) { prev_residue_seq += (cur_residue_int - prev_residue_int); } else { prev_residue_seq += 1; } free(prev_residue); prev_residue = strdup(cur_residue); if (ag->nres +1 == alloc_res) { alloc_res *= 2; ag->iares = _mol_realloc(ag->iares, alloc_res * i); } ag->iares[ag->nres] = i; ag->nres++; } ag->atoms[i].comb_res_seq = prev_residue_seq; } else { ag->atoms[i].comb_res_seq = prev_residue_seq; } ace_volume = json_object_get(atom, "ace_volume"); if (!json_is_real(ace_volume)) { fprintf(stderr, "json ace volume is not floating point for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].acevolume = json_real_value(ace_volume); ftype_index = json_object_get(atom, "ftype_index"); if (!json_is_integer(ftype_index)) { fprintf(stderr, "json ftype index is not integer for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].atom_ftypen = json_integer_value(ftype_index); if (ag->atoms[i].atom_ftypen > ag->num_atom_types) { ag->num_atom_types = ag->atoms[i].atom_ftypen; } ftype_name = json_object_get(atom, "ftype_name"); if (!json_is_string(ftype_name)) { fprintf(stderr, "json ftype name is not string for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].ftype_name = strdup(json_string_value(ftype_name)); element = json_object_get(atom, "element"); if (!json_is_string(element)) { fprintf(stderr, "json element name is not string for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].element = strdup(json_string_value(element)); eps = json_object_get(atom, "eps"); if (!json_is_real(eps)) { fprintf(stderr, "json eps is not floating point for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].eps = sqrt(-json_real_value(eps)); eps03 = json_object_get(atom, "eps03"); if (!json_is_real(eps03)) { fprintf(stderr, "json eps03 is not floating point for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].eps03 = sqrt(-json_real_value(eps03)); radius = json_object_get(atom, "radius"); if (!json_is_real(radius)) { fprintf(stderr, "json radius is not floating point for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].rminh = json_real_value(radius); radius03 = json_object_get(atom, "radius03"); if (!json_is_real(radius03)) { fprintf(stderr, "json radius03 is not floating point for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].rminh03 = json_real_value(radius03); charge = json_object_get(atom, "charge"); if (!json_is_real(radius03)) { fprintf(stderr, "json charge is not floating point for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].chrg = json_real_value(charge); name = json_object_get(atom, "name"); if (!json_is_string(name)) { fprintf(stderr, "json name is not string for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].name = strdup(json_string_value(name)); residue_name = json_object_get(atom, "residue_name"); if (residue_name != NULL) { if (!json_is_string(residue_name)) { fprintf(stderr, "json residue_name is not string for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].residue_name = strdup(json_string_value(residue_name)); } else { ag->atoms[i].residue_name = NULL; } x = json_object_get(atom, "x"); if (!json_is_real(x)) { fprintf(stderr, "json coordinate x is not floating point for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].X = json_real_value(x); y = json_object_get(atom, "y"); if (!json_is_real(y)) { fprintf(stderr, "json coordinate y is not floating point for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].Y = json_real_value(y); z = json_object_get(atom, "z"); if (!json_is_real(z)) { fprintf(stderr, "json coordinate z is not floating point for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].Z = json_real_value(z); acp_type = json_object_get(atom, "acp_type"); if (acp_type != NULL) { if (!json_is_integer(acp_type)) { fprintf(stderr, "json acp_type index is not integer for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].acp_type = json_integer_value(acp_type); } else { ag->atoms[i].acp_type = -1; } yeti_type = json_object_get(atom, "yeti_type"); if (yeti_type != NULL) { const char *yeti_type_string; if (!json_is_string(yeti_type)) { fprintf(stderr, "json yeti_type is not string for atom %zd in json_file %s\n", i, json_file); } yeti_type_string = json_string_value(yeti_type); if (strcmp("carbonyl", yeti_type_string) == 0) { ag->atoms[i].yeti_type = MOL_YETI_CARBONYL; } else if (strcmp("hydroxyl", yeti_type_string) == 0) { ag->atoms[i].yeti_type = MOL_YETI_HYDROXYL; } else if (strcmp("sulfonamide", yeti_type_string) == 0) { ag->atoms[i].yeti_type = MOL_YETI_SULFONAMIDE; } else if (strcmp("N5_aromatic", yeti_type_string) == 0) { ag->atoms[i].yeti_type = MOL_YETI_N5_AROMATIC; } else if (strcmp("N6_aromatic", yeti_type_string) == 0) { ag->atoms[i].yeti_type = MOL_YETI_N6_AROMATIC; } else { fprintf(stderr, "unknown json yeti_type %s for atom %zd in json_file %s\n", yeti_type_string, i, json_file); ag->atoms[i].yeti_type = MOL_YETI_NONE; } } else { ag->atoms[i].yeti_type = MOL_YETI_NONE; } sybyl_type = json_object_get(atom, "sybyl_type"); if (sybyl_type != NULL) { const char *sybyl_type_string; if (!json_is_string(sybyl_type)) { fprintf(stderr, "json sybyl_type is not string for atom %zd in json_file %s\n", i, json_file); } sybyl_type_string = json_string_value(sybyl_type); ag->atoms[i].hybridization = mol_hydridization_from_sybyl(sybyl_type_string); } else { ag->atoms[i].hybridization = UNKNOWN_HYBRID; } backbone = json_object_get(atom, "backbone"); if (backbone != NULL) { if (!json_is_boolean(backbone)) { fprintf(stderr, "json backbone is not boolean for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].backbone = json_is_true(backbone); } else { ag->atoms[i].backbone = false; } ag->atoms[i].hprop = 0; hb_acceptor = json_object_get(atom, "hb_acceptor"); if (hb_acceptor != NULL) { if (!json_is_boolean(hb_acceptor)) { fprintf(stderr, "json hb_acceptor is not boolean for atom %zd in json_file %s\n", i, json_file); } if (json_is_true(hb_acceptor)) { ag->atoms[i].hprop |= HBOND_ACCEPTOR; } } hb_donor = json_object_get(atom, "hb_donor"); if (hb_donor != NULL) { if (!json_is_boolean(hb_donor)) { fprintf(stderr, "json hb_donor is not boolean for atom %zd in json_file %s\n", i, json_file); } if (json_is_true(hb_donor)) { ag->atoms[i].hprop |= DONATABLE_HYDROGEN; } } ag->atoms[i].hbond_weight = 1.0; hb_weight = json_object_get(atom, "hb_weight"); if (hb_weight != NULL) { if (!json_is_real(hb_weight)) { fprintf(stderr, "json hb_weight is not floating point for atom %zd in json_file %s\n", i, json_file); } ag->atoms[i].hbond_weight = json_real_value(hb_weight); } ag->atoms[i].nbonds = 0; ag->atoms[i].nangs = 0; ag->atoms[i].ntors = 0; ag->atoms[i].nimps = 0; ag->atoms[i].fixed = 0; ag->atoms[i].sa = -1; ag->atoms[i].base = -1; ag->atoms[i].base2 = -1; } ag->iares[ag->nres] = ag->natoms; ag->iares = _mol_realloc(ag->iares, (ag->nres+1) * sizeof(int)); free(prev_segment); free(prev_residue); bonds = json_object_get(base, "bonds"); if (!json_is_array(bonds)) { fprintf(stderr, "json bonds are not an array %s\n", json_file); } size_t nbonds = json_array_size(bonds); ag->nbonds = nbonds; ag->bonds = _mol_calloc(nbonds, sizeof(struct atombond)); for (size_t i = 0; i < nbonds; i++) { json_t *bond = json_array_get(bonds, i); if (!json_is_object(bond)) { fprintf(stderr, "Bond %zd not an object in json file %s\n", i, json_file); } json_t *length, *atom1, *atom2, *spring_constant, *sdf_type; atom1 = json_object_get(bond, "atom1"); if (!json_is_integer(atom1)) { fprintf(stderr, "json atom1 is not integer for bond %zd in json_file %s\n", i, json_file); } int i1 = json_integer_value(atom1) - 1; ag->bonds[i].a0 = &(ag->atoms[i1]); (ag->atoms[i1].nbonds)++; atom2 = json_object_get(bond, "atom2"); if (!json_is_integer(atom2)) { fprintf(stderr, "json atom2 is not integer for bond %zd in json_file %s\n", i, json_file); } int i2 = json_integer_value(atom2) - 1; ag->bonds[i].a1 = &(ag->atoms[i2]); (ag->atoms[i2].nbonds)++; length = json_object_get(bond, "length"); if (!json_is_real(length)) { fprintf(stderr, "json length is not floating point for bond %zd in json_file %s\n", i, json_file); } ag->bonds[i].l0 = json_real_value(length); spring_constant = json_object_get(bond, "spring_constant"); if (!json_is_real(spring_constant)) { fprintf(stderr, "json spring_constant is not floating point for bond %zd in json_file %s\n", i, json_file); } ag->bonds[i].k = json_real_value(spring_constant); sdf_type = json_object_get(bond, "sdf_type"); if (sdf_type != NULL) { if (!json_is_integer(sdf_type)) { fprintf(stderr, "json sdf_type is not integer for bond %zd in json_file %s\n", i, json_file); } ag->bonds[i].sdf_type = json_integer_value(sdf_type); } else { ag->bonds[i].sdf_type = 0; } } angles = json_object_get(base, "angles"); if (!json_is_array(angles)) { fprintf(stderr, "json angles are not an array %s\n", json_file); } size_t nangles = json_array_size(angles); ag->nangs = nangles; ag->angs = _mol_calloc(nangles, sizeof(struct atomangle)); for (size_t i = 0; i < nangles; i++) { json_t *angle = json_array_get(angles, i); if (!json_is_object(angle)) { fprintf(stderr, "Angle %zd not an object in json file %s\n", i, json_file); } json_t *theta, *atom1, *atom2, *atom3, *spring_constant; atom1 = json_object_get(angle, "atom1"); if (!json_is_integer(atom1)) { fprintf(stderr, "json atom1 is not integer for angle %zd in json_file %s\n", i, json_file); } int i1 = json_integer_value(atom1) - 1; ag->angs[i].a0 = &(ag->atoms[i1]); (ag->atoms[i1].nangs)++; atom2 = json_object_get(angle, "atom2"); if (!json_is_integer(atom2)) { fprintf(stderr, "json atom2 is not integer for angle %zd in json_file %s\n", i, json_file); } int i2 = json_integer_value(atom2) - 1; ag->angs[i].a1 = &(ag->atoms[i2]); (ag->atoms[i2].nangs)++; atom3 = json_object_get(angle, "atom3"); if (!json_is_integer(atom3)) { fprintf(stderr, "json atom3 is not integer for angle %zd in json_file %s\n", i, json_file); } int i3 = json_integer_value(atom3) - 1; ag->angs[i].a2 = &(ag->atoms[i3]); (ag->atoms[i3].nangs)++; theta = json_object_get(angle, "theta"); if (!json_is_real(theta)) { fprintf(stderr, "json theta is not floating point for angle %zd in json_file %s\n", i, json_file); } ag->angs[i].th0 = json_real_value(theta); spring_constant = json_object_get(angle, "spring_constant"); if (!json_is_real(spring_constant)) { fprintf(stderr, "json spring_constant is not floating point for angle %zd in json_file %s\n", i, json_file); } ag->angs[i].k = json_real_value(spring_constant); } torsions = json_object_get(base, "torsions"); if (!json_is_array(torsions)) { fprintf(stderr, "json torsions are not an array %s\n", json_file); } size_t ntorsions = json_array_size(torsions); ag->ntors = ntorsions; ag->tors = _mol_calloc(ntorsions, sizeof(struct atomtorsion)); for (size_t i = 0; i < ntorsions; i++) { json_t *torsion = json_array_get(torsions, i); if (!json_is_object(torsion)) { fprintf(stderr, "Torsion %zd not an object in json file %s\n", i, json_file); } json_t *atom1, *atom2, *atom3, *atom4, *minima, *delta_constant, *spring_constant; atom1 = json_object_get(torsion, "atom1"); if (!json_is_integer(atom1)) { fprintf(stderr, "json atom1 is not integer for torsion %zd in json_file %s\n", i, json_file); } int i1 = json_integer_value(atom1) - 1; ag->tors[i].a0 = &(ag->atoms[i1]); (ag->atoms[i1].ntors)++; atom2 = json_object_get(torsion, "atom2"); if (!json_is_integer(atom2)) { fprintf(stderr, "json atom2 is not integer for torsion %zd in json_file %s\n", i, json_file); } int i2 = json_integer_value(atom2) - 1; ag->tors[i].a1 = &(ag->atoms[i2]); (ag->atoms[i2].ntors)++; atom3 = json_object_get(torsion, "atom3"); if (!json_is_integer(atom3)) { fprintf(stderr, "json atom3 is not integer for torsion %zd in json_file %s\n", i, json_file); } int i3 = json_integer_value(atom3) - 1; ag->tors[i].a2 = &(ag->atoms[i3]); (ag->atoms[i3].ntors)++; atom4 = json_object_get(torsion, "atom4"); if (!json_is_integer(atom4)) { fprintf(stderr, "json atom4 is not integer for torsion %zd in json_file %s\n", i, json_file); } int i4 = json_integer_value(atom4) - 1; ag->tors[i].a3 = &(ag->atoms[i4]); (ag->atoms[i4].ntors)++; minima = json_object_get(torsion, "minima"); if (!json_is_integer(minima)) { fprintf(stderr, "json minima is not integer for torsion %zd in json_file %s\n", i, json_file); } ag->tors[i].n = json_integer_value(minima); delta_constant = json_object_get(torsion, "delta_constant"); if (!json_is_real(delta_constant)) { fprintf(stderr, "json delta_constant is not floating point for torsion %zd in json_file %s\n", i, json_file); } ag->tors[i].d = json_real_value(delta_constant); spring_constant = json_object_get(torsion, "spring_constant"); if (!json_is_real(spring_constant)) { fprintf(stderr, "json spring_constant is not floating point for torsion %zd in json_file %s\n", i, json_file); } ag->tors[i].k = json_real_value(spring_constant); } impropers = json_object_get(base, "impropers"); if (!json_is_array(impropers)) { fprintf(stderr, "json impropers are not an array %s\n", json_file); } size_t nimpropers = json_array_size(impropers); ag->nimps = nimpropers; ag->imps = _mol_calloc(nimpropers, sizeof(struct atomimproper)); for (size_t i = 0; i < nimpropers; i++) { json_t *improper = json_array_get(impropers, i); if (!json_is_object(improper)) { fprintf(stderr, "Improper %zd not an object in json file %s\n", i, json_file); } json_t *atom1, *atom2, *atom3, *atom4, *phi, *spring_constant; atom1 = json_object_get(improper, "atom1"); if (!json_is_integer(atom1)) { fprintf(stderr, "json atom1 is not integer for improper %zd in json_file %s\n", i, json_file); } int i1 = json_integer_value(atom1) - 1; ag->imps[i].a0 = &(ag->atoms[i1]); (ag->atoms[i1].nimps)++; atom2 = json_object_get(improper, "atom2"); if (!json_is_integer(atom2)) { fprintf(stderr, "json atom2 is not integer for improper %zd in json_file %s\n", i, json_file); } int i2 = json_integer_value(atom2) - 1; ag->imps[i].a1 = &(ag->atoms[i2]); (ag->atoms[i2].nimps)++; atom3 = json_object_get(improper, "atom3"); if (!json_is_integer(atom3)) { fprintf(stderr, "json atom3 is not integer for improper %zd in json_file %s\n", i, json_file); } int i3 = json_integer_value(atom3) - 1; ag->imps[i].a2 = &(ag->atoms[i3]); (ag->atoms[i3].nimps)++; atom4 = json_object_get(improper, "atom4"); if (!json_is_integer(atom4)) { fprintf(stderr, "json atom4 is not integer for improper %zd in json_file %s\n", i, json_file); } int i4 = json_integer_value(atom4) - 1; ag->imps[i].a3 = &(ag->atoms[i4]); (ag->atoms[i4].nimps)++; phi = json_object_get(improper, "phi"); if (!json_is_real(phi)) { fprintf(stderr, "json phi is not floating point for improper %zd in json_file %s\n", i, json_file); } ag->imps[i].psi0 = json_real_value(phi); spring_constant = json_object_get(improper, "spring_constant"); if (!json_is_real(spring_constant)) { fprintf(stderr, "json spring_constant is not floating point for improper %zd in json_file %s\n", i, json_file); } ag->imps[i].k = json_real_value(spring_constant); } json_decref(base); //allocate atom arrays of pointers to parameters for (size_t i = 0; i < natoms; i++) { int i1 = ag->atoms[i].nbonds; ag->atoms[i].bonds = _mol_calloc(i1, sizeof(struct atombond *)); ag->atoms[i].nbonds = 0; i1 = ag->atoms[i].nangs; ag->atoms[i].angs = _mol_calloc(i1, sizeof(struct atomangle *)); ag->atoms[i].nangs = 0; i1 = ag->atoms[i].ntors; ag->atoms[i].tors = _mol_calloc(i1, sizeof(struct atomtorsion *)); ag->atoms[i].ntors = 0; i1 = ag->atoms[i].nimps; ag->atoms[i].imps = _mol_calloc(i1, sizeof(struct atomimproper *)); ag->atoms[i].nimps = 0; } struct atom *atm; //fill bonds for (int i = 0; i < ag->nbonds; i++) { atm = ag->bonds[i].a0; atm->bonds[(atm->nbonds)++] = &(ag->bonds[i]); atm = ag->bonds[i].a1; atm->bonds[(atm->nbonds)++] = &(ag->bonds[i]); } //fill angles for (int i = 0; i < ag->nangs; i++) { atm = ag->angs[i].a0; atm->angs[(atm->nangs)++] = &(ag->angs[i]); atm = ag->angs[i].a1; atm->angs[(atm->nangs)++] = &(ag->angs[i]); atm = ag->angs[i].a2; atm->angs[(atm->nangs)++] = &(ag->angs[i]); } //fill torsions for (int i = 0; i < ag->ntors; i++) { atm = ag->tors[i].a0; atm->tors[(atm->ntors)++] = &(ag->tors[i]); atm = ag->tors[i].a1; atm->tors[(atm->ntors)++] = &(ag->tors[i]); atm = ag->tors[i].a2; atm->tors[(atm->ntors)++] = &(ag->tors[i]); atm = ag->tors[i].a3; atm->tors[(atm->ntors)++] = &(ag->tors[i]); } //fill impropers for (int i = 0; i < ag->nimps; i++) { atm = ag->imps[i].a0; atm->imps[(atm->nimps)++] = &(ag->imps[i]); atm = ag->imps[i].a1; atm->imps[(atm->nimps)++] = &(ag->imps[i]); atm = ag->imps[i].a2; atm->imps[(atm->nimps)++] = &(ag->imps[i]); atm = ag->imps[i].a3; atm->imps[(atm->nimps)++] = &(ag->imps[i]); } //atom indices in the group fill_ingrp(ag); ag->is_psf_read = true; // copy vals from deprecated to new data structures int atomsi; for (atomsi = 0; atomsi < ag->natoms; atomsi++) { _mol_atom_create_bond_indices(&ag->atoms[atomsi], ag->atoms[atomsi].nbonds); } _mol_atom_group_copy_from_deprecated(ag); return ag; }
struct atomgrp *read_pdb(const char *path, struct prm *prm) { FILE *fp = myfopen(path, "r"); struct atomgrp *ag = (struct atomgrp *)_mol_calloc(1, sizeof(struct atomgrp)); char *line = NULL; size_t len = 0; char atypemaj[5]; char atypemin[5]; // read every line of the pdb file int atomi = 0; ag->natoms = 100; // just a guess, realloc as necessary ag->atoms = (struct atom *)_mol_malloc(sizeof(struct atom) * ag->natoms); while (getline(&line, &len, fp) != -1) { if (strncmp(line, "ATOM ", 6) != 0) // check for ATOM line continue; if (atomi + 1 > ag->natoms) { ag->natoms *= 2; ag->atoms = (struct atom *)_mol_realloc(ag->atoms, sizeof(struct atom) * ag->natoms); } /* // init bonds ag->atoms[atomi].bonds[0] = -1; ag->atoms[atomi].bonds[1] = -1; ag->atoms[atomi].bonds[2] = -1; ag->atoms[atomi].bonds[3] = -1; */ // init sa ag->atoms[atomi].sa = -1; // init mask ag->atoms[atomi].mask = 0; // init attl ag->atoms[atomi].attl = 0.0; ag->atoms[atomi].nbondis = 0; ag->atoms[atomi].nbonds = 0; ag->atoms[atomi].nangs = 0; ag->atoms[atomi].ntors = 0; ag->atoms[atomi].nimps = 0; if (sscanf(line, "%*s %*d %4s %4s", atypemin, atypemaj) < 2) { fprintf(stderr, "error: in file %s line %s: incorrect atom line\n", path, line); exit(EXIT_FAILURE); } ag->atoms[atomi].atom_typen = atomid(prm, atypemaj, atypemin); if (ag->atoms[atomi].atom_typen == -1) // val not found { if (atypemin[0] == 'H') // try one more time for hydrogen { atypemin[1] = '\0'; ag->atoms[atomi].atom_typen = atomid(prm, atypemaj, atypemin); } if (ag->atoms[atomi].atom_typen == -1) // val still not found { fprintf(stderr, "error: in file %s line %s: atom type number of %s %s not defined in prm\n", path, line, atypemaj, atypemin); exit(EXIT_FAILURE); } } if (!strcmp(atypemin, "C") || !strcmp(atypemin, "CA") || !strcmp(atypemin, "N") || !strcmp(atypemin, "O") || !strcmp(atypemin, "H")) ag->atoms[atomi].backbone = true; else ag->atoms[atomi].backbone = false; sscanf(&line[30], "%8lf%8lf%8lf", &ag->atoms[atomi].X, &ag->atoms[atomi].Y, &ag->atoms[atomi].Z); sscanf(&line[60], "%6lf", &ag->atoms[atomi].B); ag->atoms[atomi].icode = line[26]; line[26] = 0; errno = 0; ag->atoms[atomi].res_seq = atoi(&line[22]); if (errno) { perror("atoi"); exit(EXIT_FAILURE); } ag->atoms[atomi].base = ag->atoms[atomi].base2 = -1; atomi++; } if (line) free(line); myfclose(fp); // final realloc of the arrays to make them tight ag->natoms = atomi; ag->atoms = (struct atom *)_mol_realloc(ag->atoms, sizeof(struct atom) * ag->natoms); ag->is_psf_read = false; ag->prm = prm; // check_atomgrp (ag, prm); return ag; }
struct atomgrp *read_pdb_nopar(const char *path) { FILE *fp = myfopen(path, "r"); struct atomgrp *ag = (struct atomgrp *)_mol_calloc(1, sizeof(struct atomgrp)); char *line = NULL; size_t len = 0; // read every line of the pdb file int atomi = 0; ag->natoms = 100; // just a guess, realloc as necessary ag->atoms = (struct atom *)_mol_malloc(sizeof(struct atom) * ag->natoms); while (getline(&line, &len, fp) != -1) { char *atom_name; if (strncmp(line, "ATOM ", 6) != 0 && strncmp(line, "HETATM", 6) != 0) continue; if (atomi + 1 > ag->natoms) { ag->natoms *= 2; ag->atoms = (struct atom *)_mol_realloc(ag->atoms, sizeof(struct atom) * ag->natoms); } // init bonds /* ag->atoms[atomi].bonds[0] = -1; ag->atoms[atomi].bonds[1] = -1; ag->atoms[atomi].bonds[2] = -1; ag->atoms[atomi].bonds[3] = -1; */ // init sa ag->atoms[atomi].sa = -1; // init mask // ag->atoms[atomi].mask = 0; // init attl // ag->atoms[atomi].attl = 0.0; ag->atoms[atomi].atom_typen = 1; if (!strncmp(line + 13, "C ", 2) || !strncmp(line + 13, "CA ", 3) || !strncmp(line + 13, "N ", 2) || !strncmp(line + 13, "O ", 2) || !strncmp(line + 13, "H ", 2)) ag->atoms[atomi].backbone = true; else ag->atoms[atomi].backbone = false; atom_name = _mol_calloc(5, sizeof(char)); strncpy(atom_name, line + 12, 4); rstrip(atom_name); while (isspace(*atom_name)) { memmove(atom_name, atom_name + 1, 4); } ag->atoms[atomi].name = atom_name; sscanf(&line[30], "%8lf%8lf%8lf", &ag->atoms[atomi].X, &ag->atoms[atomi].Y, &ag->atoms[atomi].Z); sscanf(&line[60], "%6lf", &ag->atoms[atomi].B); ag->atoms[atomi].icode = line[26]; line[26] = 0; errno = 0; ag->atoms[atomi].res_seq = atoi(&line[22]); if (errno) { perror("atoi"); exit(EXIT_FAILURE); } ag->atoms[atomi].base = ag->atoms[atomi].base2 = -1; ag->atoms[atomi].element = NULL; atomi++; } if (line) free(line); myfclose(fp); // final realloc of the arrays to make them tight ag->natoms = atomi; ag->atoms = (struct atom *)_mol_realloc(ag->atoms, sizeof(struct atom) * ag->natoms); ag->is_psf_read = false; ag->prm = NULL; return ag; }
/*This function is the unaltered, traditional surface area accessible algorithm. Ryan Brenke altered accs to better account for protein-protein docking consideration. Dmitri Beglov apparently restored accs to its original form.*/ void accs1 (struct atomgrp* ag, int n_at, int* restat, double r_solv, short cont_acc, double* as) { const int NAC=800; /* max number of atoms in a cube */ /* integration increment */ const double P=0.01; int i, sint=sizeof(int), sdou=sizeof(double); int n_at1=ag->natoms; double xmin, xmax, ymin, ymax, zmin, zmax; double rmax=0; double pi=acos(-1.0); double pix2=2.0*pi; double ri, xi, yi, zi; for(i=0; i<n_at1; i++)as[i]=0.0; /* initialize boundary constants */ xmin=ag->atoms[restat[0]].X; xmax=xmin; ymin=ag->atoms[restat[0]].Y; ymax=ymin; zmin=ag->atoms[restat[0]].Z; zmax=zmin; /* allocate general atom related arrays */ i=n_at*sdou; float* x=(float*)_mol_malloc(i*sizeof(float)); float* y=(float*)_mol_malloc(i*sizeof(float)); float* z=(float*)_mol_malloc(i*sizeof(float)); float* r=(float*)_mol_malloc(i*sizeof(float)); float* r2=(float*)_mol_malloc(i*sizeof(float)); /* allocate arrays for neighbouring atoms */ float* dx=(float*)_mol_malloc(i*sizeof(float)); float* dy=(float*)_mol_malloc(i*sizeof(float)); float* d=(float*)_mol_malloc(i*sizeof(float)); float* dsq=(float*)_mol_malloc(i*sizeof(float)); float* arcif=(float*)_mol_malloc(2*2*i*sizeof(float)); i=n_at*sint; int* inov=(int*)_mol_malloc(i*sizeof(int)); /* calculate sizes and dimensions*/ for(i=0; i<n_at; i++) { ri=ag->atoms[restat[i]].rminh; ri=ri+r_solv; r[i]=ri; r2[i]=ri*ri; if(ri>rmax)rmax=ri; x[i]=ag->atoms[restat[i]].X; if(xmin>x[i])xmin=x[i]; if(xmax<x[i])xmax=x[i]; y[i]=ag->atoms[restat[i]].Y; if(ymin>y[i])ymin=y[i]; if(ymax<y[i])ymax=y[i]; z[i]=ag->atoms[restat[i]].Z; if(zmin>z[i])zmin=z[i]; if(zmax<z[i])zmax=z[i]; } double dmax=rmax*2; i=(xmax-xmin)/dmax+1; int idim=i<3?3:i; i=(ymax-ymin)/dmax+1; int jidim=i<3?3:i; jidim*=idim; i=(zmax-zmin)/dmax+1; int kjidim=i<3?3:i; kjidim*=jidim; /* total number of cubes */ /* map atoms to adjacent cubes */ /* allocate cubical arrays */ i=kjidim*sint; int* itab=(int*)_mol_malloc(i*sizeof(int)); /* number of atoms in each cube */ for(i=0; i<kjidim; i++)itab[i]=0; i=NAC*kjidim*sint; int* natm=(int*)_mol_malloc(i*sizeof(int)); /* atom index in each cube */ i=n_at*sint; int* cube=(int*)_mol_malloc(i*sizeof(int)); /* cube number for each atom */ int j, k, l, m, n, kji; for(l=0; l<n_at; l++) { i=(x[l]-xmin)/dmax; j=(y[l]-ymin)/dmax; k=(z[l]-zmin)/dmax; kji=k*jidim+j*idim+i; /* cube number */ n=itab[kji]+1; if(n>NAC) { printf("number of atoms in a cube %d is above the maximum NAC= %d\n", n, NAC); exit(EXIT_FAILURE); } itab[kji]=n; natm[kji*NAC+n-1]=l; cube[l]=kji; } int ir, io, in, mkji, nm, nzp, karc; double area, xr, yr, zr, rr, rrx2, rr2, b, zres, zgrid; double rsec2r, rsecr, rsec2n, rsecn; double calpha, alpha, beta, ti, tf, arcsum, parea, t, tt; /* main loop over atoms */ zi=1.0/P+0.5; nzp=zi; /* number of z planes */ for (ir=0; ir<n_at; ir++) { kji=cube[ir]; io=0; /* number of neighbouring atoms */ area=0.0; xr=x[ir]; yr=y[ir]; zr=z[ir]; rr=r[ir]; rrx2=rr*2; rr2=r2[ir]; /* loops over neighbouring cubes */ for (k=-1; k<2; k++) { for(j=-1; j<2; j++) { for(i=-1; i<2; i++) { mkji=kji+k*jidim+j*idim+i; if(mkji<0)continue; if(mkji>=kjidim)goto esc_cubes; nm=itab[mkji]; if(nm<1)continue; for(m=0; m<nm; m++) { in=natm[mkji*NAC+m]; if(in!=ir) { xi=xr-x[in]; yi=yr-y[in]; dx[io]=xi; dy[io]=yi; ri=xi*xi+yi*yi; dsq[io]=ri; d[io]=sqrtf(ri); inov[io]=in; io++; } } } } } esc_cubes: if(io!=0) { zres=rrx2/nzp; /* separation between planes */ zgrid=z[ir]-rr-zres/2.0; /* z level */ for(i=0; i<nzp; i++) { zgrid+=zres; /* radius of the circle intersection with a z-plane */ zi=zgrid-zr; rsec2r=rr2-zi*zi; rsecr=sqrtf(rsec2r); karc=0; for(j=0; j<io; j++) { in=inov[j]; /* radius of the circle for a neighbour */ zi=zgrid-z[in]; rsec2n=r2[in]-zi*zi; if(rsec2n<=0.0)continue; rsecn=sqrtf(rsec2n); /* are they close? */ if(d[j]>=rsecr+rsecn)continue; /* do they intersect? */ b=rsecr-rsecn; if(b<=0.0) { if(d[j]<=-b)goto next_plane; } else { if(d[j]<=b)continue; } /* yes, they do */ calpha=(dsq[j]+rsec2r-rsec2n)/(2.*d[j]*rsecr); if(calpha >= 1.0)continue; alpha=acosf(calpha); beta=atan2f(dy[j],dx[j])+pi; ti=beta-alpha; tf=beta+alpha; if(ti<0.0)ti+=pix2; if(tf>pix2)tf-=pix2; arcif[karc]=ti; if(tf<ti) { arcif[karc+1]=pix2; karc+=2; arcif[karc]=0.0; } arcif[karc+1]=tf; karc+=2; } /* find the atom accessible surface increment in z-plane */ karc/=2; if(karc==0) arcsum=pix2; else { qsort(arcif, karc, 2*sizeof(arcif[0]), accs_comp1); arcsum=arcif[0]; t=arcif[1]; if(karc>1) { for(k=2; k<karc*2; k+=2) { if(t<arcif[k])arcsum+=(arcif[k]-t); tt=arcif[k+1]; if(tt>t)t=tt; } } arcsum+=(pix2-t); } parea=arcsum*zres; area+=parea; next_plane:; } } else { area=pix2*rrx2; } ri=rr-r_solv; if(cont_acc) b=area*ri*ri/rr; else b=area*rr; as[restat[ir]]=b; } /* free all */ free(x); free(y); free(z); free(r); free(r2); free(dx); free(dy); free(d); free(dsq); free(arcif); free(inov); free(itab); free(natm); free(cube); }