ROOT logo
TH1 *
HistoUtils_weightedmean(TH1 *h1, TH1 *h2)
{

  TH1 *ho = (TH1 *)h1->Clone("ho");
  ho->Reset();
  Double_t val1, val2, w1, w2, mean, meane;
  for (Int_t i = 0; i < ho->GetNbinsX(); i++) {
    val1 = h1->GetBinContent(i + 1);
    w1 = 1. / (h1->GetBinError(i + 1) * h1->GetBinError(i + 1));
    val2 = h2->GetBinContent(i + 1);
    w2 = 1. / (h2->GetBinError(i + 1) * h2->GetBinError(i + 1));

    if (val1 == 0 && val2 == 0) continue;

    mean = (w1 * val1 + w2 * val2) / (w1 + w2);
    meane = TMath::Sqrt(1. / (w1 + w2));

    ho->SetBinContent(i + 1, mean);
    ho->SetBinError(i + 1, meane);
  }

  return ho;
}

//__________________________________________________________________

TH1 *
HistoUtils_smartdifference(TH1 *hnum, TH1 *hden)
{

  TH1 *hr = (TH1 *)hnum->Clone("hr");
  hr->Reset();
  Double_t ref;
  for (Int_t i = 0; i < hr->GetNbinsX(); i++) {
    if (hnum->GetBinError(i + 1) <= 0.) continue;
    ref = hden->Interpolate(hr->GetBinCenter(i + 1));
    if (ref <= 0.) continue;
    hr->SetBinContent(i + 1, (hnum->GetBinContent(i + 1) - ref) / ref);
    hr->SetBinError(i + 1, hnum->GetBinError(i + 1) / ref);
  }
  return hr;
}

//__________________________________________________________________

TH1 *
HistoUtils_smartratio(TH1 *hnum, TGraph *hden)
{

  TH1 *hr = (TH1 *)hnum->Clone("hr");
  hr->Reset();
  Double_t ref;
  for (Int_t i = 0; i < hr->GetNbinsX(); i++) {
    if (hnum->GetBinError(i + 1) <= 0.) continue;
    ref = hden->Eval(hr->GetBinCenter(i + 1));
    if (ref <= 0.) continue;
    hr->SetBinContent(i + 1, hnum->GetBinContent(i + 1) / ref);
    hr->SetBinError(i + 1, hnum->GetBinError(i + 1) / ref);
  }
  return hr;
}

//__________________________________________________________________

HistoUtils_drawthemall(const Char_t *filename, Int_t sleepms)
{
  TFile *f1 = TFile::Open(filename);
  TList *l1 = f1->GetListOfKeys();
  TObject *o;
  Char_t *name;
  for (Int_t i = 0; i < l1->GetEntries(); i++) {
    name = l1->At(i)->GetName();
    o = f1->Get(name);
    o->Draw();
    gPad->Update();
    gSystem->Sleep(sleepms);
  }
  f1->Close();
}

//__________________________________________________________________

HistoUtils_autoratio(const Char_t *f1name, const Char_t *f2name, const Char_t *outname)
{

  TFile *f1 = TFile::Open(f1name);
  TFile *f2 = TFile::Open(f2name);
  TFile *fo = TFile::Open(outname, "RECREATE");
  TList *l1 = f1->GetListOfKeys();


  TH1D *h1, *h2, *hr;
  Char_t *name;
  for (Int_t i = 0; i < l1->GetEntries(); i++) {
    name = l1->At(i)->GetName();
    h1 = (TH1D *)f1->Get(name);
    h2 = (TH1D *)f2->Get(name);
    if (!h1 || !h2) continue;
    hr = new TH1D(*h1);
    hr->Divide(h2);
    fo->cd();
    hr->Write();
  }

  delete hr;
  f1->Close();
  f2->Close();
  fo->Close();

}

//__________________________________________________________________

HistoUtils_autosystematics(const Char_t *f1name, const Char_t *f2name, const Char_t *outname)
{

  TFile *f1 = TFile::Open(f1name);
  TFile *f2 = TFile::Open(f2name);
  if (!f1 || !f1->IsOpen() || !f2 || !f2->IsOpen()) return;
  TFile *fo = TFile::Open(outname, "RECREATE");
  TList *l1 = f1->GetListOfKeys();


  TH1D *h1, *h2, *hd;
  Char_t *name;
  for (Int_t i = 0; i < l1->GetEntries(); i++) {
    name = l1->At(i)->GetName();
    h1 = (TH1D *)f1->Get(name);
    h2 = (TH1D *)f2->Get(name);
    if (!h1 || !h2) continue;

    hd = new TH1D(*h1);
    Double_t val1, val2, vald, vale1, vale2, valde;
    for (Int_t ii = 0; ii < hd->GetNbinsX(); ii++) {
      val1 = h1->GetBinContent(ii + 1);
      vale1 = h1->GetBinError(ii + 1);
      val2 = h2->GetBinContent(ii + 1);
      vale2 = h2->GetBinError(ii + 1);
      if (val2 == 0.) continue;
      vald = (val1 - val2) / val2;
      valde = TMath::Sqrt(TMath::Abs((vale1 * vale1 - vale2 * vale2))) / val2;
      hd->SetBinContent(ii + 1, vald);
      hd->SetBinError(ii + 1, valde);
    }

    fo->cd();
    hd->Write();
    delete hd;
  }

  f1->Close();
  f2->Close();
  fo->Close();

}

//__________________________________________________________________

TH1 *
HistoUtils_ratio(const Char_t *f1name, const Char_t *f2name, const Char_t *h1name, const Char_t *h2name)
{

  if (!f2name) f2name = f1name;
  TFile *f1 = TFile::Open(f1name);
  TFile *f2 = TFile::Open(f2name);

  if (!h2name) h2name = h1name;
  TH1 *h1 = (TH1 *)f1->Get(h1name);
  TH1 *h2 = (TH1 *)f2->Get(h2name);

  TH1 *hr = h1->Clone("hr");
  hr->Sumw2();
  hr->Divide(h2);

  return hr;
  
}

//__________________________________________________________________

TH1 *
HistoUtils_systematics(const Char_t *f1name, const Char_t *f2name, const Char_t *h1name, const Char_t *h2name)
{

  if (!f2name) f2name = f1name;
  TFile *f1 = TFile::Open(f1name);
  TFile *f2 = TFile::Open(f2name);

  if (!h2name) h2name = h1name;
  TH1 *h1 = (TH1 *)f1->Get(h1name);
  TH1 *h2 = (TH1 *)f2->Get(h2name);

  TH1 *hd = h1->Clone("hd");
  Double_t val1, val2, vald, vale1, vale2, valde;
  for (Int_t i = 0; i < h1->GetNbinsX(); i++) {
    val1 = h1->GetBinContent(i + 1);
    vale1 = h1->GetBinError(i + 1);
    val2 = h2->GetBinContent(i + 1);
    vale2 = h2->GetBinError(i + 1);
    if (val2 == 0.) continue;
    vald = (val1 - val2) / val2;
    valde = TMath::Sqrt(TMath::Abs((vale1 * vale1 - vale2 * vale2))) / val2;
    hd->SetBinContent(i + 1, vald);
    hd->SetBinError(i + 1, valde);
  }

  return hd;
  
}

//__________________________________________________________________

HistoUtils_BinLogX(TH1 *h)
{
  TAxis *axis = h->GetXaxis();
  Int_t bins = axis->GetNbins();
  Axis_t from = axis->GetXmin();
  Axis_t to = axis->GetXmax();
  Axis_t width = (to - from) / bins;
  Axis_t *new_bins = new Axis_t[bins + 1];
  for (int i = 0; i <= bins; i++) new_bins[i] = TMath::Power(10, from + i * width);
  axis->Set(bins, new_bins);
  delete new_bins;
}

//__________________________________________________________________

HistoUtils_BinNormX(TH1 *h)
{
  TAxis *axis = h->GetXaxis();
  Int_t bins = axis->GetNbins();
  Double_t c, ec;
  Double_t w;
  for (Int_t i = 0; i < bins; i++) {
    c = h->GetBinContent(i + 1);
    ec = h->GetBinError(i + 1);
    w = axis->GetBinWidth(i + 1);
    c /= w;
    ec /= w;
    h->SetBinContent(i + 1, c);
    h->SetBinError(i + 1, ec);
  }
}

//__________________________________________________________________

TObjArray *
HistoUtils_FitPeak(TF1 *fitFunc, TH2 *h, Float_t startSigma, Float_t nSigmaMin, Float_t nSigmaMax, Int_t minIntegral = 100., const Char_t *basename = "hParam", Bool_t monitor = kFALSE)
{

  /* gaus function if not specified */
  if (!fitFunc)
    fitFunc = (TF1*)gROOT->GetFunction("gaus");

  /* prepare output histos */
  TObjArray *outArray = new TObjArray();
  Int_t npars = fitFunc->GetNpar();
  TH1D *hpx = h->ProjectionX("hpx");
  TH1D *hParam;
  for (Int_t ipar = 0; ipar < npars; ipar++) {
    hParam = new TH1D(*hpx);
    hParam->SetName(Form("%s_%d", basename, ipar));
    hParam->Reset();
    outArray->Add(hParam);
  }

  /* loop over x-bins */
  for (Int_t ibin = 0; ibin < hpx->GetNbinsX(); ibin++) {

    /* check integral */
    if (hpx->GetBinContent(ibin + 1) < minIntegral) continue;
    /* projection y */
    TH1D *hpy = h->ProjectionY("hpy", ibin + 1, ibin + 1);
    /* fit peak */
    if (HistoUtils_FitPeak(fitFunc, hpy, startSigma, nSigmaMin, nSigmaMax) != 0) {
      delete hpy;
      continue;
    }
    /* setup output histos */
    for (Int_t ipar = 0; ipar < npars; ipar++) {
      hParam = (TH1D *)outArray->At(ipar);
      hParam->SetBinContent(ibin + 1, fitFunc->GetParameter(ipar));
      hParam->SetBinError(ibin + 1, fitFunc->GetParError(ipar));
    }
    /* monitor */
    if (monitor) {
      hpy->SetMarkerStyle(20);
      hpy->SetMarkerColor(4);
      hpy->Draw("E1");
      fitFunc->Draw("same");
      gPad->Update();
      getchar();
    }
    /* delete */
    delete hpy;

  }
  /* delete */
  delete hpx;
  /* return output array */
  return outArray;
}

//__________________________________________________________________

Int_t
HistoUtils_FitPeak(TF1 *fitFunc, TH1 *h, Float_t startSigma, Float_t nSigmaMin, Float_t nSigmaMax)
{

  Double_t fitCent = h->GetBinCenter(h->GetMaximumBin());
  Double_t fitMin = fitCent - nSigmaMin * startSigma;
  Double_t fitMax = fitCent + nSigmaMax * startSigma;
  if (fitMin < h->GetXaxis()->GetXmin()) fitMin = h->GetXaxis()->GetXmin();
  if (fitMax > h->GetXaxis()->GetXmax()) fitMax = h->GetXaxis()->GetXmax();
  fitFunc->SetParameter(1, fitCent);
  fitFunc->SetParameter(2, startSigma);
  Int_t fitres = h->Fit(fitFunc, "WWq0", "", fitMin, fitMax);
  if (fitres != 0) return fitres;
  /* refit with better range */
  for (Int_t i = 0; i < 3; i++) {
    fitCent = fitFunc->GetParameter(1);
    fitMin = fitCent - nSigmaMin * fitFunc->GetParameter(2);
    fitMax = fitCent + nSigmaMax * fitFunc->GetParameter(2);
    if (fitMin < h->GetXaxis()->GetXmin()) fitMin = h->GetXaxis()->GetXmin();
    if (fitMax > h->GetXaxis()->GetXmax()) fitMax = h->GetXaxis()->GetXmax();
    fitres = h->Fit(fitFunc, "q0", "", fitMin, fitMax);
    if (fitres != 0) return fitres;
  }
  return fitres;

}

//__________________________________________________________________

void
HistoUtils_Function2Profile(TF1 *fin, TProfile *p, Int_t ntry = 10000)
{

  TF1 *f = new TF1(*fin);
  Int_t npars = f->GetNpar();
  Double_t par[1000];
  Double_t pare[1000];
  for (Int_t ipar = 0; ipar < npars; ipar++) {
    par[ipar] = f->GetParameter(ipar);
    pare[ipar] = f->GetParError(ipar);
  }

  Double_t x;
  for (Int_t ibin = 0; ibin < p->GetNbinsX(); ibin++) {
    for (Int_t itry = 0; itry < ntry; itry++) {
      for (Int_t ipar = 0; ipar < npars; ipar++)
	f->SetParameter(ipar, gRandom->Gaus(par[ipar], pare[ipar]));
      x = gRandom->Uniform(p->GetXaxis()->GetBinLowEdge(ibin + 1), p->GetXaxis()->GetBinUpEdge(ibin + 1));
      p->Fill(x, f->Eval(x));
    }
  }
}
 HistoUtils.C:1
 HistoUtils.C:2
 HistoUtils.C:3
 HistoUtils.C:4
 HistoUtils.C:5
 HistoUtils.C:6
 HistoUtils.C:7
 HistoUtils.C:8
 HistoUtils.C:9
 HistoUtils.C:10
 HistoUtils.C:11
 HistoUtils.C:12
 HistoUtils.C:13
 HistoUtils.C:14
 HistoUtils.C:15
 HistoUtils.C:16
 HistoUtils.C:17
 HistoUtils.C:18
 HistoUtils.C:19
 HistoUtils.C:20
 HistoUtils.C:21
 HistoUtils.C:22
 HistoUtils.C:23
 HistoUtils.C:24
 HistoUtils.C:25
 HistoUtils.C:26
 HistoUtils.C:27
 HistoUtils.C:28
 HistoUtils.C:29
 HistoUtils.C:30
 HistoUtils.C:31
 HistoUtils.C:32
 HistoUtils.C:33
 HistoUtils.C:34
 HistoUtils.C:35
 HistoUtils.C:36
 HistoUtils.C:37
 HistoUtils.C:38
 HistoUtils.C:39
 HistoUtils.C:40
 HistoUtils.C:41
 HistoUtils.C:42
 HistoUtils.C:43
 HistoUtils.C:44
 HistoUtils.C:45
 HistoUtils.C:46
 HistoUtils.C:47
 HistoUtils.C:48
 HistoUtils.C:49
 HistoUtils.C:50
 HistoUtils.C:51
 HistoUtils.C:52
 HistoUtils.C:53
 HistoUtils.C:54
 HistoUtils.C:55
 HistoUtils.C:56
 HistoUtils.C:57
 HistoUtils.C:58
 HistoUtils.C:59
 HistoUtils.C:60
 HistoUtils.C:61
 HistoUtils.C:62
 HistoUtils.C:63
 HistoUtils.C:64
 HistoUtils.C:65
 HistoUtils.C:66
 HistoUtils.C:67
 HistoUtils.C:68
 HistoUtils.C:69
 HistoUtils.C:70
 HistoUtils.C:71
 HistoUtils.C:72
 HistoUtils.C:73
 HistoUtils.C:74
 HistoUtils.C:75
 HistoUtils.C:76
 HistoUtils.C:77
 HistoUtils.C:78
 HistoUtils.C:79
 HistoUtils.C:80
 HistoUtils.C:81
 HistoUtils.C:82
 HistoUtils.C:83
 HistoUtils.C:84
 HistoUtils.C:85
 HistoUtils.C:86
 HistoUtils.C:87
 HistoUtils.C:88
 HistoUtils.C:89
 HistoUtils.C:90
 HistoUtils.C:91
 HistoUtils.C:92
 HistoUtils.C:93
 HistoUtils.C:94
 HistoUtils.C:95
 HistoUtils.C:96
 HistoUtils.C:97
 HistoUtils.C:98
 HistoUtils.C:99
 HistoUtils.C:100
 HistoUtils.C:101
 HistoUtils.C:102
 HistoUtils.C:103
 HistoUtils.C:104
 HistoUtils.C:105
 HistoUtils.C:106
 HistoUtils.C:107
 HistoUtils.C:108
 HistoUtils.C:109
 HistoUtils.C:110
 HistoUtils.C:111
 HistoUtils.C:112
 HistoUtils.C:113
 HistoUtils.C:114
 HistoUtils.C:115
 HistoUtils.C:116
 HistoUtils.C:117
 HistoUtils.C:118
 HistoUtils.C:119
 HistoUtils.C:120
 HistoUtils.C:121
 HistoUtils.C:122
 HistoUtils.C:123
 HistoUtils.C:124
 HistoUtils.C:125
 HistoUtils.C:126
 HistoUtils.C:127
 HistoUtils.C:128
 HistoUtils.C:129
 HistoUtils.C:130
 HistoUtils.C:131
 HistoUtils.C:132
 HistoUtils.C:133
 HistoUtils.C:134
 HistoUtils.C:135
 HistoUtils.C:136
 HistoUtils.C:137
 HistoUtils.C:138
 HistoUtils.C:139
 HistoUtils.C:140
 HistoUtils.C:141
 HistoUtils.C:142
 HistoUtils.C:143
 HistoUtils.C:144
 HistoUtils.C:145
 HistoUtils.C:146
 HistoUtils.C:147
 HistoUtils.C:148
 HistoUtils.C:149
 HistoUtils.C:150
 HistoUtils.C:151
 HistoUtils.C:152
 HistoUtils.C:153
 HistoUtils.C:154
 HistoUtils.C:155
 HistoUtils.C:156
 HistoUtils.C:157
 HistoUtils.C:158
 HistoUtils.C:159
 HistoUtils.C:160
 HistoUtils.C:161
 HistoUtils.C:162
 HistoUtils.C:163
 HistoUtils.C:164
 HistoUtils.C:165
 HistoUtils.C:166
 HistoUtils.C:167
 HistoUtils.C:168
 HistoUtils.C:169
 HistoUtils.C:170
 HistoUtils.C:171
 HistoUtils.C:172
 HistoUtils.C:173
 HistoUtils.C:174
 HistoUtils.C:175
 HistoUtils.C:176
 HistoUtils.C:177
 HistoUtils.C:178
 HistoUtils.C:179
 HistoUtils.C:180
 HistoUtils.C:181
 HistoUtils.C:182
 HistoUtils.C:183
 HistoUtils.C:184
 HistoUtils.C:185
 HistoUtils.C:186
 HistoUtils.C:187
 HistoUtils.C:188
 HistoUtils.C:189
 HistoUtils.C:190
 HistoUtils.C:191
 HistoUtils.C:192
 HistoUtils.C:193
 HistoUtils.C:194
 HistoUtils.C:195
 HistoUtils.C:196
 HistoUtils.C:197
 HistoUtils.C:198
 HistoUtils.C:199
 HistoUtils.C:200
 HistoUtils.C:201
 HistoUtils.C:202
 HistoUtils.C:203
 HistoUtils.C:204
 HistoUtils.C:205
 HistoUtils.C:206
 HistoUtils.C:207
 HistoUtils.C:208
 HistoUtils.C:209
 HistoUtils.C:210
 HistoUtils.C:211
 HistoUtils.C:212
 HistoUtils.C:213
 HistoUtils.C:214
 HistoUtils.C:215
 HistoUtils.C:216
 HistoUtils.C:217
 HistoUtils.C:218
 HistoUtils.C:219
 HistoUtils.C:220
 HistoUtils.C:221
 HistoUtils.C:222
 HistoUtils.C:223
 HistoUtils.C:224
 HistoUtils.C:225
 HistoUtils.C:226
 HistoUtils.C:227
 HistoUtils.C:228
 HistoUtils.C:229
 HistoUtils.C:230
 HistoUtils.C:231
 HistoUtils.C:232
 HistoUtils.C:233
 HistoUtils.C:234
 HistoUtils.C:235
 HistoUtils.C:236
 HistoUtils.C:237
 HistoUtils.C:238
 HistoUtils.C:239
 HistoUtils.C:240
 HistoUtils.C:241
 HistoUtils.C:242
 HistoUtils.C:243
 HistoUtils.C:244
 HistoUtils.C:245
 HistoUtils.C:246
 HistoUtils.C:247
 HistoUtils.C:248
 HistoUtils.C:249
 HistoUtils.C:250
 HistoUtils.C:251
 HistoUtils.C:252
 HistoUtils.C:253
 HistoUtils.C:254
 HistoUtils.C:255
 HistoUtils.C:256
 HistoUtils.C:257
 HistoUtils.C:258
 HistoUtils.C:259
 HistoUtils.C:260
 HistoUtils.C:261
 HistoUtils.C:262
 HistoUtils.C:263
 HistoUtils.C:264
 HistoUtils.C:265
 HistoUtils.C:266
 HistoUtils.C:267
 HistoUtils.C:268
 HistoUtils.C:269
 HistoUtils.C:270
 HistoUtils.C:271
 HistoUtils.C:272
 HistoUtils.C:273
 HistoUtils.C:274
 HistoUtils.C:275
 HistoUtils.C:276
 HistoUtils.C:277
 HistoUtils.C:278
 HistoUtils.C:279
 HistoUtils.C:280
 HistoUtils.C:281
 HistoUtils.C:282
 HistoUtils.C:283
 HistoUtils.C:284
 HistoUtils.C:285
 HistoUtils.C:286
 HistoUtils.C:287
 HistoUtils.C:288
 HistoUtils.C:289
 HistoUtils.C:290
 HistoUtils.C:291
 HistoUtils.C:292
 HistoUtils.C:293
 HistoUtils.C:294
 HistoUtils.C:295
 HistoUtils.C:296
 HistoUtils.C:297
 HistoUtils.C:298
 HistoUtils.C:299
 HistoUtils.C:300
 HistoUtils.C:301
 HistoUtils.C:302
 HistoUtils.C:303
 HistoUtils.C:304
 HistoUtils.C:305
 HistoUtils.C:306
 HistoUtils.C:307
 HistoUtils.C:308
 HistoUtils.C:309
 HistoUtils.C:310
 HistoUtils.C:311
 HistoUtils.C:312
 HistoUtils.C:313
 HistoUtils.C:314
 HistoUtils.C:315
 HistoUtils.C:316
 HistoUtils.C:317
 HistoUtils.C:318
 HistoUtils.C:319
 HistoUtils.C:320
 HistoUtils.C:321
 HistoUtils.C:322
 HistoUtils.C:323
 HistoUtils.C:324
 HistoUtils.C:325
 HistoUtils.C:326
 HistoUtils.C:327
 HistoUtils.C:328
 HistoUtils.C:329
 HistoUtils.C:330
 HistoUtils.C:331
 HistoUtils.C:332
 HistoUtils.C:333
 HistoUtils.C:334
 HistoUtils.C:335
 HistoUtils.C:336
 HistoUtils.C:337
 HistoUtils.C:338
 HistoUtils.C:339
 HistoUtils.C:340
 HistoUtils.C:341
 HistoUtils.C:342
 HistoUtils.C:343
 HistoUtils.C:344
 HistoUtils.C:345
 HistoUtils.C:346
 HistoUtils.C:347
 HistoUtils.C:348
 HistoUtils.C:349
 HistoUtils.C:350
 HistoUtils.C:351
 HistoUtils.C:352
 HistoUtils.C:353
 HistoUtils.C:354
 HistoUtils.C:355
 HistoUtils.C:356
 HistoUtils.C:357
 HistoUtils.C:358
 HistoUtils.C:359