108 #define MAX_INTERSECT 10000
111 #define MAX_INTERSECT_EXP 100
112 #define MAX_ATOM_IN_CUBE 100
115 #define FREE_ACCESS_STORAGE \
117 if(cube) free(cube); \
118 if(radii) free(radii); \
119 if(radiiSquared) free(radiiSquared); \
120 if(neighbours) free(neighbours); \
121 if(flag) free(flag); \
122 if(arci) free(arci); \
123 if(arcf) free(arcf); \
124 if(deltaX) free(deltaX); \
125 if(deltaY) free(deltaY); \
126 if(dist) free(dist); \
127 if(distSquared) free(distSquared); \
128 if(atomTable) free(atomTable); \
130 for(i=0;i<=maxAtomInCube;i++) \
131 { if(atomsInCube[i]) free(atomsInCube[i]); \
139 #define EXPAND_INTERSECT_ARRAYS \
140 do { int newMaxIntersect = (maxIntersect+MAX_INTERSECT_EXP), \
142 neighbours = (int *)realloc(neighbours, \
143 (newMaxIntersect+1)*sizeof(int)); \
144 flag = (int *)realloc(flag, (newMaxIntersect+1)*sizeof(int)); \
145 arci = (REAL *)realloc(arci, (newMaxIntersect+1)*sizeof(REAL)); \
146 arcf = (REAL *)realloc(arcf, (newMaxIntersect+1)*sizeof(REAL)); \
147 deltaX = (REAL *)realloc(deltaX, (newMaxIntersect+1)*sizeof(REAL)); \
148 deltaY = (REAL *)realloc(deltaY, (newMaxIntersect+1)*sizeof(REAL)); \
149 dist = (REAL *)realloc(dist, (newMaxIntersect+1)*sizeof(REAL)); \
150 distSquared = (REAL *)realloc(distSquared, \
151 (newMaxIntersect+1)*sizeof(REAL)); \
152 if(neighbours==NULL || flag==NULL || arci==NULL || arcf==NULL || \
153 deltaX==NULL || deltaY==NULL || dist==NULL || \
155 { FREE_ACCESS_STORAGE; \
158 for(iexpand=maxIntersect+1; iexpand<=newMaxIntersect; iexpand++) \
159 { neighbours[iexpand] = 0; \
161 arci[iexpand] = 0.0; \
162 arcf[iexpand] = 0.0; \
163 deltaX[iexpand] = 0.0; \
164 deltaY[iexpand] = 0.0; \
165 dist[iexpand] = 0.0; \
166 distSquared[iexpand] = 0.0; \
168 maxIntersect = newMaxIntersect; \
174 static void SortArcEndpoints(
REAL *a,
int n,
int *
flag);
175 static BOOL doCalcAccess(
int numAtoms,
REAL integrationAccuracy,
179 REAL *accessResults);
181 static RESRAD *GetResidueRadii(
RESRAD *resrad,
char *resnam);
182 static RESRAD *ReadRadiusFile(FILE *fpRad);
183 static REAL GetStandardAccess(
char *resnam,
RESRAD *resrad);
184 static REAL DefaultRadius(
char *element);
185 static void SetPDBAccess(
PDB *pdb,
REAL *accessArray);
186 static char *blGetElement(
PDB *p);
187 static REAL GetStandardAccessSC(
char *resnam,
RESRAD *resrad);
204 static char *blGetElement(
PDB *p)
210 strncpy(buffer,rawAtomName,2);
216 if(strlen(buffer_ptr) == 2 && isdigit(buffer[1]))
220 else if(strlen(buffer_ptr) == 2 && !isalpha(buffer[0]))
226 if(strlen(buffer_ptr) == 2 && rawAtomName[3] !=
' ' &&
227 (rawAtomName[0] ==
'H' || rawAtomName[0] ==
'C' ||
228 rawAtomName[0] ==
'N' || rawAtomName[0] ==
'O' ||
229 rawAtomName[0] ==
'P'))
231 if(!isalpha(rawAtomName[2]) || !isalpha(rawAtomName[3]))
264 char currentResnam[8];
268 resrad=ReadRadiusFile(fpRad);
270 strcpy(currentResnam,
" ");
276 if(strncmp(p->
resnam, currentResnam, 3))
278 strcpy(currentResnam, p->
resnam);
279 radii = GetResidueRadii(resrad,p->
resnam);
285 p->
radius = DefaultRadius(blGetElement(p));
289 for(i=0; i<radii->
natoms; i++)
303 p->
radius = DefaultRadius(blGetElement(p));
332 REAL integrationAccuracy,
REAL probeRadius,
333 BOOL doAccessibility)
354 if((accessArray=(
REAL *)malloc(natoms *
sizeof(
REAL)))
363 FillArrays(pdb, x, y, z, radii);
364 doCalcAccess(natoms, integrationAccuracy, probeRadius,
368 SetPDBAccess(pdb, accessArray);
379 if(radii!=
NULL) free(radii);
380 if(accessArray!=
NULL) free(accessArray);
432 static RESRAD *GetResidueRadii(
RESRAD *resrad,
char *resnam)
439 if(!strncmp(r->
resnam, resnam, 3))
465 static RESRAD *ReadRadiusFile(FILE *fpRad)
475 while(fgets(buffer,
MAXBUFF,fpRad))
477 if((chp=strchr(buffer,
'#'))!=
NULL)
502 sscanf(buffer,
"%s %d %lf %lf",
503 r->resnam, &(r->natoms),
504 &(r->stdAccess), &(r->stdAccessSC));
505 atomCount = r->natoms;
510 strncpy(r->atnam[atomIndex],buffer,5);
511 r->atnam[atomIndex][5] =
'\0';
513 if(r->atnam[atomIndex][0] ==
' ')
516 r->atnam[atomIndex][i] = r->atnam[atomIndex][i+1];
522 sscanf(buffer,
"%s %lf",junk,&(r->radius[atomIndex]));
545 static REAL GetStandardAccess(
char *resnam,
RESRAD *resrad)
552 if(!strncmp(r->
resnam, resnam, 3))
575 static REAL GetStandardAccessSC(
char *resnam,
RESRAD *resrad)
582 if(!strncmp(r->
resnam, resnam, 3))
603 static REAL DefaultRadius(
char *element)
605 if(!strcmp(element,
"C"))
607 else if(!strcmp(element,
"N"))
609 else if(!strcmp(element,
"S"))
611 else if(!strcmp(element,
"O"))
613 else if(!strcmp(element,
"P"))
615 else if(!strcmp(element,
"CA"))
617 else if(!strcmp(element,
"FE"))
619 else if(!strcmp(element,
"CU"))
621 else if(!strcmp(element,
"ZN"))
623 else if(!strcmp(element,
"MG"))
641 static void SetPDBAccess(
PDB *pdb,
REAL *accessArray)
648 p->
access = accessArray[i++];
675 PDB *start, *stop, *p;
686 for(start=pdb; start!=
NULL; start=stop)
691 resAccess = (
REAL)0.0;
692 scAccess = (
REAL)0.0;
693 for(p=start; p!=stop;
NEXT(p))
696 if(strncmp(p->
atnam,
"N ", 4) &&
697 strncmp(p->
atnam,
"CA ", 4) &&
698 strncmp(p->
atnam,
"C ", 4) &&
699 strncmp(p->
atnam,
"O ", 4) &&
700 strncmp(p->
atnam,
"OXT ", 4))
709 stdAccess = GetStandardAccess(start->
resnam, resrad);
710 stdAccessSC = GetStandardAccessSC(start->
resnam, resrad);
715 relAccess = 100.0 * resAccess / stdAccess;
720 scRelAccess = 100.0 * scAccess / stdAccessSC;
739 strcpy(r->resnam, start->
resnam);
740 strcpy(r->insert, start->
insert);
741 strcpy(r->chain, start->
chain);
742 r->resnum = start->
resnum;
743 r->resAccess = resAccess;
744 r->relAccess = relAccess;
745 r->scAccess = scAccess;
746 r->scRelAccess = scRelAccess;
766 static void SortArcEndpoints(
REAL *endpoints,
int nEndpoints,
int *
flag)
768 int tmpFlagVal, midpoint,
772 REAL tmpEndpointVal, tmpEndpointVal2;
774 for(i=1; i<=nEndpoints; i++)
788 tmpEndpointVal=endpoints[midpoint];
790 if(endpoints[i] > tmpEndpointVal)
792 endpoints[midpoint]= endpoints[i];
793 endpoints[i]=tmpEndpointVal;
794 tmpEndpointVal=endpoints[midpoint];
795 tmpFlagVal=flag[midpoint];
796 flag[midpoint]=flag[i];
802 if(endpoints[j] < tmpEndpointVal)
804 endpoints[midpoint]=endpoints[j];
805 endpoints[j]=tmpEndpointVal;
806 tmpEndpointVal=endpoints[midpoint];
807 tmpFlagVal=flag[midpoint];
808 flag[midpoint]=flag[j];
811 if(endpoints[i] > tmpEndpointVal)
813 endpoints[midpoint]=endpoints[i];
814 endpoints[i]=tmpEndpointVal;
815 tmpEndpointVal=endpoints[midpoint];
816 tmpFlagVal=flag[midpoint];
817 flag[midpoint]=flag[i];
823 endpoints[l]=endpoints[k];
824 endpoints[k]=tmpEndpointVal2;
836 }
while((l>0) && (endpoints[l] > tmpEndpointVal));
837 tmpEndpointVal2=endpoints[l];
842 }
while((k<=nEndpoints) && (endpoints[k] < tmpEndpointVal));
844 if(k<=l)
goto jump30;
872 if(j-i>=1)
goto jump10;
881 tmpEndpointVal=endpoints[i+1];
882 if(endpoints[i]<=tmpEndpointVal)
goto jump90;
884 tmpFlagVal=flag[i+1];
889 endpoints[k+1]=endpoints[k];
892 }
while(tmpEndpointVal < endpoints[k]);
894 endpoints[k+1]=tmpEndpointVal;
895 flag[k+1]=tmpFlagVal;
927 static BOOL doCalcAccess(
int numAtoms,
REAL integrationAccuracy,
937 **atomsInCube =
NULL;
943 int i, j, k, l, m, n,
945 cubeAtom, io, keyAtom,
947 nzp, karc, idim, jidim, kjidim,
958 twoPi = 2.0*acos(-1.0),
959 maxRadius, totalArea, tmpArea,
962 radius, radiusX2, radiusSquared,
973 int maxAtomsSeenInCube = 0,
974 maxIntersectsSeen = 0;
983 cube = (
int *)malloc((numAtoms+1)*
sizeof(int));
984 radii = (
REAL *)malloc((numAtoms+1)*
sizeof(
REAL));
985 radiiSquared = (
REAL *)malloc((numAtoms+1)*
sizeof(
REAL));
1000 radiiSquared ==
NULL ||
1001 neighbours ==
NULL ||
1008 distSquared ==
NULL)
1016 for(i=1; i<=numAtoms; i++)
1018 radii[i] = atomRadii[i] + probeRadius;
1019 radiiSquared[i] = radii[i] * radii[i];
1020 accessResults[i] = 0.0;
1022 if(radii[i] > maxRadius) maxRadius=radii[i];
1023 if(x[i] < xmin) xmin=x[i];
1025 if(z[i] < zmin) zmin=z[i];
1026 if(x[i] > xmax) xmax=x[i];
1027 if(y[i] > ymax) ymax=y[i];
1028 if(z[i] > zmax) zmax=z[i];
1035 idim = (xmax-
xmin)/maxRadius + 1.0;
1036 if(idim < 3) idim = 3;
1038 jidim = (ymax-
ymin)/maxRadius + 1.0;
1039 if(jidim < 3) jidim = 3;
1042 kjidim = (zmax-zmin)/maxRadius + 1.0;
1043 if(kjidim < 3) kjidim = 3;
1047 fprintf(stderr,
"Number of cubes: %d\n", kjidim);
1063 if((atomsInCube[i] = (
int *)malloc((kjidim+1)*
sizeof(
int)))==
NULL)
1076 if((atomTable = (
int *)malloc((kjidim+1)*
sizeof(
int)))==
NULL)
1081 for(l=1; l<=kjidim; l++)
1084 for(l=1; l<=numAtoms; l++)
1086 i = (x[l]-
xmin)/maxRadius + 1.0;
1087 j = (y[l]-
ymin)/maxRadius;
1088 k = (z[l]-zmin)/maxRadius;
1090 cubeIndex = k*jidim + j*idim + i;
1091 n = atomTable[cubeIndex] + 1;
1094 if(n > maxAtomsSeenInCube)
1095 maxAtomsSeenInCube = n;
1101 if(n > maxAtomInCube)
1106 if((atomsInCube = (
int **)realloc(atomsInCube,
1107 (newMaxAtomInCube+1)*
sizeof(
int *)))
1114 for(iexpand=maxAtomInCube+1;
1115 iexpand<=newMaxAtomInCube;
1119 if((atomsInCube[iexpand] =
1120 (
int *)malloc((kjidim+1) *
sizeof(
int)))
1128 maxAtomInCube = newMaxAtomInCube;
1131 atomTable[cubeIndex] = n;
1132 atomsInCube[n][cubeIndex] = l;
1133 cube[l] = cubeIndex;
1137 fprintf(stderr,
"Max number of atoms in a cube: %d\n",
1138 maxAtomsSeenInCube);
1146 for(keyAtom=1; keyAtom<=numAtoms; keyAtom++)
1148 cubeIndex = cube[keyAtom];
1154 radius = radii[keyAtom];
1155 radiusX2 = radius*2.0;
1156 radiusSquared = radiiSquared[keyAtom];
1159 for(kk=1; kk<=3; kk++)
1163 for(jj=1; jj<=3; jj++)
1169 mkji = cubeIndex + k*jidim + j*idim + i - 2;
1179 nm = atomTable[mkji];
1186 for(m=1; m<=nm; m++)
1188 cubeAtom = atomsInCube[m][mkji];
1189 if(cubeAtom != keyAtom)
1193 if(io > maxIntersectsSeen)
1194 maxIntersectsSeen = io;
1196 if(io > maxIntersect)
1201 deltaX[io] = xr - x[cubeAtom];
1202 deltaY[io] = yr - y[cubeAtom];
1204 distSquared[io] = deltaX[io]*deltaX[io] +
1205 deltaY[io]*deltaY[io];
1206 dist[io] = sqrt(distSquared[io]);
1207 neighbours[io] = cubeAtom;
1218 totalArea = twoPi * radiusX2;
1223 nzp = 1.0/integrationAccuracy + 0.5;
1224 zres = radiusX2 / nzp;
1225 zgrid = z[keyAtom] - radius - zres/2.0;
1230 for(i=1; i<=nzp; i++)
1237 rsec2r = radiusSquared - (zgrid-zr)*(zgrid-zr);
1238 rsecr = sqrt(rsec2r);
1240 for(k=1; k<=maxIntersect; k++)
1245 for(j=1; j<=io; j++)
1247 cubeAtom = neighbours[j];
1250 rsec2n = radiiSquared[cubeAtom] -
1251 (zgrid-z[cubeAtom])*(zgrid-z[cubeAtom]);
1255 rsecn = sqrt(rsec2n);
1260 if(dist[j] < (rsecr+rsecn))
1267 intersect = rsecr - rsecn;
1270 if(dist[j] <= fabs(intersect))
1272 if(intersect <= 0.0)
1281 if(++karc >= maxIntersect)
1286 if(karc > maxIntersectsSeen)
1287 maxIntersectsSeen = karc;
1305 alpha = acos((distSquared[j] + rsec2r - rsec2n) /
1306 (2.0 * dist[j] * rsecr));
1312 beta = atan2(deltaY[j], deltaX[j]) + pi;
1360 SortArcEndpoints(arci, karc, flag);
1368 for(k=2; k<=karc; k++)
1372 arcsum += (arci[k]-t);
1383 arcsum += (twoPi-t);
1390 partialArea = arcsum * zres;
1393 totalArea += partialArea;
1399 tmpArea = totalArea * (radius-probeRadius) * (radius-probeRadius) /
1407 tmpArea *= (radius*radius) /
1408 ((radius-probeRadius) * (radius-probeRadius));
1411 accessResults[keyAtom] = tmpArea;
1415 fprintf(stderr,
"Maximum intersects: %d\n",maxIntersectsSeen);
Include file for PDB routines.
BOOL blCalcAccess(PDB *pdb, int natoms, REAL integrationAccuracy, REAL probeRadius, BOOL doAccessibility)
#define ACCESS_DEF_INTACC
#define EXPAND_INTERSECT_ARRAYS
RESACCESS * blCalcResAccess(PDB *pdb, RESRAD *resrad)
#define FREE_ACCESS_STORAGE
REAL radius[ACCESS_MAX_ATOMS_PER_RESIDUE]
#define KILLLEADSPACES(y, x)
System-type variable type definitions.
PDB * blFindNextResidue(PDB *pdb)
char chain[blMAXCHAINLABEL]
char atnam[ACCESS_MAX_ATOMS_PER_RESIDUE][8]
Accessibility calculation code.
RESRAD * blSetAtomRadii(PDB *pdb, FILE *fpRad)