diff --git a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEvent.h b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEvent.h index 84e0ff178d408..9f18b43dc41fe 100644 --- a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEvent.h +++ b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEvent.h @@ -126,6 +126,8 @@ class VisualisationEvent float getMinTimeOfTracks() const { return this->mMinTimeOfTracks; } float getMaxTimeOfTracks() const { return this->mMaxTimeOfTracks; } /// maximum time of tracks in the event + bool isEmpty() const { return getTrackCount() == 0 && getClusterCount() == 0; } + private: float mMinTimeOfTracks; /// minimum time of tracks in the event float mMaxTimeOfTracks; /// maximum time of tracks in the event diff --git a/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h b/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h index 0b164900d49b3..5ebade7ee20f9 100644 --- a/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h +++ b/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h @@ -106,12 +106,7 @@ class EveWorkflowHelper void selectTracks(const CalibObjectsConst* calib, GID::mask_t maskCl, GID::mask_t maskTrk, GID::mask_t maskMatch); void addTrackToEvent(const o2::track::TrackParCov& tr, GID gid, float trackTime, float dz, GID::Source source = GID::NSources); - void draw(const std::string& jsonPath, int numberOfFiles, int numberOfTracks, - o2::dataformats::GlobalTrackID::mask_t trkMask, - o2::dataformats::GlobalTrackID::mask_t clMask, - o2::header::DataHeader::RunNumberType runNumber, - o2::framework::DataProcessingHeader::CreationTime creation, - float mWorkflowVersion); + void draw(int numberOfTracks); void drawTPC(GID gid, float trackTime); void drawITS(GID gid, float trackTime); void drawMFT(GID gid, float trackTime); @@ -136,6 +131,7 @@ class EveWorkflowHelper void prepareITSClusters(const o2::itsmft::TopologyDictionary* dict); // fills mITSClustersArray void prepareMFTClusters(const o2::itsmft::TopologyDictionary* dict); // fills mMFTClustersArray void clear() { mEvent.clear(); } + bool isEmpty() { return mEvent.isEmpty(); } void save(const std::string& jsonPath, int numberOfFiles, diff --git a/EventVisualisation/Workflow/include/EveWorkflow/O2DPLDisplay.h b/EventVisualisation/Workflow/include/EveWorkflow/O2DPLDisplay.h index 563446dc2b57a..3a3e2618ea4f6 100644 --- a/EventVisualisation/Workflow/include/EveWorkflow/O2DPLDisplay.h +++ b/EventVisualisation/Workflow/include/EveWorkflow/O2DPLDisplay.h @@ -50,8 +50,8 @@ class O2DPLDisplaySpec : public o2::framework::Task O2DPLDisplaySpec(bool useMC, o2::dataformats::GlobalTrackID::mask_t trkMask, o2::dataformats::GlobalTrackID::mask_t clMask, std::shared_ptr dataRequest, std::string jsonPath, - std::chrono::milliseconds timeInterval, int numberOfFiles, int numberOfTracks, bool eveHostNameMatch) - : mUseMC(useMC), mTrkMask(trkMask), mClMask(clMask), mDataRequest(dataRequest), mJsonPath(jsonPath), mTimeInteval(timeInterval), mNumberOfFiles(numberOfFiles), mNumberOfTracks(numberOfTracks), mEveHostNameMatch(eveHostNameMatch) + std::chrono::milliseconds timeInterval, int numberOfFiles, int numberOfTracks, bool eveHostNameMatch, bool noEmptyOutput) + : mUseMC(useMC), mTrkMask(trkMask), mClMask(clMask), mDataRequest(dataRequest), mJsonPath(jsonPath), mTimeInteval(timeInterval), mNumberOfFiles(numberOfFiles), mNumberOfTracks(numberOfTracks), mEveHostNameMatch(eveHostNameMatch), mNoEmptyOutput(noEmptyOutput) { this->mTimeStamp = std::chrono::high_resolution_clock::now() - timeInterval; // first run meets condition } @@ -66,6 +66,7 @@ class O2DPLDisplaySpec : public o2::framework::Task bool mUseMC = false; bool mEveHostNameMatch; // empty or correct hostname + bool mNoEmptyOutput; // don't create files with no tracks/clusters std::string mJsonPath; // folder where files are stored std::chrono::milliseconds mTimeInteval; // minimal interval between files in miliseconds int mNumberOfFiles; // maximun number of files in folder - newer replaces older diff --git a/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx b/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx index 3ec67808e2fe6..84aff7a42689c 100644 --- a/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx +++ b/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx @@ -45,14 +45,7 @@ void EveWorkflowHelper::selectTracks(const CalibObjectsConst* calib, this->mRecoCont.createTracksVariadic(creator); } -void EveWorkflowHelper::draw(const std::string& jsonPath, - int numberOfFiles, - int numberOfTracks, - o2::dataformats::GlobalTrackID::mask_t trkMask, - o2::dataformats::GlobalTrackID::mask_t clMask, - o2::header::DataHeader::RunNumberType runNumber, - o2::framework::DataProcessingHeader::CreationTime creation, - float workflowVersion) +void EveWorkflowHelper::draw(int numberOfTracks) { size_t nTracks = mTrackSet.trackGID.size(); if (numberOfTracks != -1 && numberOfTracks < nTracks) { @@ -103,9 +96,6 @@ void EveWorkflowHelper::draw(const std::string& jsonPath, LOG(info) << "Track type " << gid.getSource() << " not handled"; } } - - // save json file - save(jsonPath, numberOfFiles, trkMask, clMask, workflowVersion, runNumber, creation); } void EveWorkflowHelper::save(const std::string& jsonPath, int numberOfFiles, diff --git a/EventVisualisation/Workflow/src/O2DPLDisplay.cxx b/EventVisualisation/Workflow/src/O2DPLDisplay.cxx index b5d29190e665c..83f270ac78df7 100644 --- a/EventVisualisation/Workflow/src/O2DPLDisplay.cxx +++ b/EventVisualisation/Workflow/src/O2DPLDisplay.cxx @@ -54,7 +54,8 @@ void customize(std::vector& workflowOptions) {"read-from-files", o2::framework::VariantType::Bool, false, {"comma-separated list of tracks to display"}}, {"disable-root-input", o2::framework::VariantType::Bool, false, {"Disable root input overriding read-from-files"}}, {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings ..."}}, - {"skipOnEmptyInput", o2::framework::VariantType::Bool, false, {"Just don't run the ED when no input is provided"}}}; + {"skipOnEmptyInput", o2::framework::VariantType::Bool, false, {"Just don't run the ED when no input is provided"}}, + {"no-empty-output", o2::framework::VariantType::Bool, false, {"don't create files with no tracks/clusters"}}}; std::swap(workflowOptions, options); } @@ -94,7 +95,12 @@ void O2DPLDisplaySpec::run(ProcessingContext& pc) const auto* dh = DataRefUtils::getHeader(ref); const auto* dph = DataRefUtils::getHeader(ref); - helper.draw(this->mJsonPath, this->mNumberOfFiles, this->mNumberOfTracks, this->mTrkMask, this->mClMask, dh->runNumber, dph->creation, this->mWorkflowVersion); + helper.draw(this->mNumberOfTracks); + + if (!(this->mNoEmptyOutput && helper.isEmpty())) { + helper.save(this->mJsonPath, this->mNumberOfFiles, this->mTrkMask, this->mClMask, this->mWorkflowVersion, dh->runNumber, dph->creation); + } + auto endTime = std::chrono::high_resolution_clock::now(); LOGP(info, "Visualization of TF:{} at orbit {} took {} s.", dh->tfCounter, dh->firstTForbit, std::chrono::duration_cast(endTime - currentTime).count() * 1e-6); } @@ -172,11 +178,13 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) InputHelper::addInputSpecs(cfgc, specs, srcCl, srcTrk, srcTrk, useMC); } + auto noEmptyFiles = cfgc.options().get("no-empty-output"); + specs.emplace_back(DataProcessorSpec{ "o2-eve-display", dataRequest->inputs, {}, - AlgorithmSpec{adaptFromTask(useMC, srcTrk, srcCl, dataRequest, jsonFolder, timeInterval, numberOfFiles, numberOfTracks, eveHostNameMatch)}}); + AlgorithmSpec{adaptFromTask(useMC, srcTrk, srcCl, dataRequest, jsonFolder, timeInterval, numberOfFiles, numberOfTracks, eveHostNameMatch, noEmptyFiles)}}); return std::move(specs); }