1 // ----------------------------------------------------------------
2 // AliBackgroundSelection
4 // This class implements to cuts to reject background events from the
5 // samples to be used in the physics analysis:
6 // 1. A linear cut on the correlation cluster vs tracklets
7 // 2. A cut on the delta phi window used by the vertexer Z
8 // The parameters used in both cuts can be set
10 // The class also produces control histograms for all and accepted
11 // events, for each trigger class present in the data independently.
12 // Histograms are booked on the fly in the UserExec, whenever a new
13 // trigger class is found.
15 // After the first implementation, it was realized that the deltaphi
16 // cut is more a quality selection cut than an event selection cut, so
17 // it is effectively disabled by default.
19 // Author: Michele Floris, CERN
20 // ----------------------------------------------------------------
23 #include "AliBackgroundSelection.h"
27 #include "AliESDInputHandlerRP.h"
28 #include "AliAnalysisManager.h"
30 #include "AliMultiplicity.h"
32 #include "AliITSRecPoint.h"
37 ClassImp(AliBackgroundSelection)
39 AliBackgroundSelection::AliBackgroundSelection():
40 AliAnalysisCuts(), fOutputHist(0), fACut(0), fBCut(0), fDeltaPhiCut(10)
43 fOutputHist = new TList();
44 fOutputHist->SetOwner();
47 fDeltaPhiCut = 10; // effectively disabling delta phi cut by default
50 AliBackgroundSelection::AliBackgroundSelection(const char* name, const char* title):
51 AliAnalysisCuts(name,title), fOutputHist(0), fACut(0), fBCut(0), fDeltaPhiCut(10)
54 fOutputHist = new TList();
55 fOutputHist->SetOwner();
58 fDeltaPhiCut = 10; // effectively disabling delta phi cut by default
62 AliBackgroundSelection::AliBackgroundSelection(const AliBackgroundSelection& obj) : AliAnalysisCuts(obj),
63 fOutputHist(0), fACut(0), fBCut(0), fDeltaPhiCut(0)
66 fOutputHist = obj.fOutputHist;
69 fDeltaPhiCut = obj.fDeltaPhiCut;
72 AliBackgroundSelection::~AliBackgroundSelection() {
81 Bool_t AliBackgroundSelection::IsSelected(TObject* const obj)
83 // returns false if the event is identifiead as beam background,
90 AliESDInputHandlerRP* handlerRP = dynamic_cast<AliESDInputHandlerRP*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
92 AliFatal("Cannot get the AliESDInputHandlerRP");
94 TTree* itsClusterTree = handlerRP->GetTreeR("ITS");
96 AliError("Cannot get the ITS Cluster tree");
99 // AliFatal("Cannot get the ITS Cluster tree");
101 TClonesArray* itsClusters = new TClonesArray("AliITSRecPoint");
102 TBranch* itsClusterBranch=itsClusterTree->GetBranch("ITSRecPoints");
104 itsClusterBranch->SetAddress(&itsClusters);
106 Int_t nItsSubs = (Int_t)itsClusterTree->GetEntries();
109 AliESDEvent * esdEv = (AliESDEvent*) obj;
112 Float_t deltaPhi = 0.0; // deltaPhi is not available in pass1
114 // Get # spd clusters and of tracklets
118 // loop over the its subdetectors
119 for (Int_t iIts=0; iIts < nItsSubs; iIts++) {
121 if (!itsClusterTree->GetEvent(iIts))
124 Int_t nClusters = itsClusters->GetEntriesFast();
126 // loop over clusters
127 while (nClusters--) {
128 AliITSRecPoint* cluster = (AliITSRecPoint*) itsClusters->UncheckedAt(nClusters);
130 Int_t layer = cluster->GetLayer();
132 if (layer < 3) { // SPD
139 const AliMultiplicity* mult = esdEv->GetMultiplicity();
141 AliFatal("No multiplicity object"); // TODO: Should this be fatal?
143 Int_t ntracklet = mult->GetNumberOfTracklets();
146 // get deltaphi if vertexer z
147 Float_t deltaPhi = 0.0;
149 const AliESDVertex * vtxESD = esdEv->GetPrimaryVertexSPD();
151 if (vtxESD->IsFromVertexerZ()) deltaPhi = vtxESD->GetDispersion(); // dispersion contains deltaphi in case of vertexer Z
154 AliWarning("No Vertex");
159 // compute number of spd clusters
160 Float_t spdClusters = 0;
161 for(Int_t ilayer = 0; ilayer < 2; ilayer++){
162 spdClusters += mult->GetNumberOfITSClusters(ilayer);
167 Bool_t isCvsTOk = kFALSE;
168 Bool_t isDeltaPhiOk = kFALSE;
170 Float_t limit = fACut + ntracklet * fBCut;
171 if (spdClusters > limit) isCvsTOk = kFALSE;
172 else isCvsTOk = kTRUE ;
174 if(deltaPhi > fDeltaPhiCut) isDeltaPhiOk = kFALSE;
175 else isDeltaPhiOk = kTRUE ;
177 if (!isCvsTOk || !isDeltaPhiOk) SetSelected(kFALSE);
178 else SetSelected(kTRUE );
180 // Fill control histos for all trigger classes
181 TString trgClasses = esdEv->GetFiredTriggerClasses();
182 TObjArray * tokens = trgClasses.Tokenize(" ");
184 while(TObjString * tok = (TObjString*) iter.Next()){
185 // clean up trigger name
186 TString trg = tok->GetString();
187 trg.Strip(TString::kTrailing, ' ');
188 trg.Strip(TString::kLeading, ' ');
190 // cluster vs tracklets
191 TH2F * hCvsT = GetClusterVsTrackletsHisto(trg.Data());
192 TH2F * hCvsTa = GetClusterVsTrackletsHistoAccepted(trg.Data());
193 hCvsT->Fill(ntracklet,spdClusters);
194 if(isCvsTOk) hCvsTa->Fill(ntracklet,spdClusters);
197 TH1F * hDeltaPhi = GetDeltaPhiHisto(trg.Data());
198 TH1F * hDeltaPhia = GetDeltaPhiHistoAccepted(trg.Data());
199 hDeltaPhi->Fill(deltaPhi);
200 if(isDeltaPhiOk) hDeltaPhia->Fill(deltaPhi);
202 if(tokens) delete tokens;
207 itsClusters->Delete();
215 void AliBackgroundSelection::Init(){
217 // Set default cut values
224 void AliBackgroundSelection::BookClusterVsTrackletsHisto(const char * trigger_name){
226 // Book control histogram for the cut on the correlation cluster vs tracklets
228 Bool_t oldStatus = TH1::AddDirectoryStatus();
229 TH1::AddDirectory(kFALSE);
231 TH2F * h1 = new TH2F(GetClusterVsTrackletsHistoName(trigger_name),trigger_name, 300, -0.5, 2999.5, 1000, -0.5, 9999.5);
232 h1->SetXTitle("Tracklets");
233 h1->SetYTitle("SPD Clusters");
234 // AliInfo(Form("Creating histos: %s, all and accepted", GetClusterVsTrackletsHistoName(trigger_name)));
236 TH2F * h2 = new TH2F(GetClusterVsTrackletsHistoNameAccepted(trigger_name),TString(trigger_name)+ "(accepted)",
237 300, -0.5, 2999.5, 1000, -0.5, 9999.5);
238 h2->SetXTitle("Tracklets");
239 h2->SetYTitle("SPD Clusters");
241 fOutputHist->Add(h1);
242 fOutputHist->Add(h2);
244 TH1::AddDirectory(oldStatus);
248 void AliBackgroundSelection::BookDeltaPhiHisto(const char * trigger_name){
250 // Book control histogram for the cut on the DeltaPhi window used by vertexer Z
252 Bool_t oldStatus = TH1::AddDirectoryStatus();
253 TH1::AddDirectory(kFALSE);
255 TH1F * h1 = new TH1F(GetDeltaPhiHistoName(trigger_name),trigger_name, 100,0,0.5);
256 h1->SetXTitle("#Delta #phi");
257 // AliInfo(Form("Creating histos: %s, all and accepted", GetDeltaPhiHistoName(trigger_name)));
259 TH1F * h2 = new TH1F(GetDeltaPhiHistoNameAccepted(trigger_name),TString(trigger_name)+ "(accepted)", 100,0,0.5);
260 h2->SetXTitle("#Delta #phi");
263 fOutputHist->Add(h1);
264 fOutputHist->Add(h2);
266 TH1::AddDirectory(oldStatus);
270 TH2F * AliBackgroundSelection::GetClusterVsTrackletsHisto(const char * trigger_name){
272 // Returns the control histogram corresponding to a given trigger
273 // class. If it does not exist, it creates it and adds it to the
277 if(!fOutputHist) {AliError("List of histos not initialized");return 0;}
278 TH2F * h = (TH2F*) fOutputHist->FindObject(GetClusterVsTrackletsHistoName(trigger_name));
280 BookClusterVsTrackletsHisto(trigger_name);
281 h = (TH2F*) fOutputHist->FindObject(GetClusterVsTrackletsHistoName(trigger_name));
285 TH1F * AliBackgroundSelection::GetDeltaPhiHisto(const char * trigger_name){
287 // Returns the control histogram corresponding to a given trigger
288 // class. If it does not exist, it creates it and adds it to the
292 if(!fOutputHist) {AliError("List of histos not initialized");return 0;}
293 TH1F * h = (TH1F*) fOutputHist->FindObject(GetDeltaPhiHistoName(trigger_name));
295 BookDeltaPhiHisto(trigger_name);
296 h = (TH1F*) fOutputHist->FindObject(GetDeltaPhiHistoName(trigger_name));
301 TH2F * AliBackgroundSelection::GetClusterVsTrackletsHistoAccepted(const char * trigger_name){
303 // Returns the control histogram corresponding to a given trigger
304 // class. If it does not exist, it creates it and adds it to the
306 // Events passing the cut only
308 if(!fOutputHist) {AliError("List of histos not initialized");return 0;}
309 TH2F * h = (TH2F*) fOutputHist->FindObject(GetClusterVsTrackletsHistoNameAccepted(trigger_name));
311 BookClusterVsTrackletsHisto(trigger_name);
312 h = (TH2F*) fOutputHist->FindObject(GetClusterVsTrackletsHistoNameAccepted(trigger_name));
318 TH1F * AliBackgroundSelection::GetDeltaPhiHistoAccepted(const char * trigger_name){
320 // Returns the control histogram corresponding to a given trigger
321 // class. If it does not exist, it creates it and adds it to the
323 // Events passing the cut only
325 if(!fOutputHist) {AliError("List of histos not initialized");return 0;}
326 TH1F * h = (TH1F*) fOutputHist->FindObject(GetDeltaPhiHistoNameAccepted(trigger_name));
328 BookDeltaPhiHisto(trigger_name);
329 h = (TH1F*) fOutputHist->FindObject(GetDeltaPhiHistoNameAccepted(trigger_name));
335 const char * AliBackgroundSelection::GetClusterVsTrackletsHistoName(const char * trigger_name){
337 // build up the name of the cluster vs tracklets histo using the trigger class
341 str = str+GetName()+"_"+trigger_name;
345 const char * AliBackgroundSelection::GetClusterVsTrackletsHistoNameAccepted(const char * trigger_name){
347 // build up the name of the cluster vs tracklets histo using the trigger class (accepted events)
350 str = str+GetName()+"_"+trigger_name + "_accepted";
354 const char * AliBackgroundSelection::GetDeltaPhiHistoName(const char * trigger_name){
356 // build up the name of the delta phi histo using the trigger class
361 str = str+GetName()+"_"+trigger_name;
365 const char * AliBackgroundSelection::GetDeltaPhiHistoNameAccepted(const char * trigger_name){
367 // build up the name of the delta phi histo using the trigger class (accepted events)
371 str = str+GetName()+"_"+trigger_name + "_accepted";
375 Long64_t AliBackgroundSelection::Merge(TCollection* const list)
377 // Merge a list of AliBackgroundSelection objects with this (needed for
379 // Returns the number of merged objects (including this).
381 // We have to make sure that all the list contain the same histos in
382 // the same order. We thus also have to sort the list (sorting is
383 // done by name in TList).
385 //AliInfo("Merging");
393 TIterator* iter = list->MakeIterator();
396 // collections of all histograms
397 const Int_t nHists = 1;
398 TList collections[nHists];
404 while ((obj = iter->Next())) {
405 Bool_t foundDiffinThisIterStep = kFALSE;
406 // Printf("%d - %s",count, obj->GetName());
407 AliBackgroundSelection* entry = dynamic_cast<AliBackgroundSelection*> (obj);
411 TList * hlist = entry->fOutputHist;
413 // Check if all histos in this fOutputHist are also in the one from entry and viceversa
414 // Use getters to automatically book non defined histos
416 Bool_t areListsDifferent=kTRUE;
418 Int_t maxLoops = hlist->GetSize() + fOutputHist->GetSize(); // In the worst case all of the histos will be different...
419 while(areListsDifferent) {
420 if(iloop>maxLoops) AliFatal("Infinite Loop?");
425 // loop over the largest
427 // loop over the largest
429 TIterator * iterlist = 0;
430 TList * thislist = 0; // the list over which I'm iterating (i.e. the largest)
431 TList * otherlist = 0; // the other list
433 if (hlist->GetSize() >= fOutputHist->GetSize()) {
435 otherlist = fOutputHist;
438 thislist = fOutputHist;
441 iterlist = thislist->MakeIterator();
443 while ((hist= iterlist->Next())){
444 if(!otherlist->FindObject(hist->GetName())){
445 //AliInfo(Form("Adding object %s",hist->GetName()));
446 foundDiffinThisIterStep = kTRUE;
447 TH1 * hclone = (TH1*) hist->Clone();
449 otherlist->Add(hclone);
454 // re-sort before checking
458 // check if everything is fine
459 areListsDifferent=kFALSE;
460 if (hlist->GetSize() == fOutputHist->GetSize()) {
461 Int_t nhist = fOutputHist->GetSize();
462 for(Int_t ihist = 0; ihist < nhist; ihist++){
463 if(strcmp(fOutputHist->At(ihist)->GetName(),hlist->At(ihist)->GetName())) areListsDifferent = kTRUE;
466 areListsDifferent=kTRUE;
470 // last check: if something is not ok die loudly
471 if (hlist->GetSize() != fOutputHist->GetSize()) {
472 AliFatal("Mismatching size!");
474 Int_t nhist = fOutputHist->GetSize();
475 for(Int_t ihist = 0; ihist < nhist; ihist++){
476 if(strcmp(fOutputHist->At(ihist)->GetName(),hlist->At(ihist)->GetName())){
477 AliFatal(Form("Mismatching histos: %s -> %s", fOutputHist->At(ihist)->GetName(),hlist->At(ihist)->GetName()));
481 if (foundDiffinThisIterStep){
482 iter->Reset(); // We found a difference: previous lists could
483 // also be affected... We start from scratch
485 collections[n++].Clear();
491 // AliInfo("fOutputHist");
492 // fOutputHist->Print();
495 collections[n++].Add(hlist);
502 fOutputHist->Merge(&collections[n++]);