3232#include " DetectorsVertexing/SVertexHypothesis.h"
3333#include " StrangenessTracking/StrangenessTracker.h"
3434#include " DataFormatsTPC/TrackTPC.h"
35- #include < numeric>
36- #include < algorithm>
3735#include " GPUO2InterfaceRefit.h"
3836#include " TPCFastTransform.h"
3937#include " DataFormatsTPC/PIDResponse.h"
38+ #include " CommonUtils/TreeStreamRedirector.h"
39+ #include " CommonUtils/EnumFlags.h"
40+
41+ #include < numeric>
42+ #include < algorithm>
43+ #include < span>
44+ #include < memory>
4045
4146namespace o2
4247{
@@ -104,6 +109,7 @@ class SVertexer
104109 bool hasTPC = false ;
105110 int8_t nITSclu = -1 ;
106111 bool compatibleProton = false ; // dE/dx compatibility with proton hypothesis (FIXME: use better, uint8_t compat mask?)
112+ float trk2beam = 0 .;
107113 bool hasITS () const
108114 {
109115 return nITSclu > 0 ;
@@ -117,6 +123,7 @@ class SVertexer
117123 void setEnableCascades (bool v) { mEnableCascades = v; }
118124 void setEnable3BodyDecays (bool v) { mEnable3BodyDecays = v; }
119125 void init ();
126+ void finalize ();
120127 void process (const o2::globaltracking::RecoContainer& recoTracks, o2::framework::ProcessingContext& pc);
121128 void produceOutput (o2::framework::ProcessingContext& pc);
122129 int getNV0s () const { return mNV0s ; }
@@ -150,17 +157,47 @@ class SVertexer
150157 std::array<size_t , 3 > getNFitterCalls () const ;
151158 void setSources (GIndex::mask_t src) { mSrc = src; }
152159
160+ void setDebug (const std::string& s) { mDebugFlags .set (s); }
161+
153162 private:
154163 template <class TVI , class TCI , class T3I , class TR >
155- void extractPVReferences (const TVI& v0s, TR& vtx2V0Refs, const TCI& cascades, TR& vtx2CascRefs, const T3I& vtxs3, TR& vtx2body3Refs);
156- bool checkV0 (const TrackCand& seed0, const TrackCand& seed1, int iP, int iN, int ithread);
164+ void
165+ extractPVReferences (const TVI& v0s, TR& vtx2V0Refs, const TCI& cascades, TR& vtx2CascRefs, const T3I& vtxs3, TR& vtx2body3Refs);
166+
167+ enum class CheckV0Status : uint8_t {
168+ None = 0 ,
169+ OK,
170+ RejTPCTgl,
171+ RejTPC2Beam,
172+ RejTPCDCA2,
173+ RejFitter,
174+ RejMinR2ToMeanVertex,
175+ RejCausality,
176+ RejProp,
177+ RejPt2,
178+ RejTgl,
179+ RejHypo,
180+ RejCascade,
181+ RejDCA2,
182+ RejNoCand,
183+ RejNoCandNo3Body,
184+ };
185+ CheckV0Status checkV0 (const TrackCand& seed0, const TrackCand& seed1, int iP, int iN, int ithread);
157186 int checkCascades (const V0Index& v0Idx, const V0& v0, float rv0, std::array<float , 3 > pV0, float p2V0, int avoidTrackID, int posneg, VBracket v0vlist, int ithread);
158187 int check3bodyDecays (const V0Index& v0Idx, const V0& v0, float rv0, std::array<float , 3 > pV0, float p2V0, int avoidTrackID, int posneg, VBracket v0vlist, int ithread);
159188 void setupThreads ();
160189 void buildT2V (const o2::globaltracking::RecoContainer& recoTracks);
161190 void updateTimeDependentParams ();
162191 bool acceptTrack (const GIndex gid, const o2::track::TrackParCov& trc) const ;
163- bool processTPCTrack (const o2::tpc::TrackTPC& trTPC, GIndex gid, int vtxid);
192+
193+ enum class ProcessTPCTrackStatus : uint8_t {
194+ Constrained,
195+ OK,
196+ RejMaxX,
197+ RejCorr,
198+ Rej2Beam,
199+ };
200+ ProcessTPCTrackStatus processTPCTrack (const o2::tpc::TrackTPC& trTPC, GIndex gid, int vtxid);
164201 float correctTPCTrack (TrackCand& trc, const o2::tpc::TrackTPC& tTPC, float tmus, float tmusErr) const ;
165202
166203 uint64_t getPairIdx (GIndex id1, GIndex id2) const
@@ -224,6 +261,57 @@ class SVertexer
224261 bool mEnableCascades = true ;
225262 bool mEnable3BodyDecays = false ;
226263 bool mUseMC = false ;
264+
265+ // / Debug information
266+ enum class SVDebug : uint8_t {
267+ TPCCandPool, // check which TPC tracks do not go into the pool
268+ Unassigned, // check unassigned tracks
269+ CheckV0, // checkV0 status
270+ };
271+ utils::EnumFlags<SVDebug> mDebugFlags ;
272+ std::unique_ptr<utils::TreeStreamRedirector> mDebugStream ;
273+
274+ #ifdef SVERTEXER_DEBUG
275+ template <bool log = true , typename ... Args>
276+ requires (sizeof ...(Args) % 2 == 0 && sizeof...(Args) > 0)
277+ void debugTree(SVDebug f, const char * tname, Args&&... args)
278+ {
279+ static struct LogLogThrottler {
280+ size_t evCount{0 };
281+ size_t nextLog{1 };
282+ bool needToLog ()
283+ {
284+ if (++evCount > nextLog) {
285+ nextLog *= 2 ;
286+ return true ;
287+ }
288+ return false ;
289+ }
290+ } logger;
291+ if (mDebugFlags [f]) {
292+ LOG_IF (info, logger.needToLog ()) << " debugTree: " << tname << " dumped entries " << logger.evCount ;
293+ auto & stream = (*mDebugStream ) << tname;
294+ [&]<std::size_t ... I>(std::index_sequence<I...>) {
295+ const char * names[] = {std::get<2 * I>(std::forward_as_tuple (args...))...};
296+ auto values = std::forward_as_tuple (std::get<2 * I + 1 >(std::forward_as_tuple (args...))...);
297+ ((stream << names[I] << [](auto && val) -> decltype (auto ) {
298+ if constexpr (std::is_enum_v<std::decay_t <decltype (val)>>) {
299+ return static_cast <std::underlying_type_t <std::decay_t <decltype (val)>>>(val);
300+ } else {
301+ return val;
302+ }
303+ }(std::get<I>(values))),
304+ ...);
305+ }(std::make_index_sequence<sizeof ...(Args) / 2 >{});
306+ stream << " \n " ;
307+ }
308+ }
309+ #else // turn this into a no-op
310+ template <typename ... Args>
311+ void debugTree (SVDebug f, const char * tname, Args&&... args)
312+ {
313+ }
314+ #endif
227315};
228316
229317} // namespace vertexing
0 commit comments