⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protein.c

📁 药物开发中的基于结构的从头设计代码
💻 C
字号:
# include "pocket.h"

Protein::Protein()
{
	num_res=0;

	res=new Residue[50];
	if(res==NULL) Memory_Allocation_Error();

	num_atom=0;

	atom=new Patom[10000];
	if(atom==NULL) Memory_Allocation_Error();

	num_pocket_res=0;
	
	pocket_res=new Pocket_res[50];
	if(pocket_res==NULL) Memory_Allocation_Error();
	
}

Protein::~Protein()
{
	delete [] res;
	delete [] atom;
	delete [] pocket_res;
}

void Protein::Read_RESIDUE(char *dirname)
{
	FILE *fp;
	int i,j,num;
	char buf[160],head[6],filename[160];

	strcpy(filename,dirname); strcat(filename,"RESIDUE");
	if((fp=fopen(filename,"r"))==NULL) Openning_File_Error(filename);

	i=0;
	for(;;)
		{
		 if(fgets(buf,160,fp)==NULL) break;
		 else if(Blank_Line_Check(buf)==TRUE) continue;
		 else if(buf[0]=='#') continue;
		 
		 sscanf(buf,"%s",head);

		 if(!strcmp(head,"END")) break;
		 else if(!strcmp(head,"RESI"))
			{
			 num=0;
			 sscanf(buf,"%*s%s%d",res[i].name,&num);
			 res[i].num_atom=num;

			 for(j=0;j<num;j++)
				{
				 fgets(buf,160,fp);
				 sscanf(buf,"%s",head);
				 if(strcmp(head,"ATOM")) continue;
				 sscanf(buf,"%*s%s%*s%f%s%f%f%s",
					res[i].atom[j].name,
				       &res[i].atom[j].logp,
					res[i].atom[j].hb,
                                       &res[i].atom[j].q,
				       &res[i].atom[j].r,
					res[i].atom[j].type);
				}
			 i++;
			}
		}

	fclose(fp);

	num_res=i;

	return;
}

void Protein::Show_RESIDUE() const
{
	int i,j;

	printf("The number of residue templates is: %d\n",num_res);

	for(i=0;i<num_res;i++)
		{
		 printf("Residue\t%3s\t%d\n",res[i].name,res[i].num_atom);
		 for(j=0;j<res[i].num_atom;j++)
			{
			 printf("ATOM %8s %6.3f %4s %6.3f %6.3f %8s\n",
				res[i].atom[j].name,
				res[i].atom[j].logp,
				res[i].atom[j].hb,
				res[i].atom[j].q,
				res[i].atom[j].r,
				res[i].atom[j].type);
			}
		 printf("\n");
		}

	return;
}

void Protein::Read_PDB(char *filename)
{
	int i,j,num;
	FILE *fp;
	char buf[160],head[10],name[10];

	// Now read the information of receptor atoms from the PDB file 

	if((fp=fopen(filename,"r"))==NULL) Openning_File_Error(filename);

	num=0;

	for(;;)
		{
		 if(fgets(buf,160,fp)==NULL) break;

		 sscanf(buf,"%s",head);

		 if(!strcmp(head,"END")) break;
		 else if(!strcmp(head,"ATOM"))
			{
			 // Get the atom name and erase that section 
			 i=0;
			 for(j=12;j<17;j++)
				{
				 if(buf[j]==' ') continue;
				 else {name[i]=buf[j]; buf[j]=' ';i++;}
				}
			 name[i]='\0'; 

			 // Skip lone pairs and hydrogens  
			 if(name[0]=='L'&&name[1]=='P') continue;
			 else if(name[0]=='H') continue;
			 else if((name[0]=='1'||name[0]=='2'||name[0]=='3')
				 &&name[1]=='H') continue;

			 strcpy(atom[num].name,name);

			 // Get the chain label and erase that section 
			 if(buf[21]!=' ') 
                                {
                                 atom[num].chain=buf[21]; 
				 buf[21]=' ';
                                }
			 else atom[num].chain='A';	// default

			 sscanf(buf,"%*s%d%s%s%f%f%f",
				&atom[num].atom_id,
				 atom[num].residue,
				 atom[num].res_id,
				&atom[num].coor[0],
				&atom[num].coor[1],
				&atom[num].coor[2]);
			 atom[num].valid=1;
			 num++;
			}
		 else if(!strcmp(head,"HETATM"))
			{
			 sscanf(buf,"%*s%*d%s",head);

			 // skip hydrogens
			 if(head[0]=='H') continue; 
			 else if(head[0]=='1') continue;
			 else if(head[0]=='2') continue;
			 else if(head[0]=='3') continue;

			 strcpy(atom[num].residue,"HET");

			 buf[21]=' ';	// erase the chain label

			 sscanf(buf,"%*s%d%s%*s%s%f%f%f",
				&atom[num].atom_id,
				 atom[num].name,
				 atom[num].res_id,
				&atom[num].coor[0],
				&atom[num].coor[1],
				&atom[num].coor[2]);
			 atom[num].valid=1;
			 num++;
			}
		 else continue;
		}

	fclose(fp);

	num_atom=num;

	if(num_atom==0) PDB_Format_Error(filename);

	return;
}

void Protein::Show_PDB() const
{
	int i;

	printf("Total number of atoms in the receptor is %d\n",num_atom);

	for(i=0;i<num_atom;i++)
		{
		 if(atom[i].valid==0) continue;
		 printf("ATOM %5d %4s %3s %c %5s ",
			atom[i].atom_id, 
			atom[i].name,
			atom[i].residue, 
			atom[i].chain, 
			atom[i].res_id); 
		 printf("%7.2f %7.2f %7.2f\n",
			atom[i].coor[0], 
			atom[i].coor[1], 
			atom[i].coor[2]); 
		}

	return;
}

void Protein::Value_Atom()
{
	int i,j;
	int mark,tmp;

	for(i=0;i<num_atom;i++)
	{
	 // First, check the atom to see whether it has a legal residue

	 mark=FALSE;
	 for(j=0;j<num_res;j++)
		{
		 if(strcmp(atom[i].residue,res[j].name)) continue;
		 mark=TRUE; break;
		}

	 if(mark==FALSE)
		{
		 printf("Warning: cannot find parameter for the protein atom %d %s %s\n",
			atom[i].atom_id, atom[i].name, atom[i].residue);
		 printf("This atom is skipped.\n");
		 atom[i].valid=0; continue;
		}
	 else tmp=j;

	// Second, check the atom in the specific residue

	 mark=FALSE;
	 for(j=0;j<res[tmp].num_atom;j++)
		{
		 if(strcmp(atom[i].name,res[tmp].atom[j].name)) continue;
		 else
			{
			 strcpy(atom[i].type,res[tmp].atom[j].type);
			 atom[i].r=res[tmp].atom[j].r;
			 atom[i].q=res[tmp].atom[j].q;
			 atom[i].logp=res[tmp].atom[j].logp;
			 strcpy(atom[i].hb,res[tmp].atom[j].hb);
			 atom[i].valid=1;
			 mark=TRUE; break; 
			}
		}

	 if(mark==FALSE)
		{
		 printf("Warning: cannot find parameter for the protein atom %d %s %s\n",
                       	atom[i].atom_id,atom[i].name,atom[i].residue);
                 printf("This atom is skipped.\n");
                 atom[i].valid=0;
		}
	}

	// again, skip the hydrogens

	for(i=0;i<num_atom;i++)
		{
		 if(!strcmp(atom[i].type,"H")) atom[i].valid=0;
		}
	
	return;
}

void Protein::Cal_HB_Root()
{
	int i,j;
	int num;
	float tmpx,tmpy,tmpz,tmp,cutoff;
	int neib[50];

	for(i=0;i<num_atom;i++)
		{
		 if(atom[i].valid<=0) continue;
		 else if(!strcmp(atom[i].hb,"N")) continue;
		 else if(!strcmp(atom[i].hb,"M")) cutoff=9.00; // metal
		 else if(!strcmp(atom[i].type,"O.w")) cutoff=12.50; // water
		 else cutoff=4.00; // normal

		 for(j=0;j<50;j++) neib[j]=0;

		 num=0;

		 for(j=0;j<num_atom;j++)
			{
			 if(j==i) continue;
			 else if(atom[j].valid<=0) continue;

			 tmp=Distance2(atom[i].coor,atom[j].coor);

			 if(tmp>cutoff) continue;
			 else {neib[num]=j; num++;}
			}

		 if(num==0) atom[i].valid=0;	// no neighbor!
		 else
			{
			 tmpx=tmpy=tmpz=0.000;
			 for(j=0;j<num;j++)
			{
			 tmpx+=(atom[neib[j]].coor[0]/num);
			 tmpy+=(atom[neib[j]].coor[1]/num);
			 tmpz+=(atom[neib[j]].coor[2]/num);
			}
			 atom[i].root[0]=tmpx;
			 atom[i].root[1]=tmpy;
			 atom[i].root[2]=tmpz;
			}
		}

	return;
}

void Protein::Check_Metal()
{
	int i,j;
	float d=0.000;

/* For any protein atom within a certain range around a metal ion,
   its charge and HB capacity are switched off */

	for(i=0;i<num_atom;i++)
		{
		 if(atom[i].valid<=0) continue;
		 else if(strcmp(atom[i].hb,"M")) continue;
/*
		 printf("Find metal %d %s %8.3f %8.3f %8.3f\n",
			 atom[i].atom_id,
			 atom[i].name,
			 atom[i].coor[0],
			 atom[i].coor[1],
			 atom[i].coor[2]);
*/
                 for(j=0;j<num_atom;j++)
                        {
                         if(i==j) continue;
                         else if(atom[j].valid<=0) continue;
			 else if(!strcmp(atom[j].hb,"N")) continue;
			 else if(!strcmp(atom[j].hb,"M")) continue;

                         d=Distance2(atom[i].coor,atom[j].coor);

			 if(d<9.00)	// d<3.00A 
				{
				 strcpy(atom[j].hb,"N");
				 atom[j].q=0.000;
				}
                        }
                }

        return;
}

void Protein::Check_Water()
{
	int i,j;
	int count,contact;
	float d;

	count=0;

	for(i=0;i<num_atom;i++)
		{
		 if(atom[i].valid<=0) continue;
		 else if(strcmp(atom[i].type,"O.w")) continue;

		 contact=0;

		 for(j=0;j<num_atom;j++)
			{
			 if(i==j) continue;
			 else if(atom[j].valid<=0) continue;
			 else if(!strcmp(atom[j].type,"O.w")) continue;
	 
			 d=Distance2(atom[i].coor,atom[j].coor);

			 if(d<16.00) contact++;	// d<4.00A
			}
		
		 if(contact<=1) {atom[i].valid=0;continue;}
		 else {atom[i].valid=1; count++; continue;}
		}

	// printf("Totally %d water are reserved in the protein.\n", count);

	return;
}

void Protein::Show_Atom() const
{
	int i;

	printf("\nTotal number of atoms in the protein is %d\n",num_atom);

        for(i=0;i<num_atom;i++)
                {
                 printf("%5d ", atom[i].atom_id);
		 printf("%1d ", atom[i].valid);
		 printf("%4s ", atom[i].name);
		 printf("%5s ", atom[i].type);
		 printf("%3s ", atom[i].residue);
		 printf("%5s ", atom[i].res_id);
		 printf("%c ", atom[i].chain);
		 printf("%7.2f ", atom[i].coor[0]);
		 printf("%7.2f ", atom[i].coor[1]);
		 printf("%7.2f ", atom[i].coor[2]);
		 printf("%4.2f ", atom[i].r);
		 printf("%5.2f ", atom[i].q);
		 printf("%5.2f ", atom[i].logp);
		 printf("%2s ", atom[i].hb);
		 printf("%7.2f ", atom[i].root[0]);
                 printf("%7.2f ", atom[i].root[1]);
                 printf("%7.2f", atom[i].root[2]);
		 printf("\n");                
		}

	return;
}

void Protein::Find_Pocket_Atom()
{
	int i,j,mark,tmp,count;
	float d,cutoff;
	extern Ligand *lig; 

	// find pocket atoms on the protein and label their valid as '2'

	cutoff=(DIST_CUTOFF)*(DIST_CUTOFF);

	for(i=0;i<num_atom;i++)
	{
	 if(atom[i].valid<=0) continue;

	 // check whether this patom is close to the ligand

	 mark=FALSE;

	 for(j=0;j<lig->num_atom;j++)
		{
		 if(lig->atom[j].valid<=0) continue;
		 else
			{
			 d=Distance2(atom[i].coor,lig->atom[j].coor);
			 if(d>cutoff) continue;
                         else {mark=TRUE; break;}
			}
		}

	 if(mark==TRUE) 
		{
		 atom[i].valid=2;	// pocket atom

		 // check if it has been included in an known pocket residue	

		 tmp=FALSE;

		 for(j=0;j<num_pocket_res;j++)
        		{
         		 if(!strcmp(atom[i].residue,pocket_res[j].name) 
			  &&!strcmp(atom[i].res_id,pocket_res[j].id)
			  &&(atom[i].chain==pocket_res[j].chain))
				{tmp=TRUE;break;}
			 else continue;
			}

		 // if not, add the newly found pocket residue to the list

		 if((tmp==FALSE)&&(strcmp(atom[i].residue,"HET")))
			{
			 j=num_pocket_res;
			 strcpy(pocket_res[j].name,atom[i].residue);
			 strcpy(pocket_res[j].id,atom[i].res_id);
			 pocket_res[j].chain=atom[i].chain;
			 pocket_res[j].valid=1;
			 num_pocket_res++;
			}
		}
	}

	// define all the left atoms in pocket residues as pocket atoms 

	count=0;

	for(i=0;i<num_atom;i++)
		{
		 if(atom[i].valid<=0) continue;
		 else if(atom[i].valid==2) {count++; continue;}

	 	 for(j=0;j<num_pocket_res;j++)
		{
		 if(strcmp(atom[i].residue,pocket_res[j].name)) continue;
	 	 else if(strcmp(atom[i].res_id,pocket_res[j].id)) continue;
	 	 else if(atom[i].chain!=pocket_res[j].chain) continue;
	 	 else {atom[i].valid=2; count++; break;}
		}
		}

	if(count<12) // there should be at least 3 residues as pocket!
		{
		 printf("Error: cannot find enough pocket residues.\n");
		 printf("Probably the ligand is not complexed with the protein.\n");
		 printf("Please check it and try again.\n");
		 exit(1);
		}
		 	
	return;
}

void Protein::Show_Pocket_Residue() const
{
	int i;

	printf("The binding pocket is formed by:\n\n");

	for(i=0;i<num_pocket_res;i++)
                {
                 printf("Pocket residue %d: %s %s %c\n", 
			 i+1,
                         pocket_res[i].name, 
			 pocket_res[i].id,
                         pocket_res[i].chain); 
                }

	for(i=0;i<num_atom;i++)
		{
		 if(atom[i].valid!=2) continue;
		 else if(strcmp(atom[i].residue,"HET")) continue;
		 else printf("%d %s %s\n", 
			     atom[i].atom_id, 
			     atom[i].residue, 
			     atom[i].type);
		}

	return;
}

void Protein::Output_Pocket_Atom(char *filename) const
{
	FILE *fp;
	int i,num;

	if((fp=fopen(filename,"w"))==NULL) Openning_File_Error(filename);

	fprintf(fp,"#\n");
	fprintf(fp,"# This file is create by LigBuilder/Pocket.\n");
	fprintf(fp,"# It stores the parameters for the pocket atoms.\n");
	fprintf(fp,"# Creation time: %s", Get_Time());
	fprintf(fp,"#\n");

	fprintf(fp,"# 1st column: ID of the atom\n");
	fprintf(fp,"# 2nd column: ID of the atom in the original PDB file\n");
	fprintf(fp,"# 3rd column: atom type\n");
	fprintf(fp,"# 4th column: X coordinate\n");
	fprintf(fp,"# 5th column: Y coordinate\n");
	fprintf(fp,"# 6th column: Z coordinate\n");
	fprintf(fp,"# 7th column: vdw radius\n");
	fprintf(fp,"# 8th column: atomic hydrophobic scale\n");
	fprintf(fp,"# 9th column: H-bond character\n");
	fprintf(fp,"# 10th column: H-bond root X coordinate\n"); 
	fprintf(fp,"# 11th column: H-bond root Y coordinate\n"); 
	fprintf(fp,"# 12th column: H-bond root Z coordinate\n");
	fprintf(fp,"#\n");

	num=0;

	for(i=0;i<num_atom;i++)
		{
		 if(atom[i].valid!=2) continue;
		 else num++;
		}

	fprintf(fp,"<Start>\n");
	fprintf(fp,"<Atom_number> %d\n", num);

	num=1;

	for(i=0;i<num_atom;i++)
		{
		 if(atom[i].valid!=2) continue;
	
		 fprintf(fp,"%3d ", num);
		 fprintf(fp,"%5d ", atom[i].atom_id);
		 fprintf(fp,"%5s ", atom[i].type);
		 fprintf(fp,"%7.2f ", atom[i].coor[0]);
		 fprintf(fp,"%7.2f ", atom[i].coor[1]);
		 fprintf(fp,"%7.2f  ", atom[i].coor[2]);
		 fprintf(fp,"%4.2f  ", atom[i].r);
		 fprintf(fp,"%5.2f  ", atom[i].logp);
		 fprintf(fp,"%2s ", atom[i].hb);
		 fprintf(fp,"%7.2f ", atom[i].root[0]);
                 fprintf(fp,"%7.2f ", atom[i].root[1]);
                 fprintf(fp,"%7.2f", atom[i].root[2]);
		 fprintf(fp,"\n");

		 num++;
		}

	fprintf(fp,"<End>\n");

	fclose(fp);
			
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -