Skip to content

AFIT-11 - Implementation of FEE configuration object - #15888

Draft
wpierozak wants to merge 29 commits into
AliceO2Group:devfrom
wpierozak:AFIT-11
Draft

wpierozak wants to merge 29 commits into
AliceO2Group:devfrom
wpierozak:AFIT-11

Conversation

@wpierozak

Copy link
Copy Markdown
Contributor

Implementation of FEE configuration CCDB object and DCS workflow that fetches JSON from DCS and transforms it to the CCDB object

wpieroza and others added 25 commits August 5, 2026 07:16
…static memory corruption issue in HV schema; fixed schema issues in both FEE and HV
…to FITDCSConfigProcessor, added back DeadChannelMap definition in link file'
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

// \file FeeConfiguration.h

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct filename in comments

uint16_t adcDelays[NChannels];
uint16_t rangeCorrectionAdc0[NChannels];
uint16_t rangeCorrectionAdc1[NChannels];
uint16_t thresholdCalibration[NChannels];

@sahilupadhyaya92 sahilupadhyaya92 Oct 18, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thresholdCalibration is not included later in operator==(const ChannelsConfig& other) comparison and also not defined as a getter. Any specific reasons ?


template <int NChannels>
struct ChannelsConfig {
int16_t timeAligments[NChannels];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling of "Alignment" is incorrect almost throughout the draft.

{
struct TriggersConfig {
int16_t vertexTimeLowThreshold{o2::fit::config_helpers::DefaultValue};
int16_t vertexTimeHighThreshold{o2::fit::config_helpers::DefaultValue};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just cross-check the data types..
FDD has the same time thresholds declared as "float" and here is "int16_t"

#pragma link C++ struct o2::fv0::Fv0FeeConfiguration + ;
#pragma link C++ struct o2::fit::ChannelsConfig < 48> + ;
#pragma link C++ struct o2::fv0::Fv0HvConfiguration + ;
#pragma link C++ struct o2::fit::HvChannelsConfig < 48> + ;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing ??
#pragma link C++ struct o2::fv0::TriggersConfig + ;

void setValidateUpload(bool validate)
{
mValidateUpload = validate;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mValidateUpload is not initialized in the constructor.
If createObjectInfo() is called before setValidateUpload(), this reads an indeterminate value.
Should we provide an explicit default initialization?


namespace o2::fit
{
rapidjson::Document FITDCSBaseConfigReader::parseJsonBuffer(gsl::span<const char> buffer, bool throwOnInvalidSchema)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should also check document.HasParseError() in parseJsonBuffer(), as we already do for schemaDocument in loadSchema() ?
Currently, improper JSON could be returned as the schema validation is being skipped here..

{
long dataTime = (long)(pc.services().get<o2::framework::TimingInfo>().creation);
if (dataTime == 0xffffffffffffffff) { // means it is not set
dataTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); // in ms

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of std::chrono::high_resolution_clock here might not guarantee a Unix-based epoch, whereas CCDB validity timestamps require Unix time in milliseconds. Could we double-check whether this is safe? Alternatively, std::chrono::system_clock is also an option.

BOOST_CHECK_EQUAL(parsed.adcZeros[idx], adcZeros[idx]);
BOOST_CHECK_EQUAL(parsed.adcDelays[idx], adcDelays[idx]);
BOOST_CHECK_EQUAL(parsed.channelMaskData[idx], channelMaskData[idx]);
BOOST_CHECK_EQUAL(parsed.channelMaskTriggers[idx], channelMaskTriggers[idx]);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious.. Any reason not to include thresholdCalibration in the test payload ? This is part of ChannelsConfig, but it currently isn’t covered by the channel parsing test.

SimpleFITFEEConfigurationReader reader;
reader.parsePmConfig(doc, pmConfig);

BOOST_CHECK_EQUAL(pmConfig.orGate, orGateValue);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that this is just checking this pmConfig.orGate. We should also check pmConfig.trgChargeLowLevel and pmConfig.trgChargeHighLevel on PM level.
Also, which one actually is this pmConfig.orGate variable ?

"or_gate": {"type": "number"},
"trg_charge_low_level": {"type": "number"},
"trg_charge_high_level": {"type": "number"},
"fddCoincidenceMode": {"type": "boolean}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing " after "boolean

"threshold_calibration": {"type": "array", "items": {"type": "integer"}}
},
"additionalProperties": false,
"required": [

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should threshold_calibration also be included in the required list? parseChannelData() always attempts to parse this array, so a configuration without it would pass schema validation but fail during parsing

"or_gate": {"type": "number"},
"trg_charge_low_level": {"type": "number"},
"trg_charge_high_level": {"type": "number"},
"fdd_coincidence_mode": {"type": "boolean"}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that PmConfig contains fddCoincidenceMode and the schema allows fdd_coincidence_mode, but parsePmConfig() never assigns this field. Should it also be parsed here? Otherwise, the stored configuration will always retain the default value (false), even when the JSON specifies a different coincidence mode.

"items": {
"type": ["object", "null"],
"properties": {
"or_gate": {"type": "number"},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the PM fields or_gate, trg_charge_low_level, and trg_charge_high_level use "type": "integer" rather than "number" in the schema? The parser reads them using GetUint(), while "number" also permits floating-point values that GetUint() cannot handle.


} // namespace o2::fdd

#endif // O2_FV0_DCSCONFIGREADER_H

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor typo. should be O2_FDD_....

if (triggersNode.HasMember("sides_combination_mode") == false) {
throw std::runtime_error("Missing sides_combination_mode node!");
}
const auto& sidesCombinationMode = triggersNode["sides_combination_mode"];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that sidesCombinationMode is omitted from fetchFddFeeConfig.C, although it is required by FDDFEEConfigurationReader. Is there a specific reason for not including it in the JSON output?

Also, could you clarify the intended usage of fddCoincidenceMode? It is defined in PmConfig, but it is neither required by the JSON schema nor populated by parsePmConfig()

config.innerRings = innerRingsLevelNode.GetInt();
config.nChannels = nChannelsLevelNode.GetInt();
config.charge = chargeLevelNode.GetInt();
config.outerRings = chargeLevelNode.GetInt();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be config.outerRings = outerRingsLevelNode.GetUint(); ?

@sahilupadhyaya92

Copy link
Copy Markdown
Collaborator

Hi @wpierozak ,

Thanks for the implementation!

The overall structure looks good, particularly the shared FIT configuration readers and their integration into the FDD, FT0, and FV0 DCS workflows.
I’ve left a few inline comments regarding the parsing and representation of some configuration fields.
One additional point concerning the shared CCDB handling: could you please verify that the upload-validation flag is always initialized before DcsCcdbInfo::createObjectInfo() is called? The mValidateUpload member has no default initializer, so its value would be undefined if a configuration path does not explicitly set it.

Otherwise, the implementation looks consistent across the three detectors.

I would suggest to make 4 PRs out of this one: FIT common, FT0, FV0 and FDD.

Thanks a lot for the work!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants