Skip to content

Commit d41332d

Browse files
ddobrigkalibuild
andauthored
[Common] Add run 3 hyperfine percentiling (#16275)
Co-authored-by: ALICE Builder <alibuild@users.noreply.github.com>
1 parent 8063033 commit d41332d

3 files changed

Lines changed: 111 additions & 13 deletions

File tree

Common/Tasks/centralityStudypp.cxx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ struct centralityStudypp {
263263

264264
histPointers.insert({histPath + "hFDDA_Collisions", histos.add((histPath + "hFDDA_Collisions").c_str(), "hFDDA_Collisions", {kTH1D, {{axisMultUltraFineFDDA}}})});
265265
histPointers.insert({histPath + "hFDDC_Collisions", histos.add((histPath + "hFDDC_Collisions").c_str(), "hFDDC_Collisions", {kTH1D, {{axisMultUltraFineFDDC}}})});
266+
histPointers.insert({histPath + "hFDDM_Collisions", histos.add((histPath + "hFDDM_Collisions").c_str(), "hFDDM_Collisions", {kTH1D, {{axisMultUltraFineFDDC}}})});
266267

267268
histPointers.insert({histPath + "hFV0A_Collisions", histos.add((histPath + "hFV0A_Collisions").c_str(), "hFV0A_Collisions", {kTH1D, {{axisMultUltraFineFV0A}}})});
268269
histPointers.insert({histPath + "hNGlobalTracks", histos.add((histPath + "hNGlobalTracks").c_str(), "hNGlobalTracks", {kTH1D, {{axisMultUltraFineGlobalTracks}}})});
@@ -276,6 +277,7 @@ struct centralityStudypp {
276277

277278
histPointers.insert({histPath + "hFDDA_Collisions_Unequalized", histos.add((histPath + "hFDDA_Collisions_Unequalized").c_str(), "hFDDA_Collisions_Unequalized", {kTH1D, {{axisMultUltraFineFDDA}}})});
278279
histPointers.insert({histPath + "hFDDC_Collisions_Unequalized", histos.add((histPath + "hFDDC_Collisions_Unequalized").c_str(), "hFDDC_Collisions_Unequalized", {kTH1D, {{axisMultUltraFineFDDC}}})});
280+
histPointers.insert({histPath + "hFDDM_Collisions_Unequalized", histos.add((histPath + "hFDDM_Collisions_Unequalized").c_str(), "hFDDM_Collisions_Unequalized", {kTH1D, {{axisMultUltraFineFDDC}}})});
279281

280282
histPointers.insert({histPath + "hFV0A_Collisions_Unequalized", histos.add((histPath + "hFV0A_Collisions_Unequalized").c_str(), "hFV0A_Collisions_Unequalized", {kTH1D, {{axisMultUltraFineFV0A}}})});
281283
histPointers.insert({histPath + "hNGlobalTracks_Unequalized", histos.add((histPath + "hNGlobalTracks_Unequalized").c_str(), "hNGlobalTracks_Unequalized", {kTH1D, {{axisMultUltraFineGlobalTracks}}})});
@@ -456,13 +458,13 @@ struct centralityStudypp {
456458
getHist(TH1, histPath + "hCollisionSelection")->Fill(11);
457459

458460
// if we got here, we also finally fill the FT0C histogram, please
459-
histos.fill(HIST("hNPVContributors"), collision.multNTracksPV());
460-
histos.fill(HIST("hFT0A_Collisions"), collision.multFT0A());
461-
histos.fill(HIST("hFT0C_Collisions"), collision.multFT0C());
462-
histos.fill(HIST("hFT0M_Collisions"), (collision.multFT0A() + collision.multFT0C()));
463-
histos.fill(HIST("hFDDA_Collisions"), collision.multFDDA());
464-
histos.fill(HIST("hFDDC_Collisions"), collision.multFDDC());
465-
histos.fill(HIST("hFV0A_Collisions"), collision.multFV0A());
461+
histos.fill(HIST("hNPVContributors"), multNTracksPV);
462+
histos.fill(HIST("hFT0A_Collisions"), multFT0A);
463+
histos.fill(HIST("hFT0C_Collisions"), multFT0C);
464+
histos.fill(HIST("hFT0M_Collisions"), multFT0A + multFT0C);
465+
histos.fill(HIST("hFDDA_Collisions"), multFDDA);
466+
histos.fill(HIST("hFDDC_Collisions"), multFDDC);
467+
histos.fill(HIST("hFV0A_Collisions"), multFV0A);
466468
histos.fill(HIST("hNGlobalTracks"), collision.multNTracksGlobal());
467469
histos.fill(HIST("hNMFTTracks"), collision.mftNtracks());
468470

@@ -473,6 +475,7 @@ struct centralityStudypp {
473475
getHist(TH1, histPath + "hFT0M_Collisions")->Fill((multFT0A + multFT0C));
474476
getHist(TH1, histPath + "hFDDA_Collisions")->Fill(multFDDA);
475477
getHist(TH1, histPath + "hFDDC_Collisions")->Fill(multFDDC);
478+
getHist(TH1, histPath + "hFDDM_Collisions")->Fill(multFDDA + multFDDC);
476479
getHist(TH1, histPath + "hFV0A_Collisions")->Fill(multFV0A);
477480
getHist(TH1, histPath + "hNGlobalTracks")->Fill(multNTracksGlobal);
478481
getHist(TH1, histPath + "hNMFTTracks")->Fill(mftNtracks);

Common/Tools/Multiplicity/multCalibrator.cxx

Lines changed: 99 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const TString multCalibrator::fCentEstimName[kNCentEstim] = {
4040
multCalibrator::multCalibrator() : TNamed(),
4141
lDesiredBoundaries(0),
4242
lNDesiredBoundaries(0),
43-
fkPrecisionWarningThreshold(1.0),
43+
fkPrecisionWarningThreshold(1000.0),
4444
fInputFileName("AnalysisResults.root"),
4545
fOutputFileName("CCDB-objects.root"),
4646
fAnchorPointValue(-1),
@@ -57,7 +57,7 @@ multCalibrator::multCalibrator() : TNamed(),
5757
multCalibrator::multCalibrator(const char* name, const char* title) : TNamed(name, title),
5858
lDesiredBoundaries(0),
5959
lNDesiredBoundaries(0),
60-
fkPrecisionWarningThreshold(1.0),
60+
fkPrecisionWarningThreshold(1000.0),
6161
fInputFileName("AnalysisResults.root"),
6262
fOutputFileName("CCDB-objects.root"),
6363
fAnchorPointValue(-1),
@@ -230,6 +230,54 @@ void multCalibrator::SetStandardAdaptiveBoundaries()
230230
cout << "Set standard adaptive percentile boundaries! Nboundaries: " << lNDesiredBoundaries << endl;
231231
}
232232

233+
//________________________________________________________________
234+
void multCalibrator::SetRun3AdaptiveBoundaries()
235+
{
236+
// Function to set standard adaptive boundaries
237+
// Run 3 exclusive: goes to 0.00001% binning for highest multiplicity
238+
// Warning: this setting requires well filled input histograms
239+
//
240+
// -> at 0.00001%, one needs 10 million events to get a single one in the highest
241+
// category. In Run 3, at 500 kHz, this corresponds to 20 seconds of dataking;
242+
// any run lasting over 5 minutes should have enough to calibrate to the highest
243+
// boundary.
244+
//
245+
// QA when using hyperfine binning is still advised:
246+
// Selecting very fine percentages may select on spurious situations
247+
// such as beam-background, pileup, etc.
248+
249+
lNDesiredBoundaries = 0;
250+
lDesiredBoundaries = new Double_t[1100];
251+
lDesiredBoundaries[0] = 100;
252+
// From Low To High Multiplicity
253+
for (Int_t ib = 1; ib < 91; ib++) {
254+
lNDesiredBoundaries++;
255+
lDesiredBoundaries[lNDesiredBoundaries] = lDesiredBoundaries[lNDesiredBoundaries - 1] - 1.0;
256+
}
257+
for (Int_t ib = 1; ib < 91; ib++) {
258+
lNDesiredBoundaries++;
259+
lDesiredBoundaries[lNDesiredBoundaries] = lDesiredBoundaries[lNDesiredBoundaries - 1] - 0.1;
260+
}
261+
for (Int_t ib = 1; ib < 91; ib++) {
262+
lNDesiredBoundaries++;
263+
lDesiredBoundaries[lNDesiredBoundaries] = lDesiredBoundaries[lNDesiredBoundaries - 1] - 0.01;
264+
}
265+
for (Int_t ib = 1; ib < 91; ib++) {
266+
lNDesiredBoundaries++;
267+
lDesiredBoundaries[lNDesiredBoundaries] = lDesiredBoundaries[lNDesiredBoundaries - 1] - 0.001;
268+
}
269+
for (Int_t ib = 1; ib < 91; ib++) {
270+
lNDesiredBoundaries++;
271+
lDesiredBoundaries[lNDesiredBoundaries] = lDesiredBoundaries[lNDesiredBoundaries - 1] - 0.0001;
272+
}
273+
for (Int_t ib = 1; ib < 101; ib++) {
274+
lNDesiredBoundaries++;
275+
lDesiredBoundaries[lNDesiredBoundaries] = lDesiredBoundaries[lNDesiredBoundaries - 1] - 0.00001;
276+
}
277+
lNDesiredBoundaries++;
278+
cout << "Set run 3 adaptive percentile boundaries! Nboundaries: " << lNDesiredBoundaries << endl;
279+
}
280+
233281
//________________________________________________________________
234282
void multCalibrator::SetStandardOnePercentBoundaries()
235283
{
@@ -244,6 +292,32 @@ void multCalibrator::SetStandardOnePercentBoundaries()
244292
cout << "Set standard 1%-wide percentile boundaries! Nboundaries: " << lNDesiredBoundaries << endl;
245293
}
246294

295+
//________________________________________________________________
296+
bool multCalibrator::IsBinningSane(TH1* histogram)
297+
{
298+
// check if binning that will be attempted is too fine for this histogram
299+
double minimumBinWidth = 1000.0f;
300+
for (int ib = 0; ib < lNDesiredBoundaries - 1; ib++) {
301+
if (std::abs(lDesiredBoundaries[ib + 1] - lDesiredBoundaries[ib]) < minimumBinWidth) {
302+
minimumBinWidth = std::abs(lDesiredBoundaries[ib + 1] - lDesiredBoundaries[ib]);
303+
}
304+
}
305+
if (minimumBinWidth < 1e-9) {
306+
cout << "Excessively fine binning requested: minimum bin width registers as " << minimumBinWidth << endl;
307+
return false; // not reasonable
308+
}
309+
if (histogram->GetEntries() < 1000.0 / minimumBinWidth) {
310+
cout << "Histogram " << histogram->GetName() << " does not have enough entries (" << histogram->GetEntries() << ") to calibrate!" << endl;
311+
return false;
312+
}
313+
if (std::abs(histogram->GetMean()) < 1e-9) {
314+
cout << "Histogram " << histogram->GetName() << " has suspicious mean: " << histogram->GetMean() << endl;
315+
return false;
316+
}
317+
cout << "Sanity check: " << histogram->GetName() << ", entries = " << histogram->GetEntries() << ", 1/(min bin width) = " << 100.0 / minimumBinWidth << " -> OK ! " << endl;
318+
return true;
319+
}
320+
247321
//________________________________________________________________
248322
TH1F* multCalibrator::GetCalibrationHistogram(TH1* histoRaw, TString lHistoName)
249323
{
@@ -260,6 +334,19 @@ TH1F* multCalibrator::GetCalibrationHistogram(TH1* histoRaw, TString lHistoName)
260334
cout << "Last boundary: " << lDesiredBoundaries[0] << endl;
261335
}
262336

337+
// binning check
338+
if (!IsBinningSane(histoRaw)) {
339+
cout << "Requested binning is not viable for input histogram named " << histoRaw->GetName() << "! Will return 100.5 for all requests." << endl;
340+
Double_t lDummyBounds[2];
341+
lDummyBounds[0] = 0;
342+
lDummyBounds[1] = 1.0;
343+
TH1F* hCalib = new TH1F(lHistoName.Data(), "", 1, lDummyBounds);
344+
hCalib->SetBinContent(0, 100.5);
345+
hCalib->SetBinContent(1, 100.5);
346+
hCalib->SetBinContent(2, 100.5);
347+
return hCalib;
348+
}
349+
263350
// Aux vars
264351
Double_t lMiddleOfBins[1000];
265352
for (Long_t lB = 1; lB < lNDesiredBoundaries; lB++) {
@@ -278,15 +365,22 @@ TH1F* multCalibrator::GetCalibrationHistogram(TH1* histoRaw, TString lHistoName)
278365
if (fAnchorPointValue > 0)
279366
lDisplacedii++;
280367
lBounds[lDisplacedii] = GetBoundaryForPercentile(histoRaw, lDesiredBoundaries[ii], lPrecision[ii]);
368+
bool warnUser = false;
281369
TString lPrecisionString = "(Precision OK)";
282370
if (ii != 0 && ii != lNDesiredBoundaries - 1) {
283371
// check precision, please
284-
if (lPrecision[ii] / TMath::Abs(lDesiredBoundaries[ii + 1] - lDesiredBoundaries[ii]) > fkPrecisionWarningThreshold)
372+
if ((lPrecision[ii] / TMath::Abs(lDesiredBoundaries[ii + 1] - lDesiredBoundaries[ii])) > fkPrecisionWarningThreshold) {
285373
lPrecisionString = "(WARNING: BINNING MAY LEAD TO IMPRECISION!)";
286-
if (lPrecision[ii] / TMath::Abs(lDesiredBoundaries[ii - 1] - lDesiredBoundaries[ii]) > fkPrecisionWarningThreshold)
374+
warnUser = true;
375+
}
376+
if ((lPrecision[ii] / TMath::Abs(lDesiredBoundaries[ii - 1] - lDesiredBoundaries[ii])) > fkPrecisionWarningThreshold) {
287377
lPrecisionString = "(WARNING: BINNING MAY LEAD TO IMPRECISION!)";
378+
warnUser = true;
379+
}
380+
}
381+
if (warnUser) {
382+
cout << histoRaw->GetName() << " boundaries, percentile: " << lDesiredBoundaries[ii] << "%\t Signal value = " << lBounds[lDisplacedii] << "\tprecision = " << lPrecision[ii] << "% " << lPrecisionString.Data() << endl;
288383
}
289-
cout << histoRaw->GetName() << " boundaries, percentile: " << lDesiredBoundaries[ii] << "%\t Signal value = " << lBounds[lDisplacedii] << "\tprecision = " << lPrecision[ii] << "% " << lPrecisionString.Data() << endl;
290384
}
291385
TH1F* hCalib = new TH1F(lHistoName.Data(), "", fAnchorPointValue < 0 ? lNDesiredBoundaries - 1 : lNDesiredBoundaries, lBounds);
292386
hCalib->SetDirectory(0);
@@ -311,7 +405,6 @@ void multCalibrator::ResetPrecisionHistogram()
311405
Double_t lInverseDesiredBoundaries[1100];
312406
for (Int_t ii = 0; ii < lNDesiredBoundaries; ii++) {
313407
lInverseDesiredBoundaries[ii] = lDesiredBoundaries[lNDesiredBoundaries - (ii + 1)];
314-
cout << "Boundary " << ii << " is " << lInverseDesiredBoundaries[ii] << endl;
315408
}
316409
fPrecisionHistogram = new TH1D("hPrecisionHistogram", "", lNDesiredBoundaries - 1, lInverseDesiredBoundaries);
317410
}

Common/Tools/Multiplicity/multCalibrator.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ class multCalibrator : public TNamed
6060
void SetAnchorPointPercentage(Float_t lPer) { fAnchorPointPercentage = lPer; }
6161

6262
void SetStandardAdaptiveBoundaries(); // standard adaptive (pp-like)
63+
void SetRun3AdaptiveBoundaries(); // Run 3 adaptive (down to 0.00001%)
6364
void SetStandardOnePercentBoundaries(); // standard 1% (Pb-Pb like)
65+
bool IsBinningSane(TH1* histogram); // for safety
6466

6567
// Master Function in this Class: To be called once filenames are set
6668
Bool_t Calibrate();

0 commit comments

Comments
 (0)