/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** ** ** ** ** ** ** ** ** ** ********* ** ** ** ********** ********** *** *** ** ** ** ********** ** **** **** ** ********** ** ** ** ** ** ** ** ** ** ********** ** ** ** ******** ** ** ** ** ** ** ** ** ****** ******** ** ** ** ** ** ** ** ****** *** ** ** ** ************** ** ** ** *** ** ********** ** ************** ** ** ** *** ***************** ******** ** ** ** *********** ********* ** ********* ** ** ** *********** ** ** ** *** ** ********** ** ** ** ** ** ****** ** ** ********** ** ** ** ** ** ****** ******** ** ** ** * ** ** ********* ** ** ** * ** ** ** ** ** ** ** *** ********** ** ** ** ** ** *** ********** ********** ** ** ********* ** ** ** ** ** ** E N S E M B L E T O O L S ** ** ** ** Version 2.1 ** ** ** ** ** ** Principal Investigator: Julie D. Forman-Kay ** ** ** ** Author: Mickaƫl Krzeminski ** ** ** ** Date: November 2012 ** ** ** ** ** ************************************************************************************* ** ** ** ** ** Copyright (C) The Hospital for Sick Children, 2001 ** ** ** ** Distribution of substantively modified versions of this module is prohibited ** ** without the explicit permission of the copyright holder. ** ** ** ** Any use of this work or derivative works in whole or in part for any ** ** commercial purpose or for monetary gain is prohibited. ** ** ** ** ** ** NO WARRANTY ** ** This software package is provided 'as is' without warranty of any kind, ** ** expressed or implied. ** ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __ACCESSURF_HEADER__ #define __ACCESSURF_HEADER__ counter errors; void _cleanAS(PDBListData *ENSData, accessSurf *access, char *PDBFileName, char *outFileName, char *FFName) { // This functions releases the memory affected in the main function _cleanPDB(ENSData); if (access != NULL) { free((*access).as); (*access).as = NULL; } free(PDBFileName); free(outFileName); free(FFName); } void _cleanh(int ict, unsigned int *tag, unsigned int *tag1, int *kn, int *inz, double *zlb, double *zub, double *rad, double *rad1, double *xr1, double *yr1, double *zr1,\ double *rsec, double *rsec2, double *area, double **arci, double **arcf, protein pdb, typerad *radia) { // This functions releases the memory affected in the heading function getAccSurf counter count; free(tag); free(tag1); free(kn); free(inz); free(zlb); free(zub); free(rad); free(rad1); free(xr1); free(yr1); free(zr1); free(area); //free(access); free(rsec); free(rsec2); free(radia); for (count=0; count piex2) tf -= piex2; if (tf < 0.) tf += piex2; if (tf < ti) { arcf[k1+1][m] = tf; arcf[k1][m] = piex2; ++kn[m]; } else { arcf[k1][m] = tf; } arci[k1][m] = ti; } void getColumn(double **origin, double *desti, unsigned int column, unsigned int length) { counter i; for (i=0; i ict-1) continue; if (k1 == -1) { arcsum = piex2; } else { // The arc endpoints are sorted on the value of the initial arc endpoint k11 = k1 + 1; if ((colArci = realloc(colArci, k11 * DOUBLE_SIZE)) == NULL) return 1; getColumn(arci, colArci, (*n), k11); sortag(colArci, tag, k11); setColumn(colArci, arci, (*n), k11); // Calculate the accessible area arcsum = arci[0][(*n)]; jj = tag[0]; t = arcf[jj][(*n)]; if (k1 != 0) { for (k=1; k t) { t = arcf[m][(*n)]; } } } } arcsum += piex2 - t; } a = zr1[(*n)] - zgrid; a = rad1[(*n)] - fabs(a); // The area is equal to the accessible arc length times the section thickness, // corrected if it is the first or last section, times the radius of the sphere parea = arcsum * (hzres + min(a, hzres)) * rad1[(*n)]; // Add the accessible area for this atom in this section to the area // for this atom for all the section encountered thus far area[(*n)] += parea; } free(colArci); // If this was the final atom for the z section return if (itab > 0) return 0; // The arci and arcf arrays were filled, does significant area remain ? if (parea <= cutoff) { kn[(*n)] = 9999; ++(*icnt1); return 0; } // Removing degeneracies from arci and arcf (Combine overlapping arcs) jj = tag[0]; t = arcf[jj][(*n)]; i = 0; for (k=1; k t) { t = arcf[m][(*n)]; } } } arcf[i][(*n)] = t; kn[(*n)] = i; ++i; for (k=i; k32 && uc<127) break; // Any character found } if (uc<48 || (uc>57 && uc<65) || uc>91) continue; // Ignoring empty lines or lines starting with non-letter character for (j=0; j<7 && ((uc>47 && uc<58) || (uc>64 && uc<91)); j++) { atypeElement[j] = uc; ++i; uc = toupper(atypeFileLine[i]); } atypeElement[j] = '\0'; if (! strcmp(atypeElement, "RESIDUE")) // New residue found { if (endok == False) { error_msg("The keyword 'END' was not found!\n", NULL); _cleanh(ict, tag, tag1, kn, inz, zlb, zub, rad, rad1, xr1, yr1, zr1, rsec, rsec2, area, arci, arcf, pdb, radia); return access; } if (pdb.nbResidues == maxNbResidues) { maxNbResidues += 20; if ((pdb.resAtoms = realloc(pdb.resAtoms, maxNbResidues*sizeof(residue))) == NULL) { _showError("pdb.residues"); _cleanh(ict, tag, tag1, kn, inz, zlb, zub, rad, rad1, xr1, yr1, zr1, rsec, rsec2, area, arci, arcf, pdb, radia); return access; } } while (uc<65 || uc>90) // Reading until finding the residue name { ++i; uc = toupper(atypeFileLine[i]); } for (j=0; j<3; j++) { pdb.resAtoms[pdb.nbResidues].resn[j] = uc; ++i; uc = toupper(atypeFileLine[i]); } pdb.resAtoms[pdb.nbResidues].resn[j] = '\0'; // Checking whether the residue name has not already been defined for (j=0; j 4) { error("The name of an atom must not be longer that 4 characters!", NULL); _cleanh(ict, tag, tag1, kn, inz, zlb, zub, rad, rad1, xr1, yr1, zr1, rsec, rsec2, area, arci, arcf, pdb, radia); return access; } strncpy(pdb.resAtoms[pdb.nbResidues].names[pdb.resAtoms[pdb.nbResidues].nbAtoms], atypeElement, 4); pdb.resAtoms[pdb.nbResidues].names[pdb.resAtoms[pdb.nbResidues].nbAtoms][4] = '\0'; while (uc<48 || (uc>57 && uc<65) || uc>90) // Reading until finding the atom type { ++i; uc = toupper(atypeFileLine[i]); } for (j=0; j<4 && ((uc>47 && uc<58) || (uc>64 && uc<91) || uc==95); j++) { pdb.resAtoms[pdb.nbResidues].types[pdb.resAtoms[pdb.nbResidues].nbAtoms][j] = uc; ++i; uc = toupper(atypeFileLine[i]); } pdb.resAtoms[pdb.nbResidues].types[pdb.resAtoms[pdb.nbResidues].nbAtoms][j] = '\0'; if (uc>32 && uc<127) { error("The name of an atom type must not be longer that 4 characters!", NULL); _cleanh(ict, tag, tag1, kn, inz, zlb, zub, rad, rad1, xr1, yr1, zr1, rsec, rsec2, area, arci, arcf, pdb, radia); return access; } ++pdb.resAtoms[pdb.nbResidues].nbAtoms; } } fclose(atypeFile); if ((atypeFile = fopen("ensigmatom.dat", "rt")) == NULL) { error("NO_FILE", "ensatom.types"); _cleanh(ict, tag, tag1, kn, inz, zlb, zub, rad, rad1, xr1, yr1, zr1, rsec, rsec2, area, arci, arcf, pdb, radia); return access; } while (fgets(atypeFileLine, ATYPE_LINE_LEN, atypeFile) != NULL) { uc = 0; for (i=0; i32 && uc<127) break; // Any character found } if (uc<48 || (uc>57 && uc<65) || uc>91) continue; // Ignoring empty lines or lines starting with non-letter character for (j=0; j<4 && ((uc>47 && uc<58) || (uc>64 && uc<91) || uc==95); j++) { atypeElement[j] = uc; ++i; uc = toupper(atypeFileLine[i]); } atypeElement[j] = '\0'; if (! strcmp(atypeElement, "FFNA")) // Forcefield list { if (ffok == True) continue; // Ignoring other occurences of force field specification while (uc>64 && uc<91) // Finishing reading the FFNAME keyword { ++i; uc = toupper(atypeFileLine[i]); } while (1) // Detection of the forcefield column { while (uc<33 || uc>126) // Reading until finding the first character { ++i; uc = toupper(atypeFileLine[i]); if (uc==10 || uc==13) { error("The specified forcefield was not found in the sigma value file!", NULL); _cleanh(ict, tag, tag1, kn, inz, zlb, zub, rad, rad1, xr1, yr1, zr1, rsec, rsec2, area, arci, arcf, pdb, radia); return access; } } ucseek = 0; while (uc>32 && uc<127) // Retrieving the forcefield name { ff[ucseek] = uc; ++i; ++ucseek; uc = toupper(atypeFileLine[i]); } ff[ucseek] = '\0'; if (! strcmp(ff, FFName)) { ffok = True; break; } ++ffCol; } } else { if (ffok == False) { error("No specified forcefield in the sigma value file!", NULL); _cleanh(ict, tag, tag1, kn, inz, zlb, zub, rad, rad1, xr1, yr1, zr1, rsec, rsec2, area, arci, arcf, pdb, radia); return access; } strncpy(radia[nbTypeRad].type, atypeElement, 5); if (uc>32 && uc<127) { error("The name of an atom type must not be longer that 4 characters!", NULL); _cleanh(ict, tag, tag1, kn, inz, zlb, zub, rad, rad1, xr1, yr1, zr1, rsec, rsec2, area, arci, arcf, pdb, radia); return access; } for (j=1; j57) // Reading until finding a value { ++i; uc = toupper(atypeFileLine[i]); } if (j==1) // Recording the default value { ucseek = 0; while (uc>45 && uc<58) { valchar[ucseek] = atypeFileLine[i]; ++i; ++ucseek; uc = atypeFileLine[i]; } valchar[ucseek] = '\0'; if (valchar[0] != '/') { radia[nbTypeRad].radius = atof(valchar); } else { radia[nbTypeRad].radius = 0.; } } else { while (uc>45 && uc<58) { ++i; uc = atypeFileLine[i]; } } } while (uc<46 || uc>57) // Reading until finding a value { ++i; uc = toupper(atypeFileLine[i]); } ucseek = 0; while (uc>45 && uc<58) { valchar[ucseek] = atypeFileLine[i]; ++i; ++ucseek; uc = atypeFileLine[i]; } valchar[ucseek] = '\0'; if (valchar[0] != '/') { radia[nbTypeRad].radius = atof(valchar); ++nbTypeRad; } else if (radia[nbTypeRad].radius > dEpsilon) { ++nbTypeRad; } } } fclose(atypeFile); // Now attributing the radius to each atom of the molecule char name[5] = {'\0'}; char resn[4] = {'\0'}; char resi[5] = {'\0'}; for (i=0; i= 0) // Testing whether the residue contains termini atoms { for (k=0; k zubmax) zubmax = zub[i]; area[i] = 0.; } // Z resolution determined hzres = (rmin + rh2o) * accuracy; access.zres = 2. * hzres; cutoff = access.zres / 100.; iano = 0; // Index of atoms in tables j1 = 0; iflag = 0; znext = access.zres; access.zsecnb = zubmax / access.zres; access.icnt1 = 0; access.icnt2 = 0; // Section atom spheres perpendicular to the z axis for (i=0; i zgrid) { if (zlb[j] >= zgrid) break; kn[j] = -1; for (k=0; k znext) { iflag = 1; } else { ++j1; } } iano = j1; iflag = 0; // Zero, one and more circles on section require different processing if (itab < 1) continue; if (itab != 1) { //j3 = itab - 1; // Find intersections of circles in section calarc called to find // initial and final angles of intersection of circles. If arci and // arcf arrays are filled, reduce is called. // The current first index of these arrays for the atom indicated by // the second index is stored in the array kn. If kn for any atom is // 10000, then no area remains accessible for that atom on this section // or the atom is not of interest (knset=1) for (j=0; j=a) continue; dy = yr1[m] - yr1[l]; if (fabs(dy)>=a) continue; d2 = dx * dx + dy * dy; d = sqrt(d2); if (d>=a) continue; if (kn[l] >= ict1-1 && kn[l] < ict) { reduce(&l, 0, ict, arci, arcf, tag, tag1, zr1, rad1, area, inz, kn, &access.icnt1, &access.icnt2, ict1, access.zres, rh2o, zgrid , hzres, cutoff); } ++kn[l]; if (kn[m] >= ict1-1 && kn[m] < ict) { reduce(&m, 0, ict, arci, arcf, tag, tag1, zr1, rad1, area, inz, kn, &access.icnt1, &access.icnt2, ict1, access.zres, rh2o, zgrid , hzres, cutoff); } ++kn[m]; // Do the circles intersect, or is one completely inside the other ? b = rsec[m] - rsec[l]; if (d > fabs(b)) { q = rsec2[m] - rsec2[l]; d *= 2.; if (kn[m] <= ict1) calarc(m, 1, d2, q, d, rsec, arci, arcf, kn, dy, dx); if (kn[l] <= ict1) calarc(l, -1, d2, q, d, rsec, arci, arcf, kn, dy, dx); } else if (b > 0.) { kn[l] = 9999; --kn[m]; } else { kn[m] = 9999; --kn[l]; } } } } // Find the accessible contact surface area for all spheres intersecting this section reduce(&idum, itab, ict, arci, arcf, tag, tag1, zr1, rad1, area, inz, kn, &access.icnt1, &access.icnt2, ict1, access.zres, rh2o, zgrid , hzres, cutoff); } // Output operation parameters if (mode == 'A') { for (i=0; i