/**********************************************************
      Grid searching for L-G-F-T by fitting P-to-S phase (Ps) harmonic feature in receiver functions.
	    V1 (converted from bash version), By Mei Feng, 2024/07/03
	    V0 (bash version) By Mei Feng

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

#ifdef _OPENMP
#include <omp.h>
#endif

#include <cstdio>
#include <string>
#include <cmath>
#if defined(WIN32) || defined(MSVC)
	#include "mystds.h"     //General functions
	#include "Sac_head.h"
#else
	#include "mystds.h"     //General functions
	#include "Sac_head.h"
#endif

using namespace std;

struct Arguement
{
	string output_filename;
	string input_filename;
	string fepsi;
	double Wt[3];   //weights for the three objectives (Max Rsum, Max Rcc, Min Tsum)
	double Wd[2];   //left and right time shift for the Pms window
	double mo, ka, vpc, vpm; // a priori moho and kappa 
	double dL, dG, dF, dT, Gmx;            //grid steps for Lamda, Gama, Fai, Tau, and maximum for dipping angle Gama.
	bool no_openmp; //close openmp
};

struct sacRF
{
	int npts;
	double b, dt, baz;
	float *time;
	float *amp;
};


int get_argument(struct Arguement &argu, int argc, char**argv);

int main(int argc, char **argv)
{
	struct Arguement argu;
	get_argument(argu, argc, argv);

#ifdef _OPENMP
	if (argu.no_openmp == false)
		set_openmp_parallel_process_num();
#endif


	double rayp = 0.0576;
	double tPs = argu.mo * (sqrt((argu.ka/argu.vpc)*(argu.ka/argu.vpc) - rayp*rayp) - sqrt((1.0/argu.vpc)*(1.0/argu.vpc) - rayp*rayp));
	double tA = tPs + argu.Wd[0];
	double tF = tPs + argu.Wd[1];

	// read R-RFs into memory
	int nbaz = 0;
	int nbaz_bin[360] = {0};
	struct sacRF * sacsR = new struct sacRF[360];
	memset(sacsR, 0, sizeof(struct sacRF)*360);

	string strFile=string("r")+argu.input_filename;
	FILE *fRF = openfile(strFile.c_str(), "r");
	char line[1024], strTmp[8];
	int ibaz, nptWr;
	double dBaz;
	double sumR[1000]={0.0};
	double sumR2[1000]={0.0};

	if(fRF == NULL) exit(0);
	while(feof(fRF)==false)
	{
		if(fgets(line, 1024, fRF) == NULL) continue;
		if(line[0]!='>') continue;

		if (sscanf(line, "%s%d%lf%d%lf%lf%lf%d", strTmp, &ibaz, &dBaz, &sacsR[nbaz].npts, &sacsR[nbaz].b, &sacsR[nbaz].dt, &sacsR[nbaz].baz, &nbaz_bin[nbaz] ) < 7) continue;

		sacsR[nbaz].time = new float[sacsR[nbaz].npts];
		sacsR[nbaz].amp  = new float[sacsR[nbaz].npts];
		nptWr=0;
		for(int i=0; i<sacsR[nbaz].npts; i++)
		{
			if(fgets(line, 1024, fRF) == NULL) continue;
			if(sscanf(line, "%f%f", sacsR[nbaz].time+i, sacsR[nbaz].amp+i) != 2) continue;

			if(sacsR[nbaz].time[i] >= tA && sacsR[nbaz].time[i] <= tF)
			{
				sumR[nptWr]  += sacsR[nbaz].amp[i];
				sumR2[nptWr] += sacsR[nbaz].amp[i] * sacsR[nbaz].amp[i];
				nptWr++;
			}
		}
		nbaz++;
	}
	fclose(fRF);
	// read T-RFs into memory
	struct sacRF * sacsT = new struct sacRF[nbaz];
	memset(sacsT, 0, sizeof(struct sacRF)*nbaz);

	strFile=string("t")+argu.input_filename;
	fRF = openfile(strFile.c_str(), "r");
	int nptWt;
	nbaz=0;
	double sumT2[1000]={0.0};
	
	if(fRF == NULL) exit(0);
	while(feof(fRF)==false)
	{
		if(fgets(line, 1024, fRF) == NULL) continue;
		if(line[0]!='>') continue;

		if (sscanf(line, "%s%d%lf%d%lf%lf%lf%d", strTmp, &ibaz, &dBaz, &sacsT[nbaz].npts, &sacsT[nbaz].b, &sacsT[nbaz].dt, &sacsT[nbaz].baz, &nbaz_bin[nbaz] ) < 7) continue;

		sacsT[nbaz].time = new float[sacsT[nbaz].npts];
		sacsT[nbaz].amp  = new float[sacsT[nbaz].npts];
		nptWt=0;
		for(int i=0; i<sacsT[nbaz].npts; i++)
		{
			if(fgets(line, 1024, fRF) == NULL) continue;
			if (sscanf(line, "%f%f", sacsT[nbaz].time+i, sacsT[nbaz].amp+i) != 2) continue;
			if(sacsT[nbaz].time[i] >= tA && sacsT[nbaz].time[i] <= tF)
			{
				sumT2[nptWt] += sacsT[nbaz].amp[i] * sacsT[nbaz].amp[i];
				nptWt++;
			}
		}
		nbaz++;
	}
	fclose(fRF);
	
	// get Rmax0, Rcc0 and Tsum0 for all traces
	int nptW = (nptWr > nptWt) ? nptWt : nptWr;
	double Rmax0 = 0;
	double Rcc0 = 0;
	double Tsum0 = 0;
	for(int i=0; i<nptW; i++)
	{
		Rmax0 = ((sumR[i]*sumR[i])>Rmax0) ? (sumR[i]*sumR[i]) : Rmax0;
		Rcc0 += (sumR[i]*sumR[i] - sumR2[i]);
		Tsum0 += sumT2[i];
	}


	// starting loop for lamda, gama, fai and tau
	int nL = (int)(360.0/argu.dL);
	int nG = (int) (argu.Gmx/argu.dG + 1.499);
	int nF = (int)(180.0/argu.dF);
	int nT = (int)(1.0/argu.dT +1.499);
	int nsum = nL * nG * nF * nT;
	int numG =      nG * nF * nT;
	int numF =           nF * nT;
	double *sumA=new double[nsum];

	// read epsilon into memory
	int maxepsi=nL*nG*nbaz;
	// fprintf(stderr, "%d\t%d\t%d\t%d\t%d\t%d\n", nL, nG, nF, nbaz, nT, nsum);
	float *epsi = new float[maxepsi];
	memset(epsi, 0, sizeof(float)*maxepsi);
	float lamtmp, diptmp, baztmp;
	FILE *fepsi = openfile(argu.fepsi.c_str(), "r");
	int numEpsi=0;
	if(fepsi == NULL) exit(0);
	while(feof(fepsi)==false)
	{
		if(fgets(line, 1024, fepsi) == NULL) continue;
		if (sscanf(line, "%f%f%f%f", &lamtmp, &diptmp, &baztmp, epsi+numEpsi) < 4) continue;
		epsi[numEpsi]*=pai/180;
		numEpsi++;
		if(numEpsi > maxepsi)
		{
			fprintf(stderr, "Miss Matched Number of Epsilon!\n");
			exit(0);
		}
	}
	fclose(fepsi);
	
	float *fai= new float[nbaz*nF];
	float ** fast = new float*[nbaz*nF];
	float ** slow = new float*[nbaz*nF];
	fast[0] = new float[nbaz*nF*sacsR[0].npts];
	slow[0] = new float[nbaz*nF*sacsR[0].npts];

	memset(fai,  0, nbaz * nF * sizeof(float)); 
	memset(fast[0], 0, nbaz * nF * sizeof(float) * sacsR[0].npts);
	memset(slow[0], 0, nbaz * nF * sizeof(float) * sacsR[0].npts);
	if(slow[0]==NULL) {fprintf(stderr, "Memory exhausted!\n"); exit(0);}

	for(int iF=0; iF<nF; iF++)   //loop for fai, fast-wave direction
	{
		double az=iF*argu.dF;
		// rotate  R & T   to   F & S 
		for(int ibaz=0; ibaz<nbaz; ibaz++)
		{
			int itmp = iF*nbaz + ibaz;
			fai[itmp] = (az - sacsR[ibaz].baz)*pai/180;
			// fprintf(stderr, "%lg\t%lg\t%d\n", az, sacsR[ibaz].baz, itmp);    //debug
			fast[itmp] = fast[0] + itmp*sacsR[0].npts;
			slow[itmp] = slow[0] + itmp*sacsR[0].npts;
			for(int j=0; j<sacsR[0].npts; j++)
			{
				fast[itmp][j] =    sacsR[ibaz].amp[j] * cos(fai[itmp]) + sacsT[ibaz].amp[j] * sin(fai[itmp]);
				slow[itmp][j] = -1*sacsR[ibaz].amp[j] * sin(fai[itmp]) + sacsT[ibaz].amp[j] * cos(fai[itmp]);
			}
		}
	}

	strFile=argu.output_filename.c_str()+string("0");
	FILE *fgrd = openfile(strFile.c_str(), "w");
	#pragma omp parallel for default(shared) schedule(dynamic, 1)
	for(int iL=0; iL<nL; iL++)  // loop for dipping direction  
	{
		double lamda = iL*argu.dL;
		double lam = lamda * pai/180;
		// double stk = lam - 0.5*pai;

		// double *sumRmv  = new double[nptW];
		// double *sumRc   = new double[nptW];
		// double *sumRc2  = new double[nptW];
		// double *sumTc2  = new double[nptW];
		// double *sumRcP  = new double[nptW];
		// double *sumRcP2 = new double[nptW];
		// double *sumTcP2 = new double[nptW];

		// double *ampFdt = new double[sacsR[0].npts];
		// double *ampSdt = new double[sacsR[0].npts];
		// double *timef  = new double[sacsR[0].npts];

		for(int iG=0; iG<nG; iG++) // loop for dipping angle
		{
			double tPsDip[nbaz] = {0.0};
			double gama = iG*argu.dG;
			double gam = gama * pai/180;
			for(int ibaz=0; ibaz<nbaz; ibaz++)  // loop for RFs 
			{
				double bazi=sacsR[ibaz].baz*pai/180;				
				// calculate tPs for dipping interface, according to TanPing, ChenYun et al., 2018. CJG
				double PI1=-rayp*cos(bazi);
				double PI2=-rayp*sin(bazi);
				double PI3=-sqrt(1/(argu.vpm*argu.vpm)-(rayp*rayp));          
				// double P1I1=sin(lam)*PI1-cos(lam)*PI2;
				// double P1I2=cos(gam)*cos(lam)*PI1+cos(gam)*sin(lam)*PI2+sin(gam)*PI3;
				// double P1I3=-sin(gam)*cos(lam)*PI1-sin(gam)*sin(lam)*PI2+cos(gam)*PI3;           
				// double P2I1=P1I1;
				// double P2I2=P1I2;
				// double P2I3=-sqrt(1/(argu.vpc*argu.vpc)-P1I1*P1I1-P1I2*P1I2);              
				double n1=sin(gam)*cos(lam);
				double n2=sin(gam)*sin(lam);
				double n3=-cos(gam);
				double nPI=n1*PI1+n2*PI2+n3*PI3;
				tPsDip[ibaz] = argu.mo * cos(gam) * (sqrt((argu.ka/argu.vpc)*(argu.ka/argu.vpc)-1/(argu.vpm*argu.vpm)+nPI*nPI)-sqrt(1/(argu.vpc*argu.vpc)-1/(argu.vpm*argu.vpm)+nPI*nPI));
				// fprintf(stderr, "%lg\t%lg\n", tPsDip[ibaz], sacsR[ibaz].baz);    //debug
// #ifdef _OPENMP				
				// if(omp_get_thread_num()==1)
					// fprintf(stderr, "%lg\t%lg\t%lg\n", tPs, tPsDip[ibaz], sacsR[ibaz].baz);
// #endif
			}

			for(int iF=0; iF<nF; iF++)   //loop for fai, fast-wave direction
			{
				double az=iF*argu.dF;

				for(int iT=0; iT<nT; iT++)	//loop for tau, delay time
				{
					double tau = iT * argu.dT;
					double taui = tau * cos(gam);

					double sumRmv[nptW] = {0.0};
					double sumRc[nptW]  = {0.0};
					double sumRc2[nptW] = {0.0};
					double sumTc2[nptW] = {0.0};
					double sumRcP[nptW] = {0.0};
					double sumRcP2[nptW] = {0.0};
					double sumTcP2[nptW] = {0.0};

					// double ampFdt[sacsR[0].npts] = {0};
					// double ampSdt[sacsR[0].npts] = {0};
					// double timef[sacsR[0].npts] = {0};

					// window F & S, and rotate back to R & T
					// memset(sumRmv,  0, sizeof(double) * nptW);
					// memset(sumRc,   0, sizeof(double) * nptW);
					// memset(sumRc2,  0, sizeof(double) * nptW);
					// memset(sumTc2,  0, sizeof(double) * nptW);
					// memset(sumRcP,  0, sizeof(double) * nptW);
					// memset(sumRcP2, 0, sizeof(double) * nptW);
					// memset(sumTcP2, 0, sizeof(double) * nptW);
					
					int iptc, iptp;
					int iEpsi=0;
					for(int ibaz=0; ibaz<nbaz; ibaz++)
					{
						int itmp = iF*nbaz + ibaz;
						// polarization angle, epsilon, according to Raysum
						iEpsi = iL * nG * nbaz + iG * nbaz + ibaz;
						// fprintf(stderr, "%lg\t%lg\t%lg\t%d\t%d\t%lg\n", lamda, gama, sacsR[ibaz].baz, iEpsi, itmp, epsi[iEpsi]*180/pai);    //debug
						double ampFdt[sacsR[0].npts] = {0};
						double ampSdt[sacsR[0].npts] = {0};
						double timef[sacsR[0].npts] = {0};
						// memset(ampFdt, 0, sizeof(double) * sacsR[0].npts);
						// memset(ampSdt, 0, sizeof(double) * sacsR[0].npts);
						// memset(timef,  0, sizeof(double) * sacsR[0].npts);

						int iptr=0;
						int iptk=0;
						int iptm=0;
						for(int j=0; j<sacsR[0].npts; j++)
						{
							double ttmp=sacsR[ibaz].time[j] + 0.5 * taui * cos(2*fai[itmp]) + (tPs-tPsDip[ibaz]);
							if(ttmp>=tA && ttmp<=tF) 
							{
								sumRmv[iptr]+=sacsR[ibaz].amp[j];
								iptr++;
							}
							if(sacsR[ibaz].time[j]>=(tA-5) && sacsR[ibaz].time[j]<=(tF+5)) 
							{
								timef[iptk]  = sacsR[ibaz].time[j];
								ampFdt[iptk] = fast[itmp][j];
								// fprintf(stderr, "%lg\t%lg\n", sacsR[ibaz].time[j], ampFdt[iptk]);    //debug
								iptk++;
							}
							ttmp=sacsR[ibaz].time[j]- tau;
							if(ttmp>=(tA-5) && ttmp<=(tF+5)) 
							{
								ampSdt[iptm] = slow[itmp][j];
								// fprintf(stderr, "%lg\t%lg\n", ttmp, ampSdt[iptk]);    //debug
								iptm++;
							}
						}

						double theta=-fai[itmp];
						double km = (iptm>iptk) ? iptk : iptm;
						iptc = iptp = 0;
						for(int k=0; k<km; k++)
						{
							double rc =  ampFdt[k] * cos(theta) + ampSdt[k] * sin(theta);
							double tc = -ampFdt[k] * sin(theta) + ampSdt[k] * cos(theta);
							if(timef[k]>=tA && timef[k]<=tF)
							{
								double TcP = -rc * sin(-epsi[iEpsi]) + tc * cos(-epsi[iEpsi]);
								// fprintf(stderr, "%lg\t%lg\t%lg\t%lg\n", timef[k], rc, tc,TcP);    //debug
								sumRc[iptc] += rc;
								sumRc2[iptc] += rc*rc;
								sumTc2[iptc] += tc*tc; 
								sumTcP2[iptc] += TcP*TcP;
								iptc++;
							}
							double ttmp = timef[k] + (tPs-tPsDip[ibaz]);
							if(ttmp>=tA && ttmp<=tF)
							{
								double RcP = rc * cos(-epsi[iEpsi]) + tc * sin(-epsi[iEpsi]);
								// fprintf(stderr, "%lg\t%lg\n", ttmp, RcP);   //debug
								sumRcP[iptp] += RcP;
								sumRcP2[iptp] += RcP * RcP;
								iptp++;
							}
						}
					}

					// for(int j=0; j<iptp; j++)   //debug
						// fprintf(stderr, "%d\t%lg\t%lg\t%lg\t%lg\t%lg\n", j, sumTc2[j], sumTcP2[j], sumRcP2[j]);
					// get Rmax, Rcc and Tsum for all traces
					double Rmax=0;
					double Rcc=0;
					double Tsum=0;
					double RccP=0;
					double TsumP=0;
					int kmm = (iptc>iptp) ? iptp : iptc;
					for(int k=0; k<kmm; k++)
					{
						Rmax  = ((sumRmv[k]*sumRmv[k]) > Rmax) ? (sumRmv[k]*sumRmv[k]) : Rmax;
						Rcc   += (sumRc[k]*sumRc[k] - sumRc2[k]);
						Tsum  +=  sumTc2[k];
						RccP  += (sumRcP[k]*sumRcP[k] - sumRcP2[k]);
						TsumP += sumTcP2[k];
					}
					double Icos = Rmax/Rmax0;
					// double Icc = Rcc/Rcc0;
					// Icc = sqrt(Icc*Icc);
					// double It = Tsum/Tsum0;
					// double Wt = log(Icos) + log(Icc) - log(It);
					double IccP = RccP/Rcc0;
					IccP = sqrt(IccP*IccP);
					double ItP = TsumP/Tsum0;
					double WtP = argu.Wt[0]*log(Icos) + argu.Wt[1]*log(IccP) + argu.Wt[3]*log(ItP);
					// fprintf(stderr, "%lg\t%lg\t%lg\t%lg\t%lg\t%lg\t%lg\n", lamda, gama, az, tau, TsumP, Tsum0, log(ItP));   //debug

					int isum = iL*numG +  iG*numF + iF*nT +  iT;
					// fprintf(stderr, "%lg\t%lg\t%lg\t%lg\t%d\n", lamda, gama, az, tau, isum);   //debug
					sumA[isum] = WtP;
					fprintf(fgrd, "%lg\t%lg\t%lg\t%lg\t%lg\t%lg\t%lg\t%lg\n", lamda, gama, az, tau, Icos, IccP, ItP, WtP);
				}
			}
			// delete tPsDip; tPsDip=NULL;
		}

		// delete sumRmv; sumRmv=NULL;
		// fprintf(stderr, "%g\t aaaa\n", sumRc[0]);
		// delete sumRc; sumRc=NULL;
		// exit(0);
		// delete sumRc2; sumRc2=NULL;
		// delete sumTc2; sumTc2=NULL;
		// delete sumRcP; sumRcP=NULL;
		// delete sumRcP2; sumRcP2=NULL;
		// delete sumTcP2; sumTcP2=NULL;

		// delete ampFdt; ampFdt=NULL;
		// delete ampSdt; ampSdt=NULL;
		// delete timef; timef=NULL;
	}
	fclose(fgrd);

	delete epsi;
	delete fai;
	delete fast[0];
	delete slow[0];
	delete fast;
	delete slow;
	
	fgrd = openfile(argu.output_filename.c_str(), "w");
	double maxA=sumA[0];
	double Lsol, Gsol, Fsol, Tsol;
	for (int igrd = 1; igrd < nsum; igrd++)
	{
		if(sumA[igrd] > maxA) 
		{
			maxA = sumA[igrd];
			int iL=igrd/numG; int remain=igrd % numG;
			int iG=remain/numF; remain=remain % numF;
			int iF=remain/nT; remain=remain % nT;
			int iT=remain;
			Lsol = iL * argu.dL;
			Gsol = iG * argu.dG;
			Fsol = iF * argu.dF;
			Tsol = iT * argu.dT;
		}	
	}
	fprintf(fgrd, "> Gmx,dL,dG,dF,dT,Lsol,Gsol,Fsol,Tsol= %lg %lg %lg %lg %lg %lg %lg %lg %lg\n",  argu.Gmx, argu.dL, argu.dG, argu.dF, argu.dT, Lsol, Gsol, Fsol, Tsol);
	for (int igrd = 0; igrd < nsum; igrd++)
	{
		int iL=igrd/numG; int remain=igrd % numG;
		int iG=remain/numF; remain=remain % numF;
		int iF=remain/nT; remain=remain % nT;
		int iT=remain;
		double lam = iL * argu.dL;
		double gam = iG * argu.dG;
		double fai = iF * argu.dF;
		double tau = iT * argu.dT;
		fprintf(fgrd, "%lg\t%lg\t%lg\t%lg\t%lg\n", lam, gam, fai, tau, sumA[igrd]);
	}
	fclose(fgrd);

	// free memory
	delete sumA;
	for (int ibaz = 0; ibaz < nbaz; ibaz++)
	{
		if(sacsR[ibaz].npts>0)
		{
			delete sacsR[ibaz].amp;
			delete sacsT[ibaz].amp;
			delete sacsR[ibaz].time;
			delete sacsT[ibaz].time;
		}		
	}
	delete sacsR;
	delete sacsT;

	return 0;
}

int show_help(char* argv0 /*=argv[0]*/)
{
	printf("%s (Version 2.0) by Mei Feng & Meijian An, 2024/07/30\n\n", argv0);
	printf("Info:\n"
		"   Make L-G-F-T (model space) grid by fitting P-to-S phase (Ps) in receiver functions\n\n");
	printf("arguments:\n"
		"     -h:        Show this help information.\n"
		"     files [rt]RFbin_Ps.out stored the binned Receiver functions should be prepared. \n"
		"     -o=x:      Output LGFT grid file name.\n"
		"  -input=x:   postfix of the input RFbin file name (RFbin_Ps_x.out).\n"
		"  -fepsi=x:   filename for epsilon, calculated by Raysum. Default is epsilon_all_dips.lst.\n"
		"  -Wt=\"x1 x2 x3\": Weight for the three objetives, Rsum, Rcc & Tsum. Default: 0.7. 0.2 0.1\n"
		"  -Wd=\"x1 x2\": left and right time shift to tPs (window width of the Pms). Default: -1.5, 1.5\n"
		"  -moho=x:      preliminary Moho depth. Default is 40 km \n"
		"  -kappa=x:     preliminary Kappa. Default is 1.732\n"
		"  -vpc=x:     vp in the crust. Default is 6.4 km/s \n"
		"  -vpm=x:     vp in the mantle. Default is 8.1 km/s \n"
		"  -Gmx=x:     maximum dipping angle to be grid searched. Default is 45 degree\n"
		"  -dL=x:      searching step for dipping direction Lamda. Default: 10 degree \n"
		"  -dG=x:      searching step for dipping angle     Gama.  Default: 5 degree \n"
		"  -dF=x:      searching step for fast-wave direction Fai. Default: 5 degree \n"
		"  -dT=x:      searching step for delay time Tau. Default: 0.1 s \n"
		"-no_openmp      No parallel computing.\n"
		);

	return 1;
}

int get_argument(struct Arguement &argu, int argc, char**argv)
{
	if(get_switch("-h", false, argc, argv) == true || argc < 3)
	{
		show_help(argv[0]);
		exit(0);
	}

 	//Get All arguement values.
	argu.output_filename   = get_Parameter("-o=",        string("LGFT.grd"), argc, argv);
	argu.input_filename   = get_Parameter("-input=",    string("RFbin_Ps.out"), argc, argv);
	argu.fepsi   = get_Parameter("-fepsi=",    string("epsilon_all_dips.lst"), argc, argv);

	string str_wt = get_Parameter("-Wt=", string(""), argc, argv);
	int n = sscanf(str_wt.c_str(), "%lf%lf%lf", argu.Wt, argu.Wt+1, argu.Wt+2);
	if(n < 3) argu.Wt[2] = -0.1;
	if(n < 2) argu.Wt[1] = 0.2;
	if(n < 1) argu.Wt[0] = 0.7;

	string str_wd = get_Parameter("-Wd=", string(""), argc, argv);
	n = sscanf(str_wd.c_str(), "%lf%lf", argu.Wd, argu.Wd+1);
	if(n < 2) argu.Wd[1] = 1.5;
	if(n < 1) argu.Wd[0] = -1.5;


	argu.mo    = get_Parameter("-moho=", double(40.0),   argc, argv);
	argu.ka    = get_Parameter("-kappa=", double(1.732), argc, argv);
	argu.vpc    = get_Parameter("-vpc=", double(6.4), argc, argv);
	argu.vpm    = get_Parameter("-vpm=", double(8.1), argc, argv);

	argu.dL = get_Parameter("-dL=", double(10.0), argc, argv);
	argu.dG = get_Parameter("-dG=", double(2.5), argc, argv);
	argu.dF = get_Parameter("-dF=", double(5.0), argc, argv);
	argu.dT = get_Parameter("-dT=", double(0.1), argc, argv);
	argu.Gmx = get_Parameter("-Gmx=", double(35.0), argc, argv);

#ifdef _OPENMP
	argu.no_openmp = get_switch("-no_openmp", false, argc, argv);
#else
	argu.no_openmp = true;
#endif

	SHOWerr1("%s options are:\n", argv[0]);
	SHOWerr1("\t         input = %s\n", argu.input_filename.c_str());
	SHOWerr1("\t         fepsi = %s\n", argu.fepsi.c_str());
	SHOWerr2("\t         Wd = %g %g\n", argu.Wd[0], argu.Wd[1]);
	SHOWerr3("\t         Wt = %g %g %g\n", argu.Wt[0], argu.Wt[1], argu.Wt[2]);
	SHOWerr1("\t         moho = %g\n", argu.mo);
	SHOWerr1("\t         kappa = %g\n", argu.ka);
	SHOWerr1("\t         vpc = %g\n", argu.vpc);
	SHOWerr1("\t         vpm = %g\n", argu.vpm);
	SHOWerr1("\t       dL = %g\n", argu.dL);
	SHOWerr1("\t       dG = %g\n", argu.dG);
	SHOWerr1("\t       dF = %g\n", argu.dF);
	SHOWerr1("\t       dT = %g\n", argu.dT);
	SHOWerr1("\t       Gmx = %g\n", argu.Gmx);

	return 1;
}

