@@ -327,6 +327,45 @@ auto ProjectBoostHistoXFast(const Hist& hist, std::vector<int>& bin_indices, int
327327 return histoProj;
328328}
329329
330+ template <typename Hist>
331+ auto ProjectBoostHistoXFastAllSectors (const Hist& hist, std::vector<int >& bin_indices, StackID id, const CalibdEdxCorrection* stackMean)
332+ {
333+ // get an average histogram over all stacks of the same type
334+ using ax = CalibdEdx::Axis;
335+ const unsigned int nbinsdedx = hist.axis (ax::dEdx).size ();
336+ const double binStartX = hist.axis (ax::dEdx).bin (0 ).lower ();
337+ const double binEndX = hist.axis (ax::dEdx).bin (nbinsdedx - 1 ).upper ();
338+
339+ // make fine histogram to be able to correctly store normalized dEdx values
340+ auto histoProj = boost::histogram::make_histogram (CalibdEdx::FloatAxis (nbinsdedx, binStartX, binEndX));
341+
342+ // loop over sectors for merging the histograms
343+ for (int iSec = 0 ; iSec < hist.axis (ax::Sector).size (); ++iSec) {
344+ bin_indices[ax::Sector] = iSec;
345+ id.sector = static_cast <int >(hist.axis (ax::Sector).bin (iSec).center ());
346+
347+ // loop over all bins of the requested axis
348+ for (int i = 0 ; i < nbinsdedx; ++i) {
349+ // setting bin of the requested axis
350+ bin_indices[ax::dEdx] = i;
351+
352+ // access the bin content specified by bin_indices
353+ const float counts = hist.at (bin_indices);
354+ float dEdx = hist.axis (ax::dEdx).value (i);
355+
356+ // scale the dedx to the mean
357+ if (stackMean != nullptr ) {
358+ const auto charge = static_cast <ChargeType>(bin_indices[ax::Charge]);
359+ dEdx /= stackMean->getCorrection (id, charge);
360+ }
361+
362+ // fill the histogram with dedx as the bin center and the counts as the weight
363+ histoProj (dEdx, bh::weight (counts));
364+ }
365+ }
366+ return histoProj;
367+ }
368+
330369void CalibdEdx::fitHistGaus (TLinearFitter& fitter, CalibdEdxCorrection& corr, const CalibdEdxCorrection* stackMean)
331370{
332371 using timer = std::chrono::high_resolution_clock;
@@ -335,7 +374,8 @@ void CalibdEdx::fitHistGaus(TLinearFitter& fitter, CalibdEdxCorrection& corr, co
335374 const bool projSectors = stackMean != nullptr ;
336375 constexpr int sectors = SECTORSPERSIDE * SIDES;
337376 for (int iSnp = 0 ; iSnp < mHist .axis (ax::Snp).size (); ++iSnp) {
338- for (int iSec = 0 ; iSec < mHist .axis (ax::Sector).size (); ++iSec) {
377+ const int iSecEnd = projSectors ? 1 : mHist .axis (ax::Sector).size ();
378+ for (int iSec = 0 ; iSec < iSecEnd; ++iSec) {
339379 for (int iStack = 0 ; iStack < mHist .axis (ax::Stack).size (); ++iStack) {
340380 for (int iCharge = 0 ; iCharge < mHist .axis (ax::Charge).size (); ++iCharge) {
341381
@@ -359,7 +399,7 @@ void CalibdEdx::fitHistGaus(TLinearFitter& fitter, CalibdEdxCorrection& corr, co
359399 bin_indices[ax::Charge] = iCharge;
360400
361401 for (int iter = 0 ; iter < 2 ; ++iter) {
362- auto boostHist1d = ProjectBoostHistoXFast (mHist , bin_indices, ax::dEdx);
402+ auto boostHist1d = projSectors ? ProjectBoostHistoXFastAllSectors ( mHist , bin_indices, id, stackMean) : ProjectBoostHistoXFast (mHist , bin_indices, ax::dEdx);
363403
364404 float lowerCut = 0 ;
365405 float upperCut = 0 ;
@@ -398,11 +438,6 @@ void CalibdEdx::fitHistGaus(TLinearFitter& fitter, CalibdEdxCorrection& corr, co
398438 CalibdEdx::recoverTgl (mHist .axis (ax::Tgl).bin (iTgl).center (), id.type ),
399439 mHist .axis (ax::Snp).bin (iSnp).center ()};
400440
401- // scale fitted dEdx using the stacks mean
402- if (stackMean != nullptr ) {
403- dEdx /= stackMean->getCorrection (id, charge);
404- }
405-
406441 const auto fitNPoints = fitValues[3 ];
407442 const float sigma = fitValues[2 ];
408443 const double fitMeanErr = (fitNPoints > 0 ) ? (sigma / std::sqrt (fitNPoints)) : -1 ;
@@ -445,6 +480,7 @@ void CalibdEdx::fitHistGaus(TLinearFitter& fitter, CalibdEdxCorrection& corr, co
445480 << " iter=" << iter
446481 << " mSigmaLower=" << mSigmaLower
447482 << " mSigmaUpper=" << mSigmaUpper
483+ << " projSectors=" << projSectors
448484 << " \n " ;
449485 }
450486 } catch (o2::utils::FitGausError_t err) {
@@ -530,14 +566,12 @@ void CalibdEdx::finalize(const bool useGausFits)
530566 meanCorr.setDims (0 );
531567 TLinearFitter meanFitter (0 );
532568 meanFitter.SetFormula (" 1" );
569+ // get the mean dEdx for each stack
570+ fitHist (mHist , meanCorr, meanFitter, mFitCut , mFitLowCutFactor , mFitPasses );
533571 if (!useGausFits) {
534- fitHist (mHist , meanCorr, meanFitter, mFitCut , mFitLowCutFactor , mFitPasses );
535-
536572 // get higher dimension corrections with projected sectors
537- fitHist (mHist , mCalib , fitter, mFitCut , mFitLowCutFactor , mFitPasses , &meanCorr);
573+ fitHist (mHist , mCalib , fitter, mFitCut , mFitLowCutFactor , mFitPasses , &meanCorr, mDebugOutputStreamer . get () );
538574 } else {
539- fitHistGaus (meanFitter, meanCorr, nullptr );
540-
541575 // get higher dimension corrections with projected sectors
542576 fitHistGaus (fitter, mCalib , &meanCorr);
543577 }
0 commit comments