@@ -358,6 +358,116 @@ double VarManager::ComputePIDcalibration(int species, double nSigmaValue)
358358 }
359359}
360360
361+ // __________________________________________________________________
362+ std::tuple<double , double , double , double , double > VarManager::BimodalityCoefficientUnbinned (const std::vector<double >& data) {
363+ // Bimodality coefficient = (skewness^2 + 1) / kurtosis
364+ // return a tuple including the coefficient, mean, RMS, skewness, and kurtosis
365+ size_t n = data.size ();
366+ if (n < 3 ) {
367+ return std::make_tuple (-1.0 , -1.0 , -1.0 , -1.0 , -1.0 );
368+ }
369+ double mean = std::accumulate (data.begin (), data.end (), 0.0 ) / n;
370+
371+ double m2 = 0.0 , m3 = 0.0 , m4 = 0.0 ;
372+ for (double x : data) {
373+ double diff = x - mean;
374+ double diff2 = diff * diff;
375+ double diff3 = diff2 * diff;
376+ double diff4 = diff3 * diff;
377+ m2 += diff2;
378+ m3 += diff3;
379+ m4 += diff4;
380+ }
381+
382+ m2 /= n;
383+ m3 /= n;
384+ m4 /= n;
385+
386+ if (m2 == 0.0 ) {
387+ return std::make_tuple (-1.0 , -1.0 , -1.0 , -1.0 , -1.0 );
388+ }
389+
390+ double stddev = std::sqrt (m2);
391+ double skewness = m3 / (stddev * stddev * stddev);
392+ double kurtosis = m4 / (m2 * m2);
393+
394+ return std::make_tuple ((skewness * skewness + 1.0 ) / kurtosis, mean, stddev, skewness, kurtosis);
395+ }
396+
397+ std::tuple<double , double , double , double , double > VarManager::BimodalityCoefficient (const std::vector<double >& data, float binWidth, int trim, float min, float max) {
398+ // Bimodality coefficient = (skewness^2 + 1) / kurtosis
399+ // return a tuple including the coefficient, mean, RMS, skewness, and kurtosis
400+
401+ // if the binWidth is < 0, use the unbinned calculation
402+ if (binWidth < 0 ) {
403+ return BimodalityCoefficientUnbinned (data);
404+ }
405+
406+ // bin the data and put it in a vector
407+ int nBins = static_cast <int >((max - min) / binWidth);
408+ std::vector<int > counts (nBins, 0.0 );
409+
410+ for (float x : data) {
411+ if (x < min || x >= max) {
412+ continue ; // skip out-of-range values
413+ }
414+ int bin = static_cast <int >((x - min) / binWidth);
415+ if (bin >= 0 && bin < nBins) {
416+ counts[bin]++;
417+ }
418+ }
419+
420+ // trim the distribution if requested, by requiring a minimum of "trim" counts in each bin
421+ if (trim > 0 ) {
422+ for (int i = 0 ; i < nBins; ++i) {
423+ if (counts[i] < trim) {
424+ counts[i] = 0 ;
425+ }
426+ }
427+ }
428+
429+ // first compute the mean
430+ double mean = 0.0 ;
431+ double totalCounts = 0.0 ;
432+ for (int i = 0 ; i < nBins; ++i) {
433+ double binCenter = min + (i + 0.5 ) * binWidth;
434+ mean += counts[i] * binCenter;
435+ totalCounts += counts[i];
436+ }
437+
438+ if (totalCounts == 0 ) {
439+ return std::make_tuple (-1.0 , -1.0 , -1.0 , -1.0 , -1.0 );
440+ }
441+ mean /= totalCounts;
442+
443+ // then compute the second, third, and fourth central moments
444+ double m2 = 0.0 , m3 = 0.0 , m4 = 0.0 ;
445+ for (int i = 0 ; i < nBins; ++i) {
446+ double binCenter = min + (i + 0.5 ) * binWidth;
447+ double diff = binCenter - mean;
448+ double diff2 = diff * diff;
449+ double diff3 = diff2 * diff;
450+ double diff4 = diff3 * diff;
451+ m2 += counts[i] * diff2;
452+ m3 += counts[i] * diff3;
453+ m4 += counts[i] * diff4;
454+ }
455+
456+ m2 /= totalCounts;
457+ m3 /= totalCounts;
458+ m4 /= totalCounts;
459+
460+ if (m2 == 0.0 ) {
461+ return std::make_tuple (-1.0 , -1.0 , -1.0 , -1.0 , -1.0 );
462+ }
463+
464+ double stddev = std::sqrt (m2);
465+ double skewness = m3 / (stddev * stddev * stddev);
466+ double kurtosis = m4 / (m2 * m2); // Pearson's kurtosis, not excess
467+
468+ return std::make_tuple ((skewness * skewness + 1.0 ) / kurtosis, mean, stddev, skewness, kurtosis);
469+ }
470+
361471// __________________________________________________________________
362472void VarManager::SetDefaultVarNames ()
363473{
@@ -577,12 +687,32 @@ void VarManager::SetDefaultVarNames()
577687 fgVariableUnits[kNTPCmedianTimeShortA ] = " #mu s" ;
578688 fgVariableNames[kNTPCmedianTimeShortC ] = " # TPC-C pileup median time, short time range" ;
579689 fgVariableUnits[kNTPCmedianTimeShortC ] = " #mu s" ;
580- fgVariableNames[kDCAzBimodalityCoefficient ] = " Bimodality Coeff of DCAz distribution" ;
690+ fgVariableNames[kDCAzBimodalityCoefficient ] = " Unbinned Bimodality Coeff of DCAz distribution" ;
581691 fgVariableUnits[kDCAzBimodalityCoefficient ] = " " ;
692+ fgVariableNames[kDCAzBimodalityCoefficientBinned ] = " Binned Bimodality Coeff of DCAz distribution" ;
693+ fgVariableUnits[kDCAzBimodalityCoefficientBinned ] = " " ;
694+ fgVariableNames[kDCAzBimodalityCoefficientBinnedTrimmed1 ] = " Binned Bimodality Coeff of DCAz distribution (trimmed 1)" ;
695+ fgVariableUnits[kDCAzBimodalityCoefficientBinnedTrimmed1 ] = " " ;
696+ fgVariableNames[kDCAzBimodalityCoefficientBinnedTrimmed2 ] = " Binned Bimodality Coeff of DCAz distribution (trimmed 2)" ;
697+ fgVariableUnits[kDCAzBimodalityCoefficientBinnedTrimmed2 ] = " " ;
698+ fgVariableNames[kDCAzBimodalityCoefficientBinnedTrimmed3 ] = " Binned Bimodality Coeff of DCAz distribution (trimmed 3)" ;
699+ fgVariableUnits[kDCAzBimodalityCoefficientBinnedTrimmed3 ] = " " ;
582700 fgVariableNames[kDCAzMean ] = " Mean of DCAz distribution" ;
583701 fgVariableUnits[kDCAzMean ] = " cm" ;
702+ fgVariableNames[kDCAzMeanBinnedTrimmed1 ] = " Mean of DCAz distribution (trimmed 1)" ;
703+ fgVariableUnits[kDCAzMeanBinnedTrimmed1 ] = " cm" ;
704+ fgVariableNames[kDCAzMeanBinnedTrimmed2 ] = " Mean of DCAz distribution (trimmed 2)" ;
705+ fgVariableUnits[kDCAzMeanBinnedTrimmed2 ] = " cm" ;
706+ fgVariableNames[kDCAzMeanBinnedTrimmed3 ] = " Mean of DCAz distribution (trimmed 3)" ;
707+ fgVariableUnits[kDCAzMeanBinnedTrimmed3 ] = " cm" ;
584708 fgVariableNames[kDCAzRMS ] = " RMS of DCAz distribution" ;
585709 fgVariableUnits[kDCAzRMS ] = " cm" ;
710+ fgVariableNames[kDCAzRMSBinnedTrimmed1 ] = " RMS of DCAz distribution (trimmed 1)" ;
711+ fgVariableUnits[kDCAzRMSBinnedTrimmed1 ] = " cm" ;
712+ fgVariableNames[kDCAzRMSBinnedTrimmed2 ] = " RMS of DCAz distribution (trimmed 2)" ;
713+ fgVariableUnits[kDCAzRMSBinnedTrimmed2 ] = " cm" ;
714+ fgVariableNames[kDCAzRMSBinnedTrimmed3 ] = " RMS of DCAz distribution (trimmed 3)" ;
715+ fgVariableUnits[kDCAzRMSBinnedTrimmed3 ] = " cm" ;
586716 fgVariableNames[kDCAzSkewness ] = " Skewness of DCAz distribution" ;
587717 fgVariableUnits[kDCAzSkewness ] = " " ;
588718 fgVariableNames[kDCAzKurtosis ] = " Kurtosis of DCAz distribution" ;
@@ -601,7 +731,6 @@ void VarManager::SetDefaultVarNames()
601731 fgVariableUnits[kDCAzFracAbove5mm ] = " " ;
602732 fgVariableNames[kDCAzFracAbove10mm ] = " Fraction of tracks with |DCAz| > 10 mm" ;
603733 fgVariableUnits[kDCAzFracAbove10mm ] = " " ;
604- fgVariableNames[]
605734 fgVariableNames[kPt ] = " p_{T}" ;
606735 fgVariableUnits[kPt ] = " GeV/c" ;
607736 fgVariableNames[kPt1 ] = " p_{T1}" ;
@@ -1664,8 +1793,18 @@ void VarManager::SetDefaultVarNames()
16641793 fgVarNamesMap[" kNTPCmedianTimeShortA" ] = kNTPCmedianTimeShortA ;
16651794 fgVarNamesMap[" kNTPCmedianTimeShortC" ] = kNTPCmedianTimeShortC ;
16661795 fgVarNamesMap[" kDCAzBimodalityCoefficient" ] = kDCAzBimodalityCoefficient ;
1796+ fgVarNamesMap[" kDCAzBimodalityCoefficientBinned" ] = kDCAzBimodalityCoefficientBinned ;
1797+ fgVarNamesMap[" kDCAzBimodalityCoefficientBinnedTrimmed1" ] = kDCAzBimodalityCoefficientBinnedTrimmed1 ;
1798+ fgVarNamesMap[" kDCAzBimodalityCoefficientBinnedTrimmed2" ] = kDCAzBimodalityCoefficientBinnedTrimmed2 ;
1799+ fgVarNamesMap[" kDCAzBimodalityCoefficientBinnedTrimmed3" ] = kDCAzBimodalityCoefficientBinnedTrimmed3 ;
16671800 fgVarNamesMap[" kDCAzMean" ] = kDCAzMean ;
1801+ fgVarNamesMap[" kDCAzMeanBinnedTrimmed1" ] = kDCAzMeanBinnedTrimmed1 ;
1802+ fgVarNamesMap[" kDCAzMeanBinnedTrimmed2" ] = kDCAzMeanBinnedTrimmed2 ;
1803+ fgVarNamesMap[" kDCAzMeanBinnedTrimmed3" ] = kDCAzMeanBinnedTrimmed3 ;
16681804 fgVarNamesMap[" kDCAzRMS" ] = kDCAzRMS ;
1805+ fgVarNamesMap[" kDCAzRMSBinnedTrimmed1" ] = kDCAzRMSBinnedTrimmed1 ;
1806+ fgVarNamesMap[" kDCAzRMSBinnedTrimmed2" ] = kDCAzRMSBinnedTrimmed2 ;
1807+ fgVarNamesMap[" kDCAzRMSBinnedTrimmed3" ] = kDCAzRMSBinnedTrimmed3 ;
16691808 fgVarNamesMap[" kDCAzSkewness" ] = kDCAzSkewness ;
16701809 fgVarNamesMap[" kDCAzKurtosis" ] = kDCAzKurtosis ;
16711810 fgVarNamesMap[" kDCAzFracAbove100um" ] = kDCAzFracAbove100um ;
0 commit comments