ROOTANA
analyzerDoc.cxx
Go to the documentation of this file.
1 /*! \page analyzerClass Analyzer Classes
2 
3 \section analyzerIntro Introduction
4 
5 
6 This set of classes provides the following functionality
7 
8 - A class TRootanaEventLoop that handles most of the functionality associated
9 with an event loop. The user creates a derived class that inherits from TRootanaEventLoop.
10 - A set of bank decoder classes.
11 
12 These classes depend on the Midas interface classes (TMidasFile, TMidasEvent, TMidasOnline).
13 
14 \section eventLoop Event Loop Class
15 
16 The TRootanaEventLoop provides the functionality to handle many of the features for a standard
17 event loop including
18 
19 - looping over events in a midas file or
20 - getting online events by connecting to midas server
21 
22 The idea is that the user provides a class that derives from TRootanaEventLoop. This derived class
23 would provides begin-of-run actions, end-of-run actions and midas event actions.
24 
25 The following simple example shows a full program that simply prints out the event number for
26 each event:
27 
28 
29 \verbatim
30 #include <stdio.h>
31 #include "TRootanaEventLoop.hxx"
32 
33 class Analyzer: public TRootanaEventLoop {
34 public:
35 
36  Analyzer() {};
37 
38  virtual ~Analyzer() {};
39 
40  void BeginRun(int transition,int run,int time){}
41 
42  // Get the midas event and print event number
43  bool ProcessMidasEvent(TDataContainer& dataContainer){
44  std::cout << "Event Number " << dataContainer.GetMidasEvent().GetSerialNumber() << std::endl;
45  return true;
46  }
47 };
48 
49 int main(int argc, char *argv[])
50 {
51  Analyzer::CreateSingleton<Analyzer>();
52  return Analyzer::Get().ExecuteLoop(argc, argv);
53 }
54 \endverbatim
55 
56 
57 
58 
59 \section histogramCreation Histogram Creation, Begin-Of-Run/End-Of-Run
60 
61 Users will naturally want to create and fill ROOT histograms.
62 This needs to be done with some care because of:
63 - interaction with the output ROOT file: by default, for each run, the analyzer opens a new ROOT file outputNNNNN.root
64 and make it the current directory (gOutputFile) for newly created ROOT objects, i.e. those create by "new TH1(...)".
65 At the end of a run, all these objects are saved into the file, the file is closed and all these objects disappear
66 from memory. To create ROOT objects that persist across runs, use some other ROOT directory (i.e. gOnlineHistDir->cd()).
67 - when using the netDirectoryServer (HAVE_LIBNETDIRECTORY), the contents of gOnlineHistDir and gOutputFile are
68 exported to outside applications. Other programs, i.e. ROODY, can use TNetDirectory to "see" the histograms
69 (and other objects) as they are filled. (Note: this does not work for most TTree objects because they cannot
70 be easily "exported").
71 
72 The general rule is therefore that you should create histograms in your event loop BeginRun() function, rather than
73 in the constructor or the Initialize() method. That is the only way to ensure that the histograms are created after the
74 output ROOT file is created. Also, you should ensure that you delete the old histograms before producing new ones. The following
75 example shows how this would look:
76 
77 \verbatim
78 #include <stdio.h>
79 #include "TRootanaEventLoop.hxx"
80 #include <TH1F.h>
81 
82 class Analyzer: public TRootanaEventLoop {
83 private:
84 
85  TH1F* evtno_histo; // histogram the event numbers.
86 
87 public:
88 
89  Analyzer() {
90  evtno_histo = 0; // initialize pointer to null.
91  };
92 
93  virtual ~Analyzer() {};
94 
95  void BeginRun(int transition,int run,int time){
96  // delete old histogram, if it exists.
97  TH1F *old = (TH1F*)gDirectory->Get("evtno_histo");
98  if (old) delete old;
99 
100  // create new histogram
101  evtno_histo = new TH1F("evtno_histo","Event Number Histogram",1000,0,10000);
102  }
103 
104  bool ProcessMidasEvent(TDataContainer& dataContainer){
105  evtno_histo->Fill(dataContainer.GetMidasEvent().GetSerialNumber());
106  return true;
107  }
108 };
109 
110 int main(int argc, char *argv[])
111 {
112  Analyzer::CreateSingleton<Analyzer>();
113  return Analyzer::Get().ExecuteLoop(argc, argv);
114 }
115 \endverbatim
116 
117 You also have disable the automatic creation of ROOT files for each run by using the
118 function TRootanaEventLoop::DisableRootOutput(true) and then create histograms where ever
119 you want in your program.
120 
121 
122 \section decoder Bank Decoder
123 
124 Naturally we want to do more than just checking the event numbers; we need to process the data in
125 the data banks. The rootana analyzer classes facilitate this by providing decoding
126 classes for a number of standard MIDAS banks.
127 
128 Since the data being stored in each bank is different, the format of the decoder classes will also be
129 quite different. You should see the individual decoders to see how the data is organized;
130 for now we currently have the following decoders:
131 - TV792Data
132 - TV1190Data
133 - TMesytecData
134 
135 The following example shows how to acces information for a particular V792 bank called 'ADC0' and
136 histogram the results:
137 
138 
139 \verbatim
140 #include <stdio.h>
141 #include "TRootanaEventLoop.hxx"
142 #include <TH1F.h>
143 #include <TV792Data.hxx>
144 
145 class Analyzer: public TRootanaEventLoop {
146 private:
147 
148  TH1F* adc; // ADC spectrum for all V792 channels in bank.
149 
150 public:
151 
152  Analyzer() {
153  adc = 0; // initialize pointer to null.
154  };
155 
156  virtual ~Analyzer() {};
157 
158  void BeginRun(int transition,int run,int time){
159  // delete old histogram, if it exists.
160  TH1F *old = (TH1F*)gDirectory->Get("adc");
161  if (old) delete old;
162 
163  // create new histogram
164  adc = new TH1F("adc","V792 ADC Spectrum",4200,0,4200);
165  }
166 
167  bool ProcessMidasEvent(TDataContainer& dataContainer){
168 
169  // Get pointer to the V792 decoded data; need to provide the
170  // bank name.
171  TV792Data *data = dataContainer.GetEventData<TV792Data>("ADC0");
172  if(data){
173  // Loop over all measurement for all channels
174  std::vector<VADCMeasurement> measurements = data->GetMeasurements();
175  for(unsigned int i = 0; i < measurements.size(); i++){ // loop over measurements
176  adc->Fill(measurements[i].GetMeasurement());
177  }
178  }
179 
180  return true;
181  }
182 };
183 
184 int main(int argc, char *argv[])
185 {
186  Analyzer::CreateSingleton<Analyzer>();
187  return Analyzer::Get().ExecuteLoop(argc, argv);
188 }
189 \endverbatim
190 
191 
192 
193 You can also get access to the raw information in the MIDAS banks, if you haven't yet
194 written a decoder for a particular bank type. You do this by doing accessing a bank using
195 the TGenericData class.
196 
197 \section analyzerFlowControl Program Flow Control
198 
199 The following images try to describe the program flow graphically. This is largely the same information
200 as what is described above, but presently differently.
201 
202 
203 \image html event_loop_offline_diagram.png "Program flow for offline rootana analyzer" width=10cm
204 
205 \image html event_loop_online_diagram.png "Program flow for online rootana analyzer" width=10cm
206 
207 
208 \section histogram Histogram Classes
209 
210 We also provide an ABC class for set of histograms: THistogramArrayBase.
211 The derived histogram-set class would specify how to create and fill an interesting
212 set of histograms.
213 The hope is that these generic histogram-sets would make it easy to provide
214 generic analyzer displays.
215 
216 It remains to be seen how useful these histogram-set classes
217 are in other context.
218 
219 T. Lindner
220 */
221