Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DAnalysisAction.h
Go to the documentation of this file.
1 #ifndef _DAnalysisAction_
2 #define _DAnalysisAction_
3 
4 #include <deque>
5 #include <string>
6 #include <stdlib.h>
7 
8 #include "TDirectoryFile.h"
9 #include "TFile.h"
10 #include "TROOT.h"
11 #include "TClass.h"
12 
13 #include "JANA/JEventLoop.h"
14 #include "DANA/DApplication.h"
16 #include "ANALYSIS/DReaction.h"
18 
19 using namespace std;
20 using namespace jana;
21 using namespace DAnalysis;
22 
23 namespace DAnalysis
24 {
25 
27 {
28  public:
29 
30  DAnalysisAction(const DReaction* locReaction, string locActionBaseName, bool locUseKinFitResultsFlag = false, string locActionUniqueString = ""); //inheriting classes MUST call this constructor!
31  virtual ~DAnalysisAction(void){};
32 
33  inline const DReaction* Get_Reaction(void) const{return dReaction;}
34  virtual string Get_ActionName(void) const{return dActionName;}
35  inline string Get_ActionUniqueString(void) const{return dActionUniqueString;}
36  inline bool Get_UseKinFitResultsFlag(void) const{return dUseKinFitResultsFlag;}
37 
38  //INHERITING CLASSES MUST(!) DEFINE THIS METHOD
39  //any ROOT objects to be created by this object (e.g. histograms, trees) should be created in a version of THIS function in the derived class (make it public!)
40  //when creating ROOT objects, call CreateAndChangeTo_ActionDirectory() to navigate to the proper directory
41  //if not creating any objects, just define the function but leave it empty
42  virtual void Initialize(JEventLoop* locEventLoop) = 0;
43 
44  //INHERITING CLASSES THAT OVERRIDE THIS METHOD MUST CALL THE BASE METHOD!!!
45  //Reset event (for clearing previously-histogrammed info (duplicate checking)
46  virtual void Reset_NewEvent(void){dCalledPriorWithComboFlag = false;}
47 
48  //Function-call operators: Execute the action.
49  bool operator()(JEventLoop* locEventLoop); //DON'T CALL THIS FOR COMBO-DEPENDENT ACTIONS
50  bool operator()(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo); //THIS METHOD ASSUMES THAT ONLY ONE THREAD HAS ACCESS TO THIS OBJECT
51 
52  protected:
53 
54  //INHERITING CLASSES MUST(!) DEFINE THIS METHOD
55  //FOR REACTION-INDEPENDENT ACTIONS: EXPECT THE INPUT DParticleCombo TO BE NULL.
56  //Make Perform_Action protected or private in derived classes (not public! should call operator() to execute instead)
57  virtual bool Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo = NULL) = 0;
58 
59  //FOR ALL OF THE VIRTUAL METHODS:
60  //NEVER: Grab DParticleCombo objects (of any tag!) from the JEventLoop within these methods unless you know EXACTLY what you're doing (and if you're doing this, you probably don't)
61  //NEVER EVER: Grab objects that are created post-kinfit (e.g. DParticleCombo, DKinFitResults, etc.) from the JEventLoop if Get_UseKinFitResultsFlag() == false: CAN CAUSE DEPENDENCY LOOP
62 
63  //Create/Navigate Directories //MUST(!) LOCK PRIOR TO ENTRY! (not performed in these functions!)
64  TDirectoryFile* CreateAndChangeTo_ActionDirectory(void); //get the directory this action should write ROOT objects to.
65  TDirectoryFile* ChangeTo_BaseDirectory(void); //get and change to the base (file/global) directory
66  TDirectoryFile* CreateAndChangeTo_Directory(TDirectoryFile* locBaseDirectory, string locDirName, string locDirTitle);
67  TDirectoryFile* CreateAndChangeTo_Directory(string locDirName, string locDirTitle);
68  TDirectoryFile* CreateAndChangeTo_Directory(string locBaseDirectoryPath, string locDirName, string locDirTitle);
69 
70  //Create/Get Histograms
71  //1D
72  template <typename DHistType> DHistType* GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, Double_t locXRangeMin, Double_t locXRangeMax) const;
73  template <typename DHistType, typename DBinType> DHistType* GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, DBinType* locXBinEdges) const;
74  //2D
75  template <typename DHistType> DHistType* GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, Double_t locXRangeMin, Double_t locXRangeMax, Int_t locNumBinsY, Double_t locYRangeMin, Double_t locYRangeMax) const;
76  template <typename DHistType, typename DBinType> DHistType* GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, DBinType* locXBinEdges, Int_t locNumBinsY, DBinType* locYBinEdges) const;
77  template <typename DHistType, typename DBinType> DHistType* GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, DBinType* locXBinEdges, Int_t locNumBinsY, Double_t locYRangeMin, Double_t locYRangeMax) const;
78  template <typename DHistType, typename DBinType> DHistType* GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, Double_t locXRangeMin, Double_t locXRangeMax, Int_t locNumBinsY, DBinType* locYBinEdges) const;
79  //3D
80  template <typename DHistType> DHistType* GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, Double_t locXRangeMin, Double_t locXRangeMax, Int_t locNumBinsY, Double_t locYRangeMin, Double_t locYRangeMax, Int_t locNumBinsZ, Double_t locZRangeMin, Double_t locZRangeMax) const;
81  template <typename DHistType, typename DBinType> DHistType* GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, DBinType* locXBinEdges, Int_t locNumBinsY, DBinType* locYBinEdges, Int_t locNumBinsZ, DBinType* locZBinEdges) const;
82 
83  bool Get_CalledPriorWithComboFlag(void) const{return dCalledPriorWithComboFlag;}
84 
85  // in case you need to do anything with this action that is shared amongst threads
86  // e.g. filling histograms
87  // When creating ROOT histograms, should still acquire JANA-wide ROOT lock (e.g. modifying gDirectory)
88  // this mutex is unique to this combination of: DReaction name, action name (which is base_name + unique_action_string)
89  void Lock_Action(void);
90  void Unlock_Action(void);
91 
92  public:
93  //Set by constructor:
94  bool dPerformAntiCut; //if Perform_Action returned true/false, instead return false/true
95 
96  private:
97 
98  //Set by constructor:
100  string dActionName; //if the class deriving from DAnalysisAction creates ROOT objects, AND more than one instance of it is added to the DReaction, then this should be unique
104 
105  //Valid only during function-call operators (and the functions it calls):
106  bool dCalledPriorWithComboFlag = false;
107 
108  template <typename DHistType> bool Check_IsValidTH1(string locHistName) const;
109  template <typename DHistType> bool Check_IsValidTH2(string locHistName) const;
110  template <typename DHistType> bool Check_IsValidTH3(string locHistName) const;
111 
112  // in case you need to do anything with this action that is shared amongst threads
113  // e.g. filling histograms
114  // When creating ROOT histograms, should still acquire JANA-wide ROOT lock (e.g. modifying gDirectory)
115  // this mutex is unique to this combination of: DReaction name, action name (which is base_name + unique_action_string)
116  pthread_rwlock_t* dActionLock;
117 
118  DAnalysisAction(void); //to force inheriting classes to call the public constructor
119 };
120 
121 inline bool DAnalysisAction::operator()(JEventLoop* locEventLoop)
122 {
123  //ASSUMES ONLY CALLED ONCE PER EVENT
124  bool locResult = Perform_Action(locEventLoop, nullptr);
125  return (dPerformAntiCut ? !locResult : locResult);
126 }
127 
128 inline bool DAnalysisAction::operator()(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
129 {
130  //THIS METHOD ASSUMES THAT ONLY ONE THREAD HAS ACCESS TO THIS OBJECT
131  bool locResult = Perform_Action(locEventLoop, locParticleCombo);
132  dCalledPriorWithComboFlag = true;
133  return (dPerformAntiCut ? !locResult : locResult);
134 }
135 
136 inline void DAnalysisAction::Lock_Action(void)
137 {
138  pthread_rwlock_wrlock(dActionLock);
139 }
140 
141 inline void DAnalysisAction::Unlock_Action(void)
142 {
143  pthread_rwlock_unlock(dActionLock);
144 }
145 
146 inline TDirectoryFile* DAnalysisAction::ChangeTo_BaseDirectory(void)
147 {
148  //get and change to the base (file/global) directory //MUST(!) LOCK PRIOR TO ENTRY! (not performed in here!)
149  TFile* locFile = (TFile*)gROOT->FindObject(dOutputFileName.c_str());
150  if(locFile != NULL)
151  locFile->cd("");
152  else
153  gDirectory->cd("/");
154  return (TDirectoryFile*)gDirectory;
155 }
156 
157 inline TDirectoryFile* DAnalysisAction::CreateAndChangeTo_Directory(TDirectoryFile* locBaseDirectory, string locDirName, string locDirTitle)
158 {
159  //MUST LOCK PRIOR TO ENTRY! (not performed in here!)
160  locBaseDirectory->cd();
161  TDirectoryFile* locSubDirectory = static_cast<TDirectoryFile*>(locBaseDirectory->Get(locDirName.c_str()));
162  if(locSubDirectory == NULL) //else folder already created by a different thread
163  locSubDirectory = new TDirectoryFile(locDirName.c_str(), locDirTitle.c_str());
164  locSubDirectory->cd();
165  return locSubDirectory;
166 }
167 
168 inline TDirectoryFile* DAnalysisAction::CreateAndChangeTo_Directory(string locDirName, string locDirTitle)
169 {
170  //MUST LOCK PRIOR TO ENTRY! (not performed in here!)
171  return CreateAndChangeTo_Directory((TDirectoryFile*)gDirectory, locDirName, locDirTitle);
172 }
173 
174 inline TDirectoryFile* DAnalysisAction::CreateAndChangeTo_Directory(string locBaseDirectoryPath, string locDirName, string locDirTitle)
175 {
176  //MUST LOCK PRIOR TO ENTRY! (not performed in here!)
177  TDirectoryFile* locBaseDirectory = static_cast<TDirectoryFile*>(gDirectory->GetDirectory(locBaseDirectoryPath.c_str()));
178  return CreateAndChangeTo_Directory(locBaseDirectory, locDirName, locDirTitle);
179 }
180 
181 template <typename DHistType> inline DHistType* DAnalysisAction::GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, Double_t locXRangeMin, Double_t locXRangeMax) const
182 {
183  //1D Histogram
184  if(!Check_IsValidTH1<DHistType>(locHistName))
185  return NULL;
186 
187  const char* locHistNameCString = locHistName.c_str();
188  const char* locHistTitleCString = locHistTitle.c_str();
189  TObject* locHist = gDirectory->Get(locHistNameCString);
190  if(locHist == NULL)
191  return new DHistType(locHistNameCString, locHistTitleCString, locNumBinsX, locXRangeMin, locXRangeMax);
192  else //already created by another thread, or directory name is duplicate (e.g. two identical steps)
193  return static_cast<DHistType*>(locHist);
194 }
195 
196 template <typename DHistType, typename DBinType> inline DHistType* DAnalysisAction::GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, DBinType* locXBinEdges) const
197 {
198  //1D Histogram
199  if(!Check_IsValidTH1<DHistType>(locHistName))
200  return NULL;
201 
202  const char* locHistNameCString = locHistName.c_str();
203  const char* locHistTitleCString = locHistTitle.c_str();
204  TObject* locHist = gDirectory->Get(locHistNameCString);
205  if(locHist == NULL)
206  return new DHistType(locHistNameCString, locHistTitleCString, locNumBinsX, locXBinEdges);
207  else //already created by another thread, or directory name is duplicate (e.g. two identical steps)
208  return static_cast<DHistType*>(locHist);
209 }
210 
211 template <typename DHistType> inline DHistType* DAnalysisAction::GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, Double_t locXRangeMin, Double_t locXRangeMax, Int_t locNumBinsY, Double_t locYRangeMin, Double_t locYRangeMax) const
212 {
213  //2D Histogram
214  if(!Check_IsValidTH2<DHistType>(locHistName))
215  return NULL;
216 
217  const char* locHistNameCString = locHistName.c_str();
218  const char* locHistTitleCString = locHistTitle.c_str();
219  TObject* locHist = gDirectory->Get(locHistNameCString);
220  if(locHist == NULL)
221  return new DHistType(locHistNameCString, locHistTitleCString, locNumBinsX, locXRangeMin, locXRangeMax, locNumBinsY, locYRangeMin, locYRangeMax);
222  else //already created by another thread, or directory name is duplicate (e.g. two identical steps)
223  return static_cast<DHistType*>(locHist);
224 }
225 
226 template <typename DHistType, typename DBinType> inline DHistType* DAnalysisAction::GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, DBinType* locXBinEdges, Int_t locNumBinsY, DBinType* locYBinEdges) const
227 {
228  //2D Histogram
229  if(!Check_IsValidTH2<DHistType>(locHistName))
230  return NULL;
231 
232  const char* locHistNameCString = locHistName.c_str();
233  const char* locHistTitleCString = locHistTitle.c_str();
234  TObject* locHist = gDirectory->Get(locHistNameCString);
235  if(locHist == NULL)
236  return new DHistType(locHistNameCString, locHistTitleCString, locNumBinsX, locXBinEdges, locNumBinsY, locYBinEdges);
237  else //already created by another thread, or directory name is duplicate (e.g. two identical steps)
238  return static_cast<DHistType*>(locHist);
239 }
240 
241 template <typename DHistType, typename DBinType> inline DHistType* DAnalysisAction::GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, DBinType* locXBinEdges, Int_t locNumBinsY, Double_t locYRangeMin, Double_t locYRangeMax) const
242 {
243  //2D Histogram
244  if(!Check_IsValidTH2<DHistType>(locHistName))
245  return NULL;
246 
247  const char* locHistNameCString = locHistName.c_str();
248  const char* locHistTitleCString = locHistTitle.c_str();
249  TObject* locHist = gDirectory->Get(locHistNameCString);
250  if(locHist == NULL)
251  return new DHistType(locHistNameCString, locHistTitleCString, locNumBinsX, locXBinEdges, locNumBinsY, locYRangeMin, locYRangeMax);
252  else //already created by another thread, or directory name is duplicate (e.g. two identical steps)
253  return static_cast<DHistType*>(locHist);
254 }
255 
256 template <typename DHistType, typename DBinType> inline DHistType* DAnalysisAction::GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, Double_t locXRangeMin, Double_t locXRangeMax, Int_t locNumBinsY, DBinType* locYBinEdges) const
257 {
258  //2D Histogram
259  if(!Check_IsValidTH2<DHistType>(locHistName))
260  return NULL;
261 
262  const char* locHistNameCString = locHistName.c_str();
263  const char* locHistTitleCString = locHistTitle.c_str();
264  TObject* locHist = gDirectory->Get(locHistNameCString);
265  if(locHist == NULL)
266  return new DHistType(locHistNameCString, locHistTitleCString, locNumBinsX, locXRangeMin, locXRangeMax, locNumBinsY, locYBinEdges);
267  else //already created by another thread, or directory name is duplicate (e.g. two identical steps)
268  return static_cast<DHistType*>(locHist);
269 }
270 
271 template <typename DHistType> inline DHistType* DAnalysisAction::GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, Double_t locXRangeMin, Double_t locXRangeMax, Int_t locNumBinsY, Double_t locYRangeMin, Double_t locYRangeMax, Int_t locNumBinsZ, Double_t locZRangeMin, Double_t locZRangeMax) const
272 {
273  //3D Histogram
274  if(!Check_IsValidTH3<DHistType>(locHistName))
275  return NULL;
276 
277  const char* locHistNameCString = locHistName.c_str();
278  const char* locHistTitleCString = locHistTitle.c_str();
279  TObject* locHist = gDirectory->Get(locHistNameCString);
280  if(locHist == NULL)
281  return new DHistType(locHistNameCString, locHistTitleCString, locNumBinsX, locXRangeMin, locXRangeMax, locNumBinsY, locYRangeMin, locYRangeMax, locNumBinsZ, locZRangeMin, locZRangeMax);
282  else //already created by another thread, or directory name is duplicate (e.g. two identical steps)
283  return static_cast<DHistType*>(locHist);
284 }
285 
286 template <typename DHistType, typename DBinType> inline DHistType* DAnalysisAction::GetOrCreate_Histogram(string locHistName, string locHistTitle, Int_t locNumBinsX, DBinType* locXBinEdges, Int_t locNumBinsY, DBinType* locYBinEdges, Int_t locNumBinsZ, DBinType* locZBinEdges) const
287 {
288  //3D Histogram
289  if(!Check_IsValidTH3<DHistType>(locHistName))
290  return NULL;
291 
292  const char* locHistNameCString = locHistName.c_str();
293  const char* locHistTitleCString = locHistTitle.c_str();
294  TObject* locHist = gDirectory->Get(locHistNameCString);
295  if(locHist == NULL)
296  return new DHistType(locHistNameCString, locHistTitleCString, locNumBinsX, locXBinEdges, locNumBinsY, locYBinEdges, locNumBinsZ, locZBinEdges);
297  else //already created by another thread, or directory name is duplicate (e.g. two identical steps)
298  return static_cast<DHistType*>(locHist);
299 }
300 
301 template <typename DHistType> inline bool DAnalysisAction::Check_IsValidTH3(string locHistName) const
302 {
303  const char* locTypeName = DHistType::Class()->GetName();
304  const char* locBadTypeName = "TH3";
305  if((!DHistType::Class()->InheritsFrom("TH3")) || (string(locTypeName) == string(locBadTypeName)))
306  {
307  cout << "ERROR, WRONG CLASS TYPE IN GetOrCreate_Histogram for HISTOGRAM " << locHistName << ". HISTOGRAM NOT CREATED." << endl;
308  return false;
309  }
310  return true;
311 }
312 
313 template <typename DHistType> inline bool DAnalysisAction::Check_IsValidTH2(string locHistName) const
314 {
315  const char* locTypeName = DHistType::Class()->GetName();
316  const char* locBadTypeName = "TH2";
317  if((!DHistType::Class()->InheritsFrom("TH2")) || (string(locTypeName) == string(locBadTypeName)) || DHistType::Class()->InheritsFrom("TH3"))
318  {
319  cout << "ERROR, WRONG CLASS TYPE IN GetOrCreate_Histogram for HISTOGRAM " << locHistName << ". HISTOGRAM NOT CREATED." << endl;
320  return false;
321  }
322  return true;
323 }
324 
325 template <typename DHistType> inline bool DAnalysisAction::Check_IsValidTH1(string locHistName) const
326 {
327  const char* locTypeName = DHistType::Class()->GetName();
328  const char* locBadTypeName = "TH1";
329  if((!DHistType::Class()->InheritsFrom("TH1")) || (string(locTypeName) == string(locBadTypeName)) || DHistType::Class()->InheritsFrom("TH2") || DHistType::Class()->InheritsFrom("TH3"))
330  {
331  cout << "ERROR, WRONG CLASS TYPE IN GetOrCreate_Histogram for HISTOGRAM " << locHistName << ". HISTOGRAM NOT CREATED." << endl;
332  return false;
333  }
334  return true;
335 }
336 
337 } //end namespace
338 
339 #endif // _DAnalysisAction_
340 
const DReaction * Get_Reaction(void) const
const DReaction * dReaction
bool Get_UseKinFitResultsFlag(void) const
TH2D * locHist
pthread_rwlock_t * dActionLock
string Get_ActionUniqueString(void) const
bool Get_CalledPriorWithComboFlag(void) const
virtual void Reset_NewEvent(void)
virtual string Get_ActionName(void) const