@@ -5329,6 +5329,7 @@ void VarManager::FillFIT(uint64_t midbc, std::vector<std::pair<uint64_t, int64_t
53295329 values[kAmplitudeFV0A ] = 0 .f ;
53305330 for (auto amp : amps)
53315331 values[kAmplitudeFV0A ] += amp;
5332+ values[kNFiredChannelsFV0A ] = fv0a.channel ().size ();
53325333 values[kTriggerMaskFV0A ] = fv0a.triggerMask ();
53335334 }
53345335
@@ -5345,13 +5346,69 @@ void VarManager::FillFIT(uint64_t midbc, std::vector<std::pair<uint64_t, int64_t
53455346 values[kAmplitudeFDDC ] = 0 .f ;
53465347 for (auto amp : ampsC)
53475348 values[kAmplitudeFDDC ] += amp;
5349+ values[kNFiredChannelsFDDA ] = fdd.channelA ().size ();
5350+ values[kNFiredChannelsFDDC ] = fdd.channelC ().size ();
53485351 values[kTriggerMaskFDD ] = fdd.triggerMask ();
53495352 }
5353+
53505354 }
53515355
53525356 // Fill pileup flags and distances to closest BCs
5353- // This requires scanning nearby BCs - simplified version for now
5354- // Full implementation would need the complete BC range similar to PWGUD processFITInfo
5357+ // Scan ±16 BCs around midbc (following PWGUD UPCCandidateProducer pattern)
5358+ const uint64_t scanRange = 16 ;
5359+ uint64_t leftBC = midbc >= scanRange ? midbc - scanRange : 0 ;
5360+ uint64_t rightBC = midbc + scanRange;
5361+
5362+ // Find starting BC in bcMap
5363+ std::pair<uint64_t , int64_t > searchPair (leftBC, 0 );
5364+ auto scanIt = std::lower_bound (bcMap.begin (), bcMap.end (), searchPair,
5365+ [](const std::pair<uint64_t , int64_t >& left, const std::pair<uint64_t , int64_t >& right) {
5366+ return left.first < right.first ;
5367+ });
5368+
5369+ if (scanIt != bcMap.end ()) {
5370+ uint64_t scanBc = scanIt->first ;
5371+ while (scanBc <= rightBC && scanIt != bcMap.end ()) {
5372+ uint64_t bit = scanBc - leftBC;
5373+ int64_t bcGlId = scanIt->second ;
5374+
5375+ if (bcGlId >= 0 && bcGlId < static_cast <int64_t >(bcs.size ())) {
5376+ const auto & bc = bcs.iteratorAt (bcGlId);
5377+
5378+ // Fill pileup flags using BC selection bits (following PWGUD pattern)
5379+ if (!bc.selection_bit (o2::aod::evsel::kNoBGT0A ))
5380+ values[kBGFT0Apf ] |= (1 << bit);
5381+ if (!bc.selection_bit (o2::aod::evsel::kNoBGT0C ))
5382+ values[kBGFT0Cpf ] |= (1 << bit);
5383+ if (bc.selection_bit (o2::aod::evsel::kIsBBT0A ))
5384+ values[kBBFT0Apf ] |= (1 << bit);
5385+ if (bc.selection_bit (o2::aod::evsel::kIsBBT0C ))
5386+ values[kBBFT0Cpf ] |= (1 << bit);
5387+ if (!bc.selection_bit (o2::aod::evsel::kNoBGV0A ))
5388+ values[kBGFV0Apf ] |= (1 << bit);
5389+ if (bc.selection_bit (o2::aod::evsel::kIsBBV0A ))
5390+ values[kBBFV0Apf ] |= (1 << bit);
5391+ if (!bc.selection_bit (o2::aod::evsel::kNoBGFDA ))
5392+ values[kBGFDDApf ] |= (1 << bit);
5393+ if (!bc.selection_bit (o2::aod::evsel::kNoBGFDC ))
5394+ values[kBGFDDCpf ] |= (1 << bit);
5395+ if (bc.selection_bit (o2::aod::evsel::kIsBBFDA ))
5396+ values[kBBFDDApf ] |= (1 << bit);
5397+ if (bc.selection_bit (o2::aod::evsel::kIsBBFDC ))
5398+ values[kBBFDDCpf ] |= (1 << bit);
5399+ }
5400+
5401+ ++scanIt;
5402+ if (scanIt == bcMap.end ())
5403+ break ;
5404+ scanBc = scanIt->first ;
5405+ }
5406+ }
5407+
5408+ // Note: Distance to closest BCs with specific triggers (TOR, TSC, TVX, V0A, T0A)
5409+ // would require scanning a larger range and checking trigger information.
5410+ // For now, these remain at default values (999) as the implementation would need
5411+ // access to CTP trigger information which may not be available in all cases.
53555412}
53565413
53575414template <typename T>
@@ -5361,130 +5418,40 @@ void VarManager::FillFIT(const T& obj, float* values)
53615418 values = fgValues;
53625419 }
53635420
5364- // Initialize all FIT variables to default values
5365- values[kAmplitudeFT0A ] = -1 .f ;
5366- values[kAmplitudeFT0C ] = -1 .f ;
5367- values[kTimeFT0A ] = -999 .f ;
5368- values[kTimeFT0C ] = -999 .f ;
5369- values[kTriggerMaskFT0 ] = 0 ;
5370- values[kNFiredChannelsFT0A ] = 0 ;
5371- values[kNFiredChannelsFT0C ] = 0 ;
5372- values[kAmplitudeFDDA ] = -1 .f ;
5373- values[kAmplitudeFDDC ] = -1 .f ;
5374- values[kTimeFDDA ] = -999 .f ;
5375- values[kTimeFDDC ] = -999 .f ;
5376- values[kTriggerMaskFDD ] = 0 ;
5377- values[kNFiredChannelsFDDA ] = 0 ;
5378- values[kNFiredChannelsFDDC ] = 0 ;
5379- values[kAmplitudeFV0A ] = -1 .f ;
5380- values[kTimeFV0A ] = -999 .f ;
5381- values[kTriggerMaskFV0A ] = 0 ;
5382- values[kNFiredChannelsFV0A ] = 0 ;
5383- values[kBBFT0Apf ] = 0 ;
5384- values[kBGFT0Apf ] = 0 ;
5385- values[kBBFT0Cpf ] = 0 ;
5386- values[kBGFT0Cpf ] = 0 ;
5387- values[kBBFV0Apf ] = 0 ;
5388- values[kBGFV0Apf ] = 0 ;
5389- values[kBBFDDApf ] = 0 ;
5390- values[kBGFDDApf ] = 0 ;
5391- values[kBBFDDCpf ] = 0 ;
5392- values[kBGFDDCpf ] = 0 ;
5393- values[kDistClosestBcTOR ] = 999 ;
5394- values[kDistClosestBcTSC ] = 999 ;
5395- values[kDistClosestBcTVX ] = 999 ;
5396- values[kDistClosestBcV0A ] = 999 ;
5397- values[kDistClosestBcT0A ] = 999 ;
5398-
5399- // Check if this is a ReducedFIT object (has amplitudeFT0A() method) or a BC object (has has_foundFT0() method)
5400- // Use if constexpr with requires clause or SFINAE to distinguish between the two types
5401- // For now, we'll use a simpler approach: try to call methods that exist on each type
5402-
5403- if constexpr (requires { obj.amplitudeFT0A (); }) {
5404- // This is a ReducedFIT object - fill from reduced DQ data model
5405- values[kAmplitudeFT0A ] = obj.amplitudeFT0A ();
5406- values[kAmplitudeFT0C ] = obj.amplitudeFT0C ();
5407- values[kTimeFT0A ] = obj.timeFT0A ();
5408- values[kTimeFT0C ] = obj.timeFT0C ();
5409- values[kTriggerMaskFT0 ] = obj.triggerMaskFT0 ();
5410- values[kNFiredChannelsFT0A ] = obj.nFiredChannelsFT0A ();
5411- values[kNFiredChannelsFT0C ] = obj.nFiredChannelsFT0C ();
5412- values[kAmplitudeFDDA ] = obj.amplitudeFDDA ();
5413- values[kAmplitudeFDDC ] = obj.amplitudeFDDC ();
5414- values[kTimeFDDA ] = obj.timeFDDA ();
5415- values[kTimeFDDC ] = obj.timeFDDC ();
5416- values[kTriggerMaskFDD ] = obj.triggerMaskFDD ();
5417- values[kNFiredChannelsFDDA ] = obj.nFiredChannelsFDDA ();
5418- values[kNFiredChannelsFDDC ] = obj.nFiredChannelsFDDC ();
5419- values[kAmplitudeFV0A ] = obj.amplitudeFV0A ();
5420- values[kTimeFV0A ] = obj.timeFV0A ();
5421- values[kTriggerMaskFV0A ] = obj.triggerMaskFV0A ();
5422- values[kNFiredChannelsFV0A ] = obj.nFiredChannelsFV0A ();
5423- values[kBBFT0Apf ] = obj.bbFT0Apf ();
5424- values[kBGFT0Apf ] = obj.bgFT0Apf ();
5425- values[kBBFT0Cpf ] = obj.bbFT0Cpf ();
5426- values[kBGFT0Cpf ] = obj.bgFT0Cpf ();
5427- values[kBBFV0Apf ] = obj.bbFV0Apf ();
5428- values[kBGFV0Apf ] = obj.bgFV0Apf ();
5429- values[kBBFDDApf ] = obj.bbFDDApf ();
5430- values[kBGFDDApf ] = obj.bgFDDApf ();
5431- values[kBBFDDCpf ] = obj.bbFDDCpf ();
5432- values[kBGFDDCpf ] = obj.bgFDDCpf ();
5433- values[kDistClosestBcTOR ] = obj.distClosestBcTOR ();
5434- values[kDistClosestBcTSC ] = obj.distClosestBcTSC ();
5435- values[kDistClosestBcTVX ] = obj.distClosestBcTVX ();
5436- values[kDistClosestBcV0A ] = obj.distClosestBcV0A ();
5437- values[kDistClosestBcT0A ] = obj.distClosestBcT0A ();
5438- } else if constexpr (requires { obj.has_foundFT0 (); }) {
5439- // This is a BC object - fill from raw FIT detectors
5440- // Fill FT0 information
5441- if (obj.has_foundFT0 ()) {
5442- auto ft0 = obj.foundFT0 ();
5443- values[kTimeFT0A ] = ft0.timeA ();
5444- values[kTimeFT0C ] = ft0.timeC ();
5445- const auto & ampsA = ft0.amplitudeA ();
5446- const auto & ampsC = ft0.amplitudeC ();
5447- values[kAmplitudeFT0A ] = 0 .f ;
5448- for (auto amp : ampsA)
5449- values[kAmplitudeFT0A ] += amp;
5450- values[kAmplitudeFT0C ] = 0 .f ;
5451- for (auto amp : ampsC)
5452- values[kAmplitudeFT0C ] += amp;
5453- values[kNFiredChannelsFT0A ] = ft0.channelA ().size ();
5454- values[kNFiredChannelsFT0C ] = ft0.channelC ().size ();
5455- values[kTriggerMaskFT0 ] = ft0.triggerMask ();
5456- }
5457-
5458- // Fill FV0A information
5459- if (obj.has_foundFV0 ()) {
5460- auto fv0a = obj.foundFV0 ();
5461- values[kTimeFV0A ] = fv0a.time ();
5462- const auto & amps = fv0a.amplitude ();
5463- values[kAmplitudeFV0A ] = 0 .f ;
5464- for (auto amp : amps)
5465- values[kAmplitudeFV0A ] += amp;
5466- values[kNFiredChannelsFV0A ] = fv0a.channel ().size ();
5467- values[kTriggerMaskFV0A ] = fv0a.triggerMask ();
5468- }
5469-
5470- // Fill FDD information
5471- if (obj.has_foundFDD ()) {
5472- auto fdd = obj.foundFDD ();
5473- values[kTimeFDDA ] = fdd.timeA ();
5474- values[kTimeFDDC ] = fdd.timeC ();
5475- const auto & ampsA = fdd.chargeA ();
5476- const auto & ampsC = fdd.chargeC ();
5477- values[kAmplitudeFDDA ] = 0 .f ;
5478- for (auto amp : ampsA)
5479- values[kAmplitudeFDDA ] += amp;
5480- values[kAmplitudeFDDC ] = 0 .f ;
5481- for (auto amp : ampsC)
5482- values[kAmplitudeFDDC ] += amp;
5483- values[kNFiredChannelsFDDA ] = fdd.channelA ().size ();
5484- values[kNFiredChannelsFDDC ] = fdd.channelC ().size ();
5485- values[kTriggerMaskFDD ] = fdd.triggerMask ();
5486- }
5487- }
5421+ // Fill from ReducedFIT table object - simple read of all columns
5422+ values[kAmplitudeFT0A ] = obj.amplitudeFT0A ();
5423+ values[kAmplitudeFT0C ] = obj.amplitudeFT0C ();
5424+ values[kTimeFT0A ] = obj.timeFT0A ();
5425+ values[kTimeFT0C ] = obj.timeFT0C ();
5426+ values[kTriggerMaskFT0 ] = obj.triggerMaskFT0 ();
5427+ values[kNFiredChannelsFT0A ] = obj.nFiredChannelsFT0A ();
5428+ values[kNFiredChannelsFT0C ] = obj.nFiredChannelsFT0C ();
5429+ values[kAmplitudeFDDA ] = obj.amplitudeFDDA ();
5430+ values[kAmplitudeFDDC ] = obj.amplitudeFDDC ();
5431+ values[kTimeFDDA ] = obj.timeFDDA ();
5432+ values[kTimeFDDC ] = obj.timeFDDC ();
5433+ values[kTriggerMaskFDD ] = obj.triggerMaskFDD ();
5434+ values[kNFiredChannelsFDDA ] = obj.nFiredChannelsFDDA ();
5435+ values[kNFiredChannelsFDDC ] = obj.nFiredChannelsFDDC ();
5436+ values[kAmplitudeFV0A ] = obj.amplitudeFV0A ();
5437+ values[kTimeFV0A ] = obj.timeFV0A ();
5438+ values[kTriggerMaskFV0A ] = obj.triggerMaskFV0A ();
5439+ values[kNFiredChannelsFV0A ] = obj.nFiredChannelsFV0A ();
5440+ values[kBBFT0Apf ] = obj.bbFT0Apf ();
5441+ values[kBGFT0Apf ] = obj.bgFT0Apf ();
5442+ values[kBBFT0Cpf ] = obj.bbFT0Cpf ();
5443+ values[kBGFT0Cpf ] = obj.bgFT0Cpf ();
5444+ values[kBBFV0Apf ] = obj.bbFV0Apf ();
5445+ values[kBGFV0Apf ] = obj.bgFV0Apf ();
5446+ values[kBBFDDApf ] = obj.bbFDDApf ();
5447+ values[kBGFDDApf ] = obj.bgFDDApf ();
5448+ values[kBBFDDCpf ] = obj.bbFDDCpf ();
5449+ values[kBGFDDCpf ] = obj.bgFDDCpf ();
5450+ values[kDistClosestBcTOR ] = obj.distClosestBcTOR ();
5451+ values[kDistClosestBcTSC ] = obj.distClosestBcTSC ();
5452+ values[kDistClosestBcTVX ] = obj.distClosestBcTVX ();
5453+ values[kDistClosestBcV0A ] = obj.distClosestBcV0A ();
5454+ values[kDistClosestBcT0A ] = obj.distClosestBcT0A ();
54885455}
54895456
54905457template <typename T1, typename T2>
0 commit comments