]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGDQ/dielectron/AliDielectronMixingHandler.cxx
Clean AODEvent before adding to UserInfo
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliDielectronMixingHandler.cxx
CommitLineData
5720c765 1/*************************************************************************
2* Copyright(c) 1998-2009, 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
16///////////////////////////////////////////////////////////////////////////
17// Dielectron MixingHandler //
18// //
19// //
20/*
21Detailed description
22
23
24*/
25// //
26///////////////////////////////////////////////////////////////////////////
27
28#include <TVectorD.h>
29#include <TH1.h>
30#include <TAxis.h>
31
32#include <AliLog.h>
33#include <AliVTrack.h>
34
35#include "AliDielectron.h"
36#include "AliDielectronHelper.h"
37#include "AliDielectronHistos.h"
38#include "AliDielectronEvent.h"
39
40#include "AliDielectronMixingHandler.h"
41
42ClassImp(AliDielectronMixingHandler)
43
44AliDielectronMixingHandler::AliDielectronMixingHandler() :
45 TNamed(),
46 fDepth(10),
47 fArrPools("TClonesArray"),
48 fAxes(kMaxCuts),
49 fMixType(kOSonly),
50 fMixIncomplete(kTRUE),
4fae8ef9 51 fMoveToSameVertex(kFALSE),
07d7dd21 52 fSkipFirstEvt(kFALSE),
4fae8ef9 53 fPID(0x0)
5720c765 54{
55 //
56 // Default Constructor
57 //
58 for (Int_t i=0; i<kMaxCuts; ++i){
59 fEventCuts[i]=0;
60 }
61 fAxes.SetOwner(kTRUE);
62}
63
64//______________________________________________
65AliDielectronMixingHandler::AliDielectronMixingHandler(const char* name, const char* title) :
66 TNamed(name, title),
67 fDepth(10),
68 fArrPools("TClonesArray"),
69 fAxes(kMaxCuts),
70 fMixType(kOSonly),
71 fMixIncomplete(kTRUE),
4fae8ef9 72 fMoveToSameVertex(kFALSE),
07d7dd21 73 fSkipFirstEvt(kFALSE),
4fae8ef9 74 fPID(0x0)
5720c765 75{
76 //
77 // Named Constructor
78 //
79 for (Int_t i=0; i<kMaxCuts; ++i){
80 fEventCuts[i]=0;
81 }
82 fAxes.SetOwner(kTRUE);
83}
84
85//______________________________________________
86AliDielectronMixingHandler::~AliDielectronMixingHandler()
87{
88 //
89 // Default Destructor
90 //
91 fAxes.Delete();
4fae8ef9 92 delete fPID;
5720c765 93}
94
95//________________________________________________________________
96void AliDielectronMixingHandler::AddVariable(AliDielectronVarManager::ValueTypes type,
97 Int_t nbins, Double_t min, Double_t max, Bool_t log)
98{
99 //
100 // Add a variable to the mixing handler
101 //
102
103 // limit number of variables to kMaxCuts
104 if (fAxes.GetEntriesFast()>=kMaxCuts) return;
105
106 TVectorD *binLimits=0x0;
107 if (!log) binLimits=AliDielectronHelper::MakeLinBinning(nbins,min,max);
108 else binLimits=AliDielectronHelper::MakeLogBinning(nbins,min,max);
109 if (!binLimits) return;
110
111 Int_t size=fAxes.GetEntriesFast();
112 fEventCuts[size]=(UShort_t)type;
113 fAxes.Add(binLimits);
114}
115
116//________________________________________________________________
117void AliDielectronMixingHandler::AddVariable(AliDielectronVarManager::ValueTypes type,
118 const char* binLimitStr)
119{
120 //
121 // Add a variable to the mixing handler with arbitrary binning
122 //
123
124 // limit number of variables to kMaxCuts
125 if (fAxes.GetEntriesFast()>=kMaxCuts) return;
126
127 TVectorD *binLimits=AliDielectronHelper::MakeArbitraryBinning(binLimitStr);
128 if (!binLimits) return;
129
130 Int_t size=fAxes.GetEntriesFast();
131 fEventCuts[size]=(UShort_t)type;
132 fAxes.Add(binLimits);
133}
134
135//______________________________________________
136void AliDielectronMixingHandler::Fill(const AliVEvent *ev, AliDielectron *diele)
137{
138 //
139 // fill event buffers and perform mixing if the pool depth is reached
140 //
141
142 //check if there are tracks available
143 if (diele->GetTrackArray(0)->GetEntriesFast()==0 && diele->GetTrackArray(1)->GetEntriesFast()==0) return;
67fd1119 144
5720c765 145 TString dim;
40c0574a 146 Int_t bin=FindBin(AliDielectronVarManager::GetData(),&dim);
5720c765 147
d327d9cd 148 //add mixing bin to event data
40c0574a 149 AliDielectronVarManager::SetValue(AliDielectronVarManager::kMixingBin,bin);
d327d9cd 150
5720c765 151 if (bin<0){
152 AliDebug(5,Form("Bin outside range: %s",dim.Data()));
153 return;
154 }
155
156 // get mixing pool, create it if it does not yet exist.
157 TClonesArray *poolp=static_cast<TClonesArray*>(fArrPools.At(bin));
158 if (!poolp){
159 AliDebug(10,Form("New pool at %d (%s)\n",bin,dim.Data()));
160 poolp=new(fArrPools[bin]) TClonesArray("AliDielectronEvent",fDepth);
161 }
162 TClonesArray &pool=*poolp;
163
164 AliDebug(10,Form("new event at %d: %d",bin,pool.GetEntriesFast()));
165 AliDielectronEvent *event=new(pool[pool.GetEntriesFast()]) AliDielectronEvent();
67fd1119 166 if(ev->IsA() == AliAODEvent::Class()) event->SetAOD();
88e9bae6 167 else event->SetESD();
168
4fae8ef9 169 event->SetProcessID(fPID);
5720c765 170 event->SetTracks(*diele->GetTrackArray(0), *diele->GetTrackArray(1), *diele->GetPairArray(1));
40c0574a 171 event->SetEventData(AliDielectronVarManager::GetData());
67fd1119 172
5720c765 173 // check if pool depth is reached.
174 if (pool.GetEntriesFast()<fDepth) return;
175
176 // pool depth reached, do mixing
177 DoMixing(pool,diele);
178
179 // increase counter for full bins
180 if (diele->fHistos) {
181 diele->fHistos->Fill("Mixing","Stats",0);
182 diele->fHistos->Fill("Mixing","CompletePools",bin);
183 }
184
185 //clear the current pool
186 pool.Clear("C");
187}
188
189//______________________________________________
190void AliDielectronMixingHandler::DoMixing(TClonesArray &pool, AliDielectron *diele)
191{
192 //
193 // perform the mixing
194 //
67fd1119 195
5720c765 196 //buffer track arrays and copy them back afterwards
197 TObjArray arrTrDummy[4];
198 for (Int_t i=0; i<4; ++i) arrTrDummy[i]=diele->fTracks[i];
199
200 //buffer also global event data
201 Double_t values[AliDielectronVarManager::kNMaxValues]={0};
202 for (Int_t i=AliDielectronVarManager::kPairMax; i<AliDielectronVarManager::kNMaxValues; ++i)
203 values[i]=AliDielectronVarManager::GetValue((AliDielectronVarManager::ValueTypes)i);
204
07d7dd21 205
206 // use event data from the first event
207 // all events are in the same mixing bin anyhow...
208 // optionally use only the event data from the first event and no tracks of it,
209 // by this you should get ride of event plane - leg correlations in the mixing
210 // but you loose the 1st event in the mixing statistics
211 AliDielectronEvent *ev0=static_cast<AliDielectronEvent*>(pool.At(0));
212 AliDielectronVarManager::SetEventData(ev0->GetEventData());
213 Int_t firstEvt=(fSkipFirstEvt ? 1 : 0);
214
215 for (Int_t i1=firstEvt; i1<pool.GetEntriesFast(); ++i1){
5720c765 216 AliDielectronEvent *ev1=static_cast<AliDielectronEvent*>(pool.At(i1));
217 //use event data from the first event
218 //both events are in the same mixing bin anyhow...
07d7dd21 219 if( !fSkipFirstEvt ) AliDielectronVarManager::SetEventData(ev1->GetEventData());
5720c765 220
221 TObject *o=0x0;
222 TIter ev1P(ev1->GetTrackArrayP());
223 TIter ev1N(ev1->GetTrackArrayN());
224
225 for (Int_t i2=i1+1; i2<pool.GetEntriesFast(); ++i2){
226 //clear arryas
227 diele->fTracks[0].Clear();
228 diele->fTracks[1].Clear();
229 diele->fTracks[2].Clear();
230 diele->fTracks[3].Clear();
231
232 //setup track arrays
233 AliDielectronEvent *ev2=static_cast<AliDielectronEvent*>(pool.At(i2));
5720c765 234 ev1P.Reset();
235 ev1N.Reset();
236 TIter ev2P(ev2->GetTrackArrayP());
237 TIter ev2N(ev2->GetTrackArrayN());
238
239 //
240 //move tracks to the same vertex (vertex of the first event), if requested
241 //
242 if (fMoveToSameVertex){
243 const Double_t *varsFirst=ev1->GetEventData();
244 const Double_t *varsMix=ev2->GetEventData();
245
246 const Double_t vFirst[3]={varsFirst[AliDielectronVarManager::kXvPrim],
247 varsFirst[AliDielectronVarManager::kYvPrim],
248 varsFirst[AliDielectronVarManager::kZvPrim]};
249
250 const Double_t vMix[3] ={varsMix[AliDielectronVarManager::kXvPrim],
251 varsMix[AliDielectronVarManager::kYvPrim],
252 varsMix[AliDielectronVarManager::kZvPrim]};
253
254 //loop over all tracks from the second event and move them to the vertex of the first
255 AliVTrack *vtrack=0x0;
256 while ( ( vtrack=(AliVTrack*)ev2P() ) ){
257 MoveToSameVertex(vtrack, vFirst, vMix);
258 }
259
260
261 while ( ( vtrack=(AliVTrack*)ev2N() ) ){
262 MoveToSameVertex(vtrack, vFirst, vMix);
263 }
264
265
266 ev2P.Reset();
267 ev2N.Reset();
268 }
67fd1119 269
5720c765 270 //mixing of ev1- ev2+ (pair type4). This is common for all mixing types
67fd1119 271 while ( (o=ev1N()) ) diele->fTracks[1].Add(o);
5720c765 272 while ( (o=ev2P()) ) diele->fTracks[2].Add(o);
273 diele->FillPairArrays(1,2);
274
275 if (fMixType==kAll || fMixType==kOSandLS){
276 // all 4 pair arrays will be filled
277 while ( (o=ev1P()) ) diele->fTracks[0].Add(o);
278 while ( (o=ev2N()) ) diele->fTracks[3].Add(o);
279 diele->FillPairArrays(0,2);
280 diele->FillPairArrays(1,3);
281 if (fMixType==kAll) diele->FillPairArrays(0,3);
282 }
283
284 if (fMixType==kOSonly || fMixType==kOSandLS){
285 //use the pair type of ev1- ev1+ also for ev1+ ev1-
286 diele->fTracks[1].Clear();
287 diele->fTracks[2].Clear();
288 while ( (o=ev1P()) ) diele->fTracks[1].Add(o);
289 while ( (o=ev2N()) ) diele->fTracks[2].Add(o);
290 diele->FillPairArrays(1,2);
291 }
67fd1119 292
5720c765 293 }
294 }
295
296 //copy back the tracks
297 for (Int_t i=0; i<4; ++i) {
298 diele->fTracks[i].Clear();
299 diele->fTracks[i]=arrTrDummy[i];
300 }
301
302 //set back global event values
303 AliDielectronVarManager::SetEventData(values);
304}
305
306//______________________________________________
307void AliDielectronMixingHandler::MixRemaining(AliDielectron *diele)
308{
309 //
310 // mix all pools even if they are incomplete
311 //
312
313 //Check if there was any processed data and it is requested to mix incomplete bins
ac390e40 314 if (!diele || !diele->PairArray(0) || !fMixIncomplete ) return;
5720c765 315
67fd1119 316 AliDielectronVarManager::SetEvent(0x0);
5720c765 317 for (Int_t ipool=0; ipool<fArrPools.GetSize(); ++ipool){
318 TClonesArray *poolp=static_cast<TClonesArray*>(fArrPools.At(ipool));
d327d9cd 319 if (!poolp || !poolp->GetEntriesFast() || !poolp->At(0)) continue;
5720c765 320 //clear the arrays before the final processing"
321 AliDebug(10,Form("Incomplete: Bin %d (%d)\n",ipool,poolp->GetEntriesFast()));
322 diele->ClearArrays();
323 DoMixing(*poolp,diele);
324
5720c765 325 // increase counter for incomplete bins
326 if (diele->fHistos) {
d327d9cd 327 //buffer event data and set event data using the first event in this pool
328 Double_t values[AliDielectronVarManager::kNMaxValues]={0};
329 for (Int_t i=AliDielectronVarManager::kPairMax; i<AliDielectronVarManager::kNMaxValues; ++i)
330 values[i]=AliDielectronVarManager::GetValue((AliDielectronVarManager::ValueTypes)i);
331
332 AliDielectronEvent *ev1=static_cast<AliDielectronEvent*>(poolp->At(0));
333 //use event data from the first event all events are in the same mixing bin anyhow...
334 AliDielectronVarManager::SetEventData(ev1->GetEventData());
335
336 // fill the histograms
ac390e40 337 diele->FillHistograms(0x0, kTRUE);
5720c765 338 diele->fHistos->Fill("Mixing","Stats",1);
339 diele->fHistos->Fill("Mixing","InCompletePools",ipool);
340 diele->fHistos->Fill("Mixing","Entries_InCompletePools",poolp->GetEntriesFast());
d327d9cd 341
342 //set back global event values
343 AliDielectronVarManager::SetEventData(values);
5720c765 344 }
345
346 }
347}
348
349
350//______________________________________________
351void AliDielectronMixingHandler::Init(const AliDielectron *diele)
352{
353 //
354 // initialise event buffers
355 //
356
d327d9cd 357 Int_t size=GetNumberOfBins();
5720c765 358
359 AliDebug(10,Form("Creating a pool array with size %d \n",size));
360
361 fArrPools.Expand(size);
362
363 //add statics histogram if we have a histogram manager
364 if (diele && diele->fHistos) {
365 diele->fHistos->AddClass("Mixing");
366 diele->fHistos->UserHistogram("Mixing","Stats","Mixing Statistics;;#called bins",2,0,2);
367 TH1* h=diele->fHistos->GetHistogram("Mixing","Stats");
368 h->GetXaxis()->SetBinLabel(1,"Complete");
369 h->GetXaxis()->SetBinLabel(2,"Incomplete");
370
371 diele->fHistos->UserHistogram("Mixing","CompletePools","Mixing Statistics compete pools;bin;#fills",size,0,size);
372 diele->fHistos->UserHistogram("Mixing","InCompletePools","Mixing Statistics incomplete pools;bin;#fills",size,0,size);
373 diele->fHistos->UserHistogram("Mixing","Entries_InCompletePools","#entries in incomplete pools;entries;#fills",fDepth,0,fDepth);
374 }
375
376 TString values;
377 for (Int_t i=0; i<fAxes.GetEntriesFast(); ++i){
378 TVectorD *bins=static_cast<TVectorD*>(fAxes.At(i));
379 Int_t nRows=bins->GetNrows();
380 values+=Form("%s: ",AliDielectronVarManager::GetValueName(fEventCuts[i]));
381 for (Int_t irow=0; irow<nRows; ++irow){
382 values+=Form("%.2f, ",(*bins)[irow]);
383 }
384 }
4fae8ef9 385
386 if (!fPID){
387 fPID=TProcessID::AddProcessID();
388 }
5720c765 389
390 AliDebug(10,values.Data());
391}
392
393//______________________________________________
d327d9cd 394Int_t AliDielectronMixingHandler::GetNumberOfBins() const
395{
396 //
397 // return the number of bins this mixing handler has
398 //
399 Int_t size=1;
400 for (Int_t i=0; i<fAxes.GetEntriesFast(); ++i)
401 size*=((static_cast<TVectorD*>(fAxes.At(i)))->GetNrows()-1);
402 return size;
403}
404
405//______________________________________________
5720c765 406Int_t AliDielectronMixingHandler::FindBin(const Double_t values[], TString *dim)
407{
408 //
409 // bin bin in mixing stack described by 'values'
410 // if the values are outside the binning range -1 is returned
411 // if dim is non NULL debug info will be stored in the variable
412 //
413
414 if (fAxes.GetEntriesFast()==0) {
415 if (dim) (*dim)="single bin";
416 return 0;
417 }
418 if (dim) (*dim)="";
419 Int_t sizeAdd=1;
420 Int_t bin=0;
421 for (Int_t i=0; i<fAxes.GetEntriesFast(); ++i){
422 Double_t val=values[fEventCuts[i]];
423 TVectorD *bins=static_cast<TVectorD*>(fAxes.At(i));
424 Int_t nRows=bins->GetNrows();
425 if ( (val<(*bins)[0]) || (val>(*bins)[nRows-1]) ) {
426 return -1;
427 }
428
429 Int_t pos=TMath::BinarySearch(nRows,bins->GetMatrixArray(),val);
430 bin+=sizeAdd*pos;
a823f01b 431 if (dim) (*dim)+=Form("%s: %f (%d); ",AliDielectronVarManager::GetValueName(fEventCuts[i]),val,pos);
432 sizeAdd*=(nRows-1);
5720c765 433 }
434
435 return bin;
436}
437
438//______________________________________________
439void AliDielectronMixingHandler::MoveToSameVertex(AliVTrack * const vtrack, const Double_t *vFirst, const Double_t* vMix)
440{
441 //
442 // move 'track' which belongs to the vertex information of vMix to the vertex of vFirst
443 //
444
445 static Bool_t printed=kFALSE;
446
447 if (vtrack->IsA()==AliESDtrack::Class()){
448 AliESDtrack *track=(AliESDtrack*)vtrack;
449
450 //get track information
451 Double_t x = track->GetX();
452 Double_t alpha = track->GetAlpha();
453 Double_t param[5] = {0};
454 Double_t cov[15] = {0};
455
456 for (Int_t i=0; i<5; ++i) param[i]=track->GetParameter()[i];
457 for (Int_t i=0; i<15; ++i) cov[i] =track->GetCovariance()[i];
458
459 //translation
460 Double_t vt[3] = {vMix[0]-vFirst[0],vMix[1]-vFirst[1],vMix[2]-vFirst[2]};
461 //rotate to the track frame
236e1bda 462// track->Global2LocalPosition(vt,track->GetAlpha());
5720c765 463
464 //add to track position
236e1bda 465// x = x -vt[0];
466// param[0] = param[0]-vt[1];
467// param[1] = param[1]-vt[2];
5720c765 468 param[1] = param[1]-vt[2];
469
470 //set updated track information
471 track->Set(x, alpha, param, cov);
472 } else {
473 // AliAODTrack *track=(AliAODTrack*)vtrack;
474 // Double_t pos[3]={0};
475 // track->GetPosition(pos);
476 // if (pos[0]>-999.){
477 // pos[0]=pos[0]-vMix[AliDielectronVarManager::kXvPrim]+vFirst[AliDielectronVarManager::kXvPrim];
478 // pos[1]=pos[1]-vMix[AliDielectronVarManager::kYvPrim]+vFirst[AliDielectronVarManager::kYvPrim];
479 // pos[2]=pos[2]-vMix[AliDielectronVarManager::kZvPrim]+vFirst[AliDielectronVarManager::kZvPrim];
480 // track->SetPosition(pos);
481// AliError("Move To same vertex not yet implemented for AOD!");
482 if (!printed) {
483// Error("AliDielectronMixingHandler::MoveToSameVertex","Move To same vertex not yet implemented for AOD!");
484 printed=kTRUE;
485 }
486 //
487 // Not that clear how to do it. In AOD track there is fPosition, fPositionAtDCA and "TRef fProdVertex"
488 // where Xv(), Yv(), Zv() returns the position of fProdVertex
489 //
490 }
491
492}