grow.c
来自「药物开发中的基于结构的从头设计代码」· C语言 代码 · 共 1,238 行 · 第 1/3 页
C
1,238 行
(tmp_frag[i],tmp_frag[j])==FALSE) continue;
else
{
profile[j].valid=0;
profile[j].grow=0;
profile[j].link=0;
}
}
}
// now make new molecules
for(i=0;i<24;i++)
{
if(profile[i].valid==FALSE) continue;
else
{
mark=Join_Two_Molecules(core,tmp_frag[i],
id5,id2,id6,id3,new_bond.type,
tmp_result);
if(mark==FALSE) return FALSE;
else result[i]=tmp_result;
}
}
// try to make linkings
Linking_Record record[24];
for(i=0;i<24;i++)
{
if(profile[i].link==FALSE) continue;
tmp_result<=result[i]; // notice this operator!
if(tmp_result.Link_Structure(record[i])==FALSE)
{
profile[i].link=FALSE;
profile[i].valid=FALSE;
}
else
{
result[i]=tmp_result;
}
}
// find the best conformer among linked structures
for(i=0;i<23;i++)
{
if(profile[i].link==FALSE) continue;
for(j=i+1;j<24;j++)
{
if(profile[j].link==FALSE) continue;
if(Record_Sameness_Check(record[i],record[j])==TRUE)
{
if(record[i].rmsd>record[j].rmsd)
{
profile[i].link=FALSE;
profile[i].valid=FALSE;
}
else
{
profile[j].link=FALSE;
profile[j].valid=FALSE;
}
}
else continue;
}
}
// finally, count the generated molecules
mark=0;
for(i=0;i<24;i++)
{
if(profile[i].valid) {result[i].valid=TRUE; mark++;}
else result[i].valid=FALSE;
}
/*
for(i=0;i<24;i++)
{
printf("Angle: %5.1f\tEnergy: %7.2f\tGrow: %d\tLink: %d\t",
profile[i].angle, profile[i].e,
profile[i].grow, profile[i].link);
printf("Result: %d\n", result[i].valid);
}
*/
return mark; // return the number of molecules generated
Improper_Torsion:
mark=Join_Two_Molecules(core,frag,
id5,id2,id6,id3,new_bond.type,
tmp_result);
if(mark==FALSE) return FALSE;
else
{
result[0]=tmp_result;
result[0].valid=TRUE;
}
return 1;
}
int Ligand::Join_Two_Molecules(Ligand &lig_1, Ligand &lig_2,
int seed_1, int root_1, int seed_2, int root_2,
char new_bond_type[3], Ligand &result) const
{
int i,id1,id2,tmp;
result.Clean_Members();
// first, delete the two hydrogens
lig_1.Delete_An_Atom(seed_1);
lig_2.Delete_An_Atom(seed_2);
// second, make the new molecule by adding lig_1 and lig_2
for(i=0;i<lig_1.num_atom;i++)
{
result.atom[i]=lig_1.atom[i];
}
for(i=0;i<lig_1.num_bond;i++)
{
result.bond[i]=lig_1.bond[i];
}
for(i=0;i<lig_2.num_atom;i++)
{
tmp=lig_1.num_atom+i;
result.atom[tmp]=lig_2.atom[i];
result.atom[tmp].id+=lig_1.num_atom;
}
for(i=0;i<lig_2.num_bond;i++)
{
tmp=lig_1.num_bond+i;
result.bond[tmp]=lig_2.bond[i];
result.bond[tmp].id+=lig_1.num_bond;
result.bond[tmp].atom_1+=lig_1.num_atom;
result.bond[tmp].atom_2+=lig_1.num_atom;
}
result.num_atom=lig_1.num_atom+lig_2.num_atom;
result.num_bond=lig_1.num_bond+lig_2.num_bond;
strcpy(result.name,"GENERATED");
// finally, add the new bond
id1=root_1; id2=root_2+lig_1.num_atom;
tmp=result.num_bond;
result.bond[tmp].id=tmp+1;
result.bond[tmp].atom_1=result.atom[id1-1].id;
result.bond[tmp].atom_2=result.atom[id2-1].id;
strcpy(result.bond[tmp].type,new_bond_type);
result.bond[tmp].valid=1;
result.num_bond++;
result.valid=result.Arrange_IDs();
if(result.valid==FALSE) return FALSE;
else return TRUE;
}
int Ligand::Find_Root_Of_A_Hydrogen(int id, Group &root) const
// id is the ID of the hydrogen
{
int id_root;
if(atom[id-1].type[0]!='H') return FALSE; // not a hydrogen!
// first, find the root atom
id_root=atom[id-1].neib[0];
if(id_root==0) return FALSE;
// second, find the neighbors of the root atom
root=Find_A_Group(id_root);
if(root.valid==0) return FALSE;
else return TRUE;
}
int Ligand::Select_A_Seed_Hydrogen() const
{
int i,tmp;
int num,total,final,*seed_list;
struct Wheel
{
int min;
int max;
} *wheel;
// first, count all the possible seed hydrogens
seed_list=new int[num_atom];
if(seed_list==NULL) Memory_Allocation_Error();
num=Make_Seed_List(seed_list);
if(num==0) {delete [] seed_list; return FALSE;}
// then, set the wheel acoording to their grades
wheel=new Wheel[num];
if(wheel==NULL) Memory_Allocation_Error();
total=0;
for(i=0;i<num;i++)
{
wheel[i].min=total;
total+=Pow(2,atom[seed_list[i]-1].valid);
wheel[i].max=total;
}
// then, randomly select one from the wheel
tmp=(int)(drand48()*total);
final=0;
for(i=0;i<num;i++)
{
if(tmp<wheel[i].min) continue;
else if(tmp>=wheel[i].max) continue;
else {final=seed_list[i]; break;}
}
delete [] wheel; delete [] seed_list;
return final;
}
int Ligand::Make_Seed_List(int seed_id[]) const
{
int i,num;
for(i=0;i<num_atom;i++) seed_id[i]=0;
num=0;
for(i=0;i<num_atom;i++)
{
if(atom[i].valid==0) continue;
else if(strcmp(atom[i].type,"H.spc")) continue;
else {seed_id[num]=atom[i].id; num++;}
}
return num;
}
int Ligand::Record_Sameness_Check(Linking_Record record_1,
Linking_Record record_2) const
{
int i,mark;
if(record_1.num_link!=record_2.num_link) return FALSE;
mark=TRUE;
for(i=0;i<record_1.num_link;i++)
{
if(record_1.id1[i]!=record_2.id1[i])
{
mark=FALSE; break;
}
else if(record_1.id2[i]!=record_2.id2[i])
{
mark=FALSE; break;
}
else continue;
}
return mark;
}
int Ligand::Atom_Overlap_Check(Atom atom_1, Atom atom_2) const
{
if(Distance(atom_1.coor,atom_2.coor)<ATOM_OVERLAP_RANGE) return TRUE;
else return FALSE;
}
int Ligand::Bridging(int id1, int id2)
{
extern ForceField *ff;
Atom seed_1,seed_2;
Atom result_1,result_2,result;
Group root_1, root_2;
int i;
float tmp1,tmp2,tmp3,tmp4,d;
float v1[3],v2[3],v3[3],v4[3],angle;
// find the two seed hydrogens and their roots
seed_1=atom[id1-1]; seed_2=atom[id2-1];
if(Find_Root_Of_A_Hydrogen(id1,root_1)==FALSE) return FALSE;
if(Find_Root_Of_A_Hydrogen(id2,root_2)==FALSE) return FALSE;
if(Atom_Overlap_Check(root_1.center,root_2.center)==TRUE) return FALSE;
// check the angle of the two vectors
for(i=0;i<3;i++)
{
v1[i]=root_1.center.coor[i]-seed_1.coor[i];
v2[i]=root_2.center.coor[i]-seed_2.coor[i];
}
angle=Angle_Of_Two_Vectors(v1,v2);
if(angle>(109.4+ANGLE_OVERLAP_RANGE)) return FALSE;
else if(angle<(109.4-ANGLE_OVERLAP_RANGE)) return FALSE;
// calculate the position of hypothetic atoms
tmp1=Distance(seed_1.coor,root_1.center.coor);
tmp2=Distance(seed_2.coor,root_2.center.coor);
tmp3=ff->Get_Bond_Length(root_1.center.type,"C.3","1");
tmp4=ff->Get_Bond_Length(root_2.center.type,"C.3","1");
for(i=0;i<3;i++)
{
result_1.coor[i]=root_1.center.coor[i];
result_1.coor[i]+=((seed_1.coor[i]-root_1.center.coor[i])*tmp3/tmp1);
result_2.coor[i]=root_2.center.coor[i];
result_2.coor[i]+=((seed_2.coor[i]-root_2.center.coor[i])*tmp4/tmp2);
}
if(Atom_Overlap_Check(result_1,result_2)==FALSE) return FALSE;
// first, delete the two hydrogens
Delete_An_Atom(id1); Delete_An_Atom(id2);
// add the new bridging carbon, stored in result
result.id=num_atom+1;
strcpy(result.name,"C");
strcpy(result.type,"C.3");
result.weight=12;
result.valid=seed_2.valid;
for(i=0;i<3;i++)
result.coor[i]=(result_1.coor[i]+result_2.coor[i])/2.0;
atom[num_atom]=result;
num_atom++;
bond[num_bond].id=num_bond+1;
bond[num_bond].atom_1=root_1.center.id;
bond[num_bond].atom_2=result.id;
bond[num_bond].valid=1;
strcpy(bond[num_bond].type,"1");
bond[num_bond+1].id=num_bond+2;
bond[num_bond+1].atom_1=root_2.center.id;
bond[num_bond+1].atom_2=result.id;
bond[num_bond+1].valid=1;
strcpy(bond[num_bond+1].type,"1");
num_bond+=2;
// add the two new hydrogens, stored in result_1 and result_2
for(i=0;i<=2;i++)
{
v1[i]=root_1.center.coor[i]-result.coor[i];
v2[i]=root_2.center.coor[i]-result.coor[i];
}
Unify_Vector(v1); Unify_Vector(v2);
Get_Sp3_Coordinates(v1,v2,v3,v4);
d=ff->Get_Bond_Length("C.3","H","1");
for(i=0;i<=2;i++)
{
result_1.coor[i]=result.coor[i]+v3[i]*d;
result_2.coor[i]=result.coor[i]+v4[i]*d;
}
result_1.id=num_atom+1;
strcpy(result_1.name,"H");
strcpy(result_1.type,"H.spc");
result_1.weight=1;
result_1.valid=seed_2.valid;
result_2.id=num_atom+2;
strcpy(result_2.name,"H");
strcpy(result_2.type,"H.spc");
result_2.weight=1;
result_2.valid=seed_2.valid;
atom[num_atom]=result_1;
atom[num_atom+1]=result_2;
num_atom+=2;
bond[num_bond].id=num_bond+1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?