//------------------------------------------------------------------------------
void PlotAlignmentValidation::plotHitMaps()
{
  
  setNiceStyle(); 
  //gStyle->SetOptStat(0);
  
  TCanvas *c = new TCanvas("c", "c", 1200,400);
  setCanvasStyle( *c );
  c->Divide(3,1);
  //ps->NewPage();

  //-------------------------------------------------
  //plot Hit map
  //-------------------------------------------------
  std::string histName_="Entriesprofile";
  c->cd(1);
  TTree *tree= (*sourceList.begin())->getTree();
  tree->Draw("entries:posR:posZ","","COLZ2Prof");
  c->cd(2);
  tree->Draw("entries:posY:posX","","COLZ2Prof");
  c->cd(3);
  tree->Draw("entries:posR:posPhi","","COLZ2Prof");
  
  char PlotName[1000];
  sprintf( PlotName, "%s/%s.eps", outputDir.c_str(), histName_.c_str() );
  
  c->Print(PlotName);
  //   //c->Update();
  c->Close();  
  //----------------------------------------------------
  
}
void patBJetTracks_efficiencies()
{
	// define proper canvas style
	setNiceStyle();
	gStyle->SetOptStat(0);

	// open file
	TFile* file = new TFile("analyzePatBJetTracks.root");

	TLegend *legend[3] = { 0, 0, 0 };

	// draw canvas with efficiencies

	TCanvas *canv;
	canv = new TCanvas("canv0", "hand-crafted track counting efficiencies", 800, 300);
	canv->Divide(3, 1);

	TH1 *total = (TH1*)file->Get(Form("%s/flavours", directory));
	TH1 *effVsCutB = 0;
	unsigned int i = 0;
	for(const char **flavour = flavours; *flavour; flavour++, i++) {
		TH1 *h = (TH1*)file->Get(Form("%s/trackIPSig_%s", directory, *flavour));
		TH1 *discrShape = (TH1*)h->Clone(Form("%s_discrShape", h->GetName()));
		discrShape->Scale(1.0 / discrShape->Integral());
		discrShape->SetMaximum(discrShape->GetMaximum() * 5);
		TH1 *effVsCut = computeEffVsCut(h, total->GetBinContent(4 - i));
		TH1 *effVsBEff = 0;

		if (flavour == flavours)	// b-jets
			effVsCutB = effVsCut;
		else
			effVsBEff = computeEffVsBEff(effVsCut, effVsCutB);

		discrShape->SetTitle("discriminator shape");
		effVsCut->SetTitle("efficiency versus discriminator cut");
		if (effVsBEff)
			effVsBEff->SetTitle("mistag versus b efficiency");

		setHistStyle(discrShape);
		setHistStyle(effVsCut);
		setHistStyle(effVsBEff);

		canv->cd(1);
		gPad->SetLogy(1);
		gPad->SetGridy(1);
		discrShape->SetLineColor(i + 1);
		discrShape->SetMarkerColor(i + 1);
		discrShape->Draw(i > 0 ? "same" : "");
		if (!legend[0])
			legend[0] = new TLegend(0.5, 0.7, 0.78, 0.88);
		legend[0]->AddEntry(discrShape, *flavour);

		canv->cd(2);
		gPad->SetLogy(1);
		gPad->SetGridy(1);
		effVsCut->SetLineColor(i + 1);
		effVsCut->SetMarkerColor(i + 1);
		effVsCut->Draw(i > 0 ? "same" : "");
		if (!legend[1])
			legend[1] = new TLegend(0.12, 0.12, 0.40, 0.30);
		legend[1]->AddEntry(effVsCut, *flavour);

		if (!effVsBEff)
			continue;
		canv->cd(3);
		gPad->SetLogy(1);
		gPad->SetGridx(1);
		gPad->SetGridy(1);
		effVsBEff->SetLineColor(i + 1);
		effVsBEff->SetMarkerColor(i + 1);
		effVsBEff->Draw(i > 1 ? "same" : "");
		if (!legend[2])
			legend[2] = new TLegend(0.12, 0.7, 0.40, 0.88);
		legend[2]->AddEntry(effVsBEff, *flavour);
	}

	canv->cd(1);
	legend[0]->Draw();

	canv->cd(2);
	legend[1]->Draw();

	canv->cd(3);
	legend[2]->Draw();

	////////////////////////////////////////////

	// canvas to compare negative tagger with light flavour mistag

	TCanvas *canv;
	canv = new TCanvas("canv1", "comparing light flavour mistag with negative tagger", 530, 300);
	canv->Divide(2, 1);

	TH1 *h1 = (TH1*)file->Get(Form("%s/trackIPSig_udsg", directory));
	TH1 *h2 = (TH1*)file->Get(Form("%s/negativeIPSig_all", directory));
	h2 = invertHisto(h2);	// invert x-axis

	TH1 *discrShape1 = (TH1*)h1->Clone("discrShape1");
	TH1 *discrShape2 = (TH1*)h2->Clone("discrShape2");

	discrShape1->Scale(1.0 / discrShape1->Integral());
	discrShape1->SetMaximum(discrShape1->GetMaximum() * 5);
	discrShape2->Scale(1.0 / discrShape2->Integral());

	TH1 *effVsCut1 = computeEffVsCut(h1, total->GetBinContent(2));
	TH1 *effVsCut2 = computeEffVsCut(h2, total->GetBinContent(1));

	discrShape1->SetTitle("discriminator shape");
	effVsCut1->SetTitle("efficiency versus discriminator cut");

	setHistStyle(discrShape1);
	setHistStyle(discrShape2);
	setHistStyle(effVsCut1);
	setHistStyle(effVsCut2);

	canv->cd(1);
	gPad->SetLogy(1);
	gPad->SetGridy(1);
	discrShape1->SetLineColor(1);
	discrShape1->SetMarkerColor(1);
	discrShape2->SetLineColor(2);
	discrShape2->SetMarkerColor(2);

	discrShape1->Draw();
	discrShape2->Draw("same");

	TLegend *l = new TLegend(0.5, 0.7, 0.78, 0.88);
	l->AddEntry(discrShape1, "udsg");
	l->AddEntry(discrShape2, "inv. neg");
	l->Draw();

	canv->cd(2);
	gPad->SetLogy(1);
	gPad->SetGridy(1);
	effVsCut1->SetLineColor(1);
	effVsCut1->SetMarkerColor(1);
	effVsCut2->SetLineColor(2);
	effVsCut2->SetMarkerColor(2);

	effVsCut1->Draw();
	effVsCut2->Draw("same");

	l = new TLegend(0.5, 0.7, 0.78, 0.88);
	l->AddEntry(effVsCut1, "udsg");
	l->AddEntry(effVsCut2, "inv. neg");
	l->Draw();
}
//------------------------------------------------------------------------------
void PlotAlignmentValidation::plotSubDetResiduals(bool plotNormHisto,unsigned int subDetId)
{
  setNiceStyle();
 
  gStyle->SetOptStat(11111);
  gStyle->SetOptFit(0000);

  TCanvas *c = new TCanvas("c", "c", 600,600);
  c->SetTopMargin(0.15);
  TString histoName= "";
  if (plotNormHisto) {histoName= "h_NormXprime";}
  else histoName= "h_Xprime_";
  switch (subDetId){
  case 1 : histoName+="TPBBarrel_0";break;
  case 2 : histoName+="TPEendcap_1";break;
  case 3 : histoName+="TPEendcap_2";break;
  case 4 : histoName+="TIBBarrel_0";break;
  case 5 : histoName+="TIDEndcap_1";break;
  case 6 : histoName+="TIDEndcap_2";break;
  case 7 : histoName+="TOBBarrel_3";break;
  case 8 : histoName+="TECEndcap_4";break;
  case 9 : histoName+="TECEndcap_5";break;
  }
  int tmpcounter = 0;
  TH1 *sumHisto = 0;
  for(std::vector<TkOfflineVariables*>::iterator it = sourceList.begin();
      it != sourceList.end(); ++it) {
    if (tmpcounter == 0 ) {
      TFile *f= (*it)->getFile();
      sumHisto =(TH1*) f->FindKeyAny(histoName)->ReadObj();//FindObjectAny(histoName.Data());
      sumHisto->SetLineColor(tmpcounter+1);
      sumHisto->SetLineStyle(tmpcounter+1);
      sumHisto->GetFunction("tmp")->SetBit(TF1::kNotDraw);
      sumHisto->Draw();
      
      //get statistic box coordinate to plot all boxes one below the other
      //gStyle->SetStatY(0.91);
      //gStyle->SetStatW(0.15);
      //gStyle->SetStatBorderSize(1);
      //gStyle->SetStatH(0.10);
      
      
      tmpcounter++;
    } else {
      sumHisto = (TH1*) (*it)->getFile()->FindObjectAny(histoName);
      sumHisto->SetLineColor(tmpcounter+1);
      sumHisto->SetLineStyle(tmpcounter+1);
      sumHisto->GetFunction("tmp")->SetBit(TF1::kNotDraw);
      //hstack->Add(sumHisto);
      
      c->Update();
      tmpcounter++;  
    }
    TObject *statObj = sumHisto->GetListOfFunctions()->FindObject("stats");
    if (statObj && statObj->InheritsFrom(TPaveStats::Class())) {
      TPaveStats *stats = static_cast<TPaveStats*>(statObj);
      stats->SetLineColor(tmpcounter+1);
      stats->SetTextColor(tmpcounter+1);
      stats->SetFillColor(10);
      stats->SetX1NDC(0.91-tmpcounter*0.1);
      stats->SetX2NDC(0.15);
      stats->SetY1NDC(1);
      stats->SetY2NDC(0.10);
      sumHisto->Draw("sames");
    }
  }
  //hstack->Draw("nostack");
  char PlotName[1000];
  sprintf( PlotName, "%s/%s.eps", outputDir.c_str(), histoName.Data() );
  
  c->Print(PlotName);
  //delete c;
  //c=0;
    
}
//------------------------------------------------------------------------------
void PlotAlignmentValidation::plotDMR(const std::string& variable, Int_t minHits, const std::string& options)
{
  // If several, comma-separated values are given,
  // call plotDMR with each value separately.
  // If a comma is found, the string is divided to two.
  // (no space allowed)
  std::size_t findres = variable.find(",");
  if ( findres != std::string::npos) {
    std::string substring1 = variable.substr(0,         findres);
    std::string substring2 = variable.substr(findres+1, std::string::npos);
    plotDMR(substring1, minHits, options);
    plotDMR(substring2, minHits, options);
    return;
   }

  // Variable name should end with X or Y. If it doesn't, recursively calls plotDMR twice with
  // X and Y added, respectively
  if (variable == "mean" || variable == "median" || variable == "meanNorm" ||
      variable == "rms" || variable == "rmsNorm") {
    plotDMR(variable+"X", minHits, options);
    plotDMR(variable+"Y", minHits, options);
    return;
  }

  TRegexp layer_re("layer=[0-9]+");
  bool plotPlain = false, plotSplits = false, plotLayers = false;
  int plotLayerN = 0;
  Ssiz_t index, len;
  if (options.find("plain") != std::string::npos) { plotPlain = true; }
  if (options.find("split") != std::string::npos) { plotSplits = true; }
  if (options.find("layers") != std::string::npos) { plotLayers = true; }
  if ((index = layer_re.Index(options, &len)) != -1) {
    if (plotLayers) {
      std::cerr << "Warning: option 'layers' overrides 'layer=N'" << std::endl;
    } else {
      std::string substr = options.substr(index+6, len-6);
      plotLayerN = atoi(substr.c_str());
    }
  }

  // Defaults to plotting only plain plot if empty (or invalid)
  // option string is given
  if (!plotPlain && !plotSplits) { plotPlain = true; }

  // This boolean array tells for which detector modules to plot split DMR plots
  // They are plotted for BPIX, FPIX, TIB and TOB
  static bool plotSplitsFor[6] = { true, true, true, false, true, false };

  // If layers are plotted, these are the numbers of layers for each subdetector
  static int numberOfLayers[6] = { 3, 2, 4, 3, 6, 9 };

  DMRPlotInfo plotinfo;

  setNiceStyle(); 
  gStyle->SetOptStat(0);
  
  TCanvas c("canv", "canv", 600, 600);
  setCanvasStyle( c );

  plotinfo.variable = variable;
  plotinfo.minHits = minHits;
  plotinfo.plotPlain = plotPlain;
  plotinfo.plotLayers = plotLayers;

  if (variable == "meanX") {          plotinfo.nbins = 50;  plotinfo.min = -0.001; plotinfo.max = 0.001; }
  else if (variable == "meanY") {     plotinfo.nbins = 50;  plotinfo.min = -0.005; plotinfo.max = 0.005; }
  else if (variable == "medianX") {   plotinfo.nbins = 50;  plotinfo.min = -0.005; plotinfo.max = 0.005; }
  else if (variable == "medianY") {   plotinfo.nbins = 50;  plotinfo.min = -0.005; plotinfo.max = 0.005; }
  else if (variable == "meanNormX") { plotinfo.nbins = 100; plotinfo.min = -2.0;   plotinfo.max = 2.0; }
  else if (variable == "meanNormY") { plotinfo.nbins = 100; plotinfo.min = -2.0;   plotinfo.max = 2.0; }
  else if (variable == "rmsX") {      plotinfo.nbins = 100; plotinfo.min = 0.0;    plotinfo.max = 0.1; }
  else if (variable == "rmsY") {      plotinfo.nbins = 100; plotinfo.min = 0.0;    plotinfo.max = 0.1; }
  else if (variable == "rmsNormX") {  plotinfo.nbins = 100; plotinfo.min = 0.3;    plotinfo.max = 1.8; }
  else if (variable == "rmsNormY") {  plotinfo.nbins = 100; plotinfo.min = 0.3;    plotinfo.max = 1.8; }
  else {
    std::cerr << "Unknown variable " << variable << std::endl;
    plotinfo.nbins = 100; plotinfo.min = -0.1; plotinfo.max = 0.1;
  }

  for (int i=1; i<=6; ++i) {

    // Skip strip detectors if plotting any "Y" variable
    if (i != 1 && i != 2 && variable.length() > 0 && variable[variable.length()-1] == 'Y') {
      continue;
    }
 
    // Skips plotting too high layers
    if (plotLayerN > numberOfLayers[i-1]) {
      continue;
    }

    plotinfo.plotSplits = plotSplits && plotSplitsFor[i-1];
    if (!plotinfo.plotPlain && !plotinfo.plotSplits) {
      continue;
    }

    // Sets dimension of legend according to the number of plots

    int nPlots = 1;
    if (plotinfo.plotSplits) { nPlots = 3; }
    if (plotinfo.plotLayers) { nPlots *= numberOfLayers[i-1]; }
    nPlots *= sourceList.size();

    double legendY = 0.80;
    if (nPlots > 3) { legendY -= 0.01 * (nPlots - 3); }
    if (legendY < 0.6) {
      std::cerr << "Warning: Huge legend!" << std::endl;
      legendY = 0.6;
    }

    THStack hstack("hstack", "hstack");
    plotinfo.maxY = 0;
    plotinfo.subDetId = i;
    plotinfo.nLayers = numberOfLayers[i-1];
    plotinfo.legend = new TLegend(0.17, legendY, 0.85, 0.88);
    setLegendStyle(*plotinfo.legend);
    plotinfo.hstack = &hstack;
    plotinfo.h = plotinfo.h1 = plotinfo.h2 = 0;
    plotinfo.firsthisto = true;
    
    for(std::vector<TkOfflineVariables*>::iterator it = sourceList.begin();
	it != sourceList.end(); ++it) {

      int minlayer = plotLayers ? 1 : plotLayerN;
      int maxlayer = plotLayers ? plotinfo.nLayers : plotLayerN;

      plotinfo.vars = *it;

      for (int layer = minlayer; layer <= maxlayer; layer++) {

	if (plotinfo.plotPlain) {
	  plotDMRHistogram(plotinfo, 0, layer);
	}

	if (plotinfo.plotSplits) {
	  plotDMRHistogram(plotinfo, -1, layer);
	  plotDMRHistogram(plotinfo, 1, layer);
	}

	if (plotinfo.plotPlain) {
	  if (plotinfo.h) { setDMRHistStyleAndLegend(plotinfo.h, plotinfo, 0, layer); }
	}

	if (plotinfo.plotSplits) {
	  // Add delta mu to the histogram
	  if (plotinfo.h1 != 0 && plotinfo.h2 != 0 && !plotinfo.plotPlain) {
	    std::ostringstream legend;
	    std::string unit = " #mum";
	    legend.precision(2);
	    float factor = 10000.0f;
	    if (plotinfo.variable == "meanNormX" || plotinfo.variable == "meanNormY" ||
		plotinfo.variable == "rmsNormX" || plotinfo.variable == "rmsNormY") {
	      factor = 1.0f;
	      unit = "";
	    }
	    float deltamu = factor*(plotinfo.h2->GetMean(1) - plotinfo.h1->GetMean(1));
	    legend << plotinfo.vars->getName();
	    if (layer > 0) {
	      legend << ", layer " << layer;
	    }
	    legend << ": #Delta#mu = " << deltamu << unit;
	    plotinfo.legend->AddEntry(static_cast<TObject*>(0), legend.str().c_str(), ""); 
	  }
	  if (plotinfo.h1) { setDMRHistStyleAndLegend(plotinfo.h1, plotinfo, -1, layer); }
	  if (plotinfo.h2) { setDMRHistStyleAndLegend(plotinfo.h2, plotinfo, 1, layer); }
	}
      
      }

    }
    
    if (plotinfo.h != 0 || plotinfo.h1 != 0 || plotinfo.h2 != 0) {

      hstack.Draw("nostack");
      hstack.SetMaximum(plotinfo.maxY*1.3);
      setTitleStyle(hstack, variable.c_str(), "#modules", plotinfo.subDetId);
      setHistStyle(*hstack.GetHistogram(), variable.c_str(), "#modules", 1);

      plotinfo.legend->Draw(); 
 
      std::ostringstream plotName;
      plotName << outputDir << "/D";
     
      if (variable=="medianX") plotName << "medianR_";
      else if (variable=="medianY") plotName << "medianYR_";
      else if (variable=="meanX") plotName << "meanR_";
      else if (variable=="meanY") plotName << "meanYR_";
      else if (variable=="meanNormX") plotName << "meanNR_";
      else if (variable=="meanNormY") plotName << "meanNYR_";
      else if (variable=="rmsX") plotName << "rmsR_";
      else if (variable=="rmsY") plotName << "rmsYR_";
      else if (variable=="rmsNormX") plotName << "rmsNR_";
      else if (variable=="rmsNormY") plotName << "rmsNYR_";

      switch (i) {
      case 1: plotName << "BPIX"; break;
      case 2: plotName << "FPIX"; break;
      case 3: plotName << "TIB"; break;
      case 4: plotName << "TID"; break;
      case 5: plotName << "TOB"; break;
      case 6: plotName << "TEC"; break;
      }

      if (plotPlain && !plotSplits) { plotName << "_plain"; }
      else if (!plotPlain && plotSplits) { plotName << "_split"; }
      if (plotLayers) { plotName << "_layers"; }
      if (plotLayerN > 0) { plotName << "_layer" << plotLayerN; }
 
      plotName << ".eps";

      c.Update(); 
      c.Print(plotName.str().c_str());
      
    }
    
  }

}
//------------------------------------------------------------------------------
void PlotAlignmentValidation::plotSS( const std::string& options, const std::string& residType )
{
  if (residType == "") {
    plotSS( options, "ResXvsXProfile");
    plotSS( options, "ResXvsYProfile");
    return;
  }

  int plotLayerN = 0;
  //  int plotRingN  = 0;
  //  bool plotPlain = false;
  bool plotLayers = false;  // overrides plotLayerN
  //  bool plotRings  = false;  // Todo: implement this?
  bool plotSplits = false;
  int plotSubDetN = 0;     // if zero, plot all

  TRegexp layer_re("layer=[0-9]+");
  Ssiz_t index, len;
  if (options.find("split") != std::string::npos) { plotSplits = true; }
  if (options.find("layers") != std::string::npos) { plotLayers = true; }
  if ((index = layer_re.Index(options, &len)) != -1) {
    if (plotLayers) {
      std::cerr << "Warning: option 'layers' overrides 'layer=N'" << std::endl;
    } else {
      std::string substr = options.substr(index+6, len-6);
      plotLayerN = atoi(substr.c_str());
    }
  }

  TRegexp subdet_re("subdet=[1-6]+");
  if ((index = subdet_re.Index(options, &len)) != -1) {
    std::string substr = options.substr(index+7, len-7);
    plotSubDetN = atoi(substr.c_str());
  }

  // If layers are plotted, these are the numbers of layers for each subdetector
  static int numberOfLayers[6] = { 3, 2, 4, 3, 6, 9 };

  setNiceStyle(); 
  gStyle->SetOptStat(0);
  
  TCanvas c("canv", "canv", 600, 600);
  setCanvasStyle( c );

  // todo: title, min/max, nbins?

  // Loop over detectors
  for (int iSubDet=1; iSubDet<=6; ++iSubDet) {

    // TEC requires special care since rings 1-4 and 5-7 are plotted separately
    bool isTEC = (iSubDet==6);

    // if subdet is specified, skip other subdets
    if (plotSubDetN!=0 && iSubDet!=plotSubDetN)
      continue;

    // Skips plotting too high layers
    if (plotLayerN > numberOfLayers[iSubDet-1]) {
      continue;
    }

    int minlayer = plotLayers ? 1 : plotLayerN;
    int maxlayer = plotLayers ? numberOfLayers[iSubDet-1] : plotLayerN;
    
    for (int layer = minlayer; layer <= maxlayer; layer++) {

      // two plots for TEC, skip first 
      for (int iTEC = 0; iTEC<2; iTEC++) {
	if (!isTEC && iTEC==0) continue;
	
	char  selection[1000];
	if (!isTEC){
	  if (layer==0)
	    sprintf(selection,"subDetId==%d",iSubDet); 
	  else
	    sprintf(selection,"subDetId==%d && layer == %d",iSubDet,layer); 
	}
	else{	  // TEC
	  if (iTEC==0)  // rings 
	    sprintf(selection,"subDetId==%d && ring <= 4",iSubDet); 
	  else
	    sprintf(selection,"subDetId==%d && ring > 4",iSubDet); 
	}


	// Title for plot and name for the file

	TString subDetName;
	switch (iSubDet) {
	case 1: subDetName = "BPIX"; break;
	case 2: subDetName = "FPIX"; break;
	case 3: subDetName = "TIB"; break;
	case 4: subDetName = "TID"; break;
	case 5: subDetName = "TOB"; break;
	case 6: subDetName = "TEC"; break;
	}

	TString myTitle = "Surface Shape, ";
	myTitle += subDetName;
	if (layer!=0) {
	  myTitle += TString(", layer ");
	  myTitle += Form("%d",layer); 
	}
	if (isTEC && iTEC==0)
	  myTitle += TString(" R1-4");
	if (isTEC && iTEC>0)
	  myTitle += TString(" R5-7");

	// Save plot to file
	std::ostringstream plotName;
	plotName << outputDir << "/SurfaceShape_" << subDetName << "_";
	plotName << residType; 
	if (layer!=0)
	  plotName << "_" << "layer" << layer;
	if (isTEC && iTEC==0)
	  plotName << "_" << "R1-4";
	if (isTEC && iTEC>0)
	  plotName << "_" << "R5-7";
	plotName << ".eps";

	// Generate histograms with selection
	THStack *hs = addHists(selection, residType);
	if (!hs || hs->GetHists()==0 || hs->GetHists()->GetSize()==0) {
	  std::cout << "No histogram for " << subDetName << ", perhaps not enough data?" << std::endl; 
	  continue; 
	}
	hs->SetTitle( myTitle ); 
	hs->Draw("nostack PE");  

	// Adjust Labels
	TH1* firstHisto = (TH1*) hs->GetHists()->First();
	TString xName = firstHisto->GetXaxis()->GetTitle();
	TString yName = firstHisto->GetYaxis()->GetTitle();
	hs->GetHistogram()->GetXaxis()->SetTitleColor( kBlack ); 
	hs->GetHistogram()->GetXaxis()->SetTitle( xName ); 
	hs->GetHistogram()->GetYaxis()->SetTitleColor( kBlack ); 
	hs->GetHistogram()->GetYaxis()->SetTitle( yName ); 

	// Save to file
	c.Update(); 
	c.Print(plotName.str().c_str());
      }
    }
  }

  return;
}
//------------------------------------------------------------------------------
void PlotAlignmentValidation::plotOutlierModules(const char *outputFileName, std::string plotVariable,
						 float plotVariable_cut ,int unsigned minHits)
{
 
  Int_t counter=0;
  setNiceStyle();
  
  gStyle->SetOptStat(111111);
  gStyle->SetStatY(0.9);
  //TList treelist=getTreeList();
  
  TCanvas *c1 = new TCanvas("canv", "canv", 800, 500);
  //setCanvasStyle( *c1 );
  outputFile = outputDir +'/'+ outputFileName;   
  c1->Print( (outputFile+'[').Data() ); 
  
  
  c1->Divide(2,1);
  
  TTree *tree= (*sourceList.begin())->getTree();
  TkOffTreeVariables *treeMem = 0; // ROOT will initilise
  tree->SetBranchAddress("TkOffTreeVariables", &treeMem);
  
  
  Long64_t nentries =  tree->GetEntriesFast();
  
  for (Long64_t i = 0; i < nentries; i++){
    
    tree->GetEntry(i);
    float var = 0;
    if (plotVariable == "chi2PerDofX") var =treeMem->chi2PerDofX;
    else if(plotVariable == "chi2PerDofY") var =treeMem->chi2PerDofY;
    else if(plotVariable == "fitMeanX") var =treeMem->fitMeanX;
    else if(plotVariable == "fitMeanY") var =treeMem->fitMeanY;
    else if(plotVariable == "fitSigmaX") var =treeMem->fitSigmaX;
    else if(plotVariable == "fitSigmaY") var =treeMem->fitSigmaY;
    else {
      cout<<"There is no variable "<<plotVariable<<" included in the tree."<<endl;
      break;
    }
//   cout<<"treeMem->entries  "<<treeMem->entries<<endl;  
//  cout<<"var                  "<<var<<endl;
//  cout<<"plotVariable_cut     "<<plotVariable_cut<<endl;
    
    if (var > plotVariable_cut && treeMem->entries > minHits)
      {
	
	TFile *f=(*sourceList.begin())->getFile();//(TFile*)sourcelist->First();
	
	if(f->FindKeyAny(treeMem->histNameX.c_str())!=0){
	  TH1 *h = (TH1*) f->FindKeyAny(treeMem->histNameX.c_str())->ReadObj();//f->FindObjectAny(treeMem->histNameX.c_str());
	  gStyle->SetOptFit(0111);
	  cout<<"hist name "<<h->GetName()<<endl;
	  
	  TString path =(char*)strstr( gDirectory->GetPath(), "TrackerOfflineValidation" );
	  //cout<<"hist path "<<path<<endl;
	  //cout<<"wrote text "<<endl;
	  if(h) cout<<h->GetEntries()<<endl;
	  
	  //modules' location as title
	  c1->cd(0);
	  TPaveText * text=new TPaveText(0,0.95,0.99,0.99);
	  text->AddText(path);
	  text->SetFillColor(0);
	  text->SetShadowColor(0);
	  text->SetBorderSize( 0 );
	  text->Draw();
	  
	  //residual histogram
	  c1->cd(1);
	  TPad *subpad = (TPad*)c1->GetPad(1);
	  subpad->SetPad(0,0,0.5,0.94);
	  h->Draw();
	  
	  //norm. residual histogram
	  h = (TH1*) f->FindObjectAny(treeMem->histNameNormX.c_str());
	  if(h) cout<<h->GetEntries()<<endl;
	  c1->cd(2);
	  TPad *subpad2 = (TPad*)c1->GetPad(2);
	  subpad2->SetPad(0.5,0,0.99,0.94);
	  h->Draw();
	  
	  c1->Print(outputFile);
	  counter++;
	}
	else{
	  cout<<"There are no residual histograms on module level stored!"<<endl;
	  cout<<"Please make sure that moduleLevelHistsTransient = cms.bool(False) in the validation job!"<<endl;
	  break;
	}
      }
    
  }
  c1->Print( (outputFile+"]").Data() );
  if (counter == 0) cout<<"no bad modules found"<<endl;
  
  
  //read the number of entries in the t3
  //TTree* tree=0;
  //tree=(TTree*)treeList->At(0);
  
  
  //c1->Close();
  
}
void patBJetVertex_efficiencies()
{
	// define proper canvas style
	setNiceStyle();
	gStyle->SetOptStat(0);

	// open file
	TFile* file = new TFile("analyzePatBJetVertex.root");

	unsigned int j = 0;
	for(const char **algo = algos; *algo; algo++, j++) {
		TLegend *legend[3] = { 0, 0, 0 };

		// draw canvas with efficiencies
		TCanvas *canv;
		canv = new TCanvas(*algo, Form("%s efficiencies", algoNames[j]), 800, 300);
		canv->Divide(3, 1);

		TH1 *total = (TH1*)file->Get(Form("%s/flavours", directory));
		TH1 *effVsCutB = 0;
		unsigned int i = 0;
		for(const char **flavour = flavours; *flavour; flavour++, i++) {
			TH1 *h = (TH1*)file->Get(Form("%s/%s_%s", directory, *algo, *flavour));
			TH1 *discrShape = (TH1*)h->Clone(Form("%s_discrShape", h->GetName()));
			discrShape->Scale(1.0 / discrShape->Integral());
			discrShape->SetMaximum(discrShape->GetMaximum() * 5);
			TH1 *effVsCut = computeEffVsCut(h, total->GetBinContent(4 - i));
			TH1 *effVsBEff = 0;

			if (flavour == flavours)	// b-jets
				effVsCutB = effVsCut;
			else
				effVsBEff = computeEffVsBEff(effVsCut, effVsCutB);

			discrShape->SetTitle("discriminator shape");
			effVsCut->SetTitle("efficiency versus discriminator cut");
			if (effVsBEff)
				effVsBEff->SetTitle("mistag versus b efficiency");

			setHistStyle(discrShape);
			setHistStyle(effVsCut);
			setHistStyle(effVsBEff);

			canv->cd(1);
			gPad->SetLogy(1);
			gPad->SetGridy(1);
			discrShape->SetLineColor(i + 1);
			discrShape->SetMarkerColor(i + 1);
			discrShape->Draw(i > 0 ? "same" : "");
			if (!legend[0])
				legend[0] = new TLegend(0.5, 0.7, 0.78, 0.88);
			legend[0]->AddEntry(discrShape, *flavour);

			canv->cd(2);
			gPad->SetLogy(1);
			gPad->SetGridy(1);
			effVsCut->SetLineColor(i + 1);
			effVsCut->SetMarkerColor(i + 1);
			effVsCut->Draw(i > 0 ? "same" : "");
			if (!legend[1])
				legend[1] = new TLegend(0.3, 0.4, 0.58, 0.58);
			legend[1]->AddEntry(effVsCut, *flavour);

			if (!effVsBEff)
				continue;
			canv->cd(3);
			gPad->SetLogy(1);
			gPad->SetGridx(1);
			gPad->SetGridy(1);
			effVsBEff->SetLineColor(i + 1);
			effVsBEff->SetMarkerColor(i + 1);
			effVsBEff->Draw(i > 1 ? "same" : "");
			if (!legend[2])
				legend[2] = new TLegend(0.12, 0.7, 0.40, 0.88);
			legend[2]->AddEntry(effVsBEff, *flavour);
		}

		canv->cd(1);
		legend[0]->Draw();

		canv->cd(2);
		legend[1]->Draw();

		canv->cd(3);
		legend[2]->Draw();
	}
}
void  PlotAlignmentValidation::plotDMR(const std::string variable, Int_t minHits )
{
 setNiceStyle(); 
 gStyle->SetOptStat(0);

 // TList treeList=getTreeList();

 TCanvas *c = new TCanvas("canv", "canv", 600, 600);
 setCanvasStyle( *c );
 //loop over sub-detectors 
 for (int i=1;i<7;++i){
 
   int histo_Counter=1;
   TLegend *leg_hist = new TLegend(0.17,0.8,0.85,0.88);
   setLegendStyle(*leg_hist);
   //loop over file list
   //TTree *tree= (TTree*)treeList.First();
   //binning
   int nbinsX=100;
   double xmin=0;
   double xmax=0;
   float maxY=0;
   bool isHisto = false;
   std::string plotVar=variable;
   THStack *hstack=new THStack("hstack","hstack");

   for(std::vector<TkOfflineVariables*>::iterator it = sourceList.begin();
       it != sourceList.end(); ++it){
      
     //while ( tree ){
     plotVar=variable;
     TString subdet = "entries>=";
     subdet+=minHits; 
     subdet+=" && subDetId==";
     subdet+=i;
      
     char binning [50]="";
     sprintf (binning, ">>myhisto(%d,  %f , %f)", nbinsX, xmin, xmax);
     TH1F *h = 0;
     
     if (histo_Counter==1&&plotVar=="meanX")(*it)->getTree()->Draw( (plotVar+=">>myhisto(50,-0.005,0.005)").c_str(),subdet,"goff");
     else if (histo_Counter==1&&plotVar=="meanY")(*it)->getTree()->Draw( (plotVar+=">>myhisto(50,-0.005,0.005)").c_str(),subdet,"goff");
     else if (histo_Counter==1&&plotVar=="medianX")(*it)->getTree()->Draw( (plotVar+=">>myhisto(50,-0.005,0.005)").c_str(),subdet,"goff");
     else if (histo_Counter==1&&plotVar=="meanNormX")(*it)->getTree()->Draw( (plotVar+=">>myhisto(100,-2,2)").c_str(),subdet,"goff");
     else if (histo_Counter==1&&plotVar=="rmsX")(*it)->getTree()->Draw( (plotVar+=">>myhisto(100,0.,0.1)").c_str(),subdet,"goff");
     else if (histo_Counter!=1)(*it)->getTree()->Draw( (plotVar+=binning).c_str(),subdet,"goff");

     if (gDirectory) gDirectory->GetObject("myhisto", h);
     std::pair<float,float> fitResults(9999., 9999.);
     if (h){
       if (h->GetEntries()>0) {
	 isHisto = true;
	 h->SetDirectory(0);
	 //general draw options
	 h->SetLineWidth(2);
	 //first histo only, setting optStat...
	 if (histo_Counter==1)
	   setHistStyle(*h,plotVar.c_str() ,"#modules", 1 ); //set color later

	 h->SetLineColor( (*it)->getLineColor() );
	 h->SetLineStyle( (*it)->getLineStyle() );
	   //h->SetMarkerStyle(20+file_Counter);
      
	 //draw options
	 
	 if (maxY<h->GetMaximum()){
	   maxY=h->GetMaximum();
	 }
      
	 //fit histogram for median and mean
	 if (variable=="medianX"||variable =="meanX")fitResults=fitGauss(h, (*it)->getLineColor() );

	 if (histo_Counter==1){
	   //get mean and sigma from fit: gauss for 2sigma range
	   hstack->Add(h);
	   nbinsX=h->GetXaxis()->GetNbins();
	   xmin=h->GetXaxis()->GetXmin();
	   xmax=h->GetXaxis()->GetXmax();
	  
	 }else if (histo_Counter!=1 &&  h->GetEntries()>0)hstack->Add(h);
     
	 char legend [50]="";
	 std::string legEntry = (*it)->getName();
	 if (variable=="medianX"||variable =="meanX")sprintf (legend, "%s: #mu = %4.2f#mum, #sigma = %4.2f#mum ",legEntry.c_str(),fitResults.first ,fitResults.second);
	 else sprintf (legend, "%s ",legEntry.c_str());
	 if(h)
	   leg_hist->AddEntry(h,legend,"l");
	 else
	   std::cerr<< "histogram did not exist!";
       }
     }
     //     tree= (TTree*)treeList.After( tree );
     //     file_Counter++;
     histo_Counter++;
        
   }
    
   if (isHisto){
     hstack->Draw("nostack");
     hstack->SetMaximum(maxY*1.3);
     setTitleStyle(*hstack,plotVar.c_str() ,"#modules",i);
     setHistStyle(*hstack->GetHistogram(),plotVar.c_str() ,"#modules", 1 );
     leg_hist->Draw(); 

     std::string histName="D";
     if (variable=="medianX") histName+="medianR_";
     else if (variable=="meanX") histName+="meanR_";
     else if (variable=="meanY") histName+="meanYR_";
     else if (variable=="rmsX") histName+="rmsR_";
     std::string subDetector ="";
     switch (i){
     case 1 : subDetector+="TPB";break;
     case 2 : subDetector+="TPE";break;
     case 3 : subDetector+="TIB";break;
     case 4 : subDetector+="TID";break;
     case 5 : subDetector+="TOB";break;
     case 6 : subDetector+="TEC";break;
     }
 
     char PlotName[100];
     sprintf( PlotName, "%s/%s%s.eps",outputDir.c_str(), histName.c_str(), subDetector.c_str() );
     c->Update(); 
     c->Print(PlotName);
     //c->Update();
     //c->Close();
    
   }
   delete hstack;
   hstack=0; 
  
 }
 
 delete c;
 c=0;
}