gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-252-gf9a3f78
a Global And Modular Bsm Inference Tool
spec_fptrfinder.hpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
19 
20 #ifndef __SpecFptrFinder_hpp__
21 #define __SpecFptrFinder_hpp__
22 
26 
27 // Particle database access
28 #define PDB Models::ParticleDB()
29 
30 // Debugging
31 //#define CHECK_WHERE_FOUND
32 
33 namespace Gambit {
34 
36  template<class HostSpec, class MTag>
37  class FptrFinder;
38 
40  template<class HostSpec, class MTag>
41  class SetMaps
42  {
43  public:
44  SetMaps(const std::string& label, HostSpec* const fakethis)
45  : label_(label)
46  , fakethis_(fakethis)
47  , const_fakethis_(fakethis)
48  , no_overrides_(false)
49  , override_only_(false)
50  , map0_(NULL)
51  , map1_(NULL)
52  , map2_(NULL)
53  , map0W_(NULL)
54  , map1W_(NULL)
55  , map2W_(NULL)
56  , map0M_(NULL)
57  , map1M_(NULL)
58  , map2M_(NULL)
59  , map0I_(NULL)
60  , map1I_(NULL)
61  , map2I_(NULL)
62  , omap0_(NULL)
63  , omap1_(NULL)
64  , omap2_(NULL)
65  {}
66 
68  SetMaps(const std::string& label, const HostSpec* const fakethis)
69  : label_(label)
70  , fakethis_(NULL) // CANNOT USE WHEN HOST IS CONST
71  , const_fakethis_(fakethis)
72  , no_overrides_(false)
73  , override_only_(false)
74  , map0_(NULL)
75  , map1_(NULL)
76  , map2_(NULL)
77  , map0W_(NULL)
78  , map1W_(NULL)
79  , map2W_(NULL)
80  , map0M_(NULL)
81  , map1M_(NULL)
82  , map2M_(NULL)
83  , map0I_(NULL)
84  , map1I_(NULL)
85  , map2I_(NULL)
86  , omap0_(NULL)
87  , omap1_(NULL)
88  , omap2_(NULL)
89  {}
90 
92  typedef typename HostSpec::D D;
93 
95  SetMaps& map0 (const typename MapTypes<D,MTag>::fmap0& map0) { map0_ =&map0; return *this; }
96  SetMaps& map1 (const typename MapTypes<D,MTag>::fmap1& map1) { map1_ =&map1; return *this; }
97  SetMaps& map2 (const typename MapTypes<D,MTag>::fmap2& map2) { map2_ =&map2; return *this; }
98  SetMaps& map0W(const typename MapTypes<D,MTag>::fmap0W& map0W){ map0W_=&map0W; return *this; }
99  SetMaps& map1W(const typename MapTypes<D,MTag>::fmap1W& map1W){ map1W_=&map1W; return *this; }
100  SetMaps& map2W(const typename MapTypes<D,MTag>::fmap2W& map2W){ map2W_=&map2W; return *this; }
101  SetMaps& map0M(const typename MapTypes<D,MTag>::fmap0_extraM& map0M){ map0M_=&map0M; return *this; }
102  SetMaps& map1M(const typename MapTypes<D,MTag>::fmap1_extraM& map1M){ map1M_=&map1M; return *this; }
103  SetMaps& map2M(const typename MapTypes<D,MTag>::fmap2_extraM& map2M){ map2M_=&map2M; return *this; }
104  SetMaps& map0I(const typename MapTypes<D,MTag>::fmap0_extraI& map0I){ map0I_=&map0I; return *this; }
105  SetMaps& map1I(const typename MapTypes<D,MTag>::fmap1_extraI& map1I){ map1I_=&map1I; return *this; }
106  SetMaps& map2I(const typename MapTypes<D,MTag>::fmap2_extraI& map2I){ map2I_=&map2I; return *this; }
108  SetMaps& omap0(const std::map<std::string,double>& om0) { omap0_=&om0; return *this;}
109  SetMaps& omap1(const std::map<std::string,std::map<int,double>>& om1){ omap1_=&om1; return *this;}
110  SetMaps& omap2(const std::map<std::string,std::map<int,std::map<int,double>>>& om2){ omap2_=&om2; return *this;}
112  SetMaps& no_overrides(const bool flag) { no_overrides_=flag; return *this;}
114  SetMaps& override_only(const bool flag) { override_only_=flag; return *this;}
115  // (Obviously don't set both of the above flags at once, or else there will be no maps to search...)
116 
117  private:
118  friend class FptrFinder<HostSpec,MTag>;
119  const std::string label_;
120  HostSpec* const fakethis_;
121  const HostSpec* const const_fakethis_;
124 
138 
140  const std::map<std::string,double>* omap0_;
141  const std::map<std::string,std::map<int,double>>* omap1_;
142  const std::map<std::string,std::map<int,std::map<int,double>>>* omap2_;
143  };
144 
146  template<class HostSpec, class MTag>
147  class CallFcn;
148 
152  template<class HostSpec, class MTag>
153  class FptrFinder
154  {
155  friend class CallFcn<HostSpec,MTag>;
156 
157  private:
159  const std::string label;
160 
162  std::string lastname;
163 
165  HostSpec* const fakethis;
166  const HostSpec* const const_fakethis;
167 
169  typedef typename HostSpec::D D; // D for "DerivedSpec"
170 
172  const bool no_overrides_;
173 
175  const bool override_only_;
176 
179  const std::map<std::string,double>* omap0_;
180  const std::map<std::string,std::map<int,double>>* omap1_;
181  const std::map<std::string,std::map<int,std::map<int,double>>>* omap2_;
195 
198  std::map<std::string,double>::const_iterator ito0; // 0
199  std::map<std::string,std::map<int,double>>::const_iterator ito1; // 1
200  std::map<std::string,std::map<int,std::map<int,double>>>::const_iterator ito2; // 2
214 
216  static const std::map<std::string,double> nullmap_ito0; // 0
217  static const std::map<std::string,std::map<int,double>> nullmap_ito1; // 1
218  static const std::map<std::string,std::map<int,std::map<int,double>>> nullmap_ito2; // 2
219  static const typename MapTypes<D,MTag>::fmap0 nullmap_it0; // 3
220  static const typename MapTypes<D,MTag>::fmap1 nullmap_it1; // 6
221  static const typename MapTypes<D,MTag>::fmap2 nullmap_it2; // 9 //was 7
222  static const typename MapTypes<D,MTag>::fmap0W nullmap_it0W; // ? 12
223  static const typename MapTypes<D,MTag>::fmap1W nullmap_it1W; // ? 13
224  static const typename MapTypes<D,MTag>::fmap2W nullmap_it2W; // ? 14
225  static const typename MapTypes<D,MTag>::fmap0_extraM nullmap_it0M; // 4
226  static const typename MapTypes<D,MTag>::fmap1_extraM nullmap_it1M; // 7
227  static const typename MapTypes<D,MTag>::fmap2_extraM nullmap_it2M; // 10
228  static const typename MapTypes<D,MTag>::fmap0_extraI nullmap_it0I; // 5
229  static const typename MapTypes<D,MTag>::fmap1_extraI nullmap_it1I; // 8
230  static const typename MapTypes<D,MTag>::fmap2_extraI nullmap_it2I; // 11
231 
233  bool ito0_safe() { return ito0 != nullmap_ito0.end(); };
234  bool ito1_safe() { return ito1 != nullmap_ito1.end(); };
235  bool ito2_safe() { return ito2 != nullmap_ito2.end(); };
236  bool it0_safe() { return it0 != nullmap_it0.end(); };
237  bool it1_safe() { return it1 != nullmap_it1.end(); };
238  bool it2_safe() { return it2 != nullmap_it2.end(); };
239  bool it0W_safe() { return it0W != nullmap_it0W.end(); };
240  bool it1W_safe() { return it1W != nullmap_it1W.end(); };
241  bool it2W_safe() { return it2W != nullmap_it2W.end(); };
242  bool it0M_safe() { return it0M != nullmap_it0M.end(); };
243  bool it1M_safe() { return it1M != nullmap_it1M.end(); };
244  bool it2M_safe() { return it2M != nullmap_it2M.end(); };
245  bool it0I_safe() { return it0I != nullmap_it0I.end(); };
246  bool it1I_safe() { return it1I != nullmap_it1I.end(); };
247  bool it2I_safe() { return it2I != nullmap_it2I.end(); };
248 
249  // int which records which iterator points to the search result
250  int whichiter;
251 
252  // indices required for function call
253  int index1;
254  int index2;
255 
256  // error code
257  // -1 : search not yet attempted
258  // 0 : no problem, search succeeded
259  // 1 : string name lookup failed
260  // 2 : string name lookup succeeded, index1 out of bounds
261  // 3 : string name lookup succeeded, index2 out of bounds
263 
264  // Messages corresponding to the above error codes
265  static const std::map<int, const std::string> error_msg;
266 
267  public:
275 
276  // Constructor utilising named "parameters"
278  : label(params.label_)
279  , lastname("NONE")
280  , fakethis(params.fakethis_)
281  , const_fakethis(params.const_fakethis_)
282  , no_overrides_(params.no_overrides_)
283  , override_only_(params.override_only_)
284  , omap0_(params.omap0_)
285  , omap1_(params.omap1_)
286  , omap2_(params.omap2_)
287  , map0_ (params.map0_)
288  , map1_ (params.map1_)
289  , map2_ (params.map2_)
290  , map0W_(params.map0W_)
291  , map1W_(params.map1W_)
292  , map2W_(params.map2W_)
293  , map0M_(params.map0M_)
294  , map1M_(params.map1M_)
295  , map2M_(params.map2M_)
296  , map0I_(params.map0I_)
297  , map1I_(params.map1I_)
298  , map2I_(params.map2I_)
299  , ito0(nullmap_ito0.end())
300  , ito1(nullmap_ito1.end())
301  , ito2(nullmap_ito2.end())
302  , it0 (nullmap_it0.end())
303  , it1 (nullmap_it1.end())
304  , it2 (nullmap_it2.end())
305  , it0W(nullmap_it0W.end())
306  , it1W(nullmap_it1W.end())
307  , it2W(nullmap_it2W.end())
308  , it0M(nullmap_it0M.end())
309  , it1M(nullmap_it1M.end())
310  , it2M(nullmap_it2M.end())
311  , it0I(nullmap_it0I.end())
312  , it1I(nullmap_it1I.end())
313  , it2I(nullmap_it2I.end())
314  , whichiter(-1)
315  , index1(-1)
316  , index2(-1)
317  , error_code(-1)
318  , callfcn(this)
319  {}
320 
322  int get_error_code(){ return error_code; }
323  std::string get_error_message()
324  {
325  std::string msg;
326  switch(error_code)
327  {
328  case -2: msg = "Search began but did not properly set the error code!"; break;
329  case -1: msg = "Search not yet attempted"; break;
330  case 0: msg = "No problem, search succeeded"; break;
331  case 1: msg = "String name lookup failed"; break;
332  case 2: msg = "String name lookup succeeded, index1 out of bounds"; break;
333  case 3: msg = "String name lookup succeeded, index2 out of bounds"; break;
334  default: msg = "Unrecognised error code! This is a bug in FptrFinder!";
335  }
336  return msg;
337  }
338  // Raise error if the calling context can't handle a failed search
339  void raise_error(const std::string& origin)
340  {
341  std::ostringstream errmsg;
342  errmsg << "Error retrieving particle spectrum data!" << std::endl;
343  errmsg << "No "<<label<<" with string reference '"<<lastname<<"' exists!" <<std::endl;
344  errmsg << "Search failed with error_code "<<error_code<<" from FptrFinder with label "<<label<<": "<<get_error_message();
345  if(index1!=-1) errmsg << " index1: "<<index1<<std::endl;
346  if(index2!=-1) errmsg << " index2: "<<index2<<std::endl;
347  utils_error().forced_throw(origin,errmsg.str());
348  }
349  // Check if an index has been set, and raise error if not
350  void check_index_initd(const std::string& origin, const int index, const std::string& label)
351  {
352  if(index==-1)
353  {
354  std::ostringstream errmsg;
355  errmsg << "Error retrieving particle spectrum data!" << std::endl;
356  errmsg << "An index ("<<label<<") was not set when retrieving item of type '"<<label<<"' with string reference '"<<lastname<<"'!" <<std::endl;
357  errmsg << "This is a bug in the FptrFinder class, please report it."<<std::endl;
358  utils_error().forced_throw(origin,errmsg.str());
359  }
360  }
362 
364  template<class Map>
365  bool search_map(const std::string& name, const Map* const map, typename Map::const_iterator& it)
366  {
367  bool found = true;
368  if(map==NULL)
369  {
370  std::ostringstream errmsg;
371  errmsg << "Tried to use FptrFinder to search a SubSpectrum function pointer map, but did not correctly supply the map to FptrFinder! This is a bug in the SubSpectrum class; please report it. (Attempted to access map of type "<<typeid(Map).name()<<")";
372  utils_error().forced_throw(LOCAL_INFO,errmsg.str());
373  }
374  it = map->find(name);
375  if( it == map->end() ){ found = false; lastname = name; }
376  return found;
377  }
378 
381  void check(bool safe)
382  {
383  if(not safe)
384  {
385  std::ostringstream errmsg;
386  errmsg << "Safety check for map iterator failed! (in FptrFinder). This indicates a bug in the FptrFinder class; please report it.";
387  utils_error().forced_throw(LOCAL_INFO,errmsg.str());
388  }
389  }
390 
398 
399  template<class ITER>
400  bool check_indices_1(const std::string& name, const ITER& it, const int i, const int whichit, const bool debug)
401  {
402  bool found = false;
403  /* Switch index convention */
404  int offset = const_fakethis->get_index_offset();
405  index1 = i + offset; /* set for later use */
406  /* Check that index is in the permitted set */
407  if( not within_bounds(index1, it->second.iset1) )
408  {
409  /* index1 out of bounds */
410  found = false;
411  error_code = 2;
412  }
413  else {
414  /* everything cool. */
415  found = true;
416  if(debug) std::cout<<" Found ("<<name<<","<<i<<") in 1-index map"<<std::endl;
417  whichiter=whichit;
418  }
419  return found;
420  }
421 
422  template<class ITER>
423  bool check_indices_2(const std::string& /*name*/, const ITER& it, const int i, const int j, const int whichit)
424  {
425  bool found = false;
426  /* Switch index convention */
427  int offset = const_fakethis->get_index_offset();
428  index1 = i + offset; /* set for later use */
429  index2 = j + offset; /* set for later use */
430  /* Check that index is in the permitted set */
431  if( not within_bounds(index1, it->second.iset1) )
432  {
433  /* index1 out of bounds */
434  found = false;
435  error_code = 2;
436  }
437  else if( not within_bounds(index2, it->second.iset2) )
438  {
439  /* index2 out of bounds */
440  found = false;
441  error_code = 3;
442  }
443  else {
444  /* everything cool. */
445  found = true;
446  whichiter=whichit;
447  }
448  return found;
449  }
450 
453 
455  bool find_override_0index(const std::string& name)
456  {
457  bool found = false;
458  #ifdef CHECK_WHERE_FOUND
459  std::cout<<" Searching 0-index override maps for "<<name<<std::endl;
460  #endif
461  if( omap0_!=NULL and search_map(name,omap0_,ito0) )
462  {
463  found=true;
464  whichiter=0;
465  #ifdef CHECK_WHERE_FOUND
466  std::cout<<" Found "<<name<<" in 0-index override map"<<std::endl;
467  #endif
468  }
469  return found;
470  }
471 
473  bool find_override_1index(const std::string& name, const int i)
474  {
475  bool found = false;
476  #ifdef CHECK_WHERE_FOUND
477  std::cout<<" Searching 1-index override maps for ("<<name<<","<<i<<")"<<std::endl;
478  #endif
479  if( omap1_!=NULL and search_map(name,omap1_,ito1) )
480  {
481  // Check that index (key) exists in inner map
482  std::map<int,double>::const_iterator it = ito1->second.find(i);
483  if( it != ito1->second.end() )
484  {
485  found=true;
486  index1=i;
487  whichiter=1;
488  #ifdef CHECK_WHERE_FOUND
489  std::cout<<" Found ("<<name<<","<<i<<") in 1-index override map"<<std::endl;
490  #endif
491  }
492  }
493  return found;
494  }
495 
497  bool find_override_2index(const std::string& name, const int i, const int j)
498  {
499  bool found = false;
500  #ifdef CHECK_WHERE_FOUND
501  std::cout<<" Searching 2-index override maps for ("<<name<<","<<i<<","<<j<<")"<<std::endl;
502  #endif
503  if( omap2_!=NULL and search_map(name,omap2_,ito2) )
504  {
505  // Check that first index (key) exists in inner map
506  std::map<int,std::map<int,double>>::const_iterator jt = ito2->second.find(i);
507  if( jt != ito2->second.end() )
508  {
509  // Check that second index (key) exists in second-inner map
510  std::map<int,double>::const_iterator jt2 = jt->second.find(j);
511  if( jt2 != jt->second.end() )
512  {
513  found=true;
514  index1=i;
515  index2=j;
516  whichiter=2;
517  }
518  }
519  }
520  return found;
521  }
522 
524  bool find_0index(const std::string& name)
525  {
526  bool found = false;
527  #ifdef CHECK_WHERE_FOUND
528  std::cout<<" Searching 0-index standard maps for "<<name<<std::endl;
529  #endif
530  if ( search_map(name,map0_,it0) ){ found=true; whichiter=3;
531  #ifdef CHECK_WHERE_FOUND
532  std::cout<<" Found "<<name<<" in found in 0-index map (type O)"<<std::endl;
533  #endif
534  }
535  else if( search_map(name,map0W_,it0W) ){ found=true; whichiter=12;
536  #ifdef CHECK_WHERE_FOUND
537  std::cout<<" Found "<<name<<" in found in 0-index map (type OW)"<<std::endl;
538  #endif
539  }
540  else if( search_map(name,map0M_,it0M) ){ found=true; whichiter=4;
541  #ifdef CHECK_WHERE_FOUND
542  std::cout<<" Found "<<name<<" in found in 0-index map (type OM)"<<std::endl;
543  #endif
544  }
545  else if( search_map(name,map0I_,it0I) ){ found=true; whichiter=5;
546  #ifdef CHECK_WHERE_FOUND
547  std::cout<<" Found "<<name<<" in found in 0-index map (type OI)"<<std::endl;
548  #endif
549  }
550  return found;
551  }
552 
554  bool find_1index(const std::string& name, const int i)
555  {
556  bool found = false;
557  #ifdef CHECK_WHERE_FOUND
558  std::cout<<" Searching standard 1-index maps for ("<<name<<","<<i<<")"<<std::endl;
559  #endif
560 
561  bool debug=false;
562  #ifdef CHECK_WHERE_FOUND
563  debug=true;
564  #endif
565 
566  if( search_map(name,map1_,it1) ) { check(it1_safe()); found=check_indices_1(name,it1 ,i,6,debug); }
567  else if( search_map(name,map1W_,it1W) ){ check(it1W_safe()); found=check_indices_1(name,it1W,i,13,debug); }
568  else if( search_map(name,map1M_,it1M) ){ check(it1M_safe()); found=check_indices_1(name,it1M,i,7,debug); }
569  else if( search_map(name,map1I_,it1I) ){ check(it1I_safe()); found=check_indices_1(name,it1I,i,8,debug); }
570  return found;
571  }
572 
574  bool find_2index(const std::string& name, const int i, const int j)
575  {
576  bool found = false;
577  #ifdef CHECK_WHERE_FOUND
578  std::cout<<" Searching standard 2-index maps for ("<<name<<","<<i<<","<<j<<")"<<std::endl;
579  #endif
580 
581  if( search_map(name,map2_,it2) ) { check(it2_safe()); found=check_indices_2(name,it2, i,j,9); }
582  else if( search_map(name,map2W_,it2W) ){ check(it2W_safe()); found=check_indices_2(name,it2W,i,j,14); }
583  else if( search_map(name,map2M_,it2M) ){ check(it2M_safe()); found=check_indices_2(name,it2M,i,j,10); }
584  else if( search_map(name,map2I_,it2I) ){ check(it2I_safe()); found=check_indices_2(name,it2I,i,j,11); }
585  else {
586  found = false;
587  error_code = 1;
588  }
589 
590  return found;
591  }
592 
594 
596  bool find(const std::string& name, bool /*doublecheck*/=true, SafeBool check_antiparticle = SafeBool(true))
597  {
598  bool found = false;
599  lastname = name;
600  error_code = -2;
601  #ifdef CHECK_WHERE_FOUND
602  std::cout<<" Searching all 0-index maps for "<<name<<std::endl;
603  #endif
604 
608  std::string antiname = "none";
609  if(check_antiparticle and PDB.has_particle(name) and PDB.has_antiparticle(name))
610  {
611  antiname = PDB.get_antiparticle(name);
612  } else {
613  check_antiparticle = SafeBool(false); // No antiparticle PDB entry, so cancel that part of search.
614  }
615 
616  // Search override maps first
617  if(not found and not no_overrides_)
618  {
619  if(not found) found = find_override_0index(name);
620  if(not found and PDB.has_short_name(name) ) {
621  std::pair<str, int> p = PDB.short_name_pair(name);
622  found = find_override_1index(p.first, p.second);
623  }
624  if(check_antiparticle) // Check antiparticles
625  {
626  if(not found) found = find_override_0index(antiname);
627  if(not found and PDB.has_short_name(antiname) ) {
628  std::pair<str, int> p = PDB.short_name_pair(antiname);
629  found = find_override_1index(p.first, p.second);
630  }
631  }
632  if(not found) error_code = 1;
633  }
634 
635  // If no override match, search the wrapper class maps
636  if(not found and not override_only_)
637  {
638  if(not found) found = find_0index(name);
639  if(not found and PDB.has_short_name(name) ) {
640  std::pair<str, int> p = PDB.short_name_pair(name);
641  found = find_1index(p.first, p.second);
642  }
643  if(check_antiparticle) // Check antiparticles
644  {
645  if(not found) found = find_0index(antiname);
646  if(not found and PDB.has_short_name(antiname) ) {
647  std::pair<str, int> p = PDB.short_name_pair(antiname);
648  found = find_1index(p.first, p.second);
649  }
650  }
651  if(not found) error_code = 1;
652  }
653 
654  #ifdef CHECK_WHERE_FOUND
655  std::cout<<" 0-index search result: found="<<found<<std::endl;
656  #endif
657 
658  if(found) error_code = 0; // Should be no problem!
659  return found;
660  }
661 
663  bool find(const std::string& name, int i, bool /*doublecheck*/=true, SafeBool check_antiparticle = SafeBool(true))
664  {
665  bool found = false;
666  lastname = name;
667  error_code = -2;
668  #ifdef CHECK_WHERE_FOUND
669  std::cout<<" Searching all 1-index maps for ("<<name<<","<<i<<")"<<std::endl;
670  #endif
671 
673  std::string antiname = "none";
674  int ai = 0;
675  if(check_antiparticle and PDB.has_particle(name,i) and PDB.has_antiparticle(name,i))
676  {
677  std::pair<str,int> p = PDB.get_antiparticle(name,i);
678  antiname = p.first;
679  ai = p.second;
680  } else {
681  check_antiparticle = SafeBool(false); // No antiparticle PDB entry, so cancel that part of search.
682  }
683 
684  // Search override maps first
685  if(not found and not no_overrides_)
686  {
687  if(not found) found = find_override_1index(name,i);
688  if(not found) found = find_override_0index(PDB.long_name(name,i));
689  if(check_antiparticle) // Check antiparticles
690  {
691  if(not found) found = find_override_1index(antiname,ai);
692  if(not found) found = find_override_0index(PDB.long_name(antiname,ai));
693  }
694  if(not found) error_code = 1;
695  }
696 
697  if(not found and not override_only_)
698  {
699  if(not found) found = find_1index(name,i);
700  if(not found) found = find_0index(PDB.long_name(name,i));
701  if(check_antiparticle) // Check antiparticles
702  {
703  if(not found) found = find_1index(antiname,ai);
704  if(not found) found = find_0index(PDB.long_name(antiname,ai));
705  }
706  if(not found) error_code = 1;
707  }
708 
709  #ifdef CHECK_WHERE_FOUND
710  std::cout<<" 1-index search result: found="<<found<<std::endl;
711  #endif
712 
713  if(found) error_code = 0; // Should be no problem!
714  return found;
715  }
716 
718  bool find(const std::string& name, int i, int j)
719  {
720  bool found = false;
721  lastname = name;
722  error_code = -2;
723 
724  // Antiparticle string is a bit tricky here, because it is not
725  // well-defined whether the name or a name plus index is needed
726  // for the conversion. Better off just banning antiparticle
727  // name conversions for two-index cases.
728 
729  // Search maps for function; if found then store it
730  if( not no_overrides_ )
731  {
732  if(not found) found = find_override_2index(name,i,j);
733  if(not found) error_code = 1;
734  }
735 
736  // If no override, search the wrapper class maps
737  if(not found and not override_only_)
738  {
739  if(not found) found = find_2index(name,i,j);
740  if(not found) error_code = 1;
741  }
742 
743  #ifdef CHECK_WHERE_FOUND
744  std::cout<<" 2-index search result: found="<<found<<std::endl;
745  #endif
746 
747  if(found) error_code = 0; // Should be no problem!
748  return found;
749  }
750 
751  }; // end class FptrFinder
752 
754  template<class HS, class MT> const std::map<std::string,double> FptrFinder<HS,MT>::nullmap_ito0 = std::map<std::string,double> (); // 0
755  template<class HS, class MT> const std::map<std::string,std::map<int,double>> FptrFinder<HS,MT>::nullmap_ito1 = std::map<std::string,std::map<int,double>>(); // 1
756  template<class HS, class MT> const std::map<std::string,std::map<int,std::map<int,double>>> FptrFinder<HS,MT>::nullmap_ito2 = std::map<std::string,std::map<int,std::map<int,double>>>(); // 2
758  template<class HS, class MT> const typename MapTypes<typename HS::D,MT>::fmap0 FptrFinder<HS,MT>::nullmap_it0 = typename MapTypes<typename HS::D,MT>::fmap0 (); // 3
759  template<class HS, class MT> const typename MapTypes<typename HS::D,MT>::fmap1 FptrFinder<HS,MT>::nullmap_it1 = typename MapTypes<typename HS::D,MT>::fmap1 (); // 6
760  template<class HS, class MT> const typename MapTypes<typename HS::D,MT>::fmap2 FptrFinder<HS,MT>::nullmap_it2 = typename MapTypes<typename HS::D,MT>::fmap2 (); // 9 //was 7
761  template<class HS, class MT> const typename MapTypes<typename HS::D,MT>::fmap0W FptrFinder<HS,MT>::nullmap_it0W = typename MapTypes<typename HS::D,MT>::fmap0W (); // 12
762  template<class HS, class MT> const typename MapTypes<typename HS::D,MT>::fmap1W FptrFinder<HS,MT>::nullmap_it1W = typename MapTypes<typename HS::D,MT>::fmap1W (); // 13
763  template<class HS, class MT> const typename MapTypes<typename HS::D,MT>::fmap2W FptrFinder<HS,MT>::nullmap_it2W = typename MapTypes<typename HS::D,MT>::fmap2W (); // 14
770 
771 
773  template<class HostSpec>
774  class CallFcn<HostSpec,MapTag::Get>
775  {
776  private:
777  // Model and Input types from wrapper traits class
778  typedef typename HostSpec::D DerivedSpec;
781 
784 
785  public:
787  : ff(host)
788  {}
789 
790  double operator()()
791  {
792  double result(-1); // should not be returned in this state
793  if(ff->error_code==0)
794  {
795  const Model& model = ff->const_fakethis->model();
796  const Input& input = ff->const_fakethis->input();
797  switch( ff->whichiter )
798  {
799  // Override retrieval cases
800  case 0: {
801  ff->check(ff->ito0_safe());
802  result = ff->ito0->second;
803  break;}
804  case 1: {
805  ff->check(ff->ito1_safe());
806  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
807  result = (ff->ito1->second).at(ff->index1);
808  break;}
809  case 2: {
810  ff->check(ff->ito2_safe());
811  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
812  ff->check_index_initd(LOCAL_INFO,ff->index2,"index2");
813  result = (ff->ito2->second).at(ff->index1).at(ff->index2);
814  break;}
815  // Wrapper class function call cases
816  case 3: {
817  ff->check(ff->it0_safe());
818  typename MT::FSptr f = ff->it0->second;
819  result = (model.*f)();
820  break;}
821  case 4: {
822  ff->check(ff->it0M_safe());
823  typename MT::plainfptrM f = ff->it0M->second;
824  result = (*f)(model);
825  break;}
826  case 5: {
827  ff->check(ff->it0I_safe());
828  typename MT::plainfptrI f = ff->it0I->second;
829  result = (*f)(input);
830  break;}
831  case 6: {
832  ff->check(ff->it1_safe());
833  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
834  typename MT::FSptr1 f = ff->it1->second.fptr;
835  result = (model.*f)(ff->index1);
836  break;}
837  case 7: {
838  ff->check(ff->it1M_safe());
839  typename MT::plainfptrM1 f = ff->it1M->second.fptr;
840  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
841  result = (*f)(model,ff->index1);
842  break;}
843  case 8: {
844  ff->check(ff->it1I_safe());
845  typename MT::plainfptrI1 f = ff->it1I->second.fptr;
846  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
847  result = (*f)(input,ff->index1);
848  break;}
849  case 9: {
850  ff->check(ff->it2_safe());
851  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
852  ff->check_index_initd(LOCAL_INFO,ff->index2,"index2");
853  typename MT::FSptr2 f = ff->it2->second.fptr;
854  result = (model.*f)(ff->index1,ff->index2);
855  break;}
856  case 10: {
857  ff->check(ff->it2M_safe());
858  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
859  ff->check_index_initd(LOCAL_INFO,ff->index2,"index2");
860  typename MT::plainfptrM2 f = ff->it2M->second.fptr;
861  result = (*f)(model,ff->index1,ff->index2);
862  break;}
863  case 11: {
864  ff->check(ff->it2I_safe());
865  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
866  ff->check_index_initd(LOCAL_INFO,ff->index2,"index2");
867  typename MT::plainfptrI2 f = ff->it2I->second.fptr;
868  result = (*f)(input,ff->index1,ff->index2);
869  break;}
870  case 12: {
871  ff->check(ff->it0W_safe());
872  typename MT::FSptrW f = ff->it0W->second;
873  // These are member functions of DerivedSpec, but "HostSpec"
874  // (and therefore the fakethis pointers) is going to be of
875  // type Spec<DerivedSpec>. Therefore need to cast to the
876  // derived type to call the function.
877  const DerivedSpec* wrapper = static_cast<const DerivedSpec*>(ff->const_fakethis);
878  result = (wrapper->*f)();
879  break;}
880  case 13: {
881  ff->check(ff->it1W_safe());
882  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
883  typename MT::FSptr1W f = ff->it1W->second.fptr;
884  const DerivedSpec* wrapper = static_cast<const DerivedSpec*>(ff->const_fakethis);
885  result = (wrapper->*f)(ff->index1);
886  break;}
887  case 14: {
888  ff->check(ff->it2W_safe());
889  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
890  ff->check_index_initd(LOCAL_INFO,ff->index2,"index2");
891  typename MT::FSptr2W f = ff->it2W->second.fptr;
892  const DerivedSpec* wrapper = static_cast<const DerivedSpec*>(ff->const_fakethis);
893  result = (wrapper->*f)(ff->index1,ff->index2);
894  break;}
895  default:{
896  std::ostringstream errmsg;
897  errmsg << "Error! Unanticipated whichiter code received while trying to call a function from SubSpectrum maps. This indicates a bug in the FptrFinder class. Please report it! (this FptrFinder has label="<<ff->label<<" and is specialised for Getter maps, current error_code="<<ff->error_code<<", whichiter="<<ff->whichiter<<")"<<std::endl;
898  utils_error().forced_throw(LOCAL_INFO,errmsg.str());
899  }
900  }
901  } else if(ff->error_code==-1)
902  {
903  std::ostringstream errmsg;
904  errmsg << "Error! Tried to call function from SubSpectrum maps without first finding the function! This indicates a bug, probably in the Spectrum or SubSpectrum classes. Please report it! (this FptrFinder has label="<<ff->label<<" and is specialised for Getter maps, current error_code="<<ff->error_code<<")"<<std::endl;
905  utils_error().forced_throw(LOCAL_INFO,errmsg.str());
906  } else {
907  std::ostringstream errmsg;
908  errmsg << "Error! Unanticipated error code received while trying to call a function from SubSpectrum maps. This indicates a bug in the FptrFinder class. Please report it! (this FptrFinder has label="<<ff->label<<" and is specialised for Getter maps, current error_code="<<ff->error_code<<")"<<std::endl;
909  utils_error().forced_throw(LOCAL_INFO,errmsg.str());
910  }
911  return result;
912  }
913  };
914 
916  template<class HostSpec>
917  class CallFcn<HostSpec,MapTag::Set>
918  {
919  private:
920  // Model and Input types from wrapper traits class
921  typedef typename HostSpec::D DerivedSpec;
924 
927 
928  public:
930  : ff(host)
931  {}
932 
933  void operator()(const double set_value)
934  {
935  if(ff->error_code==0)
936  {
937  // Must use NON-const version; make sure pointer correctly initialised!
938  if(ff->fakethis==NULL)
939  {
940  std::ostringstream errmsg;
941  errmsg << "Error! 'Setter' version of FptrFinder tried to use non-const 'fakethis' pointer, but the pointer was not initialised! This indicates a bug in the FptrFinder class. Please report it! (this FptrFinder has label="<<ff->label<<" and is specialised for Setter maps, current error_code="<<ff->error_code<<", whichiter="<<ff->whichiter<<")"<<std::endl;
942  utils_error().forced_throw(LOCAL_INFO,errmsg.str());
943  }
944  Model& model = ff->fakethis->model();
945  Input& input = ff->fakethis->input();
946  switch( ff->whichiter )
947  {
948  // Override retrieval cases
949  // ABSENT ON PURPOSE. set_override functions don't work via an fptrfinder
950  case 0:
951  case 1:
952  case 2: {
953  std::ostringstream errmsg;
954  errmsg << "Error! 'Setter' version of FptrFinder called a map-access case reserved for override maps, however these only work in the 'Getter' version (since SubSpectrum override values are not supposed to be set via an FptrFinder). This indicates a bug in the FptrFinder class. Please report it! (this FptrFinder has label="<<ff->label<<" and is specialised for Setter maps, current error_code="<<ff->error_code<<", whichiter="<<ff->whichiter<<")"<<std::endl;
955  utils_error().forced_throw(LOCAL_INFO,errmsg.str());
956  break;
957  }
958  // Wrapper class function call cases
959  case 3: {
960  ff->check(ff->it0_safe());
961  typename MT::FSptr f = ff->it0->second;
962  (model.*f)(set_value);
963  break;}
964  case 4: {
965  ff->check(ff->it0M_safe());
966  typename MT::plainfptrM f = ff->it0M->second;
967  (*f)(model,set_value);
968  break;}
969  case 5: {
970  ff->check(ff->it0I_safe());
971  typename MT::plainfptrI f = ff->it0I->second;
972  (*f)(input,set_value);
973  break;}
974  case 6: {
975  ff->check(ff->it1_safe());
976  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
977  typename MT::FSptr1 f = ff->it1->second.fptr;
978  (model.*f)(set_value,ff->index1);
979  break;}
980  case 7: {
981  ff->check(ff->it1M_safe());
982  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
983  typename MT::plainfptrM1 f = ff->it1M->second.fptr;
984  (*f)(model,set_value,ff->index1);
985  break;}
986  case 8: {
987  ff->check(ff->it1I_safe());
988  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
989  typename MT::plainfptrI1 f = ff->it1I->second.fptr;
990  (*f)(input,set_value,ff->index1);
991  break;}
992  case 9: {
993  ff->check(ff->it2_safe());
994  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
995  ff->check_index_initd(LOCAL_INFO,ff->index2,"index2");
996  typename MT::FSptr2 f = ff->it2->second.fptr;
997  (model.*f)(set_value,ff->index1,ff->index2);
998  break;}
999  case 10: {
1000  ff->check(ff->it2M_safe());
1001  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
1002  ff->check_index_initd(LOCAL_INFO,ff->index2,"index2");
1003  typename MT::plainfptrM2 f = ff->it2M->second.fptr;
1004  (*f)(model,set_value,ff->index1,ff->index2);
1005  break;}
1006  case 11: {
1007  ff->check(ff->it2I_safe());
1008  ff->check_index_initd(LOCAL_INFO,ff->index1,"index1");
1009  ff->check_index_initd(LOCAL_INFO,ff->index2,"index2");
1010  typename MT::plainfptrI2 f = ff->it2I->second.fptr;
1011  (*f)(input,set_value,ff->index1,ff->index2);
1012  break;}
1013  default:{
1014  std::ostringstream errmsg;
1015  errmsg << "Error! Unanticipated whichiter code received while trying to call a function from SubSpectrum maps. This indicates a bug in the FptrFinder class. Please report it! (this FptrFinder has label="<<ff->label<<" and is specialised for Setter maps, current error_code="<<ff->error_code<<", whichiter="<<ff->whichiter<<")"<<std::endl;
1016  utils_error().forced_throw(LOCAL_INFO,errmsg.str());
1017  }
1018  }
1019  } else if(ff->error_code==-1)
1020  {
1021  std::ostringstream errmsg;
1022  errmsg << "Error! Tried to call function from SubSpectrum maps without first finding the function! This indicates a bug, probably in the Spectrum or SubSpectrum classes. Please report it! (this FptrFinder has label="<<ff->label<<" and is specialised for Getter maps, current error_code="<<ff->error_code<<")"<<std::endl;
1023  utils_error().forced_throw(LOCAL_INFO,errmsg.str());
1024  } else {
1025  std::ostringstream errmsg;
1026  errmsg << "Error! Unanticipated error code received while trying to call a function from SubSpectrum maps. This indicates a bug in the FptrFinder class. Please report it! (this FptrFinder has label="<<ff->label<<" and is specialised for Getter maps, current error_code="<<ff->error_code<<")"<<std::endl;
1027  utils_error().forced_throw(LOCAL_INFO,errmsg.str());
1028  }
1029  }
1030  };
1031 
1032 }
1033 #undef PDB
1034 #undef CHECK_WHERE_FOUND
1035 
1036 #endif
const std::map< std::string, std::map< int, double > > * omap1_
FptrFinder(const SetMaps< HostSpec, MTag > &params)
const std::map< std::string, std::map< int, std::map< int, double > > > * omap2_
Fully unspecialised MapTypes declaration.
const bool override_only_
Flag to permit searching only override maps.
bool ito0_safe()
Functions to check whether or not it is safe to dereference the above iterators.
std::string lastname
Last used search string (only set if there was a problem, for error messages)
const MapTypes< D, MTag >::fmap1_extraM * map1M_
bool find(const std::string &name, bool=true, SafeBool check_antiparticle=SafeBool(true))
Search function for 0-index maps.
const bool no_overrides_
Flag to disable searching of override maps (for retrieving original, unoverriden values) ...
static const MapTypes< D, MTag >::fmap2W nullmap_it2W
std::string get_error_message()
SetMaps & map1I(const typename MapTypes< D, MTag >::fmap1_extraI &map1I)
const MapTypes< D, MTag >::fmap2_extraM * map2M_
HostSpec *const fakethis_
bool find(const std::string &name, int i, int j)
Search function for 2-index maps.
CallFcn< HostSpec, MTag > callfcn
Caller for whatever function was found HostSpec has to work slightly differently depending on whether...
const MapTypes< D, MTag >::fmap0_extraI * map0I_
EXPORT_SYMBOLS error & utils_error()
Utility errors.
static const std::map< std::string, double > nullmap_ito0
empty maps used to initialise the above iterators
const MapTypes< D, MTag >::fmap1W * map1W_
const MapTypes< D, MTag >::fmap1_extraI * map1I_
FptrFinder friend class for implementing named parameter idiom.
const MapTypes< D, MTag >::fmap0_extraM * map0M_
MapTypes< DerivedSpec, MapTag::Get > MT
const std::string label_
void check(bool safe)
Check if it is (supposed to be) safe to dereference a map iterator Throw an error if it isn&#39;t...
const std::map< std::string, double > * omap0_
Maps from base class (override maps, only used in getter case)
SetMaps(const std::string &label, HostSpec *const fakethis)
SetMaps & omap0(const std::map< std::string, double > &om0)
base class override maps
std::map< std::string, std::map< int, std::map< int, double > > >::const_iterator ito2
SetMaps & map1(const typename MapTypes< D, MTag >::fmap1 &map1)
MapTypes< D, MTag >::fmap2W::const_iterator it2W
bool find(const std::string &name, int i, bool=true, SafeBool check_antiparticle=SafeBool(true))
Search function for 1-index maps.
const MapTypes< D, MTag >::fmap1 * map1_
#define LOCAL_INFO
Definition: local_info.hpp:34
std::map< std::string, double >::const_iterator ito0
Iterators needed for storing locatation of search result ...for override values.
static const MapTypes< D, MTag >::fmap1_extraM nullmap_it1M
CallFcn(FptrFinder< HostSpec, MapTag::Get > *host)
HostSpec::D D
Type of derived spectrum wrapper is known to HostSpec as D.
MapTypes< D, MTag >::fmap0_extraI::const_iterator it0I
const MapTypes< D, MTag >::fmap0 * map0_
Maps filled by derived (wrapper) classes.
const std::string label
Label to help track down errors if they occur.
bool find_2index(const std::string &name, const int i, const int j)
Search 2-index wrapper maps.
static const MapTypes< D, MTag >::fmap0_extraM nullmap_it0M
SpecTraits< DerivedSpec >::Input Input
SetMaps & map1W(const typename MapTypes< D, MTag >::fmap1W &map1W)
MapTypes< D, MTag >::fmap1::const_iterator it1
const MapTypes< D, MTag >::fmap2W * map2W_
const std::map< std::string, std::map< int, double > > * omap1_
static const MapTypes< D, MTag >::fmap0 nullmap_it0
...for derived class values
const MapTypes< D, MTag >::fmap1 * map1_
bool find_override_2index(const std::string &name, const int i, const int j)
Search 2-index override map.
SetMaps & map2(const typename MapTypes< D, MTag >::fmap2 &map2)
const MapTypes< D, MTag >::fmap1_extraI * map1I_
void operator()(const double set_value)
SetMaps & map2W(const typename MapTypes< D, MTag >::fmap2W &map2W)
const MapTypes< D, MTag >::fmap1W * map1W_
MapTypes< D, MTag >::fmap2::const_iterator it2
MapTypes< D, MTag >::fmap0::const_iterator it0
...for derived class values
bool search_map(const std::string &name, const Map *const map, typename Map::const_iterator &it)
helper functions for searching individual maps
const MapTypes< D, MTag >::fmap2 * map2_
static const MapTypes< D, MTag >::fmap2_extraM nullmap_it2M
SetMaps & map2M(const typename MapTypes< D, MTag >::fmap2_extraM &map2M)
MapTypes< D, MTag >::fmap0W::const_iterator it0W
MapTypes< D, MTag >::fmap2_extraI::const_iterator it2I
SetMaps & map0I(const typename MapTypes< D, MTag >::fmap0_extraI &map0I)
MapTypes< D, MTag >::fmap1_extraI::const_iterator it1I
SetMaps & map1M(const typename MapTypes< D, MTag >::fmap1_extraM &map1M)
Types needed for function pointer maps Partial specialisation for "setter" maps.
HostSpec *const fakethis
HostSpec class pretending to be an extra set of class functions, so need the "this" pointer...
static const std::map< std::string, std::map< int, double > > nullmap_ito1
static const std::map< std::string, std::map< int, std::map< int, double > > > nullmap_ito2
static const MapTypes< D, MTag >::fmap1_extraI nullmap_it1I
const HostSpec *const const_fakethis_
SpecTraits< DerivedSpec >::Input Input
SetMaps & map0(const typename MapTypes< D, MTag >::fmap0 &map0)
derived class maps
MapTypes< D, MTag >::fmap2_extraM::const_iterator it2M
SetMaps & omap1(const std::map< std::string, std::map< int, double >> &om1)
SpecTraits< DerivedSpec >::Model Model
const MapTypes< D, MTag >::fmap2 * map2_
MapTypes< D, MTag >::fmap1_extraM::const_iterator it1M
SpecTraits< DerivedSpec >::Model Model
HostSpec::D D
Get type of the derived spectrum wrapper from HostSpec.
Helper class for calling function pointers found by FptrFinder.
const MapTypes< D, MTag >::fmap0_extraI * map0I_
SetMaps & no_overrides(const bool flag)
Flag to disable searching of override maps (for retrieving original, unoverriden values) ...
static const MapTypes< D, MTag >::fmap0_extraI nullmap_it0I
#define PDB
MapTypes< D, MTag >::fmap0_extraM::const_iterator it0M
bool within_bounds(const int i, const std::set< int > allowed)
Helper function for checking if indices are valid.
bool find_0index(const std::string &name)
Search 0-index wrapper maps.
Types needed for function pointer maps Partial specialisation for "getter" maps.
Abstract class for accessing general spectrum information.
bool check_indices_1(const std::string &name, const ITER &it, const int i, const int whichit, const bool debug)
Methods for setting parameters (named parameter idiom) E.g.
MapTypes< D, MTag >::fmap1W::const_iterator it1W
const std::map< std::string, std::map< int, std::map< int, double > > > * omap2_
static const MapTypes< D, MTag >::fmap1 nullmap_it1
SetMaps & map2I(const typename MapTypes< D, MTag >::fmap2_extraI &map2I)
Forward declaration of FptrFinder.
bool find_1index(const std::string &name, const int i)
Search 1-index wrapper maps.
static const MapTypes< D, MTag >::fmap2 nullmap_it2
std::map< std::string, std::map< int, double > >::const_iterator ito1
const MapTypes< D, MTag >::fmap0W * map0W_
const MapTypes< D, MTag >::fmap0_extraM * map0M_
void raise_error(const std::string &origin)
Forward declare base traits class which communicates Model and Input typedefs from the wrapper class ...
Definition: spec_head.hpp:59
MapTypes< DerivedSpec, MapTag::Set > MT
const MapTypes< D, MTag >::fmap2_extraI * map2I_
const MapTypes< D, MTag >::fmap2_extraI * map2I_
SetMaps & omap2(const std::map< std::string, std::map< int, std::map< int, double >>> &om2)
SetMaps & map0M(const typename MapTypes< D, MTag >::fmap0_extraM &map0M)
static const MapTypes< D, MTag >::fmap1W nullmap_it1W
bool check_indices_2(const std::string &, const ITER &it, const int i, const int j, const int whichit)
const MapTypes< D, MTag >::fmap1_extraM * map1M_
FptrFinder< HostSpec, MapTag::Set > * ff
Class definitions for GAMBIT particle database.
void check_index_initd(const std::string &origin, const int index, const std::string &label)
static const MapTypes< D, MTag >::fmap2_extraI nullmap_it2I
SetMaps & map0W(const typename MapTypes< D, MTag >::fmap0W &map0W)
const HostSpec *const const_fakethis
static const MapTypes< D, MTag >::fmap0W nullmap_it0W
const MapTypes< D, MTag >::fmap2_extraM * map2M_
const MapTypes< D, MTag >::fmap0 * map0_
Maps from derived class.
SetMaps(const std::string &label, const HostSpec *const fakethis)
Version to deal with const host object.
const MapTypes< D, MTag >::fmap2W * map2W_
const MapTypes< D, MTag >::fmap0W * map0W_
bool find_override_0index(const std::string &name)
Search 0-index override map.
bool find_override_1index(const std::string &name, const int i)
Search 1-index override map.
Helpers for using the spectrum and subspectrum classes.
static const std::map< int, const std::string > error_msg
FptrFinder< HostSpec, MapTag::Get > * ff
TODO: see if we can use this one:
Definition: Analysis.hpp:33
CallFcn(FptrFinder< HostSpec, MapTag::Set > *host)
SetMaps & override_only(const bool flag)
Flag to permit searching only override maps.
int get_error_code()
Error reporting.
const std::map< std::string, double > * omap0_
Pointers to const maps to use for search Maps from base class (override maps, should only be used in ...