CCL Home Page
Up Directory CCL mm2_params.c
/*============================================================================*/
/* FILENAME: MM2_PARAMS.C (MM2_PARAMS)
/* USAGE: MM2_PARAMS [-A] [-D] {MM2/MM3 OUTPUT FILE WITH ERRORS}
/*	-A	AUTOMATICALLY TAKE ALL DERIVED PARAMETERS.
/*	-D	PRINTS OUT DEBUGGING INFO AS TO HOW PARAMETERS ARE DERIVED.
/* PURPOSE: SIFT THROUGH MM2/MM3 OUTPUT FILE FOR ERRORS REGARDING MISSING
/*	PARAMETERS AND DERIVE THOSE PARAMETERS BASED ON SIMILARITIES
/*	BETWEEN THE INVOLVED ATOM TYPES AND EXISTING PARAMETERS FOR OTHER
/*	ATOM TYPES (OR BY ASKING USER IF NO SIMILAR CASES EXIST).
/*	NOTE THAT THERE ARE SIGNIFICANT DIFFERENCES IN THE DETAILS OF HANDLING
/*	MM2 VERSUS MM3 OUTPUT FILES (DIFFERENT BUILTIN PARAMETER FILE FORMATS,
/*	DIFFERENT SITE PARAMETER FILES, DIFFERENT FILENAMES, DIFFERENT ERROR
/*	MESSAGE FORMATS, ETC).
/* REFERENCE: JOURNAL OF COMPUTATIONAL CHEMISTRY, VOLUME 12, NUMBER 7,
/*	844-849 (1991) DORA SCHNUR, MARK GRIESHABER, J. PHILLIP BOWEN,
/*	"DEVELOPMENT OF AN INTERNAL SEARCHING ALGORITHM FOR PARAMETERIZATION
/*	OF THE MM2/MM3 FORCE FIELDS".
/* COPYRIGHT 1992 MONSANTO COMPANY
/* WRITTEN: M.V.GRIESHABER + D.M.SCHNUR
/* LAST MODIFICATION: 6 APRIL 1992 MVG (ADDED COPYRIGHT NOTICE)
/*============================================================================*/
#include "utility.h"

#define MAX_TORSION_ERRORS 100		/* MAX ALLOWED TORSION ERRORS. */
#define MAX_BOND_ERRORS 100		/* MAX ALLOWED BOND ERRORS. */
#define MAX_ANGLE_ERRORS 100		/* MAX ALLOWED (2D) ANGLE ERRORS. */
#define MAX_OUTOFPLANE_ERRORS 100	/* MAX ALLOWED OUT-OF-PLANE ERRORS. */

#define MAX_TORSION_PARAMS_NORMAL 900	/* MAX ALLOWED NORMAL TORSION PARAMETERS. */
#define MAX_TORSION_PARAMS_4RING 200	/* MAX ALLOWED 4 MEMBERED RING TORSION PARAMETERS. */
#define MAX_TORSION_PARAMS_ALLENE 20	/* MAX ALLOWED ALLENE TORSION PARAMETERS. */
#define MAX_BOND_PARAMS 400		/* MAX ALLOWED BOND PARAMETERS. */
#define MAX_ANGLE_PARAMS_NORMAL 600	/* MAX ALLOWED NORMAL (2D) ANGLE PARAMETERS. */
#define MAX_ANGLE_PARAMS_4RING 100	/* MAX ALLOWED 4 MEMBERED RING (2D) ANGLE PARAMETERS. */
#define MAX_ANGLE_PARAMS_3RING 100	/* MAX ALLOWED 3 MEMBERED RING (2D) ANGLE PARAMETERS. */
#define MAX_OUTOFPLANE_PARAMS 200	/* MAX ALLOWED OUT-OF-PLANE PARAMETERS. */

#define MAX_ATOM_TYPES 60		/* MAX MM2/MM3 ATOM TYPES. */
#define MAX_TRANSFORMS 3		/* MAX TRANSFORMATIONS FOR ANY ATOM TYPE. */
#define MAX_ATOMS 256			/* MAX ATOMS IN MOLECULE STRUCTURE. */
#define MAX_BONDS_PER_ATOM 8		/* MAX BONDS TO ONE ATOM. */

#define MM3_END_OF_SECTION '9'		/* END OF MM3 PARAMETER SECTION FLAG. */

#define NORMAL 1			/* NORMAL (DEFAULT) ENVIRONMENT. */
#define ALLENE 2			/* ALLENE ENVIRONMENT. */
#define THREE_RING 3			/* 3-MEMBERED RING ENVIRONMENT. */
#define FOUR_RING 4			/* 4-MEMBERED RING ENVIRONMENT. */

#define NO_MATCH 1			/* NO SIMILAR PARAMETER FOUND. */
#define EXACT_MATCH 2			/* EXACT PARAMETER FOUND. */
#define SIMILAR_MATCH 3			/* SIMILAR PARAMETER FOUND. */

#define READ_ACCESS 4			/* FLAG FOR ACCESS ROUTINE. */
#define ATOM_TYPE 0			/* ARRAY INDEX FOR NEW ATOM TYPE. */
#define COST 1				/* ARRAY INDEX FOR COST. */

struct torsion_data
   {
   int atom_types[4];	/* ATOM TYPES IN TORSION. */
   int atom_numbers[4];	/* ATOM NUMBERS IN TORSION (ERRORS ONLY). */
   double v1;		/* ONE-FOLD TORSIONAL CONSTANT. */
   double v2;		/* TWO-FOLD TORSIONAL CONSTANT. */
   double v3;		/* THREE-FOLD TORSIONAL CONSTANT. */
   int orig_env;	/* ORIGINAL ENVIRONMENT OF TORSION (ERRORS ONLY). */
   int save_param;	/* FLAG; SAVE THIS PARAMETER (ERRORS ONLY). */
   };

struct bond_data
   {
   int atom_types[2];	/* ATOM TYPES IN BOND. */
   double s;		/* STRETCHING CONSTANT. */
   double l0;		/* MINIMUM ENERGY BOND LENGTH. */
   double slps;		/* SLOPE OF BOND-ORDER STRETCHING EQUATION. */
   double slpt;		/* SLOPE OF BOND-ORDER LENGTH EQUATION. */
   double bmom;		/* BOND MOMENT. */
   int save_param;	/* FLAG; SAVE THIS PARAMETER (ERRORS ONLY). */
   };

struct angle_data
   {
   int atom_types[3];	/* ATOM TYPES IN ANGLE. */
   int atom_numbers[3];	/* ATOM NUMBERS IN ANGLE (ERRORS ONLY). */
   double b;		/* BENDING CONSTANT. */
   double t;		/* MINIMUM ENERGY BOND ANGLE (ALL ENVIRONMENTS). */
   int orig_env;	/* ORIGINAL ENVIRONMENT OF ANGLE (ERRORS ONLY). */
   int save_param;	/* FLAG; SAVE THIS PARAMETER (ERRORS ONLY). */
   };

struct outofplane_data
   {
   int atom_types[3];	/* ATOM TYPES IN OUT OF PLANE. */
   double b;		/* BENDING CONSTANT. */
   int save_param;	/* FLAG; SAVE THIS PARAMETER (ERRORS ONLY). */
   };

/* REMEMBER EACH ERROR FOUND IN THE MM2 OUTPUT FILE. */
struct torsion_data torsion_errors[MAX_TORSION_ERRORS];
struct bond_data bond_errors[MAX_BOND_ERRORS];
struct angle_data angle_errors[MAX_ANGLE_ERRORS];
struct outofplane_data outofplane_errors[MAX_OUTOFPLANE_ERRORS];

int ntorsion_errors;	/* NUMBER OF TORSION (DIHEDRAL) ERRORS. */
int nbond_errors;	/* NUMBER OF BOND ERRORS. */
int nangle_errors;	/* NUMBER OF (2D) ANGLE ERRORS. */
int noutofplane_errors;	/* NUMBER OF OUT-OF-PLANE ERRORS. */

/* REMEMBER ALL KNOWN PARAMETERS FOR COMPARISONS (TORSION AND ANGLE DATA IS */
/* SPECIFIC FOR THE STRUCTURAL ENVIRONMENT). */
/* NOTE: USAGE OF TORSION_PARAMS_ALLENE IS *NOT* CURRENTLY IMPLEMENTED SINCE */
/* THERE IS A BUG IN MM2 SUCH THAT THE ALLENE PARAMETERS DO NOT WORK; HOWEVER */
/* WE LEAVE THE DATA STRUCTURE HERE FOR FUTURE ACTIVATION. */
struct torsion_data torsion_params_normal[MAX_TORSION_PARAMS_NORMAL];
struct torsion_data torsion_params_4ring[MAX_TORSION_PARAMS_4RING];
struct torsion_data torsion_params_allene[MAX_TORSION_PARAMS_ALLENE];
struct bond_data bond_params[MAX_BOND_PARAMS];
struct angle_data angle_params_normal[MAX_ANGLE_PARAMS_NORMAL];
struct angle_data angle_params_4ring[MAX_ANGLE_PARAMS_4RING];
struct angle_data angle_params_3ring[MAX_ANGLE_PARAMS_3RING];
struct outofplane_data outofplane_params[MAX_OUTOFPLANE_PARAMS];

int ntorsion_params_normal;	/* NUMBER OF NORMAL TORSION PARAMETERS. */
int ntorsion_params_4ring;	/* NUMBER OF 4 MEMBER RING TORSION PARAMETERS. */
int ntorsion_params_allene;	/* NUMBER OF ALLENE TORSION PARAMETERS. */
int nbond_params;		/* NUMBER OF BOND PARAMETERS. */
int nangle_params_normal;	/* NUMBER OF NORMAL (2D) ANGLE PARAMETERS. */
int nangle_params_4ring;	/* NUMBER OF 4 MEMBERED RING (2D) ANGLE PARAMETERS. */
int nangle_params_3ring;	/* NUMBER OF 3 MEMBERED RING (2D) ANGLE PARAMETERS. */
int noutofplane_params;		/* NUMBER OF OUT-OF-PLANE PARAMETERS. */
int debug_on;			/* FLAG; EXTRA DEBUGGING INFORMATION PRINTED. */
int auto_take;			/* FLAG; AUTOMATICALLY TAKE ALL DEFAULTS. */

struct				/* MOLECULE STRUCTURE, CONNECTIVITY ONLY. */
	{
	int nbonds;			/* NUMBER OF BONDS TO THIS ATOM. */
	int bonds[MAX_BONDS_PER_ATOM];	/* ATOMS BONDED TO THIS ATOM. */
	} connect[MAX_ATOMS];
int natoms;			/* NUMBER OF ATOMS IN MOLECULE STRUCTURE. */

int main(argc,argv)
/*============================================================================*/
/* PURPOSE: CREATE MISSING MM2/MM3 PARAMETERS BASED ON SIMILARITY TO OTHER
/*	(KNOWN) PARAMETERS.
*/
   int argc;
   char* argv[];
   {
   char program[10];		/* NAME OF PROGRAM USED (MM2 OR MM3). */
   char error_filename[100];	/* NAME OF MM2 OUTPUT FILE CONTAINING ERRORS. */
   char param_filename[100];	/* NAME OF CREATED NEW PARAMETER FILE. */

   int initialize();		/* VERIFY INPUTS, READ KNOWN PARAMETERS. */
   void digest_mm2_errors();	/* COLLECT ERRORS FROM MM2 .OUT FILE. */
   void digest_mm3_errors();	/* COLLECT ERRORS FROM MM3 .OUT FILE. */
   int make_parameters();	/* GENERATE MISSING PARAMETERS. */
   void write_parameters();	/* CREATE THE MM2 ADDITIONAL PARAMETER FILE. */

   /* VALIDATE INPUT AND READ KNOWN PARAMETERS FOR LATER COMPARISON. */
   if (!initialize(argc,argv,program,error_filename,param_filename)) return(PROGRAM_FAILED);

   /* PICK THE ERRORS OUT OF THE MM2/MM3 OUTPUT FILE. */
   if (strcmp(program,"mm2")==0)
      digest_mm2_errors(error_filename);
   else
      digest_mm3_errors(error_filename);

   /* CREATE THE MISSING PARAMETERS BY SIMILARITY OR DIRECT USER QUERY AND */
   /* WRITE OUT THE CORRECTLY FORMATTED MM2 ADDITIONAL INPUT PARAMETER FILE. */
   if (make_parameters())
      {
      write_parameters(param_filename);
      }

   return(PROGRAM_SUCCEEDED);
   }

int initialize(argc,argv,program,error_filename,param_filename)
/*============================================================================*/
/* PURPOSE: VERIFY INPUTS AND FILE EXISTENCE, AND READ KNOWN PARAMETERS
/*	FOR LATER COMPARISONS.
*/
   int argc;
   char* argv[];
   char program[];		/* NAME OF PROGRAM USED (MM2 OR MM3). */
   char error_filename[];	/* NAME OF MM2 OUTPUT FILE CONTAINING ERRORS. */
   char param_filename[];	/* NAME OF CREATED NEW PARAMETER FILE. */
   {
   char struct_filename[100];	/* NAME OF MOLECULE STRUCTURE FILE. */
   char builtin_filename[100];	/* NAME OF BUILTIN DEFAULT PARAMETER FILE. */
   char site_filename[100];	/* NAME OF LOCAL SITE PARAMETER FILE. */
   int option;			/* OPTION CHARACTER. */

   extern int optind;		/* ARGV INDEX OF NEXT OPTION TO PROCESS. */
   extern int opterr;		/* ERROR CONTROL FOR OPTION PROCESSING. */
   extern char *optarg;		/* OPTION ARGUMENT. */
   int getopt();		/* GET OPTION LETTER FROM ARGUMENT VECTOR. */
   char* getenv();		/* GET ENVIRONMENT NAME VALUE. */

   /* CHECK PROPER USAGE. */
   if (argc>4 || argc<2)
      {
      printf("Usage: mm2_params [-a] [-d] {mm2/mm3 output file containing errors}\n");
      printf("       -a = automatically take all parameters found.\n");
      printf("       -d = debug printing on.\n");
      return(FALSE);
      }

   opterr=0;	/* DISABLE ERROR MESSAGE ON BAD OPTION (SIMPLY IGNORE). */
   debug_on=auto_take=FALSE;
   while ((option=getopt(argc,argv,"ad")) != -1)
      {
      if (option=='a') auto_take=TRUE;
      else if (option=='d') debug_on=TRUE;
      }

   /* FORM THE NAME OF THE MM2/MM3 OUTPUT FILE (WHICH CONTAINS THE ERRORS), */
   /* AND DETERMINE THE NAME OF THE ORIGINATING PROGRAM. */
   strcpy(error_filename,argv[optind]);
   new_extension(error_filename,".out");
   if (strstr(error_filename,"_mm2")!=NULL) strcpy(program,"mm2");
   else if (strstr(error_filename,"_mm3")!=NULL) strcpy(program,"mm3");
   else
      {
      printf("Error: Illegal MM2/MM3 output file name \"%s\".\n",error_filename);
      return(FALSE);
      }
   if (access(error_filename,READ_ACCESS)!=0)
      {
      printf("Error: Cannot read MM2/MM3 output file \"%s\".\n",error_filename);
      return(FALSE);
      }

   /* GET THE MOLECULE STRUCTURE FROM THE ORIGINAL MM2/MM3 INPUT FILE. */
   strcpy(struct_filename,error_filename);
   *strrchr(struct_filename,'_')=0;	/* TRUNCATE "_MM2.OUT". */
   if (strcmp(program,"mm2")==0)
      new_extension(struct_filename,".mm2");
   else
      new_extension(struct_filename,".mm3");
   if (!read_mm2_input(struct_filename)) return(FALSE);

   /* READ THE BUILTIN DEFAULT (CAME WITH MM2 PROGRAM) PARAMETERS. */
   strcpy(builtin_filename,getenv("LOCAL_DATA"));
   if (strcmp(program,"mm2")==0)
      {
      strcat(builtin_filename,"/mm2.builtin_parameters");
      if (!read_default_mm2_params(builtin_filename)) return(FALSE);
      }
   else
      {
      strcat(builtin_filename,"/KONST89.MM3");
      if (!read_default_mm3_params(builtin_filename)) return(FALSE);
      }

   /* READ THE LOCAL SITE (LOCALLY OPTIMIZED) PARAMETERS. */
   strcpy(site_filename,getenv("LOCAL_DATA"));
   if (strcmp(program,"mm2")==0)
      strcat(site_filename,"/mm2.site_parameters");
   else
      strcat(site_filename,"/mm3.site_parameters");
   if (!read_local_params(site_filename)) return(FALSE);

   /* FORM THE NAME OF THE NEW INPUT PARAMETER FILE TO BE CREATED. */
   strcpy(param_filename,error_filename);
   *strrchr(param_filename,'_')=0;	/* TRUNCATE "_MM2.OUT". */
   new_extension(param_filename,".para");

   return(TRUE);
   }

int read_mm2_input(struct_filename)
/*============================================================================*/
/* PURPOSE: READ IN MOLECULE STRUCTURE (CONNECTIVITY) FROM AN MM2 INPUT FILE.
*/
   char struct_filename[];	/* NAME OF MM2 INPUT (STRUCTURE) FILE. */
   {
   FILE* struct_file;		/* OPENED MM2 INPUT FILE. */
   char line[130];		/* RAW LINE FROM MM2 INPUT FILE. */
   int method;			/* FLAG; WHETHER PI SYSTEM INFO PRESENT. */
   int nconnected_atom_lists;	/* NUMBER OF CONNECTED ATOM LISTS. */
   int nattached_atoms;		/* NUMBER OF ATTACHED ATOMS. */
   int i;			/* LOOP INDEX. */

   /* OPEN THE SPECIFIED MM2 INPUT STRUCTURE FILE. */
   if ((struct_file=fopen(struct_filename,"r"))==NULL)
      {
      printf("Error: Cannot read MM2/MM3 input file \"%s\".\n",struct_filename);
      return(FALSE);
      }

   /* GET THE METHOD AND NUMBER OF ATOMS. */
   if (fgets(line,sizeof line,struct_file)==NULL)
      return(errmsg("Reading MM2/MM3 input file (number of atoms)",FALSE));
   sscanf(&line[60],"%1d%4d",&method,&natoms);

   /* SKIP THE AROMATIC FLAGS (THIS MAY CONTINUE ACROSS MULTIPLE CARDS). */
   if (method)
      {
      do
         {
         if (fgets(line,sizeof line,struct_file)==NULL)
            return(errmsg("Reading MM2/MM3 input file (aromatic flags)",FALSE));
         } while (line[79]=='1');
      }

   /* GET NUMBER OF CONNECTED ATOM LISTS AND NUMBER OF ATTACHED ATOMS. */
   if (fgets(line,sizeof line,struct_file)==NULL)
      return(errmsg("Reading MM2/MM3 input file (number of atom lists)",FALSE));
   sscanf(line,"%5d %*f %5d",&nconnected_atom_lists,&nattached_atoms);

   /* BUILD THE BONDS BY READING IN THE CONNECTED AND ATTACHED ATOM LISTS. */
   for (i=0; i=MAX_BONDS_PER_ATOM || connect[second_atom].nbonds>=MAX_BONDS_PER_ATOM)
         return(errmsg("Too many bonds to a single atom",FALSE));
      connect[first_atom].bonds[connect[first_atom].nbonds++] = second_atom;
      connect[second_atom].bonds[connect[second_atom].nbonds++] = first_atom;
      }

   return(TRUE);
   }

int process_attached_atom_list(line)
/*============================================================================*/
/* PURPOSE: PROCESS AN MM2 ATTACHED ATOM LIST INTO THE INDIVIDUAL BONDS.
/*	NOTE THAT EACH PAIR IS COMPLETELY INDEPENDENT.
*/
   char line[];		/* RAW ATTACHED ATOM LIST FROM MM2 INPUT FILE. */
   {
   int i;		/* INDEX OF FIRST ATOM OF PAIR IN LINE. */
   int first_atom;	/* FIRST ATOM OF VALID PAIR. */
   int second_atom;	/* SECOND ATOM OF VALID PAIR. */

   /* TAKE APART AN ATTACHED ATOM LIST AN ATOM PAIR AT A TIME. */
   i=0;
   while (i<15 && atoi(&line[i*5])!=0)
      {
      /* GET THE VALID ATOM PAIR. */
      sscanf(&line[i*5],"%5d%5d",&first_atom,&second_atom);
      first_atom--;	/* ADJUST TO INDEX FROM 0 (MM2 COUNTS FROM 1). */
      second_atom--;
      i+=2;		/* FINISHED THIS PAIR, MOVE AHEAD TO NEXT. */

      /* ADD THE BONDS TO EACH ATOM'S RESPECTIVE BOND LIST. */
      if (connect[first_atom].nbonds>=MAX_BONDS_PER_ATOM || connect[second_atom].nbonds>=MAX_BONDS_PER_ATOM)
         return(errmsg("Too many bonds to a single atom",FALSE));
      connect[first_atom].bonds[connect[first_atom].nbonds++] = second_atom;
      connect[second_atom].bonds[connect[second_atom].nbonds++] = first_atom;
      }

   return(TRUE);
   }

int read_default_mm2_params(builtin_filename)
/*============================================================================*/
/* PURPOSE: READ IN ALL NEEDED DEFAULT PARAMETERS FOR MM2.
*/
   char builtin_filename[];	/* NAME OF THE BUILTIN PARAMETER FILE. */
   {
   FILE* builtin_file;		/* FILE DESCRIPTOR FOR KNOWN PARAMETER FILE. */
   char line[100];		/* RAW LINE FROM PARAMETER FILE. */

   builtin_file=fopen(builtin_filename,"r");

   /* FIND THE START OF THE REGULAR (NON SPECIAL) TORSIONAL PARAMETERS, */
   /* THEN SUCK UP REGULAR TORSION PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"TORSIONAL PARAMETERS",line,sizeof line);
   find_line(builtin_file,"ANGLE           V1",line,sizeof line);
   while (!find_string(fgets(line,sizeof line,builtin_file),"4-MEMBERED RING"))
      {
      /* SKIP BLANK, FORTRAN CONTROL, AND EXTRA COLUMN HEADER LINES. */
      if (strlen(line)>1 && line[0]!='+' && line[0]!='1' && line[0]!='0' && !find_string(line,"ANGLE"))
         {
         sscanf(line,"%*d %d-%d-%d-%d %lf %lf %lf",
            &torsion_params_normal[ntorsion_params_normal].atom_types[0],
            &torsion_params_normal[ntorsion_params_normal].atom_types[1],
            &torsion_params_normal[ntorsion_params_normal].atom_types[2],
            &torsion_params_normal[ntorsion_params_normal].atom_types[3],
            &torsion_params_normal[ntorsion_params_normal].v1,
            &torsion_params_normal[ntorsion_params_normal].v2,
            &torsion_params_normal[ntorsion_params_normal].v3);
         ntorsion_params_normal++;
         }
      }

   /* NOW AT START OF 4 MEMBERED RING TORSION PARAMETERS, SKIP TO DATA, */
   /* THEN SUCK UP 4 MEMBER TORSIONAL PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"ANGLE           V1",line,sizeof line);
   while (!find_string(fgets(line,sizeof line,builtin_file),"ALLENES"))
      {
      /* SKIP BLANK, FORTRAN CONTROL, AND EXTRA COLUMN HEADER LINES. */
      if (strlen(line)>1 && line[0]!='+' && line[0]!='1' && line[0]!='0' && !find_string(line,"ANGLE"))
         {
         sscanf(line,"%*d %d-%d-%d-%d %lf %lf %lf",
            &torsion_params_4ring[ntorsion_params_4ring].atom_types[0],
            &torsion_params_4ring[ntorsion_params_4ring].atom_types[1],
            &torsion_params_4ring[ntorsion_params_4ring].atom_types[2],
            &torsion_params_4ring[ntorsion_params_4ring].atom_types[3],
            &torsion_params_4ring[ntorsion_params_4ring].v1,
            &torsion_params_4ring[ntorsion_params_4ring].v2,
            &torsion_params_4ring[ntorsion_params_4ring].v3);
         ntorsion_params_4ring++;
         }
      }

   /* NOW AT START OF ALLENES TORSION PARAMETERS, SKIP TO DATA, THEN */
   /* SUCK UP ALLENES TORSIONAL PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"ANGLE           V1",line,sizeof line);
   while (!find_string(fgets(line,sizeof line,builtin_file),"MM2 (1987)"))
      {
      /* SKIP BLANK, FORTRAN CONTROL, AND EXTRA COLUMN HEADER LINES. */
      if (strlen(line)>1 && line[0]!='+' && line[0]!='1' && line[0]!='0' && !find_string(line,"ANGLE"))
         {
         sscanf(line,"%*d %d-%d-%d-%d %lf %lf %lf",
            &torsion_params_allene[ntorsion_params_allene].atom_types[0],
            &torsion_params_allene[ntorsion_params_allene].atom_types[1],
            &torsion_params_allene[ntorsion_params_allene].atom_types[2],
            &torsion_params_allene[ntorsion_params_allene].atom_types[3],
            &torsion_params_allene[ntorsion_params_allene].v1,
            &torsion_params_allene[ntorsion_params_allene].v2,
            &torsion_params_allene[ntorsion_params_allene].v3);
         ntorsion_params_allene++;
         }
      }

   /* FIND THE START OF THE BOND PARAMETERS, THEN */
   /* SUCK UP BOND PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"STRETCHING PARAMETERS",line,sizeof line);
   find_line(builtin_file,"BOND         KS",line,sizeof line);
   while (!find_string(fgets(line,sizeof line,builtin_file),"4-MEMBERED RING"))
      {
      /* SKIP BLANK, FORTRAN CONTROL, AND EXTRA COLUMN HEADER LINES. */
      if (strlen(line)>1 && line[0]!='+' && line[0]!='1' && line[0]!='0' && !find_string(line,"BOND"))
         {
         sscanf(line,"%*d %d-%d %lf %lf %lf %lf %lf",
            &bond_params[nbond_params].atom_types[0],
            &bond_params[nbond_params].atom_types[1],
            &bond_params[nbond_params].s,
            &bond_params[nbond_params].l0,
            &bond_params[nbond_params].bmom,
            &bond_params[nbond_params].slps,
            &bond_params[nbond_params].slpt);

         /* BONDS MARKED WITH 999 ARE PLACE HOLDERS AND ARE INVALID. */
         if (bond_params[nbond_params].s < 999.0) nbond_params++;
         }
      }

   /* FIND THE START OF THE REGULAR (NON SPECIAL) ANGLE PARAMETERS, THEN */
   /* SUCK UP ANGLE PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"BENDING PARAMETERS",line,sizeof line);
   find_line(builtin_file,"ANGLE         KS",line,sizeof line);
   find_line(builtin_file,"(-CR2-)",line,sizeof line);
   while (!find_string(fgets(line,sizeof line,builtin_file),"TYPE-2 BENDING KS"))
      {
      /* SKIP BLANK, FORTRAN CONTROL, AND EXTRA COLUMN HEADER LINES. */
      if (strlen(line)>1 && line[0]!='+' && line[0]!='1' && line[0]!='0' &&
         !find_string(line,"ANGLE") && !find_string(line,"(-CR2-)"))
         {
         sscanf(line,"%*d %d-%d-%d %lf %lf",
            &angle_params_normal[nangle_params_normal].atom_types[0],
            &angle_params_normal[nangle_params_normal].atom_types[1],
            &angle_params_normal[nangle_params_normal].atom_types[2],
            &angle_params_normal[nangle_params_normal].b,
            &angle_params_normal[nangle_params_normal].t);

         /* ANGLES MARKED WITH 99 ARE PLACE HOLDERS AND ARE INVALID. */
         if (angle_params_normal[nangle_params_normal].b < 99.0) nangle_params_normal++;
         }
      }

   /* FIND THE START OF THE 4-MEMBERED RING ANGLE PARAMETERS, THEN */
   /* SUCK UP 4-MEMBERED RING ANGLE PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"4-MEMBERED RING",line,sizeof line);
   find_line(builtin_file,"ANGLE         KS",line,sizeof line);
   find_line(builtin_file,"(-CR2-)",line,sizeof line);
   while (!find_string(fgets(line,sizeof line,builtin_file),"TYPE-2 BENDING KS"))
      {
      /* SKIP BLANK, FORTRAN CONTROL, AND EXTRA COLUMN HEADER LINES. */
      if (strlen(line)>1 && line[0]!='+' && line[0]!='1' && line[0]!='0' &&
         !find_string(line,"ANGLE") && !find_string(line,"(-CR2-)"))
         {
         sscanf(line,"%*d %d-%d-%d %lf %lf",
            &angle_params_4ring[nangle_params_4ring].atom_types[0],
            &angle_params_4ring[nangle_params_4ring].atom_types[1],
            &angle_params_4ring[nangle_params_4ring].atom_types[2],
            &angle_params_4ring[nangle_params_4ring].b,
            &angle_params_4ring[nangle_params_4ring].t);
         nangle_params_4ring++;
         }
      }

   /* FIND THE START OF THE 3-MEMBERED RING ANGLE PARAMETERS, THEN */
   /* SUCK UP 3-MEMBERED RING ANGLE PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"3-MEMBERED RING",line,sizeof line);
   while (!find_string(fgets(line,sizeof line,builtin_file),"TYPE-2 BENDING KS"))
      {
      /* SKIP BLANK, FORTRAN CONTROL, AND EXTRA COLUMN HEADER LINES. */
      if (strlen(line)>1 && line[0]!='+' && line[0]!='1' && line[0]!='0' &&
         !find_string(line,"ANGLE") && !find_string(line,"(-CR2-)"))
         {
         sscanf(line,"%*d %d-%d-%d %lf %lf",
            &angle_params_3ring[nangle_params_3ring].atom_types[0],
            &angle_params_3ring[nangle_params_3ring].atom_types[1],
            &angle_params_3ring[nangle_params_3ring].atom_types[2],
            &angle_params_3ring[nangle_params_3ring].b,
            &angle_params_3ring[nangle_params_3ring].t);
         nangle_params_3ring++;
         }
      }

   /* FIND THE START OF THE OUT OF PLANE PARAMETERS, THEN */
   /* SUCK UP OUT OF PLANE PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"OUT-OF-PLANE BENDING PARAMETERS",line,sizeof line);
   while (!find_string(fgets(line,sizeof line,builtin_file),"STRETCH-BEND"))
      {
      /* SKIP BLANK AND FORTRAN CONTROL LINES. */
      if (strlen(line)>1 && line[0]!='+' && line[0]!='1' && line[0]!='0')
         {
         outofplane_params[noutofplane_params].atom_types[0]=0;
         sscanf(line,"%*d %d-%d %lf",
            &outofplane_params[noutofplane_params].atom_types[1],
            &outofplane_params[noutofplane_params].atom_types[2],
            &outofplane_params[noutofplane_params].b);
         noutofplane_params++;
         }
      }

   /* DONE READING BUILT IN DEFAULT PARAMETERS, CLOSE THE FILE AND RETURN. */
   fclose(builtin_file);
   return(TRUE);
   }

int read_default_mm3_params(builtin_filename)
/*============================================================================*/
/* PURPOSE: READ IN ALL NEEDED DEFAULT PARAMETERS FOR MM3.  NOTE SLIGHT
/*	TRICKERY WITH ATOM TYPES - THEY ARE PACKED ########, BUT THE FIRST
/*	DIGIT MAY BE BLANK (WHICH PRECLUDES USING SSCANF DIRECTLY).
*/
   char builtin_filename[];	/* NAME OF THE BUILTIN PARAMETER FILE. */
   {
   FILE* builtin_file;		/* FILE DESCRIPTOR FOR KNOWN PARAMETER FILE. */
   char line[100];		/* RAW LINE FROM PARAMETER FILE. */
   char packed_atom_types[20];	/* ATOM TYPES PACKED AS ########. */
   char tmp_str[20];		/* TEMP STRING FOR STRNCPY. */

   builtin_file=fopen(builtin_filename,"r");

   /* FIND THE START OF THE REGULAR (NON SPECIAL) TORSIONAL PARAMETERS, */
   /* THEN SUCK UP REGULAR TORSION PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"TORSIONAL PARAMETERS",line,sizeof line);
   find_line(builtin_file,"--------------------",line,sizeof line);
   find_line(builtin_file,"--------------------",line,sizeof line);
   while (fgets(line,sizeof line,builtin_file) && line[0]!=MM3_END_OF_SECTION)
      {
      sscanf(line,"%*d %8c %lf %lf %lf",
         packed_atom_types,
         &torsion_params_normal[ntorsion_params_normal].v1,
         &torsion_params_normal[ntorsion_params_normal].v2,
         &torsion_params_normal[ntorsion_params_normal].v3);
      torsion_params_normal[ntorsion_params_normal].atom_types[0]=atoi(strncpy(tmp_str,packed_atom_types,2));
      torsion_params_normal[ntorsion_params_normal].atom_types[1]=atoi(strncpy(tmp_str,&packed_atom_types[2],2));
      torsion_params_normal[ntorsion_params_normal].atom_types[2]=atoi(strncpy(tmp_str,&packed_atom_types[4],2));
      torsion_params_normal[ntorsion_params_normal].atom_types[3]=atoi(strncpy(tmp_str,&packed_atom_types[6],2));
      ntorsion_params_normal++;
      }

   /* SKIP 5 MEMBERED RING SECTION TO GET TO THE START OF THE 4 MEMBERED RING */
   /* TORSION PARAMETERS, SKIP TO DATA, THEN SUCK UP 4 MEMBER TORSIONAL */
   /* PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"4-MEMBERED RING",line,sizeof line);
   find_line(builtin_file,"--------------------",line,sizeof line);
   while (fgets(line,sizeof line,builtin_file) && line[0]!=MM3_END_OF_SECTION)
      {
      sscanf(line,"%*d %8c %lf %lf %lf",
         packed_atom_types,
         &torsion_params_4ring[ntorsion_params_4ring].v1,
         &torsion_params_4ring[ntorsion_params_4ring].v2,
         &torsion_params_4ring[ntorsion_params_4ring].v3);
      torsion_params_4ring[ntorsion_params_4ring].atom_types[0]=atoi(strncpy(tmp_str,packed_atom_types,2));
      torsion_params_4ring[ntorsion_params_4ring].atom_types[1]=atoi(strncpy(tmp_str,&packed_atom_types[2],2));
      torsion_params_4ring[ntorsion_params_4ring].atom_types[2]=atoi(strncpy(tmp_str,&packed_atom_types[4],2));
      torsion_params_4ring[ntorsion_params_4ring].atom_types[3]=atoi(strncpy(tmp_str,&packed_atom_types[6],2));
      ntorsion_params_4ring++;
      }

   /* FIND START OF ALLENES TORSION PARAMETERS, SKIP TO DATA, THEN */
   /* SUCK UP ALLENES TORSIONAL PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"ALLENES",line,sizeof line);
   find_line(builtin_file,"--------------------",line,sizeof line);
   while (fgets(line,sizeof line,builtin_file) && line[0]!=MM3_END_OF_SECTION)
      {
      sscanf(line,"%*d %8c %lf %lf %lf",
         packed_atom_types,
         &torsion_params_allene[ntorsion_params_allene].v1,
         &torsion_params_allene[ntorsion_params_allene].v2,
         &torsion_params_allene[ntorsion_params_allene].v3);
      torsion_params_allene[ntorsion_params_allene].atom_types[0]=atoi(strncpy(tmp_str,packed_atom_types,2));
      torsion_params_allene[ntorsion_params_allene].atom_types[1]=atoi(strncpy(tmp_str,&packed_atom_types[2],2));
      torsion_params_allene[ntorsion_params_allene].atom_types[2]=atoi(strncpy(tmp_str,&packed_atom_types[4],2));
      torsion_params_allene[ntorsion_params_allene].atom_types[3]=atoi(strncpy(tmp_str,&packed_atom_types[6],2));
      ntorsion_params_allene++;
      }

   /* FIND THE START OF THE BOND PARAMETERS, THEN */
   /* SUCK UP BOND PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"BOND PARAMETERS",line,sizeof line);
   find_line(builtin_file,"--------------------",line,sizeof line);
   find_line(builtin_file,"--------------------",line,sizeof line);
   while (fgets(line,sizeof line,builtin_file) && line[0]!=MM3_END_OF_SECTION)
      {
      sscanf(line,"%*d %4c %lf %lf %lf %lf %lf",
         packed_atom_types,
         &bond_params[nbond_params].s,
         &bond_params[nbond_params].l0,
         &bond_params[nbond_params].bmom,
         &bond_params[nbond_params].slps,
         &bond_params[nbond_params].slpt);
      bond_params[nbond_params].atom_types[0]=atoi(strncpy(tmp_str,packed_atom_types,2));
      bond_params[nbond_params].atom_types[1]=atoi(strncpy(tmp_str,&packed_atom_types[2],2));

      /* BONDS MARKED WITH 999 ARE PLACE HOLDERS AND ARE INVALID. */
      if (bond_params[nbond_params].s < 999.0) nbond_params++;
      }

   /* FIND THE START OF THE REGULAR (NON SPECIAL) ANGLE PARAMETERS, THEN */
   /* SUCK UP ANGLE PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"BENDING PARAMETERS",line,sizeof line);
   find_line(builtin_file,"--------------------",line,sizeof line);
   find_line(builtin_file,"--------------------",line,sizeof line);
   while (fgets(line,sizeof line,builtin_file) && line[0]!=MM3_END_OF_SECTION)
      {
      sscanf(line,"%*d %6c %lf %lf",
         packed_atom_types,
         &angle_params_normal[nangle_params_normal].b,
         &angle_params_normal[nangle_params_normal].t);
      angle_params_normal[nangle_params_normal].atom_types[0]=atoi(strncpy(tmp_str,packed_atom_types,2));
      angle_params_normal[nangle_params_normal].atom_types[1]=atoi(strncpy(tmp_str,&packed_atom_types[2],2));
      angle_params_normal[nangle_params_normal].atom_types[2]=atoi(strncpy(tmp_str,&packed_atom_types[4],2));

      /* ANGLES MARKED WITH 99 ARE PLACE HOLDERS AND ARE INVALID. */
      if (angle_params_normal[nangle_params_normal].b < 99.0) nangle_params_normal++;
      }

   /* FIND THE START OF THE 4-MEMBERED RING ANGLE PARAMETERS, THEN */
   /* SUCK UP 4-MEMBERED RING ANGLE PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"4-MEMBERED RING",line,sizeof line);
   find_line(builtin_file,"--------------------",line,sizeof line);
   while (fgets(line,sizeof line,builtin_file) && line[0]!=MM3_END_OF_SECTION)
      {
      sscanf(line,"%*d %6c %lf %lf",
         packed_atom_types,
         &angle_params_4ring[nangle_params_4ring].b,
         &angle_params_4ring[nangle_params_4ring].t);
      angle_params_4ring[nangle_params_4ring].atom_types[0]=atoi(strncpy(tmp_str,packed_atom_types,2));
      angle_params_4ring[nangle_params_4ring].atom_types[1]=atoi(strncpy(tmp_str,&packed_atom_types[2],2));
      angle_params_4ring[nangle_params_4ring].atom_types[2]=atoi(strncpy(tmp_str,&packed_atom_types[4],2));
      nangle_params_4ring++;
      }

   /* FIND THE START OF THE 3-MEMBERED RING ANGLE PARAMETERS, THEN */
   /* SUCK UP 3-MEMBERED RING ANGLE PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"3-MEMBERED RING",line,sizeof line);
   find_line(builtin_file,"--------------------",line,sizeof line);
   while (fgets(line,sizeof line,builtin_file) && line[0]!=MM3_END_OF_SECTION)
      {
      sscanf(line,"%*d %6c %lf %lf",
         packed_atom_types,
         &angle_params_3ring[nangle_params_3ring].b,
         &angle_params_3ring[nangle_params_3ring].t);
      angle_params_3ring[nangle_params_3ring].atom_types[0]=atoi(strncpy(tmp_str,packed_atom_types,2));
      angle_params_3ring[nangle_params_3ring].atom_types[1]=atoi(strncpy(tmp_str,&packed_atom_types[2],2));
      angle_params_3ring[nangle_params_3ring].atom_types[2]=atoi(strncpy(tmp_str,&packed_atom_types[4],2));
      nangle_params_3ring++;
      }

   /* FIND THE START OF THE OUT OF PLANE PARAMETERS, THEN */
   /* SUCK UP OUT OF PLANE PARAMETERS UNTIL END OF SECTION. */
   find_line(builtin_file,"OUT OF PLANE BENDING PARAMETERS",line,sizeof line);
   find_line(builtin_file,"--------------------",line,sizeof line);
   find_line(builtin_file,"--------------------",line,sizeof line);
   while (fgets(line,sizeof line,builtin_file) && line[0]!=MM3_END_OF_SECTION)
      {
      sscanf(line,"%*d %4c %lf",
         packed_atom_types,
         &outofplane_params[noutofplane_params].b);
      outofplane_params[noutofplane_params].atom_types[0]=0;
      outofplane_params[noutofplane_params].atom_types[1]=atoi(strncpy(tmp_str,packed_atom_types,2));
      outofplane_params[noutofplane_params].atom_types[2]=atoi(strncpy(tmp_str,&packed_atom_types[2],2));
      noutofplane_params++;
      }

   /* DONE READING BUILT IN DEFAULT PARAMETERS, CLOSE THE FILE AND RETURN. */
   fclose(builtin_file);
   return(TRUE);
   }

int read_local_params(param_filename)
/*============================================================================*/
/* PURPOSE: READ IN LOCAL SITE PARAMETERS.  THESE ARE PARAMETERS
/*	THAT HAVE BEEN OPTIMIZED AT LOCAL SITE.
*/
   char param_filename[];	/* NAME OF THE LOCAL PARAMETER FILE. */
   {
   FILE* param_file;		/* FILE DESCRIPTOR FOR PARAMETER FILE. */
   char line[100];		/* RAW LINE FROM PARAMETER FILE. */
   int nparameters;		/* NUMBER OF PARAMETERS IN EACH SECTION. */
   int i;			/* LOOP INDEX. */

   /* PERFECTLY VALID NOT TO HAVE ANY LOCAL PARAMETER FILE. */
   if ((param_file=fopen(param_filename,"r"))==NULL) return(TRUE);

   /* READ NORMAL TORSION PARAMETERS. */
   get_data_line(param_file,line,sizeof line);
   sscanf(line,"%d",&nparameters);
   for (i=0; i=MAX_TRANSFORMS || original_atom_type<1) return(FALSE);
   else
      {
      /* VALID TRANSFORMATION REQUESTED; RETURN NEW TYPE AND COST IF DEFINED. */
      *new_atom_type=similar[original_atom_type-1][*transform_level][ATOM_TYPE];
      if (*new_atom_type==0) return(FALSE);
      else
         {
         /* THIS IS A DEFINED TRANSFORMATION; GET THE COST AND INCREMENT THE LEVEL FOR NEXT TIME. */
         *cost=similar[original_atom_type-1][*transform_level][COST];
         (*transform_level)++;
         return(TRUE);
         }
      }
   }

void write_parameters(param_filename)
/*============================================================================*/
/* PURPOSE: WRITE A CORRECTLY FORMATTED MM2/MM3 PARAMETER FILE CONTAINING ALL
/*	THE NEW PARAMETERS.  LINE DESCRIPTIONS ARE VERBATIM FROM THE MM2(87)
/*	QCPE PROGRAM MANUAL.
*/
   char param_filename[];	/* NEW PARAMETER FILE NAME. */
   {
   FILE* param_file;		/* NEW PARAMETER FILE. */
   char env_flag;		/* ORIGINAL ENVIRONMENT FLAG (LINES 9A,9F). */
   int i;			/* LOOP INDEX. */

   param_file=fopen(param_filename,"w");

   /* WRITE LINE 9 (CHANGED CONSTANTS). */
   fprintf(param_file,"%5d%5d%2d%3d%5d%5d%5d%5d%5d\n",
      ntorsion_errors,nbond_errors,0,0,nangle_errors+noutofplane_errors,nbond_errors,0,0,0);

   /* WRITE LINES 9A (TORSIONAL CONSTANTS). */
   for (i=0; i
  
Modified: Tue Apr 14 16:00:00 1992 GMT
Page accessed 1853 times since Sat Apr 17 21:32:58 1999 GMT