All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FlashMatchManager.cxx
Go to the documentation of this file.
1 #ifndef OPT0FINDER_FLASHMATCHMANAGER_CXX
2 #define OPT0FINDER_FLASHMATCHMANAGER_CXX
3 
4 #include <sstream>
5 #include <map>
6 #include <set>
7 #include "FlashMatchManager.h"
8 #include "OpT0FinderException.h"
9 #include "FlashFilterFactory.h"
10 #include "TPCFilterFactory.h"
11 #include "FlashMatchFactory.h"
12 #include "FlashHypothesisFactory.h"
13 #include "FlashProhibitFactory.h"
14 #include "CustomAlgoFactory.h"
15 #include <chrono>
16 
17 using namespace std::chrono;
18 namespace flashmatch {
19 
20  FlashMatchManager::FlashMatchManager(const std::string name)
21  : LoggerFeature(name)
22  , _alg_flash_filter(nullptr)
23  , _alg_tpc_filter(nullptr)
24  , _alg_match_prohibit(nullptr)
25  , _alg_flash_match(nullptr)
26  , _alg_flash_hypothesis(nullptr)
27  , _configured(false)
28  , _name(name)
29  {
30  _allow_reuse_flash = true;
31  }
32 
33  const std::string& FlashMatchManager::Name() const
34  { return _name; }
35 
36  /*
37  void FlashMatchManager::SetAlgo(BaseAlgorithm* alg)
38  {
39  _configured = false;
40  // Figure out the type of a provided algorithm
41  switch (alg->AlgorithmType()) {
42 
43  // TPC filter
44  case kTPCFilter:
45  _alg_tpc_filter = (BaseTPCFilter*)alg; break;
46 
47  // Flash filter
48  case kFlashFilter:
49  _alg_flash_filter = (BaseFlashFilter*)alg; break;
50 
51  // Match prohibit algo
52  case kMatchProhibit:
53  _alg_match_prohibit = (BaseProhibitAlgo*)alg; break;
54 
55  // Flash matching
56  case kFlashMatch:
57  _alg_flash_match = (BaseFlashMatch*)alg; break;
58 
59  // Flash hypothesis
60  case kFlashHypothesis:
61  _alg_flash_hypothesis = (BaseFlashHypothesis*)alg; break;
62 
63  // Other algorithms
64  case kCustomAlgo:
65  if(_custom_alg_m.find(alg->AlgorithmName()) != _custom_alg_m.end()) {
66  std::stringstream ss;
67  ss << "Duplicate name: " << alg->AlgorithmName() << std::endl;
68  throw OpT0FinderException(ss.str());
69  }
70  _custom_alg_m[alg->AlgorithmName()] = alg;
71  break;
72  // Fuck it
73  default:
74  std::stringstream ss;
75  ss << "Unsupported algorithm type: " << alg->AlgorithmType();
76  throw OpT0FinderException(ss.str());
77  }
78  }
79 
80  */
81 
83  {
84  if(_custom_alg_m.find(alg->AlgorithmName()) != _custom_alg_m.end()) {
85  std::stringstream ss;
86  ss << "Duplicate name: " << alg->AlgorithmName() << std::endl;
87  throw OpT0FinderException(ss.str());
88  }
89  _custom_alg_m[alg->AlgorithmName()] = alg;
90  }
91 
92  void FlashMatchManager::Configure(const Config_t& main_cfg)
93  {
94  /*
95  ::fcllite::ConfigManager cfg_mgr("FlashMatchManager");
96 
97  cfg_mgr.AddCfgFile(_config_file);
98 
99  auto const& main_cfg = cfg_mgr.Config();
100  */
101  auto const& mgr_cfg = main_cfg.get<flashmatch::Config_t>(Name());
102 
103  _allow_reuse_flash = mgr_cfg.get<bool>("AllowReuseFlash");
104  this->set_verbosity((msg::Level_t)(mgr_cfg.get<unsigned int>("Verbosity")));
105  _store_full = mgr_cfg.get<bool>("StoreFullResult");
106 
107  auto const flash_filter_name = mgr_cfg.get<std::string>("FlashFilterAlgo","");
108  auto const tpc_filter_name = mgr_cfg.get<std::string>("TPCFilterAlgo","");
109  auto const prohibit_name = mgr_cfg.get<std::string>("ProhibitAlgo","");
110  auto const hypothesis_name = mgr_cfg.get<std::string>("HypothesisAlgo","");
111  auto const match_name = mgr_cfg.get<std::string>("MatchAlgo","");
112  std::vector<std::string> custom_algo_v;
113  custom_algo_v = mgr_cfg.get<std::vector<std::string> >("CustomAlgo",custom_algo_v);
114 
115  if(!flash_filter_name.empty()) _alg_flash_filter = FlashFilterFactory::get().create(flash_filter_name,flash_filter_name);
116  if(!tpc_filter_name.empty() ) _alg_tpc_filter = TPCFilterFactory::get().create(tpc_filter_name,tpc_filter_name);
117  if(!prohibit_name.empty() ) _alg_match_prohibit = FlashProhibitFactory::get().create(prohibit_name,prohibit_name);
118  if(!hypothesis_name.empty() ) _alg_flash_hypothesis = FlashHypothesisFactory::get().create(hypothesis_name,hypothesis_name);
119  if(!match_name.empty() ) _alg_flash_match = FlashMatchFactory::get().create(match_name,match_name);
120  for(auto const& name : custom_algo_v)
122 
123  // checks
126 
129 
130  if (_alg_flash_match) {
133  }
134 
135  for (auto& name_ptr : _custom_alg_m)
136  name_ptr.second->Configure(main_cfg.get<flashmatch::Config_t>(name_ptr.first));
137 
138  _configured = true;
139  }
140 
142  {
143  if (!_configured)
144  FLASH_WARNING() << "Algorithm may be not configured yet!" << std::endl;
145 
146  // Figure out the type of a provided algorithm
147  switch (type) {
148 
149  // TPC filter
150  case kTPCFilter:
151  return _alg_tpc_filter;
152 
153  // Flash filter
154  case kFlashFilter:
155  return _alg_flash_filter;
156 
157  // Match prohibit algo
158  case kMatchProhibit:
159  return _alg_match_prohibit;
160 
161  // Flash matching
162  case kFlashMatch:
163  return _alg_flash_match;
164 
165  // Flash hypothesis
166  case kFlashHypothesis:
167  return _alg_flash_hypothesis;
168 
169  // Fuck it
170  default:
171  std::stringstream ss;
172  ss << "Unsupported algorithm type: " << type;
173  throw OpT0FinderException(ss.str());
174  }
175  return nullptr;
176  }
177 
179  {
180  if(_custom_alg_m.find(name) == _custom_alg_m.end()) {
181  FLASH_ERROR() << "Algorithm name " << name << " not found!" << std::endl;
182  throw OpT0FinderException();
183  }
184  return _custom_alg_m[name];
185  }
186 
188  { _tpc_object_v.push_back(obj); }
189 
191  { _tpc_object_v.emplace_back(std::move(obj)); }
192 
194  {
195  if(!obj.Valid()) throw OpT0FinderException("Invalid Flash_t object cannot be registered!");
196  _flash_v.push_back(obj);
197  }
198 
200  {
201  if(!obj.Valid()) throw OpT0FinderException("Invalid Flash_t object cannot be registered!");
202  _flash_v.emplace_back(std::move(obj));
203  }
204 
205  // CORE FUNCTION
206  std::vector<FlashMatch_t> FlashMatchManager::Match()
207  {
208  // Clear some history variables
209  _res_tpc_flash_v.clear();
210  _res_flash_tpc_v.clear();
211  if(_store_full) {
212  _res_tpc_flash_v.resize(_tpc_object_v.size(),std::vector<flashmatch::FlashMatch_t>(_flash_v.size()));
213  _res_flash_tpc_v.resize(_flash_v.size(),std::vector<flashmatch::FlashMatch_t>(_tpc_object_v.size()));
214  }
215 
216  // Create also a result container
217  std::vector<FlashMatch_t> result;
218 
219  if (!_alg_flash_match)
220  throw OpT0FinderException("Flash matching algorithm is reuqired! (not attached)");
222  throw OpT0FinderException("Flash hypothesis algorithm is required! (not attached)");
223 
224  if (!_configured)
225  throw OpT0FinderException("Have not configured yet!");
226 
227  if(_tpc_object_v.empty() || _flash_v.empty()) return result;
228 
229  //
230  // Filter stage: for both TPC and Flash
231  //
232 
233  // IDArray_t to store candidate list of tpc/flash to be used for matching
234  IDArray_t tpc_index_v;
235  IDArray_t flash_index_v;
236 
237  // Figure out which tpc object to use: if algorithm provided, ask it. Else use all.
238  if (_alg_tpc_filter)
239  tpc_index_v = _alg_tpc_filter->Filter(_tpc_object_v);
240  else {
241  tpc_index_v.reserve(_tpc_object_v.size());
242  for (size_t i = 0; i < _tpc_object_v.size(); ++i) tpc_index_v.push_back(i);
243  }
244 
245  FLASH_INFO() << "TPC Filter: " << _tpc_object_v.size() << " => " << tpc_index_v.size() << std::endl;
246 
247  // Figure out which flash to use: if algorithm provided, ask it. Else use all
248  if (_alg_flash_filter)
249  flash_index_v = _alg_flash_filter->Filter(_flash_v);
250  else {
251  flash_index_v.reserve(_flash_v.size());
252  for (size_t i = 0; i < _flash_v.size(); ++i) flash_index_v.push_back(i);
253  }
254  FLASH_INFO() << "Flash Filter: " << _flash_v.size() << " => " << flash_index_v.size() << std::endl;
255 
256  //
257  // Flash matching stage
258  //
259 
260  // use multi-map for possible equally-scored matches
261  std::multimap<double, FlashMatch_t> score_map;
262 
263  // Double loop over a list of tpc object & flash
264  // Call matching function to inspect the compatibility.
265  for (size_t tpc_index = 0; tpc_index < tpc_index_v.size(); ++tpc_index) {
266  // Loop over flash list
267  for (auto const& flash_index : flash_index_v) {
268  FLASH_INFO() << "TPC index " << tpc_index << ", Flash index " << flash_index << std::endl;
269  auto const& tpc = _tpc_object_v[tpc_index_v[tpc_index]]; // Retrieve TPC object
270  auto const& flash = _flash_v[flash_index]; // Retrieve flash
271 
272  if (tpc.size() == 0 )
273  continue;
274 
275  // run the match-prohibit algo first
276  if (_alg_match_prohibit) {
277  bool compat = _alg_match_prohibit->MatchCompatible( tpc, flash);
278  if (compat == false) {
279  FLASH_INFO() << "Match not compatible. " << std::endl;
280  continue;
281  }
282  }
283  auto start = high_resolution_clock::now();
284  auto res = _alg_flash_match->Match( tpc, flash ); // Run matching
286  auto duration = duration_cast<nanoseconds>(end - start);
287  FLASH_INFO() << "Match duration = " << duration.count() << "ns" << std::endl;
288 
289  // ignore this match if the score is <= 0
290  if (res.score <= 0) continue;
291 
292  // Else we store this match. Assign TPC & flash index info
293  res.tpc_id = tpc_index_v[tpc_index];//_index;
294  res.flash_id = flash_index;//_index;
295  res.duration = duration.count();
296 
297 
298  if(_store_full) {
299  _res_tpc_flash_v[res.tpc_id][res.flash_id] = res;
300  _res_flash_tpc_v[res.flash_id][res.tpc_id] = res;
301  }
302  // For ordering purpose, take an inverse of the score for sorting
303  score_map.emplace( 1. / res.score, res);
304 
305  FLASH_DEBUG() << "Candidate Match: "
306  << " TPC=" << tpc_index << " (" << tpc.min_x() << " min x)" << " @ " << tpc.time
307  << " with Flash=" << flash_index << " @ " << flash.time
308  << " ... Score=" << res.score
309  << " ... PE=" << flash.TotalPE()
310  << std::endl;
311  }
312  }
313 
314  // We have a score-ordered list of match information at this point.
315  // Prepare return match information by respecting a score of each possible match.
316  // Note _allow_reuse_flash becomes relevant here as well.
317 
318  // Create a std::set of tpc/flash IDs to keep track of already-matched tpc/flash input.
319  std::set<ID_t> tpc_used, flash_used;
320  result.reserve(tpc_index_v.size());
321  // Loop over score map created with matching algorithm
322  for (auto& score_info : score_map) {
323 
324  auto& match_info = score_info.second; // match information
325  auto const& tpc_index = match_info.tpc_id; // matched tpc original id
326  auto const& flash_index = match_info.flash_id; // matched flash original id
327 
328 // std::cout<<"tpc_index and flash_index : "<<tpc_index<<", "<<flash_index<<std::endl ;
329 
330  // If this tpc object is already assigned (=better match found), ignore
331  if (tpc_used.find(tpc_index) != tpc_used.end()) continue;
332 
333  // If this flash object is already assigned + re-use is not allowed, ignore
334  if (!_allow_reuse_flash && flash_used.find(flash_index) != flash_used.end()) continue;
335 
336  // Reaching this point means a new match. Yay!
337  FLASH_INFO () << "Concrete Match: " << " TPC=" << tpc_index << " Flash=" << flash_index
338  << " Score=" << match_info.score
339  << std::endl;
340 
341  // Register to a list of a "used" flash and tpc info
342  tpc_used.insert(tpc_index);
343  flash_used.insert(flash_index);
344 
345  // std::move matched info from the map to result vector
346  result.emplace_back( match_info );
347 
348  }
349  // Return result
350  return result;
351 
352  }
353 
355 
356  std::cout << "---- FLASH MATCH MANAGER PRINTING CONFIG ----" << std::endl
357  << "_allow_reuse_flash = " << _allow_reuse_flash << std::endl
358  << "_name = " << _name << std::endl
359  << "_alg_flash_filter?" << std::endl;
360  if (_alg_flash_filter)
361  std::cout << "\t" << _alg_flash_filter->AlgorithmName() << std::endl;
362  std::cout << "_alg_tpc_filter?" << std::endl;
363  if (_alg_tpc_filter)
364  std::cout << "\t" << _alg_tpc_filter->AlgorithmName() << std::endl;
365  std::cout << "_alg_match_prohibit?" << std::endl;
367  std::cout << "\t" << _alg_match_prohibit->AlgorithmName() << std::endl;
368  std::cout << "_alg_flash_hypothesis?" << std::endl;
370  std::cout << "\t" << _alg_flash_hypothesis->AlgorithmName() << std::endl;
371  std::cout << "_alg_flash_match?" << std::endl;
372  if (_alg_flash_match)
373  std::cout << "\t" << _alg_flash_match->AlgorithmName() << std::endl;
374  std::cout << "_custom_alg_m?" << std::endl;
375  for (auto& name_ptr : _custom_alg_m)
376  std::cout << "\t" << name_ptr.first << std::endl;
377  std::cout << "---- END FLASH MATCH MANAGER PRINTING CONFIG ----" << std::endl;
378  }
379 
380  void FlashMatchManager::SetChannelMask(std::vector<int> ch_mask) {
381 
382  if (!_alg_flash_hypothesis) {
383  throw OpT0FinderException("Flash hypothesis algorithm is required to set channel mask!");
384  }
385 
387  }
388 
389  void FlashMatchManager::SetTPCCryo(int tpc, int cryo) {
390  _tpc = tpc;
391  _cryo = cryo;
392 
393  if (_alg_flash_match) {
395  }
396  }
397 
398  void FlashMatchManager::SetUncoatedPMTs(std::vector<int> ch_uncoated) {
399  if (_alg_flash_hypothesis) {
401  }
402  }
403 
404  #if USING_LARSOFT == 1
405  void FlashMatchManager::SetSemiAnalyticalModel(std::unique_ptr<SemiAnalyticalModel> model) {
406  if (_alg_flash_hypothesis) {
408  }
409  }
410  #endif
411 
412 }
413 
414 #endif
Algorithm type to make QCluster_t =&gt; Flash_t hypothesis.
void set_verbosity(::flashmatch::msg::Level_t level)
Verbosity level.
Definition: LoggerFeature.h:47
Algorithm_t
Enumerator for different types of algorithm.
BaseTPCFilter * _alg_tpc_filter
TPC filter algorithm.
Algorithm type to match flash hypothesis and reconstructed flash.
BaseFlashFilter * create(const std::string name, const std::string instance_name)
Factory creation method (should be called by clients, possibly you!)
std::vector< flashmatch::FlashMatch_t > Match()
virtual IDArray_t Filter(const QClusterArray_t &)=0
std::vector< std::vector< flashmatch::FlashMatch_t > > _res_flash_tpc_v
Full result container indexed by [flash][tpc].
virtual bool MatchCompatible(const QCluster_t &clus, const Flash_t &flash)=0
CORE FUNCTION: determines if a flash and cluster are at all compatible (bool return) ...
flashmatch::BaseAlgorithm * GetCustomAlgo(std::string name)
Custom algorithm getter.
void SetSemiAnalyticalModel(std::unique_ptr< SemiAnalyticalModel > model)
BaseFlashHypothesis * _alg_flash_hypothesis
Flash hypothesis algorithm.
Class def header for a class TPCFilterFactory.
static FlashMatchFactory & get()
Static sharable instance getter.
#define FLASH_WARNING()
Compiler macro for WARNING message.
const std::string & Name() const
Name getter.
Algorithm type to filter out TPC objects from matching candidate list.
std::map< std::string, flashmatch::BaseAlgorithm * > _custom_alg_m
void SetTPCCryo(int tpc, int _cryo)
Sets the TPC and Cryo numbers.
#define FLASH_INFO()
Compiler macro for INFO message.
Algorithm type to filter out flash from matching candidate list.
fhicl::ParameterSet Config_t
Configuration object.
Definition: FMWKInterface.h:31
BaseAlgorithm * create(const std::string name, const std::string instance_name)
Factory creation method (should be called by clients, possibly you!)
void Add(flashmatch::QCluster_t &obj)
Adder of a TPC object.
Struct to represent an optical flash.
void SetChannelMask(std::vector< int >)
Sets the op channels to be used for matching.
BaseFlashFilter * _alg_flash_filter
Flash filter algorithm.
virtual IDArray_t Filter(const FlashArray_t &)=0
Class def header for a class FlashHypothesisFactory.
BaseProhibitAlgo * _alg_match_prohibit
Flash matchinig prohibit algorithm.
BaseFlashHypothesis * create(const std::string name, const std::string instance_name)
Factory creation method (should be called by clients, possibly you!)
void SetUncoatedPMTs(std::vector< int > ch_uncoated)
Sets the channels sensitive to visible light.
const std::string & AlgorithmName() const
Algorithm name.
flashmatch::BaseAlgorithm * GetAlgo(flashmatch::Algorithm_t type)
Algorithm getter.
BaseFlashMatch * create(const std::string name, const std::string instance_name)
Factory creation method (should be called by clients, possibly you!)
Class def header for a class FlashProhibitFactory.
Class def header for a class FlashMatchFactory.
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
Collection of charge deposition 3D point (cluster)
virtual void SetTPCCryo(int tpc, int cryo)=0
Sets the TPC and Cryo numbers.
Algorithm type to prohibit a match between a flash and a cluster.
BaseProhibitAlgo * create(const std::string name, const std::string instance_name)
Factory creation method (should be called by clients, possibly you!)
Class def header for a class FlashMatchManager.
static FlashProhibitFactory & get()
Static sharable instance getter.
static FlashFilterFactory & get()
Static sharable instance getter.
Class def header for exception classes in OpT0Finder package.
bool _configured
Configuration readiness flag.
bool _store_full
Request boolean to store full matching result (per Match function call)
std::vector< std::vector< flashmatch::FlashMatch_t > > _res_tpc_flash_v
Full result container indexed by [tpc][flash].
bool _allow_reuse_flash
Configuration option to allow re-use of a flash (i.e. 1 flash can be assigned to multiple TPC object)...
int _tpc
TPC number where to perform the matching.
QClusterArray_t _tpc_object_v
TPC object information collection (provided by a user)
void Configure(const Config_t &pset)
Function to accept configuration.
Level_t
Verbosity message level.
static CustomAlgoFactory & get()
Static sharable instance getter.
Class def header for a class CustomAlgoFactory.
#define FLASH_DEBUG()
Compiler macro for DEBUG message.
void SetFlashHypothesis(flashmatch::BaseFlashHypothesis *)
#define FLASH_ERROR()
Compiler macro for ERROR message.
BaseTPCFilter * create(const std::string name, const std::string instance_name)
Factory creation method (should be called by clients, possibly you!)
void SetUncoatedPMTs(std::vector< int > ch_uncoated)
Sets the channels sensitive to visible light.
std::vector< flashmatch::ID_t > IDArray_t
Index collection.
virtual FlashMatch_t Match(const QCluster_t &, const Flash_t &)=0
FlashArray_t _flash_v
Flash object information collection (provided by a user)
int _cryo
Cryo number where to perform the matching.
void Configure(const Config_t &cfg)
Configuration.
then echo fcl name
void SetSemiAnalyticalModel(std::unique_ptr< SemiAnalyticalModel > model)
Sets the semi analytical model.
void SetChannelMask(std::vector< int > ch_mask)
Sets the channels to use.
static FlashHypothesisFactory & get()
Static sharable instance getter.
Class def header for a class FlashFilterFactory.
const std::string & name() const
Name getter, defined in a logger instance attribute.
Definition: LoggerFeature.h:51
void Emplace(flashmatch::QCluster_t &&obj)
Emplacer of a TPC object (hidden from ROOT5 CINT)
BEGIN_PROLOG could also be cout
nanosecond nanoseconds
Alias for common language habits.
Definition: spacetime.h:139
BaseFlashMatch * _alg_flash_match
Flash matching algorithm.
static TPCFilterFactory & get()
Static sharable instance getter.
void AddCustomAlgo(BaseAlgorithm *alg)
bool Valid(size_t nopdet=0) const
Check validity.