Skip to content

Commit 9e152ee

Browse files
BongHwialibuild
andauthored
[PWGLF,Tutorial] Resonance Framework - introducing microTrack table (#10418)
Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent 9cf085d commit 9e152ee

File tree

5 files changed

+619
-13
lines changed

5 files changed

+619
-13
lines changed

PWGLF/DataModel/LFResonanceTables.h

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define PWGLF_DATAMODEL_LFRESONANCETABLES_H_
2424

2525
#include <cmath>
26+
#include <algorithm>
2627

2728
#include "Common/DataModel/PIDResponse.h"
2829
#include "Common/Core/RecoDecay.h"
@@ -330,6 +331,148 @@ DECLARE_SOA_DYNAMIC_COLUMN(Sign, sign,
330331
});
331332

332333
} // namespace resodaughter
334+
335+
namespace resodmciroaughter
336+
{
337+
// micro track for primary pion
338+
339+
/// @brief Save TPC & TOF nSigma info with 8-bit variable
340+
struct PidNSigma {
341+
uint8_t flag;
342+
343+
/// @brief Constructor: Convert TPC & TOF values and save
344+
PidNSigma(float TPCnSigma, float TOFnSigma, bool hasTOF)
345+
{
346+
uint8_t TPCencoded = encodeNSigma(TPCnSigma);
347+
uint8_t TOFencoded = hasTOF ? encodeNSigma(TOFnSigma) : 0x0F; // If TOF is not available, set all 4 bits to 1
348+
flag = (TPCencoded << 4) | TOFencoded; // Upper 4 bits = TPC, Lower 4 bits = TOF
349+
}
350+
351+
/// @brief Encode 0.2 sigma interval to 0~10 range
352+
static uint8_t encodeNSigma(float nSigma)
353+
{
354+
float encoded = std::abs((nSigma - 1.5) / 0.2); // Convert to 0~10 range
355+
encoded = std::min(std::max(encoded, 0.f), 10.f); // Clamp to 0~10 range
356+
return (uint8_t)round(encoded);
357+
}
358+
359+
/// @brief Decode 0~10 value to original 1.5~3.5 sigma range
360+
static float decodeNSigma(uint8_t encoded)
361+
{
362+
encoded = std::min(encoded, (uint8_t)10); // Safety check, should not be needed if encode is used properly
363+
return (encoded * 0.2) + 1.5;
364+
}
365+
366+
/// @brief Check if TOF info is available
367+
bool hasTOF() const
368+
{
369+
return (flag & 0x0F) != 0x0F; // Check if lower 4 bits are not all 1
370+
}
371+
372+
/// @brief Restore TPC nSigma value
373+
static float getTPCnSigma(uint8_t encoded)
374+
{
375+
return decodeNSigma((encoded >> 4) & 0x0F); // Extract upper 4 bits
376+
}
377+
378+
/// @brief Restore TOF nSigma value (if not available, return NAN)
379+
static float getTOFnSigma(uint8_t encoded)
380+
{
381+
uint8_t TOFencoded = encoded & 0x0F; // Extract lower 4 bits
382+
return (TOFencoded == 0x0F) ? NAN : decodeNSigma(TOFencoded);
383+
}
384+
385+
/// @brief Operator to convert to uint8_t (automatic conversion support)
386+
operator uint8_t() const
387+
{
388+
return flag;
389+
}
390+
};
391+
392+
DECLARE_SOA_COLUMN(PidNSigmaPiFlag, pidNSigmaPiFlag, uint8_t); //! Pid flag for the track as Pion
393+
DECLARE_SOA_COLUMN(PidNSigmaKaFlag, pidNSigmaKaFlag, uint8_t); //! Pid flag for the track as Kaon
394+
DECLARE_SOA_COLUMN(PidNSigmaPrFlag, pidNSigmaPrFlag, uint8_t); //! Pid flag for the track as Proton
395+
DECLARE_SOA_COLUMN(TrackSelectionFlags, trackSelectionFlags, int8_t); //! Track selection flags
396+
DECLARE_SOA_DYNAMIC_COLUMN(HasTOF, hasTOF,
397+
[](uint8_t pidNSigmaFlags) -> bool {
398+
return (pidNSigmaFlags & 0x0F) != 0x0F;
399+
});
400+
401+
/// @brief DCAxy & DCAz selection flag
402+
struct ResoMicroTrackSelFlag {
403+
uint8_t flag; // Flag for DCAxy & DCAz selection (8-bit variable)
404+
405+
/// @brief Default constructor
406+
ResoMicroTrackSelFlag()
407+
{
408+
flag = 0x00;
409+
}
410+
411+
/// @brief Constructor: Convert DCAxy/DCAz and save (default 1~15 values)
412+
ResoMicroTrackSelFlag(float DCAxy, float DCAz)
413+
{
414+
uint8_t DCAxyEncoded = encodeDCA(DCAxy);
415+
uint8_t DCAzEncoded = encodeDCA(DCAz);
416+
flag = (DCAxyEncoded << 4) | DCAzEncoded; // Upper 4 bits = DCAxy, Lower 4 bits = DCAz
417+
}
418+
419+
/// @brief Convert DCA to 1~15 steps (0 value is not used)
420+
static uint8_t encodeDCA(float DCA)
421+
{
422+
for (uint8_t i = 1; i < 15; i++) {
423+
if (DCA < i * 0.1f)
424+
return i;
425+
}
426+
return 15;
427+
}
428+
429+
/// @brief Operator to convert to `uint8_t` (for SOA storage)
430+
operator uint8_t() const
431+
{
432+
return flag;
433+
}
434+
435+
/// @brief Get DCAxy value
436+
uint8_t getDCAxyFlag() const
437+
{
438+
return (flag >> 4) & 0x0F; // Extract upper 4 bits
439+
}
440+
441+
/// @brief Get DCAz value
442+
uint8_t getDCAzFlag() const
443+
{
444+
return flag & 0x0F; // Extract lower 4 bits
445+
}
446+
447+
/// @brief Apply DCAxy tight cut (0 value)
448+
void setDCAxy0()
449+
{
450+
flag &= 0x0F; // Set DCAxy to 0 (delete upper 4 bits)
451+
}
452+
453+
/// @brief Apply DCAz tight cut (0 value)
454+
void setDCAz0()
455+
{
456+
flag &= 0xF0; // Set DCAz to 0 (delete lower 4 bits)
457+
}
458+
/// @brief Decode DCAxy
459+
static float decodeDCAxy(uint8_t flag_saved)
460+
{
461+
uint8_t DCAxyFlag = (flag_saved >> 4) & 0x0F; // Extract upper 4 bits
462+
return (DCAxyFlag == 0) ? 0.0f : DCAxyFlag * 0.1f; // Tight cut(0) is 0.0, otherwise flag * 0.1 cm
463+
}
464+
465+
/// @brief Decode DCAz
466+
static float decodeDCAz(uint8_t flag_saved)
467+
{
468+
uint8_t DCAzFlag = flag_saved & 0x0F; // Extract lower 4 bits
469+
return (DCAzFlag == 0) ? 0.0f : DCAzFlag * 0.1f; // Tight cut(0) is 0.0, otherwise flag * 0.1 cm
470+
}
471+
};
472+
473+
DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, [](float px, float py) -> float { return RecoDecay::sqrtSumOfSquares(px, py); });
474+
} // namespace resodmciroaughter
475+
333476
DECLARE_SOA_TABLE(ResoTracks, "AOD", "RESOTRACK",
334477
o2::soa::Index<>,
335478
resodaughter::ResoCollisionId,
@@ -373,6 +516,32 @@ DECLARE_SOA_TABLE(ResoTracks, "AOD", "RESOTRACK",
373516
resodaughter::Sign<resodaughter::TrackFlags>);
374517
using ResoTrack = ResoTracks::iterator;
375518

519+
DECLARE_SOA_TABLE(ResoMicroTracks, "AOD", "RESOMICROTRACK",
520+
o2::soa::Index<>,
521+
resodaughter::ResoCollisionId,
522+
resodaughter::TrackId,
523+
resodaughter::Px,
524+
resodaughter::Py,
525+
resodaughter::Pz,
526+
resodmciroaughter::PidNSigmaPiFlag,
527+
resodmciroaughter::PidNSigmaKaFlag,
528+
resodmciroaughter::PidNSigmaPrFlag,
529+
resodmciroaughter::TrackSelectionFlags,
530+
resodaughter::TrackFlags,
531+
// Dynamic columns
532+
resodmciroaughter::Pt<resodaughter::Px, resodaughter::Py>,
533+
resodaughter::Eta<resodaughter::Px, resodaughter::Py, resodaughter::Pz>,
534+
resodaughter::Phi<resodaughter::Px, resodaughter::Py>,
535+
resodaughter::PassedITSRefit<resodaughter::TrackFlags>,
536+
resodaughter::PassedTPCRefit<resodaughter::TrackFlags>,
537+
resodaughter::IsGlobalTrackWoDCA<resodaughter::TrackFlags>,
538+
resodaughter::IsGlobalTrack<resodaughter::TrackFlags>,
539+
resodaughter::IsPrimaryTrack<resodaughter::TrackFlags>,
540+
resodaughter::IsPVContributor<resodaughter::TrackFlags>,
541+
resodmciroaughter::HasTOF<resodmciroaughter::PidNSigmaPiFlag>,
542+
resodaughter::Sign<resodaughter::TrackFlags>);
543+
using ResoMicroTrack = ResoMicroTracks::iterator;
544+
376545
// For DF mixing study
377546
DECLARE_SOA_TABLE(ResoTrackDFs, "AOD", "RESOTRACKDF",
378547
o2::soa::Index<>,

0 commit comments

Comments
 (0)