KaliVeda
Toolkit for HIC analysis
Loading...
Searching...
No Matches
KVTemplateParticleCondition.h
1/*
2$Id: KVParticleCondition.h,v 1.3 2007/03/26 10:14:56 franklan Exp $
3$Revision: 1.3 $
4$Date: 2007/03/26 10:14:56 $
5*/
6
9
10#ifndef __KVTEMPLATEPARTICLECONDITION_H
11#define __KVTEMPLATEPARTICLECONDITION_H
12
13#include "KVBase.h"
14#include "KVString.h"
15#include "KVHashList.h"
16#include <vector>
17#include <functional>
18#include <KVClassFactory.h>
19#include "TROOT.h"
20
21class KVClassFactory;
22
66template<typename ParticleType>
68 static KVHashList fgOptimized;// list of optimized particle conditions
69 mutable Int_t fNUsing;
70 using LambdaFunc = std::function<bool(const ParticleType*)>;
73 enum class LogOp { AND, OR } fOpType;
74
76 {
78 if (IsLambda() && !IsSet()) {
79 switch (fOpType) {
80 case LogOp::AND:
81 fLambdaCondition = [this](const ParticleType * nuc) {
82 return (fSavedLambda1(nuc) && fSavedLambda2(nuc));
83 };
84 break;
85 case LogOp::OR:
86 fLambdaCondition = [this](const ParticleType * nuc) {
87 return (fSavedLambda1(nuc) || fSavedLambda2(nuc));
88 };
89 break;
90 }
91 }
92 }
93
94protected:
95
96 KVString fCondition;//string containing selection criteria with ";" at end
97 KVString fCondition_raw;//'raw' condition, i.e. no ';'
98 KVString fCondition_brackets;//condition with '(' and ')' around it
99
104 mutable Bool_t fOptOK;
105
106 void Optimize() const
107 {
120
122 if (fOptimal) { /* check that the same condition has not already been optimized */
124 fOptimal->fNUsing++;
125 fOptOK = kTRUE;
126 return;
127 }
128 Info("Optimize", "Optimization of KVParticleCondition : %s", fCondition.Data());
129
131 KVString created_class_name = cf->GetClassName();
133 cf->AddMethod("optimized_test", "Bool_t", "public", false, true);
134 cf->AddMethodArgument("optimized_test", "const KVNucleus*", "nuc");
135 cf->AddHeaderIncludeFile("KVNucleus.h");
136
138 KVString body(" //Optimized Test method for particle condition\n");
139 KVString pointer = "nuc";
140 if (fClassName != "") {
141 pointer.Form("((%s*)nuc)", fClassName.Data());
144 }
145 KVString tmp;
146 tmp = fCondition;
147 tmp.ReplaceAll("_NUC_", pointer.Data());
148 body += " return ";
149 body += tmp;
150
151 cf->AddMethodBody("optimized_test", body);
152
154 cf->GenerateCode();
155
157 gROOT->GetPluginManager()->AddHandler("KVParticleCondition", cf->GetClassName(), cf->GetClassName(),
158 Form("%s+", cf->GetImpFileName()), Form("%s()", cf->GetClassName()));
160 TPluginHandler* ph;
161 if (!(ph = LoadPlugin("KVParticleCondition", cf->GetClassName()))) {
162 Error("Optimize", " *** Optimization failed for KVParticleCondition : %s", fCondition.Data());
163 Error("Optimize", " *** Use method AddExtraInclude(const Char_t*) to give the names of all necessary header files for compilation of your condition.");
164 Fatal("Optimize", " *** THIS CONDITION WILL BE EVALUATED AS kFALSE FOR ALL PARTICLES!!!");
165 delete cf;
166 cf = 0;
169 fOptimal = this;
170 fOptOK = kFALSE;
171 return;
172 }
173 fOptOK = kTRUE;
174 delete cf;
175 cf = 0;
178
179 Info("Optimize", "fOptimal = %p", fOptimal);
180 if (!fOptimal) {
181 Error("Optimize", " *** Optimization failed for KVParticleCondition : %s", fCondition.Data());
182 Error("Optimize", " *** Use method AddExtraInclude(const Char_t*) to give the names of all necessary header files for compilation of your condition.");
183 Fatal("Optimize", " *** THIS CONDITION WILL BE EVALUATED AS kFALSE FOR ALL PARTICLES!!!");
186 fOptimal = this;
187 fOptOK = kFALSE;
188 }
191 const_cast<KVTemplateParticleCondition*>(fOptimal)->fOptimizedClassName = created_class_name;
193 fOptimal->fNUsing++;
194 Info("Optimize", "Success");
195 }
196
197 virtual bool optimized_test(const ParticleType*) const
198 {
199 return kFALSE;
200 }
202 {
204
205 if (cf) return;
206
208 TUUID unique;
209 KVString new_class = unique.AsString();
211 new_class.Remove(8);
212 new_class.Prepend("KVParticleCondition_");
213
215 cf = new KVClassFactory(new_class.Data(), "Particle condition to test", "KVParticleCondition");
216 cf->SetInheritAllConstructors(kFALSE); // avoid generating ctor with LambdaFunc argument!!!
217 }
218
220 {
224 CF->Copy(*cf);
225 }
226
227public:
229 : KVBase("KVParticleCondition", "Particle selection criteria")
230 {
232 fOptimal = nullptr;
233 cf = nullptr;
234 fOptOK = kFALSE;
235 fNUsing = 0;
236 }
237
239 : KVBase(cond, "KVParticleCondition")
240 {
260 fOptimal = nullptr;
261 Set(cond);
262 cf = nullptr;
263 fOptOK = kFALSE;
264 fNUsing = 0;
265 }
266
268 : KVBase(cond, "KVParticleCondition")
269 {
289 fOptimal = nullptr;
290 Set(cond);
291 cf = nullptr;
292 fOptOK = kFALSE;
293 fNUsing = 0;
294 }
295
297 : KVBase("KVParticleCondition", "Particle selection criteria")
298 {
300 fOptimal = nullptr;
301 cf = nullptr;
302 fOptOK = kFALSE;
303 fNUsing = 0;
304 obj.Copy(*this);
305 }
306
308 : KVBase(name, "KVParticleCondition"), fLambdaCondition(F)
309 {
333 fOptimal = nullptr;
334 cf = nullptr;
335 fOptOK = kFALSE;
336 fNUsing = 0;
337 }
338 bool IsLambda() const
339 {
341 return (bool)fLambdaCondition || ((bool)fSavedLambda1 && (bool)fSavedLambda2);
342 }
343
345 {
347 if (fOptimal) {
349 --(fOptimal->fNUsing);
350 if (!(fOptimal->fNUsing)) {
352 delete fOptimal;
353 fOptimal = nullptr;
354 }
355 }
356 SafeDelete(cf);
357 }
358
359 void Set(const KVString& name, const LambdaFunc& F)
360 {
372 SetName(name);
373 }
374
375 void Set(const KVString& cond)
376 {
386
388
389 fCondition = cond;
390 Ssiz_t ind = fCondition.Index(";");
391 if (ind < 0) {
393 fCondition += ";"; //we add a ";" if there isn't already
394 }
395 else {
396 fCondition_raw = fCondition.Strip(TString::kTrailing, ';');
397 }
399 }
400
401 Bool_t Test(const ParticleType* nuc) const
402 {
410
412 if (!IsSet()) return kTRUE;
413 if (IsLambda()) return fLambdaCondition(nuc);
414 if (!fOptimal) Optimize();
415
416 return (fOptOK ? fOptimal->optimized_test(nuc) : kFALSE);
417 }
418
419 Bool_t Test(const ParticleType& nuc) const
420 {
428
429 return Test(&nuc);
430 }
431
433 {
434 fClassName = cl;
435 }
436 void AddExtraInclude(const Char_t* inc_file)
437 {
466
468 cf->AddImplIncludeFile(inc_file);
469 }
470
471 void Copy(TObject& obj) const
472 {
474 KVBase::Copy(obj);
475 ((KVTemplateParticleCondition&) obj).fCondition = fCondition;
476 ((KVTemplateParticleCondition&) obj).fCondition_raw = fCondition_raw;
477 ((KVTemplateParticleCondition&) obj).fCondition_brackets = fCondition_brackets;
478 ((KVTemplateParticleCondition&) obj).fLambdaCondition = fLambdaCondition;
479 ((KVTemplateParticleCondition&) obj).fSavedLambda1 = fSavedLambda1;
480 ((KVTemplateParticleCondition&) obj).fSavedLambda2 = fSavedLambda2;
481 ((KVTemplateParticleCondition&) obj).fOpType = fOpType;
482 ((KVTemplateParticleCondition&) obj).fOptOK = fOptOK;
485 ((KVTemplateParticleCondition&) obj).fOptimal = nullptr;
486 if (fClassName != "")((KVTemplateParticleCondition&) obj).SetParticleClassName(fClassName.Data());
487 if (cf) {
488 ((KVTemplateParticleCondition&) obj).SetClassFactory(cf);
489 }
490 }
491
493 {
495 if (&obj != this) obj.Copy(*this);
496 return (*this);
497 }
498
500 {
517 Set(sel);
518 return (*this);
519 }
520
522 {
525 return (*this);
526 }
527
529 {
539
542
543 if (!(A.IsSet() && B.IsSet())) {
545 if (!(A.IsSet() || B.IsSet())) {
548 }
549 else if (A.IsSet()) return KVTemplateParticleCondition(A);
550 else return KVTemplateParticleCondition(B);
551 }
553 if (A.IsLambda() || B.IsLambda()) {
554 if (A.IsLambda() && B.IsLambda()) {
559 tmp.SetName(Form("(%s) && (%s)", A.GetName(), B.GetName()));
560 return tmp;
561 }
562 else {
563 ::Error("KVTemplateParticleCondition::operator&&", "Both KVParticleCondition objects must use lambda captures in order to do this");
565 }
566 }
568 tmp.Set(A.fCondition_brackets + " && " + B.fCondition_brackets);
569 if (A.fClassName != "") tmp.SetParticleClassName(A.fClassName);
570 else if (B.fClassName != "") tmp.SetParticleClassName(B.fClassName);
571 return tmp;
572 }
573
575 {
585
588
589 if (!(A.IsSet() && B.IsSet())) {
591 if (!(A.IsSet() || B.IsSet())) {
594 }
595 else if (A.IsSet()) return KVTemplateParticleCondition(A);
596 else return KVTemplateParticleCondition(B);
597 }
599 if (A.IsLambda() || B.IsLambda()) {
600 if (A.IsLambda() && B.IsLambda()) {
605 tmp.SetName(Form("(%s) || (%s)", A.GetName(), B.GetName()));
606 return tmp;
607 }
608 else {
609 ::Error("operator&&", "Both KVParticleCondition objects must use lambda captures in order to do this");
611 }
612 }
614 tmp.Set(A.fCondition_brackets + " || " + B.fCondition_brackets);
615 if (A.fClassName != "") tmp.SetParticleClassName(A.fClassName);
616 else if (B.fClassName != "") tmp.SetParticleClassName(B.fClassName);
617 return tmp;
618 }
619
621 {
626
627 KVTemplateParticleCondition tmp = *this || other;
628 tmp.Copy(*this);
629 return *this;
630 }
631
633 {
638
639 KVTemplateParticleCondition tmp = *this && other;
640 tmp.Copy(*this);
641 return *this;
642 }
643 void Print(Option_t* opt = "") const
644 {
646 if (fCondition != "") {
647 Info("Print", "object name = %s, address = %p", GetName(), this);
648 std::cout << " * condition = " << fCondition.Data() << std::endl;
649 std::cout << " * classname = " << fClassName.Data() << std::endl;
650 std::cout << " * fOptimal = " << fOptimal << std::endl;
651 std::cout << " * fNUsing = " << fNUsing << std::endl;
652 if (cf) {
653 std::cout << " * classfactory :" << std::endl;
654 cf->Print();
655 }
656 }
657 else {
658 std::cout << GetName() << std::endl;
659 }
660 }
661
662 static void PrintOptimizedList()
663 {
665 }
666 Bool_t IsSet() const
667 {
671
672 return (fLambdaCondition || fCondition != "");
673 }
674
675 ClassDef(KVTemplateParticleCondition, 1) //Implements parser of particle selection criteria
676};
677
678template<typename ParticleClass>
680#endif
int Int_t
#define SafeDelete(p)
#define f(i)
bool Bool_t
int Ssiz_t
char Char_t
constexpr Bool_t kFALSE
constexpr Bool_t kTRUE
const char Option_t
#define ClassDef(name, id)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t sel
char name[80]
#define gROOT
char * Form(const char *fmt,...)
Base class for KaliVeda framework.
Definition KVBase.h:142
virtual void Copy(TObject &) const
Make a copy of this object.
Definition KVBase.cpp:394
static TPluginHandler * LoadPlugin(const Char_t *base, const Char_t *uri="0")
Definition KVBase.cpp:793
Factory class for generating skeleton files for new classes.
void Print(Option_t *opt="") const
Print infos on object.
const Char_t * GetClassName() const
void GenerateCode()
Generate header and implementation file for currently-defined class.
void SetInheritAllConstructors(Bool_t yes=kTRUE)
void AddHeaderIncludeFile(const Char_t *filename)
void Copy(TObject &obj) const
Copy the state of this KVClassFactory to the one referenced by 'obj'.
void AddImplIncludeFile(const Char_t *filename)
const Char_t * GetImpFileName() const
void AddMethodBody(const Char_t *method_name, const KVString &body)
void AddMethodArgument(const Char_t *method_name, const Char_t *argument_type, const Char_t *argument_name="", const Char_t *default_value="")
KVClassMethod * AddMethod(const Char_t *name, const Char_t *return_type, const Char_t *access="public", Bool_t isVirtual=kFALSE, Bool_t isConst=kFALSE)
Extended version of ROOT THashList.
Definition KVHashList.h:29
virtual TObject * FindObject(const char *name) const
virtual void Add(TObject *obj)
virtual TObject * Remove(TObject *obj)
Remove object from list.
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition KVString.h:73
An object for handling particle selection.
friend KVTemplateParticleCondition operator||(const KVTemplateParticleCondition &A, const KVTemplateParticleCondition &B)
friend KVTemplateParticleCondition operator&&(const KVTemplateParticleCondition &A, const KVTemplateParticleCondition &B)
Bool_t Test(const ParticleType *nuc) const
KVTemplateParticleCondition(const KVTemplateParticleCondition &obj)
KVTemplateParticleCondition & operator&=(const KVTemplateParticleCondition &other)
Bool_t Test(const ParticleType &nuc) const
KVTemplateParticleCondition & operator=(const LambdaFunc &f)
void Set(const KVString &name, const LambdaFunc &F)
virtual bool optimized_test(const ParticleType *) const
void AddExtraInclude(const Char_t *inc_file)
KVTemplateParticleCondition & operator=(const KVString &sel)
KVTemplateParticleCondition(const KVString &cond)
KVTemplateParticleCondition & operator=(const KVTemplateParticleCondition &obj)
const KVTemplateParticleCondition * fOptimal
KVTemplateParticleCondition & operator|=(const KVTemplateParticleCondition &other)
void Optimize() const
false if optimisation failed (can't load generated code)
KVString fOptimizedClassName
used to generate code for optimisation
Bool_t fOptOK
name of generated class used for optimisation
std::function< bool(const ParticleType *)> LambdaFunc
number of classes using this as an optimized condition
KVTemplateParticleCondition(const KVString &name, const LambdaFunc &F)
void Print(Option_t *opt="") const
enum KVTemplateParticleCondition::LogOp fOpType
virtual void Print(Option_t *option, const char *wildcard, Int_t recurse=1) const
const char * GetName() const override
virtual void SetName(const char *name)
virtual void Error(const char *method, const char *msgfmt,...) const
virtual void Fatal(const char *method, const char *msgfmt,...) const
virtual void Info(const char *method, const char *msgfmt,...) const
Longptr_t ExecPlugin(int nargs)
TSubString Strip(EStripType s=kTrailing, char c=' ') const
const char * Data() const
TString & Prepend(char c, Ssiz_t rep=1)
void Form(const char *fmt,...)
TString & Remove(EStripType s, char c)
TString & ReplaceAll(const char *s1, const char *s2)
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
const char * AsString() const
#define F(x, y, z)