Belle II Software  release-06-00-14
KLMTriggerModule.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <trg/klm/modules/klmtrigger/KLMTriggerModule.h>
10 #include <trg/klm/modules/klmtrigger/group_helper.h>
11 
12 // framework - DataStore
13 #include <framework/datastore/StoreArray.h>
14 #include <framework/datastore/StoreObjPtr.h>
15 
16 // event data
17 #include <framework/dataobjects/EventMetaData.h>
18 
19 // digits
20 #include <klm/dataobjects/KLMDigit.h>
21 
22 #include <trg/klm/dataobjects/KLMTriggerHit.h>
23 #include <trg/klm/dataobjects/KLMTriggerTrack.h>
24 #include <trg/klm/dataobjects/KLMTrgSummary.h>
25 
26 #include <unordered_map>
27 #include <algorithm>
28 #include <numeric>
29 #include <vector>
30 #include <tuple>
31 #include <iostream>
32 
33 using namespace std;
34 using namespace Belle2;
35 using namespace Belle2::group_helper;
36 
38 const int c_TotalSections_per_EKLM_BKLM = 2;
39 const int c_MaxSectorID = 7;
40 
41 const int i_forward_eklm = 2;
42 const int i_backward_eklm = 3;
43 const int i_forward_bklm = 0;
44 const int i_backward_bklm = 1;
45 
46 const std::string m_klmTriggerSummery = "TRGKLMSummery"; //"Name of the StoreArray holding the Trigger Summery"
47 
48 // part of unused old Trigger collection
49 const std::string m_klmtrackCollectionName = "TRGKLMTracks";
50 const std::string m_klmhitCollectionName = "TRGKLMHits";
51 // end
52 
53 
54 //-----------------------------------------------------------------
55 // Register the Module
56 //-----------------------------------------------------------------
57 REG_MODULE(KLMTrigger)
58 
59 //-----------------------------------------------------------------
60 // Implementation
61 //-----------------------------------------------------------------
62 struct compare {
63  int key;
64  explicit compare(int const& i): key(i) { }
65 
66  bool operator()(int const& i)
67  {
68  return (i == key);
69  }
70 };
71 
72 
73 vector<string> split(const string& str, const string& delim)
74 {
75  vector<string> tokens;
76  size_t prev = 0, pos = 0;
77  do {
78  pos = str.find(delim, prev);
79  if (pos == string::npos) pos = str.length();
80  string token = str.substr(prev, pos - prev);
81  if (!token.empty()) tokens.push_back(token);
82  prev = pos + delim.length();
83  } while (pos < str.length() && prev < str.length());
84  return tokens;
85 }
86 
87 std::vector<int> layer_string_list_to_integer_range(const std::string& instr)
88 {
89  std::vector<int> ret;
90  auto str_spl = split(instr, ":");
91 
92  int start = std::stoi(str_spl[0]);
93  int stop = std::stoi(str_spl[1]);
94  for (int i = start; i < stop ; ++i) {
95  ret.push_back(i);
96  }
97 
98  return ret;
99 }
100 std::vector<int> layer_string_list_to_integer_list(const std::string& instr)
101 {
102  std::vector<int> ret;
103  auto str_spl = split(instr, ",");
104 
105  for (const auto& e : str_spl) {
106  ret.push_back(std::stoi(e));
107  }
108 
109  return ret;
110 }
111 std::vector<int> layer_string_list_to_integer(const std::string& instr)
112 {
113  if (instr.find(":") != string::npos) {
114  return layer_string_list_to_integer_range(instr);
115  }
116  if (instr.find(",") != string::npos) {
117  return layer_string_list_to_integer_list(instr);
118  }
119  std::vector<int> ret;
120  return ret;
121 }
122 KLMTriggerModule::KLMTriggerModule() : Module()
123 {
124  setDescription("KLM trigger simulation");
125  setPropertyFlags(c_ParallelProcessingCertified);
126 }
127 
128 void KLMTriggerModule::initialize()
129 {
130  m_KLMTrgSummary.registerInDataStore(DataStore::c_ErrorIfAlreadyRegistered);
131  StoreArray<KLMDigit> klmDigits;
132  klmDigits.isRequired();
133  if (!klmDigits.isValid())
134  return;
135 
136 // unused
137  StoreArray<KLMTriggerHit> klmTriggerHits(m_klmhitCollectionName);
138  klmTriggerHits.registerInDataStore();
139  klmTriggerHits.registerRelationTo(klmDigits);
140 
141  StoreArray<KLMTriggerTrack> klmTriggerTracks(m_klmtrackCollectionName);
142  klmTriggerTracks.registerInDataStore();
143  klmTriggerTracks.registerRelationTo(klmTriggerHits);
144 // end unused
145 }
146 
148 {
149  StoreObjPtr<EventMetaData> evtMetaData;
150  B2DEBUG(100, "KLMTrigger: Experiment " << evtMetaData->getExperiment() << ", run " << evtMetaData->getRun());
151 
152  if (not m_KLMTriggerParameters.isValid())
153  B2FATAL("KLM trigger parameters are not available.");
154  m_nLayerTrigger = m_KLMTriggerParameters->getNLayers();
155  try {
156  m_layerUsed = layer_string_list_to_integer(m_KLMTriggerParameters->getWhichLayers());
157  B2DEBUG(20, "KLMTrigger: m_layerUsed " << m_KLMTriggerParameters->getWhichLayers());
158  for (auto e : m_layerUsed) {
159  B2DEBUG(20, "KLMTrigger: layer " << e << " used.");
160  }
161  } catch (const std::exception& e) {
162  B2FATAL("Something went wrong when parsing the 'm_whichLayers' string"
163  << LogVar("string", m_KLMTriggerParameters->getWhichLayers())
164  << LogVar("exception", e.what()));
165  }
166 }
167 
168 
170 {
171 
172 }
173 
174 AXIS_NAME(KLM_type, int);// cppcheck-suppress noExplicitConstructor
175 AXIS_NAME(section_t, int);// cppcheck-suppress noExplicitConstructor
176 AXIS_NAME(sector_t, int);// cppcheck-suppress noExplicitConstructor
177 AXIS_NAME(layer_t, int);// cppcheck-suppress noExplicitConstructor
178 AXIS_NAME(layer_count, int);// cppcheck-suppress noExplicitConstructor
179 AXIS_NAME(layer_mask, int);// cppcheck-suppress noExplicitConstructor
180 AXIS_NAME(n_triggered, int);// cppcheck-suppress noExplicitConstructor
181 AXIS_NAME(sector_mask, int);// cppcheck-suppress noExplicitConstructor
182 AXIS_NAME(sector_mask_or, int);// cppcheck-suppress noExplicitConstructor
183 
184 AXIS_NAME(n_sections_trig, int);// cppcheck-suppress noExplicitConstructor
185 AXIS_NAME(back2back_t, int);// cppcheck-suppress noExplicitConstructor
186 AXIS_NAME(isectors_t, int);// cppcheck-suppress noExplicitConstructor
187 AXIS_NAME(TriggerCut, int);// cppcheck-suppress noExplicitConstructor
188 AXIS_NAME(vetoCut, int);// cppcheck-suppress noExplicitConstructor
189 
190 int to_i_sector(int KLM_type_, int section_)
191 {
192  if (KLM_type_ == KLMElementNumbers::c_BKLM && section_ == BKLMElementNumbers::c_BackwardSection) {
193  return i_backward_bklm;
194  } else if (KLM_type_ == KLMElementNumbers::c_BKLM && section_ == BKLMElementNumbers::c_ForwardSection) {
195  return i_forward_bklm;
196  } else if (KLM_type_ == KLMElementNumbers::c_EKLM && section_ == EKLMElementNumbers::c_BackwardSection) {
197  return i_backward_eklm;
198  } else if (KLM_type_ == KLMElementNumbers::c_EKLM && section_ == EKLMElementNumbers::c_ForwardSection) {
199  return i_forward_eklm;
200  }
201  B2FATAL("unecpected KLM type");
202  return 0;
203 }
204 
205 
206 template <typename T>
207 int to_i_sector(const T& e)
208 {
209  return to_i_sector(KLM_type(e) , section_t(e));
210 }
211 
212 
213 template <typename AXIS_NAME_T, typename CONTAINER_T>
214 auto to_bit_mask(const CONTAINER_T& container)
215 {
216  return std::accumulate(container.begin(), container.end(), 0, [](const auto & lhs, const auto & rhs) { return lhs | (1 << AXIS_NAME_T(rhs));});
217 }
218 
219 unsigned int countBits(unsigned int n)
220 {
221  return std::bitset<16>(n).count();
222 }
223 
224 
225 bool sectors_adjacent(int e1, int e2)
226 {
227  if (e1 == 0 && e2 == c_MaxSectorID) {
228  return true;
229  }
230  if (e1 - e2 == 1) {
231  return true;
232  }
233  return false;
234 }
235 
236 template <typename CONTAINER_T>
237 auto to_sector_bit_mask(const CONTAINER_T& container, TriggerCut TriggerCut_ , vetoCut vetoCut_ = 0)
238 {
239  int ret = 0;
240  auto back = container.back();
241  for (const auto& e : container) {
242  int bitcount = countBits(layer_mask(e));
243  int bitcount_or = countBits(layer_mask(back) | layer_mask(e));
244  int bitcount_back = countBits(layer_mask(back));
245  if (bitcount >= TriggerCut_) {
246  ret |= (1 << sector_t(e));
247  } else if (
248  bitcount_or >= TriggerCut_
249  && bitcount_back < vetoCut_
250  && bitcount < vetoCut_
251  && (sectors_adjacent(sector_t(e) , sector_t(back)))
252  ) {
253  ret |= (1 << sector_t(e));
254  ret |= (1024);
255  }
256  back = e;
257  }
258  return ret;
259 }
260 
261 
263 {
264  m_KLMTrgSummary.create();
265 
266  StoreArray<KLMDigit> klmDigits;
267 
268  auto hits = fill_vector(klmDigits,
269  [](auto klmdig) -> KLM_type { return klmdig->getSubdetector(); },
270  [](auto klmdig) -> section_t { return klmdig->getSection(); },
271  [](auto klmdig) -> sector_t { return klmdig->getSector() - 1;},
272  [](auto klmdig) -> layer_t { return klmdig->getLayer() - 1;}
273  );
274 
275 
276  sort(hits);
277  drop_duplicates(hits);
278  auto is_not_containt_in_vector_with_projected = [](const auto & vec, auto project) {
279  return [&vec, project](const auto & ele) mutable {
280  return std::find_if(vec.begin(), vec.end(), [&](const auto & e1) { return e1 == project(ele); }) == vec.end();
281  };
282  };
283 
284  hits.erase(std::remove_if(hits.begin(), hits.end(),
285  is_not_containt_in_vector_with_projected(m_layerUsed, layer_t())),
286  hits.end());
287 
288 
290  [](const auto & e1) -> layer_count { return e1.size(); },
291  [](const auto & e1) -> layer_mask { return to_bit_mask<layer_t>(e1);}
292  );
293 
294 
295  sort(grouped);
296 
297 
298  auto summery2 = group<KLM_type>::apply(grouped,
299  [&](const auto & e1) -> n_sections_trig {
300  return count_if(e1, group_helper::greater_equal<int>{m_nLayerTrigger }, layer_count());
301  });
302 
303 
304  auto n_triggered_sectors2 = group<KLM_type, section_t>::apply(grouped,
305  [&](const auto & e1) -> sector_mask { return to_sector_bit_mask(e1, TriggerCut(m_nLayerTrigger));},
306  [&](const auto & e1) -> sector_mask_or { return to_sector_bit_mask(e1, TriggerCut(m_nLayerTrigger), vetoCut(m_nLayerTrigger));},
307  [ ](const auto & e1) -> isectors_t { return to_i_sector(e1[0]); }
308  );
309 
310 
311  auto summery1 = group<KLM_type>::apply(n_triggered_sectors2,
312  [](const auto & e1) -> back2back_t {
313  return count_if(e1, group_helper::greater<int>{0}, sector_mask()) >= c_TotalSections_per_EKLM_BKLM;
314  }
315  );
316 
317  m_KLMTrgSummary->setBKLM_n_trg_sectors(first_or_default(summery2, KLM_type(KLMElementNumbers::c_BKLM), 0 , n_sections_trig{}));
318  m_KLMTrgSummary->setEKLM_n_trg_sectors(first_or_default(summery2, KLM_type(KLMElementNumbers::c_EKLM), 0 , n_sections_trig{}));
319 
320  m_KLMTrgSummary->setSector_mask_Backward_Barrel(first_or_default(n_triggered_sectors2, isectors_t(i_backward_bklm), 0 , sector_mask{}));
321  m_KLMTrgSummary->setSector_mask_Forward_Barrel(first_or_default(n_triggered_sectors2, isectors_t(i_forward_bklm) , 0 , sector_mask{}));
322  m_KLMTrgSummary->setSector_mask_Backward_Endcap(first_or_default(n_triggered_sectors2, isectors_t(i_backward_eklm), 0 , sector_mask{}));
323  m_KLMTrgSummary->setSector_mask_Forward_Endcap(first_or_default(n_triggered_sectors2, isectors_t(i_forward_eklm) , 0 , sector_mask{}));
324 
325  m_KLMTrgSummary->setSector_mask_OR_Backward_Barrel(first_or_default(n_triggered_sectors2, isectors_t(i_backward_bklm), 0 ,
326  sector_mask_or{}));
327  m_KLMTrgSummary->setSector_mask_OR_Forward_Barrel(first_or_default(n_triggered_sectors2, isectors_t(i_forward_bklm) , 0 ,
328  sector_mask_or{}));
329  m_KLMTrgSummary->setSector_mask_OR_Backward_Endcap(first_or_default(n_triggered_sectors2, isectors_t(i_backward_eklm), 0 ,
330  sector_mask_or{}));
331  m_KLMTrgSummary->setSector_mask_OR_Forward_Endcap(first_or_default(n_triggered_sectors2, isectors_t(i_forward_eklm) , 0 ,
332  sector_mask_or{}));
333 
334  m_KLMTrgSummary->setBKLM_back_to_back_flag(first_or_default(summery1, KLM_type(KLMElementNumbers::c_BKLM), 0 , back2back_t{}));
335  m_KLMTrgSummary->setEKLM_back_to_back_flag(first_or_default(summery1, KLM_type(KLMElementNumbers::c_EKLM), 0 , back2back_t{}));
336 
337 }
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
Definition: DataStore.h:72
virtual void event() override
This method is the core of the module.
virtual void endRun() override
This method is called if the current run ends.
virtual void beginRun() override
Called when entering a new run.
Base class for Modules.
Definition: Module.h:72
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
bool isValid() const
Check wether the array was registered.
Definition: StoreArray.h:288
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Definition: StoreArray.h:140
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:95
Class to store variables with their name which were sent to the logging service.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.