Beispiel #1
0
void danss_calc_ratio(void)
{
#ifdef STRONG_CUTS
	const char fname[] = "danss_report_strong.root";
	const char pname[] = "danss_ratio_strong.pdf";
#else
	const char fname[] = "danss_report.root";
	const char pname[] = "danss_ratio.pdf";
#endif
	const struct {
		char name[32];
		int first;
		int last;
	} positions[] = {
		{ "down_21.04.16",   2307, 2361},	// [0] - 0-
		{ "up_22.04.16",     2366, 2387},	// [1] - 0+
		{ "down_23.04.16",   2399, 2445},	// [2] - 0-
		{ "mid_24.04.16",    2449, 2512},
		{ "up_25.04.16",     2514, 2562},	// [4] - 1+
		{ "down_26.04.16",   2564, 2609},	// [5] - 1-
		{ "mid_27.04.16",    2620, 2685},
		{ "up_28.04.16",     2687, 2730},	// [7] - 2+
		{ "down_29.04.16",   2733, 2788},	// [8] - 2-
		{ "mid_30.04.16",    2791, 2832},
		{ "stuck_01.05.16",  2836, 3399},
		{ "stuck_10.05.16",  3400, 3788},
		{ "up_03.06.16",     4261, 4400},	// [12] - 3+
		{ "down_06.06.16",   4403, 4439},	// [13] - 3-
		{ "up_08.06.16",     4508, 4601},	// [14] - 3+
		{ "raised_30.09.16", 5540, 5807},
		{ "raised_04.10.16", 5808, 5903},	// veto corners on
		{ "mid_05.10.16",    5907, 5995},	// [17]
		{ "up_10.10.16",     6007, 6130},	// [18] - 5+
//		{ "mid_12.10.16",    6136, 6275},
//		{ "down_14.10.16",   6278, 6467},
//		{ "up_17.10.16",     6469, 6570},
//		{ "mid_21.10.16",    6573, 6582},
//		{ "down_21.10.16",   6587, 6745},
//		{ "up_24.10.16",     6757, 6815},
//		{ "mid_27.10.16",    6842, 6923},
//		{ "down_28.10.16",   6926, 7095},
		{ "up_31.10.16",     7106, 7364},	// [19] - 5+
		{ "mid_11.11.16",    7387, 7406},	// [20]
		{ "down_11.11.16",   7418, 7458},	// [21] - 5-
		{ "up_14.11.16",     7478, 7579},	// [22] - 6+
//		{ "mid_16.11.16",    7581, 7717},
		{ "down_18.11.16",   7727, 7913},	// [23] - 6-
		{ "up_21.11.16",     7922, 8042},	// [24] - 7+
		{ "mid_23.11.16",    8048, 8179},	// [25]
		{ "down_25.11.16",   8185, 8353},	// [26] - 7-
		{ "up_28.11.16",     8357, 8430},	// [27] - 8+
		{ "mid_01.12.16",    8470, 8571},	// [28]
		{ "down_02.12.16",   8574, 8738},	// [29] - 8-
		{ "up_05.12.16",     8741, 8869},	// [30] - 8+
		{ "mid_07.12.16",    8873, 9009},	// [31]
		{ "up_12.12.16",     9012, 9112},	// [32] - 9+
		{ "mid_14.12.16",    9116, 9245},	// [33]
		{ "down_16.12.16",   9253, 9470},	// [34] - 9-
//		{ "up_19.12.16",     9475, 9600},
//		{ "mid_21.12.16",    9603, 9712},
//		{ "down_23.12.16",   9715, 9869},
//		{ "up_26.12.16",     9871, 10019}
//		{ "mid_28.12.16",    10021, 10171},
//		{ "down_30.12.16",   10175, 10307},
//		{ "down_02.01.17",   10308, 10356},
//		{ "down_03.01.17",   10357, 10424},
		{ "up_04.01.17",     10433, 10832},	// [35] - 10+
		{ "mid_11.01.17",    10834, 10973},	// [36]
		{ "down_13.01.17",   10979, 11147},	// [37] - 10-
		{ "up_16.01.17",     11150, 11267},	// [38] - 11+
		{ "mid_18.01.17",    11271, 11401},	// [39]
		{ "down_20.01.17",   11404, 11563},	// [40] - 11-
		{ "up_23.01.17",     11570, 11619}	// [41] - 11+
	};
	int i, j;
	int N;
	TCanvas *cv;
	TFile *f;
	TH1 *h[sizeof(positions) / sizeof(positions[0])];
	TH1 *hSum[12];
	TH1 *hRatio[7];
	TH1 *hTmp[3];
	char str[1024];
	TLatex *txt;
	double val, err;
	TVirtualPad *pd;
	const char periods[3][30] = {"April-June", "October-November", "December-January"};
	
	gStyle->SetOptStat(0);
	gStyle->SetOptFit(1);
	N = sizeof(positions) / sizeof(positions[0]);
	cv = new TCanvas("CV", "Results", 2400, 1200);
	f = new TFile(fname, "UPDATE");
	if (!f->IsOpen()) return;
	sprintf(str, "%s[", pname);
	cv->Print(str);
	txt = new TLatex();
	
	for (i=0; i<N; i++) {
		sprintf(str, "%s_hRes", positions[i].name);
		h[i] = (TH1 *) f->Get(str);
		if (!h[i]) {
			printf("%s not found in %s\n", positions[i].name, fname);
			return;
		}
		h[i]->SetBit(TH1::kIsAverage);
	}
	
	hSum[0] = (TH1 *) h[0]->Clone("hUp");
	hSum[1] = (TH1 *) h[0]->Clone("hDown");
	hSum[2] = (TH1 *) h[0]->Clone("hMid");
	hSum[3] = (TH1 *) h[0]->Clone("hSum");
	hSum[4] = (TH1 *) h[0]->Clone("hSum_first");
	hSum[5] = (TH1 *) h[0]->Clone("hSum_last");
	hSum[6] = (TH1 *) h[0]->Clone("hUpAprilJune");
	hSum[7] = (TH1 *) h[0]->Clone("hDownAprilJune");
	hSum[8] = (TH1 *) h[0]->Clone("hUpOctoberNovember");
	hSum[9] = (TH1 *) h[0]->Clone("hDownOctoberNovember");
	hSum[10] = (TH1 *) h[0]->Clone("hUpDecemberJanuary");
	hSum[11] = (TH1 *) h[0]->Clone("hDownDecemberJanuary");
	hRatio[0] = (TH1 *) h[0]->Clone("hRatio");
	hRatio[1] = (TH1 *) h[0]->Clone("hMix");
	hRatio[2] = (TH1 *) h[0]->Clone("hRatio2");
	hRatio[3] = (TH1 *) h[0]->Clone("hRatioMidUp");
	hRatio[4] = (TH1 *) h[0]->Clone("hRatioAprilJune");
	hRatio[5] = (TH1 *) h[0]->Clone("hRatioOctoberNovember");
	hRatio[6] = (TH1 *) h[0]->Clone("hRatioDecemberJanuary");
	hTmp[0] = (TH1 *) h[0]->Clone("hTmpUp");
	hTmp[1] = (TH1 *) h[0]->Clone("hTmpDown");
	hTmp[2] = (TH1 *) h[0]->Clone("hTmpRatio");
	for (i=0; i<12; i++) hSum[i]->Reset();
	for (i=0; i<12; i++) hSum[i]->SetLineWidth(2);
	
	for (i=0; i<N; i++) {
		switch (positions[i].name[0]) {
			case 'u' : j = 0; break;
			case 'd' : j = 1; break;
			case 'm' : j = 2; break;
			default : j = -1; break;
		}
		if (j >= 0) hSum[j]->Add(h[i]);
		hSum[(i < N/2) ? 4 : 5]->Add(h[i]);
		hSum[3]->Add(h[i]);
	}
//	for (i=0; i<3; i++) hSum[3]->Add(hSum[i]);
	hRatio[0]->Divide(hSum[1], hSum[0]);
	hRatio[1]->Divide(hSum[5], hSum[4]);
	hRatio[3]->Divide(hSum[2], hSum[0]);
//	Ratio from short ratios
	hRatio[2]->Reset();
	hRatio[2]->SetBit(TH1::kIsAverage);
//	0+2 / 1
	hTmp[0]->Add(h[0], h[2]);
	hTmp[2]->Divide(hTmp[0], h[1]);
	hRatio[2]->Add(hTmp[2]);
//	5 / 4
	hTmp[2]->Divide(h[5], h[4]);
	hRatio[2]->Add(hTmp[2]);
//	8 / 7
	hTmp[2]->Divide(h[8], h[7]);
	hRatio[2]->Add(hTmp[2]);
//	13 / 12 + 14
	hTmp[0]->Add(h[12], h[14]);
	hTmp[2]->Divide(h[13], hTmp[0]);
	hRatio[2]->Add(hTmp[2]);
//	21 / 18+19
	hTmp[0]->Add(h[18], h[19]);
	hTmp[2]->Divide(h[21], hTmp[0]);
	hRatio[2]->Add(hTmp[2]);
//	23 / 22
	hTmp[2]->Divide(h[23], h[22]);
	hRatio[2]->Add(hTmp[2]);
//	26 / 24
	hTmp[2]->Divide(h[26], h[24]);
	hRatio[2]->Add(hTmp[2]);
//	29 / 27 + 30
	hTmp[0]->Add(h[27], h[30]);
	hTmp[2]->Divide(h[29], hTmp[0]);
	hRatio[2]->Add(hTmp[2]);
//	34 / 32
	hTmp[2]->Divide(h[34], h[32]);
	hRatio[2]->Add(hTmp[2]);
//	37 / 35
	hTmp[2]->Divide(h[37], h[35]);
	hRatio[2]->Add(hTmp[2]);
//	40 / 38 + 41
	hTmp[0]->Add(h[38], h[41]);
	hTmp[2]->Divide(h[40], hTmp[0]);
	hRatio[2]->Add(hTmp[2]);
//	AprilJune (0 + 2 + 5 + 8 + 13) / (1 + 4 + 7 + 12 + 14)
	hSum[6]->Add(h[1]);
	hSum[6]->Add(h[4]);
	hSum[6]->Add(h[7]);
	hSum[6]->Add(h[12]);
	hSum[6]->Add(h[14]);
	hSum[7]->Add(h[0]);
	hSum[7]->Add(h[2]);
	hSum[7]->Add(h[5]);
	hSum[7]->Add(h[8]);
	hSum[7]->Add(h[13]);
	hRatio[4]->Divide(hSum[7], hSum[6]);
//	OctoberNovember (21 + 23 + 26 + 29) / (18 + 19 + 22 + 24 + 27 + 30)
	hSum[8]->Add(h[18]);
	hSum[8]->Add(h[19]);
	hSum[8]->Add(h[22]);
	hSum[8]->Add(h[24]);
	hSum[8]->Add(h[27]);
	hSum[8]->Add(h[30]);
	hSum[9]->Add(h[21]);
	hSum[9]->Add(h[23]);
	hSum[9]->Add(h[26]);
	hSum[9]->Add(h[29]);
	hRatio[5]->Divide(hSum[9], hSum[8]);
//	DecemberJanuary (34 + 37 + 40) / (32 + 35 + 38 + 41)
	hSum[10]->Add(h[32]);
	hSum[10]->Add(h[35]);
	hSum[10]->Add(h[38]);
	hSum[10]->Add(h[41]);
	hSum[11]->Add(h[34]);
	hSum[11]->Add(h[37]);
	hSum[11]->Add(h[40]);
	hRatio[6]->Divide(hSum[11], hSum[10]);
	cv->Divide(2, 1);

	pd = cv->cd(1);
	pd->Divide(1, 2);
	pd->cd(1);
	hSum[0]->SetTitle("Up - Middle - Down;MeV;mHz");
	hSum[0]->SetLineColor(kRed);
	hSum[2]->SetLineColor(kGreen);
	hSum[1]->SetLineColor(kBlue);
	for (i=0; i<4; i++) hSum[i]->SetLineWidth(2);
	hSum[0]->Draw();
	hSum[2]->Draw("same");
	hSum[1]->Draw("same");
	val = hSum[0]->IntegralAndError(1, 35, err);
	sprintf(str, "Up = %5.2f+-%4.2f", val, err);
	txt->SetTextColor(kRed);
	txt->DrawTextNDC(0.4, 0.85, str);
	val = hSum[2]->IntegralAndError(1, 35, err);
	sprintf(str, "Mid = %5.2f+-%4.2f", val, err);
	txt->SetTextColor(kGreen);
	txt->DrawTextNDC(0.4, 0.8, str);
	val = hSum[1]->IntegralAndError(1, 35, err);
	sprintf(str, "Down = %5.2f+-%4.2f", val, err);
	txt->SetTextColor(kBlue);
	txt->DrawTextNDC(0.4, 0.75, str);
	
	pd->cd(2);
	hSum[3]->SetTitle("Average of all positions;MeV;mHz");
	hSum[3]->SetLineColor(kBlack);
	hSum[3]->Draw();
	val = hSum[3]->IntegralAndError(1, 35, err);
	sprintf(str, "Avr = %5.2f+-%4.2f", val, err);
	txt->SetTextColor(kBlack);
	txt->DrawTextNDC(0.4, 0.8, str);

	pd = cv->cd(2);
	pd->Divide(1, 4);
	pd->cd(1);
	hRatio[0]->SetTitle("Down/Up all by all;MeV;");
	hRatio[0]->SetLineColor(kBlack);
	hRatio[0]->SetLineWidth(2);
	hRatio[0]->SetMinimum(0.5);
	hRatio[0]->SetMaximum(1.0);
	hRatio[0]->Fit("pol0", "", "", 1, 7);
	
	pd->cd(2);
	hRatio[2]->SetTitle("Down/Up pair by pair;MeV;");
	hRatio[2]->SetLineColor(kBlack);
	hRatio[2]->SetLineWidth(2);
	hRatio[2]->SetMinimum(0.5);
	hRatio[2]->SetMaximum(1.0);
	hRatio[2]->Fit("pol0", "", "", 1, 7);

	pd->cd(3);
	hRatio[3]->SetTitle("Mid/Up all by all;MeV;");
	hRatio[3]->SetLineColor(kBlack);
	hRatio[3]->SetLineWidth(2);
	hRatio[3]->SetMinimum(0.65);
	hRatio[3]->SetMaximum(1.15);
	hRatio[3]->Fit("pol0", "", "", 1, 7);

	pd->cd(4);
	hRatio[1]->SetTitle("First half/Last half;MeV;");
	hRatio[1]->SetLineColor(kBlack);
	hRatio[1]->SetLineWidth(2);
	hRatio[1]->SetMinimum(0.75);
	hRatio[1]->SetMaximum(1.25);
	hRatio[1]->Fit("pol0", "", "", 1, 7);

	cv->Update();
	cv->Print(pname);

	cv->Clear();
	cv->Divide(2, 2);
	for (i=0; i<3; i++) {
		cv->cd(i+1);
		sprintf(str, "Down/Up all by all for %s;MeV;", periods[i]);
		hRatio[4+i]->SetTitle(str);
		hRatio[4+i]->SetLineColor(kBlack);
		hRatio[4+i]->SetLineWidth(2);
		hRatio[4+i]->SetMinimum(0.5);
		hRatio[4+i]->SetMaximum(1.0);
		hRatio[4+i]->Fit("pol0", "", "", 1, 7);
	}
	cv->Update();
	cv->Print(pname);

	sprintf(str, "%s]", pname);
	cv->Print(str);
	for (i=0; i<12; i++) hSum[i]->Write();
	for (i=0; i<7; i++) hRatio[i]->Write();
	f->Close();
	delete cv;
}
void PlotPubHisto(TObjArray histograms,TEnv *params){
    // This is a modification of the AddHistos macro
    
    // Number of histos to plot:
    Int_t ntot = histograms.GetEntries();
    
    // Check we have what we expect (the order should be: data, qcd, wjets, etc...)
    for(Int_t i = 0; i<ntot; i++){
	if(histograms[i]==0) {
	    cout<<"Error in AddHistos: histogram "<<i<<" is a NULL pointer!"<<endl;
	    return;
	}
	TH1F * hthis = (TH1F*) histograms[i];
	// include the overflow/underflow bins:
	int numbins = hthis->GetNbinsX(); //this is the last bin plotted
	double hicontent = hthis->GetBinContent(numbins);
	double overflow  = hthis->GetBinContent(numbins+1);// this bin contains the overflow
	double locontent = hthis->GetBinContent(1);// this is the first bin plotted
	double underflow = hthis->GetBinContent(0);// this bin contains the underflow
	if (underflow>0 || overflow>0){
	    //printf("%-20s numbins=%4i hicontent=%4.2f over=%4.2f locontent=%4.2f underflow=%4.2f \n",
	    //	 title.Data(),numbins,hicontent,overflow,locontent,underflow);
	}
	hthis->SetBinContent(numbins,hicontent+overflow);
	hthis->SetBinContent(1,locontent+underflow);
    }
    
    // define a few additional line styles:
    gStyle->SetLineStyleString(5,"20 12 4 12");
    gStyle->SetLineStyleString(6,"20 12 4 12 4 12 4 12");
    gStyle->SetLineStyleString(7,"20 20");
    gStyle->SetLineStyleString(8,"20 12 4 12 4 12");
    gStyle->SetLineStyleString(9,"80 25");
    gStyle->SetLineStyleString(10,"50 10 10 10");
    gStyle->SetLineStyleString(17,"30 25");
    gStyle->SetLineStyleString(20,"60 20");
    gStyle->SetLineStyleString(21,"60 20 20 20");
    int lineStyle[20];
    for(int i=0;i<20;i++) {
	lineStyle[i]=i;
    }

    // the first histogram in the list:
    TH1F *h0=((TH1F*) histograms[0])->Clone();
    
    // histogram output filename
    TString oFileName=params->GetValue("Histo.Output.Filename","bogus.eps");
    
    // figure out the number of signals
    Int_t nsig=1;
    if(params->Defined("Histo.Signal.Title.1")) nsig=1;
    if(params->Defined("Histo.Signal.Title.2")) nsig=2;
    if(params->Defined("Histo.Signal.Title.3")) nsig=3;
    
    cout << " I will use nsig = " << nsig << " signal sources" << endl;
    
    // Do the cumulative summing, except for the data
    TObjArray addedhistos; addedhistos.Clear();
    TObjArray signalhistos; signalhistos.Clear();
    TString sampletitles[20];
    Int_t nbkg=0;
    for(Int_t i = 1; i<ntot; i++){// i runs over histograms[i], so data is for i=0
	ostringstream baseSrcName;
	baseSrcName << "Files." << i+1 << ".";// Counting starts at 1: Files.1.Name: Data
	TString bSrcName(baseSrcName.str().c_str());
	// skip some if we want to show them as lines
	TString htitle=params->GetValue(bSrcName+"Title","");
	sampletitles[i-1]=htitle;
	if(params->GetValue("Histo.ShowSignalSeparately",0)==1 &&
	   // skip the last two if the signal title is not defined:
	   ( ( !(params->Defined("Histo.Signal.Title")||params->Defined("Histo.Signal.Title.1")) && i>=ntot-nsig) 
	     // skip the signal if the signal title is defined
	     || params->GetValue("Histo.Signal.Title",".")==htitle
	     || params->GetValue("Histo.Signal.Title.1",".")==htitle
	     || params->GetValue("Histo.Signal.Title.2",".")==htitle
	     || params->GetValue("Histo.Signal.Title.3",".")==htitle
	     ) ) {
	    TH1F * hthis = (TH1F*) histograms[i]->Clone();
	    cout<<" Found signal in location "<<i+1<<" with name "<<htitle.Data()<<endl;
	    signalhistos.Add(hthis);
	} else {
	    TH1F * hthis = (TH1F*) histograms[i]->Clone();
	    addedhistos.Add(hthis); // Fill in the new TObjArray with a copy 
	    //cout << " Adding bkg " << i << " " << htitle.Data() << " " << hthis->Integral() << endl;
	    // add all of the backgrounds
	    if (i>1) {// i=0 is the data, and we must start with the second
		      // background to add the previous
		TH1F * hprevious = (TH1F*) addedhistos[i-2];
		if ( hthis->GetXaxis()->GetNbins() != hprevious->GetXaxis()->GetNbins() ) {
		    // Protection against _whoran histogram. 
		    // We cannot add two histograms with different numbers of bins!
		    cout<<"Error in AddHistos: incompatible number of bins!"<<endl;  
		    return;
		}
		hthis->Add(hprevious); // Do the addition
		addedhistos.RemoveAt(i-1); // And substitute whatever we had 
		addedhistos.AddAt(hthis,i-1);
		nbkg++;
		//cout << "Substituing bkg " << i << " + " << i-1 << " in addedhistos["<< i-1 <<"]" << endl;
	    }	    
	} // end of: if adding histograms
    }
    cout << " nbkg = " << nbkg << endl; 
    
    // Rebin histos if necessary, but first calculate KS:
    TH1F *hbkg = (TH1F*) addedhistos[nbkg];
    double KS = h0->KolmogorovTest(hbkg);
    double chi2ndf = h0->Chi2Test(hbkg, "UWUFOFCHI2/NDF");
    //cout << title.Data() << " KS = " << KS << " chi2/NDF = " << chi2ndf << endl;
    // Rebin? Set nrebin = 0 to NOT do rebinning. 
    // Will rebin only histos whose maximum x axis value exceeds 20. 
    // Anything with less will most probably be already made of integers, so no
    // need to rebin that! 
    Int_t nbinsx = h0->GetXaxis()->GetNbins();
    Int_t nbinsy = 100;
    Int_t nrebin = 5;
    if ( nbinsx > 750 && nbinsx <= 1000) nrebin = 30;
    if ( nbinsx > 400 && nbinsx <= 750 ) nrebin = 25;//20
    if ( nbinsx > 300 && nbinsx <= 400 ) nrebin = 25;//15
    if ( nbinsx > 200 && nbinsx <= 300 ) nrebin = 25;//15
    if ( nbinsx > 150 && nbinsx <= 200 ) nrebin = 10;//10
    if ( nbinsx > 100 && nbinsx <= 150 ) nrebin = 10;//10
    if ( nbinsx > 50 && nbinsx <= 100 )  nrebin = 10;//10
    if ( nbinsx > 20 && nbinsx <= 50 )   nrebin = 2;
    if ( nbinsx <= 20 ) nrebin = 1;  
    
    printf(" Saw nbins =%4i, rebinning by nrebin =%2i to final %3i bins \n",nbinsx,nrebin,int(nbinsx/nrebin));	

    if ( nrebin != 0 ) {
	h0->Rebin(nrebin); // data
	for (Int_t i = 0; i<=nbkg; i++){
	    TH1F * h = (TH1F*) addedhistos[i];
	    h->Rebin(nrebin);
	}
	for (Int_t i = 0; i<nsig; i++){
	    TH1F * h = (TH1F*) signalhistos[i];
	    h->Rebin(nrebin);
	}
    }

    // default text size: 0.045
    // make it bigger for the paper
    float textSize = 0.045;
    if(params->GetValue("Histo.Preliminary","yes")==TString("paper")) textSize=0.07;
    if(params->Defined("Histo.TextSize")) textSize=params->GetValue("Histo.TextSize",0.07);
    
    // Now, check largest dimensions so that we can plot all histograms at once.
    Float_t xmin=9999., xmax=-9999., ymin=9999., ymax=-9999.;
    for(Int_t i = 0; i<=nbkg; i++){
	TH1F * h = (TH1F*) addedhistos[i];
	ostringstream baseSrcName;
	baseSrcName << "Files." << i+1 << ".";
	TString bSrcName(baseSrcName.str().c_str());
	
	TAxis *axis = h->GetXaxis();
	if( axis->GetXmin() < xmin ) xmin = axis->GetXmin();
	if( axis->GetXmax() > xmax ) xmax = axis->GetXmax();
	if( h->GetMinimum() < ymin ) ymin = h->GetMinimum();
	if( h->GetMaximum() > ymax ) ymax = h->GetMaximum();
    }
    ymax = TMath::Nint(ymax*1.25+1); // Make enough room for the big legend
    TString title = h0->GetTitle();
    
    //
    // now check if we should simply use the ranges that was passed to us.
    if(params->Defined("Histo.Xmin")) xmin = params->GetValue("Histo.Xmin",0.);
    if(params->Defined("Histo.Xmax")) xmax = params->GetValue("Histo.Xmax",0.);
    if(params->Defined("Histo.Ymin")) ymin = params->GetValue("Histo.Ymin",0.);
    if(params->Defined("Histo.Ymax")) ymax = params->GetValue("Histo.Ymax",0.);
    
    // Now make the frame:
    TH2F * frame = new TH2F("frame","",nbinsx,xmin,xmax,nbinsy,ymin,ymax);
    cout<<" frame has xmin "<<xmin<<", xmax "<<xmax<<", ymax "<<ymax<<endl;
    
    // get the x- and y-axis titles
    TString ytitle=params->GetValue("Histo.YTitle","");
    if ( params->Defined("Histo.XTitle")) {
	frame->SetXTitle(params->GetValue("Histo.XTitle",""));
    } else {
	frame->SetXTitle(h0->GetTitle());
    }
    frame->SetYTitle(ytitle.Data()); 
    // also set the text size for the X and Y axis titles and numbers
    // do this globally for the style we are using
    float axisLabelSize=textSize;
    frame->GetXaxis()->SetLabelSize(axisLabelSize);
    frame->GetYaxis()->SetLabelSize(axisLabelSize);
    frame->GetXaxis()->SetTitleSize(axisLabelSize);
    frame->GetYaxis()->SetTitleSize(axisLabelSize);
    
    frame->SetStats(false);
    // reduce the axis title offset if the fonts are very large
    if(textSize>0.055) frame->GetXaxis()->SetTitleOffset(1.0);
    // also change the X axis title offset to move it farther away from the numbers
    if(params->Defined("Histo.XTitle.Offset")) {
	float xtitoffset=params->GetValue("Histo.XTitle.Offset",1.0);
	frame->GetXaxis()->SetTitleOffset(xtitoffset);
    }
    
    // also change the y axis title offset to move it farther away from the numbers
    frame->GetYaxis()->SetTitleOffset(1.0);
    // reduce the axis title offset if the fonts are very large
    if(textSize>0.055) frame->GetYaxis()->SetTitleOffset(1.0);
    
    // set the axes divisions
    frame->GetXaxis()->SetNdivisions(505,true);
    if(params->Defined("Histo.XNdivisions")) frame->GetXaxis()->SetNdivisions(params->GetValue("Histo.XNdivisions",505),kTRUE);
    if(params->Defined("Histo.YNdivisions")) frame->GetYaxis()->SetNdivisions(params->GetValue("Histo.YNdivisions",505),kTRUE);
    
    // make sure the X axis title and Y axis title are in black!
    frame->GetXaxis()->SetTitleColor(1);
    frame->GetYaxis()->SetTitleColor(1);

    // Could plot in log scale...
    //gPad->SetLogy();

    // finally: Draw
    frame->Draw();
    
    // Draw the background ones:
    for(Int_t i=nbkg; i>=0; i--){
	TH1F * h = (TH1F*) addedhistos[i];
	h->SetStats(kFALSE);
	
	ostringstream baseSrcName;
	baseSrcName << "Files." << i+2 << ".";// to account for the data which is Files.1
	TString bSrcName(baseSrcName.str().c_str());
	Int_t hcolor=params->GetValue(bSrcName+"Color",1); 	
	h->SetLineColor(1);      
	h->SetFillColor(hcolor);
        if (i==nbkg) printf(" Data Yield = %5.2f ; SumBkg = %5.2f ; Data-SumBkg diff = %5.2f%% \n",
	   		     h0->Integral(),h->Integral(),(h0->Integral()-h->Integral())*100./h0->Integral());
	printf(" plotting bkg i=%2i name=%20.20s file=%2i integral=%5.1f color=%2i\n",
	       i,sampletitles[i].Data(),i+2,h->Integral(),hcolor);
	int fillStyle=params->GetValue(bSrcName+"FillStyle",1001);
	h->SetFillStyle(fillStyle);
	h->DrawCopy("Hist,Same");
    }
    //
    // and draw the signal ones
    // draw them in reverse order so that the last one will be on top.
    //for(Int_t i=ntot-3; i<ntot; i++){
    for(Int_t i=nsig-1; i>=0; i--){
	ostringstream baseSrcName;
	baseSrcName << "Files." << ntot+1-nsig+i << ".";
	TString bSrcName(baseSrcName.str().c_str());
	
	Int_t hcolor=params->GetValue(bSrcName+"Color",1);
	TH1F * h = (TH1F*) signalhistos[i];
       	if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=90"))        h->Add (h, 1.07874865  -1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=100"))  h->Add (h, 1.62317373  -1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=110"))  h->Add (h, 2.31347600  -1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=120"))  h->Add (h, 3.25275183  -1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=130"))  h->Add (h, 4.54142919  -1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=140"))  h->Add (h, 6.19195046  -1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=150"))  h->Add (h, 8.38307290  -1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=160"))  h->Add (h, 11.31721008 -1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=170"))  h->Add (h, 14.85376469 -1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=180"))  h->Add (h, 19.54537459 -1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=190"))  h->Add (h, 25.44594010 -1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=200"))  h->Add (h, 32.94784356 -1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=220"))  h->Add (h, 54.09499080 -1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=240"))  h->Add (h, 86.85079034 -1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=260"))  h->Add (h, 136.31406761-1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=280"))  h->Add (h, 210.70375053-1.000);
	else if (sampletitles[ntot-1-nsig+i].Contains("m_{H}=300"))  h->Add (h, 319.79533099-1.000);
	
	printf(" plotting sig i=%2i name=%20.20s file=%2i integral=%5.1f color=%2i\n",
	       i,sampletitles[ntot-1-nsig+i].Data(),ntot+1-nsig+i,h->Integral(),hcolor);
	// create a white background around each line (helps readibility):
	TH1F *h1=h->Clone();
	h1->SetStats(kFALSE);
	h1->SetLineWidth(6);
	h1->SetLineColor(0);h1->SetFillColor(0);
	h1->SetLineStyle(1);
	h1->SetFillStyle(0);
	h1->Draw("HIST,SAME");
	// now draw the proper line:
	h->SetStats(kFALSE);
	h->SetLineWidth(6);
	h->SetLineColor(hcolor);h->SetFillColor(0);	
	Int_t hlinestyle = params->GetValue(bSrcName+"LineStyle",1);
	h->SetLineStyle(hlinestyle);
	h->SetFillStyle(0);	
	// finally, draw!
	h->Draw("HIST,SAME");      
    } // end of: drawing signal as separate lines
    
    // Data is special: 
    // change the default size of the little bar at the end of the error bar here
    gStyle->SetEndErrorSize(3);
    // also, maybe don't display the error bars along the X axis:
    //gStyle->SetErrorX(0);  // X error bars not displayed
    gStyle->SetErrorX(0.5);  // X error bars have width of a bin
    // now set the rest
    h0->SetMarkerSize(2);
    // if there are too many points (>80), keep the marker size smaller
    if(h0->GetNbinsX()>=50) h0->SetMarkerSize(1);
    //if(h0->GetNbinsX()>=100) h0->SetMarkerSize(1);
    h0->SetLineWidth(3);
    h0->SetMarkerStyle(8);
    h0->SetMarkerColor(1);
    h0->Draw("E1,SAME");
    
    // Print some comparison:
    //ostringstream basefactor;
    //basefactor << "Files." << nbkg+3 << "." << "Factor";
    //TString timesfactor(basefactor.str().c_str()); 
    //Double_t nprod = params->GetValue(timesfactor,1.000);
    //printf("Data Yield = %5.2f ; SumBkg = %5.2f ; SumBkg+Sig = %5.2f ; Data-SumBkg diff = %5.2f%% \n",
    //        h0->Integral(),hbkg2->Integral,(hbkg2->Integral()+(signalhistos[0]->Integral()/nprod),
    //        (h0->Integral()-hbkg2->Integral)*100./h0->Integral()));

    //
    // Print D0 and lumi:
    //
    TText *t1 = new TText();
    t1->SetTextFont(62);
    t1->SetTextColor(1);   
    t1->SetNDC();
    t1->SetTextAlign(12);
    t1->SetTextSize(textSize);
    TString prelim="D\328 Preliminary";
    if(oFileName.EndsWith(".eps")) {
	prelim="D\349 Preliminary L=3.7 fb^-1#";
    }
    else if(oFileName.EndsWith(".gif")) {
	prelim="D\328 Preliminary L=3.7 fb^-1#";
    }
    t1->DrawTextNDC(0.13,0.965,prelim.Data());

    // a counter of how much text we have added from the top
    int nAddTextLines=0;
    
    // any additional text?
    for(int iText=1;iText<20;iText++) {
	ostringstream baseTextName;
	baseTextName << "Histo.AddText." << iText;
	TString bTextName(baseTextName.str().c_str());
	if(params->Defined(bTextName)) {
	    // we are adding a line of text
	    TLatex *t2 = new TLatex();
	    t2->SetTextFont(62);
	    t2->SetTextColor(13);   
	    t2->SetTextAlign(32);
	    t2->SetNDC();
	    t2->SetTextSize(textSize);
	    TString addText(params->GetValue(bTextName,"."));
	    float x0=0.94;
	    float y0=0.96-(nAddTextLines)*0.05;
	    
	    // check if the user specified an alternative location for the text
	    if(params->Defined(bTextName+".X0")) x0=params->GetValue(bTextName+".X0",0.94);
	    if(params->Defined(bTextName+".Y0")) y0=params->GetValue(bTextName+".Y0",0.8);
	    if(params->Defined(bTextName+".TextSize")) t2->SetTextSize(params->GetValue(bTextName+".TextSize",textSize));
	    
	    // and increment the counter keeping track of how much we added,
	    // but only if the user didn't move the label around.
	    if(!params->Defined(bTextName+".X0")) nAddTextLines++;
	    printf("AddText %4.2f %4.2f %s\n",x0,y0,addText.Data());
	    
	    t2->DrawLatex(x0,y0,addText.Data()); 
	}
    }// end additional text
    
    // now draw the frame axis again so that we can see the tick marks
    frame->Draw("sameaxis");
    
    // Legend:
    TString showLegend(params->GetValue("Histo.ShowLegend","."));
    if( showLegend != "no" ){ 
	float lgdxmin=.65, lgdxmax=.90, lgdymin=.50, lgdymax=.91;
	if(showLegend=="yes" || showLegend=="right") {
	    
	} else if (showLegend=="left"){
	    lgdxmin=.16;
	    lgdxmax=.42;
	}
	TLegend *lgd = new TLegend(lgdxmin,lgdymin,lgdxmax,lgdymax); 
	// This line makes the legend transparent (not grey, ewwww!): 
	lgd->SetBorderSize(0); lgd->SetTextSize(textSize*0.9);// 10% less size 
	lgd->SetTextFont(62); lgd->SetFillColor(0);
	// Plot the legend in reverse order (but data goes first):
	NiceAddEntry(lgd,h0,params->GetValue("Files.1.Title","Data"),"PL");
	for(Int_t i = nbkg; i>=0; i--){
	    TH1F * h = (TH1F*) addedhistos[i];
	    TString lgd_entry= sampletitles[i]; // sampletitles runs from 0 (firstbkg) to ntot-1
	    NiceAddEntry(lgd,h,lgd_entry.Data(),"F");	
	}
	for(Int_t i = nsig-1; i>=0; i--){
	    TH1F * h = (TH1F*) signalhistos[i];
	    TString lgd_entry = sampletitles[i+nbkg+1]; // sampletitles runs from 0 (firstbkg) to ntot-1
	    ostringstream basefactor;
	    basefactor << "Files." << i+nbkg+3 << "." << "Factor";
	    TString timesfactor(basefactor.str().c_str());
	    Double_t nprod = params->GetValue(timesfactor,1.000);
	    if (nprod != 1.0 ) lgd_entry.Form("%s x%2.0f",lgd_entry.Data(),nprod);
	    //cout << i+nbkg+3 << " " << nprod << " " << lgd_entry.Data() << endl;
	    NiceAddEntry(lgd,h,lgd_entry.Data(),"L"); 
	}
	lgd->Draw("SAME");	
    }// show legend


    // Draw the KS:
    TLatex *ks = new TLatex();
    ks->SetTextFont(62);
    ks->SetTextColor(1);   
    TString ks_val = Form("KS = %3.2f",KS);
    ks->SetTextAlign(11); ks->SetTextSize(0.03); // ks->SetTextAngle(90); 
    ks->DrawTextNDC(0.83,0.93,ks_val.Data());
    TString chi2_val = Form("#chi^{2}/ndf = %3.1f",chi2ndf);
    ks->SetNDC(true); ks->DrawLatex(0.83,0.97,chi2_val.Data());
    //
    // Voila!
    //
}