Esempio n. 1
0
//_____________________________________________________
TLegend* GFHistManager::AddLegend(Int_t layer, Int_t histoNum, 
				  const char* header, Bool_t referAll)
{
  // adds a legend referencing all hists in same pad 'histoNum' of layer
  // 

  // FIXME: use help of other AddLegend method?
  if(!this->CheckHistNum("AddLegend", layer, histoNum)) return NULL;

  TObjArray* legendsOfLayer = this->MakeLegends(layer);
  TLegend* legend = (legendsOfLayer->GetSize() <= histoNum ? 
		     NULL : static_cast<TLegend*>(legendsOfLayer->At(histoNum)));
  if(!legend) {
    legend = new TLegend(fLegendX1, fLegendY1, fLegendX2, fLegendY2);
#if ROOT_VERSION_CODE < ROOT_VERSION(5,6,0)
    if (TString(gStyle->GetName()) == "Plain") legend->SetBorderSize(1);
#endif
    legendsOfLayer->AddAtAndExpand(legend, histoNum);
  }

  if(header) legend->SetHeader(header);
  GFHistArray* hists = this->GetHistsOf(layer, histoNum);
  TList* legendEntries = legend->GetListOfPrimitives();

  if(referAll){
    TIter histsIter(hists);
    while(TObject* hist = histsIter.Next()){
      Bool_t addNew = kTRUE;
      TIter legEntrIter(legendEntries);
      while(TLegendEntry* entry = static_cast<TLegendEntry*>(legEntrIter())){
	if(hist == entry->GetObject()) {addNew = kFALSE; break;}
      }  
      if(addNew) legend->AddEntry(hist, hist->GetName(), fgLegendEntryOption);
    }
  }

  if(layer < fCanArrays->GetEntriesFast()) {
    this->Update(layer); // if canvas already drawn
  }
  return legend;
}
void Combine_HTBin(){
  
   //========================================Define Variables=================================================================

   TFile* f[21];
   TH1F* Event;
   TH1F* bg[21];
   TH1F* Entry[21];
   TH1F* HistPlot[16][15];
   THStack* Stack[15];
   TCanvas* can[16];
   TCanvas* cMET[16];
   TPad* p[6];
   TLegend* leg;
   string str[15];
   string str2[15];
   Float_t Cuts[17];
   Float_t xsecwzjet[16]={  2.109e+06   
                        ,   7.785e+04   
                        ,   7.401e+03   
                        ,   6.824e+02   
                        ,   1.606e+02   
                        ,   5.545e+01   
                        ,   2.428e+01   
                        ,   4.945e+00   
                        ,   1.563e+00   
                        ,   6.254e-01   
                        ,   2.905e-01   
                        ,   8.535e-02   
                        ,   3.261e-02   
                        ,   1.310e-03   
                        ,   1.464e-04   
                        ,   2.075e-05   }; // in pb
   Float_t NormLumi = 1.0; // in fb-1
   Int_t rebin_pt     = 10;
   Int_t rebin_eta    = 20;
   Int_t rebin_delphi = 2;
   Float_t can_w      = 800; // Canvas Size 
   Float_t can_h      = 800;

   //=====================================================String Part======================================================

   string selec  = "Select";
   string selec2 = "Plot_Select";
   string Canvas = "Canvas";
   string Stk    = "Stack";
   string saveAll;
   string proc[] = {"wzjet","tj","tt","BB"};
   string phys[] = {"_MET_","_Jet1_Pt_","_Jet2_Pt_","_Jet1_Eta_","_Jet2_Eta_","_Jetdel_Phi_","_Jet_Multi_" ,"_Jet_Pt_","_Jet_Eta_"  ,"_Elec_Pt_","_Elec_Eta_"  ,"_Muon_Pt_","_Muon_Eta_"  ,"_tau_Pt_","_tau_Eta_"  };
   Int_t   bin[] = {    3000 , 3000       , 3000       ,   1000     ,      1000  ,    64        ,   20     , 3000     , 1000        , 3000     , 1000        , 3000     , 1000        , 3000     , 1000        }; 
   Double_t min[] = {    0.0 ,   0.0      ,   0.0      ,  -5.0      ,      -5.0  ,     0.       ,    0     ,   0.0    , -5.0        ,   0.0    , -5.0        ,   0.0    , -5.0        ,   0.0    , -5.0        }; 
   Double_t max[] = { 30000.0, 30000.0    , 30000.0    ,   5.0      ,       5.0  ,   6.4        ,   20     , 30000.0  ,  5.0        , 30000.0  ,  5.0        , 30000.0  ,  5.0        , 30000.0  ,  5.0        };

   f[0]=new  TFile("tev100_wzjet_50_100_result.root");
   f[1]=new  TFile("tev100_wzjet_100_200_result.root");
   f[2]=new  TFile("tev100_wzjet_200_400_result.root");
   f[3]=new  TFile("tev100_wzjet_400_600_result.root");
   f[4]=new  TFile("tev100_wzjet_600_800_result.root");
   f[5]=new  TFile("tev100_wzjet_800_1000_result.root");
   f[6]=new  TFile("tev100_wzjet_1000_1500_result.root");
   f[7]=new  TFile("tev100_wzjet_1500_2000_result.root");
   f[8]=new  TFile("tev100_wzjet_2000_2500_result.root");
   f[9]=new  TFile("tev100_wzjet_2500_3000_result.root");
   f[10]=new TFile("tev100_wzjet_3000_4000_result.root");
   f[11]=new TFile("tev100_wzjet_4000_5000_result.root");
   f[12]=new TFile("tev100_wzjet_5000_10000_result.root");
   f[13]=new TFile("tev100_wzjet_10000_15000_result.root");
   f[14]=new TFile("tev100_wzjet_15000_20000_result.root");
   f[15]=new TFile("tev100_wzjet_20000_25000_result.root");

   //==============================================Work Space========================================================

   //===========================================Part 1: Plot=================================================== 

   //  ---------------------------------------------------------------------------------------------------- 
 
   for (Int_t i = 0 ; i < 16 ; i ++ ) {   // index for Selection Cut   

       stringstream ss;
       ss<<i;
       for (Int_t i_stack = 0 ; i_stack < 15 ; i_stack++) {
            stringstream ss2;
            ss2<<i_stack;
            string str_can = Canvas+ss2.str();
            string str_stk = Stk+ss2.str();
            //cout << str_stk << endl;
            can[i_stack] = new TCanvas(str_can.c_str(),str_can.c_str(),can_w,can_h);
            can[i_stack]->SetCanvasSize(can_w,can_h);
            can[i_stack]->SetLogy();
            //can[i_stack]->SetGrid();
            Stack[i_stack] = new THStack(str_stk.c_str(),""); 
            //Stack[i_stack] = new THStack("Stack",""); 
       }

       for (Int_t i_main = 0 ;i_main<16;i_main++ ) {   // index for open each file

         Entry[i_main]=(TH1F*)f[i_main]->Get("Select_MET_0");
         factor = NormLumi*xsecwzjet[i_main]*1000.f/Entry[i_main]->GetEntries();//GetSumOfWeights();
         cout << "Number: " << i_main << " xsec: " << xsecwzjet[i_main] << " factor: " << factor << " Entry: " << Entry[i_main]->GetEntries() << endl;
         for (Int_t i_hist = 0 ; i_hist < 15 ; i_hist++){
            str[i_hist]  = selec+phys[i_hist]+ss.str();
            str2[i_hist] = selec2+phys[i_hist]+ss.str();
            HistPlot[i_main][i_hist]    = new TH1F(str2[i_hist].c_str(),phys[i_hist].c_str(), bin[i_hist], min[i_hist], max[i_hist]);
            bg[i_main]=(TH1F*)f[i_main]->Get(str[i_hist].c_str());
            HistPlot[i_main][i_hist]->Add(bg[i_main],factor);
            //HistPlot[i_main][i_hist]->Draw();

            //Set color
            if (i_main <  5){
                HistPlot[i_main][i_hist]->SetLineColor(604-i_main);
                HistPlot[i_main][i_hist]->SetFillColor(604-i_main);
            } else if (i_main < 9) {
                HistPlot[i_main][i_hist]->SetLineColor(640-i_main);
                HistPlot[i_main][i_hist]->SetFillColor(640-i_main);
            } else if (i_main < 13) {
                HistPlot[i_main][i_hist]->SetLineColor(428-i_main);
                HistPlot[i_main][i_hist]->SetFillColor(428-i_main);
            } else {
                HistPlot[i_main][i_hist]->SetLineColor(632-i_main);
                HistPlot[i_main][i_hist]->SetFillColor(632-i_main);
            }
            // Rebinning
            if (i_hist == 0 || i_hist == 1 ||i_hist == 2 || i_hist == 7 || i_hist == 9 || i_hist == 11 || i_hist == 13 ) {// Rebin PT and MET
                HistPlot[i_main][i_hist]->Rebin(rebin_pt);
            }  

            if (i_hist == 3 || i_hist == 4 || i_hist == 8 || i_hist == 10 || i_hist == 12 || i_hist == 14 ) {// Rebin Eta
                HistPlot[i_main][i_hist]->Rebin(rebin_eta);
            }  

            if (i_hist == 5 ) {// Rebin DelPhi
                HistPlot[i_main][i_hist]->Rebin(rebin_delphi);
            }  
            // Add to Hist Stack
            Stack[i_hist]->Add(HistPlot[i_main][i_hist]);
         }
       }
       // ================================================================================================
       Cuts[i] = ((TH1*)(Stack[0]->GetStack()->Last()))->GetEntries();
       //cout << "Entries: " << Cuts[i] << endl; 


       gStyle->SetOptStat(0); 
       gStyle->SetOptTitle(0);
       gStyle->SetLegendBorderSize(0); 


       // Plot Parameters
       leg = new TLegend(0.50,0.35,0.8,0.8);
       leg->SetHeader("#splitline{#sqrt{s} = 100 TeV, #int L dt = 1 fb^{-1}}{W^{#pm}/Z^{0} + Jets}");
       //leg->SetHeader("#sqrt{s} = 100 TeV, #int L dt = 10 pb^{-1}");
       leg->AddEntry(HistPlot[0][0] ," ","");
       leg->AddEntry(HistPlot[0][0] ," ","");
       leg->AddEntry(HistPlot[0][0] ,"HTBin 50#rightarrow100     ","f");
       leg->AddEntry(HistPlot[1][0] ,"HTBin 100#rightarrow200    ","f");
       leg->AddEntry(HistPlot[2][0] ,"HTBin 200#rightarrow400    ","f");
       leg->AddEntry(HistPlot[3][0] ,"HTBin 400#rightarrow600    ","f");
       leg->AddEntry(HistPlot[4][0] ,"HTBin 600#rightarrow800    ","f");
       leg->AddEntry(HistPlot[5][0] ,"HTBin 800#rightarrow1000   ","f");
       leg->AddEntry(HistPlot[6][0] ,"HTBin 1000#rightarrow1500  ","f");
       leg->AddEntry(HistPlot[7][0] ,"HTBin 1500#rightarrow2000  ","f");
       leg->AddEntry(HistPlot[8][0] ,"HTBin 2000#rightarrow2500  ","f");
       leg->AddEntry(HistPlot[9][0] ,"HTBin 2500#rightarrow3000  ","f");
       leg->AddEntry(HistPlot[10][0],"HTBin 3000#rightarrow4000  ","f");
       leg->AddEntry(HistPlot[11][0],"HTBin 4000#rightarrow5000  ","f");
       leg->AddEntry(HistPlot[12][0],"HTBin 5000#rightarrow10000 ","f");
       leg->AddEntry(HistPlot[13][0],"HTBin 10000#rightarrow15000","f");
       leg->AddEntry(HistPlot[14][0],"HTBin 15000#rightarrow20000","f");
       leg->AddEntry(HistPlot[15][0],"HTBin 20000#rightarrow25000","f");
       //leg->SetFillColorAlpha(0,0);
       TLegendEntry *header = (TLegendEntry*)leg->GetListOfPrimitives()->First();
       //header->SetTextAlign(22);
       //header->SetTextColor(2);
       header->SetTextSize(0.03);

       //Draw an axis on the right side
       //TGaxis *A1 = new TGaxis(0,5e9,6000,5e9,"",510,"-");


       // MET

       can[0]->cd();
       Stack[0]->Draw();
       Stack[0]->GetXaxis()->SetTitle("E^{Miss}_{T} [GeV]");
       Stack[0]->GetYaxis()->SetTitle("Events/100 GeV");
       Stack[0]->GetYaxis()->SetTitleOffset(1.25);
       Stack[0]->GetXaxis()->SetRangeUser(0,6000);
       Stack[0]->SetMinimum(0.3);
       Stack[0]->SetMaximum(10e8);
       Stack[0]->Draw();
       leg->Draw("same");
 
       // Jet1 Pt
       can[1]->cd();
       Stack[1]->Draw();
       Stack[1]->GetXaxis()->SetTitle("P_{T} Jet_{1} [GeV/c]");
       Stack[1]->GetYaxis()->SetTitle("Events/100 GeV");
       Stack[1]->GetYaxis()->SetTitleOffset(1.25);
       Stack[1]->GetXaxis()->SetRangeUser(0,6000);
       Stack[1]->SetMinimum(0.3);
       Stack[1]->SetMaximum(10e8);
       Stack[1]->Draw();
       leg->Draw("same");

       // Jet2 Pt
       can[2]->cd();
       Stack[2]->Draw();
       Stack[2]->GetXaxis()->SetTitle("P_{T} Jet_{2} [GeV/c]");
       Stack[2]->GetYaxis()->SetTitle("Events/100 GeV");
       Stack[2]->GetYaxis()->SetTitleOffset(1.25);
       Stack[2]->GetXaxis()->SetRangeUser(0,6000);
       Stack[2]->SetMaximum(10e8);
       Stack[2]->SetMinimum(0.3);
       Stack[2]->Draw();
       leg->Draw("same");

       
       // Jet1 Eta
       can[3]->cd();
       Stack[3]->Draw();
       Stack[3]->GetXaxis()->SetTitle("#eta Jet_{1} ");
       Stack[3]->GetYaxis()->SetTitle("Events/0.2 ");
       Stack[3]->GetYaxis()->SetTitleOffset(1.25);
       Stack[3]->GetXaxis()->SetRangeUser(-5,5);
       Stack[3]->SetMinimum(0.3);
       Stack[3]->SetMaximum(10e8);
       Stack[3]->Draw();
       leg->Draw("same");
       
       
       // Jet2 Eta
       can[4]->cd();
       Stack[4]->Draw();
       Stack[4]->GetXaxis()->SetTitle("#eta Jet_{2} ");
       Stack[4]->GetYaxis()->SetTitle("Events/0.01 ");
       Stack[4]->GetYaxis()->SetTitleOffset(1.25);
       Stack[4]->GetXaxis()->SetRangeUser(-5,5);
       Stack[4]->SetMinimum(0.3);
       Stack[4]->SetMaximum(10e8);
       Stack[4]->Draw();
       leg->Draw("same");
       
       // JetDelPhi
       can[5]->cd();
       Stack[5]->Draw();
       Stack[5]->GetXaxis()->SetTitle("#Delta#phi Jet_{1,2}");
       Stack[5]->GetYaxis()->SetTitle("Events/0.2 ");
       Stack[5]->GetYaxis()->SetTitleOffset(1.25);
       Stack[5]->GetXaxis()->SetRangeUser(0,6.4);
       Stack[5]->SetMinimum(0.3);
       Stack[5]->SetMaximum(10e8);
       Stack[5]->Draw();
       leg->Draw("same");
       
       // JetMulti
       can[6]->cd();
       Stack[6]->Draw();
       Stack[6]->GetXaxis()->SetTitle("Jet Multiplicity");
       Stack[6]->GetYaxis()->SetTitle("Events ");
       Stack[6]->GetYaxis()->SetTitleOffset(1.40);
       Stack[6]->GetXaxis()->SetRangeUser(0,20);
       Stack[6]->SetMinimum(0.3);
       Stack[6]->SetMaximum(10e9);
       Stack[6]->Draw();
       leg->Draw("same");
       
       // Jet Pt
       can[7]->cd();
       Stack[7]->Draw();
       Stack[7]->GetXaxis()->SetTitle("P_{T} Jet [GeV/c]");
       Stack[7]->GetYaxis()->SetTitle("Events/100 GeV");
       Stack[7]->GetYaxis()->SetTitleOffset(1.25);
       Stack[7]->GetXaxis()->SetRangeUser(0,6000);
       Stack[7]->SetMinimum(0.03);
       Stack[7]->Draw();
       leg->Draw("same");

       
       // Jet Eta
       can[8]->cd();
       Stack[8]->Draw();
       Stack[8]->GetXaxis()->SetTitle("#eta Jet [GeV/c]");
       Stack[8]->GetYaxis()->SetTitle("Events/0.2 ");
       Stack[8]->GetYaxis()->SetTitleOffset(1.25);
       Stack[8]->GetXaxis()->SetRangeUser(-5,5);
       Stack[8]->SetMinimum(0.3);
       Stack[8]->SetMaximum(10e8);
       Stack[8]->Draw();
       leg->Draw("same");

       // Elec Pt
       can[9]->cd();
       Stack[9]->Draw();
       Stack[9]->GetXaxis()->SetTitle("P_{T} Electron [GeV/c]");
       Stack[9]->GetYaxis()->SetTitle("Events/100 GeV");
       Stack[9]->GetYaxis()->SetTitleOffset(1.25);
       Stack[9]->GetXaxis()->SetRangeUser(0,6000);
       Stack[9]->SetMinimum(0.03);
       Stack[9]->Draw();
       leg->Draw("same");

       
       // Elec Eta
       can[10]->cd();
       Stack[10]->Draw();
       Stack[10]->GetXaxis()->SetTitle("#eta Elec [GeV/c]");
       Stack[10]->GetYaxis()->SetTitle("Events/0.2 ");
       Stack[10]->GetYaxis()->SetTitleOffset(1.25);
       Stack[10]->GetXaxis()->SetRangeUser(-5,5);
       Stack[10]->SetMinimum(0.3);
       Stack[10]->SetMaximum(10e8);
       Stack[10]->Draw();
       leg->Draw("same");

       // Muon Pt
       can[11]->cd();
       Stack[11]->Draw();
       Stack[11]->GetXaxis()->SetTitle("P_{T} Muon [GeV/c]");
       Stack[11]->GetYaxis()->SetTitle("Events/100 GeV");
       Stack[11]->GetYaxis()->SetTitleOffset(1.25);
       Stack[11]->GetXaxis()->SetRangeUser(0,6000);
       Stack[11]->SetMinimum(0.03);
       Stack[11]->Draw();
       leg->Draw("same");

       
       // Muon Eta
       can[12]->cd();
       Stack[12]->Draw();
       Stack[12]->GetXaxis()->SetTitle("#eta Muon [GeV/c]");
       Stack[12]->GetYaxis()->SetTitle("Events/0.2 ");
       Stack[12]->GetYaxis()->SetTitleOffset(1.25);
       Stack[12]->GetXaxis()->SetRangeUser(-5,5);
       Stack[12]->SetMinimum(0.3);
       Stack[12]->SetMaximum(10e8);
       Stack[12]->Draw();
       leg->Draw("same");

       // tau Pt
       can[13]->cd();
       Stack[13]->Draw();
       Stack[13]->GetXaxis()->SetTitle("P_{T} tau [GeV/c]");
       Stack[13]->GetYaxis()->SetTitle("Events/100 GeV");
       Stack[13]->GetYaxis()->SetTitleOffset(1.25);
       Stack[13]->GetXaxis()->SetRangeUser(0,6000);
       Stack[13]->SetMinimum(0.03);
       Stack[13]->Draw();
       leg->Draw("same");

       
       // tau Eta
       can[14]->cd();
       Stack[14]->Draw();
       Stack[14]->GetXaxis()->SetTitle("#eta tau [GeV/c]");
       Stack[14]->GetYaxis()->SetTitle("Events/0.2 ");
       Stack[14]->GetYaxis()->SetTitleOffset(1.25);
       Stack[14]->GetXaxis()->SetRangeUser(-5,5);
       Stack[14]->SetMinimum(0.3);
       Stack[14]->SetMaximum(10e8);
       Stack[14]->Draw();
       leg->Draw("same");

       
       // Save
       for (Int_t i_hist = 0; i_hist<15 ; i_hist++){ 
            saveAll = str[i_hist]+".pdf";
            can[i_hist]->SaveAs(saveAll.c_str());
            delete can[i_hist];
       }
   }
   // Print Results 
   // Create file for data aquisition

   fstream myfile;
   myfile.open("Results.txt", std::fstream::in | std::fstream::out | std::fstream::app);
   
   for (Int_t i = 0; i < 17 ; i++) {
     myfile << "Selection Cut " << i << " : " << Cuts[i] << endl;
   }   
   
   myfile.close(); 
       
}
Esempio n. 3
0
void misalignmentDependence(TCanvas *c1old,
                            Int_t nFiles,TString *names,TString misalignment,Double_t *values,Double_t *phases,TString xvar,TString yvar,
                            TF1 *function,Int_t parameter,TString parametername = "",TString functionname = "",
                            Bool_t resolution = false,
                            TString saveas = "")
{
    cout << saveas << endl;
    if (c1old == 0) return;
    c1old = (TCanvas*)c1old->Clone("c1old");
    if (misalignment == "" || yvar == "") return;
    Bool_t drawfits = (parameter < 0);
    if (parameter < 0)
        parameter = -parameter - 1;   //-1 --> 0, -2 --> 1, -3 --> 2, ...
    TString yaxislabel = nPart(1,parametername);
    TString parameterunits = nPart(2,parametername);
    if (parameterunits != "")
        yaxislabel.Append(" (").Append(parameterunits).Append(")");
    TList *list = c1old->GetListOfPrimitives();
    int n = list->GetEntries() - 2 - (xvar == "");

    setTDRStyle();
    gStyle->SetOptStat(0);
    gStyle->SetOptFit(0);
    gStyle->SetFitFormat("5.4g");
    gStyle->SetFuncColor(2);
    gStyle->SetFuncStyle(1);
    gStyle->SetFuncWidth(1);
    if (!drawfits)
    {
        gStyle->SetCanvasDefW(678);
        gStyle->SetPadRightMargin(0.115);
    }

    TH1 **p = new TH1*[n];
    TF1 **f = new TF1*[n];
    Bool_t used[n];
    for (Int_t i = 0; i < n; i++)
    {
        stringstream s0;
        s0 << "p" << i;
        TString pname = s0.str();
        p[i] = (TH1*)list->/*At(i+1+(xvar == ""))*/FindObject(pname);
        used[i] = (p[i] != 0);
        if (used[i])
            p[i]->SetDirectory(0);
        if (xvar == "" && function == 0)
            continue;
        stringstream s;
        s << function->GetName() << i;
        TString newname = s.str();
        f[i] = (TF1*)function->Clone(newname);
        stufftodelete->Add(f[i]);
    }

    Double_t *result = new Double_t[nFiles];
    Double_t *error  = new Double_t[nFiles];
    if (xvar == "" && function == 0)
    {
        yaxislabel = axislabel(yvar,'y',resolution);
        for (Int_t i = 0; i < nFiles; i++)
        {
            if (!used[i]) continue;
            if (!resolution)
            {
                result[i] = p[i]->GetMean();
                error[i]  = p[i]->GetMeanError();
            }
            else
            {
                result[i] = p[i]->GetRMS();
                error[i]  = p[i]->GetRMSError();
            }
            cout << result[i] << " +/- " << error[i] << endl;
        }
    }
    else
    {
        for (int i = 0; i < n; i++)
        {
            if (!used[i]) continue;
            f[i]->SetLineColor(colors[i]);
            f[i]->SetLineStyle(styles[i]);
            f[i]->SetLineWidth(1);
            p[i]->SetMarkerColor(colors[i]);
            p[i]->SetMarkerStyle(20+i);
            p[i]->SetLineColor(colors[i]);
            p[i]->SetLineStyle(styles[i]);
            p[i]->Fit(f[i],"IM");
            error[i]  = f[i]->GetParError (parameter);
            if (function->GetName() == TString("sine"))
            {
                if (f[i]->GetParameter(0) < 0)
                {
                    f[i]->SetParameter(0,-f[i]->GetParameter(0));
                    f[i]->SetParameter(2,f[i]->GetParameter(2)+pi);
                }
                while(f[i]->GetParameter(2) >= 2*pi)
                    f[i]->SetParameter(2,f[i]->GetParameter(2)-2*pi);
                while(f[i]->GetParameter(2) < 0)
                    f[i]->SetParameter(2,f[i]->GetParameter(2)+2*pi);
            }
            result[i] = f[i]->GetParameter(parameter);
        }
    }


    TCanvas *c1 = TCanvas::MakeDefCanvas();

    if (drawfits && !(xvar == "" && function == 0) && yvar != "")
    {
        TString legendtitle = "[";
        legendtitle.Append(functionname);
        legendtitle.Append("]");
        TLegend *legend = new TLegend(.7,.7,.9,.9,legendtitle,"br");
        stufftodelete->Add(legend);
        TString drawoption = "";
        TH1 *maxp = (TH1*)list->FindObject("maxp");
        if (maxp != 0)
        {
            maxp->Draw();
            drawoption = "same";
        }
        for (int i = 0; i < n; i++)
        {
            if (!used[i]) continue;
            p[i]->Draw(drawoption);
            f[i]->Draw("same");
            drawoption = "same";

            stringstream s;
            s.precision(3);
            s << nPart(1,parametername) << " = " <<  result[i] << " #pm " << error[i];
            if (parameterunits != "") s << " " << parameterunits;
            TString str = s.str();
            legend->AddEntry(p[i],names[i],"pl");
            legend->AddEntry(f[i],str,"l");
        }
        c1->Update();
        Double_t x1min  = .98*gPad->GetUxmin() + .02*gPad->GetUxmax();
        Double_t x2max  = .02*gPad->GetUxmin() + .98*gPad->GetUxmax();
        Double_t y1min  = .98*gPad->GetUymin() + .02*gPad->GetUymax();
        Double_t y2max  = .02*gPad->GetUymin() + .98*gPad->GetUymax();
        Double_t width  = .4*(x2max-x1min);
        Double_t height = (1./20)*legend->GetListOfPrimitives()->GetEntries()*(y2max-y1min);
        width *= 2;
        height /= 2;
        legend->SetNColumns(2);

        Double_t newy2max = placeLegend(legend,width,height,x1min,y1min,x2max,y2max);
        p[0]->GetYaxis()->SetRangeUser(gPad->GetUymin(),(newy2max-.02*gPad->GetUymin())/.98);
        if (maxp != 0)
            maxp->GetYaxis()->SetRangeUser(gPad->GetUymin(),(newy2max-.02*gPad->GetUymin())/.98);

        legend->SetFillStyle(0);
        legend->Draw();
    }
    else
    {
        if (values == 0) return;

        Bool_t phasesmatter = false;
        if (misalignment == "elliptical" || misalignment == "sagitta" || misalignment == "skew")
        {
            if (phases == 0)
            {
                cout << "This misalignment has a phase, but you didn't supply the phases!" << endl
                     << "Can't produce plots depending on the misalignment value." << endl;
                return;
            }
            int firstnonzero = -1;
            for (Int_t i = 0; i < nFiles; i++)
            {
                if (values[i] == 0) continue;                    //if the amplitude is 0 the phase is arbitrary
                if (firstnonzero == -1) firstnonzero = i;
                if (phases[i] != phases[firstnonzero])
                    phasesmatter = true;
            }
        }

        if (!phasesmatter)
        {
            TGraphErrors *g = new TGraphErrors(nFiles,values,result,(Double_t*)0,error);
            g->SetName("");
            stufftodelete->Add(g);

            TString xaxislabel = "#epsilon_{";
            xaxislabel.Append(misalignment);
            xaxislabel.Append("}");
            g->GetXaxis()->SetTitle(xaxislabel);
            if (xvar != "")
            {
                yaxislabel.Append("   [");
                yaxislabel.Append(functionname);
                yaxislabel.Append("]");
            }
            g->GetYaxis()->SetTitle(yaxislabel);

            g->SetMarkerColor(colors[0]);
            g->SetMarkerStyle(20);

            g->Draw("AP");
            Double_t yaxismax = g->GetYaxis()->GetXmax();
            Double_t yaxismin = g->GetYaxis()->GetXmin();
            if (yaxismin > 0)
            {
                yaxismax += yaxismin;
                yaxismin = 0;
            }
            g->GetYaxis()->SetRangeUser(yaxismin,yaxismax);
            g->Draw("AP");
        }
        else
        {
            double *xvalues = new double[nFiles];
            double *yvalues = new double[nFiles];      //these are not physically x and y (except in the case of skew)
            for (int i = 0; i < nFiles; i++)
            {
                xvalues[i] = values[i] * cos(phases[i]);
                yvalues[i] = values[i] * sin(phases[i]);
            }
            TGraph2DErrors *g = new TGraph2DErrors(nFiles,xvalues,yvalues,result,(Double_t*)0,(Double_t*)0,error);
            g->SetName("");
            stufftodelete->Add(g);
            delete[] xvalues;        //A TGraph2DErrors has its own copy of xvalues and yvalues, so it's ok to delete these copies.
            delete[] yvalues;
            
            TString xaxislabel = "#epsilon_{";
            xaxislabel.Append(misalignment);
            xaxislabel.Append("}cos(#delta)");
            TString realyaxislabel = xaxislabel;
            realyaxislabel.ReplaceAll("cos(#delta)","sin(#delta)");
            g->GetXaxis()->SetTitle(xaxislabel);
            g->GetYaxis()->SetTitle(realyaxislabel);
            TString zaxislabel = /*"fake"*/yaxislabel;         //yaxislabel is defined earlier
            if (xvar != "")
            {
                zaxislabel.Append("   [");
                zaxislabel.Append(functionname);
                zaxislabel.Append("]");
            }
            g->GetZaxis()->SetTitle(zaxislabel);
            g->SetMarkerStyle(20);
            g->Draw("pcolerr");
        }
    }

    if (saveas != "")
    {
        saveplot(c1,saveas);
        delete[] p;
        delete[] f;
        delete[] result;
        delete[] error;
        delete c1old;
    }
}
Esempio n. 4
0
  void drawpdgstack(std::string const & which_pdg,
		    std::string const & cname,
		    std::string const & dr,
		    std::string const & binning,
		    std::string const & we = "",
		    std::string const & op = "",
		    std::string const & title = "",
		    std::string const & xtitle = "",
		    std::string const & ytitle = "",
		    bool const pdg_sign = true) {

    ofile->cd();
    
    TH1F * hist = getpdgs(which_pdg.c_str(), we);
    if(!hist) {
      std::cout << "drawpdgstack: Empty pdg hist for \"" << which_pdg << "\" with selection \"" << we << "\"\n";
      return;
    }    

    THStack * stack = new THStack("stack", "");
    TLegend * legend = new TLegend(0.6, 0.9, 0.9, 0.6);

    double sig_evtsppot = 0;

    if(tree2) {

      TString draw_str = "";
      draw_str += dr;
      draw_str += ">>h_sig";
      draw_str += binning;

      TCanvas * canvas_pdg_temp = new TCanvas("temp");
      tree2->Draw(draw_str.Data(),
		  we.c_str(),
		  op.c_str());
      delete canvas_pdg_temp;
      TH1F * hist_sig = (TH1F*)gDirectory->Get("h_sig");
      hist_sig->SetLineColor(1);
      hist_sig->SetFillColor(kRed+3);
      hist_sig->Scale(1. / signal_pot * run_pot);

      stack->Add(hist_sig);
      legend->AddEntry(hist_sig, ("Signal: "+to_string_with_precision(hist_sig->Integral())).c_str());
      
      sig_evtsppot = hist_sig->Integral();

    }

    legend->SetHeader(("Total: "+to_string_with_precision((hist->Integral()/background_pot*run_pot + sig_evtsppot))).c_str());
    ((TLegendEntry*)legend->GetListOfPrimitives()->First())->SetTextAlign(22);

    std::vector<int> pdg_vec;
    for(int i = 1; i <= hist->GetNbinsX(); ++i) {

      if(hist->GetBinContent(i) == 0) continue;      
      int const pdg = i+hist->GetBinLowEdge(0);

      if(!pdg_sign) {
	if(std::find(pdg_vec.begin(), pdg_vec.end(), abs(pdg)) != pdg_vec.end())
	  continue;
	pdg_vec.push_back(abs(pdg));
      }
  
      TString hname = "";
      hname += "h_";
      hname += pdg;
      
      TString draw_str = "";
      draw_str += dr;
      draw_str += ">>h_";
      draw_str += pdg;
      draw_str += binning;
      
      TString weight_str = "";
      weight_str += we;
      weight_str += "&&(";
      weight_str += which_pdg;
      weight_str += "==";
      weight_str += pdg;
      if(!pdg_sign && pdg < 0) {
	weight_str += "||";
	weight_str += which_pdg;
	weight_str += "==";
	weight_str += abs(pdg);
      }
      weight_str += ")";
      
      TCanvas * canvas_pdg_temp = new TCanvas("temp");
      tree->Draw(draw_str.Data(),
		 weight_str.Data(),
		 op.c_str());
      delete canvas_pdg_temp;

      int pdg_temp = pdg;
      if(!pdg_sign) pdg_temp = abs(pdg);
      pdg_stuff const & pdg_s = get_pdg_stuff(pdg_temp, pdg_sign);

      TH1F * hist_pdg = (TH1F*)gDirectory->Get(hname.Data());
      hist_pdg->SetLineColor(1);
      hist_pdg->SetFillColor(pdg_s._color);
      hist_pdg->Scale(1. / background_pot * run_pot);
      stack->Add(hist_pdg);
      legend->AddEntry(hist_pdg, (pdg_s._particle_name+": "+to_string_with_precision(hist_pdg->Integral())).c_str());
      
    }
    
    TCanvas * canvas = new TCanvas(cname.c_str());
    stack->Draw();
    stack->SetTitle(title.c_str());
    stack->GetXaxis()->SetTitle(xtitle.c_str());
    stack->GetXaxis()->CenterTitle(); 
    stack->GetYaxis()->SetTitle(ytitle.c_str());
    stack->GetYaxis()->CenterTitle();
    legend->Draw();
    canvas->Write();
    delete stack;
    delete legend;
    delete canvas;
    delete hist;
    
  }
Esempio n. 5
0
TCanvas *trackSplitPlot(Int_t nFiles,TString *files,TString *names,TString xvar,TString yvar,
                     Bool_t relative = kFALSE,Bool_t logscale = kFALSE,Bool_t resolution = kFALSE,Bool_t pull = kFALSE,
                     TString saveas = "")
{
    cout << xvar << " " << yvar << endl;
    if (xvar == "" && yvar == "")
        return 0;

    PlotType type;
    if (xvar == "")      type = Histogram;
    else if (yvar == "") type = OrgHistogram;
    else if (resolution) type = Resolution;
    else if (nFiles < 1) type = ScatterPlot;
    else                 type = Profile;
    if (nFiles < 1) nFiles = 1;

    const Int_t n = nFiles;
    
    TStyle *tdrStyle = setTDRStyle();
    tdrStyle->SetOptStat(0);
    if ((type == Histogram || type == OrgHistogram) && nFiles == 1)
        tdrStyle->SetOptStat(1110);
    if (type == ScatterPlot || (type == Histogram && !pull) || xvar == "runNumber")
    {
        tdrStyle->SetCanvasDefW(678);
        tdrStyle->SetPadRightMargin(0.115);
    }

    Bool_t nHits = (xvar[0] == 'n' && xvar[1] == 'H' && xvar[2] == 'i'
                                   && xvar[3] == 't' && xvar[4] == 's');

    Int_t nBinsScatterPlotx = binsScatterPlotx;
    Int_t nBinsScatterPloty = binsScatterPloty;
    Int_t nBinsHistogram = binsHistogram;
    Int_t nBinsProfileResolution = binsProfileResolution;
    if (xvar == "runNumber")
    {
        nBinsProfileResolution = runNumberBins;
        nBinsHistogram = runNumberBins;
    }
    if (nHits)
    {
        nBinsHistogram = (int)(findMax(nFiles,files,xvar,'x') - findMin(nFiles,files,xvar,'x') + 1.1);     //in case it's .99999
        nBinsScatterPlotx = nBinsHistogram;
        nBinsProfileResolution = nBinsHistogram;
    }

    TH1 **p = new TH1*[n];
    Int_t lengths[n];

    stringstream sx,sy,srel,ssigma1,ssigma2,ssigmaorg;

    sx << xvar << "_org";
    TString xvariable = sx.str();
    TString xvariable2 = "";
    if (xvar == "runNumber") xvariable = "runNumber";
    if (nHits)
    {
        xvariable  = xvar;
        xvariable2 = xvar;
        xvariable.Append("1_spl");
        xvariable2.Append("2_spl");
    }

    sy << "Delta_" << yvar;
    TString yvariable = sy.str();

    TString relvariable = "1";
    if (relative)
    {
        srel << yvar << "_org";
        relvariable = srel.str();
    }

    TString sigma1variable = "",sigma2variable = "";
    if (pull)
    {
        ssigma1 << yvar << "1Err_spl";
        ssigma2 << yvar << "2Err_spl";
    }
    sigma1variable = ssigma1.str();
    sigma2variable = ssigma2.str();

    TString sigmaorgvariable = "";
    if (pull && relative)
        ssigmaorg << yvar << "Err_org";
    sigmaorgvariable = ssigmaorg.str();


    Double_t xmin = -1,xmax = 1,ymin = -1,ymax = 1;
    if (type == Profile || type == ScatterPlot || type == OrgHistogram || type == Resolution)
        axislimits(nFiles,files,xvar,'x',relative,pull,xmin,xmax);
    if (type == Profile || type == ScatterPlot || type == Histogram || type == Resolution)
        axislimits(nFiles,files,yvar,'y',relative,pull,ymin,ymax);

    TString meansrmss[n];

    for (Int_t i = 0; i < n; i++)
    {
        TFile *f = TFile::Open(files[i]);
        TTree *tree = (TTree*)f->Get("splitterTree");

        stringstream sid;
        sid << "p" << i;
        TString id = sid.str();

        TH1F **q = new TH1F*[nBinsProfileResolution];
        if (type == ScatterPlot)
            p[i] = new TH2F(id,"",nBinsScatterPlotx,xmin,xmax,nBinsScatterPloty,ymin,ymax);
        if (type == Histogram)
            p[i] = new TH1F(id,"",nBinsHistogram,ymin,ymax);
        if (type == OrgHistogram)
            p[i] = new TH1F(id,"",nBinsHistogram,xmin,xmax);
        if (type == Resolution || type == Profile)
        {
            p[i] = new TH1F(id,"",nBinsProfileResolution,xmin,xmax);
            for (Int_t j = 0; j < nBinsProfileResolution; j++)
            {
                stringstream sid2;
                sid2 << "q" << j;
                TString id2 = sid2.str();
                q[j] = new TH1F(id2,"",nBinsHistogram,ymin,ymax);
            }
        }
        p[i]->SetDirectory(0);

        lengths[i] = tree->GetEntries();

        if (files[i].Contains("MC") && xvar == "runNumber")
        {
            p[i]->SetLineColor(kWhite);
            p[i]->SetMarkerColor(kWhite);
            f->Close();
            continue;
        }

        Double_t x = 0, y = 0, rel = 1, sigma1 = 1, sigma2 = 1,           //if !pull, we want to divide by sqrt(2) because we want the error from 1 track
                                                  sigmaorg = 0;
        Int_t xint = 0, xint2 = 0;
        Int_t runNumber = 0;

        if (!relative && !pull && (yvar == "dz" || yvar == "dxy"))
            rel = 1e-4;                                     //it's in cm but we want it in um, so divide by 1e-4

        tree->SetBranchAddress("runNumber",&runNumber);
        if (type == Profile || type == ScatterPlot || type == Resolution || type == OrgHistogram)
        {
            if (xvar == "runNumber")
                tree->SetBranchAddress(xvariable,&xint);
            else if (nHits)
            {
                tree->SetBranchAddress(xvariable,&xint);
                tree->SetBranchAddress(xvariable2,&xint2);
            }
            else
                tree->SetBranchAddress(xvariable,&x);
        }
        if (type == Profile || type == ScatterPlot || type == Resolution || type == Histogram)
            tree->SetBranchAddress(yvariable,&y);
        if (relative && xvar != yvar)                       //if xvar == yvar, setting the branch here will undo setting it to x 2 lines earlier
            tree->SetBranchAddress(relvariable,&rel);
        if (pull)
        {
            tree->SetBranchAddress(sigma1variable,&sigma1);
            tree->SetBranchAddress(sigma2variable,&sigma2);
        }
        if (relative && pull)
            tree->SetBranchAddress(sigmaorgvariable,&sigmaorg);
   
        Int_t notincluded = 0;

        for (Int_t j = 0; j<lengths[i]; j++)
        {
            tree->GetEntry(j);
            if (xvar == "runNumber" || nHits)
                x = xint;
            if (xvar == "runNumber")
                runNumber = x;
            if (runNumber < minrun || (runNumber > maxrun && maxrun > 0)) 
            {
                notincluded++;
                continue;
            }
            if (relative && xvar == yvar)
            {
                rel = x;
            }
            Double_t error = 0;
            if (relative && pull)
                error = sqrt((sigma1/rel)*(sigma1/rel) + (sigma2/rel)*(sigma2/rel) + (sigmaorg*y/(rel*rel))*(sigmaorg*x/(rel*rel)));
            else
                error = sqrt(sigma1 * sigma1 + sigma2 * sigma2);   // = sqrt(2) if !pull, to get the error in 1 track
            y /= (rel * error);

            if (logscale)
                y = fabs(y);
            if (ymin <= y && y < ymax && xmin <= x && x < xmax)
            {
                if (type == Histogram)
                    p[i]->Fill(y);
                if (type == ScatterPlot)
                    p[i]->Fill(x,y);
                if (type == Resolution || type == Profile)
                {
                    int which = (p[i]->Fill(x,0)) - 1;
                    if (which >= 0) q[which]->Fill(y);         //get which q[j] by filling p[i] (with nothing), which returns the bin number
                }
                if (type == OrgHistogram)
                    p[i]->Fill(x);
            }

            if (nHits)
            {
                x = xint2;
                if (ymin <= y && y < ymax && xmin <= x && x < xmax)
                {
                    if (type == Histogram)
                        p[i]->Fill(y);
                    if (type == ScatterPlot)
                        p[i]->Fill(x,y);
                    if (type == Resolution || type == Profile)
                    {
                        int which = (p[i]->Fill(x,0)) - 1;
                        if (which >= 0) q[which]->Fill(y);         //get which q[j] by filling p[i] (with nothing), which returns the bin number
                    }
                    if (type == OrgHistogram)
                        p[i]->Fill(x);
                }
            }

            if (((j+1)/(int)(pow(10,(int)(log10(lengths[i]))-1)))*(int)(pow(10,(int)(log10(lengths[i]))-1)) == j + 1 || j + 1 == lengths[i])
            {
                cout << j + 1 << "/" << lengths[i] << ": "; 
                if (type == Profile || type == ScatterPlot || type == Resolution)
                    cout << x << ", " << y << endl;
                if (type == OrgHistogram)
                    cout << x << endl;
                if (type == Histogram)
                    cout << y << endl;
            }
        }
        lengths[i] -= notincluded;

        meansrmss[i] = "";
        if (type == Histogram || type == OrgHistogram)
        {
            cout << "Average = " << p[i]->GetMean() << endl;
            cout << "RMS     = " << p[i]->GetRMS()  << endl;
            stringstream meanrms;
            meanrms.precision(3);
            meanrms << "#mu=" << p[i]->GetMean() << ", #sigma=" << p[i]->GetRMS();
            meansrmss[i] = meanrms.str();
        }

        if (type == Resolution)
        {
            for (Int_t j = 0; j < nBinsProfileResolution; j++)
            {
                p[i]->SetBinContent(j+1,q[j]->GetRMS());
                p[i]->SetBinError  (j+1,q[j]->GetRMSError());
                delete q[j];
            }
        }

        if (type == Profile)
        {
            for (Int_t j = 0; j < nBinsProfileResolution; j++)
            {
                p[i]->SetBinContent(j+1,q[j]->GetMean());
                p[i]->SetBinError  (j+1,q[j]->GetMeanError());
                delete q[j];
            }
        }
        delete[] q;

        setAxisLabels(p[i],type,xvar,yvar,relative,pull);

        p[i]->SetLineColor(colors[i]);
        if (type == Resolution || type == Profile)
        {
            p[i]->SetMarkerColor(colors[i]);
            p[i]->SetMarkerStyle(20+i);
        }
        else
        {
            p[i]->SetMarkerStyle(1);
        }
        f->Close();
    }

    TCanvas *c1 = TCanvas::MakeDefCanvas();
    if (type == ScatterPlot || type == Profile || type == Resolution || type == OrgHistogram)
        c1->SetLogy((Bool_t)(logscale));
    if (type == Histogram)
        c1->SetLogx((Bool_t)(logscale));

    TH1 *maxp = p[0];
    TGraphErrors *g[n];
    TMultiGraph *list = new TMultiGraph();
    if (type == ScatterPlot)
        p[0]->Draw("COLZ");
    else if (type == Resolution || type == Profile)
    {
        for (Int_t i = 0; i < n; i++)
        {
            if (files[i].Contains("MC") && xvar == "runNumber")
                continue;
            g[i] = new TGraphErrors(p[i]);
            for (Int_t j = 0; j < g[i]->GetN(); j++)
            {
                if (g[i]->GetY()[j] == 0 && g[i]->GetEY()[j] == 0)
                {
                    g[i]->RemovePoint(j);
                    j--;
                }
            }
            list->Add(g[i]);
        }
        list->Draw("AP");
        Double_t yaxismax = list->GetYaxis()->GetXmax();
        Double_t yaxismin = list->GetYaxis()->GetXmin();
        if (yaxismin > 0)
        {
            yaxismax += yaxismin;
            yaxismin = 0;
        }
        p[0]->GetYaxis()->SetRangeUser(yaxismin,yaxismax);
        p[0]->Draw("P");
    }
    else if (type == Histogram || type == OrgHistogram)
    {
        Bool_t allthesame = true;
        for (Int_t i = 1; i < n && allthesame; i++)
        {
            if (lengths[i] != lengths[0])
                allthesame = false;
        }
        if (!allthesame && xvar != "runNumber")
            for (Int_t i = 0; i < n; i++)
            {
                p[i]->Scale(1.0/lengths[i]);
            }
        maxp = (TH1F*)p[0]->Clone("maxp");
        maxp->SetLineColor(kWhite);
        for (Int_t i = 1; i <= maxp->GetNbinsX(); i++)
        {
            for (Int_t j = 0; j < n; j++)
            {
                if (files[j].Contains("MC") && xvar == "runNumber")
                    continue;
                maxp->SetBinContent(i,TMath::Max(maxp->GetBinContent(i),p[j]->GetBinContent(i)));
            }
        }
        maxp->Draw();
        p[0]->Draw("same");
    }
    TLegend *legend = new TLegend(.6,.7,.9,.9,"","br");
    if (n == 1 && files[0].Contains("MC") && xvar == "runNumber")
    {
        placeholder(saveas,yvar == "");
        return 0;
    }
    if (n>=2)
    {
        if (!(files[0].Contains("MC") && xvar == "runNumber") && files[0] != "")
        {
            if (type == Resolution || type == Profile)
                legend->AddEntry(p[0],names[0],"pl");
            else if (type == Histogram || type == OrgHistogram)
            {
                legend->AddEntry(p[0],names[0],"l");
                legend->AddEntry((TObject*)0,meansrmss[0],"");
            }
        }
        for (Int_t i = 1; i < n; i++)
        {
            if (files[i].Contains("MC") && xvar == "runNumber")
                continue;
            if (type == Resolution || type == Profile)
            {
                p[i]->Draw("same P");
                legend->AddEntry(p[i],names[i],"pl");
            }
            else if (type == Histogram || type == OrgHistogram)
            {
                p[i]->Draw("same");
                legend->AddEntry(p[i],names[i],"l");
                legend->AddEntry((TObject*)0,meansrmss[i],"");
            }
        }

        if (legend->GetListOfPrimitives()->At(0) == 0)
        {
            delete legend;
            placeholder(saveas,yvar == "");
            return 0;
        }

        
        c1->Update();
        Double_t x1min  = .98*gPad->GetUxmin() + .02*gPad->GetUxmax();
        Double_t x2max  = .02*gPad->GetUxmin() + .98*gPad->GetUxmax();
        Double_t y1min  = .98*gPad->GetUymin() + .02*gPad->GetUymax();
        Double_t y2max  = .02*gPad->GetUymin() + .98*gPad->GetUymax();
        Double_t width  = .4*(x2max-x1min);
        Double_t height = (1./20)*legend->GetListOfPrimitives()->GetEntries()*(y2max-y1min);
        if (type == Histogram || type == OrgHistogram)
        {
            width *= 2;
            height /= 2;
            legend->SetNColumns(2);
        }
        Double_t newy2max = placeLegend(legend,width,height,x1min,y1min,x2max,y2max);
        maxp->GetYaxis()->SetRangeUser(gPad->GetUymin(),(newy2max-.02*gPad->GetUymin())/.98);
                
        legend->SetFillStyle(0);
        legend->Draw();
    }
    if (saveas != "")
    {
        saveplot(c1,saveas);
        for (int i = 0; i < n; i++)
        {
            //delete p[i];
            //delete g[i];
        }
        //delete list;
        //delete maxp;
        //delete legend;
    }
    return c1;
}