]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HBTAN/AliHBTAnalysis.cxx
Paramterisation of CDF J/Psi data used. (G. Martinez)
[u/mrichter/AliRoot.git] / HBTAN / AliHBTAnalysis.cxx
CommitLineData
0aca58be 1#include "AliHBTAnalysis.h"
bfb09ece 2//_________________________________________________________
3////////////////////////////////////////////////////////////////////////////
4//
5// class AliHBTAnalysis
6//
7// Central Object Of HBTAnalyser:
8// This class performs main looping within HBT Analysis
78d7c6d3 9// User must plug a reader of Type AliReader
bfb09ece 10// User plugs in coorelation and monitor functions
11// as well as monitor functions
12//
13// HBT Analysis Tool, which is integral part of AliRoot,
14// ALICE Off-Line framework:
15//
16// Piotr.Skowronski@cern.ch
17// more info: http://alisoft.cern.ch/people/skowron/analyzer/index.html
18//
19////////////////////////////////////////////////////////////////////////////
20//_________________________________________________________
21
78d7c6d3 22
8fba7c63 23#include <TSystem.h>
24#include <TFile.h>
25
78d7c6d3 26#include "AliAOD.h"
27#include "AliAODParticle.h"
28#include "AliAODPairCut.h"
7b6503d6 29#include "AliEventCut.h"
78d7c6d3 30
31#include "AliEventBuffer.h"
32
33#include "AliReader.h"
1b446896 34#include "AliHBTPair.h"
1b446896 35#include "AliHBTFunction.h"
5c58441a 36#include "AliHBTMonitorFunction.h"
81b7b887 37
e4f2b1da 38
1b446896 39ClassImp(AliHBTAnalysis)
40
41const UInt_t AliHBTAnalysis::fgkFctnArraySize = 100;
81b7b887 42const UInt_t AliHBTAnalysis::fgkDefaultMixingInfo = 1000;
43const Int_t AliHBTAnalysis::fgkDefaultBufferSize = 5;
44
45AliHBTAnalysis::AliHBTAnalysis():
090e46d6 46 fProcEvent(0x0),
2dc7203b 47 fReader(0x0),
48 fNTrackFunctions(0),
49 fNParticleFunctions(0),
50 fNParticleAndTrackFunctions(0),
51 fNTrackMonitorFunctions(0),
52 fNParticleMonitorFunctions(0),
53 fNParticleAndTrackMonitorFunctions(0),
9616170a 54 fTrackFunctions ( new AliHBTOnePairFctn* [fgkFctnArraySize]),
55 fParticleFunctions ( new AliHBTOnePairFctn* [fgkFctnArraySize]),
56 fParticleAndTrackFunctions ( new AliHBTTwoPairFctn* [fgkFctnArraySize]),
57 fParticleMonitorFunctions ( new AliHBTMonOneParticleFctn* [fgkFctnArraySize]),
58 fTrackMonitorFunctions ( new AliHBTMonOneParticleFctn* [fgkFctnArraySize]),
59 fParticleAndTrackMonitorFunctions ( new AliHBTMonTwoParticleFctn* [fgkFctnArraySize]),
7b6503d6 60 fBkgEventCut(0x0),
5994509d 61 fPartBuffer(0x0),
62 fTrackBuffer(0x0),
2dc7203b 63 fBufferSize(2),
64 fDisplayMixingInfo(fgkDefaultMixingInfo),
66d1d1a4 65 fIsOwner(kFALSE),
090e46d6 66 fProcessOption(kSimulatedAndReconstructed),
e92ecbdf 67 fNoCorrfctns(kFALSE),
5994509d 68 fOutputFileName(0x0),
69 fVertexX(0.0),
70 fVertexY(0.0),
71 fVertexZ(0.0)
1b446896 72 {
9616170a 73 //default constructor
66d1d1a4 74
1b446896 75 }
491d1b5d 76/*************************************************************************************/
1b446896 77
81b7b887 78AliHBTAnalysis::AliHBTAnalysis(const AliHBTAnalysis& in):
78d7c6d3 79 AliAnalysis(in),
090e46d6 80 fProcEvent(0x0),
2dc7203b 81 fReader(0x0),
82 fNTrackFunctions(0),
83 fNParticleFunctions(0),
84 fNParticleAndTrackFunctions(0),
85 fNTrackMonitorFunctions(0),
86 fNParticleMonitorFunctions(0),
87 fNParticleAndTrackMonitorFunctions(0),
88 fTrackFunctions(0x0),
89 fParticleFunctions(0x0),
90 fParticleAndTrackFunctions(0x0),
91 fParticleMonitorFunctions(0x0),
92 fTrackMonitorFunctions(0x0),
93 fParticleAndTrackMonitorFunctions(0x0),
7b6503d6 94 fBkgEventCut(0x0),
5994509d 95 fPartBuffer(0x0),
96 fTrackBuffer(0x0),
2dc7203b 97 fBufferSize(fgkDefaultBufferSize),
98 fDisplayMixingInfo(fgkDefaultMixingInfo),
66d1d1a4 99 fIsOwner(kFALSE),
090e46d6 100 fProcessOption(kSimulatedAndReconstructed),
e92ecbdf 101 fNoCorrfctns(kFALSE),
5994509d 102 fOutputFileName(0x0),
103 fVertexX(0.0),
104 fVertexY(0.0),
105 fVertexZ(0.0)
81b7b887 106 {
2dc7203b 107//copy constructor
81b7b887 108 Fatal("AliHBTAnalysis(const AliHBTAnalysis&)","Sensless");
109 }
110/*************************************************************************************/
34914285 111AliHBTAnalysis& AliHBTAnalysis::operator=(const AliHBTAnalysis& /*right*/)
81b7b887 112 {
2dc7203b 113//operator =
81b7b887 114 Fatal("AliHBTAnalysis(const AliHBTAnalysis&)","Sensless");
115 return *this;
116 }
117/*************************************************************************************/
1b446896 118AliHBTAnalysis::~AliHBTAnalysis()
119 {
120 //destructor
121 //note that we do not delete functions itself
122 // they should be deleted by whom where created
123 //we only store pointers, and we use "new" only for pointers array
e7a04795 124
125 if (fIsOwner)
126 {
78d7c6d3 127 if (AliVAODParticle::GetDebug()>5)Info("~AliHBTAnalysis","Is Owner: Attempting to delete functions");
e7a04795 128 DeleteFunctions();
78d7c6d3 129 if (AliVAODParticle::GetDebug()>5)Info("~AliHBTAnalysis","Delete functions done");
e7a04795 130 }
1b446896 131 delete [] fTrackFunctions;
132 delete [] fParticleFunctions;
133 delete [] fParticleAndTrackFunctions;
134
5c58441a 135 delete [] fParticleMonitorFunctions;
136 delete [] fTrackMonitorFunctions;
090e46d6 137 delete [] fParticleAndTrackMonitorFunctions;
5c58441a 138
7b6503d6 139 delete fBkgEventCut;
8fba7c63 140 delete fOutputFileName;
1b446896 141 }
142
143/*************************************************************************************/
7b6503d6 144
78d7c6d3 145Int_t AliHBTAnalysis::ProcessEvent(AliAOD* aodrec, AliAOD* aodsim)
146{
147 //Processes one event
090e46d6 148 if (fProcEvent == 0x0)
78d7c6d3 149 {
a2b9dcc7 150 Error("ProcessEvent","Analysis <<%s>> option not specified.",GetName());
78d7c6d3 151 return 1;
152 }
a74ad849 153 if ( Rejected(aodrec,aodsim) )
154 {
155// Double_t x = 0, y = 0, z = 0;
156// aodrec->GetPrimaryVertex(x,y,z);
157// Info("ProcessEvent","Event has vertex at %f %f %f",x,y,z);
158 Info("ProcessEvent","Nch is %d",aodsim->GetNumberOfCharged());
159 Info("ProcessEvent","%s: Event cut rejected this event",GetName());
160 return 0;
161 }
163cad1f 162
5994509d 163 //Move event to the apparent vertex -> must be after the event cut
164 //It is important for any cut that use any spacial coordiantes,
165 //f.g. anti-merging cut in order to preserve the same bahavior of variables (f.g. distance between tracks)
166 Double_t dvx = 0, dvy = 0, dvz = 0;
167 if (aodrec)
168 {
169 Double_t pvx,pvy,pvz;
170 aodrec->GetPrimaryVertex(pvx,pvy,pvz);
171
172 dvx = fVertexX - pvx;
173 dvy = fVertexY - pvy;
174 dvz = fVertexZ - pvz;
175 aodrec->Move(dvx,dvy,dvz);
176 }
177
178 Int_t result = (this->*fProcEvent)(aodrec,aodsim);
179
180 if (aodrec) aodrec->Move(-dvx,-dvy,-dvz);//move event back to the same spacial coordinates
181
182 return result;
78d7c6d3 183}
184/*************************************************************************************/
185
186Int_t AliHBTAnalysis::Finish()
187{
090e46d6 188//Finishes analysis
78d7c6d3 189 WriteFunctions();
e92ecbdf 190 return 0;
78d7c6d3 191}
192/*************************************************************************************/
e4f2b1da 193
81b7b887 194void AliHBTAnalysis::DeleteFunctions()
195{
e4f2b1da 196 //Deletes all functions added to analysis
5994509d 197
81b7b887 198 UInt_t ii;
199 for(ii = 0;ii<fNParticleFunctions;ii++)
e7a04795 200 {
78d7c6d3 201 if (AliVAODParticle::GetDebug()>5)
90520373 202 {
203 Info("DeleteFunctions","Deleting ParticleFunction %#x",fParticleFunctions[ii]);
204 Info("DeleteFunctions","Deleting ParticleFunction %s",fParticleFunctions[ii]->Name());
205 }
e7a04795 206 delete fParticleFunctions[ii];
207 }
e4f2b1da 208 fNParticleFunctions = 0;
81b7b887 209
210 for(ii = 0;ii<fNTrackFunctions;ii++)
e7a04795 211 {
78d7c6d3 212 if (AliVAODParticle::GetDebug()>5)
e7a04795 213 {
90520373 214 Info("DeleteFunctions","Deleting TrackFunction %#x",fTrackFunctions[ii]);
215 Info("DeleteFunctions","Deleting TrackFunction %s",fTrackFunctions[ii]->Name());
e7a04795 216 }
217 delete fTrackFunctions[ii];
218 }
e4f2b1da 219 fNTrackFunctions = 0;
220
81b7b887 221 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
e7a04795 222 {
78d7c6d3 223 if (AliVAODParticle::GetDebug()>5)
90520373 224 {
225 Info("DeleteFunctions","Deleting ParticleAndTrackFunction %#x",fParticleAndTrackFunctions[ii]);
226 Info("DeleteFunctions","Deleting ParticleAndTrackFunction %s",fParticleAndTrackFunctions[ii]->Name());
227 }
e7a04795 228 delete fParticleAndTrackFunctions[ii];
229 }
e4f2b1da 230 fNParticleAndTrackFunctions = 0;
81b7b887 231
232 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
e7a04795 233 {
78d7c6d3 234 if (AliVAODParticle::GetDebug()>5)
90520373 235 {
236 Info("DeleteFunctions","Deleting ParticleMonitorFunction %#x",fParticleMonitorFunctions[ii]);
237 Info("DeleteFunctions","Deleting ParticleMonitorFunction %s",fParticleMonitorFunctions[ii]->Name());
238 }
e7a04795 239 delete fParticleMonitorFunctions[ii];
240 }
e4f2b1da 241 fNParticleMonitorFunctions = 0;
81b7b887 242
243 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
e7a04795 244 {
78d7c6d3 245 if (AliVAODParticle::GetDebug()>5)
90520373 246 {
247 Info("DeleteFunctions","Deleting TrackMonitorFunction %#x",fTrackMonitorFunctions[ii]);
248 Info("DeleteFunctions","Deleting TrackMonitorFunction %s",fTrackMonitorFunctions[ii]->Name());
249 }
e7a04795 250 delete fTrackMonitorFunctions[ii];
251 }
e4f2b1da 252 fNTrackMonitorFunctions = 0;
81b7b887 253
254 for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
e7a04795 255 {
78d7c6d3 256 if (AliVAODParticle::GetDebug()>5)
90520373 257 {
258 Info("DeleteFunctions","Deleting ParticleAndTrackMonitorFunction %#x",fParticleAndTrackMonitorFunctions[ii]);
259 Info("DeleteFunctions","Deleting ParticleAndTrackMonitorFunction %s",fParticleAndTrackMonitorFunctions[ii]->Name());
260 }
e7a04795 261 delete fParticleAndTrackMonitorFunctions[ii];
262 }
e4f2b1da 263 fNParticleAndTrackMonitorFunctions = 0;
bfb09ece 264
81b7b887 265}
e4f2b1da 266/*************************************************************************************/
267
78d7c6d3 268Int_t AliHBTAnalysis::Init()
e4f2b1da 269{
2dc7203b 270//Initializeation method
271//calls Init for all functions
090e46d6 272
273 //Depending on option and pair cut assigns proper analysis method
274 Bool_t nonid = IsNonIdentAnalysis();
275 switch(fProcessOption)
276 {
277 case kReconstructed:
278 if (nonid) fProcEvent = &AliHBTAnalysis::ProcessRecNonId;
279 else fProcEvent = &AliHBTAnalysis::ProcessRec;
a2b9dcc7 280 SetCutsOnRec();
090e46d6 281 break;
282
283 case kSimulated:
284 if (nonid) fProcEvent = &AliHBTAnalysis::ProcessSimNonId;
285 else fProcEvent = &AliHBTAnalysis::ProcessSim;
a2b9dcc7 286 SetCutsOnSim();
090e46d6 287 break;
288
289 case kSimulatedAndReconstructed:
290 if (nonid) fProcEvent = &AliHBTAnalysis::ProcessRecAndSimNonId;
291 else fProcEvent = &AliHBTAnalysis::ProcessRecAndSim;
292 break;
293 }
e92ecbdf 294
295 if (fPartBuffer == 0x0) fPartBuffer = new AliEventBuffer (fBufferSize);
296 else fPartBuffer->Reset();
297
298 if (fTrackBuffer == 0x0) fTrackBuffer = new AliEventBuffer (fBufferSize);
299 else fTrackBuffer->Reset();
300
301
302 fNoCorrfctns = (fNParticleFunctions == 0) && (fNTrackFunctions == 0) && (fNParticleAndTrackFunctions == 0);
303
e4f2b1da 304 UInt_t ii;
305 for(ii = 0;ii<fNParticleFunctions;ii++)
306 fParticleFunctions[ii]->Init();
307
308 for(ii = 0;ii<fNTrackFunctions;ii++)
309 fTrackFunctions[ii]->Init();
310
311 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
312 fParticleAndTrackFunctions[ii]->Init();
313
314 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
315 fParticleMonitorFunctions[ii]->Init();
316
317 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
318 fTrackMonitorFunctions[ii]->Init();
319
320 for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
321 fParticleAndTrackMonitorFunctions[ii]->Init();
bfb09ece 322
78d7c6d3 323 return 0;
e4f2b1da 324}
325/*************************************************************************************/
326
327void AliHBTAnalysis::ResetFunctions()
328{
329//In case fOwner is true, deletes all functions
330//in other case, just set number of analysis to 0
331 if (fIsOwner) DeleteFunctions();
332 else
333 {
334 fNParticleFunctions = 0;
335 fNTrackFunctions = 0;
336 fNParticleAndTrackFunctions = 0;
337 fNParticleMonitorFunctions = 0;
338 fNTrackMonitorFunctions = 0;
339 fNParticleAndTrackMonitorFunctions = 0;
340 }
341}
342/*************************************************************************************/
e92ecbdf 343Int_t AliHBTAnalysis::ProcessRecAndSim(AliAOD* aodrec, AliAOD* aodsim)
344{
090e46d6 345//Does analysis for both tracks and particles
e92ecbdf 346//mainly for resolution study and analysies with weighting algirithms
e92ecbdf 347
348// cut on particles only -- why?
349// - PID: when we make resolution analysis we want to take only tracks with correct PID
090e46d6 350// We need cut on tracks because there are data characteristic
e92ecbdf 351
352 AliVAODParticle * part1, * part2;
353 AliVAODParticle * track1, * track2;
354
355 AliAOD * trackEvent = aodrec, *partEvent = aodsim;
356 AliAOD* trackEvent1 = new AliAOD();
357 AliAOD* partEvent1 = new AliAOD();
e92ecbdf 358
359 AliAOD * trackEvent2,*partEvent2;
360
361// Int_t N1, N2, N=0; //number of particles in current event(we prcess two events in one time)
362
363// Int_t nev = fReader->GetNumberOfTrackEvents();
090e46d6 364 static AliHBTPair tpair;
365 static AliHBTPair ppair;
e92ecbdf 366
367 AliHBTPair* trackpair = &tpair;
368 AliHBTPair* partpair = &ppair;
369
370 AliHBTPair * tmptrackpair;//temprary pointers to pairs
371 AliHBTPair * tmppartpair;
372
373 register UInt_t ii;
374
375
376
377 if ( !partEvent || !trackEvent )
378 {
a2b9dcc7 379 Error("ProcessRecAndSim","<<%s>> Can not get event",GetName());
e92ecbdf 380 return 1;
381 }
382
383 if ( partEvent->GetNumberOfParticles() != trackEvent->GetNumberOfParticles() )
384 {
385 Error("ProcessRecAndSim",
386 "Number of simulated particles (%d) not equal to number of reconstructed tracks (%d). Skipping Event.",
387 partEvent->GetNumberOfParticles() , trackEvent->GetNumberOfParticles());
388 return 2;
389 }
390
391
392 for (Int_t j = 0; j<partEvent->GetNumberOfParticles() ; j++)
393 {
394 /***************************************/
395 /****** Looping same events ********/
396 /****** filling numerators ********/
397 /***************************************/
398 if ( (j%fDisplayMixingInfo) == 0)
a296aa84 399 Info("ProcessRecAndSim",
e92ecbdf 400 "Mixing particle %d with particles from the same event",j);
401
402 part1= partEvent->GetParticle(j);
403 track1= trackEvent->GetParticle(j);
d50bb49a 404
e92ecbdf 405 Bool_t firstcut = (this->*fkPass1)(part1,track1);
406 if (fBufferSize != 0)
407 if ( (firstcut == kFALSE) || ( (this->*fkPass2)(part1,track1) == kFALSE ) )
408 {
409 //accepted by any cut
410 // we have to copy because reader keeps only one event
411
d50bb49a 412 partEvent1->AddParticle(part1);
413 trackEvent1->AddParticle(track1);
e92ecbdf 414 }
415
416 if (firstcut) continue;
417
418 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
419 fParticleMonitorFunctions[ii]->Process(part1);
420 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
421 fTrackMonitorFunctions[ii]->Process(track1);
422 for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
423 fParticleAndTrackMonitorFunctions[ii]->Process(track1,part1);
424
425 if (fNoCorrfctns) continue;
426
427 for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
428 {
429 part2= partEvent->GetParticle(k);
430 if (part1->GetUID() == part2->GetUID()) continue;
431 partpair->SetParticles(part1,part2);
432
433 track2= trackEvent->GetParticle(k);
434 trackpair->SetParticles(track1,track2);
435
436 if( (this->*fkPass)(partpair,trackpair) ) //check pair cut
437 { //do not meets crietria of the pair cut, try with swapped pairs
438 if( (this->*fkPass)((AliHBTPair*)partpair->GetSwappedPair(),(AliHBTPair*)trackpair->GetSwappedPair()) )
439 continue; //swaped pairs do not meet criteria of pair cut as well, take next particle
440 else
441 { //swaped pair meets all the criteria
442 tmppartpair = (AliHBTPair*)partpair->GetSwappedPair();
443 tmptrackpair = (AliHBTPair*)trackpair->GetSwappedPair();
444 }
445 }
446 else
447 {//meets criteria of the pair cut
448 tmptrackpair = trackpair;
449 tmppartpair = partpair;
450 }
451
452 for(ii = 0;ii<fNParticleFunctions;ii++)
453 fParticleFunctions[ii]->ProcessSameEventParticles(tmppartpair);
454
455 for(ii = 0;ii<fNTrackFunctions;ii++)
456 fTrackFunctions[ii]->ProcessSameEventParticles(tmptrackpair);
457
458 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
459 fParticleAndTrackFunctions[ii]->ProcessSameEventParticles(tmptrackpair,tmppartpair);
460 //end of 2nd loop over particles from the same event
461 }//for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
462
463 /***************************************/
464 /***** Filling denominators *********/
465 /***************************************/
466 if (fBufferSize == 0) continue;
467
468 fPartBuffer->ResetIter();
469 fTrackBuffer->ResetIter();
470 Int_t m = 0;
471 while (( partEvent2 = fPartBuffer->Next() ))
472 {
473 trackEvent2 = fTrackBuffer->Next();
474
475 m++;
476 if ( (j%fDisplayMixingInfo) == 0)
a296aa84 477 Info("ProcessRecAndSim",
e92ecbdf 478 "Mixing particle %d from current event with particles from event %d",j,-m);
479
480 for(Int_t l = 0; l<partEvent2->GetNumberOfParticles();l++) // ... on all particles
481 {
482 part2= partEvent2->GetParticle(l);
483 partpair->SetParticles(part1,part2);
484
485 track2= trackEvent2->GetParticle(l);
486 trackpair->SetParticles(track1,track2);
487
488 if( (this->*fkPass)(partpair,trackpair) ) //check pair cut
489 { //do not meets crietria of the
490 if( (this->*fkPass)((AliHBTPair*)partpair->GetSwappedPair(),(AliHBTPair*)trackpair->GetSwappedPair()) )
491 continue;
492 else
493 {
494 tmppartpair = (AliHBTPair*)partpair->GetSwappedPair();
495 tmptrackpair = (AliHBTPair*)trackpair->GetSwappedPair();
496 }
497 }
498 else
499 {//meets criteria of the pair cut
500 tmptrackpair = trackpair;
501 tmppartpair = partpair;
502 }
503
504 for(ii = 0;ii<fNParticleFunctions;ii++)
505 fParticleFunctions[ii]->ProcessDiffEventParticles(tmppartpair);
506
507 for(ii = 0;ii<fNTrackFunctions;ii++)
508 fTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair);
509
510 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
511 fParticleAndTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair,tmppartpair);
512 }//for(Int_t l = 0; l<N2;l++) // ... on all particles
513
514 }
515 //end of loop over particles from first event
516 }//for (Int_t j = 0; j<partEvent->GetNumberOfParticles() ; j++)
517 delete fPartBuffer->Push(partEvent1);
518 delete fTrackBuffer->Push(trackEvent1);
519 //end of loop over events
520 return 0;
521}
522/*************************************************************************************/
e4f2b1da 523
e92ecbdf 524Int_t AliHBTAnalysis::ProcessSim(AliAOD* /*aodrec*/, AliAOD* aodsim)
525{
090e46d6 526 //Does analysis of simulated data
527 AliVAODParticle * part1, * part2;
528
529 AliAOD* partEvent = aodsim;
530 AliAOD* partEvent1 = new AliAOD();
090e46d6 531
532 AliAOD* partEvent2;
533
534 AliHBTPair ppair;
535
536 AliHBTPair* partpair = &ppair;
537
538 AliHBTPair * tmppartpair;
539
540 register UInt_t ii;
541
542
543
544 if ( !partEvent )
545 {
a296aa84 546 Error("ProcessSim","Can not get event");
090e46d6 547 return 1;
548 }
549
550
551 for (Int_t j = 0; j<partEvent->GetNumberOfParticles() ; j++)
552 {
a296aa84 553 /***************************************/
554 /****** Looping same events ********/
555 /****** filling numerators ********/
556 /***************************************/
557 if ( (j%fDisplayMixingInfo) == 0)
558 Info("ProcessSim",
559 "Mixing particle %d with particles from the same event",j);
090e46d6 560
a296aa84 561 part1= partEvent->GetParticle(j);
090e46d6 562
a296aa84 563 Bool_t firstcut = fPairCut->GetFirstPartCut()->Rejected(part1);
090e46d6 564
a296aa84 565 if (fBufferSize != 0)
566 if ( (firstcut == kFALSE) || ( fPairCut->GetSecondPartCut()->Rejected(part1) == kFALSE ) )
567 {
568 //accepted by any cut
569 // we have to copy because reader keeps only one event
090e46d6 570
a296aa84 571 partEvent1->AddParticle(part1);
572 }
090e46d6 573
a296aa84 574 if (firstcut) continue;
090e46d6 575
a296aa84 576 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
577 fParticleMonitorFunctions[ii]->Process(part1);
090e46d6 578
a296aa84 579 if ( fNParticleFunctions == 0 ) continue;
090e46d6 580
a296aa84 581 for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
582 {
583 part2= partEvent->GetParticle(k);
584 if (part1->GetUID() == part2->GetUID()) continue;
585 partpair->SetParticles(part1,part2);
586
587 if(fPairCut->Rejected(partpair)) //check pair cut
588 { //do not meets crietria of the
589 if( fPairCut->Rejected((AliHBTPair*)partpair->GetSwappedPair()) ) continue;
590 else tmppartpair = (AliHBTPair*)partpair->GetSwappedPair();
591 }
592 else
593 {
594 tmppartpair = partpair;
595 }
090e46d6 596
a296aa84 597 for(ii = 0;ii<fNParticleFunctions;ii++)
598 fParticleFunctions[ii]->ProcessSameEventParticles(tmppartpair);
090e46d6 599
a296aa84 600 //end of 2nd loop over particles from the same event
601 }//for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
090e46d6 602
a296aa84 603 /***************************************/
604 /***** Filling denominators *********/
605 /***************************************/
606 if (fBufferSize == 0) continue;
090e46d6 607
a296aa84 608 fPartBuffer->ResetIter();
609 Int_t m = 0;
610 while (( partEvent2 = fPartBuffer->Next() ))
611 {
612 m++;
613 if ( (j%fDisplayMixingInfo) == 0)
614 Info("ProcessSim",
615 "Mixing particle %d from current event with particles from event %d",j,-m);
616 for(Int_t l = 0; l<partEvent2->GetNumberOfParticles();l++) // ... on all particles
617 {
090e46d6 618
a296aa84 619 part2= partEvent2->GetParticle(l);
620 partpair->SetParticles(part1,part2);
621
622 if( fPairCut->Rejected(partpair) ) //check pair cut
623 { //do not meets crietria of the
624 if( fPairCut->Rejected((AliHBTPair*)partpair->GetSwappedPair()) )
625 continue;
626 else
627 {
628 tmppartpair = (AliHBTPair*)partpair->GetSwappedPair();
629 }
630 }
631 else
632 {//meets criteria of the pair cut
633 tmppartpair = partpair;
634 }
635
636 for(ii = 0;ii<fNParticleFunctions;ii++)
637 fParticleFunctions[ii]->ProcessDiffEventParticles(tmppartpair);
638
639 }//for(Int_t l = 0; l<N2;l++) // ... on all particles
640 }
641 }
642
643
090e46d6 644 delete fPartBuffer->Push(partEvent1);
645 //end of loop over events
646 return 0;
e92ecbdf 647}
648/*************************************************************************************/
649Int_t AliHBTAnalysis::ProcessRec(AliAOD* aodrec, AliAOD* /*aodsim*/)
650{
090e46d6 651 //Does analysis of reconstructed data
652 AliVAODParticle * track1, * track2;
653
654 AliAOD* trackEvent = aodrec;
655 AliAOD* trackEvent1 = new AliAOD();
090e46d6 656
657 AliAOD* trackEvent2;
658
659 AliHBTPair tpair;
660
661 AliHBTPair* trackpair = &tpair;
662
663 AliHBTPair * tmptrackpair;
664
665 register UInt_t ii;
666
667
668 if ( !trackEvent )
669 {
670 Error("ProcessRecAndSim","Can not get event");
671 return 1;
672 }
673
674
675 for (Int_t j = 0; j<trackEvent->GetNumberOfParticles() ; j++)
676 {
677 /***************************************/
678 /****** Looping same events ********/
679 /****** filling numerators ********/
680 /***************************************/
681 if ( (j%fDisplayMixingInfo) == 0)
682 Info("ProcessTracksAndParticles",
683 "Mixing Particle %d with Particles from the same event",j);
684
685 track1= trackEvent->GetParticle(j);
686
cea0a066 687 Bool_t firstcut = fPairCut->GetFirstPartCut()->Rejected(track1);
090e46d6 688
689 if (fBufferSize != 0)
cea0a066 690 if ( (firstcut == kFALSE) || ( fPairCut->GetSecondPartCut()->Rejected(track1) == kFALSE ) )
090e46d6 691 {
692 //accepted by any cut
693 // we have to copy because reader keeps only one event
694
d50bb49a 695 trackEvent1->AddParticle(track1);
090e46d6 696 }
697
698 if (firstcut) continue;
699
700 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
701 fParticleMonitorFunctions[ii]->Process(track1);
702
703 if ( fNParticleFunctions == 0 ) continue;
704
705 for (Int_t k =j+1; k < trackEvent->GetNumberOfParticles() ; k++)
706 {
707 track2= trackEvent->GetParticle(k);
708 if (track1->GetUID() == track2->GetUID()) continue;
709 trackpair->SetParticles(track1,track2);
710
cea0a066 711 if(fPairCut->Rejected(trackpair)) //check pair cut
090e46d6 712 { //do not meets crietria of the
cea0a066 713 if( fPairCut->Rejected((AliHBTPair*)trackpair->GetSwappedPair()) ) continue;
090e46d6 714 else tmptrackpair = (AliHBTPair*)trackpair->GetSwappedPair();
715 }
716 else
717 {
718 tmptrackpair = trackpair;
719 }
720
721 for(ii = 0;ii<fNTrackFunctions;ii++)
722 fParticleFunctions[ii]->ProcessSameEventParticles(tmptrackpair);
723
724 //end of 2nd loop over Particles from the same event
725 }//for (Int_t k =j+1; k < trackEvent->GetNumberOfParticles() ; k++)
726
727 /***************************************/
728 /***** Filling denominators *********/
729 /***************************************/
730 if (fBufferSize == 0) continue;
731
732 fTrackBuffer->ResetIter();
733 Int_t m = 0;
734 while (( trackEvent2 = fTrackBuffer->Next() ))
735 {
736 m++;
737 if ( (j%fDisplayMixingInfo) == 0)
738 Info("ProcessParticles",
739 "Mixing Particle %d from current event with Particles from event %d",j,-m);
740 for(Int_t l = 0; l<trackEvent2->GetNumberOfParticles();l++) // ... on all Particles
741 {
742
743 track2= trackEvent2->GetParticle(l);
744 trackpair->SetParticles(track1,track2);
745
cea0a066 746 if( fPairCut->Rejected(trackpair) ) //check pair cut
090e46d6 747 { //do not meets crietria of the
cea0a066 748 if( fPairCut->Rejected((AliHBTPair*)trackpair->GetSwappedPair()) )
090e46d6 749 continue;
750 else
751 {
752 tmptrackpair = (AliHBTPair*)trackpair->GetSwappedPair();
753 }
754 }
755 else
756 {//meets criteria of the pair cut
757 tmptrackpair = trackpair;
758 }
759
760 for(ii = 0;ii<fNTrackFunctions;ii++)
761 fTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair);
762
763 }//for(Int_t l = 0; l<N2;l++) // ... on all Particles
764 }
765 }
766 delete fTrackBuffer->Push(trackEvent1);
767 //end of loop over events
768 return 0;
e92ecbdf 769}
770/*************************************************************************************/
771
772Int_t AliHBTAnalysis::ProcessRecAndSimNonId(AliAOD* aodrec, AliAOD* aodsim)
773{
090e46d6 774//Analyzes both reconstructed and simulated data
775 if (aodrec == 0x0)
776 {
777 Error("ProcessTracksAndParticlesNonIdentAnal","Reconstructed event is NULL");
778 return 1;
779 }
780
781 if (aodsim == 0x0)
782 {
783 Error("ProcessTracksAndParticlesNonIdentAnal","Simulated event is NULL");
784 return 1;
785 }
786
787 if ( aodrec->GetNumberOfParticles() != aodsim->GetNumberOfParticles() )
788 {
789 Error("ProcessTracksAndParticlesNonIdentAnal",
790 "Number of simulated particles (%d) not equal to number of reconstructed tracks (%d)",
791 aodsim->GetNumberOfParticles() , aodrec->GetNumberOfParticles());
792 return 2;
793 }
794
795
796 AliVAODParticle * part1, * part2;
797 AliVAODParticle * track1, * track2;
798
799 static AliAOD aodrec1;
800 static AliAOD aodsim1;
801
802 AliAOD * trackEvent1=&aodrec1,*partEvent1=&aodsim1;//Particle that passes first particle cut, this event
3dcb03f2 803 trackEvent1->Reset();
804 partEvent1->Reset();
090e46d6 805 AliAOD * trackEvent2=0x0,*partEvent2=0x0;//Particle that passes second particle cut, this event
806 AliAOD * trackEvent3=0x0,*partEvent3=0x0;//Particle that passes second particle cut, events from buffer
807
808 AliAOD* rawtrackEvent = aodrec;//this we get from Reader
809 AliAOD* rawpartEvent = aodsim;//this we get from Reader
810
811 static AliHBTPair tpair;
812 static AliHBTPair ppair;
813
814 AliHBTPair* trackpair = &tpair;
815 AliHBTPair* partpair = &ppair;
816
817 register UInt_t ii;
818
090e46d6 819 /********************************/
820 /* Filtering out */
821 /********************************/
822 if ( ( (partEvent2==0x0) || (trackEvent2==0x0)) )//in case fBufferSize == 0 and pointers are created do not eneter
823 {
824 partEvent2 = new AliAOD();
825 trackEvent2 = new AliAOD();
090e46d6 826 }
827
828 FilterOut(partEvent1, partEvent2, rawpartEvent, trackEvent1, trackEvent2, rawtrackEvent);
829
830 for (Int_t j = 0; j<partEvent1->GetNumberOfParticles() ; j++)
831 {
832 if ( (j%fDisplayMixingInfo) == 0)
833 Info("ProcessTracksAndParticlesNonIdentAnal",
834 "Mixing particle %d from current event with particles from current event",j);
835
836 part1= partEvent1->GetParticle(j);
837 track1= trackEvent1->GetParticle(j);
838
839
840 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
841 fParticleMonitorFunctions[ii]->Process(part1);
842 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
843 fTrackMonitorFunctions[ii]->Process(track1);
844 for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
845 fParticleAndTrackMonitorFunctions[ii]->Process(track1,part1);
846
847 if (fNoCorrfctns) continue;
848
849 /***************************************/
850 /****** filling numerators ********/
851 /****** (particles from event2) ********/
852 /***************************************/
853
854 for (Int_t k = 0; k < partEvent2->GetNumberOfParticles() ; k++) //partEvent1 and partEvent2 are particles from the same event but separated to two groups
855 {
856 part2= partEvent2->GetParticle(k);
857 if (part1->GetUID() == part2->GetUID()) continue;//this is the same particle but with different PID
858 partpair->SetParticles(part1,part2);
859
860 track2= trackEvent2->GetParticle(k);
861 trackpair->SetParticles(track1,track2);
862
863 if( (this->*fkPassPairProp)(partpair,trackpair) ) //check pair cut
864 { //do not meets crietria of the pair cut
865 continue;
866 }
867 else
868 {//meets criteria of the pair cut
869 for(ii = 0;ii<fNParticleFunctions;ii++)
870 fParticleFunctions[ii]->ProcessSameEventParticles(partpair);
871
872 for(ii = 0;ii<fNTrackFunctions;ii++)
873 fTrackFunctions[ii]->ProcessSameEventParticles(trackpair);
874
875 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
876 fParticleAndTrackFunctions[ii]->ProcessSameEventParticles(trackpair,partpair);
877 }
878 }
879
3dcb03f2 880 if ( fBufferSize == 0) continue;//do not mix diff histograms
881 /***************************************/
882 /***** Filling denominators *********/
883 /***************************************/
884 fPartBuffer->ResetIter();
885 fTrackBuffer->ResetIter();
090e46d6 886
3dcb03f2 887 Int_t nmonitor = 0;
090e46d6 888
3dcb03f2 889 while ( (partEvent3 = fPartBuffer->Next() ) != 0x0)
890 {
891 trackEvent3 = fTrackBuffer->Next();
090e46d6 892
3dcb03f2 893 if ( (j%fDisplayMixingInfo) == 0)
894 Info("ProcessTracksAndParticlesNonIdentAnal",
895 "Mixing particle %d from current event with particles from event%d",j,-(++nmonitor));
090e46d6 896
3dcb03f2 897 for (Int_t k = 0; k < partEvent3->GetNumberOfParticles() ; k++)
898 {
899 part2= partEvent3->GetParticle(k);
900 partpair->SetParticles(part1,part2);
090e46d6 901
3dcb03f2 902 track2= trackEvent3->GetParticle(k);
903 trackpair->SetParticles(track1,track2);
090e46d6 904
3dcb03f2 905 if( (this->*fkPassPairProp)(partpair,trackpair) ) //check pair cut
906 { //do not meets crietria of the pair cut
907 continue;
908 }
909 else
910 {//meets criteria of the pair cut
911 UInt_t ii;
912 for(ii = 0;ii<fNParticleFunctions;ii++)
913 fParticleFunctions[ii]->ProcessDiffEventParticles(partpair);
090e46d6 914
3dcb03f2 915 for(ii = 0;ii<fNTrackFunctions;ii++)
916 fTrackFunctions[ii]->ProcessDiffEventParticles(trackpair);
090e46d6 917
3dcb03f2 918 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
919 fParticleAndTrackFunctions[ii]->ProcessDiffEventParticles(trackpair,partpair);
920 }
921 }// for particles event2
922 }//while event2
090e46d6 923 }//for over particles in event1
924
925 delete fPartBuffer->Push(partEvent2);
926 delete fTrackBuffer->Push(trackEvent2);
927
928 return 0;
e92ecbdf 929}
930/*************************************************************************************/
090e46d6 931Int_t AliHBTAnalysis::ProcessSimNonId(AliAOD* /*aodrec*/, AliAOD* aodsim)
e92ecbdf 932{
090e46d6 933//does analysis of simulated (MC) data in non-identical mode
934//i.e. when particles selected by first part. cut are a disjunctive set than particles
935//passed by the second part. cut
936 if (aodsim == 0x0)
937 {
938 return 1;
939 }
940
941
942 AliVAODParticle * part1, * part2;
943
944 static AliAOD aodsim1;
945
946 AliAOD* partEvent1=&aodsim1;//Particle that passes first particle cut, this event
3dcb03f2 947 partEvent1->Reset();
090e46d6 948 AliAOD* partEvent2=0x0;//Particle that passes second particle cut, this event
949 AliAOD* partEvent3=0x0;//Particle that passes second particle cut, events from buffer
950
951 AliAOD* rawpartEvent = aodsim;//this we get from Reader
952
953 static AliHBTPair ppair;
954
955 AliHBTPair* partpair = &ppair;
956
957 register UInt_t ii;
958
090e46d6 959 /********************************/
960 /* Filtering out */
961 /********************************/
962 if (partEvent2==0x0)//in case fBufferSize == 0 and pointers are created do not eneter
963 {
964 partEvent2 = new AliAOD();
090e46d6 965 }
966
967 FilterOut(partEvent1, partEvent2, rawpartEvent);
968
969 for (Int_t j = 0; j<partEvent1->GetNumberOfParticles() ; j++)
970 {
971 if ( (j%fDisplayMixingInfo) == 0)
972 Info("ProcessParticlesNonIdentAnal",
973 "Mixing particle %d from current event with particles from current event",j);
974
975 part1= partEvent1->GetParticle(j);
976
977
978 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
979 fParticleMonitorFunctions[ii]->Process(part1);
980
981 if (fNParticleFunctions == 0) continue;
982
983 /***************************************/
984 /****** filling numerators ********/
985 /****** (particles from event2) ********/
986 /***************************************/
987
988 for (Int_t k = 0; k < partEvent2->GetNumberOfParticles() ; k++) //partEvent1 and partEvent2 are particles from the same event but separated to two groups
989 {
990 part2= partEvent2->GetParticle(k);
991 if (part1->GetUID() == part2->GetUID()) continue;//this is the same particle but with different PID
992 partpair->SetParticles(part1,part2);
993
994
995 if(fPairCut->PassPairProp(partpair) ) //check pair cut
996 { //do not meets crietria of the pair cut
997 continue;
998 }
999 else
1000 {//meets criteria of the pair cut
1001 for(ii = 0;ii<fNParticleFunctions;ii++)
1002 fParticleFunctions[ii]->ProcessSameEventParticles(partpair);
1003 }
1004 }
1005
1006 if ( fBufferSize == 0) continue;//do not mix diff histograms
1007 /***************************************/
1008 /***** Filling denominators *********/
1009 /***************************************/
1010 fPartBuffer->ResetIter();
1011
1012 Int_t nmonitor = 0;
1013
1014 while ( (partEvent3 = fPartBuffer->Next() ) != 0x0)
1015 {
1016
1017 if ( (j%fDisplayMixingInfo) == 0)
1018 Info("ProcessParticlesNonIdentAnal",
1019 "Mixing particle %d from current event with particles from event%d",j,-(++nmonitor));
1020
1021 for (Int_t k = 0; k < partEvent3->GetNumberOfParticles() ; k++)
1022 {
1023 part2= partEvent3->GetParticle(k);
1024 partpair->SetParticles(part1,part2);
1025
1026
1027 if(fPairCut->PassPairProp(partpair) ) //check pair cut
1028 { //do not meets crietria of the pair cut
1029 continue;
1030 }
1031 else
1032 {//meets criteria of the pair cut
1033 for(ii = 0;ii<fNParticleFunctions;ii++)
1034 {
1035 fParticleFunctions[ii]->ProcessDiffEventParticles(partpair);
1036 }
1037 }
1038 }// for particles event2
1039 }//while event2
1040 }//for over particles in event1
1041
1042 delete fPartBuffer->Push(partEvent2);
1043
1044 return 0;
e92ecbdf 1045}
1046/*************************************************************************************/
090e46d6 1047Int_t AliHBTAnalysis::ProcessRecNonId(AliAOD* aodrec, AliAOD* /*aodsim*/)
e92ecbdf 1048{
090e46d6 1049//Analyzes both reconstructed and simulated data
1050 if (aodrec == 0x0)
1051 {
1052 return 1;
1053 }
1054
1055 AliVAODParticle * track1, * track2;
1056
1057 static AliAOD aodrec1;
090e46d6 1058 AliAOD * trackEvent1=&aodrec1;//Particle that passes first particle cut, this event
3dcb03f2 1059 trackEvent1->Reset();
090e46d6 1060 AliAOD * trackEvent2=0x0;//Particle that passes second particle cut, this event
1061 AliAOD * trackEvent3=0x0;//Particle that passes second particle cut, events from buffer
090e46d6 1062 AliAOD* rawtrackEvent = aodrec;//this we get from Reader
1063
1064 static AliHBTPair tpair;
1065
1066 AliHBTPair* trackpair = &tpair;
1067
1068 register UInt_t ii;
1069
1070
090e46d6 1071 /********************************/
1072 /* Filtering out */
1073 /********************************/
1074 if ( trackEvent2==0x0 )//in case fBufferSize == 0 and pointers are created do not eneter
1075 {
1076 trackEvent2 = new AliAOD();
090e46d6 1077 }
1078
1079 FilterOut(trackEvent1, trackEvent2, rawtrackEvent);
1080
1081 for (Int_t j = 0; j<trackEvent1->GetNumberOfParticles() ; j++)
1082 {
1083 if ( (j%fDisplayMixingInfo) == 0)
1084 Info("ProcessTracksNonIdentAnal",
1085 "Mixing particle %d from current event with particles from current event",j);
1086
1087 track1= trackEvent1->GetParticle(j);
1088
1089
1090 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
1091 fTrackMonitorFunctions[ii]->Process(track1);
1092
1093 if (fNTrackFunctions == 0x0) continue;
1094
1095 /***************************************/
1096 /****** filling numerators ********/
1097 /****** (particles from event2) ********/
1098 /***************************************/
1099
1100 for (Int_t k = 0; k < trackEvent2->GetNumberOfParticles() ; k++) //partEvent1 and partEvent2 are particles from the same event but separated to two groups
1101 {
1102 track2= trackEvent2->GetParticle(k);
1103 if (track1->GetUID() == track2->GetUID()) continue;//this is the same particle but with different PID
1104 trackpair->SetParticles(track1,track2);
1105
1106
1107 if( fPairCut->PassPairProp(trackpair)) //check pair cut
1108 { //do not meets crietria of the pair cut
1109 continue;
1110 }
1111 else
1112 {//meets criteria of the pair cut
1113 UInt_t ii;
1114 for(ii = 0;ii<fNTrackFunctions;ii++)
1115 fTrackFunctions[ii]->ProcessSameEventParticles(trackpair);
1116 }
1117 }
1118
1119 if ( fBufferSize == 0) continue;//do not mix diff histograms
1120 /***************************************/
1121 /***** Filling denominators *********/
1122 /***************************************/
1123 fTrackBuffer->ResetIter();
1124
1125 Int_t nmonitor = 0;
1126
1127 while ( (trackEvent3 = fTrackBuffer->Next() ) != 0x0)
1128 {
1129 if ( (j%fDisplayMixingInfo) == 0)
1130 Info("ProcessTracksNonIdentAnal",
1131 "Mixing particle %d from current event with particles from event%d",j,-(++nmonitor));
1132
1133 for (Int_t k = 0; k < trackEvent3->GetNumberOfParticles() ; k++)
1134 {
1135 track2= trackEvent3->GetParticle(k);
1136 trackpair->SetParticles(track1,track2);
1137
1138 if( fPairCut->PassPairProp(trackpair)) //check pair cut
1139 { //do not meets crietria of the pair cut
1140 continue;
1141 }
1142 else
1143 {//meets criteria of the pair cut
1144 for(ii = 0;ii<fNTrackFunctions;ii++)
1145 fTrackFunctions[ii]->ProcessDiffEventParticles(trackpair);
1146 }
1147 }// for particles event2
1148 }//while event2
1149 }//for over particles in event1
1150
1151 delete fTrackBuffer->Push(trackEvent2);
1152
1153 return 0;
e92ecbdf 1154}
1155/*************************************************************************************/
090e46d6 1156
1b446896 1157void AliHBTAnalysis::Process(Option_t* option)
1158{
1159 //default option = "TracksAndParticles"
1160 //Main method of the HBT Analysis Package
1161 //It triggers reading with the global cut (default is an empty cut)
1162 //Than it checks options and data which are read
1163 //if everything is OK, then it calls one of the looping methods
1164 //depending on tfReaderhe option
1165 //These methods differs on what thay are looping on
1166 //
1167 // METHOD OPTION
1168 //--------------------------------------------------------------------
1169 //ProcessTracksAndParticles - "TracksAndParticles"
1170 // DEFAULT
1171 // it loops over both, tracks(reconstructed) and particles(simulated)
1172 // all function gethered in all 3 lists are called for each (double)pair
1173 //
1174 //ProcessTracks - "Tracks"
1175 // it loops only on tracks(reconstructed),
1176 // functions ONLY from fTrackFunctions list are called
1177 //
1178 //ProcessParticles - "Particles"
1179 // it loops only on particles(simulated),
1180 // functions ONLY from fParticleAndTrackFunctions list are called
1181 //
1182 //
1183 if (!fReader)
1184 {
01725374 1185 Error("Process","The reader is not set");
1b446896 1186 return;
1187 }
1188
1b446896 1189 const char *oT = strstr(option,"Tracks");
1190 const char *oP = strstr(option,"Particles");
1191
dc2c3f36 1192 Bool_t nonid = IsNonIdentAnalysis();
1193
bed069a4 1194 Init();
1195
1b446896 1196 if(oT && oP)
1197 {
dc2c3f36 1198 if (nonid) ProcessTracksAndParticlesNonIdentAnal();
1199 else ProcessTracksAndParticles();
1b446896 1200 return;
1201 }
1202
1203 if(oT)
1204 {
dc2c3f36 1205 if (nonid) ProcessTracksNonIdentAnal();
1206 else ProcessTracks();
1b446896 1207 return;
1208 }
1209
1210 if(oP)
1211 {
dc2c3f36 1212 if (nonid) ProcessParticlesNonIdentAnal();
1213 else ProcessParticles();
1b446896 1214 return;
1215 }
1216
1217}
1b446896 1218/*************************************************************************************/
491d1b5d 1219
1b446896 1220void AliHBTAnalysis::ProcessTracksAndParticles()
1221{
9616170a 1222//Makes analysis for both tracks and particles
1223//mainly for resolution study and analysies with weighting algirithms
1b446896 1224//In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
1225//the loops are splited
1226
66d1d1a4 1227// cut on particles only -- why?
1228// - PID: when we make resolution analysis we want to take only tracks with correct PID
1229// We need cut on tracks because there are data characteristic to
1b446896 1230
78d7c6d3 1231 AliAOD * trackEvent, *partEvent;
81b7b887 1232
bed069a4 1233 fReader->Rewind();
bed069a4 1234 while (fReader->Next() == kFALSE)
1b446896 1235 {
e92ecbdf 1236 partEvent = fReader->GetEventSim();
78d7c6d3 1237 trackEvent = fReader->GetEventRec();
e92ecbdf 1238 ProcessRecAndSim(trackEvent,partEvent);
1b446896 1239
bed069a4 1240 }//while (fReader->Next() == kFALSE)
4cb6e8f7 1241
1b446896 1242}
1243/*************************************************************************************/
1244
1245void AliHBTAnalysis::ProcessTracks()
1246{
2dc7203b 1247//In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
1b446896 1248//the loops are splited
78d7c6d3 1249 AliAOD * trackEvent;
bed069a4 1250 fReader->Rewind();
bed069a4 1251 while (fReader->Next() == kFALSE)
1b446896 1252 {
78d7c6d3 1253 trackEvent = fReader->GetEventRec();
090e46d6 1254 ProcessRec(trackEvent,0x0);
bed069a4 1255 }//while (fReader->Next() == kFALSE)
1b446896 1256}
1257
1258/*************************************************************************************/
491d1b5d 1259
1b446896 1260void AliHBTAnalysis::ProcessParticles()
1261{
81b7b887 1262//In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
1b446896 1263//the loops are splited
78d7c6d3 1264 AliAOD * partEvent;
bed069a4 1265 fReader->Rewind();
bed069a4 1266 while (fReader->Next() == kFALSE)
1b446896 1267 {
78d7c6d3 1268 partEvent = fReader->GetEventSim();
090e46d6 1269 ProcessSim(0x0,partEvent);
bed069a4 1270 }//while (fReader->Next() == kFALSE)
1b446896 1271}
1b446896 1272/*************************************************************************************/
1273
491d1b5d 1274void AliHBTAnalysis::WriteFunctions()
1b446896 1275{
81b7b887 1276//Calls Write for all defined functions in analysis
1277//== writes all results
8fba7c63 1278 TFile* oututfile = 0x0;
1279 if (fOutputFileName)
1280 {
1281 oututfile = TFile::Open(*fOutputFileName,"update");
1282 }
1b446896 1283 UInt_t ii;
1284 for(ii = 0;ii<fNParticleFunctions;ii++)
90520373 1285 {
78d7c6d3 1286 if (AliVAODParticle::GetDebug()>5)
90520373 1287 {
1288 Info("WriteFunctions","Writing ParticleFunction %#x",fParticleFunctions[ii]);
1289 Info("WriteFunctions","Writing ParticleFunction %s",fParticleFunctions[ii]->Name());
1290 }
1291 fParticleFunctions[ii]->Write();
1292 }
1b446896 1293
1294 for(ii = 0;ii<fNTrackFunctions;ii++)
90520373 1295 {
78d7c6d3 1296 if (AliVAODParticle::GetDebug()>5)
90520373 1297 {
1298 Info("WriteFunctions","Writing TrackFunction %#x",fTrackFunctions[ii]);
1299 Info("WriteFunctions","Writing TrackFunction %s",fTrackFunctions[ii]->Name());
1300 }
1301 fTrackFunctions[ii]->Write();
1302 }
1b446896 1303
1304 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
90520373 1305 {
78d7c6d3 1306 if (AliVAODParticle::GetDebug()>5)
90520373 1307 {
1308 Info("WriteFunctions","Writing ParticleAndTrackFunction %#x",fParticleAndTrackFunctions[ii]);
1309 Info("WriteFunctions","Writing ParticleAndTrackFunction %s",fParticleAndTrackFunctions[ii]->Name());
1310 }
1311 fParticleAndTrackFunctions[ii]->Write();
1312 }
5c58441a 1313
1314 for(ii = 0;ii<fNParticleMonitorFunctions;ii++)
90520373 1315 {
78d7c6d3 1316 if (AliVAODParticle::GetDebug()>5)
90520373 1317 {
1318 Info("WriteFunctions","Writing ParticleMonitorFunction %#x",fParticleMonitorFunctions[ii]);
1319 Info("WriteFunctions","Writing ParticleMonitorFunction %s",fParticleMonitorFunctions[ii]->Name());
1320 }
1321 fParticleMonitorFunctions[ii]->Write();
1322 }
5c58441a 1323
1324 for(ii = 0;ii<fNTrackMonitorFunctions;ii++)
90520373 1325 {
78d7c6d3 1326 if (AliVAODParticle::GetDebug()>5)
90520373 1327 {
1328 Info("WriteFunctions","Writing TrackMonitorFunction %#x",fTrackMonitorFunctions[ii]);
1329 Info("WriteFunctions","Writing TrackMonitorFunction %s",fTrackMonitorFunctions[ii]->Name());
1330 }
1331 fTrackMonitorFunctions[ii]->Write();
1332 }
5c58441a 1333
1334 for(ii = 0;ii<fNParticleAndTrackMonitorFunctions;ii++)
90520373 1335 {
78d7c6d3 1336 if (AliVAODParticle::GetDebug()>5)
90520373 1337 {
1338 Info("WriteFunctions","Writing ParticleAndTrackMonitorFunction %#x",fParticleAndTrackMonitorFunctions[ii]);
1339 Info("WriteFunctions","Writing ParticleAndTrackMonitorFunction %s",fParticleAndTrackMonitorFunctions[ii]->Name());
1340 }
1341 fParticleAndTrackMonitorFunctions[ii]->Write();
1342 }
8fba7c63 1343 delete oututfile;
1344}
1345/*************************************************************************************/
1346
1347void AliHBTAnalysis::SetOutputFileName(const char* fname)
1348{
1349 //Sets fiele name where to dump results,
1350 //if not specified reults are written to gDirectory
1351 if (fname == 0x0)
1352 {
1353 delete fOutputFileName;
1354 fOutputFileName = 0x0;
1355 return;
1356 }
1357 if ( strcmp(fname,"") == 0 )
1358 {
1359 delete fOutputFileName;
1360 fOutputFileName = 0x0;
1361 return;
1362 }
1363 if (fOutputFileName == 0x0) fOutputFileName = new TString(fname);
1364 else *fOutputFileName = fname;
1b446896 1365}
1366/*************************************************************************************/
491d1b5d 1367
78d7c6d3 1368void AliHBTAnalysis::SetGlobalPairCut(AliAODPairCut* cut)
1b446896 1369{
81b7b887 1370//Sets the global cut
1b446896 1371 if (cut == 0x0)
1372 {
1373 Error("AliHBTAnalysis::SetGlobalPairCut","Pointer is NULL. Ignoring");
1374 }
1375 delete fPairCut;
78d7c6d3 1376 fPairCut = (AliAODPairCut*)cut->Clone();
1b446896 1377}
1378
1379/*************************************************************************************/
491d1b5d 1380
27b3fe5d 1381void AliHBTAnalysis::AddTrackFunction(AliHBTOnePairFctn* f)
1b446896 1382{
81b7b887 1383//Adds track function
1b446896 1384 if (f == 0x0) return;
1385 if (fNTrackFunctions == fgkFctnArraySize)
1386 {
1387 Error("AliHBTAnalysis::AddTrackFunction","Can not add this function, not enough place in the array.");
1388 }
1389 fTrackFunctions[fNTrackFunctions] = f;
1390 fNTrackFunctions++;
1391}
491d1b5d 1392/*************************************************************************************/
1393
27b3fe5d 1394void AliHBTAnalysis::AddParticleFunction(AliHBTOnePairFctn* f)
1b446896 1395{
81b7b887 1396//adds particle function
1b446896 1397 if (f == 0x0) return;
1398
1399 if (fNParticleFunctions == fgkFctnArraySize)
1400 {
1401 Error("AliHBTAnalysis::AddParticleFunction","Can not add this function, not enough place in the array.");
1402 }
1403 fParticleFunctions[fNParticleFunctions] = f;
1404 fNParticleFunctions++;
1b446896 1405}
5c58441a 1406/*************************************************************************************/
1407
27b3fe5d 1408void AliHBTAnalysis::AddParticleAndTrackFunction(AliHBTTwoPairFctn* f)
1b446896 1409{
81b7b887 1410//add resolution function
1b446896 1411 if (f == 0x0) return;
1412 if (fNParticleAndTrackFunctions == fgkFctnArraySize)
1413 {
1414 Error("AliHBTAnalysis::AddParticleAndTrackFunction","Can not add this function, not enough place in the array.");
1415 }
1416 fParticleAndTrackFunctions[fNParticleAndTrackFunctions] = f;
1417 fNParticleAndTrackFunctions++;
1418}
5c58441a 1419/*************************************************************************************/
1420
1421void AliHBTAnalysis::AddParticleMonitorFunction(AliHBTMonOneParticleFctn* f)
1422{
81b7b887 1423//add particle monitoring function
5c58441a 1424 if (f == 0x0) return;
1425
1426 if (fNParticleMonitorFunctions == fgkFctnArraySize)
1427 {
1428 Error("AliHBTAnalysis::AddParticleMonitorFunction","Can not add this function, not enough place in the array.");
1429 }
1430 fParticleMonitorFunctions[fNParticleMonitorFunctions] = f;
1431 fNParticleMonitorFunctions++;
1432}
1433/*************************************************************************************/
1b446896 1434
5c58441a 1435void AliHBTAnalysis::AddTrackMonitorFunction(AliHBTMonOneParticleFctn* f)
1436{
81b7b887 1437//add track monitoring function
5c58441a 1438 if (f == 0x0) return;
1b446896 1439
5c58441a 1440 if (fNTrackMonitorFunctions == fgkFctnArraySize)
1441 {
1442 Error("AliHBTAnalysis::AddTrackMonitorFunction","Can not add this function, not enough place in the array.");
1443 }
1444 fTrackMonitorFunctions[fNTrackMonitorFunctions] = f;
1445 fNTrackMonitorFunctions++;
1446}
1b446896 1447/*************************************************************************************/
1448
5c58441a 1449void AliHBTAnalysis::AddParticleAndTrackMonitorFunction(AliHBTMonTwoParticleFctn* f)
1450{
81b7b887 1451//add resolution monitoring function
5c58441a 1452 if (f == 0x0) return;
1453 if (fNParticleAndTrackMonitorFunctions == fgkFctnArraySize)
1454 {
1455 Error("AliHBTAnalysis::AddParticleAndTrackMonitorFunction","Can not add this function, not enough place in the array.");
1456 }
1457 fParticleAndTrackMonitorFunctions[fNParticleAndTrackMonitorFunctions] = f;
1458 fNParticleAndTrackMonitorFunctions++;
1459}
1460
1b446896 1461
5c58441a 1462/*************************************************************************************/
1b446896 1463/*************************************************************************************/
491d1b5d 1464
1b446896 1465Bool_t AliHBTAnalysis::RunCoherencyCheck()
1466{
1467 //Checks if both HBTRuns are similar
1468 //return true if error found
1469 //if they seem to be OK return false
78d7c6d3 1470/*
1471
1b446896 1472 Int_t i;
81b7b887 1473 Info("RunCoherencyCheck","Checking HBT Runs Coherency");
1474
78d7c6d3 1475//When we use non-buffering reader this is a big waste of time -> We need to read all data to check it
1476//and reader is implemented safe in this case anyway
1477// Info("RunCoherencyCheck","Number of events ...");
1478// if (fReader->GetNumberOfPartEvents() == fReader->GetNumberOfTrackEvents() ) //check whether there is the same number of events
1479// {
1480// Info("RunCoherencyCheck","OK. %d found\n",fReader->GetNumberOfTrackEvents());
1481// }
1482// else
1483// { //if not the same - ERROR
1484// Error("RunCoherencyCheck",
1485// "Number of simulated events (%d) is not equal to number of reconstructed events(%d)",
1486// fReader->GetNumberOfPartEvents(),fReader->GetNumberOfTrackEvents());
1487// return kTRUE;
1488// }
1b446896 1489
81b7b887 1490 Info("RunCoherencyCheck","Checking number of Particles AND Particles Types in each event ...");
1b446896 1491
78d7c6d3 1492 AliAOD *partEvent;
1493 AliAOD *trackEvent;
1b446896 1494 for( i = 0; i<fReader->GetNumberOfTrackEvents();i++)
1495 {
78d7c6d3 1496 partEvent= fReader->GetEventSim(i); //gets the "ith" event
1497 trackEvent = fReader->GetEventRec(i);
1b446896 1498
1499 if ( (partEvent == 0x0) && (partEvent == 0x0) ) continue;
1500 if ( (partEvent == 0x0) || (partEvent == 0x0) )
1501 {
78d7c6d3 1502 Error("RunCoherencyCheck",
1b446896 1503 "One event is NULL and the other one not. Event Number %d",i);
1504 return kTRUE;
1505 }
1506
1507 if ( partEvent->GetNumberOfParticles() != trackEvent->GetNumberOfParticles() )
1508 {
78d7c6d3 1509 Error("RunCoherencyCheck",
1b446896 1510 "Event %d: Number of simulated particles (%d) not equal to number of reconstructed tracks (%d)",
1511 i,partEvent->GetNumberOfParticles() , trackEvent->GetNumberOfParticles());
1512 return kTRUE;
1513 }
1514 else
1515 for (Int_t j = 0; j<partEvent->GetNumberOfParticles(); j++)
1516 {
1517 if( partEvent->GetParticle(j)->GetPdgCode() != trackEvent->GetParticle(j)->GetPdgCode() )
1518 {
78d7c6d3 1519 Error("RunCoherencyCheck",
1b446896 1520 "Event %d: Particle %d: PID of simulated particle (%d) not the same of reconstructed track (%d)",
1521 i,j, partEvent->GetParticle(j)->GetPdgCode(),trackEvent->GetParticle(j)->GetPdgCode() );
1522 return kTRUE;
1523
1524 }
1525 }
1526 }
81b7b887 1527 Info("RunCoherencyCheck"," Done");
1528 Info("RunCoherencyCheck"," Everything looks OK");
78d7c6d3 1529*/
1b446896 1530 return kFALSE;
1531}
1532
dc2c3f36 1533/*************************************************************************************/
1534
1535void AliHBTAnalysis::ProcessTracksAndParticlesNonIdentAnal()
1536{
81b7b887 1537//Performs analysis for both, tracks and particles
090e46d6 1538 AliAOD* rawtrackEvent, * rawpartEvent;
bed069a4 1539 fReader->Rewind();
090e46d6 1540
81b7b887 1541 Info("ProcessTracksAndParticlesNonIdentAnal","**************************************");
1542 Info("ProcessTracksAndParticlesNonIdentAnal","***** NON IDENT MODE ****************");
1543 Info("ProcessTracksAndParticlesNonIdentAnal","**************************************");
090e46d6 1544
bed069a4 1545 for (Int_t i = 0;;i++)//infinite loop
dc2c3f36 1546 {
bed069a4 1547 if (fReader->Next()) break; //end when no more events available
1548
78d7c6d3 1549 rawpartEvent = fReader->GetEventSim();
1550 rawtrackEvent = fReader->GetEventRec();
bed069a4 1551
090e46d6 1552 ProcessRecAndSimNonId(rawtrackEvent,rawpartEvent);
dc2c3f36 1553 }//end of loop over events (1)
dc2c3f36 1554}
1b446896 1555/*************************************************************************************/
1556
dc2c3f36 1557void AliHBTAnalysis::ProcessTracksNonIdentAnal()
1558{
2dc7203b 1559//Process Tracks only with non identical mode
78d7c6d3 1560 AliAOD * rawtrackEvent;
bed069a4 1561 fReader->Rewind();
1562
81b7b887 1563 Info("ProcessTracksNonIdentAnal","**************************************");
1564 Info("ProcessTracksNonIdentAnal","***** NON IDENT MODE ****************");
1565 Info("ProcessTracksNonIdentAnal","**************************************");
1566
bed069a4 1567 for (Int_t i = 0;;i++)//infinite loop
dc2c3f36 1568 {
bed069a4 1569 if (fReader->Next()) break; //end when no more events available
78d7c6d3 1570 rawtrackEvent = fReader->GetEventRec();
090e46d6 1571 ProcessRecNonId(rawtrackEvent,0x0);
dc2c3f36 1572 }//end of loop over events (1)
dc2c3f36 1573}
1574/*************************************************************************************/
1575
1576void AliHBTAnalysis::ProcessParticlesNonIdentAnal()
1577{
2dc7203b 1578//process paricles only with non identical mode
78d7c6d3 1579 AliAOD * rawpartEvent = 0x0;
bed069a4 1580 fReader->Rewind();
dc2c3f36 1581
81b7b887 1582 Info("ProcessParticlesNonIdentAnal","**************************************");
1583 Info("ProcessParticlesNonIdentAnal","***** NON IDENT MODE ****************");
1584 Info("ProcessParticlesNonIdentAnal","**************************************");
dc2c3f36 1585
bed069a4 1586 for (Int_t i = 0;;i++)//infinite loop
dc2c3f36 1587 {
bed069a4 1588 if (fReader->Next()) break; //end when no more events available
1589
78d7c6d3 1590 rawpartEvent = fReader->GetEventSim();
090e46d6 1591 ProcessSimNonId(0x0,rawpartEvent);
dc2c3f36 1592 }//end of loop over events (1)
dc2c3f36 1593}
1594
1595/*************************************************************************************/
78d7c6d3 1596void AliHBTAnalysis::FilterOut(AliAOD* outpart1, AliAOD* outpart2, AliAOD* inpart,
1597 AliAOD* outtrack1, AliAOD* outtrack2, AliAOD* intrack) const
dc2c3f36 1598{
1599 //Puts particles accepted as a first particle by global cut in out1
1600 //and as a second particle in out2
1601
78d7c6d3 1602 AliVAODParticle* part, *track;
dc2c3f36 1603
1604 outpart1->Reset();
1605 outpart2->Reset();
1606 outtrack1->Reset();
1607 outtrack2->Reset();
1608
dc2c3f36 1609 Bool_t in1, in2;
1610
1611 for (Int_t i = 0; i < inpart->GetNumberOfParticles(); i++)
1612 {
1613 in1 = in2 = kTRUE;
1614 part = inpart->GetParticle(i);
1615 track = intrack->GetParticle(i);
1616
17d74b37 1617 if ( ((this->*fkPass1)(part,track)) ) in1 = kFALSE; //if part is rejected by cut1, in1 is false
1618 if ( ((this->*fkPass2)(part,track)) ) in2 = kFALSE; //if part is rejected by cut2, in2 is false
dc2c3f36 1619
1620 if (gDebug)//to be removed in real analysis
1621 if ( in1 && in2 ) //both cuts accepted, should never happen, just in case
1622 {
1623 //Particle accpted by both cuts
1624 Error("FilterOut","Particle accepted by both cuts");
1625 continue;
1626 }
1627
1628 if (in1)
1629 {
1630 outpart1->AddParticle(part);
1631 outtrack1->AddParticle(track);
1632 continue;
1633 }
1634
1635 if (in2)
1636 {
d50bb49a 1637 outpart2->AddParticle(part);
1638 outtrack2->AddParticle(track);
dc2c3f36 1639 continue;
1640 }
1641 }
dc2c3f36 1642}
1b446896 1643/*************************************************************************************/
81b7b887 1644
78d7c6d3 1645void AliHBTAnalysis::FilterOut(AliAOD* out1, AliAOD* out2, AliAOD* in) const
dc2c3f36 1646{
1647 //Puts particles accepted as a first particle by global cut in out1
1648 //and as a second particle in out2
78d7c6d3 1649 AliVAODParticle* part;
dc2c3f36 1650
1651 out1->Reset();
1652 out2->Reset();
1653
78d7c6d3 1654 AliAODParticleCut *cut1 = fPairCut->GetFirstPartCut();
1655 AliAODParticleCut *cut2 = fPairCut->GetSecondPartCut();
dc2c3f36 1656
1657 Bool_t in1, in2;
1658
1659 for (Int_t i = 0; i < in->GetNumberOfParticles(); i++)
1660 {
1661 in1 = in2 = kTRUE;
1662 part = in->GetParticle(i);
1663
cea0a066 1664 if ( cut1->Rejected(part) ) in1 = kFALSE; //if part is rejected by cut1, in1 is false
1665 if ( cut2->Rejected(part) ) in2 = kFALSE; //if part is rejected by cut2, in2 is false
dc2c3f36 1666
1667 if (gDebug)//to be removed in real analysis
1668 if ( in1 && in2 ) //both cuts accepted, should never happen, just in case
1669 {
1670 //Particle accpted by both cuts
1671 Error("FilterOut","Particle accepted by both cuts");
1672 continue;
1673 }
1b446896 1674
dc2c3f36 1675 if (in1)
1676 {
1677 out1->AddParticle(part);
1678 continue;
1679 }
1680
1681 if (in2)
1682 {
d50bb49a 1683 out2->AddParticle(part);
dc2c3f36 1684 continue;
1685 }
1686 }
1687}
1688/*************************************************************************************/
1b446896 1689
dc2c3f36 1690Bool_t AliHBTAnalysis::IsNonIdentAnalysis()
1691{
1692 //checks if it is possible to use special analysis for non identical particles
1693 //it means - in global pair cut first particle id is different than second one
1694 //and both are different from 0
1695 //in the future is possible to perform more sophisticated check
1696 //if cuts have excluding requirements
1697
5c58441a 1698 if (fPairCut->IsEmpty())
1699 return kFALSE;
1700
1701 if (fPairCut->GetFirstPartCut()->IsEmpty())
1702 return kFALSE;
1703
1704 if (fPairCut->GetSecondPartCut()->IsEmpty())
1705 return kFALSE;
dc2c3f36 1706
1707 Int_t id1 = fPairCut->GetFirstPartCut()->GetPID();
1708 Int_t id2 = fPairCut->GetSecondPartCut()->GetPID();
dc2c3f36 1709
5c58441a 1710 if ( (id1==0) || (id2==0) || (id1==id2) )
1711 return kFALSE;
1712
dc2c3f36 1713 return kTRUE;
1714}
66d1d1a4 1715/*************************************************************************************/
9616170a 1716
5994509d 1717void AliHBTAnalysis::SetApparentVertex(Double_t x, Double_t y, Double_t z)
1718{
1719 //Sets apparent vertex
1720 // All events have to be moved to the same vertex position in order to
1721 // to be able to comare any space positions (f.g. anti-merging)
1722 // This method defines this position
1723
1724 fVertexX = x;
1725 fVertexY = y;
1726 fVertexZ = z;
1727}
1728/*************************************************************************************/
1729
9616170a 1730void AliHBTAnalysis::PressAnyKey()
17d74b37 1731{
1732 //small utility function that helps to make comfortable macros
9616170a 1733 char c;
1734 int nread = -1;
1735 fcntl(0, F_SETFL, O_NONBLOCK);
1736 ::Info("","Press Any Key to continue ...");
1737 while (nread<1)
1738 {
1739 nread = read(0, &c, 1);
1740 gSystem->ProcessEvents();
1741 }
1742}
1743
66d1d1a4 1744/*************************************************************************************/
9616170a 1745