ATLAS Offline Software
Loading...
Searching...
No Matches
WTAConeParallelHelper.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef WTAConeParallelHelper_h
6#define WTAConeParallelHelper_h
7
8
9
10#include "./WTAObject.h" // Use the WTAObject
11#include "./WTAConeMaker.h" // The base class
12#include <vector>
13#include <memory>
14
16 public:
17 WTAConeParallelHelper(unsigned int block_n = 1):
18 m_BlockN(block_n), m_DivideByEta(false), m_JetN(10), m_StoreAmbiguousJets(true)
19 {}; // Constructor
20 ~WTAConeParallelHelper () {}; // Destructor
21
22 void SetBlockN(unsigned int block_n); // Call SetBlockN in the constructor
23 void SetDivideByEta(bool divide_by_eta){m_DivideByEta = divide_by_eta;}
24 void SetJetN(unsigned int jet_n){m_JetN = jet_n;}
25 void SetStoreAmbiguousJets(bool store_ambiguous_jets){m_StoreAmbiguousJets = store_ambiguous_jets;}
27 // When merging the final four phi-blocks, the FW and cpp implementations differ
28 // In FW, the phi-blocks come in according to their latency
29 // In cpp, the phi-blocks come in fixed order of 0-1-2-3
30 // There can be cases when two or more jets with same pt_t are created,
31 // their ordering or some jet may get discarded due to the final truncation
32 // If m_StoreAmbiguousJets is set true, it tracks all jets with same pt_t
33 // and extend the length of final jet list(m_JetN)
34 // Storing all possible jets that can be found in the FW implementation
35 // This is a temporary solution(jae.jin.hong@cern.ch)
36
37 template<typename T>
38 T PhiWrap(T phi);
39 template<typename T>
40 bool CheckInsideRegionPhi(T tower_pos, unsigned int iBlock, bool doWithOverlap = false);
41 template<typename T>
42 bool CheckInsideRegionEta(T tower_pos, unsigned int iBlock, bool doWithOverlap = false);
43 void CreateBlocks(const std::vector<WTATrigObj>& all_towers);
44 unsigned int GetBlockN(){return m_BlockN;};
45 unsigned int GetJetN(){return m_JetN;};
47
48 template<typename WTAClassType>
49 void RunParallelWTA(std::unique_ptr<WTAClassType>& AnyWTAClass); // Run this N times, without argument
50 void CheckJetInCore();
51 std::vector<WTAJet> GetAllJets();
52
53 std::vector<WTATrigObj> GetStage1ConstituentListPerBlock(unsigned int iBlock) const {
54 return m_stage1_constituentListPerBlock.at(iBlock);
55 }
56 std::vector<WTATrigObj> GetStage1SeedSortingPerBlock(unsigned int iBlock) const {
57 return m_stage1_seedSortingListPerBlock.at(iBlock);
58 }
59 std::vector<WTAJet> GetStage2ConeSeedsPPerBlock(unsigned int iBlock) const {
60 return m_stage2_coneSeedsPerBlock.at(iBlock);
61 }
62 std::vector<WTAJet> GetStage3ConeJetsPerBlock(unsigned int iBlock) const {
63 return m_stage3_coneJetsPerBlock.at(iBlock);
64 }
65
66 private:
67 unsigned int m_BlockN;
69
70 // Merge all BlockN jets > OverlapRemoval > final JetN truncation
71 unsigned int m_JetN;
73
74 std::vector<std::vector<WTATrigObj>> m_InputTowersPerBlock;
75 std::vector<std::vector<WTAJet>> m_OutputJetsPerBlock;
76
77 // For debugging
78 std::vector<std::vector<WTATrigObj>> m_stage1_constituentListPerBlock;
79 std::vector<std::vector<WTATrigObj>> m_stage1_seedSortingListPerBlock;
80 std::vector<std::vector<WTAJet>> m_stage2_coneSeedsPerBlock;
81 std::vector<std::vector<WTAJet>> m_stage3_coneJetsPerBlock;
82};
83
84inline void WTAConeParallelHelper::SetBlockN(unsigned int block_n)
85{
86 m_BlockN = block_n;
88 for(unsigned int i = 0; i < m_BlockN; i++)
89 {
90 m_InputTowersPerBlock.emplace_back();
91 m_OutputJetsPerBlock.emplace_back();
92 }
93
98}
99
100template<typename T>
102#ifdef FLOATING_POINT_SIMULATION
103 while(phi >= PHI_MAX)phi -= 2*PI;
104 while(phi < PHI_MIN)phi += 2*PI;
105 return phi;
106#else
107 T wrapped = phi % PHI_LEN;
108 if (wrapped < 0) wrapped = wrapped + PHI_LEN;
109 return wrapped;
110#endif
111}
112
113template<typename T>
114bool WTAConeParallelHelper::CheckInsideRegionEta(T tower_pos, unsigned int iBlock, bool doWithOverlap) {
115 T block_half_width = ETA_LEN / T(m_BlockN *2);
116 T block_center = ETA_MIN + ETA_LEN / T(m_BlockN) * iBlock + block_half_width;
117 if (doWithOverlap) {
118 block_half_width = block_half_width + T(CORE_DIST);
119 }
120 // Compute min and max with potential wrap-around
121 T block_min = block_center - block_half_width;
122 T block_max = block_center + block_half_width;
123 // Check inclusion
124 return (tower_pos >= block_min) && (tower_pos < block_max);
125}
126
127template<typename T>
128bool WTAConeParallelHelper::CheckInsideRegionPhi(T tower_pos, unsigned int iBlock, bool doWithOverlap) {
129 T block_center = PHI_MIN + PHI_LEN / T(m_BlockN) * iBlock;
130 T block_half_width = PHI_LEN / T(m_BlockN *2);
131 if (doWithOverlap) {
132 block_half_width = block_half_width + T(CORE_DIST);
133 }
134
135 // Compute min and max with potential wrap-around
136 T block_min = PhiWrap(block_center - block_half_width);
137 T block_max = PhiWrap(block_center + block_half_width);
138 tower_pos = PhiWrap(tower_pos);
139 // Check inclusion using modular range
140 if (block_min < block_max) {
141 return (tower_pos >= block_min) && (tower_pos < block_max);
142 } else {
143 // The Region wraps around (e.g., from +3.2 to -3.2)
144 return (tower_pos >= block_min) || (tower_pos < block_max);
145 }
146}
147
148inline void WTAConeParallelHelper::CreateBlocks(const std::vector<WTATrigObj>& all_towers)
149{
150 const unsigned tower_n = all_towers.size();
151 for(unsigned int iBlock = 0; iBlock < m_BlockN; iBlock++)
152 {
153 if(m_DivideByEta)
154 {
155 for(unsigned int iTower = 0; iTower < tower_n; iTower++)
156 {
157 eta_t tower_pos = all_towers.at(iBlock).eta(); // Get tower's eta position
158 if(CheckInsideRegionEta(tower_pos, iBlock, true))
159 m_InputTowersPerBlock.at(iBlock).push_back(all_towers.at(iTower));
160 }
161 }
162 else
163 {
164 for(unsigned int iTower = 0; iTower < tower_n; iTower++)
165 {
166 phi_t tower_pos = PhiWrap(all_towers.at(iTower).phi()); // Get tower's phi position
167 if(CheckInsideRegionPhi(tower_pos, iBlock, true))
168 m_InputTowersPerBlock.at(iBlock).push_back(all_towers.at(iTower));
169 }
170 }
171 }
172}
173
174template<typename WTAClassType>
175inline void WTAConeParallelHelper::RunParallelWTA(std::unique_ptr<WTAClassType>& MyWTAMakerClass)
176{
177 for(unsigned int i = 0; i < m_BlockN; i++)
178 {
179 MyWTAMakerClass->InitiateInputs(m_InputTowersPerBlock.at(i));
180 m_stage1_constituentListPerBlock.push_back(MyWTAMakerClass->GetConstituentList());
181 m_stage1_seedSortingListPerBlock.push_back(MyWTAMakerClass->GetSeedSortingList());
182 MyWTAMakerClass->SeedCleaning();
183 m_stage2_coneSeedsPerBlock.push_back(MyWTAMakerClass->GetSeedList());
184 MyWTAMakerClass->MergeConstsToSeeds();
185 MyWTAMakerClass->CreateERingInfo();
186 m_stage3_coneJetsPerBlock.push_back(MyWTAMakerClass->GetSeedList());
187 m_OutputJetsPerBlock.at(i) = MyWTAMakerClass->GetSeedList(); // Define the ith vector, not push_back
188 }
189}
190
191inline void WTAConeParallelHelper::CheckJetInCore() // DON'T CALL THIS FOR SINGLE REGION!!
192{
193 std::vector<WTAJet> all_jets;
194 for(unsigned int iBlock = 0; iBlock < m_BlockN; iBlock++)
195 {
196 unsigned int this_block_jet_n = m_OutputJetsPerBlock.at(iBlock).size();
197 if(this_block_jet_n == 0) continue; // Only run if there are jets in the ith ROI
198
199 if (m_DivideByEta)
200 {
201 for (int j = this_block_jet_n - 1; j >= 0; j--)
202 {
203 WTAJet jet = m_OutputJetsPerBlock.at(iBlock).at(j);
204 eta_t jet_pos = jet.eta();
205 if (!CheckInsideRegionEta(jet_pos, iBlock, false))
206 m_OutputJetsPerBlock.at(iBlock).erase(m_OutputJetsPerBlock.at(iBlock).begin() + j);
207 }
208 }
209 else
210 {
211 for (int j = this_block_jet_n - 1; j >= 0; j--) {
212 WTAJet jet = m_OutputJetsPerBlock.at(iBlock).at(j);
213 phi_t jet_pos = jet.phi();
214 if (!CheckInsideRegionPhi(jet_pos, iBlock, false))
215 m_OutputJetsPerBlock.at(iBlock).erase(m_OutputJetsPerBlock.at(iBlock).begin() + j);
216 }
217 }
218 }
219}
220
221inline std::vector<WTAJet> WTAConeParallelHelper::GetAllJets()
222{
223 std::vector<WTAJet> all_jets;
224 for(unsigned int i = 0; i < m_BlockN; i++)
225 {
226 all_jets.insert(all_jets.end(), m_OutputJetsPerBlock.at(i).begin(), m_OutputJetsPerBlock.at(i).end());
227 }
228 SortByPt(all_jets); // Maximum 40 jets here
230 std::vector<pt_t> duplicated_pt_list;
231 unsigned int cnt = 0;
232 for(unsigned int i = 0; i < all_jets.size() - 1; i++){
233 pt_t i_pt = all_jets.at(i).pt();
234
235 if(std::find(duplicated_pt_list.begin(), duplicated_pt_list.end(),i_pt)!= duplicated_pt_list.end()) continue; // Skip counted pt_t
236 for(unsigned int j = i + 1; j < all_jets.size(); j++){
237 pt_t j_pt = all_jets.at(j).pt();
238 if(i_pt == j_pt){
239 cnt++;
240 if(std::find(duplicated_pt_list.begin(), duplicated_pt_list.end(),i_pt)!= duplicated_pt_list.end())duplicated_pt_list.push_back(i_pt);
241 }
242 }
243 }
244 m_JetN += cnt;
245 }
246 if(all_jets.size() > m_JetN)all_jets.resize(m_JetN); // Do finial truncation
247 return all_jets;
248}
249
250#endif
Scalar phi() const
phi method
static void SortByPt(std::vector< T > &list)
Definition WTAObject.h:16
std::vector< std::vector< WTATrigObj > > m_stage1_seedSortingListPerBlock
std::vector< WTAJet > GetAllJets()
std::vector< std::vector< WTATrigObj > > m_stage1_constituentListPerBlock
std::vector< std::vector< WTAJet > > m_OutputJetsPerBlock
void RunParallelWTA(std::unique_ptr< WTAClassType > &AnyWTAClass)
std::vector< WTATrigObj > GetStage1ConstituentListPerBlock(unsigned int iBlock) const
std::vector< WTAJet > GetStage3ConeJetsPerBlock(unsigned int iBlock) const
WTAConeParallelHelper(unsigned int block_n=1)
std::vector< std::vector< WTAJet > > m_stage3_coneJetsPerBlock
std::vector< WTAJet > GetStage2ConeSeedsPPerBlock(unsigned int iBlock) const
void SetJetN(unsigned int jet_n)
bool CheckInsideRegionEta(T tower_pos, unsigned int iBlock, bool doWithOverlap=false)
T PhiWrap(T phi)
StoreAmbiguousJets.
std::vector< WTATrigObj > GetStage1SeedSortingPerBlock(unsigned int iBlock) const
void CreateBlocks(const std::vector< WTATrigObj > &all_towers)
std::vector< std::vector< WTAJet > > m_stage2_coneSeedsPerBlock
bool CheckInsideRegionPhi(T tower_pos, unsigned int iBlock, bool doWithOverlap=false)
void SetBlockN(unsigned int block_n)
void SetStoreAmbiguousJets(bool store_ambiguous_jets)
std::vector< std::vector< WTATrigObj > > m_InputTowersPerBlock
void SetDivideByEta(bool divide_by_eta)
const float PI