|
44 | 44 | #include <random> |
45 | 45 | #include <sstream> |
46 | 46 | #include <string> |
| 47 | +#include <unordered_set> |
47 | 48 | #include <vector> |
48 | 49 |
|
49 | 50 | using namespace o2; |
@@ -140,86 +141,94 @@ struct f1protoncorrelation { |
140 | 141 | // ------------------------- |
141 | 142 | void buildSystematicCuts() |
142 | 143 | { |
143 | | - // choices from your table/picture |
144 | | - const std::array<float, 2> optDcaxy{0.01f, 0.03f}; |
145 | | - const std::array<float, 2> optDcaz{0.01f, 0.03f}; |
146 | | - const std::array<int, 2> optNcrs{90, 100}; |
147 | | - const std::array<int, 2> optNcls{90, 100}; |
148 | | - |
149 | | - const std::array<float, 2> optCPA{0.99f, 0.995f}; |
150 | | - const std::array<float, 2> optRad{0.8f, 1.0f}; |
151 | | - const std::array<float, 2> optDcaDD{0.9f, 0.8f}; |
152 | | - const std::array<float, 2> optDcaV0{0.2f, 0.15f}; |
153 | | - const std::array<float, 2> optLife{16.f, 18.f}; |
154 | | - const std::array<float, 2> optDcaD1{0.06f, 0.08f}; |
155 | | - const std::array<float, 2> optDcaD2{0.06f, 0.08f}; |
156 | | - |
157 | | - // bit layout: |
158 | | - // primary: 4 bits (0..3) |
159 | | - // v0: 7 bits (4..10) |
160 | | - // pid: 3 bits (11..13) |
161 | | - // total: 14 bits -> 16384 combos |
162 | | - auto buildFromMask = [&](uint32_t m) -> SysCuts { |
| 144 | + // 3 options per cut: index 0 = DEFAULT, index 1/2 = variations |
| 145 | + // Fill these with the exact values you want (I used your def as index 0 + your old options as 1/2) |
| 146 | + const std::array<float, 3> optDcaxy{0.05f, 0.01f, 0.03f}; |
| 147 | + const std::array<float, 3> optDcaz{0.05f, 0.01f, 0.03f}; |
| 148 | + const std::array<int, 3> optNcrs{80, 90, 100}; |
| 149 | + const std::array<int, 3> optNcls{80, 90, 100}; |
| 150 | + |
| 151 | + const std::array<float, 3> optCPA{0.985f, 0.99f, 0.995f}; |
| 152 | + const std::array<float, 3> optRad{0.50f, 0.80f, 1.00f}; |
| 153 | + const std::array<float, 3> optDcaDD{1.00f, 0.90f, 0.80f}; |
| 154 | + const std::array<float, 3> optDcaV0{0.30f, 0.20f, 0.15f}; |
| 155 | + const std::array<float, 3> optLife{20.f, 16.f, 18.f}; |
| 156 | + const std::array<float, 3> optDcaD1{0.05f, 0.06f, 0.08f}; |
| 157 | + const std::array<float, 3> optDcaD2{0.05f, 0.06f, 0.08f}; |
| 158 | + |
| 159 | + // PID modes: also allow default (0) to appear in random variations |
| 160 | + const std::array<int, 3> optPidPi{0, 1, 2}; |
| 161 | + const std::array<int, 3> optPidK{0, 1, 2}; |
| 162 | + const std::array<int, 3> optPidP{0, 1, 2}; |
| 163 | + |
| 164 | + // Helper: build SysCuts from chosen indices (0..2) |
| 165 | + auto buildFromIdx = [&](int i0, int i1, int i2, int i3, |
| 166 | + int i4, int i5, int i6, int i7, int i8, int i9, int i10, |
| 167 | + int i11, int i12, int i13) -> SysCuts { |
163 | 168 | SysCuts c{}; |
164 | | - c.maxDcaxy = optDcaxy[(m >> 0) & 1u]; |
165 | | - c.maxDcaz = optDcaz[(m >> 1) & 1u]; |
166 | | - c.minTPCCrossedRows = optNcrs[(m >> 2) & 1u]; |
167 | | - c.minTPCClusters = optNcls[(m >> 3) & 1u]; |
168 | | - |
169 | | - c.minCPA = optCPA[(m >> 4) & 1u]; |
170 | | - c.minRadius = optRad[(m >> 5) & 1u]; |
171 | | - c.maxDcaDaughters = optDcaDD[(m >> 6) & 1u]; |
172 | | - c.maxDcaV0 = optDcaV0[(m >> 7) & 1u]; |
173 | | - c.maxLifetime = optLife[(m >> 8) & 1u]; |
174 | | - c.minDcaD1 = optDcaD1[(m >> 9) & 1u]; |
175 | | - c.minDcaD2 = optDcaD2[(m >> 10) & 1u]; |
176 | | - |
177 | | - c.pidPi = (m >> 11) & 1u; |
178 | | - c.pidK = (m >> 12) & 1u; |
179 | | - c.pidP = (m >> 13) & 1u; |
| 169 | + c.maxDcaxy = optDcaxy[i0]; |
| 170 | + c.maxDcaz = optDcaz[i1]; |
| 171 | + c.minTPCCrossedRows = optNcrs[i2]; |
| 172 | + c.minTPCClusters = optNcls[i3]; |
| 173 | + |
| 174 | + c.minCPA = optCPA[i4]; |
| 175 | + c.minRadius = optRad[i5]; |
| 176 | + c.maxDcaDaughters = optDcaDD[i6]; |
| 177 | + c.maxDcaV0 = optDcaV0[i7]; |
| 178 | + c.maxLifetime = optLife[i8]; |
| 179 | + c.minDcaD1 = optDcaD1[i9]; |
| 180 | + c.minDcaD2 = optDcaD2[i10]; |
| 181 | + |
| 182 | + c.pidPi = optPidPi[i11]; |
| 183 | + c.pidK = optPidK[i12]; |
| 184 | + c.pidP = optPidP[i13]; |
180 | 185 | return c; |
181 | 186 | }; |
182 | 187 |
|
183 | | - // DEFAULT (sysId=0): set to your baseline |
184 | | - SysCuts def{}; |
185 | | - def.maxDcaxy = 0.05f; |
186 | | - def.maxDcaz = 0.05f; |
187 | | - def.minTPCCrossedRows = 80; |
188 | | - def.minTPCClusters = 80; |
189 | | - |
190 | | - def.minCPA = 0.985f; |
191 | | - def.minRadius = 0.5f; |
192 | | - def.maxDcaDaughters = 1.0f; |
193 | | - def.maxDcaV0 = 0.3f; |
194 | | - def.maxLifetime = 20.f; |
195 | | - def.minDcaD1 = 0.05f; |
196 | | - def.minDcaD2 = 0.05f; |
197 | | - |
198 | | - def.pidPi = 0; |
199 | | - def.pidK = 0; |
200 | | - def.pidP = 0; |
201 | | - |
202 | | - std::vector<uint32_t> masks; |
203 | | - masks.reserve(16384); |
204 | | - for (uint32_t m = 0; m < 16384; ++m) { |
205 | | - masks.push_back(m); |
206 | | - } |
| 188 | + // sysId=0 must be strict default (all indices = 0) |
| 189 | + SysCuts def = buildFromIdx(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); |
207 | 190 |
|
208 | 191 | std::mt19937 rng(sysSeed); |
209 | | - std::shuffle(masks.begin(), masks.end(), rng); |
| 192 | + std::uniform_int_distribution<int> pick012(0, 2); |
| 193 | + |
| 194 | + // Optional: keep unique combinations (by packing indices in 2 bits each) |
| 195 | + auto packCode = [&](const std::array<int, 14>& idx) -> uint32_t { |
| 196 | + uint32_t code = 0u; |
| 197 | + for (int k = 0; k < 14; ++k) { |
| 198 | + code |= (uint32_t(idx[k] & 0x3) << (2 * k)); |
| 199 | + } |
| 200 | + return code; |
| 201 | + }; |
210 | 202 |
|
211 | 203 | sysCuts.clear(); |
212 | | - sysCuts.reserve(1 + nSysRand); |
213 | | - sysCuts.push_back(def); |
| 204 | + sysCuts.reserve(1 + (size_t)nSysRand); |
| 205 | + sysCuts.push_back(def); // sysId=0 |
| 206 | + |
| 207 | + std::unordered_set<uint32_t> used; |
| 208 | + used.reserve((size_t)nSysRand * 2); |
| 209 | + used.insert(0u); // all-default code |
| 210 | + |
| 211 | + const int nPick = std::max(0, (int)nSysRand); |
| 212 | + while ((int)sysCuts.size() < 1 + nPick) { |
| 213 | + |
| 214 | + std::array<int, 14> idx{}; |
| 215 | + for (int k = 0; k < 14; ++k) |
| 216 | + idx[k] = pick012(rng); |
| 217 | + |
| 218 | + uint32_t code = packCode(idx); |
| 219 | + if (!used.insert(code).second) |
| 220 | + continue; // already have this combination |
214 | 221 |
|
215 | | - const int nPick = std::min<int>(nSysRand, (int)masks.size()); |
216 | | - for (int i = 0, picked = 0; picked < nPick && i < (int)masks.size(); ++i) { |
217 | | - if (masks[i] == 0u) { // avoid trivial mask that can reproduce default |
| 222 | + // (optional) avoid generating exactly default again |
| 223 | + if (code == 0u) |
218 | 224 | continue; |
219 | | - } |
220 | | - sysCuts.push_back(buildFromMask(masks[i])); |
221 | | - ++picked; |
| 225 | + |
| 226 | + sysCuts.push_back(buildFromIdx( |
| 227 | + idx[0], idx[1], idx[2], idx[3], |
| 228 | + idx[4], idx[5], idx[6], idx[7], idx[8], idx[9], idx[10], |
| 229 | + idx[11], idx[12], idx[13])); |
222 | 230 | } |
| 231 | + |
223 | 232 | nSysTotal = (int)sysCuts.size(); |
224 | 233 | } |
225 | 234 |
|
@@ -598,7 +607,7 @@ struct f1protoncorrelation { |
598 | 607 | } |
599 | 608 | auto relative_momentum = getkstar(F1, Proton); |
600 | 609 | if (relative_momentum <= 0.5) { |
601 | | - histos.fill(HIST("hNsigmaProtonTPC"), protontrack.protonNsigmaTPC(), Proton.Pt()); |
| 610 | + histos.fill(HIST("hNsigmaProtonTPC"), protontrack.protonNsigmaTPC(), protontrack.protonNsigmaTOF(), Proton.Pt()); |
602 | 611 | } |
603 | 612 | histos.fill(HIST("h2SameEventPtCorrelation"), relative_momentum, F1.Pt(), Proton.Pt()); |
604 | 613 |
|
@@ -968,7 +977,8 @@ struct f1protoncorrelation { |
968 | 977 | Kaon.SetXYZM(f1track.f1d2Px(), f1track.f1d2Py(), f1track.f1d2Pz(), 0.493); |
969 | 978 | Kshort.SetXYZM(f1track.f1d3Px(), f1track.f1d3Py(), f1track.f1d3Pz(), 0.497); |
970 | 979 | KaonKshortPair = Kaon + Kshort; |
971 | | - |
| 980 | + if (F1.Pt() < lowPtF1 || F1.Pt() > 50.0) |
| 981 | + continue; |
972 | 982 | std::vector<int> activeSys; |
973 | 983 | activeSys.reserve((size_t)nSysTotal); |
974 | 984 |
|
@@ -1014,7 +1024,7 @@ struct f1protoncorrelation { |
1014 | 1024 |
|
1015 | 1025 | const auto& sc0 = sysCuts[0]; |
1016 | 1026 |
|
1017 | | - if (countf1 && passPrimary(protontrack.protonDcaxy(), protontrack.protonDcaz(), protontrack.protonTPCNcrs(), protontrack.protonTPCNcls(), sc0)) { |
| 1027 | + if (countf1 && passPrimary(protontrack.protonDcaxy(), protontrack.protonDcaz(), protontrack.protonTPCNcrs(), protontrack.protonTPCNcls(), sc0) && passProtonPID(0, protontrack, Proton, pMinP, pMaxP, pTofP)) { |
1018 | 1028 | histos.fill(HIST("hNsigmaProtonTPC"), protontrack.protonNsigmaTPC(), protontrack.protonNsigmaTOF(), Proton.Pt()); |
1019 | 1029 | } |
1020 | 1030 |
|
@@ -1110,6 +1120,8 @@ struct f1protoncorrelation { |
1110 | 1120 | Kshort.SetXYZM(t1.f1d3Px(), t1.f1d3Py(), t1.f1d3Pz(), 0.497); |
1111 | 1121 | KaonKshortPair = Kaon + Kshort; |
1112 | 1122 | Proton.SetXYZM(t2.protonPx(), t2.protonPy(), t2.protonPz(), 0.938); |
| 1123 | + if (F1.Pt() < lowPtF1 || F1.Pt() > 50.0) |
| 1124 | + continue; |
1113 | 1125 | auto relative_momentum = getkstar(F1, Proton); |
1114 | 1126 | auto mT = getmT(F1, Proton); |
1115 | 1127 | // sys list for this (F1, p) pair |
|
0 commit comments