void help(){
	cout <<endl;
	cout <<"___________________________________"<<endl;
	cout <<"command reference:"<<endl;
	cout <<"free(): free data"<<endl;
	cout <<"setTrappingVoltage()"<<endl;
	cout <<"setExtractionVoltage()"<<endl;
	cout <<"PlotPotdouble x1=33,double y1=0,double z1=0,double x2=70,double y2=0,double z2=0,int num=100,bool plotfield=false)"<<endl;
}
void free(){
	delete wr;
}

void setTrappingVoltage(){
	el01->SetVoltage(0);
	el02->SetVoltage(0);
	el03->SetVoltage(0);
	el04->SetVoltage(0);
	el05->SetVoltage(0);
	el06->SetVoltage(0);
	el07->SetVoltage(6.8);
	el08->SetVoltage(00);
	el09->SetVoltage(00);
	el10->SetVoltage(00);
	el11->SetVoltage(00);
	el12->SetVoltage(00);
	el13->SetVoltage(10);
	el14->SetVoltage(0);
	el15->SetVoltage(0);
	eldc1->SetVoltage(0);
	eldc2->SetVoltage(0);
	elrf1->SetVoltage(0);//RF unten
	elrf2->SetVoltage(0);//RF oben
	gndElectrode->SetVoltage(0);
}

#define PI 3.141592653589793


void setExtractionVoltage(){
	el01->SetVoltage(0);
	el02->SetVoltage(0);
	el03->SetVoltage(0);
	el04->SetVoltage(0);
	el05->SetVoltage(0);
	el06->SetVoltage(0);
	el07->SetVoltage(35);
	el08->SetVoltage(0);
	el09->SetVoltage(500);
	el10->SetVoltage(500);
	el11->SetVoltage(0);
	el12->SetVoltage(00);
	el13->SetVoltage(35);
	el14->SetVoltage(0);
	el15->SetVoltage(0);
	eldc1->SetVoltage(0);
	eldc2->SetVoltage(0);
	elrf1->SetVoltage(0);//RF unten
	elrf2->SetVoltage(0);//RF oben
gndElectrode->SetVoltage(0);
}

void setBig(){
	el01->SetVoltage(10);
	el02->SetVoltage(10);
	el03->SetVoltage(10);
	el04->SetVoltage(10);
	el05->SetVoltage(10);
	el06->SetVoltage(10);
	el07->SetVoltage(10);
	el08->SetVoltage(10);
	el09->SetVoltage(10);
	el10->SetVoltage(10);
	el11->SetVoltage(10);
	el12->SetVoltage(10);
	el13->SetVoltage(10);
	el14->SetVoltage(10);
	el15->SetVoltage(10);
	eldc1->SetVoltage(10);
	eldc2->SetVoltage(10);
	elrf1->SetVoltage(10);//RF unten
	elrf2->SetVoltage(10);//RF oben
gndElectrode->SetVoltage(10);
}
void setZero(){
	el01->SetVoltage(0);
	el02->SetVoltage(0);
	el03->SetVoltage(0);
	el04->SetVoltage(0);
	el05->SetVoltage(0);
	el06->SetVoltage(0);
	el07->SetVoltage(0);
	el08->SetVoltage(0);
	el09->SetVoltage(0);
	el10->SetVoltage(0);
	el11->SetVoltage(0);
	el12->SetVoltage(0);
	el13->SetVoltage(0);
	el14->SetVoltage(0);
	el15->SetVoltage(0);
	eldc1->SetVoltage(0);
	eldc2->SetVoltage(0);
	elrf1->SetVoltage(0);//RF unten
	elrf2->SetVoltage(0);//RF oben
	gndElectrode->SetVoltage(0);
}

double calcit(double x,double y,double z){
	double p,ex,ey,ez;
	wr->calc(x,y,z,p,ex,ey,ez);
	return p;
}

void PlotPot(double x1=33,double y1=0,double z1=0,double x2=40,double y2=0,double z2=0,int num=20,bool plotfield=false){
		//logfile.Section("PlotPot");

		int nx=500,ny=51,nz=51;
		//int num=100;
		double *pot=new double[num];
		double *Ex=new double[num];
		double *Ey=new double[num];
		double *Ez=new double[num];
		double *xaxis=new double[num];
		double xstart=x1,xstop=x2;
		double ystart=y1,ystop=y2;
		double zstart=z1,zstop=z2;
		
		
		int n;



		for(n=0;n<num;n++) {
			wr->calc(xstart+(-xstart+xstop)/double(num-1)*n,
				     ystart+(-ystart+ystop)/double(num-1)*n,
					 zstart+(-zstart+zstop)/double(num-1)*n,
					 pot[n],Ex[n],Ey[n],Ez[n]);
			xaxis[n]=sqrt(pow(xstart+(-xstart+xstop)/double(num-1)*n,2)+
				     pow(ystart+(-ystart+ystop)/double(num-1)*n,2)+
					 pow(zstart+(-zstart+zstop)/double(num-1)*n,2));
				
		}
		//for(n=0;n<num;n++) Ex[n]*=Ex[n];
		logfile.Graph("axialcutpot",xaxis,pot,num,"x [mm]","Potential [V] ","AL");	
		
		//logfile.Graph("axialcutpot2","axialcutpot",xaxis,pot,num,"L",2);
		logfile.Print("axialcutpot");
		logfile.WriteTSV("axialcutpot");
		if(plotfield){
			logfile.Graph("axialcutEx",xaxis,Ex,num,"x","Ex","L");
			logfile.Print("axialcutEx");

			logfile.Graph("axialcutEy",xaxis,Ey,num,"x","Ey","L");
			logfile.Print("axialcutEy");

			logfile.Graph("axialcutEz",xaxis,Ez,num,"x","Ez","L");
			logfile.Print("axialcutEz");

		}
		delete[] xaxis;
		delete[] Ez;
		delete[] Ey;
		delete[] Ex;
		delete[] pot;
}

void PlotPot3(double x1=33,double y1=0,double z1=0,double x2=40,double y2=0,double z2=0,int num=200,bool plotfield=false){
		//logfile.Section("PlotPot");
		time_t zeit = clock();
		int nx=500,ny=51,nz=51;
		//int num=100;
		double *pot=new double[num];
		double *Ex=new double[num];
		double *Ey=new double[num];
		double *Ez=new double[num];
		double *xaxis=new double[num];
		double xstart=x1,xstop=x2;
		double ystart=y1,ystop=y2;
		double zstart=z1,zstop=z2;
		
		
		int n;



		for(n=0;n<num;n++) {
			pot[n]=wr->calc_slow(xstart+(-xstart+xstop)/double(num-1)*n,
				     ystart+(-ystart+ystop)/double(num-1)*n,
					 zstart+(-zstart+zstop)/double(num-1)*n
					 );
			xaxis[n]=sqrt(pow(xstart+(-xstart+xstop)/double(num-1)*n,2)+
				     pow(ystart+(-ystart+ystop)/double(num-1)*n,2)+
					 pow(zstart+(-zstart+zstop)/double(num-1)*n,2));
					xaxis[n]=ystart+(-ystart+ystop)/double(num-1)*n;	
	
		}
		zeit = clock()-zeit;
		cout <<"Plottet in: "<<zeit/1000.<<"seconds"<<endl;
		//for(n=0;n<num;n++) Ex[n]*=Ex[n];
		logfile.Graph("axialcutpot_slowslow",xaxis,pot,num,"x [mm]","Potential [V] ","AL");	
		
		//logfile.Graph("axialcutpot_slowslow","axialcutpot",xaxis,pot,num,"L",2);
		logfile.Print("axialcutpot_slowslow");
		logfile.WriteTSV("axialcutpot_slowslow");
		
		delete[] xaxis;
		delete[] Ez;
		delete[] Ey;
		delete[] Ex;
		delete[] pot;
}

void PlotDiff(double x1=33,double y1=0,double z1=0,double x2=40,double y2=0,double z2=0,int num=20,bool plotfield=false){
		//logfile.Section("PlotPot");

		int nx=500,ny=51,nz=51;
		//int num=100;
		double *pot=new double[num];
		double *Ex=new double[num];
		double *Ey=new double[num];
		double *Ez=new double[num];
		double *xaxis=new double[num];
		double xstart=x1,xstop=x2;
		double ystart=y1,ystop=y2;
		double zstart=z1,zstop=z2;
		
		
		int n;



		for(n=0;n<num;n++) {
			wr->calc(xstart+(-xstart+xstop)/double(num-1)*n,0.0/double(num)*double(n),0.0/double(num)*double(n),pot[n],Ex[n],Ey[n],Ez[n]);
			pot[n]-=wr->calc_slow(xstart+(-xstart+xstop)/double(num-1)*n,0.0/double(num)*double(n),0.0/double(num)*double(n));
				
			xaxis[n]=xstart+(-xstart+xstop)/double(num-1)*n,0.0/double(num)*double(n);
		}
		//for(n=0;n<num;n++) Ex[n]*=Ex[n];
		logfile.Graph("axialcutpot_diff",xaxis,pot,num,"x [mm]","Potential [V] ","AL");	
		
		//logfile.Graph("axialcutpot_slowslow","axialcutpot",xaxis,pot,num,"L",2);
		logfile.Print("axialcutpot_diff");
		logfile.WriteTSV("axialcutpot_diff");
	
		delete[] xaxis;
		delete[] Ez;
		delete[] Ey;
		delete[] Ex;
		delete[] pot;
}
void Trajectory(double rf1c=0,double rf2c=0,double dc1c=0,double dc2c=0,double x=36.5281,double y=0,double z=0.0,double vx=0,double vy=0,double vz=0,double stoptime=500./12e6,int steps=50000,double RFVoltage=150,double RFfreq=12155000){
	setTrappingVoltage();
	logfile.Logging(true);
	double h=stoptime/double(steps);
	int i;
	double xx[3]={x,y,z},vv[3]={vx,vy,vz};
	double *xpos=new double[steps]; 
	double *ypos=new double[steps];
	double *zpos=new double[steps];
	double *vxpos=new double[steps];
	double *vypos=new double[steps];
	double *vzpos=new double[steps];
	double *tpos=new double[steps];
	double t=0;
	double qDivM=2.41187e6; //Ca40+
	for(i=0;i<steps;++i){
		double Urf=RFVoltage*sin(2.*PI*RFfreq*t);
		elrf1->SetVoltage(Urf+rf1c);
		elrf2->SetVoltage(Urf+rf2c);
		eldc1->SetVoltage(dc1c);
		eldc2->SetVoltage(dc2c);
		xpos[i]=xx[0];ypos[i]=xx[1];zpos[i]=xx[2];
		vxpos[i]=vv[0];vypos[i]=vv[1];vzpos[i]=vv[2];
		tpos[i]=t;
		wr->propagateForwardVerlet(xx,vv,h,qDivM);
		t+=h;
	}
	xpos[steps-1]=xx[0];ypos[steps-1]=xx[1];zpos[steps-1]=xx[2];
	vxpos[steps-1]=vv[0];vypos[steps-1]=vv[1];vzpos[steps-1]=vv[2];

	logfile.Graph("xpos",tpos,xpos,steps,"time [s]","x [mm]","AL");
	logfile.Print("xpos");
	logfile.Graph("ypos",tpos,ypos,steps,"time [s]","y [mm]","AL");
	logfile.Print("ypos");
	logfile.Graph("zpos",tpos,zpos,steps,"time [s]","z [mm]","AL");
	logfile.Print("zpos");
	logfile.Graph("vxpos",tpos,vxpos,steps,"time [s]","vx [mm/s]","AL");
	logfile.Print("vxpos");
	logfile.Graph("vypos",tpos,vypos,steps,"time [s]","vy [mm/s]","AL");
	logfile.Print("vypos");
	logfile.Graph("vzpos",tpos,vzpos,steps,"time [s]","vz [mm/s]","AL");
	logfile.Print("vzpos");
	logfile.Logging(false);
}
struct xv{
	double x;
	double y;
	double z;
	double vx;
	double vy;
	double vz;
};

xv Extraction(double rf1c=0,double rf2c=0,double dc1c=0,double dc2c=0,double x=36.5281,double y=0,double z=0,double vx=0,double vy=0,double vz=0,double stoptime=500./12e6,int steps=50000,double RFVoltage=150,double RFfreq=12155000,double startphase=0,double triggerphase=0,int phasecnt=20,bool doplot=true){
	setTrappingVoltage();
	if (doplot) logfile.Logging(true);
	double h=stoptime/double(steps);
	int i;
	double xx[3]={x,y,z},vv[3]={vx,vy,vz};
	double *xpos=new double[steps]; 
	double *ypos=new double[steps];
	double *zpos=new double[steps];
	double *vxpos=new double[steps];
	double *vypos=new double[steps];
	double *vzpos=new double[steps];
	double *tpos=new double[steps];
	double t=0;
	double qDivM=2.41187e6; //Ca40+
	double phasecnt2=0;
	for(i=0;i<steps;++i){

		double phaseval;
		phaseval=modf(RFfreq*t+startphase,&phasecnt2);

		if((phasecnt2>=phasecnt) && (phaseval>triggerphase)) setExtractionVoltage();
		double Urf=RFVoltage*cos(2.*PI*(RFfreq*t+startphase) );
		elrf1->SetVoltage(Urf+rf1c);
		elrf2->SetVoltage(Urf+rf2c);
		eldc1->SetVoltage(dc1c);
		eldc2->SetVoltage(dc2c);
		xpos[i]=xx[0];ypos[i]=xx[1];zpos[i]=xx[2];
		vxpos[i]=vv[0];vypos[i]=vv[1];vzpos[i]=vv[2];
		tpos[i]=t;
		wr->propagateForwardVerlet(xx,vv,h,qDivM);
		if (xx[0]>=70.) break;
		t+=h;
	}
	xpos[i]=xx[0];ypos[i]=xx[1];zpos[i]=xx[2];
	vxpos[i]=vv[0];vypos[i]=vv[1];vzpos[i]=vv[2];
	xv data;
	data.x=xx[0];
	data.y=xx[1];
	data.z=xx[2];
	data.vx=vv[0];
	data.vy=vv[1];
	data.vz=vv[2];

	if(doplot){
		logfile.Graph("xpos",tpos,xpos,i,"time [s]","x [mm]","AL");
		logfile.Print("xpos");
		logfile.Graph("ypos",tpos,ypos,i,"time [s]","y [mm]","AL");
		logfile.Print("ypos");
		logfile.Graph("zpos",tpos,zpos,i,"time [s]","z [mm]","AL");
		logfile.Print("zpos");
		logfile.Graph("vxpos",tpos,vxpos,i,"time [s]","vx [mm/s]","AL");
		logfile.Print("vxpos");
		logfile.Graph("vypos",tpos,vypos,i,"time [s]","vy [mm/s]","AL");
		logfile.Print("vypos");
		logfile.Graph("vzpos",tpos,vzpos,i,"time [s]","vz [mm/s]","AL");
		logfile.Print("vzpos");
		logfile.Logging(false);
	}
	
	delete[] tpos;
	delete[] vzpos;
	delete[] vypos;
	delete[] vxpos;
	delete[] zpos;
	delete[] ypos;
	delete[] xpos; 
	
	return data;
}

void Spot(double rf1c=0,double rf2c=0,double dc1c=0,double dc2c=0,double T=1e-4,double triggerphase=0.6,int loops=1000,double x0=36.5281,bool dolog=false){
	if (dolog) logfile.Logging(true);
	srand(time(NULL));
	TRandom3 random(time(NULL));
	const double k_B = 1.3807; // *10^(-23); Boltzmann Konstante [J/K]
	const double masse = 0.006664216; // *10^(-23); Masse Kalzium [kg]

	int i;
	xv res;
	double *ye=new double[loops];
	double *ze=new double[loops];
	double *vxe=new double[loops];
	double *vye=new double[loops];
	double *vze=new double[loops];
	double *xxx=new double[loops];
	double mean=0;
	double meanvx=0;
	for(i=0;i<loops;i++){
		double v[3];
		for(int j=0; j<3; j++)			//Schleife setzt Anfangswerte für v
		{
			//-------------------------------- BOLTZMANN - VERTEILTE - ZUFALLSVARIABLE -----------------------------
			double sigma=sqrt(k_B*T/masse);
			v[j]=random.Gaus(0,sigma)*1000.;
		}

		int phasecnt=random.Uniform(0,40);
		cout <<v[0]<<" "<<v[1]<<" "<<v[2]<<" "<<phasecnt<<" ";

		   
		double startphase=random.Uniform(0,1);
		res=Extraction(rf1c,rf2c,dc1c,dc2c, x0, 0,0,v[0], v[1],v[2], 500./12e6,200000,150,12155000,startphase,triggerphase,phasecnt,false);
		double d_extr=247-(res.x-x0); //entspricht der Distanz zwischen Fallenmitte und Detektor abzüglich der Strecke, die in der Simulations
		double t_extr=d_extr/res.vx;
		
		// Extrapolation of the spatial coordinates (xe, ye, ze) [mm]

		double xe=res.x+t_extr*res.vx;
		ye[i]=res.y+t_extr*res.vy;
		ze[i]=res.z+t_extr*res.vz;
		mean+=sqrt(ye[i]*ye[i]+ze[i]*ze[i]);
		meanvx+=res.vx;
		vye[i]=res.vy;
		vze[i]=res.vz;
		vxe[i]=res.vx;
		xxx[i]=i;
		
		cout << (wr->rangeerror?1:0)<<" ";
		cout <<xe<<" "<<ye[i]<<" "<<ze[i]<<" "<<res.vx<<" "<<res.vy<<" "<<res.vz<<endl;
		wr->rangeerror=false;
	}
	mean/=double(loops);
	meanvx/=double(loops);
	logfile.Graph("y-z-spot",ye,ze,loops,"y","z","A*");
	logfile.WriteTSV("y-z-spot",ye,ze,loops);
	logfile.Graph("vy-vz-spot",vye,vze,loops,"vy","vz","A*");
	logfile.WriteTSV("vy-vz-spot",vye,vze,loops);
	double var=0;
	double varvx=0;
	for(i=0;i<loops;i++){
		var+=( mean-sqrt(ye[i]*ye[i]+ze[i]*ze[i]) )*( mean-sqrt(ye[i]*ye[i]+ze[i]*ze[i]) );
		varvx+= (meanvx-vxe[i])*(meanvx-vxe[i]);
	}
	var=sqrt(var);
	var/=double(loops-1);
	varvx=sqrt(varvx);
	varvx/=double(loops-1);
	cout <<"radius   mean: "<<mean<<"varianz: "<<var<<endl;
	cout <<"vx   mean: "<<meanvx<<"varianz: "<<varvx<<endl;
	logfile.Graph("vx",xxx,vxe,loops,"loop","vx","A*");
	logfile.WriteTSV("vx",xxx,vxe,loops);
	if (dolog) logfile.Logging(false);
	delete[] xxx;
	delete[] vze;
	delete[] vye;
	delete[] vxe;
	delete[] ze;
	delete[] ye;


}