Skip to content

Commit dd935bb

Browse files
minjungkim12claude
andcommitted
[PWGDQ] Fix FIT detector filling by extracting detector objects explicitly
- Add type traits to detect FT0, FV0A, FDD detector objects - Modify FillFIT template to handle individual detector objects - Follow ZDC pattern: extract detector objects from BC before filling - Fix FT0 amplitude initialization to preserve sentinel values - Count only fired channels (amp > 0) for all detectors This fixes the issue where FT0 data was not being filled because bc.has_ft0() was checking for associations that weren't established when passing BC object directly. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent b9437df commit dd935bb

File tree

2 files changed

+109
-112
lines changed

2 files changed

+109
-112
lines changed

PWGDQ/Core/VarManager.h

Lines changed: 90 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -5262,15 +5262,42 @@ template <typename T>
52625262
struct has_amplitudeFT0A<T, std::void_t<decltype(std::declval<T>().amplitudeFT0A())>> : std::true_type {
52635263
};
52645264

5265-
// Unified FillFIT version for both BC objects and ReducedFIT table objects
5265+
// Helper to detect FT0 detector object (has amplitudeA method)
5266+
template <typename T, typename = void>
5267+
struct is_FT0 : std::false_type {
5268+
};
5269+
5270+
template <typename T>
5271+
struct is_FT0<T, std::void_t<decltype(std::declval<T>().amplitudeA())>> : std::true_type {
5272+
};
5273+
5274+
// Helper to detect FV0A detector object (has amplitude method, not amplitudeA)
5275+
template <typename T, typename = void>
5276+
struct is_FV0A : std::false_type {
5277+
};
5278+
5279+
template <typename T>
5280+
struct is_FV0A<T, std::void_t<decltype(std::declval<T>().amplitude())>> : std::true_type {
5281+
};
5282+
5283+
// Helper to detect FDD detector object (has chargeA method)
5284+
template <typename T, typename = void>
5285+
struct is_FDD : std::false_type {
5286+
};
5287+
5288+
template <typename T>
5289+
struct is_FDD<T, std::void_t<decltype(std::declval<T>().chargeA())>> : std::true_type {
5290+
};
5291+
5292+
// Unified FillFIT version for ReducedFIT table objects and individual detector objects (FT0, FV0A, FDD)
52665293
template <typename T>
52675294
void VarManager::FillFIT(T const& obj, float* values)
52685295
{
52695296
if (!values) {
52705297
values = fgValues;
52715298
}
52725299

5273-
// Check if this is a BC object (has has_foundFT0 method) or ReducedFIT table object (has amplitudeFT0A method)
5300+
// Handle different object types using type traits
52745301
if constexpr (has_amplitudeFT0A<T>::value) {
52755302
// This is a ReducedFIT table object - read all columns directly
52765303
values[kAmplitudeFT0A] = obj.amplitudeFT0A();
@@ -5306,119 +5333,73 @@ void VarManager::FillFIT(T const& obj, float* values)
53065333
values[kDistClosestBcTVX] = obj.distClosestBcTVX();
53075334
values[kDistClosestBcV0A] = obj.distClosestBcV0A();
53085335
values[kDistClosestBcT0A] = obj.distClosestBcT0A();
5309-
} else {
5310-
// This is a BC object - access FIT detectors via BC associations
5311-
LOG(info) << "VarManager::FillFIT: Using BC object path";
5312-
// Initialize all FIT variables to default values first
5313-
values[kAmplitudeFT0A] = -1.f;
5314-
values[kAmplitudeFT0C] = -1.f;
5315-
values[kTimeFT0A] = -999.f;
5316-
values[kTimeFT0C] = -999.f;
5317-
values[kTriggerMaskFT0] = 0;
5318-
values[kNFiredChannelsFT0A] = 0;
5319-
values[kNFiredChannelsFT0C] = 0;
5320-
values[kAmplitudeFDDA] = -1.f;
5321-
values[kAmplitudeFDDC] = -1.f;
5322-
values[kTimeFDDA] = -999.f;
5323-
values[kTimeFDDC] = -999.f;
5324-
values[kTriggerMaskFDD] = 0;
5325-
values[kNFiredChannelsFDDA] = 0;
5326-
values[kNFiredChannelsFDDC] = 0;
5327-
values[kAmplitudeFV0A] = -1.f;
5328-
values[kTimeFV0A] = -999.f;
5329-
values[kTriggerMaskFV0A] = 0;
5330-
values[kNFiredChannelsFV0A] = 0;
5331-
values[kBGFT0Apf] = 0.f;
5332-
values[kBGFT0Cpf] = 0.f;
5333-
values[kBBFT0Apf] = 0.f;
5334-
values[kBBFT0Cpf] = 0.f;
5335-
values[kBGFV0Apf] = 0.f;
5336-
values[kBBFV0Apf] = 0.f;
5337-
values[kBGFDDApf] = 0.f;
5338-
values[kBGFDDCpf] = 0.f;
5339-
values[kBBFDDApf] = 0.f;
5340-
values[kBBFDDCpf] = 0.f;
5341-
values[kDistClosestBcTOR] = 999.f;
5342-
values[kDistClosestBcTSC] = 999.f;
5343-
values[kDistClosestBcTVX] = 999.f;
5344-
values[kDistClosestBcV0A] = 999.f;
5345-
values[kDistClosestBcT0A] = 999.f;
5346-
5347-
// Fill FT0 information from BC
5348-
if (obj.has_ft0()) {
5349-
auto ft0 = obj.ft0();
5350-
float ampA = 0.f;
5351-
int nFiredFT0A = 0;
5352-
for (auto const& amp : ft0.amplitudeA()) {
5353-
if (amp > 0) {
5354-
ampA += amp;
5355-
nFiredFT0A++;
5356-
}
5336+
} else if constexpr (is_FT0<T>::value) {
5337+
// This is an FT0 detector object
5338+
float ampA = 0.f;
5339+
int nFiredFT0A = 0;
5340+
for (auto const& amp : obj.amplitudeA()) {
5341+
if (amp > 0) {
5342+
ampA += amp;
5343+
nFiredFT0A++;
53575344
}
5358-
float ampC = 0.f;
5359-
int nFiredFT0C = 0;
5360-
for (auto const& amp : ft0.amplitudeC()) {
5361-
if (amp > 0) {
5362-
ampC += amp;
5363-
nFiredFT0C++;
5364-
}
5345+
}
5346+
float ampC = 0.f;
5347+
int nFiredFT0C = 0;
5348+
for (auto const& amp : obj.amplitudeC()) {
5349+
if (amp > 0) {
5350+
ampC += amp;
5351+
nFiredFT0C++;
53655352
}
5366-
// Only overwrite defaults if we have actual signal
5367-
if (nFiredFT0A > 0) values[kAmplitudeFT0A] = ampA;
5368-
if (nFiredFT0C > 0) values[kAmplitudeFT0C] = ampC;
5369-
values[kTimeFT0A] = ft0.timeA();
5370-
values[kTimeFT0C] = ft0.timeC();
5371-
values[kTriggerMaskFT0] = ft0.triggerMask();
5372-
values[kNFiredChannelsFT0A] = nFiredFT0A;
5373-
values[kNFiredChannelsFT0C] = nFiredFT0C;
5374-
}
5375-
5376-
// Fill FV0A information from BC
5377-
if (obj.has_fv0a()) {
5378-
auto fv0a = obj.fv0a();
5379-
float ampV0A = 0.f;
5380-
int nFiredFV0A = 0;
5381-
for (auto const& amp : fv0a.amplitude()) {
5382-
if (amp > 0) {
5383-
ampV0A += amp;
5384-
nFiredFV0A++;
5385-
}
5353+
}
5354+
// Only overwrite defaults if we have actual signal
5355+
if (nFiredFT0A > 0) values[kAmplitudeFT0A] = ampA;
5356+
if (nFiredFT0C > 0) values[kAmplitudeFT0C] = ampC;
5357+
values[kTimeFT0A] = obj.timeA();
5358+
values[kTimeFT0C] = obj.timeC();
5359+
values[kTriggerMaskFT0] = obj.triggerMask();
5360+
values[kNFiredChannelsFT0A] = nFiredFT0A;
5361+
values[kNFiredChannelsFT0C] = nFiredFT0C;
5362+
} else if constexpr (is_FDD<T>::value) {
5363+
// This is an FDD detector object
5364+
float ampFDDA = 0.f;
5365+
int nFiredFDDA = 0;
5366+
for (auto const& amp : obj.chargeA()) {
5367+
if (amp > 0) {
5368+
ampFDDA += amp;
5369+
nFiredFDDA++;
53865370
}
5387-
// Only overwrite defaults if we have actual signal
5388-
if (nFiredFV0A > 0) values[kAmplitudeFV0A] = ampV0A;
5389-
values[kTimeFV0A] = fv0a.time();
5390-
values[kTriggerMaskFV0A] = fv0a.triggerMask();
5391-
values[kNFiredChannelsFV0A] = nFiredFV0A;
5392-
}
5393-
5394-
// Fill FDD information from BC
5395-
if (obj.has_fdd()) {
5396-
auto fdd = obj.fdd();
5397-
float ampFDDA = 0.f;
5398-
int nFiredFDDA = 0;
5399-
for (auto const& amp : fdd.chargeA()) {
5400-
if (amp > 0) {
5401-
ampFDDA += amp;
5402-
nFiredFDDA++;
5403-
}
5371+
}
5372+
float ampFDDC = 0.f;
5373+
int nFiredFDDC = 0;
5374+
for (auto const& amp : obj.chargeC()) {
5375+
if (amp > 0) {
5376+
ampFDDC += amp;
5377+
nFiredFDDC++;
54045378
}
5405-
float ampFDDC = 0.f;
5406-
int nFiredFDDC = 0;
5407-
for (auto const& amp : fdd.chargeC()) {
5408-
if (amp > 0) {
5409-
ampFDDC += amp;
5410-
nFiredFDDC++;
5411-
}
5379+
}
5380+
// Only overwrite defaults if we have actual signal
5381+
if (nFiredFDDA > 0) values[kAmplitudeFDDA] = ampFDDA;
5382+
if (nFiredFDDC > 0) values[kAmplitudeFDDC] = ampFDDC;
5383+
values[kTimeFDDA] = obj.timeA();
5384+
values[kTimeFDDC] = obj.timeC();
5385+
values[kTriggerMaskFDD] = obj.triggerMask();
5386+
values[kNFiredChannelsFDDA] = nFiredFDDA;
5387+
values[kNFiredChannelsFDDC] = nFiredFDDC;
5388+
} else if constexpr (is_FV0A<T>::value && !is_FT0<T>::value) {
5389+
// This is an FV0A detector object (exclude FT0 which also has amplitude method)
5390+
float ampV0A = 0.f;
5391+
int nFiredFV0A = 0;
5392+
for (auto const& amp : obj.amplitude()) {
5393+
if (amp > 0) {
5394+
ampV0A += amp;
5395+
nFiredFV0A++;
54125396
}
5413-
// Only overwrite defaults if we have actual signal
5414-
if (nFiredFDDA > 0) values[kAmplitudeFDDA] = ampFDDA;
5415-
if (nFiredFDDC > 0) values[kAmplitudeFDDC] = ampFDDC;
5416-
values[kTimeFDDA] = fdd.timeA();
5417-
values[kTimeFDDC] = fdd.timeC();
5418-
values[kTriggerMaskFDD] = fdd.triggerMask();
5419-
values[kNFiredChannelsFDDA] = nFiredFDDA;
5420-
values[kNFiredChannelsFDDC] = nFiredFDDC;
54215397
}
5398+
// Only overwrite defaults if we have actual signal
5399+
if (nFiredFV0A > 0) values[kAmplitudeFV0A] = ampV0A;
5400+
values[kTimeFV0A] = obj.time();
5401+
values[kTriggerMaskFV0A] = obj.triggerMask();
5402+
values[kNFiredChannelsFV0A] = nFiredFV0A;
54225403
}
54235404
}
54245405

PWGDQ/TableProducer/tableMaker_withAssoc.cxx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -868,11 +868,27 @@ struct TableMaker {
868868
if constexpr ((TEventFillMap & VarManager::ObjTypes::RapidityGapFilter) > 0) {
869869
// The DQRapidityGapFilter contains the index of the bc we want to get FIT info from
870870
auto newbc = bcs.rawIteratorAt(collision.newBcIndex());
871-
// Fill FIT information from newbc using simple VarManager::FillFIT() like FillZDC
872-
VarManager::FillFIT(newbc);
871+
// Fill FIT information from detectors explicitly like ZDC
872+
if (newbc.has_ft0()) {
873+
VarManager::FillFIT(newbc.ft0());
874+
}
875+
if (newbc.has_fv0a()) {
876+
VarManager::FillFIT(newbc.fv0a());
877+
}
878+
if (newbc.has_fdd()) {
879+
VarManager::FillFIT(newbc.fdd());
880+
}
873881
} else {
874882
// Use bcEvSel (collision BC) when RapidityGapFilter is not enabled
875-
VarManager::FillFIT(bcEvSel);
883+
if (bcEvSel.has_ft0()) {
884+
VarManager::FillFIT(bcEvSel.ft0());
885+
}
886+
if (bcEvSel.has_fv0a()) {
887+
VarManager::FillFIT(bcEvSel.fv0a());
888+
}
889+
if (bcEvSel.has_fdd()) {
890+
VarManager::FillFIT(bcEvSel.fdd());
891+
}
876892
}
877893
}
878894
if constexpr ((TEventFillMap & VarManager::ObjTypes::CollisionMultExtra) > 0 && (TTrackFillMap & VarManager::ObjTypes::Track) > 0 && (TTrackFillMap & VarManager::ObjTypes::TrackDCA) > 0) {

0 commit comments

Comments
 (0)