Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
VDCeff.cxx
Go to the documentation of this file.
1//*-- Author : Ole Hansen 04-Nov-13
2
4// //
5// VDCeff //
6// //
7// VDC hit efficiency calculation. Since the VDC records clusters //
8// of hits, the efficiency can be estimated quite well without //
9// tracking information. If in a group of three adjacent wires //
10// the two outer wires have a hit, check if the middle wire has a hit //
11// as well. The hit efficiency for that wire, then, is the probability //
12// that there is a hit. Of course, noise and overlapping clusters //
13// cause errors in this calculation, assumed to be small. //
14// //
15// This module reads a list of global variable names for VDC hit //
16// spectra (wire numbers) from the database. For each variable, it //
17// sets up a hit efficiency histogram which is updated every 500 //
18// events (configurable, if desired). //
19// //
21
22#include "VDCeff.h"
23#include "THaVarList.h"
24#include "THaGlobals.h"
25#include "TObjArray.h"
26#include "TH1F.h"
27#include "TMath.h"
28#include "TDirectory.h"
29#include "TClass.h"
30
31#include <stdexcept>
32#include <memory>
33#include <cassert>
34
35using namespace std;
36using namespace Podd;
37
38const TString nhit_suffix( "nhit" );
39const TString eff_suffix( "eff" );
40
41//_____________________________________________________________________________
42static void SafeDeleteHist( const TString& name, TH1F*& the_hist )
43{
44 // Verify that each histogram is still in memory. It usually isn't because
45 // ROOT deletes it when the output file is closed.
46 if( !the_hist ) return;
47 TObject* obj = gDirectory->FindObject(name);
48 if( obj && obj->IsA() && obj->IsA()->InheritsFrom(TH1::Class()) ) {
49 assert( name == obj->GetName() );
50 delete the_hist;
51 }
52 // Zero out now-invalid pointer, regardless of who deleted it
53 the_hist = nullptr;
54}
55
56//_____________________________________________________________________________
58{
59 // VDCvar_t destructor. Delete histograms, if defined.
60
63}
64
65//_____________________________________________________________________________
67{
68 // Reset histograms and counters of this VDCvar
69
70 if( nwire > 0 ) {
71 ncnt.assign( nwire, 0 );
72 nhit.assign( nwire, 0 );
73 }
74 if( hist_nhit ) hist_nhit->Reset();
75 if( hist_eff ) hist_eff->Reset();
76}
77
78//_____________________________________________________________________________
79VDCeff::VDCeff( const char* name, const char* description )
80 : THaPhysicsModule(name,description), fNevt(0), fCycle(500), fMaxOcc(0.25)
81{
82 // VDCeff module constructor
83
84}
85
86//_____________________________________________________________________________
88{
89 // Destructor
90
92}
93
94//_____________________________________________________________________________
96{
97 // Clear event-by-event data
98
99 Clear(opt);
100 for( auto& var : fVDCvar ) {
101 var.Reset(opt);
102 }
103}
104
105//_____________________________________________________________________________
107{
108 // Start of analysis
109
110 if( !IsOK() ) return -1;
111
112 for( auto& thePlane : fVDCvar ) {
113 assert( thePlane.nwire > 0 );
114 thePlane.ncnt.assign( thePlane.nwire, 0 );
115 thePlane.nhit.assign( thePlane.nwire, 0 );
116 // Book histograms here, not in Init. The output file must be open for the
117 // histogram to be saved. This is the case here, but not when Init runs.
118 if( !thePlane.hist_nhit ) {
119 TString name = thePlane.histname + nhit_suffix;
120 TString title = "Num hits " + thePlane.histname;
121 Int_t nmax = TMath::Nint(TMath::Ceil(thePlane.nwire * fMaxOcc));
122 thePlane.hist_nhit = new TH1F( name, title, nmax, -1, nmax-1 );
123 }
124 if( !thePlane.hist_eff ) {
125 TString name = thePlane.histname + eff_suffix;
126 TString title = thePlane.histname + " efficiency";
127 thePlane.hist_eff = new TH1F( name, title,
128 thePlane.nwire, 0, thePlane.nwire );
129 }
130 }
131 fNevt = 0;
132
133 return 0;
134}
135
136//_____________________________________________________________________________
138{
139 // End of analysis
140
141 WriteHist();
142 return 0;
143}
144
145//_____________________________________________________________________________
147{
148 // Initialize VDCeff physics module
149
150 const char* const here = "Init";
151
152 // Standard initialization. Calls ReadDatabase(), ReadRunDatabase(),
153 // and DefineVariables() (see THaAnalysisObject::Init)
154 if( THaPhysicsModule::Init( run_time ) != kOK )
155 return fStatus;
156
157 // Associate global variable pointers. This can and should be done
158 // at every reinitialization (pointers in VDC class may have changed)
159 for( auto& thePlane : fVDCvar ) {
160 assert( !thePlane.name.IsNull() );
161 thePlane.pvar = gHaVars->Find( thePlane.name );
162 if( !thePlane.pvar ) {
163 Warning( Here(here), "Cannot find global VDC variable %s. Ignoring.",
164 thePlane.name.Data() );
165 }
166 }
167
168 return fStatus = kOK;
169}
170
171//_____________________________________________________________________________
172Int_t VDCeff::Process( const THaEvData& /*evdata*/ )
173{
174 // Update VDC efficiency histograms with current event data.
175 // The data come from the VDC detector and are accessed via global variables
176
177 const char* const here = "Process";
178
179 if( !IsOK() ) return -1;
180
181 ++fNevt;
182 bool cycle_event = ( (fNevt%fCycle) == 0 );
183
184 for( auto& thePlane : fVDCvar ) {
185
186 if( !thePlane.pvar ) continue; // global variable wasn't found
187
188 Int_t nwire = thePlane.nwire;
189 fWire.clear();
190 fHitWire.assign( nwire, false );
191
192 Int_t nhit = thePlane.pvar->GetLen();
193 thePlane.hist_nhit->Fill(nhit);
194 if( nhit < 0 ) {
195 Warning( Here(here), "nhit = %d < 0?", nhit );
196 nhit = 0;
197 } else if( nhit > nwire ) {
198 Warning( Here(here), "nhit = %d > nwire = %d?", nhit, nwire );
199 nhit = nwire;
200 }
201
202 for( Int_t i = 0; i < nhit; ++i ) {
203 auto wire = static_cast<Short_t>(TMath::Nint(thePlane.pvar->GetValue(i)));
204 if( wire >= 0 && wire < nwire ) {
205 fWire.push_back(wire);
206 fHitWire[wire] = true;
207 }
208 }
209
210 for( Int_t wire : fWire ) {
211 Int_t ngh2 = wire+2;
212 if( ngh2 >= nwire ) continue;
213
214 if( fHitWire[ngh2] ) {
215 Int_t awire = wire+1;
216 thePlane.ncnt[awire]++;
217 if( fHitWire[awire] )
218 thePlane.nhit[awire]++;
219 }
220 }
221
222 if( cycle_event ) {
223 thePlane.hist_eff->Reset();
224 for( Int_t i = 0; i < nwire; ++i ) {
225 if( thePlane.ncnt[i] != 0 ) {
226 Double_t xeff = static_cast<Double_t>(thePlane.nhit[i]) /
227 static_cast<Double_t>(thePlane.ncnt[i]);
228 thePlane.hist_eff->Fill(i,xeff);
229 }
230 }
231 }
232 }
233
234 // FIXME: repeated WriteHist seems to cause problems with split files
235 // (multiple cycles left in output)
236 if( (cycle_event && fNevt < 4*static_cast<Long64_t>(fCycle)) ||
237 (fNevt % (10*fCycle) == 0) )
238 WriteHist();
239
240#ifdef WITH_DEBUG
241 if( fDebug>1 && (fNevt%10) == 0 )
242 Print();
243#endif
244
245 fDataValid = true;
246 return 0;
247}
248
249//_____________________________________________________________________________
251{
252 // Read database. Gets the VDC variables containing wire spectra.
253
254 const char* const here = "ReadDatabase";
255 const char* const separators = ", \t";
256 const Int_t NPAR = 3;
257
258 FILE* f = OpenFile( date );
259 if( !f ) return kFileError;
260
261 TString configstr;
262 // Default values
263 fCycle = 500;
264 fMaxOcc = 0.25;
265
266 Int_t status = kOK;
267 try {
268 const DBRequest request[] = {
269 { "vdcvars", &configstr, kTString },
270 { "cycle", &fCycle, kInt, 0, true },
271 { "maxocc", &fMaxOcc, kDouble, 0, true },
272 { nullptr }
273 };
274 status = LoadDB( f, date, request );
275 }
276 catch(...) {
277 fclose(f);
278 throw;
279 }
280 fclose(f);
281 if( status != kOK ) {
282 return status;
283 }
284
285 if( configstr.Length() == 0 ) {
286 Error( Here(here), "No VDC variables defined. Fix database." );
287 return kInitError;
288 }
289 // Parse the vdcvars string and set up definition structure for each item
290 unique_ptr<TObjArray> vdcvars( configstr.Tokenize(separators) );
291 Int_t nparams = vdcvars->GetLast()+1;
292 if( nparams == 0 ) {
293 Error( Here(here), "No VDC variable names in vdcvars = %s. Fix database.",
294 configstr.Data() );
295 return kInitError;
296 }
297 if( nparams % NPAR != 0 ) {
298 Error( Here(here), "Incorrect number of parameters in vdcvars. "
299 "Have %d, but must be a multiple of %d. Fix database.",
300 nparams, NPAR );
301 return kInitError;
302 }
303 fVDCvar.clear();
304 const TObjArray* params = vdcvars.get();
305 Int_t max_nwire = 0;
306 for( Int_t ip = 0; ip < nparams; ip += NPAR ) {
307 const TString& name = GetObjArrayString(params,ip);
308 const TString& histname = GetObjArrayString(params,ip+1);
309 Int_t nwire = GetObjArrayString(params,ip+2).Atoi();
310 if( name.IsNull() ) {
311 Error( Here(here), "Missing global variable name at vdcvars[%d]. "
312 "Fix database.", ip );
313 return kInitError;
314 }
315 if( histname.IsNull() ) {
316 Error( Here(here), "Missing histogram name at vdcvars[%d]. "
317 "Fix database.", ip );
318 return kInitError;
319 }
320 if( nwire <= 0 || nwire > kMaxShort ) {
321 Error( Here(here), "Illegal number of wires = %d for VDC variable %s. "
322 "Fix database.", nwire, name.Data() );
323 return kInitError;
324 }
325 // Check for duplicate name or histname
326 for( auto& thePlane : fVDCvar ) {
327 if( thePlane.name == name ) {
328 Error( Here(here), "Duplicate global variable name %s. "
329 "Fix database.", name.Data() );
330 return kInitError;
331 }
332 if( thePlane.histname == histname ) {
333 Error( Here(here), "Duplicate histogram name %s. "
334 "Fix database.", histname.Data() );
335 return kInitError;
336 }
337 }
338 if( fDebug>2 )
339 Info( Here(here), "Defining VDC variable %s", name.Data() );
340
341 fVDCvar.emplace_back(name, histname, nwire );
342 VDCvar_t& thePlane = fVDCvar.back();
343 thePlane.ncnt.reserve( thePlane.nwire );
344 thePlane.nhit.reserve( thePlane.nwire );
345 max_nwire = TMath::Max(max_nwire,thePlane.nwire);
346 }
347
349 fWire.reserve(TMath::Nint(TMath::Ceil(max_nwire * fMaxOcc)));
350 fHitWire.assign(max_nwire, false);
351
352 return kOK;
353}
354
355//_____________________________________________________________________________
357{
358 // Write all defined histograms
359
360 for( auto& thePlane : fVDCvar ) {
361 if( thePlane.hist_nhit )
362 thePlane.hist_nhit->Write();
363 if( thePlane.hist_eff )
364 thePlane.hist_eff->Write();
365 }
366}
367
368//_____________________________________________________________________________
int Int_t
#define f(i)
const Int_t kMaxShort
short Short_t
double Double_t
const char Option_t
#define gDirectory
char name[80]
R__EXTERN class THaVarList * gHaVars
Definition THaGlobals.h:11
static const char *const here
Definition THaVar.cxx:64
static void SafeDeleteHist(const TString &name, TH1F *&the_hist)
Definition VDCeff.cxx:42
const TString nhit_suffix("nhit")
const TString eff_suffix("eff")
Bool_t InheritsFrom(const char *cl) const override
static TClass * Class()
static Int_t LoadDB(FILE *file, const TDatime &date, const DBRequest *request, const char *prefix, Int_t search=0, const char *here="THaAnalysisObject::LoadDB")
virtual const char * Here(const char *) const
Bool_t IsOK() const
virtual FILE * OpenFile(const TDatime &date)
virtual void Print(Option_t *opt="") const
virtual void Clear(Option_t *opt="")
virtual THaVar * Find(const char *name) const
virtual const char * GetName() const
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual void Error(const char *method, const char *msgfmt,...) const
virtual TClass * IsA() const
virtual void Info(const char *method, const char *msgfmt,...) const
Ssiz_t Length() const
const char * Data() const
TObjArray * Tokenize(const TString &delim) const
Bool_t IsNull() const
Vcnt_t ncnt
Definition VDCeff.h:45
TString histname
Definition VDCeff.h:42
Vcnt_t nhit
Definition VDCeff.h:46
TH1F * hist_nhit
Definition VDCeff.h:47
void Reset(Option_t *opt="")
Definition VDCeff.cxx:66
TH1F * hist_eff
Definition VDCeff.h:48
void Reset(Option_t *opt="")
Definition VDCeff.cxx:95
void WriteHist()
Definition VDCeff.cxx:356
Double_t fMaxOcc
Definition VDCeff.h:60
Long64_t fNevt
Definition VDCeff.h:56
virtual Int_t ReadDatabase(const TDatime &date)
Definition VDCeff.cxx:250
std::vector< Short_t > fWire
Definition VDCeff.h:53
VDCeff(const char *name, const char *description)
Definition VDCeff.cxx:79
virtual Int_t Process(const THaEvData &)
Definition VDCeff.cxx:172
virtual ~VDCeff()
Definition VDCeff.cxx:87
virtual Int_t End(THaRunBase *r=nullptr)
Definition VDCeff.cxx:137
std::vector< bool > fHitWire
Definition VDCeff.h:54
std::vector< VDCvar_t > fVDCvar
Definition VDCeff.h:52
Int_t fCycle
Definition VDCeff.h:59
virtual Int_t Begin(THaRunBase *r=nullptr)
Definition VDCeff.cxx:106
long long Long64_t
Double_t Min(Double_t a, Double_t b)
Int_t Nint(T x)
Double_t Ceil(Double_t x)
Double_t Abs(Double_t d)
Double_t Max(Double_t a, Double_t b)
STL namespace.
ClassImp(TPyArg)