Skip to content

Commit 3e6fde1

Browse files
authored
TRD Kr cluster writing to EOS (#12113)
1 parent 95c4cf8 commit 3e6fde1

File tree

6 files changed

+225
-141
lines changed

6 files changed

+225
-141
lines changed

Detectors/TRD/workflow/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ o2_add_library(TRDWorkflow
2121
src/EntropyDecoderSpec.cxx
2222
src/EntropyEncoderSpec.cxx
2323
src/TrackBasedCalibSpec.cxx
24-
src/KrClustererSpec.cxx
24+
include/TRDWorkflow/KrClustererSpec.h
2525
include/TRDWorkflow/VdAndExBCalibSpec.h
2626
include/TRDWorkflow/GainCalibSpec.h
2727
include/TRDWorkflow/TRDPulseHeightSpec.h

Detectors/TRD/workflow/include/TRDWorkflow/KrClustererSpec.h

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,82 @@
1919
// input TRD digits, TRD trigger records
2020
// output Kr clusters
2121

22+
#include "TRDWorkflow/KrClustererSpec.h"
23+
#include "TRDCalibration/KrClusterFinder.h"
24+
#include "Framework/Task.h"
25+
#include "Framework/ConfigParamRegistry.h"
2226
#include "Framework/DataProcessorSpec.h"
27+
#include "TStopwatch.h"
28+
#include <fairlogger/Logger.h>
2329

2430
using namespace o2::framework;
2531

2632
namespace o2
2733
{
2834
namespace trd
2935
{
30-
/// create a processor spec
31-
framework::DataProcessorSpec getKrClustererSpec();
36+
class TRDKrClustererDevice : public Task
37+
{
38+
public:
39+
TRDKrClustererDevice() = default;
40+
~TRDKrClustererDevice() override = default;
41+
void init(InitContext& ic) final;
42+
void run(ProcessingContext& pc) final;
43+
void endOfStream(framework::EndOfStreamContext& ec) final;
44+
45+
private:
46+
o2::trd::KrClusterFinder mKrClFinder;
47+
};
48+
49+
void TRDKrClustererDevice::init(InitContext& ic)
50+
{
51+
mKrClFinder.init();
52+
}
53+
54+
void TRDKrClustererDevice::run(ProcessingContext& pc)
55+
{
56+
TStopwatch timer;
57+
58+
const auto digits = pc.inputs().get<gsl::span<Digit>>("digits");
59+
const auto triggerRecords = pc.inputs().get<gsl::span<TriggerRecord>>("triggerRecords");
60+
61+
mKrClFinder.reset();
62+
mKrClFinder.setInput(digits, triggerRecords);
63+
timer.Start();
64+
mKrClFinder.findClusters();
65+
timer.Stop();
66+
67+
LOGP(info, "Found {} Kr clusters in {} input trigger records. Timing: CPU: {}, Real: {}",
68+
mKrClFinder.getKrClusters().size(), triggerRecords.size(), timer.CpuTime(), timer.RealTime());
69+
70+
pc.outputs().snapshot(Output{o2::header::gDataOriginTRD, "KRCLUSTER", 0, Lifetime::Timeframe}, mKrClFinder.getKrClusters());
71+
pc.outputs().snapshot(Output{o2::header::gDataOriginTRD, "TRGKRCLS", 0, Lifetime::Timeframe}, mKrClFinder.getKrTrigRecs());
72+
}
73+
74+
void TRDKrClustererDevice::endOfStream(EndOfStreamContext& ec)
75+
{
76+
LOG(info) << "Done with the cluster finding (EoS received)";
77+
}
78+
79+
framework::DataProcessorSpec getKrClustererSpec()
80+
{
81+
std::vector<InputSpec> inputs;
82+
inputs.emplace_back("digits", ConcreteDataTypeMatcher{o2::header::gDataOriginTRD, "DIGITS"}, Lifetime::Timeframe);
83+
inputs.emplace_back("triggerRecords", ConcreteDataTypeMatcher{o2::header::gDataOriginTRD, "TRKTRGRD"}, Lifetime::Timeframe);
84+
std::vector<OutputSpec> outputs;
85+
outputs.emplace_back(o2::header::gDataOriginTRD, "KRCLUSTER", 0, Lifetime::Timeframe);
86+
outputs.emplace_back(o2::header::gDataOriginTRD, "TRGKRCLS", 0, Lifetime::Timeframe);
87+
88+
return DataProcessorSpec{
89+
"trd-kr-clusterer",
90+
inputs,
91+
outputs,
92+
AlgorithmSpec{adaptFromTask<o2::trd::TRDKrClustererDevice>()},
93+
Options{}};
94+
}
3295

3396
} // namespace trd
97+
3498
} // namespace o2
3599

36100
#endif // O2_TRD_KRCLUSTERERSPEC_H

Detectors/TRD/workflow/io/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ o2_add_library(TRDWorkflowIO
2222
src/TRDTrackReaderSpec.cxx
2323
src/TRDCalibWriterSpec.cxx
2424
src/TRDPHReaderSpec.cxx
25-
src/KrClusterWriterSpec.cxx
25+
include/TRDWorkflowIO/KrClusterWriterSpec.h
2626
PUBLIC_LINK_LIBRARIES O2::DataFormatsTRD O2::SimulationDataFormat O2::DPLUtils O2::GPUDataTypeHeaders O2::DataFormatsTPC)
2727

2828

Detectors/TRD/workflow/io/include/TRDWorkflowIO/KrClusterWriterSpec.h

Lines changed: 157 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,170 @@
1212
#ifndef O2_TRD_KRWRITERSPEC_H
1313
#define O2_TRD_KRWRITERSPEC_H
1414

15+
#include "Framework/DataProcessorSpec.h"
16+
#include "Framework/DataTakingContext.h"
17+
#include "DataFormatsTRD/KrCluster.h"
18+
#include "DataFormatsTRD/KrClusterTriggerRecord.h"
19+
#include "CommonUtils/MemFileHelper.h"
20+
#include "DetectorsCommonDataFormats/FileMetaData.h"
21+
22+
#include <TFile.h>
23+
#include <TTree.h>
24+
#include <filesystem>
25+
#include <fmt/format.h>
26+
1527
namespace o2
1628
{
17-
namespace framework
29+
namespace trd
1830
{
19-
struct DataProcessorSpec;
20-
}
21-
} // namespace o2
2231

23-
namespace o2
32+
class TRDKrClsWriterTask : public o2::framework::Task
2433
{
25-
namespace trd
34+
public:
35+
TRDKrClsWriterTask() = default;
36+
37+
void init(o2::framework::InitContext& ic) final
38+
{
39+
mOutputDir = o2::utils::Str::rectifyDirectory(ic.options().get<std::string>("output-dir"));
40+
41+
// should we write meta files for epn2eos?
42+
mMetaFileDir = ic.options().get<std::string>("meta-output-dir");
43+
if (mMetaFileDir != "/dev/null") {
44+
mMetaFileDir = o2::utils::Str::rectifyDirectory(mMetaFileDir);
45+
mStoreMetaFile = true;
46+
}
47+
48+
LOGP(info, "Storing output in {}, meta file writing enabled: {}", mOutputDir, mStoreMetaFile);
49+
mAutoSave = ic.options().get<int>("autosave-interval");
50+
51+
char hostname[_POSIX_HOST_NAME_MAX];
52+
gethostname(hostname, _POSIX_HOST_NAME_MAX);
53+
mHostName = hostname;
54+
mHostName = mHostName.substr(0, mHostName.find('.'));
55+
}
56+
57+
void createOutputFile(int runNumber, o2::framework::ProcessingContext& pc)
58+
{
59+
mFileName = fmt::format("o2_trdKrCls_run{}_{}.root", runNumber, mHostName);
60+
auto fileNameTmp = o2::utils::Str::concat_string(mOutputDir, mFileName, ".part");
61+
mFileOut = std::make_unique<TFile>(fileNameTmp.c_str(), "recreate");
62+
mTreeOut = std::make_unique<TTree>("krData", "TRD krypton cluster data");
63+
mTreeOut->Branch("cluster", &krClusterPtr);
64+
mTreeOut->Branch("trigRec", &krTrigRecPtr);
65+
mDataTakingContext = pc.services().get<DataTakingContext>();
66+
mOutputFileCreated = true;
67+
}
68+
69+
void writeToFile()
70+
{
71+
if (!mOutputFileCreated) {
72+
return;
73+
}
74+
mFileOut->cd();
75+
mTreeOut->Write();
76+
}
77+
78+
void closeOutputFile()
79+
{
80+
if (!mOutputFileCreated) {
81+
return;
82+
}
83+
writeToFile();
84+
mTreeOut.reset();
85+
mFileOut->Close();
86+
mFileOut.reset();
87+
auto fileNameWithPath = mOutputDir + mFileName;
88+
std::filesystem::rename(o2::utils::Str::concat_string(mOutputDir, mFileName, ".part"), fileNameWithPath);
89+
if (mStoreMetaFile) {
90+
o2::dataformats::FileMetaData fileMetaData; // object with information for meta data file
91+
fileMetaData.fillFileData(fileNameWithPath);
92+
fileMetaData.setDataTakingContext(mDataTakingContext);
93+
fileMetaData.type = "calib";
94+
fileMetaData.priority = "high";
95+
auto metaFileNameTmp = fmt::format("{}{}.tmp", mMetaFileDir, mFileName);
96+
auto metaFileName = fmt::format("{}{}.done", mMetaFileDir, mFileName);
97+
try {
98+
std::ofstream metaFileOut(metaFileNameTmp);
99+
metaFileOut << fileMetaData;
100+
metaFileOut.close();
101+
std::filesystem::rename(metaFileNameTmp, metaFileName);
102+
} catch (std::exception const& e) {
103+
LOG(error) << "Failed to store meta data file " << metaFileName << ", reason: " << e.what();
104+
}
105+
}
106+
}
107+
108+
void run(o2::framework::ProcessingContext& pc) final
109+
{
110+
if (!mOutputFileCreated) {
111+
auto tInfo = pc.services().get<o2::framework::TimingInfo>();
112+
createOutputFile(tInfo.runNumber, pc);
113+
}
114+
if (pc.transitionState() == TransitionHandlingState::Requested) {
115+
LOG(info) << "Run stop requested, closing output file";
116+
mRunStopRequested = true;
117+
closeOutputFile();
118+
}
119+
if (mRunStopRequested) {
120+
return;
121+
}
122+
auto cluster = pc.inputs().get<gsl::span<KrCluster>>("krcluster");
123+
auto triggerRecords = pc.inputs().get<gsl::span<KrClusterTriggerRecord>>("krtrigrec");
124+
for (const auto& cls : cluster) {
125+
krCluster.push_back(cls);
126+
}
127+
for (const auto& trig : triggerRecords) {
128+
krTrigRec.push_back(trig);
129+
}
130+
mTreeOut->Fill();
131+
krCluster.clear();
132+
krTrigRec.clear();
133+
if (mAutoSave > 0 && ++mTFCounter % mAutoSave == 0) {
134+
writeToFile();
135+
}
136+
}
137+
138+
void endOfStream(o2::framework::EndOfStreamContext& ec) final
139+
{
140+
if (mRunStopRequested) {
141+
return;
142+
}
143+
LOG(info) << "End of stream received, closing output file";
144+
closeOutputFile();
145+
}
146+
147+
private:
148+
bool mRunStopRequested{false};
149+
bool mStoreMetaFile{false};
150+
bool mOutputFileCreated{false};
151+
int mAutoSave{0};
152+
uint64_t mTFCounter{0};
153+
std::string mOutputDir{"none"};
154+
std::string mMetaFileDir{"/dev/null"};
155+
std::string mHostName{};
156+
std::string mFileName{};
157+
std::unique_ptr<TFile> mFileOut{};
158+
std::unique_ptr<TTree> mTreeOut{};
159+
std::vector<KrCluster> krCluster, *krClusterPtr{&krCluster};
160+
std::vector<KrClusterTriggerRecord> krTrigRec, *krTrigRecPtr{&krTrigRec};
161+
o2::framework::DataTakingContext mDataTakingContext;
162+
};
163+
164+
framework::DataProcessorSpec getKrClusterWriterSpec()
26165
{
166+
std::vector<InputSpec> inputs;
167+
inputs.emplace_back("krcluster", "TRD", "KRCLUSTER");
168+
inputs.emplace_back("krtrigrec", "TRD", "TRGKRCLS");
27169

28-
o2::framework::DataProcessorSpec getKrClusterWriterSpec();
170+
return DataProcessorSpec{"kr-cluster-writer",
171+
inputs,
172+
Outputs{},
173+
AlgorithmSpec{adaptFromTask<o2::trd::TRDKrClsWriterTask>()},
174+
Options{
175+
{"output-dir", VariantType::String, "none", {"Output directory for data. Defaults to current working directory"}},
176+
{"meta-output-dir", VariantType::String, "/dev/null", {"metadata output directory, must exist (if not /dev/null)"}},
177+
{"autosave-interval", VariantType::Int, 0, {"Write output to file for every n-th TF. 0 means this feature is OFF"}}}};
178+
}
29179

30180
} // end namespace trd
31181
} // end namespace o2

Detectors/TRD/workflow/io/src/KrClusterWriterSpec.cxx

Lines changed: 0 additions & 39 deletions
This file was deleted.

0 commit comments

Comments
 (0)