Project
Loading...
Searching...
No Matches
KrClusterWriterSpec.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#ifndef O2_TRD_KRWRITERSPEC_H
13#define O2_TRD_KRWRITERSPEC_H
14
21
22#include <TFile.h>
23#include <TTree.h>
24#include <filesystem>
25#include <mutex>
26#include <fmt/format.h>
27
28namespace o2
29{
30namespace trd
31{
32
34{
35 public:
36 TRDKrClsWriterTask() = default;
37
39 {
40 mOutputDir = o2::utils::Str::rectifyDirectory(ic.options().get<std::string>("output-dir"));
41
42 // should we write meta files for epn2eos?
43 mMetaFileDir = ic.options().get<std::string>("meta-output-dir");
44 if (mMetaFileDir != "/dev/null") {
45 mMetaFileDir = o2::utils::Str::rectifyDirectory(mMetaFileDir);
46 mStoreMetaFile = true;
47 }
48
49 LOGP(info, "Storing output in {}, meta file writing enabled: {}", mOutputDir, mStoreMetaFile);
50 mAutoSave = ic.options().get<int>("autosave-interval");
51
52 char hostname[_POSIX_HOST_NAME_MAX];
53 gethostname(hostname, _POSIX_HOST_NAME_MAX);
54 mHostName = hostname;
55 mHostName = mHostName.substr(0, mHostName.find('.'));
56 }
57
59 {
60 mFileName = fmt::format("o2_trdKrCls_run{}_{}.root", runNumber, mHostName);
61 auto fileNameTmp = o2::utils::Str::concat_string(mOutputDir, mFileName, ".part");
62 mFileOut = std::make_unique<TFile>(fileNameTmp.c_str(), "recreate");
63 mTreeOut = std::make_unique<TTree>("krData", "TRD krypton cluster data");
64 mTreeOut->Branch("cluster", &krClusterPtr);
65 mTreeOut->Branch("trigRec", &krTrigRecPtr);
66 mDataTakingContext = pc.services().get<DataTakingContext>();
67 mOutputFileCreated = true;
68 }
69
71 {
72 if (!mOutputFileCreated) {
73 return;
74 }
75 mFileOut->cd();
76 mTreeOut->Write();
77 }
78
80 {
81 if (!mOutputFileCreated || mOutputFileClosed) {
82 return;
83 }
84 std::lock_guard<std::mutex> guard(mMutex);
86 mTreeOut.reset();
87 mFileOut->Close();
88 mFileOut.reset();
89 auto fileNameWithPath = mOutputDir + mFileName;
90 std::filesystem::rename(o2::utils::Str::concat_string(mOutputDir, mFileName, ".part"), fileNameWithPath);
91 if (mStoreMetaFile) {
92 o2::dataformats::FileMetaData fileMetaData; // object with information for meta data file
93 fileMetaData.fillFileData(fileNameWithPath);
94 fileMetaData.setDataTakingContext(mDataTakingContext);
95 fileMetaData.type = "calib";
96 fileMetaData.priority = "high";
97 auto metaFileNameTmp = fmt::format("{}{}.tmp", mMetaFileDir, mFileName);
98 auto metaFileName = fmt::format("{}{}.done", mMetaFileDir, mFileName);
99 try {
100 std::ofstream metaFileOut(metaFileNameTmp);
101 metaFileOut << fileMetaData;
102 metaFileOut.close();
103 std::filesystem::rename(metaFileNameTmp, metaFileName);
104 } catch (std::exception const& e) {
105 LOG(error) << "Failed to store meta data file " << metaFileName << ", reason: " << e.what();
106 }
107 }
108 mOutputFileClosed = true;
109 }
110
112 {
113 if (!mOutputFileCreated) {
114 auto tInfo = pc.services().get<o2::framework::TimingInfo>();
115 createOutputFile(tInfo.runNumber, pc);
116 }
117 if (mRunStopRequested) {
118 return;
119 }
120 if (pc.transitionState() == TransitionHandlingState::Requested) {
121 LOG(info) << "Run stop requested, closing output file";
122 mRunStopRequested = true;
124 return;
125 }
126 auto cluster = pc.inputs().get<gsl::span<KrCluster>>("krcluster");
127 auto triggerRecords = pc.inputs().get<gsl::span<KrClusterTriggerRecord>>("krtrigrec");
128 for (const auto& cls : cluster) {
129 krCluster.push_back(cls);
130 }
131 for (const auto& trig : triggerRecords) {
132 krTrigRec.push_back(trig);
133 }
134 mTreeOut->Fill();
135 krCluster.clear();
136 krTrigRec.clear();
137 if (mAutoSave > 0 && ++mTFCounter % mAutoSave == 0) {
138 writeToFile();
139 }
140 }
141
143 {
144 if (mRunStopRequested) {
145 return;
146 }
147 LOG(info) << "End of stream received, closing output file";
149 }
150
151 private:
152 bool mRunStopRequested{false};
153 bool mStoreMetaFile{false};
154 bool mOutputFileCreated{false};
155 bool mOutputFileClosed{false};
156 int mAutoSave{0};
157 uint64_t mTFCounter{0};
158 std::mutex mMutex;
159 std::string mOutputDir{"none"};
160 std::string mMetaFileDir{"/dev/null"};
161 std::string mHostName{};
162 std::string mFileName{};
163 std::unique_ptr<TFile> mFileOut{};
164 std::unique_ptr<TTree> mTreeOut{};
165 std::vector<KrCluster> krCluster, *krClusterPtr{&krCluster};
166 std::vector<KrClusterTriggerRecord> krTrigRec, *krTrigRecPtr{&krTrigRec};
167 o2::framework::DataTakingContext mDataTakingContext;
168};
169
171{
172 std::vector<InputSpec> inputs;
173 inputs.emplace_back("krcluster", "TRD", "KRCLUSTER");
174 inputs.emplace_back("krtrigrec", "TRD", "TRGKRCLS");
175
176 return DataProcessorSpec{"kr-cluster-writer",
177 inputs,
178 Outputs{},
179 AlgorithmSpec{adaptFromTask<o2::trd::TRDKrClsWriterTask>()},
180 Options{
181 {"output-dir", VariantType::String, "none", {"Output directory for data. Defaults to current working directory"}},
182 {"meta-output-dir", VariantType::String, "/dev/null", {"metadata output directory, must exist (if not /dev/null)"}},
183 {"autosave-interval", VariantType::Int, 0, {"Write output to file for every n-th TF. 0 means this feature is OFF"}}}};
184}
185
186} // end namespace trd
187} // end namespace o2
188
189#endif // O2_TRD_KRWRITERSPEC_H
A cluster formed from digits during TRD Krypton calibration.
ServiceRegistryRef services()
The services registry associated with this processing context.
void run(o2::framework::ProcessingContext &pc) final
void endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void createOutputFile(int runNumber, o2::framework::ProcessingContext &pc)
void init(o2::framework::InitContext &ic) final
std::vector< ConfigParamSpec > Options
std::vector< OutputSpec > Outputs
framework::DataProcessorSpec getKrClusterWriterSpec()
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
bool fillFileData(const std::string &fname, bool fillmd5=false, const std::string &tmpEnding="")
void setDataTakingContext(const o2::framework::DataTakingContext &dtc)
static std::string rectifyDirectory(const std::string_view p)
static std::string concat_string(Ts const &... ts)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"