AliPhysics  3b4a69f (3b4a69f)
AliEmcalTriggerOfflineSelection.cxx
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright(c) 1998-2016, ALICE Experiment at CERN, All rights reserved. *
3  * *
4  * Author: The ALICE Off-line Project. *
5  * Contributors are mentioned in the code where appropriate. *
6  * *
7  * Permission to use, copy, modify and distribute this software and its *
8  * documentation strictly for non-commercial purposes is hereby granted *
9  * without fee, provided that the above copyright notice appears in all *
10  * copies and that both the copyright notice and this permission notice *
11  * appear in the supporting documentation. The authors make no claims *
12  * about the suitability of this software for any purpose. It is *
13  * provided "as is" without express or implied warranty. *
14  **************************************************************************/
15 #include <algorithm>
16 #include <cfloat>
17 #include <iostream>
18 #include <vector>
19 
20 #include <TClonesArray.h>
21 #include <TH2.h>
22 #include <TLorentzVector.h>
23 #include <TRandom.h>
24 
25 #include "AliEMCALTriggerConstants.h"
26 #include "AliEMCALTriggerPatchInfo.h"
28 #include "AliLog.h"
29 #include "AliVEvent.h"
30 
34 
35 namespace EMCalTriggerPtAnalysis {
36 
37 const TString AliEmcalTriggerOfflineSelection::fgkTriggerNames[AliEmcalTriggerOfflineSelection::kTrgn] = {
38  "EMC7", "EG1", "EG2", "EJ1", "EJ2", "DMC7", "DG1", "DG2", "DJ1", "DJ2"
39 };
40 
41 AliEmcalTriggerOfflineSelection::AliEmcalTriggerOfflineSelection():
42  TObject(),
43  fEnergyDefinition(kFEEEnergy),
44  fNameClusterContainer(),
45  fResolution(0),
46  fUseSmearedEnergy(false)
47 {
48  for(int itrg = 0; itrg < kTrgn; itrg++) fOfflineEnergyThreshold[itrg] = 100000.; // unimplemented triggers get very high threshold assinged, so that the result is automatically false
49  memset(fAcceptanceMaps, 0, sizeof(TH2 *) * kTrgn);
50 }
51 
53  for(int itrg = 0; itrg < kTrgn; itrg++){
54  if(fAcceptanceMaps[itrg]) delete fAcceptanceMaps[itrg];
55  }
56 }
57 
59  if(fOfflineEnergyThreshold[trgcls] < 0) return true;
60  AliDebugStream(1) << "Applying offline threshold " << fOfflineEnergyThreshold[trgcls] << " for trigger class " << GetTriggerName(trgcls) << std::endl;
61  if(UseClusters()){
62  return ApplyClusterTrigger(trgcls, data);
63  }
64  return ApplyPatchTrigger(trgcls, static_cast<TClonesArray *>(data->FindListObject("EmcalTriggers")));
65 }
66 
67 bool AliEmcalTriggerOfflineSelection::ApplyPatchTrigger(EmcalTriggerClass trgcls, const TClonesArray * const triggerpatches) const {
68  AliDebugStream(1) << "Using patch trigger with energy definition " << fEnergyDefinition << std::endl;
69  bool isSingleShower = IsSingleShower(trgcls), isDCAL = IsDCAL(trgcls);
70  int nfound = 0;
71  AliEMCALTriggerPatchInfo *patch = NULL;
72  std::vector<double> patchefficiencies;
73  for(auto patchIter : *triggerpatches){
74  patch = static_cast<AliEMCALTriggerPatchInfo *>(patchIter);
75  if(!patch->IsOfflineSimple()) continue;
76  if((isDCAL && !patch->IsDCalPHOS()) || (!isDCAL && patch->IsDCalPHOS())) continue; // reject patches in opposite detector
77  if(isSingleShower){
78  if(!patch->IsGammaLowSimple()) continue;
79  } else {
80  if(!patch->IsJetLowSimple()) continue;
81  }
82  AliDebugStream(1) << "Patch energy: " << patch->GetPatchE() << ", smeared " << patch->GetSmearedEnergy() << std::endl;
83  double energy(0);
84  // No switch as only cases for patches are handled in this class
87  AliDebugStream(1) << "Using smeared energy" << std::endl;
88  energy = patch->GetSmearedEnergy();
89  } else {
90  AliDebugStream (1) << "Using default energy" << std::endl;
91  energy = patch->GetPatchE();
92  }
93  }
96  TLorentzVector cm = patch->GetLorentzVectorCM();
97  cm.SetE(patch->GetSmearedEnergy());
98  energy = cm.Et();
99  } else {
100  energy = patch->GetPatchET();
101  }
102  }
103  else if(fEnergyDefinition == kFEEADC) energy = patch->GetADCOfflineAmp();
104  else if(fEnergyDefinition == kFEETransverseADC) energy = patch->GetPatchET() / EMCALTrigger::kEMCL1ADCtoGeV;
105  double threshold(fOfflineEnergyThreshold[trgcls]);
106  if(TMath::Abs(fResolution) > DBL_EPSILON){
107  // Simulation effect of the finite online energy resolution:
108  // The threshold is smeared using a gaussinan using the
109  // energy resolution as parameter for the smearing. A patch is
110  // selected in case the energy is above the smeared threshold.
111  // The approach is equivalent to smearing the patch energy itself.
112  AliDebugStream(1) << "Smearing energy with resolution " << fResolution << std::endl;
113  threshold = gRandom->Gaus(threshold, fResolution);
114  AliDebugStream(1) << "Thresholds: original(" << fOfflineEnergyThreshold[trgcls] << "), smeared(" << threshold << ")" << std::endl;
115  }
116  if(energy > threshold){
117  AliDebugStream(2) << GetTriggerName(trgcls) << " patch above threshold (" << patch->GetPatchE() << " | " << fOfflineEnergyThreshold[trgcls] << ")" << std::endl;
118  if(fAcceptanceMaps[trgcls]){
119  // Handle azimuthal inefficiencies of the trigger observed online:
120  // For each patch provide an efficiency. Once all patches in the event
121  // is determined, only the patch with the maximum efficiency is chosen.
122  // The event is selected in this case if the sample value is below the
123  // efficiency for the chosen patch.
124  double peff = fAcceptanceMaps[trgcls]->GetBinContent(patch->GetColStart(), patch->GetRowStart());
125  patchefficiencies.push_back(peff);
126  AliDebugStream(2) << "Spatial Efficiency " << peff
127  << " for trigger patch at position (" << patch->GetColStart()
128  << "," << patch->GetRowStart() << ")" << std::endl;
129  } else{
130  patchefficiencies.push_back(1.);
131  }
132  }
133  }
134  if(patchefficiencies.size()){
135  std::sort(patchefficiencies.begin(), patchefficiencies.end(), std::greater<double>());
136  double sample = gRandom->Uniform(0., 1.);
137  if(sample < patchefficiencies[0]){
138  AliDebugStream(1) << "Event selected for trigger class " << GetTriggerName(trgcls) << ", " << nfound << " good patch(es) found" << std::endl;
139  return true;
140  }
141  }
142  return false;
143 }
144 
145 bool AliEmcalTriggerOfflineSelection::ApplyClusterTrigger(EmcalTriggerClass trgcls, const AliVEvent * const ev) const {
146  AliDebugStream(1) << "Applying cluster trigger with energy definition " << fEnergyDefinition << std::endl;
147  int ntrigger = 0;
148  TClonesArray *clusters = static_cast<TClonesArray *>(ev->FindListObject(fNameClusterContainer));
149  double vertex[3]; ev->GetPrimaryVertex()->GetXYZ(vertex);
150  for(auto o : *clusters){
151  AliVCluster *c = dynamic_cast<AliVCluster *>(o);
152  if(!c->IsEMCAL()) continue;
153  // don't apply a time cut in case of simulations
154  double energy = c->GetNonLinCorrEnergy();
156  TLorentzVector vec;
157  c->GetMomentum(vec, vertex);
158  vec.SetE(c->GetNonLinCorrEnergy());
159  energy = vec.Et();
160  }
161  double threshold(fOfflineEnergyThreshold[trgcls]);
162  if(TMath::Abs(fResolution) > DBL_EPSILON){
163  // Simulation effect of the finite online energy resolution:
164  // The threshold is smeared using a gaussinan using the
165  // energy resolution as parameter for the smearing. A patch is
166  // selected in case the energy is above the smeared threshold.
167  // The approach is equivalent to smearing the patch energy itself.
168  threshold = gRandom->Gaus(threshold, fResolution);
169  }
170  if(energy > threshold) ntrigger++;
171  }
172  return ntrigger > 0;
173 }
174 
176  return ((cls == kTrgEG1) || (cls == kTrgEG2) || (cls == kTrgEL0) || (cls == kTrgDG1) || (cls == kTrgDG2) || (cls == kTrgDL0));
177 
178 }
179 
181  return ((cls == kTrgDL0) || (cls == kTrgDG1) || (cls == kTrgDG2) || (cls == kTrgDJ1) || (cls == kTrgDJ2));
182 }
183 
186 }
187 
190 }
191 
192 } /* namespace EMCalTriggerPtAnalysis */
Bool_t IsOfflineSelected(EmcalTriggerClass trgcls, const AliVEvent *const data) const
Select event as triggered event.
energy
Definition: HFPtSpectrum.C:44
static const TString & GetTriggerName(EmcalTriggerClass cls)
Get the name of the trigger class as string representation.
TCanvas * c
Definition: TestFitELoss.C:172
Helper class selecting events on the presence of a trigger patch for the given type above threshold...
bool ApplyClusterTrigger(EmcalTriggerClass trgcls, const AliVEvent *const event) const
Run event selection using a EMCAL clusters.
TRandom * gRandom
Double_t fOfflineEnergyThreshold[kTrgn]
Thresholds applied on offline energy.
Bool_t fUseSmearedEnergy
Switch whether to use smeared or original energy.
EmcalTriggerClass
Definition of the various supported trigger types.
static Bool_t IsSingleShower(EmcalTriggerClass cls)
Checks if the trigger class is a single shower patch trigger class.
bool UseClusters() const
Check whether the trigger observable is based on clusters.
Definition: External.C:220
Analysis of high- tracks in triggered events.
bool ApplyPatchTrigger(EmcalTriggerClass trgcls, const TClonesArray *const triggerpatches) const
Run event selection using trigger patches.
static Bool_t IsDCAL(EmcalTriggerClass cls)
Checks if the trigger class is a jet patch trigger class.
EmcalEnergyDefinition_t fEnergyDefinition
Define type of energy to be use for the patch selection.
const TH2 * fAcceptanceMaps[kTrgn]
! Online acceptance distribution
bool UsePatches() const
Check whether the trigger observable is based on trigger patches.
bool Bool_t
Definition: External.C:53