Belle II Software  release-08-01-10
KLM_Trig.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 
10 
11 #include <unordered_map>
12 #include <algorithm>
13 #include <numeric>
14 #include <vector>
15 #include <tuple>
16 #include <iostream>
17 #include <bitset>
18 #include <cassert>
19 
20 #include "trg/klm/modules/klmtrigger/group_helper.h"
21 #include "trg/klm/modules/klmtrigger/KLMAxis.h"
22 #include "trg/klm/modules/klmtrigger/KLM_Trig.h"
23 #include "klm/dataobjects/KLMElementNumbers.h"
24 
25 
26 
27 
28 AXIS_NAME(layer_count, int);
29 AXIS_NAME(layer_mask, uint64_t);
30 AXIS_NAME(n_triggered, int);
31 AXIS_NAME(sector_mask, int);
32 AXIS_NAME(sector_mask_or, int);
33 
34 AXIS_NAME(n_sections_trig, int);
35 AXIS_NAME(back2back_t, int);
36 
37 
38 
39 
40 using namespace Belle2;
41 using namespace Belle2::group_helper::KLM_Coordinates_n;
42 using namespace Belle2::group_helper::KLM_Generic;
43 using namespace Belle2::group_helper;
44 
45 
46 
48 const int c_TotalSections_per_EKLM_BKLM = 2;
49 const int c_MaxSectorID = 7;
50 
51 
52 
53 const int c_TotalLayers = 15;
54 
55 
56 constexpr Subdetector c_BKLM = Subdetector(KLMElementNumbers::c_BKLM);
57 constexpr Subdetector c_EKLM = Subdetector(KLMElementNumbers::c_EKLM);
58 
59 
60 constexpr isectors_t c_backward_eklm = isectors_t(KLM_TRG_definitions::c_backward_eklm);
61 constexpr isectors_t c_backward_bklm = isectors_t(KLM_TRG_definitions::c_backward_bklm);
62 
63 constexpr isectors_t c_forward_bklm = isectors_t(KLM_TRG_definitions::c_forward_bklm);
64 constexpr isectors_t c_forward_eklm = isectors_t(KLM_TRG_definitions::c_forward_eklm);
65 
66 
67 std::size_t countBits(uint64_t n)
68 {
69  return std::bitset<64>(n).count();
70 }
71 
72 
73 
74 
75 template <typename CONTAINER_T>
76 uint64_t to_bit_mask(const CONTAINER_T& container)
77 {
78 
79  uint64_t ret = 0;
80  for (let& e : container) {
81  assert(e <= 32);
82  ret |= (uint64_t(1) << e);
83  }
84  return ret;
85 
86 
87 
88 
89 
90 }
91 
92 bool sectors_adjacent(int e1, int e2)
93 {
94  if (e1 == 0 && e2 == c_MaxSectorID) {
95  return true;
96  }
97  if (e1 - e2 == 1) {
98  return true;
99  }
100  return false;
101 }
102 
103 
104 template <typename CONTAINER_T>
105 auto to_sector_bit_mask(const CONTAINER_T& container, int TriggerCut_, int vetoCut_ = 0)
106 {
107  int ret = 0;
108  auto back = container.back();
109  for (const auto& e : container) {
110  int bitcount = countBits(layer_mask(e));
111  int bitcount_or = countBits(layer_mask(back) | layer_mask(e));
112  int bitcount_back = countBits(layer_mask(back));
113  if (bitcount >= TriggerCut_) {
114  ret |= (1 << sector(e));
115  } else if (
116  bitcount_or >= TriggerCut_
117  && bitcount_back < vetoCut_
118  && bitcount < vetoCut_
119  && (sectors_adjacent(sector(e), sector(back)))
120  ) {
121  ret |= (1 << sector(e));
122  ret |= (1024);
123  }
124  back = e;
125  }
126  return ret;
127 }
128 
129 
130 
131 
132 
133 
134 
135 
136 Belle2::group_helper::KLM_trg_summery Belle2::make_trg(const std::vector<Belle2::group_helper::KLM_Digit_compact>& hits,
137  int eventNr, int NLayerTrigger)
138 {
139 
140 
141 
143  [](letref e1) {
144  let bit_mask = to_bit_mask(project(e1, [](letref t) { return (layer(t) + 1) * 2 + plane(t); }));
145  let layer_count_ = countBits(bit_mask);
146  return std::tuple(layer_count(layer_count_), layer_mask(bit_mask));
147  }
148  );
149 
150 
151  sort(grouped);
152 
153 
154  let summery2 = group<Subdetector>::apply(grouped,
155  [&](letref e1) {
156  return (n_sections_trig) count_if(project<layer_count>(e1), [NLayerTrigger](letref e) {return e >= NLayerTrigger; });
157  });
158 
159 
160  let n_triggered_sectors2 = group<Subdetector, section, isectors_t>::apply(grouped,
161  [&](letref e1) { return (sector_mask) to_sector_bit_mask(e1, NLayerTrigger); },
162  [&](letref e1) { return (sector_mask_or) to_sector_bit_mask(e1, NLayerTrigger, NLayerTrigger); }
163  );
164 
165 
166  let summery1 = group<Subdetector>::apply(n_triggered_sectors2,
167  [](letref e1) {
168  return back2back_t(count_if(project<sector_mask>(e1)) >= c_TotalSections_per_EKLM_BKLM);
169  }
170  );
171 
172 
173 
174  return std::make_tuple(
175  event_nr(eventNr),
176  BKLM_n_trg_sectors(n_sections_trig(get_first(summery2, c_BKLM))),
177  EKLM_n_trg_sectors(n_sections_trig(get_first(summery2, c_EKLM))),
178 
179 
180  Sector_mask_Backward_Barrel(sector_mask(get_first(n_triggered_sectors2, c_backward_bklm))),
181  Sector_mask_Forward_Barrel(sector_mask(get_first(n_triggered_sectors2, c_forward_bklm))),
182  Sector_mask_Backward_Endcap(sector_mask(get_first(n_triggered_sectors2, c_backward_eklm))),
183  Sector_mask_Forward_Endcap(sector_mask(get_first(n_triggered_sectors2, c_forward_eklm))),
184 
185 
186  Sector_mask_OR_Backward_Barrel(sector_mask_or(get_first(n_triggered_sectors2, c_backward_bklm))),
187  Sector_mask_OR_Forward_Barrel(sector_mask_or(get_first(n_triggered_sectors2, c_forward_bklm))),
188  Sector_mask_OR_Backward_Endcap(sector_mask_or(get_first(n_triggered_sectors2, c_backward_eklm))),
189  Sector_mask_OR_Forward_Endcap(sector_mask_or(get_first(n_triggered_sectors2, c_forward_eklm))),
190 
191 
192  BKLM_back_to_back_flag(back2back_t(get_first(summery1, c_BKLM))),
193  EKLM_back_to_back_flag(back2back_t(get_first(summery1, c_EKLM)))
194 
195  );
196 
197 
198 
199 
200 }
Abstract base class for different kinds of events.