25#include <unordered_map>
29#include <TObjString.h>
74 : mComputeTime(computeTime), mDigits(
digits), mCCDBRequest(req) {}
81 LOG(info) <<
"initializing track finder";
86 auto grpFile = ic.
options().
get<std::string>(
"grp-file");
87 if (std::filesystem::exists(grpFile)) {
92 float l3Current = ic.
options().
get<
float>(
"l3Current");
93 float dipoleCurrent = ic.
options().
get<
float>(
"dipoleCurrent");
94 mTrackFinder.initField(l3Current, dipoleCurrent);
98 auto config = ic.
options().
get<std::string>(
"mch-config");
99 if (!config.empty()) {
104 auto debugLevel = ic.
options().
get<
int>(
"mch-debug");
105 mTrackFinder.debug(debugLevel);
107 auto stop = [
this]() {
108 mTrackFinder.printStats();
109 mTrackFinder.printTimers();
110 LOG(info) <<
"tracking duration = " << mElapsedTime.count() <<
" s";
112 LOGP(warning,
"{}", error.asString());
142 auto clusterROFs = pc.
inputs().
get<gsl::span<ROFRecord>>(
"clusterrofs");
143 auto clustersIn = pc.
inputs().
get<gsl::span<Cluster>>(
"clusters");
144 gsl::span<const Digit> digitsIn{};
145 if (mComputeTime || mDigits) {
146 digitsIn = pc.
inputs().
get<gsl::span<Digit>>(
"clusterdigits");
153 std::vector<Digit, o2::pmr::polymorphic_allocator<Digit>>* usedDigits(
nullptr);
159 auto timeStart = std::chrono::high_resolution_clock::now();
160 auto& errorMap = mTrackFinder.getErrorMap();
163 for (
const auto& clusterROF : clusterROFs) {
166 auto tStart = std::chrono::high_resolution_clock::now();
167 const auto&
tracks = mTrackFinder.findTracks(clustersIn.subspan(clusterROF.getFirstIdx(), clusterROF.getNEntries()));
168 auto tEnd = std::chrono::high_resolution_clock::now();
169 mElapsedTime += tEnd - tStart;
172 int trackOffset(mchTracks.size());
173 writeTracks(
tracks, digitsIn, clusterROF, firstTForbit, mchTracks, usedClusters, usedDigits);
174 trackROFs.emplace_back(clusterROF.getBCData(), trackOffset, mchTracks.size() - trackOffset,
175 clusterROF.getBCWidth());
180 errorMap.forEach([&trackErrors](
Error error) {
181 trackErrors.emplace_back(error);
183 mErrorMap.
add(errorMap);
185 auto timeEnd = std::chrono::high_resolution_clock::now();
186 std::chrono::duration<double, std::milli> elapsed = timeEnd - timeStart;
187 LOGP(info,
"Found {:3d} MCH tracks from {:4d} clusters in {:2d} ROFs in {:8.0f} ms",
188 mchTracks.size(), clustersIn.size(), clusterROFs.size(), elapsed.count());
193 TrackMCH::Time computeTrackTime(
const Track& track,
const gsl::span<const Digit>& digitsIn,
194 const ROFRecord& clusterROF, uint32_t firstTForbit)
const
198 double trackBCinTF = 0.;
202 for (
const auto&
param : track) {
203 for (
const auto& digit : digitsIn.subspan(
param.getClusterPtr()->firstDigit,
param.getClusterPtr()->nDigits)) {
205 trackBCinTF += (double(digit.getTime()) - trackBCinTF) / nDigits;
214 float tMean = o2::constants::lhc::LHCBunchSpacingMUS * (trackBCinTF + 1.5);
215 float tErr = o2::constants::lhc::LHCBunchSpacingMUS * mTrackTime3Sigma;
220 LOG(fatal) <<
"MCH: no digits found when computing the track mean time";
225 void writeTracks(
const std::list<Track>&
tracks,
const gsl::span<const Digit>& digitsIn,
226 const ROFRecord& clusterROF, uint32_t firstTForbit,
234 std::unordered_map<uint32_t, uint32_t> digitLocMap{};
236 for (
const auto& track :
tracks) {
238 TrackParam paramAtMID(
track.last());
240 LOG(warning) <<
"propagation to MID failed --> track discarded";
244 const auto time = mComputeTime ? computeTrackTime(track, digitsIn, clusterROF, firstTForbit)
248 mchTracks.emplace_back(
param.getZ(),
param.getParameters(),
param.getCovariances(),
249 param.getTrackChi2(), usedClusters.size(),
track.getNClusters(),
250 paramAtMID.getZ(), paramAtMID.getParameters(), paramAtMID.getCovariances(),
255 usedClusters.emplace_back(*
param.getClusterPtr());
260 auto& cluster = usedClusters.back();
261 auto digitLoc = digitLocMap.emplace(cluster.firstDigit, usedDigits->size());
264 if (digitLoc.second) {
265 auto itFirstDigit = digitsIn.begin() + cluster.firstDigit;
266 usedDigits->insert(usedDigits->end(), itFirstDigit, itFirstDigit + cluster.nDigits);
270 cluster.firstDigit = digitLoc.first->second;
279 static bool first =
true;
286 md.SetOwnerKeyValue();
293 bool mComputeTime =
false;
294 bool mDigits =
false;
295 std::shared_ptr<base::GRPGeomRequest> mCCDBRequest{};
296 float mTrackTime3Sigma{6.0};
298 ErrorMap mErrorMap{};
299 std::chrono::duration<double> mElapsedTime{};
304 bool disableCCDBMagField,
bool original)
306 std::vector<InputSpec> inputSpecs{};
307 inputSpecs.emplace_back(
InputSpec{
"clusterrofs",
"MCH",
"CLUSTERROFS", 0, Lifetime::Timeframe});
308 inputSpecs.emplace_back(
InputSpec{
"clusters",
"MCH",
"GLOBALCLUSTERS", 0, Lifetime::Timeframe});
309 if (computeTime ||
digits) {
310 inputSpecs.emplace_back(
InputSpec{
"clusterdigits",
"MCH",
"CLUSTERDIGITS", 0, Lifetime::Timeframe});
313 std::vector<OutputSpec> outputSpecs{};
314 outputSpecs.emplace_back(
OutputSpec{{
"trackrofs"},
"MCH",
"TRACKROFS", 0, Lifetime::Timeframe});
315 outputSpecs.emplace_back(
OutputSpec{{
"tracks"},
"MCH",
"TRACKS", 0, Lifetime::Timeframe});
316 outputSpecs.emplace_back(
OutputSpec{{
"trackclusters"},
"MCH",
"TRACKCLUSTERS", 0, Lifetime::Timeframe});
318 outputSpecs.emplace_back(
OutputSpec{{
"trackdigits"},
"MCH",
"TRACKDIGITS", 0, Lifetime::Timeframe});
320 outputSpecs.emplace_back(
OutputSpec{{
"trackerrors"},
"MCH",
"TRACKERRORS", 0, Lifetime::Timeframe});
321 outputSpecs.emplace_back(
"META",
"MCHTRACKER", 0, Lifetime::Sporadic);
323 auto ccdbRequest = disableCCDBMagField ? nullptr
324 : std::make_shared<base::GRPGeomRequest>(
false,
336 original ?
AlgorithmSpec{adaptFromTask<TrackFinderTask<TrackFinderOriginal>>(computeTime,
digits, ccdbRequest)}
337 :
AlgorithmSpec{adaptFromTask<TrackFinderTask<TrackFinder>>(computeTime,
digits, ccdbRequest)},
338 Options{{
"l3Current", VariantType::Float, -30000.0f, {
"L3 current"}},
339 {
"dipoleCurrent", VariantType::Float, -6000.0f, {
"Dipole current"}},
341 {
"mch-config", VariantType::String,
"", {
"JSON or INI file with tracking parameters"}},
342 {
"mch-debug", VariantType::Int, 0, {
"debug level"}}}};
Definition of the MCH track for internal use.
definition of the MCH processing errors
Helper for geometry and GRP related CCDB requests.
Header of the General Run Parameters object.
std::vector< o2::itsmft::ROFRecord > trackROFs
std::vector< o2::its::TrackITS > tracks
Configurable parameters for MCH tracking.
Definition of the Names Generator class.
Definition of a class to reconstruct tracks with the original algorithm.
Definition of a data processor to read clusters, reconstruct tracks and send them.
Definition of a class to reconstruct tracks.
Definition of the MCH track.
Definition of the MCH track parameters for internal use.
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static std::string getGRPFileName(const std::string_view prefix=STANDARDSIMPREFIX)
static std::string getConfigOutputFileName(const std::string &procName, const std::string &confName="", bool json=true)
static int initFieldFromGRP(const o2::parameters::GRPMagField *grp, bool verbose=false)
static const TrackerParam & Instance()
static std::string asJSON(std::string const &keyOnly="")
static void updateFromFile(std::string const &, std::string const ¶msList="", bool unchangedOnly=false)
static void write(std::string const &filename, std::string const &keyOnly="")
T get(const char *key) const
void snapshot(const Output &spec, T const &object)
decltype(auto) make(const Output &spec, Args... args)
ServiceRegistryRef services()
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.
ServiceRegistryRef services()
The services registry associated with this processing context.
HMPID cluster implementation.
void forEach(ErrorFunction f) const
void add(ErrorType errorType, uint32_t id0, uint32_t id1, uint64_t n=1)
std::pair< Time, bool > getTimeMUS(const BCData &startIR, uint32_t nOrbits=128, bool printError=false) const
void finaliseCCDB(framework::ConcreteDataMatcher &matcher, void *obj)
void run(framework::ProcessingContext &pc)
void init(framework::InitContext &ic)
TrackFinderTask(bool computeTime, bool digits, std::shared_ptr< base::GRPGeomRequest > req)
o2::dataformats::TimeStampWithError< float, float > Time
static GRPObject * loadFrom(const std::string &grpFileName="")
Defining ITS Vertex explicitly as messageable.
std::vector< ConfigParamSpec > Options
const bool const int TrackITSInternal< NLayers > & track
o2::framework::DataProcessorSpec getTrackFinderSpec(const char *specName="mch-track-finder", bool computeTime=true, bool digits=false, bool disableCCDBMagField=false, bool original=false)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string name
The name of the associated DataProcessorSpec.
size_t inputTimesliceId
The time pipelining id of this particular device.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits