@@ -40,7 +40,7 @@ const TString multCalibrator::fCentEstimName[kNCentEstim] = {
4040multCalibrator::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(),
5757multCalibrator::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// ________________________________________________________________
234282void 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// ________________________________________________________________
248322TH1F* 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] << " \t precision = " << lPrecision[ii] << " % " << lPrecisionString.Data () << endl;
288383 }
289- cout << histoRaw->GetName () << " boundaries, percentile: " << lDesiredBoundaries[ii] << " %\t Signal value = " << lBounds[lDisplacedii] << " \t precision = " << 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 }
0 commit comments