42using std::chrono::duration_cast;
43using std::chrono::milliseconds;
44using std::chrono::system_clock;
54void customize(std::vector<o2::framework::CallbacksPolicy>& policies)
59void customize(std::vector<ConfigParamSpec>& workflowOptions)
61 std::vector<o2::framework::ConfigParamSpec> options{
62 {
"jsons-folder", VariantType::String,
"jsons", {
"name of the folder to store json files"}},
63 {
"use-json-format", VariantType::Bool,
false, {
"instead of eve format (default) use json format"}},
64 {
"use-root-format", VariantType::Bool,
false, {
"instead of eve format (default) use root format"}},
65 {
"eve-hostname", VariantType::String,
"", {
"name of the host allowed to produce files (empty means no limit)"}},
66 {
"eve-dds-collection-index", VariantType::Int, -1, {
"number of dpl collection allowed to produce files (-1 means no limit)"}},
67 {
"time-interval", VariantType::Int, 5000, {
"time interval in milliseconds between stored files"}},
68 {
"disable-mc", VariantType::Bool,
false, {
"disable visualization of MC data"}},
69 {
"disable-write", VariantType::Bool,
false, {
"disable writing output files"}},
70 {
"display-clusters", VariantType::String,
"ITS,TPC,TRD,TOF", {
"comma-separated list of clusters to display"}},
71 {
"display-tracks", VariantType::String,
"TPC,ITS,ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF", {
"comma-separated list of tracks to display"}},
72 {
"disable-root-input", VariantType::Bool,
false, {
"disable root-files input reader"}},
73 {
"configKeyValues", VariantType::String,
"", {
"semicolon separated key=value strings, e.g. EveConfParam content..."}},
74 {
"skipOnEmptyInput", VariantType::Bool,
false, {
"don't run the ED when no input is provided"}},
78 std::swap(workflowOptions, options);
84 LOGF(info,
"------------------------ O2DPLDisplay::init version ", o2_eve_version,
" ------------------------------------");
87 if (mEMCALCalibLoader) {
88 mEMCALCalibrator = std::make_unique<o2::emcal::CellRecalibrator>();
96 if (!mEveHostNameMatch) {
99 if (conf.onlyNthEvent > 1 && mEventCounter++ % conf.onlyNthEvent) {
102 LOGF(info,
"------------------------ O2DPLDisplay::run version ", o2_eve_version,
" ------------------------------------");
104 auto currentTime = std::chrono::high_resolution_clock::now();
105 std::chrono::duration<double> elapsed = currentTime - this->mTimeStamp;
106 if (elapsed < this->mTimeInterval) {
109 this->mTimeStamp = currentTime;
112 updateTimeDependentParams(pc);
113 if (mEMCALCalibLoader) {
114 mEMCALCalibLoader->checkUpdates(pc);
115 if (mEMCALCalibLoader->hasUpdateBadChannelMap()) {
116 mEMCALCalibrator->setBadChannelMap(mEMCALCalibLoader->getBadChannelMap());
118 if (mEMCALCalibLoader->hasUpdateTimeCalib()) {
119 mEMCALCalibrator->setTimeCalibration(mEMCALCalibLoader->getTimeCalibration());
121 if (mEMCALCalibLoader->hasUpdateGainCalib()) {
122 mEMCALCalibrator->setGainCalibration(mEMCALCalibLoader->getGainCalibration());
129 if (mEMCALCalibrator) {
141 std::size_t filesSaved = 0;
143 const std::string
marker =
"_";
144 const std::vector<std::string> exts = {
".json",
".root",
".eve"};
145 auto processData = [&](
const auto& dataMap) {
146 for (
const auto& keyVal : dataMap) {
147 if (conf.maxPVs > 0 && filesSaved >= conf.maxPVs) {
150 if (conf.maxBytes > 0) {
152 duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count() - this->mTimeInterval.count();
154 LOGF(info,
"Already too much data (> %d) to transfer in this period - event will not be not saved ...", conf.maxBytes);
158 const auto pv = keyVal.first;
161 helper.
draw(pv, conf.trackSorting);
164 helper.
draw(pv, conf.trackSorting);
176 if (this->mDisableWrite) {
189 helper.
save(this->mJsonPath, this->mExt, conf.maxFiles);
191 currentTime = std::chrono::high_resolution_clock::now();
192 this->mTimeStamp = currentTime;
198 if (conf.PVTriggersMode) {
204 auto endTime = std::chrono::high_resolution_clock::now();
205 LOGP(info,
"Visualization of TF:{} at orbit {} took {} s.", tinfo.tfCounter, tinfo.firstTForbit, std::chrono::duration_cast<std::chrono::microseconds>(endTime - currentTime).count() * 1e-6);
209 LOGP(info,
"Data files saved: {}", filesSaved);
211 std::unordered_map<o2::dataformats::GlobalTrackID, std::size_t> savedDataTypes;
214 savedDataTypes[
i] = 0;
218 savedDataTypes[gid.getSource()] += 1;
221 std::vector<std::string> sourceStats;
224 const auto combinedMask = mTrkMask | mClMask;
227 if (combinedMask[
i]) {
243 static bool initOnceDone =
false;
251 mRunType = grpECS->getRunType();
263 if (mEMCALCalibLoader && mEMCALCalibLoader->finalizeCCDB(matcher, obj)) {
267 LOGF(info,
"ITS cluster dictionary updated");
272 LOGF(info,
"MFT cluster dictionary updated");
284 LOGF(info,
"------------------------ defineDataProcessing ", o2_eve_version,
" ------------------------------------");
288 auto jsonFolder = cfgc.
options().
get<std::string>(
"jsons-folder");
289 std::string ext =
".eve";
290 auto useJsonFormat = cfgc.
options().
get<
bool>(
"use-json-format");
294 auto useROOTFormat = cfgc.
options().
get<
bool>(
"use-root-format");
298 auto eveHostName = cfgc.
options().
get<std::string>(
"eve-hostname");
302 bool useMC = !cfgc.
options().
get<
bool>(
"disable-mc");
303 bool disableWrite = cfgc.
options().
get<
bool>(
"disable-write");
305 char hostname[_POSIX_HOST_NAME_MAX];
306 gethostname(hostname, _POSIX_HOST_NAME_MAX);
307 bool eveHostNameMatch = eveHostName.empty() || eveHostName == hostname;
309 int eveDDSColIdx = cfgc.
options().
get<
int>(
"eve-dds-collection-index");
310 if (eveDDSColIdx != -1) {
311 char* colIdx = getenv(
"DDS_COLLECTION_INDEX");
312 int myIdx = colIdx ? atoi(colIdx) : -1;
313 if (myIdx == eveDDSColIdx) {
314 LOGF(important,
"Restricting DPL Display to collection index, my index ", myIdx,
", enabled ",
int(myIdx == eveDDSColIdx));
316 LOGF(info,
"Restricting DPL Display to collection index, my index ", myIdx,
", enabled ",
int(myIdx == eveDDSColIdx));
318 eveHostNameMatch &= myIdx == eveDDSColIdx;
321 std::chrono::milliseconds timeInterval(cfgc.
options().
get<
int>(
"time-interval"));
333 srcTrk &= allowedTracks;
334 srcCl &= allowedClusters;
336 if (!srcTrk.any() && !srcCl.any()) {
337 if (cfgc.
options().
get<
bool>(
"skipOnEmptyInput")) {
338 LOGF(info,
"No valid inputs for event display, disabling event display");
339 return std::move(specs);
341 throw std::runtime_error(
"No input configured");
344 auto isRangeEnabled = [&opts = cfgc.
options()](
const char* min_name,
const char* max_name) {
346 bool optEnabled =
false;
348 if (bracket.getMin() < 0 && bracket.getMax() < 0) {
350 }
else if (bracket.getMin() >= 0 && bracket.getMax() >= 0) {
353 if (bracket.isInvalid()) {
354 throw std::runtime_error(fmt::format(
"{}, {} bracket is invalid", min_name, max_name));
357 throw std::runtime_error(fmt::format(
"Both boundaries, {} and {}, have to be specified at the same time", min_name, max_name));
360 return std::make_tuple(optEnabled, bracket);
363 std::shared_ptr<DataRequest> dataRequest = std::make_shared<DataRequest>();
364 dataRequest->requestTracks(srcTrk, useMC);
365 dataRequest->requestClusters(srcCl, useMC);
367 if (conf.filterITSROF) {
368 dataRequest->requestIRFramesITS();
374 dataRequest->requestPrimaryVertices(useMC);
379 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
false,
388 std::shared_ptr<o2::emcal::CalibLoader> emcalCalibLoader;
389 if (conf.calibrateEMC) {
390 emcalCalibLoader = std::make_shared<o2::emcal::CalibLoader>();
391 emcalCalibLoader->enableTimeCalib(
true);
392 emcalCalibLoader->enableBadChannelMap(
true);
393 emcalCalibLoader->enableGainCalib(
true);
394 emcalCalibLoader->defineInputSpecs(dataRequest->inputs);
401 AlgorithmSpec{adaptFromTask<O2DPLDisplaySpec>(disableWrite, useMC, srcTrk, srcCl, dataRequest, ggRequest, emcalCalibLoader, jsonFolder, ext, timeInterval, eveHostNameMatch)}});
406 return std::move(specs);
Loading content of the Folder and returning sorted.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Definition of the Names Generator class.
void customize(std::vector< o2::framework::CallbacksPolicy > &policies)
Definition of the MCH track.
Helper class to obtain TPC clusters / digits / labels from DPL.
WorkflowSpec defineDataProcessing(ConfigContext const &configcontext)
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static const EveConfParam & Instance()
static void updateFromString(std::string const &)
const o2::itsmft::TopologyDictionary * mMFTDict
const o2::itsmft::TopologyDictionary * mITSDict
void setITSDict(const o2::itsmft::TopologyDictionary *d)
void setMFTDict(const o2::itsmft::TopologyDictionary *d)
static bool canCreateNextFile(const std::vector< std::string > &paths, const std::string &marker, const std::vector< std::string > &ext, long long millisec, long capacityAllowed)
static std::vector< std::string > allFolders(const std::string &location)
std::unordered_map< std::size_t, std::vector< GID > > mPrimaryVertexTriggerGIDs
void save(const std::string &jsonPath, const std::string &ext, int numberOfFiles)
o2::event_visualisation::VisualisationEvent mEvent
void setRecoContainer(const o2::globaltracking::RecoContainer *rc)
void setTPCVDrift(const o2::tpc::VDriftCorrFact *v)
void draw(std::size_t primaryVertexIdx, bool sortTracks)
void selectTracks(const CalibObjectsConst *calib, GID::mask_t maskCl, GID::mask_t maskTrk, GID::mask_t maskMatch)
void setEMCALCellRecalibrator(o2::emcal::CellRecalibrator *calibrator)
void prepareITSClusters(const o2::itsmft::TopologyDictionary *dict)
void prepareMFTClusters(const o2::itsmft::TopologyDictionary *dict)
std::unordered_map< std::size_t, std::vector< GID > > mPrimaryVertexTrackGIDs
std::unordered_set< GID > mTotalAcceptedDataTypes
std::unordered_map< GID, std::size_t > mTotalDataTypes
void endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj) final
void run(o2::framework::ProcessingContext &pc) final
static constexpr auto allowedClusters
void init(o2::framework::InitContext &ic) final
static constexpr auto allowedTracks
size_t getDetectorTrackCount(o2::detectors::DetID::ID id) const
void setFirstTForbit(o2::header::DataHeader::TForbitType value)
void setRunNumber(o2::header::DataHeader::RunNumberType runNumber)
void setCreationTime(o2::framework::DataProcessingHeader::CreationTime creationTime)
void setTrkMask(int value)
void setRunType(o2::parameters::GRPECS::RunType runType)
void setTfCounter(o2::header::DataHeader::TFCounterType value)
size_t getTrackCount() const
void setPrimaryVertex(std::size_t pv)
void setClMask(int value)
ConfigParamRegistry & options() const
T get(const char *key) const
ServiceRegistryRef services()
The services registry associated with this processing context.
static void requestCCDBInputs(std::vector< o2::framework::InputSpec > &inputs, bool laser=true, bool itstpcTgl=true)
void extractCCDBInputs(o2::framework::ProcessingContext &pc, bool laser=true, bool itstpcTgl=true)
const VDriftCorrFact & getVDriftObject() const
bool accountCCDBInputs(const o2::framework::ConcreteDataMatcher &matcher, void *obj)
Defining PrimaryVertex explicitly as messageable.
std::vector< DataProcessorSpec > WorkflowSpec
Global TPC definitions and constants.
SettingsProcessing configProcessing
CalibObjectsConst configCalib
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
static void addNewTimeSliceCallback(std::vector< o2::framework::CallbacksPolicy > &policies)
static void addConfigOption(std::vector< o2::framework::ConfigParamSpec > &opts, const std::string &defOpt=std::string(o2::base::NameConf::DIGITIZATIONCONFIGFILE))