60a780004bb3d2308cb64a0338e71684ba617c48
[u/mrichter/AliRoot.git] / PWG2 / FORWARD / analysis2 / AliFMDEventInspector.cxx
1 // 
2 // This class inspects the event 
3 //
4 // Input:
5 //   - AliESDFMD object possibly corrected for sharing
6 //
7 // Output:
8 //   - A histogram of v_z of events with triggers. 
9 //   - A histogram of v_z of events with vertex and triggers 
10 //   - A histogram of trigger counters 
11 // 
12 // Note, that these are added to the master output list 
13 //
14 // Corrections used: 
15 //   - None
16 //
17 #include "AliFMDEventInspector.h"
18 #include "AliLog.h"
19 #include "AliESDEvent.h"
20 #include "AliMultiplicity.h"
21 #include "AliAnalysisManager.h"
22 #include "AliInputEventHandler.h"
23 #include "AliTriggerAnalysis.h"
24 #include "AliPhysicsSelection.h"
25 #include "AliAODForwardMult.h"
26 #include "AliForwardUtil.h"
27 #include "AliCentrality.h"
28 #include <TH1.h>
29 #include <TList.h>
30 #include <TDirectory.h>
31 #include <TROOT.h>
32 #include <iostream>
33 #include <iomanip>
34
35 //====================================================================
36 AliFMDEventInspector::AliFMDEventInspector()
37   : TNamed(),
38     fHEventsTr(0), 
39     fHEventsTrVtx(0),
40     fHEventsAccepted(0),
41     fHTriggers(0),
42     fHType(0),
43     fHWords(0),
44     fHCent(0),
45     fHCentVsQual(0),
46     fLowFluxCut(1000),
47     fMaxVzErr(0.2),
48     fList(0),
49     fEnergy(0),
50     fField(999), 
51     fCollisionSystem(kUnknown),
52     fDebug(0),
53     fCentAxis(0),
54     fVtxAxis(10,-10,10)
55 {
56   // 
57   // Constructor 
58   //
59 }
60
61 //____________________________________________________________________
62 AliFMDEventInspector::AliFMDEventInspector(const char* name)
63   : TNamed("fmdEventInspector", name),
64     fHEventsTr(0), 
65     fHEventsTrVtx(0), 
66     fHEventsAccepted(0),
67     fHTriggers(0),
68     fHType(0),
69     fHWords(0),
70     fHCent(0),
71     fHCentVsQual(0),
72     fLowFluxCut(1000),
73     fMaxVzErr(0.2),
74     fList(0),
75     fEnergy(0),
76     fField(999), 
77     fCollisionSystem(kUnknown),
78     fDebug(0),
79     fCentAxis(0),
80     fVtxAxis(10,-10,10)
81 {
82   // 
83   // Constructor 
84   // 
85   // Parameters:
86   //   name Name of object
87   //
88 }
89
90 //____________________________________________________________________
91 AliFMDEventInspector::AliFMDEventInspector(const AliFMDEventInspector& o)
92   : TNamed(o), 
93     fHEventsTr(o.fHEventsTr), 
94     fHEventsTrVtx(o.fHEventsTrVtx), 
95     fHEventsAccepted(o.fHEventsAccepted),
96     fHTriggers(o.fHTriggers),
97     fHType(o.fHType),
98     fHWords(o.fHWords),
99     fHCent(o.fHCent),
100     fHCentVsQual(o.fHCentVsQual),
101     fLowFluxCut(o.fLowFluxCut),
102     fMaxVzErr(o.fMaxVzErr),
103     fList(o.fList),
104     fEnergy(o.fEnergy),
105     fField(o.fField), 
106     fCollisionSystem(o.fCollisionSystem),
107     fDebug(0),
108     fCentAxis(0),
109     fVtxAxis(o.fVtxAxis)
110 {
111   // 
112   // Copy constructor 
113   // 
114   // Parameters:
115   //   o Object to copy from 
116   //
117 }
118
119 //____________________________________________________________________
120 AliFMDEventInspector::~AliFMDEventInspector()
121 {
122   // 
123   // Destructor 
124   //
125   if (fList)         delete fList;
126 }
127 //____________________________________________________________________
128 AliFMDEventInspector&
129 AliFMDEventInspector::operator=(const AliFMDEventInspector& o)
130 {
131   // 
132   // Assignement operator
133   // 
134   // Parameters:
135   //   o Object to assign from 
136   // 
137   // Return:
138   //    Reference to this object
139   //
140   TNamed::operator=(o);
141   fHEventsTr         = o.fHEventsTr;
142   fHEventsTrVtx      = o.fHEventsTrVtx;
143   fHEventsAccepted   = o.fHEventsAccepted;
144   fHTriggers         = o.fHTriggers;
145   fHType             = o.fHType;
146   fHWords            = o.fHWords;
147   fHCent             = o.fHCent;
148   fHCentVsQual       = o.fHCentVsQual;
149   fLowFluxCut        = o.fLowFluxCut;
150   fMaxVzErr          = o.fMaxVzErr;
151   fDebug             = o.fDebug;
152   fList              = (o.fList ? new TList : 0);
153   fEnergy            = o.fEnergy;
154   fField             = o.fField;
155   fCollisionSystem   = o.fCollisionSystem;
156   fVtxAxis.Set(o.fVtxAxis.GetNbins(), o.fVtxAxis.GetXmin(), 
157                o.fVtxAxis.GetXmax());
158   if (fList) { 
159     fList->SetName(GetName());
160     if (fHEventsTr)    fList->Add(fHEventsTr);
161     if (fHEventsTrVtx) fList->Add(fHEventsTrVtx);
162     if (fHTriggers)    fList->Add(fHTriggers);
163     if (fHType)        fList->Add(fHType);
164     if (fHWords)       fList->Add(fHWords);
165     if (fHCent)        fList->Add(fHCent);
166     if (fHCentVsQual)  fList->Add(fHCentVsQual);
167   }
168   return *this;
169 }
170
171 //____________________________________________________________________
172 Bool_t
173 AliFMDEventInspector::FetchHistograms(const TList* d, 
174                                       TH1I*& hEventsTr, 
175                                       TH1I*& hEventsTrVtx, 
176                                       TH1I*& hTriggers) const
177 {
178   // 
179   // Fetch our histograms from the passed list 
180   // 
181   // Parameters:
182   //   d             Input
183   //   hEventsTr     On return, pointer to histogram, or null
184   //   hEventsTrVtx  On return, pointer to histogram, or null
185   //   hTriggers     On return, pointer to histogram, or null
186   // 
187   // Return:
188   //    true on success, false otherwise 
189   //
190   hEventsTr    = 0;
191   hEventsTrVtx = 0;
192   hTriggers    = 0;
193   TList* dd    = dynamic_cast<TList*>(d->FindObject(GetName()));
194   if (!dd) return kFALSE;
195   
196   hEventsTr    = dynamic_cast<TH1I*>(dd->FindObject("nEventsTr"));
197   hEventsTrVtx = dynamic_cast<TH1I*>(dd->FindObject("nEventsTrVtx"));
198   hTriggers    = dynamic_cast<TH1I*>(dd->FindObject("triggers"));
199
200   if (!hEventsTr || !hEventsTrVtx || !hTriggers) return kFALSE;
201   return kTRUE;
202 }
203 //____________________________________________________________________
204 void
205 AliFMDEventInspector::Init(const TAxis& vtxAxis)
206 {
207   // 
208   // Initialize the object 
209   // 
210   // Parameters:
211   //   vtxAxis Vertex axis in use 
212   //
213   
214   // -1.5 -0.5 0.5 1.5 ... 89.5 ... 100.5
215   // ----- 92 number --------- ---- 1 ---
216   TArrayD limits(93);
217   for (Int_t i = 0; i < 92; i++) limits[i] = -1.5 + i;
218
219   fVtxAxis.Set(vtxAxis.GetNbins(), vtxAxis.GetXmin(), vtxAxis.GetXmax());
220   
221   fCentAxis  = new TAxis(limits.GetSize()-1, limits.GetArray());
222   fHEventsTr = new TH1I("nEventsTr", "Number of events w/trigger", 
223                         4*vtxAxis.GetNbins(), 
224                         2*vtxAxis.GetXmin(), 
225                         2*vtxAxis.GetXmax());
226   fHEventsTr->SetXTitle("v_{z} [cm]");
227   fHEventsTr->SetYTitle("# of events");
228   fHEventsTr->SetFillColor(kRed+1);
229   fHEventsTr->SetFillStyle(3001);
230   fHEventsTr->SetDirectory(0);
231   // fHEventsTr->Sumw2();
232   fList->Add(fHEventsTr);
233
234   fHEventsTrVtx = static_cast<TH1I*>(fHEventsTr->Clone("nEventsTrVtx"));
235   fHEventsTrVtx->SetTitle("Number of events w/trigger and vertex"); 
236   fHEventsTrVtx->SetFillColor(kBlue+1);
237   fHEventsTrVtx->SetDirectory(0);
238   // fHEventsTrVtx->Sumw2();
239   fList->Add(fHEventsTrVtx);
240
241   fHEventsAccepted = new TH1I("nEventsAccepted", 
242                               "Number of events  w/trigger and vertex in range",
243                               2*vtxAxis.GetNbins(), 
244                               2*vtxAxis.GetXmin(), 
245                               2*vtxAxis.GetXmax());
246   fHEventsAccepted->SetXTitle("v_{z} [cm]");
247   fHEventsAccepted->SetYTitle("# of events");
248   fHEventsAccepted->SetFillColor(kGreen+1);
249   fHEventsAccepted->SetFillStyle(3001);
250   fHEventsAccepted->SetDirectory(0);
251   // fHEventsAccepted->Sumw2();
252   fList->Add(fHEventsAccepted);
253                               
254       
255   fHTriggers = new TH1I("triggers", "Triggers", kOffline+1, 0, kOffline+1);
256   fHTriggers->SetFillColor(kRed+1);
257   fHTriggers->SetFillStyle(3001);
258   fHTriggers->SetStats(0);
259   fHTriggers->SetDirectory(0);
260   fHTriggers->GetXaxis()->SetBinLabel(kInel   +1,"INEL");
261   fHTriggers->GetXaxis()->SetBinLabel(kInelGt0+1,"INEL>0");
262   fHTriggers->GetXaxis()->SetBinLabel(kNSD    +1,"NSD");
263   fHTriggers->GetXaxis()->SetBinLabel(kEmpty  +1,"Empty");
264   fHTriggers->GetXaxis()->SetBinLabel(kA      +1,"A");
265   fHTriggers->GetXaxis()->SetBinLabel(kB      +1,"B");
266   fHTriggers->GetXaxis()->SetBinLabel(kC      +1,"C");
267   fHTriggers->GetXaxis()->SetBinLabel(kE      +1,"E");
268   fHTriggers->GetXaxis()->SetBinLabel(kPileUp +1,"Pileup");
269   fHTriggers->GetXaxis()->SetBinLabel(kMCNSD  +1,"NSD_{MC}");
270   fHTriggers->GetXaxis()->SetBinLabel(kOffline+1,"Offline");
271   fList->Add(fHTriggers);
272
273   fHType = new TH1I("type", Form("Event type (cut: SPD mult>%d)", 
274                                  fLowFluxCut), 2, -.5, 1.5);
275   fHType->SetFillColor(kRed+1);
276   fHType->SetFillStyle(3001);
277   fHType->SetStats(0);
278   fHType->SetDirectory(0);
279   fHType->GetXaxis()->SetBinLabel(1,"Low-flux");
280   fHType->GetXaxis()->SetBinLabel(2,"High-flux");
281   fList->Add(fHType);
282
283
284   fHWords = new TH1I("words", "Trigger words seen", 1, 0, 0); 
285   fHWords->SetFillColor(kBlue+1);
286   fHWords->SetFillStyle(3001);
287   fHWords->SetStats(0);
288   fHWords->SetDirectory(0);
289   fHWords->SetBit(TH1::kCanRebin);
290   fList->Add(fHWords);
291
292   fHCent = new TH1F("cent", "Centrality", limits.GetSize()-1,limits.GetArray());
293   fHCent->SetFillColor(kBlue+1);
294   fHCent->SetFillStyle(3001);
295   fHCent->SetStats(0);
296   fHCent->SetDirectory(0);
297   fHCent->SetXTitle("Centrality [%]");
298   fHCent->SetYTitle("Events");
299   fList->Add(fHCent);
300
301   fHCentVsQual = new TH2F("centVsQuality", "Quality vs Centrality", 
302                           5, 0, 5, limits.GetSize()-1, limits.GetArray());
303   fHCentVsQual->SetXTitle("Quality");
304   fHCentVsQual->SetYTitle("Centrality [%]");
305   fHCentVsQual->SetZTitle("Events");
306   fHCentVsQual->GetXaxis()->SetBinLabel(1, "OK");
307   fHCentVsQual->GetXaxis()->SetBinLabel(2, "Outside v_{z} cut");
308   fHCentVsQual->GetXaxis()->SetBinLabel(3, "V0 vs SPD outlier");
309   fHCentVsQual->GetXaxis()->SetBinLabel(4, "V0 vs TPC outlier");
310   fHCentVsQual->GetXaxis()->SetBinLabel(5, "V0 vs ZDC outlier");
311   fList->Add(fHCentVsQual);
312 }
313
314 //____________________________________________________________________
315 void
316 AliFMDEventInspector::DefineOutput(TList* dir)
317 {
318   // 
319   // Define the output histograms.  These are put in a sub list of the
320   // passed list.   The histograms are merged before the parent task calls 
321   // AliAnalysisTaskSE::Terminate 
322   // 
323   //   dir Directory to add to 
324   //
325   fList = new TList;
326   fList->SetName(GetName());
327   dir->Add(fList);
328 }
329
330 //____________________________________________________________________
331 UInt_t
332 AliFMDEventInspector::Process(const AliESDEvent* event, 
333                               UInt_t&            triggers,
334                               Bool_t&            lowFlux,
335                               UShort_t&          ivz, 
336                               Double_t&          vz,
337                               Double_t&          cent,
338                               UShort_t&          nClusters)
339 {
340   // 
341   // Process the event 
342   // 
343   // Parameters:
344   //   event     Input event 
345   //   triggers  On return, the triggers fired 
346   //   lowFlux   On return, true if the event is considered a low-flux 
347   //                  event (according to the setting of fLowFluxCut) 
348   //   ivz       On return, the found vertex bin (1-based).  A zero
349   //                  means outside of the defined vertex range
350   //   vz        On return, the z position of the interaction
351   //   cent      On return, the centrality - if not available < 0
352   // 
353   // Return:
354   //    0 (or kOk) on success, otherwise a bit mask of error codes 
355   //
356
357   // --- Check that we have an event ---------------------------------
358   if (!event) { 
359     AliWarning("No ESD event found for input event");
360     return kNoEvent;
361   }
362
363   // --- Read trigger information from the ESD and store in AOD object
364   if (!ReadTriggers(event, triggers, nClusters)) { 
365     if (fDebug > 2) {
366       AliWarning("Failed to read triggers from ESD"); }
367     return kNoTriggers;
368   }
369
370   // --- Check if this is a high-flux event --------------------------
371   const AliMultiplicity* testmult = event->GetMultiplicity();
372   if (!testmult) {
373     if (fDebug > 3) {
374       AliWarning("No central multiplicity object found"); }
375   }
376   else 
377     lowFlux = testmult->GetNumberOfTracklets() < fLowFluxCut;
378
379   fHType->Fill(lowFlux ? 0 : 1);
380   
381   // --- Read centrality information 
382   cent          = -10;
383   UShort_t qual = 0;
384   if (!ReadCentrality(event, cent, qual)) {
385     if (fDebug > 3) 
386       AliWarning("Failed to get centrality");
387   }
388   fHCent->Fill(cent);
389   if (qual == 0) fHCentVsQual->Fill(0., cent);
390   else { 
391     for (UShort_t i = 0; i < 4; i++) 
392       if (qual & (1 << i)) fHCentVsQual->Fill(Double_t(i+1), cent);
393   }
394
395   // --- Get the vertex information ----------------------------------
396   vz          = 0;
397   Bool_t vzOk = ReadVertex(event, vz);
398
399   fHEventsTr->Fill(vz);
400   if (!vzOk) { 
401     if (fDebug > 3) {
402       AliWarning("Failed to read vertex from ESD"); }
403     return kNoVertex;
404   }
405   fHEventsTrVtx->Fill(vz);
406
407   // --- Get the vertex bin ------------------------------------------
408   ivz = fVtxAxis.FindBin(vz);
409   if (ivz <= 0 || ivz > fVtxAxis.GetNbins()) { 
410     if (fDebug > 3) {
411       AliWarning(Form("Vertex @ %f outside of range [%f,%f]", 
412                       vz, fVtxAxis.GetXmin(), fVtxAxis.GetXmax())); 
413     }
414     ivz = 0;
415     return kBadVertex;
416   }
417   fHEventsAccepted->Fill(vz);
418   
419   // --- Check the FMD ESD data --------------------------------------
420   if (!event->GetFMDData()) { 
421     if (fDebug > 3) {
422       AliWarning("No FMD data found in ESD"); }
423     return kNoFMD;
424   }
425
426   
427   return kOk;
428 }
429
430 //____________________________________________________________________
431 Bool_t
432 AliFMDEventInspector::ReadCentrality(const AliESDEvent* esd, 
433                                      Double_t& cent, 
434                                      UShort_t& qual) const
435 {
436   // 
437   // Read centrality from event 
438   // 
439   // Parameters:
440   //    esd  Event 
441   //    cent On return, the centrality or negative if not found
442   // 
443   // Return:
444   //    False on error, true otherwise 
445   //
446   cent = -1;
447   qual = 0;
448   AliCentrality* centObj = const_cast<AliESDEvent*>(esd)->GetCentrality();
449   if (!centObj)  return true;
450
451   // AliInfo(Form("Got centrality object %p with quality %d", 
452   //              centObj, centObj->GetQuality()));
453   // centObj->Print();
454   cent = centObj->GetCentralityPercentile("V0M");  
455   qual = centObj->GetQuality();
456
457   return true;
458 }
459
460 //____________________________________________________________________
461 Bool_t
462 AliFMDEventInspector::ReadTriggers(const AliESDEvent* esd, UInt_t& triggers,
463                                    UShort_t& nClusters)
464 {
465   // 
466   // Read the trigger information from the ESD event 
467   // 
468   // Parameters:
469   //   esd        ESD event 
470   //   triggers   On return, contains the trigger bits 
471   // 
472   // Return:
473   //    @c true on success, @c false otherwise 
474   //
475   triggers = 0;
476
477   // Get the analysis manager - should always be there 
478   AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
479   if (!am) { 
480     AliWarning("No analysis manager defined!");
481     return kFALSE;
482   }
483
484   // Get the input handler - should always be there 
485   AliInputEventHandler* ih = 
486     static_cast<AliInputEventHandler*>(am->GetInputEventHandler());
487   if (!ih) { 
488     AliWarning("No input handler");
489     return kFALSE;
490   }
491     
492   // Check if this is a collision candidate (MB)
493   // Note, that we should use the value cached in the input 
494   // handler rather than calling IsCollisionCandiate directly 
495   // on the AliPhysicsSelection obejct.  If we called the latter
496   // then the AliPhysicsSelection object would overcount by a 
497   // factor of 2! :-(
498   Bool_t offline = ih->IsEventSelected();
499   nClusters = 0;
500   if (offline) {
501     triggers |= AliAODForwardMult::kOffline;
502     triggers |= AliAODForwardMult::kInel;
503     fHTriggers->Fill(kOffline+0.5);
504
505     // If this is inel, see if we have a tracklet 
506     const AliMultiplicity* spdmult = esd->GetMultiplicity();
507     if (!spdmult) {
508       AliWarning("No SPD multiplicity");
509     }
510     else { 
511       // Check if we have one or more tracklets 
512       // in the range -1 < eta < 1 to set the INEL>0 
513       // trigger flag. 
514       // 
515       // Also count tracklets as a single cluster 
516       Int_t n = spdmult->GetNumberOfTracklets();
517       for (Int_t j = 0; j < n; j++) { 
518         if(TMath::Abs(spdmult->GetEta(j)) < 1) { 
519           triggers |= AliAODForwardMult::kInelGt0;
520           nClusters++;
521         }
522       }
523       n = spdmult->GetNumberOfSingleClusters();
524       for (Int_t j = 0; j < n; j++) { 
525         Double_t eta = -TMath::Log(TMath::Tan(spdmult->GetThetaSingle(j)/2.));
526         if (TMath::Abs(eta) < 1) nClusters++;
527       }
528     }
529     if (nClusters > 0) triggers |= AliAODForwardMult::kNClusterGt0;
530   }
531
532   // Analyse some trigger stuff 
533   AliTriggerAnalysis ta;
534   if (ta.IsOfflineTriggerFired(esd, AliTriggerAnalysis::kNSD1)) 
535     triggers |= AliAODForwardMult::kNSD;
536  
537     
538   // Check for multiple vertices (pile-up) with at least 3
539   // contributors and at least 0.8cm from the primary vertex
540   Bool_t pileup =  esd->IsPileupFromSPD(3,0.8);
541   if (pileup) {
542     triggers |= AliAODForwardMult::kPileUp;
543     fHTriggers->Fill(kPileUp+.5);
544   }
545
546     
547   // Get trigger stuff 
548   TString trigStr = esd->GetFiredTriggerClasses();
549   // AliWarning(Form("Fired trigger classes: %s", trigStr.Data()));
550   fHWords->Fill(trigStr.Data(), 1);
551 #if 0
552   if (trigStr.Contains("MB1") || trigStr.Contains("MBBG3"))
553     triggers |= AliAOODForwardMult::kB;
554   if (trigStr.Contains("COTA")) 
555     triggers |= AliAODForwardMult::kA;
556   if (trigStr.Contains("COTC")) 
557     triggers |= AliAODForwardMult::kC;
558 #endif
559   if (trigStr.Contains("CBEAMB-ABCE-NOPF-ALL")) {
560     triggers |= AliAODForwardMult::kEmpty;
561     fHTriggers->Fill(kEmpty+.5);
562   }
563
564   // Check for B triggers
565   if (trigStr.Contains("CINT1B-ABCE-NOPF-ALL")   ||   // Early pp
566       trigStr.Contains("CINT1-B-NOPF-ALLNOTRD")  ||   // Late pp 
567       trigStr.Contains("CSMBB-ABCE-NOPF-ALL")    ||   // pp
568       trigStr.Contains("CMBACS2-B-NOPF-ALL")     ||   // PbPb
569       // trigStr.Contains("C0SMH-B-NOPF-ALL")    ||   // PbPb - high mult
570       trigStr.Contains("CMBS2A-B-NOPF-ALL")      ||   // PbPb
571       trigStr.Contains("CMBS2C-B-NOPF-ALL")      ||   // PbPb
572       trigStr.Contains("CMBAC-B-NOPF-ALL")       ||   // PbPb
573       // trigStr.Contains("C0SMH-B-NOPF-ALL")    ||   // PbPb - high mult
574       trigStr.Contains("CMBACS2-B-NOPF-ALLNOTRD")     // PbPb
575       // trigStr.Contains("C0SMH-B-NOPF-ALLNOTRD")    // PbPb - high mult
576       ) {
577     triggers |= AliAODForwardMult::kB;
578     fHTriggers->Fill(kB+.5);
579   }
580   
581   // Check for A triggers
582   if (trigStr.Contains("CINT1A-ABCE-NOPF-ALL")   ||   // Early pp
583       trigStr.Contains("CINT1-AC_NOPF-ALLNOTRD") ||   // Late pp
584       (trigStr.Contains("CSMBA-ABCE-NOPF-ALL") && 
585        !(triggers & AliAODForwardMult::kB))      ||   // pp
586       trigStr.Contains("CMBACS2-A-NOPF-ALL")     ||   // PbPb
587       // trigStr.Contains("C0SMH-A-NOPF-ALL")    ||   // PbPb - high mult
588       trigStr.Contains("CMBS2A-A-NOPF-ALL")      ||   // PbPb
589       trigStr.Contains("CMBS2C-A-NOPF-ALL")      ||   // PbPb
590       trigStr.Contains("CMBAC-A-NOPF-ALL")       ||   // PbPb
591       // trigStr.Contains("C0SMH-A-NOPF-ALL")    ||   // PbPb - high mult
592       trigStr.Contains("CMBACS2-A-NOPF-ALLNOTRD")     // PbPb
593       // trigStr.Contains("C0SMH-A-NOPF-ALLNOTRD")    // PbPb - high mult
594       ) {
595     triggers |= AliAODForwardMult::kA;
596     fHTriggers->Fill(kA+.5);
597   }
598
599   // Check for C triggers
600   if (trigStr.Contains("CINT1C-ABCE-NOPF-ALL")   ||  // Early pp
601       (trigStr.Contains("CSMBC-ABCE-NOPF-ALL") && 
602        !(triggers & AliAODForwardMult::kB))      ||   // pp
603       trigStr.Contains("CMBACS2-C-NOPF-ALL")     ||   // PbPb
604       // trigStr.Contains("C0SMH-B-NOPF-ALL")    ||   // PbPb - high mult
605       trigStr.Contains("CMBS2A-C-NOPF-ALL")      ||   // PbPb
606       trigStr.Contains("CMBS2C-C-NOPF-ALL")      ||   // PbPb
607       trigStr.Contains("CMBAC-C-NOPF-ALL")       ||   // PbPb
608       // trigStr.Contains("C0SMH-B-NOPF-ALL")    ||   // PbPb - high mult
609       trigStr.Contains("CMBACS2-C-NOPF-ALLNOTRD")     // PbPb
610       // trigStr.Contains("C0SMH-B-NOPF-ALLNOTRD")    // PbPb - high mult
611       ) {
612     triggers |= AliAODForwardMult::kC;
613     fHTriggers->Fill(kC+.5);
614   }
615
616   // Check for E triggers 
617   if (trigStr.Contains("CINT1-E-NOPF-ALL")       ||   // Early pp 
618       trigStr.Contains("CINT1-E-NOPF-ALLNOTRD")  ||   // Late pp 
619       trigStr.Contains("CMBACS2-E-NOPF-ALL")     ||   // PbPb
620       // trigStr.Contains("C0SMH-B-NOPF-ALL")    ||   // PbPb - high mult
621       trigStr.Contains("CMBS2A-E-NOPF-ALL")      ||   // PbPb
622       trigStr.Contains("CMBS2C-E-NOPF-ALL")      ||   // PbPb
623       trigStr.Contains("CMBAC-E-NOPF-ALL")       ||   // PbPb
624       // trigStr.Contains("C0SMH-B-NOPF-ALL")    ||   // PbPb - high mult
625       trigStr.Contains("CMBACS2-E-NOPF-ALLNOTRD")     // PbPb
626       // trigStr.Contains("C0SMH-B-NOPF-ALLNOTRD")    // PbPb - high mult
627       ) {
628     triggers |= AliAODForwardMult::kE;
629     fHTriggers->Fill(kE+.5);
630   }
631
632   // Now check - if we have a collision - for offline triggers and
633   // fill histogram.
634   if (triggers & AliAODForwardMult::kB) {
635     if (triggers & AliAODForwardMult::kInel) 
636       fHTriggers->Fill(kInel);
637     
638     if (triggers & AliAODForwardMult::kInelGt0)
639       fHTriggers->Fill(kInelGt0+.5);
640     
641     if (triggers & AliAODForwardMult::kNSD)
642       fHTriggers->Fill(kNSD+.5);
643   }
644   
645   return kTRUE;
646 }
647 //____________________________________________________________________
648 Bool_t
649 AliFMDEventInspector::ReadVertex(const AliESDEvent* esd, Double_t& vz)
650 {
651   // 
652   // Read the vertex information from the ESD event 
653   // 
654   // Parameters:
655   //   esd  ESD event 
656   //   vz   On return, the vertex Z position 
657   // 
658   // Return:
659   //    @c true on success, @c false otherwise 
660   //
661   vz = 0;
662 #if 1
663   // This is the code used by the 1st physics people 
664   const AliESDVertex* vertex    = esd->GetPrimaryVertex();
665   if (!vertex  || !vertex->GetStatus()) {
666     if (fDebug > 2) {
667       AliWarning(Form("No primary vertex (%p) or bad status %d", 
668                       vertex, (vertex ? vertex->GetStatus() : -1)));
669     }
670     return false;
671   }
672   const AliESDVertex* vertexSPD = esd->GetPrimaryVertexSPD();
673   if (!vertexSPD || !vertexSPD->GetStatus()) {
674     if (fDebug > 2) {
675       AliWarning(Form("No primary SPD vertex (%p) or bad status %d", 
676                       vertexSPD, (vertexSPD ? vertexSPD->GetStatus() : -1)));
677     }
678     return false;
679   }
680
681   // if vertex is from SPD vertexZ, require more stringent cuts 
682   if (vertex->IsFromVertexerZ()) { 
683     if (vertex->GetDispersion() > fMaxVzErr || 
684         vertex->GetZRes() > 1.25 * fMaxVzErr) {
685       if (fDebug > 2) {
686         AliWarning(Form("Dispersion %f > %f or resolution %f > %f",
687                         vertex->GetDispersion(), fMaxVzErr,
688                         vertex->GetZRes(), 1.25 * fMaxVzErr)); 
689       }
690       return false;
691     }
692   }
693   vz = vertex->GetZ();
694   return true;
695 #else 
696   // Get the vertex 
697   const AliESDVertex* vertex = esd->GetPrimaryVertexSPD();
698   if (!vertex) { 
699     if (fDebug > 2) {
700       AliWarning("No SPD vertex found in ESD"); }
701     return kFALSE;
702   }
703   
704   // Check that enough tracklets contributed 
705   if(vertex->GetNContributors() <= 0) {
706     if (fDebug > 2) {
707       AliWarning(Form("Number of contributors to vertex is %d<=0",
708                       vertex->GetNContributors())); }
709     vz = 0;
710     return kFALSE;
711   } 
712   // Check that the uncertainty isn't too large 
713   if (vertex->GetZRes() > fMaxVzErr) { 
714     if (fDebug > 2) {
715       AliWarning(Form("Uncertaintity in Z of vertex is too large %f > %f", 
716                       vertex->GetZRes(), fMaxVzErr)); }
717     return kFALSE;
718   }
719   
720   // Get the z coordiante 
721   vz = vertex->GetZ();
722   return kTRUE;
723 #endif 
724 }
725   
726 //____________________________________________________________________
727 Bool_t
728 AliFMDEventInspector::ReadRunDetails(const AliESDEvent* esd)
729 {
730   // 
731   // Read the collision system, collision energy, and L3 field setting
732   // from the ESD
733   // 
734   // Parameters:
735   //   esd ESD to get information from 
736   // 
737   // Return:
738   //    true on success, false 
739   //
740   // AliInfo(Form("Parameters from 1st ESD event: cms=%s, sNN=%f, field=%f",
741   //           esd->GetBeamType(), 2*esd->GetBeamEnergy(), 
742   //           esd->GetMagneticField()));
743   fCollisionSystem = 
744     AliForwardUtil::ParseCollisionSystem(esd->GetBeamType());
745   fEnergy          = 
746     AliForwardUtil::ParseCenterOfMassEnergy(fCollisionSystem,   
747                                             2 * esd->GetBeamEnergy());
748   fField           = 
749     AliForwardUtil::ParseMagneticField(esd->GetMagneticField());
750   
751   if (fCollisionSystem   == AliForwardUtil::kUnknown || 
752       fEnergy            <= 0                        || 
753       TMath::Abs(fField) >  10) 
754     return kFALSE;
755
756   return kTRUE;
757 }
758
759 //____________________________________________________________________
760 void
761 AliFMDEventInspector::Print(Option_t*) const
762 {
763   // 
764   // Print information
765   // 
766   //   option Not used 
767   //
768   char ind[gROOT->GetDirLevel()+1];
769   for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
770   ind[gROOT->GetDirLevel()] = '\0';
771   TString sNN(AliForwardUtil::CenterOfMassEnergyString(fEnergy));
772   sNN.Strip(TString::kBoth, '0');
773   sNN.ReplaceAll("GeV", " GeV");
774   TString field(AliForwardUtil::MagneticFieldString(fField));
775   field.ReplaceAll("p",  "+");
776   field.ReplaceAll("m",  "-");
777   field.ReplaceAll("kG", " kG");
778   
779   std::cout << ind << ClassName() << ": " << GetName() << '\n'
780             << ind << " Vertex bins:            " << fVtxAxis.GetNbins() << '\n'
781             << ind << " Vertex range:           [" << fVtxAxis.GetXmin() 
782             << "," << fVtxAxis.GetXmax() << "]\n"
783             << ind << " Low flux cut:           " << fLowFluxCut << '\n'
784             << ind << " Max(delta v_z):         " << fMaxVzErr << " cm\n"
785             << ind << " System:                 " 
786             << AliForwardUtil::CollisionSystemString(fCollisionSystem) << '\n'
787             << ind << " CMS energy per nucleon: " << sNN << '\n'
788             << ind << " Field:                  " <<  field << std::endl;
789 }
790
791   
792 //
793 // EOF
794 //
795