Exemple #1
0
ExtraAxis anotherScale (const TH1* refHist, double scale, int color, const char* title, double offset) {
  ExtraAxis result;
  double x0 = refHist->GetXaxis()->GetXmin();
  double x1 = refHist->GetXaxis()->GetXmax();
  double y0 = refHist->GetMinimum();
  double y1 = refHist->GetMaximum();
  // double y0 = refHist->GetYaxis()->GetXmin();
  // double y1 = refHist->GetYaxis()->GetXmax();
  double xoffset = exp (log(x0) - (log(x1) - log(x0))*offset);

  TGaxis* axis = new TGaxis(xoffset, y0, xoffset, y1, y0*scale,y1*scale,510,"-GS");
  axis->ImportAxisAttributes (refHist->GetXaxis());
  axis->SetTitle(title);
  axis->SetTextColor (color);
  axis->SetLineColor (color);
  axis->SetLineWidth (1);
  axis->SetTextColor (color);
  axis->SetLabelColor (color);
  axis->SetLabelOffset (0.);
  axis->SetTitleOffset (0.65);
  axis->SetTickSize(0.015);	
  result.Add (axis);

  TLine* line = new TLine (xoffset, y0, xoffset, y1);
  line->SetLineColor (color);
  line->SetLineWidth (2);
  result.Add (line);

  line = new TLine (x0, y0, xoffset, y0);
  line->SetLineColor (kGray);
  line->SetLineWidth (2);
  result.Add (line);
  
  line = new TLine (x0, y1, xoffset, y1);
  line->SetLineColor (kGray);
  line->SetLineWidth (2);
  result.Add (line);

  return result;
}
///
/// Make a plot out of a 1D histogram holding a 1-CL curve.
/// The strategy is to always convert the 1-CL histogram (hCL) into
/// a TGraph. This way we can add known points (solutions, points
/// at end of scan range) and also have a filled area without line
/// smoothing. This is not possible with histograms due to a Root bug.
///
/// The function draws the TGraphs, and returns a pointer to the
/// TGraph object that can be used in the TLegend.
///
/// Markers are plotted if the method name of the scanner is "Plugin" or "BergerBoos" or "DatasetsPlugin".
/// One can plot a line instead of points even for the Plugin method by
/// using setPluginMarkers().
///
/// For the angle variables, a new axis is painted that is in Deg.
///
/// \param s The scanner to plot.
/// \param first
/// \param last
/// \param filled
///
TGraph* OneMinusClPlot::scan1dPlot(MethodAbsScan* s, bool first, bool last, bool filled, int CLsType)
{
	if ( arg->debug ){
		cout << "OneMinusClPlot::scan1dPlot() : plotting ";
		cout << s->getName() << " (" << s->getMethodName() << ")" << endl;
	}
	if ( m_mainCanvas==0 ){
		m_mainCanvas = newNoWarnTCanvas(name+getUniqueRootName(), title, 800, 600);
	}
	m_mainCanvas->cd();
	bool plotPoints = ( s->getMethodName()=="Plugin" || s->getMethodName()=="BergerBoos" || s->getMethodName()=="DatasetsPlugin" ) && plotPluginMarkers;
	TH1F *hCL = (TH1F*)s->getHCL()->Clone(getUniqueRootName());
	if (CLsType==1) hCL = (TH1F*)s->getHCLs()->Clone(getUniqueRootName());
  else if (CLsType==2) hCL = (TH1F*)s->getHCLsFreq()->Clone(getUniqueRootName());
	// fix inf and nan entries
	for ( int i=1; i<=s->getHCL()->GetNbinsX(); i++ ){
		if ( s->getHCL()->GetBinContent(i)!=s->getHCL()->GetBinContent(i)
				|| std::isinf(s->getHCL()->GetBinContent(i)) ) s->getHCL()->SetBinContent(i, 0.0);
	}

	// remove errors the hard way, else root ALWAYS plots them
	if ( !plotPoints ) hCL = histHardCopy(hCL, true, true);

	// disable any statistics box
	hCL->SetStats(0);

	// Convert the histogram into a TGraph so we can add the solution.
	// Also, the lf2 drawing option is broken in latest root versions.
	TGraph *g;
	if ( plotPoints ) g = new TGraphErrors(hCL->GetNbinsX());
	else              g = new TGraph(hCL->GetNbinsX());
	g->SetName(getUniqueRootName());
	for ( int i=0; i<hCL->GetNbinsX(); i++ ){
		g->SetPoint(i, hCL->GetBinCenter(i+1), hCL->GetBinContent(i+1));
		if ( plotPoints ) ((TGraphErrors*)g)->SetPointError(i, 0.0, hCL->GetBinError(i+1));
	}

	// add solution
	if ( ! s->getSolutions().empty() ){
		TGraphTools t;
		TGraph *gNew = t.addPointToGraphAtFirstMatchingX(g, s->getScanVar1Solution(0), 1.0);
		delete g;
		g = gNew;
	}

	// // set last point to the same p-value as first point by hand
	// // some angle plots sometimes don't manage to do it by themselves...
	// if ( arg->isQuickhack(XX) )
	// {
	//   Double_t pointx0, pointy0, err0;
	//   Double_t pointx1, pointy1, err1;
	//   g->GetPoint(0, pointx0, pointy0);
	//   g->GetPoint(g->GetN()-1, pointx1, pointy1);
	//   g->SetPoint(g->GetN()-1, pointx1, pointy0);
	//   if ( plotPoints ) err0 = ((TGraphErrors*)g)->GetErrorY(0);
	//   if ( plotPoints ) ((TGraphErrors*)g)->SetPointError(g->GetN()-1, 0.0, err0);
	// }

	// add end points of scan range
	if ( !plotPoints )
	{
		Double_t pointx0, pointy0;
		TGraph *gNew = new TGraph(g->GetN()+4);
		gNew->SetName(getUniqueRootName());
		for ( int i=0; i<g->GetN(); i++)
		{
			g->GetPoint(i, pointx0, pointy0);
			gNew->SetPoint(i+2, pointx0, pointy0);
		}

		// add origin
		gNew->SetPoint(0, hCL->GetXaxis()->GetXmin(), 0);

		// add a point at first y height but at x=origin.
		g->GetPoint(0, pointx0, pointy0);
		gNew->SetPoint(1, hCL->GetXaxis()->GetXmin(), pointy0);

		// add a point at last y height but at x=xmax.
		g->GetPoint(g->GetN()-1, pointx0, pointy0);
		gNew->SetPoint(gNew->GetN()-2, hCL->GetXaxis()->GetXmax(), pointy0);

		// add a point at xmax, 0
		gNew->SetPoint(gNew->GetN()-1, hCL->GetXaxis()->GetXmax(), 0);
		g = gNew;
	}

	int color = s->getLineColor();
	if(CLsType>0 && s->getMethodName().Contains("Plugin") && !arg->plotpluginonly) {
    if (CLsType==1) color = kBlue-7;
    else if (CLsType==2) color = kBlue+2;
  }
	else if(CLsType>0) {
    if (CLsType==1) color = s->getLineColor() - 5;
    if (CLsType==2) color = s->getLineColor() - 4;
  }
	g->SetLineColor(color);

	if ( filled ){
		g->SetLineWidth(2);
    double alpha = arg->isQuickhack(12) ? 0.4 : 1.;
    if ( arg->isQuickhack(24) ) alpha = 0.;
		g->SetFillColorAlpha(color,alpha);
		g->SetLineStyle(1);
    g->SetFillStyle( s->getFillStyle() );
	}
	else{
		g->SetLineWidth(2);
		g->SetLineStyle(s->getLineStyle());
    if ( last && arg->isQuickhack(25) ) g->SetLineWidth(3);
	}

	if ( plotPoints ){
		g->SetLineWidth(1);
		g->SetMarkerColor(color);
		g->SetMarkerStyle(8);
		g->SetMarkerSize(0.6);
		if(CLsType==1) {
			g->SetMarkerStyle(33);
			g->SetMarkerSize(1);
		}
		if(CLsType==2) {
			g->SetMarkerStyle(21);
		}
	}

	// build a histogram which holds the axes
	float min = arg->scanrangeMin == arg->scanrangeMax ? hCL->GetXaxis()->GetXmin() : arg->scanrangeMin;
	float max = arg->scanrangeMin == arg->scanrangeMax ? hCL->GetXaxis()->GetXmax() : arg->scanrangeMax;
	TH1F *haxes = new TH1F("haxes"+getUniqueRootName(), "", 100, min, max);
	haxes->SetStats(0);
	haxes->GetXaxis()->SetTitle(s->getScanVar1()->GetTitle());
	haxes->GetYaxis()->SetTitle("1-CL");
	haxes->GetXaxis()->SetLabelFont(font);
	haxes->GetYaxis()->SetLabelFont(font);
	haxes->GetXaxis()->SetTitleFont(font);
	haxes->GetYaxis()->SetTitleFont(font);
	haxes->GetXaxis()->SetTitleOffset(0.9);
	haxes->GetYaxis()->SetTitleOffset(0.85);
	haxes->GetXaxis()->SetLabelSize(labelsize);
	haxes->GetYaxis()->SetLabelSize(labelsize);
	haxes->GetXaxis()->SetTitleSize(titlesize);
	haxes->GetYaxis()->SetTitleSize(titlesize);
	int xndiv = arg->ndiv==-1 ? 407 : abs(arg->ndiv);
	bool optimizeNdiv = arg->ndiv<0 ? true : false;
	haxes->GetXaxis()->SetNdivisions(xndiv, optimizeNdiv);
	haxes->GetYaxis()->SetNdivisions(407, true);

  // plot y range
  float plotYMax;
  float plotYMin;
  if ( plotLegend && !arg->isQuickhack(22) ) {
    if ( arg->plotlog ) { plotYMin = 1.e-3; plotYMax = 10.; }
    else                { plotYMin = 0.0  ; plotYMax = 1.3; }
  }
  else {
    if ( arg->plotlog ) { plotYMin = 1.e-3; plotYMax = 1.0; }
    else                { plotYMin = 0.0  ; plotYMax = 1.0; }
  }
  // change if passed as option
	plotYMin = arg->plotymin > 0. ? arg->plotymin : plotYMin;
  plotYMax = arg->plotymax > 0. ? arg->plotymax : plotYMax;

  haxes->GetYaxis()->SetRangeUser( plotYMin, plotYMax );
	haxes->Draw("axissame");
	g->SetHistogram(haxes);

	TString drawOption = "";
	if ( plotPoints )   drawOption += " pe";
	else if ( filled )  drawOption += " F";
	else                drawOption += " L";
	if ( first )        drawOption += " A";
	g->Draw(drawOption);
  //if ( drawOption.Contains("F") ) ((TGraph*)g->Clone())->Draw("L");

	gPad->Update();
	float ymin = gPad->GetUymin();
	float ymax = gPad->GetUymax();
	float xmin = gPad->GetUxmin();
	float xmax = gPad->GetUxmax();

	// for the angles, draw a new axis in units of degrees
	if ( isAngle(s->getScanVar1()) ){
		haxes->GetXaxis()->SetTitle(s->getScanVar1()->GetTitle() + TString(" [#circ]"));
		haxes->GetXaxis()->SetNdivisions(0);  // disable old axis
		if ( last ){
			// new top axis
			TString chopt = "-U"; // - = downward ticks, U = unlabeled, http://root.cern.ch/root/html534/TGaxis.html
			if ( !optimizeNdiv ) chopt += "N"; // n = no bin optimization
			TGaxis *axist = new TGaxis(xmin, 1, xmax, 1, RadToDeg(xmin), RadToDeg(xmax), xndiv, chopt);
			axist->SetName("axist");
			axist->Draw();

			// new bottom axis
			float axisbMin = RadToDeg(xmin);
			float axisbMax = RadToDeg(xmax);
			if ( arg->isQuickhack(3) ){ ///< see documentation of --qh option in OptParser.cpp
				axisbMin += 180.;
				axisbMax += 180.;
			}
			chopt = ""; // - = downward ticks, U = unlabeled, http://root.cern.ch/root/html534/TGaxis.html
			if ( !optimizeNdiv ) chopt += "N"; // n = no bin optimization
			TGaxis *axisb = new TGaxis(xmin, ymin, xmax, ymin, axisbMin, axisbMax, xndiv, chopt);
			axisb->SetName("axisb");
			axisb->SetLabelFont(font);
			axisb->SetLabelSize(labelsize);
			axisb->Draw();
		}
	}
	else
	{
		if ( last ){
			// add top axis
			TString chopt = "-U"; // - = downward ticks, U = unlabeled, http://root.cern.ch/root/html534/TGaxis.html
			if ( !optimizeNdiv ) chopt += "N"; // n = no bin optimization
			TGaxis *axist = new TGaxis(xmin, 1.0, xmax, 1.0, xmin, xmax, xndiv, chopt);
			axist->SetName("axist");
			axist->SetLineWidth(1);
			axist->Draw();
		}
	}

	if ( last )
	{
		// add right axis
		TGaxis *axisr = 0;
		if ( arg->plotlog ){
			float f3min = 1e-3;
			float f3max = (plotLegend && !arg->isQuickhack(22)) ? 10. : 1.;
			TF1 *f3 = new TF1("f3","log10(x)",f3min,f3max);
			axisr = new TGaxis(xmax, f3min, xmax, f3max, "f3", 510, "G+");
		}
		else{
			axisr = new TGaxis(xmax, ymin, xmax, ymax, 0, (plotLegend && !arg->isQuickhack(22)) ? 1.3 : 1.0, 407, "+");
		}
		axisr->SetLabelSize(0);
		axisr->SetLineWidth(1);
		axisr->SetName("axisr");
		axisr->SetLabelColor(kWhite);
		axisr->SetTitleColor(kWhite);
		axisr->Draw();

		// redraw right axis as well because the 1-CL graph can cover the old one
		haxes->Draw("axissame");
	}

	return g;
}
Exemple #3
0
void PlotDensity1D( const TString &sim, Int_t time, Int_t Nbins=1, const TString &options="") {
  
#ifdef __CINT__  
  gSystem->Load("libplasma.so");
#endif

  PlasmaGlob::Initialize();
  
  // Init Units table
  PUnits::UnitsTable::Get();

  // Load PData
  PData *pData = PData::Get(sim.Data());
  pData->LoadFileNames(time);
  if(!pData->IsInit()) return; 

  TString opt = options;
 
  gStyle->SetPadRightMargin(0.20); // Margin right axis 
  if(opt.Contains("grid")) {
    gStyle->SetPadGridX(1);
    gStyle->SetPadGridY(1);
  }

  Bool_t CYL = kFALSE;
  if(sim.Contains("cyl")) { CYL = kTRUE; opt += "cyl"; } 
  
  Bool_t ThreeD = kFALSE;
  if(sim.Contains("3D")) ThreeD = kTRUE; 

  Bool_t INT = kTRUE; // Integrate instead of averaging.
  
  // Some plasma constants
  Float_t n0 = pData->GetPlasmaDensity(); 
  Float_t kp = pData->GetPlasmaK();       
  Float_t skindepth = (1/kp);               
  Float_t E0 = pData->GetPlasmaE0();

  // Some beam properties:
  Double_t Ebeam = pData->GetBeamEnergy();
  Double_t gamma = pData->GetBeamGamma();
  Double_t vbeam = pData->GetBeamVelocity();
  Double_t kbeta = PFunc::BeamBetatronWavenumber(gamma,n0);
  Double_t rms0  = pData->GetBeamRmsY() * kp;
  if(CYL)  rms0  = pData->GetBeamRmsR() * kp;
  
  cout << Form(" - Bunch gamma      = %8.4f", gamma ) << endl;
  cout << Form(" - Bunch velocity   = %8.4f c", vbeam ) << endl;
  cout << Form(" - Bunch betatron k = %8.4f mm-1", kbeta * PUnits::mm) << endl;
  cout << Form(" - Bunch RMS_0      = %8.4f um", rms0 * skindepth / PUnits::um) << endl;
  cout << endl;

  // Time in OU
  Float_t Time = pData->GetRealTime();
  // z start of the plasma in normalized units.
  Float_t zStartPlasma = pData->GetPlasmaStart()*kp;
  // z start of the beam in normalized units.
  Float_t zStartBeam = pData->GetBeamStart()*kp;
  
  if(opt.Contains("center")) {
    Time -= zStartPlasma;
    if(opt.Contains("comov"))      // Centers on the head of the beam.
      Time += zStartBeam;
  }
  
  // Get charge density histos
  Int_t Nspecies = pData->NSpecies();
  TH1F **hDen1D = new TH1F*[Nspecies];
  TH2F *hDen2D = NULL;
  for(Int_t i=0;i<Nspecies;i++) {
    hDen1D[i] = NULL;
    
    if(!pData->GetChargeFileName(i)) 
      continue;
    
    if(i==0) {
      if(ThreeD)
	hDen2D = pData->GetCharge2DSliceZY(i,-1,Nbins);
      else
	hDen2D = pData->GetCharge(i,opt);
      
      char hName[24];
      sprintf(hName,"hDen_%i",i);
      hDen2D->SetName(hName);
      hDen2D->GetXaxis()->CenterTitle();
      hDen2D->GetYaxis()->CenterTitle();
      hDen2D->GetZaxis()->CenterTitle();
      hDen2D->GetXaxis()->SetTitle("z [c/#omega_{p}]");
      hDen2D->GetYaxis()->SetTitle("y [c/#omega_{p}]");
      if(i==0)
	hDen2D->GetZaxis()->SetTitle("#LTn_{e}#GT [n_{0}]");
      else
	hDen2D->GetZaxis()->SetTitle("#LTn_{b}#GT [n_{0}]");
    }
    
    if(Nbins==0) {
      Nbins = TMath::Nint(rms0 / hDen2D->GetYaxis()->GetBinWidth(1)) ;
      // cout << Form(" Rms0 = %6.2f  Dx = %6.2f  Nbins = %4i .", 
      // 	   rms0, hDen2D[i]->GetYaxis()->GetBinWidth(1), Nbins) << endl;
    }
    
    // 1D histograms
    TString opth1 = opt;
    opth1 += "avg";
    if(CYL) opth1 += "cyl";
    
    if(ThreeD) {
      hDen1D[i] = pData->GetH1SliceZ3D(pData->GetChargeFileName(i)->c_str(),"charge",-1,Nbins,-1,Nbins);
    } else if(CYL) { // Cylindrical: The first bin with r>0 is actually the number 1 (not the 0).
      hDen1D[i] = pData->GetH1SliceZ(pData->GetChargeFileName(i)->c_str(),"charge",1,Nbins,opth1.Data());
    } else {         // 2D cartesian
      hDen1D[i] = pData->GetH1SliceZ(pData->GetChargeFileName(i)->c_str(),"charge",-1,Nbins,opth1.Data());
    }
    
    char hName[24];
    sprintf(hName,"hDen_%i",i);
    hDen1D[i]->SetName(hName);
    hDen1D[i]->GetXaxis()->SetTitle("z [c/#omega_{p}]");
    hDen1D[i]->GetYaxis()->SetTitle("#LTn_{e}#GT [n_{0}]");
    
  }
  
  // Get electric fields
  const Int_t Nfields = 2;
  TH1F **hE1D = new TH1F*[Nfields];
  for(Int_t i=0;i<Nfields;i++) {
    hE1D[i] = NULL;
    
    if(!pData->GetEfieldFileName(i)) 
      continue;

    // 1D histograms
    TString opth1 = opt;
    opth1 += "avg";
    if(CYL) opth1 += "cyl";
    
    char nam[3]; sprintf(nam,"e%i",i+1);
    if(ThreeD) {
      if(i==0) 
	hE1D[i] = pData->GetH1SliceZ3D(pData->GetEfieldFileName(i)->c_str(),nam,-1,Nbins,-1,Nbins);
      else  
	hE1D[i] = pData->GetH1SliceZ3D(pData->GetEfieldFileName(i)->c_str(),nam,-Nbins,Nbins,-Nbins,Nbins);
    } else if(CYL) { // Cylindrical: The firt bin with r>0 is actually the number 1 (not the 0).
      if(i==0) 
	hE1D[i] = pData->GetH1SliceZ(pData->GetEfieldFileName(i)->c_str(),nam,1,Nbins,opth1.Data());
      else
	hE1D[i] = pData->GetH1SliceZ(pData->GetEfieldFileName(i)->c_str(),nam,1,Nbins,opth1.Data());
    } else {         // 2D cartesian
      if(i==0) 
	hE1D[i] = pData->GetH1SliceZ(pData->GetEfieldFileName(i)->c_str(),nam,-1,Nbins,opth1.Data());
      else 
	hE1D[i] = pData->GetH1SliceZ(pData->GetEfieldFileName(i)->c_str(),nam,-Nbins,Nbins,opth1.Data());
    }
    
    
    char hName[24];
    sprintf(hName,"hE_%i",i);
    hE1D[i]->SetName(hName);
    hE1D[i]->GetXaxis()->SetTitle("z [c/#omega_{p}]");
    hE1D[i]->GetYaxis()->SetTitle("E [E_{e}]");
  }
  
  // Y range:
  Int_t NbinsY  = (Int_t) hDen2D->GetNbinsY();
  Int_t midyBin = NbinsY/2;
  if(!CYL && (Nbins >  midyBin) ) Nbins = midyBin;
  if(CYL  && (Nbins >= NbinsY ) ) Nbins = NbinsY-1;
  
  Int_t FirstyBin = midyBin + 1 - Nbins;
  Int_t LastyBin  = midyBin + Nbins;
  if(CYL) {
    FirstyBin = 1; 
    LastyBin  = Nbins;
  }
  
  if(LastyBin>=NbinsY) LastyBin = NbinsY - 1;
  Float_t ymin = hDen2D->GetYaxis()->GetBinLowEdge(FirstyBin);
  Float_t ymax = hDen2D->GetYaxis()->GetBinLowEdge(LastyBin+1);

  cout << Form(" Nbins = %i. Firstbin = %i Lastbin = %i  ->  ymin = %7.2f , ymax = %7.2f",Nbins,FirstyBin,LastyBin,ymin,ymax) << endl;
  // ----

  // Tunning the Histograms
  // ---------------------

  // Chaning to user units: 

  // cout << Form(" n0 = %10e ", n0 * PUnits::cm3) << endl;
  
  if(opt.Contains("units") && n0) {
    
    Int_t NbinsX = hDen2D->GetNbinsX();
    Float_t xMin = skindepth * hDen2D->GetXaxis()->GetXmin() / PUnits::mm;
    Float_t xMax = skindepth * hDen2D->GetXaxis()->GetXmax() / PUnits::mm;
    Int_t NbinsY = hDen2D->GetNbinsY();
    Float_t yMin = skindepth * hDen2D->GetYaxis()->GetXmin() / PUnits::mm;
    Float_t yMax = skindepth * hDen2D->GetYaxis()->GetXmax() / PUnits::mm;
    hDen2D->SetBins(NbinsX,xMin,xMax,NbinsY,yMin,yMax);
    for(Int_t j=0;j<hDen2D->GetNbinsX();j++) {
      for(Int_t k=0;k<hDen2D->GetNbinsY();k++) {
	hDen2D->SetBinContent(j,k, hDen2D->GetBinContent(j,k) * n0 / (1e15/PUnits::cm3) );
      }
    }
    
    hDen2D->GetYaxis()->SetTitle("y [mm]");      
    if(opt.Contains("comov"))
      hDen2D->GetXaxis()->SetTitle("#zeta [mm]");
    else
      hDen2D->GetXaxis()->SetTitle("z [mm]");
    
    hDen2D->GetZaxis()->SetTitle("#LTn_{b}#GT [10^{15}/cm^{3}]"); 
  
    
    for(Int_t i=0;i<Nspecies;i++) {
    
      Int_t NbinsX = hDen1D[i]->GetNbinsX();
      Float_t xMin = skindepth * hDen1D[i]->GetXaxis()->GetXmin() / PUnits::mm;
      Float_t xMax = skindepth * hDen1D[i]->GetXaxis()->GetXmax() / PUnits::mm;
      hDen1D[i]->SetBins(NbinsX,xMin,xMax);
      for(Int_t j=0;j<hDen1D[i]->GetNbinsX();j++) {
	Float_t bincontent = (hDen1D[i]->GetBinContent(j) * n0 / (1e15/PUnits::cm3));
	hDen1D[i]->SetBinContent(j,bincontent);
      }
      
      hDen1D[i]->GetYaxis()->SetTitle("#LTn_{e}#GT [10^{15}/cm^{3}]");
      
      if(opt.Contains("comov"))
	hDen1D[i]->GetXaxis()->SetTitle("#zeta [mm]");
      else
	hDen1D[i]->GetXaxis()->SetTitle("z [mm]");
    
    }


    for(Int_t i=0;i<Nfields;i++) {
      Int_t NbinsX = hE1D[i]->GetNbinsX();
      Float_t xMin = skindepth * hE1D[i]->GetXaxis()->GetXmin() / PUnits::mm;
      Float_t xMax = skindepth * hE1D[i]->GetXaxis()->GetXmax() / PUnits::mm;
      hE1D[i]->SetBins(NbinsX,xMin,xMax);
      
      for(Int_t j=0;j<hE1D[i]->GetNbinsX();j++) {
	hE1D[i]->SetBinContent(j, hE1D[i]->GetBinContent(j) * ( E0 / (PUnits::GV/PUnits::m) ) );
      }
      
      hE1D[i]->GetYaxis()->SetTitle("E [GV/m]");
      
      if(opt.Contains("comov"))
	hE1D[i]->GetXaxis()->SetTitle("#zeta [mm]");
      else
	hE1D[i]->GetXaxis()->SetTitle("z [mm]");
    }
  }
  
  // Set the range of the histogram for maximum constrast
  Float_t density = 1;
  if(opt.Contains("units") && n0)
    density = 1e-15 * 1e-6 * n0;
  
  Float_t Max  = 1.1*hDen1D[0]->GetMaximum();
  Float_t Min  = 0;
  // Float_t Base = density;
  // Float_t Min  = 2.* Base - Max;
  // if(Max >= 2. * Base) {
  //   Max = 2. * Base;
  //   Min = 2. * Base  - Max;
  // } else if(Max<1.0 * Base) {
  //   Max = 1.1 * Base;
  //   Min = 0.;
  // }
 
  hDen1D[0]->GetYaxis()->SetRangeUser(0.,Max);  
  
  // Plotting
  // -----------------------------------------------

  // Canvas setup
  TCanvas *C = new TCanvas("C","Charge density and Electric field on axis",850,500);

  TPaveText *textTime = new TPaveText(0.63,0.87,0.78,0.92,"NDC");
  PlasmaGlob::SetPaveTextStyle(textTime); 
  textTime->SetTextColor(kGray+2);
  char ctext[128];

  if(opt.Contains("units") && n0) 
    sprintf(ctext,"Z = %5.1f mm", 1e3 * skindepth * Time);
  else
    sprintf(ctext,"T = %5.1f 1/#omega_{p}",Time);
  textTime->AddText(ctext);

  
  TPaveText *textRange = new TPaveText(0.13,0.87,0.38,0.92,"NDC");
  PlasmaGlob::SetPaveTextStyle(textRange,12); 
  textRange->SetTextColor(kGray+2);
  if(opt.Contains("units") && n0)
    sprintf(ctext,"%5.3f < y < %5.3f mm",ymin,ymax);
  else
    sprintf(ctext,"%5.3f < y < %5.3f c/#omega_{p}",ymin,ymax);
  textRange->AddText(ctext);

  // Actual Plotting!
  // ------------------------------------------------------------

  // Output file
  TString fOutName = Form("./%s/Plots/Density1D/Density1D",sim.Data());
  fOutName += Form("-%s_%i",sim.Data(),time);

  // Colors
  Int_t plasmaC = kGray+1;
  Int_t beamC   = kAzure-5;
  Int_t fieldC  = kOrange+10;
  Int_t fieldCb = kGray+1;

  C->cd(0);
  gPad->SetFrameLineWidth(2);  

  hDen1D[0]->SetLineColor(plasmaC);
  hDen1D[0]->SetLineWidth(1);
  hDen1D[0]->Draw("C");
  hDen1D[0]->GetYaxis()->CenterTitle();
  hDen1D[0]->GetXaxis()->CenterTitle();
  
  C->Update();

  TLine *line0 = new TLine(hDen1D[0]->GetXaxis()->GetXmin(),
			  (gPad->GetUymin()+gPad->GetUymax())/2.,
			  hDen1D[0]->GetXaxis()->GetXmax(),
			  (gPad->GetUymin()+gPad->GetUymax())/2.);
  line0->SetLineColor(kGray+1);
  line0->SetLineStyle(2);
  line0->Draw();

  Float_t rightmax = 2.5 * hDen1D[1]->GetMaximum();
  Float_t slope = (gPad->GetUymax() - gPad->GetUymin())/rightmax;

  for(Int_t i=0;i<hDen1D[1]->GetNbinsX();i++) {
    hDen1D[1]->SetBinContent(i+1,hDen1D[1]->GetBinContent(i+1)*slope + Min);
  }

  hDen1D[1]->SetLineWidth(2);
  hDen1D[1]->SetLineColor(beamC);
  hDen1D[1]->Draw("same C");
  // hTest->Draw("same");
 
  //draw an axis on the right side
  TGaxis *axis = new TGaxis(gPad->GetUxmax(),gPad->GetUymin(),gPad->GetUxmax(),
			    gPad->GetUymax(),0,rightmax,505,"+L");
  
  axis->SetLineWidth(1);
  axis->SetLineColor(beamC);
  axis->SetLabelColor(beamC);
  if(opt.Contains("units") && n0) 
    axis->SetTitle("#LTn_{b}#GT [10^{15}/cm^{3}]");
  else
    axis->SetTitle("#LTn_{b}#GT [n_{0}]");
  axis->CenterTitle();
  axis->SetTitleColor(beamC);
  axis->SetTitleOffset(1.2);
  
  axis->Draw();

  // Longitudinal Electric field
  Float_t factor = 1.5;
  Float_t rightmin = factor * hE1D[0]->GetMinimum();
  rightmax = factor * hE1D[0]->GetMaximum();
  if(hE1D[1]) {
    if(hE1D[1]->GetMaximum() > hE1D[0]->GetMaximum())
      rightmax = factor * hE1D[1]->GetMaximum();
  }
  
  if(rightmax > TMath::Abs(rightmin)) rightmin = -rightmax;
  else rightmax = - rightmin;
  slope = (gPad->GetUymax() - gPad->GetUymin())/(rightmax-rightmin);
  
  for(Int_t i=0;i<hE1D[0]->GetNbinsX();i++) {
    hE1D[0]->SetBinContent(i+1,(hE1D[0]->GetBinContent(i+1)-rightmin)*slope + Min);
  }
  
  hE1D[0]->SetLineStyle(1);
  hE1D[0]->SetLineWidth(2);
  hE1D[0]->SetLineColor(fieldC);
  hE1D[0]->Draw("same C");

  // Transverse field
  for(Int_t i=0;i<hE1D[1]->GetNbinsX();i++) {
    hE1D[1]->SetBinContent(i+1,(hE1D[1]->GetBinContent(i+1)-rightmin)*slope + Min);
  }
  
  hE1D[1]->SetLineStyle(2);
  hE1D[1]->SetLineWidth(1);
  hE1D[1]->SetLineColor(fieldC);
  hE1D[1]->Draw("same C");

  //draw an axis on the right side
  Float_t rightmargin = 0.08;
  Float_t ux = gPad->PixeltoX(gPad->UtoPixel(1-rightmargin));
  TGaxis *axisE = new TGaxis(ux,gPad->GetUymin(),ux,
			     gPad->GetUymax(),rightmin,rightmax,505,"+L");
  
  axisE->SetLineWidth(1);
  axisE->SetLineColor(fieldC);
  axisE->SetLabelColor(fieldC);
  axisE->SetTitleColor(fieldC);
  if(opt.Contains("units") && n0) 
    axisE->SetTitle("E [GV/m]");
  else
    axisE->SetTitle("E [E_{0}]");
  axisE->CenterTitle();
  axisE->SetTitleOffset(0.8);

  axisE->Draw();
  
  textTime->Draw();

  textRange->Draw();

  C->cd();

  // Print to a file
  PlasmaGlob::imgconv(C,fOutName,opt);
  // ---------------------------------------------------------
}
Exemple #4
0
void PlotPotential2D( const TString &sim, Int_t time, Int_t zoom=2, Int_t Nbins=2, const TString &options="") {

#ifdef __CINT__
    gSystem->Load("libplasma.so");
#endif

    PlasmaGlob::Initialize();

    // Palettes!
    gROOT->Macro("PlasmaPalettes.C");

    // Init Units table
    PUnits::UnitsTable::Get();

    // Load PData
    PData *pData = PData::Get(sim.Data());
    pData->LoadFileNames(time);
    if(!pData->IsInit()) return;

    TString opt = options;

    // More makeup
    gStyle->SetPadGridY(0);
    if(opt.Contains("gridx")) {
        gStyle->SetPadGridX(1);
    }
    if(opt.Contains("gridy")) {
        gStyle->SetPadGridY(1);
    }


    // Some plasma constants
    Double_t n0 = pData->GetPlasmaDensity();
    Double_t omegap = pData->GetPlasmaFrequency();
    Double_t timedepth = 1.;
    if(omegap!=0.0) timedepth = 1/omegap;
    Double_t kp = pData->GetPlasmaK();
    Double_t skindepth = 1.;
    if(kp!=0.0) skindepth = 1/kp;
    Double_t E0 = pData->GetPlasmaE0();

    // Some beam properties:
    Double_t Ebeam = pData->GetBeamEnergy();
    Double_t gamma = pData->GetBeamGamma();
    Double_t vbeam = pData->GetBeamVelocity();

    cout << Form(" - Bunch gamma      = %8.4f", gamma ) << endl;
    cout << Form(" - Bunch velocity   = %8.4f c", vbeam ) << endl;

    // Other parameters
    Float_t trapPotential = 1.0 - (1.0/gamma);
    cout << Form(" - Trap. potential  = %8.4f mc2/e",trapPotential) << endl;
    cout << endl;

    // Time in OU
    Float_t Time = pData->GetRealTime();
    // z start of the plasma in normalized units.
    Float_t zStartPlasma = pData->GetPlasmaStart()*kp;
    // z start of the beam in normalized units.
    Float_t zStartBeam = pData->GetBeamStart()*kp;
    // z start of the neutral in normalized units.
    Float_t zStartNeutral = pData->GetNeutralStart()*kp;
    // z end of the neutral in normalized units.
    Float_t zEndNeutral = pData->GetNeutralEnd()*kp;

    if(opt.Contains("center")) {
        Time -= zStartPlasma;
        if(opt.Contains("comov"))      // Centers on the head of the beam.
            Time += zStartBeam;
    }
    Float_t shiftz = pData->Shift(opt);
    //  cout << "Shift = " << shiftz << endl;


    // Calculate the "axis range" in number of bins. If Nbins==0 a RMS width is taken.
    Double_t rms0 = pData->GetBeamRmsY() * kp;
    if(pData->IsCyl())  rms0  = pData->GetBeamRmsR() * kp;

    Int_t FirstyBin = 0;
    Int_t LastyBin = 0;
    if(Nbins==0) {
        if(rms0>0.0)
            Nbins =  TMath::Nint(rms0 / pData->GetDX(1));
        else
            Nbins = 1;
    }

    // Slice width limits.
    if(!pData->IsCyl()) {
        FirstyBin = pData->GetNX(1)/2 + 1 - Nbins;
        LastyBin =  pData->GetNX(1)/2 + Nbins;
    } else {
        FirstyBin = 1;
        LastyBin  = Nbins;
    }
    // ----------------------------------------------------------------------------------


    // Get charge density histos
    Int_t Nspecies = pData->NSpecies();
    TH2F **hDen2D = new TH2F*[Nspecies];
    // Get charge density on-axis
    TH1F **hDen1D = new TH1F*[Nspecies];
    // And electric current (integrated)
    TH1F **hCur1D = new TH1F*[Nspecies];
    for(Int_t i=0; i<Nspecies; i++) {

        hDen2D[i] = NULL;

        if(!pData->GetChargeFileName(i))
            continue;

        cout << Form(" Getting charge density of specie: ") << i << endl;


        char hName[24];
        sprintf(hName,"hDen2D_%i",i);
        hDen2D[i] = (TH2F*) gROOT->FindObject(hName);
        if(hDen2D[i]) delete hDen2D[i];

        if(!pData->Is3D())
            hDen2D[i] = pData->GetCharge(i,opt);
        else
            hDen2D[i] = pData->GetCharge2DSliceZY(i,-1,Nbins,opt+"avg");

        hDen2D[i]->SetName(hName);
        hDen2D[i]->GetXaxis()->CenterTitle();
        hDen2D[i]->GetYaxis()->CenterTitle();
        hDen2D[i]->GetZaxis()->CenterTitle();

        if(opt.Contains("comov"))
            hDen2D[i]->GetXaxis()->SetTitle("k_{p} #zeta");
        else
            hDen2D[i]->GetXaxis()->SetTitle("k_{p} z");

        if(pData->IsCyl())
            hDen2D[i]->GetYaxis()->SetTitle("k_{p} r");
        else
            hDen2D[i]->GetYaxis()->SetTitle("k_{p} y");

        hDen2D[i]->GetZaxis()->SetTitle("n [n_{0}]");


        hDen1D[i] = NULL;
        hCur1D[i] = NULL;

        if(!pData->GetEfieldFileName(i))
            continue;

        sprintf(hName,"hDen1D_%i",i);
        hDen1D[i] = (TH1F*) gROOT->FindObject(hName);
        if(hDen1D[i]) delete hDen1D[i];

        // 1D histograms
        if(pData->Is3D()) {
            hDen1D[i] = pData->GetH1SliceZ3D(pData->GetChargeFileName(i)->c_str(),"charge",-1,Nbins,-1,Nbins,opt+"avg");
        } else if(pData->IsCyl()) { // Cylindrical: The first bin with r>0 is actually the number 1 (not the 0).
            hDen1D[i] = pData->GetH1SliceZ(pData->GetChargeFileName(i)->c_str(),"charge",1,Nbins,opt+"avg");
        } else { // 2D cartesian
            hDen1D[i] = pData->GetH1SliceZ(pData->GetChargeFileName(i)->c_str(),"charge",-1,Nbins,opt+"avg");
        }
        hDen1D[i]->SetName(hName);

        // if(hDen1D[i]) delete hDen1D[i];
        // hDen1D[i] = (TH1F*) hE2D[i]->ProjectionX(hName,FirstyBin,LastyBin);
        // hDen1D[i]->Scale(1.0/(LastyBin-FirstyBin+1));

        if(opt.Contains("comov"))
            hDen1D[i]->GetXaxis()->SetTitle("#zeta [c/#omega_{p}]");
        else
            hDen1D[i]->GetXaxis()->SetTitle("z [c/#omega_{p}]");

        if(i==0)
            hDen1D[i]->GetYaxis()->SetTitle("n/n_{0}");
        else if(i==1)
            hDen1D[i]->GetYaxis()->SetTitle("n_{b}/n_{0}");
        else
            hDen1D[i]->GetYaxis()->SetTitle("n_{i}/n_{0}");

        // Get the current:
        if(i==0) continue;

        sprintf(hName,"hCur1D_%i",i);
        hCur1D[i] = (TH1F*) gROOT->FindObject(hName);
        if(hCur1D[i]) delete hCur1D[i];

        if(opt.Contains("curr")) {
            // To get the current is needed to read in a wider transverse range which includes all the charge.
            Int_t NbinsT = 100;
            if(pData->Is3D()) {
                hCur1D[i] = pData->GetH1SliceZ3D(pData->GetChargeFileName(i)->c_str(),"charge",-1,NbinsT,-1,NbinsT,opt+"int");
            } else if(pData->IsCyl()) { // Cylindrical: The first bin with r>0 is actually the number 1 (not the 0).
                hCur1D[i] = pData->GetH1SliceZ(pData->GetChargeFileName(i)->c_str(),"charge",1,NbinsT,opt+"int");
            } else { // 2D cartesian
                hCur1D[i] = pData->GetH1SliceZ(pData->GetChargeFileName(i)->c_str(),"charge",-1,NbinsT,opt+"int");
            }
            hCur1D[i]->SetName(hName);

            if(opt.Contains("comov")) {
                hCur1D[i]->GetXaxis()->SetTitle("#zeta [c/#omega_{p}]");
                hCur1D[i]->GetYaxis()->SetTitle("dn/d#zeta [(n_{0}/k_{p}^{3}) (#omega_{p}/c)]");
            } else {
                hCur1D[i]->GetXaxis()->SetTitle("z [c/#omega_{p}]");
                hCur1D[i]->GetYaxis()->SetTitle("dn/dz [(n_{0}/k_{p}^{3}) (#omega_{p}/c)]");
            }

            Int_t NB = hCur1D[i]->GetNbinsX();
            Float_t dx = (hCur1D[i]->GetBinLowEdge(1)-hCur1D[i]->GetBinLowEdge(NB+1))/NB;

            // hCur1D[i]->Scale(dx);
            Float_t Charge = hCur1D[i]->Integral() * dx;

            cout << Form(" Integrated charge of specie %3i = %8.4f n0 * kp^-3",i,Charge) << endl;
        }
    }


    // Get electric fields 2D
    const Int_t Nfields = 3;
    TH2F **hE2D = new TH2F*[Nfields];
    TH1F **hE1D = new TH1F*[Nfields];
    TH2F *hV2D = NULL;
    TH1F *hV1D = NULL;
    for(Int_t i=0; i<Nfields; i++) {
        hE2D[i] = NULL;
        hE1D[i] = NULL;

        if(!pData->GetEfieldFileName(i))
            continue;

        cout << Form(" Getting electric field number ") << i+1 << endl;

        char hName[24];
        sprintf(hName,"hE2D_%i",i);
        hE2D[i] = (TH2F*) gROOT->FindObject(hName);
        if(hE2D[i]) delete hE2D[i];

        if(!pData->Is3D())
            hE2D[i] = pData->GetEField(i,opt);
        else
            hE2D[i] = pData->GetEField2DSliceZY(i,-1,Nbins,opt+"avg");

        hE2D[i]->SetName(hName);
        hE2D[i]->GetXaxis()->CenterTitle();
        hE2D[i]->GetYaxis()->CenterTitle();
        hE2D[i]->GetZaxis()->CenterTitle();
        if(opt.Contains("comov"))
            hE2D[i]->GetXaxis()->SetTitle("k_{p} #zeta");
        else
            hE2D[i]->GetXaxis()->SetTitle("k_{p} z");

        if(pData->IsCyl())
            hE2D[i]->GetYaxis()->SetTitle("k_{p} r");
        else
            hE2D[i]->GetYaxis()->SetTitle("k_{p} y");

        if(i==0)
            hE2D[i]->GetZaxis()->SetTitle("E_{z}/E_{0}");
        else if(i==1)
            hE2D[i]->GetZaxis()->SetTitle("E_{y}/E_{0}");
        else if(i==2)
            hE2D[i]->GetZaxis()->SetTitle("E_{x}/E_{0}");

        sprintf(hName,"hE1D_%i",i);
        hE1D[i] = (TH1F*) gROOT->FindObject(hName);
        if(hE1D[i]) delete hE1D[i];

        // 1D histograms
        char nam[3];
        sprintf(nam,"e%i",i+1);
        if(pData->Is3D()) {

            if(i==0)
                hE1D[i] = pData->GetH1SliceZ3D(pData->GetEfieldFileName(i)->c_str(),nam,-1,Nbins,-1,Nbins,opt+"avg");
            else
                hE1D[i] = pData->GetH1SliceZ3D(pData->GetEfieldFileName(i)->c_str(),nam,-Nbins,Nbins,-Nbins,Nbins,opt+"avg");

        } else if(pData->IsCyl()) { // Cylindrical: The first bin with r>0 is actually the number 1 (not the 0).

            hE1D[i] = pData->GetH1SliceZ(pData->GetEfieldFileName(i)->c_str(),nam,1,Nbins,opt+"avg");

        } else { // 2D cartesian

            if(i==0)
                hE1D[i] = pData->GetH1SliceZ(pData->GetEfieldFileName(i)->c_str(),nam,-1,Nbins,opt+"avg");
            else
                hE1D[i] = pData->GetH1SliceZ(pData->GetEfieldFileName(i)->c_str(),nam,-Nbins,Nbins,opt+"avg");
        }

        hE1D[i]->SetName(hName);
        if(opt.Contains("comov"))
            hE1D[i]->GetXaxis()->SetTitle("#zeta [c/#omega_{p}]");
        else
            hE1D[i]->GetXaxis()->SetTitle("z [c/#omega_{p}]");

        if(i==0)
            hE1D[i]->GetYaxis()->SetTitle("E_{z} [E_{0}]");
        else if(i==1)
            hE1D[i]->GetYaxis()->SetTitle("E_{y} [E_{0}]");
        else if(i==2)
            hE1D[i]->GetYaxis()->SetTitle("E_{x} [E_{0}]");

        // Alternative
        // if(hE1D[i]) delete hE1D[i];
        // hE1D[i] = (TH1F*) hE2D[i]->ProjectionX(hName,FirstyBin,LastyBin);
        // hE1D[i]->Scale(1.0/(LastyBin-FirstyBin+1));

        if(i==0) {
            Int_t   NbinsX = hE2D[i]->GetNbinsX();
            Int_t   NbinsY = hE2D[i]->GetNbinsY();

            Float_t dx = pData->GetDX(0);

            sprintf(hName,"hV2D");
            hV2D = (TH2F*) hE2D[i]->Clone(hName);
            hV2D->Reset();

            sprintf(hName,"hV1D");
            hV1D = (TH1F*) hE1D[i]->Clone(hName);
            hV1D->Reset();

            for(Int_t j=NbinsY; j>0; j--) {
                Double_t integral = 0.0;
                for(Int_t k=NbinsX; k>0; k--) {
                    integral += hE2D[i]->GetBinContent(k,j) * dx;
                    hV2D->SetBinContent(k,j,integral);
                }
            }

            Double_t integral = 0.0;
            for(Int_t k=NbinsX; k>0; k--) {
                integral += hE1D[i]->GetBinContent(k) * dx;
                hV1D->SetBinContent(k,integral);
            }

        }

    }

    // Now, combine the electric field components into the total |E|
    // and calculate ionization probability for He:
    // Outter Helium electron
    Double_t Eion0 = 24.59 * PUnits::eV;
    Double_t Z     = 1;

    TH2F *hETotal2D = (TH2F*) hE2D[0]->Clone("hETotal2D");
    hETotal2D->Reset();
    TH2F *hIonProb2D = (TH2F*) hE2D[0]->Clone("hIonProb2D");
    hIonProb2D->Reset();
    TH1F *hETotal1D = (TH1F*) hE1D[0]->Clone("hETotal1D");
    hETotal1D->Reset();
    TH1F *hIonProb1D = (TH1F*) hE1D[0]->Clone("hIonProb1D");
    hIonProb1D->Reset();
    {
        Int_t NbinsX = hE2D[0]->GetNbinsX();
        Int_t NbinsY = hE2D[0]->GetNbinsY();
        for(Int_t j=0; j<NbinsX; j++) {
            for(Int_t k=0; k<NbinsY; k++) {
                Double_t E1 = hE2D[0]->GetBinContent(j,k);
                Double_t E2 = hE2D[1]->GetBinContent(j,k);
                Double_t E3 = hE2D[2]->GetBinContent(j,k);
                Double_t E  = TMath::Sqrt(E1*E1+E2*E2+E3*E3);

                hETotal2D->SetBinContent(j,k,E);

                E *= E0;

                // Double_t IonProb = (PFunc::ADK(E,Eion0,Z,l,m)/PUnits::atomictime)*PUnits::femtosecond;
                Double_t IonProb = PFunc::ADK_ENG(E,Eion0,Z) * PUnits::femtosecond;
                // if(IonProb>1) IonProb = 1.0;
                // cout << "Ion prob = " << IonProb << endl;
                hIonProb2D->SetBinContent(j,k,IonProb);
            }
            Double_t E1 = hE1D[0]->GetBinContent(j);
            Double_t E2 = hE1D[1]->GetBinContent(j);
            Double_t E3 = hE1D[2]->GetBinContent(j);
            Double_t E  = TMath::Sqrt(E1*E1+E2*E2+E3*E3);

            hETotal1D->SetBinContent(j,E);

            E *= E0;

            // Double_t IonProb = (PFunc::ADK(E,Eion0,Z,l,m)/PUnits::atomictime)*PUnits::femtosecond;
            Double_t IonProb = PFunc::ADK_ENG(E,Eion0,Z) * PUnits::femtosecond;
            // cout << "Ion prob = " << IonProb << endl;

            hIonProb1D->SetBinContent(j,IonProb);


        }
    }
    hETotal2D->GetZaxis()->SetTitle("E [E_{0}]");
    hIonProb2D->GetZaxis()->SetTitle("W_{ADK} [fs^{-1}]");
    hETotal1D->GetYaxis()->SetTitle("E [E_{0}]");
    hIonProb1D->GetYaxis()->SetTitle("W_{ADK} [fs^{-1}]");



    // Tunning the Histograms
    // ---------------------

    // Chaning to user units:
    // --------------------------

    if(opt.Contains("units") && n0) {

        for(Int_t i=0; i<Nspecies; i++) {

            if(!hDen2D[i]) continue;

            Int_t NbinsX = hDen2D[i]->GetNbinsX();
            Float_t xMin = skindepth * hDen2D[i]->GetXaxis()->GetXmin() / PUnits::um;
            Float_t xMax = skindepth * hDen2D[i]->GetXaxis()->GetXmax() / PUnits::um;
            Int_t NbinsY = hDen2D[i]->GetNbinsY();
            Float_t ymin = skindepth * hDen2D[i]->GetYaxis()->GetXmin() / PUnits::um;
            Float_t ymax = skindepth * hDen2D[i]->GetYaxis()->GetXmax() / PUnits::um;
            hDen2D[i]->SetBins(NbinsX,xMin,xMax,NbinsY,ymin,ymax);
            // for(Int_t j=0;j<hDen2D[i]->GetNbinsX();j++) {
            // 	for(Int_t k=0;k<hDen2D[i]->GetNbinsY();k++) {
            // 	  hDen2D[i]->SetBinContent(j,k, hDen2D[i]->GetBinContent(j,k) * n0 / (1e17/PUnits::cm3) );
            // 	}
            // }

            if(pData->IsCyl())
                hDen2D[i]->GetYaxis()->SetTitle("r [#mum]");
            else
                hDen2D[i]->GetYaxis()->SetTitle("y [#mum]");

            if(opt.Contains("comov"))
                hDen2D[i]->GetXaxis()->SetTitle("#zeta [#mum]");
            else
                hDen2D[i]->GetXaxis()->SetTitle("z [#mum]");

            // if(i==0)
            // 	hDen2D[i]->GetZaxis()->SetTitle("n_{e} [10^{17}/cm^{3}]");
            // else if(i==1)
            // 	hDen2D[i]->GetZaxis()->SetTitle("n_{b} [10^{17}/cm^{3}]");
            // else
            // 	hDen2D[i]->GetZaxis()->SetTitle("n_{i} [10^{17}/cm^{3}]");

            hDen1D[i]->SetBins(NbinsX,xMin,xMax);
            // for(Int_t j=0;j<hDen1D[i]->GetNbinsX();j++) {
            // 	hDen1D[i]->SetBinContent(j, hDen1D[i]->GetBinContent(j) * n0 / (1e17/PUnits::cm3) );
            // }


            if(opt.Contains("comov"))
                hDen1D[i]->GetXaxis()->SetTitle("#zeta [#mum]");
            else
                hDen1D[i]->GetXaxis()->SetTitle("z [#mum]");

            if(hCur1D[i]) {

                hCur1D[i]->SetBins(NbinsX,xMin,xMax);
                Double_t binSize = (xMax - xMin)/NbinsX;  // bin size in um.

                Double_t dV = skindepth * skindepth * skindepth;
                Double_t lightspeed =  PConst::c_light / (PUnits::um/PUnits::femtosecond);

                hCur1D[i]->Scale(TMath::Abs(n0 * dV * (PConst::ElectronCharge/PUnits::picocoulomb) * (kp * PConst::c_light * PUnits::femtosecond)));

                hCur1D[i]->GetYaxis()->SetTitle("I[kA]");
                hCur1D[i]->GetYaxis()->SetTitle("");
                if(opt.Contains("comov"))
                    hCur1D[i]->GetXaxis()->SetTitle("#zeta [#mum]");
                else
                    hCur1D[i]->GetXaxis()->SetTitle("z [#mum]");


                Float_t Charge = hCur1D[i]->Integral() * (binSize / lightspeed);
                cout << Form(" Integrated charge of specie %3i = %8f pC",i,Charge) << endl;
            }
        }


        for(Int_t i=0; i<Nfields; i++) {
            Int_t NbinsX = hE2D[i]->GetNbinsX();
            Float_t xMin = skindepth * hE2D[i]->GetXaxis()->GetXmin() / PUnits::um;
            Float_t xMax = skindepth * hE2D[i]->GetXaxis()->GetXmax() / PUnits::um;
            Int_t NbinsY = hE2D[i]->GetNbinsY();
            Float_t ymin = skindepth * hE2D[i]->GetYaxis()->GetXmin() / PUnits::um;
            Float_t ymax = skindepth * hE2D[i]->GetYaxis()->GetXmax() / PUnits::um;
            hE2D[i]->SetBins(NbinsX,xMin,xMax,NbinsY,ymin,ymax);
            hE1D[i]->SetBins(NbinsX,xMin,xMax);

            for(Int_t j=0; j<hE2D[i]->GetNbinsX(); j++) {
                for(Int_t k=0; k<hE2D[i]->GetNbinsY(); k++) {
                    hE2D[i]->SetBinContent(j,k, hE2D[i]->GetBinContent(j,k) * ( E0 / (PUnits::GV/PUnits::m) ) );
                }
                hE1D[i]->SetBinContent(j, hE1D[i]->GetBinContent(j) * ( E0 / (PUnits::GV/PUnits::m) ) );
            }

            if(pData->IsCyl())
                hE2D[i]->GetYaxis()->SetTitle("r [#mum]");
            else
                hE2D[i]->GetYaxis()->SetTitle("y [#mum]");

            if(opt.Contains("comov"))
                hE2D[i]->GetXaxis()->SetTitle("#zeta [#mum]");
            else
                hE2D[i]->GetXaxis()->SetTitle("z [#mum]");

            if(i==0)
                hE2D[i]->GetZaxis()->SetTitle("E_{z} [GV/m]");
            else if(i==1)
                hE2D[i]->GetZaxis()->SetTitle("E_{y} [GV/m]");
            else if(i==2)
                hE2D[i]->GetZaxis()->SetTitle("E_{x} [GV/m]");


            if(opt.Contains("comov"))
                hE1D[i]->GetXaxis()->SetTitle("#zeta [mm]");
            else
                hE1D[i]->GetXaxis()->SetTitle("z [mm]");

            if(i==0)
                hE1D[i]->GetYaxis()->SetTitle("E_{z} [GV/m]");
            else if(i==1)
                hE1D[i]->GetYaxis()->SetTitle("E_{y} [GV/m]");
            else if(i==2)
                hE1D[i]->GetYaxis()->SetTitle("E_{x} [GV/m]");


            if(i==0) {
                hV2D->SetBins(NbinsX,xMin,xMax,NbinsY,ymin,ymax);
                hETotal2D->SetBins(NbinsX,xMin,xMax,NbinsY,ymin,ymax);
                hIonProb2D->SetBins(NbinsX,xMin,xMax,NbinsY,ymin,ymax);
                hV1D->SetBins(NbinsX,xMin,xMax);
                hETotal1D->SetBins(NbinsX,xMin,xMax);
                hIonProb1D->SetBins(NbinsX,xMin,xMax);
                for(Int_t j=0; j<NbinsX; j++) {
                    for(Int_t k=0; k<NbinsY; k++) {
                        hV2D->SetBinContent(j,k, hV2D->GetBinContent(j,k) * E0 * skindepth / (PUnits::MV));
                        hETotal2D->SetBinContent(j,k, hETotal2D->GetBinContent(j,k) * ( E0 / (PUnits::GV/PUnits::m) ) );
                    }
                    hV1D->SetBinContent(j, hV1D->GetBinContent(j) * ( E0 * skindepth / (PUnits::MV) ) );
                    hETotal1D->SetBinContent(j, hETotal1D->GetBinContent(j) * ( E0 / (PUnits::GV/PUnits::m) ) );
                }

                if(pData->IsCyl()) {
                    hV2D->GetYaxis()->SetTitle("r [#mum]");
                    hETotal2D->GetYaxis()->SetTitle("r [#mum]");
                } else {
                    hV2D->GetYaxis()->SetTitle("y [#mum]");
                    hETotal2D->GetYaxis()->SetTitle("y [#mum]");

                }

                if(opt.Contains("comov")) {
                    hV2D->GetXaxis()->SetTitle("#zeta [#mum]");
                    hV1D->GetXaxis()->SetTitle("#zeta [#mum]");
                    hETotal2D->GetXaxis()->SetTitle("#zeta [#mum]");
                    hETotal1D->GetXaxis()->SetTitle("#zeta [#mum]");
                } else {
                    hV2D->GetXaxis()->SetTitle("z [#mum]");
                    hV2D->GetXaxis()->SetTitle("z [#mum]");
                    hETotal2D->GetXaxis()->SetTitle("z [#mum]");
                    hETotal1D->GetXaxis()->SetTitle("z [#mum]");
                }

                hV2D->GetZaxis()->SetTitle("#Psi-#Psi_{t} [MV]");
                hV1D->GetYaxis()->SetTitle("#Psi-#Psi_{t} [MV]");
                hETotal2D->GetZaxis()->SetTitle("E [GV/m]");
                hETotal1D->GetYaxis()->SetTitle("E [GV/m]");
            }
        }
    }


    // --------------------------------------------------- Vertical Zoom ------------

    Float_t yRange    = (hDen2D[0]->GetYaxis()->GetXmax() - hDen2D[0]->GetYaxis()->GetXmin())/zoom;
    Float_t midPoint = (hDen2D[0]->GetYaxis()->GetXmax() + hDen2D[0]->GetYaxis()->GetXmin())/2.;
    Float_t yMin = midPoint-yRange/2;
    Float_t yMax = midPoint+yRange/2;
    if(pData->IsCyl()) {
        yMin = pData->GetXMin(1);
        yMax = yRange;
    }

    for(Int_t i=0; i<Nspecies; i++) {
        if(!hDen2D[i]) continue;
        hDen2D[i]->GetYaxis()->SetRangeUser(yMin,yMax);
    }

    for(Int_t i=0; i<Nfields; i++) {
        if(!hE2D[i]) continue;
        hE2D[i]->GetYaxis()->SetRangeUser(yMin,yMax);
    }

    hETotal2D->GetYaxis()->SetRangeUser(yMin,yMax);

    Float_t xMin = hDen2D[0]->GetXaxis()->GetXmin();
    Float_t xMax = hDen2D[0]->GetXaxis()->GetXmax();
    Float_t xRange = xMax - xMin;

    // ------------- z Zoom --------------------------------- Plasma palette -----------
    // Set the range of the plasma charge density histogram for maximum constrast
    // using a dynamic palette wich adjust the nominal value to a certain color.


    Float_t density = 1;
    Float_t Base  = density;

    Float_t *Max = new Float_t[Nspecies];
    Float_t *Min = new Float_t[Nspecies];

    for(Int_t i=0; i<Nspecies; i++) {
        if(!hDen2D[i]) continue;

        Max[i] = hDen2D[i]->GetMaximum();
        Min[i] = 1.01E-1 * Base;
        if(i==1) Min[i] = 1.01E-1 * Base;
        if(i==2) Min[i] = 1.01E-4 * Base;
        hDen2D[i]->GetZaxis()->SetRangeUser(Min[i],Max[i]);
    }

    // Dynamic plasma palette
    const Int_t plasmaDNRGBs = 3;
    const Int_t plasmaDNCont = 64;
    Float_t basePos = 0.5;
    if(Max[0]!=Min[0]) {
        if(opt.Contains("logz")) {
            Float_t a = 1.0/(TMath::Log10(Max[0])-TMath::Log10(Min[0]));
            Float_t b = TMath::Log10(Min[0]);
            basePos = a*(TMath::Log10(Base) - b);

        } else {
            basePos = (1.0/(Max[0]-Min[0]))*(Base - Min[0]);
        }
    }

    Double_t plasmaDStops[plasmaDNRGBs] = { 0.00, basePos, 1.00 };
    Double_t plasmaDRed[plasmaDNRGBs]   = { 0.99, 0.90, 0.00 };
    Double_t plasmaDGreen[plasmaDNRGBs] = { 0.99, 0.90, 0.00 };
    Double_t plasmaDBlue[plasmaDNRGBs]  = { 0.99, 0.90, 0.00 };

    PPalette * plasmaPalette = (PPalette*) gROOT->FindObject("plasma");
    plasmaPalette->CreateGradientColorTable(plasmaDNRGBs, plasmaDStops,
                                            plasmaDRed, plasmaDGreen, plasmaDBlue, plasmaDNCont);
    // Change the range of z axis for the fields to be symmetric.
    Float_t *Emax = new Float_t[Nfields];
    Float_t *Emin = new Float_t[Nfields];
    for(Int_t i=0; i<Nfields; i++) {
        Emax[i] = hE2D[i]->GetMaximum();
        Emin[i] = hE2D[i]->GetMinimum();
        if(Emax[i] > TMath::Abs(Emin[i]))
            Emin[i] = -Emax[i];
        else
            Emax[i] = -Emin[i];
        hE2D[i]->GetZaxis()->SetRangeUser(Emin[i],Emax[i]);
    }


    // Potential
    if(opt.Contains("units")) {
        trapPotential *=  ( E0 * skindepth / (PUnits::MV) );
    }

    Float_t Vmin = hV1D->GetMinimum();
    {   // Shift potential
        Int_t   NbinsX = hV2D->GetNbinsX();
        Int_t   NbinsY = hV2D->GetNbinsY();
        for(Int_t j=0; j<NbinsX; j++) {
            for(Int_t k=0; k<NbinsY; k++) {
                hV2D->SetBinContent(j,k, hV2D->GetBinContent(j,k) - Vmin -trapPotential);
            }
            hV1D->SetBinContent(j, hV1D->GetBinContent(j) - Vmin -trapPotential);
        }
    }

    Vmin = hV1D->GetMinimum();
    Float_t Vmax = hV1D->GetMaximum();

    // Dynamic potential palette
    const Int_t potPNRGBs = 5;
    const Int_t potPNCont = 64;
    Float_t zeroPos = -Vmin/(Vmax-Vmin);

    Double_t potPStops[potPNRGBs] = { 0.00, zeroPos-3.0/potPNCont,zeroPos, zeroPos+3.0/potPNCont, 1.00 };
    Double_t potPRed[potPNRGBs]   = { 0.518, 0.965, 0.90, 0.498, 0.106 };
    Double_t potPGreen[potPNRGBs] = { 0.078, 0.925, 0.90, 0.718, 0.078 };
    Double_t potPBlue[potPNRGBs]  = { 0.106, 0.353, 0.90, 0.780, 0.518 };

    PPalette * potentialPalette = (PPalette*) gROOT->FindObject("rbow2inv");
    potentialPalette->CreateGradientColorTable(potPNRGBs, potPStops,
            potPRed, potPGreen, potPBlue, potPNCont);

    // Extract contours
    TCanvas* c = new TCanvas("c","Contour List",0,0,600,600);
    c->cd();

    // Potential
    TH2F *hV2Dc = (TH2F*) hV2D->Clone("hV2Dc");
    const Int_t Ncontours = 25;
    Double_t contours[Ncontours];
    for(Int_t i=0; i<Ncontours; i++) {
        contours[i] = i*(trapPotential/5.0) - trapPotential;
    }
    hV2Dc->SetContour(Ncontours, contours);
    hV2Dc->Draw("cont list");

    c->Update();
    TObjArray *contsV2D = (TObjArray*) gROOT->GetListOfSpecials()->FindObject("contours");
    TClonesArray graphsV2D("TGraph",Ncontours);
    {
        Int_t ncontours = contsV2D->GetSize();
        TList* clist = NULL;
        Int_t nGraphs = 0;
        TGraph *gr = NULL;
        for(Int_t i = 0; i < ncontours; i++) {
            if(i==0) continue;

            clist = (TList*) contsV2D->At(i);

            for(Int_t j = 0 ; j < clist->GetSize(); j++) {
                gr = (TGraph*) clist->At(j);
                if(!gr) continue;

                gr->SetLineWidth(1);
                gr->SetLineColor(kGray+1);

                if( !((i)%5) ) {
                    gr->SetLineWidth(2);
                    gr->SetLineColor(kGray+2);
                }
                new(graphsV2D[nGraphs]) TGraph(*gr) ;
                nGraphs++;
            }
        }
    }

    // Ion probability
    hIonProb2D->GetZaxis()->SetRangeUser(0.00501,80);

    TH2F *hIonProb2Dc = (TH2F*) hIonProb2D->Clone("hIonProb2Dc");
    const Int_t NcontI = 4;
    Double_t contI[NcontI] = {0.01,0.1,1.0,10.0};
    hIonProb2Dc->SetContour(NcontI, contI);
    hIonProb2Dc->Draw("cont list");

    c->Update();
    TObjArray *contsI2D = (TObjArray*) gROOT->GetListOfSpecials()->FindObject("contours");
    TClonesArray graphsI2D("TGraph",NcontI);
    {
        Int_t ncontours = contsI2D->GetSize();
        TList* clist = NULL;
        Int_t nGraphs = 0;
        TGraph *gr = NULL;
        for(Int_t i = 0; i < ncontours; i++) {
            clist = (TList*) contsI2D->At(i);

            for(Int_t j = 0 ; j < clist->GetSize(); j++) {
                gr = (TGraph*) clist->At(j);
                if(!gr) continue;

                if( !(i%2) ) {
                    gr->SetLineWidth(1);
                    gr->SetLineStyle(2);
                    gr->SetLineColor(kOrange-3);
                } else {
                    gr->SetLineWidth(1);
                    gr->SetLineStyle(1);
                    gr->SetLineColor(kOrange-3);
                }

                new(graphsI2D[nGraphs]) TGraph(*gr) ;
                nGraphs++;
            }
        }
    }




    // "Axis range" in Osiris units:
    Double_t ylow  = hDen2D[0]->GetYaxis()->GetBinLowEdge(FirstyBin);
    Double_t yup = hDen2D[0]->GetYaxis()->GetBinUpEdge(LastyBin);
    Double_t xmin = hDen2D[0]->GetXaxis()->GetXmin();
    Double_t xmax = hDen2D[0]->GetXaxis()->GetXmax();

    TLine *lineYzero = new TLine(xmin,0.0,xmax,0.0);
    lineYzero->SetLineColor(kGray+2);
    lineYzero->SetLineStyle(2);

    TLine *lineYup = new TLine(xmin,yup,xmax,yup);
    lineYup->SetLineColor(kGray+1);
    lineYup->SetLineStyle(2);

    TLine *lineYdown = new TLine(xmin,ylow,xmax,ylow);
    lineYdown->SetLineColor(kGray+1);
    lineYdown->SetLineStyle(2);

    zStartPlasma -= shiftz;
    zStartNeutral -= shiftz;
    zEndNeutral -= shiftz;

    if(opt.Contains("units")) {
        zStartPlasma *= skindepth / PUnits::um;
        zStartNeutral *= skindepth / PUnits::um;
        zEndNeutral *= skindepth / PUnits::um;
    }

    //  cout << "Start plasma = " << zStartPlasma << endl;
    TLine *lineStartPlasma = new TLine(zStartPlasma,yMin,zStartPlasma,yMax);
    lineStartPlasma->SetLineColor(kGray+2);
    lineStartPlasma->SetLineStyle(2);
    lineStartPlasma->SetLineWidth(3);

    //  cout << "Start plasma = " << zStartNeutral << endl;
    TLine *lineStartNeutral = new TLine(zStartNeutral,yMin,zStartNeutral,yMax);
    lineStartNeutral->SetLineColor(kGray+1);
    lineStartNeutral->SetLineStyle(2);
    lineStartNeutral->SetLineWidth(3);

    //  cout << "End plasma = " << zEndNeutral << endl;
    TLine *lineEndNeutral = new TLine(zEndNeutral,yMin,zEndNeutral,yMax);
    lineEndNeutral->SetLineColor(kGray+1);
    lineEndNeutral->SetLineStyle(2);
    lineEndNeutral->SetLineWidth(3);


    // Plotting
    // -----------------------------------------------

    // Canvas setup
    TCanvas *C = new TCanvas("C","2D Charge density and Electric field",750,666);

    // Palettes setup
    TExec *exPlasma = new TExec("exPlasma","plasmaPalette->cd();");
    TExec *exElec   = new TExec("exElec","redelectronPalette->cd();");
    TExec *exHot    = new TExec("exHot","hotPalette->cd();");
    TExec *exField  = new TExec("exField","rbow2Palette->cd();");
    TExec *exFieldT = new TExec("exFieldT","redPalette->cd();");
    TExec *exIonP   = new TExec("exIonP","redPalette->cd();");
    TExec *exPot    = new TExec("exPot","rbow2invPalette->cd();");

    // Actual Plotting!
    // ------------------------------------------------------------

    // Output file
    TString fOutName = Form("./%s/Plots/Potential2D/Potential2D",pData->GetPath().c_str());
    fOutName += Form("-%s_%i",pData->GetName(),time);

    // Setup Pad layout:
    Float_t lMargin = 0.15;
    Float_t rMargin = 0.18;
    Float_t bMargin = 0.15;
    Float_t tMargin = 0.04;
    Float_t factor = 1.0;
    PlasmaGlob::CanvasAsymPartition(C,2,lMargin,rMargin,bMargin,tMargin,factor);

    TPad *pad[2];
    TString sLabels[] = {"(a)","(b)"};
    // Text objects
    TPaveText **textLabel = new TPaveText*[2];

    C->cd(0);
    char pname[16];
    sprintf(pname,"pad_%i",1);
    pad[0] = (TPad*) gROOT->FindObject(pname);
    pad[0]->Draw();
    pad[0]->cd(); // <---------------------------------------------- Top Plot ---------
    if(opt.Contains("logz")) {
        pad[0]->SetLogz(1);
    } else {
        pad[0]->SetLogz(0);
    }
    pad[0]->SetFrameLineWidth(3);
    pad[0]->SetTickx(1);

    // Re-range:
    for(Int_t i=0; i<Nspecies; i++) {
        if(!hDen2D[i]) continue;
        hDen2D[i]->GetYaxis()->SetRangeUser(yMin -(factor-1)*yRange, yMax);
    }


    TH2F *hFrame = (TH2F*) gROOT->FindObject("hFrame1");
    if(hFrame) delete hFrame;
    hFrame = (TH2F*) hDen2D[0]->Clone("hFrame1");
    hFrame->Reset();

    hFrame->SetLabelFont(42,"xyz");
    hFrame->SetTitleFont(42,"xyz");

    hFrame->GetYaxis()->SetNdivisions(505);
    hFrame->GetYaxis()->SetLabelSize(0.085);
    hFrame->GetYaxis()->SetTitleSize(0.09);
    hFrame->GetYaxis()->SetTitleOffset(0.7);
    hFrame->GetYaxis()->SetTickLength(0.02);

    hFrame->GetXaxis()->SetLabelOffset(999.);
    hFrame->GetXaxis()->SetTitleOffset(999.);
    hFrame->GetXaxis()->SetTickLength(0.04);

    // Frame asymmetry:
    hFrame->Draw("col");

    // hDen2D[0]->GetZaxis()->SetNdivisions(505);

    // Injected electrons if any
    if(Nspecies>=3) {
        if(hDen2D[2]) {
            exHot->Draw();
            hDen2D[2]->Draw("colz same");
        }
    }

    // Plasma
    hDen2D[0]->GetZaxis()->SetTitleFont(42);
    exPlasma->Draw();
    hDen2D[0]->Draw("colz same");

    // Beam driver.
    if(hDen2D[1]) {
        //    hDen2D[1]->GetZaxis()->SetNdivisions(505);
        exElec->Draw();
        hDen2D[1]->Draw("colz same");
    }

    {
        TGraph *gr = (TGraph*) graphsV2D.At(4);
        gr->Draw("C");
    }

    {
        TGraph *gr = (TGraph*) graphsI2D.At(1);
        gr->Draw("C");
    }


    if(opt.Contains("1dline")) {
        lineYzero->Draw();
        lineYdown->Draw();
        lineYup->Draw();
    }

    if(opt.Contains("sline")) {
        if(zStartPlasma>xmin && zStartPlasma<xmax)
            lineStartPlasma->Draw();
        if(zStartNeutral>xmin && zStartNeutral<xmax)
            lineStartNeutral->Draw();
        if(zEndNeutral>xmin && zEndNeutral<xmax)
            lineEndNeutral->Draw();
    }

    // lineYdown->Draw();
    // lineYup->Draw();

    // Palettes re-arrangement
    pad[0]->Update();
    Float_t y1 = pad[0]->GetBottomMargin();
    Float_t y2 = 1 - pad[0]->GetTopMargin();
    Float_t x1 = pad[0]->GetLeftMargin();
    Float_t x2 = 1 - pad[0]->GetRightMargin();

    TPaletteAxis *palette = NULL;
    if(Nspecies>=3) {
        if(hDen2D[2]) {
            palette = (TPaletteAxis*)hDen2D[2]->GetListOfFunctions()->FindObject("palette");
        }
    }
    if(palette) {
        palette->SetY2NDC(y2 - 0.00);
        palette->SetY1NDC(0.66*(y1+y2) + 0.00);
        palette->SetX1NDC(x2 + 0.005);
        palette->SetX2NDC(x2 + 0.03);
        //  palette->SetTitleFont(42);
        //  palette->SetTitleOffset(0.85);
        palette->SetTitleOffset(999.9);
        palette->SetTitleSize(0.075);
        palette->SetLabelFont(42);
        palette->SetLabelSize(0.075);
        palette->SetLabelOffset(0.001);
        palette->SetBorderSize(2);
        palette->SetLineColor(1);
    }

    palette = (TPaletteAxis*)hDen2D[0]->GetListOfFunctions()->FindObject("palette");
    if(palette) {
        palette->SetY2NDC(0.66*(y1+y2) - 0.00);
        palette->SetY1NDC(0.33*(y1+y2) + 0.00);
        palette->SetX1NDC(x2 + 0.005);
        palette->SetX2NDC(x2 + 0.03);
        // palette->SetTitleFont(42);
        palette->SetTitleOffset(0.80);
        palette->SetTitleSize(0.075);
        palette->SetLabelFont(42);
        palette->SetLabelSize(0.075);
        palette->SetLabelOffset(0.001);
        palette->SetBorderSize(2);
        palette->SetLineColor(1);
    }

    palette = (TPaletteAxis*)hDen2D[1]->GetListOfFunctions()->FindObject("palette");
    if(palette) {
        palette->SetY2NDC(0.33*(y1+y2) - 0.00);
        palette->SetY1NDC(y1 + 0.00);
        palette->SetX1NDC(x2 + 0.005);
        palette->SetX2NDC(x2 + 0.03);
        //palette->SetTitleFont(42);
        //palette->SetTitleOffset(0.85);
        palette->SetTitleOffset(999.9);
        palette->SetTitleSize(0.075);
        palette->SetLabelFont(42);
        palette->SetLabelSize(0.075);
        palette->SetLabelOffset(0.001);
        palette->SetBorderSize(2);
        palette->SetLineColor(1);
    }


    // 1D charge density plots:
    Float_t yaxismin  =  pad[0]->GetUymin();
    Float_t yaxismax  =  pad[0]->GetUymin() + 0.33*(pad[0]->GetUymax() - pad[0]->GetUymin()) - 0.00;
    Float_t denmin = Min[1];
    Float_t denmax = Max[1];
    if(opt.Contains("logz")) {
        denmin = TMath::Log10(denmin);
        denmax = TMath::Log10(denmax);
    }

    Float_t curmin = 0.0;
    Float_t curmax = 0.0;
    if(opt.Contains("curr")) {
        curmin = 0.0;
        curmax = hCur1D[1]->GetMaximum();

        cout << Form(" Maximum driver  current = %6.2f kA ", curmax) << endl ;
        if(Nspecies>=3)
            if(hCur1D[2])
                cout << Form(" Maximum witness current = %6.2f kA ", hCur1D[2]->GetMaximum()) << endl ;

        // Round for better plotting
        curmax = 0.1*TMath::Nint(curmax*10);
    }

    for(Int_t i=0; i<Nspecies; i++) {
        if(!hDen1D[i]) continue;

        Float_t slope = (yaxismax - yaxismin)/(denmax - denmin);

        for(Int_t j=0; j<hDen1D[i]->GetNbinsX(); j++) {
            Float_t content = hDen1D[i]->GetBinContent(j+1);
            if(opt.Contains("logz")) content = TMath::Log10(content);

            if(content<denmin)
                hDen1D[i]->SetBinContent(j+1,yaxismin);
            else
                hDen1D[i]->SetBinContent(j+1,(content - denmin) * slope + yaxismin);


        }

        if(hCur1D[i]) {
            slope = (yaxismax - yaxismin)/(curmax - curmin);

            for(Int_t j=0; j<hCur1D[i]->GetNbinsX(); j++) {
                Float_t content = hCur1D[i]->GetBinContent(j+1);

                if(content<curmin)
                    hCur1D[i]->SetBinContent(j+1,yaxismin);
                else
                    hCur1D[i]->SetBinContent(j+1,(content - curmin) * slope + yaxismin);
            }

        }

    }

    // Plasma on-axis density:
    // hDen1D[0]->SetLineWidth(2);
    // hDen1D[0]->SetLineColor(kGray+1);
    // // // PlasmaGlob::SetH1Style(hDen1D[0],1);
    // hDen1D[0]->Draw("same C");


    if(opt.Contains("curr")) {
        hCur1D[1]->SetLineWidth(2);
        hCur1D[1]->SetLineColor(PlasmaGlob::elecLine);
        hCur1D[1]->Draw("same C");
    } else {
        hDen1D[1]->SetLineWidth(2);
        hDen1D[1]->SetLineColor(PlasmaGlob::elecLine);
        //    hDen1D[1]->Draw("same C");
    }

    if(Nspecies>=3) {
        if(hDen1D[2]) {
            if(opt.Contains("curr")) {
                hCur1D[2]->SetLineWidth(2);
                hCur1D[2]->SetLineColor(kOrange+8);
                hCur1D[2]->Draw("same C");
            } else {
                hDen1D[2]->SetLineWidth(2);
                hDen1D[2]->SetLineColor(kOrange+8);
                //   hDen1D[2]->Draw("same C");
            }
        }
    }

    // Current axis
    TGaxis *axis = NULL;
    if(opt.Contains("curr")) {
        axis = new TGaxis(xMax-xRange/6.0,yMin - (factor-1)*yRange,
                          xMax-xRange/6.0,yaxismax,
                          0.001,curmax,503,"+LS");

        axis->SetLineWidth(1);
        axis->SetLineColor(kGray+3);//PlasmaGlob::elecLine);
        axis->SetLabelColor(kGray+3);//PlasmaGlob::elecLine);
        axis->SetLabelSize(0.06);
        axis->SetLabelOffset(0.01);
        axis->SetLabelFont(42);
        axis->SetTitleColor(kGray+3);//PlasmaGlob::elecLine);
        axis->SetTitleSize(0.06);
        axis->SetTitleOffset(0.6);
        axis->SetTitleFont(42);
        axis->SetTickSize(0.03);
        axis->SetTitle("I [kA]");
        axis->CenterTitle();
        axis->SetNdivisions(505);

        axis->Draw();
    }


    TPaveText *textTime = new TPaveText(xMax - 0.3*xRange, yMax-0.15*yRange, xMax-0.1, yMax-0.05*yRange);
    //x2-0.17,y2-0.12,x2-0.02,y2-0.02,"NDC");
    PlasmaGlob::SetPaveTextStyle(textTime,32);
    char ctext[128];
    if(opt.Contains("units") && n0)
        sprintf(ctext,"z = %5.1f #mum", Time * skindepth / PUnits::um);
    else
        sprintf(ctext,"t = %5.1f #omega_{p}^{-1}",Time);
    textTime->SetTextFont(42);
    textTime->AddText(ctext);

    textTime->Draw();
    // textDen->Draw();
    // if(opt.Contains("units"))
    //   textWav->Draw();

    textLabel[0] = new TPaveText(xMin + 0.02*xRange, yMax-0.2*yRange, xMin+0.30*xRange, yMax-0.05*yRange);
    PlasmaGlob::SetPaveTextStyle(textLabel[0],12);
    textLabel[0]->SetTextFont(42);
    textLabel[0]->AddText(sLabels[0]);
    textLabel[0]->Draw();


    pad[0]->RedrawAxis();

    C->cd(0);
    sprintf(pname,"pad_%i",0);
    pad[1] = (TPad*) gROOT->FindObject(pname);
    pad[1]->Draw();
    pad[1]->cd(); // <--------------------------------------------------------- Bottom Plot
    pad[1]->SetFrameLineWidth(3);
    pad[1]->SetTickx(1);

    hFrame = (TH2F*) gROOT->FindObject("hFrame2");
    if(hFrame) delete hFrame;
    hFrame = (TH2F*) hDen2D[0]->Clone("hFrame2");
    hFrame->Reset();

    Float_t yFactor = pad[0]->GetAbsHNDC()/pad[1]->GetAbsHNDC();


    hFrame->GetYaxis()->SetLabelSize(yFactor*0.085);
    hFrame->GetYaxis()->SetTitleSize(yFactor*0.09);
    hFrame->GetYaxis()->SetTitleOffset(0.7/yFactor);
    hFrame->GetYaxis()->SetTickLength(0.02/yFactor);

    hFrame->GetXaxis()->SetTitleSize(0.10);
    hFrame->GetXaxis()->SetLabelSize(0.08);
    hFrame->GetXaxis()->SetLabelOffset(0.02);
    hFrame->GetXaxis()->SetTitleOffset(1.0);
    hFrame->GetXaxis()->SetTickLength(0.04*yFactor);

    hFrame->SetLabelFont(42,"xyz");
    hFrame->SetTitleFont(42,"xyz");

    hFrame->Draw("col");

    //  hE2D[0]->GetZaxis()->SetNdivisions(505);
    hV2D->GetZaxis()->SetTitleFont(42);
    hV2D->GetZaxis()->SetTickLength(0.02/yFactor);


    exPot->Draw();

    hV2D->Draw("col z same");

    for(Int_t i=0; i<graphsV2D.GetEntriesFast(); i++) {
        TGraph *gr = (TGraph*) graphsV2D.At(i);
        if(!gr) continue;
        gr->Draw("C");
    }

    for(Int_t i=0; i<graphsI2D.GetEntriesFast(); i++) {
        //if(i!=2) continue;
        TGraph *gr = (TGraph*) graphsI2D.At(i);
        if(!gr) continue;
        gr->Draw("C");
    }


    if(opt.Contains("1dline")) {
        lineYzero->Draw();
        lineYdown->Draw();
        lineYup->Draw();
    }

    if(opt.Contains("sline")) {
        if(zStartPlasma>xmin && zStartPlasma<xmax)
            lineStartPlasma->Draw();
        if(zStartNeutral>xmin && zStartNeutral<xmax)
            lineStartNeutral->Draw();
        if(zEndNeutral>xmin && zEndNeutral<xmax)
            lineEndNeutral->Draw();
    }


    pad[1]->Update();

    y1 = pad[1]->GetBottomMargin();
    y2 = 1 - pad[1]->GetTopMargin();
    x1 = pad[1]->GetLeftMargin();
    x2 = 1 - pad[1]->GetRightMargin();

    palette = (TPaletteAxis*)hV2D->GetListOfFunctions()->FindObject("palette");
    if(palette) {
        palette->SetY2NDC(y2 - 0.00);
        palette->SetY1NDC(y1 + 0.00);
        palette->SetX1NDC(x2 + 0.005);
        palette->SetX2NDC(x2 + 0.03);
        // palette->SetTitleFont(42);
        palette->SetTitleSize(yFactor*0.075);
        palette->SetTitleOffset(0.80/yFactor);
        palette->SetLabelSize(yFactor*0.075);
        palette->SetLabelFont(42);
        palette->SetLabelOffset(0.01/yFactor);
        palette->SetBorderSize(2);
        palette->SetLineColor(1);
    }



    pad[1]->RedrawAxis();

    textLabel[1] = new TPaveText(xMin + 0.02*xRange, yMax-0.2*yRange, xMin+0.30*xRange, yMax-0.05*yRange);
    PlasmaGlob::SetPaveTextStyle(textLabel[1],12);
    textLabel[1]->SetTextFont(42);
    textLabel[1]->AddText(sLabels[1]);
    textLabel[1]->Draw();

    C->cd();

    // Print to a file
    PlasmaGlob::imgconv(C,fOutName,opt);
    // ---------------------------------------------------------

    PlasmaGlob::DestroyCanvases();
}
Exemple #5
0
void PlotField1D( const TString &sim, Int_t time, Int_t Nbins=1, const TString &options="") { 
  
#ifdef __CINT__  
  gSystem->Load("libplasma.so");
#endif

  PlasmaGlob::Initialize();
    
  TString opt = options;

  gStyle->SetPadLeftMargin(0.10);  // Margin left axis  
  gStyle->SetPadRightMargin(0.12); // Margin right axis 
  if(opt.Contains("grid")) {
    gStyle->SetPadGridX(1);
    gStyle->SetPadGridY(1);
  }

  // Load PData
  PData *pData = PData::Get(sim.Data());
  pData->LoadFileNames(time);
  if(!pData->IsInit()) return;

  Bool_t CYL = kFALSE;
  if(sim.Contains("cyl")) { CYL = kTRUE; opt += "cyl"; } 
    
  Bool_t ThreeD = kFALSE;
  if(sim.Contains("3D")) ThreeD = kTRUE; 

  // Some plasma constants
  Double_t n0 = pData->GetPlasmaDensity();
  Double_t kp = pData->GetPlasmaK();
  Double_t skindepth = 1/kp;
  Double_t E0 = pData->GetPlasmaE0();

  // Some beam properties:
  Float_t Ebeam = pData->GetBeamEnergy() * PUnits::MeV;
  Float_t gamma = Ebeam / PConst::ElectronMassE;
  Float_t vbeam = TMath::Sqrt(1 - 1/(gamma*gamma));
  // cout << Form(" - Bunch gamma      = %8.4f", gamma ) << endl;
  // cout << Form(" - Bunch velocity   = %8.4f c", vbeam ) << endl;

  Float_t Time = pData->GetRealTime();
  // z start of the plasma in normalized units.
  Float_t zStartPlasma = pData->GetPlasmaStart()*kp;
  // z start of the beam in normalized units.
  Float_t zStartBeam = pData->GetBeamStart()*kp;
  Time -= zStartPlasma - zStartBeam;

  // 1D histograms
  TString opth1 = opt;
  opth1 += "avg";
  // Get electric fields
  const Int_t Nfields = 1;
  TH1F **hE1D = new TH1F*[Nfields];
  for(Int_t i=0;i<Nfields;i++) {
    hE1D[i] = NULL;
    if(!pData->GetEfieldFileName(i))
      continue;
    
    char nam[3]; sprintf(nam,"e%i",i+1);
    if(ThreeD) {
      if(i==0) 
	hE1D[i] = pData->GetH1SliceZ3D(pData->GetEfieldFileName(i)->c_str(),nam,-1,Nbins,-1,Nbins,opth1.Data());
      else  
	hE1D[i] = pData->GetH1SliceZ3D(pData->GetEfieldFileName(i)->c_str(),nam,-Nbins,Nbins,-Nbins,Nbins,opth1.Data());
    } else if(CYL) { // Cylindrical: The firt bin with r>0 is actually the number 1 (not the 0).
      if(i==0) 
	hE1D[i] = pData->GetH1SliceZ(pData->GetEfieldFileName(i)->c_str(),nam,1,Nbins,opth1.Data());
      else
	hE1D[i] = pData->GetH1SliceZ(pData->GetEfieldFileName(i)->c_str(),nam,1,Nbins,opth1.Data());
    } else { // 2D cartesian
      if(i==0) 
	hE1D[i] = pData->GetH1SliceZ(pData->GetEfieldFileName(i)->c_str(),nam,-1,Nbins,opth1.Data());
      else 
	hE1D[i] = pData->GetH1SliceZ(pData->GetEfieldFileName(i)->c_str(),nam,-Nbins,Nbins,opth1.Data());
    }
    
    char hName[24];
    sprintf(hName,"hE_%i",i);
    hE1D[i]->SetName(hName);
    if(opt.Contains("comov"))
      hE1D[i]->GetXaxis()->SetTitle("#zeta [c/#omega_{p}]");
    else
      hE1D[i]->GetXaxis()->SetTitle("z [c/#omega_{p}]");
   
    if(i==0)
      hE1D[i]->GetYaxis()->SetTitle("E_{z} [E_{0}]");
    else if(i==1)
      hE1D[i]->GetYaxis()->SetTitle("E_{y} [E_{0}}]");
    else if(i==2)
      hE1D[i]->GetYaxis()->SetTitle("E_{x} [E_{0}}]");
    
    
  }  
  
  // Chaning to user units: 
  if(opt.Contains("units") && n0) {
    for(Int_t i=0;i<Nfields;i++) {
      Int_t NbinsX = hE1D[i]->GetNbinsX();
      Float_t xMin = (skindepth/PUnits::mm) * hE1D[i]->GetXaxis()->GetXmin();
      Float_t xMax = (skindepth/PUnits::mm) * hE1D[i]->GetXaxis()->GetXmax();
      
      hE1D[i]->SetBins(NbinsX,xMin,xMax);
      
      for(Int_t j=0;j<NbinsX;j++) {
	hE1D[i]->SetBinContent(j, hE1D[i]->GetBinContent(j) * ( E0 / (PUnits::GV/PUnits::m) ) );
      }
      
      if(opt.Contains("comov"))
	hE1D[i]->GetXaxis()->SetTitle("#zeta [mm]");
      else
	hE1D[i]->GetXaxis()->SetTitle("z [mm]");
      
      if(i==0)
	hE1D[i]->GetYaxis()->SetTitle("E_{z} [GV/m]");
      else if(i==1)
	hE1D[i]->GetYaxis()->SetTitle("E_{y} [GV/m]");
      else if(i==2)
	hE1D[i]->GetYaxis()->SetTitle("E_{x} [GV/m]");
    }
  }
  
  // Calculate wave positions:
  // ----------------------------------------------------------------
  
  // Retrieve the previous time TGraph if any;
  // Open TGraph
  TString filename = Form("./%s/Plots/Field1D/Field1D-%s.root",sim.Data(),sim.Data());
  TFile * ifile = (TFile*) gROOT->GetListOfFiles()->FindObject(filename);
  // if doesn't exist the directory should be created
  if (!ifile) {
    TString f = filename;
    TString dir2 = f.Remove( f.Last( '/' ), f.Length() - f.Last( '/' ) );
    TString dir1 = f.Remove( f.Last( '/' ), f.Length() - f.Last( '/' ) );
    gSystem->mkdir( dir1 );
    gSystem->mkdir( dir2 );
    ifile = new TFile(filename,"UPDATE");
  }  
  
  
  
  Float_t *EMaxPos = new Float_t[Nfields];
  Float_t *EMaxValue = new Float_t[Nfields];
  
  // Get the Graph with the x1 positions of the maximum E_1
  TGraph **graph = new TGraph*[Nfields];
  char gName[24];
  for(Int_t i=0;i<Nfields;i++) {
    if(!hE1D[i]) continue;
    
    EMaxPos[i] = EMaxValue[i] = -999;
    
    // Initial time search window:
    Float_t xCenter = (hE1D[i]->GetXaxis()->GetXmin()+hE1D[i]->GetXaxis()->GetXmax())/2.; 
    Float_t xs1min = 0.5*(hE1D[i]->GetXaxis()->GetXmin()+xCenter);
    Float_t xs1max = xCenter;

    // For focusing fields i==1,2 we use a narrower window based on the previosly found 
    // minimum for the accelerating fields i==0.
    if(i>0) {
      xCenter = EMaxPos[0];
      if(opt.Contains("units") && n0) {
	xs1min = xCenter - (0.25*TMath::Pi() * 1e3 * skindepth);
	xs1max = xCenter + (0.25*TMath::Pi() * 1e3 * skindepth);
      } else {
	xs1min = xCenter - 0.25*TMath::Pi();
	xs1max = xCenter + 0.25*TMath::Pi();
      }
    }

    sprintf(gName,"gEMaxPos_%i",i);
    graph[i] =  (TGraph*) ifile->Get(gName);
    if(graph[i]) {
      Double_t *y = graph[i]->GetY();
      
      // Setup the searching windows to +/- pi/2 respect the last found minimum.
      if(opt.Contains("units") && n0) {
	xs1min = y[graph[i]->GetN()-1] - (0.5*TMath::Pi() * 1e3 * skindepth);
	xs1max = y[graph[i]->GetN()-1] + (0.5*TMath::Pi() * 1e3 * skindepth);
      } else {
	xs1min = y[graph[i]->GetN()-1] - 0.5*TMath::Pi();
	xs1max = y[graph[i]->GetN()-1] + 0.5*TMath::Pi();
      }
      
      delete graph[i];
    }
    
    TH1F *htemp = (TH1F*) hE1D[i]->Clone("htemp");
    htemp->GetXaxis()->SetRangeUser(xs1min,xs1max);
    
    //htemp->Smooth(1,"R");
    Int_t binMax = htemp->GetMinimumBin();
    EMaxPos[i] = (Float_t) htemp->GetBinCenter(binMax);
    EMaxValue[i] = (Float_t) htemp->GetBinContent(binMax);
    delete htemp;
    
  }
  
  
  // Tunning the Histograms
  // ---------------------
  
  
  // Plotting
  // -----------------------------------------------
  
  // Output file
  TString fOutName = Form("./%s/Plots/Field1D/Field1D",sim.Data());
  fOutName += Form("-%s_%i",sim.Data(),time);
  
  // Canvas setup
  TCanvas *C = new TCanvas("C","Electric wakefield on axis",850,1000);
  C->Divide(1,2);

  // Draw objects
  TPaveText *textTime = new TPaveText(0.70,0.87,0.85,0.92,"NDC");
  PlasmaGlob::SetPaveTextStyle(textTime); 
  char ctext[128];
  if(opt.Contains("units") && n0) 
    sprintf(ctext,"Z = %5.1f mm", 1e3 * skindepth * Time);
  else
    sprintf(ctext,"T = %5.1f 1/#omega_{p}",Time);
  textTime->AddText(ctext);
  
  // Colors
  Int_t fieldC  = PlasmaGlob::fieldLine;
  Int_t phaseC  = kGray+1;
 
  // Actual Plotting!
  // ------------------------------------------------------------

  // More makeup
  C->cd(1);
  gPad->SetGridy(0);
  gPad->SetGridx(0);
  gPad->SetFrameLineWidth(2);  

  hE1D[0]->SetLineWidth(1);
  hE1D[0]->GetYaxis()->CenterTitle();
  hE1D[0]->GetXaxis()->CenterTitle();
  hE1D[0]->SetLineStyle(1);
  hE1D[0]->SetLineWidth(3);
  hE1D[0]->SetLineColor(fieldC);
  hE1D[0]->SetMarkerStyle(20);

  if(Nfields>1) {
    hE1D[1]->GetYaxis()->CenterTitle();
    hE1D[1]->GetXaxis()->CenterTitle();
    hE1D[1]->SetLineStyle(1);
    hE1D[1]->SetLineWidth(1);  
    hE1D[1]->SetLineColor(fieldC);
    hE1D[1]->SetMarkerStyle(24);
  }

  Float_t factor = 1.5;
  Float_t minimum = factor * hE1D[0]->GetMinimum();
  Float_t maximum = factor * hE1D[0]->GetMaximum();
    
  if(Nfields>1) {
    if(hE1D[1]->GetMaximum() > hE1D[0]->GetMaximum()) {
      maximum = factor * hE1D[1]->GetMaximum();
    } 
    
    if(hE1D[1]->GetMinimum() < hE1D[0]->GetMinimum()) {
    minimum = factor * hE1D[1]->GetMinimum();
    } 
  }
  
  if( maximum >= TMath::Abs(minimum)) minimum = -maximum;
  else maximum = - minimum;
  
  hE1D[0]->GetYaxis()->SetRangeUser(minimum,maximum);
  hE1D[0]->Draw("C");
  
  if(Nfields>1)
    hE1D[1]->Draw("C same");
  
  C->Update();
  
  TLine *line0 = new TLine(hE1D[0]->GetXaxis()->GetXmin(),
			   (gPad->GetUymin()+gPad->GetUymax())/2.,
			   hE1D[0]->GetXaxis()->GetXmax(),
			   (gPad->GetUymin()+gPad->GetUymax())/2.);
  line0->SetLineColor(kGray+1);
  line0->SetLineStyle(2);
  line0->Draw();
  
  TMarker *markEMax0 = new TMarker(EMaxPos[0],EMaxValue[0], 24);
  markEMax0->SetMarkerColor(fieldC);
  markEMax0->SetMarkerSize(1.6);
  markEMax0->Draw();

  if(Nfields>1) {
    TMarker *markEMax1 = new TMarker(EMaxPos[1],EMaxValue[1], 24);
    markEMax1->SetMarkerColor(fieldC);
    markEMax1->SetMarkerSize(1.4);
    markEMax1->Draw();
  }
  
  textTime->Draw();

  // ----
  
  // Define the TGraphs
  Int_t nPoints = 0;  
  TGraph **gEMaxPos = new TGraph*[Nfields];
  TGraph **gEMaxValue = new TGraph*[Nfields];
  for(Int_t i=0;i<Nfields;i++) {
    if(!hE1D[i]) continue;

    sprintf(gName,"gEMaxPos_%i",i);
    gEMaxPos[i] = (TGraph*) ifile->Get(gName);
    if(gEMaxPos[i]==NULL) {
      gEMaxPos[i] = new TGraph();
      gEMaxPos[i]->SetName(gName);
    } else {
      nPoints = gEMaxPos[i]->GetN(); 
    }  
    gEMaxPos[i]->Set(nPoints+1);
    if(opt.Contains("units") && n0) 
      gEMaxPos[i]->SetPoint(nPoints, 1e3 * skindepth * Time,EMaxPos[i]);
    else
      gEMaxPos[i]->SetPoint(nPoints,Time,EMaxPos[i]);
    
    if(opt.Contains("units") && n0) {
      gEMaxPos[i]->GetYaxis()->SetTitle("#zeta_{min} [mm]");
      gEMaxPos[i]->GetXaxis()->SetTitle("Z [mm]");
    } else {
      gEMaxPos[i]->GetYaxis()->SetTitle("#zeta_{min} [c/#omega_{p}]");
      gEMaxPos[i]->GetXaxis()->SetTitle("T [c/#omega_{p}]");
    }

    gEMaxPos[i]->Write(gEMaxPos[i]->GetName(),TObject::kOverwrite);

    sprintf(gName,"gEMaxValue_%i",i);
    gEMaxValue[i] = (TGraph*) ifile->Get(gName);
    if(gEMaxValue[i]==NULL) {
      gEMaxValue[i] = new TGraph();  
      gEMaxValue[i]->SetName(gName);
    } else {
      nPoints = gEMaxValue[i]->GetN(); 
    }  
    gEMaxValue[i]->Set(nPoints+1);
    if(opt.Contains("units") && n0) 
      gEMaxValue[i]->SetPoint(nPoints, 1e3 * skindepth * Time,EMaxValue[i]);
    else
      gEMaxValue[i]->SetPoint(nPoints,Time,EMaxValue[i]);
    
    if(opt.Contains("units") && n0) {
      gEMaxValue[i]->GetYaxis()->SetTitle("E_{min} [GV/m]");
      gEMaxValue[i]->GetXaxis()->SetTitle("Z [mm]");
    } else {
      gEMaxValue[i]->GetYaxis()->SetTitle("E_{min} [E_{0}]");
      gEMaxValue[i]->GetXaxis()->SetTitle("T [c/#omega_{p}]");
    }
    
    gEMaxValue[i]->Write(gEMaxValue[i]->GetName(),TObject::kOverwrite);    
  }


  C->cd(2);
  gPad->SetGridy(1);
  gPad->SetGridx(0);
  gPad->SetFrameLineWidth(2);  

  Float_t minPhase = 99.;
  Float_t maxPhase = -99.;
  Float_t minField = 99.;
  Float_t maxField = -99.;

  Double_t *yEMaxPos[Nfields];
  Double_t *yEMaxValue[Nfields];

  for(Int_t i=0;i<Nfields;i++) {
    yEMaxPos[i]   = gEMaxPos[i]->GetY();
    yEMaxValue[i] = gEMaxValue[i]->GetY();
    
    for(Int_t j=0;j<gEMaxPos[0]->GetN();j++) {
      if(yEMaxPos[i][j]>maxPhase)
	maxPhase = yEMaxPos[i][j];
      if(yEMaxPos[i][j]<minPhase)
	minPhase = yEMaxPos[i][j];
 
      if(yEMaxValue[i][j]>maxField)
	maxField = yEMaxValue[i][j];
      if(yEMaxValue[i][j]<minField)
	minField = yEMaxValue[i][j];
    }
  }

  Float_t margin = (maxPhase - minPhase)/10;
  gEMaxPos[0]->GetYaxis()->SetRangeUser(minPhase-margin,maxPhase+margin);
  gEMaxPos[0]->GetYaxis()->CenterTitle();
  gEMaxPos[0]->GetXaxis()->CenterTitle();
  gEMaxPos[0]->SetLineColor(phaseC);
  gEMaxPos[0]->SetMarkerColor(phaseC);
  gEMaxPos[0]->SetLineWidth(3);
  gEMaxPos[0]->SetMarkerStyle(20);
  gEMaxPos[0]->SetMarkerSize(1.4);
  gEMaxPos[0]->Draw("APC");

  if(Nfields>1) {
    gEMaxPos[1]->SetLineStyle(1);
    gEMaxPos[1]->SetLineColor(phaseC);
    gEMaxPos[1]->SetMarkerColor(phaseC);
    gEMaxPos[1]->SetLineWidth(1);
    gEMaxPos[1]->SetMarkerStyle(24);
    gEMaxPos[1]->SetMarkerSize(1.4);
    gEMaxPos[1]->Draw("PC");
  }

  // Emax value
  // New axis first:
  C->Update();  // Needed for the axis!

  margin = (maxField - minField)/10;
  if (margin==0) margin = 1; 
  Float_t rightmin = minField-margin;
  Float_t rightmax = maxField+margin;
  Float_t slope = (gPad->GetUymax() - gPad->GetUymin())/(rightmax-rightmin);
  TGaxis *axisEmax = new TGaxis(gPad->GetUxmax(),gPad->GetUymin(),gPad->GetUxmax(),
				gPad->GetUymax(),rightmin,rightmax,505,"+L");
  axisEmax->SetLineWidth(1);
  axisEmax->SetLineColor(fieldC);
  axisEmax->SetLabelColor(fieldC);
  axisEmax->SetTitleColor(fieldC);
  if(opt.Contains("units") && n0) 
    axisEmax->SetTitle("E_{min} [GV/m]");
  else
    axisEmax->SetTitle("E_{min} [E_{0}]");
  axisEmax->CenterTitle();
  axisEmax->SetTitleSize(0.05);
  axisEmax->SetTitleOffset(1.2);
  axisEmax->SetLabelSize(0.05);
  axisEmax->SetLabelOffset(0.006);
  
  axisEmax->Draw();
  
  // Adjust the TGraph
  Double_t *x = gEMaxValue[0]->GetX();
  Double_t *y = gEMaxValue[0]->GetY();
  for(Int_t i=0;i<gEMaxValue[0]->GetN();i++) {
    gEMaxValue[0]->SetPoint(i,x[i],(y[i]-rightmin)*slope + gPad->GetUymin());
  }  
  gEMaxValue[0]->SetLineColor(fieldC);
  gEMaxValue[0]->SetMarkerColor(fieldC);
  gEMaxValue[0]->SetLineWidth(3);
  gEMaxValue[0]->SetMarkerStyle(20);
  gEMaxValue[0]->SetMarkerSize(1.4);
  gEMaxValue[0]->Draw("PC");

   if(Nfields>1) {
    x = gEMaxValue[1]->GetX();
    y = gEMaxValue[1]->GetY();
    for(Int_t i=0;i<gEMaxValue[1]->GetN();i++) {
      gEMaxValue[1]->SetPoint(i,x[i],(y[i]-rightmin)*slope + gPad->GetUymin());
    }  
    gEMaxValue[1]->SetLineColor(fieldC);
    gEMaxValue[1]->SetMarkerColor(fieldC);
    gEMaxValue[1]->SetLineWidth(1);
    gEMaxValue[1]->SetMarkerStyle(24);
    gEMaxValue[1]->SetMarkerSize(1.4);
    gEMaxValue[1]->Draw("PC");
  }

  // Emax value
  // New axis first:
  C->Update();  // Needed for the axis!

  C->cd();

  ifile->Close();
  
  // Print to a file
  PlasmaGlob::imgconv(C,fOutName,opt);
  // ---------------------------------------------------------
  
  }