From 623abe8a683292734f70b793ad78b5ace0d8e8aa Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Tue, 30 Nov 2021 11:51:38 +0100 Subject: [PATCH 01/36] Add hypertracking workflow skeleton --- Detectors/CMakeLists.txt | 2 +- Detectors/StrangenessTracking/CMakeLists.txt | 13 +++ .../strangeness/CMakeLists.txt | 13 +++ .../strangeness/src/StrangenessTracking.cxx | 10 +++ .../workflow/CMakeLists.txt | 18 +++++ .../HyperTrackingWorkflow/HyperWorkflow.h | 29 +++++++ .../workflow/src/HyperWorkflow.cxx | 41 ++++++++++ .../workflow/src/hypertracking-workflow.cxx | 80 +++++++++++++++++++ 8 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 Detectors/StrangenessTracking/CMakeLists.txt create mode 100644 Detectors/StrangenessTracking/strangeness/CMakeLists.txt create mode 100644 Detectors/StrangenessTracking/strangeness/src/StrangenessTracking.cxx create mode 100644 Detectors/StrangenessTracking/workflow/CMakeLists.txt create mode 100644 Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HyperWorkflow.h create mode 100644 Detectors/StrangenessTracking/workflow/src/HyperWorkflow.cxx create mode 100644 Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx diff --git a/Detectors/CMakeLists.txt b/Detectors/CMakeLists.txt index 255a155136e0e..473f6dffa5cd6 100644 --- a/Detectors/CMakeLists.txt +++ b/Detectors/CMakeLists.txt @@ -36,7 +36,7 @@ add_subdirectory(FOCAL) add_subdirectory(GlobalTracking) add_subdirectory(GlobalTrackingWorkflow) add_subdirectory(Vertexing) - +add_subdirectory(StrangenessTracking) if(BUILD_ANALYSIS) add_subdirectory(AOD) endif() diff --git a/Detectors/StrangenessTracking/CMakeLists.txt b/Detectors/StrangenessTracking/CMakeLists.txt new file mode 100644 index 0000000000000..d3626dc45561c --- /dev/null +++ b/Detectors/StrangenessTracking/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +add_subdirectory(workflow) +# add_subdirectory(strangeness) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/strangeness/CMakeLists.txt b/Detectors/StrangenessTracking/strangeness/CMakeLists.txt new file mode 100644 index 0000000000000..99d670b02b1d0 --- /dev/null +++ b/Detectors/StrangenessTracking/strangeness/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +o2_add_library(StrangenessTracking + SOURCES src/StrangenessTracking.cxx) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/strangeness/src/StrangenessTracking.cxx b/Detectors/StrangenessTracking/strangeness/src/StrangenessTracking.cxx new file mode 100644 index 0000000000000..e6fc06b52b845 --- /dev/null +++ b/Detectors/StrangenessTracking/strangeness/src/StrangenessTracking.cxx @@ -0,0 +1,10 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/CMakeLists.txt b/Detectors/StrangenessTracking/workflow/CMakeLists.txt new file mode 100644 index 0000000000000..74f5192af7fb9 --- /dev/null +++ b/Detectors/StrangenessTracking/workflow/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +o2_add_library(HyperWorkflow + SOURCES src/HyperWorkflow.cxx + PUBLIC_LINK_LIBRARIES O2::Framework) + +o2_add_executable(hypertracking-workflow + SOURCES src/hypertracking-workflow.cxx + PUBLIC_LINK_LIBRARIES O2::HyperWorkflow) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HyperWorkflow.h b/Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HyperWorkflow.h new file mode 100644 index 0000000000000..aae68ac28209d --- /dev/null +++ b/Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HyperWorkflow.h @@ -0,0 +1,29 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// @file HyperWorkflow.h + +#ifndef O2_STRANGENESS_HYPERWORKFLOW_H +#define O2_STRANGENESS_HYPERWORKFLOW_H + +#include "Framework/WorkflowSpec.h" +namespace o2 +{ +namespace strangeness +{ +namespace hyper_workflow +{ + +framework::WorkflowSpec getWorkflow(); + +} +} // namespace strangeness +} // namespace o2 +#endif // O2_STRANGENESS_HYPERWORKFLOW_H \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/src/HyperWorkflow.cxx b/Detectors/StrangenessTracking/workflow/src/HyperWorkflow.cxx new file mode 100644 index 0000000000000..96f59e80b3bcb --- /dev/null +++ b/Detectors/StrangenessTracking/workflow/src/HyperWorkflow.cxx @@ -0,0 +1,41 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// @file HyperWorkflow.cxx + +#include "HyperTrackingWorkflow/HyperWorkflow.h" +// #include "ITSWorkflow/RecoWorkflow.h" +// #include "ITSWorkflow/ClustererSpec.h" +// #include "ITSWorkflow/ClusterWriterSpec.h" +// #include "ITSWorkflow/IRFrameWriterSpec.h" +// #include "ITSWorkflow/TrackerSpec.h" +// #include "ITSWorkflow/CookedTrackerSpec.h" +// #include "ITSWorkflow/TrackWriterSpec.h" +// #include "ITSMFTWorkflow/EntropyEncoderSpec.h" +// #include "ITSMFTWorkflow/DigitReaderSpec.h" + +namespace o2 +{ +namespace strangeness +{ + +namespace hyper_workflow +{ + +framework::WorkflowSpec getWorkflow() +{ + framework::WorkflowSpec specs; + return specs; +} + +} // namespace reco_workflow +} // namespace its +} // namespace o2 \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx b/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx new file mode 100644 index 0000000000000..b122f18e0b916 --- /dev/null +++ b/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx @@ -0,0 +1,80 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "HyperTrackingWorkflow/HyperWorkflow.h" +#include "CommonUtils/ConfigurableParam.h" +// #include "ITStracking/TrackingConfigParam.h" +// #include "ITStracking/Configuration.h" +// #include "DetectorsRaw/HBFUtilsInitializer.h" +#include "Framework/CallbacksPolicy.h" +#include "Framework/ConfigContext.h" + +// #include "GPUO2Interface.h" +// #include "GPUReconstruction.h" +// #include "GPUChainITS.h" +#include + +using namespace o2::framework; + +void customize(std::vector& policies) +{ + // o2::raw::HBFUtilsInitializer::addNewTimeSliceCallback(policies); +} + +void customize(std::vector& workflowOptions) +{ + // option allowing to set parameters + std::vector options{ + // {"digits-from-upstream", o2::framework::VariantType::Bool, false, {"digits will be provided from upstream, skip digits reader"}}, + // {"clusters-from-upstream", o2::framework::VariantType::Bool, false, {"clusters will be provided from upstream, skip clusterizer"}}, + // {"disable-root-output", o2::framework::VariantType::Bool, false, {"do not write output root files"}}, + // {"disable-mc", o2::framework::VariantType::Bool, false, {"disable MC propagation even if available"}}, + // {"trackerCA", o2::framework::VariantType::Bool, false, {"use trackerCA (default: trackerCM)"}}, + // {"tracking-mode", o2::framework::VariantType::String, "sync", {"sync,async,cosmics"}}, + // {"entropy-encoding", o2::framework::VariantType::Bool, false, {"produce entropy encoded data"}}, + // {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings"}}, + // {"gpuDevice", o2::framework::VariantType::Int, 1, {"use gpu device: CPU=1,CUDA=2,HIP=3 (default: CPU)"}} + }; + + std::swap(workflowOptions, options); +} + +// ------------------------------------------------------------------ + +#include "Framework/runDataProcessing.h" +#include "Framework/Logger.h" + +WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) +{ + // Update the (declared) parameters if changed from the command line + // auto useMC = !configcontext.options().get("disable-mc"); + // auto useCAtracker = configcontext.options().get("trackerCA"); + // auto trmode = configcontext.options().get("tracking-mode"); + // auto gpuDevice = static_cast(configcontext.options().get("gpuDevice")); + // auto extDigits = configcontext.options().get("digits-from-upstream"); + // auto extClusters = configcontext.options().get("clusters-from-upstream"); + // auto disableRootOutput = configcontext.options().get("disable-root-output"); + // auto eencode = configcontext.options().get("entropy-encoding"); + + // std::transform(trmode.begin(), trmode.end(), trmode.begin(), [](unsigned char c) { return std::tolower(c); }); + + o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); + + auto wf = o2::strangeness::hyper_workflow::getWorkflow(); + + // configure dpl timer to inject correct firstTFOrbit: start from the 1st orbit of TF containing 1st sampled orbit + // o2::raw::HBFUtilsInitializer hbfIni(configcontext, wf); + + // write the configuration used for the reco workflow + o2::conf::ConfigurableParam::writeINI("o2itsrecoflow_configuration.ini"); + + return std::move(wf); +} From 34e6b41403bf67ea4df3463b7b719dacb2934486 Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi <43742195+fmazzasc@users.noreply.github.com> Date: Tue, 30 Nov 2021 12:09:16 +0100 Subject: [PATCH 02/36] First skeleton of hypertracker (#9) --- .../StrangenessTracking/hyperTracker.cxx | 191 +++++++++ Detectors/StrangenessTracking/hyperTracker.h | 80 ++++ .../StrangenessTracking/macro/matchV0s.C | 361 ++++++++++++++++++ 3 files changed, 632 insertions(+) create mode 100644 Detectors/StrangenessTracking/hyperTracker.cxx create mode 100644 Detectors/StrangenessTracking/hyperTracker.h create mode 100644 Detectors/StrangenessTracking/macro/matchV0s.C diff --git a/Detectors/StrangenessTracking/hyperTracker.cxx b/Detectors/StrangenessTracking/hyperTracker.cxx new file mode 100644 index 0000000000000..d64273bdd5bd0 --- /dev/null +++ b/Detectors/StrangenessTracking/hyperTracker.cxx @@ -0,0 +1,191 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "hyperTracker.h" +namespace o2 +{ + namespace tracking + { + + hyperTracker::hyperTracker(const TrackITS &motherTrack, const V0 &v0, const std::vector &motherClusters, o2::its::GeometryTGeo *gman, DCAFitter2 &mFitterV0) + : hyperTrack{motherTrack}, hyperClusters{motherClusters}, geomITS{gman}, mFitterV0{mFitterV0} + { + + auto posTrack = v0.getProng(0); + auto negTrack = v0.getProng(1); + auto alphaV0 = calcV0alpha(v0); + alphaV0 > 0 ? posTrack.setAbsCharge(2) : negTrack.setAbsCharge(2); + + auto isRecr = recreateV0(posTrack, negTrack, v0.getProngID(0), v0.getProngID(1)); + if (!isRecr) + { + LOG(INFO) << "V0 regeneration not successful, using default one"; + hypV0 = v0; + } + setNclusMatching(motherClusters.size()); + } + + hyperTracker::hyperTracker(const TrackITS &motherTrack, const V0 &v0, const std::vector &motherClusters, o2::its::GeometryTGeo *gman) + : hyperTrack{motherTrack}, hypV0{v0}, hyperClusters{motherClusters}, geomITS{gman} + { + setNclusMatching(motherClusters.size()); + } + + double hyperTracker::getMatchingChi2() + { + auto &outerClus = hyperClusters[0]; + float alpha = geomITS->getSensorRefAlpha(outerClus.getSensorID()), x = outerClus.getX(); + + auto p0 = hypV0.getProng(0); + auto p1 = hypV0.getProng(1); + + if (hypV0.rotate(alpha)) + { + if (hypV0.propagateTo(x, mBz)) + { + std::cout << "Pred chi2 outermost Cluster: " << hypV0.getPredictedChi2(outerClus) << std::endl; + std::cout << "Pred chi2 V0-ITStrack: " << hypV0.getPredictedChi2(hyperTrack.getParamOut()) << std::endl; + return hypV0.getPredictedChi2(hyperTrack.getParamOut()); + } + } + return -1; + } + + bool hyperTracker::process() + { + int isProcessed = 0; + bool tryDaughter = true; + + for (auto &clus : hyperClusters) + { + + if (updateV0topology(clus, tryDaughter) == 1) + { + tryDaughter = false; + isProcessed++; + LOG(INFO) << "Attach cluster to V0 for layer: " << geomITS->getLayer(clus.getSensorID()); + continue; + } + else if (updateV0topology(clus, tryDaughter) == 2) + { + recreateV0(hypV0.getProng(0), hypV0.getProng(1), hypV0.getProngID(0), hypV0.getProngID(1)); + isProcessed++; + LOG(INFO) << "Attach cluster to He3 for layer: " << geomITS->getLayer(clus.getSensorID()); + continue; + } + else + { + break; + } + } + return isProcessed >= nClusMatching; + } + + int hyperTracker::updateV0topology(const ITSCluster &clus, bool tryDaughter) + { + int isUpdated = 0; + + if (propagateToClus(clus, hypV0)) + { + if (hypV0.getPredictedChi2(clus) < mMaxChi2) + { + hypV0.update(clus); + isUpdated++; + } + } + + if (!isUpdated && tryDaughter) + { + auto alphaArm = calcV0alpha(hypV0); + auto &he3track = alphaArm > 0 ? hypV0.getProng(0) : hypV0.getProng(1); + + if (propagateToClus(clus, he3track)) + { + if (he3track.getPredictedChi2(clus) < mMaxChi2) + { + he3track.update(clus); + isUpdated += 2; + } + } + } + return isUpdated; + } + + bool hyperTracker::propagateToClus(const ITSCluster &clus, o2::track::TrackParCov &track) + { + float alpha = geomITS->getSensorRefAlpha(clus.getSensorID()), x = clus.getX(); + int layer{geomITS->getLayer(clus.getSensorID())}; + float thick = layer < 3 ? 0.005 : 0.01; + + if (track.rotate(alpha)) + { + if (track.propagateTo(x, mBz)) + { + constexpr float radl = 9.36f; // Radiation length of Si [cm] + constexpr float rho = 2.33f; // Density of Si [g/cm^3] + return track.correctForMaterial(thick, thick * rho * radl); + } + } + return false; + } + + bool hyperTracker::recreateV0(const o2::track::TrackParCov &posTrack, const o2::track::TrackParCov &negTrack, const int posID, const int negID) + { + + int cand = 0; //best V0 candidate + int nCand; + + try + { + nCand = mFitterV0.process(posTrack, negTrack); + } + catch (std::runtime_error &e) + { + return false; + } + if (!nCand) + return false; + + mFitterV0.propagateTracksToVertex(); + auto &propPos = mFitterV0.getTrack(0, 0); + auto &propNeg = mFitterV0.getTrack(1, 0); + + const auto &v0XYZ = mFitterV0.getPCACandidatePos(); + std::array pP, pN; + propPos.getPxPyPzGlo(pP); + propNeg.getPxPyPzGlo(pN); + std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; + + hypV0 = V0(v0XYZ, pV0, mFitterV0.calcPCACovMatrixFlat(cand), propPos, propNeg, posID, negID, o2::track::PID::HyperTriton); + hypV0.setAbsCharge(1); + + return true; + } + + double hyperTracker::calcV0alpha(const V0 &v0) + { + std::array fV0mom, fPmom, fNmom = {0, 0, 0}; + v0.getProng(0).getPxPyPzGlo(fPmom); + v0.getProng(1).getPxPyPzGlo(fNmom); + v0.getPxPyPzGlo(fV0mom); + + TVector3 momNeg(fNmom[0], fNmom[1], fNmom[2]); + TVector3 momPos(fPmom[0], fPmom[1], fPmom[2]); + TVector3 momTot(fV0mom[0], fV0mom[1], fV0mom[2]); + + Double_t lQlNeg = momNeg.Dot(momTot) / momTot.Mag(); + Double_t lQlPos = momPos.Dot(momTot) / momTot.Mag(); + + return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); + } + + } // namespace tracking +} // namespace o2 \ No newline at end of file diff --git a/Detectors/StrangenessTracking/hyperTracker.h b/Detectors/StrangenessTracking/hyperTracker.h new file mode 100644 index 0000000000000..73b31b7d23743 --- /dev/null +++ b/Detectors/StrangenessTracking/hyperTracker.h @@ -0,0 +1,80 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file hyperTracker.h +/// \brief hypertracker +/// \author francesco.mazzaschi@cern.ch +/// + +#ifndef _ALICEO2_HYPER_TRACKER_ +#define _ALICEO2_HYPER_TRACKER_ +#include "ReconstructionDataFormats/PID.h" +#include "ReconstructionDataFormats/V0.h" +#include "DataFormatsITS/TrackITS.h" +#include "ITSBase/GeometryTGeo.h" +#include "ReconstructionDataFormats/Track.h" +#include +#include "TMath.h" +#include "DetectorsVertexing/DCAFitterN.h" + +namespace o2 +{ + namespace tracking + { + + class hyperTracker + { + public: + using PID = o2::track::PID; + using TrackITS = o2::its::TrackITS; + using ITSCluster = o2::BaseCluster; + using V0 = o2::dataformats::V0; + using DCAFitter2 = o2::vertexing::DCAFitterN<2>; + + hyperTracker() = default; + hyperTracker(const TrackITS &motherTrack, const V0 &v0, const std::vector &motherClusters, o2::its::GeometryTGeo *gman, DCAFitter2 &mFitterV0); //recompute V0 using hypertriton hypothesis + hyperTracker(const TrackITS &motherTrack, const V0 &v0, const std::vector &motherClusters, o2::its::GeometryTGeo *gman); + + double getMatchingChi2(); + double calcV0alpha(const V0 &v0); + bool process(); + bool propagateToClus(const ITSCluster &clus, o2::track::TrackParCov &track); + int updateV0topology(const ITSCluster &clus, bool tryDaughter); + bool recreateV0(const o2::track::TrackParCov &posTrack, const o2::track::TrackParCov &negTrack, const int posID, const int negID); + V0 &getV0() { return hypV0; }; + + float getNclusMatching() const { return nClusMatching; } + void setNclusMatching(float d) { nClusMatching = d; } + + float getMaxChi2() const { return mMaxChi2; } + void setMaxChi2(float d) { mMaxChi2 = d; } + + float getBz() const { return mBz; } + void setBz(float d) { mBz = d; } + + protected: + TrackITS hyperTrack; // track of hypertriton mother + V0 hypV0; // V0 of decay daughters + std::vector hyperClusters; // clusters of hypertriton mother + o2::its::GeometryTGeo *geomITS; //geometry for ITS clusters + DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis + + int nClusMatching; // number of cluster to be matched to V0 + float mMaxChi2 = 40; + float mBz = -5; + + ClassDefNV(hyperTracker, 1); + }; + + } // namespace vertexing +} // namespace o2 + +#endif // _ALICEO2_HYPER_TRACKER_ diff --git a/Detectors/StrangenessTracking/macro/matchV0s.C b/Detectors/StrangenessTracking/macro/matchV0s.C new file mode 100644 index 0000000000000..4262fa41eeccc --- /dev/null +++ b/Detectors/StrangenessTracking/macro/matchV0s.C @@ -0,0 +1,361 @@ +#if !defined(CLING) || defined(ROOTCLING) +#include "CommonDataFormat/RangeReference.h" +#include "ReconstructionDataFormats/Cascade.h" +#include "ReconstructionDataFormats/PID.h" +#include "ReconstructionDataFormats/V0.h" +#include "SimulationDataFormat/MCCompLabel.h" +#include "SimulationDataFormat/MCTrack.h" + +#include "DataFormatsITSMFT/TopologyDictionary.h" +#include "DetectorsCommonDataFormats/NameConf.h" +#include "ITSBase/GeometryTGeo.h" +#include "DataFormatsITS/TrackITS.h" +#include "DataFormatsITSMFT/CompCluster.h" +#include "DataFormatsITSMFT/ROFRecord.h" +#include "ITStracking/IOUtils.h" + +#include +#include +#include "TCanvas.h" +#include "TFile.h" +#include "TH1F.h" +#include "TH2D.h" + +#include "TMath.h" +#include "TString.h" +#include "TTree.h" +#include "TLegend.h" +#include "CommonDataFormat/RangeReference.h" +#include "DetectorsVertexing/DCAFitterN.h" + +#include "hyperTracker.h" + +#endif + +using GIndex = o2::dataformats::VtxTrackIndex; +using V0 = o2::dataformats::V0; +using MCTrack = o2::MCTrack; +using Cascade = o2::dataformats::Cascade; +using RRef = o2::dataformats::RangeReference; +using VBracket = o2::math_utils::Bracket; +using namespace o2::itsmft; +using CompClusterExt = o2::itsmft::CompClusterExt; +using ITSCluster = o2::BaseCluster; +using Vec3 = ROOT::Math::SVector; +using hyperTracker = o2::tracking::hyperTracker; + +const int motherPDG = 1010010030; +const int firstDaughterPDG = 1000020030; +const int secondDaughterPDG = -211; + +std::vector> matchV0stoMC(const std::vector> &mcTracksMatrix, std::map *> &map, std::vector *v0vec); +std::array matchITStracktoMC(const std::vector> &mcTracksMatrix, o2::MCCompLabel ITSlabel); +std::vector getTrackClusters(const o2::its::TrackITS &ITStrack, const std::vector &ITSClustersArray, std::vector *ITSTrackClusIdx); + +void matchV0s() +{ + // Output Histograms + TH1D *hChi2Sgn = new TH1D("Chi2 Signal", "; #chi^{2}; Counts", 102, -2, 100); + TH1D *hChi2Bkg = new TH1D("Chi2 background", "; #chi^{2} (90 is default for overflows and not propagated); Counts", 102, -2, 100); + TH1D *hSigBkg = new TH1D("Hypertracker eff", "; ; Efficiency", 2, 0, 2); + TH2D *hPtResBef = new TH2D("pT resolution before hypertracking", "; #it{p}_{T}^{gen} (GeV); (#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, 0, 10, 20, -1, 1); + TH2D *hPtResAft = new TH2D("pT resolution before hypertracking", "; #it{p}_{T}^{gen} (GeV); (#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, 0, 10, 20, -1, 1); + + // Files + auto fMCTracks = TFile::Open("sgn_Kine.root"); + auto fSecondaries = TFile::Open("o2_secondary_vertex.root"); + auto fITSTPC = TFile::Open("o2match_itstpc.root"); + auto fTPCTOF = TFile::Open("o2match_tof_tpc.root"); + auto fITSTPCTOF = TFile::Open("o2match_tof_itstpc.root"); + + auto fITS = TFile::Open("o2trac_its.root"); + auto fITSclus = TFile::Open("o2clus_its.root"); + + // Geometry + o2::base::GeometryManager::loadGeometry(""); + + // Trees + auto treeMCTracks = (TTree *)fMCTracks->Get("o2sim"); + auto treeSecondaries = (TTree *)fSecondaries->Get("o2sim"); + auto treeITSTPC = (TTree *)fITSTPC->Get("matchTPCITS"); + auto treeITSTPCTOF = (TTree *)fITSTPCTOF->Get("matchTOF"); + auto treeTPCTOF = (TTree *)fTPCTOF->Get("matchTOF"); + + auto treeITS = (TTree *)fITS->Get("o2sim"); + auto treeITSclus = (TTree *)fITSclus->Get("o2sim"); + + // Topology dictionary + o2::itsmft::TopologyDictionary mdict; + mdict.readFromFile(o2::base::NameConf::getAlpideClusterDictionaryFileName(o2::detectors::DetID::ITS)); + + // Tracks + std::vector *MCtracks = nullptr; + std::vector *v0vec = nullptr; + std::vector *ITStracks = nullptr; + std::vector *ITSTrackClusIdx = nullptr; + + // Clusters + std::vector *ITSclus = nullptr; + std::vector *ITSpatt = nullptr; + + // Labels + std::vector *labITSvec = nullptr; + std::vector *labITSTPCvec = nullptr; + std::vector *labITSTPCTOFvec = nullptr; + std::vector *labTPCTOFvec = nullptr; + + // Setting branches + treeSecondaries->SetBranchAddress("V0s", &v0vec); + treeMCTracks->SetBranchAddress("MCTrack", &MCtracks); + treeITSTPC->SetBranchAddress("MatchMCTruth", &labITSTPCvec); + treeTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labTPCTOFvec); + treeITSTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labITSTPCTOFvec); + treeITS->SetBranchAddress("ITSTrackMCTruth", &labITSvec); + treeITS->SetBranchAddress("ITSTrack", &ITStracks); + treeITS->SetBranchAddress("ITSTrackClusIdx", &ITSTrackClusIdx); + + treeITSclus->SetBranchAddress("ITSClusterComp", &ITSclus); + treeITSclus->SetBranchAddress("ITSClusterPatt", &ITSpatt); + + // define detector map + std::map *> map{{"ITS", labITSvec}, {"ITS-TPC", labITSTPCvec}, {"TPC-TOF", labTPCTOFvec}, {"ITS-TPC-TOF", labITSTPCTOFvec}}; + + // load geometry + auto gman = o2::its::GeometryTGeo::Instance(); + gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G)); + + // fill MC matrix + std::vector> mcTracksMatrix; + auto nev = treeMCTracks->GetEntriesFast(); + mcTracksMatrix.resize(nev); + for (int n = 0; n < nev; n++) + { // loop over MC events + treeMCTracks->GetEvent(n); + + mcTracksMatrix[n].resize(MCtracks->size()); + for (unsigned int mcI{0}; mcI < MCtracks->size(); ++mcI) + { + mcTracksMatrix[n][mcI] = MCtracks->at(mcI); + } + } + + treeSecondaries->GetEntry(); + treeITS->GetEntry(); + treeITSclus->GetEntry(); + treeITSTPC->GetEntry(); + treeTPCTOF->GetEntry(); + treeITSTPCTOF->GetEntry(); + + std::vector> V0sMCref = matchV0stoMC(mcTracksMatrix, map, v0vec); + + // convert Comp Clusters into 3D point + std::vector mITSClustersArray; + mITSClustersArray.reserve((*ITSclus).size()); + gsl::span spanPatt{*ITSpatt}; + auto pattIt = spanPatt.begin(); + o2::its::ioutils::convertCompactClusters(*ITSclus, pattIt, mITSClustersArray, mdict); + + // preparing DCA Fitter + o2::vertexing::DCAFitterN<2> mFitterV0; + mFitterV0.setBz(-5); + + auto sig_counter = 0.; + auto bkg_counter = 0.; + + // Starting matching loop + for (int frame = 0; frame < treeITS->GetEntriesFast(); frame++) + { + if (!treeITS->GetEvent(frame) || !treeITS->GetEvent(frame)) + continue; + if (!treeITS->GetEvent(frame)) + { + continue; + } + + for (unsigned int iTrack{0}; iTrack < labITSvec->size(); ++iTrack) + { + auto lab = labITSvec->at(iTrack); + auto ITStrackMCref = matchITStracktoMC(mcTracksMatrix, lab); + auto ITStrack = ITStracks->at(iTrack); + + auto ITSclusters = getTrackClusters(ITStrack, mITSClustersArray, ITSTrackClusIdx); + + for (unsigned int iV0vec = 0; iV0vec < v0vec->size(); iV0vec++) + { + auto &v0MCref = V0sMCref[iV0vec]; + auto &v0 = (*v0vec)[iV0vec]; + + if (ITStrackMCref == v0MCref && ITStrackMCref[0] != -1) + { + + auto &mcTrack = mcTracksMatrix[v0MCref[0]][v0MCref[1]]; + sig_counter++; + auto hyperTrack = hyperTracker(ITStrack, v0, ITSclusters, gman, mFitterV0); + hyperTrack.setBz(-5.); + // hyperTrack.setNclusMatching(ITSclusters.size()); + hyperTrack.setMaxChi2(40); + auto chi2 = hyperTrack.getMatchingChi2(); + std::cout << "V0 orig Pt: " << v0.getPt() << ", V0 recr Pt: " << hyperTrack.getV0().getPt() << std::endl; + hPtResBef->Fill(mcTrack.GetPt(), (mcTrack.GetPt() - hyperTrack.getV0().getPt()) / mcTrack.GetPt()); + std::cout << "ITS track Pt: " << ITStrack.getPt() << std::endl; + std::cout << "Starting hyperTracking algorithm..." << std::endl; + auto isAcc = hyperTrack.process(); + + std::cout << "After processing hyperTracking algorithm..." << std::endl; + hPtResAft->Fill(mcTrack.GetPt(), (mcTrack.GetPt() - hyperTrack.getV0().getPt()) / mcTrack.GetPt()); + + std::cout << "Is accepted? : " << isAcc << std::endl; + + for (auto i{0}; i < 7; i++) + { + if (ITStrack.isFakeOnLayer(i) && ITStrack.hasHitOnLayer(i)) + std::cout << "Fake clusters on layer: " << i << std::endl; + } + + std::cout << "------------------------" << std::endl; + hChi2Sgn->Fill(chi2); + if (isAcc) + hSigBkg->Fill(0.5); + } + if (ITStrackMCref != v0MCref) + { + if (bkg_counter > 20000) + continue; + bkg_counter++; + + auto hyperTrack = hyperTracker(ITStrack, v0, ITSclusters, gman, mFitterV0); + hyperTrack.setBz(-5.); + // hyperTrack.setNclusMatching(ITSclusters.size()); + hyperTrack.setMaxChi2(40); + + auto chi2 = hyperTrack.getMatchingChi2(); + if (chi2 > 90 || chi2 == -1) + chi2 = 90; + auto isAcc = hyperTrack.process(); + hChi2Bkg->Fill(chi2); + if (isAcc) + hSigBkg->Fill(1.5); + } + } + } + } + auto outFile = TFile("v0sITSmatch.root", "recreate"); + // efficiency histo + hSigBkg->SetBinContent(1, hSigBkg->GetBinContent(1) / sig_counter); + hSigBkg->SetBinContent(2, hSigBkg->GetBinContent(2) / bkg_counter); + hSigBkg->GetXaxis()->SetBinLabel(1, "Signal"); + hSigBkg->GetXaxis()->SetBinLabel(2, "Background"); + hSigBkg->Write(); + hPtResAft->Write(); + hPtResBef->Write(); + + // chi2 histos + auto *c = new TCanvas("c1", "chi2", 1000, 400); + hChi2Bkg->SetStats(0); + hChi2Sgn->SetLineColor(kRed); + hChi2Sgn->SetLineWidth(2); + hChi2Bkg->SetLineColor(kBlue); + hChi2Bkg->SetLineWidth(2); + c->cd(); + hChi2Bkg->DrawNormalized(); + hChi2Sgn->DrawNormalized("same"); + auto legend = new TLegend(0.55, 0.2, 0.85, 0.4); + legend->SetMargin(0.10); + legend->SetTextSize(0.03); + + legend->AddEntry(hChi2Sgn, "V0-ITStrack #chi^{2} for signal"); + legend->AddEntry(hChi2Bkg, "V0-ITStrack #chi^{2} for background"); + legend->Draw(); + c->Write(); + hChi2Sgn->Write(); + hChi2Bkg->Write(); + outFile.Close(); +} + +std::vector> matchV0stoMC(const std::vector> &mcTracksMatrix, std::map *> &map, std::vector *v0vec) +{ + std::vector> outArray; + outArray.resize(v0vec->size()); + int count_V0 = 0; + for (unsigned int iV0vec = 0; iV0vec < v0vec->size(); iV0vec++) + { + std::vector motherIDvec; + std::vector daughterIDvec; + std::vector evIDvec; + + outArray[iV0vec] = {-1, -1}; + auto &v0 = (*v0vec)[iV0vec]; + + for (unsigned int iV0 = 0; iV0 < 2; iV0++) + { + if (map[v0.getProngID(iV0).getSourceName()]) + { + auto labTrackType = map[v0.getProngID(iV0).getSourceName()]; + auto lab = labTrackType->at(v0.getProngID(iV0).getIndex()); + + int trackID, evID, srcID; + bool fake; + lab.get(trackID, evID, srcID, fake); + if (!lab.isNoise() && lab.isValid() && lab.isCorrect() && srcID) + { + auto motherID = mcTracksMatrix[evID][trackID].getMotherTrackId(); + motherIDvec.push_back(motherID); + daughterIDvec.push_back(trackID); + evIDvec.push_back(evID); + } + } + } + + if (motherIDvec.size() < 2) + continue; + if (motherIDvec[0] != motherIDvec[1] || evIDvec[0] != evIDvec[1]) + continue; + + if (motherIDvec[0] <= 0 || motherIDvec[0] > 10000) + continue; + + int pdg0 = mcTracksMatrix[evIDvec[0]][daughterIDvec[0]].GetPdgCode(); + int pdg1 = mcTracksMatrix[evIDvec[0]][daughterIDvec[1]].GetPdgCode(); + + if (pdg0 != firstDaughterPDG && pdg0 != secondDaughterPDG) + continue; + if (pdg1 != firstDaughterPDG && pdg1 != secondDaughterPDG) + continue; + + // std::cout << "Mother PDG: " << mcTracksMatrix[evIDvec[0]][motherIDvec[0]].GetPt() << std::endl; + outArray[iV0vec] = {evIDvec[0], motherIDvec[0]}; + count_V0++; + } + std::cout << "Number of V0s: " << count_V0 << std::endl; + return outArray; +} + +std::array matchITStracktoMC(const std::vector> &mcTracksMatrix, o2::MCCompLabel ITSlabel) + +{ + std::array outArray = {-1, -1}; + int trackID, evID, srcID; + bool fake; + ITSlabel.get(trackID, evID, srcID, fake); + if (!ITSlabel.isNoise() && ITSlabel.isValid() && srcID && mcTracksMatrix[evID][trackID].GetPdgCode() == motherPDG) + { + outArray = {evID, trackID}; + // std::cout << "ITS EvID, track Id : " << evID << " " << trackID << std::endl; + // std::cout << "ITS Mother Pt: " << mcTracksMatrix[evID][trackID].GetPt() << std::endl; + } + + return outArray; +} + +std::vector getTrackClusters(const o2::its::TrackITS &ITStrack, const std::vector &ITSClustersArray, std::vector *ITSTrackClusIdx) +{ + + std::vector outVec; + auto firstClus = ITStrack.getFirstClusterEntry(); + auto ncl = ITStrack.getNumberOfClusters(); + for (int icl = 0; icl < ncl; icl++) + { + outVec.push_back(ITSClustersArray[(*ITSTrackClusIdx)[firstClus + icl]]); + } + return outVec; +} \ No newline at end of file From 8781cc64b41bf152aee92c5c1e03a3850891e785 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Tue, 30 Nov 2021 14:07:26 +0100 Subject: [PATCH 03/36] Improve hypertracking workflow --- Detectors/StrangenessTracking/CMakeLists.txt | 2 +- .../StrangenessTracking/hyperTracker.cxx | 191 ---------- Detectors/StrangenessTracking/hyperTracker.h | 80 ---- .../strangeness/CMakeLists.txt | 4 +- .../include/Strangeness/HyperTracker.h | 78 ++++ .../strangeness/src/HyperTracker.cxx | 172 +++++++++ .../strangeness/src/StrangenessTracking.cxx | 10 - .../workflow/CMakeLists.txt | 2 +- .../HyperTrackingWorkflow/HypertrackerSpecs.h | 0 ...yperWorkflow.h => HypertrackingWorkflow.h} | 6 +- .../workflow/src/HypertrackerSpecs.cxx | 348 ++++++++++++++++++ ...Workflow.cxx => HypertrackingWorkflow.cxx} | 11 +- 12 files changed, 606 insertions(+), 298 deletions(-) delete mode 100644 Detectors/StrangenessTracking/hyperTracker.cxx delete mode 100644 Detectors/StrangenessTracking/hyperTracker.h create mode 100644 Detectors/StrangenessTracking/strangeness/include/Strangeness/HyperTracker.h create mode 100644 Detectors/StrangenessTracking/strangeness/src/HyperTracker.cxx delete mode 100644 Detectors/StrangenessTracking/strangeness/src/StrangenessTracking.cxx create mode 100644 Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HypertrackerSpecs.h rename Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/{HyperWorkflow.h => HypertrackingWorkflow.h} (86%) create mode 100644 Detectors/StrangenessTracking/workflow/src/HypertrackerSpecs.cxx rename Detectors/StrangenessTracking/workflow/src/{HyperWorkflow.cxx => HypertrackingWorkflow.cxx} (64%) diff --git a/Detectors/StrangenessTracking/CMakeLists.txt b/Detectors/StrangenessTracking/CMakeLists.txt index d3626dc45561c..7c8e1ea7445b7 100644 --- a/Detectors/StrangenessTracking/CMakeLists.txt +++ b/Detectors/StrangenessTracking/CMakeLists.txt @@ -10,4 +10,4 @@ # or submit itself to any jurisdiction. add_subdirectory(workflow) -# add_subdirectory(strangeness) \ No newline at end of file +add_subdirectory(strangeness) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/hyperTracker.cxx b/Detectors/StrangenessTracking/hyperTracker.cxx deleted file mode 100644 index d64273bdd5bd0..0000000000000 --- a/Detectors/StrangenessTracking/hyperTracker.cxx +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include "hyperTracker.h" -namespace o2 -{ - namespace tracking - { - - hyperTracker::hyperTracker(const TrackITS &motherTrack, const V0 &v0, const std::vector &motherClusters, o2::its::GeometryTGeo *gman, DCAFitter2 &mFitterV0) - : hyperTrack{motherTrack}, hyperClusters{motherClusters}, geomITS{gman}, mFitterV0{mFitterV0} - { - - auto posTrack = v0.getProng(0); - auto negTrack = v0.getProng(1); - auto alphaV0 = calcV0alpha(v0); - alphaV0 > 0 ? posTrack.setAbsCharge(2) : negTrack.setAbsCharge(2); - - auto isRecr = recreateV0(posTrack, negTrack, v0.getProngID(0), v0.getProngID(1)); - if (!isRecr) - { - LOG(INFO) << "V0 regeneration not successful, using default one"; - hypV0 = v0; - } - setNclusMatching(motherClusters.size()); - } - - hyperTracker::hyperTracker(const TrackITS &motherTrack, const V0 &v0, const std::vector &motherClusters, o2::its::GeometryTGeo *gman) - : hyperTrack{motherTrack}, hypV0{v0}, hyperClusters{motherClusters}, geomITS{gman} - { - setNclusMatching(motherClusters.size()); - } - - double hyperTracker::getMatchingChi2() - { - auto &outerClus = hyperClusters[0]; - float alpha = geomITS->getSensorRefAlpha(outerClus.getSensorID()), x = outerClus.getX(); - - auto p0 = hypV0.getProng(0); - auto p1 = hypV0.getProng(1); - - if (hypV0.rotate(alpha)) - { - if (hypV0.propagateTo(x, mBz)) - { - std::cout << "Pred chi2 outermost Cluster: " << hypV0.getPredictedChi2(outerClus) << std::endl; - std::cout << "Pred chi2 V0-ITStrack: " << hypV0.getPredictedChi2(hyperTrack.getParamOut()) << std::endl; - return hypV0.getPredictedChi2(hyperTrack.getParamOut()); - } - } - return -1; - } - - bool hyperTracker::process() - { - int isProcessed = 0; - bool tryDaughter = true; - - for (auto &clus : hyperClusters) - { - - if (updateV0topology(clus, tryDaughter) == 1) - { - tryDaughter = false; - isProcessed++; - LOG(INFO) << "Attach cluster to V0 for layer: " << geomITS->getLayer(clus.getSensorID()); - continue; - } - else if (updateV0topology(clus, tryDaughter) == 2) - { - recreateV0(hypV0.getProng(0), hypV0.getProng(1), hypV0.getProngID(0), hypV0.getProngID(1)); - isProcessed++; - LOG(INFO) << "Attach cluster to He3 for layer: " << geomITS->getLayer(clus.getSensorID()); - continue; - } - else - { - break; - } - } - return isProcessed >= nClusMatching; - } - - int hyperTracker::updateV0topology(const ITSCluster &clus, bool tryDaughter) - { - int isUpdated = 0; - - if (propagateToClus(clus, hypV0)) - { - if (hypV0.getPredictedChi2(clus) < mMaxChi2) - { - hypV0.update(clus); - isUpdated++; - } - } - - if (!isUpdated && tryDaughter) - { - auto alphaArm = calcV0alpha(hypV0); - auto &he3track = alphaArm > 0 ? hypV0.getProng(0) : hypV0.getProng(1); - - if (propagateToClus(clus, he3track)) - { - if (he3track.getPredictedChi2(clus) < mMaxChi2) - { - he3track.update(clus); - isUpdated += 2; - } - } - } - return isUpdated; - } - - bool hyperTracker::propagateToClus(const ITSCluster &clus, o2::track::TrackParCov &track) - { - float alpha = geomITS->getSensorRefAlpha(clus.getSensorID()), x = clus.getX(); - int layer{geomITS->getLayer(clus.getSensorID())}; - float thick = layer < 3 ? 0.005 : 0.01; - - if (track.rotate(alpha)) - { - if (track.propagateTo(x, mBz)) - { - constexpr float radl = 9.36f; // Radiation length of Si [cm] - constexpr float rho = 2.33f; // Density of Si [g/cm^3] - return track.correctForMaterial(thick, thick * rho * radl); - } - } - return false; - } - - bool hyperTracker::recreateV0(const o2::track::TrackParCov &posTrack, const o2::track::TrackParCov &negTrack, const int posID, const int negID) - { - - int cand = 0; //best V0 candidate - int nCand; - - try - { - nCand = mFitterV0.process(posTrack, negTrack); - } - catch (std::runtime_error &e) - { - return false; - } - if (!nCand) - return false; - - mFitterV0.propagateTracksToVertex(); - auto &propPos = mFitterV0.getTrack(0, 0); - auto &propNeg = mFitterV0.getTrack(1, 0); - - const auto &v0XYZ = mFitterV0.getPCACandidatePos(); - std::array pP, pN; - propPos.getPxPyPzGlo(pP); - propNeg.getPxPyPzGlo(pN); - std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; - - hypV0 = V0(v0XYZ, pV0, mFitterV0.calcPCACovMatrixFlat(cand), propPos, propNeg, posID, negID, o2::track::PID::HyperTriton); - hypV0.setAbsCharge(1); - - return true; - } - - double hyperTracker::calcV0alpha(const V0 &v0) - { - std::array fV0mom, fPmom, fNmom = {0, 0, 0}; - v0.getProng(0).getPxPyPzGlo(fPmom); - v0.getProng(1).getPxPyPzGlo(fNmom); - v0.getPxPyPzGlo(fV0mom); - - TVector3 momNeg(fNmom[0], fNmom[1], fNmom[2]); - TVector3 momPos(fPmom[0], fPmom[1], fPmom[2]); - TVector3 momTot(fV0mom[0], fV0mom[1], fV0mom[2]); - - Double_t lQlNeg = momNeg.Dot(momTot) / momTot.Mag(); - Double_t lQlPos = momPos.Dot(momTot) / momTot.Mag(); - - return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); - } - - } // namespace tracking -} // namespace o2 \ No newline at end of file diff --git a/Detectors/StrangenessTracking/hyperTracker.h b/Detectors/StrangenessTracking/hyperTracker.h deleted file mode 100644 index 73b31b7d23743..0000000000000 --- a/Detectors/StrangenessTracking/hyperTracker.h +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file hyperTracker.h -/// \brief hypertracker -/// \author francesco.mazzaschi@cern.ch -/// - -#ifndef _ALICEO2_HYPER_TRACKER_ -#define _ALICEO2_HYPER_TRACKER_ -#include "ReconstructionDataFormats/PID.h" -#include "ReconstructionDataFormats/V0.h" -#include "DataFormatsITS/TrackITS.h" -#include "ITSBase/GeometryTGeo.h" -#include "ReconstructionDataFormats/Track.h" -#include -#include "TMath.h" -#include "DetectorsVertexing/DCAFitterN.h" - -namespace o2 -{ - namespace tracking - { - - class hyperTracker - { - public: - using PID = o2::track::PID; - using TrackITS = o2::its::TrackITS; - using ITSCluster = o2::BaseCluster; - using V0 = o2::dataformats::V0; - using DCAFitter2 = o2::vertexing::DCAFitterN<2>; - - hyperTracker() = default; - hyperTracker(const TrackITS &motherTrack, const V0 &v0, const std::vector &motherClusters, o2::its::GeometryTGeo *gman, DCAFitter2 &mFitterV0); //recompute V0 using hypertriton hypothesis - hyperTracker(const TrackITS &motherTrack, const V0 &v0, const std::vector &motherClusters, o2::its::GeometryTGeo *gman); - - double getMatchingChi2(); - double calcV0alpha(const V0 &v0); - bool process(); - bool propagateToClus(const ITSCluster &clus, o2::track::TrackParCov &track); - int updateV0topology(const ITSCluster &clus, bool tryDaughter); - bool recreateV0(const o2::track::TrackParCov &posTrack, const o2::track::TrackParCov &negTrack, const int posID, const int negID); - V0 &getV0() { return hypV0; }; - - float getNclusMatching() const { return nClusMatching; } - void setNclusMatching(float d) { nClusMatching = d; } - - float getMaxChi2() const { return mMaxChi2; } - void setMaxChi2(float d) { mMaxChi2 = d; } - - float getBz() const { return mBz; } - void setBz(float d) { mBz = d; } - - protected: - TrackITS hyperTrack; // track of hypertriton mother - V0 hypV0; // V0 of decay daughters - std::vector hyperClusters; // clusters of hypertriton mother - o2::its::GeometryTGeo *geomITS; //geometry for ITS clusters - DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis - - int nClusMatching; // number of cluster to be matched to V0 - float mMaxChi2 = 40; - float mBz = -5; - - ClassDefNV(hyperTracker, 1); - }; - - } // namespace vertexing -} // namespace o2 - -#endif // _ALICEO2_HYPER_TRACKER_ diff --git a/Detectors/StrangenessTracking/strangeness/CMakeLists.txt b/Detectors/StrangenessTracking/strangeness/CMakeLists.txt index 99d670b02b1d0..6237e9167bbfd 100644 --- a/Detectors/StrangenessTracking/strangeness/CMakeLists.txt +++ b/Detectors/StrangenessTracking/strangeness/CMakeLists.txt @@ -9,5 +9,5 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -o2_add_library(StrangenessTracking - SOURCES src/StrangenessTracking.cxx) \ No newline at end of file +o2_add_library(HyperTracking + SOURCES src/HyperTracker.cxx) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/strangeness/include/Strangeness/HyperTracker.h b/Detectors/StrangenessTracking/strangeness/include/Strangeness/HyperTracker.h new file mode 100644 index 0000000000000..96d74a1280899 --- /dev/null +++ b/Detectors/StrangenessTracking/strangeness/include/Strangeness/HyperTracker.h @@ -0,0 +1,78 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file HyperTracker.h +/// \brief hypertracker +/// \author francesco.mazzaschi@cern.ch + +#ifndef _ALICEO2_HYPER_TRACKER_ +#define _ALICEO2_HYPER_TRACKER_ +#include "ReconstructionDataFormats/PID.h" +#include "ReconstructionDataFormats/V0.h" +#include "DataFormatsITS/TrackITS.h" +#include "ITSBase/GeometryTGeo.h" +#include "ReconstructionDataFormats/Track.h" +#include "DetectorsVertexing/DCAFitterN.h" + +#include +#include "TMath.h" + +namespace o2 +{ +namespace tracking +{ + +class HyperTracker +{ + public: + using PID = o2::track::PID; + using TrackITS = o2::its::TrackITS; + using ITSCluster = o2::BaseCluster; + using V0 = o2::dataformats::V0; + using DCAFitter2 = o2::vertexing::DCAFitterN<2>; + + HyperTracker() = default; + HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0); //recompute V0 using hypertriton hypothesis + HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman); + + double getMatchingChi2(); + double calcV0alpha(const V0& v0); + bool process(); + bool propagateToClus(const ITSCluster& clus, o2::track::TrackParCov& track); + int updateV0topology(const ITSCluster& clus, bool tryDaughter); + bool recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID); + V0& getV0() { return hypV0; }; + + float getNclusMatching() const { return nClusMatching; } + void setNclusMatching(float d) { nClusMatching = d; } + + float getMaxChi2() const { return mMaxChi2; } + void setMaxChi2(float d) { mMaxChi2 = d; } + + float getBz() const { return mBz; } + void setBz(float d) { mBz = d; } + + protected: + TrackITS hyperTrack; // track of hypertriton mother + V0 hypV0; // V0 of decay daughters + std::vector hyperClusters; // clusters of hypertriton mother + o2::its::GeometryTGeo* geomITS; //geometry for ITS clusters + DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis + + int nClusMatching; // number of cluster to be matched to V0 + float mMaxChi2 = 40; + float mBz = -5; +}; + +} // namespace tracking +} // namespace o2 + +#endif // _ALICEO2_HYPER_TRACKER_ diff --git a/Detectors/StrangenessTracking/strangeness/src/HyperTracker.cxx b/Detectors/StrangenessTracking/strangeness/src/HyperTracker.cxx new file mode 100644 index 0000000000000..2141a474759ea --- /dev/null +++ b/Detectors/StrangenessTracking/strangeness/src/HyperTracker.cxx @@ -0,0 +1,172 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "Strangeness/HyperTracker.h" +namespace o2 +{ +namespace tracking +{ + +HyperTracker::HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0) + : hyperTrack{motherTrack}, hyperClusters{motherClusters}, geomITS{gman}, mFitterV0{mFitterV0} +{ + + auto posTrack = v0.getProng(0); + auto negTrack = v0.getProng(1); + auto alphaV0 = calcV0alpha(v0); + alphaV0 > 0 ? posTrack.setAbsCharge(2) : negTrack.setAbsCharge(2); + + auto isRecr = recreateV0(posTrack, negTrack, v0.getProngID(0), v0.getProngID(1)); + if (!isRecr) { + LOG(INFO) << "V0 regeneration not successful, using default one"; + hypV0 = v0; + } + setNclusMatching(motherClusters.size()); +} + +HyperTracker::HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman) + : hyperTrack{motherTrack}, hypV0{v0}, hyperClusters{motherClusters}, geomITS{gman} +{ + setNclusMatching(motherClusters.size()); +} + +double HyperTracker::getMatchingChi2() +{ + auto& outerClus = hyperClusters[0]; + float alpha = geomITS->getSensorRefAlpha(outerClus.getSensorID()), x = outerClus.getX(); + + auto p0 = hypV0.getProng(0); + auto p1 = hypV0.getProng(1); + + if (hypV0.rotate(alpha)) { + if (hypV0.propagateTo(x, mBz)) { + std::cout << "Pred chi2 outermost Cluster: " << hypV0.getPredictedChi2(outerClus) << std::endl; + std::cout << "Pred chi2 V0-ITStrack: " << hypV0.getPredictedChi2(hyperTrack.getParamOut()) << std::endl; + return hypV0.getPredictedChi2(hyperTrack.getParamOut()); + } + } + return -1; +} + +bool HyperTracker::process() +{ + int isProcessed = 0; + bool tryDaughter = true; + + for (auto& clus : hyperClusters) { + + if (updateV0topology(clus, tryDaughter) == 1) { + tryDaughter = false; + isProcessed++; + LOG(INFO) << "Attach cluster to V0 for layer: " << geomITS->getLayer(clus.getSensorID()); + continue; + } else if (updateV0topology(clus, tryDaughter) == 2) { + recreateV0(hypV0.getProng(0), hypV0.getProng(1), hypV0.getProngID(0), hypV0.getProngID(1)); + isProcessed++; + LOG(INFO) << "Attach cluster to He3 for layer: " << geomITS->getLayer(clus.getSensorID()); + continue; + } else { + break; + } + } + return isProcessed >= nClusMatching; +} + +int HyperTracker::updateV0topology(const ITSCluster& clus, bool tryDaughter) +{ + int isUpdated = 0; + + if (propagateToClus(clus, hypV0)) { + if (hypV0.getPredictedChi2(clus) < mMaxChi2) { + hypV0.update(clus); + isUpdated++; + } + } + + if (!isUpdated && tryDaughter) { + auto alphaArm = calcV0alpha(hypV0); + auto& he3track = alphaArm > 0 ? hypV0.getProng(0) : hypV0.getProng(1); + + if (propagateToClus(clus, he3track)) { + if (he3track.getPredictedChi2(clus) < mMaxChi2) { + he3track.update(clus); + isUpdated += 2; + } + } + } + return isUpdated; +} + +bool HyperTracker::propagateToClus(const ITSCluster& clus, o2::track::TrackParCov& track) +{ + float alpha = geomITS->getSensorRefAlpha(clus.getSensorID()), x = clus.getX(); + int layer{geomITS->getLayer(clus.getSensorID())}; + float thick = layer < 3 ? 0.005 : 0.01; + + if (track.rotate(alpha)) { + if (track.propagateTo(x, mBz)) { + constexpr float radl = 9.36f; // Radiation length of Si [cm] + constexpr float rho = 2.33f; // Density of Si [g/cm^3] + return track.correctForMaterial(thick, thick * rho * radl); + } + } + return false; +} + +bool HyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID) +{ + + int cand = 0; //best V0 candidate + int nCand; + + try { + nCand = mFitterV0.process(posTrack, negTrack); + } catch (std::runtime_error& e) { + return false; + } + if (!nCand) + return false; + + mFitterV0.propagateTracksToVertex(); + auto& propPos = mFitterV0.getTrack(0, 0); + auto& propNeg = mFitterV0.getTrack(1, 0); + + const auto& v0XYZ = mFitterV0.getPCACandidatePos(); + std::array pP, pN; + propPos.getPxPyPzGlo(pP); + propNeg.getPxPyPzGlo(pN); + std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; + + hypV0 = V0(v0XYZ, pV0, mFitterV0.calcPCACovMatrixFlat(cand), propPos, propNeg, posID, negID, o2::track::PID::HyperTriton); + hypV0.setAbsCharge(1); + + return true; +} + +double HyperTracker::calcV0alpha(const V0& v0) +{ + std::array fV0mom, fPmom, fNmom = {0, 0, 0}; + v0.getProng(0).getPxPyPzGlo(fPmom); + v0.getProng(1).getPxPyPzGlo(fNmom); + v0.getPxPyPzGlo(fV0mom); + + TVector3 momNeg(fNmom[0], fNmom[1], fNmom[2]); + TVector3 momPos(fPmom[0], fPmom[1], fPmom[2]); + TVector3 momTot(fV0mom[0], fV0mom[1], fV0mom[2]); + + Double_t lQlNeg = momNeg.Dot(momTot) / momTot.Mag(); + Double_t lQlPos = momPos.Dot(momTot) / momTot.Mag(); + + return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); +} + +} // namespace tracking +} // namespace o2 \ No newline at end of file diff --git a/Detectors/StrangenessTracking/strangeness/src/StrangenessTracking.cxx b/Detectors/StrangenessTracking/strangeness/src/StrangenessTracking.cxx deleted file mode 100644 index e6fc06b52b845..0000000000000 --- a/Detectors/StrangenessTracking/strangeness/src/StrangenessTracking.cxx +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/CMakeLists.txt b/Detectors/StrangenessTracking/workflow/CMakeLists.txt index 74f5192af7fb9..90e8df2e32085 100644 --- a/Detectors/StrangenessTracking/workflow/CMakeLists.txt +++ b/Detectors/StrangenessTracking/workflow/CMakeLists.txt @@ -10,7 +10,7 @@ # or submit itself to any jurisdiction. o2_add_library(HyperWorkflow - SOURCES src/HyperWorkflow.cxx + SOURCES src/HypertrackingWorkflow.cxx PUBLIC_LINK_LIBRARIES O2::Framework) o2_add_executable(hypertracking-workflow diff --git a/Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HypertrackerSpecs.h b/Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HypertrackerSpecs.h new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HyperWorkflow.h b/Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HypertrackingWorkflow.h similarity index 86% rename from Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HyperWorkflow.h rename to Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HypertrackingWorkflow.h index aae68ac28209d..a75361f660e0d 100644 --- a/Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HyperWorkflow.h +++ b/Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HypertrackingWorkflow.h @@ -10,8 +10,8 @@ // or submit itself to any jurisdiction. /// @file HyperWorkflow.h -#ifndef O2_STRANGENESS_HYPERWORKFLOW_H -#define O2_STRANGENESS_HYPERWORKFLOW_H +#ifndef O2_STRANGENESS_HYPERTRACKING_WORKFLOW_H +#define O2_STRANGENESS_HYPERTRACKING_WORKFLOW_H #include "Framework/WorkflowSpec.h" namespace o2 @@ -26,4 +26,4 @@ framework::WorkflowSpec getWorkflow(); } } // namespace strangeness } // namespace o2 -#endif // O2_STRANGENESS_HYPERWORKFLOW_H \ No newline at end of file +#endif \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackerSpecs.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackerSpecs.cxx new file mode 100644 index 0000000000000..2a01cecd1013c --- /dev/null +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackerSpecs.cxx @@ -0,0 +1,348 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#include + +namespace o2 +{ +using namespace framework; +namespace its +{ +using Vertex = o2::dataformats::Vertex>; + +TrackerDPL::TrackerDPL(bool isMC, const std::string& trModeS, o2::gpu::GPUDataTypes::DeviceType dType) : mIsMC{isMC}, mMode{trModeS}, mRecChain{o2::gpu::GPUReconstruction::CreateInstance(dType, true)} +{ + std::transform(mMode.begin(), mMode.end(), mMode.begin(), [](unsigned char c) { return std::tolower(c); }); +} + +void TrackerDPL::init(InitContext& ic) +{ + mTimer.Stop(); + mTimer.Reset(); + + auto* chainITS = mRecChain->AddChain(); + mVertexer = std::make_unique(chainITS->GetITSVertexerTraits()); + mTracker = std::make_unique(new TrackerTraitsCPU); + + auto filename = ic.options().get("grp-file"); + const auto grp = parameters::GRPObject::loadFrom(filename); + if (grp) { + mGRP.reset(grp); + base::Propagator::initFieldFromGRP(grp); + auto field = static_cast(TGeoGlobalMagField::Instance()->GetField()); + + base::GeometryManager::loadGeometry(); + GeometryTGeo* geom = GeometryTGeo::Instance(); + geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, + o2::math_utils::TransformType::T2G)); + + std::string matLUTPath = ic.options().get("material-lut-path"); + std::string matLUTFile = o2::base::NameConf::getMatLUTFileName(matLUTPath); + if (o2::utils::Str::pathExists(matLUTFile)) { + auto* lut = o2::base::MatLayerCylSet::loadFromFile(matLUTFile); + o2::base::Propagator::Instance()->setMatLUT(lut); + mTracker->setCorrType(o2::base::PropagatorImpl::MatCorrType::USEMatCorrLUT); + LOG(info) << "Loaded material LUT from " << matLUTFile; + } else { + LOG(info) << "Material LUT " << matLUTFile << " file is absent, only heuristic material correction can be used"; + } + + std::vector trackParams; + std::vector memParams; + + mRunVertexer = true; + if (mMode == "async") { + + trackParams.resize(2); + trackParams[1].TrackletMinPt = 0.2f; + trackParams[1].CellDeltaTanLambdaSigma *= 2.; + trackParams[1].MinTrackLength = 4; + memParams.resize(2); + LOG(info) << "Initializing tracker in async. phase reconstruction with " << trackParams.size() << " passes"; + + } else if (mMode == "sync_misaligned") { + + trackParams.resize(1); + trackParams[0].PhiBins = 32; + trackParams[0].ZBins = 64; + trackParams[0].CellDeltaTanLambdaSigma *= 10; + trackParams[0].LayerMisalignment[0] = 3.e-2; + trackParams[0].LayerMisalignment[1] = 3.e-2; + trackParams[0].LayerMisalignment[2] = 3.e-2; + trackParams[0].LayerMisalignment[3] = 1.e-1; + trackParams[0].LayerMisalignment[4] = 1.e-1; + trackParams[0].LayerMisalignment[5] = 1.e-1; + trackParams[0].LayerMisalignment[6] = 1.e-1; + trackParams[0].FitIterationMaxChi2[0] = 100.; + trackParams[0].FitIterationMaxChi2[1] = 50.; + trackParams[0].MinTrackLength = 4; + memParams.resize(1); + LOG(info) << "Initializing tracker in misaligned sync. phase reconstruction with " << trackParams.size() << " passes"; + + } else if (mMode == "sync") { + memParams.resize(1); + trackParams.resize(1); + LOG(info) << "Initializing tracker in sync. phase reconstruction with " << trackParams.size() << " passes"; + } else if (mMode == "cosmics") { + mRunVertexer = false; + trackParams.resize(1); + memParams.resize(1); + trackParams[0].MinTrackLength = 4; + trackParams[0].CellDeltaTanLambdaSigma *= 10; + trackParams[0].PhiBins = 4; + trackParams[0].ZBins = 16; + trackParams[0].PVres = 1.e5f; + trackParams[0].LayerMisalignment[0] = 3.e-2; + trackParams[0].LayerMisalignment[1] = 3.e-2; + trackParams[0].LayerMisalignment[2] = 3.e-2; + trackParams[0].LayerMisalignment[3] = 1.e-1; + trackParams[0].LayerMisalignment[4] = 1.e-1; + trackParams[0].LayerMisalignment[5] = 1.e-1; + trackParams[0].LayerMisalignment[6] = 1.e-1; + trackParams[0].FitIterationMaxChi2[0] = 100.; + trackParams[0].FitIterationMaxChi2[1] = 50.; + LOG(info) << "Initializing tracker in reconstruction for cosmics with " << trackParams.size() << " passes"; + + } else { + throw std::runtime_error(fmt::format("Unsupported ITS tracking mode {:s} ", mMode)); + } + mTracker->setParameters(memParams, trackParams); + + mVertexer->getGlobalConfiguration(); + mTracker->getGlobalConfiguration(); + LOG(info) << Form("Using %s for material budget approximation", (mTracker->isMatLUT() ? "lookup table" : "TGeometry")); + + double origD[3] = {0., 0., 0.}; + mBz = field->getBz(origD); + } else { + throw std::runtime_error(o2::utils::Str::concat_string("Cannot retrieve GRP from the ", filename)); + } + + std::string dictPath = o2::itsmft::ClustererParam::Instance().dictFilePath; + std::string dictFile = o2::base::NameConf::getAlpideClusterDictionaryFileName(o2::detectors::DetID::ITS, dictPath); + if (o2::utils::Str::pathExists(dictFile)) { + mDict.readFromFile(dictFile); + LOG(info) << "Tracker running with a provided dictionary: " << dictFile; + } else { + LOG(info) << "Dictionary " << dictFile << " is absent, Tracker expects cluster patterns"; + } +} + +void TrackerDPL::run(ProcessingContext& pc) +{ + mTimer.Start(false); + auto compClusters = pc.inputs().get>("compClusters"); + gsl::span patterns = pc.inputs().get>("patterns"); + + // code further down does assignment to the rofs and the altered object is used for output + // we therefore need a copy of the vector rather than an object created directly on the input data, + // the output vector however is created directly inside the message memory thus avoiding copy by + // snapshot + auto rofsinput = pc.inputs().get>("ROframes"); + auto& rofs = pc.outputs().make>(Output{"ITS", "ITSTrackROF", 0, Lifetime::Timeframe}, rofsinput.begin(), rofsinput.end()); + + auto& irFrames = pc.outputs().make>(Output{"ITS", "IRFRAMES", 0, Lifetime::Timeframe}); + + const auto& alpParams = o2::itsmft::DPLAlpideParam::Instance(); // RS: this should come from CCDB + int nBCPerTF = alpParams.roFrameLengthInBC; + + LOG(info) << "ITSTracker pulled " << compClusters.size() << " clusters, " << rofs.size() << " RO frames"; + + const dataformats::MCTruthContainer* labels = nullptr; + gsl::span mc2rofs; + if (mIsMC) { + labels = pc.inputs().get*>("labels").release(); + // get the array as read-only span, a snapshot is send forward + mc2rofs = pc.inputs().get>("MC2ROframes"); + LOG(info) << labels->getIndexedSize() << " MC label objects , in " << mc2rofs.size() << " MC events"; + } + + std::vector tracks; + auto& allClusIdx = pc.outputs().make>(Output{"ITS", "TRACKCLSID", 0, Lifetime::Timeframe}); + std::vector trackLabels; + auto& allTracks = pc.outputs().make>(Output{"ITS", "TRACKS", 0, Lifetime::Timeframe}); + std::vector allTrackLabels; + + auto& vertROFvec = pc.outputs().make>(Output{"ITS", "VERTICESROF", 0, Lifetime::Timeframe}); + auto& vertices = pc.outputs().make>(Output{"ITS", "VERTICES", 0, Lifetime::Timeframe}); + + std::uint32_t roFrame = 0; + ROframe event(0, 7); + + bool continuous = mGRP->isDetContinuousReadOut("ITS"); + LOG(info) << "ITSTracker RO: continuous=" << continuous; + + const auto& multEstConf = FastMultEstConfig::Instance(); // parameters for mult estimation and cuts + FastMultEst multEst; // mult estimator + + TimeFrame mTimeFrame; + mTracker->adoptTimeFrame(mTimeFrame); + mTracker->setBz(mBz); + + gsl::span::iterator pattIt = patterns.begin(); + + gsl::span rofspan(rofs); + mTimeFrame.loadROFrameData(rofspan, compClusters, pattIt, mDict, labels); + pattIt = patterns.begin(); + std::vector savedROF; + auto logger = [&](std::string s) { LOG(info) << s; }; + float vertexerElapsedTime{0.f}; + int nclUsed = 0; + + std::vector processingMask; + int cutClusterMult{0}, cutVertexMult{0}, cutTotalMult{0}; + for (auto& rof : rofspan) { + nclUsed += ioutils::loadROFrameData(rof, event, compClusters, pattIt, mDict, labels); + // prepare in advance output ROFRecords, even if this ROF to be rejected + int first = allTracks.size(); + + // for vertices output + auto& vtxROF = vertROFvec.emplace_back(rof); // register entry and number of vertices in the + vtxROF.setFirstEntry(vertices.size()); // dedicated ROFRecord + vtxROF.setNEntries(0); + + bool multCut = (multEstConf.cutMultClusLow <= 0 && multEstConf.cutMultClusHigh <= 0); // cut was requested + if (!multCut) { + float mult = multEst.process(rof.getROFData(compClusters)); + multCut = mult >= multEstConf.cutMultClusLow && mult <= multEstConf.cutMultClusHigh; + LOG(debug) << fmt::format("ROF {} rejected by the cluster multiplicity selection [{},{}]", processingMask.size(), multEstConf.cutMultClusLow, multEstConf.cutMultClusHigh); + cutClusterMult += !multCut; + } + + std::vector vtxVecLoc; + if (multCut) { + if (mRunVertexer) { + vertexerElapsedTime += mVertexer->clustersToVertices(event, false, logger); + auto allVerts = mVertexer->exportVertices(); + multCut = allVerts.size() == 0; + for (const auto& vtx : allVerts) { + if (vtx.getNContributors() < multEstConf.cutMultVtxLow || (multEstConf.cutMultVtxHigh > 0 && vtx.getNContributors() > multEstConf.cutMultVtxHigh)) { + continue; // skip vertex of unwanted multiplicity + } + multCut = true; // At least one passes the selection + vtxVecLoc.push_back(vtx); + } + } else { + vtxVecLoc.emplace_back(Vertex()); + vtxVecLoc.back().setNContributors(1); + } + + if (!multCut) { + LOG(debug) << fmt::format("ROF {} rejected by the vertex multiplicity selection [{},{}]", processingMask.size(), multEstConf.cutMultVtxLow, multEstConf.cutMultVtxHigh); + cutVertexMult++; + } + } + cutTotalMult += !multCut; + processingMask.push_back(multCut); + mTimeFrame.addPrimaryVertices(vtxVecLoc); + + vtxROF.setNEntries(vtxVecLoc.size()); + for (const auto& vtx : vtxVecLoc) { + vertices.push_back(vtx); + } + savedROF.push_back(roFrame); + roFrame++; + } + + LOG(info) << fmt::format(" - In total, multiplicity selection rejected {}/{} ROFs", cutTotalMult, rofspan.size()); + LOG(info) << fmt::format("\t - Cluster multiplicity selection rejected {}/{} ROFs", cutClusterMult, rofspan.size()); + LOG(info) << fmt::format("\t - Vertex multiplicity selection rejected {}/{} ROFs", cutVertexMult, rofspan.size()); + LOG(info) << fmt::format(" - Vertex seeding total elapsed time: {} ms for {} clusters in {} ROFs", vertexerElapsedTime, nclUsed, rofspan.size()); + LOG(info) << fmt::format(" - Beam position computed for the TF: {}, {}", mTimeFrame.getBeamX(), mTimeFrame.getBeamY()); + + mTimeFrame.setMultiplicityCutMask(processingMask); + mTracker->clustersToTracks(logger); + if (mTimeFrame.hasBogusClusters()) { + LOG(warning) << fmt::format(" - The processed timeframe had {} clusters with wild z coordinates, check the dictionaries", mTimeFrame.hasBogusClusters()); + } + + for (unsigned int iROF{0}; iROF < rofs.size(); ++iROF) { + + auto& rof{rofs[iROF]}; + tracks = mTimeFrame.getTracks(iROF); + trackLabels = mTimeFrame.getTracksLabel(iROF); + auto number{tracks.size()}; + auto first{allTracks.size()}; + int offset = -rof.getFirstEntry(); // cluster entry!!! + rof.setFirstEntry(first); + rof.setNEntries(number); + + if (tracks.size()) { + irFrames.emplace_back(rof.getBCData(), rof.getBCData() + nBCPerTF - 1); + } + std::copy(trackLabels.begin(), trackLabels.end(), std::back_inserter(allTrackLabels)); + // Some conversions that needs to be moved in the tracker internals + for (unsigned int iTrk{0}; iTrk < tracks.size(); ++iTrk) { + auto& trc{tracks[iTrk]}; + trc.setFirstClusterEntry(allClusIdx.size()); // before adding tracks, create final cluster indices + int ncl = trc.getNumberOfClusters(), nclf = 0; + for (int ic = TrackITSExt::MaxClusters; ic--;) { // track internally keeps in->out cluster indices, but we want to store the references as out->in!!! + auto clid = trc.getClusterIndex(ic); + if (clid >= 0) { + allClusIdx.push_back(clid); + nclf++; + } + } + assert(ncl == nclf); + allTracks.emplace_back(trc); + } + } + + LOG(info) << "ITSTracker pushed " << allTracks.size() << " tracks"; + if (mIsMC) { + LOG(info) << "ITSTracker pushed " << allTrackLabels.size() << " track labels"; + + pc.outputs().snapshot(Output{"ITS", "TRACKSMCTR", 0, Lifetime::Timeframe}, allTrackLabels); + pc.outputs().snapshot(Output{"ITS", "ITSTrackMC2ROF", 0, Lifetime::Timeframe}, mc2rofs); + } + mTimer.Stop(); +} + +void TrackerDPL::endOfStream(EndOfStreamContext& ec) +{ + LOGF(info, "ITS CA-Tracker total timing: Cpu: %.3e Real: %.3e s in %d slots", + mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); +} + +DataProcessorSpec getTrackerSpec(bool useMC, const std::string& trModeS, o2::gpu::GPUDataTypes::DeviceType dType) +{ + std::vector inputs; + inputs.emplace_back("compClusters", "ITS", "COMPCLUSTERS", 0, Lifetime::Timeframe); + inputs.emplace_back("patterns", "ITS", "PATTERNS", 0, Lifetime::Timeframe); + inputs.emplace_back("ROframes", "ITS", "CLUSTERSROF", 0, Lifetime::Timeframe); + + std::vector outputs; + outputs.emplace_back("ITS", "TRACKS", 0, Lifetime::Timeframe); + outputs.emplace_back("ITS", "TRACKCLSID", 0, Lifetime::Timeframe); + outputs.emplace_back("ITS", "ITSTrackROF", 0, Lifetime::Timeframe); + outputs.emplace_back("ITS", "VERTICES", 0, Lifetime::Timeframe); + outputs.emplace_back("ITS", "VERTICESROF", 0, Lifetime::Timeframe); + outputs.emplace_back("ITS", "IRFRAMES", 0, Lifetime::Timeframe); + + if (useMC) { + inputs.emplace_back("labels", "ITS", "CLUSTERSMCTR", 0, Lifetime::Timeframe); + inputs.emplace_back("MC2ROframes", "ITS", "CLUSTERSMC2ROF", 0, Lifetime::Timeframe); + outputs.emplace_back("ITS", "TRACKSMCTR", 0, Lifetime::Timeframe); + outputs.emplace_back("ITS", "ITSTrackMC2ROF", 0, Lifetime::Timeframe); + outputs.emplace_back("ITS", "VERTICES", 0, Lifetime::Timeframe); + } + + return DataProcessorSpec{ + "its-tracker", + inputs, + outputs, + AlgorithmSpec{adaptFromTask(useMC, trModeS, dType)}, + Options{ + {"grp-file", VariantType::String, "o2sim_grp.root", {"Name of the grp file"}}, + {"material-lut-path", VariantType::String, "", {"Path of the material LUT file"}}}}; +} + +} // namespace its +} // namespace o2 \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/src/HyperWorkflow.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingWorkflow.cxx similarity index 64% rename from Detectors/StrangenessTracking/workflow/src/HyperWorkflow.cxx rename to Detectors/StrangenessTracking/workflow/src/HypertrackingWorkflow.cxx index 96f59e80b3bcb..882930a7dd9d9 100644 --- a/Detectors/StrangenessTracking/workflow/src/HyperWorkflow.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingWorkflow.cxx @@ -11,16 +11,7 @@ /// @file HyperWorkflow.cxx -#include "HyperTrackingWorkflow/HyperWorkflow.h" -// #include "ITSWorkflow/RecoWorkflow.h" -// #include "ITSWorkflow/ClustererSpec.h" -// #include "ITSWorkflow/ClusterWriterSpec.h" -// #include "ITSWorkflow/IRFrameWriterSpec.h" -// #include "ITSWorkflow/TrackerSpec.h" -// #include "ITSWorkflow/CookedTrackerSpec.h" -// #include "ITSWorkflow/TrackWriterSpec.h" -// #include "ITSMFTWorkflow/EntropyEncoderSpec.h" -// #include "ITSMFTWorkflow/DigitReaderSpec.h" +#include "HyperTrackingWorkflow/HypertrackingWorkflow.h" namespace o2 { From 2359be7983c92a36bd4977987de1f412a3568892 Mon Sep 17 00:00:00 2001 From: Maximiliano Puccio Date: Tue, 30 Nov 2021 14:53:01 +0100 Subject: [PATCH 04/36] Make the skeleton compile in O2 Co-authored with @mconcas --- Detectors/StrangenessTracking/CMakeLists.txt | 3 +- .../StrangenessTracking/macros/CMakeLists.txt | 9 + .../{macro => macros}/matchV0s.C | 0 .../strangeness/CMakeLists.txt | 13 - .../tracking/CMakeLists.txt | 23 ++ .../StrangenessTracking}/HyperTracker.h | 0 .../src/HyperTracker.cxx | 2 +- .../workflow/CMakeLists.txt | 4 +- .../HyperTrackingWorkflow/HypertrackerSpecs.h | 0 .../HypertrackingWorkflow.h | 13 +- .../workflow/src/HypertrackerSpecs.cxx | 348 ------------------ .../workflow/src/HypertrackingWorkflow.cxx | 14 +- .../workflow/src/hypertracking-workflow.cxx | 4 +- 13 files changed, 49 insertions(+), 384 deletions(-) create mode 100644 Detectors/StrangenessTracking/macros/CMakeLists.txt rename Detectors/StrangenessTracking/{macro => macros}/matchV0s.C (100%) delete mode 100644 Detectors/StrangenessTracking/strangeness/CMakeLists.txt create mode 100644 Detectors/StrangenessTracking/tracking/CMakeLists.txt rename Detectors/StrangenessTracking/{strangeness/include/Strangeness => tracking/include/StrangenessTracking}/HyperTracker.h (100%) rename Detectors/StrangenessTracking/{strangeness => tracking}/src/HyperTracker.cxx (99%) delete mode 100644 Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HypertrackerSpecs.h rename Detectors/StrangenessTracking/workflow/include/{HyperTrackingWorkflow => StrangenessTrackingWorkflow}/HypertrackingWorkflow.h (83%) delete mode 100644 Detectors/StrangenessTracking/workflow/src/HypertrackerSpecs.cxx diff --git a/Detectors/StrangenessTracking/CMakeLists.txt b/Detectors/StrangenessTracking/CMakeLists.txt index 7c8e1ea7445b7..723a7693e0c6f 100644 --- a/Detectors/StrangenessTracking/CMakeLists.txt +++ b/Detectors/StrangenessTracking/CMakeLists.txt @@ -10,4 +10,5 @@ # or submit itself to any jurisdiction. add_subdirectory(workflow) -add_subdirectory(strangeness) \ No newline at end of file +add_subdirectory(tracking) +add_subdirectory(macros) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/macros/CMakeLists.txt b/Detectors/StrangenessTracking/macros/CMakeLists.txt new file mode 100644 index 0000000000000..ed28e9545248a --- /dev/null +++ b/Detectors/StrangenessTracking/macros/CMakeLists.txt @@ -0,0 +1,9 @@ +o2_add_test_root_macro(matchV0s.C + PUBLIC_LINK_LIBRARIES O2::MathUtils + O2::ITSBase + O2::ITSMFTReconstruction + O2::ITSMFTSimulation + O2::DataFormatsITSMFT + O2::DataFormatsITS + O2::SimulationDataFormat + LABELS strangeness-tracking) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/macro/matchV0s.C b/Detectors/StrangenessTracking/macros/matchV0s.C similarity index 100% rename from Detectors/StrangenessTracking/macro/matchV0s.C rename to Detectors/StrangenessTracking/macros/matchV0s.C diff --git a/Detectors/StrangenessTracking/strangeness/CMakeLists.txt b/Detectors/StrangenessTracking/strangeness/CMakeLists.txt deleted file mode 100644 index 6237e9167bbfd..0000000000000 --- a/Detectors/StrangenessTracking/strangeness/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2019-2020 CERN and copyright holders of ALICE O2. -# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -# All rights not expressly granted are reserved. -# -# This software is distributed under the terms of the GNU General Public -# License v3 (GPL Version 3), copied verbatim in the file "COPYING". -# -# In applying this license CERN does not waive the privileges and immunities -# granted to it by virtue of its status as an Intergovernmental Organization -# or submit itself to any jurisdiction. - -o2_add_library(HyperTracking - SOURCES src/HyperTracker.cxx) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/tracking/CMakeLists.txt b/Detectors/StrangenessTracking/tracking/CMakeLists.txt new file mode 100644 index 0000000000000..aecf3cdf49b03 --- /dev/null +++ b/Detectors/StrangenessTracking/tracking/CMakeLists.txt @@ -0,0 +1,23 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +o2_add_library(StrangenessTracking + SOURCES src/HyperTracker.cxx + PUBLIC_LINK_LIBRARIES O2::MathUtils + O2::ITSBase + O2::ITSMFTReconstruction + O2::ITSMFTSimulation + O2::DataFormatsITSMFT + O2::DataFormatsITS + O2::SimulationDataFormat + O2::DetectorsVertexing + O2::ReconstructionDataFormats + ) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/strangeness/include/Strangeness/HyperTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h similarity index 100% rename from Detectors/StrangenessTracking/strangeness/include/Strangeness/HyperTracker.h rename to Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h diff --git a/Detectors/StrangenessTracking/strangeness/src/HyperTracker.cxx b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx similarity index 99% rename from Detectors/StrangenessTracking/strangeness/src/HyperTracker.cxx rename to Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx index 2141a474759ea..5a167c8948bdd 100644 --- a/Detectors/StrangenessTracking/strangeness/src/HyperTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "Strangeness/HyperTracker.h" +#include "StrangenessTracking/HyperTracker.h" namespace o2 { namespace tracking diff --git a/Detectors/StrangenessTracking/workflow/CMakeLists.txt b/Detectors/StrangenessTracking/workflow/CMakeLists.txt index 90e8df2e32085..944a08165989c 100644 --- a/Detectors/StrangenessTracking/workflow/CMakeLists.txt +++ b/Detectors/StrangenessTracking/workflow/CMakeLists.txt @@ -9,10 +9,10 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -o2_add_library(HyperWorkflow +o2_add_library(StrangenessTrackingWorkflow SOURCES src/HypertrackingWorkflow.cxx PUBLIC_LINK_LIBRARIES O2::Framework) o2_add_executable(hypertracking-workflow SOURCES src/hypertracking-workflow.cxx - PUBLIC_LINK_LIBRARIES O2::HyperWorkflow) \ No newline at end of file + PUBLIC_LINK_LIBRARIES O2::StrangenessTrackingWorkflow) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HypertrackerSpecs.h b/Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HypertrackerSpecs.h deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HypertrackingWorkflow.h b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingWorkflow.h similarity index 83% rename from Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HypertrackingWorkflow.h rename to Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingWorkflow.h index a75361f660e0d..ef698a5aa6688 100644 --- a/Detectors/StrangenessTracking/workflow/include/HyperTrackingWorkflow/HypertrackingWorkflow.h +++ b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingWorkflow.h @@ -16,14 +16,15 @@ #include "Framework/WorkflowSpec.h" namespace o2 { -namespace strangeness +namespace stangeness_tracking { -namespace hyper_workflow -{ - -framework::WorkflowSpec getWorkflow(); +framework::WorkflowSpec getWorkflow() +{ + framework::WorkflowSpec specs; + return specs; } -} // namespace strangeness + +} // namespace stangeness_tracking } // namespace o2 #endif \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackerSpecs.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackerSpecs.cxx deleted file mode 100644 index 2a01cecd1013c..0000000000000 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackerSpecs.cxx +++ /dev/null @@ -1,348 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -#include - -namespace o2 -{ -using namespace framework; -namespace its -{ -using Vertex = o2::dataformats::Vertex>; - -TrackerDPL::TrackerDPL(bool isMC, const std::string& trModeS, o2::gpu::GPUDataTypes::DeviceType dType) : mIsMC{isMC}, mMode{trModeS}, mRecChain{o2::gpu::GPUReconstruction::CreateInstance(dType, true)} -{ - std::transform(mMode.begin(), mMode.end(), mMode.begin(), [](unsigned char c) { return std::tolower(c); }); -} - -void TrackerDPL::init(InitContext& ic) -{ - mTimer.Stop(); - mTimer.Reset(); - - auto* chainITS = mRecChain->AddChain(); - mVertexer = std::make_unique(chainITS->GetITSVertexerTraits()); - mTracker = std::make_unique(new TrackerTraitsCPU); - - auto filename = ic.options().get("grp-file"); - const auto grp = parameters::GRPObject::loadFrom(filename); - if (grp) { - mGRP.reset(grp); - base::Propagator::initFieldFromGRP(grp); - auto field = static_cast(TGeoGlobalMagField::Instance()->GetField()); - - base::GeometryManager::loadGeometry(); - GeometryTGeo* geom = GeometryTGeo::Instance(); - geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, - o2::math_utils::TransformType::T2G)); - - std::string matLUTPath = ic.options().get("material-lut-path"); - std::string matLUTFile = o2::base::NameConf::getMatLUTFileName(matLUTPath); - if (o2::utils::Str::pathExists(matLUTFile)) { - auto* lut = o2::base::MatLayerCylSet::loadFromFile(matLUTFile); - o2::base::Propagator::Instance()->setMatLUT(lut); - mTracker->setCorrType(o2::base::PropagatorImpl::MatCorrType::USEMatCorrLUT); - LOG(info) << "Loaded material LUT from " << matLUTFile; - } else { - LOG(info) << "Material LUT " << matLUTFile << " file is absent, only heuristic material correction can be used"; - } - - std::vector trackParams; - std::vector memParams; - - mRunVertexer = true; - if (mMode == "async") { - - trackParams.resize(2); - trackParams[1].TrackletMinPt = 0.2f; - trackParams[1].CellDeltaTanLambdaSigma *= 2.; - trackParams[1].MinTrackLength = 4; - memParams.resize(2); - LOG(info) << "Initializing tracker in async. phase reconstruction with " << trackParams.size() << " passes"; - - } else if (mMode == "sync_misaligned") { - - trackParams.resize(1); - trackParams[0].PhiBins = 32; - trackParams[0].ZBins = 64; - trackParams[0].CellDeltaTanLambdaSigma *= 10; - trackParams[0].LayerMisalignment[0] = 3.e-2; - trackParams[0].LayerMisalignment[1] = 3.e-2; - trackParams[0].LayerMisalignment[2] = 3.e-2; - trackParams[0].LayerMisalignment[3] = 1.e-1; - trackParams[0].LayerMisalignment[4] = 1.e-1; - trackParams[0].LayerMisalignment[5] = 1.e-1; - trackParams[0].LayerMisalignment[6] = 1.e-1; - trackParams[0].FitIterationMaxChi2[0] = 100.; - trackParams[0].FitIterationMaxChi2[1] = 50.; - trackParams[0].MinTrackLength = 4; - memParams.resize(1); - LOG(info) << "Initializing tracker in misaligned sync. phase reconstruction with " << trackParams.size() << " passes"; - - } else if (mMode == "sync") { - memParams.resize(1); - trackParams.resize(1); - LOG(info) << "Initializing tracker in sync. phase reconstruction with " << trackParams.size() << " passes"; - } else if (mMode == "cosmics") { - mRunVertexer = false; - trackParams.resize(1); - memParams.resize(1); - trackParams[0].MinTrackLength = 4; - trackParams[0].CellDeltaTanLambdaSigma *= 10; - trackParams[0].PhiBins = 4; - trackParams[0].ZBins = 16; - trackParams[0].PVres = 1.e5f; - trackParams[0].LayerMisalignment[0] = 3.e-2; - trackParams[0].LayerMisalignment[1] = 3.e-2; - trackParams[0].LayerMisalignment[2] = 3.e-2; - trackParams[0].LayerMisalignment[3] = 1.e-1; - trackParams[0].LayerMisalignment[4] = 1.e-1; - trackParams[0].LayerMisalignment[5] = 1.e-1; - trackParams[0].LayerMisalignment[6] = 1.e-1; - trackParams[0].FitIterationMaxChi2[0] = 100.; - trackParams[0].FitIterationMaxChi2[1] = 50.; - LOG(info) << "Initializing tracker in reconstruction for cosmics with " << trackParams.size() << " passes"; - - } else { - throw std::runtime_error(fmt::format("Unsupported ITS tracking mode {:s} ", mMode)); - } - mTracker->setParameters(memParams, trackParams); - - mVertexer->getGlobalConfiguration(); - mTracker->getGlobalConfiguration(); - LOG(info) << Form("Using %s for material budget approximation", (mTracker->isMatLUT() ? "lookup table" : "TGeometry")); - - double origD[3] = {0., 0., 0.}; - mBz = field->getBz(origD); - } else { - throw std::runtime_error(o2::utils::Str::concat_string("Cannot retrieve GRP from the ", filename)); - } - - std::string dictPath = o2::itsmft::ClustererParam::Instance().dictFilePath; - std::string dictFile = o2::base::NameConf::getAlpideClusterDictionaryFileName(o2::detectors::DetID::ITS, dictPath); - if (o2::utils::Str::pathExists(dictFile)) { - mDict.readFromFile(dictFile); - LOG(info) << "Tracker running with a provided dictionary: " << dictFile; - } else { - LOG(info) << "Dictionary " << dictFile << " is absent, Tracker expects cluster patterns"; - } -} - -void TrackerDPL::run(ProcessingContext& pc) -{ - mTimer.Start(false); - auto compClusters = pc.inputs().get>("compClusters"); - gsl::span patterns = pc.inputs().get>("patterns"); - - // code further down does assignment to the rofs and the altered object is used for output - // we therefore need a copy of the vector rather than an object created directly on the input data, - // the output vector however is created directly inside the message memory thus avoiding copy by - // snapshot - auto rofsinput = pc.inputs().get>("ROframes"); - auto& rofs = pc.outputs().make>(Output{"ITS", "ITSTrackROF", 0, Lifetime::Timeframe}, rofsinput.begin(), rofsinput.end()); - - auto& irFrames = pc.outputs().make>(Output{"ITS", "IRFRAMES", 0, Lifetime::Timeframe}); - - const auto& alpParams = o2::itsmft::DPLAlpideParam::Instance(); // RS: this should come from CCDB - int nBCPerTF = alpParams.roFrameLengthInBC; - - LOG(info) << "ITSTracker pulled " << compClusters.size() << " clusters, " << rofs.size() << " RO frames"; - - const dataformats::MCTruthContainer* labels = nullptr; - gsl::span mc2rofs; - if (mIsMC) { - labels = pc.inputs().get*>("labels").release(); - // get the array as read-only span, a snapshot is send forward - mc2rofs = pc.inputs().get>("MC2ROframes"); - LOG(info) << labels->getIndexedSize() << " MC label objects , in " << mc2rofs.size() << " MC events"; - } - - std::vector tracks; - auto& allClusIdx = pc.outputs().make>(Output{"ITS", "TRACKCLSID", 0, Lifetime::Timeframe}); - std::vector trackLabels; - auto& allTracks = pc.outputs().make>(Output{"ITS", "TRACKS", 0, Lifetime::Timeframe}); - std::vector allTrackLabels; - - auto& vertROFvec = pc.outputs().make>(Output{"ITS", "VERTICESROF", 0, Lifetime::Timeframe}); - auto& vertices = pc.outputs().make>(Output{"ITS", "VERTICES", 0, Lifetime::Timeframe}); - - std::uint32_t roFrame = 0; - ROframe event(0, 7); - - bool continuous = mGRP->isDetContinuousReadOut("ITS"); - LOG(info) << "ITSTracker RO: continuous=" << continuous; - - const auto& multEstConf = FastMultEstConfig::Instance(); // parameters for mult estimation and cuts - FastMultEst multEst; // mult estimator - - TimeFrame mTimeFrame; - mTracker->adoptTimeFrame(mTimeFrame); - mTracker->setBz(mBz); - - gsl::span::iterator pattIt = patterns.begin(); - - gsl::span rofspan(rofs); - mTimeFrame.loadROFrameData(rofspan, compClusters, pattIt, mDict, labels); - pattIt = patterns.begin(); - std::vector savedROF; - auto logger = [&](std::string s) { LOG(info) << s; }; - float vertexerElapsedTime{0.f}; - int nclUsed = 0; - - std::vector processingMask; - int cutClusterMult{0}, cutVertexMult{0}, cutTotalMult{0}; - for (auto& rof : rofspan) { - nclUsed += ioutils::loadROFrameData(rof, event, compClusters, pattIt, mDict, labels); - // prepare in advance output ROFRecords, even if this ROF to be rejected - int first = allTracks.size(); - - // for vertices output - auto& vtxROF = vertROFvec.emplace_back(rof); // register entry and number of vertices in the - vtxROF.setFirstEntry(vertices.size()); // dedicated ROFRecord - vtxROF.setNEntries(0); - - bool multCut = (multEstConf.cutMultClusLow <= 0 && multEstConf.cutMultClusHigh <= 0); // cut was requested - if (!multCut) { - float mult = multEst.process(rof.getROFData(compClusters)); - multCut = mult >= multEstConf.cutMultClusLow && mult <= multEstConf.cutMultClusHigh; - LOG(debug) << fmt::format("ROF {} rejected by the cluster multiplicity selection [{},{}]", processingMask.size(), multEstConf.cutMultClusLow, multEstConf.cutMultClusHigh); - cutClusterMult += !multCut; - } - - std::vector vtxVecLoc; - if (multCut) { - if (mRunVertexer) { - vertexerElapsedTime += mVertexer->clustersToVertices(event, false, logger); - auto allVerts = mVertexer->exportVertices(); - multCut = allVerts.size() == 0; - for (const auto& vtx : allVerts) { - if (vtx.getNContributors() < multEstConf.cutMultVtxLow || (multEstConf.cutMultVtxHigh > 0 && vtx.getNContributors() > multEstConf.cutMultVtxHigh)) { - continue; // skip vertex of unwanted multiplicity - } - multCut = true; // At least one passes the selection - vtxVecLoc.push_back(vtx); - } - } else { - vtxVecLoc.emplace_back(Vertex()); - vtxVecLoc.back().setNContributors(1); - } - - if (!multCut) { - LOG(debug) << fmt::format("ROF {} rejected by the vertex multiplicity selection [{},{}]", processingMask.size(), multEstConf.cutMultVtxLow, multEstConf.cutMultVtxHigh); - cutVertexMult++; - } - } - cutTotalMult += !multCut; - processingMask.push_back(multCut); - mTimeFrame.addPrimaryVertices(vtxVecLoc); - - vtxROF.setNEntries(vtxVecLoc.size()); - for (const auto& vtx : vtxVecLoc) { - vertices.push_back(vtx); - } - savedROF.push_back(roFrame); - roFrame++; - } - - LOG(info) << fmt::format(" - In total, multiplicity selection rejected {}/{} ROFs", cutTotalMult, rofspan.size()); - LOG(info) << fmt::format("\t - Cluster multiplicity selection rejected {}/{} ROFs", cutClusterMult, rofspan.size()); - LOG(info) << fmt::format("\t - Vertex multiplicity selection rejected {}/{} ROFs", cutVertexMult, rofspan.size()); - LOG(info) << fmt::format(" - Vertex seeding total elapsed time: {} ms for {} clusters in {} ROFs", vertexerElapsedTime, nclUsed, rofspan.size()); - LOG(info) << fmt::format(" - Beam position computed for the TF: {}, {}", mTimeFrame.getBeamX(), mTimeFrame.getBeamY()); - - mTimeFrame.setMultiplicityCutMask(processingMask); - mTracker->clustersToTracks(logger); - if (mTimeFrame.hasBogusClusters()) { - LOG(warning) << fmt::format(" - The processed timeframe had {} clusters with wild z coordinates, check the dictionaries", mTimeFrame.hasBogusClusters()); - } - - for (unsigned int iROF{0}; iROF < rofs.size(); ++iROF) { - - auto& rof{rofs[iROF]}; - tracks = mTimeFrame.getTracks(iROF); - trackLabels = mTimeFrame.getTracksLabel(iROF); - auto number{tracks.size()}; - auto first{allTracks.size()}; - int offset = -rof.getFirstEntry(); // cluster entry!!! - rof.setFirstEntry(first); - rof.setNEntries(number); - - if (tracks.size()) { - irFrames.emplace_back(rof.getBCData(), rof.getBCData() + nBCPerTF - 1); - } - std::copy(trackLabels.begin(), trackLabels.end(), std::back_inserter(allTrackLabels)); - // Some conversions that needs to be moved in the tracker internals - for (unsigned int iTrk{0}; iTrk < tracks.size(); ++iTrk) { - auto& trc{tracks[iTrk]}; - trc.setFirstClusterEntry(allClusIdx.size()); // before adding tracks, create final cluster indices - int ncl = trc.getNumberOfClusters(), nclf = 0; - for (int ic = TrackITSExt::MaxClusters; ic--;) { // track internally keeps in->out cluster indices, but we want to store the references as out->in!!! - auto clid = trc.getClusterIndex(ic); - if (clid >= 0) { - allClusIdx.push_back(clid); - nclf++; - } - } - assert(ncl == nclf); - allTracks.emplace_back(trc); - } - } - - LOG(info) << "ITSTracker pushed " << allTracks.size() << " tracks"; - if (mIsMC) { - LOG(info) << "ITSTracker pushed " << allTrackLabels.size() << " track labels"; - - pc.outputs().snapshot(Output{"ITS", "TRACKSMCTR", 0, Lifetime::Timeframe}, allTrackLabels); - pc.outputs().snapshot(Output{"ITS", "ITSTrackMC2ROF", 0, Lifetime::Timeframe}, mc2rofs); - } - mTimer.Stop(); -} - -void TrackerDPL::endOfStream(EndOfStreamContext& ec) -{ - LOGF(info, "ITS CA-Tracker total timing: Cpu: %.3e Real: %.3e s in %d slots", - mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); -} - -DataProcessorSpec getTrackerSpec(bool useMC, const std::string& trModeS, o2::gpu::GPUDataTypes::DeviceType dType) -{ - std::vector inputs; - inputs.emplace_back("compClusters", "ITS", "COMPCLUSTERS", 0, Lifetime::Timeframe); - inputs.emplace_back("patterns", "ITS", "PATTERNS", 0, Lifetime::Timeframe); - inputs.emplace_back("ROframes", "ITS", "CLUSTERSROF", 0, Lifetime::Timeframe); - - std::vector outputs; - outputs.emplace_back("ITS", "TRACKS", 0, Lifetime::Timeframe); - outputs.emplace_back("ITS", "TRACKCLSID", 0, Lifetime::Timeframe); - outputs.emplace_back("ITS", "ITSTrackROF", 0, Lifetime::Timeframe); - outputs.emplace_back("ITS", "VERTICES", 0, Lifetime::Timeframe); - outputs.emplace_back("ITS", "VERTICESROF", 0, Lifetime::Timeframe); - outputs.emplace_back("ITS", "IRFRAMES", 0, Lifetime::Timeframe); - - if (useMC) { - inputs.emplace_back("labels", "ITS", "CLUSTERSMCTR", 0, Lifetime::Timeframe); - inputs.emplace_back("MC2ROframes", "ITS", "CLUSTERSMC2ROF", 0, Lifetime::Timeframe); - outputs.emplace_back("ITS", "TRACKSMCTR", 0, Lifetime::Timeframe); - outputs.emplace_back("ITS", "ITSTrackMC2ROF", 0, Lifetime::Timeframe); - outputs.emplace_back("ITS", "VERTICES", 0, Lifetime::Timeframe); - } - - return DataProcessorSpec{ - "its-tracker", - inputs, - outputs, - AlgorithmSpec{adaptFromTask(useMC, trModeS, dType)}, - Options{ - {"grp-file", VariantType::String, "o2sim_grp.root", {"Name of the grp file"}}, - {"material-lut-path", VariantType::String, "", {"Path of the material LUT file"}}}}; -} - -} // namespace its -} // namespace o2 \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingWorkflow.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingWorkflow.cxx index 882930a7dd9d9..33b66e5259af7 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingWorkflow.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingWorkflow.cxx @@ -11,22 +11,14 @@ /// @file HyperWorkflow.cxx -#include "HyperTrackingWorkflow/HypertrackingWorkflow.h" +#include "StrangenessTrackingWorkflow/HypertrackingWorkflow.h" namespace o2 { -namespace strangeness -{ -namespace hyper_workflow +namespace strangeness_tracking { -framework::WorkflowSpec getWorkflow() -{ - framework::WorkflowSpec specs; - return specs; -} -} // namespace reco_workflow -} // namespace its +} // namespace strangeness_tracking } // namespace o2 \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx b/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx index b122f18e0b916..5b53e3413cfa3 100644 --- a/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx +++ b/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "HyperTrackingWorkflow/HyperWorkflow.h" +#include "StrangenessTrackingWorkflow/HypertrackingWorkflow.h" #include "CommonUtils/ConfigurableParam.h" // #include "ITStracking/TrackingConfigParam.h" // #include "ITStracking/Configuration.h" @@ -68,7 +68,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); - auto wf = o2::strangeness::hyper_workflow::getWorkflow(); + auto wf = o2::stangeness_tracking::getWorkflow(); // configure dpl timer to inject correct firstTFOrbit: start from the 1st orbit of TF containing 1st sampled orbit // o2::raw::HBFUtilsInitializer hbfIni(configcontext, wf); From 61a2804a9834ea21f4fed6fdc0a06aca4abba86d Mon Sep 17 00:00:00 2001 From: Maximiliano Puccio Date: Tue, 30 Nov 2021 15:02:21 +0100 Subject: [PATCH 05/36] Aestetics --- Detectors/StrangenessTracking/workflow/CMakeLists.txt | 2 +- .../{HypertrackingWorkflow.h => HypertrackingSpec.h} | 0 .../src/{HypertrackingWorkflow.cxx => HypertrackingSpec.cxx} | 2 +- .../StrangenessTracking/workflow/src/hypertracking-workflow.cxx | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/{HypertrackingWorkflow.h => HypertrackingSpec.h} (100%) rename Detectors/StrangenessTracking/workflow/src/{HypertrackingWorkflow.cxx => HypertrackingSpec.cxx} (91%) diff --git a/Detectors/StrangenessTracking/workflow/CMakeLists.txt b/Detectors/StrangenessTracking/workflow/CMakeLists.txt index 944a08165989c..6bb9a0c40d222 100644 --- a/Detectors/StrangenessTracking/workflow/CMakeLists.txt +++ b/Detectors/StrangenessTracking/workflow/CMakeLists.txt @@ -10,7 +10,7 @@ # or submit itself to any jurisdiction. o2_add_library(StrangenessTrackingWorkflow - SOURCES src/HypertrackingWorkflow.cxx + SOURCES src/HypertrackingSpec.cxx PUBLIC_LINK_LIBRARIES O2::Framework) o2_add_executable(hypertracking-workflow diff --git a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingWorkflow.h b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h similarity index 100% rename from Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingWorkflow.h rename to Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingWorkflow.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx similarity index 91% rename from Detectors/StrangenessTracking/workflow/src/HypertrackingWorkflow.cxx rename to Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx index 33b66e5259af7..83e0ef5e9c295 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingWorkflow.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx @@ -11,7 +11,7 @@ /// @file HyperWorkflow.cxx -#include "StrangenessTrackingWorkflow/HypertrackingWorkflow.h" +#include "StrangenessTrackingWorkflow/HypertrackingSpec.h" namespace o2 { diff --git a/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx b/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx index 5b53e3413cfa3..846de1573e243 100644 --- a/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx +++ b/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "StrangenessTrackingWorkflow/HypertrackingWorkflow.h" +#include "StrangenessTrackingWorkflow/HypertrackingSpec.h" #include "CommonUtils/ConfigurableParam.h" // #include "ITStracking/TrackingConfigParam.h" // #include "ITStracking/Configuration.h" From cea3d986744187e41f8eca1a48d941613b0d4923 Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi <43742195+fmazzasc@users.noreply.github.com> Date: Fri, 3 Dec 2021 12:04:05 +0100 Subject: [PATCH 06/36] Update tracking algorithm (#10) --- .../StrangenessTracking/HyperTracker.h | 26 ++-- .../tracking/src/HyperTracker.cxx | 123 ++++++++++++------ 2 files changed, 97 insertions(+), 52 deletions(-) diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h index 96d74a1280899..49d8a2c87f76b 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h @@ -9,9 +9,9 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file HyperTracker.h +/// \file hyperTracker.h /// \brief hypertracker -/// \author francesco.mazzaschi@cern.ch +/// #ifndef _ALICEO2_HYPER_TRACKER_ #define _ALICEO2_HYPER_TRACKER_ @@ -20,17 +20,17 @@ #include "DataFormatsITS/TrackITS.h" #include "ITSBase/GeometryTGeo.h" #include "ReconstructionDataFormats/Track.h" -#include "DetectorsVertexing/DCAFitterN.h" - #include #include "TMath.h" +#include "DetectorsVertexing/DCAFitterN.h" +#include "DetectorsBase/Propagator.h" namespace o2 { namespace tracking { -class HyperTracker +class hyperTracker { public: using PID = o2::track::PID; @@ -38,18 +38,20 @@ class HyperTracker using ITSCluster = o2::BaseCluster; using V0 = o2::dataformats::V0; using DCAFitter2 = o2::vertexing::DCAFitterN<2>; + using DCAFitter3 = o2::vertexing::DCAFitterN<3>; - HyperTracker() = default; - HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0); //recompute V0 using hypertriton hypothesis - HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman); + hyperTracker() = default; + hyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0); // recompute V0 using hypertriton hypothesis + hyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman); double getMatchingChi2(); double calcV0alpha(const V0& v0); bool process(); bool propagateToClus(const ITSCluster& clus, o2::track::TrackParCov& track); - int updateV0topology(const ITSCluster& clus, bool tryDaughter); + bool updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track); bool recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID); V0& getV0() { return hypV0; }; + bool Refit3Body(); float getNclusMatching() const { return nClusMatching; } void setNclusMatching(float d) { nClusMatching = d; } @@ -64,12 +66,16 @@ class HyperTracker TrackITS hyperTrack; // track of hypertriton mother V0 hypV0; // V0 of decay daughters std::vector hyperClusters; // clusters of hypertriton mother - o2::its::GeometryTGeo* geomITS; //geometry for ITS clusters + o2::its::GeometryTGeo* geomITS; // geometry for ITS clusters DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis + DCAFitter3 mFitter3Body; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis int nClusMatching; // number of cluster to be matched to V0 + float mInitR2; float mMaxChi2 = 40; float mBz = -5; + + ClassDefNV(hyperTracker, 1); }; } // namespace tracking diff --git a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx index 5a167c8948bdd..fd0af0e7004ab 100644 --- a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx @@ -9,15 +9,17 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "StrangenessTracking/HyperTracker.h" +#include "hyperTracker.h" namespace o2 { namespace tracking { -HyperTracker::HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0) +hyperTracker::hyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0) : hyperTrack{motherTrack}, hyperClusters{motherClusters}, geomITS{gman}, mFitterV0{mFitterV0} { + mInitR2 = v0.calcR2(); + LOG(INFO) << "Original V0 radius: " << v0.calcR2(); auto posTrack = v0.getProng(0); auto negTrack = v0.getProng(1); @@ -25,6 +27,7 @@ HyperTracker::HyperTracker(const TrackITS& motherTrack, const V0& v0, const std: alphaV0 > 0 ? posTrack.setAbsCharge(2) : negTrack.setAbsCharge(2); auto isRecr = recreateV0(posTrack, negTrack, v0.getProngID(0), v0.getProngID(1)); + if (!isRecr) { LOG(INFO) << "V0 regeneration not successful, using default one"; hypV0 = v0; @@ -32,13 +35,13 @@ HyperTracker::HyperTracker(const TrackITS& motherTrack, const V0& v0, const std: setNclusMatching(motherClusters.size()); } -HyperTracker::HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman) +hyperTracker::hyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman) : hyperTrack{motherTrack}, hypV0{v0}, hyperClusters{motherClusters}, geomITS{gman} { setNclusMatching(motherClusters.size()); } -double HyperTracker::getMatchingChi2() +double hyperTracker::getMatchingChi2() { auto& outerClus = hyperClusters[0]; float alpha = geomITS->getSensorRefAlpha(outerClus.getSensorID()), x = outerClus.getX(); @@ -48,65 +51,69 @@ double HyperTracker::getMatchingChi2() if (hypV0.rotate(alpha)) { if (hypV0.propagateTo(x, mBz)) { + std::cout << "Pred chi2 outermost Cluster: " << hypV0.getPredictedChi2(outerClus) << std::endl; std::cout << "Pred chi2 V0-ITStrack: " << hypV0.getPredictedChi2(hyperTrack.getParamOut()) << std::endl; - return hypV0.getPredictedChi2(hyperTrack.getParamOut()); + return hypV0.getPredictedChi2(outerClus); } } return -1; } -bool HyperTracker::process() +bool hyperTracker::process() { + std::vector ITSclusV0; int isProcessed = 0; bool tryDaughter = true; for (auto& clus : hyperClusters) { + auto diffR2 = mInitR2 - clus.getX() * clus.getX() - clus.getY() * clus.getY(); + + // check V0 compatibility + if (diffR2 > -4) { + if (updateTrack(clus, hypV0)) { + tryDaughter = false; + LOG(INFO) << "Attach cluster to V0 for layer: " << geomITS->getLayer(clus.getSensorID()); + isProcessed++; + ITSclusV0.push_back(clus); + } + } - if (updateV0topology(clus, tryDaughter) == 1) { - tryDaughter = false; - isProcessed++; - LOG(INFO) << "Attach cluster to V0 for layer: " << geomITS->getLayer(clus.getSensorID()); - continue; - } else if (updateV0topology(clus, tryDaughter) == 2) { + // if V0 is not found, check He3 compatibility + if (diffR2 < 4 && tryDaughter == true) { + auto& he3track = calcV0alpha(hypV0) > 0 ? hypV0.getProng(0) : hypV0.getProng(1); + if (!updateTrack(clus, he3track)) + return false; // no V0 or He3 compatible clusters recreateV0(hypV0.getProng(0), hypV0.getProng(1), hypV0.getProngID(0), hypV0.getProngID(1)); - isProcessed++; LOG(INFO) << "Attach cluster to He3 for layer: " << geomITS->getLayer(clus.getSensorID()); + isProcessed++; continue; - } else { - break; } + if (isProcessed == 0) + return false; // no V0 or He3 compatible clusters } - return isProcessed >= nClusMatching; -} -int HyperTracker::updateV0topology(const ITSCluster& clus, bool tryDaughter) -{ - int isUpdated = 0; - - if (propagateToClus(clus, hypV0)) { - if (hypV0.getPredictedChi2(clus) < mMaxChi2) { - hypV0.update(clus); - isUpdated++; + // outward V0 propagation + if (ITSclusV0.size() > 0) { + hypV0.resetCovariance(); + std::reverse(ITSclusV0.begin(), ITSclusV0.end()); + for (auto& clus : ITSclusV0) { + if (!updateTrack(clus, hypV0)) + return false; } } - if (!isUpdated && tryDaughter) { - auto alphaArm = calcV0alpha(hypV0); - auto& he3track = alphaArm > 0 ? hypV0.getProng(0) : hypV0.getProng(1); - - if (propagateToClus(clus, he3track)) { - if (he3track.getPredictedChi2(clus) < mMaxChi2) { - he3track.update(clus); - isUpdated += 2; - } - } - } - return isUpdated; + // final 3body refit + auto finalRefit = Refit3Body(); + if (!finalRefit) + return false; + LOG(INFO) << "Final V0 radius: " << hypV0.calcR2(); + return isProcessed >= nClusMatching; } -bool HyperTracker::propagateToClus(const ITSCluster& clus, o2::track::TrackParCov& track) +bool hyperTracker::updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track) { + int isUpdated = 0; float alpha = geomITS->getSensorRefAlpha(clus.getSensorID()), x = clus.getX(); int layer{geomITS->getLayer(clus.getSensorID())}; float thick = layer < 3 ? 0.005 : 0.01; @@ -115,16 +122,19 @@ bool HyperTracker::propagateToClus(const ITSCluster& clus, o2::track::TrackParCo if (track.propagateTo(x, mBz)) { constexpr float radl = 9.36f; // Radiation length of Si [cm] constexpr float rho = 2.33f; // Density of Si [g/cm^3] - return track.correctForMaterial(thick, thick * rho * radl); + if (track.correctForMaterial(thick, thick * rho * radl) && track.getPredictedChi2(clus) < mMaxChi2 && track.getPredictedChi2(clus) > 0) { + track.update(clus); + return true; + } } } return false; } -bool HyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID) +bool hyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID) { - int cand = 0; //best V0 candidate + int cand = 0; // best V0 candidate int nCand; try { @@ -147,11 +157,40 @@ bool HyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2:: hypV0 = V0(v0XYZ, pV0, mFitterV0.calcPCACovMatrixFlat(cand), propPos, propNeg, posID, negID, o2::track::PID::HyperTriton); hypV0.setAbsCharge(1); + hypV0.setPID(o2::track::PID::HyperTriton); + return true; +} + +bool hyperTracker::Refit3Body() +{ + + int cand = 0; // best V0 candidate + int nCand; + + try { + nCand = mFitter3Body.process(hypV0, hypV0.getProng(0), hypV0.getProng(1)); + } catch (std::runtime_error& e) { + return false; + } + if (!nCand) + return false; + + mFitter3Body.propagateTracksToVertex(); + auto& propPos = mFitter3Body.getTrack(1, 0); + auto& propNeg = mFitter3Body.getTrack(2, 0); + + const auto& v0XYZ = mFitter3Body.getPCACandidatePos(); + std::array pP, pN; + propPos.getPxPyPzGlo(pP); + propNeg.getPxPyPzGlo(pN); + std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; + hypV0 = V0(v0XYZ, pV0, mFitter3Body.calcPCACovMatrixFlat(cand), propPos, propNeg, hypV0.getProngID(0), hypV0.getProngID(1), o2::track::PID::HyperTriton); + hypV0.setAbsCharge(1); return true; } -double HyperTracker::calcV0alpha(const V0& v0) +double hyperTracker::calcV0alpha(const V0& v0) { std::array fV0mom, fPmom, fNmom = {0, 0, 0}; v0.getProng(0).getPxPyPzGlo(fPmom); From 7e15edca1afb8c4a696513f7b4d9b677257b338c Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Fri, 3 Dec 2021 12:06:07 +0100 Subject: [PATCH 07/36] Improve hypertracking wf --- .../tracking/CMakeLists.txt | 7 +- .../StrangenessTracking/HyperTracker.h | 14 ++-- .../HypertrackingConfigParam.h | 31 ++++++++ .../tracking/src/HyperTracker.cxx | 32 ++++----- .../tracking/src/HypertrackingConfigParam.cxx | 22 ++++++ .../tracking/src/HypertrackingLinkDef.h | 21 ++++++ .../workflow/CMakeLists.txt | 8 ++- .../HypertrackingSpec.h | 37 +++++++--- .../workflow/src/HypertrackingSpec.cxx | 70 ++++++++++++++++++- .../workflow/src/hypertracking-workflow.cxx | 43 ++++-------- 10 files changed, 218 insertions(+), 67 deletions(-) create mode 100644 Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HypertrackingConfigParam.h create mode 100644 Detectors/StrangenessTracking/tracking/src/HypertrackingConfigParam.cxx create mode 100644 Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h diff --git a/Detectors/StrangenessTracking/tracking/CMakeLists.txt b/Detectors/StrangenessTracking/tracking/CMakeLists.txt index aecf3cdf49b03..24ded4dba4f65 100644 --- a/Detectors/StrangenessTracking/tracking/CMakeLists.txt +++ b/Detectors/StrangenessTracking/tracking/CMakeLists.txt @@ -11,6 +11,7 @@ o2_add_library(StrangenessTracking SOURCES src/HyperTracker.cxx + src/HypertrackingConfigParam.cxx PUBLIC_LINK_LIBRARIES O2::MathUtils O2::ITSBase O2::ITSMFTReconstruction @@ -20,4 +21,8 @@ o2_add_library(StrangenessTracking O2::SimulationDataFormat O2::DetectorsVertexing O2::ReconstructionDataFormats - ) \ No newline at end of file + ) + +o2_target_root_dictionary(StrangenessTracking + HEADERS include/StrangenessTracking/HypertrackingConfigParam.h + LINKDEF src/HypertrackingLinkDef.h) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h index 49d8a2c87f76b..4c890e4321ff8 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file hyperTracker.h +/// \file HyperTracker.h /// \brief hypertracker /// @@ -27,10 +27,10 @@ namespace o2 { -namespace tracking +namespace strangeness_tracking { -class hyperTracker +class HyperTracker { public: using PID = o2::track::PID; @@ -40,9 +40,9 @@ class hyperTracker using DCAFitter2 = o2::vertexing::DCAFitterN<2>; using DCAFitter3 = o2::vertexing::DCAFitterN<3>; - hyperTracker() = default; - hyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0); // recompute V0 using hypertriton hypothesis - hyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman); + HyperTracker() = default; + HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0); // recompute V0 using hypertriton hypothesis + HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman); double getMatchingChi2(); double calcV0alpha(const V0& v0); @@ -75,7 +75,7 @@ class hyperTracker float mMaxChi2 = 40; float mBz = -5; - ClassDefNV(hyperTracker, 1); + ClassDefNV(HyperTracker, 1); }; } // namespace tracking diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HypertrackingConfigParam.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HypertrackingConfigParam.h new file mode 100644 index 0000000000000..03d3c6d630ef5 --- /dev/null +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HypertrackingConfigParam.h @@ -0,0 +1,31 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef ALICEO2_HYPERTRACKINGPARAM_H_ +#define ALICEO2_HYPERTRACKINGPARAM_H_ + +#include "CommonUtils/ConfigurableParam.h" +#include "CommonUtils/ConfigurableParamHelper.h" + +namespace o2 +{ +namespace strangeness_tracking +{ + +struct HypertrackerParamConfig : public o2::conf::ConfigurableParamHelper { + float dummy = 0; + + O2ParamDef(HypertrackerParamConfig, "HypertrackerParam"); +}; + +} // namespace strangeness_tracking +} // namespace o2 +#endif \ No newline at end of file diff --git a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx index fd0af0e7004ab..84ff345c71caa 100644 --- a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx @@ -9,17 +9,17 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "hyperTracker.h" +#include "StrangenessTracking/HyperTracker.h" namespace o2 { -namespace tracking +namespace strangeness_tracking { -hyperTracker::hyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0) +HyperTracker::HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0) : hyperTrack{motherTrack}, hyperClusters{motherClusters}, geomITS{gman}, mFitterV0{mFitterV0} { mInitR2 = v0.calcR2(); - LOG(INFO) << "Original V0 radius: " << v0.calcR2(); + LOG(info) << "Original V0 radius: " << v0.calcR2(); auto posTrack = v0.getProng(0); auto negTrack = v0.getProng(1); @@ -29,19 +29,19 @@ hyperTracker::hyperTracker(const TrackITS& motherTrack, const V0& v0, const std: auto isRecr = recreateV0(posTrack, negTrack, v0.getProngID(0), v0.getProngID(1)); if (!isRecr) { - LOG(INFO) << "V0 regeneration not successful, using default one"; + LOG(info) << "V0 regeneration not successful, using default one"; hypV0 = v0; } setNclusMatching(motherClusters.size()); } -hyperTracker::hyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman) +HyperTracker::HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman) : hyperTrack{motherTrack}, hypV0{v0}, hyperClusters{motherClusters}, geomITS{gman} { setNclusMatching(motherClusters.size()); } -double hyperTracker::getMatchingChi2() +double HyperTracker::getMatchingChi2() { auto& outerClus = hyperClusters[0]; float alpha = geomITS->getSensorRefAlpha(outerClus.getSensorID()), x = outerClus.getX(); @@ -60,9 +60,9 @@ double hyperTracker::getMatchingChi2() return -1; } -bool hyperTracker::process() +bool HyperTracker::process() { - std::vector ITSclusV0; + std::vector ITSclusV0; int isProcessed = 0; bool tryDaughter = true; @@ -73,7 +73,7 @@ bool hyperTracker::process() if (diffR2 > -4) { if (updateTrack(clus, hypV0)) { tryDaughter = false; - LOG(INFO) << "Attach cluster to V0 for layer: " << geomITS->getLayer(clus.getSensorID()); + LOG(info) << "Attach cluster to V0 for layer: " << geomITS->getLayer(clus.getSensorID()); isProcessed++; ITSclusV0.push_back(clus); } @@ -85,7 +85,7 @@ bool hyperTracker::process() if (!updateTrack(clus, he3track)) return false; // no V0 or He3 compatible clusters recreateV0(hypV0.getProng(0), hypV0.getProng(1), hypV0.getProngID(0), hypV0.getProngID(1)); - LOG(INFO) << "Attach cluster to He3 for layer: " << geomITS->getLayer(clus.getSensorID()); + LOG(info) << "Attach cluster to He3 for layer: " << geomITS->getLayer(clus.getSensorID()); isProcessed++; continue; } @@ -107,11 +107,11 @@ bool hyperTracker::process() auto finalRefit = Refit3Body(); if (!finalRefit) return false; - LOG(INFO) << "Final V0 radius: " << hypV0.calcR2(); + LOG(info) << "Final V0 radius: " << hypV0.calcR2(); return isProcessed >= nClusMatching; } -bool hyperTracker::updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track) +bool HyperTracker::updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track) { int isUpdated = 0; float alpha = geomITS->getSensorRefAlpha(clus.getSensorID()), x = clus.getX(); @@ -131,7 +131,7 @@ bool hyperTracker::updateTrack(const ITSCluster& clus, o2::track::TrackParCov& t return false; } -bool hyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID) +bool HyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID) { int cand = 0; // best V0 candidate @@ -161,7 +161,7 @@ bool hyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2:: return true; } -bool hyperTracker::Refit3Body() +bool HyperTracker::Refit3Body() { int cand = 0; // best V0 candidate @@ -190,7 +190,7 @@ bool hyperTracker::Refit3Body() return true; } -double hyperTracker::calcV0alpha(const V0& v0) +double HyperTracker::calcV0alpha(const V0& v0) { std::array fV0mom, fPmom, fNmom = {0, 0, 0}; v0.getProng(0).getPxPyPzGlo(fPmom); diff --git a/Detectors/StrangenessTracking/tracking/src/HypertrackingConfigParam.cxx b/Detectors/StrangenessTracking/tracking/src/HypertrackingConfigParam.cxx new file mode 100644 index 0000000000000..9609e65bfd1e0 --- /dev/null +++ b/Detectors/StrangenessTracking/tracking/src/HypertrackingConfigParam.cxx @@ -0,0 +1,22 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "StrangenessTracking/HypertrackingConfigParam.h" + +namespace o2 +{ +namespace strangeness_tracking +{ +static auto& sHypertrackerParam = o2::strangeness_tracking::HypertrackerParamConfig::Instance(); + +O2ParamImpl(o2::strangeness_tracking::HypertrackerParamConfig); +} // namespace strangeness_tracking +} // namespace o2 diff --git a/Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h b/Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h new file mode 100644 index 0000000000000..76996b045f537 --- /dev/null +++ b/Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h @@ -0,0 +1,21 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifdef __CLING__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class o2::strangeness_tracking::HypertrackerParamConfig + ; +#pragma link C++ class o2::conf::ConfigurableParamHelper + ; + +#endif diff --git a/Detectors/StrangenessTracking/workflow/CMakeLists.txt b/Detectors/StrangenessTracking/workflow/CMakeLists.txt index 6bb9a0c40d222..62f719d5d2c87 100644 --- a/Detectors/StrangenessTracking/workflow/CMakeLists.txt +++ b/Detectors/StrangenessTracking/workflow/CMakeLists.txt @@ -10,8 +10,14 @@ # or submit itself to any jurisdiction. o2_add_library(StrangenessTrackingWorkflow + TARGETVARNAME targetName SOURCES src/HypertrackingSpec.cxx - PUBLIC_LINK_LIBRARIES O2::Framework) + PUBLIC_LINK_LIBRARIES O2::GlobalTrackingWorkflowReaders + O2::ITSWorkflow + O2::StrangenessTracking + O2::SimulationDataFormat + O2::Framework + O2::DetectorsRaw) o2_add_executable(hypertracking-workflow SOURCES src/hypertracking-workflow.cxx diff --git a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h index ef698a5aa6688..38df3a16774ca 100644 --- a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h +++ b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h @@ -8,23 +8,42 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// @file HyperWorkflow.h -#ifndef O2_STRANGENESS_HYPERTRACKING_WORKFLOW_H -#define O2_STRANGENESS_HYPERTRACKING_WORKFLOW_H +#ifndef O2_HYPERTRACKING_SPEC_H +#define O2_HYPERTRACKING_SPEC_H #include "Framework/WorkflowSpec.h" +#include "Framework/DataProcessorSpec.h" +#include "ITSMFTWorkflow/ClusterReaderSpec.h" +#include "GlobalTrackingWorkflowReaders/SecondaryVertexReaderSpec.h" +#include "Framework/Task.h" +#include + +#include "TStopwatch.h" + namespace o2 { -namespace stangeness_tracking +namespace strangeness_tracking { -framework::WorkflowSpec getWorkflow() +class HypertrackerDPL : public framework::Task { - framework::WorkflowSpec specs; - return specs; -} + public: + HypertrackerDPL() = default; + ~HypertrackerDPL() override = default; + + void init(framework::InitContext& ic) final; + void run(framework::ProcessingContext& pc) final; + void endOfStream(framework::EndOfStreamContext& ec) final; + + private: + TStopwatch mTimer; +}; + +framework::DataProcessorSpec getHyperTrackerSpec(); + +framework::WorkflowSpec getWorkflow(bool upstreamClusters = false, bool upstreamV0s = false); -} // namespace stangeness_tracking +} // namespace strangeness_tracking } // namespace o2 #endif \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx index 83e0ef5e9c295..a23d1361ee34c 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx @@ -9,16 +9,80 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// @file HyperWorkflow.cxx - #include "StrangenessTrackingWorkflow/HypertrackingSpec.h" +#include "ITSWorkflow/ClusterWriterSpec.h" +#include "ITSWorkflow/TrackerSpec.h" +#include "ITSWorkflow/TrackReaderSpec.h" + +#include "DataFormatsITSMFT/CompCluster.h" +#include "DataFormatsITSMFT/ROFRecord.h" namespace o2 { - +using namespace o2::framework; namespace strangeness_tracking { +framework::WorkflowSpec getWorkflow(bool useMC, bool useRootInput) +{ + framework::WorkflowSpec specs; + if (useRootInput) { + specs.emplace_back(o2::itsmft::getITSClusterReaderSpec(useMC, true)); + specs.emplace_back(o2::its::getITSTrackReaderSpec(useMC)); + specs.emplace_back(o2::vertexing::getSecondaryVertexReaderSpec()); + } + specs.emplace_back(getHyperTrackerSpec()); + return specs; +} + +void HypertrackerDPL::init(framework::InitContext& ic) +{ + mTimer.Stop(); + mTimer.Reset(); + + LOG(info) << "Initialized HypertrackerDPL"; +} + +void HypertrackerDPL::run(framework::ProcessingContext& pc) +{ + mTimer.Start(false); + LOG(info) << "Running HypertrackerDPL"; + auto compClusters = pc.inputs().get>("compClusters"); + gsl::span patterns = pc.inputs().get>("patterns"); + + // code further down does assignment to the rofs and the altered object is used for output + // we therefore need a copy of the vector rather than an object created directly on the input data, + // the output vector however is created directly inside the message memory thus avoiding copy by + // snapshot + auto rofsinput = pc.inputs().get>("ROframes"); + mTimer.Stop(); +} + +void HypertrackerDPL::endOfStream(framework::EndOfStreamContext& ec) +{ + LOGF(info, "Hypertracker total timing: Cpu: %.3e Real: %.3e s in %d slots", + mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); +} + +DataProcessorSpec getHyperTrackerSpec() +{ + std::vector inputs; + inputs.emplace_back("compClusters", "ITS", "COMPCLUSTERS", 0, Lifetime::Timeframe); + inputs.emplace_back("ITSTrack", "ITS", "TRACKS", 0, Lifetime::Timeframe); + inputs.emplace_back("asd1", "GLO", "V0S", 0, Lifetime::Timeframe); // found V0s + inputs.emplace_back("asd2", "GLO", "PVTX_V0REFS", 0, Lifetime::Timeframe); // prim.vertex -> V0s refs + inputs.emplace_back("asd3", "GLO", "CASCS", 0, Lifetime::Timeframe); // found Cascades + inputs.emplace_back("asd4", "GLO", "PVTX_CASCREFS", 0, Lifetime::Timeframe); // prim.vertex -> Cascades refs + // inputs.emplace_back("patterns", "ITS", "PATTERNS", 0, Lifetime::Timeframe); + // inputs.emplace_back("ROframes", "ITS", "CLUSTERSROF", 0, Lifetime::Timeframe); + + std::vector outputs; + + return DataProcessorSpec{ + "hypertracker", + inputs, + outputs}; +} } // namespace strangeness_tracking } // namespace o2 \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx b/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx index 846de1573e243..e4fb3764e46f8 100644 --- a/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx +++ b/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx @@ -11,37 +11,28 @@ #include "StrangenessTrackingWorkflow/HypertrackingSpec.h" #include "CommonUtils/ConfigurableParam.h" -// #include "ITStracking/TrackingConfigParam.h" -// #include "ITStracking/Configuration.h" -// #include "DetectorsRaw/HBFUtilsInitializer.h" +#include "StrangenessTracking/HypertrackingConfigParam.h" + +#include "DetectorsRaw/HBFUtilsInitializer.h" #include "Framework/CallbacksPolicy.h" #include "Framework/ConfigContext.h" -// #include "GPUO2Interface.h" -// #include "GPUReconstruction.h" -// #include "GPUChainITS.h" #include using namespace o2::framework; void customize(std::vector& policies) { - // o2::raw::HBFUtilsInitializer::addNewTimeSliceCallback(policies); + o2::raw::HBFUtilsInitializer::addNewTimeSliceCallback(policies); } void customize(std::vector& workflowOptions) { // option allowing to set parameters std::vector options{ - // {"digits-from-upstream", o2::framework::VariantType::Bool, false, {"digits will be provided from upstream, skip digits reader"}}, - // {"clusters-from-upstream", o2::framework::VariantType::Bool, false, {"clusters will be provided from upstream, skip clusterizer"}}, - // {"disable-root-output", o2::framework::VariantType::Bool, false, {"do not write output root files"}}, - // {"disable-mc", o2::framework::VariantType::Bool, false, {"disable MC propagation even if available"}}, - // {"trackerCA", o2::framework::VariantType::Bool, false, {"use trackerCA (default: trackerCM)"}}, - // {"tracking-mode", o2::framework::VariantType::String, "sync", {"sync,async,cosmics"}}, - // {"entropy-encoding", o2::framework::VariantType::Bool, false, {"produce entropy encoded data"}}, - // {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings"}}, - // {"gpuDevice", o2::framework::VariantType::Int, 1, {"use gpu device: CPU=1,CUDA=2,HIP=3 (default: CPU)"}} + {"disable-root-input", o2::framework::VariantType::Bool, false, {"disable root-files input reader"}}, + {"disable-mc", o2::framework::VariantType::Bool, false, {"disable MC"}}, + {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings"}} }; std::swap(workflowOptions, options); @@ -55,26 +46,18 @@ void customize(std::vector& workflowOptions) WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) { // Update the (declared) parameters if changed from the command line - // auto useMC = !configcontext.options().get("disable-mc"); - // auto useCAtracker = configcontext.options().get("trackerCA"); - // auto trmode = configcontext.options().get("tracking-mode"); - // auto gpuDevice = static_cast(configcontext.options().get("gpuDevice")); - // auto extDigits = configcontext.options().get("digits-from-upstream"); - // auto extClusters = configcontext.options().get("clusters-from-upstream"); - // auto disableRootOutput = configcontext.options().get("disable-root-output"); - // auto eencode = configcontext.options().get("entropy-encoding"); - - // std::transform(trmode.begin(), trmode.end(), trmode.begin(), [](unsigned char c) { return std::tolower(c); }); - + auto useMC = !configcontext.options().get("disable-mc"); + auto useRootInput = !configcontext.options().get("disable-root-input"); + o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); - auto wf = o2::stangeness_tracking::getWorkflow(); + auto wf = o2::strangeness_tracking::getWorkflow(useMC, useRootInput); // configure dpl timer to inject correct firstTFOrbit: start from the 1st orbit of TF containing 1st sampled orbit - // o2::raw::HBFUtilsInitializer hbfIni(configcontext, wf); + o2::raw::HBFUtilsInitializer hbfIni(configcontext, wf); // write the configuration used for the reco workflow - o2::conf::ConfigurableParam::writeINI("o2itsrecoflow_configuration.ini"); + o2::conf::ConfigurableParam::writeINI("o2hypertrackingflow_configuration.ini"); return std::move(wf); } From afe06f8245ef6e2e7e94292ecb424f7f1d932578 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Sun, 5 Dec 2021 13:43:29 +0100 Subject: [PATCH 08/36] Hypertracking wf does things --- .../StrangenessTracking/macros/matchV0s.C | 557 +++++++++--------- .../StrangenessTracking/HyperTracker.h | 2 - .../HypertrackingSpec.h | 24 +- .../workflow/src/HypertrackingSpec.cxx | 60 +- 4 files changed, 320 insertions(+), 323 deletions(-) diff --git a/Detectors/StrangenessTracking/macros/matchV0s.C b/Detectors/StrangenessTracking/macros/matchV0s.C index 4262fa41eeccc..2b128166cbecc 100644 --- a/Detectors/StrangenessTracking/macros/matchV0s.C +++ b/Detectors/StrangenessTracking/macros/matchV0s.C @@ -28,7 +28,7 @@ #include "CommonDataFormat/RangeReference.h" #include "DetectorsVertexing/DCAFitterN.h" -#include "hyperTracker.h" +#include "HyperTracker.h" #endif @@ -48,314 +48,299 @@ const int motherPDG = 1010010030; const int firstDaughterPDG = 1000020030; const int secondDaughterPDG = -211; -std::vector> matchV0stoMC(const std::vector> &mcTracksMatrix, std::map *> &map, std::vector *v0vec); -std::array matchITStracktoMC(const std::vector> &mcTracksMatrix, o2::MCCompLabel ITSlabel); -std::vector getTrackClusters(const o2::its::TrackITS &ITStrack, const std::vector &ITSClustersArray, std::vector *ITSTrackClusIdx); +std::vector> matchV0stoMC(const std::vector>& mcTracksMatrix, std::map*>& map, std::vector* v0vec); +std::array matchITStracktoMC(const std::vector>& mcTracksMatrix, o2::MCCompLabel ITSlabel); +std::vector getTrackClusters(const o2::its::TrackITS& ITStrack, const std::vector& ITSClustersArray, std::vector* ITSTrackClusIdx); void matchV0s() { - // Output Histograms - TH1D *hChi2Sgn = new TH1D("Chi2 Signal", "; #chi^{2}; Counts", 102, -2, 100); - TH1D *hChi2Bkg = new TH1D("Chi2 background", "; #chi^{2} (90 is default for overflows and not propagated); Counts", 102, -2, 100); - TH1D *hSigBkg = new TH1D("Hypertracker eff", "; ; Efficiency", 2, 0, 2); - TH2D *hPtResBef = new TH2D("pT resolution before hypertracking", "; #it{p}_{T}^{gen} (GeV); (#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, 0, 10, 20, -1, 1); - TH2D *hPtResAft = new TH2D("pT resolution before hypertracking", "; #it{p}_{T}^{gen} (GeV); (#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, 0, 10, 20, -1, 1); - - // Files - auto fMCTracks = TFile::Open("sgn_Kine.root"); - auto fSecondaries = TFile::Open("o2_secondary_vertex.root"); - auto fITSTPC = TFile::Open("o2match_itstpc.root"); - auto fTPCTOF = TFile::Open("o2match_tof_tpc.root"); - auto fITSTPCTOF = TFile::Open("o2match_tof_itstpc.root"); - - auto fITS = TFile::Open("o2trac_its.root"); - auto fITSclus = TFile::Open("o2clus_its.root"); - - // Geometry - o2::base::GeometryManager::loadGeometry(""); - - // Trees - auto treeMCTracks = (TTree *)fMCTracks->Get("o2sim"); - auto treeSecondaries = (TTree *)fSecondaries->Get("o2sim"); - auto treeITSTPC = (TTree *)fITSTPC->Get("matchTPCITS"); - auto treeITSTPCTOF = (TTree *)fITSTPCTOF->Get("matchTOF"); - auto treeTPCTOF = (TTree *)fTPCTOF->Get("matchTOF"); - - auto treeITS = (TTree *)fITS->Get("o2sim"); - auto treeITSclus = (TTree *)fITSclus->Get("o2sim"); - - // Topology dictionary - o2::itsmft::TopologyDictionary mdict; - mdict.readFromFile(o2::base::NameConf::getAlpideClusterDictionaryFileName(o2::detectors::DetID::ITS)); - - // Tracks - std::vector *MCtracks = nullptr; - std::vector *v0vec = nullptr; - std::vector *ITStracks = nullptr; - std::vector *ITSTrackClusIdx = nullptr; - - // Clusters - std::vector *ITSclus = nullptr; - std::vector *ITSpatt = nullptr; - - // Labels - std::vector *labITSvec = nullptr; - std::vector *labITSTPCvec = nullptr; - std::vector *labITSTPCTOFvec = nullptr; - std::vector *labTPCTOFvec = nullptr; - - // Setting branches - treeSecondaries->SetBranchAddress("V0s", &v0vec); - treeMCTracks->SetBranchAddress("MCTrack", &MCtracks); - treeITSTPC->SetBranchAddress("MatchMCTruth", &labITSTPCvec); - treeTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labTPCTOFvec); - treeITSTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labITSTPCTOFvec); - treeITS->SetBranchAddress("ITSTrackMCTruth", &labITSvec); - treeITS->SetBranchAddress("ITSTrack", &ITStracks); - treeITS->SetBranchAddress("ITSTrackClusIdx", &ITSTrackClusIdx); - - treeITSclus->SetBranchAddress("ITSClusterComp", &ITSclus); - treeITSclus->SetBranchAddress("ITSClusterPatt", &ITSpatt); - - // define detector map - std::map *> map{{"ITS", labITSvec}, {"ITS-TPC", labITSTPCvec}, {"TPC-TOF", labTPCTOFvec}, {"ITS-TPC-TOF", labITSTPCTOFvec}}; - - // load geometry - auto gman = o2::its::GeometryTGeo::Instance(); - gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G)); - - // fill MC matrix - std::vector> mcTracksMatrix; - auto nev = treeMCTracks->GetEntriesFast(); - mcTracksMatrix.resize(nev); - for (int n = 0; n < nev; n++) - { // loop over MC events - treeMCTracks->GetEvent(n); - - mcTracksMatrix[n].resize(MCtracks->size()); - for (unsigned int mcI{0}; mcI < MCtracks->size(); ++mcI) - { - mcTracksMatrix[n][mcI] = MCtracks->at(mcI); - } + // Output Histograms + TH1D* hChi2Sgn = new TH1D("Chi2 Signal", "; #chi^{2}; Counts", 102, -2, 100); + TH1D* hChi2Bkg = new TH1D("Chi2 background", "; #chi^{2} (90 is default for overflows and not propagated); Counts", 102, -2, 100); + TH1D* hSigBkg = new TH1D("Hypertracker eff", "; ; Efficiency", 2, 0, 2); + TH2D* hPtResBef = new TH2D("pT resolution before hypertracking", "; #it{p}_{T}^{gen} (GeV); (#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, 0, 10, 20, -1, 1); + TH2D* hPtResAft = new TH2D("pT resolution before hypertracking", "; #it{p}_{T}^{gen} (GeV); (#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, 0, 10, 20, -1, 1); + + // Files + auto fMCTracks = TFile::Open("sgn_Kine.root"); + auto fSecondaries = TFile::Open("o2_secondary_vertex.root"); + auto fITSTPC = TFile::Open("o2match_itstpc.root"); + auto fTPCTOF = TFile::Open("o2match_tof_tpc.root"); + auto fITSTPCTOF = TFile::Open("o2match_tof_itstpc.root"); + + auto fITS = TFile::Open("o2trac_its.root"); + auto fITSclus = TFile::Open("o2clus_its.root"); + + // Geometry + o2::base::GeometryManager::loadGeometry(""); + + // Trees + auto treeMCTracks = (TTree*)fMCTracks->Get("o2sim"); + auto treeSecondaries = (TTree*)fSecondaries->Get("o2sim"); + auto treeITSTPC = (TTree*)fITSTPC->Get("matchTPCITS"); + auto treeITSTPCTOF = (TTree*)fITSTPCTOF->Get("matchTOF"); + auto treeTPCTOF = (TTree*)fTPCTOF->Get("matchTOF"); + + auto treeITS = (TTree*)fITS->Get("o2sim"); + auto treeITSclus = (TTree*)fITSclus->Get("o2sim"); + + // Topology dictionary + o2::itsmft::TopologyDictionary mdict; + mdict.readFromFile(o2::base::NameConf::getAlpideClusterDictionaryFileName(o2::detectors::DetID::ITS)); + + // Tracks + std::vector* MCtracks = nullptr; + std::vector* v0vec = nullptr; + std::vector* ITStracks = nullptr; + std::vector* ITSTrackClusIdx = nullptr; + + // Clusters + std::vector* ITSclus = nullptr; + std::vector* ITSpatt = nullptr; + + // Labels + std::vector* labITSvec = nullptr; + std::vector* labITSTPCvec = nullptr; + std::vector* labITSTPCTOFvec = nullptr; + std::vector* labTPCTOFvec = nullptr; + + // Setting branches + treeSecondaries->SetBranchAddress("V0s", &v0vec); + treeMCTracks->SetBranchAddress("MCTrack", &MCtracks); + treeITSTPC->SetBranchAddress("MatchMCTruth", &labITSTPCvec); + treeTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labTPCTOFvec); + treeITSTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labITSTPCTOFvec); + treeITS->SetBranchAddress("ITSTrackMCTruth", &labITSvec); + treeITS->SetBranchAddress("ITSTrack", &ITStracks); + treeITS->SetBranchAddress("ITSTrackClusIdx", &ITSTrackClusIdx); + + treeITSclus->SetBranchAddress("ITSClusterComp", &ITSclus); + treeITSclus->SetBranchAddress("ITSClusterPatt", &ITSpatt); + + // define detector map + std::map*> map{{"ITS", labITSvec}, {"ITS-TPC", labITSTPCvec}, {"TPC-TOF", labTPCTOFvec}, {"ITS-TPC-TOF", labITSTPCTOFvec}}; + + // load geometry + auto gman = o2::its::GeometryTGeo::Instance(); + gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G)); + + // fill MC matrix + std::vector> mcTracksMatrix; + auto nev = treeMCTracks->GetEntriesFast(); + mcTracksMatrix.resize(nev); + for (int n = 0; n < nev; n++) { // loop over MC events + treeMCTracks->GetEvent(n); + + mcTracksMatrix[n].resize(MCtracks->size()); + for (unsigned int mcI{0}; mcI < MCtracks->size(); ++mcI) { + mcTracksMatrix[n][mcI] = MCtracks->at(mcI); + } + } + + treeSecondaries->GetEntry(); + treeITS->GetEntry(); + treeITSclus->GetEntry(); + treeITSTPC->GetEntry(); + treeTPCTOF->GetEntry(); + treeITSTPCTOF->GetEntry(); + + std::vector> V0sMCref = matchV0stoMC(mcTracksMatrix, map, v0vec); + + // convert Comp Clusters into 3D point + std::vector mITSClustersArray; + mITSClustersArray.reserve((*ITSclus).size()); + gsl::span spanPatt{*ITSpatt}; + auto pattIt = spanPatt.begin(); + o2::its::ioutils::convertCompactClusters(*ITSclus, pattIt, mITSClustersArray, mdict); + + // preparing DCA Fitter + o2::vertexing::DCAFitterN<2> mFitterV0; + mFitterV0.setBz(-5); + + auto sig_counter = 0.; + auto bkg_counter = 0.; + + // Starting matching loop + for (int frame = 0; frame < treeITS->GetEntriesFast(); frame++) { + if (!treeITS->GetEvent(frame) || !treeITS->GetEvent(frame)) + continue; + if (!treeITS->GetEvent(frame)) { + continue; } - treeSecondaries->GetEntry(); - treeITS->GetEntry(); - treeITSclus->GetEntry(); - treeITSTPC->GetEntry(); - treeTPCTOF->GetEntry(); - treeITSTPCTOF->GetEntry(); - - std::vector> V0sMCref = matchV0stoMC(mcTracksMatrix, map, v0vec); - - // convert Comp Clusters into 3D point - std::vector mITSClustersArray; - mITSClustersArray.reserve((*ITSclus).size()); - gsl::span spanPatt{*ITSpatt}; - auto pattIt = spanPatt.begin(); - o2::its::ioutils::convertCompactClusters(*ITSclus, pattIt, mITSClustersArray, mdict); - - // preparing DCA Fitter - o2::vertexing::DCAFitterN<2> mFitterV0; - mFitterV0.setBz(-5); - - auto sig_counter = 0.; - auto bkg_counter = 0.; - - // Starting matching loop - for (int frame = 0; frame < treeITS->GetEntriesFast(); frame++) - { - if (!treeITS->GetEvent(frame) || !treeITS->GetEvent(frame)) - continue; - if (!treeITS->GetEvent(frame)) - { - continue; + for (unsigned int iTrack{0}; iTrack < labITSvec->size(); ++iTrack) { + auto lab = labITSvec->at(iTrack); + auto ITStrackMCref = matchITStracktoMC(mcTracksMatrix, lab); + auto ITStrack = ITStracks->at(iTrack); + + auto ITSclusters = getTrackClusters(ITStrack, mITSClustersArray, ITSTrackClusIdx); + + for (unsigned int iV0vec = 0; iV0vec < v0vec->size(); iV0vec++) { + auto& v0MCref = V0sMCref[iV0vec]; + auto& v0 = (*v0vec)[iV0vec]; + + if (ITStrackMCref == v0MCref && ITStrackMCref[0] != -1) { + + auto& mcTrack = mcTracksMatrix[v0MCref[0]][v0MCref[1]]; + sig_counter++; + auto hyperTrack = hyperTracker(ITStrack, v0, ITSclusters, gman, mFitterV0); + hyperTrack.setBz(-5.); + // hyperTrack.setNclusMatching(ITSclusters.size()); + hyperTrack.setMaxChi2(40); + auto chi2 = hyperTrack.getMatchingChi2(); + std::cout << "V0 orig Pt: " << v0.getPt() << ", V0 recr Pt: " << hyperTrack.getV0().getPt() << std::endl; + hPtResBef->Fill(mcTrack.GetPt(), (mcTrack.GetPt() - hyperTrack.getV0().getPt()) / mcTrack.GetPt()); + std::cout << "ITS track Pt: " << ITStrack.getPt() << std::endl; + std::cout << "Starting hyperTracking algorithm..." << std::endl; + auto isAcc = hyperTrack.process(); + + std::cout << "After processing hyperTracking algorithm..." << std::endl; + hPtResAft->Fill(mcTrack.GetPt(), (mcTrack.GetPt() - hyperTrack.getV0().getPt()) / mcTrack.GetPt()); + + std::cout << "Is accepted? : " << isAcc << std::endl; + + for (auto i{0}; i < 7; i++) { + if (ITStrack.isFakeOnLayer(i) && ITStrack.hasHitOnLayer(i)) + std::cout << "Fake clusters on layer: " << i << std::endl; + } + + std::cout << "------------------------" << std::endl; + hChi2Sgn->Fill(chi2); + if (isAcc) + hSigBkg->Fill(0.5); } - - for (unsigned int iTrack{0}; iTrack < labITSvec->size(); ++iTrack) - { - auto lab = labITSvec->at(iTrack); - auto ITStrackMCref = matchITStracktoMC(mcTracksMatrix, lab); - auto ITStrack = ITStracks->at(iTrack); - - auto ITSclusters = getTrackClusters(ITStrack, mITSClustersArray, ITSTrackClusIdx); - - for (unsigned int iV0vec = 0; iV0vec < v0vec->size(); iV0vec++) - { - auto &v0MCref = V0sMCref[iV0vec]; - auto &v0 = (*v0vec)[iV0vec]; - - if (ITStrackMCref == v0MCref && ITStrackMCref[0] != -1) - { - - auto &mcTrack = mcTracksMatrix[v0MCref[0]][v0MCref[1]]; - sig_counter++; - auto hyperTrack = hyperTracker(ITStrack, v0, ITSclusters, gman, mFitterV0); - hyperTrack.setBz(-5.); - // hyperTrack.setNclusMatching(ITSclusters.size()); - hyperTrack.setMaxChi2(40); - auto chi2 = hyperTrack.getMatchingChi2(); - std::cout << "V0 orig Pt: " << v0.getPt() << ", V0 recr Pt: " << hyperTrack.getV0().getPt() << std::endl; - hPtResBef->Fill(mcTrack.GetPt(), (mcTrack.GetPt() - hyperTrack.getV0().getPt()) / mcTrack.GetPt()); - std::cout << "ITS track Pt: " << ITStrack.getPt() << std::endl; - std::cout << "Starting hyperTracking algorithm..." << std::endl; - auto isAcc = hyperTrack.process(); - - std::cout << "After processing hyperTracking algorithm..." << std::endl; - hPtResAft->Fill(mcTrack.GetPt(), (mcTrack.GetPt() - hyperTrack.getV0().getPt()) / mcTrack.GetPt()); - - std::cout << "Is accepted? : " << isAcc << std::endl; - - for (auto i{0}; i < 7; i++) - { - if (ITStrack.isFakeOnLayer(i) && ITStrack.hasHitOnLayer(i)) - std::cout << "Fake clusters on layer: " << i << std::endl; - } - - std::cout << "------------------------" << std::endl; - hChi2Sgn->Fill(chi2); - if (isAcc) - hSigBkg->Fill(0.5); - } - if (ITStrackMCref != v0MCref) - { - if (bkg_counter > 20000) - continue; - bkg_counter++; - - auto hyperTrack = hyperTracker(ITStrack, v0, ITSclusters, gman, mFitterV0); - hyperTrack.setBz(-5.); - // hyperTrack.setNclusMatching(ITSclusters.size()); - hyperTrack.setMaxChi2(40); - - auto chi2 = hyperTrack.getMatchingChi2(); - if (chi2 > 90 || chi2 == -1) - chi2 = 90; - auto isAcc = hyperTrack.process(); - hChi2Bkg->Fill(chi2); - if (isAcc) - hSigBkg->Fill(1.5); - } - } + if (ITStrackMCref != v0MCref) { + if (bkg_counter > 20000) + continue; + bkg_counter++; + + auto hyperTrack = hyperTracker(ITStrack, v0, ITSclusters, gman, mFitterV0); + hyperTrack.setBz(-5.); + // hyperTrack.setNclusMatching(ITSclusters.size()); + hyperTrack.setMaxChi2(40); + + auto chi2 = hyperTrack.getMatchingChi2(); + if (chi2 > 90 || chi2 == -1) + chi2 = 90; + auto isAcc = hyperTrack.process(); + hChi2Bkg->Fill(chi2); + if (isAcc) + hSigBkg->Fill(1.5); } + } } - auto outFile = TFile("v0sITSmatch.root", "recreate"); - // efficiency histo - hSigBkg->SetBinContent(1, hSigBkg->GetBinContent(1) / sig_counter); - hSigBkg->SetBinContent(2, hSigBkg->GetBinContent(2) / bkg_counter); - hSigBkg->GetXaxis()->SetBinLabel(1, "Signal"); - hSigBkg->GetXaxis()->SetBinLabel(2, "Background"); - hSigBkg->Write(); - hPtResAft->Write(); - hPtResBef->Write(); - - // chi2 histos - auto *c = new TCanvas("c1", "chi2", 1000, 400); - hChi2Bkg->SetStats(0); - hChi2Sgn->SetLineColor(kRed); - hChi2Sgn->SetLineWidth(2); - hChi2Bkg->SetLineColor(kBlue); - hChi2Bkg->SetLineWidth(2); - c->cd(); - hChi2Bkg->DrawNormalized(); - hChi2Sgn->DrawNormalized("same"); - auto legend = new TLegend(0.55, 0.2, 0.85, 0.4); - legend->SetMargin(0.10); - legend->SetTextSize(0.03); - - legend->AddEntry(hChi2Sgn, "V0-ITStrack #chi^{2} for signal"); - legend->AddEntry(hChi2Bkg, "V0-ITStrack #chi^{2} for background"); - legend->Draw(); - c->Write(); - hChi2Sgn->Write(); - hChi2Bkg->Write(); - outFile.Close(); + } + auto outFile = TFile("v0sITSmatch.root", "recreate"); + // efficiency histo + hSigBkg->SetBinContent(1, hSigBkg->GetBinContent(1) / sig_counter); + hSigBkg->SetBinContent(2, hSigBkg->GetBinContent(2) / bkg_counter); + hSigBkg->GetXaxis()->SetBinLabel(1, "Signal"); + hSigBkg->GetXaxis()->SetBinLabel(2, "Background"); + hSigBkg->Write(); + hPtResAft->Write(); + hPtResBef->Write(); + + // chi2 histos + auto* c = new TCanvas("c1", "chi2", 1000, 400); + hChi2Bkg->SetStats(0); + hChi2Sgn->SetLineColor(kRed); + hChi2Sgn->SetLineWidth(2); + hChi2Bkg->SetLineColor(kBlue); + hChi2Bkg->SetLineWidth(2); + c->cd(); + hChi2Bkg->DrawNormalized(); + hChi2Sgn->DrawNormalized("same"); + auto legend = new TLegend(0.55, 0.2, 0.85, 0.4); + legend->SetMargin(0.10); + legend->SetTextSize(0.03); + + legend->AddEntry(hChi2Sgn, "V0-ITStrack #chi^{2} for signal"); + legend->AddEntry(hChi2Bkg, "V0-ITStrack #chi^{2} for background"); + legend->Draw(); + c->Write(); + hChi2Sgn->Write(); + hChi2Bkg->Write(); + outFile.Close(); } -std::vector> matchV0stoMC(const std::vector> &mcTracksMatrix, std::map *> &map, std::vector *v0vec) +std::vector> matchV0stoMC(const std::vector>& mcTracksMatrix, std::map*>& map, std::vector* v0vec) { - std::vector> outArray; - outArray.resize(v0vec->size()); - int count_V0 = 0; - for (unsigned int iV0vec = 0; iV0vec < v0vec->size(); iV0vec++) - { - std::vector motherIDvec; - std::vector daughterIDvec; - std::vector evIDvec; - - outArray[iV0vec] = {-1, -1}; - auto &v0 = (*v0vec)[iV0vec]; - - for (unsigned int iV0 = 0; iV0 < 2; iV0++) - { - if (map[v0.getProngID(iV0).getSourceName()]) - { - auto labTrackType = map[v0.getProngID(iV0).getSourceName()]; - auto lab = labTrackType->at(v0.getProngID(iV0).getIndex()); - - int trackID, evID, srcID; - bool fake; - lab.get(trackID, evID, srcID, fake); - if (!lab.isNoise() && lab.isValid() && lab.isCorrect() && srcID) - { - auto motherID = mcTracksMatrix[evID][trackID].getMotherTrackId(); - motherIDvec.push_back(motherID); - daughterIDvec.push_back(trackID); - evIDvec.push_back(evID); - } - } + std::vector> outArray; + outArray.resize(v0vec->size()); + int count_V0 = 0; + for (unsigned int iV0vec = 0; iV0vec < v0vec->size(); iV0vec++) { + std::vector motherIDvec; + std::vector daughterIDvec; + std::vector evIDvec; + + outArray[iV0vec] = {-1, -1}; + auto& v0 = (*v0vec)[iV0vec]; + + for (unsigned int iV0 = 0; iV0 < 2; iV0++) { + if (map[v0.getProngID(iV0).getSourceName()]) { + auto labTrackType = map[v0.getProngID(iV0).getSourceName()]; + auto lab = labTrackType->at(v0.getProngID(iV0).getIndex()); + + int trackID, evID, srcID; + bool fake; + lab.get(trackID, evID, srcID, fake); + if (!lab.isNoise() && lab.isValid() && lab.isCorrect() && srcID) { + auto motherID = mcTracksMatrix[evID][trackID].getMotherTrackId(); + motherIDvec.push_back(motherID); + daughterIDvec.push_back(trackID); + evIDvec.push_back(evID); } + } + } - if (motherIDvec.size() < 2) - continue; - if (motherIDvec[0] != motherIDvec[1] || evIDvec[0] != evIDvec[1]) - continue; + if (motherIDvec.size() < 2) + continue; + if (motherIDvec[0] != motherIDvec[1] || evIDvec[0] != evIDvec[1]) + continue; - if (motherIDvec[0] <= 0 || motherIDvec[0] > 10000) - continue; + if (motherIDvec[0] <= 0 || motherIDvec[0] > 10000) + continue; - int pdg0 = mcTracksMatrix[evIDvec[0]][daughterIDvec[0]].GetPdgCode(); - int pdg1 = mcTracksMatrix[evIDvec[0]][daughterIDvec[1]].GetPdgCode(); + int pdg0 = mcTracksMatrix[evIDvec[0]][daughterIDvec[0]].GetPdgCode(); + int pdg1 = mcTracksMatrix[evIDvec[0]][daughterIDvec[1]].GetPdgCode(); - if (pdg0 != firstDaughterPDG && pdg0 != secondDaughterPDG) - continue; - if (pdg1 != firstDaughterPDG && pdg1 != secondDaughterPDG) - continue; + if (pdg0 != firstDaughterPDG && pdg0 != secondDaughterPDG) + continue; + if (pdg1 != firstDaughterPDG && pdg1 != secondDaughterPDG) + continue; - // std::cout << "Mother PDG: " << mcTracksMatrix[evIDvec[0]][motherIDvec[0]].GetPt() << std::endl; - outArray[iV0vec] = {evIDvec[0], motherIDvec[0]}; - count_V0++; - } - std::cout << "Number of V0s: " << count_V0 << std::endl; - return outArray; + // std::cout << "Mother PDG: " << mcTracksMatrix[evIDvec[0]][motherIDvec[0]].GetPt() << std::endl; + outArray[iV0vec] = {evIDvec[0], motherIDvec[0]}; + count_V0++; + } + std::cout << "Number of V0s: " << count_V0 << std::endl; + return outArray; } -std::array matchITStracktoMC(const std::vector> &mcTracksMatrix, o2::MCCompLabel ITSlabel) +std::array matchITStracktoMC(const std::vector>& mcTracksMatrix, o2::MCCompLabel ITSlabel) { - std::array outArray = {-1, -1}; - int trackID, evID, srcID; - bool fake; - ITSlabel.get(trackID, evID, srcID, fake); - if (!ITSlabel.isNoise() && ITSlabel.isValid() && srcID && mcTracksMatrix[evID][trackID].GetPdgCode() == motherPDG) - { - outArray = {evID, trackID}; - // std::cout << "ITS EvID, track Id : " << evID << " " << trackID << std::endl; - // std::cout << "ITS Mother Pt: " << mcTracksMatrix[evID][trackID].GetPt() << std::endl; - } - - return outArray; + std::array outArray = {-1, -1}; + int trackID, evID, srcID; + bool fake; + ITSlabel.get(trackID, evID, srcID, fake); + if (!ITSlabel.isNoise() && ITSlabel.isValid() && srcID && mcTracksMatrix[evID][trackID].GetPdgCode() == motherPDG) { + outArray = {evID, trackID}; + // std::cout << "ITS EvID, track Id : " << evID << " " << trackID << std::endl; + // std::cout << "ITS Mother Pt: " << mcTracksMatrix[evID][trackID].GetPt() << std::endl; + } + + return outArray; } -std::vector getTrackClusters(const o2::its::TrackITS &ITStrack, const std::vector &ITSClustersArray, std::vector *ITSTrackClusIdx) +std::vector getTrackClusters(const o2::its::TrackITS& ITStrack, const std::vector& ITSClustersArray, std::vector* ITSTrackClusIdx) { - std::vector outVec; - auto firstClus = ITStrack.getFirstClusterEntry(); - auto ncl = ITStrack.getNumberOfClusters(); - for (int icl = 0; icl < ncl; icl++) - { - outVec.push_back(ITSClustersArray[(*ITSTrackClusIdx)[firstClus + icl]]); - } - return outVec; + std::vector outVec; + auto firstClus = ITStrack.getFirstClusterEntry(); + auto ncl = ITStrack.getNumberOfClusters(); + for (int icl = 0; icl < ncl; icl++) { + outVec.push_back(ITSClustersArray[(*ITSTrackClusIdx)[firstClus + icl]]); + } + return outVec; } \ No newline at end of file diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h index 4c890e4321ff8..c47c96dd1d286 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h @@ -74,8 +74,6 @@ class HyperTracker float mInitR2; float mMaxChi2 = 40; float mBz = -5; - - ClassDefNV(HyperTracker, 1); }; } // namespace tracking diff --git a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h index 38df3a16774ca..7bad1ab3f11e6 100644 --- a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h +++ b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h @@ -14,35 +14,15 @@ #include "Framework/WorkflowSpec.h" #include "Framework/DataProcessorSpec.h" -#include "ITSMFTWorkflow/ClusterReaderSpec.h" -#include "GlobalTrackingWorkflowReaders/SecondaryVertexReaderSpec.h" #include "Framework/Task.h" -#include - -#include "TStopwatch.h" namespace o2 { namespace strangeness_tracking { -class HypertrackerDPL : public framework::Task -{ - public: - HypertrackerDPL() = default; - ~HypertrackerDPL() override = default; - - void init(framework::InitContext& ic) final; - void run(framework::ProcessingContext& pc) final; - void endOfStream(framework::EndOfStreamContext& ec) final; - - private: - TStopwatch mTimer; -}; - -framework::DataProcessorSpec getHyperTrackerSpec(); - -framework::WorkflowSpec getWorkflow(bool upstreamClusters = false, bool upstreamV0s = false); +o2::framework::DataProcessorSpec getHyperTrackerSpec(); +o2::framework::WorkflowSpec getWorkflow(bool upstreamClusters = false, bool upstreamV0s = false); } // namespace strangeness_tracking } // namespace o2 diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx index a23d1361ee34c..d17635922566d 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx @@ -13,9 +13,14 @@ #include "ITSWorkflow/ClusterWriterSpec.h" #include "ITSWorkflow/TrackerSpec.h" #include "ITSWorkflow/TrackReaderSpec.h" +#include "ITSMFTWorkflow/ClusterReaderSpec.h" +#include "GlobalTrackingWorkflowReaders/SecondaryVertexReaderSpec.h" #include "DataFormatsITSMFT/CompCluster.h" #include "DataFormatsITSMFT/ROFRecord.h" +#include "DataFormatsITS/TrackITS.h" + +#include "StrangenessTracking/HyperTracker.h" namespace o2 { @@ -23,6 +28,22 @@ using namespace o2::framework; namespace strangeness_tracking { +class HypertrackerSpec : public framework::Task +{ + public: + HypertrackerSpec(bool isMC = false); + ~HypertrackerSpec() override = default; + + void init(framework::InitContext& ic) final; + void run(framework::ProcessingContext& pc) final; + void endOfStream(framework::EndOfStreamContext& ec) final; + + private: + bool mIsMC = false; + TStopwatch mTimer; + HyperTracker mTracker; +}; + framework::WorkflowSpec getWorkflow(bool useMC, bool useRootInput) { framework::WorkflowSpec specs; @@ -35,20 +56,31 @@ framework::WorkflowSpec getWorkflow(bool useMC, bool useRootInput) return specs; } -void HypertrackerDPL::init(framework::InitContext& ic) +HypertrackerSpec::HypertrackerSpec(bool isMC) : mIsMC{isMC} +{ + // no ops +} + +void HypertrackerSpec::init(framework::InitContext& ic) { mTimer.Stop(); mTimer.Reset(); - LOG(info) << "Initialized HypertrackerDPL"; + // load geometry + base::GeometryManager::loadGeometry(); + auto gman = o2::its::GeometryTGeo::Instance(); + gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G)); + + LOG(info) << "Initialized Hypertracker..."; } -void HypertrackerDPL::run(framework::ProcessingContext& pc) +void HypertrackerSpec::run(framework::ProcessingContext& pc) { mTimer.Start(false); - LOG(info) << "Running HypertrackerDPL"; + LOG(info) << "Running Hypertracker..."; auto compClusters = pc.inputs().get>("compClusters"); - gsl::span patterns = pc.inputs().get>("patterns"); + auto patterns = pc.inputs().get>("patterns"); + auto itsTracks = pc.inputs().get>("ITSTrack"); // code further down does assignment to the rofs and the altered object is used for output // we therefore need a copy of the vector rather than an object created directly on the input data, @@ -58,7 +90,7 @@ void HypertrackerDPL::run(framework::ProcessingContext& pc) mTimer.Stop(); } -void HypertrackerDPL::endOfStream(framework::EndOfStreamContext& ec) +void HypertrackerSpec::endOfStream(framework::EndOfStreamContext& ec) { LOGF(info, "Hypertracker total timing: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); @@ -69,19 +101,21 @@ DataProcessorSpec getHyperTrackerSpec() std::vector inputs; inputs.emplace_back("compClusters", "ITS", "COMPCLUSTERS", 0, Lifetime::Timeframe); inputs.emplace_back("ITSTrack", "ITS", "TRACKS", 0, Lifetime::Timeframe); - inputs.emplace_back("asd1", "GLO", "V0S", 0, Lifetime::Timeframe); // found V0s - inputs.emplace_back("asd2", "GLO", "PVTX_V0REFS", 0, Lifetime::Timeframe); // prim.vertex -> V0s refs - inputs.emplace_back("asd3", "GLO", "CASCS", 0, Lifetime::Timeframe); // found Cascades - inputs.emplace_back("asd4", "GLO", "PVTX_CASCREFS", 0, Lifetime::Timeframe); // prim.vertex -> Cascades refs - // inputs.emplace_back("patterns", "ITS", "PATTERNS", 0, Lifetime::Timeframe); - // inputs.emplace_back("ROframes", "ITS", "CLUSTERSROF", 0, Lifetime::Timeframe); + inputs.emplace_back("vos", "GLO", "V0S", 0, Lifetime::Timeframe); // found V0s + inputs.emplace_back("v02pvrf", "GLO", "PVTX_V0REFS", 0, Lifetime::Timeframe); // prim.vertex -> V0s refs + inputs.emplace_back("cascs", "GLO", "CASCS", 0, Lifetime::Timeframe); // found Cascades + inputs.emplace_back("cas2pvrf", "GLO", "PVTX_CASCREFS", 0, Lifetime::Timeframe); // prim.vertex -> Cascades refs + inputs.emplace_back("patterns", "ITS", "PATTERNS", 0, Lifetime::Timeframe); + inputs.emplace_back("ROframes", "ITS", "CLUSTERSROF", 0, Lifetime::Timeframe); std::vector outputs; return DataProcessorSpec{ "hypertracker", inputs, - outputs}; + outputs, + AlgorithmSpec{adaptFromTask()}, + }; } } // namespace strangeness_tracking From bbc22a242f35bb0fc2f89ad4663e66d133d34346 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Sun, 5 Dec 2021 19:07:42 +0100 Subject: [PATCH 09/36] Add TPCITS matching with @fmazzasc --- Detectors/StrangenessTracking/workflow/CMakeLists.txt | 1 + .../workflow/src/HypertrackingSpec.cxx | 11 ++++++++++- .../workflow/src/hypertracking-workflow.cxx | 5 ++--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Detectors/StrangenessTracking/workflow/CMakeLists.txt b/Detectors/StrangenessTracking/workflow/CMakeLists.txt index 62f719d5d2c87..9f9056e7073eb 100644 --- a/Detectors/StrangenessTracking/workflow/CMakeLists.txt +++ b/Detectors/StrangenessTracking/workflow/CMakeLists.txt @@ -16,6 +16,7 @@ o2_add_library(StrangenessTrackingWorkflow O2::ITSWorkflow O2::StrangenessTracking O2::SimulationDataFormat + O2::ReconstructionDataFormats O2::Framework O2::DetectorsRaw) diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx index d17635922566d..4c332cbc2a691 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx @@ -15,10 +15,12 @@ #include "ITSWorkflow/TrackReaderSpec.h" #include "ITSMFTWorkflow/ClusterReaderSpec.h" #include "GlobalTrackingWorkflowReaders/SecondaryVertexReaderSpec.h" +#include "GlobalTrackingWorkflowReaders/TrackTPCITSReaderSpec.h" #include "DataFormatsITSMFT/CompCluster.h" #include "DataFormatsITSMFT/ROFRecord.h" #include "DataFormatsITS/TrackITS.h" +#include "ReconstructionDataFormats/TrackTPCITS.h" #include "StrangenessTracking/HyperTracker.h" @@ -51,6 +53,7 @@ framework::WorkflowSpec getWorkflow(bool useMC, bool useRootInput) specs.emplace_back(o2::itsmft::getITSClusterReaderSpec(useMC, true)); specs.emplace_back(o2::its::getITSTrackReaderSpec(useMC)); specs.emplace_back(o2::vertexing::getSecondaryVertexReaderSpec()); + specs.emplace_back(o2::globaltracking::getTrackTPCITSReaderSpec(true)); } specs.emplace_back(getHyperTrackerSpec()); return specs; @@ -81,12 +84,17 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) auto compClusters = pc.inputs().get>("compClusters"); auto patterns = pc.inputs().get>("patterns"); auto itsTracks = pc.inputs().get>("ITSTrack"); + auto tpcITSTracks = pc.inputs().get>("trackTPCITS"); // code further down does assignment to the rofs and the altered object is used for output // we therefore need a copy of the vector rather than an object created directly on the input data, // the output vector however is created directly inside the message memory thus avoiding copy by // snapshot auto rofsinput = pc.inputs().get>("ROframes"); + auto v0s = pc.inputs().get>("v0s"); + + LOGF(info, "clus: %d, patterns: %d, itsTracks: %d, rofsinput: %d, v0s: %d, TPCITStracks: %d", + compClusters.size(), patterns.size(), itsTracks.size(), rofsinput.size(), v0s.size(), tpcITSTracks.size()); mTimer.Stop(); } @@ -101,12 +109,13 @@ DataProcessorSpec getHyperTrackerSpec() std::vector inputs; inputs.emplace_back("compClusters", "ITS", "COMPCLUSTERS", 0, Lifetime::Timeframe); inputs.emplace_back("ITSTrack", "ITS", "TRACKS", 0, Lifetime::Timeframe); - inputs.emplace_back("vos", "GLO", "V0S", 0, Lifetime::Timeframe); // found V0s + inputs.emplace_back("v0s", "GLO", "V0S", 0, Lifetime::Timeframe); // found V0s inputs.emplace_back("v02pvrf", "GLO", "PVTX_V0REFS", 0, Lifetime::Timeframe); // prim.vertex -> V0s refs inputs.emplace_back("cascs", "GLO", "CASCS", 0, Lifetime::Timeframe); // found Cascades inputs.emplace_back("cas2pvrf", "GLO", "PVTX_CASCREFS", 0, Lifetime::Timeframe); // prim.vertex -> Cascades refs inputs.emplace_back("patterns", "ITS", "PATTERNS", 0, Lifetime::Timeframe); inputs.emplace_back("ROframes", "ITS", "CLUSTERSROF", 0, Lifetime::Timeframe); + inputs.emplace_back("trackTPCITS", "GLO", "TPCITS", 0, Lifetime::Timeframe); std::vector outputs; diff --git a/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx b/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx index e4fb3764e46f8..8096dd67ce550 100644 --- a/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx +++ b/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx @@ -32,8 +32,7 @@ void customize(std::vector& workflowOptions) std::vector options{ {"disable-root-input", o2::framework::VariantType::Bool, false, {"disable root-files input reader"}}, {"disable-mc", o2::framework::VariantType::Bool, false, {"disable MC"}}, - {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings"}} - }; + {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings"}}}; std::swap(workflowOptions, options); } @@ -48,7 +47,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) // Update the (declared) parameters if changed from the command line auto useMC = !configcontext.options().get("disable-mc"); auto useRootInput = !configcontext.options().get("disable-root-input"); - + o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); auto wf = o2::strangeness_tracking::getWorkflow(useMC, useRootInput); From b635513c930a47157f448da60f9ac5bb09e706f8 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Mon, 6 Dec 2021 01:44:28 +0100 Subject: [PATCH 10/36] Add all available readers --- .../workflow/CMakeLists.txt | 1 + .../workflow/src/HypertrackingSpec.cxx | 63 ++++++++++++++----- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/Detectors/StrangenessTracking/workflow/CMakeLists.txt b/Detectors/StrangenessTracking/workflow/CMakeLists.txt index 9f9056e7073eb..2dc04a6e082ba 100644 --- a/Detectors/StrangenessTracking/workflow/CMakeLists.txt +++ b/Detectors/StrangenessTracking/workflow/CMakeLists.txt @@ -13,6 +13,7 @@ o2_add_library(StrangenessTrackingWorkflow TARGETVARNAME targetName SOURCES src/HypertrackingSpec.cxx PUBLIC_LINK_LIBRARIES O2::GlobalTrackingWorkflowReaders + O2::GlobalTrackingWorkflow O2::ITSWorkflow O2::StrangenessTracking O2::SimulationDataFormat diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx index 4c332cbc2a691..a553087fe5b72 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx @@ -16,11 +16,13 @@ #include "ITSMFTWorkflow/ClusterReaderSpec.h" #include "GlobalTrackingWorkflowReaders/SecondaryVertexReaderSpec.h" #include "GlobalTrackingWorkflowReaders/TrackTPCITSReaderSpec.h" +#include "GlobalTrackingWorkflow/TOFMatcherSpec.h" #include "DataFormatsITSMFT/CompCluster.h" #include "DataFormatsITSMFT/ROFRecord.h" #include "DataFormatsITS/TrackITS.h" #include "ReconstructionDataFormats/TrackTPCITS.h" +#include "SimulationDataFormat/MCCompLabel.h" #include "StrangenessTracking/HyperTracker.h" @@ -54,6 +56,8 @@ framework::WorkflowSpec getWorkflow(bool useMC, bool useRootInput) specs.emplace_back(o2::its::getITSTrackReaderSpec(useMC)); specs.emplace_back(o2::vertexing::getSecondaryVertexReaderSpec()); specs.emplace_back(o2::globaltracking::getTrackTPCITSReaderSpec(true)); + // auto src = o2::dataformats::GlobalTrackID::Source::ITSTPCTOF | o2::dataformats::GlobalTrackID::Source::ITSTPC | o2::dataformats::GlobalTrackID::Source::TPCTOF; + // specs.emplace_back(o2::globaltracking::getTOFMatcherSpec(src, true, false, false, 0)); } specs.emplace_back(getHyperTrackerSpec()); return specs; @@ -81,20 +85,35 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) { mTimer.Start(false); LOG(info) << "Running Hypertracker..."; - auto compClusters = pc.inputs().get>("compClusters"); - auto patterns = pc.inputs().get>("patterns"); - auto itsTracks = pc.inputs().get>("ITSTrack"); + // ITS + auto ITSclus = pc.inputs().get>("compClusters"); + auto ITSpatt = pc.inputs().get>("patterns"); + auto ITStracks = pc.inputs().get>("ITSTrack"); + auto ROFsInput = pc.inputs().get>("ROframes"); + auto ITSTrackClusIdx = pc.inputs().get>("trackITSClIdx"); + + // V0 + auto v0vec = pc.inputs().get>("v0s"); auto tpcITSTracks = pc.inputs().get>("trackTPCITS"); - // code further down does assignment to the rofs and the altered object is used for output - // we therefore need a copy of the vector rather than an object created directly on the input data, - // the output vector however is created directly inside the message memory thus avoiding copy by - // snapshot - auto rofsinput = pc.inputs().get>("ROframes"); - auto v0s = pc.inputs().get>("v0s"); - - LOGF(info, "clus: %d, patterns: %d, itsTracks: %d, rofsinput: %d, v0s: %d, TPCITStracks: %d", - compClusters.size(), patterns.size(), itsTracks.size(), rofsinput.size(), v0s.size(), tpcITSTracks.size()); + // Monte Carlo + auto labITSTPC = pc.inputs().get>("trackITSTPCMCTR"); + // auto labTPCTOF = pc.inputs().get>("clsTOF_TPC_MCTR"); + // auto labITSTPCTOF = pc.inputs().get>("clsTOF_GLO_MCTR"); + auto labITS = pc.inputs().get>("trackITSMCTR"); + LOGF(info, "ITSclus: %d \nITSpatt: %d \nITStracks: %d \nROFsInput: %d \nITSTrackClusIdx: %d \nTPCITStracks: %d \nv0s: %d \nlabITSTPC: %d\nlabITS: %d", + ITSclus.size(), + ITSpatt.size(), + ITStracks.size(), + ROFsInput.size(), + ITSTrackClusIdx.size(), + tpcITSTracks.size(), + v0vec.size(), + labITSTPC.size(), + // labTPCTOF.size(), + // labITSTPCTOF.size(), + labITS.size()); + // \nlabTPCTOF: %d\nlabITSTPCTOF: %d mTimer.Stop(); } @@ -107,16 +126,32 @@ void HypertrackerSpec::endOfStream(framework::EndOfStreamContext& ec) DataProcessorSpec getHyperTrackerSpec() { std::vector inputs; + + // ITS inputs.emplace_back("compClusters", "ITS", "COMPCLUSTERS", 0, Lifetime::Timeframe); + inputs.emplace_back("patterns", "ITS", "PATTERNS", 0, Lifetime::Timeframe); + inputs.emplace_back("ROframes", "ITS", "CLUSTERSROF", 0, Lifetime::Timeframe); + inputs.emplace_back("trackITSClIdx", "ITS", "TRACKCLSID", 0, Lifetime::Timeframe); inputs.emplace_back("ITSTrack", "ITS", "TRACKS", 0, Lifetime::Timeframe); + + // V0 inputs.emplace_back("v0s", "GLO", "V0S", 0, Lifetime::Timeframe); // found V0s inputs.emplace_back("v02pvrf", "GLO", "PVTX_V0REFS", 0, Lifetime::Timeframe); // prim.vertex -> V0s refs inputs.emplace_back("cascs", "GLO", "CASCS", 0, Lifetime::Timeframe); // found Cascades inputs.emplace_back("cas2pvrf", "GLO", "PVTX_CASCREFS", 0, Lifetime::Timeframe); // prim.vertex -> Cascades refs - inputs.emplace_back("patterns", "ITS", "PATTERNS", 0, Lifetime::Timeframe); - inputs.emplace_back("ROframes", "ITS", "CLUSTERSROF", 0, Lifetime::Timeframe); + + // TPC-ITS inputs.emplace_back("trackTPCITS", "GLO", "TPCITS", 0, Lifetime::Timeframe); + // TPC-TOF + // inputs.emplace_back("matchTPCTOF", "TOF", "MTC_TPC", 0, Lifetime::Timeframe); // Matching input type manually set to 0 + + // Monte Carlo + inputs.emplace_back("trackITSTPCMCTR", "GLO", "TPCITS_MC", 0, Lifetime::Timeframe); // MC truth + // inputs.emplace_back("clsTOF_GLO_MCTR", "TOF", "MCMTC_ITSTPC", 0, Lifetime::Timeframe); // MC truth + inputs.emplace_back("trackITSMCTR", "ITS", "TRACKSMCTR", 0, Lifetime::Timeframe); // MC truth + // inputs.emplace_back("clsTOF_TPC_MCTR", "TOF", "MCMTC_TPC", 0, Lifetime::Timeframe); // MC truth, // Matching input type manually set to 0 + std::vector outputs; return DataProcessorSpec{ From 99e4b98e0b4b5ddf15817a9358a13a7131419689 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Thu, 13 Jan 2022 17:52:41 +0100 Subject: [PATCH 11/36] First version of hypertracking workflow --- .../src/ReconstructionDataFormatsLinkDef.h | 3 + .../StrangenessTracking/HyperTracker.h | 79 +++--- .../tracking/src/HyperTracker.cxx | 227 +++++++++--------- .../workflow/CMakeLists.txt | 1 + .../HypertrackingWriterSpec.h | 31 +++ .../workflow/src/HypertrackingSpec.cxx | 51 +++- .../workflow/src/HypertrackingWriterSpec.cxx | 59 +++++ .../workflow/src/hypertracking-workflow.cxx | 5 + 8 files changed, 314 insertions(+), 142 deletions(-) create mode 100644 Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingWriterSpec.h create mode 100644 Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx diff --git a/DataFormats/Reconstruction/src/ReconstructionDataFormatsLinkDef.h b/DataFormats/Reconstruction/src/ReconstructionDataFormatsLinkDef.h index ad235797d79ff..da3f5ac1ca0c0 100644 --- a/DataFormats/Reconstruction/src/ReconstructionDataFormatsLinkDef.h +++ b/DataFormats/Reconstruction/src/ReconstructionDataFormatsLinkDef.h @@ -24,6 +24,9 @@ #pragma link C++ class o2::track::TrackParCovD + ; #pragma link C++ class o2::track::TrackParCov + ; #pragma link C++ class o2::track::TrackParametrizationWithError < float> + ; +#pragma link C++ class std::vector > + ; + + #pragma link C++ class o2::track::TrackParametrizationWithError < double> + ; #pragma link C++ class o2::track::TrackParFwd + ; #pragma link C++ class o2::track::PID + ; diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h index c47c96dd1d286..09a178f55f986 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h @@ -10,18 +10,23 @@ // or submit itself to any jurisdiction. /// \file HyperTracker.h -/// \brief hypertracker +/// \brief /// #ifndef _ALICEO2_HYPER_TRACKER_ #define _ALICEO2_HYPER_TRACKER_ + +#include +#include +#include "TMath.h" + #include "ReconstructionDataFormats/PID.h" #include "ReconstructionDataFormats/V0.h" #include "DataFormatsITS/TrackITS.h" #include "ITSBase/GeometryTGeo.h" #include "ReconstructionDataFormats/Track.h" -#include -#include "TMath.h" +#include "DataFormatsITSMFT/CompCluster.h" + #include "DetectorsVertexing/DCAFitterN.h" #include "DetectorsBase/Propagator.h" @@ -41,42 +46,60 @@ class HyperTracker using DCAFitter3 = o2::vertexing::DCAFitterN<3>; HyperTracker() = default; - HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0); // recompute V0 using hypertriton hypothesis - HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman); + ~HyperTracker() = default; - double getMatchingChi2(); - double calcV0alpha(const V0& v0); - bool process(); - bool propagateToClus(const ITSCluster& clus, o2::track::TrackParCov& track); - bool updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track); - bool recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID); - V0& getV0() { return hypV0; }; - bool Refit3Body(); + std::vector& getV0() { return mV0s; }; + std::vector& getHyperTracks() { return mHyperTracks; }; + std::vector& getITStrackRef() { return mITStrackRef; }; - float getNclusMatching() const { return nClusMatching; } - void setNclusMatching(float d) { nClusMatching = d; } float getMaxChi2() const { return mMaxChi2; } void setMaxChi2(float d) { mMaxChi2 = d; } - float getBz() const { return mBz; } void setBz(float d) { mBz = d; } + void setupFitters() + { + mFitterV0.setBz(mBz); + mFitter3Body.setBz(mBz); + mFitterV0.setUseAbsDCA(true); + mFitter3Body.setUseAbsDCA(true); + } + + bool loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, o2::its::GeometryTGeo* geomITS, float Bz); + double calcV0alpha(const V0& v0); + std::vector getTrackClusters(o2::its::TrackITS const& ITStrack); + + bool updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track); + + void process(); + + bool recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID); + bool refitAllTracks(); + protected: - TrackITS hyperTrack; // track of hypertriton mother - V0 hypV0; // V0 of decay daughters - std::vector hyperClusters; // clusters of hypertriton mother - o2::its::GeometryTGeo* geomITS; // geometry for ITS clusters - DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis - DCAFitter3 mFitter3Body; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis - - int nClusMatching; // number of cluster to be matched to V0 - float mInitR2; - float mMaxChi2 = 40; - float mBz = -5; + gsl::span mInputITStracks; // input ITS tracks + std::vector mInputITSclusters; // input ITS clusters + gsl::span mInputITSidxs; // input ITS track-cluster indexes + gsl::span mInputV0tracks; // input V0 of decay daughters + + std::vector mHyperTracks; // Final hypertrack + std::vector mV0s; // V0 of decay daughters + std::vector mITStrackRef; // Ref to the ITS track + + DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis + DCAFitter3 mFitter3Body; // optional DCA Fitter for final 3 Body refit + + float mMaxChi2 = 40; // Maximum matching chi2 + float mBz = -5; // Magnetic field + + o2::its::GeometryTGeo* mGeomITS; // ITS geometry + V0 mV0; // V0 employed for the tracking + + ClassDefNV(HyperTracker, 1); }; -} // namespace tracking +} // namespace strangeness_tracking } // namespace o2 #endif // _ALICEO2_HYPER_TRACKER_ diff --git a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx index 84ff345c71caa..3aa4ee61929ba 100644 --- a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx @@ -8,121 +8,143 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +/// \file HyperTracker.cxx +/// \brief #include "StrangenessTracking/HyperTracker.h" + namespace o2 { namespace strangeness_tracking { +using ITSCluster = o2::BaseCluster; -HyperTracker::HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0) - : hyperTrack{motherTrack}, hyperClusters{motherClusters}, geomITS{gman}, mFitterV0{mFitterV0} +bool HyperTracker::loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, o2::its::GeometryTGeo* geomITS, float Bz) { - mInitR2 = v0.calcR2(); - LOG(info) << "Original V0 radius: " << v0.calcR2(); - - auto posTrack = v0.getProng(0); - auto negTrack = v0.getProng(1); - auto alphaV0 = calcV0alpha(v0); - alphaV0 > 0 ? posTrack.setAbsCharge(2) : negTrack.setAbsCharge(2); - - auto isRecr = recreateV0(posTrack, negTrack, v0.getProngID(0), v0.getProngID(1)); - - if (!isRecr) { - LOG(info) << "V0 regeneration not successful, using default one"; - hypV0 = v0; - } - setNclusMatching(motherClusters.size()); + mInputV0tracks = InputV0tracks; + mInputITStracks = InputITStracks; + mInputITSclusters = InputITSclusters; + mInputITSidxs = InputITSidxs; + LOG(INFO) << "all tracks loaded"; + LOG(INFO) << "V0 tracks size: " << mInputV0tracks.size(); + LOG(INFO) << "ITS tracks size: " << mInputITStracks.size(); + LOG(INFO) << "ITS clusters size: " << mInputITSclusters.size(); + LOG(INFO) << "ITS idxs size: " << mInputITSidxs.size(); + + mBz = Bz; + mGeomITS = geomITS; + setupFitters(); + return true; } -HyperTracker::HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector& motherClusters, o2::its::GeometryTGeo* gman) - : hyperTrack{motherTrack}, hypV0{v0}, hyperClusters{motherClusters}, geomITS{gman} +double HyperTracker::calcV0alpha(const V0& v0) { - setNclusMatching(motherClusters.size()); -} + std::array fV0mom, fPmom, fNmom = {0, 0, 0}; + v0.getProng(0).getPxPyPzGlo(fPmom); + v0.getProng(1).getPxPyPzGlo(fNmom); + v0.getPxPyPzGlo(fV0mom); -double HyperTracker::getMatchingChi2() -{ - auto& outerClus = hyperClusters[0]; - float alpha = geomITS->getSensorRefAlpha(outerClus.getSensorID()), x = outerClus.getX(); + TVector3 momNeg(fNmom[0], fNmom[1], fNmom[2]); + TVector3 momPos(fPmom[0], fPmom[1], fPmom[2]); + TVector3 momTot(fV0mom[0], fV0mom[1], fV0mom[2]); - auto p0 = hypV0.getProng(0); - auto p1 = hypV0.getProng(1); + Double_t lQlNeg = momNeg.Dot(momTot) / momTot.Mag(); + Double_t lQlPos = momPos.Dot(momTot) / momTot.Mag(); - if (hypV0.rotate(alpha)) { - if (hypV0.propagateTo(x, mBz)) { + return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); +} - std::cout << "Pred chi2 outermost Cluster: " << hypV0.getPredictedChi2(outerClus) << std::endl; - std::cout << "Pred chi2 V0-ITStrack: " << hypV0.getPredictedChi2(hyperTrack.getParamOut()) << std::endl; - return hypV0.getPredictedChi2(outerClus); - } +std::vector HyperTracker::getTrackClusters(o2::its::TrackITS const& ITStrack) +{ + std::vector outVec; + auto firstClus = ITStrack.getFirstClusterEntry(); + auto ncl = ITStrack.getNumberOfClusters(); + for (int icl = 0; icl < ncl; icl++) { + outVec.push_back(mInputITSclusters[mInputITSidxs[firstClus + icl]]); } - return -1; + return outVec; } -bool HyperTracker::process() +void HyperTracker::process() { - std::vector ITSclusV0; - int isProcessed = 0; - bool tryDaughter = true; - - for (auto& clus : hyperClusters) { - auto diffR2 = mInitR2 - clus.getX() * clus.getX() - clus.getY() * clus.getY(); - - // check V0 compatibility - if (diffR2 > -4) { - if (updateTrack(clus, hypV0)) { - tryDaughter = false; - LOG(info) << "Attach cluster to V0 for layer: " << geomITS->getLayer(clus.getSensorID()); - isProcessed++; - ITSclusV0.push_back(clus); - } - } - - // if V0 is not found, check He3 compatibility - if (diffR2 < 4 && tryDaughter == true) { - auto& he3track = calcV0alpha(hypV0) > 0 ? hypV0.getProng(0) : hypV0.getProng(1); - if (!updateTrack(clus, he3track)) - return false; // no V0 or He3 compatible clusters - recreateV0(hypV0.getProng(0), hypV0.getProng(1), hypV0.getProngID(0), hypV0.getProngID(1)); - LOG(info) << "Attach cluster to He3 for layer: " << geomITS->getLayer(clus.getSensorID()); - isProcessed++; + int counter = 0; + for (auto& v0 : mInputV0tracks) { + counter++; + LOG(INFO) << "Analysing V0: " << counter << "/" << mInputV0tracks.size(); + + auto posTrack = v0.getProng(0); + auto negTrack = v0.getProng(1); + auto alphaV0 = calcV0alpha(v0); + alphaV0 > 0 ? posTrack.setAbsCharge(2) : negTrack.setAbsCharge(2); + if (!recreateV0(posTrack, negTrack, v0.getProngID(0), v0.getProngID(1))) continue; - } - if (isProcessed == 0) - return false; // no V0 or He3 compatible clusters - } - - // outward V0 propagation - if (ITSclusV0.size() > 0) { - hypV0.resetCovariance(); - std::reverse(ITSclusV0.begin(), ITSclusV0.end()); - for (auto& clus : ITSclusV0) { - if (!updateTrack(clus, hypV0)) - return false; + auto v0R2 = v0.calcR2(); + + for (int iTrack{0}; iTrack < mInputITStracks.size(); iTrack++) { + + auto &ITStrack = mInputITStracks[iTrack]; + auto trackClusters = getTrackClusters(ITStrack); + std::vector v0Clusters; + + for (auto& clus : trackClusters) { + auto isV0Upd = false; + auto diffR2 = v0R2 - clus.getX() * clus.getX() - clus.getY() * clus.getY(); // difference between V0 and Layer R2 + // check V0 compatibility + if (diffR2 > -4) { + // LOG(INFO) << "Try to attach V0 for layer: " << mGeomITS->getLayer(clus.getSensorID()); + if (updateTrack(clus, mV0)) { + // LOG(INFO) << "Attach cluster to V0 for layer: " << mGeomITS->getLayer(clus.getSensorID()); + isV0Upd = true; + v0Clusters.push_back(clus); + } + } + // if V0 is not found, check He3 compatibility + if (diffR2 < 4 && !isV0Upd) { + // LOG(INFO) << "Try to attach He3 for layer: " << mGeomITS->getLayer(clus.getSensorID()); + auto& he3track = calcV0alpha(mV0) > 0 ? mV0.getProng(0) : mV0.getProng(1); + if (!updateTrack(clus, he3track)) { + break; + } + recreateV0(mV0.getProng(0), mV0.getProng(1), mV0.getProngID(0), mV0.getProngID(1)); + // LOG(INFO) << "Attach cluster to He3 for layer: " << mGeomITS->getLayer(clus.getSensorID()); + } + + o2::track::TrackParCov hyperTrack = mV0; + // outward V0 propagation + if (v0Clusters.size() > 0) { + mV0.resetCovariance(); + std::reverse(v0Clusters.begin(), v0Clusters.end()); + for (auto& clus : v0Clusters) { + if (!updateTrack(clus, mV0)) + break; + } + } + + // final 3body refit + if (refitAllTracks()) { + mV0s.push_back(mV0); + mHyperTracks.push_back(hyperTrack); + mITStrackRef.push_back(iTrack); + } + } } } - - // final 3body refit - auto finalRefit = Refit3Body(); - if (!finalRefit) - return false; - LOG(info) << "Final V0 radius: " << hypV0.calcR2(); - return isProcessed >= nClusMatching; } bool HyperTracker::updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track) { - int isUpdated = 0; - float alpha = geomITS->getSensorRefAlpha(clus.getSensorID()), x = clus.getX(); - int layer{geomITS->getLayer(clus.getSensorID())}; + float alpha = mGeomITS->getSensorRefAlpha(clus.getSensorID()), x = clus.getX(); + int layer{mGeomITS->getLayer(clus.getSensorID())}; float thick = layer < 3 ? 0.005 : 0.01; if (track.rotate(alpha)) { + if (track.propagateTo(x, mBz)) { constexpr float radl = 9.36f; // Radiation length of Si [cm] constexpr float rho = 2.33f; // Density of Si [g/cm^3] - if (track.correctForMaterial(thick, thick * rho * radl) && track.getPredictedChi2(clus) < mMaxChi2 && track.getPredictedChi2(clus) > 0) { + + auto chi2 = std::abs(track.getPredictedChi2(clus)); + if (track.correctForMaterial(thick, thick * rho * radl) && chi2 < mMaxChi2 && chi2 > 0) { track.update(clus); return true; } @@ -134,9 +156,7 @@ bool HyperTracker::updateTrack(const ITSCluster& clus, o2::track::TrackParCov& t bool HyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID) { - int cand = 0; // best V0 candidate int nCand; - try { nCand = mFitterV0.process(posTrack, negTrack); } catch (std::runtime_error& e) { @@ -146,29 +166,29 @@ bool HyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2:: return false; mFitterV0.propagateTracksToVertex(); + const auto& v0XYZ = mFitterV0.getPCACandidatePos(); + auto& propPos = mFitterV0.getTrack(0, 0); auto& propNeg = mFitterV0.getTrack(1, 0); - const auto& v0XYZ = mFitterV0.getPCACandidatePos(); std::array pP, pN; propPos.getPxPyPzGlo(pP); propNeg.getPxPyPzGlo(pN); std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; - hypV0 = V0(v0XYZ, pV0, mFitterV0.calcPCACovMatrixFlat(cand), propPos, propNeg, posID, negID, o2::track::PID::HyperTriton); - hypV0.setAbsCharge(1); - hypV0.setPID(o2::track::PID::HyperTriton); + mV0 = V0(v0XYZ, pV0, mFitterV0.calcPCACovMatrixFlat(0), propPos, propNeg, posID, negID, o2::track::PID::HyperTriton); + mV0.setAbsCharge(1); + mV0.setPID(o2::track::PID::HyperTriton); return true; } -bool HyperTracker::Refit3Body() +bool HyperTracker::refitAllTracks() { - int cand = 0; // best V0 candidate int nCand; try { - nCand = mFitter3Body.process(hypV0, hypV0.getProng(0), hypV0.getProng(1)); + nCand = mFitter3Body.process(mV0, mV0.getProng(0), mV0.getProng(1)); } catch (std::runtime_error& e) { return false; } @@ -185,27 +205,10 @@ bool HyperTracker::Refit3Body() propNeg.getPxPyPzGlo(pN); std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; - hypV0 = V0(v0XYZ, pV0, mFitter3Body.calcPCACovMatrixFlat(cand), propPos, propNeg, hypV0.getProngID(0), hypV0.getProngID(1), o2::track::PID::HyperTriton); - hypV0.setAbsCharge(1); + mV0 = V0(v0XYZ, pV0, mFitter3Body.calcPCACovMatrixFlat(cand), propPos, propNeg, mV0.getProngID(0), mV0.getProngID(1), o2::track::PID::HyperTriton); + mV0.setAbsCharge(1); return true; } -double HyperTracker::calcV0alpha(const V0& v0) -{ - std::array fV0mom, fPmom, fNmom = {0, 0, 0}; - v0.getProng(0).getPxPyPzGlo(fPmom); - v0.getProng(1).getPxPyPzGlo(fNmom); - v0.getPxPyPzGlo(fV0mom); - - TVector3 momNeg(fNmom[0], fNmom[1], fNmom[2]); - TVector3 momPos(fPmom[0], fPmom[1], fPmom[2]); - TVector3 momTot(fV0mom[0], fV0mom[1], fV0mom[2]); - - Double_t lQlNeg = momNeg.Dot(momTot) / momTot.Mag(); - Double_t lQlPos = momPos.Dot(momTot) / momTot.Mag(); - - return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); -} - -} // namespace tracking +} // namespace strangeness_tracking } // namespace o2 \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/CMakeLists.txt b/Detectors/StrangenessTracking/workflow/CMakeLists.txt index 2dc04a6e082ba..979ecda225d71 100644 --- a/Detectors/StrangenessTracking/workflow/CMakeLists.txt +++ b/Detectors/StrangenessTracking/workflow/CMakeLists.txt @@ -12,6 +12,7 @@ o2_add_library(StrangenessTrackingWorkflow TARGETVARNAME targetName SOURCES src/HypertrackingSpec.cxx + SOURCES src/HypertrackingWriterSpec.cxx PUBLIC_LINK_LIBRARIES O2::GlobalTrackingWorkflowReaders O2::GlobalTrackingWorkflow O2::ITSWorkflow diff --git a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingWriterSpec.h b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingWriterSpec.h new file mode 100644 index 0000000000000..1dc37fc9fe14b --- /dev/null +++ b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingWriterSpec.h @@ -0,0 +1,31 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// @file TrackWriterSpec.h + +#ifndef O2_HYPERTRACKINGWRITER +#define O2_HYPERTRACKINGWRITER + +#include "Framework/DataProcessorSpec.h" + +namespace o2 +{ +namespace strangeness_tracking +{ + +/// create a processor spec +/// write ITS tracks to ROOT file +o2::framework::DataProcessorSpec getHypertrackingWriterSpec(); + +} // namespace strangeness_tracking +} // namespace o2 + +#endif /* O2_HYPERTRACKINGWRITER */ diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx index a553087fe5b72..52fbc741a5d5c 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx @@ -9,6 +9,9 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include "TGeoGlobalMagField.h" +#include "DataFormatsParameters/GRPObject.h" + #include "StrangenessTrackingWorkflow/HypertrackingSpec.h" #include "ITSWorkflow/ClusterWriterSpec.h" #include "ITSWorkflow/TrackerSpec.h" @@ -23,9 +26,14 @@ #include "DataFormatsITS/TrackITS.h" #include "ReconstructionDataFormats/TrackTPCITS.h" #include "SimulationDataFormat/MCCompLabel.h" +#include "ITStracking/IOUtils.h" +#include "ITSMFTReconstruction/ClustererParam.h" +#include "DetectorsCommonDataFormats/DetectorNameConf.h" #include "StrangenessTracking/HyperTracker.h" +#include + namespace o2 { using namespace o2::framework; @@ -35,6 +43,8 @@ namespace strangeness_tracking class HypertrackerSpec : public framework::Task { public: + using ITSCluster = o2::BaseCluster; + HypertrackerSpec(bool isMC = false); ~HypertrackerSpec() override = default; @@ -44,8 +54,10 @@ class HypertrackerSpec : public framework::Task private: bool mIsMC = false; + bool mRecreateV0 = true; TStopwatch mTimer; HyperTracker mTracker; + std::unique_ptr mGRP = nullptr; }; framework::WorkflowSpec getWorkflow(bool useMC, bool useRootInput) @@ -73,6 +85,14 @@ void HypertrackerSpec::init(framework::InitContext& ic) mTimer.Stop(); mTimer.Reset(); + // auto filename = ic.options().get("grp-file"); + // const auto grp = parameters::GRPObject::loadFrom(filename); + // if (grp) { + // mGRP.reset(grp); + // base::Propagator::initFieldFromGRP(grp); + // auto field = static_cast(TGeoGlobalMagField::Instance()->GetField()); + // } + // load geometry base::GeometryManager::loadGeometry(); auto gman = o2::its::GeometryTGeo::Instance(); @@ -114,6 +134,29 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) // labITSTPCTOF.size(), labITS.size()); // \nlabTPCTOF: %d\nlabITSTPCTOF: %d + + // ITS dict + o2::itsmft::TopologyDictionary ITSdict; + std::string dictPath = o2::itsmft::ClustererParam::Instance().dictFilePath; + std::string dictFile = o2::base::DetectorNameConf::getAlpideClusterDictionaryFileName(o2::detectors::DetID::ITS, dictPath); + ITSdict.readFromFile(dictFile); + + auto pattIt = ITSpatt.begin(); + std::vector ITSClustersArray; + ITSClustersArray.reserve(ITSclus.size()); + o2::its::ioutils::convertCompactClusters(ITSclus, pattIt, ITSClustersArray, ITSdict); + + auto geom = o2::its::GeometryTGeo::Instance(); + + mTracker.loadData(ITStracks, ITSClustersArray, ITSTrackClusIdx, v0vec, geom, -5.); + mTracker.process(); + + pc.outputs().snapshot(Output{"HYP", "V0S", 0, Lifetime::Timeframe}, mTracker.getV0()); + pc.outputs().snapshot(Output{"HYP", "HYPERTRACKS", 0, Lifetime::Timeframe}, mTracker.getHyperTracks()); + pc.outputs().snapshot(Output{"HYP", "ITSREFS", 0, Lifetime::Timeframe}, mTracker.getITStrackRef()); + + + mTimer.Stop(); } @@ -147,12 +190,16 @@ DataProcessorSpec getHyperTrackerSpec() // inputs.emplace_back("matchTPCTOF", "TOF", "MTC_TPC", 0, Lifetime::Timeframe); // Matching input type manually set to 0 // Monte Carlo - inputs.emplace_back("trackITSTPCMCTR", "GLO", "TPCITS_MC", 0, Lifetime::Timeframe); // MC truth + inputs.emplace_back("trackITSTPCMCTR", "GLO", "TPCITS_MC", 0, Lifetime::Timeframe); // MC truth // inputs.emplace_back("clsTOF_GLO_MCTR", "TOF", "MCMTC_ITSTPC", 0, Lifetime::Timeframe); // MC truth - inputs.emplace_back("trackITSMCTR", "ITS", "TRACKSMCTR", 0, Lifetime::Timeframe); // MC truth + inputs.emplace_back("trackITSMCTR", "ITS", "TRACKSMCTR", 0, Lifetime::Timeframe); // MC truth // inputs.emplace_back("clsTOF_TPC_MCTR", "TOF", "MCMTC_TPC", 0, Lifetime::Timeframe); // MC truth, // Matching input type manually set to 0 std::vector outputs; + outputs.emplace_back("HYP", "V0S", 0, Lifetime::Timeframe); + outputs.emplace_back("HYP", "HYPERTRACKS", 0, Lifetime::Timeframe); + outputs.emplace_back("HYP", "ITSREFS", 0, Lifetime::Timeframe); + return DataProcessorSpec{ "hypertracker", diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx new file mode 100644 index 0000000000000..3c5f357276533 --- /dev/null +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx @@ -0,0 +1,59 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// @file HypertrackingWriterSpec.cxx + +#include +#include "StrangenessTrackingWorkflow/HypertrackingWriterSpec.h" +#include "DPLUtils/MakeRootTreeWriterSpec.h" +#include "CommonDataFormat/TimeStamp.h" +#include "CommonDataFormat/RangeReference.h" +#include "ReconstructionDataFormats/V0.h" +#include "ReconstructionDataFormats/Track.h" + +using namespace o2::framework; + +namespace o2 +{ +namespace strangeness_tracking +{ +using V0 = o2::dataformats::V0; + +template +using BranchDefinition = MakeRootTreeWriterSpec::BranchDefinition; + +using namespace o2::header; + +DataProcessorSpec getHypertrackingWriterSpec() +{ + auto loggerV = [](std::vector const& v) { + LOG(info) << "Hypertracker writer pulled " << v.size() << " v0s"; + }; + + auto loggerT = [](std::vector const& v) { + LOG(info) << "Hypertracker writer pulled " << v.size() << " tracks"; + }; + + auto inpV0ID = InputSpec{"v0s", "HYP", "V0S", 0}; + auto inpTrackID = InputSpec{"hypertrack", "HYP", "HYPERTRACKS", 0}; + auto inpRefID = InputSpec{"itsrefs", "HYP", "ITSREFS", 0}; + + + return MakeRootTreeWriterSpec("hypertracking-writer", + "o2_hypertrack.root", + MakeRootTreeWriterSpec::TreeAttributes{"o2sim", "Tree with Hypertracks"}, + BranchDefinition>{inpV0ID, "V0s", loggerV}, + BranchDefinition>{inpTrackID, "Hypertracks", loggerT}, + BranchDefinition>{inpRefID, "ITSTrackRefs"})(); +} + +} // namespace strangeness_tracking +} // namespace o2 \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx b/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx index 8096dd67ce550..a17899b658e7e 100644 --- a/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx +++ b/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx @@ -10,6 +10,8 @@ // or submit itself to any jurisdiction. #include "StrangenessTrackingWorkflow/HypertrackingSpec.h" +#include "StrangenessTrackingWorkflow/HypertrackingWriterSpec.h" + #include "CommonUtils/ConfigurableParam.h" #include "StrangenessTracking/HypertrackingConfigParam.h" @@ -20,6 +22,8 @@ #include using namespace o2::framework; +using namespace o2::strangeness_tracking; + void customize(std::vector& policies) { @@ -51,6 +55,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); auto wf = o2::strangeness_tracking::getWorkflow(useMC, useRootInput); + wf.emplace_back(getHypertrackingWriterSpec()); // configure dpl timer to inject correct firstTFOrbit: start from the 1st orbit of TF containing 1st sampled orbit o2::raw::HBFUtilsInitializer hbfIni(configcontext, wf); From 0f86b70480e61fa99cf526aaf0b1c358ae1a3572 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Fri, 14 Jan 2022 16:16:01 +0100 Subject: [PATCH 12/36] Fix v0-track association --- .../StrangenessTracking/HyperTracker.h | 13 +++--- .../tracking/src/HyperTracker.cxx | 45 ++++++++++--------- .../workflow/src/HypertrackingSpec.cxx | 2 - .../workflow/src/HypertrackingWriterSpec.cxx | 1 - 4 files changed, 30 insertions(+), 31 deletions(-) diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h index 09a178f55f986..b85cde6b3b1e4 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h @@ -52,7 +52,6 @@ class HyperTracker std::vector& getHyperTracks() { return mHyperTracks; }; std::vector& getITStrackRef() { return mITStrackRef; }; - float getMaxChi2() const { return mMaxChi2; } void setMaxChi2(float d) { mMaxChi2 = d; } float getBz() const { return mBz; } @@ -78,17 +77,17 @@ class HyperTracker bool refitAllTracks(); protected: - gsl::span mInputITStracks; // input ITS tracks - std::vector mInputITSclusters; // input ITS clusters - gsl::span mInputITSidxs; // input ITS track-cluster indexes - gsl::span mInputV0tracks; // input V0 of decay daughters + gsl::span mInputITStracks; // input ITS tracks + std::vector mInputITSclusters; // input ITS clusters + gsl::span mInputITSidxs; // input ITS track-cluster indexes + gsl::span mInputV0tracks; // input V0 of decay daughters std::vector mHyperTracks; // Final hypertrack std::vector mV0s; // V0 of decay daughters std::vector mITStrackRef; // Ref to the ITS track - DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis - DCAFitter3 mFitter3Body; // optional DCA Fitter for final 3 Body refit + DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis + DCAFitter3 mFitter3Body; // optional DCA Fitter for final 3 Body refit float mMaxChi2 = 40; // Maximum matching chi2 float mBz = -5; // Magnetic field diff --git a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx index 3aa4ee61929ba..968d8dfef1d1a 100644 --- a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx @@ -82,51 +82,54 @@ void HyperTracker::process() for (int iTrack{0}; iTrack < mInputITStracks.size(); iTrack++) { - auto &ITStrack = mInputITStracks[iTrack]; + auto& ITStrack = mInputITStracks[iTrack]; auto trackClusters = getTrackClusters(ITStrack); std::vector v0Clusters; + int nUpdates = 0; for (auto& clus : trackClusters) { + auto isV0Upd = false; auto diffR2 = v0R2 - clus.getX() * clus.getX() - clus.getY() * clus.getY(); // difference between V0 and Layer R2 // check V0 compatibility if (diffR2 > -4) { - // LOG(INFO) << "Try to attach V0 for layer: " << mGeomITS->getLayer(clus.getSensorID()); if (updateTrack(clus, mV0)) { - // LOG(INFO) << "Attach cluster to V0 for layer: " << mGeomITS->getLayer(clus.getSensorID()); isV0Upd = true; v0Clusters.push_back(clus); + nUpdates++; } } // if V0 is not found, check He3 compatibility if (diffR2 < 4 && !isV0Upd) { - // LOG(INFO) << "Try to attach He3 for layer: " << mGeomITS->getLayer(clus.getSensorID()); auto& he3track = calcV0alpha(mV0) > 0 ? mV0.getProng(0) : mV0.getProng(1); if (!updateTrack(clus, he3track)) { break; } - recreateV0(mV0.getProng(0), mV0.getProng(1), mV0.getProngID(0), mV0.getProngID(1)); - // LOG(INFO) << "Attach cluster to He3 for layer: " << mGeomITS->getLayer(clus.getSensorID()); + if (recreateV0(mV0.getProng(0), mV0.getProng(1), mV0.getProngID(0), mV0.getProngID(1))) + nUpdates++; } + } - o2::track::TrackParCov hyperTrack = mV0; - // outward V0 propagation - if (v0Clusters.size() > 0) { - mV0.resetCovariance(); - std::reverse(v0Clusters.begin(), v0Clusters.end()); - for (auto& clus : v0Clusters) { - if (!updateTrack(clus, mV0)) - break; - } - } + if (nUpdates < trackClusters.size()) + continue; - // final 3body refit - if (refitAllTracks()) { - mV0s.push_back(mV0); - mHyperTracks.push_back(hyperTrack); - mITStrackRef.push_back(iTrack); + o2::track::TrackParCov hyperTrack = mV0; + // outward V0 propagation + if (v0Clusters.size() > 0) { + mV0.resetCovariance(); + std::reverse(v0Clusters.begin(), v0Clusters.end()); + for (auto& clus : v0Clusters) { + if (!updateTrack(clus, mV0)) + break; } } + + // final 3body refit + if (refitAllTracks()) { + mV0s.push_back(mV0); + mHyperTracks.push_back(hyperTrack); + mITStrackRef.push_back(iTrack); + } } } } diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx index 52fbc741a5d5c..88ec4f2761c75 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx @@ -155,8 +155,6 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) pc.outputs().snapshot(Output{"HYP", "HYPERTRACKS", 0, Lifetime::Timeframe}, mTracker.getHyperTracks()); pc.outputs().snapshot(Output{"HYP", "ITSREFS", 0, Lifetime::Timeframe}, mTracker.getITStrackRef()); - - mTimer.Stop(); } diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx index 3c5f357276533..c750bb47485f8 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx @@ -46,7 +46,6 @@ DataProcessorSpec getHypertrackingWriterSpec() auto inpTrackID = InputSpec{"hypertrack", "HYP", "HYPERTRACKS", 0}; auto inpRefID = InputSpec{"itsrefs", "HYP", "ITSREFS", 0}; - return MakeRootTreeWriterSpec("hypertracking-writer", "o2_hypertrack.root", MakeRootTreeWriterSpec::TreeAttributes{"o2sim", "Tree with Hypertracks"}, From 83966e176b4e12d2bf391ff2f353a832bd76dbab Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Wed, 19 Jan 2022 15:28:12 +0100 Subject: [PATCH 13/36] Update hypertracker + post processing macro --- .../macros/AnalyseHyperTree.C | 204 +++++++++++ .../StrangenessTracking/macros/CMakeLists.txt | 2 +- .../StrangenessTracking/macros/matchV0s.C | 346 ------------------ .../StrangenessTracking/HyperTracker.h | 11 +- .../tracking/src/HyperTracker.cxx | 53 ++- .../workflow/src/HypertrackingSpec.cxx | 3 + .../workflow/src/HypertrackingWriterSpec.cxx | 2 + 7 files changed, 257 insertions(+), 364 deletions(-) create mode 100644 Detectors/StrangenessTracking/macros/AnalyseHyperTree.C delete mode 100644 Detectors/StrangenessTracking/macros/matchV0s.C diff --git a/Detectors/StrangenessTracking/macros/AnalyseHyperTree.C b/Detectors/StrangenessTracking/macros/AnalyseHyperTree.C new file mode 100644 index 0000000000000..32c3135b42bda --- /dev/null +++ b/Detectors/StrangenessTracking/macros/AnalyseHyperTree.C @@ -0,0 +1,204 @@ +#if !defined(CLING) || defined(ROOTCLING) +#include "CommonDataFormat/RangeReference.h" +#include "ReconstructionDataFormats/Cascade.h" +#include "ReconstructionDataFormats/PID.h" +#include "ReconstructionDataFormats/V0.h" +#include "SimulationDataFormat/MCCompLabel.h" +#include "SimulationDataFormat/MCTrack.h" +#include "DataFormatsITS/TrackITS.h" +#include "DataFormatsITSMFT/ROFRecord.h" + +#include +#include "TCanvas.h" +#include "TFile.h" +#include "TH1F.h" +#include "TMath.h" +#include "TString.h" +#include "TTree.h" +#endif + +using GIndex = o2::dataformats::VtxTrackIndex; +using V0 = o2::dataformats::V0; +using MCTrack = o2::MCTrack; +using Cascade = o2::dataformats::Cascade; +using RRef = o2::dataformats::RangeReference; +using VBracket = o2::math_utils::Bracket; +using namespace o2::itsmft; +using Vec3 = ROOT::Math::SVector; + +const int motherPDG = 1010010030; +const int firstDaughterPDG = 1000020030; +const int secondDaughterPDG = -211; + +// const int motherPDG = 3122; +// const int firstDaughterPDG = 2212; +// const int secondDaughterPDG = -211; + +o2::its::TrackITS *getITSTrack(int motherEvID, int motherTrackID, TTree *ITStree, std::vector *ITSlabel, std::vector *ITStrack); +void doMatching(const std::vector> &mcTracksMatrix, TTree *treeDetectors, std::vector *labDetectors, TH1D *histo); +double calcMass(const V0 &v0, double dauMass[2], int dauCharges[2]); + +void AnalyseHyperTree() +{ + auto fMCTracks = TFile::Open("sgn_1_Kine.root"); + auto fSecondaries = TFile::Open("o2_hypertrack.root"); + auto fITS = TFile::Open("o2trac_its.root"); + auto fTPC = TFile::Open("tpctracks.root"); + + auto fITSTPC = TFile::Open("o2match_itstpc.root"); + auto fTPCTOF = TFile::Open("o2match_tof_tpc.root"); + auto fITSTPCTOF = TFile::Open("o2match_tof_itstpc.root"); + + // Trees + auto treeMCTracks = (TTree *)fMCTracks->Get("o2sim"); + auto treeSecondaries = (TTree *)fSecondaries->Get("o2sim"); + auto treeITS = (TTree *)fITS->Get("o2sim"); + auto treeTPC = (TTree *)fTPC->Get("tpcrec"); + + auto treeITSTPC = (TTree *)fITSTPC->Get("matchTPCITS"); + auto treeITSTPCTOF = (TTree *)fITSTPCTOF->Get("matchTOF"); + auto treeTPCTOF = (TTree *)fTPCTOF->Get("matchTOF"); + + // Tracks + std::vector *MCtracks = nullptr; + std::vector *v0vec = nullptr; + std::vector *ITSref = nullptr; + std::vector *chi2vec = nullptr; + + + std::vector *ITStracks = nullptr; + std::vector *rofArr = nullptr; + + // Labels + std::vector *labITSvec = nullptr; + std::vector *labITSTPCvec = nullptr; + std::vector *labITSTPCTOFvec = nullptr; + std::vector *labTPCTOFvec = nullptr; + std::vector *labTPCvec = nullptr; + + treeSecondaries->SetBranchAddress("V0s", &v0vec); + treeSecondaries->SetBranchAddress("ITSTrackRefs", &ITSref); + treeSecondaries->SetBranchAddress("ITSV0Chi2", &chi2vec); + + + treeMCTracks->SetBranchAddress("MCTrack", &MCtracks); + treeITSTPC->SetBranchAddress("MatchMCTruth", &labITSTPCvec); + treeTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labTPCTOFvec); + treeITSTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labITSTPCTOFvec); + treeITS->SetBranchAddress("ITSTrackMCTruth", &labITSvec); + treeITS->SetBranchAddress("ITSTrack", &ITStracks); + treeITS->SetBranchAddress("ITSTracksROF", &rofArr); + treeTPC->SetBranchAddress("TPCTracksMCTruth", &labTPCvec); + + std::map *> + map{{"TPC", labTPCvec}, {"ITS", labITSvec}, {"ITS-TPC", labITSTPCvec}, {"TPC-TOF", labTPCTOFvec}, {"ITS-TPC-TOF", labITSTPCTOFvec}}; + + // fill MC matrix + int injectedParticles = 0; + std::vector> mcTracksMatrix; + auto nev = treeMCTracks->GetEntriesFast(); + + mcTracksMatrix.resize(nev); + for (int n = 0; n < nev; n++) + { // loop over MC events + treeMCTracks->GetEvent(n); + + mcTracksMatrix[n].resize(MCtracks->size()); + for (unsigned int mcI{0}; mcI < MCtracks->size(); ++mcI) + { + mcTracksMatrix[n][mcI] = MCtracks->at(mcI); + if (MCtracks->at(mcI).GetPdgCode() == motherPDG) + { + injectedParticles++; + } + } + } + + treeSecondaries->GetEntry(); + treeITS->GetEntry(); + treeTPC->GetEntry(); + + treeITSTPC->GetEntry(); + treeTPCTOF->GetEntry(); + treeITSTPCTOF->GetEntry(); + + int counter = 0; + for (unsigned int hTrack{0}; hTrack < v0vec->size(); hTrack++) + { + auto &v0 = v0vec->at(hTrack); + auto &chi2 = chi2vec->at(hTrack); + + std::vector motherIDvec; + std::vector daughterIDvec; + std::vector evIDvec; + + for (int iV0 = 0; iV0 < 2; iV0++) + { + std::cout << "---------------------------------" << std::endl; + LOG(INFO) << "Daughter 0, Rec Pt: " << v0.getProng(0).getPt() << ", Track type: " << v0.getProngID(0).getSourceName(); + LOG(INFO) << "Daughter 1, Rec Pt: " << v0.getProng(1).getPt() << ", Track type: " << v0.getProngID(1).getSourceName(); + + + + + if (map[v0.getProngID(iV0).getSourceName()]) + { + auto labTrackType = map[v0.getProngID(iV0).getSourceName()]; + auto lab = labTrackType->at(v0.getProngID(iV0).getIndex()); + // LOG(INFO) << v0.getProngID(iV0); + + int trackID, evID, srcID; + bool fake; + lab.get(trackID, evID, srcID, fake); + if (!lab.isNoise() && lab.isValid() && lab.isCorrect() && srcID) + { + auto motherID = mcTracksMatrix[evID][trackID].getMotherTrackId(); + motherIDvec.push_back(motherID); + daughterIDvec.push_back(trackID); + evIDvec.push_back(evID); + } + } + } + + + + if (motherIDvec.size() < 2) + continue; + if (motherIDvec[0] != motherIDvec[1] || evIDvec[0] != evIDvec[1]) + continue; + if (motherIDvec[0] <= 0 || motherIDvec[0] > 10000) + continue; + + int pdg0 = mcTracksMatrix[evIDvec[0]][daughterIDvec[0]].GetPdgCode(); + int pdg1 = mcTracksMatrix[evIDvec[0]][daughterIDvec[1]].GetPdgCode(); + + if (pdg0 != firstDaughterPDG && pdg0 != secondDaughterPDG) + continue; + if (pdg1 != firstDaughterPDG && pdg1 != secondDaughterPDG) + continue; + + auto ITSlabel = labITSvec->at(ITSref->at(hTrack)); + int ITStrackID, ITSevID, ITSsrcID; + bool ITSfake; + ITSlabel.get(ITStrackID, ITSevID, ITSsrcID, ITSfake); + + if(ITStrackID == daughterIDvec[0]) LOG(INFO) << "ITS TRACK == He3 TRACK"; + if(ITStrackID == daughterIDvec[1]) LOG(INFO) << "ITS TRACK == PI TRACK"; + LOG(INFO) << "Chi2: " << chi2; + + + + if (ITStrackID != motherIDvec[1] || ITSevID != evIDvec[0]) + continue; + + counter++; + LOG(INFO) << "Counter: " << counter; + LOG(INFO) << evIDvec[0] << ", " << motherIDvec[0] << ", " << motherIDvec[1]; + LOG(INFO) << "Common mother found, PDG: " << mcTracksMatrix[evIDvec[0]][motherIDvec[0]].GetPdgCode(); + LOG(INFO) << "Daughter 0, PDG: " << pdg0 << ", Pt: " << mcTracksMatrix[evIDvec[0]][daughterIDvec[0]].GetPt(); + LOG(INFO) << "Daughter 0, Rec Pt: " << v0.getProng(0).getPt() << ", Track type: " << v0.getProngID(0).getSourceName(); + LOG(INFO) << "Daughter 1, PDG: " << pdg1 << ", Pt: " << mcTracksMatrix[evIDvec[0]][daughterIDvec[1]].GetPt(); + LOG(INFO) << "Daughter 1, Rec Pt: " << v0.getProng(1).getPt() << ", Track type: " << v0.getProngID(1).getSourceName(); + auto motherTrack = mcTracksMatrix[evIDvec[0]][motherIDvec[0]]; + } +} diff --git a/Detectors/StrangenessTracking/macros/CMakeLists.txt b/Detectors/StrangenessTracking/macros/CMakeLists.txt index ed28e9545248a..537bafafe37f4 100644 --- a/Detectors/StrangenessTracking/macros/CMakeLists.txt +++ b/Detectors/StrangenessTracking/macros/CMakeLists.txt @@ -1,4 +1,4 @@ -o2_add_test_root_macro(matchV0s.C +o2_add_test_root_macro(AnalyseHyperTree.C PUBLIC_LINK_LIBRARIES O2::MathUtils O2::ITSBase O2::ITSMFTReconstruction diff --git a/Detectors/StrangenessTracking/macros/matchV0s.C b/Detectors/StrangenessTracking/macros/matchV0s.C deleted file mode 100644 index 2b128166cbecc..0000000000000 --- a/Detectors/StrangenessTracking/macros/matchV0s.C +++ /dev/null @@ -1,346 +0,0 @@ -#if !defined(CLING) || defined(ROOTCLING) -#include "CommonDataFormat/RangeReference.h" -#include "ReconstructionDataFormats/Cascade.h" -#include "ReconstructionDataFormats/PID.h" -#include "ReconstructionDataFormats/V0.h" -#include "SimulationDataFormat/MCCompLabel.h" -#include "SimulationDataFormat/MCTrack.h" - -#include "DataFormatsITSMFT/TopologyDictionary.h" -#include "DetectorsCommonDataFormats/NameConf.h" -#include "ITSBase/GeometryTGeo.h" -#include "DataFormatsITS/TrackITS.h" -#include "DataFormatsITSMFT/CompCluster.h" -#include "DataFormatsITSMFT/ROFRecord.h" -#include "ITStracking/IOUtils.h" - -#include -#include -#include "TCanvas.h" -#include "TFile.h" -#include "TH1F.h" -#include "TH2D.h" - -#include "TMath.h" -#include "TString.h" -#include "TTree.h" -#include "TLegend.h" -#include "CommonDataFormat/RangeReference.h" -#include "DetectorsVertexing/DCAFitterN.h" - -#include "HyperTracker.h" - -#endif - -using GIndex = o2::dataformats::VtxTrackIndex; -using V0 = o2::dataformats::V0; -using MCTrack = o2::MCTrack; -using Cascade = o2::dataformats::Cascade; -using RRef = o2::dataformats::RangeReference; -using VBracket = o2::math_utils::Bracket; -using namespace o2::itsmft; -using CompClusterExt = o2::itsmft::CompClusterExt; -using ITSCluster = o2::BaseCluster; -using Vec3 = ROOT::Math::SVector; -using hyperTracker = o2::tracking::hyperTracker; - -const int motherPDG = 1010010030; -const int firstDaughterPDG = 1000020030; -const int secondDaughterPDG = -211; - -std::vector> matchV0stoMC(const std::vector>& mcTracksMatrix, std::map*>& map, std::vector* v0vec); -std::array matchITStracktoMC(const std::vector>& mcTracksMatrix, o2::MCCompLabel ITSlabel); -std::vector getTrackClusters(const o2::its::TrackITS& ITStrack, const std::vector& ITSClustersArray, std::vector* ITSTrackClusIdx); - -void matchV0s() -{ - // Output Histograms - TH1D* hChi2Sgn = new TH1D("Chi2 Signal", "; #chi^{2}; Counts", 102, -2, 100); - TH1D* hChi2Bkg = new TH1D("Chi2 background", "; #chi^{2} (90 is default for overflows and not propagated); Counts", 102, -2, 100); - TH1D* hSigBkg = new TH1D("Hypertracker eff", "; ; Efficiency", 2, 0, 2); - TH2D* hPtResBef = new TH2D("pT resolution before hypertracking", "; #it{p}_{T}^{gen} (GeV); (#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, 0, 10, 20, -1, 1); - TH2D* hPtResAft = new TH2D("pT resolution before hypertracking", "; #it{p}_{T}^{gen} (GeV); (#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, 0, 10, 20, -1, 1); - - // Files - auto fMCTracks = TFile::Open("sgn_Kine.root"); - auto fSecondaries = TFile::Open("o2_secondary_vertex.root"); - auto fITSTPC = TFile::Open("o2match_itstpc.root"); - auto fTPCTOF = TFile::Open("o2match_tof_tpc.root"); - auto fITSTPCTOF = TFile::Open("o2match_tof_itstpc.root"); - - auto fITS = TFile::Open("o2trac_its.root"); - auto fITSclus = TFile::Open("o2clus_its.root"); - - // Geometry - o2::base::GeometryManager::loadGeometry(""); - - // Trees - auto treeMCTracks = (TTree*)fMCTracks->Get("o2sim"); - auto treeSecondaries = (TTree*)fSecondaries->Get("o2sim"); - auto treeITSTPC = (TTree*)fITSTPC->Get("matchTPCITS"); - auto treeITSTPCTOF = (TTree*)fITSTPCTOF->Get("matchTOF"); - auto treeTPCTOF = (TTree*)fTPCTOF->Get("matchTOF"); - - auto treeITS = (TTree*)fITS->Get("o2sim"); - auto treeITSclus = (TTree*)fITSclus->Get("o2sim"); - - // Topology dictionary - o2::itsmft::TopologyDictionary mdict; - mdict.readFromFile(o2::base::NameConf::getAlpideClusterDictionaryFileName(o2::detectors::DetID::ITS)); - - // Tracks - std::vector* MCtracks = nullptr; - std::vector* v0vec = nullptr; - std::vector* ITStracks = nullptr; - std::vector* ITSTrackClusIdx = nullptr; - - // Clusters - std::vector* ITSclus = nullptr; - std::vector* ITSpatt = nullptr; - - // Labels - std::vector* labITSvec = nullptr; - std::vector* labITSTPCvec = nullptr; - std::vector* labITSTPCTOFvec = nullptr; - std::vector* labTPCTOFvec = nullptr; - - // Setting branches - treeSecondaries->SetBranchAddress("V0s", &v0vec); - treeMCTracks->SetBranchAddress("MCTrack", &MCtracks); - treeITSTPC->SetBranchAddress("MatchMCTruth", &labITSTPCvec); - treeTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labTPCTOFvec); - treeITSTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labITSTPCTOFvec); - treeITS->SetBranchAddress("ITSTrackMCTruth", &labITSvec); - treeITS->SetBranchAddress("ITSTrack", &ITStracks); - treeITS->SetBranchAddress("ITSTrackClusIdx", &ITSTrackClusIdx); - - treeITSclus->SetBranchAddress("ITSClusterComp", &ITSclus); - treeITSclus->SetBranchAddress("ITSClusterPatt", &ITSpatt); - - // define detector map - std::map*> map{{"ITS", labITSvec}, {"ITS-TPC", labITSTPCvec}, {"TPC-TOF", labTPCTOFvec}, {"ITS-TPC-TOF", labITSTPCTOFvec}}; - - // load geometry - auto gman = o2::its::GeometryTGeo::Instance(); - gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G)); - - // fill MC matrix - std::vector> mcTracksMatrix; - auto nev = treeMCTracks->GetEntriesFast(); - mcTracksMatrix.resize(nev); - for (int n = 0; n < nev; n++) { // loop over MC events - treeMCTracks->GetEvent(n); - - mcTracksMatrix[n].resize(MCtracks->size()); - for (unsigned int mcI{0}; mcI < MCtracks->size(); ++mcI) { - mcTracksMatrix[n][mcI] = MCtracks->at(mcI); - } - } - - treeSecondaries->GetEntry(); - treeITS->GetEntry(); - treeITSclus->GetEntry(); - treeITSTPC->GetEntry(); - treeTPCTOF->GetEntry(); - treeITSTPCTOF->GetEntry(); - - std::vector> V0sMCref = matchV0stoMC(mcTracksMatrix, map, v0vec); - - // convert Comp Clusters into 3D point - std::vector mITSClustersArray; - mITSClustersArray.reserve((*ITSclus).size()); - gsl::span spanPatt{*ITSpatt}; - auto pattIt = spanPatt.begin(); - o2::its::ioutils::convertCompactClusters(*ITSclus, pattIt, mITSClustersArray, mdict); - - // preparing DCA Fitter - o2::vertexing::DCAFitterN<2> mFitterV0; - mFitterV0.setBz(-5); - - auto sig_counter = 0.; - auto bkg_counter = 0.; - - // Starting matching loop - for (int frame = 0; frame < treeITS->GetEntriesFast(); frame++) { - if (!treeITS->GetEvent(frame) || !treeITS->GetEvent(frame)) - continue; - if (!treeITS->GetEvent(frame)) { - continue; - } - - for (unsigned int iTrack{0}; iTrack < labITSvec->size(); ++iTrack) { - auto lab = labITSvec->at(iTrack); - auto ITStrackMCref = matchITStracktoMC(mcTracksMatrix, lab); - auto ITStrack = ITStracks->at(iTrack); - - auto ITSclusters = getTrackClusters(ITStrack, mITSClustersArray, ITSTrackClusIdx); - - for (unsigned int iV0vec = 0; iV0vec < v0vec->size(); iV0vec++) { - auto& v0MCref = V0sMCref[iV0vec]; - auto& v0 = (*v0vec)[iV0vec]; - - if (ITStrackMCref == v0MCref && ITStrackMCref[0] != -1) { - - auto& mcTrack = mcTracksMatrix[v0MCref[0]][v0MCref[1]]; - sig_counter++; - auto hyperTrack = hyperTracker(ITStrack, v0, ITSclusters, gman, mFitterV0); - hyperTrack.setBz(-5.); - // hyperTrack.setNclusMatching(ITSclusters.size()); - hyperTrack.setMaxChi2(40); - auto chi2 = hyperTrack.getMatchingChi2(); - std::cout << "V0 orig Pt: " << v0.getPt() << ", V0 recr Pt: " << hyperTrack.getV0().getPt() << std::endl; - hPtResBef->Fill(mcTrack.GetPt(), (mcTrack.GetPt() - hyperTrack.getV0().getPt()) / mcTrack.GetPt()); - std::cout << "ITS track Pt: " << ITStrack.getPt() << std::endl; - std::cout << "Starting hyperTracking algorithm..." << std::endl; - auto isAcc = hyperTrack.process(); - - std::cout << "After processing hyperTracking algorithm..." << std::endl; - hPtResAft->Fill(mcTrack.GetPt(), (mcTrack.GetPt() - hyperTrack.getV0().getPt()) / mcTrack.GetPt()); - - std::cout << "Is accepted? : " << isAcc << std::endl; - - for (auto i{0}; i < 7; i++) { - if (ITStrack.isFakeOnLayer(i) && ITStrack.hasHitOnLayer(i)) - std::cout << "Fake clusters on layer: " << i << std::endl; - } - - std::cout << "------------------------" << std::endl; - hChi2Sgn->Fill(chi2); - if (isAcc) - hSigBkg->Fill(0.5); - } - if (ITStrackMCref != v0MCref) { - if (bkg_counter > 20000) - continue; - bkg_counter++; - - auto hyperTrack = hyperTracker(ITStrack, v0, ITSclusters, gman, mFitterV0); - hyperTrack.setBz(-5.); - // hyperTrack.setNclusMatching(ITSclusters.size()); - hyperTrack.setMaxChi2(40); - - auto chi2 = hyperTrack.getMatchingChi2(); - if (chi2 > 90 || chi2 == -1) - chi2 = 90; - auto isAcc = hyperTrack.process(); - hChi2Bkg->Fill(chi2); - if (isAcc) - hSigBkg->Fill(1.5); - } - } - } - } - auto outFile = TFile("v0sITSmatch.root", "recreate"); - // efficiency histo - hSigBkg->SetBinContent(1, hSigBkg->GetBinContent(1) / sig_counter); - hSigBkg->SetBinContent(2, hSigBkg->GetBinContent(2) / bkg_counter); - hSigBkg->GetXaxis()->SetBinLabel(1, "Signal"); - hSigBkg->GetXaxis()->SetBinLabel(2, "Background"); - hSigBkg->Write(); - hPtResAft->Write(); - hPtResBef->Write(); - - // chi2 histos - auto* c = new TCanvas("c1", "chi2", 1000, 400); - hChi2Bkg->SetStats(0); - hChi2Sgn->SetLineColor(kRed); - hChi2Sgn->SetLineWidth(2); - hChi2Bkg->SetLineColor(kBlue); - hChi2Bkg->SetLineWidth(2); - c->cd(); - hChi2Bkg->DrawNormalized(); - hChi2Sgn->DrawNormalized("same"); - auto legend = new TLegend(0.55, 0.2, 0.85, 0.4); - legend->SetMargin(0.10); - legend->SetTextSize(0.03); - - legend->AddEntry(hChi2Sgn, "V0-ITStrack #chi^{2} for signal"); - legend->AddEntry(hChi2Bkg, "V0-ITStrack #chi^{2} for background"); - legend->Draw(); - c->Write(); - hChi2Sgn->Write(); - hChi2Bkg->Write(); - outFile.Close(); -} - -std::vector> matchV0stoMC(const std::vector>& mcTracksMatrix, std::map*>& map, std::vector* v0vec) -{ - std::vector> outArray; - outArray.resize(v0vec->size()); - int count_V0 = 0; - for (unsigned int iV0vec = 0; iV0vec < v0vec->size(); iV0vec++) { - std::vector motherIDvec; - std::vector daughterIDvec; - std::vector evIDvec; - - outArray[iV0vec] = {-1, -1}; - auto& v0 = (*v0vec)[iV0vec]; - - for (unsigned int iV0 = 0; iV0 < 2; iV0++) { - if (map[v0.getProngID(iV0).getSourceName()]) { - auto labTrackType = map[v0.getProngID(iV0).getSourceName()]; - auto lab = labTrackType->at(v0.getProngID(iV0).getIndex()); - - int trackID, evID, srcID; - bool fake; - lab.get(trackID, evID, srcID, fake); - if (!lab.isNoise() && lab.isValid() && lab.isCorrect() && srcID) { - auto motherID = mcTracksMatrix[evID][trackID].getMotherTrackId(); - motherIDvec.push_back(motherID); - daughterIDvec.push_back(trackID); - evIDvec.push_back(evID); - } - } - } - - if (motherIDvec.size() < 2) - continue; - if (motherIDvec[0] != motherIDvec[1] || evIDvec[0] != evIDvec[1]) - continue; - - if (motherIDvec[0] <= 0 || motherIDvec[0] > 10000) - continue; - - int pdg0 = mcTracksMatrix[evIDvec[0]][daughterIDvec[0]].GetPdgCode(); - int pdg1 = mcTracksMatrix[evIDvec[0]][daughterIDvec[1]].GetPdgCode(); - - if (pdg0 != firstDaughterPDG && pdg0 != secondDaughterPDG) - continue; - if (pdg1 != firstDaughterPDG && pdg1 != secondDaughterPDG) - continue; - - // std::cout << "Mother PDG: " << mcTracksMatrix[evIDvec[0]][motherIDvec[0]].GetPt() << std::endl; - outArray[iV0vec] = {evIDvec[0], motherIDvec[0]}; - count_V0++; - } - std::cout << "Number of V0s: " << count_V0 << std::endl; - return outArray; -} - -std::array matchITStracktoMC(const std::vector>& mcTracksMatrix, o2::MCCompLabel ITSlabel) - -{ - std::array outArray = {-1, -1}; - int trackID, evID, srcID; - bool fake; - ITSlabel.get(trackID, evID, srcID, fake); - if (!ITSlabel.isNoise() && ITSlabel.isValid() && srcID && mcTracksMatrix[evID][trackID].GetPdgCode() == motherPDG) { - outArray = {evID, trackID}; - // std::cout << "ITS EvID, track Id : " << evID << " " << trackID << std::endl; - // std::cout << "ITS Mother Pt: " << mcTracksMatrix[evID][trackID].GetPt() << std::endl; - } - - return outArray; -} - -std::vector getTrackClusters(const o2::its::TrackITS& ITStrack, const std::vector& ITSClustersArray, std::vector* ITSTrackClusIdx) -{ - - std::vector outVec; - auto firstClus = ITStrack.getFirstClusterEntry(); - auto ncl = ITStrack.getNumberOfClusters(); - for (int icl = 0; icl < ncl; icl++) { - outVec.push_back(ITSClustersArray[(*ITSTrackClusIdx)[firstClus + icl]]); - } - return outVec; -} \ No newline at end of file diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h index b85cde6b3b1e4..6c185eca4b101 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h @@ -42,6 +42,7 @@ class HyperTracker using TrackITS = o2::its::TrackITS; using ITSCluster = o2::BaseCluster; using V0 = o2::dataformats::V0; + using GIndex = o2::dataformats::VtxTrackIndex; using DCAFitter2 = o2::vertexing::DCAFitterN<2>; using DCAFitter3 = o2::vertexing::DCAFitterN<3>; @@ -50,6 +51,7 @@ class HyperTracker std::vector& getV0() { return mV0s; }; std::vector& getHyperTracks() { return mHyperTracks; }; + std::vector& getChi2vec() { return mChi2; }; std::vector& getITStrackRef() { return mITStrackRef; }; float getMaxChi2() const { return mMaxChi2; } @@ -62,7 +64,7 @@ class HyperTracker mFitterV0.setBz(mBz); mFitter3Body.setBz(mBz); mFitterV0.setUseAbsDCA(true); - mFitter3Body.setUseAbsDCA(true); + // mFitter3Body.setUseAbsDCA(true); } bool loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, o2::its::GeometryTGeo* geomITS, float Bz); @@ -73,9 +75,11 @@ class HyperTracker void process(); - bool recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID); + bool recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const GIndex posID, const GIndex negID); bool refitAllTracks(); + float getMatchingChi2(V0 v0, const TrackITS ITSTrack, ITSCluster matchingClus); + protected: gsl::span mInputITStracks; // input ITS tracks std::vector mInputITSclusters; // input ITS clusters @@ -84,12 +88,13 @@ class HyperTracker std::vector mHyperTracks; // Final hypertrack std::vector mV0s; // V0 of decay daughters + std::vector mChi2; // V0-ITS Tracks chi2 std::vector mITStrackRef; // Ref to the ITS track DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis DCAFitter3 mFitter3Body; // optional DCA Fitter for final 3 Body refit - float mMaxChi2 = 40; // Maximum matching chi2 + float mMaxChi2 = 10; // Maximum matching chi2 float mBz = -5; // Magnetic field o2::its::GeometryTGeo* mGeomITS; // ITS geometry diff --git a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx index 968d8dfef1d1a..96be024285951 100644 --- a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx @@ -67,6 +67,7 @@ std::vector HyperTracker::ge void HyperTracker::process() { + int counter = 0; for (auto& v0 : mInputV0tracks) { counter++; @@ -78,41 +79,49 @@ void HyperTracker::process() alphaV0 > 0 ? posTrack.setAbsCharge(2) : negTrack.setAbsCharge(2); if (!recreateV0(posTrack, negTrack, v0.getProngID(0), v0.getProngID(1))) continue; + auto tmpV0 = mV0; auto v0R2 = v0.calcR2(); for (int iTrack{0}; iTrack < mInputITStracks.size(); iTrack++) { + mV0 = tmpV0; auto& ITStrack = mInputITStracks[iTrack]; + auto trackClusters = getTrackClusters(ITStrack); std::vector v0Clusters; - int nUpdates = 0; for (auto& clus : trackClusters) { - auto isV0Upd = false; auto diffR2 = v0R2 - clus.getX() * clus.getX() - clus.getY() * clus.getY(); // difference between V0 and Layer R2 // check V0 compatibility if (diffR2 > -4) { if (updateTrack(clus, mV0)) { - isV0Upd = true; v0Clusters.push_back(clus); + // LOG(INFO) << "Attach cluster to V0, layer: " << mGeomITS->getLayer(clus.getSensorID()); + isV0Upd = true; nUpdates++; } } // if V0 is not found, check He3 compatibility if (diffR2 < 4 && !isV0Upd) { auto& he3track = calcV0alpha(mV0) > 0 ? mV0.getProng(0) : mV0.getProng(1); - if (!updateTrack(clus, he3track)) { + if (!updateTrack(clus, he3track)) break; - } - if (recreateV0(mV0.getProng(0), mV0.getProng(1), mV0.getProngID(0), mV0.getProngID(1))) - nUpdates++; + if (!recreateV0(mV0.getProng(0), mV0.getProng(1), mV0.getProngID(0), mV0.getProngID(1))) + break; + + isV0Upd = true; + nUpdates++; } + + if (!isV0Upd) + break; } if (nUpdates < trackClusters.size()) continue; + o2::track::TrackParCov hyperTrack = mV0; // outward V0 propagation if (v0Clusters.size() > 0) { @@ -122,13 +131,17 @@ void HyperTracker::process() if (!updateTrack(clus, mV0)) break; } - } - // final 3body refit - if (refitAllTracks()) { - mV0s.push_back(mV0); - mHyperTracks.push_back(hyperTrack); - mITStrackRef.push_back(iTrack); + // final 3body refit + if (refitAllTracks()) { + LOG(INFO) << "Pushing back v0: " << v0.getProngID(0) << ", " << v0.getProngID(1); + auto& lastClus = trackClusters[0]; + + mV0s.push_back(mV0); + mHyperTracks.push_back(hyperTrack); + mChi2.push_back(getMatchingChi2(tmpV0, ITStrack, lastClus)); + mITStrackRef.push_back(iTrack); + } } } } @@ -156,7 +169,7 @@ bool HyperTracker::updateTrack(const ITSCluster& clus, o2::track::TrackParCov& t return false; } -bool HyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID) +bool HyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const GIndex posID, const GIndex negID) { int nCand; @@ -182,6 +195,7 @@ bool HyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2:: mV0 = V0(v0XYZ, pV0, mFitterV0.calcPCACovMatrixFlat(0), propPos, propNeg, posID, negID, o2::track::PID::HyperTriton); mV0.setAbsCharge(1); mV0.setPID(o2::track::PID::HyperTriton); + return true; } @@ -213,5 +227,16 @@ bool HyperTracker::refitAllTracks() return true; } +float HyperTracker::getMatchingChi2(V0 v0, const TrackITS ITStrack, ITSCluster matchingClus) +{ + float alpha = mGeomITS->getSensorRefAlpha(matchingClus.getSensorID()), x = matchingClus.getX(); + if (v0.rotate(alpha)) { + if (v0.propagateTo(x, mBz)) { + return v0.getPredictedChi2(ITStrack.getParamOut()); + } + } + return -100; +} + } // namespace strangeness_tracking } // namespace o2 \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx index 88ec4f2761c75..71887d21d846f 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx @@ -153,6 +153,7 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) pc.outputs().snapshot(Output{"HYP", "V0S", 0, Lifetime::Timeframe}, mTracker.getV0()); pc.outputs().snapshot(Output{"HYP", "HYPERTRACKS", 0, Lifetime::Timeframe}, mTracker.getHyperTracks()); + pc.outputs().snapshot(Output{"HYP", "CHI2", 0, Lifetime::Timeframe}, mTracker.getChi2vec()); pc.outputs().snapshot(Output{"HYP", "ITSREFS", 0, Lifetime::Timeframe}, mTracker.getITStrackRef()); mTimer.Stop(); @@ -196,6 +197,8 @@ DataProcessorSpec getHyperTrackerSpec() std::vector outputs; outputs.emplace_back("HYP", "V0S", 0, Lifetime::Timeframe); outputs.emplace_back("HYP", "HYPERTRACKS", 0, Lifetime::Timeframe); + + outputs.emplace_back("HYP", "CHI2", 0, Lifetime::Timeframe); outputs.emplace_back("HYP", "ITSREFS", 0, Lifetime::Timeframe); diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx index c750bb47485f8..3e4edafaecb1c 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx @@ -44,6 +44,7 @@ DataProcessorSpec getHypertrackingWriterSpec() auto inpV0ID = InputSpec{"v0s", "HYP", "V0S", 0}; auto inpTrackID = InputSpec{"hypertrack", "HYP", "HYPERTRACKS", 0}; + auto inpChi2ID = InputSpec{"v0itschi2", "HYP", "CHI2", 0}; auto inpRefID = InputSpec{"itsrefs", "HYP", "ITSREFS", 0}; return MakeRootTreeWriterSpec("hypertracking-writer", @@ -51,6 +52,7 @@ DataProcessorSpec getHypertrackingWriterSpec() MakeRootTreeWriterSpec::TreeAttributes{"o2sim", "Tree with Hypertracks"}, BranchDefinition>{inpV0ID, "V0s", loggerV}, BranchDefinition>{inpTrackID, "Hypertracks", loggerT}, + BranchDefinition>{inpChi2ID, "ITSV0Chi2"}, BranchDefinition>{inpRefID, "ITSTrackRefs"})(); } From 6896b6acdb504b67837b4da1aabaa4cbb6c42d38 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Thu, 20 Jan 2022 13:45:04 +0100 Subject: [PATCH 14/36] Add propagator --- .../StrangenessTracking/HyperTracker.h | 5 ++- .../tracking/src/HyperTracker.cxx | 37 ++++++++++--------- .../workflow/src/HypertrackingSpec.cxx | 34 ++++++++++++----- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h index 6c185eca4b101..8b73bc558ac84 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h @@ -58,6 +58,8 @@ class HyperTracker void setMaxChi2(float d) { mMaxChi2 = d; } float getBz() const { return mBz; } void setBz(float d) { mBz = d; } + void setCorrType(const o2::base::PropagatorImpl::MatCorrType& type) { mCorrType = type; } + void setupFitters() { @@ -67,7 +69,7 @@ class HyperTracker // mFitter3Body.setUseAbsDCA(true); } - bool loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, o2::its::GeometryTGeo* geomITS, float Bz); + bool loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, o2::its::GeometryTGeo* geomITS); double calcV0alpha(const V0& v0); std::vector getTrackClusters(o2::its::TrackITS const& ITStrack); @@ -96,6 +98,7 @@ class HyperTracker float mMaxChi2 = 10; // Maximum matching chi2 float mBz = -5; // Magnetic field + o2::base::PropagatorImpl::MatCorrType mCorrType = o2::base::PropagatorImpl::MatCorrType::USEMatCorrNONE; //use mat correction o2::its::GeometryTGeo* mGeomITS; // ITS geometry V0 mV0; // V0 employed for the tracking diff --git a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx index 96be024285951..29b161a6a2452 100644 --- a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx @@ -19,7 +19,7 @@ namespace strangeness_tracking { using ITSCluster = o2::BaseCluster; -bool HyperTracker::loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, o2::its::GeometryTGeo* geomITS, float Bz) +bool HyperTracker::loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, o2::its::GeometryTGeo* geomITS) { mInputV0tracks = InputV0tracks; mInputITStracks = InputITStracks; @@ -30,8 +30,6 @@ bool HyperTracker::loadData(gsl::span InputITStracks, s LOG(INFO) << "ITS tracks size: " << mInputITStracks.size(); LOG(INFO) << "ITS clusters size: " << mInputITSclusters.size(); LOG(INFO) << "ITS idxs size: " << mInputITSidxs.size(); - - mBz = Bz; mGeomITS = geomITS; setupFitters(); return true; @@ -121,7 +119,6 @@ void HyperTracker::process() if (nUpdates < trackClusters.size()) continue; - o2::track::TrackParCov hyperTrack = mV0; // outward V0 propagation if (v0Clusters.size() > 0) { @@ -149,24 +146,30 @@ void HyperTracker::process() bool HyperTracker::updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track) { + auto propInstance = o2::base::Propagator::Instance(); float alpha = mGeomITS->getSensorRefAlpha(clus.getSensorID()), x = clus.getX(); int layer{mGeomITS->getLayer(clus.getSensorID())}; - float thick = layer < 3 ? 0.005 : 0.01; - - if (track.rotate(alpha)) { - if (track.propagateTo(x, mBz)) { - constexpr float radl = 9.36f; // Radiation length of Si [cm] - constexpr float rho = 2.33f; // Density of Si [g/cm^3] + if (!track.rotate(alpha)) + return false; - auto chi2 = std::abs(track.getPredictedChi2(clus)); - if (track.correctForMaterial(thick, thick * rho * radl) && chi2 < mMaxChi2 && chi2 > 0) { - track.update(clus); - return true; - } - } + if (!propInstance->propagateToX(track, x, getBz(), o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, mCorrType)) + return false; + if (mCorrType == o2::base::PropagatorF::MatCorrType::USEMatCorrNONE) { + float thick = layer < 3 ? 0.005 : 0.01; + constexpr float radl = 9.36f; // Radiation length of Si [cm] + constexpr float rho = 2.33f; // Density of Si [g/cm^3] + if (!track.correctForMaterial(thick, thick * rho * radl)) + return false; } - return false; + auto chi2 = std::abs(track.getPredictedChi2(clus)); + if (chi2 > mMaxChi2 || chi2 < 0) + return false; + + if (!track.update(clus)) + return false; + + return true; } bool HyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const GIndex posID, const GIndex negID) diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx index 71887d21d846f..edf1a796b723b 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx @@ -11,6 +11,8 @@ #include "TGeoGlobalMagField.h" #include "DataFormatsParameters/GRPObject.h" +#include "Framework/ConfigParamRegistry.h" +#include "Field/MagneticField.h" #include "StrangenessTrackingWorkflow/HypertrackingSpec.h" #include "ITSWorkflow/ClusterWriterSpec.h" @@ -85,13 +87,21 @@ void HypertrackerSpec::init(framework::InitContext& ic) mTimer.Stop(); mTimer.Reset(); - // auto filename = ic.options().get("grp-file"); - // const auto grp = parameters::GRPObject::loadFrom(filename); - // if (grp) { - // mGRP.reset(grp); - // base::Propagator::initFieldFromGRP(grp); - // auto field = static_cast(TGeoGlobalMagField::Instance()->GetField()); - // } + auto filename = ic.options().get("grp-file"); + const auto grp = parameters::GRPObject::loadFrom(filename); + + // load propagator + base::Propagator::initFieldFromGRP(grp); + std::string matLUTPath = ic.options().get("material-lut-path"); + std::string matLUTFile = o2::base::NameConf::getMatLUTFileName(matLUTPath); + if (o2::utils::Str::pathExists(matLUTFile)) { + auto* lut = o2::base::MatLayerCylSet::loadFromFile(matLUTFile); + o2::base::Propagator::Instance()->setMatLUT(lut); + mTracker.setCorrType(o2::base::PropagatorImpl::MatCorrType::USEMatCorrLUT); + LOG(info) << "Loaded material LUT from " << matLUTFile; + } else { + LOG(info) << "Material LUT " << matLUTFile << " file is absent, only heuristic material correction can be used"; + } // load geometry base::GeometryManager::loadGeometry(); @@ -147,8 +157,11 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) o2::its::ioutils::convertCompactClusters(ITSclus, pattIt, ITSClustersArray, ITSdict); auto geom = o2::its::GeometryTGeo::Instance(); + auto field = static_cast(TGeoGlobalMagField::Instance()->GetField()); + double origD[3] = {0., 0., 0.}; + mTracker.setBz(field->getBz(origD)); - mTracker.loadData(ITStracks, ITSClustersArray, ITSTrackClusIdx, v0vec, geom, -5.); + mTracker.loadData(ITStracks, ITSClustersArray, ITSTrackClusIdx, v0vec, geom); mTracker.process(); pc.outputs().snapshot(Output{"HYP", "V0S", 0, Lifetime::Timeframe}, mTracker.getV0()); @@ -201,13 +214,14 @@ DataProcessorSpec getHyperTrackerSpec() outputs.emplace_back("HYP", "CHI2", 0, Lifetime::Timeframe); outputs.emplace_back("HYP", "ITSREFS", 0, Lifetime::Timeframe); - return DataProcessorSpec{ "hypertracker", inputs, outputs, AlgorithmSpec{adaptFromTask()}, - }; + Options{ + {"grp-file", VariantType::String, "o2sim_grp.root", {"Name of the grp file"}}, + {"material-lut-path", VariantType::String, "", {"Path of the material LUT file"}}}}; } } // namespace strangeness_tracking From baefa2db7718d59f78f19c876ece18cf75d3e7b4 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Wed, 4 May 2022 08:24:59 +0200 Subject: [PATCH 15/36] Update hypertracking --- .../tracking/CMakeLists.txt | 2 + .../StrangenessTracking/HyperTracker.h | 17 ++++-- .../tracking/src/HyperTracker.cxx | 52 ++++++++++++------- .../tracking/src/HypertrackingLinkDef.h | 2 + .../workflow/src/HypertrackingSpec.cxx | 12 +++-- .../workflow/src/HypertrackingWriterSpec.cxx | 3 ++ 6 files changed, 62 insertions(+), 26 deletions(-) diff --git a/Detectors/StrangenessTracking/tracking/CMakeLists.txt b/Detectors/StrangenessTracking/tracking/CMakeLists.txt index 24ded4dba4f65..f0c510e4319e8 100644 --- a/Detectors/StrangenessTracking/tracking/CMakeLists.txt +++ b/Detectors/StrangenessTracking/tracking/CMakeLists.txt @@ -25,4 +25,6 @@ o2_add_library(StrangenessTracking o2_target_root_dictionary(StrangenessTracking HEADERS include/StrangenessTracking/HypertrackingConfigParam.h + include/StrangenessTracking/HyperTracker.h + LINKDEF src/HypertrackingLinkDef.h) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h index 8b73bc558ac84..6a85a5c3f17b2 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h @@ -35,6 +35,13 @@ namespace o2 namespace strangeness_tracking { +struct He3Attachments{ + + std::array arr; + +}; + + class HyperTracker { public: @@ -52,6 +59,8 @@ class HyperTracker std::vector& getV0() { return mV0s; }; std::vector& getHyperTracks() { return mHyperTracks; }; std::vector& getChi2vec() { return mChi2; }; + std::vector& getHe3Attachments(){ return mHe3Attachments; }; + std::vector& getITStrackRef() { return mITStrackRef; }; float getMaxChi2() const { return mMaxChi2; } @@ -88,15 +97,17 @@ class HyperTracker gsl::span mInputITSidxs; // input ITS track-cluster indexes gsl::span mInputV0tracks; // input V0 of decay daughters - std::vector mHyperTracks; // Final hypertrack - std::vector mV0s; // V0 of decay daughters + std::vector mHyperTracks; // Final hypertrack + std::vector mV0s; // V0 of decay daughters std::vector mChi2; // V0-ITS Tracks chi2 + std::vector mHe3Attachments; // # of attached tracks, 1 for V0s, 2 for He3s + std::vector mITStrackRef; // Ref to the ITS track DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis DCAFitter3 mFitter3Body; // optional DCA Fitter for final 3 Body refit - float mMaxChi2 = 10; // Maximum matching chi2 + float mMaxChi2 = 30; // Maximum matching chi2 float mBz = -5; // Magnetic field o2::base::PropagatorImpl::MatCorrType mCorrType = o2::base::PropagatorImpl::MatCorrType::USEMatCorrNONE; //use mat correction diff --git a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx index 29b161a6a2452..535d9097d2a07 100644 --- a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx @@ -25,11 +25,11 @@ bool HyperTracker::loadData(gsl::span InputITStracks, s mInputITStracks = InputITStracks; mInputITSclusters = InputITSclusters; mInputITSidxs = InputITSidxs; - LOG(INFO) << "all tracks loaded"; - LOG(INFO) << "V0 tracks size: " << mInputV0tracks.size(); - LOG(INFO) << "ITS tracks size: " << mInputITStracks.size(); - LOG(INFO) << "ITS clusters size: " << mInputITSclusters.size(); - LOG(INFO) << "ITS idxs size: " << mInputITSidxs.size(); + LOG(info) << "all tracks loaded"; + LOG(info) << "V0 tracks size: " << mInputV0tracks.size(); + LOG(info) << "ITS tracks size: " << mInputITStracks.size(); + LOG(info) << "ITS clusters size: " << mInputITSclusters.size(); + LOG(info) << "ITS idxs size: " << mInputITSidxs.size(); mGeomITS = geomITS; setupFitters(); return true; @@ -69,7 +69,7 @@ void HyperTracker::process() int counter = 0; for (auto& v0 : mInputV0tracks) { counter++; - LOG(INFO) << "Analysing V0: " << counter << "/" << mInputV0tracks.size(); + LOG(info) << "Analysing V0: " << counter << "/" << mInputV0tracks.size(); auto posTrack = v0.getProng(0); auto negTrack = v0.getProng(1); @@ -87,19 +87,22 @@ void HyperTracker::process() auto trackClusters = getTrackClusters(ITStrack); std::vector v0Clusters; + std::array nAttachments; int nUpdates = 0; + auto isV0Upd = false; + for (auto& clus : trackClusters) { - auto isV0Upd = false; + int prevUpdate = nUpdates; auto diffR2 = v0R2 - clus.getX() * clus.getX() - clus.getY() * clus.getY(); // difference between V0 and Layer R2 - // check V0 compatibility - if (diffR2 > -4) { - if (updateTrack(clus, mV0)) { - v0Clusters.push_back(clus); - // LOG(INFO) << "Attach cluster to V0, layer: " << mGeomITS->getLayer(clus.getSensorID()); - isV0Upd = true; - nUpdates++; - } + + if (updateTrack(clus, mV0) and diffR2 > -4) { + v0Clusters.push_back(clus); + LOG(info) << "Attach cluster to V0, layer: " << mGeomITS->getLayer(clus.getSensorID()); + nAttachments[mGeomITS->getLayer(clus.getSensorID())] = 1; + isV0Upd = true; + nUpdates++; } + // if V0 is not found, check He3 compatibility if (diffR2 < 4 && !isV0Upd) { auto& he3track = calcV0alpha(mV0) > 0 ? mV0.getProng(0) : mV0.getProng(1); @@ -107,12 +110,12 @@ void HyperTracker::process() break; if (!recreateV0(mV0.getProng(0), mV0.getProng(1), mV0.getProngID(0), mV0.getProngID(1))) break; - - isV0Upd = true; + LOG(info) << "Attach cluster to he3, layer: " << mGeomITS->getLayer(clus.getSensorID()); + nAttachments[mGeomITS->getLayer(clus.getSensorID())] = 2; nUpdates++; } - if (!isV0Upd) + if (nUpdates == prevUpdate) break; } @@ -131,13 +134,21 @@ void HyperTracker::process() // final 3body refit if (refitAllTracks()) { - LOG(INFO) << "Pushing back v0: " << v0.getProngID(0) << ", " << v0.getProngID(1); + LOG(info) << "------------------------------------------------------"; + LOG(info) << "Pushing back v0: " << v0.getProngID(0) << ", " << v0.getProngID(1); + LOG(info) << "number of clusters attached: " << v0Clusters.size(); + LOG(info) << "Number of ITS track clusters: " << ITStrack.getNumberOfClusters(); + LOG(info) << "number of clusters attached to V0: " << nAttachments[0] << ", " << nAttachments[1] << ", " << nAttachments[2] << ", " << nAttachments[3] << ", " << nAttachments[4] << ", " << nAttachments[5] << ", " << nAttachments[6]; auto& lastClus = trackClusters[0]; + LOG(info) << "Matching chi2: " << getMatchingChi2(tmpV0, ITStrack, lastClus); mV0s.push_back(mV0); mHyperTracks.push_back(hyperTrack); mChi2.push_back(getMatchingChi2(tmpV0, ITStrack, lastClus)); mITStrackRef.push_back(iTrack); + He3Attachments structHe3; + structHe3.arr = nAttachments; + mHe3Attachments.push_back(structHe3); } } } @@ -163,12 +174,13 @@ bool HyperTracker::updateTrack(const ITSCluster& clus, o2::track::TrackParCov& t return false; } auto chi2 = std::abs(track.getPredictedChi2(clus)); + // LOG(info) << track.getPredictedChi2(clus); if (chi2 > mMaxChi2 || chi2 < 0) return false; if (!track.update(clus)) return false; - + return true; } diff --git a/Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h b/Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h index 76996b045f537..a44bbbc05eda1 100644 --- a/Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h +++ b/Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h @@ -17,5 +17,7 @@ #pragma link C++ class o2::strangeness_tracking::HypertrackerParamConfig + ; #pragma link C++ class o2::conf::ConfigurableParamHelper + ; +#pragma link C++ struct o2::strangeness_tracking::He3Attachments + ; +#pragma link C++ class std::vector + ; #endif diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx index edf1a796b723b..a139d3da7eb8e 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx @@ -98,7 +98,9 @@ void HypertrackerSpec::init(framework::InitContext& ic) auto* lut = o2::base::MatLayerCylSet::loadFromFile(matLUTFile); o2::base::Propagator::Instance()->setMatLUT(lut); mTracker.setCorrType(o2::base::PropagatorImpl::MatCorrType::USEMatCorrLUT); + mTracker.setBz(grp->getNominalL3Field()); LOG(info) << "Loaded material LUT from " << matLUTFile; + LOG(info) << "Magnetic field loaded from GRP " << grp->getNominalL3Field(); } else { LOG(info) << "Material LUT " << matLUTFile << " file is absent, only heuristic material correction can be used"; } @@ -147,14 +149,14 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) // ITS dict o2::itsmft::TopologyDictionary ITSdict; - std::string dictPath = o2::itsmft::ClustererParam::Instance().dictFilePath; - std::string dictFile = o2::base::DetectorNameConf::getAlpideClusterDictionaryFileName(o2::detectors::DetID::ITS, dictPath); + // std::string dictPath = o2::itsmft::ClustererParam::Instance().dictFilePath; + std::string dictFile = o2::base::DetectorNameConf::getAlpideClusterDictionaryFileName(o2::detectors::DetID::ITS); ITSdict.readFromFile(dictFile); auto pattIt = ITSpatt.begin(); std::vector ITSClustersArray; ITSClustersArray.reserve(ITSclus.size()); - o2::its::ioutils::convertCompactClusters(ITSclus, pattIt, ITSClustersArray, ITSdict); + o2::its::ioutils::convertCompactClusters(ITSclus, pattIt, ITSClustersArray, &ITSdict); auto geom = o2::its::GeometryTGeo::Instance(); auto field = static_cast(TGeoGlobalMagField::Instance()->GetField()); @@ -164,9 +166,12 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) mTracker.loadData(ITStracks, ITSClustersArray, ITSTrackClusIdx, v0vec, geom); mTracker.process(); + // LOG(info) << "PROVAAA: " << mTracker.getHe3Attachments()[0][0] << " " << mTracker.getHe3Attachments()[0][1] << " " << mTracker.getHe3Attachments()[0][2]; + pc.outputs().snapshot(Output{"HYP", "V0S", 0, Lifetime::Timeframe}, mTracker.getV0()); pc.outputs().snapshot(Output{"HYP", "HYPERTRACKS", 0, Lifetime::Timeframe}, mTracker.getHyperTracks()); pc.outputs().snapshot(Output{"HYP", "CHI2", 0, Lifetime::Timeframe}, mTracker.getChi2vec()); + pc.outputs().snapshot(Output{"HYP", "HE3UPDATES", 0, Lifetime::Timeframe}, mTracker.getHe3Attachments()); pc.outputs().snapshot(Output{"HYP", "ITSREFS", 0, Lifetime::Timeframe}, mTracker.getITStrackRef()); mTimer.Stop(); @@ -212,6 +217,7 @@ DataProcessorSpec getHyperTrackerSpec() outputs.emplace_back("HYP", "HYPERTRACKS", 0, Lifetime::Timeframe); outputs.emplace_back("HYP", "CHI2", 0, Lifetime::Timeframe); + outputs.emplace_back("HYP", "HE3UPDATES", 0, Lifetime::Timeframe); outputs.emplace_back("HYP", "ITSREFS", 0, Lifetime::Timeframe); return DataProcessorSpec{ diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx index 3e4edafaecb1c..6dfe2b0814b93 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx @@ -18,6 +18,7 @@ #include "CommonDataFormat/RangeReference.h" #include "ReconstructionDataFormats/V0.h" #include "ReconstructionDataFormats/Track.h" +#include "StrangenessTracking/HyperTracker.h" using namespace o2::framework; @@ -45,6 +46,7 @@ DataProcessorSpec getHypertrackingWriterSpec() auto inpV0ID = InputSpec{"v0s", "HYP", "V0S", 0}; auto inpTrackID = InputSpec{"hypertrack", "HYP", "HYPERTRACKS", 0}; auto inpChi2ID = InputSpec{"v0itschi2", "HYP", "CHI2", 0}; + auto inpHe3Att = InputSpec{"he3updates", "HYP", "HE3UPDATES",0}; auto inpRefID = InputSpec{"itsrefs", "HYP", "ITSREFS", 0}; return MakeRootTreeWriterSpec("hypertracking-writer", @@ -53,6 +55,7 @@ DataProcessorSpec getHypertrackingWriterSpec() BranchDefinition>{inpV0ID, "V0s", loggerV}, BranchDefinition>{inpTrackID, "Hypertracks", loggerT}, BranchDefinition>{inpChi2ID, "ITSV0Chi2"}, + BranchDefinition>{inpHe3Att, "He3Updates"}, BranchDefinition>{inpRefID, "ITSTrackRefs"})(); } From ecb34581b0f1bad4396b0b673284f4ce0792df1f Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Wed, 15 Jun 2022 19:05:59 +0200 Subject: [PATCH 16/36] Get ITS cluster dictionary from CCDB --- CODEOWNERS | 1 + .../tracking/src/HyperTracker.cxx | 18 ++--- .../workflow/CMakeLists.txt | 15 ++++- .../HypertrackingSpec.h | 32 +++++++++ .../workflow/src/HypertrackingSpec.cxx | 65 ++++++++----------- 5 files changed, 82 insertions(+), 49 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 3c31287f6727b..6b51b6cfc630e 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -73,6 +73,7 @@ /Detectors/ZDC @coppedis /Detectors/CTF @shahor02 /Detectors/Raw @shahor02 +/Detectors/StrangenessTracking @mconcas @mpuccio @fmazzasc /EventVisualisation @jmyrcha #/EventVisualisation/Base diff --git a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx index 535d9097d2a07..98bc924dda12f 100644 --- a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx @@ -69,7 +69,7 @@ void HyperTracker::process() int counter = 0; for (auto& v0 : mInputV0tracks) { counter++; - LOG(info) << "Analysing V0: " << counter << "/" << mInputV0tracks.size(); + LOG(debug) << "Analysing V0: " << counter << "/" << mInputV0tracks.size(); auto posTrack = v0.getProng(0); auto negTrack = v0.getProng(1); @@ -97,7 +97,7 @@ void HyperTracker::process() if (updateTrack(clus, mV0) and diffR2 > -4) { v0Clusters.push_back(clus); - LOG(info) << "Attach cluster to V0, layer: " << mGeomITS->getLayer(clus.getSensorID()); + LOG(debug) << "Attach cluster to V0, layer: " << mGeomITS->getLayer(clus.getSensorID()); nAttachments[mGeomITS->getLayer(clus.getSensorID())] = 1; isV0Upd = true; nUpdates++; @@ -110,7 +110,7 @@ void HyperTracker::process() break; if (!recreateV0(mV0.getProng(0), mV0.getProng(1), mV0.getProngID(0), mV0.getProngID(1))) break; - LOG(info) << "Attach cluster to he3, layer: " << mGeomITS->getLayer(clus.getSensorID()); + LOG(debug) << "Attach cluster to he3, layer: " << mGeomITS->getLayer(clus.getSensorID()); nAttachments[mGeomITS->getLayer(clus.getSensorID())] = 2; nUpdates++; } @@ -134,13 +134,13 @@ void HyperTracker::process() // final 3body refit if (refitAllTracks()) { - LOG(info) << "------------------------------------------------------"; - LOG(info) << "Pushing back v0: " << v0.getProngID(0) << ", " << v0.getProngID(1); - LOG(info) << "number of clusters attached: " << v0Clusters.size(); - LOG(info) << "Number of ITS track clusters: " << ITStrack.getNumberOfClusters(); - LOG(info) << "number of clusters attached to V0: " << nAttachments[0] << ", " << nAttachments[1] << ", " << nAttachments[2] << ", " << nAttachments[3] << ", " << nAttachments[4] << ", " << nAttachments[5] << ", " << nAttachments[6]; + LOG(debug) << "------------------------------------------------------"; + LOG(debug) << "Pushing back v0: " << v0.getProngID(0) << ", " << v0.getProngID(1); + LOG(debug) << "number of clusters attached: " << v0Clusters.size(); + LOG(debug) << "Number of ITS track clusters: " << ITStrack.getNumberOfClusters(); + LOG(debug) << "number of clusters attached to V0: " << nAttachments[0] << ", " << nAttachments[1] << ", " << nAttachments[2] << ", " << nAttachments[3] << ", " << nAttachments[4] << ", " << nAttachments[5] << ", " << nAttachments[6]; auto& lastClus = trackClusters[0]; - LOG(info) << "Matching chi2: " << getMatchingChi2(tmpV0, ITStrack, lastClus); + LOG(debug) << "Matching chi2: " << getMatchingChi2(tmpV0, ITStrack, lastClus); mV0s.push_back(mV0); mHyperTracks.push_back(hyperTrack); diff --git a/Detectors/StrangenessTracking/workflow/CMakeLists.txt b/Detectors/StrangenessTracking/workflow/CMakeLists.txt index 979ecda225d71..1bcae28e7dd88 100644 --- a/Detectors/StrangenessTracking/workflow/CMakeLists.txt +++ b/Detectors/StrangenessTracking/workflow/CMakeLists.txt @@ -20,8 +20,19 @@ o2_add_library(StrangenessTrackingWorkflow O2::SimulationDataFormat O2::ReconstructionDataFormats O2::Framework - O2::DetectorsRaw) + O2::DetectorsRaw + O2::SimConfig + O2::DataFormatsITS + O2::DataFormatsDCS + O2::ITStracking + O2::ITSReconstruction + O2::ITSMFTReconstruction + O2::ITSMFTWorkflow + O2::DetectorsCalibration + O2::GlobalTrackingWorkflowWriters + O2::CCDB) o2_add_executable(hypertracking-workflow SOURCES src/hypertracking-workflow.cxx - PUBLIC_LINK_LIBRARIES O2::StrangenessTrackingWorkflow) \ No newline at end of file + PUBLIC_LINK_LIBRARIES O2::StrangenessTrackingWorkflow + O2::GlobalTrackingWorkflowReaders) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h index 7bad1ab3f11e6..c066eefaadfeb 100644 --- a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h +++ b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h @@ -15,11 +15,43 @@ #include "Framework/WorkflowSpec.h" #include "Framework/DataProcessorSpec.h" #include "Framework/Task.h" +#include "DataFormatsITSMFT/CompCluster.h" +#include "DataFormatsParameters/GRPObject.h" +#include "ITSMFTReconstruction/ClustererParam.h" +#include "DataFormatsITSMFT/TopologyDictionary.h" + +#include "TStopwatch.h" + +#include "StrangenessTracking/HyperTracker.h" namespace o2 { namespace strangeness_tracking { +class HypertrackerSpec : public framework::Task +{ + public: + using ITSCluster = o2::BaseCluster; + + HypertrackerSpec(bool isMC = false); + ~HypertrackerSpec() override = default; + + void init(framework::InitContext& ic) final; + void run(framework::ProcessingContext& pc) final; + void endOfStream(framework::EndOfStreamContext& ec) final; + void finaliseCCDB(framework::ConcreteDataMatcher& matcher, void* obj) final; + void setClusterDictionary(const o2::itsmft::TopologyDictionary* d) { mDict = d; } + + private: + void updateTimeDependentParams(framework::ProcessingContext& pc); + + bool mIsMC = false; + bool mRecreateV0 = true; + TStopwatch mTimer; + HyperTracker mTracker; + std::unique_ptr mGRP = nullptr; + const o2::itsmft::TopologyDictionary* mDict = nullptr; +}; o2::framework::DataProcessorSpec getHyperTrackerSpec(); o2::framework::WorkflowSpec getWorkflow(bool upstreamClusters = false, bool upstreamV0s = false); diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx index a139d3da7eb8e..94edbefb6e8e3 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx @@ -10,7 +10,6 @@ // or submit itself to any jurisdiction. #include "TGeoGlobalMagField.h" -#include "DataFormatsParameters/GRPObject.h" #include "Framework/ConfigParamRegistry.h" #include "Field/MagneticField.h" @@ -22,18 +21,15 @@ #include "GlobalTrackingWorkflowReaders/SecondaryVertexReaderSpec.h" #include "GlobalTrackingWorkflowReaders/TrackTPCITSReaderSpec.h" #include "GlobalTrackingWorkflow/TOFMatcherSpec.h" +#include "Framework/CCDBParamSpec.h" -#include "DataFormatsITSMFT/CompCluster.h" #include "DataFormatsITSMFT/ROFRecord.h" #include "DataFormatsITS/TrackITS.h" #include "ReconstructionDataFormats/TrackTPCITS.h" #include "SimulationDataFormat/MCCompLabel.h" #include "ITStracking/IOUtils.h" -#include "ITSMFTReconstruction/ClustererParam.h" #include "DetectorsCommonDataFormats/DetectorNameConf.h" -#include "StrangenessTracking/HyperTracker.h" - #include namespace o2 @@ -42,26 +38,6 @@ using namespace o2::framework; namespace strangeness_tracking { -class HypertrackerSpec : public framework::Task -{ - public: - using ITSCluster = o2::BaseCluster; - - HypertrackerSpec(bool isMC = false); - ~HypertrackerSpec() override = default; - - void init(framework::InitContext& ic) final; - void run(framework::ProcessingContext& pc) final; - void endOfStream(framework::EndOfStreamContext& ec) final; - - private: - bool mIsMC = false; - bool mRecreateV0 = true; - TStopwatch mTimer; - HyperTracker mTracker; - std::unique_ptr mGRP = nullptr; -}; - framework::WorkflowSpec getWorkflow(bool useMC, bool useRootInput) { framework::WorkflowSpec specs; @@ -116,7 +92,8 @@ void HypertrackerSpec::init(framework::InitContext& ic) void HypertrackerSpec::run(framework::ProcessingContext& pc) { mTimer.Start(false); - LOG(info) << "Running Hypertracker..."; + LOG(info) << "Running hypertracker..."; + updateTimeDependentParams(pc); // ITS auto ITSclus = pc.inputs().get>("compClusters"); auto ITSpatt = pc.inputs().get>("patterns"); @@ -133,7 +110,7 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) // auto labTPCTOF = pc.inputs().get>("clsTOF_TPC_MCTR"); // auto labITSTPCTOF = pc.inputs().get>("clsTOF_GLO_MCTR"); auto labITS = pc.inputs().get>("trackITSMCTR"); - LOGF(info, "ITSclus: %d \nITSpatt: %d \nITStracks: %d \nROFsInput: %d \nITSTrackClusIdx: %d \nTPCITStracks: %d \nv0s: %d \nlabITSTPC: %d\nlabITS: %d", + LOGF(debug, "ITSclus: %d \nITSpatt: %d \nITStracks: %d \nROFsInput: %d \nITSTrackClusIdx: %d \nTPCITStracks: %d \nv0s: %d \nlabITSTPC: %d\nlabITS: %d", ITSclus.size(), ITSpatt.size(), ITStracks.size(), @@ -147,17 +124,10 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) labITS.size()); // \nlabTPCTOF: %d\nlabITSTPCTOF: %d - // ITS dict - o2::itsmft::TopologyDictionary ITSdict; - // std::string dictPath = o2::itsmft::ClustererParam::Instance().dictFilePath; - std::string dictFile = o2::base::DetectorNameConf::getAlpideClusterDictionaryFileName(o2::detectors::DetID::ITS); - ITSdict.readFromFile(dictFile); - auto pattIt = ITSpatt.begin(); std::vector ITSClustersArray; ITSClustersArray.reserve(ITSclus.size()); - o2::its::ioutils::convertCompactClusters(ITSclus, pattIt, ITSClustersArray, &ITSdict); - + o2::its::ioutils::convertCompactClusters(ITSclus, pattIt, ITSClustersArray, mDict); auto geom = o2::its::GeometryTGeo::Instance(); auto field = static_cast(TGeoGlobalMagField::Instance()->GetField()); double origD[3] = {0., 0., 0.}; @@ -166,8 +136,6 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) mTracker.loadData(ITStracks, ITSClustersArray, ITSTrackClusIdx, v0vec, geom); mTracker.process(); - // LOG(info) << "PROVAAA: " << mTracker.getHe3Attachments()[0][0] << " " << mTracker.getHe3Attachments()[0][1] << " " << mTracker.getHe3Attachments()[0][2]; - pc.outputs().snapshot(Output{"HYP", "V0S", 0, Lifetime::Timeframe}, mTracker.getV0()); pc.outputs().snapshot(Output{"HYP", "HYPERTRACKS", 0, Lifetime::Timeframe}, mTracker.getHyperTracks()); pc.outputs().snapshot(Output{"HYP", "CHI2", 0, Lifetime::Timeframe}, mTracker.getChi2vec()); @@ -177,6 +145,26 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) mTimer.Stop(); } +///_______________________________________ +void HypertrackerSpec::updateTimeDependentParams(ProcessingContext& pc) +{ + static bool initOnceDone = false; + if (!initOnceDone) { // this params need to be queried only once + initOnceDone = true; + pc.inputs().get("cldict"); // just to trigger the finaliseCCDB + } +} + +///_______________________________________ +void HypertrackerSpec::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) +{ + if (matcher == ConcreteDataMatcher("ITS", "CLUSDICT", 0)) { + LOG(info) << "cluster dictionary updated"; + setClusterDictionary((const o2::itsmft::TopologyDictionary*)obj); + return; + } +} + void HypertrackerSpec::endOfStream(framework::EndOfStreamContext& ec) { LOGF(info, "Hypertracker total timing: Cpu: %.3e Real: %.3e s in %d slots", @@ -193,6 +181,7 @@ DataProcessorSpec getHyperTrackerSpec() inputs.emplace_back("ROframes", "ITS", "CLUSTERSROF", 0, Lifetime::Timeframe); inputs.emplace_back("trackITSClIdx", "ITS", "TRACKCLSID", 0, Lifetime::Timeframe); inputs.emplace_back("ITSTrack", "ITS", "TRACKS", 0, Lifetime::Timeframe); + inputs.emplace_back("cldict", "ITS", "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec("ITS/Calib/ClusterDictionary")); // V0 inputs.emplace_back("v0s", "GLO", "V0S", 0, Lifetime::Timeframe); // found V0s @@ -221,7 +210,7 @@ DataProcessorSpec getHyperTrackerSpec() outputs.emplace_back("HYP", "ITSREFS", 0, Lifetime::Timeframe); return DataProcessorSpec{ - "hypertracker", + "hyper-tracker", inputs, outputs, AlgorithmSpec{adaptFromTask()}, From 04d54a674aefe7c9e90178a57d6e6e64a5c1cf5b Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Tue, 21 Jun 2022 11:14:33 +0200 Subject: [PATCH 17/36] Add phi-eta preselection --- .../StrangenessTracking/HyperTracker.h | 42 +++-- .../tracking/src/HyperTracker.cxx | 170 +++++++++++------- .../tracking/src/HypertrackingLinkDef.h | 4 +- .../workflow/src/HypertrackingSpec.cxx | 8 +- .../workflow/src/HypertrackingWriterSpec.cxx | 6 +- 5 files changed, 147 insertions(+), 83 deletions(-) diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h index 6a85a5c3f17b2..e827f57754f34 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h @@ -35,16 +35,25 @@ namespace o2 namespace strangeness_tracking { -struct He3Attachments{ +struct ClusAttachments { std::array arr; - }; +struct indexTableUtils { + int getBinIndex(float phi, float eta); + int mEtaBins = 64, mPhiBins = 128; + float minEta = -1.5, maxEta = 1.5; +}; class HyperTracker { public: + enum kTopology { kMother = 0, + kFirstDaughter = 1, + kSecondDaughter = 2, + kThirdDaughter = 3 }; + using PID = o2::track::PID; using TrackITS = o2::its::TrackITS; using ITSCluster = o2::BaseCluster; @@ -59,8 +68,9 @@ class HyperTracker std::vector& getV0() { return mV0s; }; std::vector& getHyperTracks() { return mHyperTracks; }; std::vector& getChi2vec() { return mChi2; }; - std::vector& getHe3Attachments(){ return mHe3Attachments; }; + std::vector& getR2vec() { return mR2; }; + std::vector& getClusAttachments() { return mClusAttachments; }; std::vector& getITStrackRef() { return mITStrackRef; }; float getMaxChi2() const { return mMaxChi2; } @@ -69,7 +79,6 @@ class HyperTracker void setBz(float d) { mBz = d; } void setCorrType(const o2::base::PropagatorImpl::MatCorrType& type) { mCorrType = type; } - void setupFitters() { mFitterV0.setBz(mBz); @@ -84,32 +93,39 @@ class HyperTracker bool updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track); + void initialise(); void process(); bool recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const GIndex posID, const GIndex negID); - bool refitAllTracks(); + bool refitTopology(); float getMatchingChi2(V0 v0, const TrackITS ITSTrack, ITSCluster matchingClus); protected: gsl::span mInputITStracks; // input ITS tracks + std::vector mTracksIdxTable; // index table for ITS tracks std::vector mInputITSclusters; // input ITS clusters gsl::span mInputITSidxs; // input ITS track-cluster indexes gsl::span mInputV0tracks; // input V0 of decay daughters + std::vector mSortedITStracks; // sorted ITS tracks + indexTableUtils mUtils; + + std::vector mHyperTracks; // Final hypertrack + std::vector mV0s; // V0 of decay daughters + std::vector mChi2; // V0-ITS Tracks chi2 + std::vector mR2; // Updated decay radius - std::vector mHyperTracks; // Final hypertrack - std::vector mV0s; // V0 of decay daughters - std::vector mChi2; // V0-ITS Tracks chi2 - std::vector mHe3Attachments; // # of attached tracks, 1 for V0s, 2 for He3s + std::vector mClusAttachments; // # of attached tracks, 1 for V0s, 2 for He3s + float mRadiusTol = 4.; // Radius tolerance for matching V0s - std::vector mITStrackRef; // Ref to the ITS track + std::vector mITStrackRef; // Ref to the ITS track DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis DCAFitter3 mFitter3Body; // optional DCA Fitter for final 3 Body refit - float mMaxChi2 = 30; // Maximum matching chi2 - float mBz = -5; // Magnetic field - o2::base::PropagatorImpl::MatCorrType mCorrType = o2::base::PropagatorImpl::MatCorrType::USEMatCorrNONE; //use mat correction + float mMaxChi2 = 30; // Maximum matching chi2 + float mBz = -5; // Magnetic field + o2::base::PropagatorImpl::MatCorrType mCorrType = o2::base::PropagatorImpl::MatCorrType::USEMatCorrNONE; // use mat correction o2::its::GeometryTGeo* mGeomITS; // ITS geometry V0 mV0; // V0 employed for the tracking diff --git a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx index 98bc924dda12f..1f5cdc95f7290 100644 --- a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx @@ -12,6 +12,7 @@ /// \brief #include "StrangenessTracking/HyperTracker.h" +#include namespace o2 { @@ -19,6 +20,15 @@ namespace strangeness_tracking { using ITSCluster = o2::BaseCluster; +int indexTableUtils::getBinIndex(float eta, float phi) +{ + float deltaPhi = 2 * TMath::Pi() / (mPhiBins); + float deltaEta = (maxEta - minEta) / (mEtaBins); + int bEta = (eta + (maxEta - minEta) / 2) / deltaEta; + int bPhi = phi / deltaPhi; + return abs(eta) > 1.5 ? mEtaBins * mPhiBins : bEta + mEtaBins * bPhi; +} + bool HyperTracker::loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, o2::its::GeometryTGeo* geomITS) { mInputV0tracks = InputV0tracks; @@ -35,32 +45,27 @@ bool HyperTracker::loadData(gsl::span InputITStracks, s return true; } -double HyperTracker::calcV0alpha(const V0& v0) +void HyperTracker::initialise() { - std::array fV0mom, fPmom, fNmom = {0, 0, 0}; - v0.getProng(0).getPxPyPzGlo(fPmom); - v0.getProng(1).getPxPyPzGlo(fNmom); - v0.getPxPyPzGlo(fV0mom); - - TVector3 momNeg(fNmom[0], fNmom[1], fNmom[2]); - TVector3 momPos(fPmom[0], fPmom[1], fPmom[2]); - TVector3 momTot(fV0mom[0], fV0mom[1], fV0mom[2]); + mTracksIdxTable.clear(); - Double_t lQlNeg = momNeg.Dot(momTot) / momTot.Mag(); - Double_t lQlPos = momPos.Dot(momTot) / momTot.Mag(); - - return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); -} + for (auto& track : mInputITStracks) { + mSortedITStracks.push_back(track); + } -std::vector HyperTracker::getTrackClusters(o2::its::TrackITS const& ITStrack) -{ - std::vector outVec; - auto firstClus = ITStrack.getFirstClusterEntry(); - auto ncl = ITStrack.getNumberOfClusters(); - for (int icl = 0; icl < ncl; icl++) { - outVec.push_back(mInputITSclusters[mInputITSidxs[firstClus + icl]]); + mTracksIdxTable.resize(mUtils.mPhiBins * mUtils.mEtaBins + 1); + std::sort(mSortedITStracks.begin(), mSortedITStracks.end(), [&](o2::its::TrackITS& a, o2::its::TrackITS& b) { return mUtils.getBinIndex(a.getEta(), a.getPhi()) < mUtils.getBinIndex(b.getEta(), b.getPhi()); }); + for (auto& track : mSortedITStracks) { + mTracksIdxTable[mUtils.getBinIndex(track.getEta(), track.getPhi())]++; + } + std::exclusive_scan(mTracksIdxTable.begin(), mTracksIdxTable.begin() + mUtils.mPhiBins * mUtils.mEtaBins, mTracksIdxTable.begin(), 0); + mTracksIdxTable[mUtils.mPhiBins * mUtils.mEtaBins] = mSortedITStracks.size(); + for (int iPhi{0}; iPhi < mUtils.mPhiBins; ++iPhi) { + for (int iEta{0}; iEta < mUtils.mEtaBins; ++iEta) { + std::cout << mTracksIdxTable[iEta + iPhi * mUtils.mEtaBins] << "\t"; + } + std::cout << std::endl; } - return outVec; } void HyperTracker::process() @@ -69,74 +74,84 @@ void HyperTracker::process() int counter = 0; for (auto& v0 : mInputV0tracks) { counter++; - LOG(debug) << "Analysing V0: " << counter << "/" << mInputV0tracks.size(); + LOG(info) << "Analysing V0: " << counter << "/" << mInputV0tracks.size(); auto posTrack = v0.getProng(0); auto negTrack = v0.getProng(1); auto alphaV0 = calcV0alpha(v0); + alphaV0 > 0 ? posTrack.setAbsCharge(2) : negTrack.setAbsCharge(2); if (!recreateV0(posTrack, negTrack, v0.getProngID(0), v0.getProngID(1))) continue; + auto tmpV0 = mV0; auto v0R2 = v0.calcR2(); - for (int iTrack{0}; iTrack < mInputITStracks.size(); iTrack++) { + int ibinV0 = mUtils.getBinIndex(tmpV0.getEta(), tmpV0.getPhi()); + // LOG(info) << "V0eta: " << v0.getEta() << " V0phi: " << v0.getPhi() << " V0r2: " << v0R2 << " ibinV0: " << ibinV0; + LOG(info) << mTracksIdxTable[ibinV0] << " " << mTracksIdxTable[ibinV0 + 1]; + + for (int iTrack{mTracksIdxTable[ibinV0]}; iTrack < TMath::Min(mTracksIdxTable[ibinV0 + 1], int(mSortedITStracks.size())); iTrack++) { mV0 = tmpV0; - auto& ITStrack = mInputITStracks[iTrack]; + auto& he3Track = alphaV0 > 0 ? mV0.getProng(0) : mV0.getProng(1); + auto& piTrack = alphaV0 < 0 ? mV0.getProng(0) : mV0.getProng(1); + auto& ITStrack = mSortedITStracks[iTrack]; + + // LOG(info) << "itrack: " << iTrack <<" V0 eta: " << tmpV0.getEta() << " phi: " << tmpV0.getPhi() << ", ITS eta: " << ITStrack.getEta() << " phi: " << ITStrack.getPhi(); auto trackClusters = getTrackClusters(ITStrack); - std::vector v0Clusters; + std::vector motherClusters; std::array nAttachments; + int nUpdates = 0; - auto isV0Upd = false; + bool isMotherUpdated = false; for (auto& clus : trackClusters) { - int prevUpdate = nUpdates; auto diffR2 = v0R2 - clus.getX() * clus.getX() - clus.getY() * clus.getY(); // difference between V0 and Layer R2 - - if (updateTrack(clus, mV0) and diffR2 > -4) { - v0Clusters.push_back(clus); - LOG(debug) << "Attach cluster to V0, layer: " << mGeomITS->getLayer(clus.getSensorID()); - nAttachments[mGeomITS->getLayer(clus.getSensorID())] = 1; - isV0Upd = true; - nUpdates++; + if (diffR2 > -mRadiusTol) { + // LOG(info) << "Try to attach cluster to V0, layer: " << mGeomITS->getLayer(clus.getSensorID()); + if (updateTrack(clus, mV0)) { + motherClusters.push_back(clus); + nAttachments[mGeomITS->getLayer(clus.getSensorID())] = 1; + isMotherUpdated = true; + nUpdates++; + continue; + } else { + if (isMotherUpdated == true) { + break; + } // no daughter clusters can be attached + } } - // if V0 is not found, check He3 compatibility - if (diffR2 < 4 && !isV0Upd) { - auto& he3track = calcV0alpha(mV0) > 0 ? mV0.getProng(0) : mV0.getProng(1); - if (!updateTrack(clus, he3track)) + // if V0 is not found, check for daughters compatibility + if (diffR2 < mRadiusTol && !isMotherUpdated) { + // LOG(info) << "Try to attach cluster to daughters, layer: " << mGeomITS->getLayer(clus.getSensorID()); + if (updateTrack(clus, he3Track)) + nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kFirstDaughter; + else if (updateTrack(clus, piTrack)) + nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kSecondDaughter; + else break; - if (!recreateV0(mV0.getProng(0), mV0.getProng(1), mV0.getProngID(0), mV0.getProngID(1))) - break; - LOG(debug) << "Attach cluster to he3, layer: " << mGeomITS->getLayer(clus.getSensorID()); - nAttachments[mGeomITS->getLayer(clus.getSensorID())] = 2; nUpdates++; } - - if (nUpdates == prevUpdate) - break; } - if (nUpdates < trackClusters.size()) + if (nUpdates < trackClusters.size() || motherClusters.size() == 0) continue; o2::track::TrackParCov hyperTrack = mV0; - // outward V0 propagation - if (v0Clusters.size() > 0) { - mV0.resetCovariance(); - std::reverse(v0Clusters.begin(), v0Clusters.end()); - for (auto& clus : v0Clusters) { - if (!updateTrack(clus, mV0)) - break; - } + mV0.resetCovariance(); + std::reverse(motherClusters.begin(), motherClusters.end()); + for (auto& clus : motherClusters) { + if (!updateTrack(clus, mV0)) + break; // final 3body refit - if (refitAllTracks()) { + if (refitTopology()) { LOG(debug) << "------------------------------------------------------"; LOG(debug) << "Pushing back v0: " << v0.getProngID(0) << ", " << v0.getProngID(1); - LOG(debug) << "number of clusters attached: " << v0Clusters.size(); + LOG(debug) << "number of clusters attached: " << motherClusters.size(); LOG(debug) << "Number of ITS track clusters: " << ITStrack.getNumberOfClusters(); LOG(debug) << "number of clusters attached to V0: " << nAttachments[0] << ", " << nAttachments[1] << ", " << nAttachments[2] << ", " << nAttachments[3] << ", " << nAttachments[4] << ", " << nAttachments[5] << ", " << nAttachments[6]; auto& lastClus = trackClusters[0]; @@ -145,10 +160,11 @@ void HyperTracker::process() mV0s.push_back(mV0); mHyperTracks.push_back(hyperTrack); mChi2.push_back(getMatchingChi2(tmpV0, ITStrack, lastClus)); + mR2.push_back(mV0.calcR2()); mITStrackRef.push_back(iTrack); - He3Attachments structHe3; - structHe3.arr = nAttachments; - mHe3Attachments.push_back(structHe3); + ClusAttachments structClus; + structClus.arr = nAttachments; + mClusAttachments.push_back(structClus); } } } @@ -174,7 +190,7 @@ bool HyperTracker::updateTrack(const ITSCluster& clus, o2::track::TrackParCov& t return false; } auto chi2 = std::abs(track.getPredictedChi2(clus)); - // LOG(info) << track.getPredictedChi2(clus); + // LOG(info) << "chi2" << track.getPredictedChi2(clus); if (chi2 > mMaxChi2 || chi2 < 0) return false; @@ -209,12 +225,38 @@ bool HyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2:: mV0 = V0(v0XYZ, pV0, mFitterV0.calcPCACovMatrixFlat(0), propPos, propNeg, posID, negID, o2::track::PID::HyperTriton); mV0.setAbsCharge(1); - mV0.setPID(o2::track::PID::HyperTriton); - return true; } -bool HyperTracker::refitAllTracks() +double HyperTracker::calcV0alpha(const V0& v0) +{ + std::array fV0mom, fPmom, fNmom = {0, 0, 0}; + v0.getProng(0).getPxPyPzGlo(fPmom); + v0.getProng(1).getPxPyPzGlo(fNmom); + v0.getPxPyPzGlo(fV0mom); + + TVector3 momNeg(fNmom[0], fNmom[1], fNmom[2]); + TVector3 momPos(fPmom[0], fPmom[1], fPmom[2]); + TVector3 momTot(fV0mom[0], fV0mom[1], fV0mom[2]); + + Double_t lQlNeg = momNeg.Dot(momTot) / momTot.Mag(); + Double_t lQlPos = momPos.Dot(momTot) / momTot.Mag(); + + return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); +} + +std::vector HyperTracker::getTrackClusters(o2::its::TrackITS const& ITStrack) +{ + std::vector outVec; + auto firstClus = ITStrack.getFirstClusterEntry(); + auto ncl = ITStrack.getNumberOfClusters(); + for (int icl = 0; icl < ncl; icl++) { + outVec.push_back(mInputITSclusters[mInputITSidxs[firstClus + icl]]); + } + return outVec; +} + +bool HyperTracker::refitTopology() { int cand = 0; // best V0 candidate int nCand; diff --git a/Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h b/Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h index a44bbbc05eda1..dedf27d8dfe64 100644 --- a/Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h +++ b/Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h @@ -17,7 +17,7 @@ #pragma link C++ class o2::strangeness_tracking::HypertrackerParamConfig + ; #pragma link C++ class o2::conf::ConfigurableParamHelper + ; -#pragma link C++ struct o2::strangeness_tracking::He3Attachments + ; -#pragma link C++ class std::vector + ; +#pragma link C++ struct o2::strangeness_tracking::ClusAttachments + ; +#pragma link C++ class std::vector + ; #endif diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx index 94edbefb6e8e3..9dfebb12ce365 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx @@ -134,12 +134,14 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) mTracker.setBz(field->getBz(origD)); mTracker.loadData(ITStracks, ITSClustersArray, ITSTrackClusIdx, v0vec, geom); + mTracker.initialise(); mTracker.process(); pc.outputs().snapshot(Output{"HYP", "V0S", 0, Lifetime::Timeframe}, mTracker.getV0()); pc.outputs().snapshot(Output{"HYP", "HYPERTRACKS", 0, Lifetime::Timeframe}, mTracker.getHyperTracks()); pc.outputs().snapshot(Output{"HYP", "CHI2", 0, Lifetime::Timeframe}, mTracker.getChi2vec()); - pc.outputs().snapshot(Output{"HYP", "HE3UPDATES", 0, Lifetime::Timeframe}, mTracker.getHe3Attachments()); + pc.outputs().snapshot(Output{"HYP", "R2", 0, Lifetime::Timeframe}, mTracker.getR2vec()); + pc.outputs().snapshot(Output{"HYP", "CLUSUPDATES", 0, Lifetime::Timeframe}, mTracker.getClusAttachments()); pc.outputs().snapshot(Output{"HYP", "ITSREFS", 0, Lifetime::Timeframe}, mTracker.getITStrackRef()); mTimer.Stop(); @@ -206,7 +208,9 @@ DataProcessorSpec getHyperTrackerSpec() outputs.emplace_back("HYP", "HYPERTRACKS", 0, Lifetime::Timeframe); outputs.emplace_back("HYP", "CHI2", 0, Lifetime::Timeframe); - outputs.emplace_back("HYP", "HE3UPDATES", 0, Lifetime::Timeframe); + outputs.emplace_back("HYP", "R2", 0, Lifetime::Timeframe); + + outputs.emplace_back("HYP", "CLUSUPDATES", 0, Lifetime::Timeframe); outputs.emplace_back("HYP", "ITSREFS", 0, Lifetime::Timeframe); return DataProcessorSpec{ diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx b/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx index 6dfe2b0814b93..7350c7f60b028 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx @@ -46,7 +46,8 @@ DataProcessorSpec getHypertrackingWriterSpec() auto inpV0ID = InputSpec{"v0s", "HYP", "V0S", 0}; auto inpTrackID = InputSpec{"hypertrack", "HYP", "HYPERTRACKS", 0}; auto inpChi2ID = InputSpec{"v0itschi2", "HYP", "CHI2", 0}; - auto inpHe3Att = InputSpec{"he3updates", "HYP", "HE3UPDATES",0}; + auto inpR2ID = InputSpec{"v0r2", "HYP", "R2", 0}; + auto inpClusAtt = InputSpec{"clusupdates", "HYP", "CLUSUPDATES",0}; auto inpRefID = InputSpec{"itsrefs", "HYP", "ITSREFS", 0}; return MakeRootTreeWriterSpec("hypertracking-writer", @@ -55,7 +56,8 @@ DataProcessorSpec getHypertrackingWriterSpec() BranchDefinition>{inpV0ID, "V0s", loggerV}, BranchDefinition>{inpTrackID, "Hypertracks", loggerT}, BranchDefinition>{inpChi2ID, "ITSV0Chi2"}, - BranchDefinition>{inpHe3Att, "He3Updates"}, + BranchDefinition>{inpR2ID, "R2"}, + BranchDefinition>{inpClusAtt, "ClusUpdates"}, BranchDefinition>{inpRefID, "ITSTrackRefs"})(); } From bfe43a63d2e8d23e05127b793d00ef364f8b158b Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Wed, 22 Jun 2022 18:04:06 +0200 Subject: [PATCH 18/36] Rectangular area for phi, eta selection --- .../StrangenessTracking/HyperTracker.h | 29 ++- .../tracking/src/HyperTracker.cxx | 212 +++++++++++------- 2 files changed, 146 insertions(+), 95 deletions(-) diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h index e827f57754f34..10792359b562d 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h @@ -41,18 +41,22 @@ struct ClusAttachments { }; struct indexTableUtils { - int getBinIndex(float phi, float eta); - int mEtaBins = 64, mPhiBins = 128; + int getEtaBin(float eta); + int getPhiBin(float phi); + int getBinIndex(float eta, float phi); + std::vector getBinRect(float eta, float phi, float deltaEta, float deltaPhi); + int mEtaBins = 64, mPhiBins = 64; float minEta = -1.5, maxEta = 1.5; + float minPhi = 0., maxPhi = 2 * TMath::Pi(); }; class HyperTracker { public: - enum kTopology { kMother = 0, - kFirstDaughter = 1, - kSecondDaughter = 2, - kThirdDaughter = 3 }; + enum kTopology { kMother = 1, + kFirstDaughter = 2, + kSecondDaughter = 3, + kThirdDaughter = 4}; using PID = o2::track::PID; using TrackITS = o2::its::TrackITS; @@ -108,6 +112,8 @@ class HyperTracker gsl::span mInputITSidxs; // input ITS track-cluster indexes gsl::span mInputV0tracks; // input V0 of decay daughters std::vector mSortedITStracks; // sorted ITS tracks + std::vector mSortedITSindexes; // indexes of sorted ITS tracks + indexTableUtils mUtils; std::vector mHyperTracks; // Final hypertrack @@ -115,22 +121,25 @@ class HyperTracker std::vector mChi2; // V0-ITS Tracks chi2 std::vector mR2; // Updated decay radius - std::vector mClusAttachments; // # of attached tracks, 1 for V0s, 2 for He3s + std::vector mClusAttachments; // # of attached tracks, 1 for mother, 2 for daughter float mRadiusTol = 4.; // Radius tolerance for matching V0s + float mMinMotherClus = 3.; // minimum number of cluster to be attached to the mother std::vector mITStrackRef; // Ref to the ITS track DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis DCAFitter3 mFitter3Body; // optional DCA Fitter for final 3 Body refit - float mMaxChi2 = 30; // Maximum matching chi2 - float mBz = -5; // Magnetic field + float mMaxChi2 = 50; // Maximum matching chi2 + float mBz = -5; + + // Magnetic field o2::base::PropagatorImpl::MatCorrType mCorrType = o2::base::PropagatorImpl::MatCorrType::USEMatCorrNONE; // use mat correction o2::its::GeometryTGeo* mGeomITS; // ITS geometry V0 mV0; // V0 employed for the tracking - ClassDefNV(HyperTracker, 1); + ClassDefNV(HyperTracker, 2); }; } // namespace strangeness_tracking diff --git a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx index 1f5cdc95f7290..96170eba34ebc 100644 --- a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx @@ -20,13 +20,54 @@ namespace strangeness_tracking { using ITSCluster = o2::BaseCluster; +int indexTableUtils::getEtaBin(float eta) +{ + float deltaEta = (maxEta - minEta) / (mEtaBins); + int bEta = (eta - minEta) / deltaEta; // bins recentered to 0 + return bEta; +} + +int indexTableUtils::getPhiBin(float phi) +{ + float deltaPhi = (maxPhi - minPhi) / (mPhiBins); + int bPhi = (phi - minPhi) / deltaPhi; // bin recentered to 0 + return bPhi; +} + int indexTableUtils::getBinIndex(float eta, float phi) { - float deltaPhi = 2 * TMath::Pi() / (mPhiBins); + float deltaPhi = (maxPhi - minPhi) / (mPhiBins); float deltaEta = (maxEta - minEta) / (mEtaBins); - int bEta = (eta + (maxEta - minEta) / 2) / deltaEta; - int bPhi = phi / deltaPhi; - return abs(eta) > 1.5 ? mEtaBins * mPhiBins : bEta + mEtaBins * bPhi; + int bEta = getEtaBin(eta); + int bPhi = getPhiBin(phi); + return bEta >= mEtaBins || bPhi >= mPhiBins ? mEtaBins * mPhiBins : bEta + mEtaBins * bPhi; +} + +std::vector indexTableUtils::getBinRect(float eta, float phi, float deltaEta, float deltaPhi) +{ + std::vector idxVec; + int centralBin = getBinIndex(eta, phi); + if (centralBin == mPhiBins * mEtaBins) { // condition for overflows + idxVec.push_back(centralBin); + return idxVec; + } + int minEtaBin = TMath::Max(0, getEtaBin(eta - deltaEta)); + int maxEtaBin = getEtaBin(eta + deltaEta); + LOG(info) << getPhiBin(phi - deltaPhi); + int minPhiBin = TMath::Max(0, getPhiBin(phi - deltaPhi)); + int maxPhiBin = getPhiBin(phi + deltaPhi); + // LOG(info) << minEtaBin << " " << maxEtaBin << " " << minPhiBin << " " << maxPhiBin; + + for (int iPhi{minPhiBin}; iPhi <= maxPhiBin; iPhi++) { + if (iPhi >= mPhiBins) + break; + for (int iEta{minEtaBin}; iEta <= maxEtaBin; iEta++) { + if (iEta >= mEtaBins) + break; + idxVec.push_back(iEta + mEtaBins * iPhi); + } + } + return idxVec; } bool HyperTracker::loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, o2::its::GeometryTGeo* geomITS) @@ -49,23 +90,20 @@ void HyperTracker::initialise() { mTracksIdxTable.clear(); - for (auto& track : mInputITStracks) { - mSortedITStracks.push_back(track); + for (int iTrack{0}; iTrack < mInputITStracks.size(); iTrack++) { + mSortedITStracks.push_back(mInputITStracks[iTrack]); + mSortedITSindexes.push_back(iTrack); } mTracksIdxTable.resize(mUtils.mPhiBins * mUtils.mEtaBins + 1); std::sort(mSortedITStracks.begin(), mSortedITStracks.end(), [&](o2::its::TrackITS& a, o2::its::TrackITS& b) { return mUtils.getBinIndex(a.getEta(), a.getPhi()) < mUtils.getBinIndex(b.getEta(), b.getPhi()); }); + std::sort(mSortedITSindexes.begin(), mSortedITSindexes.end(), [&](int i, int j) { return mUtils.getBinIndex(mInputITStracks[i].getEta(), mInputITStracks[i].getPhi()) < mUtils.getBinIndex(mInputITStracks[j].getEta(), mInputITStracks[j].getPhi()); }); + for (auto& track : mSortedITStracks) { mTracksIdxTable[mUtils.getBinIndex(track.getEta(), track.getPhi())]++; } std::exclusive_scan(mTracksIdxTable.begin(), mTracksIdxTable.begin() + mUtils.mPhiBins * mUtils.mEtaBins, mTracksIdxTable.begin(), 0); mTracksIdxTable[mUtils.mPhiBins * mUtils.mEtaBins] = mSortedITStracks.size(); - for (int iPhi{0}; iPhi < mUtils.mPhiBins; ++iPhi) { - for (int iEta{0}; iEta < mUtils.mEtaBins; ++iEta) { - std::cout << mTracksIdxTable[iEta + iPhi * mUtils.mEtaBins] << "\t"; - } - std::cout << std::endl; - } } void HyperTracker::process() @@ -86,85 +124,89 @@ void HyperTracker::process() auto tmpV0 = mV0; auto v0R2 = v0.calcR2(); + auto iBinsV0 = mUtils.getBinRect(tmpV0.getEta(), tmpV0.getPhi(), 0.1, 0.1); + for (int& iBinV0 : iBinsV0) { + LOG(info) << "iBinV0: " << iBinV0; + for (int iTrack{mTracksIdxTable[iBinV0]}; iTrack < TMath::Min(mTracksIdxTable[iBinV0 + 1], int(mSortedITStracks.size())); iTrack++) { + + mV0 = tmpV0; + auto& he3Track = alphaV0 > 0 ? mV0.getProng(0) : mV0.getProng(1); + auto& piTrack = alphaV0 < 0 ? mV0.getProng(0) : mV0.getProng(1); + auto& ITStrack = mSortedITStracks[iTrack]; + auto& ITSindexRef = mSortedITSindexes[iTrack]; + + LOG(info) << "V0 pos: " << v0.getProngID(0) << " V0 neg: " << v0.getProngID(1) << " V0pt: " << v0.getPt() << " ITSpt: " << ITStrack.getPt(); + LOG(info) << "V0 eta: " << v0.getEta() << " V0 phi: " << v0.getPhi() << " ITS eta: " << ITStrack.getEta() << " ITS phi: " << ITStrack.getPhi(); + + auto trackClusters = getTrackClusters(ITStrack); + std::vector motherClusters; + std::array nAttachments; + + int nUpdates = 0; + bool isMotherUpdated = false; + + for (auto& clus : trackClusters) { + auto diffR2 = v0R2 - clus.getX() * clus.getX() - clus.getY() * clus.getY(); // difference between V0 and Layer R2 + if (diffR2 > -mRadiusTol) { + LOG(info) << "Try to attach cluster to V0, layer: " << mGeomITS->getLayer(clus.getSensorID()); + if (updateTrack(clus, mV0)) { + motherClusters.push_back(clus); + nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kMother; + isMotherUpdated = true; + nUpdates++; + continue; + } else { + if (isMotherUpdated == true) { + break; + } // no daughter clusters can be attached + } + } - int ibinV0 = mUtils.getBinIndex(tmpV0.getEta(), tmpV0.getPhi()); - // LOG(info) << "V0eta: " << v0.getEta() << " V0phi: " << v0.getPhi() << " V0r2: " << v0R2 << " ibinV0: " << ibinV0; - LOG(info) << mTracksIdxTable[ibinV0] << " " << mTracksIdxTable[ibinV0 + 1]; - - for (int iTrack{mTracksIdxTable[ibinV0]}; iTrack < TMath::Min(mTracksIdxTable[ibinV0 + 1], int(mSortedITStracks.size())); iTrack++) { - - mV0 = tmpV0; - auto& he3Track = alphaV0 > 0 ? mV0.getProng(0) : mV0.getProng(1); - auto& piTrack = alphaV0 < 0 ? mV0.getProng(0) : mV0.getProng(1); - auto& ITStrack = mSortedITStracks[iTrack]; - - // LOG(info) << "itrack: " << iTrack <<" V0 eta: " << tmpV0.getEta() << " phi: " << tmpV0.getPhi() << ", ITS eta: " << ITStrack.getEta() << " phi: " << ITStrack.getPhi(); - - auto trackClusters = getTrackClusters(ITStrack); - std::vector motherClusters; - std::array nAttachments; - - int nUpdates = 0; - bool isMotherUpdated = false; + // if V0 is not found, check for daughters compatibility + if (diffR2 < mRadiusTol && !isMotherUpdated) { + LOG(info) << "Try to attach cluster to daughters, layer: " << mGeomITS->getLayer(clus.getSensorID()); - for (auto& clus : trackClusters) { - auto diffR2 = v0R2 - clus.getX() * clus.getX() - clus.getY() * clus.getY(); // difference between V0 and Layer R2 - if (diffR2 > -mRadiusTol) { - // LOG(info) << "Try to attach cluster to V0, layer: " << mGeomITS->getLayer(clus.getSensorID()); - if (updateTrack(clus, mV0)) { - motherClusters.push_back(clus); - nAttachments[mGeomITS->getLayer(clus.getSensorID())] = 1; - isMotherUpdated = true; - nUpdates++; - continue; - } else { - if (isMotherUpdated == true) { + if (updateTrack(clus, he3Track)) + nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kFirstDaughter; + else if (updateTrack(clus, piTrack)) + nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kSecondDaughter; + else break; - } // no daughter clusters can be attached + nUpdates++; } } - // if V0 is not found, check for daughters compatibility - if (diffR2 < mRadiusTol && !isMotherUpdated) { - // LOG(info) << "Try to attach cluster to daughters, layer: " << mGeomITS->getLayer(clus.getSensorID()); - if (updateTrack(clus, he3Track)) - nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kFirstDaughter; - else if (updateTrack(clus, piTrack)) - nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kSecondDaughter; - else - break; - nUpdates++; - } - } + if (nUpdates < trackClusters.size() || motherClusters.size() == 0) + continue; - if (nUpdates < trackClusters.size() || motherClusters.size() == 0) - continue; - - o2::track::TrackParCov hyperTrack = mV0; - mV0.resetCovariance(); - std::reverse(motherClusters.begin(), motherClusters.end()); - for (auto& clus : motherClusters) { - if (!updateTrack(clus, mV0)) - break; - - // final 3body refit - if (refitTopology()) { - LOG(debug) << "------------------------------------------------------"; - LOG(debug) << "Pushing back v0: " << v0.getProngID(0) << ", " << v0.getProngID(1); - LOG(debug) << "number of clusters attached: " << motherClusters.size(); - LOG(debug) << "Number of ITS track clusters: " << ITStrack.getNumberOfClusters(); - LOG(debug) << "number of clusters attached to V0: " << nAttachments[0] << ", " << nAttachments[1] << ", " << nAttachments[2] << ", " << nAttachments[3] << ", " << nAttachments[4] << ", " << nAttachments[5] << ", " << nAttachments[6]; - auto& lastClus = trackClusters[0]; - LOG(debug) << "Matching chi2: " << getMatchingChi2(tmpV0, ITStrack, lastClus); - - mV0s.push_back(mV0); - mHyperTracks.push_back(hyperTrack); - mChi2.push_back(getMatchingChi2(tmpV0, ITStrack, lastClus)); - mR2.push_back(mV0.calcR2()); - mITStrackRef.push_back(iTrack); - ClusAttachments structClus; - structClus.arr = nAttachments; - mClusAttachments.push_back(structClus); + o2::track::TrackParCov hyperTrack = mV0; + mV0.resetCovariance(); + if (motherClusters.size() >= mMinMotherClus) { //fill only if at least mMinMotherClus clusters of the mother V0 have been attached + std::reverse(motherClusters.begin(), motherClusters.end()); + for (auto& clus : motherClusters) { + if (!updateTrack(clus, mV0)) + break; + } + + // final 3body refit + if (refitTopology()) { + LOG(info) << "------------------------------------------------------"; + LOG(info) << "Pushing back v0: " << v0.getProngID(0) << ", " << v0.getProngID(1); + LOG(info) << "number of clusters attached: " << motherClusters.size(); + LOG(info) << "Number of ITS track clusters: " << ITStrack.getNumberOfClusters(); + LOG(info) << "number of clusters attached to V0: " << nAttachments[0] << ", " << nAttachments[1] << ", " << nAttachments[2] << ", " << nAttachments[3] << ", " << nAttachments[4] << ", " << nAttachments[5] << ", " << nAttachments[6]; + auto& lastClus = trackClusters[0]; + LOG(info) << "Matching chi2: " << getMatchingChi2(tmpV0, ITStrack, lastClus); + + mV0s.push_back(mV0); + mHyperTracks.push_back(hyperTrack); + mChi2.push_back(getMatchingChi2(tmpV0, ITStrack, lastClus)); + mR2.push_back(mV0.calcR2()); + mITStrackRef.push_back(ITSindexRef); + ClusAttachments structClus; + structClus.arr = nAttachments; + mClusAttachments.push_back(structClus); + } } } } @@ -190,7 +232,7 @@ bool HyperTracker::updateTrack(const ITSCluster& clus, o2::track::TrackParCov& t return false; } auto chi2 = std::abs(track.getPredictedChi2(clus)); - // LOG(info) << "chi2" << track.getPredictedChi2(clus); + LOG(info) << "chi2: " << track.getPredictedChi2(clus); if (chi2 > mMaxChi2 || chi2 < 0) return false; From 47fc42f99e7983697cde01ce0a074ffdc822157d Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Thu, 23 Jun 2022 19:01:19 +0200 Subject: [PATCH 19/36] Directory and code refactoring --- .../tracking/CMakeLists.txt | 13 +- .../StrangenessTracking/IndexTableUtils.h | 37 ++ .../{HyperTracker.h => StrangenessTracker.h} | 98 ++--- ...ram.h => StrangenessTrackingConfigParam.h} | 8 +- .../tracking/src/HyperTracker.cxx | 341 ------------------ .../tracking/src/IndexTableUtils.cxx | 72 ++++ .../tracking/src/StrangenessTracker.cxx | 301 ++++++++++++++++ ...cxx => StrangenessTrackingConfigParam.cxx} | 6 +- ...LinkDef.h => StrangenessTrackingLinkDef.h} | 11 +- .../workflow/CMakeLists.txt | 8 +- ...ackingSpec.h => StrangenessTrackingSpec.h} | 16 +- ...Spec.h => StrangenessTrackingWriterSpec.h} | 8 +- ...ngSpec.cxx => StrangenessTrackingSpec.cxx} | 57 ++- ....cxx => StrangenessTrackingWriterSpec.cxx} | 37 +- ....cxx => strangeness-tracking-workflow.cxx} | 10 +- 15 files changed, 550 insertions(+), 473 deletions(-) create mode 100644 Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h rename Detectors/StrangenessTracking/tracking/include/StrangenessTracking/{HyperTracker.h => StrangenessTracker.h} (57%) rename Detectors/StrangenessTracking/tracking/include/StrangenessTracking/{HypertrackingConfigParam.h => StrangenessTrackingConfigParam.h} (73%) delete mode 100644 Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx create mode 100644 Detectors/StrangenessTracking/tracking/src/IndexTableUtils.cxx create mode 100644 Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx rename Detectors/StrangenessTracking/tracking/src/{HypertrackingConfigParam.cxx => StrangenessTrackingConfigParam.cxx} (72%) rename Detectors/StrangenessTracking/tracking/src/{HypertrackingLinkDef.h => StrangenessTrackingLinkDef.h} (66%) rename Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/{HypertrackingSpec.h => StrangenessTrackingSpec.h} (83%) rename Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/{HypertrackingWriterSpec.h => StrangenessTrackingWriterSpec.h} (80%) rename Detectors/StrangenessTracking/workflow/src/{HypertrackingSpec.cxx => StrangenessTrackingSpec.cxx} (82%) rename Detectors/StrangenessTracking/workflow/src/{HypertrackingWriterSpec.cxx => StrangenessTrackingWriterSpec.cxx} (54%) rename Detectors/StrangenessTracking/workflow/src/{hypertracking-workflow.cxx => strangeness-tracking-workflow.cxx} (86%) diff --git a/Detectors/StrangenessTracking/tracking/CMakeLists.txt b/Detectors/StrangenessTracking/tracking/CMakeLists.txt index f0c510e4319e8..da0688ce9859a 100644 --- a/Detectors/StrangenessTracking/tracking/CMakeLists.txt +++ b/Detectors/StrangenessTracking/tracking/CMakeLists.txt @@ -10,8 +10,9 @@ # or submit itself to any jurisdiction. o2_add_library(StrangenessTracking - SOURCES src/HyperTracker.cxx - src/HypertrackingConfigParam.cxx + SOURCES src/StrangenessTracker.cxx + src/StrangenessTrackingConfigParam.cxx + src/IndexTableUtils.cxx PUBLIC_LINK_LIBRARIES O2::MathUtils O2::ITSBase O2::ITSMFTReconstruction @@ -24,7 +25,9 @@ o2_add_library(StrangenessTracking ) o2_target_root_dictionary(StrangenessTracking - HEADERS include/StrangenessTracking/HypertrackingConfigParam.h - include/StrangenessTracking/HyperTracker.h + HEADERS include/StrangenessTracking/StrangenessTrackingConfigParam.h + include/StrangenessTracking/IndexTableUtils.h + include/StrangenessTracking/StrangenessTracker.h - LINKDEF src/HypertrackingLinkDef.h) \ No newline at end of file + + LINKDEF src/StrangenessTrackingLinkDef.h) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h new file mode 100644 index 0000000000000..6fbfefc8a4783 --- /dev/null +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h @@ -0,0 +1,37 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file IndexTableUtils.h +/// \brief +/// +#ifndef STRTRACKING_INCLUDE_INDEXTABLEUTILS_H_ +#define STRTRACKING_INCLUDE_INDEXTABLEUTILS_H_ + +#include "TMath.h" + +namespace o2 +{ +namespace strangeness_tracking +{ + +struct indexTableUtils { + int getEtaBin(float eta); + int getPhiBin(float phi); + int getBinIndex(float eta, float phi); + std::vector getBinRect(float eta, float phi, float deltaEta, float deltaPhi); + int mEtaBins = 64, mPhiBins = 64; + float minEta = -1.5, maxEta = 1.5; + float minPhi = 0., maxPhi = 2 * TMath::Pi(); +}; +} // namespace strangeness_tracking +} // namespace o2 + +#endif \ No newline at end of file diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h similarity index 57% rename from Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h rename to Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h index 10792359b562d..1188975050f3a 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h @@ -9,19 +9,22 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file HyperTracker.h +/// \file StrangenessTracker.h /// \brief /// -#ifndef _ALICEO2_HYPER_TRACKER_ -#define _ALICEO2_HYPER_TRACKER_ +#ifndef _ALICEO2_STRANGENESS_TRACKER_ +#define _ALICEO2_STRANGENESS_TRACKER_ #include #include #include "TMath.h" +#include "IndexTableUtils.h" #include "ReconstructionDataFormats/PID.h" #include "ReconstructionDataFormats/V0.h" +#include "ReconstructionDataFormats/Cascade.h" + #include "DataFormatsITS/TrackITS.h" #include "ITSBase/GeometryTGeo.h" #include "ReconstructionDataFormats/Track.h" @@ -40,42 +43,47 @@ struct ClusAttachments { std::array arr; }; -struct indexTableUtils { - int getEtaBin(float eta); - int getPhiBin(float phi); - int getBinIndex(float eta, float phi); - std::vector getBinRect(float eta, float phi, float deltaEta, float deltaPhi); - int mEtaBins = 64, mPhiBins = 64; - float minEta = -1.5, maxEta = 1.5; - float minPhi = 0., maxPhi = 2 * TMath::Pi(); +struct StrangeTrack { + o2::track::TrackParCovF mMother; + o2::track::TrackParCovF mDaughterFirst; + o2::track::TrackParCovF mDaughterSecond; + o2::track::TrackParCovF mBachelor; + std::array decayVtx; + + float mMatchChi2; + float mTopoChi2; + int isCascade = false; }; -class HyperTracker +class StrangenessTracker { public: enum kTopology { kMother = 1, kFirstDaughter = 2, kSecondDaughter = 3, - kThirdDaughter = 4}; + kThirdDaughter = 4, + kBachelor = 5 }; using PID = o2::track::PID; using TrackITS = o2::its::TrackITS; using ITSCluster = o2::BaseCluster; using V0 = o2::dataformats::V0; + using Cascade = o2::dataformats::Cascade; + using GIndex = o2::dataformats::VtxTrackIndex; using DCAFitter2 = o2::vertexing::DCAFitterN<2>; using DCAFitter3 = o2::vertexing::DCAFitterN<3>; - HyperTracker() = default; - ~HyperTracker() = default; + StrangenessTracker() = default; + ~StrangenessTracker() = default; - std::vector& getV0() { return mV0s; }; - std::vector& getHyperTracks() { return mHyperTracks; }; - std::vector& getChi2vec() { return mChi2; }; - std::vector& getR2vec() { return mR2; }; + void initialise(); + void process(); std::vector& getClusAttachments() { return mClusAttachments; }; - std::vector& getITStrackRef() { return mITStrackRef; }; + std::vector& getStrangeTrackVec() { return mStrangeTrackVec; }; + std::vector& getITStrackRefVec() { return mITStrackRefVec; }; + std::vector& getDecayTrackRefVec() { return mDecayTrackRefVec; }; float getMaxChi2() const { return mMaxChi2; } void setMaxChi2(float d) { mMaxChi2 = d; } @@ -91,19 +99,17 @@ class HyperTracker // mFitter3Body.setUseAbsDCA(true); } - bool loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, o2::its::GeometryTGeo* geomITS); + bool loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, gsl::span InputCascadeTracks, o2::its::GeometryTGeo* geomITS); double calcV0alpha(const V0& v0); - std::vector getTrackClusters(o2::its::TrackITS const& ITStrack); + std::vector getTrackClusters(); + float getMatchingChi2(V0 v0, const TrackITS ITSTrack, ITSCluster matchingClus); + bool recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const GIndex posID, const GIndex negID, V0& newV0); bool updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track); + bool updateTopology(std::array& nAttachments, std::vector& motherClusters, const std::vector& trackClusters, float decayRadius, bool isCascade); + bool refitTopology(o2::track::TrackParCovF& ITSmotherTrack); - void initialise(); - void process(); - - bool recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const GIndex posID, const GIndex negID); - bool refitTopology(); - float getMatchingChi2(V0 v0, const TrackITS ITSTrack, ITSCluster matchingClus); protected: gsl::span mInputITStracks; // input ITS tracks @@ -111,38 +117,34 @@ class HyperTracker std::vector mInputITSclusters; // input ITS clusters gsl::span mInputITSidxs; // input ITS track-cluster indexes gsl::span mInputV0tracks; // input V0 of decay daughters - std::vector mSortedITStracks; // sorted ITS tracks - std::vector mSortedITSindexes; // indexes of sorted ITS tracks - - indexTableUtils mUtils; + gsl::span mInputCascadeTracks; // input V0 of decay daughters - std::vector mHyperTracks; // Final hypertrack - std::vector mV0s; // V0 of decay daughters - std::vector mChi2; // V0-ITS Tracks chi2 - std::vector mR2; // Updated decay radius + std::vector mSortedITStracks; // sorted ITS tracks + std::vector mSortedITSindexes; // indexes of sorted ITS tracks + indexTableUtils mUtils; // structure for computing eta/phi matching selections + std::vector mStrangeTrackVec; // structure containing updated mother and daughter tracks std::vector mClusAttachments; // # of attached tracks, 1 for mother, 2 for daughter - float mRadiusTol = 4.; // Radius tolerance for matching V0s - float mMinMotherClus = 3.; // minimum number of cluster to be attached to the mother + std::vector mITStrackRefVec; // Ref to the ITS tracks + std::vector mDecayTrackRefVec; // Ref to the Cascade and V0 files - std::vector mITStrackRef; // Ref to the ITS track + float mRadiusTol = 4.; // Radius tolerance for matching V0s + float mMinMotherClus = 3.; // minimum number of cluster to be attached to the mother + float mMaxChi2 = 50; // Maximum matching chi2 + float mBz = -5; // Magnetic field DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis DCAFitter3 mFitter3Body; // optional DCA Fitter for final 3 Body refit - float mMaxChi2 = 50; // Maximum matching chi2 - float mBz = -5; - - // Magnetic field o2::base::PropagatorImpl::MatCorrType mCorrType = o2::base::PropagatorImpl::MatCorrType::USEMatCorrNONE; // use mat correction + o2::its::GeometryTGeo* mGeomITS; // ITS geometry + StrangeTrack mStrangeTrack; + o2::its::TrackITS mITStrack; - o2::its::GeometryTGeo* mGeomITS; // ITS geometry - V0 mV0; // V0 employed for the tracking - - ClassDefNV(HyperTracker, 2); + ClassDefNV(StrangenessTracker, 1); }; } // namespace strangeness_tracking } // namespace o2 -#endif // _ALICEO2_HYPER_TRACKER_ +#endif // _ALICEO2_STRANGENESS_TRACKER_ diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HypertrackingConfigParam.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h similarity index 73% rename from Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HypertrackingConfigParam.h rename to Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h index 03d3c6d630ef5..21792256a9f66 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HypertrackingConfigParam.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h @@ -9,8 +9,8 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef ALICEO2_HYPERTRACKINGPARAM_H_ -#define ALICEO2_HYPERTRACKINGPARAM_H_ +#ifndef ALICEO2_STRANGENESS_TRACKING_PARAM_H_ +#define ALICEO2_STRANGENESS_TRACKING_PARAM_H_ #include "CommonUtils/ConfigurableParam.h" #include "CommonUtils/ConfigurableParamHelper.h" @@ -20,10 +20,10 @@ namespace o2 namespace strangeness_tracking { -struct HypertrackerParamConfig : public o2::conf::ConfigurableParamHelper { +struct StrangenessTrackingParamConfig : public o2::conf::ConfigurableParamHelper { float dummy = 0; - O2ParamDef(HypertrackerParamConfig, "HypertrackerParam"); + O2ParamDef(StrangenessTrackingParamConfig, "StrangenessTrackingParam"); }; } // namespace strangeness_tracking diff --git a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx b/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx deleted file mode 100644 index 96170eba34ebc..0000000000000 --- a/Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -/// \file HyperTracker.cxx -/// \brief - -#include "StrangenessTracking/HyperTracker.h" -#include - -namespace o2 -{ -namespace strangeness_tracking -{ -using ITSCluster = o2::BaseCluster; - -int indexTableUtils::getEtaBin(float eta) -{ - float deltaEta = (maxEta - minEta) / (mEtaBins); - int bEta = (eta - minEta) / deltaEta; // bins recentered to 0 - return bEta; -} - -int indexTableUtils::getPhiBin(float phi) -{ - float deltaPhi = (maxPhi - minPhi) / (mPhiBins); - int bPhi = (phi - minPhi) / deltaPhi; // bin recentered to 0 - return bPhi; -} - -int indexTableUtils::getBinIndex(float eta, float phi) -{ - float deltaPhi = (maxPhi - minPhi) / (mPhiBins); - float deltaEta = (maxEta - minEta) / (mEtaBins); - int bEta = getEtaBin(eta); - int bPhi = getPhiBin(phi); - return bEta >= mEtaBins || bPhi >= mPhiBins ? mEtaBins * mPhiBins : bEta + mEtaBins * bPhi; -} - -std::vector indexTableUtils::getBinRect(float eta, float phi, float deltaEta, float deltaPhi) -{ - std::vector idxVec; - int centralBin = getBinIndex(eta, phi); - if (centralBin == mPhiBins * mEtaBins) { // condition for overflows - idxVec.push_back(centralBin); - return idxVec; - } - int minEtaBin = TMath::Max(0, getEtaBin(eta - deltaEta)); - int maxEtaBin = getEtaBin(eta + deltaEta); - LOG(info) << getPhiBin(phi - deltaPhi); - int minPhiBin = TMath::Max(0, getPhiBin(phi - deltaPhi)); - int maxPhiBin = getPhiBin(phi + deltaPhi); - // LOG(info) << minEtaBin << " " << maxEtaBin << " " << minPhiBin << " " << maxPhiBin; - - for (int iPhi{minPhiBin}; iPhi <= maxPhiBin; iPhi++) { - if (iPhi >= mPhiBins) - break; - for (int iEta{minEtaBin}; iEta <= maxEtaBin; iEta++) { - if (iEta >= mEtaBins) - break; - idxVec.push_back(iEta + mEtaBins * iPhi); - } - } - return idxVec; -} - -bool HyperTracker::loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, o2::its::GeometryTGeo* geomITS) -{ - mInputV0tracks = InputV0tracks; - mInputITStracks = InputITStracks; - mInputITSclusters = InputITSclusters; - mInputITSidxs = InputITSidxs; - LOG(info) << "all tracks loaded"; - LOG(info) << "V0 tracks size: " << mInputV0tracks.size(); - LOG(info) << "ITS tracks size: " << mInputITStracks.size(); - LOG(info) << "ITS clusters size: " << mInputITSclusters.size(); - LOG(info) << "ITS idxs size: " << mInputITSidxs.size(); - mGeomITS = geomITS; - setupFitters(); - return true; -} - -void HyperTracker::initialise() -{ - mTracksIdxTable.clear(); - - for (int iTrack{0}; iTrack < mInputITStracks.size(); iTrack++) { - mSortedITStracks.push_back(mInputITStracks[iTrack]); - mSortedITSindexes.push_back(iTrack); - } - - mTracksIdxTable.resize(mUtils.mPhiBins * mUtils.mEtaBins + 1); - std::sort(mSortedITStracks.begin(), mSortedITStracks.end(), [&](o2::its::TrackITS& a, o2::its::TrackITS& b) { return mUtils.getBinIndex(a.getEta(), a.getPhi()) < mUtils.getBinIndex(b.getEta(), b.getPhi()); }); - std::sort(mSortedITSindexes.begin(), mSortedITSindexes.end(), [&](int i, int j) { return mUtils.getBinIndex(mInputITStracks[i].getEta(), mInputITStracks[i].getPhi()) < mUtils.getBinIndex(mInputITStracks[j].getEta(), mInputITStracks[j].getPhi()); }); - - for (auto& track : mSortedITStracks) { - mTracksIdxTable[mUtils.getBinIndex(track.getEta(), track.getPhi())]++; - } - std::exclusive_scan(mTracksIdxTable.begin(), mTracksIdxTable.begin() + mUtils.mPhiBins * mUtils.mEtaBins, mTracksIdxTable.begin(), 0); - mTracksIdxTable[mUtils.mPhiBins * mUtils.mEtaBins] = mSortedITStracks.size(); -} - -void HyperTracker::process() -{ - - int counter = 0; - for (auto& v0 : mInputV0tracks) { - counter++; - LOG(info) << "Analysing V0: " << counter << "/" << mInputV0tracks.size(); - - auto posTrack = v0.getProng(0); - auto negTrack = v0.getProng(1); - auto alphaV0 = calcV0alpha(v0); - - alphaV0 > 0 ? posTrack.setAbsCharge(2) : negTrack.setAbsCharge(2); - if (!recreateV0(posTrack, negTrack, v0.getProngID(0), v0.getProngID(1))) - continue; - - auto tmpV0 = mV0; - auto v0R2 = v0.calcR2(); - auto iBinsV0 = mUtils.getBinRect(tmpV0.getEta(), tmpV0.getPhi(), 0.1, 0.1); - for (int& iBinV0 : iBinsV0) { - LOG(info) << "iBinV0: " << iBinV0; - for (int iTrack{mTracksIdxTable[iBinV0]}; iTrack < TMath::Min(mTracksIdxTable[iBinV0 + 1], int(mSortedITStracks.size())); iTrack++) { - - mV0 = tmpV0; - auto& he3Track = alphaV0 > 0 ? mV0.getProng(0) : mV0.getProng(1); - auto& piTrack = alphaV0 < 0 ? mV0.getProng(0) : mV0.getProng(1); - auto& ITStrack = mSortedITStracks[iTrack]; - auto& ITSindexRef = mSortedITSindexes[iTrack]; - - LOG(info) << "V0 pos: " << v0.getProngID(0) << " V0 neg: " << v0.getProngID(1) << " V0pt: " << v0.getPt() << " ITSpt: " << ITStrack.getPt(); - LOG(info) << "V0 eta: " << v0.getEta() << " V0 phi: " << v0.getPhi() << " ITS eta: " << ITStrack.getEta() << " ITS phi: " << ITStrack.getPhi(); - - auto trackClusters = getTrackClusters(ITStrack); - std::vector motherClusters; - std::array nAttachments; - - int nUpdates = 0; - bool isMotherUpdated = false; - - for (auto& clus : trackClusters) { - auto diffR2 = v0R2 - clus.getX() * clus.getX() - clus.getY() * clus.getY(); // difference between V0 and Layer R2 - if (diffR2 > -mRadiusTol) { - LOG(info) << "Try to attach cluster to V0, layer: " << mGeomITS->getLayer(clus.getSensorID()); - if (updateTrack(clus, mV0)) { - motherClusters.push_back(clus); - nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kMother; - isMotherUpdated = true; - nUpdates++; - continue; - } else { - if (isMotherUpdated == true) { - break; - } // no daughter clusters can be attached - } - } - - // if V0 is not found, check for daughters compatibility - if (diffR2 < mRadiusTol && !isMotherUpdated) { - LOG(info) << "Try to attach cluster to daughters, layer: " << mGeomITS->getLayer(clus.getSensorID()); - - if (updateTrack(clus, he3Track)) - nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kFirstDaughter; - else if (updateTrack(clus, piTrack)) - nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kSecondDaughter; - else - break; - nUpdates++; - } - } - - if (nUpdates < trackClusters.size() || motherClusters.size() == 0) - continue; - - o2::track::TrackParCov hyperTrack = mV0; - mV0.resetCovariance(); - if (motherClusters.size() >= mMinMotherClus) { //fill only if at least mMinMotherClus clusters of the mother V0 have been attached - std::reverse(motherClusters.begin(), motherClusters.end()); - for (auto& clus : motherClusters) { - if (!updateTrack(clus, mV0)) - break; - } - - // final 3body refit - if (refitTopology()) { - LOG(info) << "------------------------------------------------------"; - LOG(info) << "Pushing back v0: " << v0.getProngID(0) << ", " << v0.getProngID(1); - LOG(info) << "number of clusters attached: " << motherClusters.size(); - LOG(info) << "Number of ITS track clusters: " << ITStrack.getNumberOfClusters(); - LOG(info) << "number of clusters attached to V0: " << nAttachments[0] << ", " << nAttachments[1] << ", " << nAttachments[2] << ", " << nAttachments[3] << ", " << nAttachments[4] << ", " << nAttachments[5] << ", " << nAttachments[6]; - auto& lastClus = trackClusters[0]; - LOG(info) << "Matching chi2: " << getMatchingChi2(tmpV0, ITStrack, lastClus); - - mV0s.push_back(mV0); - mHyperTracks.push_back(hyperTrack); - mChi2.push_back(getMatchingChi2(tmpV0, ITStrack, lastClus)); - mR2.push_back(mV0.calcR2()); - mITStrackRef.push_back(ITSindexRef); - ClusAttachments structClus; - structClus.arr = nAttachments; - mClusAttachments.push_back(structClus); - } - } - } - } - } -} - -bool HyperTracker::updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track) -{ - auto propInstance = o2::base::Propagator::Instance(); - float alpha = mGeomITS->getSensorRefAlpha(clus.getSensorID()), x = clus.getX(); - int layer{mGeomITS->getLayer(clus.getSensorID())}; - - if (!track.rotate(alpha)) - return false; - - if (!propInstance->propagateToX(track, x, getBz(), o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, mCorrType)) - return false; - if (mCorrType == o2::base::PropagatorF::MatCorrType::USEMatCorrNONE) { - float thick = layer < 3 ? 0.005 : 0.01; - constexpr float radl = 9.36f; // Radiation length of Si [cm] - constexpr float rho = 2.33f; // Density of Si [g/cm^3] - if (!track.correctForMaterial(thick, thick * rho * radl)) - return false; - } - auto chi2 = std::abs(track.getPredictedChi2(clus)); - LOG(info) << "chi2: " << track.getPredictedChi2(clus); - if (chi2 > mMaxChi2 || chi2 < 0) - return false; - - if (!track.update(clus)) - return false; - - return true; -} - -bool HyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const GIndex posID, const GIndex negID) -{ - - int nCand; - try { - nCand = mFitterV0.process(posTrack, negTrack); - } catch (std::runtime_error& e) { - return false; - } - if (!nCand) - return false; - - mFitterV0.propagateTracksToVertex(); - const auto& v0XYZ = mFitterV0.getPCACandidatePos(); - - auto& propPos = mFitterV0.getTrack(0, 0); - auto& propNeg = mFitterV0.getTrack(1, 0); - - std::array pP, pN; - propPos.getPxPyPzGlo(pP); - propNeg.getPxPyPzGlo(pN); - std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; - - mV0 = V0(v0XYZ, pV0, mFitterV0.calcPCACovMatrixFlat(0), propPos, propNeg, posID, negID, o2::track::PID::HyperTriton); - mV0.setAbsCharge(1); - return true; -} - -double HyperTracker::calcV0alpha(const V0& v0) -{ - std::array fV0mom, fPmom, fNmom = {0, 0, 0}; - v0.getProng(0).getPxPyPzGlo(fPmom); - v0.getProng(1).getPxPyPzGlo(fNmom); - v0.getPxPyPzGlo(fV0mom); - - TVector3 momNeg(fNmom[0], fNmom[1], fNmom[2]); - TVector3 momPos(fPmom[0], fPmom[1], fPmom[2]); - TVector3 momTot(fV0mom[0], fV0mom[1], fV0mom[2]); - - Double_t lQlNeg = momNeg.Dot(momTot) / momTot.Mag(); - Double_t lQlPos = momPos.Dot(momTot) / momTot.Mag(); - - return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); -} - -std::vector HyperTracker::getTrackClusters(o2::its::TrackITS const& ITStrack) -{ - std::vector outVec; - auto firstClus = ITStrack.getFirstClusterEntry(); - auto ncl = ITStrack.getNumberOfClusters(); - for (int icl = 0; icl < ncl; icl++) { - outVec.push_back(mInputITSclusters[mInputITSidxs[firstClus + icl]]); - } - return outVec; -} - -bool HyperTracker::refitTopology() -{ - int cand = 0; // best V0 candidate - int nCand; - - try { - nCand = mFitter3Body.process(mV0, mV0.getProng(0), mV0.getProng(1)); - } catch (std::runtime_error& e) { - return false; - } - if (!nCand) - return false; - - mFitter3Body.propagateTracksToVertex(); - auto& propPos = mFitter3Body.getTrack(1, 0); - auto& propNeg = mFitter3Body.getTrack(2, 0); - - const auto& v0XYZ = mFitter3Body.getPCACandidatePos(); - std::array pP, pN; - propPos.getPxPyPzGlo(pP); - propNeg.getPxPyPzGlo(pN); - std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; - - mV0 = V0(v0XYZ, pV0, mFitter3Body.calcPCACovMatrixFlat(cand), propPos, propNeg, mV0.getProngID(0), mV0.getProngID(1), o2::track::PID::HyperTriton); - mV0.setAbsCharge(1); - return true; -} - -float HyperTracker::getMatchingChi2(V0 v0, const TrackITS ITStrack, ITSCluster matchingClus) -{ - float alpha = mGeomITS->getSensorRefAlpha(matchingClus.getSensorID()), x = matchingClus.getX(); - if (v0.rotate(alpha)) { - if (v0.propagateTo(x, mBz)) { - return v0.getPredictedChi2(ITStrack.getParamOut()); - } - } - return -100; -} - -} // namespace strangeness_tracking -} // namespace o2 \ No newline at end of file diff --git a/Detectors/StrangenessTracking/tracking/src/IndexTableUtils.cxx b/Detectors/StrangenessTracking/tracking/src/IndexTableUtils.cxx new file mode 100644 index 0000000000000..fd9045ff85cc4 --- /dev/null +++ b/Detectors/StrangenessTracking/tracking/src/IndexTableUtils.cxx @@ -0,0 +1,72 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file IndexTableUtils.cxx +/// \brief +/// + +#include "TMath.h" +#include "StrangenessTracking/IndexTableUtils.h" + +namespace o2 +{ +namespace strangeness_tracking +{ + +int indexTableUtils::getEtaBin(float eta) +{ + float deltaEta = (maxEta - minEta) / (mEtaBins); + int bEta = (eta - minEta) / deltaEta; // bins recentered to 0 + return bEta; +}; + +int indexTableUtils::getPhiBin(float phi) +{ + float deltaPhi = (maxPhi - minPhi) / (mPhiBins); + int bPhi = (phi - minPhi) / deltaPhi; // bin recentered to 0 + return bPhi; +} + +int indexTableUtils::getBinIndex(float eta, float phi) +{ + float deltaPhi = (maxPhi - minPhi) / (mPhiBins); + float deltaEta = (maxEta - minEta) / (mEtaBins); + int bEta = getEtaBin(eta); + int bPhi = getPhiBin(phi); + return bEta >= mEtaBins || bPhi >= mPhiBins ? mEtaBins * mPhiBins : bEta + mEtaBins * bPhi; +} + +std::vector indexTableUtils::getBinRect(float eta, float phi, float deltaEta, float deltaPhi) +{ + std::vector idxVec; + int centralBin = getBinIndex(eta, phi); + if (centralBin == mPhiBins * mEtaBins) { // condition for overflows + idxVec.push_back(centralBin); + return idxVec; + } + int minEtaBin = TMath::Max(0, getEtaBin(eta - deltaEta)); + int maxEtaBin = getEtaBin(eta + deltaEta); + int minPhiBin = TMath::Max(0, getPhiBin(phi - deltaPhi)); + int maxPhiBin = getPhiBin(phi + deltaPhi); + + for (int iPhi{minPhiBin}; iPhi <= maxPhiBin; iPhi++) { + if (iPhi >= mPhiBins) + break; + for (int iEta{minEtaBin}; iEta <= maxEtaBin; iEta++) { + if (iEta >= mEtaBins) + break; + idxVec.push_back(iEta + mEtaBins * iPhi); + } + } + return idxVec; +}; +} // namespace strangeness_tracking +} // namespace o2 diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx new file mode 100644 index 0000000000000..9142d61b76e04 --- /dev/null +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx @@ -0,0 +1,301 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// StrangenessTracker +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// \file StrangenessTracker.cxx +/// \brief + +#include +#include "StrangenessTracking/StrangenessTracker.h" + +namespace o2 +{ +namespace strangeness_tracking +{ + +bool StrangenessTracker::loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, gsl::span InputCascadeTracks, o2::its::GeometryTGeo* geomITS) +{ + mInputV0tracks = InputV0tracks; + mInputCascadeTracks = InputCascadeTracks; + mInputITStracks = InputITStracks; + mInputITSclusters = InputITSclusters; + mInputITSidxs = InputITSidxs; + LOG(info) << "all tracks loaded"; + LOG(info) << "V0 tracks size: " << mInputV0tracks.size(); + LOG(info) << "V0 tracks size: " << mInputCascadeTracks.size(); + LOG(info) << "ITS tracks size: " << mInputITStracks.size(); + LOG(info) << "ITS clusters size: " << mInputITSclusters.size(); + LOG(info) << "ITS idxs size: " << mInputITSidxs.size(); + mGeomITS = geomITS; + setupFitters(); + return true; +} + +void StrangenessTracker::initialise() +{ + mTracksIdxTable.clear(); + + for (int iTrack{0}; iTrack < mInputITStracks.size(); iTrack++) { + mSortedITStracks.push_back(mInputITStracks[iTrack]); + mSortedITSindexes.push_back(iTrack); + } + + mTracksIdxTable.resize(mUtils.mPhiBins * mUtils.mEtaBins + 1); + std::sort(mSortedITStracks.begin(), mSortedITStracks.end(), [&](o2::its::TrackITS& a, o2::its::TrackITS& b) { return mUtils.getBinIndex(a.getEta(), a.getPhi()) < mUtils.getBinIndex(b.getEta(), b.getPhi()); }); + std::sort(mSortedITSindexes.begin(), mSortedITSindexes.end(), [&](int i, int j) { return mUtils.getBinIndex(mInputITStracks[i].getEta(), mInputITStracks[i].getPhi()) < mUtils.getBinIndex(mInputITStracks[j].getEta(), mInputITStracks[j].getPhi()); }); + + for (auto& track : mSortedITStracks) { + mTracksIdxTable[mUtils.getBinIndex(track.getEta(), track.getPhi())]++; + } + std::exclusive_scan(mTracksIdxTable.begin(), mTracksIdxTable.begin() + mUtils.mPhiBins * mUtils.mEtaBins, mTracksIdxTable.begin(), 0); + mTracksIdxTable[mUtils.mPhiBins * mUtils.mEtaBins] = mSortedITStracks.size(); +} + +void StrangenessTracker::process() +{ + + int counter = 0; + for (auto& v0 : mInputV0tracks) { + counter++; + LOG(debug) << "Analysing V0: " << counter << "/" << mInputV0tracks.size(); + + auto posTrack = v0.getProng(0); + auto negTrack = v0.getProng(1); + auto alphaV0 = calcV0alpha(v0); + alphaV0 > 0 ? posTrack.setAbsCharge(2) : negTrack.setAbsCharge(2); + V0 correctedV0; // recompute V0 for Hypertriton + + if (!recreateV0(posTrack, negTrack, v0.getProngID(0), v0.getProngID(1), correctedV0)) + continue; + + auto v0R2 = v0.calcR2(); + auto iBinsV0 = mUtils.getBinRect(correctedV0.getEta(), correctedV0.getPhi(), 0.1, 0.1); + for (int& iBinV0 : iBinsV0) { + LOG(debug) << "iBinV0: " << iBinV0; + for (int iTrack{mTracksIdxTable[iBinV0]}; iTrack < TMath::Min(mTracksIdxTable[iBinV0 + 1], int(mSortedITStracks.size())); iTrack++) { + auto trackClusters = getTrackClusters(); + auto& lastClus = trackClusters[0]; + + mStrangeTrack.mMother = (o2::track::TrackParCovF)correctedV0; + mStrangeTrack.mDaughterFirst = alphaV0 > 0 ? correctedV0.getProng(0) : correctedV0.getProng(1); + mStrangeTrack.mDaughterSecond = alphaV0 < 0 ? correctedV0.getProng(0) : correctedV0.getProng(1); + mStrangeTrack.mMatchChi2 = getMatchingChi2(correctedV0, mITStrack, lastClus); + + mITStrack = mSortedITStracks[iTrack]; + auto& ITSindexRef = mSortedITSindexes[iTrack]; + + LOG(debug) << "V0 pos: " << correctedV0.getProngID(0) << " V0 neg: " << correctedV0.getProngID(1) << " V0pt: " << correctedV0.getPt() << " ITSpt: " << mITStrack.getPt(); + LOG(debug) << "V0 eta: " << correctedV0.getEta() << " V0 phi: " << correctedV0.getPhi() << " ITS eta: " << mITStrack.getEta() << " ITS phi: " << mITStrack.getPhi(); + + std::vector motherClusters; + std::array nAttachments; + + updateTopology(nAttachments, motherClusters, trackClusters, v0R2, false); + + o2::track::TrackParCov motherTrackClone = mStrangeTrack.mMother; // clone and reset covariance + motherTrackClone.resetCovariance(); + + if (motherClusters.size() >= mMinMotherClus) { // fill only if at least mMinMotherClus clusters of the mother V0 have been attached + std::reverse(motherClusters.begin(), motherClusters.end()); + for (auto& clus : motherClusters) { + if (!updateTrack(clus, motherTrackClone)) + break; + } + + // final 3body refit + if (refitTopology(motherTrackClone)) { + LOG(debug) << "------------------------------------------------------"; + LOG(debug) << "Pushing back v0: " << v0.getProngID(0) << ", " << v0.getProngID(1); + LOG(debug) << "number of clusters attached: " << motherClusters.size(); + LOG(debug) << "Number of ITS track clusters: " << mITStrack.getNumberOfClusters(); + LOG(debug) << "number of clusters attached to V0: " << nAttachments[0] << ", " << nAttachments[1] << ", " << nAttachments[2] << ", " << nAttachments[3] << ", " << nAttachments[4] << ", " << nAttachments[5] << ", " << nAttachments[6]; + auto& lastClus = trackClusters[0]; + LOG(debug) << "Matching chi2: " << getMatchingChi2(correctedV0, mITStrack, lastClus); + + mStrangeTrackVec.push_back(mStrangeTrack); + mITStrackRefVec.push_back(ITSindexRef); + ClusAttachments structClus; + structClus.arr = nAttachments; + mClusAttachments.push_back(structClus); + } + } + } + } + } +} + +bool StrangenessTracker::updateTopology(std::array& nAttachments, std::vector& motherClusters, const std::vector& trackClusters, float decayRadius, bool isCascade) +{ + int nUpdates = 0; + bool isMotherUpdated = false; + + for (auto& clus : trackClusters) { + auto diffR2 = decayRadius - clus.getX() * clus.getX() - clus.getY() * clus.getY(); // difference between decay radius and Layer R2 + if (diffR2 > -mRadiusTol) { + LOG(debug) << "Try to attach cluster to Mother, layer: " << mGeomITS->getLayer(clus.getSensorID()); + if (updateTrack(clus, mStrangeTrack.mMother)) { + motherClusters.push_back(clus); + nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kMother; + isMotherUpdated = true; + nUpdates++; + continue; + } else { + if (isMotherUpdated == true) { + break; // daughter clusters cannot be attached now + } + } + } + + // if Mother is not found, check for V0 daughters compatibility + if (diffR2 < mRadiusTol && !isMotherUpdated) { + LOG(debug) << "Try to attach cluster to Daughters, layer: " << mGeomITS->getLayer(clus.getSensorID()); + + if (!isCascade) { + if (updateTrack(clus, mStrangeTrack.mDaughterFirst)) + nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kFirstDaughter; + else if (updateTrack(clus, mStrangeTrack.mDaughterSecond)) + nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kSecondDaughter; + else + break; + } + // if Mother is not found, check for cascade bachelor compatibility + else { + if (updateTrack(clus, mStrangeTrack.mBachelor)) + nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kBachelor; + else + break; + } + nUpdates++; + } + } + if (nUpdates < trackClusters.size() || motherClusters.size() == 0) + return false; + + return true; +} + +bool StrangenessTracker::updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track) +{ + auto propInstance = o2::base::Propagator::Instance(); + float alpha = mGeomITS->getSensorRefAlpha(clus.getSensorID()), x = clus.getX(); + int layer{mGeomITS->getLayer(clus.getSensorID())}; + + if (!track.rotate(alpha)) + return false; + + if (!propInstance->propagateToX(track, x, getBz(), o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, mCorrType)) + return false; + if (mCorrType == o2::base::PropagatorF::MatCorrType::USEMatCorrNONE) { + float thick = layer < 3 ? 0.005 : 0.01; + constexpr float radl = 9.36f; // Radiation length of Si [cm] + constexpr float rho = 2.33f; // Density of Si [g/cm^3] + if (!track.correctForMaterial(thick, thick * rho * radl)) + return false; + } + auto chi2 = std::abs(track.getPredictedChi2(clus)); + LOG(debug) << "chi2: " << track.getPredictedChi2(clus); + if (chi2 > mMaxChi2 || chi2 < 0) + return false; + + if (!track.update(clus)) + return false; + + return true; +} + +bool StrangenessTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const GIndex posID, const GIndex negID, V0& newV0) +{ + + int nCand; + try { + nCand = mFitterV0.process(posTrack, negTrack); + } catch (std::runtime_error& e) { + return false; + } + if (!nCand) + return false; + + mFitterV0.propagateTracksToVertex(); + const auto& v0XYZ = mFitterV0.getPCACandidatePos(); + + auto& propPos = mFitterV0.getTrack(0, 0); + auto& propNeg = mFitterV0.getTrack(1, 0); + + std::array pP, pN; + propPos.getPxPyPzGlo(pP); + propNeg.getPxPyPzGlo(pN); + std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; + newV0 = V0(v0XYZ, pV0, mFitterV0.calcPCACovMatrixFlat(0), propPos, propNeg, posID, negID, o2::track::PID::HyperTriton); + return true; +}; + +std::vector StrangenessTracker::getTrackClusters() +{ + std::vector outVec; + auto firstClus = mITStrack.getFirstClusterEntry(); + auto ncl = mITStrack.getNumberOfClusters(); + for (int icl = 0; icl < ncl; icl++) { + outVec.push_back(mInputITSclusters[mInputITSidxs[firstClus + icl]]); + } + return outVec; +}; + +bool StrangenessTracker::refitTopology(o2::track::TrackParCovF& ITSmotherTrack) +{ + int cand = 0; // best V0 candidate + int nCand; + + try { + nCand = mFitter3Body.process(ITSmotherTrack, mStrangeTrack.mDaughterFirst, mStrangeTrack.mDaughterSecond); + } catch (std::runtime_error& e) { + return false; + } + if (!nCand) + return false; + + mFitter3Body.propagateTracksToVertex(); + + mStrangeTrack.mDaughterFirst = mFitter3Body.getTrack(1, 0); + mStrangeTrack.mDaughterSecond = mFitter3Body.getTrack(2, 0); + mStrangeTrack.decayVtx = mFitter3Body.getPCACandidatePos(); + mStrangeTrack.mTopoChi2 = mFitter3Body.getChi2AtPCACandidate(); + + return true; +}; + +float StrangenessTracker::getMatchingChi2(V0 v0, const TrackITS ITStrack, ITSCluster matchingClus) +{ + float alpha = mGeomITS->getSensorRefAlpha(matchingClus.getSensorID()), x = matchingClus.getX(); + if (v0.rotate(alpha)) { + if (v0.propagateTo(x, mBz)) { + return v0.getPredictedChi2(ITStrack.getParamOut()); + } + } + return -100; +}; + +double StrangenessTracker::calcV0alpha(const V0& v0) +{ + std::array fV0mom, fPmom, fNmom = {0, 0, 0}; + v0.getProng(0).getPxPyPzGlo(fPmom); + v0.getProng(1).getPxPyPzGlo(fNmom); + v0.getPxPyPzGlo(fV0mom); + + TVector3 momNeg(fNmom[0], fNmom[1], fNmom[2]); + TVector3 momPos(fPmom[0], fPmom[1], fPmom[2]); + TVector3 momTot(fV0mom[0], fV0mom[1], fV0mom[2]); + + Double_t lQlNeg = momNeg.Dot(momTot) / momTot.Mag(); + Double_t lQlPos = momPos.Dot(momTot) / momTot.Mag(); + + return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); +}; + +} // namespace strangeness_tracking +} // namespace o2 \ No newline at end of file diff --git a/Detectors/StrangenessTracking/tracking/src/HypertrackingConfigParam.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingConfigParam.cxx similarity index 72% rename from Detectors/StrangenessTracking/tracking/src/HypertrackingConfigParam.cxx rename to Detectors/StrangenessTracking/tracking/src/StrangenessTrackingConfigParam.cxx index 9609e65bfd1e0..4a1128e1bb4bd 100644 --- a/Detectors/StrangenessTracking/tracking/src/HypertrackingConfigParam.cxx +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingConfigParam.cxx @@ -9,14 +9,14 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "StrangenessTracking/HypertrackingConfigParam.h" +#include "StrangenessTracking/StrangenessTrackingConfigParam.h" namespace o2 { namespace strangeness_tracking { -static auto& sHypertrackerParam = o2::strangeness_tracking::HypertrackerParamConfig::Instance(); +static auto& sStrangenessTrackingParam = o2::strangeness_tracking::StrangenessTrackingParamConfig::Instance(); -O2ParamImpl(o2::strangeness_tracking::HypertrackerParamConfig); +O2ParamImpl(o2::strangeness_tracking::StrangenessTrackingParamConfig); } // namespace strangeness_tracking } // namespace o2 diff --git a/Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h b/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingLinkDef.h similarity index 66% rename from Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h rename to Detectors/StrangenessTracking/tracking/src/StrangenessTrackingLinkDef.h index dedf27d8dfe64..ecd72ea5cafbc 100644 --- a/Detectors/StrangenessTracking/tracking/src/HypertrackingLinkDef.h +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingLinkDef.h @@ -15,9 +15,16 @@ #pragma link off all classes; #pragma link off all functions; -#pragma link C++ class o2::strangeness_tracking::HypertrackerParamConfig + ; -#pragma link C++ class o2::conf::ConfigurableParamHelper + ; +#pragma link C++ class o2::strangeness_tracking::StrangenessTrackingParamConfig + ; +#pragma link C++ class o2::conf::ConfigurableParamHelper + ; #pragma link C++ struct o2::strangeness_tracking::ClusAttachments + ; +#pragma link C++ struct o2::strangeness_tracking::StrangeTrack + ; + +#pragma link C++ struct o2::strangeness_tracking::IndexTableUtils + ; + #pragma link C++ class std::vector + ; +#pragma link C++ class std::vector + ; +#pragma link C++ class std::vector + ; + #endif diff --git a/Detectors/StrangenessTracking/workflow/CMakeLists.txt b/Detectors/StrangenessTracking/workflow/CMakeLists.txt index 1bcae28e7dd88..1954e8ea7548a 100644 --- a/Detectors/StrangenessTracking/workflow/CMakeLists.txt +++ b/Detectors/StrangenessTracking/workflow/CMakeLists.txt @@ -11,8 +11,8 @@ o2_add_library(StrangenessTrackingWorkflow TARGETVARNAME targetName - SOURCES src/HypertrackingSpec.cxx - SOURCES src/HypertrackingWriterSpec.cxx + SOURCES src/StrangenessTrackingSpec.cxx + SOURCES src/StrangenessTrackingWriterSpec.cxx PUBLIC_LINK_LIBRARIES O2::GlobalTrackingWorkflowReaders O2::GlobalTrackingWorkflow O2::ITSWorkflow @@ -32,7 +32,7 @@ o2_add_library(StrangenessTrackingWorkflow O2::GlobalTrackingWorkflowWriters O2::CCDB) -o2_add_executable(hypertracking-workflow - SOURCES src/hypertracking-workflow.cxx +o2_add_executable(strangeness-tracking-workflow + SOURCES src/strangeness-tracking-workflow.cxx PUBLIC_LINK_LIBRARIES O2::StrangenessTrackingWorkflow O2::GlobalTrackingWorkflowReaders) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingSpec.h similarity index 83% rename from Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h rename to Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingSpec.h index c066eefaadfeb..cae6d53b8b1cb 100644 --- a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingSpec.h +++ b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingSpec.h @@ -9,8 +9,8 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef O2_HYPERTRACKING_SPEC_H -#define O2_HYPERTRACKING_SPEC_H +#ifndef O2_STRANGENESS_SPEC_H +#define O2_STRANGENESS_SPEC_H #include "Framework/WorkflowSpec.h" #include "Framework/DataProcessorSpec.h" @@ -22,19 +22,19 @@ #include "TStopwatch.h" -#include "StrangenessTracking/HyperTracker.h" +#include "StrangenessTracking/StrangenessTracker.h" namespace o2 { namespace strangeness_tracking { -class HypertrackerSpec : public framework::Task +class StrangenessTrackerSpec : public framework::Task { public: using ITSCluster = o2::BaseCluster; - HypertrackerSpec(bool isMC = false); - ~HypertrackerSpec() override = default; + StrangenessTrackerSpec(bool isMC = false); + ~StrangenessTrackerSpec() override = default; void init(framework::InitContext& ic) final; void run(framework::ProcessingContext& pc) final; @@ -48,12 +48,12 @@ class HypertrackerSpec : public framework::Task bool mIsMC = false; bool mRecreateV0 = true; TStopwatch mTimer; - HyperTracker mTracker; + StrangenessTracker mTracker; std::unique_ptr mGRP = nullptr; const o2::itsmft::TopologyDictionary* mDict = nullptr; }; -o2::framework::DataProcessorSpec getHyperTrackerSpec(); +o2::framework::DataProcessorSpec getStrangenessTrackerSpec(); o2::framework::WorkflowSpec getWorkflow(bool upstreamClusters = false, bool upstreamV0s = false); } // namespace strangeness_tracking diff --git a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingWriterSpec.h b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingWriterSpec.h similarity index 80% rename from Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingWriterSpec.h rename to Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingWriterSpec.h index 1dc37fc9fe14b..ae38e2a3567ed 100644 --- a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/HypertrackingWriterSpec.h +++ b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingWriterSpec.h @@ -11,8 +11,8 @@ /// @file TrackWriterSpec.h -#ifndef O2_HYPERTRACKINGWRITER -#define O2_HYPERTRACKINGWRITER +#ifndef O2_STRANGENESSTRACKINGWRITER +#define O2_STRANGENESSTRACKINGWRITER #include "Framework/DataProcessorSpec.h" @@ -23,9 +23,9 @@ namespace strangeness_tracking /// create a processor spec /// write ITS tracks to ROOT file -o2::framework::DataProcessorSpec getHypertrackingWriterSpec(); +o2::framework::DataProcessorSpec getStrangenessTrackingWriterSpec(); } // namespace strangeness_tracking } // namespace o2 -#endif /* O2_HYPERTRACKINGWRITER */ +#endif /* O2_STRANGENESSTRACKINGWRITER */ diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx similarity index 82% rename from Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx rename to Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx index 9dfebb12ce365..6b819334ddd57 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx @@ -13,7 +13,7 @@ #include "Framework/ConfigParamRegistry.h" #include "Field/MagneticField.h" -#include "StrangenessTrackingWorkflow/HypertrackingSpec.h" +#include "StrangenessTrackingWorkflow/StrangenessTrackingSpec.h" #include "ITSWorkflow/ClusterWriterSpec.h" #include "ITSWorkflow/TrackerSpec.h" #include "ITSWorkflow/TrackReaderSpec.h" @@ -49,16 +49,16 @@ framework::WorkflowSpec getWorkflow(bool useMC, bool useRootInput) // auto src = o2::dataformats::GlobalTrackID::Source::ITSTPCTOF | o2::dataformats::GlobalTrackID::Source::ITSTPC | o2::dataformats::GlobalTrackID::Source::TPCTOF; // specs.emplace_back(o2::globaltracking::getTOFMatcherSpec(src, true, false, false, 0)); } - specs.emplace_back(getHyperTrackerSpec()); + specs.emplace_back(getStrangenessTrackerSpec()); return specs; } -HypertrackerSpec::HypertrackerSpec(bool isMC) : mIsMC{isMC} +StrangenessTrackerSpec::StrangenessTrackerSpec(bool isMC) : mIsMC{isMC} { // no ops } -void HypertrackerSpec::init(framework::InitContext& ic) +void StrangenessTrackerSpec::init(framework::InitContext& ic) { mTimer.Stop(); mTimer.Reset(); @@ -86,13 +86,13 @@ void HypertrackerSpec::init(framework::InitContext& ic) auto gman = o2::its::GeometryTGeo::Instance(); gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G)); - LOG(info) << "Initialized Hypertracker..."; + LOG(info) << "Initialized strangeness tracker..."; } -void HypertrackerSpec::run(framework::ProcessingContext& pc) +void StrangenessTrackerSpec::run(framework::ProcessingContext& pc) { mTimer.Start(false); - LOG(info) << "Running hypertracker..."; + LOG(info) << "Running strangeness tracker..."; updateTimeDependentParams(pc); // ITS auto ITSclus = pc.inputs().get>("compClusters"); @@ -102,7 +102,8 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) auto ITSTrackClusIdx = pc.inputs().get>("trackITSClIdx"); // V0 - auto v0vec = pc.inputs().get>("v0s"); + auto v0Vec = pc.inputs().get>("v0s"); + auto cascadeVec = pc.inputs().get>("cascs"); auto tpcITSTracks = pc.inputs().get>("trackTPCITS"); // Monte Carlo @@ -117,7 +118,8 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) ROFsInput.size(), ITSTrackClusIdx.size(), tpcITSTracks.size(), - v0vec.size(), + v0Vec.size(), + cascadeVec.size(), labITSTPC.size(), // labTPCTOF.size(), // labITSTPCTOF.size(), @@ -133,22 +135,22 @@ void HypertrackerSpec::run(framework::ProcessingContext& pc) double origD[3] = {0., 0., 0.}; mTracker.setBz(field->getBz(origD)); - mTracker.loadData(ITStracks, ITSClustersArray, ITSTrackClusIdx, v0vec, geom); + mTracker.loadData(ITStracks, ITSClustersArray, ITSTrackClusIdx, v0Vec, cascadeVec, geom); mTracker.initialise(); mTracker.process(); - pc.outputs().snapshot(Output{"HYP", "V0S", 0, Lifetime::Timeframe}, mTracker.getV0()); - pc.outputs().snapshot(Output{"HYP", "HYPERTRACKS", 0, Lifetime::Timeframe}, mTracker.getHyperTracks()); - pc.outputs().snapshot(Output{"HYP", "CHI2", 0, Lifetime::Timeframe}, mTracker.getChi2vec()); - pc.outputs().snapshot(Output{"HYP", "R2", 0, Lifetime::Timeframe}, mTracker.getR2vec()); - pc.outputs().snapshot(Output{"HYP", "CLUSUPDATES", 0, Lifetime::Timeframe}, mTracker.getClusAttachments()); - pc.outputs().snapshot(Output{"HYP", "ITSREFS", 0, Lifetime::Timeframe}, mTracker.getITStrackRef()); + + pc.outputs().snapshot(Output{"STK", "STRTRACKS", 0, Lifetime::Timeframe}, mTracker.getStrangeTrackVec()); + pc.outputs().snapshot(Output{"STK", "CLUSUPDATES", 0, Lifetime::Timeframe}, mTracker.getClusAttachments()); + pc.outputs().snapshot(Output{"STK", "ITSREFS", 0, Lifetime::Timeframe}, mTracker.getITStrackRefVec()); + pc.outputs().snapshot(Output{"STK", "DECREFS", 0, Lifetime::Timeframe}, mTracker.getDecayTrackRefVec()); + mTimer.Stop(); } ///_______________________________________ -void HypertrackerSpec::updateTimeDependentParams(ProcessingContext& pc) +void StrangenessTrackerSpec::updateTimeDependentParams(ProcessingContext& pc) { static bool initOnceDone = false; if (!initOnceDone) { // this params need to be queried only once @@ -158,7 +160,7 @@ void HypertrackerSpec::updateTimeDependentParams(ProcessingContext& pc) } ///_______________________________________ -void HypertrackerSpec::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) +void StrangenessTrackerSpec::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) { if (matcher == ConcreteDataMatcher("ITS", "CLUSDICT", 0)) { LOG(info) << "cluster dictionary updated"; @@ -167,13 +169,13 @@ void HypertrackerSpec::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) } } -void HypertrackerSpec::endOfStream(framework::EndOfStreamContext& ec) +void StrangenessTrackerSpec::endOfStream(framework::EndOfStreamContext& ec) { LOGF(info, "Hypertracker total timing: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); } -DataProcessorSpec getHyperTrackerSpec() +DataProcessorSpec getStrangenessTrackerSpec() { std::vector inputs; @@ -204,20 +206,17 @@ DataProcessorSpec getHyperTrackerSpec() // inputs.emplace_back("clsTOF_TPC_MCTR", "TOF", "MCMTC_TPC", 0, Lifetime::Timeframe); // MC truth, // Matching input type manually set to 0 std::vector outputs; - outputs.emplace_back("HYP", "V0S", 0, Lifetime::Timeframe); - outputs.emplace_back("HYP", "HYPERTRACKS", 0, Lifetime::Timeframe); - - outputs.emplace_back("HYP", "CHI2", 0, Lifetime::Timeframe); - outputs.emplace_back("HYP", "R2", 0, Lifetime::Timeframe); + outputs.emplace_back("STK", "STRTRACKS", 0, Lifetime::Timeframe); + outputs.emplace_back("STK", "CLUSUPDATES", 0, Lifetime::Timeframe); + outputs.emplace_back("STK", "ITSREFS", 0, Lifetime::Timeframe); + outputs.emplace_back("STK", "DECREFS", 0, Lifetime::Timeframe); - outputs.emplace_back("HYP", "CLUSUPDATES", 0, Lifetime::Timeframe); - outputs.emplace_back("HYP", "ITSREFS", 0, Lifetime::Timeframe); return DataProcessorSpec{ - "hyper-tracker", + "strangeness-tracker", inputs, outputs, - AlgorithmSpec{adaptFromTask()}, + AlgorithmSpec{adaptFromTask()}, Options{ {"grp-file", VariantType::String, "o2sim_grp.root", {"Name of the grp file"}}, {"material-lut-path", VariantType::String, "", {"Path of the material LUT file"}}}}; diff --git a/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx similarity index 54% rename from Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx rename to Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx index 7350c7f60b028..f49da2553963b 100644 --- a/Detectors/StrangenessTracking/workflow/src/HypertrackingWriterSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx @@ -9,16 +9,16 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// @file HypertrackingWriterSpec.cxx +/// @file StrangenessWriterSpec.cxx #include -#include "StrangenessTrackingWorkflow/HypertrackingWriterSpec.h" +#include "StrangenessTrackingWorkflow/StrangenessTrackingWriterSpec.h" #include "DPLUtils/MakeRootTreeWriterSpec.h" #include "CommonDataFormat/TimeStamp.h" #include "CommonDataFormat/RangeReference.h" #include "ReconstructionDataFormats/V0.h" #include "ReconstructionDataFormats/Track.h" -#include "StrangenessTracking/HyperTracker.h" +#include "StrangenessTracking/StrangenessTracker.h" using namespace o2::framework; @@ -33,32 +33,29 @@ using BranchDefinition = MakeRootTreeWriterSpec::BranchDefinition; using namespace o2::header; -DataProcessorSpec getHypertrackingWriterSpec() +DataProcessorSpec getStrangenessTrackingWriterSpec() { - auto loggerV = [](std::vector const& v) { - LOG(info) << "Hypertracker writer pulled " << v.size() << " v0s"; + auto loggerV = [](std::vector const& v) { + LOG(info) << "StrangenessTracker writer pulled " << v.size() << " v0s"; }; auto loggerT = [](std::vector const& v) { LOG(info) << "Hypertracker writer pulled " << v.size() << " tracks"; }; - auto inpV0ID = InputSpec{"v0s", "HYP", "V0S", 0}; - auto inpTrackID = InputSpec{"hypertrack", "HYP", "HYPERTRACKS", 0}; - auto inpChi2ID = InputSpec{"v0itschi2", "HYP", "CHI2", 0}; - auto inpR2ID = InputSpec{"v0r2", "HYP", "R2", 0}; - auto inpClusAtt = InputSpec{"clusupdates", "HYP", "CLUSUPDATES",0}; - auto inpRefID = InputSpec{"itsrefs", "HYP", "ITSREFS", 0}; + auto inpStTrkID = InputSpec{"strangetracks", "STK", "STRTRACKS", 0}; + auto inpClusAtt = InputSpec{"clusupdates", "STK", "CLUSUPDATES",0}; + auto inpITSRefID = InputSpec{"itsrefs", "STK", "ITSREFS", 0}; + auto inpDecRefID = InputSpec{"decrefs", "STK", "DECREFS", 0}; - return MakeRootTreeWriterSpec("hypertracking-writer", - "o2_hypertrack.root", - MakeRootTreeWriterSpec::TreeAttributes{"o2sim", "Tree with Hypertracks"}, - BranchDefinition>{inpV0ID, "V0s", loggerV}, - BranchDefinition>{inpTrackID, "Hypertracks", loggerT}, - BranchDefinition>{inpChi2ID, "ITSV0Chi2"}, - BranchDefinition>{inpR2ID, "R2"}, + + return MakeRootTreeWriterSpec("strangenesstracking-writer", + "o2_strangeness_track.root", + MakeRootTreeWriterSpec::TreeAttributes{"o2sim", "Tree with Strange Tracks"}, + BranchDefinition>{inpStTrkID, "StrangeTracks", loggerV}, BranchDefinition>{inpClusAtt, "ClusUpdates"}, - BranchDefinition>{inpRefID, "ITSTrackRefs"})(); + BranchDefinition>{inpITSRefID, "ITSTrackRefs"}, + BranchDefinition>{inpDecRefID, "DecayTrackRefs"})(); } } // namespace strangeness_tracking diff --git a/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx b/Detectors/StrangenessTracking/workflow/src/strangeness-tracking-workflow.cxx similarity index 86% rename from Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx rename to Detectors/StrangenessTracking/workflow/src/strangeness-tracking-workflow.cxx index a17899b658e7e..4f4b86d60c15b 100644 --- a/Detectors/StrangenessTracking/workflow/src/hypertracking-workflow.cxx +++ b/Detectors/StrangenessTracking/workflow/src/strangeness-tracking-workflow.cxx @@ -9,11 +9,11 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "StrangenessTrackingWorkflow/HypertrackingSpec.h" -#include "StrangenessTrackingWorkflow/HypertrackingWriterSpec.h" +#include "StrangenessTrackingWorkflow/StrangenessTrackingSpec.h" +#include "StrangenessTrackingWorkflow/StrangenessTrackingWriterSpec.h" #include "CommonUtils/ConfigurableParam.h" -#include "StrangenessTracking/HypertrackingConfigParam.h" +#include "StrangenessTracking/StrangenessTrackingConfigParam.h" #include "DetectorsRaw/HBFUtilsInitializer.h" #include "Framework/CallbacksPolicy.h" @@ -55,13 +55,13 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); auto wf = o2::strangeness_tracking::getWorkflow(useMC, useRootInput); - wf.emplace_back(getHypertrackingWriterSpec()); + wf.emplace_back(getStrangenessTrackingWriterSpec()); // configure dpl timer to inject correct firstTFOrbit: start from the 1st orbit of TF containing 1st sampled orbit o2::raw::HBFUtilsInitializer hbfIni(configcontext, wf); // write the configuration used for the reco workflow - o2::conf::ConfigurableParam::writeINI("o2hypertrackingflow_configuration.ini"); + o2::conf::ConfigurableParam::writeINI("o2strangeness_tracking_workflow_configuration.ini"); return std::move(wf); } From e6f5c786ad2dd323559c13c0106d7e9e1285df56 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Fri, 24 Jun 2022 09:50:43 +0200 Subject: [PATCH 20/36] Fix output structure --- .../tracking/CMakeLists.txt | 1 - .../StrangenessTracking/IndexTableUtils.h | 51 ++++++++++++++++++- .../StrangenessTracking/StrangenessTracker.h | 4 +- .../tracking/src/StrangenessTracker.cxx | 36 +++++++------ .../tracking/src/StrangenessTrackingLinkDef.h | 3 +- .../workflow/src/StrangenessTrackingSpec.cxx | 2 +- .../src/StrangenessTrackingWriterSpec.cxx | 2 +- 7 files changed, 72 insertions(+), 27 deletions(-) diff --git a/Detectors/StrangenessTracking/tracking/CMakeLists.txt b/Detectors/StrangenessTracking/tracking/CMakeLists.txt index da0688ce9859a..c5fceb6888f29 100644 --- a/Detectors/StrangenessTracking/tracking/CMakeLists.txt +++ b/Detectors/StrangenessTracking/tracking/CMakeLists.txt @@ -12,7 +12,6 @@ o2_add_library(StrangenessTracking SOURCES src/StrangenessTracker.cxx src/StrangenessTrackingConfigParam.cxx - src/IndexTableUtils.cxx PUBLIC_LINK_LIBRARIES O2::MathUtils O2::ITSBase O2::ITSMFTReconstruction diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h index 6fbfefc8a4783..49b92e59a7a19 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h @@ -22,7 +22,7 @@ namespace o2 namespace strangeness_tracking { -struct indexTableUtils { +struct IndexTableUtils { int getEtaBin(float eta); int getPhiBin(float phi); int getBinIndex(float eta, float phi); @@ -31,6 +31,55 @@ struct indexTableUtils { float minEta = -1.5, maxEta = 1.5; float minPhi = 0., maxPhi = 2 * TMath::Pi(); }; + +inline int IndexTableUtils::getEtaBin(float eta) +{ + float deltaEta = (maxEta - minEta) / (mEtaBins); + int bEta = (eta - minEta) / deltaEta; // bins recentered to 0 + return bEta; +}; + +inline int IndexTableUtils::getPhiBin(float phi) +{ + float deltaPhi = (maxPhi - minPhi) / (mPhiBins); + int bPhi = (phi - minPhi) / deltaPhi; // bin recentered to 0 + return bPhi; +} + +inline int IndexTableUtils::getBinIndex(float eta, float phi) +{ + float deltaPhi = (maxPhi - minPhi) / (mPhiBins); + float deltaEta = (maxEta - minEta) / (mEtaBins); + int bEta = getEtaBin(eta); + int bPhi = getPhiBin(phi); + return bEta >= mEtaBins || bPhi >= mPhiBins ? mEtaBins * mPhiBins : bEta + mEtaBins * bPhi; +} + +inline std::vector IndexTableUtils::getBinRect(float eta, float phi, float deltaEta, float deltaPhi) +{ + std::vector idxVec; + int centralBin = getBinIndex(eta, phi); + if (centralBin == mPhiBins * mEtaBins) { // condition for overflows + idxVec.push_back(centralBin); + return idxVec; + } + int minEtaBin = TMath::Max(0, getEtaBin(eta - deltaEta)); + int maxEtaBin = getEtaBin(eta + deltaEta); + int minPhiBin = TMath::Max(0, getPhiBin(phi - deltaPhi)); + int maxPhiBin = getPhiBin(phi + deltaPhi); + + for (int iPhi{minPhiBin}; iPhi <= maxPhiBin; iPhi++) { + if (iPhi >= mPhiBins) + break; + for (int iEta{minEtaBin}; iEta <= maxEtaBin; iEta++) { + if (iEta >= mEtaBins) + break; + idxVec.push_back(iEta + mEtaBins * iPhi); + } + } + return idxVec; +}; + } // namespace strangeness_tracking } // namespace o2 diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h index 1188975050f3a..f1263ca3e2cf7 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h @@ -19,7 +19,7 @@ #include #include #include "TMath.h" -#include "IndexTableUtils.h" +#include "StrangenessTracking/IndexTableUtils.h" #include "ReconstructionDataFormats/PID.h" #include "ReconstructionDataFormats/V0.h" @@ -121,7 +121,7 @@ class StrangenessTracker std::vector mSortedITStracks; // sorted ITS tracks std::vector mSortedITSindexes; // indexes of sorted ITS tracks - indexTableUtils mUtils; // structure for computing eta/phi matching selections + IndexTableUtils mUtils; // structure for computing eta/phi matching selections std::vector mStrangeTrackVec; // structure containing updated mother and daughter tracks std::vector mClusAttachments; // # of attached tracks, 1 for mother, 2 for daughter diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx index 9142d61b76e04..74bc4e94a0ea0 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx @@ -28,7 +28,7 @@ bool StrangenessTracker::loadData(gsl::span InputITStra mInputITSidxs = InputITSidxs; LOG(info) << "all tracks loaded"; LOG(info) << "V0 tracks size: " << mInputV0tracks.size(); - LOG(info) << "V0 tracks size: " << mInputCascadeTracks.size(); + LOG(info) << "Cascade tracks size: " << mInputCascadeTracks.size(); LOG(info) << "ITS tracks size: " << mInputITStracks.size(); LOG(info) << "ITS clusters size: " << mInputITSclusters.size(); LOG(info) << "ITS idxs size: " << mInputITSidxs.size(); @@ -60,10 +60,10 @@ void StrangenessTracker::initialise() void StrangenessTracker::process() { - int counter = 0; - for (auto& v0 : mInputV0tracks) { - counter++; - LOG(debug) << "Analysing V0: " << counter << "/" << mInputV0tracks.size(); + for (int iV0{0}; iV0 < mInputV0tracks.size(); iV0++) { + LOG(info) << "Analysing V0: " << iV0 + 1 << "/" << mInputV0tracks.size(); + auto& DecIndexRef = iV0; + auto& v0 = mInputV0tracks[iV0]; auto posTrack = v0.getProng(0); auto negTrack = v0.getProng(1); @@ -77,8 +77,11 @@ void StrangenessTracker::process() auto v0R2 = v0.calcR2(); auto iBinsV0 = mUtils.getBinRect(correctedV0.getEta(), correctedV0.getPhi(), 0.1, 0.1); for (int& iBinV0 : iBinsV0) { - LOG(debug) << "iBinV0: " << iBinV0; + LOG(info) << "iBinV0: " << iBinV0; for (int iTrack{mTracksIdxTable[iBinV0]}; iTrack < TMath::Min(mTracksIdxTable[iBinV0 + 1], int(mSortedITStracks.size())); iTrack++) { + + mITStrack = mSortedITStracks[iTrack]; + auto& ITSindexRef = mSortedITSindexes[iTrack]; auto trackClusters = getTrackClusters(); auto& lastClus = trackClusters[0]; @@ -87,11 +90,8 @@ void StrangenessTracker::process() mStrangeTrack.mDaughterSecond = alphaV0 < 0 ? correctedV0.getProng(0) : correctedV0.getProng(1); mStrangeTrack.mMatchChi2 = getMatchingChi2(correctedV0, mITStrack, lastClus); - mITStrack = mSortedITStracks[iTrack]; - auto& ITSindexRef = mSortedITSindexes[iTrack]; - - LOG(debug) << "V0 pos: " << correctedV0.getProngID(0) << " V0 neg: " << correctedV0.getProngID(1) << " V0pt: " << correctedV0.getPt() << " ITSpt: " << mITStrack.getPt(); - LOG(debug) << "V0 eta: " << correctedV0.getEta() << " V0 phi: " << correctedV0.getPhi() << " ITS eta: " << mITStrack.getEta() << " ITS phi: " << mITStrack.getPhi(); + LOG(info) << "V0 pos: " << correctedV0.getProngID(0) << " V0 neg: " << correctedV0.getProngID(1) << " V0pt: " << correctedV0.getPt() << " ITSpt: " << mITStrack.getPt(); + LOG(info) << "V0 eta: " << correctedV0.getEta() << " V0 phi: " << correctedV0.getPhi() << " ITS eta: " << mITStrack.getEta() << " ITS phi: " << mITStrack.getPhi(); std::vector motherClusters; std::array nAttachments; @@ -110,16 +110,14 @@ void StrangenessTracker::process() // final 3body refit if (refitTopology(motherTrackClone)) { - LOG(debug) << "------------------------------------------------------"; - LOG(debug) << "Pushing back v0: " << v0.getProngID(0) << ", " << v0.getProngID(1); - LOG(debug) << "number of clusters attached: " << motherClusters.size(); - LOG(debug) << "Number of ITS track clusters: " << mITStrack.getNumberOfClusters(); - LOG(debug) << "number of clusters attached to V0: " << nAttachments[0] << ", " << nAttachments[1] << ", " << nAttachments[2] << ", " << nAttachments[3] << ", " << nAttachments[4] << ", " << nAttachments[5] << ", " << nAttachments[6]; - auto& lastClus = trackClusters[0]; - LOG(debug) << "Matching chi2: " << getMatchingChi2(correctedV0, mITStrack, lastClus); - + LOG(info) << "------------------------------------------------------"; + LOG(info) << "Pushing back v0: " << v0.getProngID(0) << ", " << v0.getProngID(1); + LOG(info) << "Number of clusters attached: " << motherClusters.size(); + LOG(info) << "Number of ITS track clusters: " << mITStrack.getNumberOfClusters(); + LOG(info) << "Number of clusters attached to V0: " << nAttachments[0] << ", " << nAttachments[1] << ", " << nAttachments[2] << ", " << nAttachments[3] << ", " << nAttachments[4] << ", " << nAttachments[5] << ", " << nAttachments[6]; mStrangeTrackVec.push_back(mStrangeTrack); mITStrackRefVec.push_back(ITSindexRef); + mDecayTrackRefVec.push_back(DecIndexRef); ClusAttachments structClus; structClus.arr = nAttachments; mClusAttachments.push_back(structClus); diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingLinkDef.h b/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingLinkDef.h index ecd72ea5cafbc..3abdac69f73a0 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingLinkDef.h +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingLinkDef.h @@ -19,8 +19,7 @@ #pragma link C++ class o2::conf::ConfigurableParamHelper + ; #pragma link C++ struct o2::strangeness_tracking::ClusAttachments + ; #pragma link C++ struct o2::strangeness_tracking::StrangeTrack + ; - -#pragma link C++ struct o2::strangeness_tracking::IndexTableUtils + ; +#pragma link C++ class o2::strangeness_tracking::IndexTableUtils + ; #pragma link C++ class std::vector + ; #pragma link C++ class std::vector + ; diff --git a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx index 6b819334ddd57..c06b44af53fd0 100644 --- a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx @@ -171,7 +171,7 @@ void StrangenessTrackerSpec::finaliseCCDB(ConcreteDataMatcher& matcher, void* ob void StrangenessTrackerSpec::endOfStream(framework::EndOfStreamContext& ec) { - LOGF(info, "Hypertracker total timing: Cpu: %.3e Real: %.3e s in %d slots", + LOGF(info, "Strangeness tracking total timing: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); } diff --git a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx index f49da2553963b..4b689c6485a26 100644 --- a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx @@ -40,7 +40,7 @@ DataProcessorSpec getStrangenessTrackingWriterSpec() }; auto loggerT = [](std::vector const& v) { - LOG(info) << "Hypertracker writer pulled " << v.size() << " tracks"; + LOG(info) << "Strangeness tracker writer pulled " << v.size() << " tracks"; }; auto inpStTrkID = InputSpec{"strangetracks", "STK", "STRTRACKS", 0}; From 893fbdcae32d972ba614b3e2f51df22225694dd4 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Fri, 24 Jun 2022 12:14:06 +0200 Subject: [PATCH 21/36] Add Cascades loop --- .../StrangenessTracking/StrangenessTracker.h | 6 +- .../tracking/src/StrangenessTracker.cxx | 153 ++++++++++-------- 2 files changed, 90 insertions(+), 69 deletions(-) diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h index f1263ca3e2cf7..18f9ccca184df 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h @@ -102,12 +102,11 @@ class StrangenessTracker bool loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, gsl::span InputCascadeTracks, o2::its::GeometryTGeo* geomITS); double calcV0alpha(const V0& v0); std::vector getTrackClusters(); - float getMatchingChi2(V0 v0, const TrackITS ITSTrack, ITSCluster matchingClus); + float getMatchingChi2(o2::track::TrackParCovF, const TrackITS ITSTrack, ITSCluster matchingClus); bool recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const GIndex posID, const GIndex negID, V0& newV0); bool updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track); - bool updateTopology(std::array& nAttachments, std::vector& motherClusters, const std::vector& trackClusters, float decayRadius, bool isCascade); - bool refitTopology(o2::track::TrackParCovF& ITSmotherTrack); + bool matchDecayToITStrack(float decayR2, bool isCascade); @@ -139,6 +138,7 @@ class StrangenessTracker o2::base::PropagatorImpl::MatCorrType mCorrType = o2::base::PropagatorImpl::MatCorrType::USEMatCorrNONE; // use mat correction o2::its::GeometryTGeo* mGeomITS; // ITS geometry StrangeTrack mStrangeTrack; + ClusAttachments mStructClus; o2::its::TrackITS mITStrack; ClassDefNV(StrangenessTracker, 1); diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx index 74bc4e94a0ea0..c8f86faf3b86f 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx @@ -59,7 +59,7 @@ void StrangenessTracker::initialise() void StrangenessTracker::process() { - + // Loop over V0s for (int iV0{0}; iV0 < mInputV0tracks.size(); iV0++) { LOG(info) << "Analysing V0: " << iV0 + 1 << "/" << mInputV0tracks.size(); auto& DecIndexRef = iV0; @@ -79,62 +79,71 @@ void StrangenessTracker::process() for (int& iBinV0 : iBinsV0) { LOG(info) << "iBinV0: " << iBinV0; for (int iTrack{mTracksIdxTable[iBinV0]}; iTrack < TMath::Min(mTracksIdxTable[iBinV0 + 1], int(mSortedITStracks.size())); iTrack++) { - mITStrack = mSortedITStracks[iTrack]; auto& ITSindexRef = mSortedITSindexes[iTrack]; - auto trackClusters = getTrackClusters(); - auto& lastClus = trackClusters[0]; - mStrangeTrack.mMother = (o2::track::TrackParCovF)correctedV0; mStrangeTrack.mDaughterFirst = alphaV0 > 0 ? correctedV0.getProng(0) : correctedV0.getProng(1); mStrangeTrack.mDaughterSecond = alphaV0 < 0 ? correctedV0.getProng(0) : correctedV0.getProng(1); - mStrangeTrack.mMatchChi2 = getMatchingChi2(correctedV0, mITStrack, lastClus); - - LOG(info) << "V0 pos: " << correctedV0.getProngID(0) << " V0 neg: " << correctedV0.getProngID(1) << " V0pt: " << correctedV0.getPt() << " ITSpt: " << mITStrack.getPt(); - LOG(info) << "V0 eta: " << correctedV0.getEta() << " V0 phi: " << correctedV0.getPhi() << " ITS eta: " << mITStrack.getEta() << " ITS phi: " << mITStrack.getPhi(); - - std::vector motherClusters; - std::array nAttachments; - - updateTopology(nAttachments, motherClusters, trackClusters, v0R2, false); - - o2::track::TrackParCov motherTrackClone = mStrangeTrack.mMother; // clone and reset covariance - motherTrackClone.resetCovariance(); - - if (motherClusters.size() >= mMinMotherClus) { // fill only if at least mMinMotherClus clusters of the mother V0 have been attached - std::reverse(motherClusters.begin(), motherClusters.end()); - for (auto& clus : motherClusters) { - if (!updateTrack(clus, motherTrackClone)) - break; - } - - // final 3body refit - if (refitTopology(motherTrackClone)) { - LOG(info) << "------------------------------------------------------"; - LOG(info) << "Pushing back v0: " << v0.getProngID(0) << ", " << v0.getProngID(1); - LOG(info) << "Number of clusters attached: " << motherClusters.size(); - LOG(info) << "Number of ITS track clusters: " << mITStrack.getNumberOfClusters(); - LOG(info) << "Number of clusters attached to V0: " << nAttachments[0] << ", " << nAttachments[1] << ", " << nAttachments[2] << ", " << nAttachments[3] << ", " << nAttachments[4] << ", " << nAttachments[5] << ", " << nAttachments[6]; - mStrangeTrackVec.push_back(mStrangeTrack); - mITStrackRefVec.push_back(ITSindexRef); - mDecayTrackRefVec.push_back(DecIndexRef); - ClusAttachments structClus; - structClus.arr = nAttachments; - mClusAttachments.push_back(structClus); - } + if (matchDecayToITStrack(v0R2, false)) { + LOG(info) << "------------------------------------------------------"; + LOG(info) << "------------------------------------------------------"; + LOG(info) << "ITS Track matched with a V0 decay topology ...."; + LOG(info) << "Number of ITS track clusters attached: " << mITStrack.getNumberOfClusters(); + mStrangeTrackVec.push_back(mStrangeTrack); + mITStrackRefVec.push_back(ITSindexRef); + mDecayTrackRefVec.push_back(DecIndexRef); + mClusAttachments.push_back(mStructClus); + } + } + } + } + + // Loop over Cascades + for (int iCasc{0}; iCasc < mInputCascadeTracks.size(); iCasc++) { + LOG(info) << "Analysing Cascade: " << iCasc + 1 << "/" << mInputCascadeTracks.size(); + auto& DecIndexRef = iCasc; + auto& casc = mInputCascadeTracks[iCasc]; + + auto cascR2 = casc.calcR2(); + auto iBinsCasc = mUtils.getBinRect(casc.getEta(), casc.getPhi(), 0.1, 0.1); + for (int& iBinCasc : iBinsCasc) { + // LOG(info) << "iBinCasc: " << iBinCasc; + for (int iTrack{mTracksIdxTable[iBinCasc]}; iTrack < TMath::Min(mTracksIdxTable[iBinCasc + 1], int(mSortedITStracks.size())); iTrack++) { + mITStrack = mSortedITStracks[iTrack]; + auto& ITSindexRef = mSortedITSindexes[iTrack]; + mStrangeTrack.mMother = (o2::track::TrackParCovF)casc; + mStrangeTrack.mDaughterFirst = casc.getV0Track(); + mStrangeTrack.mBachelor = casc.getBachelorTrack(); + if (matchDecayToITStrack(cascR2, true)) { + LOG(info) << "------------------------------------------------------"; + LOG(info) << "ITS Track matched with a Cascade decay topology ...."; + LOG(info) << "Number of ITS track clusters attached: " << mITStrack.getNumberOfClusters(); + mStrangeTrackVec.push_back(mStrangeTrack); + mITStrackRefVec.push_back(ITSindexRef); + mDecayTrackRefVec.push_back(DecIndexRef); + mClusAttachments.push_back(mStructClus); } } } } } -bool StrangenessTracker::updateTopology(std::array& nAttachments, std::vector& motherClusters, const std::vector& trackClusters, float decayRadius, bool isCascade) +bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) { + + auto trackClusters = getTrackClusters(); + auto& lastClus = trackClusters[0]; + mStrangeTrack.mMatchChi2 = getMatchingChi2(mStrangeTrack.mMother, mITStrack, lastClus); + + std::vector motherClusters; + std::array nAttachments; + int nUpdates = 0; bool isMotherUpdated = false; for (auto& clus : trackClusters) { - auto diffR2 = decayRadius - clus.getX() * clus.getX() - clus.getY() * clus.getY(); // difference between decay radius and Layer R2 + auto diffR2 = decayR2 - clus.getX() * clus.getX() - clus.getY() * clus.getY(); // difference between decay radius and Layer R2 + // Look for the Mother if the Decay radius allows for it, within a tolerance if (diffR2 > -mRadiusTol) { LOG(debug) << "Try to attach cluster to Mother, layer: " << mGeomITS->getLayer(clus.getSensorID()); if (updateTrack(clus, mStrangeTrack.mMother)) { @@ -172,9 +181,44 @@ bool StrangenessTracker::updateTopology(std::array& nAttachment nUpdates++; } } - if (nUpdates < trackClusters.size() || motherClusters.size() == 0) + + if (nUpdates < trackClusters.size() || motherClusters.size() < mMinMotherClus) + return false; + + o2::track::TrackParCov motherTrackClone = mStrangeTrack.mMother; // clone and reset covariance for final topology refit + motherTrackClone.resetCovariance(); + + std::reverse(motherClusters.begin(), motherClusters.end()); + for (auto& clus : motherClusters) { + if (!updateTrack(clus, motherTrackClone)) + break; + } + + // final Topology refit + + int cand = 0; // best V0 candidate + int nCand; + + try { + nCand = isCascade ? mFitter3Body.process(motherTrackClone, mStrangeTrack.mDaughterFirst, mStrangeTrack.mBachelor) : mFitter3Body.process(motherTrackClone, mStrangeTrack.mDaughterFirst, mStrangeTrack.mDaughterSecond); + } catch (std::runtime_error& e) { + return false; + } + if (!nCand) return false; + mFitter3Body.propagateTracksToVertex(); + + mStrangeTrack.mDaughterFirst = mFitter3Body.getTrack(1, 0); + if (isCascade) + mStrangeTrack.mBachelor = mFitter3Body.getTrack(2, 0); + else + mStrangeTrack.mDaughterSecond = mFitter3Body.getTrack(2, 0); + + mStrangeTrack.decayVtx = mFitter3Body.getPCACandidatePos(); + mStrangeTrack.mTopoChi2 = mFitter3Body.getChi2AtPCACandidate(); + mStructClus.arr = nAttachments; + return true; } @@ -244,30 +288,7 @@ std::vector Strangenes return outVec; }; -bool StrangenessTracker::refitTopology(o2::track::TrackParCovF& ITSmotherTrack) -{ - int cand = 0; // best V0 candidate - int nCand; - - try { - nCand = mFitter3Body.process(ITSmotherTrack, mStrangeTrack.mDaughterFirst, mStrangeTrack.mDaughterSecond); - } catch (std::runtime_error& e) { - return false; - } - if (!nCand) - return false; - - mFitter3Body.propagateTracksToVertex(); - - mStrangeTrack.mDaughterFirst = mFitter3Body.getTrack(1, 0); - mStrangeTrack.mDaughterSecond = mFitter3Body.getTrack(2, 0); - mStrangeTrack.decayVtx = mFitter3Body.getPCACandidatePos(); - mStrangeTrack.mTopoChi2 = mFitter3Body.getChi2AtPCACandidate(); - - return true; -}; - -float StrangenessTracker::getMatchingChi2(V0 v0, const TrackITS ITStrack, ITSCluster matchingClus) +float StrangenessTracker::getMatchingChi2(o2::track::TrackParCovF v0, const TrackITS ITStrack, ITSCluster matchingClus) { float alpha = mGeomITS->getSensorRefAlpha(matchingClus.getSensorID()), x = matchingClus.getX(); if (v0.rotate(alpha)) { From 57d29c470ea1aafa2a6ea46fca7a67254133149c Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Mon, 27 Jun 2022 14:25:58 +0200 Subject: [PATCH 22/36] Fix memory error --- .../StrangenessTracking/IndexTableUtils.h | 2 +- .../StrangenessTracking/StrangenessTracker.h | 2 - .../tracking/src/IndexTableUtils.cxx | 72 ------------------- .../tracking/src/StrangenessTracker.cxx | 19 ++--- .../src/StrangenessTrackingWriterSpec.cxx | 9 +-- 5 files changed, 14 insertions(+), 90 deletions(-) delete mode 100644 Detectors/StrangenessTracking/tracking/src/IndexTableUtils.cxx diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h index 49b92e59a7a19..fbf33d624af47 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h @@ -52,7 +52,7 @@ inline int IndexTableUtils::getBinIndex(float eta, float phi) float deltaEta = (maxEta - minEta) / (mEtaBins); int bEta = getEtaBin(eta); int bPhi = getPhiBin(phi); - return bEta >= mEtaBins || bPhi >= mPhiBins ? mEtaBins * mPhiBins : bEta + mEtaBins * bPhi; + return (bEta >= mEtaBins || bPhi >= mPhiBins || bEta < 0 || bPhi < 0) ? mEtaBins * mPhiBins : bEta + mEtaBins * bPhi; } inline std::vector IndexTableUtils::getBinRect(float eta, float phi, float deltaEta, float deltaPhi) diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h index 18f9ccca184df..b4efa71e211c3 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h @@ -20,7 +20,6 @@ #include #include "TMath.h" #include "StrangenessTracking/IndexTableUtils.h" - #include "ReconstructionDataFormats/PID.h" #include "ReconstructionDataFormats/V0.h" #include "ReconstructionDataFormats/Cascade.h" @@ -47,7 +46,6 @@ struct StrangeTrack { o2::track::TrackParCovF mMother; o2::track::TrackParCovF mDaughterFirst; o2::track::TrackParCovF mDaughterSecond; - o2::track::TrackParCovF mBachelor; std::array decayVtx; float mMatchChi2; diff --git a/Detectors/StrangenessTracking/tracking/src/IndexTableUtils.cxx b/Detectors/StrangenessTracking/tracking/src/IndexTableUtils.cxx deleted file mode 100644 index fd9045ff85cc4..0000000000000 --- a/Detectors/StrangenessTracking/tracking/src/IndexTableUtils.cxx +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file IndexTableUtils.cxx -/// \brief -/// - -#include "TMath.h" -#include "StrangenessTracking/IndexTableUtils.h" - -namespace o2 -{ -namespace strangeness_tracking -{ - -int indexTableUtils::getEtaBin(float eta) -{ - float deltaEta = (maxEta - minEta) / (mEtaBins); - int bEta = (eta - minEta) / deltaEta; // bins recentered to 0 - return bEta; -}; - -int indexTableUtils::getPhiBin(float phi) -{ - float deltaPhi = (maxPhi - minPhi) / (mPhiBins); - int bPhi = (phi - minPhi) / deltaPhi; // bin recentered to 0 - return bPhi; -} - -int indexTableUtils::getBinIndex(float eta, float phi) -{ - float deltaPhi = (maxPhi - minPhi) / (mPhiBins); - float deltaEta = (maxEta - minEta) / (mEtaBins); - int bEta = getEtaBin(eta); - int bPhi = getPhiBin(phi); - return bEta >= mEtaBins || bPhi >= mPhiBins ? mEtaBins * mPhiBins : bEta + mEtaBins * bPhi; -} - -std::vector indexTableUtils::getBinRect(float eta, float phi, float deltaEta, float deltaPhi) -{ - std::vector idxVec; - int centralBin = getBinIndex(eta, phi); - if (centralBin == mPhiBins * mEtaBins) { // condition for overflows - idxVec.push_back(centralBin); - return idxVec; - } - int minEtaBin = TMath::Max(0, getEtaBin(eta - deltaEta)); - int maxEtaBin = getEtaBin(eta + deltaEta); - int minPhiBin = TMath::Max(0, getPhiBin(phi - deltaPhi)); - int maxPhiBin = getPhiBin(phi + deltaPhi); - - for (int iPhi{minPhiBin}; iPhi <= maxPhiBin; iPhi++) { - if (iPhi >= mPhiBins) - break; - for (int iEta{minEtaBin}; iEta <= maxEtaBin; iEta++) { - if (iEta >= mEtaBins) - break; - idxVec.push_back(iEta + mEtaBins * iPhi); - } - } - return idxVec; -}; -} // namespace strangeness_tracking -} // namespace o2 diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx index c8f86faf3b86f..f3dd6e5395e68 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx @@ -40,6 +40,8 @@ bool StrangenessTracker::loadData(gsl::span InputITStra void StrangenessTracker::initialise() { mTracksIdxTable.clear(); + mSortedITStracks.clear(); + mSortedITSindexes.clear(); for (int iTrack{0}; iTrack < mInputITStracks.size(); iTrack++) { mSortedITStracks.push_back(mInputITStracks[iTrack]); @@ -55,6 +57,7 @@ void StrangenessTracker::initialise() } std::exclusive_scan(mTracksIdxTable.begin(), mTracksIdxTable.begin() + mUtils.mPhiBins * mUtils.mEtaBins, mTracksIdxTable.begin(), 0); mTracksIdxTable[mUtils.mPhiBins * mUtils.mEtaBins] = mSortedITStracks.size(); + mTracksIdxTable.clear(); } void StrangenessTracker::process() @@ -77,7 +80,7 @@ void StrangenessTracker::process() auto v0R2 = v0.calcR2(); auto iBinsV0 = mUtils.getBinRect(correctedV0.getEta(), correctedV0.getPhi(), 0.1, 0.1); for (int& iBinV0 : iBinsV0) { - LOG(info) << "iBinV0: " << iBinV0; + // LOG(info) << "iBinV0: " << iBinV0; for (int iTrack{mTracksIdxTable[iBinV0]}; iTrack < TMath::Min(mTracksIdxTable[iBinV0 + 1], int(mSortedITStracks.size())); iTrack++) { mITStrack = mSortedITStracks[iTrack]; auto& ITSindexRef = mSortedITSindexes[iTrack]; @@ -111,9 +114,12 @@ void StrangenessTracker::process() for (int iTrack{mTracksIdxTable[iBinCasc]}; iTrack < TMath::Min(mTracksIdxTable[iBinCasc + 1], int(mSortedITStracks.size())); iTrack++) { mITStrack = mSortedITStracks[iTrack]; auto& ITSindexRef = mSortedITSindexes[iTrack]; + + mStrangeTrack.isCascade = true; mStrangeTrack.mMother = (o2::track::TrackParCovF)casc; mStrangeTrack.mDaughterFirst = casc.getV0Track(); - mStrangeTrack.mBachelor = casc.getBachelorTrack(); + mStrangeTrack.mDaughterSecond = casc.getBachelorTrack(); + if (matchDecayToITStrack(cascR2, true)) { LOG(info) << "------------------------------------------------------"; LOG(info) << "ITS Track matched with a Cascade decay topology ...."; @@ -173,7 +179,7 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) } // if Mother is not found, check for cascade bachelor compatibility else { - if (updateTrack(clus, mStrangeTrack.mBachelor)) + if (updateTrack(clus, mStrangeTrack.mDaughterSecond)) nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kBachelor; else break; @@ -200,7 +206,7 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) int nCand; try { - nCand = isCascade ? mFitter3Body.process(motherTrackClone, mStrangeTrack.mDaughterFirst, mStrangeTrack.mBachelor) : mFitter3Body.process(motherTrackClone, mStrangeTrack.mDaughterFirst, mStrangeTrack.mDaughterSecond); + nCand = mFitter3Body.process(motherTrackClone, mStrangeTrack.mDaughterFirst, mStrangeTrack.mDaughterSecond); } catch (std::runtime_error& e) { return false; } @@ -210,10 +216,7 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) mFitter3Body.propagateTracksToVertex(); mStrangeTrack.mDaughterFirst = mFitter3Body.getTrack(1, 0); - if (isCascade) - mStrangeTrack.mBachelor = mFitter3Body.getTrack(2, 0); - else - mStrangeTrack.mDaughterSecond = mFitter3Body.getTrack(2, 0); + mStrangeTrack.mDaughterSecond = mFitter3Body.getTrack(2, 0); mStrangeTrack.decayVtx = mFitter3Body.getPCACandidatePos(); mStrangeTrack.mTopoChi2 = mFitter3Body.getChi2AtPCACandidate(); diff --git a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx index 4b689c6485a26..e90e8bbf95df0 100644 --- a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx @@ -36,11 +36,7 @@ using namespace o2::header; DataProcessorSpec getStrangenessTrackingWriterSpec() { auto loggerV = [](std::vector const& v) { - LOG(info) << "StrangenessTracker writer pulled " << v.size() << " v0s"; - }; - - auto loggerT = [](std::vector const& v) { - LOG(info) << "Strangeness tracker writer pulled " << v.size() << " tracks"; + LOG(info) << "StrangenessTracker writer pulled " << v.size() << " strange tracks"; }; auto inpStTrkID = InputSpec{"strangetracks", "STK", "STRTRACKS", 0}; @@ -48,9 +44,8 @@ DataProcessorSpec getStrangenessTrackingWriterSpec() auto inpITSRefID = InputSpec{"itsrefs", "STK", "ITSREFS", 0}; auto inpDecRefID = InputSpec{"decrefs", "STK", "DECREFS", 0}; - return MakeRootTreeWriterSpec("strangenesstracking-writer", - "o2_strangeness_track.root", + "o2_strange_tracks.root", MakeRootTreeWriterSpec::TreeAttributes{"o2sim", "Tree with Strange Tracks"}, BranchDefinition>{inpStTrkID, "StrangeTracks", loggerV}, BranchDefinition>{inpClusAtt, "ClusUpdates"}, From 069f6a125e748d347ab0d396f251cdbe6d034656 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Mon, 27 Jun 2022 14:40:56 +0200 Subject: [PATCH 23/36] Remove debug cleaning --- .../StrangenessTracking/tracking/src/StrangenessTracker.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx index f3dd6e5395e68..605638603dce8 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx @@ -57,7 +57,6 @@ void StrangenessTracker::initialise() } std::exclusive_scan(mTracksIdxTable.begin(), mTracksIdxTable.begin() + mUtils.mPhiBins * mUtils.mEtaBins, mTracksIdxTable.begin(), 0); mTracksIdxTable[mUtils.mPhiBins * mUtils.mEtaBins] = mSortedITStracks.size(); - mTracksIdxTable.clear(); } void StrangenessTracker::process() From 613eeab4cef474da2a4825411304d8322a8ac8ac Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Wed, 10 Aug 2022 18:43:34 +0200 Subject: [PATCH 24/36] Fetch geo and grp from ccdb --- .../StrangenessTracking/StrangenessTracker.h | 2 +- .../tracking/src/StrangenessTracker.cxx | 33 ++++++------ .../StrangenessTrackingSpec.h | 5 +- .../workflow/src/StrangenessTrackingSpec.cxx | 53 ++++++++----------- .../src/strangeness-tracking-workflow.cxx | 2 +- 5 files changed, 45 insertions(+), 50 deletions(-) diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h index b4efa71e211c3..b46979c952d3e 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h @@ -94,7 +94,7 @@ class StrangenessTracker mFitterV0.setBz(mBz); mFitter3Body.setBz(mBz); mFitterV0.setUseAbsDCA(true); - // mFitter3Body.setUseAbsDCA(true); + mFitter3Body.setUseAbsDCA(true); } bool loadData(gsl::span InputITStracks, std::vector& InputITSclusters, gsl::span InputITSidxs, gsl::span InputV0tracks, gsl::span InputCascadeTracks, o2::its::GeometryTGeo* geomITS); diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx index 605638603dce8..67a2e82de6390 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx @@ -66,7 +66,6 @@ void StrangenessTracker::process() LOG(info) << "Analysing V0: " << iV0 + 1 << "/" << mInputV0tracks.size(); auto& DecIndexRef = iV0; auto& v0 = mInputV0tracks[iV0]; - auto posTrack = v0.getProng(0); auto negTrack = v0.getProng(1); auto alphaV0 = calcV0alpha(v0); @@ -79,18 +78,16 @@ void StrangenessTracker::process() auto v0R2 = v0.calcR2(); auto iBinsV0 = mUtils.getBinRect(correctedV0.getEta(), correctedV0.getPhi(), 0.1, 0.1); for (int& iBinV0 : iBinsV0) { - // LOG(info) << "iBinV0: " << iBinV0; for (int iTrack{mTracksIdxTable[iBinV0]}; iTrack < TMath::Min(mTracksIdxTable[iBinV0 + 1], int(mSortedITStracks.size())); iTrack++) { mITStrack = mSortedITStracks[iTrack]; auto& ITSindexRef = mSortedITSindexes[iTrack]; + LOG(debug) << "V0 pos: " << v0.getProngID(0) << " V0 neg: " << v0.getProngID(1) << ", ITS track ref: " << ITSindexRef; mStrangeTrack.mMother = (o2::track::TrackParCovF)correctedV0; mStrangeTrack.mDaughterFirst = alphaV0 > 0 ? correctedV0.getProng(0) : correctedV0.getProng(1); mStrangeTrack.mDaughterSecond = alphaV0 < 0 ? correctedV0.getProng(0) : correctedV0.getProng(1); if (matchDecayToITStrack(v0R2, false)) { - LOG(info) << "------------------------------------------------------"; - LOG(info) << "------------------------------------------------------"; - LOG(info) << "ITS Track matched with a V0 decay topology ...."; - LOG(info) << "Number of ITS track clusters attached: " << mITStrack.getNumberOfClusters(); + LOG(debug) << "ITS Track matched with a V0 decay topology ...."; + LOG(debug) << "Number of ITS track clusters attached: " << mITStrack.getNumberOfClusters(); mStrangeTrackVec.push_back(mStrangeTrack); mITStrackRefVec.push_back(ITSindexRef); mDecayTrackRefVec.push_back(DecIndexRef); @@ -102,14 +99,13 @@ void StrangenessTracker::process() // Loop over Cascades for (int iCasc{0}; iCasc < mInputCascadeTracks.size(); iCasc++) { - LOG(info) << "Analysing Cascade: " << iCasc + 1 << "/" << mInputCascadeTracks.size(); + LOG(debug) << "Analysing Cascade: " << iCasc + 1 << "/" << mInputCascadeTracks.size(); auto& DecIndexRef = iCasc; auto& casc = mInputCascadeTracks[iCasc]; auto cascR2 = casc.calcR2(); auto iBinsCasc = mUtils.getBinRect(casc.getEta(), casc.getPhi(), 0.1, 0.1); for (int& iBinCasc : iBinsCasc) { - // LOG(info) << "iBinCasc: " << iBinCasc; for (int iTrack{mTracksIdxTable[iBinCasc]}; iTrack < TMath::Min(mTracksIdxTable[iBinCasc + 1], int(mSortedITStracks.size())); iTrack++) { mITStrack = mSortedITStracks[iTrack]; auto& ITSindexRef = mSortedITSindexes[iTrack]; @@ -120,9 +116,8 @@ void StrangenessTracker::process() mStrangeTrack.mDaughterSecond = casc.getBachelorTrack(); if (matchDecayToITStrack(cascR2, true)) { - LOG(info) << "------------------------------------------------------"; - LOG(info) << "ITS Track matched with a Cascade decay topology ...."; - LOG(info) << "Number of ITS track clusters attached: " << mITStrack.getNumberOfClusters(); + LOG(debug) << "ITS Track matched with a Cascade decay topology ...."; + LOG(debug) << "Number of ITS track clusters attached: " << mITStrack.getNumberOfClusters(); mStrangeTrackVec.push_back(mStrangeTrack); mITStrackRefVec.push_back(ITSindexRef); mDecayTrackRefVec.push_back(DecIndexRef); @@ -193,11 +188,14 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) o2::track::TrackParCov motherTrackClone = mStrangeTrack.mMother; // clone and reset covariance for final topology refit motherTrackClone.resetCovariance(); + LOG(debug) << "Clusters attached, starting inward-outward refit"; + std::reverse(motherClusters.begin(), motherClusters.end()); for (auto& clus : motherClusters) { if (!updateTrack(clus, motherTrackClone)) break; } + LOG(debug) << "Inward-outward refit finished, starting final topology refit"; // final Topology refit @@ -207,12 +205,18 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) try { nCand = mFitter3Body.process(motherTrackClone, mStrangeTrack.mDaughterFirst, mStrangeTrack.mDaughterSecond); } catch (std::runtime_error& e) { + LOG(debug) << "Fitter3Body failed: " << e.what(); return false; } - if (!nCand) + if (!nCand) { + LOG(debug) << "Fitter3Body failed: no candidate"; return false; + } - mFitter3Body.propagateTracksToVertex(); + if (!mFitter3Body.propagateTracksToVertex()) { + LOG(debug) << "Fitter3Body failed: propagation to vertex failed"; + return false; + } mStrangeTrack.mDaughterFirst = mFitter3Body.getTrack(1, 0); mStrangeTrack.mDaughterSecond = mFitter3Body.getTrack(2, 0); @@ -242,8 +246,7 @@ bool StrangenessTracker::updateTrack(const ITSCluster& clus, o2::track::TrackPar if (!track.correctForMaterial(thick, thick * rho * radl)) return false; } - auto chi2 = std::abs(track.getPredictedChi2(clus)); - LOG(debug) << "chi2: " << track.getPredictedChi2(clus); + auto chi2 = std::abs(track.getPredictedChi2(clus)); // abs to be understood if (chi2 > mMaxChi2 || chi2 < 0) return false; diff --git a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingSpec.h b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingSpec.h index cae6d53b8b1cb..477289afddf4d 100644 --- a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingSpec.h +++ b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingSpec.h @@ -17,6 +17,7 @@ #include "Framework/Task.h" #include "DataFormatsITSMFT/CompCluster.h" #include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GRPGeomHelper.h" #include "ITSMFTReconstruction/ClustererParam.h" #include "DataFormatsITSMFT/TopologyDictionary.h" @@ -33,7 +34,7 @@ class StrangenessTrackerSpec : public framework::Task public: using ITSCluster = o2::BaseCluster; - StrangenessTrackerSpec(bool isMC = false); + StrangenessTrackerSpec(std::shared_ptr gr, bool isMC); ~StrangenessTrackerSpec() override = default; void init(framework::InitContext& ic) final; @@ -46,9 +47,9 @@ class StrangenessTrackerSpec : public framework::Task void updateTimeDependentParams(framework::ProcessingContext& pc); bool mIsMC = false; - bool mRecreateV0 = true; TStopwatch mTimer; StrangenessTracker mTracker; + std::shared_ptr mGGCCDBRequest; std::unique_ptr mGRP = nullptr; const o2::itsmft::TopologyDictionary* mDict = nullptr; }; diff --git a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx index c06b44af53fd0..94ad79e4b77e8 100644 --- a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx @@ -22,6 +22,7 @@ #include "GlobalTrackingWorkflowReaders/TrackTPCITSReaderSpec.h" #include "GlobalTrackingWorkflow/TOFMatcherSpec.h" #include "Framework/CCDBParamSpec.h" +#include "DataFormatsParameters/GRPObject.h" #include "DataFormatsITSMFT/ROFRecord.h" #include "DataFormatsITS/TrackITS.h" @@ -53,7 +54,7 @@ framework::WorkflowSpec getWorkflow(bool useMC, bool useRootInput) return specs; } -StrangenessTrackerSpec::StrangenessTrackerSpec(bool isMC) : mIsMC{isMC} +StrangenessTrackerSpec::StrangenessTrackerSpec(std::shared_ptr gr, bool isMC) : mGGCCDBRequest(gr), mIsMC{isMC} { // no ops } @@ -63,28 +64,9 @@ void StrangenessTrackerSpec::init(framework::InitContext& ic) mTimer.Stop(); mTimer.Reset(); - auto filename = ic.options().get("grp-file"); - const auto grp = parameters::GRPObject::loadFrom(filename); - // load propagator - base::Propagator::initFieldFromGRP(grp); - std::string matLUTPath = ic.options().get("material-lut-path"); - std::string matLUTFile = o2::base::NameConf::getMatLUTFileName(matLUTPath); - if (o2::utils::Str::pathExists(matLUTFile)) { - auto* lut = o2::base::MatLayerCylSet::loadFromFile(matLUTFile); - o2::base::Propagator::Instance()->setMatLUT(lut); - mTracker.setCorrType(o2::base::PropagatorImpl::MatCorrType::USEMatCorrLUT); - mTracker.setBz(grp->getNominalL3Field()); - LOG(info) << "Loaded material LUT from " << matLUTFile; - LOG(info) << "Magnetic field loaded from GRP " << grp->getNominalL3Field(); - } else { - LOG(info) << "Material LUT " << matLUTFile << " file is absent, only heuristic material correction can be used"; - } - // load geometry - base::GeometryManager::loadGeometry(); - auto gman = o2::its::GeometryTGeo::Instance(); - gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G)); + o2::base::GRPGeomHelper::instance().setRequest(mGGCCDBRequest); LOG(info) << "Initialized strangeness tracker..."; } @@ -126,42 +108,46 @@ void StrangenessTrackerSpec::run(framework::ProcessingContext& pc) labITS.size()); // \nlabTPCTOF: %d\nlabITSTPCTOF: %d + mTracker.setCorrType(o2::base::PropagatorImpl::MatCorrType::USEMatCorrLUT); + mTracker.setBz(o2::base::Propagator::Instance()->getNominalBz()); + auto pattIt = ITSpatt.begin(); std::vector ITSClustersArray; ITSClustersArray.reserve(ITSclus.size()); o2::its::ioutils::convertCompactClusters(ITSclus, pattIt, ITSClustersArray, mDict); auto geom = o2::its::GeometryTGeo::Instance(); - auto field = static_cast(TGeoGlobalMagField::Instance()->GetField()); - double origD[3] = {0., 0., 0.}; - mTracker.setBz(field->getBz(origD)); mTracker.loadData(ITStracks, ITSClustersArray, ITSTrackClusIdx, v0Vec, cascadeVec, geom); mTracker.initialise(); mTracker.process(); - pc.outputs().snapshot(Output{"STK", "STRTRACKS", 0, Lifetime::Timeframe}, mTracker.getStrangeTrackVec()); pc.outputs().snapshot(Output{"STK", "CLUSUPDATES", 0, Lifetime::Timeframe}, mTracker.getClusAttachments()); pc.outputs().snapshot(Output{"STK", "ITSREFS", 0, Lifetime::Timeframe}, mTracker.getITStrackRefVec()); pc.outputs().snapshot(Output{"STK", "DECREFS", 0, Lifetime::Timeframe}, mTracker.getDecayTrackRefVec()); - mTimer.Stop(); } ///_______________________________________ void StrangenessTrackerSpec::updateTimeDependentParams(ProcessingContext& pc) { + o2::base::GRPGeomHelper::instance().checkUpdates(pc); static bool initOnceDone = false; if (!initOnceDone) { // this params need to be queried only once initOnceDone = true; pc.inputs().get("cldict"); // just to trigger the finaliseCCDB + o2::its::GeometryTGeo* geom = o2::its::GeometryTGeo::Instance(); + geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, o2::math_utils::TransformType::T2G)); } } ///_______________________________________ void StrangenessTrackerSpec::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) { + if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) { + return; + } if (matcher == ConcreteDataMatcher("ITS", "CLUSDICT", 0)) { LOG(info) << "cluster dictionary updated"; setClusterDictionary((const o2::itsmft::TopologyDictionary*)obj); @@ -186,6 +172,14 @@ DataProcessorSpec getStrangenessTrackerSpec() inputs.emplace_back("trackITSClIdx", "ITS", "TRACKCLSID", 0, Lifetime::Timeframe); inputs.emplace_back("ITSTrack", "ITS", "TRACKS", 0, Lifetime::Timeframe); inputs.emplace_back("cldict", "ITS", "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec("ITS/Calib/ClusterDictionary")); + auto ggRequest = std::make_shared(false, // orbitResetTime + true, // GRPECS=true + false, // GRPLHCIF + true, // GRPMagField + true, // askMatLUT + o2::base::GRPGeomRequest::Aligned, // geometry + inputs, + true); // V0 inputs.emplace_back("v0s", "GLO", "V0S", 0, Lifetime::Timeframe); // found V0s @@ -211,15 +205,12 @@ DataProcessorSpec getStrangenessTrackerSpec() outputs.emplace_back("STK", "ITSREFS", 0, Lifetime::Timeframe); outputs.emplace_back("STK", "DECREFS", 0, Lifetime::Timeframe); - return DataProcessorSpec{ "strangeness-tracker", inputs, outputs, - AlgorithmSpec{adaptFromTask()}, - Options{ - {"grp-file", VariantType::String, "o2sim_grp.root", {"Name of the grp file"}}, - {"material-lut-path", VariantType::String, "", {"Path of the material LUT file"}}}}; + AlgorithmSpec{adaptFromTask(ggRequest, false)}, + Options{}}; } } // namespace strangeness_tracking diff --git a/Detectors/StrangenessTracking/workflow/src/strangeness-tracking-workflow.cxx b/Detectors/StrangenessTracking/workflow/src/strangeness-tracking-workflow.cxx index 4f4b86d60c15b..c48069d534019 100644 --- a/Detectors/StrangenessTracking/workflow/src/strangeness-tracking-workflow.cxx +++ b/Detectors/StrangenessTracking/workflow/src/strangeness-tracking-workflow.cxx @@ -37,7 +37,7 @@ void customize(std::vector& workflowOptions) {"disable-root-input", o2::framework::VariantType::Bool, false, {"disable root-files input reader"}}, {"disable-mc", o2::framework::VariantType::Bool, false, {"disable MC"}}, {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings"}}}; - + o2::raw::HBFUtilsInitializer::addConfigOption(options); std::swap(workflowOptions, options); } From 036da2e0fc598979e800db542dbeda2e19ffa841 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Thu, 11 Aug 2022 10:41:17 +0200 Subject: [PATCH 25/36] Add config params --- .../include/StrangenessTracking/StrangenessTracker.h | 7 ++----- .../StrangenessTracking/StrangenessTrackingConfigParam.h | 8 ++++++-- .../tracking/src/StrangenessTracker.cxx | 8 ++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h index b46979c952d3e..4447cb56f5d29 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h @@ -20,6 +20,7 @@ #include #include "TMath.h" #include "StrangenessTracking/IndexTableUtils.h" +#include "StrangenessTracking/StrangenessTrackingConfigParam.h" #include "ReconstructionDataFormats/PID.h" #include "ReconstructionDataFormats/V0.h" #include "ReconstructionDataFormats/Cascade.h" @@ -83,8 +84,6 @@ class StrangenessTracker std::vector& getITStrackRefVec() { return mITStrackRefVec; }; std::vector& getDecayTrackRefVec() { return mDecayTrackRefVec; }; - float getMaxChi2() const { return mMaxChi2; } - void setMaxChi2(float d) { mMaxChi2 = d; } float getBz() const { return mBz; } void setBz(float d) { mBz = d; } void setCorrType(const o2::base::PropagatorImpl::MatCorrType& type) { mCorrType = type; } @@ -125,9 +124,7 @@ class StrangenessTracker std::vector mITStrackRefVec; // Ref to the ITS tracks std::vector mDecayTrackRefVec; // Ref to the Cascade and V0 files - float mRadiusTol = 4.; // Radius tolerance for matching V0s - float mMinMotherClus = 3.; // minimum number of cluster to be attached to the mother - float mMaxChi2 = 50; // Maximum matching chi2 +const StrangenessTrackingParamConfig* mStrParams = nullptr; float mBz = -5; // Magnetic field DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h index 21792256a9f66..1e7f33f36b1db 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h @@ -21,9 +21,13 @@ namespace strangeness_tracking { struct StrangenessTrackingParamConfig : public o2::conf::ConfigurableParamHelper { - float dummy = 0; - O2ParamDef(StrangenessTrackingParamConfig, "StrangenessTrackingParam"); + // parameters + float mRadiusTol = 4.; // Radius tolerance for matching V0s + float mMinMotherClus = 3.; // minimum number of cluster to be attached to the mother + float mMaxChi2 = 50; // Maximum matching chi2 + + O2ParamDef(StrangenessTrackingParamConfig, "strtracker"); }; } // namespace strangeness_tracking diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx index 67a2e82de6390..2561a08920fec 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx @@ -144,7 +144,7 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) for (auto& clus : trackClusters) { auto diffR2 = decayR2 - clus.getX() * clus.getX() - clus.getY() * clus.getY(); // difference between decay radius and Layer R2 // Look for the Mother if the Decay radius allows for it, within a tolerance - if (diffR2 > -mRadiusTol) { + if (diffR2 > -mStrParams->mRadiusTol) { LOG(debug) << "Try to attach cluster to Mother, layer: " << mGeomITS->getLayer(clus.getSensorID()); if (updateTrack(clus, mStrangeTrack.mMother)) { motherClusters.push_back(clus); @@ -160,7 +160,7 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) } // if Mother is not found, check for V0 daughters compatibility - if (diffR2 < mRadiusTol && !isMotherUpdated) { + if (diffR2 < mStrParams->mRadiusTol && !isMotherUpdated) { LOG(debug) << "Try to attach cluster to Daughters, layer: " << mGeomITS->getLayer(clus.getSensorID()); if (!isCascade) { @@ -182,7 +182,7 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) } } - if (nUpdates < trackClusters.size() || motherClusters.size() < mMinMotherClus) + if (nUpdates < trackClusters.size() || motherClusters.size() < mStrParams->mMinMotherClus) return false; o2::track::TrackParCov motherTrackClone = mStrangeTrack.mMother; // clone and reset covariance for final topology refit @@ -247,7 +247,7 @@ bool StrangenessTracker::updateTrack(const ITSCluster& clus, o2::track::TrackPar return false; } auto chi2 = std::abs(track.getPredictedChi2(clus)); // abs to be understood - if (chi2 > mMaxChi2 || chi2 < 0) + if (chi2 > mStrParams->mMaxChi2 || chi2 < 0) return false; if (!track.update(clus)) From c35a40ee30d6686c2017dc329e9c6aeb71ebe256 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Fri, 12 Aug 2022 10:44:30 +0200 Subject: [PATCH 26/36] Fix params assignment --- .../include/StrangenessTracking/StrangenessTracker.h | 6 ++---- .../StrangenessTracking/tracking/src/StrangenessTracker.cxx | 6 +++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h index 4447cb56f5d29..c2636a616a60e 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h @@ -105,8 +105,6 @@ class StrangenessTracker bool updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track); bool matchDecayToITStrack(float decayR2, bool isCascade); - - protected: gsl::span mInputITStracks; // input ITS tracks std::vector mTracksIdxTable; // index table for ITS tracks @@ -124,8 +122,8 @@ class StrangenessTracker std::vector mITStrackRefVec; // Ref to the ITS tracks std::vector mDecayTrackRefVec; // Ref to the Cascade and V0 files -const StrangenessTrackingParamConfig* mStrParams = nullptr; - float mBz = -5; // Magnetic field + const StrangenessTrackingParamConfig* mStrParams = nullptr; + float mBz = -5; // Magnetic field DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis DCAFitter3 mFitter3Body; // optional DCA Fitter for final 3 Body refit diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx index 2561a08920fec..a57bed88223f4 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx @@ -57,13 +57,17 @@ void StrangenessTracker::initialise() } std::exclusive_scan(mTracksIdxTable.begin(), mTracksIdxTable.begin() + mUtils.mPhiBins * mUtils.mEtaBins, mTracksIdxTable.begin(), 0); mTracksIdxTable[mUtils.mPhiBins * mUtils.mEtaBins] = mSortedITStracks.size(); + + // create config param instance + mStrParams = &StrangenessTrackingParamConfig::Instance(); + } void StrangenessTracker::process() { // Loop over V0s for (int iV0{0}; iV0 < mInputV0tracks.size(); iV0++) { - LOG(info) << "Analysing V0: " << iV0 + 1 << "/" << mInputV0tracks.size(); + LOG(debug) << "Analysing V0: " << iV0 + 1 << "/" << mInputV0tracks.size(); auto& DecIndexRef = iV0; auto& v0 = mInputV0tracks[iV0]; auto posTrack = v0.getProng(0); From a91fa667812954810afd196d434a8d94b0ca33c9 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Tue, 16 Aug 2022 10:43:29 +0200 Subject: [PATCH 27/36] Add + parameters --- .../StrangenessTrackingConfigParam.h | 4 +++- .../tracking/src/StrangenessTracker.cxx | 21 +++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h index 1e7f33f36b1db..18d0ab7b32c8f 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h @@ -23,7 +23,9 @@ namespace strangeness_tracking struct StrangenessTrackingParamConfig : public o2::conf::ConfigurableParamHelper { // parameters - float mRadiusTol = 4.; // Radius tolerance for matching V0s + float mRadiusTolIB = .5; // Radius tolerance for matching V0s in the IB + float mRadiusTolOB = 4.; // Radius tolerance for matching V0s in the OB + float mMinMotherClus = 3.; // minimum number of cluster to be attached to the mother float mMaxChi2 = 50; // Maximum matching chi2 diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx index a57bed88223f4..67eec24ac25b2 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx @@ -60,7 +60,6 @@ void StrangenessTracker::initialise() // create config param instance mStrParams = &StrangenessTrackingParamConfig::Instance(); - } void StrangenessTracker::process() @@ -80,7 +79,7 @@ void StrangenessTracker::process() continue; auto v0R2 = v0.calcR2(); - auto iBinsV0 = mUtils.getBinRect(correctedV0.getEta(), correctedV0.getPhi(), 0.1, 0.1); + auto iBinsV0 = mUtils.getBinRect(correctedV0.getEta(), correctedV0.getPhi(), 0.01, 0.01); for (int& iBinV0 : iBinsV0) { for (int iTrack{mTracksIdxTable[iBinV0]}; iTrack < TMath::Min(mTracksIdxTable[iBinV0 + 1], int(mSortedITStracks.size())); iTrack++) { mITStrack = mSortedITStracks[iTrack]; @@ -139,6 +138,9 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) auto& lastClus = trackClusters[0]; mStrangeTrack.mMatchChi2 = getMatchingChi2(mStrangeTrack.mMother, mITStrack, lastClus); + auto radTol = decayR2 < 25 ? mStrParams->mRadiusTolIB : mStrParams->mRadiusTolOB; + auto nClusMother = trackClusters.size() < 4 ? 2 : mStrParams->mMinMotherClus; + std::vector motherClusters; std::array nAttachments; @@ -148,7 +150,7 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) for (auto& clus : trackClusters) { auto diffR2 = decayR2 - clus.getX() * clus.getX() - clus.getY() * clus.getY(); // difference between decay radius and Layer R2 // Look for the Mother if the Decay radius allows for it, within a tolerance - if (diffR2 > -mStrParams->mRadiusTol) { + if (diffR2 > radTol) { LOG(debug) << "Try to attach cluster to Mother, layer: " << mGeomITS->getLayer(clus.getSensorID()); if (updateTrack(clus, mStrangeTrack.mMother)) { motherClusters.push_back(clus); @@ -164,7 +166,7 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) } // if Mother is not found, check for V0 daughters compatibility - if (diffR2 < mStrParams->mRadiusTol && !isMotherUpdated) { + if (diffR2 < radTol && !isMotherUpdated) { LOG(debug) << "Try to attach cluster to Daughters, layer: " << mGeomITS->getLayer(clus.getSensorID()); if (!isCascade) { @@ -186,7 +188,7 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) } } - if (nUpdates < trackClusters.size() || motherClusters.size() < mStrParams->mMinMotherClus) + if (nUpdates < trackClusters.size() || motherClusters.size() < nClusMother) return false; o2::track::TrackParCov motherTrackClone = mStrangeTrack.mMother; // clone and reset covariance for final topology refit @@ -207,7 +209,7 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) int nCand; try { - nCand = mFitter3Body.process(motherTrackClone, mStrangeTrack.mDaughterFirst, mStrangeTrack.mDaughterSecond); + nCand = mFitter3Body.process(mStrangeTrack.mDaughterFirst, mStrangeTrack.mDaughterSecond, motherTrackClone); } catch (std::runtime_error& e) { LOG(debug) << "Fitter3Body failed: " << e.what(); return false; @@ -222,8 +224,8 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) return false; } - mStrangeTrack.mDaughterFirst = mFitter3Body.getTrack(1, 0); - mStrangeTrack.mDaughterSecond = mFitter3Body.getTrack(2, 0); + mStrangeTrack.mDaughterFirst = mFitter3Body.getTrack(0, 0); + mStrangeTrack.mDaughterSecond = mFitter3Body.getTrack(1, 0); mStrangeTrack.decayVtx = mFitter3Body.getPCACandidatePos(); mStrangeTrack.mTopoChi2 = mFitter3Body.getChi2AtPCACandidate(); @@ -250,7 +252,8 @@ bool StrangenessTracker::updateTrack(const ITSCluster& clus, o2::track::TrackPar if (!track.correctForMaterial(thick, thick * rho * radl)) return false; } - auto chi2 = std::abs(track.getPredictedChi2(clus)); // abs to be understood + auto chi2 = std::abs(track.getPredictedChi2(clus)); // abs to be understood + LOG(debug) << "Chi2: " << chi2; if (chi2 > mStrParams->mMaxChi2 || chi2 < 0) return false; From 7b236d374e7625afd55dd42e75dccc62d78fb37a Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Tue, 30 Aug 2022 16:14:07 +0200 Subject: [PATCH 28/36] Attach cascade daughters --- .../StrangenessTracking/StrangenessTracker.h | 36 ++-- .../StrangenessTrackingConfigParam.h | 9 +- .../tracking/src/StrangenessTracker.cxx | 164 +++++++++++------- .../workflow/src/StrangenessTrackingSpec.cxx | 5 +- .../src/StrangenessTrackingWriterSpec.cxx | 6 +- 5 files changed, 122 insertions(+), 98 deletions(-) diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h index c2636a616a60e..f6fe0c3b4275c 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h @@ -38,37 +38,36 @@ namespace o2 namespace strangeness_tracking { +enum kPartType { kV0, + kCascade, + kThreeBody }; + struct ClusAttachments { std::array arr; }; struct StrangeTrack { + kPartType mPartType; o2::track::TrackParCovF mMother; - o2::track::TrackParCovF mDaughterFirst; - o2::track::TrackParCovF mDaughterSecond; + int mITSRef = -1; + int mDecayRef = -1; std::array decayVtx; - + std::array decayMom; + float mInvMass; float mMatchChi2; float mTopoChi2; - int isCascade = false; }; class StrangenessTracker { public: - enum kTopology { kMother = 1, - kFirstDaughter = 2, - kSecondDaughter = 3, - kThirdDaughter = 4, - kBachelor = 5 }; using PID = o2::track::PID; using TrackITS = o2::its::TrackITS; using ITSCluster = o2::BaseCluster; using V0 = o2::dataformats::V0; using Cascade = o2::dataformats::Cascade; - using GIndex = o2::dataformats::VtxTrackIndex; using DCAFitter2 = o2::vertexing::DCAFitterN<2>; using DCAFitter3 = o2::vertexing::DCAFitterN<3>; @@ -81,8 +80,6 @@ class StrangenessTracker std::vector& getClusAttachments() { return mClusAttachments; }; std::vector& getStrangeTrackVec() { return mStrangeTrackVec; }; - std::vector& getITStrackRefVec() { return mITStrackRefVec; }; - std::vector& getDecayTrackRefVec() { return mDecayTrackRefVec; }; float getBz() const { return mBz; } void setBz(float d) { mBz = d; } @@ -100,10 +97,10 @@ class StrangenessTracker double calcV0alpha(const V0& v0); std::vector getTrackClusters(); float getMatchingChi2(o2::track::TrackParCovF, const TrackITS ITSTrack, ITSCluster matchingClus); - bool recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const GIndex posID, const GIndex negID, V0& newV0); + bool recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, V0& newV0); bool updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track); - bool matchDecayToITStrack(float decayR2, bool isCascade); + bool matchDecayToITStrack(float decayR); protected: gsl::span mInputITStracks; // input ITS tracks @@ -119,8 +116,6 @@ class StrangenessTracker std::vector mStrangeTrackVec; // structure containing updated mother and daughter tracks std::vector mClusAttachments; // # of attached tracks, 1 for mother, 2 for daughter - std::vector mITStrackRefVec; // Ref to the ITS tracks - std::vector mDecayTrackRefVec; // Ref to the Cascade and V0 files const StrangenessTrackingParamConfig* mStrParams = nullptr; float mBz = -5; // Magnetic field @@ -130,9 +125,12 @@ class StrangenessTracker o2::base::PropagatorImpl::MatCorrType mCorrType = o2::base::PropagatorImpl::MatCorrType::USEMatCorrNONE; // use mat correction o2::its::GeometryTGeo* mGeomITS; // ITS geometry - StrangeTrack mStrangeTrack; - ClusAttachments mStructClus; - o2::its::TrackITS mITStrack; + + std::vector mDaughterTracks; // vector of daughter tracks + StrangeTrack mStrangeTrack; // structure containing updated mother and daughter track refs + ClusAttachments mStructClus; // # of attached tracks, 1 for mother, 2 for daughter + o2::its::TrackITS mITStrack; // ITS track + std::array mV0dauIDs; // V0 daughter IDs ClassDefNV(StrangenessTracker, 1); }; diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h index 18d0ab7b32c8f..db4374c473b09 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h @@ -22,10 +22,11 @@ namespace strangeness_tracking struct StrangenessTrackingParamConfig : public o2::conf::ConfigurableParamHelper { - // parameters - float mRadiusTolIB = .5; // Radius tolerance for matching V0s in the IB - float mRadiusTolOB = 4.; // Radius tolerance for matching V0s in the OB - + // parameters + float mRadiusTolIB = .3; // Radius tolerance for matching V0s in the IB + float mRadiusTolOB = .1; // Radius tolerance for matching V0s in the OB + float mPhiBinSize = 0.1; // Phi bin size for the matching grid + float mEtaBinSize = 0.1; // Eta bin size for the matching grid float mMinMotherClus = 3.; // minimum number of cluster to be attached to the mother float mMaxChi2 = 50; // Maximum matching chi2 diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx index 67eec24ac25b2..f66022ea5ccf0 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx @@ -65,35 +65,41 @@ void StrangenessTracker::initialise() void StrangenessTracker::process() { // Loop over V0s + mDaughterTracks.resize(2); // resize to 2 prongs + for (int iV0{0}; iV0 < mInputV0tracks.size(); iV0++) { LOG(debug) << "Analysing V0: " << iV0 + 1 << "/" << mInputV0tracks.size(); auto& DecIndexRef = iV0; auto& v0 = mInputV0tracks[iV0]; + mV0dauIDs[0] = v0.getProngID(0), mV0dauIDs[1] = v0.getProngID(1); auto posTrack = v0.getProng(0); auto negTrack = v0.getProng(1); auto alphaV0 = calcV0alpha(v0); alphaV0 > 0 ? posTrack.setAbsCharge(2) : negTrack.setAbsCharge(2); V0 correctedV0; // recompute V0 for Hypertriton - if (!recreateV0(posTrack, negTrack, v0.getProngID(0), v0.getProngID(1), correctedV0)) + if (!recreateV0(posTrack, negTrack, correctedV0)) continue; + mStrangeTrack.mPartType = kV0; + auto v0R2 = v0.calcR2(); - auto iBinsV0 = mUtils.getBinRect(correctedV0.getEta(), correctedV0.getPhi(), 0.01, 0.01); + auto iBinsV0 = mUtils.getBinRect(correctedV0.getEta(), correctedV0.getPhi(), mStrParams->mEtaBinSize, mStrParams->mPhiBinSize); for (int& iBinV0 : iBinsV0) { for (int iTrack{mTracksIdxTable[iBinV0]}; iTrack < TMath::Min(mTracksIdxTable[iBinV0 + 1], int(mSortedITStracks.size())); iTrack++) { - mITStrack = mSortedITStracks[iTrack]; - auto& ITSindexRef = mSortedITSindexes[iTrack]; - LOG(debug) << "V0 pos: " << v0.getProngID(0) << " V0 neg: " << v0.getProngID(1) << ", ITS track ref: " << ITSindexRef; mStrangeTrack.mMother = (o2::track::TrackParCovF)correctedV0; - mStrangeTrack.mDaughterFirst = alphaV0 > 0 ? correctedV0.getProng(0) : correctedV0.getProng(1); - mStrangeTrack.mDaughterSecond = alphaV0 < 0 ? correctedV0.getProng(0) : correctedV0.getProng(1); - if (matchDecayToITStrack(v0R2, false)) { + mDaughterTracks[0] = correctedV0.getProng(0); + mDaughterTracks[1] = correctedV0.getProng(1); + mITStrack = mSortedITStracks[iTrack]; + + LOG(debug) << "V0 pos: " << v0.getProngID(0) << " V0 neg: " << v0.getProngID(1) << ", ITS track ref: " << mSortedITSindexes[iTrack]; + + if (matchDecayToITStrack(sqrt(v0R2))) { LOG(debug) << "ITS Track matched with a V0 decay topology ...."; LOG(debug) << "Number of ITS track clusters attached: " << mITStrack.getNumberOfClusters(); + mStrangeTrack.mDecayRef = iV0; + mStrangeTrack.mITSRef = mSortedITSindexes[iTrack]; mStrangeTrackVec.push_back(mStrangeTrack); - mITStrackRefVec.push_back(ITSindexRef); - mDecayTrackRefVec.push_back(DecIndexRef); mClusAttachments.push_back(mStructClus); } } @@ -101,29 +107,33 @@ void StrangenessTracker::process() } // Loop over Cascades + mDaughterTracks.resize(3); // resize to 3 prongs + for (int iCasc{0}; iCasc < mInputCascadeTracks.size(); iCasc++) { LOG(debug) << "Analysing Cascade: " << iCasc + 1 << "/" << mInputCascadeTracks.size(); auto& DecIndexRef = iCasc; auto& casc = mInputCascadeTracks[iCasc]; + auto& cascV0 = mInputV0tracks[casc.getV0ID()]; + mV0dauIDs[0] = cascV0.getProngID(0), mV0dauIDs[1] = cascV0.getProngID(1); + mStrangeTrack.mPartType = kCascade; + // first: bachelor, second: V0 pos, third: V0 neg auto cascR2 = casc.calcR2(); - auto iBinsCasc = mUtils.getBinRect(casc.getEta(), casc.getPhi(), 0.1, 0.1); + auto iBinsCasc = mUtils.getBinRect(casc.getEta(), casc.getPhi(), mStrParams->mEtaBinSize, mStrParams->mPhiBinSize); for (int& iBinCasc : iBinsCasc) { for (int iTrack{mTracksIdxTable[iBinCasc]}; iTrack < TMath::Min(mTracksIdxTable[iBinCasc + 1], int(mSortedITStracks.size())); iTrack++) { + mStrangeTrack.mMother = (o2::track::TrackParCovF)casc; + mDaughterTracks[0] = casc.getBachelorTrack(), mDaughterTracks[1] = cascV0.getProng(0), mDaughterTracks[2] = cascV0.getProng(1); mITStrack = mSortedITStracks[iTrack]; auto& ITSindexRef = mSortedITSindexes[iTrack]; - - mStrangeTrack.isCascade = true; - mStrangeTrack.mMother = (o2::track::TrackParCovF)casc; - mStrangeTrack.mDaughterFirst = casc.getV0Track(); - mStrangeTrack.mDaughterSecond = casc.getBachelorTrack(); - - if (matchDecayToITStrack(cascR2, true)) { + LOG(debug) << "----------------------"; + LOG(debug) << "CascV0: " << casc.getV0ID() << ", Bach ID: " << casc.getBachelorID() << ", ITS track ref: " << mSortedITSindexes[iTrack]; + if (matchDecayToITStrack(sqrt(cascR2))) { LOG(debug) << "ITS Track matched with a Cascade decay topology ...."; LOG(debug) << "Number of ITS track clusters attached: " << mITStrack.getNumberOfClusters(); + mStrangeTrack.mDecayRef = iCasc; + mStrangeTrack.mITSRef = mSortedITSindexes[iTrack]; mStrangeTrackVec.push_back(mStrangeTrack); - mITStrackRefVec.push_back(ITSindexRef); - mDecayTrackRefVec.push_back(DecIndexRef); mClusAttachments.push_back(mStructClus); } } @@ -131,15 +141,15 @@ void StrangenessTracker::process() } } -bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) +bool StrangenessTracker::matchDecayToITStrack(float decayR) { auto trackClusters = getTrackClusters(); auto& lastClus = trackClusters[0]; mStrangeTrack.mMatchChi2 = getMatchingChi2(mStrangeTrack.mMother, mITStrack, lastClus); - auto radTol = decayR2 < 25 ? mStrParams->mRadiusTolIB : mStrParams->mRadiusTolOB; - auto nClusMother = trackClusters.size() < 4 ? 2 : mStrParams->mMinMotherClus; + auto radTol = decayR < 4 ? mStrParams->mRadiusTolIB : mStrParams->mRadiusTolOB; + auto nMinClusMother = trackClusters.size() < 4 ? 2 : mStrParams->mMinMotherClus; std::vector motherClusters; std::array nAttachments; @@ -148,47 +158,47 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) bool isMotherUpdated = false; for (auto& clus : trackClusters) { - auto diffR2 = decayR2 - clus.getX() * clus.getX() - clus.getY() * clus.getY(); // difference between decay radius and Layer R2 + int nUpdOld = nUpdates; + double clusRad = sqrt(clus.getX() * clus.getX() - clus.getY() * clus.getY()); + auto diffR = decayR - clusRad; + auto relDiffR = diffR / decayR; // Look for the Mother if the Decay radius allows for it, within a tolerance - if (diffR2 > radTol) { + LOG(debug) << "++++++++"; + LOG(debug) << "decayR: " << decayR << ", diffR: " << diffR << ", clus rad: " << clusRad << ", radTol: " << radTol; + if (relDiffR > -radTol) { LOG(debug) << "Try to attach cluster to Mother, layer: " << mGeomITS->getLayer(clus.getSensorID()); if (updateTrack(clus, mStrangeTrack.mMother)) { motherClusters.push_back(clus); - nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kMother; + nAttachments[mGeomITS->getLayer(clus.getSensorID())] = 0; isMotherUpdated = true; nUpdates++; - continue; - } else { - if (isMotherUpdated == true) { - break; // daughter clusters cannot be attached now - } + LOG(debug) << "Cluster attached to Mother"; + continue; // if the cluster is attached to the mother, skip the rest of the loop } } // if Mother is not found, check for V0 daughters compatibility - if (diffR2 < radTol && !isMotherUpdated) { + if (relDiffR < radTol && !isMotherUpdated) { + bool isDauUpdated = false; LOG(debug) << "Try to attach cluster to Daughters, layer: " << mGeomITS->getLayer(clus.getSensorID()); - - if (!isCascade) { - if (updateTrack(clus, mStrangeTrack.mDaughterFirst)) - nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kFirstDaughter; - else if (updateTrack(clus, mStrangeTrack.mDaughterSecond)) - nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kSecondDaughter; - else - break; - } - // if Mother is not found, check for cascade bachelor compatibility - else { - if (updateTrack(clus, mStrangeTrack.mDaughterSecond)) - nAttachments[mGeomITS->getLayer(clus.getSensorID())] = kBachelor; - else + for (int iDau{0}; iDau < mDaughterTracks.size(); iDau++) { + auto& dauTrack = mDaughterTracks[iDau]; + if (updateTrack(clus, dauTrack)) { + nAttachments[mGeomITS->getLayer(clus.getSensorID())] = iDau + 1; + isDauUpdated = true; break; + } } + if (!isDauUpdated) + break; // no daughter track updated, stop the loop + nUpdates++; } + if (nUpdates == nUpdOld) + break; // no track updated, stop the loop } - if (nUpdates < trackClusters.size() || motherClusters.size() < nClusMother) + if (nUpdates < trackClusters.size() || motherClusters.size() < nMinClusMother) return false; o2::track::TrackParCov motherTrackClone = mStrangeTrack.mMother; // clone and reset covariance for final topology refit @@ -208,25 +218,39 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR2, bool isCascade) int cand = 0; // best V0 candidate int nCand; - try { - nCand = mFitter3Body.process(mStrangeTrack.mDaughterFirst, mStrangeTrack.mDaughterSecond, motherTrackClone); - } catch (std::runtime_error& e) { - LOG(debug) << "Fitter3Body failed: " << e.what(); - return false; - } - if (!nCand) { - LOG(debug) << "Fitter3Body failed: no candidate"; - return false; + // refit cascade + if (mStrangeTrack.mPartType == kCascade) { + V0 cascV0Upd; + if (!recreateV0(mDaughterTracks[1], mDaughterTracks[2], cascV0Upd)) { + LOG(debug) << "Cascade V0 refit failed"; + return false; + } + try { + nCand = mFitter3Body.process(cascV0Upd, mDaughterTracks[0], motherTrackClone); + } catch (std::runtime_error& e) { + LOG(debug) << "Fitter3Body failed: " << e.what(); + return false; + } + if (!nCand || !mFitter3Body.propagateTracksToVertex()) { + LOG(debug) << "Fitter3Body failed: propagation to vertex failed"; + return false; + } } - if (!mFitter3Body.propagateTracksToVertex()) { - LOG(debug) << "Fitter3Body failed: propagation to vertex failed"; - return false; + // refit V0 + else if (mStrangeTrack.mPartType == kV0) { + try { + nCand = mFitter3Body.process(mDaughterTracks[0], mDaughterTracks[1], motherTrackClone); + } catch (std::runtime_error& e) { + LOG(debug) << "Fitter3Body failed: " << e.what(); + return false; + } + if (!nCand || !mFitter3Body.propagateTracksToVertex()) { + LOG(debug) << "Fitter3Body failed: propagation to vertex failed"; + return false; + } } - mStrangeTrack.mDaughterFirst = mFitter3Body.getTrack(0, 0); - mStrangeTrack.mDaughterSecond = mFitter3Body.getTrack(1, 0); - mStrangeTrack.decayVtx = mFitter3Body.getPCACandidatePos(); mStrangeTrack.mTopoChi2 = mFitter3Body.getChi2AtPCACandidate(); mStructClus.arr = nAttachments; @@ -240,11 +264,20 @@ bool StrangenessTracker::updateTrack(const ITSCluster& clus, o2::track::TrackPar float alpha = mGeomITS->getSensorRefAlpha(clus.getSensorID()), x = clus.getX(); int layer{mGeomITS->getLayer(clus.getSensorID())}; + auto stringOld = track.asString(); + LOG(debug) << "Track before update, Y2: " << track.getSigmaY2() << ", Z2: " << track.getSigmaZ2(); + if (!track.rotate(alpha)) return false; + LOG(debug) << "Track rotated, Y2: " << track.getSigmaY2() << ", Z2: " << track.getSigmaZ2(); + if (!propInstance->propagateToX(track, x, getBz(), o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, mCorrType)) return false; + + auto stringNew = track.asString(); + LOG(debug) << "Track after propagation, Y2: " << track.getSigmaY2() << ", Z2: " << track.getSigmaZ2(); + if (mCorrType == o2::base::PropagatorF::MatCorrType::USEMatCorrNONE) { float thick = layer < 3 ? 0.005 : 0.01; constexpr float radl = 9.36f; // Radiation length of Si [cm] @@ -263,7 +296,7 @@ bool StrangenessTracker::updateTrack(const ITSCluster& clus, o2::track::TrackPar return true; } -bool StrangenessTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const GIndex posID, const GIndex negID, V0& newV0) +bool StrangenessTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, V0& newV0) { int nCand; @@ -272,10 +305,9 @@ bool StrangenessTracker::recreateV0(const o2::track::TrackParCov& posTrack, cons } catch (std::runtime_error& e) { return false; } - if (!nCand) + if (!nCand || !mFitterV0.propagateTracksToVertex()) return false; - mFitterV0.propagateTracksToVertex(); const auto& v0XYZ = mFitterV0.getPCACandidatePos(); auto& propPos = mFitterV0.getTrack(0, 0); @@ -285,7 +317,7 @@ bool StrangenessTracker::recreateV0(const o2::track::TrackParCov& posTrack, cons propPos.getPxPyPzGlo(pP); propNeg.getPxPyPzGlo(pN); std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; - newV0 = V0(v0XYZ, pV0, mFitterV0.calcPCACovMatrixFlat(0), propPos, propNeg, posID, negID, o2::track::PID::HyperTriton); + newV0 = V0(v0XYZ, pV0, mFitterV0.calcPCACovMatrixFlat(0), propPos, propNeg, mV0dauIDs[0], mV0dauIDs[1], o2::track::PID::HyperTriton); return true; }; diff --git a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx index 94ad79e4b77e8..c2cef13ed1db2 100644 --- a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx @@ -109,6 +109,7 @@ void StrangenessTrackerSpec::run(framework::ProcessingContext& pc) // \nlabTPCTOF: %d\nlabITSTPCTOF: %d mTracker.setCorrType(o2::base::PropagatorImpl::MatCorrType::USEMatCorrLUT); + LOG(debug) << "Bz: " << o2::base::Propagator::Instance()->getNominalBz(); mTracker.setBz(o2::base::Propagator::Instance()->getNominalBz()); auto pattIt = ITSpatt.begin(); @@ -123,8 +124,6 @@ void StrangenessTrackerSpec::run(framework::ProcessingContext& pc) pc.outputs().snapshot(Output{"STK", "STRTRACKS", 0, Lifetime::Timeframe}, mTracker.getStrangeTrackVec()); pc.outputs().snapshot(Output{"STK", "CLUSUPDATES", 0, Lifetime::Timeframe}, mTracker.getClusAttachments()); - pc.outputs().snapshot(Output{"STK", "ITSREFS", 0, Lifetime::Timeframe}, mTracker.getITStrackRefVec()); - pc.outputs().snapshot(Output{"STK", "DECREFS", 0, Lifetime::Timeframe}, mTracker.getDecayTrackRefVec()); mTimer.Stop(); } @@ -202,8 +201,6 @@ DataProcessorSpec getStrangenessTrackerSpec() std::vector outputs; outputs.emplace_back("STK", "STRTRACKS", 0, Lifetime::Timeframe); outputs.emplace_back("STK", "CLUSUPDATES", 0, Lifetime::Timeframe); - outputs.emplace_back("STK", "ITSREFS", 0, Lifetime::Timeframe); - outputs.emplace_back("STK", "DECREFS", 0, Lifetime::Timeframe); return DataProcessorSpec{ "strangeness-tracker", diff --git a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx index e90e8bbf95df0..1888b055df19d 100644 --- a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx @@ -41,16 +41,12 @@ DataProcessorSpec getStrangenessTrackingWriterSpec() auto inpStTrkID = InputSpec{"strangetracks", "STK", "STRTRACKS", 0}; auto inpClusAtt = InputSpec{"clusupdates", "STK", "CLUSUPDATES",0}; - auto inpITSRefID = InputSpec{"itsrefs", "STK", "ITSREFS", 0}; - auto inpDecRefID = InputSpec{"decrefs", "STK", "DECREFS", 0}; return MakeRootTreeWriterSpec("strangenesstracking-writer", "o2_strange_tracks.root", MakeRootTreeWriterSpec::TreeAttributes{"o2sim", "Tree with Strange Tracks"}, BranchDefinition>{inpStTrkID, "StrangeTracks", loggerV}, - BranchDefinition>{inpClusAtt, "ClusUpdates"}, - BranchDefinition>{inpITSRefID, "ITSTrackRefs"}, - BranchDefinition>{inpDecRefID, "DecayTrackRefs"})(); + BranchDefinition>{inpClusAtt, "ClusUpdates"})(); } } // namespace strangeness_tracking From 666ed1e5966642d93e37e3d805c1cbc714ee78f8 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Mon, 5 Dec 2022 17:12:29 +0100 Subject: [PATCH 29/36] Add macros --- .../macros/AnalyseHyperTree.C | 204 ------ .../StrangenessTracking/macros/CMakeLists.txt | 2 +- .../macros/XiTrackingStudy.C | 587 ++++++++++++++++++ .../macros/cascadeStudyUtils.h | 340 ++++++++++ 4 files changed, 928 insertions(+), 205 deletions(-) delete mode 100644 Detectors/StrangenessTracking/macros/AnalyseHyperTree.C create mode 100644 Detectors/StrangenessTracking/macros/XiTrackingStudy.C create mode 100644 Detectors/StrangenessTracking/macros/cascadeStudyUtils.h diff --git a/Detectors/StrangenessTracking/macros/AnalyseHyperTree.C b/Detectors/StrangenessTracking/macros/AnalyseHyperTree.C deleted file mode 100644 index 32c3135b42bda..0000000000000 --- a/Detectors/StrangenessTracking/macros/AnalyseHyperTree.C +++ /dev/null @@ -1,204 +0,0 @@ -#if !defined(CLING) || defined(ROOTCLING) -#include "CommonDataFormat/RangeReference.h" -#include "ReconstructionDataFormats/Cascade.h" -#include "ReconstructionDataFormats/PID.h" -#include "ReconstructionDataFormats/V0.h" -#include "SimulationDataFormat/MCCompLabel.h" -#include "SimulationDataFormat/MCTrack.h" -#include "DataFormatsITS/TrackITS.h" -#include "DataFormatsITSMFT/ROFRecord.h" - -#include -#include "TCanvas.h" -#include "TFile.h" -#include "TH1F.h" -#include "TMath.h" -#include "TString.h" -#include "TTree.h" -#endif - -using GIndex = o2::dataformats::VtxTrackIndex; -using V0 = o2::dataformats::V0; -using MCTrack = o2::MCTrack; -using Cascade = o2::dataformats::Cascade; -using RRef = o2::dataformats::RangeReference; -using VBracket = o2::math_utils::Bracket; -using namespace o2::itsmft; -using Vec3 = ROOT::Math::SVector; - -const int motherPDG = 1010010030; -const int firstDaughterPDG = 1000020030; -const int secondDaughterPDG = -211; - -// const int motherPDG = 3122; -// const int firstDaughterPDG = 2212; -// const int secondDaughterPDG = -211; - -o2::its::TrackITS *getITSTrack(int motherEvID, int motherTrackID, TTree *ITStree, std::vector *ITSlabel, std::vector *ITStrack); -void doMatching(const std::vector> &mcTracksMatrix, TTree *treeDetectors, std::vector *labDetectors, TH1D *histo); -double calcMass(const V0 &v0, double dauMass[2], int dauCharges[2]); - -void AnalyseHyperTree() -{ - auto fMCTracks = TFile::Open("sgn_1_Kine.root"); - auto fSecondaries = TFile::Open("o2_hypertrack.root"); - auto fITS = TFile::Open("o2trac_its.root"); - auto fTPC = TFile::Open("tpctracks.root"); - - auto fITSTPC = TFile::Open("o2match_itstpc.root"); - auto fTPCTOF = TFile::Open("o2match_tof_tpc.root"); - auto fITSTPCTOF = TFile::Open("o2match_tof_itstpc.root"); - - // Trees - auto treeMCTracks = (TTree *)fMCTracks->Get("o2sim"); - auto treeSecondaries = (TTree *)fSecondaries->Get("o2sim"); - auto treeITS = (TTree *)fITS->Get("o2sim"); - auto treeTPC = (TTree *)fTPC->Get("tpcrec"); - - auto treeITSTPC = (TTree *)fITSTPC->Get("matchTPCITS"); - auto treeITSTPCTOF = (TTree *)fITSTPCTOF->Get("matchTOF"); - auto treeTPCTOF = (TTree *)fTPCTOF->Get("matchTOF"); - - // Tracks - std::vector *MCtracks = nullptr; - std::vector *v0vec = nullptr; - std::vector *ITSref = nullptr; - std::vector *chi2vec = nullptr; - - - std::vector *ITStracks = nullptr; - std::vector *rofArr = nullptr; - - // Labels - std::vector *labITSvec = nullptr; - std::vector *labITSTPCvec = nullptr; - std::vector *labITSTPCTOFvec = nullptr; - std::vector *labTPCTOFvec = nullptr; - std::vector *labTPCvec = nullptr; - - treeSecondaries->SetBranchAddress("V0s", &v0vec); - treeSecondaries->SetBranchAddress("ITSTrackRefs", &ITSref); - treeSecondaries->SetBranchAddress("ITSV0Chi2", &chi2vec); - - - treeMCTracks->SetBranchAddress("MCTrack", &MCtracks); - treeITSTPC->SetBranchAddress("MatchMCTruth", &labITSTPCvec); - treeTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labTPCTOFvec); - treeITSTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labITSTPCTOFvec); - treeITS->SetBranchAddress("ITSTrackMCTruth", &labITSvec); - treeITS->SetBranchAddress("ITSTrack", &ITStracks); - treeITS->SetBranchAddress("ITSTracksROF", &rofArr); - treeTPC->SetBranchAddress("TPCTracksMCTruth", &labTPCvec); - - std::map *> - map{{"TPC", labTPCvec}, {"ITS", labITSvec}, {"ITS-TPC", labITSTPCvec}, {"TPC-TOF", labTPCTOFvec}, {"ITS-TPC-TOF", labITSTPCTOFvec}}; - - // fill MC matrix - int injectedParticles = 0; - std::vector> mcTracksMatrix; - auto nev = treeMCTracks->GetEntriesFast(); - - mcTracksMatrix.resize(nev); - for (int n = 0; n < nev; n++) - { // loop over MC events - treeMCTracks->GetEvent(n); - - mcTracksMatrix[n].resize(MCtracks->size()); - for (unsigned int mcI{0}; mcI < MCtracks->size(); ++mcI) - { - mcTracksMatrix[n][mcI] = MCtracks->at(mcI); - if (MCtracks->at(mcI).GetPdgCode() == motherPDG) - { - injectedParticles++; - } - } - } - - treeSecondaries->GetEntry(); - treeITS->GetEntry(); - treeTPC->GetEntry(); - - treeITSTPC->GetEntry(); - treeTPCTOF->GetEntry(); - treeITSTPCTOF->GetEntry(); - - int counter = 0; - for (unsigned int hTrack{0}; hTrack < v0vec->size(); hTrack++) - { - auto &v0 = v0vec->at(hTrack); - auto &chi2 = chi2vec->at(hTrack); - - std::vector motherIDvec; - std::vector daughterIDvec; - std::vector evIDvec; - - for (int iV0 = 0; iV0 < 2; iV0++) - { - std::cout << "---------------------------------" << std::endl; - LOG(INFO) << "Daughter 0, Rec Pt: " << v0.getProng(0).getPt() << ", Track type: " << v0.getProngID(0).getSourceName(); - LOG(INFO) << "Daughter 1, Rec Pt: " << v0.getProng(1).getPt() << ", Track type: " << v0.getProngID(1).getSourceName(); - - - - - if (map[v0.getProngID(iV0).getSourceName()]) - { - auto labTrackType = map[v0.getProngID(iV0).getSourceName()]; - auto lab = labTrackType->at(v0.getProngID(iV0).getIndex()); - // LOG(INFO) << v0.getProngID(iV0); - - int trackID, evID, srcID; - bool fake; - lab.get(trackID, evID, srcID, fake); - if (!lab.isNoise() && lab.isValid() && lab.isCorrect() && srcID) - { - auto motherID = mcTracksMatrix[evID][trackID].getMotherTrackId(); - motherIDvec.push_back(motherID); - daughterIDvec.push_back(trackID); - evIDvec.push_back(evID); - } - } - } - - - - if (motherIDvec.size() < 2) - continue; - if (motherIDvec[0] != motherIDvec[1] || evIDvec[0] != evIDvec[1]) - continue; - if (motherIDvec[0] <= 0 || motherIDvec[0] > 10000) - continue; - - int pdg0 = mcTracksMatrix[evIDvec[0]][daughterIDvec[0]].GetPdgCode(); - int pdg1 = mcTracksMatrix[evIDvec[0]][daughterIDvec[1]].GetPdgCode(); - - if (pdg0 != firstDaughterPDG && pdg0 != secondDaughterPDG) - continue; - if (pdg1 != firstDaughterPDG && pdg1 != secondDaughterPDG) - continue; - - auto ITSlabel = labITSvec->at(ITSref->at(hTrack)); - int ITStrackID, ITSevID, ITSsrcID; - bool ITSfake; - ITSlabel.get(ITStrackID, ITSevID, ITSsrcID, ITSfake); - - if(ITStrackID == daughterIDvec[0]) LOG(INFO) << "ITS TRACK == He3 TRACK"; - if(ITStrackID == daughterIDvec[1]) LOG(INFO) << "ITS TRACK == PI TRACK"; - LOG(INFO) << "Chi2: " << chi2; - - - - if (ITStrackID != motherIDvec[1] || ITSevID != evIDvec[0]) - continue; - - counter++; - LOG(INFO) << "Counter: " << counter; - LOG(INFO) << evIDvec[0] << ", " << motherIDvec[0] << ", " << motherIDvec[1]; - LOG(INFO) << "Common mother found, PDG: " << mcTracksMatrix[evIDvec[0]][motherIDvec[0]].GetPdgCode(); - LOG(INFO) << "Daughter 0, PDG: " << pdg0 << ", Pt: " << mcTracksMatrix[evIDvec[0]][daughterIDvec[0]].GetPt(); - LOG(INFO) << "Daughter 0, Rec Pt: " << v0.getProng(0).getPt() << ", Track type: " << v0.getProngID(0).getSourceName(); - LOG(INFO) << "Daughter 1, PDG: " << pdg1 << ", Pt: " << mcTracksMatrix[evIDvec[0]][daughterIDvec[1]].GetPt(); - LOG(INFO) << "Daughter 1, Rec Pt: " << v0.getProng(1).getPt() << ", Track type: " << v0.getProngID(1).getSourceName(); - auto motherTrack = mcTracksMatrix[evIDvec[0]][motherIDvec[0]]; - } -} diff --git a/Detectors/StrangenessTracking/macros/CMakeLists.txt b/Detectors/StrangenessTracking/macros/CMakeLists.txt index 537bafafe37f4..17a83b26781ac 100644 --- a/Detectors/StrangenessTracking/macros/CMakeLists.txt +++ b/Detectors/StrangenessTracking/macros/CMakeLists.txt @@ -1,4 +1,4 @@ -o2_add_test_root_macro(AnalyseHyperTree.C +o2_add_test_root_macro(XiTrackingStudy.C PUBLIC_LINK_LIBRARIES O2::MathUtils O2::ITSBase O2::ITSMFTReconstruction diff --git a/Detectors/StrangenessTracking/macros/XiTrackingStudy.C b/Detectors/StrangenessTracking/macros/XiTrackingStudy.C new file mode 100644 index 0000000000000..31fbeed09e3aa --- /dev/null +++ b/Detectors/StrangenessTracking/macros/XiTrackingStudy.C @@ -0,0 +1,587 @@ +#if !defined(CLING) || defined(ROOTCLING) +#include "ReconstructionDataFormats/PID.h" +#include "ReconstructionDataFormats/V0.h" +#include "SimulationDataFormat/MCTruthContainer.h" +#include "SimulationDataFormat/MCCompLabel.h" +#include "SimulationDataFormat/MCTrack.h" +#include "ITSMFTSimulation/Hit.h" + +#include "DataFormatsITSMFT/TopologyDictionary.h" +#include "DetectorsCommonDataFormats/DetectorNameConf.h" +#include "ITSBase/GeometryTGeo.h" +#include "DataFormatsITS/TrackITS.h" +#include "DataFormatsITSMFT/CompCluster.h" +#include "DataFormatsITSMFT/ROFRecord.h" +#include "ITStracking/IOUtils.h" + +#include +#include +#include "TCanvas.h" +#include "TFile.h" +#include "TH1F.h" +#include "TH2D.h" +#include "TSystemDirectory.h" +#include "TMath.h" +#include "TString.h" +#include "TTree.h" +#include "TLegend.h" +#include "CommonDataFormat/RangeReference.h" +#include "DetectorsVertexing/DCAFitterN.h" +#include "StrangenessTracking/StrangenessTracker.h" +#include "cascadeStudyUtils.h" + +#endif + +using GIndex = o2::dataformats::VtxTrackIndex; +using V0 = o2::dataformats::V0; +using Cascade = o2::dataformats::Cascade; + +using MCTrack = o2::MCTrack; +using VBracket = o2::math_utils::Bracket; +using namespace o2::itsmft; +using CompClusterExt = o2::itsmft::CompClusterExt; +using ITSCluster = o2::BaseCluster; +using Vec3 = ROOT::Math::SVector; +using StrangeTrack = o2::strangeness_tracking::StrangeTrack; + +std::array matchCascToMC(const std::vector> &mcTracksMatrix, std::map *> &map, std::vector *v0vec, Cascade &casc, bool &isV0reco); +std::array checkV0mother(const std::vector> &mcTracksMatrix, std::map *> &map, V0 &v0); + +void XiTrackingStudy(std::string path) +{ + TSystemDirectory dir("MyDir", path.data()); + auto files = dir.GetListOfFiles(); + std::vector dirs; + std::vector kine_files; + + for (auto fileObj : *files) + { + std::string file = ((TSystemFile *)fileObj)->GetName(); + if (file.substr(0, 2) == "tf") + { + dirs.push_back(path + file); + auto innerdir = (TSystemDirectory *)fileObj; + auto innerfiles = innerdir->GetListOfFiles(); + for (auto innerfileObj : *innerfiles) + { + TString innerfile = ((TSystemFile *)innerfileObj)->GetName(); + if (innerfile.EndsWith("Kine.root") && innerfile.Contains("sgn")) + { + kine_files.push_back(innerfile); + } + } + } + } + + TH2D *hHyperhisto = new TH2D("histo hyperV0", ";#it{p}_{T} (GeV/#it{c}); Radius^2 (cm) ; Counts", 20, 1, 10, 30, 1, 900); + TH1D *hResV0histo = new TH1D("pT resolution before hypertracking", ";(#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, -0.2, 0.2); + TH1D *hResHyperhisto = new TH1D("pT resolution after hypertracking", ";(#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, -0.2, 0.2); + TH1D *hResCascR2 = new TH1D("R2 resolution before tracking", ";(R2^{gen} - R2^{rec})/R2^{gen}; Counts", 200, -0.1, 0.1); + TH1D *hResCascTrackedR2 = new TH1D("R2 resolution after tracking", ";(R2^{gen} - R2^{rec})/R2^{gen}; Counts", 200, -0.1, 0.1); + + TH1D *hCascCounter = new TH1D("Casc counter", ";Casc counter; Counts", 1, 0.5, 1.5); + TH1D *hGenXiCounter = new TH1D("Gen Casc counter", ";Casc counter; Counts", 1, 0.5, 1.5); + + + TH1D *hFakeAssocCounter = new TH1D("Fake assoc counter", ";Fake assoc counter; Counts", 1, 0.5, 1.5); + + TH1D *hRecXiCounter = new TH1D("Rec Xi counter", "; ; Counts", 1, 0.5, 1.5); + TH1D *hCascMomsInV0s = new TH1D("Rec V0s from Xi counter", "; ; Counts", 1, 0.5, 1.5); + TH1D *hFindableBachfromXiCounter = new TH1D("Rec bachelors from Xi counter", "; ; Counts", 1, 0.5, 1.5); + + TH1D *hRecCascInvMass = new TH1D("Rec Casc InvMass", "; M (GeV/c^{2}); Counts", 150, 1.2, 1.5); + TH1D *hStrangeTrackInvMass = new TH1D("Strange track inv mass", ";M (GeV/c^{2}); Counts", 150, 1.2, 1.5); + TH1D *hXiStats = new TH1D("cascade_stats", "; ; Counts", 3, 0.5, 3.5); + + TH1D *hGenXiRadius = new TH1D("gen_casc_r", "; Radius (cm); Counts", 40, 0., 40.); + TH1D *hRecXiRad = new TH1D("rec_casc_r", ";Radius_{trackable} (cm); Counts", 40, 0, 40); + TH1D *hTrackedXiRad = new TH1D("r_dist_aft_track", ";R2^{rec} (cm); Counts", 40, 0, 40); + + TH1D *hGenXiMom = new TH1D("gen_casc_pt", "; #it{p}_{T}^{gen} (GeV/#it{c}); Counts", 40, 1, 6); + TH1D *hRecXiMom = new TH1D("rec_casc_pt", "; #it{p}_{T}^{gen} (GeV/#it{c}); Counts", 40, 1, 6); + TH1D *hTrackedXiMom = new TH1D("pT_dist_aft_track", ";#it{p}_{T}^{rec} (GeV/#it{c}); Counts", 40, 1, 6); + + // Geometry + o2::base::GeometryManager::loadGeometry(dirs[0] + "/o2sim_geometry.root"); + auto gman = o2::its::GeometryTGeo::Instance(); + gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G)); + + int counter = 0; + for (unsigned int i = 0; i < dirs.size(); i++) + { + auto &dir = dirs[i]; + auto &kine_file = kine_files[i]; + LOG(info) << "Processing " << dir; + LOG(info) << "kine file " << kine_file; + // Files + auto fMCTracks = TFile::Open((TString(dir + "/") + kine_file)); + auto fStrangeTracks = TFile::Open((dir + "/o2_strange_tracks.root").data()); + auto fSecondaries = TFile::Open((dir + "/o2_secondary_vertex.root").data()); + auto fITSTPC = TFile::Open((dir + "/o2match_itstpc.root").data()); + auto fTPCTOF = TFile::Open((dir + "/o2match_tof_tpc.root").data()); + auto fTPCTRD = TFile::Open((dir + "/trdmatches_tpc.root").data()); + auto fITSTPCTOF = TFile::Open((dir + "/o2match_tof_itstpc.root").data()); + auto fITS = TFile::Open((dir + "/o2trac_its.root").data()); + auto fClusITS = TFile::Open((dir + "/o2clus_its.root").data()); + auto fTPC = TFile::Open((dir + "/tpctracks.root").data()); + + // Trees + auto treeMCTracks = (TTree *)fMCTracks->Get("o2sim"); + auto treeStrangeTracks = (TTree *)fStrangeTracks->Get("o2sim"); + auto treeSecondaries = (TTree *)fSecondaries->Get("o2sim"); + auto treeITSTPC = (TTree *)fITSTPC->Get("matchTPCITS"); + auto treeITSTPCTOF = (TTree *)fITSTPCTOF->Get("matchTOF"); + auto treeTPCTOF = (TTree *)fTPCTOF->Get("matchTOF"); + auto treeTPCTRD = (TTree *)fTPCTRD->Get("tracksTRD"); + + auto treeITS = (TTree *)fITS->Get("o2sim"); + auto treeITSclus = (TTree *)fClusITS->Get("o2sim"); + auto treeTPC = (TTree *)fTPC->Get("tpcrec"); + + // MC Tracks + std::vector *MCtracks = nullptr; + std::vector *ITSHits = nullptr; + + // Hypertracks + std::vector *strangeTrackVec = nullptr; + std::vector> *hypertrackVec = nullptr; + std::vector *nAttachments = nullptr; + + // Secondary Vertices + std::vector *cascVec = nullptr; + std::vector *v0Vec = nullptr; + + // ITS tracks + std::vector *ITStracks = nullptr; + + // Labels + std::vector *labITSvec = nullptr; + std::vector *labTPCvec = nullptr; + std::vector *labITSTPCvec = nullptr; + std::vector *labITSTPCTOFvec = nullptr; + std::vector *labTPCTOFvec = nullptr; + std::vector *labTPCTRDvec = nullptr; + + // Clusters + std::vector *ITSclus = nullptr; + o2::dataformats::MCTruthContainer *clusLabArr = nullptr; + std::vector *ITSTrackClusIdx = nullptr; + std::vector *ITSpatt = nullptr; + + // Setting branches + treeStrangeTracks->SetBranchAddress("StrangeTracks", &strangeTrackVec); + treeStrangeTracks->SetBranchAddress("ClusUpdates", &nAttachments); + + treeSecondaries->SetBranchAddress("Cascades", &cascVec); + treeSecondaries->SetBranchAddress("V0s", &v0Vec); + + treeMCTracks->SetBranchAddress("MCTrack", &MCtracks); + + treeITS->SetBranchAddress("ITSTrackMCTruth", &labITSvec); + treeITS->SetBranchAddress("ITSTrack", &ITStracks); + treeTPC->SetBranchAddress("TPCTracksMCTruth", &labTPCvec); + treeITSTPC->SetBranchAddress("MatchMCTruth", &labITSTPCvec); + treeTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labTPCTOFvec); + treeTPCTRD->SetBranchAddress("labels", &labTPCTRDvec); + + treeITSTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labITSTPCTOFvec); + + treeITS->SetBranchAddress("ITSTrackClusIdx", &ITSTrackClusIdx); + treeITSclus->SetBranchAddress("ITSClusterComp", &ITSclus); + treeITSclus->SetBranchAddress("ITSClusterMCTruth", &clusLabArr); + + // define detector map + std::map *> map{{"ITS", labITSvec}, {"TPC", labTPCvec}, {"ITS-TPC", labITSTPCvec}, {"TPC-TOF", labTPCTOFvec}, {"TPC-TRD", labTPCTRDvec}, {"ITS-TPC-TOF", labITSTPCTOFvec}}; + + // fill MC matrix + std::vector> mcTracksMatrix; + auto nev = treeMCTracks->GetEntriesFast(); + mcTracksMatrix.resize(nev); + for (int n = 0; n < nev; n++) + { // loop over MC events + treeMCTracks->GetEvent(n); + mcTracksMatrix[n].resize(MCtracks->size()); + for (unsigned int mcI{0}; mcI < MCtracks->size(); ++mcI) + { + mcTracksMatrix[n][mcI] = MCtracks->at(mcI); + if (abs(MCtracks->at(mcI).GetPdgCode()) == motherPDG) + { + auto &motherTrack = mcTracksMatrix[n][mcI]; + hGenXiCounter->Fill(1); + hGenXiMom->Fill(motherTrack.GetPt()); + hGenXiRadius->Fill(calcDecLength(MCtracks, motherTrack)); + } + } + } + + // Starting matching Cascades and ITS tracks + int counterV0 = 0; + for (int frame = 0; frame < treeITS->GetEntriesFast(); frame++) + { + if (!treeITS->GetEvent(frame) || !treeITS->GetEvent(frame) || !treeSecondaries->GetEvent(frame) || !treeITSTPC->GetEvent(frame) || !treeTPC->GetEvent(frame) || + !treeITSTPCTOF->GetEvent(frame) || !treeTPCTOF->GetEvent(frame) || !treeITSclus->GetEvent(frame) || !treeTPCTRD->GetEvent(frame) || !treeStrangeTracks->GetEvent(frame)) + continue; + + for (unsigned int iCascVec = 0; iCascVec < cascVec->size(); iCascVec++) + { + hCascCounter->Fill(1); + auto &casc = cascVec->at(iCascVec); + + hRecCascInvMass->Fill(sqrt(casc.calcMass2())); + + bool isV0reco = false; + auto cascMCref = matchCascToMC(mcTracksMatrix, map, v0Vec, casc, isV0reco); + + if (cascMCref[0] == -1 || cascMCref[1] == -1) + continue; + + hRecXiCounter->Fill(1); + hRecXiRad->Fill(sqrt(casc.calcR2())); + hRecXiMom->Fill(casc.getPt()); + auto &mcCasc = mcTracksMatrix[cascMCref[0]][cascMCref[1]]; + + // Matching ITS tracks to MC tracks and V0 + std::array ITSref = {-1, 1}; + o2::its::TrackITS ITStrack; + std::array, 7> clsRef; + + int iTrack = -1; + bool isMatched = false; + + for (unsigned int iITStrack = 0; iITStrack < ITStracks->size(); iITStrack++) + { + auto &labITS = (*labITSvec)[iITStrack]; + auto &trackIdx = (*ITSTrackClusIdx)[iITStrack]; + + ITSref = matchITStracktoMC(mcTracksMatrix, labITS); + ITStrack = (*ITStracks)[iITStrack]; + + if (ITSref[0] == cascMCref[0] && ITSref[1] == cascMCref[1]) + { + LOG(info) << "++++++++++++++++"; + LOG(info) << "Cascade + ITS track found! "; + LOG(info) << "CascV0: " << casc.getV0ID() << ", Bach ID: " << casc.getBachelorID() << ", ITS track ref: " << iITStrack; + LOG(info) << "Casc Momentum: " << casc.getPt() << ", ITS track momentum: " << ITStrack.getPt(); + LOG(info) << "Casc Cov Y: " << casc.getSigmaY2() << ", Cov Z: " << casc.getSigmaZ2(); + + auto &MCTrack = mcTracksMatrix[ITSref[0]][ITSref[1]]; + auto &MCTracks = mcTracksMatrix[ITSref[0]]; + auto MCrad = calcDecLength(&MCTracks, MCTrack); + LOG(info) << "Casc rad: " << casc.calcR2() << ", MC radius: " << MCrad; + hXiStats->Fill(1); + + auto firstClus = ITStrack.getFirstClusterEntry(); + auto ncl = ITStrack.getNumberOfClusters(); + + // check whether the corresponding strange track is found + bool isStrangeTrackFound = false; + for (unsigned int iStTr = 0; iStTr < strangeTrackVec->size(); iStTr++) + { + + auto &strangeTrack = strangeTrackVec->at(iStTr); + if (!(strangeTrack.mPartType == o2::strangeness_tracking::kCascade)) + { + continue; + } + + auto &itsRef = strangeTrack.mITSRef; + auto &cascRef = strangeTrack.mDecayRef; + if (itsRef == int(iITStrack) && cascRef == int(iCascVec)) + { + isStrangeTrackFound = true; + break; + } + } + + LOG(info) << "is Strange Track Found? " << isStrangeTrackFound; + + for (int icl = 0; icl < ncl; icl++) + { + auto &labCls = (clusLabArr->getLabels(ITSTrackClusIdx->at(firstClus + icl)))[0]; + auto &clus = (*ITSclus)[(*ITSTrackClusIdx)[firstClus + icl]]; + auto layer = gman->getLayer(clus.getSensorID()); + clsRef[layer] = matchCompLabelToMC(mcTracksMatrix, labCls); + if (clsRef[layer][0] > -1 && clsRef[layer][1] > -1) + { + auto &mcTrack = mcTracksMatrix[clsRef[layer][0]][clsRef[layer][1]]; + auto pdg = mcTrack.GetPdgCode(); + auto pdgMom1 = -1, pdgMom2 = -1; + if (!mcTrack.isPrimary()) + { + auto &mcTrackMom1 = mcTracksMatrix[clsRef[layer][0]][mcTrack.getMotherTrackId()]; + pdgMom1 = mcTrackMom1.GetPdgCode(); + if (!mcTrackMom1.isPrimary()) + { + pdgMom2 = mcTracksMatrix[clsRef[layer][0]][mcTrackMom1.getMotherTrackId()].GetPdgCode(); + } + } + LOG(info) << "Layer: " << layer << ", pdg " << pdg << ", pdgMom1 " << pdgMom1 << ", pdgMom2 " << pdgMom2 << ", refs: " << clsRef[layer][0] << ", " << clsRef[layer][1]; + } + else + LOG(info) << "Layer: " << layer << ", No valid cluster ref" + << ", isNoise: " << labCls.isNoise() << ", isFake: " << labCls.isFake(); + } + } + } + } + + LOG(info) << "+++++++++++++++++++++++++++++++++++++++++++++"; + + for (unsigned int iHyperVec = 0; iHyperVec < strangeTrackVec->size(); iHyperVec++) + { + + auto &strangeTrack = strangeTrackVec->at(iHyperVec); + if (!(strangeTrack.mPartType == o2::strangeness_tracking::kCascade)) + { + continue; + } + + auto &hyperChi2 = strangeTrack.mMatchChi2; + auto &clusAttachments = nAttachments->at(iHyperVec); + auto &ITStrack = ITStracks->at(strangeTrack.mITSRef); + auto &ITStrackLab = labITSvec->at(strangeTrack.mITSRef); + + auto clusAttArr = clusAttachments.arr; + auto &casc = cascVec->at(strangeTrack.mDecayRef); + auto &v0Casc = casc.getV0Track(); + auto &bach = casc.getBachelorTrack(); + + auto ITStrackRef = matchCompLabelToMC(mcTracksMatrix, ITStrackLab); + bool isV0reco = false; + auto cascMCref = matchCascToMC(mcTracksMatrix, map, v0Vec, casc, isV0reco); + + std::vector dauTracks = {v0Casc, bach}; + + hStrangeTrackInvMass->Fill(calcMass(dauTracks)); + + if (cascMCref[0] == -1 || cascMCref[1] == -1 || ITStrackRef[0] == -1 || ITStrackRef[1] == -1) + continue; + + if (ITStrackRef[0] == cascMCref[0] && ITStrackRef[1] == cascMCref[1]) + { + hXiStats->Fill(2); + hTrackedXiRad->Fill(sqrt(casc.calcR2())); + hTrackedXiMom->Fill(casc.getPt()); + + auto &mcTracks = mcTracksMatrix[cascMCref[0]]; + auto &mcTrack = mcTracksMatrix[cascMCref[0]][cascMCref[1]]; + hResCascR2->Fill((sqrt(casc.calcR2()) - calcDecLength(&mcTracks, mcTrack)) / calcDecLength(&mcTracks, mcTrack)); + + auto trackedR = sqrt(strangeTrack.decayVtx[0] * strangeTrack.decayVtx[0] + strangeTrack.decayVtx[1] * strangeTrack.decayVtx[1]); + hResCascTrackedR2->Fill((trackedR - calcDecLength(&mcTracks, mcTrack)) / calcDecLength(&mcTracks, mcTrack)); + } + else + { + hFakeAssocCounter->Fill(1); + } + } + } + } + + auto outFile = TFile("cascade_study.root", "recreate"); + + hResV0histo->Write(); + hHyperhisto->Write(); + hResHyperhisto->Write(); + hResCascR2->Write(); + hResCascTrackedR2->Write(); + + hGenXiCounter->Write(); + hCascCounter->Write(); + hXiStats->Write(); + hRecXiCounter->Write(); + hFakeAssocCounter->Write(); + hCascMomsInV0s->Write(); + hRecCascInvMass->Write(); + hStrangeTrackInvMass->Write(); + + + + TH1D *hMomEffFound = (TH1D *)hTrackedXiMom->Clone("efficiency_found_mom"); + hMomEffFound->Divide(hRecXiMom); + auto cv1 = TCanvas("found_efficiency_pt", "", 1000, 1000); + hMomEffFound->GetYaxis()->SetTitle("Tracked/Found"); + hMomEffFound->SetLineColor(kBlue); + hMomEffFound->Draw(); + cv1.Write(); + + TH1D *hRadEffFound = (TH1D *)hTrackedXiRad->Clone("efficiency_found_rad"); + hRadEffFound->Divide(hRecXiRad); + auto cv2 = TCanvas("found_efficiency_rad", "", 1000, 1000); + hRadEffFound->GetXaxis()->SetTitle("Radius (cm)"); + hRadEffFound->GetYaxis()->SetTitle("Tracked/Found"); + hRadEffFound->SetLineColor(kBlue); + hRadEffFound->Draw(); + cv2.Write(); + + + TH1D *hMomEffGen = (TH1D *)hTrackedXiMom->Clone("efficiency_gen_mom"); + hMomEffGen->Divide(hGenXiMom); + auto cv3 = TCanvas("gen_efficiency_pt", "", 1000, 1000); + hMomEffGen->GetYaxis()->SetTitle("Efficiency"); + hMomEffGen->SetLineColor(kBlue); + hMomEffGen->Draw(); + cv3.Write(); + + TH1D *hRadEffGen = (TH1D *)hTrackedXiRad->Clone("efficiency_gen_rad"); + hRadEffGen->Divide(hGenXiRadius); + auto cv4 = TCanvas("gen_efficiency_rad", "", 1000, 1000); + hRadEffGen->GetXaxis()->SetTitle("Radius (cm)"); + hRadEffGen->GetYaxis()->SetTitle("Efficiency"); + hRadEffGen->SetLineColor(kBlue); + hRadEffGen->Draw(); + cv4.Write(); + + auto cv5 = TCanvas("inv_mass_res_study", "", 1000, 1000); + hStrangeTrackInvMass->GetXaxis()->SetTitle("M(GeV/#it{c}^{2})"); + hStrangeTrackInvMass->GetYaxis()->SetTitle("Normalised Counts"); + hStrangeTrackInvMass->SetLineColor(kRed); + hStrangeTrackInvMass->SetLineWidth(2); + hRecCascInvMass->SetLineWidth(2); + hStrangeTrackInvMass->DrawNormalized(); + hRecCascInvMass->DrawNormalized("same"); + auto leg2 = new TLegend(0.5, 0.5, 0.8, 0.8); + leg2->AddEntry(hStrangeTrackInvMass, "After tracking"); + leg2->AddEntry(hRecCascInvMass, "Before tracking"); + leg2->Draw(); + cv5.Write(); + + hRecXiRad->Sumw2(); + hRecXiRad->Divide(hGenXiRadius); + auto cv6 = TCanvas("reco_efficiency_r", "", 1000, 1000); + hRecXiRad->GetXaxis()->SetTitle("Radius (cm)"); + hRecXiRad->GetYaxis()->SetTitle("Efficiency"); + hRecXiRad->SetLineColor(kBlue); + hRecXiRad->Draw(); + cv6.Write(); + + hRecXiMom->Sumw2(); + hRecXiMom->Divide(hGenXiMom); + auto cv7 = TCanvas("reco_efficiency_pt", "", 1000, 1000); + hRecXiMom->GetYaxis()->SetTitle("Efficiency"); + hRecXiMom->SetLineColor(kBlue); + hRecXiMom->Draw("pe"); + cv7.Write(); + + outFile.Close(); +} +std::array matchCascToMC(const std::vector> &mcTracksMatrix, std::map *> &map, std::vector *v0vec, Cascade &casc, bool &isV0reco) +{ + std::array motherVec{-1, -1}; + std::array, 2> v0DauRefs; + std::array bachRef; + + auto v0Idx = casc.getV0ID(); + auto &v0 = v0vec->at(v0Idx); + + auto bachID = casc.getBachelorID(); + if (!map[bachID.getSourceName()]) + return motherVec; + auto &bachLab = map[bachID.getSourceName()]->at(bachID.getIndex()); + if (bachLab.isValid()) + bachRef = {bachLab.getEventID(), bachLab.getTrackID()}; + else + return motherVec; + + for (unsigned int iV0 = 0; iV0 < 2; iV0++) + { + v0DauRefs[iV0] = {-1, -1}; + if (map[v0.getProngID(iV0).getSourceName()]) + { + auto labTrackType = map[v0.getProngID(iV0).getSourceName()]; + auto lab = labTrackType->at(v0.getProngID(iV0).getIndex()); + + int trackID, evID, srcID; + bool fake; + lab.get(trackID, evID, srcID, fake); + if (lab.isValid()) + { + v0DauRefs[iV0] = {lab.getEventID(), lab.getTrackID()}; + } + } + } + + if (v0DauRefs[0][1] == -1 || v0DauRefs[1][1] == -1) + return motherVec; + + auto &dau1MC = mcTracksMatrix[v0DauRefs[0][0]][v0DauRefs[0][1]]; + auto &dau2MC = mcTracksMatrix[v0DauRefs[1][0]][v0DauRefs[1][1]]; + + if (!(std::abs(dau1MC.GetPdgCode()) == firstV0dauPDG && std::abs(dau2MC.GetPdgCode()) == secondV0dauPDG) && !(std::abs(dau1MC.GetPdgCode()) == secondV0dauPDG && std::abs(dau2MC.GetPdgCode()) == firstV0dauPDG)) + return motherVec; + + if (!dau1MC.isSecondary() || !dau2MC.isSecondary() || dau1MC.getMotherTrackId() != dau2MC.getMotherTrackId()) + return motherVec; + + auto v0MC = mcTracksMatrix[v0DauRefs[0][0]][dau1MC.getMotherTrackId()]; + auto &bachMC = mcTracksMatrix[bachRef[0]][bachRef[1]]; + + if (v0MC.getMotherTrackId() >= 0) + { + + if (std::abs(mcTracksMatrix[v0DauRefs[0][0]][v0MC.getMotherTrackId()].GetPdgCode()) == motherPDG) + isV0reco = true; + } + + if (std::abs(v0MC.GetPdgCode()) != v0PDG || !v0MC.isSecondary() || !bachMC.isSecondary()) + return motherVec; + + auto cascMC = mcTracksMatrix[v0DauRefs[0][0]][v0MC.getMotherTrackId()]; + if (v0MC.getMotherTrackId() != bachMC.getMotherTrackId() || std::abs(cascMC.GetPdgCode()) != motherPDG) + return motherVec; + + motherVec = {v0DauRefs[0][0], v0MC.getMotherTrackId()}; + return motherVec; +} + +std::array checkV0mother(const std::vector> &mcTracksMatrix, std::map *> &map, V0 &v0) +{ + std::array motherVec{-1, -1}; + std::array, 2> v0DauRefs; + + for (unsigned int iV0 = 0; iV0 < 2; iV0++) + { + v0DauRefs[iV0] = {-1, -1}; + if (map[v0.getProngID(iV0).getSourceName()]) + { + auto labTrackType = map[v0.getProngID(iV0).getSourceName()]; + auto lab = labTrackType->at(v0.getProngID(iV0).getIndex()); + + int trackID, evID, srcID; + bool fake; + lab.get(trackID, evID, srcID, fake); + if (lab.isValid()) + { + v0DauRefs[iV0] = {lab.getEventID(), lab.getTrackID()}; + } + } + } + + if (v0DauRefs[0][1] == -1 || v0DauRefs[1][1] == -1) + return motherVec; + + auto &dau1MC = mcTracksMatrix[v0DauRefs[0][0]][v0DauRefs[0][1]]; + auto &dau2MC = mcTracksMatrix[v0DauRefs[1][0]][v0DauRefs[1][1]]; + + if (!(std::abs(dau1MC.GetPdgCode()) == firstV0dauPDG && std::abs(dau2MC.GetPdgCode()) == secondV0dauPDG) && !(std::abs(dau1MC.GetPdgCode()) == secondV0dauPDG && std::abs(dau2MC.GetPdgCode()) == firstV0dauPDG)) + return motherVec; + + if (!dau1MC.isSecondary() || !dau2MC.isSecondary() || dau1MC.getMotherTrackId() != dau2MC.getMotherTrackId()) + return motherVec; + + LOG(info) << "-----------------------------------------"; + LOG(info) << "V0 daughters: " << dau1MC.GetPdgCode() << " " << dau2MC.GetPdgCode(); + LOG(info) << " Dau refs: " << dau1MC.getMotherTrackId() << " " << dau2MC.getMotherTrackId(); + + auto v0MC = mcTracksMatrix[v0DauRefs[0][0]][dau1MC.getMotherTrackId()]; + LOG(info) << "V0 mother: " << v0MC.GetPdgCode() << ", Ref: " << v0MC.getMotherTrackId(); + + auto cascMC = mcTracksMatrix[v0DauRefs[0][0]][v0MC.getMotherTrackId()]; + if (std::abs(cascMC.GetPdgCode()) != motherPDG) + return motherVec; + + LOG(info) << "Casc from V0 PDG: " << mcTracksMatrix[v0DauRefs[0][0]][v0MC.getMotherTrackId()].GetPdgCode(); + + motherVec = {v0DauRefs[0][0], v0MC.getMotherTrackId()}; + return motherVec; +} diff --git a/Detectors/StrangenessTracking/macros/cascadeStudyUtils.h b/Detectors/StrangenessTracking/macros/cascadeStudyUtils.h new file mode 100644 index 0000000000000..6d528eb52cfce --- /dev/null +++ b/Detectors/StrangenessTracking/macros/cascadeStudyUtils.h @@ -0,0 +1,340 @@ + + +#if !defined(CLING) || defined(ROOTCLING) +#include "ITSMFTSimulation/Hit.h" +#include "SimulationDataFormat/MCCompLabel.h" +#include "SimulationDataFormat/MCTrack.h" +#include "SimulationDataFormat/MCTruthContainer.h" + +#include "DataFormatsITS/TrackITS.h" +#include "DataFormatsITSMFT/CompCluster.h" +#include "DataFormatsITSMFT/ROFRecord.h" +#include "DataFormatsITSMFT/TopologyDictionary.h" +#include "DetectorsCommonDataFormats/DetectorNameConf.h" +#include "ITSBase/GeometryTGeo.h" +#include "ITStracking/IOUtils.h" +#include "ReconstructionDataFormats/TrackTPCITS.h" + +#include "CommonDataFormat/RangeReference.h" +#include "DetectorsVertexing/DCAFitterN.h" +#include "TCanvas.h" +#include "TFile.h" +#include "TH1F.h" +#include "TH2D.h" +#include "TLegend.h" +#include "TMath.h" +#include "TString.h" +#include "TSystemDirectory.h" +#include "TTree.h" +#include +#include + +#endif + +using MCTrack = o2::MCTrack; +using CompClusterExt = o2::itsmft::CompClusterExt; +using ITSCluster = o2::BaseCluster; + +const int motherPDG = 3312; +const int v0PDG = 3122; +const int bachPDG = 211; +const int firstV0dauPDG = 2212; +const int secondV0dauPDG = 211; + +enum kClType +{ + kFree, + kTracked, + kFake +}; + +enum kDauType +{ + kPr, + kPi, + kBach +}; + +const float XiMass = 1.32171; +const int kDauPdgs[3] = {2212, 211, 211}; +const float kDauMasses[3] = {0.938272, 0.13957, 0.13957}; +const float kFirstDauMasses[2] = {1.115683, 0.13957}; + +double calcLifetime(std::vector *MCTracks, const MCTrack &motherTrack, + int dauPDG); + +double calcDecLength(std::vector *MCTracks, const MCTrack &motherTrack); +double calcDecLengthV0(std::vector *MCTracks, + const MCTrack &motherTrack, int dauPDG); +std::array +matchCascDauToMC(const std::vector> &mcTracksMatrix, + o2::MCCompLabel &lab, int dauPDG); +std::array +matchBachToMC(const std::vector> &mcTracksMatrix, + o2::MCCompLabel &lab); +std::array +matchCompLabelToMC(const std::vector> &mcTracksMatrix, + o2::MCCompLabel compLabel); +int checkCascRef(std::array cascRef1, std::array cascRef2, + std::array cascRef3, std::array &cascRef); +std::vector +getTrackClusters(const o2::its::TrackITS &ITStrack, + const std::vector &ITSClustersArray, + std::vector *ITSTrackClusIdx); +std::array +matchITStracktoMC(const std::vector> &mcTracksMatrix, + o2::MCCompLabel ITSlabel); +double calcMass(std::vector tracks); + +std::array +matchCascDauToMC(const std::vector> &mcTracksMatrix, + o2::MCCompLabel &lab, int dauPDG) +{ + std::array outArray{-1, -1}; + + int trackID, evID, srcID; + bool fake; + lab.get(trackID, evID, srcID, fake); + if (lab.isValid()) + { + auto motherID = mcTracksMatrix[evID][trackID].getMotherTrackId(); + if (motherID >= 0 && + std::abs(mcTracksMatrix[evID][trackID].GetPdgCode()) == dauPDG) + { + auto v0MomPDG = mcTracksMatrix[evID][motherID].GetPdgCode(); + auto v0MomID = mcTracksMatrix[evID][motherID].getMotherTrackId(); + if (std::abs(v0MomPDG) == v0PDG && v0MomID >= 0) + { + auto cascPDG = mcTracksMatrix[evID][v0MomID].GetPdgCode(); + if (std::abs(cascPDG) == motherPDG) + { + outArray[0] = evID; + outArray[1] = v0MomID; + } + } + } + } + + return outArray; +} + +std::array +matchBachToMC(const std::vector> &mcTracksMatrix, + o2::MCCompLabel &lab) +{ + std::array outArray{-1, -1}; + + int trackID, evID, srcID; + bool fake; + lab.get(trackID, evID, srcID, fake); + if (lab.isValid()) + { + auto motherID = mcTracksMatrix[evID][trackID].getMotherTrackId(); + if (motherID >= 0) + { + auto cascPDG = mcTracksMatrix[evID][motherID].GetPdgCode(); + if (std::abs(cascPDG) == motherPDG) + { + outArray[0] = evID; + outArray[1] = motherID; + } + } + } + + return outArray; +} + +double calcDecLength(std::vector *MCTracks, const MCTrack &motherTrack) +{ + auto idStart = motherTrack.getFirstDaughterTrackId(); + auto idStop = motherTrack.getLastDaughterTrackId(); + + if (idStart == -1 || idStop == -1) + return -1; + for (auto iD{idStart}; iD <= idStop; ++iD) + { + auto dauTrack = MCTracks->at(iD); + if (std::abs(dauTrack.GetPdgCode()) == v0PDG) + { + auto decLength = (dauTrack.GetStartVertexCoordinatesX() - + motherTrack.GetStartVertexCoordinatesX()) * + (dauTrack.GetStartVertexCoordinatesX() - + motherTrack.GetStartVertexCoordinatesX()) + + (dauTrack.GetStartVertexCoordinatesY() - + motherTrack.GetStartVertexCoordinatesY()) * + (dauTrack.GetStartVertexCoordinatesY() - + motherTrack.GetStartVertexCoordinatesY()); + return sqrt(decLength); + } + } + return -1; +} + +double calcLifetime(std::vector *MCTracks, const MCTrack &motherTrack, + int dauPDG) +{ + auto idStart = motherTrack.getFirstDaughterTrackId(); + auto idStop = motherTrack.getLastDaughterTrackId(); + + if (idStart == -1 || idStop == -1) + return -1; + for (auto iD{idStart}; iD <= idStop; ++iD) + { + auto dauTrack = MCTracks->at(iD); + if (std::abs(dauTrack.GetPdgCode()) == dauPDG) + { + auto decLength = (dauTrack.GetStartVertexCoordinatesX() - + motherTrack.GetStartVertexCoordinatesX()) * + (dauTrack.GetStartVertexCoordinatesX() - + motherTrack.GetStartVertexCoordinatesX()) + + (dauTrack.GetStartVertexCoordinatesY() - + motherTrack.GetStartVertexCoordinatesY()) * + (dauTrack.GetStartVertexCoordinatesY() - + motherTrack.GetStartVertexCoordinatesY()) + + (dauTrack.GetStartVertexCoordinatesZ() - + motherTrack.GetStartVertexCoordinatesZ()) * + (dauTrack.GetStartVertexCoordinatesZ() - + motherTrack.GetStartVertexCoordinatesZ()); + return sqrt(decLength)*XiMass/motherTrack.GetP(); + } + } + return -1; +} + +double calcDecLengthV0(std::vector *MCTracks, + const MCTrack &motherTrack, int dauPDG) +{ + auto idStart = motherTrack.getFirstDaughterTrackId(); + auto idStop = motherTrack.getLastDaughterTrackId(); + // LOG(info) << "idStart: " << idStart << " idStop: " << idStop; + + if (idStart == -1 || idStop == -1) + return -1; + for (auto iD{idStart}; iD <= idStop; iD++) + { + auto &v0Track = MCTracks->at(iD); + + auto jdStart = v0Track.getFirstDaughterTrackId(); + auto jdStop = v0Track.getLastDaughterTrackId(); + + // LOG(info) << "jdStart: " << jdStart << " jdStop: " << jdStop; + if (std::abs(v0Track.GetPdgCode()) == v0PDG) + { + // LOG(info) << "jdStart: " << jdStart << " jdStop: " << jdStop; + if (jdStart == -1 || jdStop == -1) + return -1; + + for (auto jD{jdStart}; jD <= jdStop; jD++) + { + auto dauTrack = MCTracks->at(jD); + if (std::abs(dauTrack.GetPdgCode()) == dauPDG) + { + // LOG(info) << "DauX: " << dauTrack.GetStartVertexCoordinatesX() << + // ", dauY: " < +matchCompLabelToMC(const std::vector> &mcTracksMatrix, + o2::MCCompLabel compLabel) +{ + std::array compRef = {-1, -1}; + int trackID, evID, srcID; + bool fake; + compLabel.get(trackID, evID, srcID, fake); + if (compLabel.isValid()) + { + compRef = {evID, trackID}; + } + return compRef; +} + +int checkCascRef(std::array cascRef1, std::array cascRef2, + std::array cascRef3, std::array &cascRef) +{ + + if (cascRef1[0] != -1 && cascRef1[1] != -1) + { + cascRef = cascRef1; + return kPr; + } + else if (cascRef2[0] != -1 && cascRef2[1] != -1) + { + cascRef = cascRef2; + return kPi; + } + else if (cascRef3[0] != -1 && cascRef3[1] != -1) + { + cascRef = cascRef3; + return kBach; + } + else + { + return -1; + } +} + +std::array +matchITStracktoMC(const std::vector> &mcTracksMatrix, + o2::MCCompLabel ITSlabel) + +{ + std::array outArray = {-1, -1}; + int trackID, evID, srcID; + bool fake; + ITSlabel.get(trackID, evID, srcID, fake); + if (ITSlabel.isValid() && + std::abs(mcTracksMatrix[evID][trackID].GetPdgCode()) == motherPDG) + { + outArray = {evID, trackID}; + } + + return outArray; +} + +std::vector +getTrackClusters(const o2::its::TrackITS &ITStrack, + const std::vector &ITSClustersArray, + std::vector *ITSTrackClusIdx) +{ + + std::vector outVec; + auto firstClus = ITStrack.getFirstClusterEntry(); + auto ncl = ITStrack.getNumberOfClusters(); + for (int icl = 0; icl < ncl; icl++) + { + outVec.push_back(ITSClustersArray[(*ITSTrackClusIdx)[firstClus + icl]]); + } + return outVec; +} + +double calcMass(std::vector tracks) +{ + TLorentzVector moth, prong; + std::array p; + for (unsigned int i = 0; i < tracks.size(); i++) + { + auto &track = tracks[i]; + auto mass = tracks.size() == 2 ? kFirstDauMasses[i] : kDauMasses[i]; + track.getPxPyPzGlo(p); + prong.SetVectM({p[0], p[1], p[2]}, mass); + moth += prong; + } + return moth.M(); +} \ No newline at end of file From 1b27f82662b4a36f746e61ebb4e8ec44264a6ac3 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Mon, 5 Dec 2022 17:42:31 +0100 Subject: [PATCH 30/36] Clang format + remove utils --- .../macros/XiTrackingStudy.C | 1025 +++++++++-------- .../macros/cascadeStudyUtils.h | 340 ------ .../StrangenessTracking/StrangenessTracker.h | 1 - .../tracking/src/StrangenessTracker.cxx | 2 +- .../workflow/src/StrangenessTrackingSpec.cxx | 2 +- .../src/StrangenessTrackingWriterSpec.cxx | 2 +- .../src/strangeness-tracking-workflow.cxx | 1 - 7 files changed, 538 insertions(+), 835 deletions(-) delete mode 100644 Detectors/StrangenessTracking/macros/cascadeStudyUtils.h diff --git a/Detectors/StrangenessTracking/macros/XiTrackingStudy.C b/Detectors/StrangenessTracking/macros/XiTrackingStudy.C index 31fbeed09e3aa..e1886a33b315b 100644 --- a/Detectors/StrangenessTracking/macros/XiTrackingStudy.C +++ b/Detectors/StrangenessTracking/macros/XiTrackingStudy.C @@ -28,7 +28,6 @@ #include "CommonDataFormat/RangeReference.h" #include "DetectorsVertexing/DCAFitterN.h" #include "StrangenessTracking/StrangenessTracker.h" -#include "cascadeStudyUtils.h" #endif @@ -44,544 +43,590 @@ using ITSCluster = o2::BaseCluster; using Vec3 = ROOT::Math::SVector; using StrangeTrack = o2::strangeness_tracking::StrangeTrack; -std::array matchCascToMC(const std::vector> &mcTracksMatrix, std::map *> &map, std::vector *v0vec, Cascade &casc, bool &isV0reco); -std::array checkV0mother(const std::vector> &mcTracksMatrix, std::map *> &map, V0 &v0); +const int motherPDG = 3312; +const int v0PDG = 3122; +const int bachPDG = 211; +const int firstV0dauPDG = 2212; +const int secondV0dauPDG = 211; + +const float XiMass = 1.32171; +const int kDauPdgs[3] = {2212, 211, 211}; +const float kDauMasses[3] = {0.938272, 0.13957, 0.13957}; +const float kFirstDauMasses[2] = {1.115683, 0.13957}; + +std::array matchCascToMC(const std::vector>& mcTracksMatrix, std::map*>& map, std::vector* v0vec, Cascade& casc, bool& isV0reco); +std::array checkV0mother(const std::vector>& mcTracksMatrix, std::map*>& map, V0& v0); +double calcDecLength(std::vector* MCTracks, const MCTrack& motherTrack); +std::array matchITStracktoMC(const std::vector>& mcTracksMatrix, o2::MCCompLabel ITSlabel); +double calcMass(std::vector tracks); +std::array matchCompLabelToMC(const std::vector>& mcTracksMatrix, o2::MCCompLabel compLabel); void XiTrackingStudy(std::string path) { - TSystemDirectory dir("MyDir", path.data()); - auto files = dir.GetListOfFiles(); - std::vector dirs; - std::vector kine_files; - - for (auto fileObj : *files) - { - std::string file = ((TSystemFile *)fileObj)->GetName(); - if (file.substr(0, 2) == "tf") - { - dirs.push_back(path + file); - auto innerdir = (TSystemDirectory *)fileObj; - auto innerfiles = innerdir->GetListOfFiles(); - for (auto innerfileObj : *innerfiles) - { - TString innerfile = ((TSystemFile *)innerfileObj)->GetName(); - if (innerfile.EndsWith("Kine.root") && innerfile.Contains("sgn")) - { - kine_files.push_back(innerfile); - } - } + TSystemDirectory dir("MyDir", path.data()); + auto files = dir.GetListOfFiles(); + std::vector dirs; + std::vector kine_files; + + for (auto fileObj : *files) { + std::string file = ((TSystemFile*)fileObj)->GetName(); + if (file.substr(0, 2) == "tf") { + dirs.push_back(path + "/" + file); + auto innerdir = (TSystemDirectory*)fileObj; + auto innerfiles = innerdir->GetListOfFiles(); + for (auto innerfileObj : *innerfiles) { + TString innerfile = ((TSystemFile*)innerfileObj)->GetName(); + if (innerfile.EndsWith("Kine.root") && innerfile.Contains("sgn")) { + kine_files.push_back(innerfile); } + } } - - TH2D *hHyperhisto = new TH2D("histo hyperV0", ";#it{p}_{T} (GeV/#it{c}); Radius^2 (cm) ; Counts", 20, 1, 10, 30, 1, 900); - TH1D *hResV0histo = new TH1D("pT resolution before hypertracking", ";(#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, -0.2, 0.2); - TH1D *hResHyperhisto = new TH1D("pT resolution after hypertracking", ";(#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, -0.2, 0.2); - TH1D *hResCascR2 = new TH1D("R2 resolution before tracking", ";(R2^{gen} - R2^{rec})/R2^{gen}; Counts", 200, -0.1, 0.1); - TH1D *hResCascTrackedR2 = new TH1D("R2 resolution after tracking", ";(R2^{gen} - R2^{rec})/R2^{gen}; Counts", 200, -0.1, 0.1); - - TH1D *hCascCounter = new TH1D("Casc counter", ";Casc counter; Counts", 1, 0.5, 1.5); - TH1D *hGenXiCounter = new TH1D("Gen Casc counter", ";Casc counter; Counts", 1, 0.5, 1.5); - - - TH1D *hFakeAssocCounter = new TH1D("Fake assoc counter", ";Fake assoc counter; Counts", 1, 0.5, 1.5); - - TH1D *hRecXiCounter = new TH1D("Rec Xi counter", "; ; Counts", 1, 0.5, 1.5); - TH1D *hCascMomsInV0s = new TH1D("Rec V0s from Xi counter", "; ; Counts", 1, 0.5, 1.5); - TH1D *hFindableBachfromXiCounter = new TH1D("Rec bachelors from Xi counter", "; ; Counts", 1, 0.5, 1.5); - - TH1D *hRecCascInvMass = new TH1D("Rec Casc InvMass", "; M (GeV/c^{2}); Counts", 150, 1.2, 1.5); - TH1D *hStrangeTrackInvMass = new TH1D("Strange track inv mass", ";M (GeV/c^{2}); Counts", 150, 1.2, 1.5); - TH1D *hXiStats = new TH1D("cascade_stats", "; ; Counts", 3, 0.5, 3.5); - - TH1D *hGenXiRadius = new TH1D("gen_casc_r", "; Radius (cm); Counts", 40, 0., 40.); - TH1D *hRecXiRad = new TH1D("rec_casc_r", ";Radius_{trackable} (cm); Counts", 40, 0, 40); - TH1D *hTrackedXiRad = new TH1D("r_dist_aft_track", ";R2^{rec} (cm); Counts", 40, 0, 40); - - TH1D *hGenXiMom = new TH1D("gen_casc_pt", "; #it{p}_{T}^{gen} (GeV/#it{c}); Counts", 40, 1, 6); - TH1D *hRecXiMom = new TH1D("rec_casc_pt", "; #it{p}_{T}^{gen} (GeV/#it{c}); Counts", 40, 1, 6); - TH1D *hTrackedXiMom = new TH1D("pT_dist_aft_track", ";#it{p}_{T}^{rec} (GeV/#it{c}); Counts", 40, 1, 6); - - // Geometry - o2::base::GeometryManager::loadGeometry(dirs[0] + "/o2sim_geometry.root"); - auto gman = o2::its::GeometryTGeo::Instance(); - gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G)); - - int counter = 0; - for (unsigned int i = 0; i < dirs.size(); i++) - { - auto &dir = dirs[i]; - auto &kine_file = kine_files[i]; - LOG(info) << "Processing " << dir; - LOG(info) << "kine file " << kine_file; - // Files - auto fMCTracks = TFile::Open((TString(dir + "/") + kine_file)); - auto fStrangeTracks = TFile::Open((dir + "/o2_strange_tracks.root").data()); - auto fSecondaries = TFile::Open((dir + "/o2_secondary_vertex.root").data()); - auto fITSTPC = TFile::Open((dir + "/o2match_itstpc.root").data()); - auto fTPCTOF = TFile::Open((dir + "/o2match_tof_tpc.root").data()); - auto fTPCTRD = TFile::Open((dir + "/trdmatches_tpc.root").data()); - auto fITSTPCTOF = TFile::Open((dir + "/o2match_tof_itstpc.root").data()); - auto fITS = TFile::Open((dir + "/o2trac_its.root").data()); - auto fClusITS = TFile::Open((dir + "/o2clus_its.root").data()); - auto fTPC = TFile::Open((dir + "/tpctracks.root").data()); - - // Trees - auto treeMCTracks = (TTree *)fMCTracks->Get("o2sim"); - auto treeStrangeTracks = (TTree *)fStrangeTracks->Get("o2sim"); - auto treeSecondaries = (TTree *)fSecondaries->Get("o2sim"); - auto treeITSTPC = (TTree *)fITSTPC->Get("matchTPCITS"); - auto treeITSTPCTOF = (TTree *)fITSTPCTOF->Get("matchTOF"); - auto treeTPCTOF = (TTree *)fTPCTOF->Get("matchTOF"); - auto treeTPCTRD = (TTree *)fTPCTRD->Get("tracksTRD"); - - auto treeITS = (TTree *)fITS->Get("o2sim"); - auto treeITSclus = (TTree *)fClusITS->Get("o2sim"); - auto treeTPC = (TTree *)fTPC->Get("tpcrec"); - - // MC Tracks - std::vector *MCtracks = nullptr; - std::vector *ITSHits = nullptr; - - // Hypertracks - std::vector *strangeTrackVec = nullptr; - std::vector> *hypertrackVec = nullptr; - std::vector *nAttachments = nullptr; - - // Secondary Vertices - std::vector *cascVec = nullptr; - std::vector *v0Vec = nullptr; - - // ITS tracks - std::vector *ITStracks = nullptr; - - // Labels - std::vector *labITSvec = nullptr; - std::vector *labTPCvec = nullptr; - std::vector *labITSTPCvec = nullptr; - std::vector *labITSTPCTOFvec = nullptr; - std::vector *labTPCTOFvec = nullptr; - std::vector *labTPCTRDvec = nullptr; - - // Clusters - std::vector *ITSclus = nullptr; - o2::dataformats::MCTruthContainer *clusLabArr = nullptr; - std::vector *ITSTrackClusIdx = nullptr; - std::vector *ITSpatt = nullptr; - - // Setting branches - treeStrangeTracks->SetBranchAddress("StrangeTracks", &strangeTrackVec); - treeStrangeTracks->SetBranchAddress("ClusUpdates", &nAttachments); - - treeSecondaries->SetBranchAddress("Cascades", &cascVec); - treeSecondaries->SetBranchAddress("V0s", &v0Vec); - - treeMCTracks->SetBranchAddress("MCTrack", &MCtracks); - - treeITS->SetBranchAddress("ITSTrackMCTruth", &labITSvec); - treeITS->SetBranchAddress("ITSTrack", &ITStracks); - treeTPC->SetBranchAddress("TPCTracksMCTruth", &labTPCvec); - treeITSTPC->SetBranchAddress("MatchMCTruth", &labITSTPCvec); - treeTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labTPCTOFvec); - treeTPCTRD->SetBranchAddress("labels", &labTPCTRDvec); - - treeITSTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labITSTPCTOFvec); - - treeITS->SetBranchAddress("ITSTrackClusIdx", &ITSTrackClusIdx); - treeITSclus->SetBranchAddress("ITSClusterComp", &ITSclus); - treeITSclus->SetBranchAddress("ITSClusterMCTruth", &clusLabArr); - - // define detector map - std::map *> map{{"ITS", labITSvec}, {"TPC", labTPCvec}, {"ITS-TPC", labITSTPCvec}, {"TPC-TOF", labTPCTOFvec}, {"TPC-TRD", labTPCTRDvec}, {"ITS-TPC-TOF", labITSTPCTOFvec}}; - - // fill MC matrix - std::vector> mcTracksMatrix; - auto nev = treeMCTracks->GetEntriesFast(); - mcTracksMatrix.resize(nev); - for (int n = 0; n < nev; n++) - { // loop over MC events - treeMCTracks->GetEvent(n); - mcTracksMatrix[n].resize(MCtracks->size()); - for (unsigned int mcI{0}; mcI < MCtracks->size(); ++mcI) - { - mcTracksMatrix[n][mcI] = MCtracks->at(mcI); - if (abs(MCtracks->at(mcI).GetPdgCode()) == motherPDG) - { - auto &motherTrack = mcTracksMatrix[n][mcI]; - hGenXiCounter->Fill(1); - hGenXiMom->Fill(motherTrack.GetPt()); - hGenXiRadius->Fill(calcDecLength(MCtracks, motherTrack)); - } - } + } + + + TH2D* hHyperhisto = new TH2D("histo hyperV0", ";#it{p}_{T} (GeV/#it{c}); Radius^2 (cm) ; Counts", 20, 1, 10, 30, 1, 900); + TH1D* hResV0histo = new TH1D("pT resolution before hypertracking", ";(#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, -0.2, 0.2); + TH1D* hResHyperhisto = new TH1D("pT resolution after hypertracking", ";(#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, -0.2, 0.2); + TH1D* hResCascR2 = new TH1D("R2 resolution before tracking", ";(R2^{gen} - R2^{rec})/R2^{gen}; Counts", 200, -0.1, 0.1); + TH1D* hResCascTrackedR2 = new TH1D("R2 resolution after tracking", ";(R2^{gen} - R2^{rec})/R2^{gen}; Counts", 200, -0.1, 0.1); + + TH1D* hCascCounter = new TH1D("Casc counter", ";Casc counter; Counts", 1, 0.5, 1.5); + TH1D* hGenXiCounter = new TH1D("Gen Casc counter", ";Casc counter; Counts", 1, 0.5, 1.5); + + TH1D* hFakeAssocCounter = new TH1D("Fake assoc counter", ";Fake assoc counter; Counts", 1, 0.5, 1.5); + + TH1D* hRecXiCounter = new TH1D("Rec Xi counter", "; ; Counts", 1, 0.5, 1.5); + TH1D* hCascMomsInV0s = new TH1D("Rec V0s from Xi counter", "; ; Counts", 1, 0.5, 1.5); + TH1D* hFindableBachfromXiCounter = new TH1D("Rec bachelors from Xi counter", "; ; Counts", 1, 0.5, 1.5); + + TH1D* hRecCascInvMass = new TH1D("Rec Casc InvMass", "; M (GeV/c^{2}); Counts", 150, 1.2, 1.5); + TH1D* hStrangeTrackInvMass = new TH1D("Strange track inv mass", ";M (GeV/c^{2}); Counts", 150, 1.2, 1.5); + TH1D* hXiStats = new TH1D("cascade_stats", "; ; Counts", 3, 0.5, 3.5); + + TH1D* hGenXiRadius = new TH1D("gen_casc_r", "; Radius (cm); Counts", 40, 0., 40.); + TH1D* hRecXiRad = new TH1D("rec_casc_r", ";Radius_{trackable} (cm); Counts", 40, 0, 40); + TH1D* hTrackedXiRad = new TH1D("r_dist_aft_track", ";R2^{rec} (cm); Counts", 40, 0, 40); + + TH1D* hGenXiMom = new TH1D("gen_casc_pt", "; #it{p}_{T}^{gen} (GeV/#it{c}); Counts", 40, 1, 6); + TH1D* hRecXiMom = new TH1D("rec_casc_pt", "; #it{p}_{T}^{gen} (GeV/#it{c}); Counts", 40, 1, 6); + TH1D* hTrackedXiMom = new TH1D("pT_dist_aft_track", ";#it{p}_{T}^{rec} (GeV/#it{c}); Counts", 40, 1, 6); + + // Geometry + o2::base::GeometryManager::loadGeometry(dirs[0] + "/o2sim_geometry.root"); + auto gman = o2::its::GeometryTGeo::Instance(); + gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G)); + + int counter = 0; + for (unsigned int i = 0; i < dirs.size(); i++) { + auto& dir = dirs[i]; + auto& kine_file = kine_files[i]; + LOG(info) << "Processing " << dir; + LOG(info) << "kine file " << kine_file; + // Files + auto fMCTracks = TFile::Open((TString(dir + "/") + kine_file)); + auto fStrangeTracks = TFile::Open((dir + "/o2_strange_tracks.root").data()); + auto fSecondaries = TFile::Open((dir + "/o2_secondary_vertex.root").data()); + auto fITSTPC = TFile::Open((dir + "/o2match_itstpc.root").data()); + auto fTPCTOF = TFile::Open((dir + "/o2match_tof_tpc.root").data()); + auto fTPCTRD = TFile::Open((dir + "/trdmatches_tpc.root").data()); + auto fITSTPCTOF = TFile::Open((dir + "/o2match_tof_itstpc.root").data()); + auto fITS = TFile::Open((dir + "/o2trac_its.root").data()); + auto fClusITS = TFile::Open((dir + "/o2clus_its.root").data()); + auto fTPC = TFile::Open((dir + "/tpctracks.root").data()); + + // Trees + auto treeMCTracks = (TTree*)fMCTracks->Get("o2sim"); + auto treeStrangeTracks = (TTree*)fStrangeTracks->Get("o2sim"); + auto treeSecondaries = (TTree*)fSecondaries->Get("o2sim"); + auto treeITSTPC = (TTree*)fITSTPC->Get("matchTPCITS"); + auto treeITSTPCTOF = (TTree*)fITSTPCTOF->Get("matchTOF"); + auto treeTPCTOF = (TTree*)fTPCTOF->Get("matchTOF"); + auto treeTPCTRD = (TTree*)fTPCTRD->Get("tracksTRD"); + + auto treeITS = (TTree*)fITS->Get("o2sim"); + auto treeITSclus = (TTree*)fClusITS->Get("o2sim"); + auto treeTPC = (TTree*)fTPC->Get("tpcrec"); + + // MC Tracks + std::vector* MCtracks = nullptr; + std::vector* ITSHits = nullptr; + + // Hypertracks + std::vector* strangeTrackVec = nullptr; + std::vector>* hypertrackVec = nullptr; + std::vector* nAttachments = nullptr; + + // Secondary Vertices + std::vector* cascVec = nullptr; + std::vector* v0Vec = nullptr; + + // ITS tracks + std::vector* ITStracks = nullptr; + + // Labels + std::vector* labITSvec = nullptr; + std::vector* labTPCvec = nullptr; + std::vector* labITSTPCvec = nullptr; + std::vector* labITSTPCTOFvec = nullptr; + std::vector* labTPCTOFvec = nullptr; + std::vector* labTPCTRDvec = nullptr; + + // Clusters + std::vector* ITSclus = nullptr; + o2::dataformats::MCTruthContainer* clusLabArr = nullptr; + std::vector* ITSTrackClusIdx = nullptr; + std::vector* ITSpatt = nullptr; + + // Setting branches + treeStrangeTracks->SetBranchAddress("StrangeTracks", &strangeTrackVec); + treeStrangeTracks->SetBranchAddress("ClusUpdates", &nAttachments); + + treeSecondaries->SetBranchAddress("Cascades", &cascVec); + treeSecondaries->SetBranchAddress("V0s", &v0Vec); + + treeMCTracks->SetBranchAddress("MCTrack", &MCtracks); + + treeITS->SetBranchAddress("ITSTrackMCTruth", &labITSvec); + treeITS->SetBranchAddress("ITSTrack", &ITStracks); + treeTPC->SetBranchAddress("TPCTracksMCTruth", &labTPCvec); + treeITSTPC->SetBranchAddress("MatchMCTruth", &labITSTPCvec); + treeTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labTPCTOFvec); + treeTPCTRD->SetBranchAddress("labels", &labTPCTRDvec); + + treeITSTPCTOF->SetBranchAddress("MatchTOFMCTruth", &labITSTPCTOFvec); + + treeITS->SetBranchAddress("ITSTrackClusIdx", &ITSTrackClusIdx); + treeITSclus->SetBranchAddress("ITSClusterComp", &ITSclus); + treeITSclus->SetBranchAddress("ITSClusterMCTruth", &clusLabArr); + + // define detector map + std::map*> map{{"ITS", labITSvec}, {"TPC", labTPCvec}, {"ITS-TPC", labITSTPCvec}, {"TPC-TOF", labTPCTOFvec}, {"TPC-TRD", labTPCTRDvec}, {"ITS-TPC-TOF", labITSTPCTOFvec}}; + + // fill MC matrix + std::vector> mcTracksMatrix; + auto nev = treeMCTracks->GetEntriesFast(); + mcTracksMatrix.resize(nev); + for (int n = 0; n < nev; n++) { // loop over MC events + treeMCTracks->GetEvent(n); + mcTracksMatrix[n].resize(MCtracks->size()); + for (unsigned int mcI{0}; mcI < MCtracks->size(); ++mcI) { + mcTracksMatrix[n][mcI] = MCtracks->at(mcI); + if (abs(MCtracks->at(mcI).GetPdgCode()) == motherPDG) { + auto& motherTrack = mcTracksMatrix[n][mcI]; + hGenXiCounter->Fill(1); + hGenXiMom->Fill(motherTrack.GetPt()); + hGenXiRadius->Fill(calcDecLength(MCtracks, motherTrack)); } + } + } + + // Starting matching Cascades and ITS tracks + int counterV0 = 0; + for (int frame = 0; frame < treeITS->GetEntriesFast(); frame++) { + if (!treeITS->GetEvent(frame) || !treeITS->GetEvent(frame) || !treeSecondaries->GetEvent(frame) || !treeITSTPC->GetEvent(frame) || !treeTPC->GetEvent(frame) || + !treeITSTPCTOF->GetEvent(frame) || !treeTPCTOF->GetEvent(frame) || !treeITSclus->GetEvent(frame) || !treeTPCTRD->GetEvent(frame) || !treeStrangeTracks->GetEvent(frame)) + continue; + + for (unsigned int iCascVec = 0; iCascVec < cascVec->size(); iCascVec++) { + hCascCounter->Fill(1); + auto& casc = cascVec->at(iCascVec); + + hRecCascInvMass->Fill(sqrt(casc.calcMass2())); + + bool isV0reco = false; + auto cascMCref = matchCascToMC(mcTracksMatrix, map, v0Vec, casc, isV0reco); + + if (cascMCref[0] == -1 || cascMCref[1] == -1) + continue; + + hRecXiCounter->Fill(1); + hRecXiRad->Fill(sqrt(casc.calcR2())); + hRecXiMom->Fill(casc.getPt()); + auto& mcCasc = mcTracksMatrix[cascMCref[0]][cascMCref[1]]; + + // Matching ITS tracks to MC tracks and V0 + std::array ITSref = {-1, 1}; + o2::its::TrackITS ITStrack; + std::array, 7> clsRef; + + int iTrack = -1; + bool isMatched = false; - // Starting matching Cascades and ITS tracks - int counterV0 = 0; - for (int frame = 0; frame < treeITS->GetEntriesFast(); frame++) - { - if (!treeITS->GetEvent(frame) || !treeITS->GetEvent(frame) || !treeSecondaries->GetEvent(frame) || !treeITSTPC->GetEvent(frame) || !treeTPC->GetEvent(frame) || - !treeITSTPCTOF->GetEvent(frame) || !treeTPCTOF->GetEvent(frame) || !treeITSclus->GetEvent(frame) || !treeTPCTRD->GetEvent(frame) || !treeStrangeTracks->GetEvent(frame)) + for (unsigned int iITStrack = 0; iITStrack < ITStracks->size(); iITStrack++) { + auto& labITS = (*labITSvec)[iITStrack]; + auto& trackIdx = (*ITSTrackClusIdx)[iITStrack]; + + ITSref = matchITStracktoMC(mcTracksMatrix, labITS); + ITStrack = (*ITStracks)[iITStrack]; + + if (ITSref[0] == cascMCref[0] && ITSref[1] == cascMCref[1]) { + LOG(info) << "++++++++++++++++"; + LOG(info) << "Cascade + ITS track found! "; + LOG(info) << "CascV0: " << casc.getV0ID() << ", Bach ID: " << casc.getBachelorID() << ", ITS track ref: " << iITStrack; + LOG(info) << "Casc Momentum: " << casc.getPt() << ", ITS track momentum: " << ITStrack.getPt(); + LOG(info) << "Casc Cov Y: " << casc.getSigmaY2() << ", Cov Z: " << casc.getSigmaZ2(); + + auto& MCTrack = mcTracksMatrix[ITSref[0]][ITSref[1]]; + auto& MCTracks = mcTracksMatrix[ITSref[0]]; + auto MCrad = calcDecLength(&MCTracks, MCTrack); + LOG(info) << "Casc rad: " << casc.calcR2() << ", MC radius: " << MCrad; + hXiStats->Fill(1); + + auto firstClus = ITStrack.getFirstClusterEntry(); + auto ncl = ITStrack.getNumberOfClusters(); + + // check whether the corresponding strange track is found + bool isStrangeTrackFound = false; + for (unsigned int iStTr = 0; iStTr < strangeTrackVec->size(); iStTr++) { + + auto& strangeTrack = strangeTrackVec->at(iStTr); + if (!(strangeTrack.mPartType == o2::strangeness_tracking::kCascade)) { continue; + } + + auto& itsRef = strangeTrack.mITSRef; + auto& cascRef = strangeTrack.mDecayRef; + if (itsRef == int(iITStrack) && cascRef == int(iCascVec)) { + isStrangeTrackFound = true; + break; + } + } - for (unsigned int iCascVec = 0; iCascVec < cascVec->size(); iCascVec++) - { - hCascCounter->Fill(1); - auto &casc = cascVec->at(iCascVec); - - hRecCascInvMass->Fill(sqrt(casc.calcMass2())); - - bool isV0reco = false; - auto cascMCref = matchCascToMC(mcTracksMatrix, map, v0Vec, casc, isV0reco); - - if (cascMCref[0] == -1 || cascMCref[1] == -1) - continue; - - hRecXiCounter->Fill(1); - hRecXiRad->Fill(sqrt(casc.calcR2())); - hRecXiMom->Fill(casc.getPt()); - auto &mcCasc = mcTracksMatrix[cascMCref[0]][cascMCref[1]]; - - // Matching ITS tracks to MC tracks and V0 - std::array ITSref = {-1, 1}; - o2::its::TrackITS ITStrack; - std::array, 7> clsRef; - - int iTrack = -1; - bool isMatched = false; - - for (unsigned int iITStrack = 0; iITStrack < ITStracks->size(); iITStrack++) - { - auto &labITS = (*labITSvec)[iITStrack]; - auto &trackIdx = (*ITSTrackClusIdx)[iITStrack]; - - ITSref = matchITStracktoMC(mcTracksMatrix, labITS); - ITStrack = (*ITStracks)[iITStrack]; - - if (ITSref[0] == cascMCref[0] && ITSref[1] == cascMCref[1]) - { - LOG(info) << "++++++++++++++++"; - LOG(info) << "Cascade + ITS track found! "; - LOG(info) << "CascV0: " << casc.getV0ID() << ", Bach ID: " << casc.getBachelorID() << ", ITS track ref: " << iITStrack; - LOG(info) << "Casc Momentum: " << casc.getPt() << ", ITS track momentum: " << ITStrack.getPt(); - LOG(info) << "Casc Cov Y: " << casc.getSigmaY2() << ", Cov Z: " << casc.getSigmaZ2(); - - auto &MCTrack = mcTracksMatrix[ITSref[0]][ITSref[1]]; - auto &MCTracks = mcTracksMatrix[ITSref[0]]; - auto MCrad = calcDecLength(&MCTracks, MCTrack); - LOG(info) << "Casc rad: " << casc.calcR2() << ", MC radius: " << MCrad; - hXiStats->Fill(1); - - auto firstClus = ITStrack.getFirstClusterEntry(); - auto ncl = ITStrack.getNumberOfClusters(); - - // check whether the corresponding strange track is found - bool isStrangeTrackFound = false; - for (unsigned int iStTr = 0; iStTr < strangeTrackVec->size(); iStTr++) - { - - auto &strangeTrack = strangeTrackVec->at(iStTr); - if (!(strangeTrack.mPartType == o2::strangeness_tracking::kCascade)) - { - continue; - } - - auto &itsRef = strangeTrack.mITSRef; - auto &cascRef = strangeTrack.mDecayRef; - if (itsRef == int(iITStrack) && cascRef == int(iCascVec)) - { - isStrangeTrackFound = true; - break; - } - } - - LOG(info) << "is Strange Track Found? " << isStrangeTrackFound; - - for (int icl = 0; icl < ncl; icl++) - { - auto &labCls = (clusLabArr->getLabels(ITSTrackClusIdx->at(firstClus + icl)))[0]; - auto &clus = (*ITSclus)[(*ITSTrackClusIdx)[firstClus + icl]]; - auto layer = gman->getLayer(clus.getSensorID()); - clsRef[layer] = matchCompLabelToMC(mcTracksMatrix, labCls); - if (clsRef[layer][0] > -1 && clsRef[layer][1] > -1) - { - auto &mcTrack = mcTracksMatrix[clsRef[layer][0]][clsRef[layer][1]]; - auto pdg = mcTrack.GetPdgCode(); - auto pdgMom1 = -1, pdgMom2 = -1; - if (!mcTrack.isPrimary()) - { - auto &mcTrackMom1 = mcTracksMatrix[clsRef[layer][0]][mcTrack.getMotherTrackId()]; - pdgMom1 = mcTrackMom1.GetPdgCode(); - if (!mcTrackMom1.isPrimary()) - { - pdgMom2 = mcTracksMatrix[clsRef[layer][0]][mcTrackMom1.getMotherTrackId()].GetPdgCode(); - } - } - LOG(info) << "Layer: " << layer << ", pdg " << pdg << ", pdgMom1 " << pdgMom1 << ", pdgMom2 " << pdgMom2 << ", refs: " << clsRef[layer][0] << ", " << clsRef[layer][1]; - } - else - LOG(info) << "Layer: " << layer << ", No valid cluster ref" - << ", isNoise: " << labCls.isNoise() << ", isFake: " << labCls.isFake(); - } - } + LOG(info) << "is Strange Track Found? " << isStrangeTrackFound; + + for (int icl = 0; icl < ncl; icl++) { + auto& labCls = (clusLabArr->getLabels(ITSTrackClusIdx->at(firstClus + icl)))[0]; + auto& clus = (*ITSclus)[(*ITSTrackClusIdx)[firstClus + icl]]; + auto layer = gman->getLayer(clus.getSensorID()); + clsRef[layer] = matchCompLabelToMC(mcTracksMatrix, labCls); + if (clsRef[layer][0] > -1 && clsRef[layer][1] > -1) { + auto& mcTrack = mcTracksMatrix[clsRef[layer][0]][clsRef[layer][1]]; + auto pdg = mcTrack.GetPdgCode(); + auto pdgMom1 = -1, pdgMom2 = -1; + if (!mcTrack.isPrimary()) { + auto& mcTrackMom1 = mcTracksMatrix[clsRef[layer][0]][mcTrack.getMotherTrackId()]; + pdgMom1 = mcTrackMom1.GetPdgCode(); + if (!mcTrackMom1.isPrimary()) { + pdgMom2 = mcTracksMatrix[clsRef[layer][0]][mcTrackMom1.getMotherTrackId()].GetPdgCode(); + } } + LOG(info) << "Layer: " << layer << ", pdg " << pdg << ", pdgMom1 " << pdgMom1 << ", pdgMom2 " << pdgMom2 << ", refs: " << clsRef[layer][0] << ", " << clsRef[layer][1]; + } else + LOG(info) << "Layer: " << layer << ", No valid cluster ref" + << ", isNoise: " << labCls.isNoise() << ", isFake: " << labCls.isFake(); } + } + } + } - LOG(info) << "+++++++++++++++++++++++++++++++++++++++++++++"; + LOG(info) << "+++++++++++++++++++++++++++++++++++++++++++++"; - for (unsigned int iHyperVec = 0; iHyperVec < strangeTrackVec->size(); iHyperVec++) - { + for (unsigned int iHyperVec = 0; iHyperVec < strangeTrackVec->size(); iHyperVec++) { - auto &strangeTrack = strangeTrackVec->at(iHyperVec); - if (!(strangeTrack.mPartType == o2::strangeness_tracking::kCascade)) - { - continue; - } + auto& strangeTrack = strangeTrackVec->at(iHyperVec); + if (!(strangeTrack.mPartType == o2::strangeness_tracking::kCascade)) { + continue; + } - auto &hyperChi2 = strangeTrack.mMatchChi2; - auto &clusAttachments = nAttachments->at(iHyperVec); - auto &ITStrack = ITStracks->at(strangeTrack.mITSRef); - auto &ITStrackLab = labITSvec->at(strangeTrack.mITSRef); + auto& hyperChi2 = strangeTrack.mMatchChi2; + auto& clusAttachments = nAttachments->at(iHyperVec); + auto& ITStrack = ITStracks->at(strangeTrack.mITSRef); + auto& ITStrackLab = labITSvec->at(strangeTrack.mITSRef); - auto clusAttArr = clusAttachments.arr; - auto &casc = cascVec->at(strangeTrack.mDecayRef); - auto &v0Casc = casc.getV0Track(); - auto &bach = casc.getBachelorTrack(); + auto clusAttArr = clusAttachments.arr; + auto& casc = cascVec->at(strangeTrack.mDecayRef); + auto& v0Casc = casc.getV0Track(); + auto& bach = casc.getBachelorTrack(); - auto ITStrackRef = matchCompLabelToMC(mcTracksMatrix, ITStrackLab); - bool isV0reco = false; - auto cascMCref = matchCascToMC(mcTracksMatrix, map, v0Vec, casc, isV0reco); + auto ITStrackRef = matchCompLabelToMC(mcTracksMatrix, ITStrackLab); + bool isV0reco = false; + auto cascMCref = matchCascToMC(mcTracksMatrix, map, v0Vec, casc, isV0reco); - std::vector dauTracks = {v0Casc, bach}; + std::vector dauTracks = {v0Casc, bach}; - hStrangeTrackInvMass->Fill(calcMass(dauTracks)); + hStrangeTrackInvMass->Fill(calcMass(dauTracks)); - if (cascMCref[0] == -1 || cascMCref[1] == -1 || ITStrackRef[0] == -1 || ITStrackRef[1] == -1) - continue; + if (cascMCref[0] == -1 || cascMCref[1] == -1 || ITStrackRef[0] == -1 || ITStrackRef[1] == -1) + continue; - if (ITStrackRef[0] == cascMCref[0] && ITStrackRef[1] == cascMCref[1]) - { - hXiStats->Fill(2); - hTrackedXiRad->Fill(sqrt(casc.calcR2())); - hTrackedXiMom->Fill(casc.getPt()); + if (ITStrackRef[0] == cascMCref[0] && ITStrackRef[1] == cascMCref[1]) { + hXiStats->Fill(2); + hTrackedXiRad->Fill(sqrt(casc.calcR2())); + hTrackedXiMom->Fill(casc.getPt()); - auto &mcTracks = mcTracksMatrix[cascMCref[0]]; - auto &mcTrack = mcTracksMatrix[cascMCref[0]][cascMCref[1]]; - hResCascR2->Fill((sqrt(casc.calcR2()) - calcDecLength(&mcTracks, mcTrack)) / calcDecLength(&mcTracks, mcTrack)); + auto& mcTracks = mcTracksMatrix[cascMCref[0]]; + auto& mcTrack = mcTracksMatrix[cascMCref[0]][cascMCref[1]]; + hResCascR2->Fill((sqrt(casc.calcR2()) - calcDecLength(&mcTracks, mcTrack)) / calcDecLength(&mcTracks, mcTrack)); - auto trackedR = sqrt(strangeTrack.decayVtx[0] * strangeTrack.decayVtx[0] + strangeTrack.decayVtx[1] * strangeTrack.decayVtx[1]); - hResCascTrackedR2->Fill((trackedR - calcDecLength(&mcTracks, mcTrack)) / calcDecLength(&mcTracks, mcTrack)); - } - else - { - hFakeAssocCounter->Fill(1); - } - } + auto trackedR = sqrt(strangeTrack.decayVtx[0] * strangeTrack.decayVtx[0] + strangeTrack.decayVtx[1] * strangeTrack.decayVtx[1]); + hResCascTrackedR2->Fill((trackedR - calcDecLength(&mcTracks, mcTrack)) / calcDecLength(&mcTracks, mcTrack)); + } else { + hFakeAssocCounter->Fill(1); } + } } - - auto outFile = TFile("cascade_study.root", "recreate"); - - hResV0histo->Write(); - hHyperhisto->Write(); - hResHyperhisto->Write(); - hResCascR2->Write(); - hResCascTrackedR2->Write(); - - hGenXiCounter->Write(); - hCascCounter->Write(); - hXiStats->Write(); - hRecXiCounter->Write(); - hFakeAssocCounter->Write(); - hCascMomsInV0s->Write(); - hRecCascInvMass->Write(); - hStrangeTrackInvMass->Write(); - - - - TH1D *hMomEffFound = (TH1D *)hTrackedXiMom->Clone("efficiency_found_mom"); - hMomEffFound->Divide(hRecXiMom); - auto cv1 = TCanvas("found_efficiency_pt", "", 1000, 1000); - hMomEffFound->GetYaxis()->SetTitle("Tracked/Found"); - hMomEffFound->SetLineColor(kBlue); - hMomEffFound->Draw(); - cv1.Write(); - - TH1D *hRadEffFound = (TH1D *)hTrackedXiRad->Clone("efficiency_found_rad"); - hRadEffFound->Divide(hRecXiRad); - auto cv2 = TCanvas("found_efficiency_rad", "", 1000, 1000); - hRadEffFound->GetXaxis()->SetTitle("Radius (cm)"); - hRadEffFound->GetYaxis()->SetTitle("Tracked/Found"); - hRadEffFound->SetLineColor(kBlue); - hRadEffFound->Draw(); - cv2.Write(); - - - TH1D *hMomEffGen = (TH1D *)hTrackedXiMom->Clone("efficiency_gen_mom"); - hMomEffGen->Divide(hGenXiMom); - auto cv3 = TCanvas("gen_efficiency_pt", "", 1000, 1000); - hMomEffGen->GetYaxis()->SetTitle("Efficiency"); - hMomEffGen->SetLineColor(kBlue); - hMomEffGen->Draw(); - cv3.Write(); - - TH1D *hRadEffGen = (TH1D *)hTrackedXiRad->Clone("efficiency_gen_rad"); - hRadEffGen->Divide(hGenXiRadius); - auto cv4 = TCanvas("gen_efficiency_rad", "", 1000, 1000); - hRadEffGen->GetXaxis()->SetTitle("Radius (cm)"); - hRadEffGen->GetYaxis()->SetTitle("Efficiency"); - hRadEffGen->SetLineColor(kBlue); - hRadEffGen->Draw(); - cv4.Write(); - - auto cv5 = TCanvas("inv_mass_res_study", "", 1000, 1000); - hStrangeTrackInvMass->GetXaxis()->SetTitle("M(GeV/#it{c}^{2})"); - hStrangeTrackInvMass->GetYaxis()->SetTitle("Normalised Counts"); - hStrangeTrackInvMass->SetLineColor(kRed); - hStrangeTrackInvMass->SetLineWidth(2); - hRecCascInvMass->SetLineWidth(2); - hStrangeTrackInvMass->DrawNormalized(); - hRecCascInvMass->DrawNormalized("same"); - auto leg2 = new TLegend(0.5, 0.5, 0.8, 0.8); - leg2->AddEntry(hStrangeTrackInvMass, "After tracking"); - leg2->AddEntry(hRecCascInvMass, "Before tracking"); - leg2->Draw(); - cv5.Write(); - - hRecXiRad->Sumw2(); - hRecXiRad->Divide(hGenXiRadius); - auto cv6 = TCanvas("reco_efficiency_r", "", 1000, 1000); - hRecXiRad->GetXaxis()->SetTitle("Radius (cm)"); - hRecXiRad->GetYaxis()->SetTitle("Efficiency"); - hRecXiRad->SetLineColor(kBlue); - hRecXiRad->Draw(); - cv6.Write(); - - hRecXiMom->Sumw2(); - hRecXiMom->Divide(hGenXiMom); - auto cv7 = TCanvas("reco_efficiency_pt", "", 1000, 1000); - hRecXiMom->GetYaxis()->SetTitle("Efficiency"); - hRecXiMom->SetLineColor(kBlue); - hRecXiMom->Draw("pe"); - cv7.Write(); - - outFile.Close(); + } + + auto outFile = TFile("cascade_study.root", "recreate"); + + hResV0histo->Write(); + hHyperhisto->Write(); + hResHyperhisto->Write(); + hResCascR2->Write(); + hResCascTrackedR2->Write(); + + hGenXiCounter->Write(); + hCascCounter->Write(); + hXiStats->Write(); + hRecXiCounter->Write(); + hFakeAssocCounter->Write(); + hCascMomsInV0s->Write(); + hRecCascInvMass->Write(); + hStrangeTrackInvMass->Write(); + + TH1D* hMomEffFound = (TH1D*)hTrackedXiMom->Clone("efficiency_found_mom"); + hMomEffFound->Divide(hRecXiMom); + auto cv1 = TCanvas("found_efficiency_pt", "", 1000, 1000); + hMomEffFound->GetYaxis()->SetTitle("Tracked/Found"); + hMomEffFound->SetLineColor(kBlue); + hMomEffFound->Draw(); + cv1.Write(); + + TH1D* hRadEffFound = (TH1D*)hTrackedXiRad->Clone("efficiency_found_rad"); + hRadEffFound->Divide(hRecXiRad); + auto cv2 = TCanvas("found_efficiency_rad", "", 1000, 1000); + hRadEffFound->GetXaxis()->SetTitle("Radius (cm)"); + hRadEffFound->GetYaxis()->SetTitle("Tracked/Found"); + hRadEffFound->SetLineColor(kBlue); + hRadEffFound->Draw(); + cv2.Write(); + + TH1D* hMomEffGen = (TH1D*)hTrackedXiMom->Clone("efficiency_gen_mom"); + hMomEffGen->Divide(hGenXiMom); + auto cv3 = TCanvas("gen_efficiency_pt", "", 1000, 1000); + hMomEffGen->GetYaxis()->SetTitle("Efficiency"); + hMomEffGen->SetLineColor(kBlue); + hMomEffGen->Draw(); + cv3.Write(); + + TH1D* hRadEffGen = (TH1D*)hTrackedXiRad->Clone("efficiency_gen_rad"); + hRadEffGen->Divide(hGenXiRadius); + auto cv4 = TCanvas("gen_efficiency_rad", "", 1000, 1000); + hRadEffGen->GetXaxis()->SetTitle("Radius (cm)"); + hRadEffGen->GetYaxis()->SetTitle("Efficiency"); + hRadEffGen->SetLineColor(kBlue); + hRadEffGen->Draw(); + cv4.Write(); + + auto cv5 = TCanvas("inv_mass_res_study", "", 1000, 1000); + hStrangeTrackInvMass->GetXaxis()->SetTitle("M(GeV/#it{c}^{2})"); + hStrangeTrackInvMass->GetYaxis()->SetTitle("Normalised Counts"); + hStrangeTrackInvMass->SetLineColor(kRed); + hStrangeTrackInvMass->SetLineWidth(2); + hRecCascInvMass->SetLineWidth(2); + hStrangeTrackInvMass->DrawNormalized(); + hRecCascInvMass->DrawNormalized("same"); + auto leg2 = new TLegend(0.5, 0.5, 0.8, 0.8); + leg2->AddEntry(hStrangeTrackInvMass, "After tracking"); + leg2->AddEntry(hRecCascInvMass, "Before tracking"); + leg2->Draw(); + cv5.Write(); + + hRecXiRad->Sumw2(); + hRecXiRad->Divide(hGenXiRadius); + auto cv6 = TCanvas("reco_efficiency_r", "", 1000, 1000); + hRecXiRad->GetXaxis()->SetTitle("Radius (cm)"); + hRecXiRad->GetYaxis()->SetTitle("Efficiency"); + hRecXiRad->SetLineColor(kBlue); + hRecXiRad->Draw(); + cv6.Write(); + + hRecXiMom->Sumw2(); + hRecXiMom->Divide(hGenXiMom); + auto cv7 = TCanvas("reco_efficiency_pt", "", 1000, 1000); + hRecXiMom->GetYaxis()->SetTitle("Efficiency"); + hRecXiMom->SetLineColor(kBlue); + hRecXiMom->Draw("pe"); + cv7.Write(); + + outFile.Close(); } -std::array matchCascToMC(const std::vector> &mcTracksMatrix, std::map *> &map, std::vector *v0vec, Cascade &casc, bool &isV0reco) +std::array matchCascToMC(const std::vector>& mcTracksMatrix, std::map*>& map, std::vector* v0vec, Cascade& casc, bool& isV0reco) { - std::array motherVec{-1, -1}; - std::array, 2> v0DauRefs; - std::array bachRef; - - auto v0Idx = casc.getV0ID(); - auto &v0 = v0vec->at(v0Idx); - - auto bachID = casc.getBachelorID(); - if (!map[bachID.getSourceName()]) - return motherVec; - auto &bachLab = map[bachID.getSourceName()]->at(bachID.getIndex()); - if (bachLab.isValid()) - bachRef = {bachLab.getEventID(), bachLab.getTrackID()}; - else - return motherVec; - - for (unsigned int iV0 = 0; iV0 < 2; iV0++) - { - v0DauRefs[iV0] = {-1, -1}; - if (map[v0.getProngID(iV0).getSourceName()]) - { - auto labTrackType = map[v0.getProngID(iV0).getSourceName()]; - auto lab = labTrackType->at(v0.getProngID(iV0).getIndex()); - - int trackID, evID, srcID; - bool fake; - lab.get(trackID, evID, srcID, fake); - if (lab.isValid()) - { - v0DauRefs[iV0] = {lab.getEventID(), lab.getTrackID()}; - } - } - } + std::array motherVec{-1, -1}; + std::array, 2> v0DauRefs; + std::array bachRef; - if (v0DauRefs[0][1] == -1 || v0DauRefs[1][1] == -1) - return motherVec; + auto v0Idx = casc.getV0ID(); + auto& v0 = v0vec->at(v0Idx); - auto &dau1MC = mcTracksMatrix[v0DauRefs[0][0]][v0DauRefs[0][1]]; - auto &dau2MC = mcTracksMatrix[v0DauRefs[1][0]][v0DauRefs[1][1]]; + auto bachID = casc.getBachelorID(); + if (!map[bachID.getSourceName()]) + return motherVec; + auto& bachLab = map[bachID.getSourceName()]->at(bachID.getIndex()); + if (bachLab.isValid()) + bachRef = {bachLab.getEventID(), bachLab.getTrackID()}; + else + return motherVec; - if (!(std::abs(dau1MC.GetPdgCode()) == firstV0dauPDG && std::abs(dau2MC.GetPdgCode()) == secondV0dauPDG) && !(std::abs(dau1MC.GetPdgCode()) == secondV0dauPDG && std::abs(dau2MC.GetPdgCode()) == firstV0dauPDG)) - return motherVec; + for (unsigned int iV0 = 0; iV0 < 2; iV0++) { + v0DauRefs[iV0] = {-1, -1}; + if (map[v0.getProngID(iV0).getSourceName()]) { + auto labTrackType = map[v0.getProngID(iV0).getSourceName()]; + auto lab = labTrackType->at(v0.getProngID(iV0).getIndex()); + + int trackID, evID, srcID; + bool fake; + lab.get(trackID, evID, srcID, fake); + if (lab.isValid()) { + v0DauRefs[iV0] = {lab.getEventID(), lab.getTrackID()}; + } + } + } - if (!dau1MC.isSecondary() || !dau2MC.isSecondary() || dau1MC.getMotherTrackId() != dau2MC.getMotherTrackId()) - return motherVec; + if (v0DauRefs[0][1] == -1 || v0DauRefs[1][1] == -1) + return motherVec; - auto v0MC = mcTracksMatrix[v0DauRefs[0][0]][dau1MC.getMotherTrackId()]; - auto &bachMC = mcTracksMatrix[bachRef[0]][bachRef[1]]; + auto& dau1MC = mcTracksMatrix[v0DauRefs[0][0]][v0DauRefs[0][1]]; + auto& dau2MC = mcTracksMatrix[v0DauRefs[1][0]][v0DauRefs[1][1]]; - if (v0MC.getMotherTrackId() >= 0) - { + if (!(std::abs(dau1MC.GetPdgCode()) == firstV0dauPDG && std::abs(dau2MC.GetPdgCode()) == secondV0dauPDG) && !(std::abs(dau1MC.GetPdgCode()) == secondV0dauPDG && std::abs(dau2MC.GetPdgCode()) == firstV0dauPDG)) + return motherVec; - if (std::abs(mcTracksMatrix[v0DauRefs[0][0]][v0MC.getMotherTrackId()].GetPdgCode()) == motherPDG) - isV0reco = true; - } + if (!dau1MC.isSecondary() || !dau2MC.isSecondary() || dau1MC.getMotherTrackId() != dau2MC.getMotherTrackId()) + return motherVec; - if (std::abs(v0MC.GetPdgCode()) != v0PDG || !v0MC.isSecondary() || !bachMC.isSecondary()) - return motherVec; + auto v0MC = mcTracksMatrix[v0DauRefs[0][0]][dau1MC.getMotherTrackId()]; + auto& bachMC = mcTracksMatrix[bachRef[0]][bachRef[1]]; - auto cascMC = mcTracksMatrix[v0DauRefs[0][0]][v0MC.getMotherTrackId()]; - if (v0MC.getMotherTrackId() != bachMC.getMotherTrackId() || std::abs(cascMC.GetPdgCode()) != motherPDG) - return motherVec; + if (v0MC.getMotherTrackId() >= 0) { - motherVec = {v0DauRefs[0][0], v0MC.getMotherTrackId()}; + if (std::abs(mcTracksMatrix[v0DauRefs[0][0]][v0MC.getMotherTrackId()].GetPdgCode()) == motherPDG) + isV0reco = true; + } + + if (std::abs(v0MC.GetPdgCode()) != v0PDG || !v0MC.isSecondary() || !bachMC.isSecondary()) + return motherVec; + + auto cascMC = mcTracksMatrix[v0DauRefs[0][0]][v0MC.getMotherTrackId()]; + if (v0MC.getMotherTrackId() != bachMC.getMotherTrackId() || std::abs(cascMC.GetPdgCode()) != motherPDG) return motherVec; + + motherVec = {v0DauRefs[0][0], v0MC.getMotherTrackId()}; + return motherVec; } -std::array checkV0mother(const std::vector> &mcTracksMatrix, std::map *> &map, V0 &v0) +std::array checkV0mother(const std::vector>& mcTracksMatrix, std::map*>& map, V0& v0) { - std::array motherVec{-1, -1}; - std::array, 2> v0DauRefs; - - for (unsigned int iV0 = 0; iV0 < 2; iV0++) - { - v0DauRefs[iV0] = {-1, -1}; - if (map[v0.getProngID(iV0).getSourceName()]) - { - auto labTrackType = map[v0.getProngID(iV0).getSourceName()]; - auto lab = labTrackType->at(v0.getProngID(iV0).getIndex()); - - int trackID, evID, srcID; - bool fake; - lab.get(trackID, evID, srcID, fake); - if (lab.isValid()) - { - v0DauRefs[iV0] = {lab.getEventID(), lab.getTrackID()}; - } - } + std::array motherVec{-1, -1}; + std::array, 2> v0DauRefs; + + for (unsigned int iV0 = 0; iV0 < 2; iV0++) { + v0DauRefs[iV0] = {-1, -1}; + if (map[v0.getProngID(iV0).getSourceName()]) { + auto labTrackType = map[v0.getProngID(iV0).getSourceName()]; + auto lab = labTrackType->at(v0.getProngID(iV0).getIndex()); + + int trackID, evID, srcID; + bool fake; + lab.get(trackID, evID, srcID, fake); + if (lab.isValid()) { + v0DauRefs[iV0] = {lab.getEventID(), lab.getTrackID()}; + } } + } + + if (v0DauRefs[0][1] == -1 || v0DauRefs[1][1] == -1) + return motherVec; - if (v0DauRefs[0][1] == -1 || v0DauRefs[1][1] == -1) - return motherVec; + auto& dau1MC = mcTracksMatrix[v0DauRefs[0][0]][v0DauRefs[0][1]]; + auto& dau2MC = mcTracksMatrix[v0DauRefs[1][0]][v0DauRefs[1][1]]; - auto &dau1MC = mcTracksMatrix[v0DauRefs[0][0]][v0DauRefs[0][1]]; - auto &dau2MC = mcTracksMatrix[v0DauRefs[1][0]][v0DauRefs[1][1]]; + if (!(std::abs(dau1MC.GetPdgCode()) == firstV0dauPDG && std::abs(dau2MC.GetPdgCode()) == secondV0dauPDG) && !(std::abs(dau1MC.GetPdgCode()) == secondV0dauPDG && std::abs(dau2MC.GetPdgCode()) == firstV0dauPDG)) + return motherVec; - if (!(std::abs(dau1MC.GetPdgCode()) == firstV0dauPDG && std::abs(dau2MC.GetPdgCode()) == secondV0dauPDG) && !(std::abs(dau1MC.GetPdgCode()) == secondV0dauPDG && std::abs(dau2MC.GetPdgCode()) == firstV0dauPDG)) - return motherVec; + if (!dau1MC.isSecondary() || !dau2MC.isSecondary() || dau1MC.getMotherTrackId() != dau2MC.getMotherTrackId()) + return motherVec; - if (!dau1MC.isSecondary() || !dau2MC.isSecondary() || dau1MC.getMotherTrackId() != dau2MC.getMotherTrackId()) - return motherVec; + LOG(info) << "-----------------------------------------"; + LOG(info) << "V0 daughters: " << dau1MC.GetPdgCode() << " " << dau2MC.GetPdgCode(); + LOG(info) << " Dau refs: " << dau1MC.getMotherTrackId() << " " << dau2MC.getMotherTrackId(); - LOG(info) << "-----------------------------------------"; - LOG(info) << "V0 daughters: " << dau1MC.GetPdgCode() << " " << dau2MC.GetPdgCode(); - LOG(info) << " Dau refs: " << dau1MC.getMotherTrackId() << " " << dau2MC.getMotherTrackId(); + auto v0MC = mcTracksMatrix[v0DauRefs[0][0]][dau1MC.getMotherTrackId()]; + LOG(info) << "V0 mother: " << v0MC.GetPdgCode() << ", Ref: " << v0MC.getMotherTrackId(); - auto v0MC = mcTracksMatrix[v0DauRefs[0][0]][dau1MC.getMotherTrackId()]; - LOG(info) << "V0 mother: " << v0MC.GetPdgCode() << ", Ref: " << v0MC.getMotherTrackId(); + auto cascMC = mcTracksMatrix[v0DauRefs[0][0]][v0MC.getMotherTrackId()]; + if (std::abs(cascMC.GetPdgCode()) != motherPDG) + return motherVec; - auto cascMC = mcTracksMatrix[v0DauRefs[0][0]][v0MC.getMotherTrackId()]; - if (std::abs(cascMC.GetPdgCode()) != motherPDG) - return motherVec; + LOG(info) << "Casc from V0 PDG: " << mcTracksMatrix[v0DauRefs[0][0]][v0MC.getMotherTrackId()].GetPdgCode(); - LOG(info) << "Casc from V0 PDG: " << mcTracksMatrix[v0DauRefs[0][0]][v0MC.getMotherTrackId()].GetPdgCode(); + motherVec = {v0DauRefs[0][0], v0MC.getMotherTrackId()}; + return motherVec; +} - motherVec = {v0DauRefs[0][0], v0MC.getMotherTrackId()}; - return motherVec; +double calcDecLength(std::vector* MCTracks, const MCTrack& motherTrack) +{ + auto idStart = motherTrack.getFirstDaughterTrackId(); + auto idStop = motherTrack.getLastDaughterTrackId(); + + if (idStart == -1 || idStop == -1) + return -1; + for (auto iD{idStart}; iD <= idStop; ++iD) { + auto dauTrack = MCTracks->at(iD); + if (std::abs(dauTrack.GetPdgCode()) == v0PDG) { + auto decLength = (dauTrack.GetStartVertexCoordinatesX() - + motherTrack.GetStartVertexCoordinatesX()) * + (dauTrack.GetStartVertexCoordinatesX() - + motherTrack.GetStartVertexCoordinatesX()) + + (dauTrack.GetStartVertexCoordinatesY() - + motherTrack.GetStartVertexCoordinatesY()) * + (dauTrack.GetStartVertexCoordinatesY() - + motherTrack.GetStartVertexCoordinatesY()); + return sqrt(decLength); + } + } + return -1; +} + +std::array matchCompLabelToMC(const std::vector>& mcTracksMatrix, o2::MCCompLabel compLabel) +{ + std::array compRef = {-1, -1}; + int trackID, evID, srcID; + bool fake; + compLabel.get(trackID, evID, srcID, fake); + if (compLabel.isValid()) { + compRef = {evID, trackID}; + } + return compRef; +} + +std::array matchITStracktoMC(const std::vector>& mcTracksMatrix, + o2::MCCompLabel ITSlabel) + +{ + std::array outArray = {-1, -1}; + int trackID, evID, srcID; + bool fake; + ITSlabel.get(trackID, evID, srcID, fake); + if (ITSlabel.isValid() && + std::abs(mcTracksMatrix[evID][trackID].GetPdgCode()) == motherPDG) { + outArray = {evID, trackID}; + } + + return outArray; } + +double calcMass(std::vector tracks) +{ + TLorentzVector moth, prong; + std::array p; + for (unsigned int i = 0; i < tracks.size(); i++) { + auto& track = tracks[i]; + auto mass = tracks.size() == 2 ? kFirstDauMasses[i] : kDauMasses[i]; + track.getPxPyPzGlo(p); + prong.SetVectM({p[0], p[1], p[2]}, mass); + moth += prong; + } + return moth.M(); +} \ No newline at end of file diff --git a/Detectors/StrangenessTracking/macros/cascadeStudyUtils.h b/Detectors/StrangenessTracking/macros/cascadeStudyUtils.h deleted file mode 100644 index 6d528eb52cfce..0000000000000 --- a/Detectors/StrangenessTracking/macros/cascadeStudyUtils.h +++ /dev/null @@ -1,340 +0,0 @@ - - -#if !defined(CLING) || defined(ROOTCLING) -#include "ITSMFTSimulation/Hit.h" -#include "SimulationDataFormat/MCCompLabel.h" -#include "SimulationDataFormat/MCTrack.h" -#include "SimulationDataFormat/MCTruthContainer.h" - -#include "DataFormatsITS/TrackITS.h" -#include "DataFormatsITSMFT/CompCluster.h" -#include "DataFormatsITSMFT/ROFRecord.h" -#include "DataFormatsITSMFT/TopologyDictionary.h" -#include "DetectorsCommonDataFormats/DetectorNameConf.h" -#include "ITSBase/GeometryTGeo.h" -#include "ITStracking/IOUtils.h" -#include "ReconstructionDataFormats/TrackTPCITS.h" - -#include "CommonDataFormat/RangeReference.h" -#include "DetectorsVertexing/DCAFitterN.h" -#include "TCanvas.h" -#include "TFile.h" -#include "TH1F.h" -#include "TH2D.h" -#include "TLegend.h" -#include "TMath.h" -#include "TString.h" -#include "TSystemDirectory.h" -#include "TTree.h" -#include -#include - -#endif - -using MCTrack = o2::MCTrack; -using CompClusterExt = o2::itsmft::CompClusterExt; -using ITSCluster = o2::BaseCluster; - -const int motherPDG = 3312; -const int v0PDG = 3122; -const int bachPDG = 211; -const int firstV0dauPDG = 2212; -const int secondV0dauPDG = 211; - -enum kClType -{ - kFree, - kTracked, - kFake -}; - -enum kDauType -{ - kPr, - kPi, - kBach -}; - -const float XiMass = 1.32171; -const int kDauPdgs[3] = {2212, 211, 211}; -const float kDauMasses[3] = {0.938272, 0.13957, 0.13957}; -const float kFirstDauMasses[2] = {1.115683, 0.13957}; - -double calcLifetime(std::vector *MCTracks, const MCTrack &motherTrack, - int dauPDG); - -double calcDecLength(std::vector *MCTracks, const MCTrack &motherTrack); -double calcDecLengthV0(std::vector *MCTracks, - const MCTrack &motherTrack, int dauPDG); -std::array -matchCascDauToMC(const std::vector> &mcTracksMatrix, - o2::MCCompLabel &lab, int dauPDG); -std::array -matchBachToMC(const std::vector> &mcTracksMatrix, - o2::MCCompLabel &lab); -std::array -matchCompLabelToMC(const std::vector> &mcTracksMatrix, - o2::MCCompLabel compLabel); -int checkCascRef(std::array cascRef1, std::array cascRef2, - std::array cascRef3, std::array &cascRef); -std::vector -getTrackClusters(const o2::its::TrackITS &ITStrack, - const std::vector &ITSClustersArray, - std::vector *ITSTrackClusIdx); -std::array -matchITStracktoMC(const std::vector> &mcTracksMatrix, - o2::MCCompLabel ITSlabel); -double calcMass(std::vector tracks); - -std::array -matchCascDauToMC(const std::vector> &mcTracksMatrix, - o2::MCCompLabel &lab, int dauPDG) -{ - std::array outArray{-1, -1}; - - int trackID, evID, srcID; - bool fake; - lab.get(trackID, evID, srcID, fake); - if (lab.isValid()) - { - auto motherID = mcTracksMatrix[evID][trackID].getMotherTrackId(); - if (motherID >= 0 && - std::abs(mcTracksMatrix[evID][trackID].GetPdgCode()) == dauPDG) - { - auto v0MomPDG = mcTracksMatrix[evID][motherID].GetPdgCode(); - auto v0MomID = mcTracksMatrix[evID][motherID].getMotherTrackId(); - if (std::abs(v0MomPDG) == v0PDG && v0MomID >= 0) - { - auto cascPDG = mcTracksMatrix[evID][v0MomID].GetPdgCode(); - if (std::abs(cascPDG) == motherPDG) - { - outArray[0] = evID; - outArray[1] = v0MomID; - } - } - } - } - - return outArray; -} - -std::array -matchBachToMC(const std::vector> &mcTracksMatrix, - o2::MCCompLabel &lab) -{ - std::array outArray{-1, -1}; - - int trackID, evID, srcID; - bool fake; - lab.get(trackID, evID, srcID, fake); - if (lab.isValid()) - { - auto motherID = mcTracksMatrix[evID][trackID].getMotherTrackId(); - if (motherID >= 0) - { - auto cascPDG = mcTracksMatrix[evID][motherID].GetPdgCode(); - if (std::abs(cascPDG) == motherPDG) - { - outArray[0] = evID; - outArray[1] = motherID; - } - } - } - - return outArray; -} - -double calcDecLength(std::vector *MCTracks, const MCTrack &motherTrack) -{ - auto idStart = motherTrack.getFirstDaughterTrackId(); - auto idStop = motherTrack.getLastDaughterTrackId(); - - if (idStart == -1 || idStop == -1) - return -1; - for (auto iD{idStart}; iD <= idStop; ++iD) - { - auto dauTrack = MCTracks->at(iD); - if (std::abs(dauTrack.GetPdgCode()) == v0PDG) - { - auto decLength = (dauTrack.GetStartVertexCoordinatesX() - - motherTrack.GetStartVertexCoordinatesX()) * - (dauTrack.GetStartVertexCoordinatesX() - - motherTrack.GetStartVertexCoordinatesX()) + - (dauTrack.GetStartVertexCoordinatesY() - - motherTrack.GetStartVertexCoordinatesY()) * - (dauTrack.GetStartVertexCoordinatesY() - - motherTrack.GetStartVertexCoordinatesY()); - return sqrt(decLength); - } - } - return -1; -} - -double calcLifetime(std::vector *MCTracks, const MCTrack &motherTrack, - int dauPDG) -{ - auto idStart = motherTrack.getFirstDaughterTrackId(); - auto idStop = motherTrack.getLastDaughterTrackId(); - - if (idStart == -1 || idStop == -1) - return -1; - for (auto iD{idStart}; iD <= idStop; ++iD) - { - auto dauTrack = MCTracks->at(iD); - if (std::abs(dauTrack.GetPdgCode()) == dauPDG) - { - auto decLength = (dauTrack.GetStartVertexCoordinatesX() - - motherTrack.GetStartVertexCoordinatesX()) * - (dauTrack.GetStartVertexCoordinatesX() - - motherTrack.GetStartVertexCoordinatesX()) + - (dauTrack.GetStartVertexCoordinatesY() - - motherTrack.GetStartVertexCoordinatesY()) * - (dauTrack.GetStartVertexCoordinatesY() - - motherTrack.GetStartVertexCoordinatesY()) + - (dauTrack.GetStartVertexCoordinatesZ() - - motherTrack.GetStartVertexCoordinatesZ()) * - (dauTrack.GetStartVertexCoordinatesZ() - - motherTrack.GetStartVertexCoordinatesZ()); - return sqrt(decLength)*XiMass/motherTrack.GetP(); - } - } - return -1; -} - -double calcDecLengthV0(std::vector *MCTracks, - const MCTrack &motherTrack, int dauPDG) -{ - auto idStart = motherTrack.getFirstDaughterTrackId(); - auto idStop = motherTrack.getLastDaughterTrackId(); - // LOG(info) << "idStart: " << idStart << " idStop: " << idStop; - - if (idStart == -1 || idStop == -1) - return -1; - for (auto iD{idStart}; iD <= idStop; iD++) - { - auto &v0Track = MCTracks->at(iD); - - auto jdStart = v0Track.getFirstDaughterTrackId(); - auto jdStop = v0Track.getLastDaughterTrackId(); - - // LOG(info) << "jdStart: " << jdStart << " jdStop: " << jdStop; - if (std::abs(v0Track.GetPdgCode()) == v0PDG) - { - // LOG(info) << "jdStart: " << jdStart << " jdStop: " << jdStop; - if (jdStart == -1 || jdStop == -1) - return -1; - - for (auto jD{jdStart}; jD <= jdStop; jD++) - { - auto dauTrack = MCTracks->at(jD); - if (std::abs(dauTrack.GetPdgCode()) == dauPDG) - { - // LOG(info) << "DauX: " << dauTrack.GetStartVertexCoordinatesX() << - // ", dauY: " < -matchCompLabelToMC(const std::vector> &mcTracksMatrix, - o2::MCCompLabel compLabel) -{ - std::array compRef = {-1, -1}; - int trackID, evID, srcID; - bool fake; - compLabel.get(trackID, evID, srcID, fake); - if (compLabel.isValid()) - { - compRef = {evID, trackID}; - } - return compRef; -} - -int checkCascRef(std::array cascRef1, std::array cascRef2, - std::array cascRef3, std::array &cascRef) -{ - - if (cascRef1[0] != -1 && cascRef1[1] != -1) - { - cascRef = cascRef1; - return kPr; - } - else if (cascRef2[0] != -1 && cascRef2[1] != -1) - { - cascRef = cascRef2; - return kPi; - } - else if (cascRef3[0] != -1 && cascRef3[1] != -1) - { - cascRef = cascRef3; - return kBach; - } - else - { - return -1; - } -} - -std::array -matchITStracktoMC(const std::vector> &mcTracksMatrix, - o2::MCCompLabel ITSlabel) - -{ - std::array outArray = {-1, -1}; - int trackID, evID, srcID; - bool fake; - ITSlabel.get(trackID, evID, srcID, fake); - if (ITSlabel.isValid() && - std::abs(mcTracksMatrix[evID][trackID].GetPdgCode()) == motherPDG) - { - outArray = {evID, trackID}; - } - - return outArray; -} - -std::vector -getTrackClusters(const o2::its::TrackITS &ITStrack, - const std::vector &ITSClustersArray, - std::vector *ITSTrackClusIdx) -{ - - std::vector outVec; - auto firstClus = ITStrack.getFirstClusterEntry(); - auto ncl = ITStrack.getNumberOfClusters(); - for (int icl = 0; icl < ncl; icl++) - { - outVec.push_back(ITSClustersArray[(*ITSTrackClusIdx)[firstClus + icl]]); - } - return outVec; -} - -double calcMass(std::vector tracks) -{ - TLorentzVector moth, prong; - std::array p; - for (unsigned int i = 0; i < tracks.size(); i++) - { - auto &track = tracks[i]; - auto mass = tracks.size() == 2 ? kFirstDauMasses[i] : kDauMasses[i]; - track.getPxPyPzGlo(p); - prong.SetVectM({p[0], p[1], p[2]}, mass); - moth += prong; - } - return moth.M(); -} \ No newline at end of file diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h index f6fe0c3b4275c..2ba048d8c028c 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTracker.h @@ -62,7 +62,6 @@ struct StrangeTrack { class StrangenessTracker { public: - using PID = o2::track::PID; using TrackITS = o2::its::TrackITS; using ITSCluster = o2::BaseCluster; diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx index f66022ea5ccf0..8eda53becd4b7 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx @@ -82,7 +82,7 @@ void StrangenessTracker::process() continue; mStrangeTrack.mPartType = kV0; - + auto v0R2 = v0.calcR2(); auto iBinsV0 = mUtils.getBinRect(correctedV0.getEta(), correctedV0.getPhi(), mStrParams->mEtaBinSize, mStrParams->mPhiBinSize); for (int& iBinV0 : iBinsV0) { diff --git a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx index c2cef13ed1db2..13e7ea4ca954f 100644 --- a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx @@ -109,7 +109,7 @@ void StrangenessTrackerSpec::run(framework::ProcessingContext& pc) // \nlabTPCTOF: %d\nlabITSTPCTOF: %d mTracker.setCorrType(o2::base::PropagatorImpl::MatCorrType::USEMatCorrLUT); - LOG(debug) << "Bz: " << o2::base::Propagator::Instance()->getNominalBz(); + LOG(debug) << "Bz: " << o2::base::Propagator::Instance()->getNominalBz(); mTracker.setBz(o2::base::Propagator::Instance()->getNominalBz()); auto pattIt = ITSpatt.begin(); diff --git a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx index 1888b055df19d..546321029a130 100644 --- a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx @@ -40,7 +40,7 @@ DataProcessorSpec getStrangenessTrackingWriterSpec() }; auto inpStTrkID = InputSpec{"strangetracks", "STK", "STRTRACKS", 0}; - auto inpClusAtt = InputSpec{"clusupdates", "STK", "CLUSUPDATES",0}; + auto inpClusAtt = InputSpec{"clusupdates", "STK", "CLUSUPDATES", 0}; return MakeRootTreeWriterSpec("strangenesstracking-writer", "o2_strange_tracks.root", diff --git a/Detectors/StrangenessTracking/workflow/src/strangeness-tracking-workflow.cxx b/Detectors/StrangenessTracking/workflow/src/strangeness-tracking-workflow.cxx index c48069d534019..ddfae84841129 100644 --- a/Detectors/StrangenessTracking/workflow/src/strangeness-tracking-workflow.cxx +++ b/Detectors/StrangenessTracking/workflow/src/strangeness-tracking-workflow.cxx @@ -24,7 +24,6 @@ using namespace o2::framework; using namespace o2::strangeness_tracking; - void customize(std::vector& policies) { o2::raw::HBFUtilsInitializer::addNewTimeSliceCallback(policies); From 8a98d94265245f2ead28b4b63d23b27c329818c3 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Mon, 5 Dec 2022 18:00:36 +0100 Subject: [PATCH 31/36] Fix clang for linkdef --- .../tracking/src/StrangenessTrackingLinkDef.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingLinkDef.h b/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingLinkDef.h index 3abdac69f73a0..25221e0dd6ea9 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingLinkDef.h +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingLinkDef.h @@ -16,14 +16,13 @@ #pragma link off all functions; #pragma link C++ class o2::strangeness_tracking::StrangenessTrackingParamConfig + ; -#pragma link C++ class o2::conf::ConfigurableParamHelper + ; +#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::strangeness_tracking::StrangenessTrackingParamConfig> + ; #pragma link C++ struct o2::strangeness_tracking::ClusAttachments + ; #pragma link C++ struct o2::strangeness_tracking::StrangeTrack + ; #pragma link C++ class o2::strangeness_tracking::IndexTableUtils + ; -#pragma link C++ class std::vector + ; -#pragma link C++ class std::vector + ; -#pragma link C++ class std::vector + ; - +#pragma link C++ class std::vector < o2::strangeness_tracking::ClusAttachments> + ; +#pragma link C++ class std::vector < o2::strangeness_tracking::StrangeTrack> + ; +#pragma link C++ class std::vector < o2::strangeness_tracking::IndexTableUtils> + ; #endif From e6ab8ec2e06b6cefe71195aa9a677d06a8cd4123 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Mon, 5 Dec 2022 17:03:36 +0000 Subject: [PATCH 32/36] Please consider the following formatting changes --- .../Reconstruction/src/ReconstructionDataFormatsLinkDef.h | 3 +-- Detectors/StrangenessTracking/macros/XiTrackingStudy.C | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/DataFormats/Reconstruction/src/ReconstructionDataFormatsLinkDef.h b/DataFormats/Reconstruction/src/ReconstructionDataFormatsLinkDef.h index da3f5ac1ca0c0..e26510b5723d5 100644 --- a/DataFormats/Reconstruction/src/ReconstructionDataFormatsLinkDef.h +++ b/DataFormats/Reconstruction/src/ReconstructionDataFormatsLinkDef.h @@ -24,8 +24,7 @@ #pragma link C++ class o2::track::TrackParCovD + ; #pragma link C++ class o2::track::TrackParCov + ; #pragma link C++ class o2::track::TrackParametrizationWithError < float> + ; -#pragma link C++ class std::vector > + ; - +#pragma link C++ class std::vector < o2::track::TrackParametrizationWithError < float>> + ; #pragma link C++ class o2::track::TrackParametrizationWithError < double> + ; #pragma link C++ class o2::track::TrackParFwd + ; diff --git a/Detectors/StrangenessTracking/macros/XiTrackingStudy.C b/Detectors/StrangenessTracking/macros/XiTrackingStudy.C index e1886a33b315b..ce2d35dd18889 100644 --- a/Detectors/StrangenessTracking/macros/XiTrackingStudy.C +++ b/Detectors/StrangenessTracking/macros/XiTrackingStudy.C @@ -83,7 +83,6 @@ void XiTrackingStudy(std::string path) } } - TH2D* hHyperhisto = new TH2D("histo hyperV0", ";#it{p}_{T} (GeV/#it{c}); Radius^2 (cm) ; Counts", 20, 1, 10, 30, 1, 900); TH1D* hResV0histo = new TH1D("pT resolution before hypertracking", ";(#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, -0.2, 0.2); TH1D* hResHyperhisto = new TH1D("pT resolution after hypertracking", ";(#it{p}_{T}^{gen} - #it{p}_{T}^{rec})/#it{p}_{T}^{gen}; Counts", 20, -0.2, 0.2); From c560aa6ba1dcc4860a1acd040b1ef62f574db569 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Mon, 5 Dec 2022 18:30:40 +0100 Subject: [PATCH 33/36] Fix file headers --- .../StrangenessTracking/macros/XiTrackingStudy.C | 13 +++++++++++++ .../StrangenessTrackingConfigParam.h | 2 ++ .../tracking/src/StrangenessTrackingConfigParam.cxx | 2 ++ .../StrangenessTrackingSpec.h | 2 ++ .../StrangenessTrackingWriterSpec.h | 4 +++- .../workflow/src/StrangenessTrackingSpec.cxx | 2 ++ .../workflow/src/StrangenessTrackingWriterSpec.cxx | 3 ++- 7 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Detectors/StrangenessTracking/macros/XiTrackingStudy.C b/Detectors/StrangenessTracking/macros/XiTrackingStudy.C index ce2d35dd18889..7e3ff8c82b1b6 100644 --- a/Detectors/StrangenessTracking/macros/XiTrackingStudy.C +++ b/Detectors/StrangenessTracking/macros/XiTrackingStudy.C @@ -1,3 +1,16 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// \file XiTrackingStudy.C +/// \brief Simple macro to check Xi strange tracks + #if !defined(CLING) || defined(ROOTCLING) #include "ReconstructionDataFormats/PID.h" #include "ReconstructionDataFormats/V0.h" diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h index db4374c473b09..5af773122691b 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/StrangenessTrackingConfigParam.h @@ -8,6 +8,8 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +/// \file StrangenessTrackingConfigParam.h +/// \brief #ifndef ALICEO2_STRANGENESS_TRACKING_PARAM_H_ #define ALICEO2_STRANGENESS_TRACKING_PARAM_H_ diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingConfigParam.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingConfigParam.cxx index 4a1128e1bb4bd..9f324b9f5db0c 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingConfigParam.cxx +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTrackingConfigParam.cxx @@ -8,6 +8,8 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +/// \file StrangenessTrackingConfigParam.cxx +/// \brief #include "StrangenessTracking/StrangenessTrackingConfigParam.h" diff --git a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingSpec.h b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingSpec.h index 477289afddf4d..9b109d2d8706b 100644 --- a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingSpec.h +++ b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingSpec.h @@ -8,6 +8,8 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +/// \file StrangenessTrackingSpec.h +/// \brief #ifndef O2_STRANGENESS_SPEC_H #define O2_STRANGENESS_SPEC_H diff --git a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingWriterSpec.h b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingWriterSpec.h index ae38e2a3567ed..2cd3262370eb5 100644 --- a/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingWriterSpec.h +++ b/Detectors/StrangenessTracking/workflow/include/StrangenessTrackingWorkflow/StrangenessTrackingWriterSpec.h @@ -9,7 +9,9 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// @file TrackWriterSpec.h +/// \file StrangenessTrackingWriterSpec.h +/// \brief +/// #ifndef O2_STRANGENESSTRACKINGWRITER #define O2_STRANGENESSTRACKINGWRITER diff --git a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx index 13e7ea4ca954f..9974a9f55d1fd 100644 --- a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingSpec.cxx @@ -8,6 +8,8 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +/// \file StrangenessTrackingSpec.cxx +/// \brief #include "TGeoGlobalMagField.h" #include "Framework/ConfigParamRegistry.h" diff --git a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx index 546321029a130..a7409b1cbb413 100644 --- a/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx +++ b/Detectors/StrangenessTracking/workflow/src/StrangenessTrackingWriterSpec.cxx @@ -9,7 +9,8 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// @file StrangenessWriterSpec.cxx +/// \file StrangenessWriterSpec.cxx +/// \brief #include #include "StrangenessTrackingWorkflow/StrangenessTrackingWriterSpec.h" From 06c5defccc5bee27eb7920b114fab3a0ccbca024 Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Mon, 5 Dec 2022 19:40:57 +0100 Subject: [PATCH 34/36] Clear typo --- .../StrangenessTracking/tracking/src/StrangenessTracker.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx index 8eda53becd4b7..d25c18686498c 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx @@ -1,7 +1,7 @@ // Copyright 2019-2020 CERN and copyright holders of ALICE O2. // See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. // All rights not expressly granted are reserved. -// StrangenessTracker +// // This software is distributed under the terms of the GNU General Public // License v3 (GPL Version 3), copied verbatim in the file "COPYING". // From 305d0e40c6b37ad20ea586e42dc8308078495a2b Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Tue, 6 Dec 2022 11:52:43 +0100 Subject: [PATCH 35/36] Make macro compile + braces after if statements --- .../StrangenessTracking/macros/CMakeLists.txt | 1 + .../macros/XiTrackingStudy.C | 3 +- .../StrangenessTracking/IndexTableUtils.h | 6 ++-- .../tracking/src/StrangenessTracker.cxx | 34 ++++++++++++------- 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/Detectors/StrangenessTracking/macros/CMakeLists.txt b/Detectors/StrangenessTracking/macros/CMakeLists.txt index 17a83b26781ac..5de6df71aa8fb 100644 --- a/Detectors/StrangenessTracking/macros/CMakeLists.txt +++ b/Detectors/StrangenessTracking/macros/CMakeLists.txt @@ -6,4 +6,5 @@ o2_add_test_root_macro(XiTrackingStudy.C O2::DataFormatsITSMFT O2::DataFormatsITS O2::SimulationDataFormat + O2::StrangenessTracking LABELS strangeness-tracking) \ No newline at end of file diff --git a/Detectors/StrangenessTracking/macros/XiTrackingStudy.C b/Detectors/StrangenessTracking/macros/XiTrackingStudy.C index 7e3ff8c82b1b6..6c6fc8c23b3e2 100644 --- a/Detectors/StrangenessTracking/macros/XiTrackingStudy.C +++ b/Detectors/StrangenessTracking/macros/XiTrackingStudy.C @@ -11,7 +11,7 @@ /// \file XiTrackingStudy.C /// \brief Simple macro to check Xi strange tracks -#if !defined(CLING) || defined(ROOTCLING) +#if !defined(__CLING__) || defined(__ROOTCLING__) #include "ReconstructionDataFormats/PID.h" #include "ReconstructionDataFormats/V0.h" #include "SimulationDataFormat/MCTruthContainer.h" @@ -42,6 +42,7 @@ #include "DetectorsVertexing/DCAFitterN.h" #include "StrangenessTracking/StrangenessTracker.h" + #endif using GIndex = o2::dataformats::VtxTrackIndex; diff --git a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h index fbf33d624af47..bfa2362155983 100644 --- a/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h +++ b/Detectors/StrangenessTracking/tracking/include/StrangenessTracking/IndexTableUtils.h @@ -69,11 +69,13 @@ inline std::vector IndexTableUtils::getBinRect(float eta, float phi, float int maxPhiBin = getPhiBin(phi + deltaPhi); for (int iPhi{minPhiBin}; iPhi <= maxPhiBin; iPhi++) { - if (iPhi >= mPhiBins) + if (iPhi >= mPhiBins) { break; + } for (int iEta{minEtaBin}; iEta <= maxEtaBin; iEta++) { - if (iEta >= mEtaBins) + if (iEta >= mEtaBins) { break; + } idxVec.push_back(iEta + mEtaBins * iPhi); } } diff --git a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx index d25c18686498c..6e01694bdaa01 100644 --- a/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx +++ b/Detectors/StrangenessTracking/tracking/src/StrangenessTracker.cxx @@ -78,8 +78,9 @@ void StrangenessTracker::process() alphaV0 > 0 ? posTrack.setAbsCharge(2) : negTrack.setAbsCharge(2); V0 correctedV0; // recompute V0 for Hypertriton - if (!recreateV0(posTrack, negTrack, correctedV0)) + if (!recreateV0(posTrack, negTrack, correctedV0)) { continue; + } mStrangeTrack.mPartType = kV0; @@ -189,17 +190,19 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR) break; } } - if (!isDauUpdated) + if (!isDauUpdated) { break; // no daughter track updated, stop the loop - + } nUpdates++; } - if (nUpdates == nUpdOld) + if (nUpdates == nUpdOld) { break; // no track updated, stop the loop + } } - if (nUpdates < trackClusters.size() || motherClusters.size() < nMinClusMother) + if (nUpdates < trackClusters.size() || motherClusters.size() < nMinClusMother) { return false; + } o2::track::TrackParCov motherTrackClone = mStrangeTrack.mMother; // clone and reset covariance for final topology refit motherTrackClone.resetCovariance(); @@ -208,8 +211,9 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR) std::reverse(motherClusters.begin(), motherClusters.end()); for (auto& clus : motherClusters) { - if (!updateTrack(clus, motherTrackClone)) + if (!updateTrack(clus, motherTrackClone)) { break; + } } LOG(debug) << "Inward-outward refit finished, starting final topology refit"; @@ -267,13 +271,15 @@ bool StrangenessTracker::updateTrack(const ITSCluster& clus, o2::track::TrackPar auto stringOld = track.asString(); LOG(debug) << "Track before update, Y2: " << track.getSigmaY2() << ", Z2: " << track.getSigmaZ2(); - if (!track.rotate(alpha)) + if (!track.rotate(alpha)) { return false; + } LOG(debug) << "Track rotated, Y2: " << track.getSigmaY2() << ", Z2: " << track.getSigmaZ2(); - if (!propInstance->propagateToX(track, x, getBz(), o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, mCorrType)) + if (!propInstance->propagateToX(track, x, getBz(), o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, mCorrType)) { return false; + } auto stringNew = track.asString(); LOG(debug) << "Track after propagation, Y2: " << track.getSigmaY2() << ", Z2: " << track.getSigmaZ2(); @@ -282,16 +288,19 @@ bool StrangenessTracker::updateTrack(const ITSCluster& clus, o2::track::TrackPar float thick = layer < 3 ? 0.005 : 0.01; constexpr float radl = 9.36f; // Radiation length of Si [cm] constexpr float rho = 2.33f; // Density of Si [g/cm^3] - if (!track.correctForMaterial(thick, thick * rho * radl)) + if (!track.correctForMaterial(thick, thick * rho * radl)) { return false; + } } auto chi2 = std::abs(track.getPredictedChi2(clus)); // abs to be understood LOG(debug) << "Chi2: " << chi2; - if (chi2 > mStrParams->mMaxChi2 || chi2 < 0) + if (chi2 > mStrParams->mMaxChi2 || chi2 < 0) { return false; + } - if (!track.update(clus)) + if (!track.update(clus)) { return false; + } return true; } @@ -305,8 +314,9 @@ bool StrangenessTracker::recreateV0(const o2::track::TrackParCov& posTrack, cons } catch (std::runtime_error& e) { return false; } - if (!nCand || !mFitterV0.propagateTracksToVertex()) + if (!nCand || !mFitterV0.propagateTracksToVertex()) { return false; + } const auto& v0XYZ = mFitterV0.getPCACandidatePos(); From 9568f59bfc6be425d50aa5dda91c2aafca30933e Mon Sep 17 00:00:00 2001 From: fmazzasc Date: Tue, 6 Dec 2022 12:04:47 +0100 Subject: [PATCH 36/36] Remove extra space --- Detectors/StrangenessTracking/macros/XiTrackingStudy.C | 1 - 1 file changed, 1 deletion(-) diff --git a/Detectors/StrangenessTracking/macros/XiTrackingStudy.C b/Detectors/StrangenessTracking/macros/XiTrackingStudy.C index 6c6fc8c23b3e2..6e666df11177c 100644 --- a/Detectors/StrangenessTracking/macros/XiTrackingStudy.C +++ b/Detectors/StrangenessTracking/macros/XiTrackingStudy.C @@ -42,7 +42,6 @@ #include "DetectorsVertexing/DCAFitterN.h" #include "StrangenessTracking/StrangenessTracker.h" - #endif using GIndex = o2::dataformats::VtxTrackIndex;