25#include <unordered_map>
70 : mComputeTime(computeTime), mDigits(
digits), mCCDBRequest(req) {}
77 LOG(info) <<
"initializing track finder";
82 auto grpFile = ic.
options().
get<std::string>(
"grp-file");
83 if (std::filesystem::exists(grpFile)) {
88 float l3Current = ic.
options().
get<
float>(
"l3Current");
89 float dipoleCurrent = ic.
options().
get<
float>(
"dipoleCurrent");
90 mTrackFinder.initField(l3Current, dipoleCurrent);
94 auto config = ic.
options().
get<std::string>(
"mch-config");
95 if (!config.empty()) {
100 auto debugLevel = ic.
options().
get<
int>(
"mch-debug");
101 mTrackFinder.debug(debugLevel);
103 auto stop = [
this]() {
104 mTrackFinder.printStats();
105 mTrackFinder.printTimers();
106 LOG(info) <<
"tracking duration = " << mElapsedTime.count() <<
" s";
108 LOGP(warning,
"{}", error.
asString());
137 auto clusterROFs = pc.
inputs().
get<gsl::span<ROFRecord>>(
"clusterrofs");
138 auto clustersIn = pc.
inputs().
get<gsl::span<Cluster>>(
"clusters");
139 gsl::span<const Digit> digitsIn{};
140 if (mComputeTime || mDigits) {
141 digitsIn = pc.
inputs().
get<gsl::span<Digit>>(
"clusterdigits");
148 std::vector<Digit, o2::pmr::polymorphic_allocator<Digit>>* usedDigits(
nullptr);
153 trackROFs.reserve(clusterROFs.size());
154 auto timeStart = std::chrono::high_resolution_clock::now();
155 auto& errorMap = mTrackFinder.getErrorMap();
158 for (
const auto& clusterROF : clusterROFs) {
161 auto tStart = std::chrono::high_resolution_clock::now();
162 const auto& tracks = mTrackFinder.findTracks(clustersIn.subspan(clusterROF.getFirstIdx(), clusterROF.getNEntries()));
163 auto tEnd = std::chrono::high_resolution_clock::now();
164 mElapsedTime += tEnd - tStart;
167 int trackOffset(mchTracks.size());
168 writeTracks(tracks, digitsIn, clusterROF, firstTForbit, mchTracks, usedClusters, usedDigits);
169 trackROFs.emplace_back(clusterROF.getBCData(), trackOffset, mchTracks.size() - trackOffset,
170 clusterROF.getBCWidth());
175 errorMap.forEach([&trackErrors](
Error error) {
176 trackErrors.emplace_back(error);
178 mErrorMap.
add(errorMap);
180 auto timeEnd = std::chrono::high_resolution_clock::now();
181 std::chrono::duration<double, std::milli> elapsed = timeEnd - timeStart;
182 LOGP(info,
"Found {:3d} MCH tracks from {:4d} clusters in {:2d} ROFs in {:8.0f} ms",
183 mchTracks.size(), clustersIn.size(), clusterROFs.size(), elapsed.count());
188 TrackMCH::Time computeTrackTime(
const Track& track,
const gsl::span<const Digit>& digitsIn,
189 const ROFRecord& clusterROF, uint32_t firstTForbit)
const
193 double trackBCinTF = 0.;
197 for (
const auto&
param : track) {
198 for (
const auto& digit : digitsIn.subspan(
param.getClusterPtr()->firstDigit,
param.getClusterPtr()->nDigits)) {
200 trackBCinTF += (double(digit.getTime()) - trackBCinTF) / nDigits;
215 LOG(fatal) <<
"MCH: no digits found when computing the track mean time";
220 void writeTracks(
const std::list<Track>& tracks,
const gsl::span<const Digit>& digitsIn,
221 const ROFRecord& clusterROF, uint32_t firstTForbit,
222 std::vector<TrackMCH, o2::pmr::polymorphic_allocator<TrackMCH>>& mchTracks,
223 std::vector<
Cluster, o2::pmr::polymorphic_allocator<Cluster>>& usedClusters,
224 std::vector<Digit, o2::pmr::polymorphic_allocator<Digit>>* usedDigits)
const
229 std::unordered_map<uint32_t, uint32_t> digitLocMap{};
231 for (
const auto& track :
tracks) {
233 TrackParam paramAtMID(track.
last());
235 LOG(warning) <<
"propagation to MID failed --> track discarded";
239 const auto time = mComputeTime ? computeTrackTime(track, digitsIn, clusterROF, firstTForbit)
243 mchTracks.emplace_back(
param.getZ(),
param.getParameters(),
param.getCovariances(),
245 paramAtMID.getZ(), paramAtMID.getParameters(), paramAtMID.getCovariances(),
248 for (
const auto&
param : track) {
250 usedClusters.emplace_back(*
param.getClusterPtr());
255 auto& cluster = usedClusters.back();
256 auto digitLoc = digitLocMap.emplace(cluster.firstDigit, usedDigits->size());
259 if (digitLoc.second) {
260 auto itFirstDigit = digitsIn.begin() + cluster.firstDigit;
261 usedDigits->insert(usedDigits->end(), itFirstDigit, itFirstDigit + cluster.nDigits);
265 cluster.firstDigit = digitLoc.first->second;
271 bool mComputeTime =
false;
272 bool mDigits =
false;
273 std::shared_ptr<base::GRPGeomRequest> mCCDBRequest{};
274 float mTrackTime3Sigma{6.0};
276 ErrorMap mErrorMap{};
277 std::chrono::duration<double> mElapsedTime{};
282 bool disableCCDBMagField,
bool original)
284 std::vector<InputSpec> inputSpecs{};
285 inputSpecs.emplace_back(
InputSpec{
"clusterrofs",
"MCH",
"CLUSTERROFS", 0, Lifetime::Timeframe});
286 inputSpecs.emplace_back(
InputSpec{
"clusters",
"MCH",
"GLOBALCLUSTERS", 0, Lifetime::Timeframe});
287 if (computeTime ||
digits) {
288 inputSpecs.emplace_back(
InputSpec{
"clusterdigits",
"MCH",
"CLUSTERDIGITS", 0, Lifetime::Timeframe});
291 std::vector<OutputSpec> outputSpecs{};
292 outputSpecs.emplace_back(
OutputSpec{{
"trackrofs"},
"MCH",
"TRACKROFS", 0, Lifetime::Timeframe});
293 outputSpecs.emplace_back(
OutputSpec{{
"tracks"},
"MCH",
"TRACKS", 0, Lifetime::Timeframe});
294 outputSpecs.emplace_back(
OutputSpec{{
"trackclusters"},
"MCH",
"TRACKCLUSTERS", 0, Lifetime::Timeframe});
296 outputSpecs.emplace_back(
OutputSpec{{
"trackdigits"},
"MCH",
"TRACKDIGITS", 0, Lifetime::Timeframe});
298 outputSpecs.emplace_back(
OutputSpec{{
"trackerrors"},
"MCH",
"TRACKERRORS", 0, Lifetime::Timeframe});
300 auto ccdbRequest = disableCCDBMagField ? nullptr
301 : std::make_shared<base::GRPGeomRequest>(
false,
313 original ?
AlgorithmSpec{adaptFromTask<TrackFinderTask<TrackFinderOriginal>>(computeTime,
digits, ccdbRequest)}
314 :
AlgorithmSpec{adaptFromTask<TrackFinderTask<TrackFinder>>(computeTime,
digits, ccdbRequest)},
315 Options{{
"l3Current", VariantType::Float, -30000.0f, {
"L3 current"}},
316 {
"dipoleCurrent", VariantType::Float, -6000.0f, {
"Dipole current"}},
318 {
"mch-config", VariantType::String,
"", {
"JSON or INI file with tracking parameters"}},
319 {
"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.
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 int initFieldFromGRP(const o2::parameters::GRPMagField *grp, bool verbose=false)
static void updateFromFile(std::string const &, std::string const ¶msList="", bool unchangedOnly=false)
T get(const char *key) const
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
int getNClusters() const
Return the number of attached clusters.
const TrackParam & first() const
Return a reference to the track parameters at first cluster.
const TrackParam & last() const
Return a reference to the track parameters at last cluster.
static GRPObject * loadFrom(const std::string &grpFileName="")
constexpr double LHCBunchSpacingMUS
Defining PrimaryVertex explicitly as messageable.
std::vector< ConfigParamSpec > Options
o2::framework::DataProcessorSpec getTrackFinderSpec(const char *specName="mch-track-finder", bool computeTime=true, bool digits=false, bool disableCCDBMagField=false, bool original=false)
struct o2::upgrades_utils::@454 tracks
structure to keep trigger-related info
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
std::string asString() const
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits