2 // See implementation or Doxygen comments for more information
4 #ifndef ALIAODFORWARDMULT_H
5 #define ALIAODFORWARDMULT_H
7 * @file AliAODForwardMult.h
8 * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
9 * @date Wed Mar 23 13:58:00 2011
11 * @brief Per-event @f$ N_{ch}@f$ per @f$(\eta,\varphi)@f$ bin
13 * @ingroup pwglf_forward_aod
21 * Class that contains the forward multiplicity data per event
23 * This class contains a histogram of
25 * \frac{d^2N_{ch}}{d\eta d\phi}\quad,
27 * as well as a trigger mask for each analysed event.
29 * The eta acceptance of the event is stored in the underflow bins of
30 * the histogram. So to build the final histogram, one needs to
31 * correct for this acceptance (properly weighted by the events), and
32 * the vertex efficiency. This simply boils down to defining a 2D
33 * histogram and summing the event histograms in that histogram. One
34 * should of course also do proper book-keeping of the accepted event.
39 * TFile* file = TFile::Open("AliAODs.root","READ");
40 * TTree* tree = static_cast<TTree*>(file->Get("aodTree"));
46 * TH2D* sum = 0; // Summed hist
47 * TTree* tree = GetAODTree(); // AOD tree
48 * AliAODForwardMult* mult = 0; // AOD object
49 * Int_t nTriggered = 0; // # of triggered ev.
50 * Int_t nWithVertex= 0; // # of ev. w/vertex
51 * Int_t nAccepted = 0; // # of ev. used
52 * Int_t nAvailable = tree->GetEntries(); // How many entries
53 * Float_t vzLow = -10; // Lower ip cut
54 * Float_t vzHigh = 10; // Upper ip cut
55 * Int_t mask = AliAODForwardMult::kInel;// Trigger mask
56 * tree->SetBranchAddress("forward", &forward); // Set the address
58 * for (int i = 0; i < nAvailable; i++) {
59 * // Create sum histogram on first event - to match binning to input
60 * if (!sum) sum = static_cast<TH2D*>(mult->Clone("d2ndetadphi"));
64 * // Other trigger/event requirements could be defined
65 * if (!mult->IsTriggerBits(mask)) continue;
68 * // Check if we have vertex
69 * if (!mult->HasIpZ()) continue;
72 * // Select vertex range (in centimeters)
73 * if (!mult->InRange(vzLow, vzHigh) continue;
76 * // Add contribution from this event
77 * sum->Add(&(mult->GetHistogram()));
80 * // Get acceptance normalisation from underflow bins
81 * TH1D* norm = sum->ProjectionX("norm", 0, 1, "");
82 * // Project onto eta axis - _ignoring_underflow_bins_!
83 * TH1D* dndeta = sum->Projection("dndeta", 1, -1, "e");
84 * // Normalize to the acceptance
85 * dndeta->Divide(norm);
86 * // Scale by the vertex efficiency
87 * dndeta->Scale(Double_t(nWithVertex)/nTriggered, "width");
88 * // And draw the result
93 * The above code will draw the final @f$ dN_{ch}/d\eta@f$ for the
94 * selected event class and vertex range
96 * The histogram can be used as input for other kinds of analysis too,
97 * like flow, event-plane, centrality, and so on.
99 * @ingroup pwglf_forward
100 * @ingroup pwglf_forward_aod
102 class AliAODForwardMult : public TObject
106 * Bits of the trigger pattern
109 /** In-elastic collision - really MBOR*/
111 /** In-elastic collision with at least one SPD tracklet */
113 /** Non-single diffractive collision - (V0AND||FASTOR>5) */
115 /** Empty bunch crossing */
117 /** A-side trigger */
119 /** B(arrel) trigger */
121 /** C-side trigger */
125 /** pileup from SPD */
127 /** true NSD from MC */
129 /** Offline MB triggered */
131 /** At least one SPD cluster */
132 kNClusterGt0 = 0x1000,
133 /** V0-AND trigger */
135 /** Satellite event */
137 /** SPD outlier event */
138 kSPDOutlier = 0x8000,
140 kPileupSPD = 0x10000,
142 kPileupTrack = 0x20000,
143 /** Out of bunch pileup */
148 * Bin numbers in trigger histograms
170 * User bits of these objects (bits 14-23 can be used)
173 /** Secondary correction maps where applied */
174 kSecondary = (1 << 14),
175 /** Vertex bias correction was applied */
176 kVertexBias = (1 << 15),
177 /** Acceptance correction was applied */
178 kAcceptance = (1 << 16),
179 /** Merging efficiency correction was applied */
180 kMergingEfficiency = (1 << 17),
181 /** Signal in overlaps is the sum */
183 /** Used eta dependent empirical correction - to be implemented */
184 kEmpirical = (1 << 19)
187 * Return codes of CheckEvent
190 /** Event accepted by cuts */
192 /** Event centrality not in range */
194 /** Event trigger isn't in the supplied mask */
196 /** Event is a pile-up event */
198 /** Event has no interaction point information */
200 /** Event interaction point is out of range */
207 * Default constructor
209 * Used by ROOT I/O sub-system - do not use
215 * @param isMC Whether this was from MC or not
217 AliAODForwardMult(Bool_t isMC);
221 virtual ~AliAODForwardMult() {} // Destructor
225 * @param etaAxis Pseudo-rapidity axis
227 void Init(const TAxis& etaAxis);
229 * Get the @f$ d^2N_{ch}/d\eta d\phi@f$ histogram,
231 * @return @f$ d^2N_{ch}/d\eta d\phi@f$ histogram,
233 const TH2D& GetHistogram() const { return fHist; } // Get histogram
235 * Get the @f$ d^2N_{ch}/d\eta d\phi@f$ histogram,
237 * @return @f$ d^2N_{ch}/d\eta d\phi@f$ histogram,
239 TH2D& GetHistogram() { return fHist; } // Get histogram
241 * Get the trigger bits
243 * @return Trigger bits
245 UInt_t GetTriggerBits() const { return fTriggers; } // Get triggers
247 * Set the trigger mask
249 * @param trg Trigger mask
251 void SetTriggerMask(UInt_t trg) { fTriggers = trg; } // Set triggers
253 * Set bit(s) in trigger mask
255 * @param bits bit(s) to set
257 void SetTriggerBits(UInt_t bits) { fTriggers |= bits; } // Set trigger bits
259 * Check if all bit(s) are set in the trigger mask. Note, this is
260 * an @e and between the bits. If you need an @e or you should use
261 * the member function IsTriggerOrBits
263 * @param bits Bits to test for
265 * @return true if all enabled bits in the argument is also set in
268 Bool_t IsTriggerBits(UInt_t bits) const;
270 * Check if any of bit(s) are enabled in the trigger word. This is
271 * an @e or between the selected bits. If you need and @a and you
272 * should use the member function IsTriggerBits;
274 * @param bits Bits to check for
276 * @return true if any of the enabled bits in the arguments are also
277 * enabled in the trigger mask
279 Bool_t IsTriggerOrBits(UInt_t bits) const;
281 * Whether we have any trigger bits
283 * @return true if we have some trigger
285 Bool_t HasTrigger() const { return fTriggers != 0; } // Check for triggers
289 * @param option Passed on to TH2::Reset verbatim
291 void Clear(Option_t* option="");
297 void Browse(TBrowser* b);
301 * @return Always true
303 Bool_t IsFolder() const { return kTRUE; } // Always true
305 * Check if the data has been secondary corrected by MC maps
307 * @return true if secondary corrected via MC maps
309 Bool_t IsSecondaryCorrected() const { return TestBit(kSecondary); }
311 * Check if vertex bias correction was applied
313 * @return true if MC based vertex bias was applied
315 Bool_t IsVertexBiasCorrected() const { return TestBit(kVertexBias); }
317 * Check if acceptance correction (from dead strips) was applied
319 * @return true if acceptance correction was applied
321 Bool_t IsAcceptanceCorrected() const { return TestBit(kAcceptance); }
323 * Check if merging efficiency (from MC) was applied
325 * @return true if merging efficiency was applied
327 Bool_t IsMergingEfficiencyCorrected() const {
328 return TestBit(kMergingEfficiency); }
330 * Check if an empirical correction was applied in the event level.
332 * @return True if the empirical correction was applied per event.
334 Bool_t IsEmpiricalCorrected() const { return TestBit(kEmpirical); }
336 * Check if the output is the sum (not average) in regions of
337 * overlap between detectors.
340 * @return true if the sum (not average) is stored in overlap
343 Bool_t IsSumSignal() const { return TestBit(kSum); }
347 * @param option Passed verbatim to TH2::Print
349 void Print(Option_t* option="") const;
351 * Set the z coordinate of the interaction point
353 * @param ipZ Interaction point z coordinate
355 void SetIpZ(Float_t ipZ) { fIpZ = ipZ; } // Set Ip's Z coordinate
357 * Set the center of mass energy per nucleon-pair. This is stored
358 * in the (0,0) of the histogram
360 * @param sNN Center of mass energy per nucleon pair (GeV)
362 void SetSNN(UShort_t sNN);
364 * Get the collision system number
369 * @param sys Collision system number
371 void SetSystem(UShort_t sys);
373 * Set the event centrality
375 * @param c Centrality
377 void SetCentrality(Float_t c) { fCentrality = c; }
379 * Set the z coordinate of the interaction point
381 * @return Interaction point z coordinate
383 Float_t GetIpZ() const { return fIpZ; } // Get Ip's Z coordinate
385 * Check if we have a valid z coordinate of the interaction point
387 * @return True if we have a valid interaction point z coordinate
389 Bool_t HasIpZ() const;
391 * Get the center of mass energy per nucleon pair (GeV)
393 * @return Center of mass energy per nucleon pair (GeV)
395 UShort_t GetSNN() const;
397 * Get the collision system number
402 * @return Collision system number
404 UShort_t GetSystem() const;
406 * Check if the z coordinate of the interaction point is within the
407 * given limits. Note that the convention used corresponds to the
408 * convention used in ROOTs TAxis.
410 * @param low Lower cut (inclusive)
411 * @param high Upper cut (exclusive)
413 * @return true if @f$ low \ge ipz < high@f$
415 Bool_t InRange(Float_t low, Float_t high) const;
417 * Get the event centrality
421 Float_t GetCentrality() const { return fCentrality; }
423 * Check if we have a valid centrality
425 * @return true if the centrality information is valid
427 Bool_t HasCentrality() const { return !(fCentrality < 0); }
429 * Get the number of SPD clusters seen in @f$ |\eta|<1@f$
431 * @return Number of SPD clusters seen
433 UShort_t GetNClusters() const { return fNClusters; }
435 * Set the number of SPD clusters seen in @f$ |\eta|<1@f$
437 * @param n Number of SPD clusters
439 void SetNClusters(UShort_t n) { fNClusters = n; }
441 * Get the name of the object
443 * @return Name of object
445 const Char_t* GetName() const { return (fIsMC ? "ForwardMC" : "Forward"); }
447 * Check if event meets the passses requirements.
449 * It returns true if @e all of the following is true
451 * - The trigger is within the bit mask passed.
452 * - The vertex is within the specified limits.
453 * - The centrality is within the specified limits, or if lower
454 * limit is equal to or larger than the upper limit.
456 * Note, for data with out a centrality estimate (e.g., pp), one
457 * must pass equal centrality cuts, or no data will be accepted. In
458 * other words, for pp data, always pass cMin=0, cMax=0
460 * If a histogram is passed in the last parameter, then that
461 * histogram is filled with the trigger bits.
463 * @param triggerMask Trigger mask
464 * @param vzMin Minimum @f$ v_z@f$ (in centimeters)
465 * @param vzMax Maximum @f$ v_z@f$ (in centimeters)
466 * @param cMin Minimum centrality (in percent)
467 * @param cMax Maximum centrality (in percent)
468 * @param hist Histogram to fill
469 * @param status Histogram to fill
470 * @param removePileup If true, do not accept pile-up events (default)
472 * @return @c true if the event meets the requirements
474 Bool_t CheckEvent(Int_t triggerMask=kInel,
475 Double_t vzMin=-10, Double_t vzMax=10,
476 UShort_t cMin=0, UShort_t cMax=100,
479 Bool_t removePileup=true) const;
481 * Get a string correspondig to the trigger mask
483 * @param mask Trigger mask
485 * @return Static string (copy before use)
487 static const Char_t* GetTriggerString(UInt_t mask);
489 * Make a histogram to record triggers in.
491 * The bins defined by the trigger enumeration in this class. One
492 * can use this enumeration to retrieve the number of triggers for
495 * @param name Name of the histogram
496 * @param mask Trigger mask
498 * @return Newly allocated histogram
500 static TH1I* MakeTriggerHistogram(const char* name="triggers",
503 * Make a histogram to record status in.
505 * The bins defined by the status enumeration in this class.
507 * @param name Name of the histogram
509 * @return Newly allocated histogram
511 static TH1I* MakeStatusHistogram(const char* name="status");
513 * Utility function to make a trigger mask from the passed string.
515 * The string is a comma or space seperated list of case-insensitive
522 * @param what Which triggers to put in the mask.
524 * @return The generated trigger mask.
526 static UInt_t MakeTriggerMask(const char* what);
528 /** From MC or not */
529 Bool_t fIsMC; // Whether this is from MC
530 /** Histogram of @f$d^2N_{ch}/(d\eta d\phi)@f$ for this event */
531 TH2D fHist; // Histogram of d^2N_{ch}/(deta dphi) for this event
533 UInt_t fTriggers; // Trigger bit mask
534 /** Interaction point @f$z@f$ coordinate */
535 Float_t fIpZ; // Z coordinate of the interaction point
537 Float_t fCentrality; // Event centrality
538 /** Number of clusters in @f$|\eta|<1@f$ */
539 UShort_t fNClusters; // Number of SPD clusters in |eta|<1
540 /** Invalid value for interaction point @f$z@f$ coordiante */
541 static const Float_t fgkInvalidIpZ; // Invalid IpZ value
542 ClassDef(AliAODForwardMult,5); // AOD forward multiplicity
545 //____________________________________________________________________
547 AliAODForwardMult::InRange(Float_t low, Float_t high) const
549 return HasIpZ() && fIpZ >= low && fIpZ < high;
552 //____________________________________________________________________
554 AliAODForwardMult::IsTriggerBits(UInt_t bits) const
556 return HasTrigger() && ((fTriggers & bits) == bits);
558 //____________________________________________________________________
560 AliAODForwardMult::IsTriggerOrBits(UInt_t bits) const
562 return HasTrigger() && ((fTriggers & bits) != 0);