forked from AliceO2Group/O2Physics
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutilsUpcHf.h
More file actions
167 lines (149 loc) · 7.33 KB
/
utilsUpcHf.h
File metadata and controls
167 lines (149 loc) · 7.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// 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 utilsUpcHf.h
/// \brief Utility functions for Ultra-Peripheral Collision (UPC) analysis in Heavy Flavor physics
///
/// \author Minjung Kim <minjung.kim@cern.ch>, CERN
/// \author Ran Tu <ran.tu@cern.ch>, Fudan University, GSI Darmstadt
#ifndef PWGHF_UTILS_UTILSUPCHF_H_
#define PWGHF_UTILS_UTILSUPCHF_H_
#include "PWGUD/Core/SGCutParHolder.h"
#include "PWGUD/Core/SGSelector.h"
#include "PWGUD/Core/UDHelpers.h"
#include <Framework/Configurable.h>
#include <string>
#include <type_traits>
namespace o2::analysis::hf_upc
{
/// \brief Use TrueGap enum from SGSelector for gap type classification
using o2::aod::sgselector::TrueGap;
/// \brief Configurable group for UPC gap determination thresholds
struct HfUpcGapThresholds : o2::framework::ConfigurableGroup {
std::string prefix = "upc"; // JSON group name
o2::framework::Configurable<int> fNDtColl{"fNDtColl", 1, "Number of standard deviations to consider in BC range"};
o2::framework::Configurable<int> fNBCsMin{"fNBCsMin", 2, "Minimum number of BCs to consider in BC range"};
o2::framework::Configurable<int> fNPVCsMin{"fNPVCsMin", 2, "Minimum number of PV contributors"};
o2::framework::Configurable<int> fNPVCsMax{"fNPVCsMax", 1000, "Maximum number of PV contributors"};
o2::framework::Configurable<float> fFITTimeMax{"fFITTimeMax", 34, "Maximum time in FIT"};
o2::framework::Configurable<float> fv0aThreshold{"fv0aThreshold", 100.0f, "FV0-A amplitude threshold for UPC gap determination (a.u.)"};
o2::framework::Configurable<float> ft0aThreshold{"ft0aThreshold", 100.0f, "FT0-A amplitude threshold for UPC gap determination (a.u.)"};
o2::framework::Configurable<float> ft0cThreshold{"ft0cThreshold", 50.0f, "FT0-C amplitude threshold for UPC gap determination (a.u.)"};
o2::framework::Configurable<float> zdcThreshold{"zdcThreshold", 1.0f, "ZDC energy threshold for UPC gap determination (a.u.)"};
};
/// \brief Default thresholds for gap determination
namespace defaults
{
constexpr float AmplitudeThresholdFV0A = 100.0f; ///< Amplitude threshold for FV0-A (a.u.)
constexpr float AmplitudeThresholdFT0A = 100.0f; ///< Amplitude threshold for FT0-A (a.u.)
constexpr float AmplitudeThresholdFT0C = 50.0f; ///< Amplitude threshold for FT0-C (a.u.)
constexpr float MaxFITTime = 4.0f; ///< Maximum FIT time (ns)
constexpr int NDtColl = 1000; ///< Time window for BC range (ns)
constexpr int MinNBCs = 7; ///< Minimum number of BCs to check
constexpr int MinNTracks = 0; ///< Minimum number of tracks
constexpr int MaxNTracks = 100; ///< Maximum number of tracks
} // namespace defaults
/// \brief Determine gap type using SGSelector with BC range checking
/// \tparam TCollision Collision type
/// \tparam TBCs BC table type
/// \param collision Collision object
/// \param bcs BC table
/// \param amplitudeThresholdFV0A Threshold for FV0-A (default: 100.0)
/// \param amplitudeThresholdFT0A Threshold for FT0-A (default: 100.0)
/// \param amplitudeThresholdFT0C Threshold for FT0-C (default: 50.0)
/// \return SelectionResult with gap type value and BC pointer
template <typename TCollision, typename TBCs>
inline auto determineGapType(TCollision const& collision,
TBCs const& bcs,
int nDtColl = defaults::NDtColl,
int nBCsMin = defaults::MinNBCs,
int nPVCsMin = defaults::MinNTracks,
int nPVCsMax = defaults::MaxNTracks,
float fITTimeMax = defaults::MaxFITTime,
float amplitudeThresholdFV0A = defaults::AmplitudeThresholdFV0A,
float amplitudeThresholdFT0A = defaults::AmplitudeThresholdFT0A,
float amplitudeThresholdFT0C = defaults::AmplitudeThresholdFT0C)
{
using BCType = std::decay_t<decltype(collision.template foundBC_as<TBCs>())>;
// Configure SGSelector thresholds
SGCutParHolder sgCuts;
sgCuts.SetNDtcoll(nDtColl);
sgCuts.SetMinNBCs(nBCsMin);
sgCuts.SetNTracks(nPVCsMin, nPVCsMax);
sgCuts.SetMaxFITtime(fITTimeMax);
sgCuts.SetFITAmpLimits({amplitudeThresholdFV0A, amplitudeThresholdFT0A, amplitudeThresholdFT0C});
// Get BC and BC range
if (!collision.has_foundBC()) {
return SelectionResult<BCType>{TrueGap::NoGap, nullptr};
}
const auto bc = collision.template foundBC_as<TBCs>();
const auto bcRange = udhelpers::compatibleBCs(collision, sgCuts.NDtcoll(), bcs, sgCuts.minNBCs());
// Create SGSelector instance and determine gap type with BC range checking
SGSelector sgSelector;
const auto sgResult = sgSelector.IsSelected(sgCuts, collision, bcRange, bc);
return sgResult;
}
/// \brief Determine gap type using SGSelector with BC range checking and HfUpcGapThresholds
/// \tparam TCollision Collision type
/// \tparam TBCs BC table type
/// \param collision Collision object
/// \param bcs BC table
/// \param thresholds HfUpcGapThresholds object containing all UPC thresholds
/// \return SelectionResult with gap type value and BC pointer
template <typename TCollision, typename TBCs>
inline auto determineGapType(TCollision const& collision,
TBCs const& bcs,
HfUpcGapThresholds const& thresholds)
{
return determineGapType(collision, bcs,
thresholds.fNDtColl.value,
thresholds.fNBCsMin.value,
thresholds.fNPVCsMin.value,
thresholds.fNPVCsMax.value,
thresholds.fFITTimeMax.value,
thresholds.fv0aThreshold.value,
thresholds.ft0aThreshold.value,
thresholds.ft0cThreshold.value);
}
/*
/// \brief Check if the gap type is a single-sided gap (SingleGapA or SingleGapC)
/// \param gap TrueGap enum value
/// \return true if single-sided gap, false otherwise
constexpr bool isSingleSidedGap(int gap) noexcept
{
return (gap == TrueGap::SingleGapA || gap == TrueGap::SingleGapC || gap == TrueGap::DoubleGap || gap == TrueGap::BadDoubleGap || gap == TrueGap::TrkOutOfRange || gap == TrueGap::NoUpc);
}
*/
/// \brief Get gap type name as string
/// \param gap TrueGap enum value
/// \return String representation of gap type
constexpr const char* getGapTypeName(int gap) noexcept
{
switch (gap) {
case TrueGap::NoGap:
return "NoGap";
case TrueGap::SingleGapA:
return "SingleGapA";
case TrueGap::SingleGapC:
return "SingleGapC";
case TrueGap::DoubleGap:
return "DoubleGap";
case TrueGap::NoUpc:
return "NoUpc";
case TrueGap::TrkOutOfRange:
return "TrkOutOfRange";
case TrueGap::BadDoubleGap:
return "BadDoubleGap";
default:
return "Unknown";
}
}
} // namespace o2::analysis::hf_upc
#endif // PWGHF_UTILS_UTILSUPCHF_H_