diff --git a/CaloFuture/CaloFuturePIDs/src/SelectiveBremMatchAlg.cpp b/CaloFuture/CaloFuturePIDs/src/SelectiveBremMatchAlg.cpp index 1163c08102c614051a48d99818849c09b617f706..54b76dbf950d29d2da00cdd0fe26b3eb46e5b150 100644 --- a/CaloFuture/CaloFuturePIDs/src/SelectiveBremMatchAlg.cpp +++ b/CaloFuture/CaloFuturePIDs/src/SelectiveBremMatchAlg.cpp @@ -295,13 +295,16 @@ namespace LHCb::Calo { } // get energy of closest cells based on track state extrapolation + // take also into account 'gamma' offset used with clusters, only above some threshold energycellids.assign( cellids.begin(), cellids.end() ); getTrackBasedEnergyCells( energycellids, state_first, calo, z_energy_planes ); auto ebrem_trackbased = accumulate( begin( energycellids ), end( energycellids ), 0., [&]( double e, Detector::Calo::CellID ci ) { - if ( const auto digit = digits( ci ); digit ) { e += digit->energy(); } - return ( e > 0. ) ? e : 0.; + auto const digit = digits( ci ); + return ( digit && digit->energy() > 0. ) ? e + digit->energy() : e; } ); + if ( ( ebrem_trackbased * state_first.slopes().unit().rho() ) > m_residualEtCut ) + ebrem_trackbased += calo.getGamma( cellids.front() ); entable.emplace_back().set( track.indices(), ebrem_trackbased ); // monitoring diff --git a/CaloFuture/CaloFuturePIDs/src/TrackBasedElectronShowerAlg.cpp b/CaloFuture/CaloFuturePIDs/src/TrackBasedElectronShowerAlg.cpp index 878da99d46ccdac6461a6af87eddb316fbc130a7..5cef78561f795d6bd69e3e0af72514dd4a966ba6 100644 --- a/CaloFuture/CaloFuturePIDs/src/TrackBasedElectronShowerAlg.cpp +++ b/CaloFuture/CaloFuturePIDs/src/TrackBasedElectronShowerAlg.cpp @@ -232,6 +232,8 @@ namespace LHCb::Calo { private: // general algorithm properties Gaudi::Property m_fmin{ this, "minFraction", 0.1, "Minimum expected energy fraction for use in E/p" }; + Gaudi::Property m_maxgammascaling{ this, "maxGammaScaling", 1.5, + "Maximum scaling in E/p by constant gamma energy offset" }; Gaudi::Property m_nzplanes{ this, "nPlanesInZ", 6, "Number of planes in z to scan for track-intersection cells" }; int m_nmaxelements; @@ -377,6 +379,10 @@ namespace LHCb::Calo { // - obtain their neigbours getNeighborCellIDs( cellids, calo, m_nsquares ); + // main cell + Detector::Calo::CellID seed_id; + float seed_energy = 0.f; + // calculate for each cell the expected energy fraction and obtain measured energy (digit) showerentries.clear(); for ( const auto& cellid : cellids ) { @@ -402,6 +408,10 @@ namespace LHCb::Calo { // obtain measured energy auto digit = digits( cellid ); showentry.energy = ( digit ) ? digit->energy() : 0.f; + if ( showentry.energy > seed_energy ) { + seed_id = cellid; + seed_energy = showentry.energy; + } // add to list of checked cells showerentries.push_back( showentry ); } @@ -409,31 +419,36 @@ namespace LHCb::Calo { // calculate relevant variables from energy fractions: // - summed (but selective) energy over momentum (eop) // - summed per-cell eop-DLL - float energy = 0.f; - float dll = 0.f; // some pre-caculation for DLL float logmom = forceinrange( LHCb::Math::Approx::approx_log( showerparam.momentum * Constants::inv_gev ), range_dll[2] ); float invmom = 1.f / showerparam.momentum; // obtain eops and DLL - for ( const auto& se : showerentries ) { - if ( se.fraction >= m_fmin ) energy += se.energy; - if ( se.fraction > range_dll[1].first ) { - dll += m_cellparams->hist( { HistType::DLL, Region::All } ) - ->Interpolate( forceinrange( invmom * se.energy, range_dll[0] ), - forceinrange( se.fraction, range_dll[1] ), logmom ); - } - } + // and make sure 'gamma' energy offset is taken into account with scaling + // but at the same time we won't create artificial deposits and clamp the scaling depending on the estimate of E/p + // itself so a full EM cluster should get the full correction, anything below should go to zero depending on + // roughly the measurement + float energy = std::accumulate( showerentries.begin(), showerentries.end(), 0.f, [&]( auto sum, auto const& se ) { + return sum + ( se.fraction >= m_fmin ? se.energy : 0.f ); + } ); + float gamma = calo.getGamma( seed_id ); + float gamma_corrected = gamma * std::clamp( ( energy + gamma ) / showerparam.momentum, 0.f, 1.f ); + float energy_scaling = + energy > 0. ? std::clamp( 1.f + gamma_corrected / energy, 1.f, m_maxgammascaling.value() ) : 1.f; + float dll = std::accumulate( showerentries.begin(), showerentries.end(), 0.f, [&]( auto sum, auto const& se ) { + return sum + ( m_cellparams->hist( { HistType::DLL, Region::All } ) + ->Interpolate( forceinrange( invmom * energy_scaling * se.energy, range_dll[0] ), + forceinrange( se.fraction, range_dll[1] ), logmom ) ); + } ); // push results to tables - auto eop = ( energy > 0. ) ? energy / showerparam.momentum : 0.f; + auto eop = ( energy > 0. ) ? ( energy_scaling * energy ) / showerparam.momentum : 0.f; output_table.add( track, eop, dll ); - } - // monitor statistics - const auto nLinks = output_table.size(); - for ( auto const& proxy : output_table.scalar() ) m_eop += proxy.get().cast() / nLinks; - for ( auto const& proxy : output_table.scalar() ) m_dll += proxy.get().cast() / nLinks; + // monitoring + m_eop += eop; + m_dll += dll; + } return output_table; }