CCL Home Page
Up Directory CCL stergrp.c
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************   "steric"   **********************************/
/**************************************************************************/
/*************     Program to calculate ligand cone    ********************/
/*************     angles as a measure of steric size  ********************/
/**************************************************************************/
/**************************************************************************/

/**************************************************************************/
/******************       Group Functions        **************************/
/**************************************************************************/
/******************        This module is        **************************/
/******************      system independant      **************************/
/**************************************************************************/

#include 
#include 
#include 

#include "sterdefn.h" /* declaration of structures, functions and globals */
#include "stercomm.h" /* definitions of all menu command options          */
#include "sterfile.h"      /* functions for all file manipulations        */
#include "stermem.h"  /* dynamic memory management module                 */
#include "stertext.h" /* all text functions for text mode                 */
#include "steraid.h"  /* additional functions needed                      */
#include "stergrp.h"  /* group manipulation functions                     */

/**************************************************************************/

void Initialize_Group(Grps *group)
{
  group->name[0]=0;         /* group lable for identification             */
  group->atex[0]=0;         /* list of extra atom types allowed           */
  group->main=NULL;         /* atom no of atom bonded to origin           */
  group->num_atoms=0;       /* no of atoms in group                       */
  group->SVangle=0.0;       /* peak semi vertex angle for group           */
  group->volume=0.0;        /* group volume                               */
  group->cavity=0.0;        /* cavity volume                              */
  group->radvol=0.0;        /* radial profile volume                      */
  group->radcav=0.0;        /* radvol cavity volume                       */
  group->volrad=0.0;        /* radius for cavity volume calculation       */
  group->mode=FIXA_BIT;     /* mode (fixed numatoms or not)               */
/* next and prev pointers have already been assigned, do not fiddle !!!   */
}

/**************************************************************************/

int Get_Group_Names(char *inline, char *outline, char **oargs)
{
  int i,n,a;
  char *iargs[MAXARG];
  char *args[MAXARG];
  int inum=0,onum=0,num=0,count=0;
  FILE *GR=NULL;
  char line[LINELEN];
  char name[LINELEN];

  sprintf(line,"steric.grp");
  if((GR=fopen(line,"rt"))==NULL)
  {
    sprintf(line,"%s/steric.grp",STERICHOME);
    if((GR=fopen(line,"rt"))==NULL)
    {
      sprintf(line,"Get Group Names [steric.grp] | [%s/steric.grp]",STERICHOME);
      Error_Message(E_NOGRPF,line);
      return(0);
    }
  }
  if((strlen(inline)<1)||((inum=Get_Arguements(inline,iargs))<1)) return(0);
  outline[0]=0;

/* load specified group names into memory                                 */

  for(a=0,i=0,n=0;n0L)&&(!feof(GR)))
    {
      if(strlen(outline)>LINELEN-10) break;
      if(strchr(line,'\n')!=NULL) strchr(line,'\n')[0]=0;
      if((num=Get_Arguements(line,args))>0)
      for(count=1;count=MAXARG) break;
  }
  fclose(GR);
  onum=Get_Arguements(outline,oargs);
  return(onum);
}

/**************************************************************************/

int Get_Groups_by_Name(Mol *M, char **args, int num, Grps **group)
{
  int i,n;
  int gi=0;

  if(M==NULL) return(0);
  if(M->groups==NULL) return(0);
  for(i=0,n=0;n=MAXARG) break;
    group[i]=NULL;
    if(((group[i]=Goto_Group_Name(M->groups,args[n]))!=NULL)
     ||((gi=Int_String(args[n]))!=0))
    {
      if((group[i]==NULL)&&(gi)) group[i]=Goto_Group(M->groups,gi);
    }
    if(group[i]!=NULL) i++;
    else
    {
      Error_Message(E_NOFGRP,"Get_Groups_by_Name");
      continue;
    }
  }
  return(i);
}

/**************************************************************************/

int Same_Bonds(Atms *A, Atms *B, int dif)
{
  Bond *bdA=NULL, *bdB=NULL;
  int a,b;
  if(dif>1000) return(1);
  for(b=0,bdB=First_Bond(B->bond);bdB!=NULL;bdB=bdB->next,b++);
  for(a=0,bdA=First_Bond(A->bond);bdA!=NULL;bdA=bdA->next,a++);
  if((a-b!=dif)&&(a-b!=0)) return(0);
  for(a=0,b=0,bdB=First_Bond(B->bond);bdB!=NULL;bdB=bdB->next,b++)
  {
    for(bdA=First_Bond(A->bond);bdA!=NULL;bdA=bdA->next)
    {
      if(stricmp(bdA->atom->type,bdB->atom->type)==0)
      {
        a++;
        break;
      }
    }
  }
  if(a==b) return(1);
  return(0);
}

/**************************************************************************/

int Same_Atom(Atms *A, Atms *B, int dif)
{
  if(stricmp(A->type,B->type)!=0) return(0);
  if(!Same_Bonds(A,B,dif)) return(0);
  return(1);
}

/**************************************************************************/

int Same_Types(Grps *mgroup, Grps *group)
{
  Atms *at=NULL;
  char *args[MAXARG];
  char line[LINELEN];
  int num=0,i,n;
  
  if((mgroup==NULL)||(group==NULL)) return(0);
  if(group->mode&FIXA_BIT) return(0);
  if(mgroup->num_atomsnum_atoms) return(0);
  n=Get_Group_Number(mgroup);
  sprintf(line,"%s ",group->atex);
  for(at=First_Atom(group->main);at!=NULL;at=at->next)
  {
    strcat(line,at->type);
    if(strlen(line)>LINELEN-5) break;
    strcat(line," ");
  }
  if((num=Get_Arguements(line,args))<1) return(0);

  for(at=First_Atom(mgroup->main);at!=NULL;at=at->next)
  {
    if(at->group!=n) continue;
    for(i=0;itype,args[i])==0) break;
    }
    if(i==num) return(0);
  }
  return(1);
}

/**************************************************************************/

int Group_Matches(Grps *mgroup, Grps *group)
{
  Atms *atM=NULL, *atG=NULL;
  int a,b,d, mgn;
  
  if((group==NULL)||(mgroup==NULL)) return(0);
  if(stricmp(mgroup->main->type,group->main->type)!=0) return(0);
  if((Same_Types(mgroup,group))||(group->num_atoms==mgroup->num_atoms))
  {
    for(a=0,b=0,d=1,atG=First_Atom(group->main);atG!=NULL;atG=atG->next,a++,d=0)
    {
      if(!(group->mode&FIXA_BIT)) d=1001;
      for(atM=First_Atom(mgroup->main);atM!=NULL;atM=atM->next)
      {
        mgn=Get_Group_Number(mgroup);
        if((atM->group==mgn)&&(Same_Atom(atM,atG,d)))
        {
          b++;
          break;
        }
      }
    }
    if(a==b) return(1);
  }
  return(0);
}

/**************************************************************************/

Grps *Load_Group(FILE *GR, Grps *group, char *line, char *name)
{
  char *args[MAXARG];
  int num=0,i;
  Atms *at=NULL;
  int a, b;
  Atms *atomA=NULL, *atomB=NULL;

  if((GR==NULL)||(strncmp(line,"GROUP",5)!=0)) return(NULL);

  group=New_Group(group);
  Initialize_Group(group);
  strcpy(group->name,name);
  while(fgets(line,148,GR),!feof(GR))
  {
    if(line[0]=='#') break;
    if(strchr(line,'\n')!=NULL) strchr(line,'\n')[0]=0;
    if((num=Get_Arguements(line,args))>0)
    if(stricmp(args[0],"GROUP")==0) break;
    if(stricmp(args[0],"ATOM")==0)
    {
      for(i=1;iname,args[i],ATM_LEN);
        strncpy(at->type,args[i],ATM_LEN);
        group->num_atoms++;
      }
      group->main=First_Atom(at);
    }
    else if(stricmp(args[0],"ATEX")==0)
    {
      for(i=1;i1) strcat(group->atex," ");
        strcat(group->atex,args[i]);
      }
      group->mode&=FULL_BIT^FIXA_BIT;
    }
    else if((stricmp(args[0],"VOLR")==0)&&(num>1))
    {
      sscanf(args[1],"%lf",&group->volrad);
      if(group->volrad<0.0) group->volrad=0.0;
      if(group->volrad>MAXVRAD) group->volrad=MAXVRAD;
    }
    else if((stricmp(args[0],"BOND")==0)&&(num>2))
    {
      a=0;b=0;
      sscanf(args[1],"%d",&a);
      atomA=Goto_Atom(group->main,a);
      for(i=2;imain,b);
        Add_New_Bond(atomA,atomB,SINGLE_B);
      }
    }
  }
  if(group->volrad<0.0) group->volrad=0.0;
  return(group);
}

/**************************************************************************/

int Kill_All_Groups(Mol *M, char *name)
{
  char *args[MAXARG];
  int num=0,count=0,i=0;
  Atms *at=NULL;
  Grps *mgroup=NULL;
  FILE *GR=NULL;
  char line[LINELEN];
  int a;

  if(M->groups==NULL)
  {
    Error_Message(E_NOGRPS,"Kill All Groups");
    return(0);
  }
  if((GR=fopen("steric.grp","rt"))==NULL)
  {
    Error_Message(E_NOGRPF,"Kill All Groups");
    return(0);
  }

/* load specified group structure into memory                             */

  while(get_next_line(GR,"GROUP",line)>0L)
  {
    if(feof(GR)) return(0);
    if(strchr(line,'\n')!=NULL) strchr(line,'\n')[0]=0;
    if((num=Get_Arguements(line,args))>0)
    for(count=1;count1)
  {
    Error_Message(E_TOMGRP,"Kill All Groups");
  }

/* loop through all molecule groups, comparing to loaded groups           */

  a=0;
  for(mgroup=First_Group(M->groups);mgroup!=NULL;mgroup=mgroup->next)
  {
    if(stricmp(mgroup->name,name)==0)
    {
      a++;
      for(at=First_Atom(M->atoms);at!=NULL;at=at->next)
      {
        if(at->group==Get_Group_Number(mgroup))
          at->stat=at->stat&(!MAIN_BIT);
      }
    }
  }
  if(a)
  {
    sprintf(line,"Killed %d %s groups",a,name);
    Out_Message(line,O_NEWLN);
  }

  return(1);
}

/**************************************************************************/

int Name_All_Groups(Mol *M)
{
  char *args[MAXARG];
  char name[LINELEN];
  int num=0;
  Grps *new=NULL, *group=NULL,*mgroup=NULL, *lgroup=NULL;
  FILE *GR=NULL;
  char line[LINELEN];

  if(M->groups==NULL)
  {
    Error_Message(E_NOGRPS,"Name All Groups");
    return(0);
  }
  if((GR=fopen("steric.grp","rt"))==NULL)
  {
    Error_Message(E_NOGRPF,"Name All Groups");
    return(0);
  }

/* load all group structures into memory                                  */

  while(get_next_line(GR,"GROUP",line)>0L)
  {
    if(feof(GR)) return(0);
    if(strchr(line,'\n')!=NULL) strchr(line,'\n')[0]=0;
    if((num=Get_Arguements(line,args))>0)
    strcpy(name,args[num-1]);
    if((new=Load_Group(GR,lgroup,line,name))==NULL)
    {
      Error_Message(E_LDGRP,"Name All Groups");
      break;
    }
    lgroup=new;
  }
  fclose(GR);

/* loop through all molecule groups, comparing to loaded groups           */

  for(group=First_Group(lgroup);group!=NULL;group=group->next)
  {
    for(mgroup=First_Group(M->groups);mgroup!=NULL;mgroup=mgroup->next)
    {
      if(Group_Matches(mgroup,group))
      {
        sprintf(line,"Renaming group %s to %s",mgroup->name,group->name);
        Out_Message(line,O_NEWLN);
        strcpy(mgroup->name,group->name);
        if(!AlmostZero(group->volrad)) mgroup->volrad=group->volrad;
      }
    }
  }

/* close down temporary group memory                                      */

  for(group=First_Group(lgroup);group!=NULL;)
  {
    Close_All_Atoms(group->main,0);
    group=Close_Group(group);
  }

  return(1);
}

/**************************************************************************/

double Find_Max_Group_SVangles(Mol *M)
{
  double cone=0.0;
  Atms *at=NULL;
  Grps *group=NULL;
  int n=0,p=0,imax=0;

  if(M->groups==NULL)
  {
    for(n=0,at=First_Atom(M->atoms);at!=NULL;at=at->next)
    {
      n++; if(n>M->num_atoms) Error_Message(E_ATMNUM,"Find Max Group SVangles");
      if((at->stat&MAIN_BIT)&&(!AlmostZero(at->SVangle))&&(conetheta+at->SVangle))
      {
        imax=n;
        cone=at->theta+at->SVangle;
      }
    }
    p=1;
  }
  else
  {
    group=First_Group(M->groups);
    if(group->name[0]=='0')
    {
      group->SVangle=group->main->SVangle;
      group=group->next;
    }
    for(p=0;group!=NULL;group=group->next,p++)
    {
      group->SVangle=0.0;
      for(n=0,at=First_Atom(M->atoms);at!=NULL;at=at->next)
      {
        n++; if(n>M->num_atoms) Error_Message(E_ATMNUM,"Find Max Group SVangles");
        if((at->stat&MAIN_BIT)&&((at->group==p+1)||(at->group==0))
         &&(!AlmostZero(at->SVangle))&&(group->SVangletheta+at->SVangle))
        {
          group->SVangle=at->theta+at->SVangle;
          imax=n;
        }
      }
      cone+=group->SVangle;
    }
    if(p<3)
    {
      if(group=First_Group(M->groups),group->name[0]=='0')
      {
        p++;
        cone+=group->SVangle;
      }
    }
  }
  M->atoms=Goto_Atom(M->atoms,imax);
  return(cone*2/p);
}

/**************************************************************************/

int Find_Bonded_Atoms(Grps *group, Atms *o, int i)
{
  Bond *bond=NULL;
  
  if((o!=NULL)&&(!(o->stat&GRP_BIT))&&(o->stat&MAIN_BIT))
  {
    o->stat|=GRP_BIT;
    o->group=i;
    group->num_atoms++;
    if(group->main==NULL) group->main=o;
    for(bond=First_Bond(o->bond);bond!=NULL;bond=bond->next)
    {
      Find_Bonded_Atoms(group,bond->atom,i);
    }
    return(1);
  }
  return(0);
}

/**************************************************************************/

int Assign_Groups(Mol *M)
{
  int i;
  Bond *bond=NULL;
  Grps *new=NULL;
  Atms *atom=NULL;
  Atms *o=M->origin;
  
  M->groups=Close_All_Groups(M->groups);
  if(o==NULL) 
  {
    M->groups=Close_All_Groups(M->groups);
    return(0);
  }
  for(atom=First_Atom(o);atom!=NULL;atom=atom->next)
  {
    atom->stat&=255^GRP_BIT;
    atom->group=0;
  }
  o->stat|=GRP_BIT;
  for(i=0,bond=First_Bond(o->bond);bond!=NULL;bond=bond->next)
  {
    if((bond->atom!=NULL)&&(bond->atom->stat&MAIN_BIT))
    {
      i++;
      atom=bond->atom;
    }
  }
  if(i<1)
  {
    M->groups=Close_All_Groups(M->groups);
    return(0);
  }
  else if(i==1)
  {
    if(atom!=NULL)
    {
      o=atom;
      o->stat|=GRP_BIT;
      M->main_atom=o;
      if((new=New_Group(M->groups))==NULL) return(0);
      M->groups=new;
      Initialize_Group(M->groups);
      M->groups->name[0]='0';
      M->groups->name[1]=0;
      M->groups->num_atoms=1;
      M->groups->SVangle=o->SVangle;
      M->groups->main=o;
    }
  }
  for(i=1,bond=First_Bond(o->bond);bond!=NULL;bond=bond->next)
  {
    if((new=New_Group(M->groups))==NULL) return(0);
    M->groups=new;
    Initialize_Group(M->groups);
    sprintf(M->groups->name,"%d",i);
    if(!Find_Bonded_Atoms(M->groups,bond->atom,i))
      M->groups=Close_Group(M->groups);
    else i++;
  }
  Name_All_Groups(M);
  return(1);
}

/**************************************************************************/

int Find_All_Bonded_Groups(Mol *M, unsigned mode)
{
  int i;
  Grps *new=NULL;
  Atms *atom=NULL;
  char line[LINELEN];
  
  M->groups=Close_All_Groups(M->groups);
  for(atom=First_Atom(M->atoms);atom!=NULL;atom=atom->next)
  {
    if(atom->group==FULL_BIT)
    {
      atom->stat|=GRP_BIT;
      continue;
    }
    if((mode==NO_SINGLE)&&(atom->bonds==0))
    {
      atom->stat|=GRP_BIT;
      continue;
    }
    atom->stat&=FULL_BIT^GRP_BIT;
    atom->group=0;
  }
  for(i=1,atom=First_Atom(M->atoms);atom!=NULL;atom=atom->next)
  {
    if(atom->stat&GRP_BIT) continue;
    if((new=New_Group(M->groups))==NULL) return(0);
    M->groups=new;
    Initialize_Group(M->groups);
    sprintf(M->groups->name,"%d",i);
    if(!Find_Bonded_Atoms(M->groups,atom,i))
      M->groups=Close_Group(M->groups);
    else
    {
      sprintf(line,"Found group %s of %d atoms",M->groups->name,M->groups->num_atoms);
      Out_Message(line,O_NEWLN);
      i++;
    }
  }
  Name_All_Groups(M);
  return(1);
}

/**************************************************************************/
/***************************  The End ... *********************************/
/**************************************************************************/
Modified: Fri Dec 8 17:00:00 1995 GMT
Page accessed 4858 times since Sat Apr 17 21:59:56 1999 GMT