9 #include <trg/klm/modules/klmtrigger/KLMTriggerModule.h>
10 #include <trg/klm/modules/klmtrigger/group_helper.h>
13 #include <framework/datastore/StoreArray.h>
14 #include <framework/datastore/StoreObjPtr.h>
17 #include <framework/dataobjects/EventMetaData.h>
20 #include <klm/dataobjects/KLMDigit.h>
22 #include <trg/klm/dataobjects/KLMTriggerHit.h>
23 #include <trg/klm/dataobjects/KLMTriggerTrack.h>
24 #include <trg/klm/dataobjects/KLMTrgSummary.h>
26 #include <unordered_map>
35 using namespace Belle2::group_helper;
38 const int c_TotalSections_per_EKLM_BKLM = 2;
39 const int c_MaxSectorID = 7;
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;
46 const std::string m_klmTriggerSummery =
"TRGKLMSummery";
49 const std::string m_klmtrackCollectionName =
"TRGKLMTracks";
50 const std::string m_klmhitCollectionName =
"TRGKLMHits";
64 explicit compare(
int const& i): key(i) { }
66 bool operator()(
int const& i)
73 vector<string> split(
const string& str,
const string& delim)
75 vector<string> tokens;
76 size_t prev = 0, pos = 0;
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());
87 std::vector<int> layer_string_list_to_integer_range(
const std::string& instr)
90 auto str_spl = split(instr,
":");
92 int start = std::stoi(str_spl[0]);
93 int stop = std::stoi(str_spl[1]);
94 for (
int i = start; i < stop ; ++i) {
100 std::vector<int> layer_string_list_to_integer_list(
const std::string& instr)
102 std::vector<int> ret;
103 auto str_spl = split(instr,
",");
105 for (
const auto& e : str_spl) {
106 ret.push_back(std::stoi(e));
111 std::vector<int> layer_string_list_to_integer(
const std::string& instr)
113 if (instr.find(
":") != string::npos) {
114 return layer_string_list_to_integer_range(instr);
116 if (instr.find(
",") != string::npos) {
117 return layer_string_list_to_integer_list(instr);
119 std::vector<int> ret;
122 KLMTriggerModule::KLMTriggerModule() :
Module()
124 setDescription(
"KLM trigger simulation");
125 setPropertyFlags(c_ParallelProcessingCertified);
128 void KLMTriggerModule::initialize()
150 B2DEBUG(100,
"KLMTrigger: Experiment " << evtMetaData->getExperiment() <<
", run " << evtMetaData->getRun());
152 if (not m_KLMTriggerParameters.isValid())
153 B2FATAL(
"KLM trigger parameters are not available.");
154 m_nLayerTrigger = m_KLMTriggerParameters->getNLayers();
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.");
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()));
174 AXIS_NAME(KLM_type,
int);
175 AXIS_NAME(section_t,
int);
176 AXIS_NAME(sector_t,
int);
177 AXIS_NAME(layer_t,
int);
178 AXIS_NAME(layer_count,
int);
179 AXIS_NAME(layer_mask,
int);
180 AXIS_NAME(n_triggered,
int);
181 AXIS_NAME(sector_mask,
int);
182 AXIS_NAME(sector_mask_or,
int);
184 AXIS_NAME(n_sections_trig,
int);
185 AXIS_NAME(back2back_t,
int);
186 AXIS_NAME(isectors_t,
int);
187 AXIS_NAME(TriggerCut,
int);
188 AXIS_NAME(vetoCut,
int);
190 int to_i_sector(
int KLM_type_,
int section_)
193 return i_backward_bklm;
195 return i_forward_bklm;
197 return i_backward_eklm;
199 return i_forward_eklm;
201 B2FATAL(
"unecpected KLM type");
206 template <
typename T>
207 int to_i_sector(
const T& e)
209 return to_i_sector(KLM_type(e) , section_t(e));
213 template <
typename AXIS_NAME_T,
typename CONTAINER_T>
214 auto to_bit_mask(
const CONTAINER_T& container)
216 return std::accumulate(container.begin(), container.end(), 0, [](
const auto & lhs,
const auto & rhs) { return lhs | (1 << AXIS_NAME_T(rhs));});
219 unsigned int countBits(
unsigned int n)
221 return std::bitset<16>(n).count();
225 bool sectors_adjacent(
int e1,
int e2)
227 if (e1 == 0 && e2 == c_MaxSectorID) {
236 template <
typename CONTAINER_T>
237 auto to_sector_bit_mask(
const CONTAINER_T& container, TriggerCut TriggerCut_ , vetoCut vetoCut_ = 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));
248 bitcount_or >= TriggerCut_
249 && bitcount_back < vetoCut_
250 && bitcount < vetoCut_
251 && (sectors_adjacent(sector_t(e) , sector_t(back)))
253 ret |= (1 << sector_t(e));
264 m_KLMTrgSummary.create();
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;}
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();
284 hits.erase(std::remove_if(hits.begin(), hits.end(),
285 is_not_containt_in_vector_with_projected(m_layerUsed, layer_t())),
290 [](
const auto & e1) -> layer_count {
return e1.size(); },
291 [](
const auto & e1) -> layer_mask {
return to_bit_mask<layer_t>(e1);}
299 [&](
const auto & e1) -> n_sections_trig {
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]); }
312 [](
const auto & e1) -> back2back_t {
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{}));
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{}));
325 m_KLMTrgSummary->setSector_mask_OR_Backward_Barrel(first_or_default(n_triggered_sectors2, isectors_t(i_backward_bklm), 0 ,
327 m_KLMTrgSummary->setSector_mask_OR_Forward_Barrel(first_or_default(n_triggered_sectors2, isectors_t(i_forward_bklm) , 0 ,
329 m_KLMTrgSummary->setSector_mask_OR_Backward_Endcap(first_or_default(n_triggered_sectors2, isectors_t(i_backward_eklm), 0 ,
331 m_KLMTrgSummary->setSector_mask_OR_Forward_Endcap(first_or_default(n_triggered_sectors2, isectors_t(i_forward_eklm) , 0 ,
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{}));
@ c_ForwardSection
Forward.
@ c_BackwardSection
Backward.
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
@ c_ForwardSection
Forward.
@ c_BackwardSection
Backward.
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.
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.
bool isValid() const
Check wether the array was registered.
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.
Type-safe access to single objects in the data store.
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.
Abstract base class for different kinds of events.