Skip to content
Snippets Groups Projects
Commit a18234e0 authored by Volker Friese's avatar Volker Friese Committed by Felix Weiglhofer
Browse files

Integrate v0 trigger into the online processing chain

parent 678b2296
No related branches found
No related tags found
1 merge request!1767Integrate v0 trigger into the online processing chain
Pipeline #29073 passed
......@@ -88,6 +88,7 @@ set(SRCS
trigger/DigiTriggerConfig.cxx
trigger/TimeClusterTrigger.cxx
trigger/V0Trigger.cxx
trigger/V0TriggerConfig.cxx
evselector/DigiEventSelector.cxx
evselector/DigiEventSelectorConfig.cxx
unpack/CommonUnpacker.cxx
......
......@@ -13,7 +13,8 @@ namespace cbm::algo::evbuild
// ----- Constructor from YAML --------------------------------------------
Config::Config(YAML::Node node)
: fTrigger(node["trigger"])
: fDigiTrigger(node["trigger"])
, fV0Trigger(node["v0trigger"])
, fBuilder(node["eventbuilder"])
, fSelector(node["selector"])
{
......@@ -26,9 +27,10 @@ namespace cbm::algo::evbuild
YAML::Node Config::ToYaml() const
{
YAML::Node result;
result["trigger"] = fTrigger.ToYaml(); // Digi trigger config
result["eventbuilder"] = fBuilder.ToYaml(); // Event builder config
result["selector"] = fSelector.ToYaml(); // Event selector config
result["digitrigger"] = fDigiTrigger.ToYaml(); // Digi trigger config
result["v0trigger"] = fV0Trigger.ToYaml(); // V0 trigger config
result["eventbuilder"] = fBuilder.ToYaml(); // Event builder config
result["selector"] = fSelector.ToYaml(); // Event selector config
return result;
}
// ----------------------------------------------------------------------------
......
......@@ -9,6 +9,7 @@
#include "DigiEventSelectorConfig.h"
#include "DigiTriggerConfig.h"
#include "EventBuilderConfig.h"
#include "V0Trigger.h"
#include <yaml-cpp/yaml.h>
......@@ -29,7 +30,8 @@ namespace cbm::algo::evbuild
YAML::Node ToYaml() const;
public: // data members
DigiTriggerConfig fTrigger; ///< Digi trigger configuration
DigiTriggerConfig fDigiTrigger; ///< Digi trigger configuration
V0TriggerConfig fV0Trigger; ///< V0 trigger configuration
EventBuilderConfig fBuilder; ///< Event builder configuration
DigiEventSelectorConfig fSelector; ///< Event selector configuration
};
......
......@@ -18,8 +18,10 @@ using namespace cbm::algo::evbuild;
// ----- Constructor ------------------------------------------------------
EventbuildChain::EventbuildChain(const Config& config, std::shared_ptr<HistogramSender> sender)
: fTriggerDet(config.fTrigger.Detector())
, fTrigger(config.fTrigger)
: fConfig(config)
, fTriggerDet(config.fDigiTrigger.Detector())
, fDigiTrigger(config.fDigiTrigger)
, fV0Trigger()
, fBuilder(config.fBuilder)
, fSelector(config.fSelector)
, fQa(DigiEventQaConfig(config.fBuilder, 10., 100))
......@@ -61,17 +63,39 @@ EventbuildChain::~EventbuildChain() {}
// ----------------------------------------------------------------------------
// ----- Run event building on a timeslice --------------------------------
EventbuildChain::ResultType EventbuildChain::Run(const DigiData& timeslice)
typedef cbm::algo::ca::Vector<cbm::algo::ca::Track> TrackVector;
EventbuildChain::ResultType EventbuildChain::Run(const DigiData& digiData,
const cbm::algo::ca::Vector<cbm::algo::ca::Track>& tracks)
{
// --- Extract the digi time stamps of the trigger detector
std::vector<double> digiTimes = GetDigiTimes(timeslice, fTriggerDet);
// --- Local variables
std::vector<double> triggers;
ResultType result;
// --- Call the trigger algorithm
auto [triggers, triggerMon] = fTrigger(digiTimes);
// --- If V0Trigger is configured, use it
if (fConfig.fV0Trigger.IsSet()) {
auto [v0Triggers, v0TriggerMon] = fV0Trigger(tracks, fConfig.fV0Trigger);
triggers = std::move(v0Triggers);
result.second.v0Trigger = std::move(v0TriggerMon);
}
// --- Else, use the digi multiplicity trigger
else if (fConfig.fDigiTrigger.IsSet()) {
std::vector<double> digiTimes = GetDigiTimes(digiData, fTriggerDet);
auto [digiTriggers, digiTriggerMon] = fDigiTrigger(digiTimes);
triggers = std::move(digiTriggers);
result.second.digiTrigger = std::move(digiTriggerMon);
}
// --- Else, throw exception
else
throw std::runtime_error("no trigger is configured");
// --- Perform event building
auto [events, evbuildMon] = fBuilder(timeslice, triggers, fSelector);
auto [events, evbuildMon] = fBuilder(digiData, triggers, fSelector);
result.first = std::move(events);
result.second.evbuild = evbuildMon;
/// => Histograms serialization and emission
if (fSender) {
......@@ -86,12 +110,7 @@ EventbuildChain::ResultType EventbuildChain::Run(const DigiData& timeslice)
}
// --- Some log
L_(info) << "Triggers: " << triggers.size() << ", events " << events.size();
ResultType result;
result.first = std::move(events);
result.second.trigger = triggerMon;
result.second.evbuild = evbuildMon;
L_(info) << "Triggers: " << triggers.size() << ", events " << result.first.size();
return result;
}
......@@ -101,9 +120,13 @@ EventbuildChain::ResultType EventbuildChain::Run(const DigiData& timeslice)
// ----- Status info ------------------------------------------------------
void EventbuildChain::Status() const
{
L_(info) << "=== Eventbuiler configuration ====================";
L_(info) << "--- Using trigger detector " << ::ToString(fTriggerDet);
L_(info) << fTrigger.ToString();
L_(info) << "=== Eventbuilder configuration ===================";
if (fConfig.fV0Trigger.IsSet())
L_(info) << fV0Trigger.ToString();
else {
L_(info) << "--- Using digi multiplicity trigger with trigger detector " << ::ToString(fTriggerDet);
L_(info) << fDigiTrigger.ToString();
}
L_(info) << fBuilder.ToString();
L_(info) << fSelector.ToString();
L_(info) << fQa.ToString();
......
......@@ -6,12 +6,15 @@
#define CBM_ALGO_EVBUILD_EVBUILDCHAIN_H 1
#include "CbmDefs.h"
#include "Config.h"
#include "DigiEventQa.h"
#include "DigiEventSelector.h"
#include "EventBuilder.h"
#include "HistogramSender.h"
#include "RecoResults.h"
#include "SubChain.h"
#include "TimeClusterTrigger.h"
#include "V0Trigger.h"
#include <memory>
......@@ -23,11 +26,10 @@ namespace cbm::algo
namespace cbm::algo::evbuild
{
class Config;
struct EventbuildChainMonitorData {
EventBuilderMonitorData evbuild;
TimeClusterTriggerMonitorData trigger;
TimeClusterTriggerMonitorData digiTrigger;
V0TriggerMoniData v0Trigger;
};
/** @class EventbuildChain
......@@ -52,7 +54,7 @@ namespace cbm::algo::evbuild
~EventbuildChain();
/** @brief Execution **/
ResultType Run(const DigiData&);
ResultType Run(const DigiData&, const cbm::algo::ca::Vector<cbm::algo::ca::Track>&);
/** @brief Status info to logger **/
void Status() const;
......@@ -61,8 +63,10 @@ namespace cbm::algo::evbuild
void RegisterTrackingSetup(std::shared_ptr<TrackingSetup> pSetup) { fSelector.RegisterTrackingSetup(pSetup); }
private: // members
Config fConfig; ///< Global configuration
ECbmModuleId fTriggerDet = ECbmModuleId::kNotExist; ///< Trigger detector
TimeClusterTrigger fTrigger; ///< Trigger algorithm
TimeClusterTrigger fDigiTrigger; ///< Digi multiplicity trigger algorithm
V0Trigger fV0Trigger; ///< V0 trigger algorithm
EventBuilder fBuilder; ///< Event builder algorithm
DigiEventSelector fSelector; ///< Event selector algorithm
DigiEventQa fQa; ///< Event QA algorithm
......
......@@ -250,15 +250,6 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
<< " FSD=" << digis.fFsd.size();
}
// --- Digi event building
std::vector<DigiEvent> events;
evbuild::EventbuildChainMonitorData evbuildMonitor;
if (Opts().Has(Step::DigiTrigger)) {
auto [ev, mon] = fEventBuild->Run(digis);
events = std::move(ev);
evbuildMonitor = mon;
QueueEvbuildMetrics(evbuildMonitor);
}
// --- Raw digi QAs
if (fSender != nullptr && Opts().Has(Subsystem::STS) && Opts().Has(Step::Unpack)) {
......@@ -310,21 +301,28 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
}
// --- Tracking
TrackingChain::Output_t trackingOutput{};
if (Opts().Has(Step::Tracking)) {
TrackingChain::Input_t input{
.stsHits = stsHits,
.tofHits = tofHits,
.trdHits = trdHits,
};
TrackingChain::Output_t trackingOutput = fTracking->Run(input);
if (Opts().HasOutput(RecoData::Track)) {
results.tracks = std::move(trackingOutput.tracks);
results.trackStsHitIndices = std::move(trackingOutput.stsHitIndices);
results.trackTofHitIndices = std::move(trackingOutput.tofHitIndices);
}
trackingOutput = fTracking->Run(input);
QueueTrackingMetrics(trackingOutput.monitorData);
}
// --- Event building
std::vector<DigiEvent> events;
evbuild::EventbuildChainMonitorData evbuildMonitor;
if (Opts().Has(Step::DigiTrigger)) {
auto [ev, mon] = fEventBuild->Run(digis, trackingOutput.tracks);
events = std::move(ev);
evbuildMonitor = mon;
QueueEvbuildMetrics(evbuildMonitor);
}
if (Opts().HasOutput(RecoData::DigiTimeslice)) {
results.bmonDigis = std::move(digis.fBmon);
results.stsDigis = std::move(digis.fSts);
......@@ -334,6 +332,11 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
results.tofDigis = std::move(digis.fTof);
results.richDigis = std::move(digis.fRich);
}
if (Opts().HasOutput(RecoData::Track)) {
results.tracks = std::move(trackingOutput.tracks);
results.trackStsHitIndices = std::move(trackingOutput.stsHitIndices);
results.trackTofHitIndices = std::move(trackingOutput.tofHitIndices);
}
if (Opts().HasOutput(RecoData::DigiEvent)) results.events = std::move(events);
if (Opts().HasOutput(RecoData::Cluster)) results.stsClusters = std::move(stsClusters);
if (Opts().HasOutput(RecoData::Hit)) {
......@@ -510,11 +513,16 @@ void Reco::QueueEvbuildMetrics(const evbuild::EventbuildChainMonitorData& mon)
double totalSelectionRatio = nDigisTotal > 0 ? double(nDigisInEventsTotal) / nDigisTotal : 0;
GetMonitor().QueueMetric("cbmreco", tags,
{{"digiTriggerTimeTotal", mon.trigger.time.wall()},
{"digiTriggerThroughput", mon.trigger.time.throughput()},
{{"digiTriggerTimeTotal", mon.digiTrigger.time.wall()},
{"digiTriggerThroughput", mon.digiTrigger.time.throughput()},
{"v0TriggerNumTrackPairs", mon.v0Trigger.numTrackPairs},
{"v0TriggerNumTrackPairsCoinc", mon.v0Trigger.numTrackPairsAfterTimeCut},
{"v0TriggerErrTracksUnsorted", mon.v0Trigger.errTracksUnsorted},
{"v0TriggerTimeTotal", mon.v0Trigger.time.wall()},
{"v0TriggerThroughput", mon.v0Trigger.time.throughput()},
{"eventbuildTimeTotal", mon.evbuild.time.wall()},
{"eventbuildThroughput", mon.evbuild.time.throughput()},
{"numTrigger", mon.trigger.nTriggers},
{"numTrigger", mon.digiTrigger.nTriggers},
{"numEvents", mon.evbuild.nEvents},
{"totalEvSelectionRatio", totalSelectionRatio}});
}
......
......@@ -11,7 +11,10 @@ namespace cbm::algo::evbuild
// ----- Constructor from YAML ------------------------------------------
DigiTriggerConfig::DigiTriggerConfig(YAML::Node config)
{
if (!config) throw std::runtime_error("no configuration node for DigiTrigger");
if (!config) {
fIsSet = false;
return;
}
auto detector = config["detector"];
if (!detector) throw std::runtime_error("trigger detector is not specified");
......@@ -28,6 +31,8 @@ namespace cbm::algo::evbuild
auto deadTime = config["deadtime"];
if (!deadTime) throw std::runtime_error("trigger dead time is not specified");
fDeadTime = deadTime.as<double>();
fIsSet = true;
}
// --------------------------------------------------------------------------
......
......@@ -34,6 +34,7 @@ namespace cbm::algo::evbuild
, fWindow(window)
, fThreshold(threshold)
, fDeadTime(deadTime)
, fIsSet(true)
{
}
......@@ -49,6 +50,9 @@ namespace cbm::algo::evbuild
/** @brief Trigger detector **/
ECbmModuleId Detector() const { return fDetector; }
/** @brief Check whether config was set **/
bool IsSet() const { return fIsSet; }
/** @brief Trigger threshold **/
size_t Threshold() const { return fThreshold; }
......@@ -64,6 +68,7 @@ namespace cbm::algo::evbuild
double fWindow; ///< Trigger window size [ns]
size_t fThreshold; ///< Minimum number if digis in trigger window
double fDeadTime; ///< Minimal time between two trigger [ns]
bool fIsSet{false}; ///< Flag config being properly set
};
......
......@@ -5,14 +5,21 @@
#include "V0Trigger.h"
#include <iterator>
#include <sstream>
namespace cbm::algo
#include <xpu/host.h>
namespace cbm::algo::evbuild
{
V0Trigger::Result V0Trigger::operator()(const TrackVector& tracks, const V0TriggerConfig& config) const
{
xpu::push_timer("V0Trigger");
xpu::t_add_bytes(tracks.size() * sizeof(cbm::algo::ca::Track));
Result result;
for (auto trackIter1 = tracks.begin(); trackIter1 != tracks.end(); trackIter1++) {
......@@ -26,18 +33,26 @@ namespace cbm::algo
continue;
}
result.second.numTrackPairs++;
if (time2 - time1 > config.cutTime) break;
result.second.numTrackPairsWithinTimeCut++;
if (time2 - time1 > config.CutTime()) break;
result.second.numTrackPairsAfterTimeCut++;
// Check PCA cuts
auto [zVertex, dist] = CalcPCA(trackIter1->fParFirst, trackIter2->fParFirst);
if (zVertex > config.cutZ && dist < config.cutDist) {
double tVertex = 0.5 * (time1 + time2);
result.first.push_back(tVertex);
if (zVertex > config.CutZ()) {
result.second.numTrackPairsAfterZCut++;
if (dist < config.CutDist()) {
result.second.numTrackPairsAfterDistCut++;
double tVertex = 0.5 * (time1 + time2);
result.first.push_back(tVertex);
}
}
}
}
result.second.time = xpu::pop_timer();
L_(info) << "V0Trigger: tracks " << tracks.size() << ", track pairs " << result.second.numTrackPairs
<< ", after time cut " << result.second.numTrackPairsAfterTimeCut << ", after z cut "
<< result.second.numTrackPairsAfterZCut << ", after dist cut " << result.second.numTrackPairsAfterDistCut;
return result;
};
......@@ -74,5 +89,12 @@ namespace cbm::algo
return std::make_pair(z, dist);
}
std::string V0Trigger::ToString() const
{
std::stringstream out;
out << "--- Using V0Trigger ---";
return out.str();
}
} // namespace cbm::algo
} // namespace cbm::algo::evbuild
......@@ -6,21 +6,15 @@
#include "CaTrack.h"
#include "CaVector.h"
#include "V0TriggerConfig.h"
#include <utility>
#include <vector>
namespace cbm::algo
{
#include <xpu/host.h>
/** @struct V0TriggerConfig
** @brief Configuration (cut values) for the V0Trigger class
**/
struct V0TriggerConfig {
double cutTime{}; /// Maximum time difference of tracks
double cutZ{}; /// Minimum z position at closest approach
double cutDist{}; /// Maximum distance at closest approach
};
namespace cbm::algo::evbuild
{
/** @struct V0TriggerMoniData
......@@ -29,7 +23,10 @@ namespace cbm::algo
struct V0TriggerMoniData {
size_t errTracksUnsorted{0};
size_t numTrackPairs{0};
size_t numTrackPairsWithinTimeCut{0};
size_t numTrackPairsAfterTimeCut{0};
size_t numTrackPairsAfterZCut{0};
size_t numTrackPairsAfterDistCut{0};
xpu::timings time; ///< Time for trigger building
};
/** @class V0Trigger
......@@ -60,6 +57,9 @@ namespace cbm::algo
**/
Result operator()(const TrackVector& tracks, const V0TriggerConfig& config) const;
/** @brief Info to string **/
std::string ToString() const;
private:
/** @brief Calculation of closest approach of two tracks (straight lines)
......@@ -74,4 +74,4 @@ namespace cbm::algo
std::pair<double, double> CalcPCA(const TrackParam& track1, const TrackParam& track2) const;
};
} // namespace cbm::algo
} // namespace cbm::algo::evbuild
/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Volker Friese [committer] */
#include "V0TriggerConfig.h"
namespace cbm::algo::evbuild
{
// ----- Constructor from YAML ------------------------------------------
V0TriggerConfig::V0TriggerConfig(YAML::Node config)
{
if (!config) {
fIsSet = false;
return;
}
auto cutTime = config["max_time_diff"];
if (!cutTime) throw std::runtime_error("time difference cut is not specified");
fCutTime = cutTime.as<double>();
auto cutZ = config["min_z_pca"];
if (!cutZ) throw std::runtime_error("PCA position cut is not specified");
fCutZ = cutZ.as<double>();
auto cutDist = config["max_dist_at_pca"];
if (!cutDist) throw std::runtime_error("track distance cut is not specified");
fCutDist = cutDist.as<size_t>();
fIsSet = true;
}
// --------------------------------------------------------------------------
// ----- Save to YAML ---------------------------------------------------
YAML::Node V0TriggerConfig::ToYaml() const
{
YAML::Node result;
result["max_time_diff"] = fCutTime;
result["min_z_pca"] = fCutZ;
result["max_dist_at_pca"] = fCutDist;
return result;
}
// --------------------------------------------------------------------------
} // namespace cbm::algo::evbuild
/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Volker Friese [committer] */
#pragma once
#include "CbmDefs.h"
#include <map>
#include <yaml-cpp/yaml.h>
namespace cbm::algo::evbuild
{
/** @class V0TriggerConfig
** @brief Configuration of the V0 trigger class (trigger on displaced vertices)
** @author Volker Friese <v.friese@gsi.de>
** @since 19.04.2024
**/
class V0TriggerConfig {
public:
/** @brief Default constructor **/
V0TriggerConfig(){};
/** @brief Constructor with parameters
** @param cutTime Maximum time difference of tracks [ns]
** @param cutZ Minimum z position at closest approach
** @param cutDist Maximum distance at closest approach
**/
V0TriggerConfig(double cutTime, double cutZ, double cutDist)
: fCutTime(cutTime)
, fCutZ(cutZ)
, fCutDist(cutDist)
, fIsSet(true)
{
}
/** @brief Constructor from YAML **/
V0TriggerConfig(YAML::Node config);
/** @brief Destructor **/
~V0TriggerConfig() = default;
/** @brief Cut on time difference between tracks **/
double CutTime() const { return fCutTime; }
/** @brief Cut on z position of closest approach **/
double CutZ() const { return fCutZ; }
/** @brief Cut on distance of tracks at closest approach **/
double CutDist() const { return fCutDist; }
/** @brief Check whether config was set **/
bool IsSet() const { return fIsSet; }
/** @brief Save to YAML **/
YAML::Node ToYaml() const;
private:
double fCutTime{0.}; /// Maximum time difference of tracks
double fCutZ{0.}; /// Minimum z position at closest approach
double fCutDist{0.}; /// Maximum distance at closest approach
bool fIsSet{false}; /// Flag whether a configuration was set
};
} // namespace cbm::algo::evbuild
......@@ -10,6 +10,8 @@
#include "CbmTaskTriggerDigi.h"
#include "CbmTaskUnpack.h"
#include "CbmTsEventHeader.h"
#include "DigiEventSelector.h"
#include "DigiEventSelectorConfig.h"
#include <FairFileSource.h>
#include <FairRootFileSink.h>
......@@ -25,9 +27,6 @@
#include <yaml-cpp/yaml.h>
#include "DigiEventSelector.h"
#include "DigiEventSelectorConfig.h"
using std::make_unique;
using std::string;
......@@ -36,7 +35,7 @@ using std::string;
CbmReco::CbmReco(Config config, string source, string outFile, string configFile, int32_t numTs, uint16_t port,
cbm::Monitor* monitor)
: fConfig(config)
, fSourceNames {source}
, fSourceNames{source}
, fOutputFileName(outFile)
, fConfigFileName(configFile)
, fNumTs(numTs)
......@@ -102,7 +101,8 @@ int32_t CbmReco::Run()
}
else {
auto source = make_unique<CbmSourceTs>(fSourceNames);
if (source) LOG(info) << "Reco: Using sources " << ListSources();
if (source)
LOG(info) << "Reco: Using sources " << ListSources();
else {
LOG(error) << "Reco: Could not open sources " << ListSources() << "; aborting.";
return -1;
......@@ -112,7 +112,8 @@ int32_t CbmReco::Run()
// --- Output file
auto sink = make_unique<FairRootFileSink>(fOutputFileName);
if (sink) LOG(info) << "Reco: Using output file " << fOutputFileName;
if (sink)
LOG(info) << "Reco: Using output file " << fOutputFileName;
else {
LOG(error) << "Reco: Could not open output " << fOutputFileName << "; aborting.";
return -1;
......@@ -138,8 +139,8 @@ int32_t CbmReco::Run()
// --- Digi trigger
auto trigger = make_unique<CbmTaskTriggerDigi>();
trigger->AddSystem(evbuildConfig.fTrigger.Detector());
trigger->SetConfig(evbuildConfig.fTrigger);
trigger->AddSystem(evbuildConfig.fDigiTrigger.Detector());
trigger->SetConfig(evbuildConfig.fDigiTrigger);
trigger->SetOutputBranchPersistent("Trigger", false);
run.AddTask(trigger.release());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment