Skip to content

Commit fdb1a5a

Browse files
minjungkim12claude
andcommitted
[PWGDQ] Complete FIT pileup flags and fired channels implementation
- Add missing fired channels counts for FV0A and FDD detectors in tableMaker BC filling - Implement complete pileup flag calculation (BB/BG flags for FT0A/C, FV0A, FDDA/C) - Scan ±16 BCs around collision BC to fill pileup flags using BC selection bits - Follow PWGUD UPCCandidateProducer::processFITInfo pattern for consistency - Note: BC distance calculations (TOR, TSC, TVX, V0A, T0A) remain at default (999) This completes the FIT detector information implementation for UPC analysis in PWGDQ framework. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
1 parent aaf800e commit fdb1a5a

File tree

1 file changed

+93
-126
lines changed

1 file changed

+93
-126
lines changed

PWGDQ/Core/VarManager.h

Lines changed: 93 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -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

53575414
template <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

54905457
template <typename T1, typename T2>

0 commit comments

Comments
 (0)