Example #1
0
void Add_Tip3_Prm_File(void)
{
	FILE *fOut;
	char *ReadLine, ErrorMsg[256];
	int i;

	Found_Improper = 0;
	fOut = fopen(szPrmFile, "r");
	if(fOut == NULL)	{
		sprintf(ErrorMsg, "Error in open file: %s\nQuit\n", szPrmFile);
		Quit_With_Error_Msg(ErrorMsg);
	}
	else	{
		n_Line = 0;

		while(1)	{
			if(feof(fOut))	{
				break;
			}
			ReadLine = fgets(szTxtPrm[n_Line], MAX_LEN, fOut);
			To_Upper_Case(szTxtPrm[n_Line]);
			if(ReadLine == NULL)	{
				break;
			}
			else	{
				if(strncmp(szTxtPrm[n_Line], "BOND", 4)==0)	{
					sprintf(szTxtPrm[n_Line], "BONDS\n");			// rename "BOND" to "BONDS"
				}
				else if(strncmp(szTxtPrm[n_Line], "ANGLE", 5)==0)	{
					sprintf(szTxtPrm[n_Line], "ANGLES\n");			// rename "ANGLE" to "ANGLES"
					Line_Insert_Bond = n_Line;
				}
				else if(strncmp(szTxtPrm[n_Line], "DIHEDRAL", 8)==0)	{
					sprintf(szTxtPrm[n_Line], "DIHEDRALS\n");			// rename "DIHEDRAL" to "DIHEDRALS"
					Line_Insert_Angle = n_Line;
				}
				else if(strncmp(szTxtPrm[n_Line], "IMPHI", 5)==0)	{
					Found_Improper = 1;
					sprintf(szTxtPrm[n_Line], "IMPROPERS\n");			// rename "IMPHI" to "IMPROPERS"
				}
				else if(strncmp(szTxtPrm[n_Line], "IMPROPER", 8)==0)	{
					Found_Improper = 1;
					sprintf(szTxtPrm[n_Line], "IMPROPERS\n");			// rename "IMPHI" to "IMPROPERS"
				}
				else if(strncmp(szTxtPrm[n_Line], "NONBONDED", 9)==0)	{
					Line_Insert_Impropers = n_Line;
				}

				if(strncmp(szTxtPrm[n_Line], "END", 3)==0)	{
					continue;
				}

				n_Line++;
				if(n_Line >= MAX_LINE)	{
					sprintf(ErrorMsg, "n_Line >= MAX_LINE\nQuit\n");
					fclose(fOut);
					Quit_With_Error_Msg(ErrorMsg);
				}
			}
		}
		fclose(fOut);
	}

	fOut = fopen(szPrmFile, "w");
	for(i=0; i<n_Line; i++)	{
		if(i == Line_Insert_Bond)	{
			fprintf(fOut, "HT_W   HT_W      0.000     1.5139 ! FROM TIPS3P GEOMETRY (FOR SHAKE/W PARAM)\n");
			fprintf(fOut, "OT_W   HT_W    450.000     0.9572 ! FROM TIPS3P GEOM\n\n");
		}
		else if(i == Line_Insert_Angle)	{
			fprintf(fOut, "HT_W   OT_W   HT_W     55.000   104.5200 ! TIP3P GEOMETRY\n\n");
		}
		else if( (Found_Improper==0) && (i==Line_Insert_Impropers) )	{	// add the entry for IMPROPERS
			fprintf(fOut, "IMPROPERS\n\n");
		}

		if(FindString(szTxtPrm[i], "NONBONDED") >= 0)	{
			fprintf(fOut, "NONBONDED  E14FAC %9.6lf\n", E14FAC);
			continue;
		}
		else if(FindString(szTxtPrm[i], "NBXMOD") >= 0)	{
			continue;
		}
		else if(FindString(szTxtPrm[i], "CUTNB") >= 0)	{
			continue;
		}
		else if(FindString(szTxtPrm[i], "E14FAC") >= 0)	{
			continue;
		}
		else if(FindString(szTxtPrm[i], "WMIN") >= 0)	{
			continue;
		}

		fprintf(fOut, "%s", szTxtPrm[i]);
	}
	fprintf(fOut, "\nHT_W     0.000000  -0.046000     0.224500 ! TIP3P HYDROGEN PARAMETERS, adm jr., NBFIX obsolete\n");
	fprintf(fOut, "OT_W     0.000000  -0.152100     1.768200 ! TIP3P OXYGEN PARAMETERS, adm jr., NBFIX obsolete\n\n");
//	fprintf(fOut, "\n\nEND\n");

	fclose(fOut);
}
Example #2
0
int main(int argc, char **argv)
{
    char ErrorMsg[256];

    fFile_Run_Log = fopen(szName_Run_Log, "w");
    if(fFile_Run_Log==NULL)	{
        sprintf(ErrorMsg, "Fail to create the log file.\n\n");
        Quit_With_Error_Msg(ErrorMsg);
    }

    strcpy(szName_Conf_File, argv[1]);
    ReadConfFile(szName_Conf_File);

//	MPI_Init(&argc, &argv);
//	MPI_Comm_rank(MPI_COMM_WORLD, &ProgID);
//	MPI_Comm_size(MPI_COMM_WORLD, &nProc);


    ForceField.ReadForceField(szName_Force_Field);

    Mol_ESP.ReadPSF(szName_XPSF, 0);
    Read_Rtf_File();

    strcpy(Mol_ESP.MolName, Mol_ESP.ResName[0]);
    Mol_ESP.AssignForceFieldParameters(&ForceField);

    Read_Soft_DihedralList();

    Mol_ESP.Is_Phi_Psi_Constrained = 0;
    Mol_ESP.E_CMap_On = 0;

    Read_QM_Rotamer_Data();
//	Read_Tor_Para_1D_Fitting();

//	Assign_Torsion_Parameters();

//	Read_1D_Scan_QM_Data();

//	Cal_E_MM_Scaned();
    Cal_E_MM_Rotamer();

    Output_Rotamer_QM_MM();

//	fFitting = fopen("fitting.dat", "w");
//	Fitting_Torsion_Parameters();
//	fclose(fFitting);

//	FILE *fOut;
//	fOut = fopen("rotamer-E.dat", "w");
//	for(i=0; i<nRotamer; i++)	{
//		fprintf(fOut, "%d %lf %lf %lf\n", i+1, E_Rotamer_QM[i], E_Rotamer_MM[i], rmsd_Rotamer[i]);
//	}
//	fclose(fOut);

//	Cal_E_MM_QM_Diff(7);

//	for(i=0; i<n_Phi; i++)	{
//		Cal_E_MM_QM_Diff(i);
//	}

//	Fit_Torsion_Parameters(7);

//	fPara = fopen("torsion-para.dat", "w");
//	for(i=0; i<n_Phi; i++)	{
//		Fit_Torsion_Parameters(i);
//	}
//	fclose(fPara);


//	Geoometry_Optimization_With_Constraint(&Mol_ESP);

    fflush(fFile_Run_Log);


    fclose(fFile_Run_Log);

//	MPI_Finalize();

    return 0;
}
Example #3
0
void Cal_E_MM_QM_Diff(int Idx)
{
	FILE *fIn, *fOut;
	char szName[256], szLine[256], *ReadLine, szTmp[256], ErrorMsg[256];
	double E_QM_Min, E_MM_Min, E_MM_Read, E_MM_Cal;
	double Para_k_Dih_Save[6], Para_phi_Dih_Save[6];
	double x_Save[MAX_NUM_ATOM], y_Save[MAX_NUM_ATOM], z_Save[MAX_NUM_ATOM];
	int i, j, ReadItem, nAtom;

	memcpy(Para_k_Dih_Save, Mol_ESP.Para_k_Dih[IdxDihSelect[Idx]]+1, sizeof(double)*6);
	memcpy(Para_phi_Dih_Save, Mol_ESP.Para_phi[IdxDihSelect[Idx]]+1, sizeof(double)*6);
	memset(Mol_ESP.Para_k_Dih[IdxDihSelect[Idx]]+1, 0, sizeof(double)*6);	// turn of this dihedral
	memset(Mol_ESP.Para_phi[IdxDihSelect[Idx]]+1, 0, sizeof(double)*6);

	sprintf(szName, "tor-1D-idx-%d.dat", Idx+1);
	fIn = fopen(szName, "r");
	if(fIn == NULL)	{
		sprintf(ErrorMsg, "Fail to open file: %s\nQuit\n", szName);
		printf("%s", ErrorMsg);
		Quit_With_Error_Msg(ErrorMsg);
	}

	sprintf(szName, "mm-tor-1D-idx-%d.dat", Idx+1);	// the one with optimized geometry in MM force field
	fOut = fopen(szName, "w");

	nAtom = Mol_ESP.nAtom;
	nScan = 0;
	while(1)	{
		if(feof(fIn))	{
			break;
		}
		ReadLine = fgets(szLine, 256, fIn);
		if(ReadLine == NULL)	{
			break;
		}
		if(strncmp(szLine, "E_Scan", 6)==0)	{
			ReadItem = sscanf(szLine, "%s %lf %lf %s %lf", szTmp, &(E_QM_Scaned[nScan]), &E_MM_Read, szTmp, &(Phi_Scaned[nScan]));


			if(ReadItem != 5)	{
				sprintf(ErrorMsg, "Error in reading file: %s\nQuit\n", szName);
				Quit_With_Error_Msg(ErrorMsg);
			}

			ReadLine = fgets(szLine, 256, fIn);	// skip one line, "Coordinate"

			for(i=0; i<nAtom; i++)	{	// read one snapshot
				ReadLine = fgets(szLine, 256, fIn);
				ReadItem = sscanf(szLine, "%lf %lf %lf", &(Mol_ESP.x[i]), &(Mol_ESP.y[i]), &(Mol_ESP.z[i]));
			}
			E_MM_Cal = Mol_ESP.Cal_E(0);	// the nergy without optimization and dihedral term is turned off

			To_Setup_All_Dihedral_Constraint();
			E_MM_Scaned[nScan] = Geoometry_Optimization_With_Constraint(&Mol_ESP);	// do restrained geometry optimizatio. soft restraint on all dihedrals. Rigid restraints on soft dihedrals

			if(E_MM_Scaned[nScan] > (1.0E3+E_MM_Cal))	{	// not a valid configuration. Something wrong in the constrained optimization
        printf(" Bad configuration: %d %f %f\n", nScan, E_MM_Scaned[nScan], E_MM_Cal );
				continue;
			}

			memcpy(x_Save, Mol_ESP.x, sizeof(double)*nAtom);
			memcpy(y_Save, Mol_ESP.y, sizeof(double)*nAtom);
			memcpy(z_Save, Mol_ESP.z, sizeof(double)*nAtom);
			
			fprintf(fOut, "E_Scan %.13E %.13E Phi %.1lf\n", E_QM_Scaned[nScan], E_MM_Scaned[nScan], Phi_Scaned[nScan]);
			fprintf(fOut, "Coordinate\n");
			for(j=0; j<nAtom; j++)	{
				fprintf(fOut, "%14.6lf%14.6lf%14.6lf\n", x_Save[j], y_Save[j], z_Save[j]);
			}
			//		fprintf(fOut, "%.1lf %.6lf %.6lf %.6lf\n", Phi_Scaned[i], E_QM_Scaned[i], E_MM_Scaned[i], E_QM_Scaned[i] - E_MM_Scaned[i]);
			

			nScan++;
		}

	}


	fclose(fOut);

	fclose(fIn);

	E_QM_Min = E_MM_Min = 1.0E100;
	for(i=0; i<nScan; i++)	{
		if(E_QM_Min > E_QM_Scaned[i])	{
			E_QM_Min = E_QM_Scaned[i];
		}
		if(E_MM_Min > E_MM_Scaned[i])	{
			E_MM_Min = E_MM_Scaned[i];
		}
	}

	for(i=0; i<nScan; i++)	{
		E_QM_Scaned[i] = (E_QM_Scaned[i]-E_QM_Min)*HARTREE_To_KCAL;
		E_MM_Scaned[i] -= E_MM_Min;
		E_QM_MM_Diff[i] = E_QM_Scaned[i]-E_MM_Scaned[i];

		if(E_MM_Scaned[i] > 60.0)	{	// an unusual large MM energy
			w_Point[i] = 0.0;
		}
		else	{
			w_Point[i] = 1.0;
		}
	}

	printf(" There are %d conformers\n", nScan );
	for(i=0;i<nScan;i++) {
		printf("%5d %8.3f %8.3f %8.3f %8.3f %d\n", i, Phi_Scaned[i], E_QM_Scaned[i], E_MM_Scaned[i], E_QM_MM_Diff[i], w_Point[i]==1.0 );
	}


/*
	sprintf(szName, "qm-mm-diff-%d.dat", Idx+1);
	fOut = fopen(szName, "w");
	for(i=0; i<nScan; i++)	{
		E_QM_Scaned[i] = (E_QM_Scaned[i]-E_QM_Min)*HARTREE_To_KCAL;
		E_MM_Scaned[i] -= E_MM_Min;
		fprintf(fOut, "%.1lf %.6lf %.6lf\n", Phi_Scaned[i], E_QM_Scaned[i], E_QM_Scaned[i]-E_MM_Scaned[i]);
//		fprintf(fOut, "%.1lf %.12e %.6lf %.6lf\n", Phi_Scaned[i], E_QM_Scaned[i]);
//		fprintf(fOut, "%.1lf %.6lf %.6lf %.6lf\n", Phi_Scaned[i], E_QM_Scaned[i], E_MM_Scaned[i], E_QM_Scaned[i] - E_MM_Scaned[i]);
	}
	fclose(fOut);
*/


	memcpy(Mol_ESP.Para_k_Dih[IdxDihSelect[Idx]]+1, Para_k_Dih_Save, sizeof(double)*6);
	memcpy(Mol_ESP.Para_phi[IdxDihSelect[Idx]]+1, Para_phi_Dih_Save, sizeof(double)*6);
}
Example #4
0
void Add_Tip3_Rtf_File(void)
{
	FILE *fOut, *fIn;
	char ErrorMsg[256], szLine[256], *ReadLine, szBuff[256], szComment[256];
	int ReadItem;
	double net_cg_local=0.0;

	szTxt_Rtf[0] = 0;
	fIn = fopen(szRtfFile, "r");
	if(fIn == NULL)	{
		sprintf(ErrorMsg, "Error in open file: %s\nQuit\n", szRtfFile);
		Quit_With_Error_Msg(ErrorMsg);
	}
	else	{
		while(1)	{
			if(feof(fIn))	{
				break;
			}
			ReadLine = fgets(szLine, 256, fIn);
			if(ReadLine == NULL)	{
				break;
			}
			else	{
				if(strncmp(szLine,"RESI", 4)==0)	{
					ReadItem = sscanf(szLine, "%s%s%lf", szBuff, szBuff, &net_cg_local);
					if(ReadItem == 3)	{
						if(fabs(net_cg_local-net_charge) > 1.0E-1)	{
							Quit_With_Error_Msg("The charge in rtf is NOT consistent with the charge provided by user.\nQuit\n");
						}
						Extract_Comment(szLine, szComment);
						sprintf(szLine, "RESI  MOL  %6.3lf %s", net_cg_local, szComment);
					}
					else	{
						ReadItem = sscanf(szLine, "%s%lf", szBuff, &net_cg_local);
						if(ReadItem == 2)	{
							if(fabs(net_cg_local-net_charge) > 1.0E-1)	{
								Quit_With_Error_Msg("The charge in rtf is NOT consistent with the charge provided by user.\nQuit\n");
							}
							Extract_Comment(szLine, szComment);
							sprintf(szLine, "RESI  MOL  %6.3lf %s", net_cg_local, szComment);
						}
					}
				}
				if(strncmp(szLine, "END", 3)==0)	{
					continue;
				}
				else if(strncmp(szLine, "ANGL", 4)==0)	{
					continue;
				}
				else if(strncmp(szLine, "DIHE", 4)==0)	{
					continue;
				}
				strcat(szTxt_Rtf, szLine);
			}
		}
		fclose(fIn);
	}

	fOut = fopen(szRtfFile, "w");
	fprintf(fOut, "%s", szTxt_Rtf);

	fprintf(fOut, "\n\nMASS 101   HT_W    1.008000 H ! TIPS3P WATER HYDROGEN\n");
	fprintf(fOut, "MASS 102   OT_W   15.999400 O ! TIPS3P WATER OXYGEN\n\n");

	fprintf(fOut, "RESI TIP3         0.000 ! tip3p water model, generate using noangle nodihedral\n");
	fprintf(fOut, "GROUP\nATOM OH2  OT_W     -0.834\nATOM H1   HT_W      0.417\nATOM H2   HT_W      0.417\nBOND OH2 H1 OH2 H2 H1 H2    ! the last bond is needed for shake\nANGLE H1 OH2 H2             ! required\n");

	fprintf(fOut, "\n\nEND\n");

	fclose(fOut);
}
void Reorganize_QM_1D_Scan_Data(void)
{
	FILE *fIn, *fOut, *fQMStates;
	int i, j, i_Left, i_Right, Idx_Phi, nScan, nScan_Mapped, ReadItem, nAtom, To_Output[MAX_SCAN];
	char szName_Input[256], szName_Output[256], ErrorMsg[256], szLine[256], *ReadLine, szTmp[256];
	double x_List[MAX_SCAN][MAX_ATOM], y_List[MAX_SCAN][MAX_ATOM], z_List[MAX_SCAN][MAX_ATOM];
	double E_QM[MAX_SCAN], E_MM[MAX_SCAN], Phi[MAX_SCAN], Phi_Mapped[MAX_SCAN], E_QM_Mapped[MAX_SCAN], E_Min, E_Max, Phi_Ini, fTmp=0.0;
	int N_Rotamer_Total=1, nState, DoubleBond;

	RestoreCoordinates();

	nAtom = Mol.nAtom;
	fQMStates = fopen("qm-1d-states.dat", "w");
	for(Idx_Phi=0; Idx_Phi<n_Phi; Idx_Phi++)	{
		sprintf(szName_Input, "tor-1D-idx-%d.dat", Idx_Phi+1);
		sprintf(szName_Output, "new-tor-1D-idx-%d.dat", Idx_Phi+1);

		E_Min = 1.0E100;
		E_Max = -1.0E100;
		Phi_Ini = Mol.QueryDihedral(IdxDihSelect[Idx_Phi]);
		DoubleBond = Is_This_A_Double_Bond(DihList[Idx_Phi][1], DihList[Idx_Phi][2]);

		nScan = 0;
		fIn = fopen(szName_Input, "r");
		if(fIn == NULL)	{
			sprintf(ErrorMsg, "Fail to open file for read: %s\nQuit\n", szName_Input);
			Quit_With_Error_Msg(ErrorMsg);
		}
		while(1)	{
			if(feof(fIn))	{
				break;
			}
			ReadLine = fgets(szLine, 256, fIn);
			if(ReadLine == NULL)	{
				break;
			}
			if(strncmp(szLine, "E_Scan", 6) == 0)	{
				ReadItem = sscanf(szLine, "%s %lf %lf %s %lf", szTmp, &(E_QM[nScan]), &(E_MM[nScan]), szTmp, &(Phi[nScan]));
				if(ReadItem == 5)	{
					fgets(szLine, 256, fIn);
					for(i=0; i<nAtom; i++)	{
						fgets(szLine, 256, fIn);
						ReadItem = sscanf(szLine, "%lf %lf %lf", &(x_List[nScan][i]), &(y_List[nScan][i]), &(z_List[nScan][i]));
						if(ReadItem != 3)	{
							fclose(fIn);
							sprintf(ErrorMsg, "Error in readubg file: %s\nQuit\n", szName_Input);
							Quit_With_Error_Msg(ErrorMsg);
						}
					}
					if(E_QM[nScan] < E_Min)	{
						E_Min = E_QM[nScan];
					}
					if(E_QM[nScan] > E_Max)	{
						E_Max = E_QM[nScan];
					}


					nScan++;
				}
				else	{
					break;
				}
			}
		}
		fclose(fIn);


		for(i=0; i<nScan; i++)	{
			To_Output[i] = 1;
		}

		if( (Phi[0] > 0.0) && (Cal_Phi_Dist(Phi[0], -180.0) < 1.0) )	{	// +180.0 at the first point
			Phi[0] -= 360.0;
		}

		//start	to delete those redundant entries
		for(i=0; i<nScan; i++)	{
			for(j=i+1; j<nScan; j++)	{
				if(Cal_Phi_Dist(Phi[i], Phi[j]) < 1.0)	{	// the same dihedral
					if(Cal_Phi_Dist(Phi[j], -180.0) > 1.0)	{	// only -180, 180 can exist, others will be removed
						To_Output[j] = 0;
					}
				}
			}
		}
		//end	to delete those redundant entries

		//start	to set the correct sign of +180 if it exists as -180
		if(Cal_Phi_Dist(Phi[0], -180.0) < 1.0)	{	// starting with -180
			for(i=nScan-1; i>0; i--)	{
				if(To_Output[i] == 0)	{
					continue;
				}
				
				if( (Phi[i] < 0.0) && (Cal_Phi_Dist(Phi[i], -180.0) < 1.0) )	{
					Phi[i] += 360.0;
//					break;
				}
			}
		}
		//end	to set the correct sign of +180 if it exists as -180

//		fOut = fopen(szName_Output, "w");
		fOut = fopen(szName_Input, "w");	// to overwrite 
		for(j=0; j<nScan; j++)	{
			if(To_Output[j]==0)	{
				continue;
			}
			fprintf(fOut, "E_Scan %.13E %.13E  Phi  %.1lf\n", E_QM[j], E_MM[j], Phi[j]);
			fprintf(fOut, "Coordinate\n");
			for(i=0; i<nAtom; i++)	{
				fprintf(fOut, "%12.6lf %12.6lf %12.6lf\n", x_List[j][i], y_List[j][i], z_List[j][i]);
			}
		}
		
		fclose(fOut);

		//start	to identify QM local minima of each dihedral
		nScan_Mapped = 0;
		for(i=0; i<nScan; i++)	{
			if(To_Output[i])	{
				if(fabs(Phi[i]-180.0) > 3.0)	{	// +180 is excluded
					Phi_Mapped[nScan_Mapped] = Phi[i];
					E_QM_Mapped[nScan_Mapped] = E_QM[i];
					nScan_Mapped++;
				}
			}
		}
		if(nScan_Mapped < 3)	{
			sprintf(ErrorMsg, "nScan_Mapped < 3 for dihedral %d \nQuit\n", Idx_Phi+1);
			Quit_With_Error_Msg(ErrorMsg);
		}
		fprintf(fQMStates, "%3d %3d %3d %3d ", DihList[Idx_Phi][0]+1, DihList[Idx_Phi][1]+1, DihList[Idx_Phi][2]+1, DihList[Idx_Phi][3]+1);
		nState = 0;
		for(i=0; i<nScan_Mapped; i++)	{
			i_Left = (i+nScan_Mapped-1)%nScan_Mapped;
			i_Right = (i+nScan_Mapped+1)%nScan_Mapped;

			if( (DoubleBond) && ( ((E_Max-E_Min)*HARTREE_KCAL) > E_BARRIER_DOUBLE_BOND ) )	{
				fprintf(fQMStates, "  %.0lf", Phi_Ini);
				nState = 1;
				break;
			}

			if( (E_QM_Mapped[i] <= E_QM_Mapped[i_Left]) && (E_QM_Mapped[i] <= E_QM_Mapped[i_Right]) )	{	// a local minimum along QM 1D profile
				fprintf(fQMStates, "  %.0lf", Phi_Mapped[i]);
				nState++;
			}
		}
		fprintf(fQMStates, "\n");
		N_Rotamer_Total *= nState;
		//end	to identify QM local minima of each dihedral
	
	}

	fclose(fQMStates);

	fOut = fopen("n_rotamer.txt", "w");
	fprintf(fOut, "%d", N_Rotamer_Total);
	fclose(fOut);
}
void Extract_Coord_E(char szName[], int Idx_Phi, int Idx_Part)
{
	FILE *fIn, *fOut;
	int i, nAtom, ToRead=1, ReadItem, n_Rec=0;
	char szOutput[256], szErrorMsg[256], szLine[256], *ReadLine, szTag[256], ErrorMsg[256];
	double E_QM, E_MM, Phi, Phi_Set, x_Save[MAX_ATOM], y_Save[MAX_ATOM], z_Save[MAX_ATOM];

	nAtom = Mol.nAtom;
	memcpy(x_Save, Mol.x, sizeof(double)*nAtom);
	memcpy(y_Save, Mol.y, sizeof(double)*nAtom);
	memcpy(z_Save, Mol.z, sizeof(double)*nAtom);


	sprintf(szOutput, "tor-1D-idx-%d.dat", Idx_Phi+1);
	fOut = fopen(szOutput, "a+");
	fseek(fOut, 0, SEEK_END);

	fIn = fopen(szName, "r");
	if(fIn == NULL)	{
		sprintf(szErrorMsg, "Fail to open %s\nQuit\n", szName);
		Quit_With_Error_Msg(szErrorMsg);
	}


	while(ToRead)	{
		if(feof(fIn))	{
			break;
		}
		ReadLine = fgets(szLine, 256, fIn);
		if(ReadLine == NULL)	{
			break;
		}
		else	{
//			if(FindString(szLine, " Center     Atomic      Atomic")>=0)	{	// to extract the coordinate
//				Skip_N_Line(fIn, szName, 2);
//			if(FindString(szLine, "     Input orientation:")>=0)	{	// to extract the coordinate
			if(FindString(szLine, " orientation:")>=0)	{	// to extract the coordinate
				Skip_N_Line(fIn, szName, 4);
				for(i=0; i<nAtom; i++)	{
					ReadLine = fgets(szLine, 256, fIn);
					if(ReadLine == NULL)	{
						break;
					}
					ReadItem = sscanf(szLine+31, "%lf %lf %lf", &(Mol.x[i]), &(Mol.y[i]), &(Mol.z[i]));
					if(ReadItem != 3)	{
						ToRead = 0;
						break;
					}
				}
			}
			else if( (FindString(szLine, " SCF Done: ")>=0) && (QM_Level == QM_LEVEL_HF) )	{	// HF
				E_QM = Get_Energy(szLine);
			}
			else if( (FindString(szLine, "EUMP2 =")>=0) && (QM_Level == QM_LEVEL_MP2) )	{
				E_QM = Get_Energy(szLine+27);
			}
			else if(FindString(szLine, " Optimization completed")>=0)	{
				sprintf(szTag, "  D(%d,%d,%d,%d)", DihList[Idx_Phi][0]+1, DihList[Idx_Phi][1]+1, DihList[Idx_Phi][2]+1, DihList[Idx_Phi][3]+1);
				To_Find_Tag(fIn, szName, szTag, szLine);
				ReadItem = sscanf(szLine+28, "%lf", &Phi_Set);	// previous, modredundant
				if(ReadItem != 1)	{
					sprintf(ErrorMsg, "Error in extracting the dihedral.\n%s\nQuit\n", szLine);
					Quit_With_Error_Msg(ErrorMsg);
				}

				Phi = Mol.QueryDihedral(IdxDihSelect[Idx_Phi]);
				E_MM = Mol.Cal_E(0);

				fprintf(fOut, "E_Scan %.13E %.13E  Phi  %.1lf\n", E_QM, E_MM, Phi);
				fprintf(fOut, "Coordinate\n");
				for(i=0; i<nAtom; i++)	{
					fprintf(fOut, "%12.6lf %12.6lf %12.6lf\n", Mol.x[i], Mol.y[i], Mol.z[i]);
				}

				n_Rec++;
			}
		}
	}




	fclose(fOut);
	fclose(fIn);

	memcpy(Mol.x, x_Save, sizeof(double)*nAtom);
	memcpy(Mol.y, y_Save, sizeof(double)*nAtom);
	memcpy(Mol.z, z_Save, sizeof(double)*nAtom);
}
int main(int argc, char **argv)
{
	int i;
	FILE *fOut;
	char szName[256], *szEnv;

//	SetEnvironmentVariable(szGAUSS_SCRDIR, "c:\\1");

	fFile_Run_Log = fopen("qm-1d-scan.log", "w");
	
	szEnv = getenv(szGAUSS_SCRDIR);
	if (szEnv == NULL) {
		Quit_With_Error_Msg("Environment variable $GAUSS_SCRDIR is NOT set.\nQuit\n");
	}
	strcpy(szGAUSS_SCRDIR_Base, szEnv);
	


	Get_EXE_Path("G09_EXE_PATH", szExe_G09);

	n_Bins = 360/BIN_SIZE+1;


	ForceField.ReadForceField(szForceFiled);
	Mol.ReadPSF(szXpsfFile, 0);
	Get_Netcharge_From_Xpsf();
	Setup_QM_Level();
	ReadElementList();

	Mol.AssignForceFieldParameters(&ForceField);
	Mol.ReadCRD(szCrdFile);
	BackupCoordinates();

	Read_Soft_DihedralList();

	nJob = nJobDone = 0;

	for(Active_Phi=0; Active_Phi<n_Phi; Active_Phi++)	{
		RestoreCoordinates();
		for(i=0; i<n_Phi; i++)	{
			Phi_To_Set[i] = Mol.QueryDihedral(IdxDihSelect[i]);
			Mol.Edit_Dihedral(IdxDihSelect[i], Phi_To_Set[i]);
		}

		MM_Fixed_1D_Scan();
		E_Barrier_Lowest = Get_Barrier(E_Phi, n_Bins, E_Min, Phi_Save);
		E_Min_Save = E_Min;
		E_Min_Org = E_Min + E_RANGE;
		memcpy(E_Scan, E_Phi, sizeof(double)*n_Bins);
		memcpy(Phi_To_Set_Scan, Phi_To_Set, sizeof(double)*n_Phi);
		Phi_To_Set_Scan[Active_Phi] = Phi_Save;

		sprintf(szName, "ini-%d.dat", Active_Phi+1);
		fOut = fopen(szName, "w");
		for(i=0; i<n_Bins; i++)	{
			fprintf(fOut, "%5d %8.5E\n", -180+i*BIN_SIZE, E_Scan[i]-E_Min);
		}
		fclose(fOut);

		sprintf(szName, "ini-%d.pdb", Active_Phi+1);
		SaveOptPdb(szName);

		n_State_List[Active_Phi] = 1;
		Enumerate_Dihedrals(0);
		n_State_List[Active_Phi] = n_State_List_Save[Active_Phi];

		sprintf(szName, "end-%d.dat", Active_Phi+1);
		fOut = fopen(szName, "w");
		for(i=0; i<n_Bins; i++)	{
			fprintf(fOut, "%5d %8.5E\n", -180+i*BIN_SIZE, E_Scan[i]-E_Min_Save);
		}
		fclose(fOut);

		sprintf(szName, "end-%d.pdb", Active_Phi+1);
		SaveOptPdb(szName);

		sprintf(szName, "phi-%d.dat", Active_Phi+1);
		fOut = fopen(szName, "w");
		for(i=0; i<n_Phi; i++)	{
			fprintf(fOut, "%lf\n", Phi_To_Set_Scan[i]);
		}
		fclose(fOut);

	
		Output_Gaussian_File();
	}

	if(nJob > 0)	{
		RunAllJobs();
		Exatract_All_Info_QM_1D_Scan();
		Reorganize_QM_1D_Scan_Data();
	}

	fclose(fFile_Run_Log);

	return 0;
}
void CWORKER::Start_Job(int CoreNum, int ID, char szGjf[], char szOut[])
{
	char szCmd[256], szEnv[256], szErrorMsg[256];
	FILE *fIn;

	nCore = CoreNum;
	Status = BUSY;
	
	JobID = ID;
	strcpy(szInput, szGjf);
	strcpy(szOutput, szOut);

	sprintf(szEnv, "%s/%d", szGAUSS_SCRDIR_Base, ID);
#ifdef WIN32
	if( SetEnvironmentVariable(szGAUSS_SCRDIR, szEnv) == 0) {
#else
	if (setenv(szGAUSS_SCRDIR, szEnv, 1) < 0) {
#endif
		sprintf(szErrorMsg, "Error setting env for %s with ID = %d.\n", szGAUSS_SCRDIR, ID);
		Quit_With_Error_Msg(szErrorMsg);
	}

	sprintf(szCmd, "mkdir %s", szEnv);
	system(szCmd);

	Update_Core_Number_Input_File();
	
	sprintf(szCmd, "%s < %s > %s &", szExe_G09, szInput, szOutput);

	fIn = fopen(szOutput, "r");
	if(fIn == NULL)	{
		system(szCmd);
	}
	else	{
		fclose(fIn);
		Get_Job_Status();
	}
}

#define SIZE_CHECK	(512)
int CWORKER::Get_Job_Status(void)
{
	FILE *fIn;
	char szErrorMsg[256], szBuff[1024];
	int i, nLen;

	if(Status == IDLE)	{
		return Status;
	}

	fIn = fopen(szOutput, "rb");

	if(fIn == NULL)	{
		sprintf(szErrorMsg, "Error in open file %s for reading.\nQuit\n", szOutput);
		Quit_With_Error_Msg(szErrorMsg);
	}

	fseek(fIn, -SIZE_CHECK, SEEK_END);

	nLen = fread(szBuff, 1, SIZE_CHECK, fIn);

	for(i=0; i<nLen; i++)	{
		if(strncmp(szBuff+i, "Job cpu time:", 13) == 0)	{
			fclose(fIn);

			JobStatus[JobID] = Job_Done;
			Status = IDLE;
			nJobDone++;
			return Status;
		}
	}

	fclose(fIn);

	Status = BUSY;
	return Status;
}
void Setup_QM_Level(void)
{
	FILE *fIn;
	char *ReadLine, szLine[256], szSubStr_1[256], szSubStr_2[256], ErrorMsg[256];
	char szKey_QM_MEM[256], szKey_QM_NPROC[256], szQM_Level_Opt[256], szQM_Level_Dimer_Opt[256], szQM_Level_ESP[256], szQM_Level_E_Monomer[256], szQM_Level_1D_Scan[256];
	int nStr, KeyCount;

	fIn = fopen(szQMParaFile, "r");
	if(fIn == NULL)	{
		sprintf(ErrorMsg, "Fail to open file %s\nQuit\n", szQMParaFile);
		Quit_With_Error_Msg(ErrorMsg);
	}

	KeyCount = 0;
	while(1)	{
		if(feof(fIn))	{
			break;
		}
		ReadLine = fgets(szLine, 256, fIn);
		Replace_NewLine(szLine);
		if(ReadLine == NULL)	{
			break;
		}
		else	{
			nStr = Split_Into_Two_String(szLine, szSubStr_1, szSubStr_2);
			if(nStr == 2)	{
				if(strcmp(szSubStr_1,"QM_MEM")==0)	{
					strcpy(szKey_QM_MEM, szSubStr_2);
					KeyCount++;
				}
				else if(strcmp(szSubStr_1,"QM_NPROC")==0)	{
					strcpy(szKey_QM_NPROC, szSubStr_2);
					KeyCount++;
					nCore_Per_Node = atoi(szKey_QM_NPROC);
				}
				else if(strcmp(szSubStr_1,"QM_LEVEL_OPT")==0)	{
					strcpy(szQM_Level_Opt, szSubStr_2);
					KeyCount++;
				}
				else if(strcmp(szSubStr_1,"QM_LEVEL_DIMER_OPT")==0)	{
					strcpy(szQM_Level_Dimer_Opt, szSubStr_2);
					KeyCount++;
				}
				else if(strcmp(szSubStr_1,"QM_LEVEL_ESP")==0)	{
					strcpy(szQM_Level_ESP, szSubStr_2);
					KeyCount++;
				}
				else if(strcmp(szSubStr_1,"QM_LEVEL_E_MONOMER")==0)	{
					strcpy(szQM_Level_E_Monomer, szSubStr_2);
					KeyCount++;
				}
				else if(strcmp(szSubStr_1,"QM_LEVEL_1D_SCAN")==0)	{
					strcpy(szQM_Level_1D_Scan, szSubStr_2);
					KeyCount++;
				}
			}
		}
	}

	fclose(fIn);

	Determine_QM_Level(szQM_Level_1D_Scan);


	if(KeyCount != 7)	{	// !!!
		sprintf(ErrorMsg, "Setup_QM_Level> Error: incomplete entries in %s\nQuit\n", szQMParaFile);
		Quit_With_Error_Msg(ErrorMsg);
	}

	sprintf(szQM_Level_1D_Scan_Cmd, "%%mem=%s%%nproc=%s%sMol dihedral scan\n\n%d,1\n",
		szKey_QM_MEM, szKey_QM_NPROC, szQM_Level_1D_Scan, netcharge_mol);
//	printf("%s", szQM_Level_1D_Scan_Cmd);
}