Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct CTFReaderInp {
std::string remoteRegex{};
std::vector<int> ctfIDs{};
bool allowMissingDetectors = false;
bool sup0xccdb = false;
int maxFileCache = 1;
int64_t delay_us = 0;
int maxLoops = 0;
Expand Down
12 changes: 10 additions & 2 deletions Detectors/CTF/workflow/src/CTFReaderSpec.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ void CTFReaderSpec::processTF(ProcessingContext& pc)

LOG(info) << ctfHeader;

auto& timingInfo = pc.services().get<TimingInfo>();
timingInfo.firstTFOrbit = ctfHeader.firstTForbit;
timingInfo.creation = ctfHeader.creationTime;
timingInfo.tfCounter = mCTFCounter;
timingInfo.runNumber = ctfHeader.run;

// send CTF Header
pc.outputs().snapshot({"header"}, ctfHeader);
setMessageHeader(pc, ctfHeader, "header");
Expand All @@ -254,7 +260,7 @@ void CTFReaderSpec::processTF(ProcessingContext& pc)
processDetector<o2::ctp::CTF>(DetID::CTP, ctfHeader, pc);

// send sTF acknowledge message
{
if (!mInput.sup0xccdb) {
auto& stfDist = pc.outputs().make<o2::header::STFHeader>(OutputRef{"STFDist", 0xccdb});
stfDist.id = uint64_t(mCurrTreeEntry);
stfDist.firstOrbit = ctfHeader.firstTForbit;
Expand Down Expand Up @@ -385,7 +391,9 @@ DataProcessorSpec getCTFReaderSpec(const CTFReaderInp& inp)
outputs.emplace_back(OutputLabel{det.getName()}, det.getDataOrigin(), "CTFDATA", 0, Lifetime::Timeframe);
}
}
outputs.emplace_back(OutputSpec{{"STFDist"}, o2::header::gDataOriginFLP, o2::header::gDataDescriptionDISTSTF, 0xccdb});
if (!inp.sup0xccdb) {
outputs.emplace_back(OutputSpec{{"STFDist"}, o2::header::gDataOriginFLP, o2::header::gDataDescriptionDISTSTF, 0xccdb});
}

return DataProcessorSpec{
"ctf-reader",
Expand Down
2 changes: 2 additions & 0 deletions Detectors/CTF/workflow/src/ctf-reader-workflow.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ void customize(std::vector<o2::framework::ConfigParamSpec>& workflowOptions)
options.push_back(ConfigParamSpec{"remote-regex", VariantType::String, "^(alien://|)/alice/data/.+", {"regex string to identify remote files"}}); // Use "^/eos/aliceo2/.+" for direct EOS access
options.push_back(ConfigParamSpec{"max-cached-files", VariantType::Int, 3, {"max CTF files queued (copied for remote source)"}});
options.push_back(ConfigParamSpec{"allow-missing-detectors", VariantType::Bool, false, {"send empty message if detector is missing in the CTF (otherwise throw)"}});
options.push_back(ConfigParamSpec{"suppress-diststf-0xccdb", VariantType::Bool, false, {"suppress explicit FLP/DISTSUBTIMEFRAME/0xccdb output"}});
options.push_back(ConfigParamSpec{"ctf-reader-verbosity", VariantType::Int, 0, {"verbosity level (0: summary per detector, 1: summary per block"}});
options.push_back(ConfigParamSpec{"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings"}});
//
Expand Down Expand Up @@ -110,6 +111,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
ctfInput.tffileRegex = configcontext.options().get<std::string>("ctf-file-regex");
ctfInput.remoteRegex = configcontext.options().get<std::string>("remote-regex");
ctfInput.allowMissingDetectors = configcontext.options().get<bool>("allow-missing-detectors");
ctfInput.sup0xccdb = configcontext.options().get<bool>("suppress-diststf-0xccdb");

specs.push_back(o2::ctf::getCTFReaderSpec(ctfInput));
int verbosity = configcontext.options().get<int>("ctf-reader-verbosity");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class SubTimeFrameFileReader
~SubTimeFrameFileReader();

/// Read a single TF from the file
std::unique_ptr<MessagesPerRoute> read(FairMQDevice* device, const std::vector<o2f::OutputRoute>& outputRoutes, const std::string& rawChannel, int verbosity);
std::unique_ptr<MessagesPerRoute> read(FairMQDevice* device, const std::vector<o2f::OutputRoute>& outputRoutes, const std::string& rawChannel, bool sup0xccdb, int verbosity);

/// Tell the current position of the file
inline std::uint64_t position() const { return mFileMapOffset; }
Expand Down
4 changes: 2 additions & 2 deletions Detectors/Raw/TFReaderDD/src/SubTimeFrameFileReader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ Stack SubTimeFrameFileReader::getHeaderStack(std::size_t& pOrigsize)
std::uint64_t SubTimeFrameFileReader::sStfId = 0; // TODO: add id to files metadata

std::unique_ptr<MessagesPerRoute> SubTimeFrameFileReader::read(FairMQDevice* device, const std::vector<o2f::OutputRoute>& outputRoutes,
const std::string& rawChannel, int verbosity)
const std::string& rawChannel, bool sup0xccdb, int verbosity)
{
std::unique_ptr<MessagesPerRoute> messagesPerRoute = std::make_unique<MessagesPerRoute>();
auto& msgMap = *messagesPerRoute.get();
Expand Down Expand Up @@ -393,7 +393,7 @@ std::unique_ptr<MessagesPerRoute> SubTimeFrameFileReader::read(FairMQDevice* dev

// add TF acknowledge part
unsigned stfSS[2] = {0, 0xccdb};
for (int iss = 0; iss < 2; iss++) {
for (int iss = 0; iss < (sup0xccdb ? 1 : 2); iss++) {
o2::header::DataHeader stfDistDataHeader(o2::header::gDataDescriptionDISTSTF, o2::header::gDataOriginFLP, stfSS[iss], sizeof(STFHeader), 0, 1);
stfDistDataHeader.payloadSerializationMethod = o2::header::gSerializationMethodNone;
stfDistDataHeader.firstTForbit = stfHeader.firstOrbit;
Expand Down
19 changes: 17 additions & 2 deletions Detectors/Raw/TFReaderDD/src/TFReaderSpec.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,16 @@ void TFReaderSpec::run(o2f::ProcessingContext& ctx)
LOGP(error, "Failed to find output channel for {}/{}/{} @ timeslice {}", h.dataOrigin.str, h.dataDescription.str, h.subSpecification, h.tfCounter);
return std::string{};
};
auto setTimingInfo = [&ctx](TFMap& msgMap) {
auto& timingInfo = ctx.services().get<TimingInfo>();
const auto* dataptr = (*msgMap.begin()->second.get())[0].GetData();
const auto* hd0 = o2h::get<o2h::DataHeader*>(dataptr);
const auto* dph = o2h::get<o2f::DataProcessingHeader*>(dataptr);
timingInfo.firstTFOrbit = hd0->firstTForbit;
timingInfo.creation = dph->creation;
timingInfo.tfCounter = hd0->tfCounter;
timingInfo.runNumber = hd0->runNumber;
};

auto addMissingParts = [this, &findOutputChannel](TFMap& msgMap) {
// at least the 1st header is guaranteed to be filled by the reader, use it for extra info
Expand All @@ -165,6 +175,7 @@ void TFReaderSpec::run(o2f::ProcessingContext& ctx)
outHeader.payloadSerializationMethod = o2h::gSerializationMethodNone;
outHeader.firstTForbit = hd0->firstTForbit;
outHeader.tfCounter = hd0->tfCounter;
outHeader.runNumber = hd0->runNumber;
const auto fmqChannel = findOutputChannel(outHeader);
if (fmqChannel.empty()) { // no output channel
continue;
Expand Down Expand Up @@ -196,6 +207,8 @@ void TFReaderSpec::run(o2f::ProcessingContext& ctx)
LOG(error) << "Builder provided nullptr TF pointer";
continue;
}
setTimingInfo(*tfPtr.get());

if (mInput.sendDummyForMissing) {
for (auto& msgIt : *tfPtr.get()) { // complete with empty output for the specs which were requested but not seen in the data
acknowledgeOutput(*msgIt.second.get());
Expand Down Expand Up @@ -311,7 +324,7 @@ void TFReaderSpec::TFBuilder()
std::this_thread::sleep_for(sleepTime);
continue;
}
auto tf = reader.read(mDevice, mOutputRoutes, mInput.rawChannelConfig, mInput.verbosity);
auto tf = reader.read(mDevice, mOutputRoutes, mInput.rawChannelConfig, mInput.sup0xccdb, mInput.verbosity);
if (tf) {
mTFBuilderCounter++;
}
Expand Down Expand Up @@ -387,7 +400,9 @@ o2f::DataProcessorSpec o2::rawdd::getTFReaderSpec(o2::rawdd::TFReaderInp& rinp)
}
}
spec.outputs.emplace_back(o2f::OutputSpec{{"stfDist"}, o2h::gDataOriginFLP, o2h::gDataDescriptionDISTSTF, 0});
spec.outputs.emplace_back(o2f::OutputSpec{{"stfDist"}, o2h::gDataOriginFLP, o2h::gDataDescriptionDISTSTF, 0xccdb});
if (!rinp.sup0xccdb) {
spec.outputs.emplace_back(o2f::OutputSpec{{"stfDistCCDB"}, o2h::gDataOriginFLP, o2h::gDataDescriptionDISTSTF, 0xccdb});
}
} else {
auto nameStart = rinp.rawChannelConfig.find("name=");
if (nameStart == std::string::npos) {
Expand Down
1 change: 1 addition & 0 deletions Detectors/Raw/TFReaderDD/src/TFReaderSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct TFReaderInp {
int maxLoops = 0;
int maxTFs = -1;
bool sendDummyForMissing = true;
bool sup0xccdb = false;
std::vector<o2::header::DataHeader> hdVec;
};

Expand Down
2 changes: 2 additions & 0 deletions Detectors/Raw/TFReaderDD/src/tf-reader-workflow.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ void customize(std::vector<ConfigParamSpec>& workflowOptions)
options.push_back(ConfigParamSpec{"max-cached-files", VariantType::Int, 3, {"max TF files queued (copied for remote source)"}});
options.push_back(ConfigParamSpec{"tf-reader-verbosity", VariantType::Int, 0, {"verbosity level (1 or 2: check RDH, print DH/DPH for 1st or all slices, >2 print RDH)"}});
options.push_back(ConfigParamSpec{"raw-channel-config", VariantType::String, "", {"optional raw FMQ channel for non-DPL output"}});
options.push_back(ConfigParamSpec{"suppress-diststf-0xccdb", VariantType::Bool, false, {"suppress explicit FLP/DISTSUBTIMEFRAME/0xccdb output"}});
options.push_back(ConfigParamSpec{"disable-dummy-output", VariantType::Bool, false, {"Disable sending empty output if corresponding data is not found in the data"}});
options.push_back(ConfigParamSpec{"configKeyValues", VariantType::String, "", {"semicolon separated key=value strings"}});
// options for error-check suppression
Expand Down Expand Up @@ -67,6 +68,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
rinp.tffileRegex = configcontext.options().get<std::string>("tf-file-regex");
rinp.remoteRegex = configcontext.options().get<std::string>("remote-regex");
rinp.sendDummyForMissing = !configcontext.options().get<bool>("disable-dummy-output");
rinp.sup0xccdb = configcontext.options().get<bool>("suppress-diststf-0xccdb");
o2::conf::ConfigurableParam::updateFromString(configcontext.options().get<std::string>("configKeyValues"));

WorkflowSpec specs;
Expand Down
2 changes: 2 additions & 0 deletions Detectors/Raw/include/DetectorsRaw/RawFileReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct ReaderInp {
size_t spSize = 1024L * 1024L;
size_t bufferSize = 1024L * 1024L;
int loop = 1;
int runNumber = 0;
uint32_t delay_us = 0;
uint32_t errMap = 0xffffffff;
uint32_t minTF = 0;
Expand All @@ -51,6 +52,7 @@ struct ReaderInp {
bool cache = false;
bool autodetectTF0 = false;
bool preferCalcTF = false;
bool sup0xccdb = false;
};

class RawFileReader
Expand Down
18 changes: 15 additions & 3 deletions Detectors/Raw/src/RawFileReaderWorkflow.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,14 @@ class RawReaderSpecs : public o2f::Task
uint32_t mDelayUSec = 0; // Delay in microseconds between TFs
uint32_t mMinTFID = 0; // 1st TF to extract
uint32_t mMaxTFID = 0xffffffff; // last TF to extrct
int mRunNumber = 0; // run number to pass
int mVerbosity = 0;
bool mPreferCalcTF = false;
size_t mLoopsDone = 0;
size_t mSentSize = 0;
size_t mSentMessages = 0;
bool mPartPerSP = true; // fill part per superpage
bool mSup0xccdb = false; // suppress explicit FLP/DISTSUBTIMEFRAME/0xccdb output
std::string mRawChannelName = ""; // name of optional non-DPL channel
std::unique_ptr<o2::raw::RawFileReader> mReader; // matching engine
std::unordered_map<std::string, std::pair<int, int>> mDropTFMap; // allows to drop certain fraction of TFs
Expand All @@ -88,7 +90,7 @@ class RawReaderSpecs : public o2f::Task

//___________________________________________________________
RawReaderSpecs::RawReaderSpecs(const ReaderInp& rinp)
: mLoop(rinp.loop < 0 ? INT_MAX : (rinp.loop < 1 ? 1 : rinp.loop)), mDelayUSec(rinp.delay_us), mMinTFID(rinp.minTF), mMaxTFID(rinp.maxTF), mPartPerSP(rinp.partPerSP), mReader(std::make_unique<o2::raw::RawFileReader>(rinp.inifile, rinp.verbosity, rinp.bufferSize)), mRawChannelName(rinp.rawChannelConfig), mVerbosity(rinp.verbosity), mPreferCalcTF(rinp.preferCalcTF)
: mLoop(rinp.loop < 0 ? INT_MAX : (rinp.loop < 1 ? 1 : rinp.loop)), mDelayUSec(rinp.delay_us), mMinTFID(rinp.minTF), mMaxTFID(rinp.maxTF), mRunNumber(rinp.runNumber), mPartPerSP(rinp.partPerSP), mSup0xccdb(rinp.sup0xccdb), mReader(std::make_unique<o2::raw::RawFileReader>(rinp.inifile, rinp.verbosity, rinp.bufferSize)), mRawChannelName(rinp.rawChannelConfig), mVerbosity(rinp.verbosity), mPreferCalcTF(rinp.preferCalcTF)
{
mReader->setCheckErrors(rinp.errMap);
mReader->setMaxTFToRead(rinp.maxTF);
Expand Down Expand Up @@ -265,6 +267,7 @@ void RawReaderSpecs::run(o2f::ProcessingContext& ctx)
hdrTmpl.payloadSerializationMethod = o2h::gSerializationMethodNone;
hdrTmpl.splitPayloadParts = nParts;
hdrTmpl.tfCounter = mTFCounter;
hdrTmpl.runNumber = mRunNumber;
if (mVerbosity > 1) {
LOG(info) << link.describe() << " will read " << nParts << " HBFs starting from block " << link.nextBlock2Read;
}
Expand Down Expand Up @@ -302,11 +305,18 @@ void RawReaderSpecs::run(o2f::ProcessingContext& ctx)
mLoopsDone, link.origin.as<std::string>(), link.description.as<std::string>(), link.subspec);
}

auto& timingInfo = ctx.services().get<TimingInfo>();
timingInfo.firstTFOrbit = firstOrbit;
timingInfo.creation = creationTime;
timingInfo.tfCounter = mTFCounter;
timingInfo.runNumber = mRunNumber;

// send sTF acknowledge message
unsigned stfSS[2] = {0, 0xccdb};
for (int iss = 0; iss < 2; iss++) {
for (int iss = 0; iss < (mSup0xccdb ? 1 : 2); iss++) {
o2::header::STFHeader stfHeader{mTFCounter, firstOrbit, 0};
o2::header::DataHeader stfDistDataHeader(o2::header::gDataDescriptionDISTSTF, o2::header::gDataOriginFLP, stfSS[iss], sizeof(o2::header::STFHeader), 0, 1);
stfDistDataHeader.runNumber = mRunNumber;
stfDistDataHeader.payloadSerializationMethod = o2h::gSerializationMethodNone;
stfDistDataHeader.firstTForbit = stfHeader.firstOrbit;
stfDistDataHeader.tfCounter = mTFCounter;
Expand Down Expand Up @@ -360,7 +370,9 @@ o2f::DataProcessorSpec getReaderSpec(ReaderInp rinp)
}
// add output for DISTSUBTIMEFRAME
spec.outputs.emplace_back(o2f::OutputSpec{{"stfDist"}, o2::header::gDataOriginFLP, o2::header::gDataDescriptionDISTSTF, 0});
spec.outputs.emplace_back(o2f::OutputSpec{{"stfDistCCDB"}, o2::header::gDataOriginFLP, o2::header::gDataDescriptionDISTSTF, 0xccdb}); // will be added automatically
if (!rinp.sup0xccdb) {
spec.outputs.emplace_back(o2f::OutputSpec{{"stfDistCCDB"}, o2::header::gDataOriginFLP, o2::header::gDataDescriptionDISTSTF, 0xccdb}); // will be added automatically
}
} else {
auto nameStart = rinp.rawChannelConfig.find("name=");
if (nameStart == std::string::npos) {
Expand Down
4 changes: 4 additions & 0 deletions Detectors/Raw/src/rawfile-reader-workflow.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ void customize(std::vector<o2::framework::ConfigParamSpec>& workflowOptions)
options.push_back(ConfigParamSpec{"input-conf", VariantType::String, "", {"configuration file with input (obligatory)"}});
options.push_back(ConfigParamSpec{"min-tf", VariantType::Int64, 0L, {"min TF ID to process"}});
options.push_back(ConfigParamSpec{"max-tf", VariantType::Int64, 0xffffffffL, {"max TF ID to process"}});
options.push_back(ConfigParamSpec{"run-number", VariantType::Int, 0, {"impose run number"}});
options.push_back(ConfigParamSpec{"loop", VariantType::Int, 1, {"loop N times (infinite for N<0)"}});
options.push_back(ConfigParamSpec{"delay", VariantType::Float, 0.f, {"delay in seconds between consecutive TFs sending"}});
options.push_back(ConfigParamSpec{"buffer-size", VariantType::Int64, 5 * 1024L, {"buffer size for files preprocessing"}});
Expand All @@ -40,6 +41,7 @@ void customize(std::vector<o2::framework::ConfigParamSpec>& workflowOptions)
options.push_back(ConfigParamSpec{"drop-tf", VariantType::String, "none", {"Drop each TFid%(1)==(2) of detector, e.g. ITS,2,4;TPC,4[,0];..."}});
options.push_back(ConfigParamSpec{"verbosity-level", VariantType::Int, 0, {"verbosity level"}});
options.push_back(ConfigParamSpec{"configKeyValues", VariantType::String, "", {"semicolon separated key=value strings"}});
options.push_back(ConfigParamSpec{"suppress-diststf-0xccdb", VariantType::Bool, false, {"suppress explicit FLP/DISTSUBTIMEFRAME/0xccdb output"}});
options.push_back(ConfigParamSpec{"hbfutils-config", VariantType::String, std::string(o2::base::NameConf::DIGITIZATIONCONFIGFILE), {"configKeyValues ini file for HBFUtils (used if exists)"}});
// options for error-check suppression

Expand All @@ -61,6 +63,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
rinp.loop = configcontext.options().get<int>("loop");
rinp.maxTF = uint32_t(configcontext.options().get<int64_t>("max-tf"));
rinp.minTF = uint32_t(configcontext.options().get<int64_t>("min-tf"));
rinp.runNumber = configcontext.options().get<int>("run-number");
rinp.bufferSize = uint64_t(configcontext.options().get<int64_t>("buffer-size"));
rinp.spSize = uint64_t(configcontext.options().get<int64_t>("super-page-size"));
rinp.partPerSP = configcontext.options().get<bool>("part-per-sp");
Expand All @@ -71,6 +74,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
rinp.delay_us = uint32_t(1e6 * configcontext.options().get<float>("delay")); // delay in microseconds
rinp.dropTF = configcontext.options().get<std::string>("drop-tf");
rinp.verbosity = configcontext.options().get<int>("verbosity-level");
rinp.sup0xccdb = configcontext.options().get<bool>("suppress-diststf-0xccdb");
rinp.errMap = 0;
for (int i = RawFileReader::NErrorsDefined; i--;) {
auto ei = RawFileReader::ErrTypes(i);
Expand Down