/*============================================================================*/ /* 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