void MoveTransformMatric(TString inFileName, TString matrixName)
{
  TFile inFile(inFileName);
  TH2D *transform = (TH2D*) inFile.Get(matrixName);
  
  TFile outFile("PreparedTransformMatrices.root","update");
  if(transform) {
    outFile.cd();
    transform->RebinX(4);
    transform->RebinY(4);
    transform->Write(transform->GetName(), TObject::kOverwrite);
  }
  else cout<<"Could not find matrix with that name"<<endl;
  outFile.Close();
  inFile.Close();
}
Exemple #2
0
//loads phi-pT efficiency from root file
TH2D *GetEfficiencyPhi(TString effLoc){
  TFile *fIn = 0;
  TH2D *hPhiPt = 0; 

  if(!fIn)fIn = TFile::Open(effLoc.Data());
  if(!fIn)Printf("%s%d no input data",(char*)__FILE__,__LINE__);
  if(!hPhiPt)hPhiPt = (TH2D*)fIn->Get("h2TrackPtPhiNorm");
  if(!hPhiPt) cout<<"Could not load h2TrackPtPhiNorm"<<endl; 
  if(!hPhiPt)Printf("%s%d no phi-pt efficiency spectrum available",(char*)__FILE__,__LINE__);

  gROOT->cd();
  TH2D *hPhiPtClone = (TH2D*)hPhiPt->Clone(hPhiPt->GetName()); 
  fIn->Close();
  return hPhiPtClone;

}
Exemple #3
0
void pidFitter::processSpecies( string species, int charge, reporter * rp ){
	cout << "[pidFitter." << __FUNCTION__ << "]" << endl;

	string hName = "nSig_" + sName( species, charge );
	// get the pt Binning
	vector<double>pBins = config->getDoubleVector( "binning.p" );

	string useNode = "";

	TH3* h3 = book->get3D( hName );
	int nFits = config->getInt( species + "_Fit:nFits", 1 );
	cout << "Number of Fit Categories: " << nFits << endl;
	for ( int iFit = 1; iFit <= nFits; iFit++ ){

		string optPath = species + "_Fit.opt" + config->getString( species + "_Fit.fit"+ts(iFit)+":options");
		int fBin = config->getInt( species + "_Fit.fit"+ts(iFit)+":min", 1 );
		int lBin = config->getInt( species + "_Fit.fit"+ts(iFit)+":max", pBins.size() );	

		cout << "Fitting P bins ( " << fBin << " --> " << lBin << " ) " << endl;
		for ( int i = fBin; i <= lBin; i ++ ){

			// get the Pt range for title etc.
			double pLow = h3->GetZaxis()->GetBinLowEdge( i );
			double pHi = h3->GetZaxis()->GetBinLowEdge( i + 1 );	

			// look at one Pt bin at a time
			h3->GetZaxis()->SetRange( i, i );
			
			// Get the 2D projection we want
			TH2D* proj;
			proj = (TH2D*)h3->Project3D( "xy" );

			string name = proj->GetName();
			TH2D* cut = (TH2D*) proj->Clone( (name + "cut").c_str() );
			rp->newPage( 1, 2 );
			proj->SetTitle( ( ts( pLow, 4 ) + " #leq " + " P #leq" + ts( pHi, 4 ) ).c_str()  );
			gPad->SetLogz( 1 );
			proj->Draw( "colz" );
			//nProj->Draw("colz");

			// process the square cuts
			makeSquareCuts( cut, optPath + ".squareCut" );

			// draw the distribution after square cuts
			rp->cd( 1, 2 );
			gPad->SetLogz( 1 );
			cut->SetTitle( ( "After 1D Cuts : " + ts( pLow, 4 ) + " #leq " + " P #leq" + ts( pHi, 4 ) ).c_str()  );
			cut->Draw( "colz" );
			rp->savePage( );

			// fit using the dkl algorithm
			if ( config->nodeExists( optPath + ".dkl" ) )
				runDkl( cut, rp, optPath );
			// runs the 2d gaussian fit
			else if ( config->nodeExists( optPath + ".mgf" ) )
				runMultiGauss( cut, rp, species, optPath, i );
			
			
		}

	} 
	
	
}
Exemple #4
0
void readroot(char* input="/gpfs/mnt/gpfs02/phenix/mpcex/liankun/Run16/Ana/offline/analysis/mpcexcode/Liankun/macro/offline_monitor/453692/Run16Ana_MinBias_NoCMN_Sub-453692-0.root"){
  char input_file[5000];
  strcpy(input_file,input);
  strtok(input_file, "-");
  int runnumber = atoi(strtok(0, "-"));
  int segment = atoi(strtok(strtok(0, "-"), "."));

  cout<<"Run Number: "<<runnumber<<" segment: "<<segment<<endl;

  gSystem->Load("libMyMpcEx.so");
  TFile* ifile = new TFile(input,"READONLY");
  if(!ifile){
    cout<<"Open "<<input<<" failed !"<<endl;
    return;
  }
  TH2D* hkey_adc_high;
  TH2D* hkey_adc_low;
  TH2D* hkey_rawadc_high;
  TH2D* hkey_rawadc_low;

  TH2D* hHL_sensor[2][8][24];
  TH2D* hHL_sensor_raw[2][8][24];
  Exogram* hgrammy_high[2];
  Exogram* hgrammy_low[2];
  Exogram* hgrammy_combine[2];
  TH2D* hadc_mpc_e[2];
  TH2D* hlayer_adc_high[2];
  TH2D* hlayer_adc_low[2];
  TH2D* htower_e;

  TH2D* hbbc_adc[2];
  TH2D* hbbc_adc_low[2];
  TH2D* hbbc_nhits[2];

  char hname[500];
  vector<TH2D*> h2d_list;
  hkey_adc_high = (TH2D*)ifile->Get("hkey_adc_high");
  h2d_list.push_back(hkey_adc_high);

  hkey_adc_low = (TH2D*)ifile->Get("hkey_adc_low");
  h2d_list.push_back(hkey_adc_low);
  
  hkey_rawadc_high = (TH2D*)ifile->Get("hkey_rawadc_high");
  h2d_list.push_back(hkey_rawadc_high);

  hkey_rawadc_low = (TH2D*)ifile->Get("hkey_rawadc_low");
  h2d_list.push_back(hkey_rawadc_low);

  hbbc_nhits[0] = (TH2D*)ifile->Get("hbbc_nhits_arm0");
  hbbc_nhits[1] = (TH2D*)ifile->Get("hbbc_nhits_arm1");
  h2d_list.push_back(hbbc_nhits[0]);
  h2d_list.push_back(hbbc_nhits[1]);
  
  hbbc_adc[0] = (TH2D*)ifile->Get("hbbc_adc_arm0");
  hbbc_adc[1] = (TH2D*)ifile->Get("hbbc_adc_arm1");
  h2d_list.push_back(hbbc_adc[0]);
  h2d_list.push_back(hbbc_adc[1]);
  
  hbbc_adc_low[0] = (TH2D*)ifile->Get("hbbc_adc_low_arm0");
  hbbc_adc_low[1] = (TH2D*)ifile->Get("hbbc_adc_low_arm1");
  h2d_list.push_back(hbbc_adc_low[0]);
  h2d_list.push_back(hbbc_adc_low[1]);
  
  hlayer_adc_high[0] = (TH2D*)ifile->Get("hlayer_adc_high_arm0");
  hlayer_adc_high[1] = (TH2D*)ifile->Get("hlayer_adc_high_arm1");
  h2d_list.push_back(hlayer_adc_high[0]);
  h2d_list.push_back(hlayer_adc_high[1]);

  hlayer_adc_low[0] = (TH2D*)ifile->Get("hlayer_adc_low_arm0");
  hlayer_adc_low[1] = (TH2D*)ifile->Get("hlayer_adc_low_arm1");
  h2d_list.push_back(hlayer_adc_low[0]);
  h2d_list.push_back(hlayer_adc_low[1]);

  htower_e = (TH2D*)ifile->Get("htower_e");
  h2d_list.push_back(htower_e);

  hadc_mpc_e[0] = (TH2D*)ifile->Get("hadc_mpc_e_arm0");
  hadc_mpc_e[1] = (TH2D*)ifile->Get("hadc_mpc_e_arm1");
  h2d_list.push_back(hadc_mpc_e[0]);
  h2d_list.push_back(hadc_mpc_e[1]);

  for(unsigned int i = 0;i < h2d_list.size();i++){
    string s = h2d_list[i]->GetName();
    stringstream ss("");
    ss<<s<<"_"<<runnumber<<"_"<<segment;
    s=ss.str();
//    cout << s <<endl;
    TCanvas* c = new TCanvas(s.c_str(),s.c_str(),1200,800);
    c->SetLogz();
    h2d_list[i]->Draw("colz");
    ss.str("");
    ss << runnumber <<"/"<<s<<".gif";
    s=ss.str();
    c->Print(s.c_str(),"gif");
    delete c;
  }

  vector<Exogram*> hexo_list;
  hgrammy_high[0] = (Exogram*)ifile->Get("hgrammy_high0");
  hgrammy_high[1] = (Exogram*)ifile->Get("hgrammy_high1");
  hexo_list.push_back(hgrammy_high[0]);
  hexo_list.push_back(hgrammy_high[1]);

  hgrammy_low[0] = (Exogram*)ifile->Get("hgrammy_low0");
  hgrammy_low[1] = (Exogram*)ifile->Get("hgrammy_low1");
  hexo_list.push_back(hgrammy_low[0]);
  hexo_list.push_back(hgrammy_low[1]);

  hgrammy_combine[0] = (Exogram*)ifile->Get("hgrammy_combine0");
  hgrammy_combine[1] = (Exogram*)ifile->Get("hgrammy_combine1");
  hexo_list.push_back(hgrammy_combine[0]);
  hexo_list.push_back(hgrammy_combine[1]);
  
  for(unsigned int i = 0;i < hexo_list.size();i++){
    string s = hexo_list[i]->GetName();
    stringstream ss("");
    ss<<s<<"_"<<runnumber<<"_"<<segment;
    s=ss.str();
    TCanvas* c = new TCanvas(s.c_str(),s.c_str(),1400,800);
    c->Divide(4,2);
    double max = hexo_list[i]->GetBinContent(hexo_list[i]->GetMaximumBin());
    for(unsigned int j = 0;j < 8;j++){
      c->cd(j+1);
      TPad *pd =(TPad*)c->cd(j+1);
      pd->SetLogz();
      hexo_list[i]->SetAxisRange(j,j,"z");
      TH2D* htemp = hexo_list[i]->Project3D("yx");
      string tmp_s = htemp->GetName();
      stringstream tmp_ss("");
      tmp_ss<<tmp_s<<"_"<<"layer"<<j;
      tmp_s = tmp_ss.str();
      htemp->SetName(tmp_s.c_str());
      htemp->SetMaximum(max);
      htemp->Draw("colz");
    }
    ss.str("");
    ss << runnumber <<"/"<<s<<".gif";
    s=ss.str();
    c->Print(s.c_str(),"gif");
    delete c;
  }

  for(int iarm = 0;iarm < 2;iarm++){
    for(int ilayer = 0;ilayer < 8;ilayer++){
      for(int isen = 0;isen< 24;isen++){
        char hname[500];
	sprintf(hname,"hHL_sensor_arm%d_layer%d_sensor%d",iarm,ilayer,isen);
	hHL_sensor[iarm][ilayer][isen] = (TH2D*)ifile->Get(hname);
	sprintf(hname,"hHL_sensor_raw_arm%d_layer%d_sensor%d",iarm,ilayer,isen);
	hHL_sensor_raw[iarm][ilayer][isen] = (TH2D*)ifile->Get(hname);
      }
    }
  }

  //sensor adc for each layer
  double max_sensor_x[2][8][24] = {{{0.}}};
  double max_sensor_y[2][8][24] = {{{0.}}};
  double min_sensor_x[2][8][24] = {{{0.}}};
  double min_sensor_y[2][8][24] = {{{0.}}};
  
  TH1D* hsensor_high[2][8][24];
  TH1D* hsensor_low[2][8][24];
 
  for(int iarm = 0;iarm < 2;iarm++){
    for(int ilayer = 0;ilayer < 8;ilayer++){
      for(int isen = 0;isen < 24;isen++){
        char name[100];
        sprintf(name,"hsensor_arm%d_layer%d_index%d_high",iarm,ilayer,isen);
        hsensor_high[iarm][ilayer][isen] = new TH1D(name,name,300,-40.5,259.5);
        sprintf(name,"hsensor_arm%d_layer%d_index%d_low",iarm,ilayer,isen);
        hsensor_low[iarm][ilayer][isen] = new TH1D(name,name,300,-40.5,259.5);
        max_sensor_x[iarm][ilayer][isen] = -9999;
        max_sensor_y[iarm][ilayer][isen] = -9999;
        min_sensor_x[iarm][ilayer][isen] = 9999;
        min_sensor_y[iarm][ilayer][isen] = 9999;
      }
    }
  }
  
  ifstream sensor_pos("sensor_position.txt");
  string s;
  while(getline(sensor_pos,s)){
    stringstream ss(s);
    int arm = 0;
    int layer = 0;
    int sensor = 0;
    double x0=0;
    double x1=0;
    double y0=0;
    double y1=0;
    ss>>arm>>layer>>sensor>>x0>>x1>>y0>>y1;
//    cout <<arm <<" "<<layer<<" "<<sensor<<" "<<x0<<" "<<x1<<" "<<y0<<" "<<y1<<endl;
    max_sensor_x[arm][layer][sensor] = x1;
    min_sensor_x[arm][layer][sensor] = x0;
    max_sensor_y[arm][layer][sensor] = y1;
    min_sensor_y[arm][layer][sensor] = y0;
  }
 
  MpcExMapper* mapper = MpcExMapper::instance(); 
  for(unsigned int i = 0;i < 50000;i++){
    hkey_adc_high->SetAxisRange(i,i,"X");
    hkey_adc_low->SetAxisRange(i,i,"X");
    TH1D* htemp0 = hkey_adc_high->ProjectionY();
    TH1D* htemp1 = hkey_adc_low->ProjectionY();
    if(htemp0->GetEntries() < 10) continue;
    int arm = mapper->get_arm(i);
    int quadrant = mapper->get_quadrant(i);
    int sensor = mapper->get_sensor_in_quadrant(i);
    int index = 6*quadrant+sensor;
    int layer = mapper->get_layer(i);
    hsensor_high[arm][layer][index]->Add(htemp0);
    hsensor_low[arm][layer][index]->Add(htemp1);
  }
  
  for(int iarm = 0;iarm < 2;iarm++){
    for(int ilayer = 0;ilayer < 8;ilayer++){
      char cname[100];
      sprintf(cname,"csensor_arm%d_layer%d_%d_%d",iarm,ilayer,runnumber,segment);
      TCanvas* c = new TCanvas(cname,cname,1400,800);
      for(int index = 0;index < 24;index++){
        char pname[100];
        sprintf(pname,"sensor_arm%d_layer%d_index%d",iarm,ilayer,index);
        double x0 = min_sensor_x[iarm][ilayer][index];
        double x1 = max_sensor_x[iarm][ilayer][index];
        double y0 = min_sensor_y[iarm][ilayer][index];
        double y1 = max_sensor_y[iarm][ilayer][index];
        if(ilayer%2 == 0){
          y0 = y0 - 0.85;
          y1 = y1 + 0.85;
        }
        if(ilayer%2 == 1){
          x0 = x0 - 0.85;
          x1 = x1 + 0.85;
        }
        TPad* pad = new TPad(pname,pname,0.5+x0/40.,0.5+y0/40.,0.5+x1/40.,0.5+y1/40.);
        pad->cd();
        pad->SetLogy();
	hsensor_high[iarm][ilayer][index]->Draw("");
	hsensor_low[iarm][ilayer][index]->SetLineColor(kRed);
        hsensor_low[iarm][ilayer][index]->Draw("");
        c->cd();
        pad->DrawClone("same");
        delete pad;
      }
      sprintf(cname,"%d/csensor_arm%d_layer%d_%d_%d.gif",runnumber,iarm,ilayer,runnumber,segment);
      c->Print(cname,"gif"); 
      delete c;
    }
  }
}
Exemple #5
0
//_________________________________________________________________________________________
Int_t checkPullTree(TString pathTree,  TString pathNameThetaMap, TString pathNameSigmaMap,
                    TString mapSuffix, const Int_t collType /*0: pp, 1: pPb, 2: PbPb*/, const Bool_t plotPull = kTRUE,
                    const Double_t downScaleFactor = 1,
                    TString pathNameSplinesFile = "", TString prSplinesName = "",
                    TString fileNameTree = "bhess_PIDetaTree.root", TString treeName = "fTree")
{
  const Bool_t isNonPP = collType != 0;
  const Double_t massProton = AliPID::ParticleMass(AliPID::kProton);
  
  Bool_t recalculateExpecteddEdx = pathNameSplinesFile != "";
  
  TFile* f = 0x0;
	
  f = TFile::Open(Form("%s/%s", pathTree.Data(), fileNameTree.Data()));
  if (!f)  {
    std::cout << "Failed to open tree file \"" << Form("%s/%s", pathTree.Data(), fileNameTree.Data()) << "\"!" << std::endl;
    return -1;
  }
      
  // Extract the data Tree
  TTree* tree = dynamic_cast<TTree*>(f->Get(treeName.Data()));
  if (!tree) {
    std::cout << "Failed to load data tree!" << std::endl;
    return -1;
  }
  
  // Extract the splines, if desired
  TSpline3* splPr = 0x0;
  if (recalculateExpecteddEdx) {
    std::cout << "Loading splines to recalculate expected dEdx!" << std::endl << std::endl;
    
    TFile* fSpl = TFile::Open(pathNameSplinesFile.Data());
    if (!fSpl) {
      std::cout << "Failed to open spline file \"" << pathNameSplinesFile.Data() << "\"!" << std::endl;
      return 0x0;
    }
    
    TObjArray* TPCPIDResponse = (TObjArray*)fSpl->Get("TPCPIDResponse");
    if (!TPCPIDResponse) {
      splPr = (TSpline3*)fSpl->Get(prSplinesName.Data());
      
      // If splines are in file directly, without TPCPIDResponse object, try to load them
      if (!splPr) {
        std::cout << "Failed to load object array from spline file \"" << pathNameSplinesFile.Data() << "\"!" << std::endl;
        return 0x0;
      }
    }
    else {
      splPr = (TSpline3*)TPCPIDResponse->FindObject(prSplinesName.Data());
      
      if (!splPr) {
        std::cout << "Failed to load splines from file \"" << pathNameSplinesFile.Data() << "\"!" << std::endl;
        return 0x0;
      }
    }
  }
  else
    std::cout << "Taking dEdxExpected from Tree..." << std::endl << std::endl;

  // Extract the correction maps
  TFile* fMap = TFile::Open(pathNameThetaMap.Data());
  if (!fMap)  {
    std::cout << "Failed to open thetaMap file \"" << pathNameThetaMap.Data() << "\"! Will not additionally correct data...." << std::endl;
  }

  TH2D* hMap = 0x0;
  
  if (fMap) {
    hMap = dynamic_cast<TH2D*>(fMap->Get(Form("hRefined%s", mapSuffix.Data())));
    if (!hMap) {
      std::cout << "Failed to load theta map!" << std::endl;
      return -1;
    }
  }

  TFile* fSigmaMap = TFile::Open(pathNameSigmaMap.Data());
  if (!fSigmaMap)  {
    std::cout << "Failed to open simgaMap file \"" << pathNameSigmaMap.Data() << "\"!" << std::endl;
    return -1;
  }

  TH2D* hThetaMapSigmaPar1 = dynamic_cast<TH2D*>(fSigmaMap->Get("hThetaMapSigmaPar1"));
  if (!hThetaMapSigmaPar1) {
    std::cout << "Failed to load sigma map for par 1!" << std::endl;
    return -1;
  }

  Double_t c0 = -1;
  TNamed* c0Info = dynamic_cast<TNamed*>(fSigmaMap->Get("c0"));
  if (!c0Info) {
    std::cout << "Failed to extract c0 from file with sigma map!" << std::endl;
    return -1;
  }

  TString c0String = c0Info->GetTitle();
  c0 = c0String.Atof();
  printf("Loaded parameter 0 for sigma: %f\n\n", c0);

  if (plotPull)
    std::cout << "Plotting pull..." << std::endl << std::endl;
  else
    std::cout << "Plotting delta'..." << std::endl << std::endl;

  Long64_t nTreeEntries = tree->GetEntriesFast();

  Double_t dEdx = 0.; // Measured dE/dx
  Double_t dEdxExpected = 0.; // Expected dE/dx according to parametrisation
  Double_t tanTheta = 0.; // Tangens of (local) theta at TPC inner wall
  Double_t pTPC = 0.; // Momentum at TPC inner wall
  UShort_t tpcSignalN = 0; // Number of clusters used for dEdx
  UChar_t  pidType = 0;
  Int_t    fMultiplicity = 0;
  //Double_t phiPrime = 0;

  // Only activate the branches of interest to save processing time
  tree->SetBranchStatus("*", 0); // Disable all branches
  tree->SetBranchStatus("pTPC", 1);
  tree->SetBranchStatus("dEdx", 1);
  tree->SetBranchStatus("dEdxExpected", 1);
  tree->SetBranchStatus("tanTheta", 1);
  tree->SetBranchStatus("tpcSignalN", 1);
  tree->SetBranchStatus("pidType", 1);
  //tree->SetBranchStatus("phiPrime", 1);
  if (isNonPP)
    tree->SetBranchStatus("fMultiplicity", 1);

  
  tree->SetBranchAddress("dEdx", &dEdx);
  tree->SetBranchAddress("dEdxExpected", &dEdxExpected);
  tree->SetBranchAddress("tanTheta", &tanTheta);
  tree->SetBranchAddress("tpcSignalN", &tpcSignalN);
  tree->SetBranchAddress("pTPC", &pTPC);
  tree->SetBranchAddress("pidType", &pidType);
  //tree->SetBranchAddress("phiPrime", &phiPrime);
  if (isNonPP)
    tree->SetBranchAddress("fMultiplicity", &fMultiplicity);

  
  // Output file
  TDatime daTime;
  TString savefileName = Form("%s%s_checkPullSigma_%04d_%02d_%02d__%02d_%02d.root", fileNameTree.ReplaceAll(".root", "").Data(),
                              recalculateExpecteddEdx ? "_recalcdEdx" : "",
                              daTime.GetYear(), daTime.GetMonth(), daTime.GetDay(), daTime.GetHour(), daTime.GetMinute());

  TFile* fSave = TFile::Open(Form("%s/%s", pathTree.Data(), savefileName.Data()), "recreate");
  if (!fSave) {
    std::cout << "Failed to open save file \"" << Form("%s/%s", pathTree.Data(), savefileName.Data()) << "\"!" << std::endl;
    return -1;
  }
  
  const Double_t pBoundLow = 0.1;
  const Double_t pBoundUp = 5;

  const Int_t nBins1 = TMath::Ceil(180 / downScaleFactor);
  const Int_t nBins2 = TMath::Ceil(100 / downScaleFactor);
  const Int_t nBins3 = TMath::Ceil(60 / downScaleFactor);
  
  const Int_t nPbinsForMap = nBins1 + nBins2 + nBins3;
  Double_t binsPforMap[nPbinsForMap + 1];
  
  Double_t binWidth1 = (1.0 - pBoundLow) / nBins1;
  Double_t binWidth2 = (2.0 - 1.0 ) / nBins2;
  Double_t binWidth3 = (pBoundUp - 2.0) / nBins3;
  
  for (Int_t i = 0; i < nBins1; i++)  {
    binsPforMap[i] = pBoundLow + i * binWidth1;
  }
  for (Int_t i = nBins1, j = 0; i < nBins1 + nBins2; i++, j++)  {
    binsPforMap[i] = 1.0 + j * binWidth2;
  }
  for (Int_t i = nBins1 + nBins2, j = 0; i < nBins1 + nBins2 + nBins3; i++, j++)  {
    binsPforMap[i] = 2.0 + j * binWidth3;
  }
  binsPforMap[nPbinsForMap] = pBoundUp;

  TH2D* hPull = new TH2D("hPull", "Pull vs. p_{TPC} integrated over tan(#Theta);p_{TPC} (GeV/c);Pull", nPbinsForMap, binsPforMap, 
                         plotPull ? 120 : 240, plotPull ? -6 : -0.6, plotPull ? 6 : 0.6);
  TH2D* hPullAdditionalCorr = (TH2D*)hPull->Clone("hPullAdditionalCorr");
  hPullAdditionalCorr->SetTitle("Pull vs. p_{TPC} integrated over tan(#Theta) with additional dEdx correction w.r.t. tan(#Theta)");
  /*
  const Int_t nThetaHistos = 3;
  TH2D* hPullTheta[nThetaHistos];
  TH2D* hPullAdditionalCorrTheta[nThetaHistos];
  Double_t tThetaLow[nThetaHistos] = { 0.0, 0.4, 0.9 };
  Double_t tThetaHigh[nThetaHistos] = { 0.1, 0.5, 1.0 };
  */
  const Int_t nThetaHistos = 10;
  TH2D* hPullTheta[nThetaHistos];
  TH2D* hPullAdditionalCorrTheta[nThetaHistos];
  Double_t tThetaLow[nThetaHistos] = { 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 };
  Double_t tThetaHigh[nThetaHistos] = { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 };
  

  for (Int_t i = 0; i < nThetaHistos; i++)    {
    hPullTheta[i] = new TH2D(Form("hPullTheta_%d", i),
                             Form("Pull vs. p_{TPC} for %.2f <= |tan(#Theta)| < %.2f;p_{TPC} (GeV/c);Pull", tThetaLow[i], tThetaHigh[i]),
                             nPbinsForMap, binsPforMap, plotPull ? 120 : 240, plotPull ? -6 : -0.6, plotPull ? 6 : 0.6);

    hPullAdditionalCorrTheta[i] =
      new TH2D(Form("hPullAdditionalCorrTheta_%d", i),
               Form("Pull vs. p_{TPC} for %.2f <= |tan(#Theta)| < %.2f with additional dEdx correction w.r.t. tan(#Theta);p_{TPC} (GeV/c);Pull",
                    tThetaLow[i], tThetaHigh[i]),
               nPbinsForMap, binsPforMap, plotPull ? 120 : 240, plotPull ? -6 : -0.6, plotPull ? 6 : 0.6);
  }

  
  
  
  
  
  TF1 corrFuncMult("corrFuncMult", "[0] + [1]*TMath::Max([4], TMath::Min(x, [3])) + [2] * TMath::Power(TMath::Max([4], TMath::Min(x, [3])), 2)",
                   0., 0.2);
  TF1 corrFuncMultTanTheta("corrFuncMultTanTheta", "[0] * (x -[2]) + [1] * (x * x - [2] * [2])", -1.5, 1.5);
  TF1 corrFuncSigmaMult("corrFuncSigmaMul", "TMath::Max(0, [0] + [1]*TMath::Min(x, [3]) + [2] * TMath::Power(TMath::Min(x, [3]), 2))", 0., 0.2);
  
  
  // LHC13b.pass2
  if (isNonPP)
    printf("Using corr Parameters for 13b.pass2\n!");
  
  corrFuncMult.SetParameter(0, -5.906e-06);
  corrFuncMult.SetParameter(1, -5.064e-04);
  corrFuncMult.SetParameter(2, -3.521e-02);
  corrFuncMult.SetParameter(3,  2.469e-02);
  corrFuncMult.SetParameter(4, 0);
  
  corrFuncMultTanTheta.SetParameter(0, -5.32e-06);
  corrFuncMultTanTheta.SetParameter(1,  1.177e-05);
  corrFuncMultTanTheta.SetParameter(2, -0.5);
  
  corrFuncSigmaMult.SetParameter(0, 0.);
  corrFuncSigmaMult.SetParameter(1, 0.);
  corrFuncSigmaMult.SetParameter(2, 0.);
  corrFuncSigmaMult.SetParameter(3, 0.);
  
  
  /* OK, but PID task was not very satisfying
  corrFuncMult.SetParameter(0, -6.27187e-06);
  corrFuncMult.SetParameter(1, -4.60649e-04);
  corrFuncMult.SetParameter(2, -4.26450e-02);
  corrFuncMult.SetParameter(3, 2.40590e-02);
  corrFuncMult.SetParameter(4, 0);
  
  corrFuncMultTanTheta.SetParameter(0, -5.338e-06);
  corrFuncMultTanTheta.SetParameter(1,  1.220e-05);
  corrFuncMultTanTheta.SetParameter(2, -0.5);
  
  corrFuncSigmaMult.SetParameter(0, 7.89237e-05);
  corrFuncSigmaMult.SetParameter(1, -1.30662e-02);
  corrFuncSigmaMult.SetParameter(2, 8.91548e-01);
  corrFuncSigmaMult.SetParameter(3, 1.47931e-02);
  */
  
  
  /*
  // LHC11a10a
  if (isNonPP)
    printf("Using corr Parameters for 11a10a\n!");
  
  corrFuncMult.SetParameter(0, 6.90133e-06);
  corrFuncMult.SetParameter(1, -1.22123e-03);
  corrFuncMult.SetParameter(2, 1.80220e-02);
  corrFuncMult.SetParameter(3, 0.1);
  corrFuncMult.SetParameter(4, 6.45306e-03);
  
  corrFuncMultTanTheta.SetParameter(0, -2.85505e-07);
  corrFuncMultTanTheta.SetParameter(1, -1.31911e-06);
  corrFuncMultTanTheta.SetParameter(2, -0.5);
  
  corrFuncSigmaMult.SetParameter(0, -4.29665e-05);
  corrFuncSigmaMult.SetParameter(1, 1.37023e-02);
  corrFuncSigmaMult.SetParameter(2, -6.36337e-01);
  corrFuncSigmaMult.SetParameter(3, 1.13479e-02);
  */
  
  /* OLD without saturation and large error for negative slopes
  corrFuncSigmaMult.SetParameter(0, -4.79684e-05);
  corrFuncSigmaMult.SetParameter(1, 1.49938e-02);
  corrFuncSigmaMult.SetParameter(2, -7.15269e-01);
  corrFuncSigmaMult.SetParameter(3, 1.06855e-02);
  */
  
  /* OLD very good try, but with fewer pBins for the fitting
  corrFuncMult.SetParameter(0, 6.88365e-06);
  corrFuncMult.SetParameter(1, -1.22324e-03);
  corrFuncMult.SetParameter(2, 1.81625e-02);
  corrFuncMult.SetParameter(3, 0.1);
  corrFuncMult.SetParameter(4, 6.36890e-03);
  
  corrFuncMultTanTheta.SetParameter(0, -2.85505e-07);
  corrFuncMultTanTheta.SetParameter(1, -1.31911e-06);
  corrFuncMultTanTheta.SetParameter(2, -0.5);
  
  corrFuncSigmaMult.SetParameter(0, -4.28401e-05);
  corrFuncSigmaMult.SetParameter(1, 1.24812e-02);
  corrFuncSigmaMult.SetParameter(2, -5.28531e-01);
  corrFuncSigmaMult.SetParameter(3, 1.25147e-02);
  */
  /*OLD good try
  corrFuncMult.SetParameter(0, 7.50321e-06);
  corrFuncMult.SetParameter(1, -1.25250e-03);
  corrFuncMult.SetParameter(2, 1.85437e-02);
  corrFuncMult.SetParameter(3, 0.1);
  corrFuncMult.SetParameter(4, 6.21192e-03);
  
  corrFuncMultTanTheta.SetParameter(0, -1.43112e-07);
  corrFuncMultTanTheta.SetParameter(1, -1.53e-06);
  corrFuncMultTanTheta.SetParameter(2, 0.3);
  
  corrFuncSigmaMult.SetParameter(0, -2.54019e-05);
  corrFuncSigmaMult.SetParameter(1, 8.68883e-03);
  corrFuncSigmaMult.SetParameter(2, -3.36176e-01);
  corrFuncSigmaMult.SetParameter(3, 1.29230e-02);
  */
  
  /*
  // LHC10h.pass2
  if (isNonPP)
    printf("Using corr Parameters for 10h.pass2\n!");
  
  corrFuncMult.SetParameter(0, 3.21636e-07);
  corrFuncMult.SetParameter(1, -6.65876e-04);
  corrFuncMult.SetParameter(2, 1.28786e-03);
  corrFuncMult.SetParameter(3, 1.47677e-02);
  corrFuncMult.SetParameter(4, 0.);
  
  corrFuncMultTanTheta.SetParameter(0, 7.23591e-08);
  corrFuncMultTanTheta.SetParameter(1, 2.7469e-06);
  corrFuncMultTanTheta.SetParameter(2, -0.5);
  
  corrFuncSigmaMult.SetParameter(0, -1.22590e-05);
  corrFuncSigmaMult.SetParameter(1, 6.88888e-03);
  corrFuncSigmaMult.SetParameter(2, -3.20788e-01);
  corrFuncSigmaMult.SetParameter(3, 1.07345e-02);
  */
  
  /*OLD bad try
  corrFuncMult.SetParameter(0, 2.71514e-07);
  corrFuncMult.SetParameter(1, -6.92031e-04);
  corrFuncMult.SetParameter(2, 3.56042e-03);
  corrFuncMult.SetParameter(3, 1.47497e-02);
  corrFuncMult.SetParameter(4, 0.);
  
  corrFuncMultTanTheta.SetParameter(0, 8.53204e-08);
  corrFuncMultTanTheta.SetParameter(1, 2.85591e-06);
  corrFuncMultTanTheta.SetParameter(2, -0.5);
  
  corrFuncSigmaMult.SetParameter(0, -6.82477e-06);
  corrFuncSigmaMult.SetParameter(1, 4.97051e-03);
  corrFuncSigmaMult.SetParameter(2, -1.64954e-01);
  corrFuncSigmaMult.SetParameter(3, 9.21061e-03);
  */
  

  //TODO NOW
  TF1* fShapeSmallP = new TF1("fShapeSmallP", "pol5", -0.4, 0.4);
  fShapeSmallP->SetParameters(1.01712, -0.0202725, -0.260692, 0.261623, 0.671854, -1.14014);
    
  for (Long64_t i = 0; i < nTreeEntries; i++) {
    tree->GetEntry(i);

    if (dEdx <= 0 || dEdxExpected <= 0 || tpcSignalN <= 10)
      continue;
    /*
    Double_t pT = pTPC*TMath::Sin(-TMath::ATan(tanTheta)+TMath::Pi()/2.0);
    if ((phiPrime > 0.072/pT+TMath::Pi()/18.0-0.035 && phiPrime < 0.07/pT/pT+0.1/pT+TMath::Pi()/18.0+0.035)) 
      continue;
    */
      
    if (pidType != kMCid) {
      if (pidType == kTPCid && pTPC > 0.6)
        continue;
      if (pidType == kTPCandTOFid && (pTPC < 0.6 || pTPC > 2.0))
        continue;
      if ((collType == 2) && pidType == kTPCandTOFid && pTPC > 1.0)
        continue;// Only V0's in case of PbPb above 1.0 GeV/c
      if (pidType == kV0idPlusTOFrejected) //TODO NOW NEW
        continue;
    }
    
    if (recalculateExpecteddEdx) {
      dEdxExpected = 50. * splPr->Eval(pTPC / massProton); //WARNING: What, if MIP is different from 50.? Seems not to be used (tested for pp, MC_pp, PbPb and MC_PbPb), but can in principle happen
    }
      
    //TODO NOW
    /*
    if (TMath::Abs(tanTheta) <= 0.4) {
      Double_t p0 = fShapeSmallP->Eval(tanTheta) - 1.0; // Strength of the correction
      Double_t p1 = -9.0; // How fast the correction is turned off
      Double_t p2 = -0.209; // Turn off correction around 0.2 GeV/c
      Double_t p3 = 1.0; // Delta' for large p should be 1

      Double_t corrFactor = TMath::Erf((pTPC + p2) * p1) * p0 + p3 + p0; // Add p0 to have 1 for p3 = 1 and large pTPC
      dEdxExpected *= corrFactor;
    }*/
    
     /*TODO old unsuccessful try 
    Double_t thetaGlobalTPC = -TMath::ATan(tanTheta) + TMath::Pi() / 2.;
    Double_t pTtpc = pTPC * TMath::Sin(thetaGlobalTPC);
    Double_t pTtpcInv = (pTtpc > 0) ? 1. / pTtpc : 0;
    Double_t p0 = 1.0;
    Double_t p1 = 1./ 0.5;//TODO 2.0;
    Double_t p2 = -0.2;//TODO 0.1
    Double_t pTcorrFactor = p0 + (pTtpcInv > p1) * p2 * (pTtpcInv - p1);
    
    dEdxExpected *= pTcorrFactor;
    */
    
      
    // From the momentum (via dEdxExpected) and the tanTheta of the track, the expected dEdx can be calculated (correctedDeDxExpected).
    // If the splines are correct, this should give in average the same value as dEdx. 
    // Now valid: Maps created from corrected data with splines adopted to corrected data, so lookup should be for dEdxExpected=dEdxSplines (no further
    // eta correction) or the corrected dEdx from the track (which should ideally be = dEdxSplines)
    
    // Tested with corrected data for LHC10d.pass2: using dEdx for the lookup (which is the corrected value and should ideally be = dEdxSplines):
    // Results almost the same. Maybe slightly better for dEdxExpected.
    
    // No longer valid: Note that the maps take always the uncorrected dEdx w.r.t.
    // tanTheta, so that correctedDeDxExpected is needed here normally. However, the information for the correction will be lost at some point.
    // Therefore, dEdxExpected can be used instead and should provide a good approximation.
    Double_t c1FromSigmaMap = hThetaMapSigmaPar1->GetBinContent(getBinX(hThetaMapSigmaPar1, tanTheta), getBinY(hThetaMapSigmaPar1, 1./dEdxExpected));
    
    Double_t expectedSigma = dEdxExpected * TMath::Sqrt( c0 * c0 + (c1FromSigmaMap * c1FromSigmaMap) / tpcSignalN);
    Double_t pull = (dEdx - dEdxExpected) / (plotPull ? expectedSigma: dEdxExpected);

    // Fill pull histo
    hPull->Fill(pTPC, pull);

    Double_t tanThetaAbs = TMath::Abs(tanTheta);
    
    for (Int_t j = 0; j < nThetaHistos; j++)    {
      if (tanThetaAbs  >= tThetaLow[j] && tanThetaAbs < tThetaHigh[j])  {
        hPullTheta[j]->Fill(pTPC, pull);
      }
    }

    if (!hMap)
      continue;

    Double_t correctionFactor = 1.;
    
    if (isNonPP) {
      // 1. Correct eta dependence
      correctionFactor = hMap->GetBinContent(getBinX(hMap, tanTheta), getBinY(hMap, 1./dEdxExpected));
      
      // 2. Correct for multiplicity dependence:
      Double_t multCorrectionFactor = 1.;
      
      if (fMultiplicity > 0) {
        Double_t relSlope = corrFuncMult.Eval(1. / (dEdxExpected * correctionFactor));
        relSlope += corrFuncMultTanTheta.Eval(tanTheta);

        multCorrectionFactor = 1. + relSlope * fMultiplicity;
      }

      c1FromSigmaMap = hThetaMapSigmaPar1->GetBinContent(getBinX(hThetaMapSigmaPar1, tanTheta), getBinY(hThetaMapSigmaPar1, 1./dEdxExpected));
      
      // Multiplicity dependence of sigma depends on the real dEdx at zero multiplicity, i.e. the eta (only) corrected dEdxExpected value has to be used
      // since all maps etc. have been created for ~zero multiplicity
      Double_t relSigmaSlope = corrFuncSigmaMult.Eval(1. / (dEdxExpected * correctionFactor));
      Double_t multSigmaCorrectionFactor = 1. + relSigmaSlope * fMultiplicity;
      
      dEdxExpected *= correctionFactor * multCorrectionFactor; 
      
      expectedSigma = dEdxExpected * TMath::Sqrt( c0 * c0 + (c1FromSigmaMap * c1FromSigmaMap) / tpcSignalN);
      expectedSigma *= multSigmaCorrectionFactor;
      
      pull = (dEdx - dEdxExpected) / (plotPull ? expectedSigma: dEdxExpected);
    }
    else {
      correctionFactor = hMap->GetBinContent(getBinX(hMap, tanTheta), getBinY(hMap, 1./dEdxExpected));
      
      c1FromSigmaMap = hThetaMapSigmaPar1->GetBinContent(getBinX(hThetaMapSigmaPar1, tanTheta), getBinY(hThetaMapSigmaPar1, 1./dEdxExpected));
   
      dEdxExpected *= correctionFactor; // If data is not corrected, but the sigma map is for corrected data, re-do analysis with corrected dEdx
      
      expectedSigma = dEdxExpected * TMath::Sqrt( c0 * c0 + (c1FromSigmaMap * c1FromSigmaMap) / tpcSignalN);
      pull = (dEdx - dEdxExpected) / (plotPull ? expectedSigma: dEdxExpected);
    }

    pull = (dEdx - dEdxExpected) / (plotPull ? expectedSigma: dEdxExpected);

    hPullAdditionalCorr->Fill(pTPC, pull);

    for (Int_t j = 0; j < nThetaHistos; j++)    {
      if (tanThetaAbs  >= tThetaLow[j] && tanThetaAbs < tThetaHigh[j])  {
        hPullAdditionalCorrTheta[j]->Fill(pTPC, pull);
      }
    }
  }
/*
  // Mean, Sigma, chi^2/NDF of pull of different theta bins and all in one plot
  TCanvas* canvPullMean = new TCanvas("canvPullMean", "canvPullMean", 100,10,1380,800);
  canvPullMean->SetLogx(kTRUE);
  canvPullMean->SetGridx(kTRUE);
  canvPullMean->SetGridy(kTRUE);
  TCanvas* canvPullSigma = new TCanvas("canvPullSigma", "canvPullSigma", 100,10,1380,800);
  canvPullSigma->SetLogx(kTRUE);
  canvPullSigma->SetGridx(kTRUE);
  canvPullSigma->SetGridy(kTRUE);
  TCanvas* canvPullChi2 = new TCanvas("canvPullChi2", "canvPullChi2", 100,10,1380,800);
  canvPullChi2->SetLogx(kTRUE);
  canvPullChi2->SetGridx(kTRUE);
  canvPullChi2->SetGridy(kTRUE);
  

  TCanvas* canvPull[nThetaHistos + 1];
  for (Int_t i = 0, j = nThetaHistos; i < nThetaHistos + 1; i++, j--)  {
    canvPull[i] = new TCanvas(Form("canvPull_%d", i), "canvPull", 100,10,1380,800);
    canvPull[i]->cd();
    canvPull[i]->SetLogx(kTRUE);
    canvPull[i]->SetLogz(kTRUE);
    canvPull[i]->SetGrid(kTRUE, kTRUE);

    TH2D* hTemp = 0x0;
    TString thetaString = "";
    if (i == nThetaHistos)  {
      hTemp = hPull;
      thetaString = "tan(#Theta) integrated";
    }
    else {
      hTemp = hPullTheta[i];
      thetaString = Form("%.2f #leq |tan(#Theta)| < %.2f", tThetaLow[i], tThetaHigh[i]);
    }
    
    normaliseHisto(hTemp);
    hTemp->FitSlicesY();
    hTemp->GetYaxis()->SetNdivisions(12);
    hTemp->GetXaxis()->SetMoreLogLabels(kTRUE);
    TH1D* hTempMean = (TH1D*)gDirectory->Get(Form("%s_1", hTemp->GetName()));
    hTempMean->SetTitle(Form("mean(pull), %s", thetaString.Data()));
    hTempMean->GetXaxis()->SetMoreLogLabels(kTRUE);
    hTempMean->SetLineWidth(2);
    hTempMean->SetMarkerStyle(20);
    TH1D* hTempSigma = (TH1D*)gDirectory->Get(Form("%s_2", hTemp->GetName()));
    hTempSigma->SetTitle(Form("#sigma(pull), %s", thetaString.Data()));
    hTempSigma->GetXaxis()->SetMoreLogLabels(kTRUE);
    hTempSigma->SetLineColor(kMagenta);
    hTempSigma->SetMarkerStyle(20);
    hTempSigma->SetMarkerColor(kMagenta);
    hTempSigma->SetLineWidth(2);
    TH1D* hTempChi2 = (TH1D*)gDirectory->Get(Form("%s_chi2", hTemp->GetName()));
    hTempChi2->SetTitle(Form("#chi^{2} / NDF (pull), %s", thetaString.Data()));
    hTempChi2->GetXaxis()->SetMoreLogLabels(kTRUE);
    hTempChi2->SetLineColor(kMagenta + 2);
    hTempChi2->SetMarkerStyle(20);
    hTempChi2->SetMarkerColor(kMagenta + 2);
    hTempChi2->SetLineWidth(2);

    hTemp->DrawCopy("colz");
    hTempMean->DrawCopy("same");
    hTempSigma->DrawCopy("same");
    hTempChi2->Scale(-1./10.);
    hTempChi2->DrawCopy("same");
    hTempChi2->Scale(-10.);

    canvPullMean->cd();
    hTempMean->SetLineColor(1 + ((j >= 9) ? (39 + 2 * (j - 9)) : j));
    hTempMean->SetMarkerColor(1 + ((j >= 9) ? (39 + 2 * (j - 9)) : j));
    hTempMean->DrawCopy((i == 0 ? "" : "same"));

    canvPullSigma->cd();
    hTempSigma->SetLineColor(1 + ((j >= 9) ? (39 + 2 * (j - 9)) : j));
    hTempSigma->SetMarkerColor(1 + ((j >= 9) ? (39 + 2 * (j - 9)) : j));
    hTempSigma->DrawCopy((i == 0 ? "" : "same"));

    canvPullChi2->cd();
    hTempChi2->SetLineColor(1 + ((j >= 9) ? (39 + 2 * (j - 9)) : j));
    hTempChi2->SetMarkerColor(1 + ((j >= 9) ? (39 + 2 * (j - 9)) : j));
    hTempChi2->DrawCopy((i == 0 ? "" : "same"));
  }

  canvPullMean->BuildLegend();
  canvPullSigma->BuildLegend();
  canvPullChi2->BuildLegend();
*/
  // Histograms with additional correction
  TCanvas* canvPullMeanCorr = 0x0;
  TCanvas* canvPullSigmaCorr = 0x0;
  TCanvas* canvPullChi2Corr = 0x0;
  TCanvas* canvPullCorr[nThetaHistos + 1];
  for (Int_t i = 0; i < nThetaHistos + 1; i++) 
    canvPullCorr[i] = 0x0;
  
  if (hMap) {
    // Mean, Sigma, chi^2/NDF of pull of different theta bins and all in one plot
    canvPullMeanCorr = new TCanvas("canvPullMeanCorr", "canvPullMeanCorr", 100,10,1380,800);
    canvPullMeanCorr->SetLogx(kTRUE);
    canvPullMeanCorr->SetGridx(kTRUE);
    canvPullMeanCorr->SetGridy(kTRUE);
    canvPullSigmaCorr = new TCanvas("canvPullSigmaCorr", "canvPullSigmaCorr", 100,10,1380,800);
    canvPullSigmaCorr->SetLogx(kTRUE);
    canvPullSigmaCorr->SetGridx(kTRUE);
    canvPullSigmaCorr->SetGridy(kTRUE);
    canvPullChi2Corr = new TCanvas("canvPullChi2Corr", "canvPullChi2Corr", 100,10,1380,800);
    canvPullChi2Corr->SetLogx(kTRUE);
    canvPullChi2Corr->SetGridx(kTRUE);
    canvPullChi2Corr->SetGridy(kTRUE);
    
    for (Int_t i = 0, j = nThetaHistos; i < nThetaHistos + 1; i++, j--)  {
      canvPullCorr[i] = new TCanvas(Form("canvPullCorr_%d", i), "canvPullCorr", 100,10,1380,800);
      canvPullCorr[i]->cd();
      canvPullCorr[i]->SetLogx(kTRUE);
      canvPullCorr[i]->SetLogz(kTRUE);
      canvPullCorr[i]->SetGrid(kTRUE, kTRUE);

      TH2D* hTemp = 0x0;
      TString thetaString = "";
      
      if (i == nThetaHistos)  {
        hTemp = hPullAdditionalCorr;
        thetaString = "tan(#Theta) integrated";
      }
      else    {
        hTemp = hPullAdditionalCorrTheta[i];
        thetaString = Form("%.2f #leq |tan(#Theta)| < %.2f", tThetaLow[i], tThetaHigh[i]);
      }

      normaliseHisto(hTemp);
      hTemp->FitSlicesY();
      hTemp->GetYaxis()->SetNdivisions(12);
      hTemp->GetXaxis()->SetMoreLogLabels(kTRUE);
      TH1D* hTempMean = (TH1D*)gDirectory->Get(Form("%s_1", hTemp->GetName()));
      hTempMean->SetTitle(Form("mean(pull), %s", thetaString.Data()));
      hTempMean->GetXaxis()->SetMoreLogLabels(kTRUE);
      hTempMean->SetLineWidth(2);
      hTempMean->SetMarkerStyle(20);
      TH1D* hTempSigma = (TH1D*)gDirectory->Get(Form("%s_2", hTemp->GetName()));
      hTempSigma->SetTitle(Form("#sigma(pull), %s", thetaString.Data()));
      hTempSigma->GetXaxis()->SetMoreLogLabels(kTRUE);
      hTempSigma->SetLineColor(kMagenta);
      hTempSigma->SetMarkerStyle(20);
      hTempSigma->SetMarkerColor(kMagenta);
      hTempSigma->SetLineWidth(2);
      TH1D* hTempChi2 = (TH1D*)gDirectory->Get(Form("%s_chi2", hTemp->GetName()));
      hTempChi2->SetTitle(Form("#chi^{2} / NDF (pull), %s", thetaString.Data()));
      hTempChi2->GetXaxis()->SetMoreLogLabels(kTRUE);
      hTempChi2->SetLineColor(kMagenta + 2);
      hTempChi2->SetMarkerStyle(20);
      hTempChi2->SetMarkerColor(kMagenta + 2);
      hTempChi2->SetLineWidth(2);

      hTemp->DrawCopy("colz");
      hTempMean->DrawCopy("same");
      hTempSigma->DrawCopy("same");
      hTempChi2->Scale(-1./10.);
      hTempChi2->DrawCopy("same");
      hTempChi2->Scale(-10.);
  
      canvPullMeanCorr->cd();
      hTempMean->SetLineColor(1 + ((j >= 9) ? (39 + 2 * (j - 9)) : j));
      hTempMean->SetMarkerColor(1 + ((j >= 9) ? (39 + 2 * (j - 9)) : j));
      hTempMean->DrawCopy((i == 0 ? "" : "same"));
      
      canvPullSigmaCorr->cd();
      hTempSigma->SetLineColor(1 + ((j >= 9) ? (39 + 2 * (j - 9)) : j));
      hTempSigma->SetMarkerColor(1 + ((j >= 9) ? (39 + 2 * (j - 9)) : j));
      hTempSigma->DrawCopy((i == 0 ? "" : "same"));
      
      canvPullChi2Corr->cd();
      hTempChi2->SetLineColor(1 + ((j >= 9) ? (39 + 2 * (j - 9)) : j));
      hTempChi2->SetMarkerColor(1 + ((j >= 9) ? (39 + 2 * (j - 9)) : j));
      hTempChi2->DrawCopy((i == 0 ? "" : "same"));
    }
    
    canvPullMeanCorr->BuildLegend();
    canvPullSigmaCorr->BuildLegend();
    canvPullChi2Corr->BuildLegend();
  }
  
  
  
  
  
  fSave->cd();
  /*canvPullMean->Write();
  canvPullSigma->Write();
  canvPullChi2->Write();
  
  for (Int_t  i = 0; i < nThetaHistos + 1; i++) {
    canvPull[i]->Write();
  }*/
  
  canvPullMeanCorr->Write();
  canvPullSigmaCorr->Write();
  canvPullChi2Corr->Write();
  
  for (Int_t  i = 0; i < nThetaHistos + 1; i++) {
    canvPullCorr[i]->Write();
  }

  TNamed* info = new TNamed(Form("Theta map: %s\n\nSigma map: %s\n\nSplines file: %s\n\nSplines name: %s", pathNameThetaMap.Data(), 
                                 pathNameSigmaMap.Data(), pathNameSplinesFile.Data(), prSplinesName.Data()),
                            "info");
  info->Write();
  fSave->Close();
  
  return 0;
}