Пример #1
0
TH2* doSmooth (TH2* hRaw, bool useLog = true) {
    //
    // smooth histogram
    //
    TH2* hSmooth = (TH2*)hRaw->Clone("hSmooth");
    hSmooth->SetTitle("hSmooth");
    if ( useLog ) {
        for ( int ix=1; ix<=hSmooth->GetNbinsX(); ++ix ) {
            for ( int iy=1; iy<=hSmooth->GetNbinsY(); ++iy ) {
                double c = hSmooth->GetBinContent(ix,iy);
                c = c>0. ? log(c) : -100.;
                hSmooth->SetBinContent(ix,iy,c);
            }
        }
    }
    fitLinear(hSmooth,hRaw);

    if ( useLog ) {
        for ( int ix=1; ix<=hSmooth->GetNbinsX(); ++ix ) {
            for ( int iy=1; iy<=hSmooth->GetNbinsY(); ++iy ) {
                double craw = hRaw->GetBinContent(ix,iy);
                double c = hSmooth->GetBinContent(ix,iy);
                c = craw>0. ? exp(c) : 0.;
                hSmooth->SetBinContent(ix,iy,c);
            }
        }
    }
    hSmooth->SetName(hRaw->GetName());

    return hSmooth;
}
Пример #2
0
void SF_TH2F_And_Eff::init(string filename,string effdata,string effmc,string errordata,string errormc)
{
    f = TFile::Open(filename.c_str() ) ;

    if (f == NULL){
        Log(__FUNCTION__,"ERROR","file '" + filename + "' does not exist");
        throw abortException() ;
    }

    TH2 * hDataEff = getHisto(effdata);
    TH2 * hDataErr = NULL;
    if (errordata != "" ) hDataErr = getHisto(errordata);
    TH2 * hMcEff = getHisto(effmc);
    TH2 * hMcErr = NULL;
    if (errormc != "" ) hMcErr = getHisto(errormc);


    for( int aetabin =1; aetabin <= hDataEff->GetNbinsX() ; ++aetabin)
    for( int ptbin =1; ptbin <= hDataEff->GetNbinsY() ; ++ptbin)
    {
        float ptmin = hDataEff->GetYaxis()->GetBinLowEdge(ptbin); 
        float ptmax = hDataEff->GetYaxis()->GetBinLowEdge(ptbin+1); 
        float aetamin = hDataEff->GetXaxis()->GetBinLowEdge(aetabin); 
        float aetamax = hDataEff->GetXaxis()->GetBinLowEdge(aetabin+1); 
        float effData = hDataEff->GetBinContent(aetabin,ptbin);
        float errData = 0.0 ;
        if (hDataErr) err=hDataErr->GetBinContent(aetabin,ptbin);
        else errData = hDataEff->GetBinError(aetabin,ptbin);

        float effMc = hMcEff->GetBinContent(aetabin,ptbin);
        float errMc = 0.0; 
        if (hMcEff) errMc = hMcEff->GetBinContent(aetabin,ptbin);
        else errMc = hMcEff->GetBinError(aetabin,ptbin);

        if (ptbin == hDataEff->GetNbinsY() ) ptmax = 8000.; // highest is open, current recommendation
        if (aetabin == hDataEff->GetNbinsX()  ) aetamax = aetamax+0.0001; // put it slightly larger  to get 2.4 as well
        add(ptmin,ptmax,aetamin,aetamax,effData,effMc,errData,errMc);
    }
    f->Close(); // delete?
    delete f;
    f = NULL;
}
void SetBorders( TH2 &hist, Double_t val=0 )
{
    int numx = hist.GetNbinsX();
    int numy = hist.GetNbinsY();

    for(int i=0; i <= numx+1 ; i++){
        hist.SetBinContent(i,0,val);
        hist.SetBinContent(i,numy+1,val);
    }
    for(int i=0; i <= numy+1 ; i++) {
        hist.SetBinContent(0,i,val);
        hist.SetBinContent(numx+1,i,val);
    }
}
Пример #4
0
// normalize migmatrix column-wise
TH2* normalizeMigMat(TH2* h)
{
  TH2* hclone = (TH2*) h->Clone();
  const int xbins = hclone->GetNbinsX();
  const int ybins = hclone->GetNbinsY();
    
  for(int x=0; x<xbins; x++)  
  {
    double integ = hclone->Integral(x+1, x+1, 1, ybins);
    for(int y=0; y<ybins; y++)
    {
      hclone->SetBinContent(x+1,y+1, hclone->GetBinContent(x+1, y+1)/integ);
    }
  }
  
  return hclone;
}
void MirrorBorders( TH2& hist ) {
    int numx = hist.GetNbinsX();
    int numy = hist.GetNbinsY();

    Float_t val;
    // corner points
    hist.SetBinContent(0,0,hist.GetBinContent(1,1));
    hist.SetBinContent(numx+1,numy+1,hist.GetBinContent(numx,numy));
    hist.SetBinContent(numx+1,0,hist.GetBinContent(numx,1));
    hist.SetBinContent(0,numy+1,hist.GetBinContent(1,numy));

    for(int i=1; i<=numx; i++){
        hist.SetBinContent(i,0,	   hist.GetBinContent(i,1));
        hist.SetBinContent(i,numy+1, hist.GetBinContent(i,numy));
    }
    for(int i=1; i<=numy; i++) {
        hist.SetBinContent(0,i,      hist.GetBinContent(1,i));
        hist.SetBinContent(numx+1,i, hist.GetBinContent(numx,i));
    }
}
Пример #6
0
TH2* smoothHoles(const TH2* originalHist)
{
  TH2* hist = (TH2*)originalHist->Clone("_smoothed");
  int xMax = hist->GetNbinsX();
  int yMax = hist->GetNbinsY();

  int xMin = 0;
  
  for(int xBin = 1; xBin <= xMax; xBin++)
    {
      for(int yBin = 1; yBin <= yMax; yBin++)
	{
	  if(hist->GetBinContent(xBin,yBin)>0)
	    {
	      xMin = xBin;
	      yBin = yMax+1;
	      xBin = xMax+1;
	    }
	}
    } 
  //  for(unsigned int i = 0; i< 1000; i++) smoothHistAcross(hist,xMin);
  for(unsigned int i = 0; i< 1000; i++) interpolateHistAcross(hist,xMin);
  return hist;
}
Пример #7
0
TH1 *
UnfoldMe_MB2(const Char_t *data, const Char_t *mc, const Char_t *anatag, Int_t bin, Bool_t useMBcorr , Bool_t usecorrfit , Bool_t ismc , Float_t smooth , Int_t iter , Int_t regul , Float_t weight , Bool_t bayesian , Int_t nloop )
{

  // MF comments:
  // usedMBcorr: changes the matrix used for unfonding, from effMatrix to bin matrix (I think this is just to use mult dependent v s mb correction_)
  // usecorrfit: if I understand correctly, fits the response matrix and uses fit to extrapolate it

  
  TFile *fdt =0;
  if (ismc)
    fdt =  TFile::Open(data);
  else
    fdt = TFile::Open(data);
  TFile *fmc = TFile::Open(mc);

  TList *ldt = (TList *)fdt->Get(Form("%s", anatag));
  TList *lmc = (TList *)fmc->Get(Form("%s", anatag));
  
  TH2 *hmatdt = (TH2 *)ldt->FindObject(Form(responseMatrix, bin));
  TH2 *hmatmc = 0;
  if (useMBcorr){
     hmatmc = (TH2 *)lmc->FindObject("effMatrix");
     std::cout << "USING MB" << std::endl;
     
  }
  else {
    hmatmc = (TH2 *)lmc->FindObject(Form(responseMatrix, bin));
  }

  TH1 *hdata = hmatdt->ProjectionY("hdata");
//  TH1 *hdata = hmatdt->ProjectionY("htrue");  // For truth Only Calculations

  hdata->Sumw2();
  hdata->SetBinContent(1, 0.);
  hdata->SetBinError(1, 0.);
  //  hdata->Scale(1. / hdata->Integral());
  hdata->SetMarkerStyle(25);
  TH1 *htrue = hmatdt->ProjectionX("htrue");
  htrue->Sumw2();
  //  htrue->Scale(1. / htrue->Integral());
  htrue->SetMarkerStyle(7);
  htrue->SetMarkerColor(2);
  htrue->SetBinContent(1, 0.);
  htrue->SetBinError(1, 0.);

  TH2 *hcorr = (TH2 *)hmatmc->Clone("hcorr");
  TH1 *hinit = (TH1 *)hdata->Clone("hinit");
  TH1 *hresu = (TH1 *)hdata->Clone("hresu");
  TH1 *hbias = (TH1 *)hdata->Clone("hbias");
  hresu->SetMarkerStyle(20);
  hresu->SetMarkerColor(4);
  hresu->Reset();

  TH1 *hnum = hcorr->ProjectionY("hnum");
  TH1 *hden = hcorr->ProjectionY("hden");
  TH1 *heff = hcorr->ProjectionY("heff");
  hnum->Reset();
  hnum->Sumw2();
  hden->Reset();
  hden->Sumw2();
  heff->Reset();
  for (Int_t i = 0; i < heff->GetNbinsX(); i++) {
    Float_t int1 = hcorr->Integral(i + 1, i + 1, 0, -1);
    if (int1 <= 0.) continue;
    Float_t int2 = hcorr->Integral(i + 1, i + 1, 2, -1);
    hnum->SetBinContent(i + 1, int2);
    hnum->SetBinError(i + 1, TMath::Sqrt(int2));
    hden->SetBinContent(i + 1, int1);
    hden->SetBinError(i + 1, TMath::Sqrt(int1));
  }
  TCanvas *cEfficiency = new TCanvas("cEfficiency", "cEfficiency");
  cEfficiency->SetLogx();
  cEfficiency->SetLogy();

  heff->Divide(hnum, hden, 1., 1., "B");
  heff->Draw();
#if 0
  for (Int_t ii = 0; ii < heff->GetNbinsX(); ii++) {
    heff->SetBinContent(ii + 1, 1.);
    heff->SetBinError(ii + 1, 0.);
  }
#endif

  for (Int_t i = 0; i < hcorr->GetNbinsX(); i++) {
    hcorr->SetBinContent(i + 1, 1, 0.);
    hcorr->SetBinError(i + 1, 1, 0.);
  }
  for (Int_t i = 0; i < hcorr->GetNbinsY(); i++) {
    hcorr->SetBinContent(1, i + 1, 0.);
    hcorr->SetBinError(1, i + 1, 0.);
  }
  TH2 *hcorrfit = ReturnCorrFromFit(hcorr);
  // Docs from AliUnfolding
  //Int_t AliUnfolding::Unfold(TH2* correlation, TH1* efficiency, TH1* measured, TH1* initialConditions, TH1* result, Bool_t check)
  // unfolds with unfolding method fgMethodType
  //
  // parameters:
  //  correlation: response matrix as measured vs. generated
  //  efficiency:  (optional) efficiency that is applied on the unfolded spectrum, i.e. it has to be in unfolded variables. If 0 no efficiency is applied.
  //  measured:    the measured spectrum
  //  initialConditions: (optional) initial conditions for the unfolding. if 0 the measured spectrum is used as initial conditions.
  //  result:      target for the unfolded result
  //  check:       depends on the unfolding method, see comments in specific functions

  for (Int_t iloop = 0; iloop < nloop; iloop++) {
    if (bayesian) {
      AliUnfolding::SetUnfoldingMethod(AliUnfolding::kBayesian);
      AliUnfolding::SetBayesianParameters(smooth, iter);
    } else {
      AliUnfolding::SetUnfoldingMethod(AliUnfolding::kChi2Minimization);
      AliUnfolding::SetChi2Regularization(AliUnfolding::RegularizationType(regul), weight);
    }
    AliUnfolding::SetSkip0BinInChi2(kTRUE);
    AliUnfolding::SetSkipBinsBegin(1);
    AliUnfolding::SetNbins(150, 150);
    AliUnfolding::Unfold(usecorrfit ? hcorrfit : hcorr, heff, hdata, hinit, hresu);
    hinit = (TH1 *)hresu->Clone(Form("hinit_%d", iloop));
  }

  printf("hdata->Integral(2, -1) = %f\n", hdata->Integral(2, -1));
  printf("hresu->Integral(2, -1) = %f\n", hresu->Integral(2, -1));


  TCanvas *cUnfolded = new TCanvas ("cUnfolded", "cUnfolded", 400, 800);
  cUnfolded->Divide(1, 2);
  cUnfolded->cd(1)->SetLogx();
  cUnfolded->cd(1)->SetLogy();
  hdata->Draw();
  hresu->Draw("same");
  htrue->Draw("same");
  cUnfolded->cd(2)->SetLogx();
  cUnfolded->cd(2)->DrawFrame(1., 0, 300., 10);
  TH1 *hrat = (TH1 *)hresu->Clone("hrat");
  hrat->Divide(htrue);
  hrat->Draw("same");

  TH1 *htrig = (TH1 *)hresu->Clone("htrig");
  htrig->Multiply(heff); 
  

  Float_t dndeta_resu = 0.;
  Float_t integr_resu = 0.;
  Float_t dndeta_trig = 0.;
  Float_t integr_trig = 0.;
  for (Int_t i = 1; i < hresu->GetNbinsX(); i++) {
    dndeta_resu += hresu->GetBinContent(i + 1) * hresu->GetBinLowEdge(i + 1);
    integr_resu += hresu->GetBinContent(i + 1);
    dndeta_trig += htrig->GetBinContent(i + 1) * htrig->GetBinLowEdge(i + 1);
    integr_trig += htrig->GetBinContent(i + 1);
  }

  cUnfolded->SaveAs("unfold_efficiency.pdf");

  integr_eff = integr_trig / integr_resu;
  integr_eff_err = TMath::Sqrt(integr_eff * (1. - integr_eff) / integr_resu);
  dndeta_eff = dndeta_trig / dndeta_resu;
  dndeta_eff_err = TMath::Sqrt(dndeta_eff * (1. - dndeta_eff) / dndeta_resu);

  printf("INEL > 0 efficiency: %.3f +- %.3f\n", integr_eff, integr_eff_err);
  printf("dN/dEta correction:  %.3f +- %.3f\n", dndeta_eff, dndeta_eff_err);

  return hresu;
}
Пример #8
0
TH1 *
UnfoldMe(Char_t *data, Char_t *mc, Char_t *anatag, Int_t bin, Bool_t useMBcorr = kTRUE, Bool_t usecorrfit = kFALSE, Bool_t ismc = kFALSE, Float_t smooth = 0.001, Int_t iter = 50, Int_t regul = AliUnfolding::kPowerLaw, Float_t weight = 100., Bool_t bayesian = kTRUE, Int_t nloop = 1)
{

  if (ismc)
    TFile *fdt = TFile::Open(data);
  else
    TFile *fdt = TFile::Open(data);
  TFile *fmc = TFile::Open(mc);
  
  TList *ldt = (TList *)fdt->Get(Form("clist_%s", anatag));
  TList *lmc = (TList *)fmc->Get(Form("clist_%s", anatag));
  
  TH2 *hmatdt = (TH2 *)ldt->FindObject(Form("b%d_corrMatrix", bin));
  if (useMBcorr)
    TH2 *hmatmc = (TH2 *)lmc->FindObject("effMatrix");
  else
    TH2 *hmatmc = (TH2 *)lmc->FindObject(Form("b%d_corrMatrix", bin));
 
  TH1 *hdata = hmatdt->ProjectionY("hdata");
  hdata->Sumw2();
  hdata->SetBinContent(1, 0.);
  hdata->SetBinError(1, 0.);
  //  hdata->Scale(1. / hdata->Integral());
  hdata->SetMarkerStyle(25);
  TH1 *htrue = hmatdt->ProjectionX("htrue");
  htrue->Sumw2();
  //  htrue->Scale(1. / htrue->Integral());
  htrue->SetMarkerStyle(7);
  htrue->SetMarkerColor(2);
  htrue->SetBinContent(1, 0.);
  htrue->SetBinError(1, 0.);
  TH2 *hcorr = (TH2 *)hmatmc->Clone("hcorr");
  TH1 *hinit = (TH1 *)hdata->Clone("hinit");
  TH1 *hresu = (TH1 *)hdata->Clone("hresu");
  TH1 *hbias = (TH1 *)hdata->Clone("hbias");
  hresu->SetMarkerStyle(20);
  hresu->SetMarkerColor(4);
  hresu->Reset();

  TH1 *hnum = hcorr->ProjectionY("hnum");
  TH1 *hden = hcorr->ProjectionY("hden");
  TH1 *heff = hcorr->ProjectionY("heff");
  hnum->Reset();
  hnum->Sumw2();
  hden->Reset();
  hden->Sumw2();
  heff->Reset();
  for (Int_t i = 0; i < heff->GetNbinsX(); i++) {
    Float_t int1 = hcorr->Integral(i + 1, i + 1, 0, -1);
    if (int1 <= 0.) continue;
    Float_t int2 = hcorr->Integral(i + 1, i + 1, 2, -1);
    hnum->SetBinContent(i + 1, int2);
    hnum->SetBinError(i + 1, TMath::Sqrt(int2));
    hden->SetBinContent(i + 1, int1);
    hden->SetBinError(i + 1, TMath::Sqrt(int1));
  }
  new TCanvas("cEfficiency");
  heff->Divide(hnum, hden, 1., 1., "B");
  heff->Draw();
#if 0
  for (Int_t ii = 0; ii < heff->GetNbinsX(); ii++) {
    heff->SetBinContent(ii + 1, 1.);
    heff->SetBinError(ii + 1, 0.);
  }
#endif
  
  for (Int_t i = 0; i < hcorr->GetNbinsX(); i++) {
    hcorr->SetBinContent(i + 1, 1, 0.);
    hcorr->SetBinError(i + 1, 1, 0.);
  }
  for (Int_t i = 0; i < hcorr->GetNbinsY(); i++) {
    hcorr->SetBinContent(1, i + 1, 0.);
    hcorr->SetBinError(1, i + 1, 0.);
  }
  TH2 *hcorrfit = ReturnCorrFromFit(hcorr);

  for (Int_t iloop = 0; iloop < nloop; iloop++) {
    if (bayesian) {
      AliUnfolding::SetUnfoldingMethod(AliUnfolding::kBayesian);
      AliUnfolding::SetBayesianParameters(smooth, iter);
    } else {
      AliUnfolding::SetUnfoldingMethod(AliUnfolding::kChi2Minimization);
      AliUnfolding::SetChi2Regularization(regul, weight);
    }
    AliUnfolding::SetSkip0BinInChi2(kTRUE);
    AliUnfolding::SetSkipBinsBegin(1);
    AliUnfolding::SetNbins(150, 150);
    AliUnfolding::Unfold(usecorrfit ? hcorrfit : hcorr, heff, hdata, hinit, hresu);
    hinit = (TH1 *)hresu->Clone(Form("hinit_%d", iloop));
  }

  printf("hdata->Integral(2, -1) = %f\n", hdata->Integral(2, -1));
  printf("hresu->Integral(2, -1) = %f\n", hresu->Integral(2, -1));
  
  
  TCanvas *cUnfolded = new TCanvas ("cUnfolded", "", 400, 800);
  cUnfolded->Divide(1, 2);
  cUnfolded->cd(1)->SetLogx();
  cUnfolded->cd(1)->SetLogy();
  hdata->Draw();
  hresu->Draw("same");
  htrue->Draw("same");
  cUnfolded->cd(2)->SetLogx();
  cUnfolded->cd(2)->DrawFrame(1., 0.75, 300., 1.25);
  TH1 *hrat = (TH1 *)hresu->Clone("hrat");
  hrat->Divide(htrue);
  hrat->Draw("same");

  TH1 *htrig = (TH1 *)hresu->Clone("htrig");
  htrig->Multiply(heff);

  Float_t dndeta_resu = 0.;
  Float_t integr_resu = 0.;
  Float_t dndeta_trig = 0.;
  Float_t integr_trig = 0.;
  for (Int_t i = 1; i < hresu->GetNbinsX(); i++) {
    dndeta_resu += hresu->GetBinContent(i + 1) * hresu->GetBinLowEdge(i + 1);
    integr_resu += hresu->GetBinContent(i + 1);
    dndeta_trig += htrig->GetBinContent(i + 1) * htrig->GetBinLowEdge(i + 1);
    integr_trig += htrig->GetBinContent(i + 1);
  }
  //  dndeta_resu /= integr_resu;
  //  dndeta_trig /= integr_trig;

  integr_eff = integr_trig / integr_resu;
  integr_eff_err = TMath::Sqrt(integr_eff * (1. - integr_eff) / integr_resu);
  dndeta_eff = dndeta_trig / dndeta_resu;
  dndeta_eff_err = TMath::Sqrt(dndeta_eff * (1. - dndeta_eff) / dndeta_resu);
  
  printf("INEL > 0 efficiency: %.3f +- %.3f\n", integr_eff, integr_eff_err);
  printf("dN/dEta correction:  %.3f +- %.3f\n", dndeta_eff, dndeta_eff_err);

  return hresu;
}
Пример #9
0
void
TestSPD(const TString& which, Double_t nVar=2)
{
  TFile* file = TFile::Open("forward.root", "READ");
  if (!file) return;

  Bool_t spd = which.EqualTo("spd", TString::kIgnoreCase);
  
  TList* l = 0;
  if (spd) l = static_cast<TList*>(file->Get("CentralSums"));
  else     l = static_cast<TList*>(file->Get("ForwardSums"));
  if (!l) { 
    Warning("", "%sSums not found", spd ? "Central" : "Forward");
    return;
  }

  TList* ei = static_cast<TList*>(l->FindObject("fmdEventInspector"));
  if (!l) { 
    Warning("", "fmdEventInspector not found");
    return;
  }
  
  TObject* run = ei->FindObject("runNo");
  if (!run) 
    Warning("", "No run number found");
  ULong_t runNo = run ? run->GetUniqueID() : 0;

  TH2* h = 0;
  if (spd) h = static_cast<TH2*>(l->FindObject("nClusterVsnTracklet"));
  else { 
    TList* den = static_cast<TList*>(l->FindObject("fmdDensityCalculator"));
    if (!den) { 
      Error("", "fmdDensityCalculator not found");
      return;
    }
    TList* rng = static_cast<TList*>(den->FindObject(which));
    if (!rng) { 
      Error("", "%s not found", which.Data());
      return;
    }
    h = static_cast<TH2*>(rng->FindObject("elossVsPoisson"));
  }
  if (!h) { 
    Warning("", "%s not found", spd ? nClusterVsnTracklet : "elossVsPoisson");
    return;
  }

  gStyle->SetOptFit(1111);
  gStyle->SetOptStat(0);
  TCanvas* c = new TCanvas("c", Form("Run %u", runNo));
  c->Divide(2,2);
  
  TVirtualPad* p = c->cd(1);
  if (spd) {
    p->SetLogx();
    p->SetLogy();
  }
  p->SetLogz();
  h->Draw("colz");

  TObjArray* fits = new TObjArray;
  h->FitSlicesY(0, 1, -1, 0, "QN", fits);

  TF1* mean = new TF1("mean", "pol1");
  TF1* var  = new TF1("var", "pol1");
  // mean->FixParameter(0, 0);
  // var->FixParameter(0, 0);
  for (Int_t i = 0; i < 3; i++) { 
    p = c->cd(2+i);
    if (spd) { 
      p->SetLogx();
      p->SetLogy();
    }
    TH1* hh = static_cast<TH1*>(fits->At(i));
    hh->Draw();

    if (i == 0) continue;
    
    hh->Fit((i == 1? mean : var), "+Q");
    
  }

  TGraphErrors* g1 = new TGraphErrors(h->GetNbinsX());
  g1->SetFillColor(kBlue-10);
  g1->SetFillStyle(3001);
  g1->SetLineStyle(1);
  TGraph* u1 = new TGraph(h->GetNbinsX());
  TGraph* l1 = new TGraph(h->GetNbinsX());
  u1->SetLineColor(kBlue+1);
  l1->SetLineColor(kBlue+1);
  u1->SetName("u1");
  l1->SetName("l1");
  TGraphErrors* g2 = new TGraphErrors(h->GetNbinsX());
  g2->SetFillColor(kRed-10);
  g2->SetFillStyle(3001);
  g2->SetLineStyle(2);
  TGraph* u2 = new TGraph(h->GetNbinsX());
  TGraph* l2 = new TGraph(h->GetNbinsX());
  u2->SetLineColor(kRed+1);
  l2->SetLineColor(kRed+1);
  u2->SetName("u2");
  l2->SetName("l2");
  for (Int_t i = 1; i <= h->GetNbinsX(); i++) {
    Double_t x  = hh->GetXaxis()->GetBinCenter(i);
    Double_t y  = mean->Eval(x);
    Double_t e  = var->Eval(y);
    Double_t e1 = nVar * e;
    if (spd) e1 *= TMath::Log10(e);
    // Printf("%10e -> %10e +/- %10e", x, y, ee);
    g1->SetPoint(i-1, x, y);
    g1->SetPointError(i-1, 0, e1);
    u1->SetPoint(i-1, x, y+e1);
    l1->SetPoint(i-1, x, y-e1);
    // Printf("%3d: %f -> %f +/- %f", i, x, y, ee);

    Double_t e2 = nVar*0.05*x;
    g2->SetPoint(i-1, x, x);
    g2->SetPointError(i-1, 0, e2);
    u2->SetPoint(i-1, x, x+e2);
    l2->SetPoint(i-1, x, x-e2);
  }

  p = c->cd(1);
  c->Clear();
  c->cd();
  c->SetLogz();
  h->Draw("colz");
  g1->Draw("3 same");
  u1->Draw("l same");
  l1->Draw("l same");
  g2->Draw("3 same");
  u2->Draw("l same");
  l2->Draw("l same");

  Double_t ly = 0.9;
  Double_t dy = 0.06;
  TLatex* ltx = new TLatex(0.15, ly, Form("#LTy#GT = %f + %f x",
					   mean->GetParameter(0),
					   mean->GetParameter(1)));
  ltx->SetNDC();
  ltx->SetTextSize(dy);
  ltx->SetTextAlign(13);
  ltx->Draw();

  ly -= dy + 0.01;
  ltx->DrawLatex(0.15, ly, Form("#sigma_{y} = %f + %f x", 
				var->GetParameter(0),
				var->GetParameter(1)));
  
  ly -= dy + 0.01;
  ltx->DrawLatex(0.15, ly, Form("#delta = %f #sigma %s", 
				nVar, (spd ? "log_{10}(#sigma" : "")));
	    
					   
}
Пример #10
0
//
// fill missing bins in histogram h fitting a plane to the
//   surrounding bins
//
void fitQuadratic (TH2* h, TH2* refHisto, int nmin=9, int nmin2=12) {
    //
    // prepare histogram
    //
    TH2* hOrig = (TH2*)h->Clone();
    int nbx = hOrig->GetNbinsX();
    int nby = hOrig->GetNbinsY();
    //
    // matrix and vector for fit
    //
    TMatrixD mat(6,6);
    TVectorD cvec(6);
    //
    // loop over histogram
    //
    for ( int ix=1; ix<=nbx; ++ix ) {
        for ( int iy=1; iy<=nby; ++iy ) {
            // clear matrix and vector used for fit
            int nn(0);
            for ( int i=0; i<6; ++i ) {
                cvec(i) = 0.;
                for ( int j=0; j<6; ++j ) mat(i,j) = 0.;
            }
            // loop over neighbours
            for ( int jx=-1; jx<2; ++jx ) {
                for ( int jy=-1; jy<2; ++jy ) {
                    if ( (ix+jx)<1 || (ix+jx)>nbx )  continue;
                    if ( (iy+jy)<1 || (iy+jy)>nby )  continue;
                    // fill vector and matrix
                    fillForQuadFit(hOrig,refHisto,ix,iy,jx,jy,nn,mat,cvec);
                }
            }
            for ( int jx=1; jx<6; ++jx ) {
                for ( int jy=0; jy<jx; ++jy )  mat(jx,jy) = mat(jy,jx);
            }
            // if < nmin neighbours in delta_i==1: try to add delta_i==2
            if ( nn<nmin ) {
                // loop over neighbours
                for ( int jx=-2; jx<3; ++jx ) {
                    for ( int jy=-2; jy<3; ++jy ) {
                        // skip the central bin (the one to be filled)
                        if ( abs(jx)<2 && abs(jy)<2 )  continue;
                        if ( (ix+jx)<1 || (ix+jx)>nbx )  continue;
                        if ( (iy+jy)<1 || (iy+jy)>nby )  continue;
                        // fill vector and matrix
                        fillForQuadFit(hOrig,refHisto,ix,iy,jx,jy,nn,mat,cvec);
                    }
                }
                for ( int jx=1; jx<6; ++jx ) {
                    for ( int jy=0; jy<jx; ++jy )  mat(jx,jy) = mat(jy,jx);
                }
                // drop bin if <nmin2 in 5x5 area
                if ( nn<nmin2 ) continue;
            }
//       cout << "x / y = " << h->GetXaxis()->GetBinCenter(ix) << " "
//                          << h->GetYaxis()->GetBinCenter(iy) << endl;
            //
            // linear 2D fit to neighbours (in units of bin number):
            //   par(0)*(x-ix)+par(1)*(y-iy)+par(2)
            //
            double det = mat.Determinant();
            if ( det < 1.e-6 )  std::cout << "************* " << det << std::endl;
            if ( det < 1.e-6 )  continue;
//       TMatrixD mat1(mat);
            mat.Invert(&det);
            TVectorD par = mat*cvec;
//       TVectorD tmp = mat1*par;
            h->SetBinContent(ix,iy,par(5));
        }
    }
    delete hOrig;
}
void fullPedestalAnalysis(string inputDIR, string outputDIR, string inputCablingMap, string outputFileName){

  gROOT->ProcessLine("gErrorIgnoreLevel = 1");
  
  // open the file and prepare the cluster tree, adding the other trees as frined --> memory consuming                                                                                                
  std::cout<<"##################################"<<std::endl;
  std::cout<<"###### fullPedestalAnalysis ######"<<std::endl;
  std::cout<<"##################################"<<std::endl;

  clock_t tStart = clock();

  // prepare style and load macros                                                                                                                                                                    
  setTDRStyle();
  gROOT->SetBatch(kTRUE);

  system(("mkdir -p "+outputDIR).c_str());
  ifstream file;

  std::cout<<"### Make input file list"<<std::endl;
  system(("find "+inputDIR+" -name \"*.root\" > file.temp").c_str());
  std::ifstream infile;
  string line;
  vector<string> fileList;
  infile.open("file.temp",ifstream::in);
  if(infile.is_open()){
    while(!infile.eof()){
      getline(infile,line);
      if(line != "" and TString(line).Contains(".root") and line !="\n"){
        fileList.push_back(line);
      }
    }
  }
  system("rm file.temp");
  std::sort(fileList.begin(),fileList.end());

  TFile* cablingFile = TFile::Open(inputCablingMap.c_str(),"READ");
  cablingFile->cd();
  TTree* readoutMap = (TTree*) cablingFile->FindObjectAny("readoutMap");
  TTreeReader reader(readoutMap);
  TTreeReaderValue<uint32_t> detid    (reader,"detid");
  TTreeReaderValue<uint16_t> fecCrate (reader,"fecCrate");
  TTreeReaderValue<uint16_t> fecSlot  (reader,"fecSlot");
  TTreeReaderValue<uint16_t> fecRing  (reader,"fecRing");
  TTreeReaderValue<uint16_t> ccuAdd   (reader,"ccuAdd");
  TTreeReaderValue<uint16_t> ccuChan  (reader,"ccuChan");
  TTreeReaderValue<uint16_t> lldChannel  (reader,"lldChannel");
  TTreeReaderValue<uint16_t> fedId  (reader,"fedId");
  TTreeReaderValue<uint16_t> fedCh  (reader,"fedCh");

  // output tree
  TFile* ouputTreeFile = new TFile((outputDIR+"/"+outputFileName).c_str(),"RECREATE");
  ouputTreeFile->cd();
  ouputTreeFile->SetCompressionLevel(0);
  TTree* outputTree = new TTree("pedestalFullNoise","pedestalFullNoise");
  
  // branches
  uint32_t detid_,fedKey_;
  uint16_t fecCrate_,fecSlot_, fecRing_, ccuAdd_, ccuChan_, lldChannel_, fedId_, fedCh_, apvId_, stripId_;
  float    noiseMean_,noiseRMS_, noiseSkewness_, noiseKurtosis_;
  float    fitChi2_, fitChi2Probab_, fitStatus_;
  float    fitGausMean_, fitGausSigma_, fitGausNormalization_;
  float    fitGausMeanError_, fitGausSigmaError_, fitGausNormalizationError_;
  float    noiseIntegral3Sigma_, noiseIntegral3SigmaFromFit_;
  float    noiseIntegral4Sigma_, noiseIntegral4SigmaFromFit_;
  float    noiseIntegral5Sigma_, noiseIntegral5SigmaFromFit_;
  float    kSValue_, kSProbab_, jBValue_, jBProbab_, aDValue_, aDProbab_;
  vector<float> noiseDistribution_, noiseDistributionError_;
  float xMin_, xMax_, nBin_ ;

  outputTree->Branch("detid",&detid_,"detid/i");
  outputTree->Branch("fedKey",&fedKey_,"fedKey/i");
  outputTree->Branch("fecCrate",&fecCrate_,"fecCrate/s");
  outputTree->Branch("fecSlot",&fecSlot_,"fecSlot/s");
  outputTree->Branch("fecRing",&fecRing_,"fecRing/s");
  outputTree->Branch("ccuAdd",&ccuAdd_,"ccuAdd/s");
  outputTree->Branch("ccuChan",&ccuChan_,"ccuChan/s");
  outputTree->Branch("lldChannel",&lldChannel_,"lldChannel/s");
  outputTree->Branch("fedId",&fedId_,"fedId/s");
  outputTree->Branch("fedCh",&fedCh_,"fedCh/s");
  outputTree->Branch("apvId",&apvId_,"apvId/s");
  outputTree->Branch("stripId",&stripId_,"stripId/s");

  outputTree->Branch("noiseMean",&noiseMean_,"noiseMean/F");
  outputTree->Branch("noiseRMS",&noiseRMS_,"noiseRMS/F");
  outputTree->Branch("noiseSkewness",&noiseSkewness_,"noiseSkewness/F");
  outputTree->Branch("noiseKurtosis",&noiseKurtosis_,"noiseKurtosis/F");
  outputTree->Branch("fitGausNormalization",&fitGausNormalization_,"fitGausNormalization/F");
  outputTree->Branch("fitGausMean",&fitGausMean_,"fitGausMean/F");
  outputTree->Branch("fitGausSigma",&fitGausSigma_,"fitGausSigma/F");
  outputTree->Branch("fitGausNormalizationError",&fitGausNormalizationError_,"fitGausNormalizationError/F");
  outputTree->Branch("fitGausMeanError",&fitGausMeanError_,"fitGausMeanError/F");
  outputTree->Branch("fitGausSigmaError",&fitGausSigmaError_,"fitGausSigmaError/F");
  outputTree->Branch("fitChi2",&fitChi2_,"fitChi2/F");
  outputTree->Branch("fitChi2Probab",&fitChi2Probab_,"fitChi2Probab/F");
  outputTree->Branch("fitStatus",&fitStatus_,"fitStatus_F");
  outputTree->Branch("noiseIntegral3Sigma",&noiseIntegral3Sigma_,"noiseIntegral3Sigma/F");
  outputTree->Branch("noiseIntegral3SigmaFromFit",&noiseIntegral3SigmaFromFit_,"noiseIntegral3SigmaFromFit/F");
  outputTree->Branch("noiseIntegral4Sigma",&noiseIntegral4Sigma_,"noiseIntegral4Sigma/F");
  outputTree->Branch("noiseIntegral4SigmaFromFit",&noiseIntegral4SigmaFromFit_,"noiseIntegral4SigmaFromFit/F");
  outputTree->Branch("noiseIntegral5Sigma",&noiseIntegral4Sigma_,"noiseIntegral5Sigma/F");
  outputTree->Branch("noiseIntegral5SigmaFromFit",&noiseIntegral4SigmaFromFit_,"noiseIntegral5SigmaFromFit/F");
  outputTree->Branch("kSValue",&kSValue_,"kSValue/F");
  outputTree->Branch("jBValue",&jBValue_,"jBValue/F");
  outputTree->Branch("aDValue",&aDValue_,"aDValue/F");
  outputTree->Branch("kSProbab",&kSProbab_,"kSProbab/F");
  outputTree->Branch("jBProbab",&jBProbab_,"jBProbab/F");
  outputTree->Branch("aDProbab",&aDProbab_,"aDProbab/F");
  outputTree->Branch("xMin",&xMin_,"xMin/F");
  outputTree->Branch("xMax",&xMax_,"xMax/F");
  outputTree->Branch("nBin",&nBin_,"nBin/F");

  bool histoBranches = false;

  // Loop on the file list to extract each histogram 2D DQM histo with full noise distribution  
  TH1F* histoNoiseStrip = NULL;
  TF1*  fitFunc = NULL;
  TH1F* randomHisto = NULL;
  TFitResultPtr result;
  for(auto file : fileList){
    cout<<"input file: "<<file<<endl;
    TFile* inputFile = TFile::Open(file.c_str(),"READ");
    inputFile->cd();
    // take into account that the DQM file structure for strips is always the same --> use cabling map to browse the histograms
    reader.SetEntry(0);
    TH2* histoNoise = NULL;
    long int iChannel = 0;
    int noFitResult = 0;
    while(reader.Next()){
      cout.flush();
      if(iChannel %10 == 0) cout<<"\r"<<"iChannel "<<100*double(iChannel)/(readoutMap->GetEntries()/reductionFactor)<<" % ";
      if(iChannel > double(readoutMap->GetEntries())/reductionFactor) break;
      iChannel++;
      TString objName;
      uint32_t fedKey =  SiStripFedKey(*fedId,SiStripFedKey::feUnit(*fedCh),SiStripFedKey::feChan(*fedCh)).key();
      std::stringstream stream;
      stream << std::hex << fedKey;
      string fedKeyStr = stream.str();
      if(fedKeyStr.size() == 4)
	objName = Form("DQMData/SiStrip/ControlView/FecCrate%d/FecSlot%d/FecRing%d/CcuAddr%d/CcuChan%d/ExpertHisto_PedsFullNoise_FedKey0x0000%s_LldChannel%d_Noise2D",*fecCrate,*fecSlot,*fecRing,*ccuAdd,*ccuChan,fedKeyStr.c_str(),*lldChannel);      
      else if(fedKeyStr.size() == 5)
	objName = Form("DQMData/SiStrip/ControlView/FecCrate%d/FecSlot%d/FecRing%d/CcuAddr%d/CcuChan%d/ExpertHisto_PedsFullNoise_FedKey0x000%s_LldChannel%d_Noise2D",*fecCrate,*fecSlot,*fecRing,*ccuAdd,*ccuChan,fedKeyStr.c_str(),*lldChannel);      
      else
	cerr<<"hex number to short "<<fedKeyStr<<" --> please check "<<endl;

      inputFile->GetObject(objName.Data(),histoNoise);
      // extract single strip noise histogram --> loop on the y-axis
      uint16_t apvID = 0;
      uint16_t stripID = 0;       
      if(histoNoiseStrip == 0 or histoNoiseStrip == NULL){
	histoNoiseStrip = new TH1F ("histoNoiseStrip","",histoNoise->GetNbinsX(),histoNoise->GetXaxis()->GetXmin(),histoNoise->GetXaxis()->GetXmax());
	histoNoiseStrip->Sumw2();
      }
      for(int iBinY = 0; iBinY < histoNoise->GetNbinsY(); iBinY++){
	histoNoiseStrip->Reset();
	histoNoiseStrip->SetDirectory(0);
	// two multiplexed APV per line
	if(iBinY < histoNoise->GetNbinsY()/2) apvID = 1;
	else apvID = 2;
	// strip id
	stripID++;
	if(stripID > 128) stripID = 1;
	// loop on x-axis bin
	for(int iBinX = 0; iBinX < histoNoise->GetNbinsX(); iBinX++){
	  histoNoiseStrip->SetBinContent(iBinX+1,histoNoise->GetBinContent(iBinX+1,iBinY+1));
	  histoNoiseStrip->SetBinError(iBinX+1,histoNoise->GetBinError(iBinX+1,iBinY+1));	    
	}
     	
	// to initialize branches
	detid_ = 0; fedKey_ = 0; fecCrate_ = 0; fecSlot_ = 0; fecRing_ = 0; ccuAdd_ = 0; ccuChan_ = 0; lldChannel_ = 0; fedId_ = 0; fedCh_ = 0; apvId_ = 0; stripId_ = 0; 
	noiseMean_ = 0.; noiseRMS_ =  0.; noiseSkewness_ = 0.; noiseKurtosis_ = 0.; 
	fitGausMean_ = 0.; fitGausSigma_ = 0.;fitGausNormalization_ = 0.;
	fitGausMeanError_ = 0.; fitGausSigmaError_ = 0.;fitGausNormalizationError_ = 0.;	  	  
	fitChi2_ = 0.; fitChi2Probab_ = 0.; fitStatus_ = -1.; 
	noiseIntegral3Sigma_ = 0.; noiseIntegral3SigmaFromFit_ = 0.; 
	noiseIntegral4Sigma_ = 0.; noiseIntegral4SigmaFromFit_ = 0.; 
	noiseIntegral5Sigma_ = 0.; noiseIntegral5SigmaFromFit_ = 0.; 
	kSProbab_ = 0.; jBProbab_ = 0.;
	kSValue_ = 0.; jBValue_ = 0.; 
	aDValue_= 0.; aDProbab_ = 0.;
	nBin_ = 0.; xMin_ = 0.; xMax_ = 0.;
	
	// basic info
	detid_ = *detid;
	fedKey_ = fedKey;
	fecCrate_ = *fecCrate;
	fecSlot_ = *fecSlot;
	fecRing_ = *fecRing;
	ccuAdd_  = *ccuAdd;
	ccuChan_ = *ccuChan;
	lldChannel_ = *lldChannel;
	fedId_   = *fedId;
	fedCh_   = *fedCh;
	apvId_   = apvID;
	stripId_ = stripID;
	
	// basic info of nioise distribution
	noiseMean_ = histoNoiseStrip->GetMean();
	noiseRMS_  = histoNoiseStrip->GetRMS();
	noiseSkewness_ = histoNoiseStrip->GetSkewness();
	noiseKurtosis_ = histoNoiseStrip->GetKurtosis();
	float integral = histoNoiseStrip->Integral();	
	noiseIntegral3Sigma_ = (histoNoiseStrip->Integral(histoNoiseStrip->FindBin(noiseMean_+noiseRMS_*3),histoNoiseStrip->GetNbinsX()+1) + histoNoiseStrip->Integral(0,histoNoiseStrip->FindBin(noiseMean_-noiseRMS_*3)))/integral;
	noiseIntegral4Sigma_ = (histoNoiseStrip->Integral(histoNoiseStrip->FindBin(noiseMean_+noiseRMS_*4),histoNoiseStrip->GetNbinsX()+1) + histoNoiseStrip->Integral(0,histoNoiseStrip->FindBin(noiseMean_-noiseRMS_*4)))/integral;
	noiseIntegral5Sigma_ = (histoNoiseStrip->Integral(histoNoiseStrip->FindBin(noiseMean_+noiseRMS_*5),histoNoiseStrip->GetNbinsX()+1) + histoNoiseStrip->Integral(0,histoNoiseStrip->FindBin(noiseMean_-noiseRMS_*5)))/integral;
	
	// make a gaussian fit	  	
	if(fitFunc == NULL or fitFunc == 0){
	  fitFunc = new TF1 ("fitFunc","gaus(0)",histoNoise->GetXaxis()->GetXmin(),histoNoise->GetXaxis()->GetXmax());
	}
	fitFunc->SetRange(histoNoise->GetXaxis()->GetXmin(),histoNoise->GetXaxis()->GetXmax());
	fitFunc->SetParameters(histoNoiseStrip->Integral(),noiseMean_,noiseRMS_);
	result = histoNoiseStrip->Fit(fitFunc,"QSR");

	if(result.Get()){
	    fitStatus_     = result->Status();
	    fitGausNormalization_  = fitFunc->GetParameter(0);
	    fitGausMean_   = fitFunc->GetParameter(1);
	    fitGausSigma_  = fitFunc->GetParameter(2);
	    fitGausNormalizationError_  = fitFunc->GetParError(0);
	    fitGausMeanError_  = fitFunc->GetParError(1);
	    fitGausSigmaError_ = fitFunc->GetParError(2);
	    fitChi2_           = result->Chi2();
	    fitChi2Probab_     = result->Prob();

	    noiseIntegral3SigmaFromFit_ = (histoNoiseStrip->Integral(histoNoiseStrip->FindBin(noiseMean_+fitGausSigma_*3),histoNoiseStrip->GetNbinsX()+1) + histoNoiseStrip->Integral(0,histoNoiseStrip->FindBin(noiseMean_-fitGausSigma_*3)))/histoNoiseStrip->Integral();
	    noiseIntegral4SigmaFromFit_ = (histoNoiseStrip->Integral(histoNoiseStrip->FindBin(noiseMean_+fitGausSigma_*4),histoNoiseStrip->GetNbinsX()+1) + histoNoiseStrip->Integral(0,histoNoiseStrip->FindBin(noiseMean_-fitGausSigma_*4)))/histoNoiseStrip->Integral();
	    noiseIntegral5SigmaFromFit_ = (histoNoiseStrip->Integral(histoNoiseStrip->FindBin(noiseMean_+fitGausSigma_*5),histoNoiseStrip->GetNbinsX()+1) + histoNoiseStrip->Integral(0,histoNoiseStrip->FindBin(noiseMean_-fitGausSigma_*5)))/histoNoiseStrip->Integral();
	    
	    jBValue_   = (histoNoiseStrip->Integral()/6)*(noiseSkewness_*noiseSkewness_+(noiseKurtosis_*noiseKurtosis_)/4);	  
	    jBProbab_  = ROOT::Math::chisquared_cdf_c(jBValue_,2);

	    if(randomHisto == 0 or randomHisto == NULL)
	      randomHisto = (TH1F*) histoNoiseStrip->Clone("randomHisto");	    	    
	    randomHisto->Reset();
	    randomHisto->SetDirectory(0);     
	
      
	    if(integral != 0){	      
	      if(generateRandomDistribution){
		randomHisto->FillRandom("fitFunc",histoNoiseStrip->Integral());	    
		kSValue_  = histoNoiseStrip->KolmogorovTest(randomHisto,"MN");
		kSProbab_ = histoNoiseStrip->KolmogorovTest(randomHisto,"N");	    
		aDValue_  = histoNoiseStrip->AndersonDarlingTest(randomHisto,"T");
		aDProbab_ = histoNoiseStrip->AndersonDarlingTest(randomHisto);
	      }
	      else{
		
		randomHisto->Add(fitFunc);		
		kSValue_  = histoNoiseStrip->KolmogorovTest(randomHisto,"MN"); 
		kSProbab_ = histoNoiseStrip->KolmogorovTest(randomHisto,"N");
		// AD test
		ROOT::Fit::BinData data1;
		ROOT::Fit::BinData data2;
		ROOT::Fit::FillData(data1,histoNoiseStrip,0);
		data2.Initialize(randomHisto->GetNbinsX()+1,1);
		for(int ibin = 0; ibin < randomHisto->GetNbinsX(); ibin++){ 
		  if(histoNoiseStrip->GetBinContent(ibin+1) != 0 or randomHisto->GetBinContent(ibin+1) >= 1)
		    data2.Add(randomHisto->GetBinCenter(ibin+1),randomHisto->GetBinContent(ibin+1),randomHisto->GetBinError(ibin+1));
		}
	  
		double probab;
		double value;
		ROOT::Math::GoFTest::AndersonDarling2SamplesTest(data1,data2,probab,value);
		aDValue_ = value;
		aDProbab_ = probab;
	      }
	    }
	}
	else
	  noFitResult++;
	
	if(not histoBranches){
	  noiseDistribution_.clear();
	  noiseDistributionError_.clear();
	  outputTree->Branch("noiseDistribution","vector<float>",&noiseDistribution_);
	  outputTree->Branch("noiseDistributionError","vector<float>",&noiseDistributionError_);
	  histoBranches = true;
	}
    
	// set histogram
	noiseDistribution_.clear();
	noiseDistributionError_.clear();
	for(int iBin = 0; iBin < histoNoiseStrip->GetNbinsX(); iBin++){
	  noiseDistribution_.push_back(histoNoiseStrip->GetBinContent(iBin+1));
	  noiseDistributionError_.push_back(histoNoiseStrip->GetBinError(iBin+1));	      
	}
    
	nBin_ = histoNoiseStrip->GetNbinsX();
	xMin_ = histoNoise->GetXaxis()->GetBinLowEdge(1);
	xMax_ = histoNoise->GetXaxis()->GetBinLowEdge(histoNoise->GetNbinsX()+1);

	// fill all branches for each strip
	ouputTreeFile->cd();
	outputTree->Fill();
      }
    }
    inputFile->Close();
    std::cout<<std::endl;
    cout<<"No fit results found for "<<100*double(noFitResult)/iChannel<<endl;
  }
  outputTree->BuildIndex("detid");
  outputTree->Write(outputTree->GetName(),TObject::kOverwrite);
  ouputTreeFile->Close();
  cablingFile->Close();

  /* Do your stuff here */
  cout<<"Time taken: "<<(double)(clock() - tStart)/CLOCKS_PER_SEC<<endl;  
}