37#include <TStopwatch.h>
60struct DigitizerWorker {
74 std::string fileName()
const {
return "tpc_driftime_digits_lane" +
std::to_string(
id) +
".root"; }
79 std::unique_ptr<TFile>
file(TFile::Open(fileName().c_str(),
"UPDATE"));
81 throw std::runtime_error(
"TPC: cannot open " + fileName());
85 size_t flushCounter = 0;
86 auto onFlush = [&]() {
88 auto fill = [&
tree](
const std::string&
name,
auto*
data) {
100 tree->SetEntries(flushCounter);
101 file->Write(
"", TObject::kOverwrite);
114 LOG(info) <<
"Initializing multithreaded TPC digitization with " << mNThreads <<
" threads";
117 const auto triggeredMode = ic.
options().
get<
bool>(
"TPCtriggered");
118 mConditions.
init(ic, mDistortionType);
123 LOG(warning) <<
"TPC sector seeding with DigiParams.seed=0 is not reproducible";
126 const ULong64_t sectorSeed = seed != 0 ? seed : gRandom->Integer(kMaxUInt);
128 for (
int i = 0;
i < mNThreads; ++
i) {
129 auto& worker = mWorkers.emplace_back(std::make_unique<DigitizerWorker>());
131 worker->digitizer.setContinuousReadout(!triggeredMode);
132 worker->digitizer.setDistortionScaleType(mDistortionType);
133 worker->digitizer.setUseSectorSeeding(sectorSeed);
135 worker->digitizer.setFlushDebugStreamer(
false);
140 std::filesystem::remove(
name);
143 ROOT::EnableThreadSafety();
154 LOG(info) <<
"Processing multithreaded TPC digitization";
156 auto& primary = mWorkers[0]->digitizer;
157 mConditions.
update(pc, primary, [
this](
float vdrift,
float tdriftOffset) {
158 for (
auto& worker : mWorkers) {
159 worker->digitizer.setVDrift(vdrift);
160 worker->digitizer.setTDriftOffset(tdriftOffset);
163 if (mDistortionType) {
164 for (
size_t i = 1;
i < mWorkers.size(); ++
i) {
165 mWorkers[
i]->digitizer.setSCDistortionsFrom(primary);
168 if (!mSeedingShared) {
170 for (
size_t i = 1;
i < mWorkers.size(); ++
i) {
171 mWorkers[
i]->digitizer.setSectorSeedingFrom(primary);
173 mSeedingShared =
true;
178 std::optional<DataRef> contextRef;
180 for (
auto const& inputref : it.parts()) {
181 if (inputref.spec->lifetime == o2::framework::Lifetime::Condition) {
184 auto const* sectorHeader = DataRefUtils::getHeader<TPCSectorHeader*>(inputref);
185 if (sectorHeader ==
nullptr) {
186 LOG(
error) <<
"TPC: Sector header missing, skipping input";
189 const int sector = sectorHeader->sector();
191 throw std::runtime_error(
"Digitizer can only work on single sectors");
195 contextRef = inputref;
202 LOG(info) <<
"TPC: Sending ROMode= " << (primary.isContinuousReadout() ?
"Continuous" :
"Triggered") <<
" to GRPUpdater";
210 if (mProcessedTimeframe) {
211 LOG(fatal) <<
"TPC: the multithreaded digitizer supports only one timeframe per process";
213 mProcessedTimeframe =
true;
215 const ULong64_t
timeframe = DataRefUtils::getHeader<o2::header::DataHeader*>(*contextRef)->tfCounter;
216 LOG(info) <<
"TPC: Processing " <<
sectors.size() <<
" sectors with " << context->
getEventRecords().size() <<
" collisions";
221 const size_t nWorkers = std::min(mWorkers.size(),
sectors.size());
222 for (
size_t i = 0;
i < nWorkers; ++
i) {
227 std::atomic<size_t> nextSector{0};
228 std::vector<std::thread> threads;
229 for (
size_t i = 0;
i < nWorkers; ++
i) {
230 threads.emplace_back([&, worker = mWorkers[
i].get()]() {
232 for (
size_t is = nextSector++; is <
sectors.size(); is = nextSector++) {
233 LOG(info) <<
"TPC: Worker " << worker->id <<
" processing sector " <<
sectors[is];
237 worker->error = std::current_exception();
242 for (
auto& thread : threads) {
245 if (
auto* streamer = o2::utils::DebugStreamer::instance()) {
248 for (
size_t i = 0;
i < nWorkers; ++
i) {
250 std::rethrow_exception(mWorkers[
i]->
error);
255 LOG(info) <<
"TPC: Digitization took " << timer.CpuTime() <<
"s CPU, " << timer.RealTime() <<
"s wall";
259 std::vector<std::unique_ptr<DigitizerWorker>> mWorkers;
261 bool mSeedingShared =
false;
262 bool mProcessedTimeframe =
false;
264 int mDistortionType = 0;
265 bool mWriteGRP =
true;
266 bool mWithMCTruth =
true;
271 std::vector<InputSpec> inputs;
276 std::vector<OutputSpec> outputs{{
"TPC",
"ROMode", 0, Lifetime::Timeframe}};
283 AlgorithmSpec{adaptFromTask<TPCDPLDigitizerMTTask>(nThreads, distortionType)},
Definition of the base digitizer task class.
Definition of the Detector class.
Definition of class for writing debug informations.
configStandalone Light OpenGL display display_light Apply smoothing to points Enable Z buffer Highlight links Highlight seeds Highlight sector tracks Highlight final tracks Show individual Show related Highlight grid Show only individual collision Color clusters belonging to track objects Set line Enable drawing TPC data Enable drawing TOF data Enable drawing magnetic field Set field line step count Invert colors configStandalone Heavy OpenGL display display_heavy Show tracks with ITS contribution Show tracks with TOF contribution Enable propagation of loopers Show clusters at nominal x of pad row for early transformed data Split CE tracks when they cross the central Mark clusters Mark adjacent clusters Hide rejected tracks Apply filter on tracks to be displayed Separate sectors
configStandalone Light OpenGL display display_light Apply smoothing to points Enable Z buffer Highlight links Highlight seeds Highlight sector tracks Highlight final tracks Show individual Show related Highlight grid Show only individual collision Color clusters belonging to track objects Set line Enable drawing TPC data Enable drawing TOF data Enable drawing magnetic field Set field line step count Invert colors configStandalone Heavy OpenGL display display_heavy Show tracks with ITS contribution Show tracks with TOF contribution Enable propagation of loopers Show clusters at nominal x of pad row for early transformed data Split CE tracks when they cross the central Mark clusters Mark adjacent clusters Hide rejected tracks Apply filter on tracks to be displayed Separate increase X h configStandalone Camera window renderer OpenGL display display_camera Orient the camera such that the y axis is always upwards Full Screen MultiSample Anti Downsampling Anti Enable Vertical Sync Target frame or if the backend cannot limit to the refresh Use OpenGL indirect draws to reduce number of draw calls Display h configStandalone Vulkan display display_vulkan Have uniform buffers in host accessible device memory h configStandalone Internal display display_internal Number of updates the Qt GUI may send ahead of the last one the display has before it waits for the display Opacity of the console background Number of console lines the history is shortened to this when it reaches twice the size Time in seconds an info message fades out after setInfoTime h OpenGL display display Font size Do not use Freetype for font Renderer for event Frontend to use for event ROOT macros used as track filter Console script file
configStandalone Light OpenGL display display_light Apply smoothing to points Enable Z buffer Highlight links Highlight seeds Highlight sector tracks Highlight final tracks Show individual sector
Timeframe settings Average distance in cm of events merged into timeframe
Header of the General Run Parameters object.
char error[CURL_ERROR_SIZE]
std::vector< TChain * > chains
Definition of the ALICE TPC digitizer.
static const DigiParams & Instance()
T get(const char *key) const
void snapshot(const Output &spec, T const &object)
ConfigParamRegistry const & options()
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
bool initSimChains(o2::detectors::DetID detid, std::vector< TChain * > &simchains) const
std::vector< o2::InteractionTimeRecord > & getEventRecords(bool withQED=false)
void finaliseCCDB(framework::ConcreteDataMatcher &matcher, void *obj)
void initDigitizerTask(framework::InitContext &ic) override
TPCDPLDigitizerMTTask(int nThreads, int distortionType)
void run(framework::ProcessingContext &pc)
CCDB conditions and calibration files of the TPC digitizer devices.
static void addInputs(std::vector< framework::InputSpec > &inputs, int distortionType)
CCDB inputs common to the TPC digitizer devices.
bool finaliseCCDB(framework::ConcreteDataMatcher &matcher, void *obj, Digitizer &digitizer)
pass a CCDB object to the digitizer; true if it was a TPC condition
static std::vector< framework::ConfigParamSpec > options()
options common to the TPC digitizer devices
void init(framework::InitContext &ic, int distortionType)
void update(framework::ProcessingContext &pc, Digitizer &digitizer, const std::function< void(float, float)> &setVDrift)
GLuint const GLchar * name
TBranch * getOrMakeBranch(TTree &tree, const char *brname, T *ptr)
Defining ITS Vertex explicitly as messageable.
std::vector< dataformats::RangeReference< int, int > > digitizeSector(Digitizer &digitizer, const steer::DigitizationContext &context, const std::vector< TChain * > &simChains, int sector, ULong64_t timeframe, SectorFlushBuffers &buffers, const std::function< void()> &onFlush)
o2::framework::DataProcessorSpec getTPCDigitizerMTSpec(int nThreads, std::vector< int > const §ors, int distortionType)
A single TPC digitizer device that digitizes the sectors with nThreads threads and writes the digits ...
std::vector< std::string > listFiles(std::string const &dir, std::string const &searchpattern)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
class listing possible services
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))